From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752640AbcEQTEJ (ORCPT ); Tue, 17 May 2016 15:04:09 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36102 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751220AbcEQTEH (ORCPT ); Tue, 17 May 2016 15:04:07 -0400 From: Jarod Wilson To: linux-kernel@vger.kernel.org Cc: Jarod Wilson , Jeff Kirsher , intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org Subject: [RFC PATCH net] e1000e: keep vlan interfaces functional after rxvlan off Date: Tue, 17 May 2016 15:03:51 -0400 Message-Id: <1463511831-13684-1-git-send-email-jarod@redhat.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Tue, 17 May 2016 19:04:06 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org I've got a bug report about an e1000e interface, where a vlan interface is set up on top of it: $ ip link add link ens1f0 name ens1f0.99 type vlan id 99 $ ip link set ens1f0 up $ ip link set ens1f0.99 up $ ip addr add 192.168.99.92 dev ens1f0.99 At this point, I can ping another host on vlan 99, ip 192.168.99.91. However, if I do the following: $ ethtool -K ens1f0 rxvlan off Then no traffic passes on ens1f0.99. It comes back if I toggle rxvlan on again. I'm not sure if this is actually intended behavior, or if there's a lack of software vlan stripping fallback, or what, but things continue to work if I simply don't call e1000e_vlan_strip_disable() if there are active vlans (plagiarizing a function from the e1000 driver here) on the interface. Also slipped a related-ish fix to the kerneldoc text for e1000e_vlan_strip_disable here... CC: Jeff Kirsher CC: intel-wired-lan@lists.osuosl.org CC: netdev@vger.kernel.org Signed-off-by: Jarod Wilson --- drivers/net/ethernet/intel/e1000e/netdev.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 75e6089..73f7452 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -154,6 +154,16 @@ void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val) writel(val, hw->hw_addr + reg); } +static bool e1000e_vlan_used(struct e1000_adapter *adapter) +{ + u16 vid; + + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) + return true; + + return false; +} + /** * e1000_regdump - register printout routine * @hw: pointer to the HW structure @@ -2789,7 +2799,7 @@ static void e1000e_vlan_filter_enable(struct e1000_adapter *adapter) } /** - * e1000e_vlan_strip_enable - helper to disable HW VLAN stripping + * e1000e_vlan_strip_disable - helper to disable HW VLAN stripping * @adapter: board private structure to initialize **/ static void e1000e_vlan_strip_disable(struct e1000_adapter *adapter) @@ -3443,7 +3453,8 @@ static void e1000e_set_rx_mode(struct net_device *netdev) ew32(RCTL, rctl); - if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) + if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX || + e1000e_vlan_used(adapter)) e1000e_vlan_strip_enable(adapter); else e1000e_vlan_strip_disable(adapter); -- 1.8.3.1