Module Name: src Committed By: msaitoh Date: Fri Sep 15 08:31:32 UTC 2017
Modified Files: src/sys/dev/pci/ixgbe: ixv.c Log Message: xv(4) VLAN fixes: - Dirty hack for VID mask bits. On ixg(4), VLAN filter is disabled. So any vlan ID's packet passes RX filter. On ixv(4), usually, PF driver uses VLAN filter enabled. There is no way to disable PF's VLAN filter function itself. NetBSD's Ethernet driver has currently no API to know which VLAN ID should be accepted. To avoid this proble, enable all VIDs... Yes, I know this is dirty hack. We should rethink. - Call ixv_setup_vlan_support() in ixv_ifflags_cb(). - Don't use global ixv_shadow_vfta[]. - Use local variable (rxr->) to reduce diff against ixgbe.c. No functional change. To generate a diff of this commit: cvs rdiff -u -r1.64 -r1.65 src/sys/dev/pci/ixgbe/ixv.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/ixgbe/ixv.c diff -u src/sys/dev/pci/ixgbe/ixv.c:1.64 src/sys/dev/pci/ixgbe/ixv.c:1.65 --- src/sys/dev/pci/ixgbe/ixv.c:1.64 Fri Sep 15 04:52:32 2017 +++ src/sys/dev/pci/ixgbe/ixv.c Fri Sep 15 08:31:32 2017 @@ -1,4 +1,4 @@ -/*$NetBSD: ixv.c,v 1.64 2017/09/15 04:52:32 msaitoh Exp $*/ +/*$NetBSD: ixv.c,v 1.65 2017/09/15 08:31:32 msaitoh Exp $*/ /****************************************************************************** @@ -204,13 +204,6 @@ TUNABLE_INT("hw.ixv.rxd", &ixv_rxd); static int ixv_enable_legacy_tx = 0; TUNABLE_INT("hw.ixv.enable_legacy_tx", &ixv_enable_legacy_tx); -/* - * Shadow VFTA table, this is needed because - * the real filter table gets cleared during - * a soft reset and we need to repopulate it. - */ -static u32 ixv_shadow_vfta[IXGBE_VFTA_SIZE]; - #ifdef NET_MPSAFE #define IXGBE_MPSAFE 1 #define IXGBE_CALLOUT_FLAGS CALLOUT_MPSAFE @@ -1713,7 +1706,9 @@ ixv_initialize_receive_units(struct adap static void ixv_setup_vlan_support(struct adapter *adapter) { + struct ethercom *ec = &adapter->osdep.ec; struct ixgbe_hw *hw = &adapter->hw; + struct rx_ring *rxr; u32 ctrl, vid, vfta, retry; /* @@ -1722,29 +1717,35 @@ ixv_setup_vlan_support(struct adapter *a * the VFTA and other state, so if there * have been no vlan's registered do nothing. */ - if (!VLAN_ATTACHED(&adapter->osdep.ec)) + if (!VLAN_ATTACHED(ec)) return; /* Enable the queues */ for (int i = 0; i < adapter->num_queues; i++) { - ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); + rxr = &adapter->rx_rings[i]; + ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(rxr->me)); ctrl |= IXGBE_RXDCTL_VME; - IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), ctrl); + IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(rxr->me), ctrl); /* * Let Rx path know that it needs to store VLAN tag * as part of extra mbuf info. */ - adapter->rx_rings[i].vtag_strip = TRUE; + rxr->vtag_strip = TRUE; } +#if 1 + /* XXX dirty hack. Enable all VIDs */ + for (int i = 0; i < IXGBE_VFTA_SIZE; i++) + adapter->shadow_vfta[i] = 0xffffffff; +#endif /* * A soft reset zero's out the VFTA, so * we need to repopulate it now. */ for (int i = 0; i < IXGBE_VFTA_SIZE; i++) { - if (ixv_shadow_vfta[i] == 0) + if (adapter->shadow_vfta[i] == 0) continue; - vfta = ixv_shadow_vfta[i]; + vfta = adapter->shadow_vfta[i]; /* * Reconstruct the vlan id's * based on the bits set in each @@ -1788,7 +1789,7 @@ ixv_register_vlan(void *arg, struct ifne IXGBE_CORE_LOCK(adapter); index = (vtag >> 5) & 0x7F; bit = vtag & 0x1F; - ixv_shadow_vfta[index] |= (1 << bit); + adapter->shadow_vfta[index] |= (1 << bit); /* Re-init to load the changes */ ixv_init_locked(adapter); IXGBE_CORE_UNLOCK(adapter); @@ -1815,7 +1816,7 @@ ixv_unregister_vlan(void *arg, struct if IXGBE_CORE_LOCK(adapter); index = (vtag >> 5) & 0x7F; bit = vtag & 0x1F; - ixv_shadow_vfta[index] &= ~(1 << bit); + adapter->shadow_vfta[index] &= ~(1 << bit); /* Re-init to load the changes */ ixv_init_locked(adapter); IXGBE_CORE_UNLOCK(adapter); @@ -2414,6 +2415,9 @@ ixv_ifflags_cb(struct ethercom *ec) if ((change & ~(IFF_CANTCHANGE | IFF_DEBUG)) != 0) rc = ENETRESET; + /* Set up VLAN support and filter */ + ixv_setup_vlan_support(adapter); + IXGBE_CORE_UNLOCK(adapter); return rc;