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;

Reply via email to