All of lore.kernel.org
 help / color / mirror / Atom feed
* [next PATCH 00/11] ixgbe: Add support for mixed PF/VF virtualization
@ 2015-11-03  1:09 ` Alexander Duyck
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:09 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: jeffrey.t.kirsher

This patch series extends the abilities of the ixgbe driver so that we can
now support VLAN trunking on top of the PF when SR-IOV is enabled.  By
doing this we are able to extend the existing capabilities that were
enabled with the "bridge fdb add" support that was added some time ago.  It
had enabled the ability to have PF and VF mixed on a flat network, this
makes it so that it also works on a VLAN enabled network.

The first few patches in this series are basically just cleanup.  They
either fix bugs found in the code, or address complexity that was making it
hard to either read or sort out exactly how the code was supposed to work.

The second half of the patch set is where we start adding features.
Specifically with this patch set the VLAN behavior changes for the PF in
two ways.  First we do not need to use the VLVF if the VFs have not already
set up a pool list.  As such I added functionality so that we can skip that
step when it is not needed.  Then I added support for VLAN promiscuous by
simply setting all of the bits in the VFTA and letting the packets fall
through to the default pool.  In addition when in promiscuous mode we set
the pool bit for the PF in all of the VLVF entries.  This way if anyone
adds a new entry it will automatically have the PF enabled.

The last few patches address some more issues I found during testing.  The
issues were primarily related to stale entries floating around in either
the RAR or VLVFB registers which were pointing to pools which were not
valid for the given L2 address.

---

Alexander Duyck (11):
      ixgbe: Return error on failure to allocate mac_table
      ixgbe: Fix SR-IOV VLAN pool configuration
      ixgbe: Simplify definitions for regidx and bit in set_vfta
      ixgbe: Reduce VT code indent in set_vfta by introducing jump label
      ixgbe: Simplify configuration of setting VLVF and VLVFB
      ixgbe: Add support for adding/removing VLAN on PF bypassing the VLVF
      ixgbe: Reorder search to work from the top down instead of bottom up
      ixgbe: Add support for VLAN promiscuous with SR-IOV
      ixgbe: Fix VLAN promisc in relation to SR-IOV
      ixgbe: Clear stale pool mappings
      ixgbe: Clean stale VLANs when changing port vlan or resetting


 drivers/net/ethernet/intel/ixgbe/ixgbe.h        |    2 
 drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c  |    3 
 drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c  |   10 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |  236 ++++++++++-------------
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.h |    2 
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c   |  194 ++++++++++++++++++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c  |  187 +++++++++++-------
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h   |    2 
 drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c   |   10 +
 9 files changed, 415 insertions(+), 231 deletions(-)

--

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 00/11] ixgbe: Add support for mixed PF/VF virtualization
@ 2015-11-03  1:09 ` Alexander Duyck
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:09 UTC (permalink / raw)
  To: intel-wired-lan

This patch series extends the abilities of the ixgbe driver so that we can
now support VLAN trunking on top of the PF when SR-IOV is enabled.  By
doing this we are able to extend the existing capabilities that were
enabled with the "bridge fdb add" support that was added some time ago.  It
had enabled the ability to have PF and VF mixed on a flat network, this
makes it so that it also works on a VLAN enabled network.

The first few patches in this series are basically just cleanup.  They
either fix bugs found in the code, or address complexity that was making it
hard to either read or sort out exactly how the code was supposed to work.

The second half of the patch set is where we start adding features.
Specifically with this patch set the VLAN behavior changes for the PF in
two ways.  First we do not need to use the VLVF if the VFs have not already
set up a pool list.  As such I added functionality so that we can skip that
step when it is not needed.  Then I added support for VLAN promiscuous by
simply setting all of the bits in the VFTA and letting the packets fall
through to the default pool.  In addition when in promiscuous mode we set
the pool bit for the PF in all of the VLVF entries.  This way if anyone
adds a new entry it will automatically have the PF enabled.

The last few patches address some more issues I found during testing.  The
issues were primarily related to stale entries floating around in either
the RAR or VLVFB registers which were pointing to pools which were not
valid for the given L2 address.

---

Alexander Duyck (11):
      ixgbe: Return error on failure to allocate mac_table
      ixgbe: Fix SR-IOV VLAN pool configuration
      ixgbe: Simplify definitions for regidx and bit in set_vfta
      ixgbe: Reduce VT code indent in set_vfta by introducing jump label
      ixgbe: Simplify configuration of setting VLVF and VLVFB
      ixgbe: Add support for adding/removing VLAN on PF bypassing the VLVF
      ixgbe: Reorder search to work from the top down instead of bottom up
      ixgbe: Add support for VLAN promiscuous with SR-IOV
      ixgbe: Fix VLAN promisc in relation to SR-IOV
      ixgbe: Clear stale pool mappings
      ixgbe: Clean stale VLANs when changing port vlan or resetting


 drivers/net/ethernet/intel/ixgbe/ixgbe.h        |    2 
 drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c  |    3 
 drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c  |   10 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |  236 ++++++++++-------------
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.h |    2 
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c   |  194 ++++++++++++++++++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c  |  187 +++++++++++-------
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h   |    2 
 drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c   |   10 +
 9 files changed, 415 insertions(+), 231 deletions(-)

--

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [next PATCH 01/11] ixgbe: Return error on failure to allocate mac_table
  2015-11-03  1:09 ` [Intel-wired-lan] " Alexander Duyck
@ 2015-11-03  1:09   ` Alexander Duyck
  -1 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:09 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: jeffrey.t.kirsher

Add a check to make certain mac_table was actually allocated and is not
NULL.  If it is NULL return -ENOMEM and allow the probe routine to fail
rather then causing a NULL pointer dereference further down the line.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index a5abcb2f9cbd..af5f367a1a22 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -5381,6 +5381,8 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
 	adapter->mac_table = kzalloc(sizeof(struct ixgbe_mac_addr) *
 				     hw->mac.num_rar_entries,
 				     GFP_ATOMIC);
+	if (!adapter->mac_table)
+		return -ENOMEM;
 
 	/* Set MAC specific capability flags and exceptions */
 	switch (hw->mac.type) {

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 01/11] ixgbe: Return error on failure to allocate mac_table
@ 2015-11-03  1:09   ` Alexander Duyck
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:09 UTC (permalink / raw)
  To: intel-wired-lan

Add a check to make certain mac_table was actually allocated and is not
NULL.  If it is NULL return -ENOMEM and allow the probe routine to fail
rather then causing a NULL pointer dereference further down the line.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index a5abcb2f9cbd..af5f367a1a22 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -5381,6 +5381,8 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
 	adapter->mac_table = kzalloc(sizeof(struct ixgbe_mac_addr) *
 				     hw->mac.num_rar_entries,
 				     GFP_ATOMIC);
+	if (!adapter->mac_table)
+		return -ENOMEM;
 
 	/* Set MAC specific capability flags and exceptions */
 	switch (hw->mac.type) {


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [next PATCH 02/11] ixgbe: Fix SR-IOV VLAN pool configuration
  2015-11-03  1:09 ` [Intel-wired-lan] " Alexander Duyck
@ 2015-11-03  1:09   ` Alexander Duyck
  -1 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:09 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: jeffrey.t.kirsher

The code for checking the PF bit in ixgbe_set_vf_vlan_msg was using the
wrong offset and as a result it was pulling the VLAN off of the PF even if
there were VFs numbered greater than 40 that still had the VLAN enabled.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 31de6cf7adb0..61a054ace56d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -887,10 +887,10 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
 			bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2));
 			bits &= ~(1 << VMDQ_P(0));
 			bits |= IXGBE_READ_REG(hw,
-					       IXGBE_VLVFB(reg_ndx * 2) + 1);
+					       IXGBE_VLVFB(reg_ndx * 2 + 1));
 		} else {
 			bits = IXGBE_READ_REG(hw,
-					      IXGBE_VLVFB(reg_ndx * 2) + 1);
+					      IXGBE_VLVFB(reg_ndx * 2 + 1));
 			bits &= ~(1 << (VMDQ_P(0) - 32));
 			bits |= IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2));
 		}

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 02/11] ixgbe: Fix SR-IOV VLAN pool configuration
@ 2015-11-03  1:09   ` Alexander Duyck
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:09 UTC (permalink / raw)
  To: intel-wired-lan

The code for checking the PF bit in ixgbe_set_vf_vlan_msg was using the
wrong offset and as a result it was pulling the VLAN off of the PF even if
there were VFs numbered greater than 40 that still had the VLAN enabled.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 31de6cf7adb0..61a054ace56d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -887,10 +887,10 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
 			bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2));
 			bits &= ~(1 << VMDQ_P(0));
 			bits |= IXGBE_READ_REG(hw,
-					       IXGBE_VLVFB(reg_ndx * 2) + 1);
+					       IXGBE_VLVFB(reg_ndx * 2 + 1));
 		} else {
 			bits = IXGBE_READ_REG(hw,
-					      IXGBE_VLVFB(reg_ndx * 2) + 1);
+					      IXGBE_VLVFB(reg_ndx * 2 + 1));
 			bits &= ~(1 << (VMDQ_P(0) - 32));
 			bits |= IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2));
 		}


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [next PATCH 03/11] ixgbe: Simplify definitions for regidx and bit in set_vfta
  2015-11-03  1:09 ` [Intel-wired-lan] " Alexander Duyck
@ 2015-11-03  1:09   ` Alexander Duyck
  -1 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:09 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: jeffrey.t.kirsher

This patch simplifies the logic for setting the VFTA register by removing
the number of conditional checks needed.  Instead we just use some boolean
logic to generate vfta_delta, and if that is set then we xor the vfta by
that value and write it back.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |   48 +++++++++--------------
 1 file changed, 19 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index daec6aef5dc8..027c1ad3e8cb 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -3050,13 +3050,9 @@ static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
 s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 			   bool vlan_on)
 {
-	s32 regindex;
-	u32 bitindex;
-	u32 vfta;
+	u32 regidx, vfta_delta, vfta;
 	u32 bits;
 	u32 vt;
-	u32 targetbit;
-	bool vfta_changed = false;
 
 	if (vlan > 4095)
 		return IXGBE_ERR_PARAM;
@@ -3073,22 +3069,16 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 	 *    bits[11-5]: which register
 	 *    bits[4-0]:  which bit in the register
 	 */
-	regindex = (vlan >> 5) & 0x7F;
-	bitindex = vlan & 0x1F;
-	targetbit = (1 << bitindex);
-	vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
-
-	if (vlan_on) {
-		if (!(vfta & targetbit)) {
-			vfta |= targetbit;
-			vfta_changed = true;
-		}
-	} else {
-		if ((vfta & targetbit)) {
-			vfta &= ~targetbit;
-			vfta_changed = true;
-		}
-	}
+	regidx = vlan / 32;
+	vfta_delta = 1 << (vlan % 32);
+	vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regidx));
+
+	/* vfta_delta represents the difference between the current value
+	 * of vfta and the value we want in the register.  Since the diff
+	 * is an XOR mask we can just update vfta using an XOR.
+	 */
+	vfta_delta &= vlan_on ? ~vfta : vfta;
+	vfta ^= vfta_delta;
 
 	/* Part 2
 	 * If VT Mode is set
@@ -3164,19 +3154,19 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 		if (bits) {
 			IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
 					(IXGBE_VLVF_VIEN | vlan));
-			if (!vlan_on) {
-				/* someone wants to clear the vfta entry
-				 * but some pools/VFs are still using it.
-				 * Ignore it. */
-				vfta_changed = false;
-			}
+
+			/* if someone wants to clear the vfta entry but
+			 * some pools/VFs are still using it.  Ignore it.
+			 */
+			if (!vlan_on)
+				vfta_delta = 0;
 		} else {
 			IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
 		}
 	}
 
-	if (vfta_changed)
-		IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta);
+	if (vfta_delta)
+		IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
 
 	return 0;
 }

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 03/11] ixgbe: Simplify definitions for regidx and bit in set_vfta
@ 2015-11-03  1:09   ` Alexander Duyck
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:09 UTC (permalink / raw)
  To: intel-wired-lan

This patch simplifies the logic for setting the VFTA register by removing
the number of conditional checks needed.  Instead we just use some boolean
logic to generate vfta_delta, and if that is set then we xor the vfta by
that value and write it back.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |   48 +++++++++--------------
 1 file changed, 19 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index daec6aef5dc8..027c1ad3e8cb 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -3050,13 +3050,9 @@ static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
 s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 			   bool vlan_on)
 {
-	s32 regindex;
-	u32 bitindex;
-	u32 vfta;
+	u32 regidx, vfta_delta, vfta;
 	u32 bits;
 	u32 vt;
-	u32 targetbit;
-	bool vfta_changed = false;
 
 	if (vlan > 4095)
 		return IXGBE_ERR_PARAM;
@@ -3073,22 +3069,16 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 	 *    bits[11-5]: which register
 	 *    bits[4-0]:  which bit in the register
 	 */
-	regindex = (vlan >> 5) & 0x7F;
-	bitindex = vlan & 0x1F;
-	targetbit = (1 << bitindex);
-	vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
-
-	if (vlan_on) {
-		if (!(vfta & targetbit)) {
-			vfta |= targetbit;
-			vfta_changed = true;
-		}
-	} else {
-		if ((vfta & targetbit)) {
-			vfta &= ~targetbit;
-			vfta_changed = true;
-		}
-	}
+	regidx = vlan / 32;
+	vfta_delta = 1 << (vlan % 32);
+	vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regidx));
+
+	/* vfta_delta represents the difference between the current value
+	 * of vfta and the value we want in the register.  Since the diff
+	 * is an XOR mask we can just update vfta using an XOR.
+	 */
+	vfta_delta &= vlan_on ? ~vfta : vfta;
+	vfta ^= vfta_delta;
 
 	/* Part 2
 	 * If VT Mode is set
@@ -3164,19 +3154,19 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 		if (bits) {
 			IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
 					(IXGBE_VLVF_VIEN | vlan));
-			if (!vlan_on) {
-				/* someone wants to clear the vfta entry
-				 * but some pools/VFs are still using it.
-				 * Ignore it. */
-				vfta_changed = false;
-			}
+
+			/* if someone wants to clear the vfta entry but
+			 * some pools/VFs are still using it.  Ignore it.
+			 */
+			if (!vlan_on)
+				vfta_delta = 0;
 		} else {
 			IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
 		}
 	}
 
-	if (vfta_changed)
-		IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta);
+	if (vfta_delta)
+		IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
 
 	return 0;
 }


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [next PATCH 04/11] ixgbe: Reduce VT code indent in set_vfta by introducing jump label
  2015-11-03  1:09 ` [Intel-wired-lan] " Alexander Duyck
@ 2015-11-03  1:09   ` Alexander Duyck
  -1 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:09 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: jeffrey.t.kirsher

In order to clear the way for upcoming work I thought it best to drop the
level of indent in the ixgbe_set_vfta_generic function.  Most of the code
is held in the virtualization specific section.  So the easiest approach is
to just add a jump label and jump past the bulk of the code if it is not
enabled.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |  142 +++++++++++------------
 1 file changed, 70 insertions(+), 72 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 027c1ad3e8cb..f608973ae73e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -3051,8 +3051,8 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 			   bool vlan_on)
 {
 	u32 regidx, vfta_delta, vfta;
+	s32 vlvf_index;
 	u32 bits;
-	u32 vt;
 
 	if (vlan > 4095)
 		return IXGBE_ERR_PARAM;
@@ -3088,83 +3088,81 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 	 *   Or !vlan_on
 	 *     clear the pool bit and possibly the vind
 	 */
-	vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
-	if (vt & IXGBE_VT_CTL_VT_ENABLE) {
-		s32 vlvf_index;
-
-		vlvf_index = ixgbe_find_vlvf_slot(hw, vlan);
-		if (vlvf_index < 0)
-			return vlvf_index;
-
-		if (vlan_on) {
-			/* set the pool bit */
-			if (vind < 32) {
-				bits = IXGBE_READ_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2));
-				bits |= (1 << vind);
-				IXGBE_WRITE_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2),
-						bits);
-			} else {
-				bits = IXGBE_READ_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1));
-				bits |= (1 << (vind-32));
-				IXGBE_WRITE_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1),
-						bits);
-			}
+	if (!(IXGBE_READ_REG(hw, IXGBE_VT_CTL) & IXGBE_VT_CTL_VT_ENABLE))
+		goto vfta_update;
+
+	vlvf_index = ixgbe_find_vlvf_slot(hw, vlan);
+	if (vlvf_index < 0)
+		return vlvf_index;
+
+	if (vlan_on) {
+		/* set the pool bit */
+		if (vind < 32) {
+			bits = IXGBE_READ_REG(hw,
+					IXGBE_VLVFB(vlvf_index*2));
+			bits |= (1 << vind);
+			IXGBE_WRITE_REG(hw,
+					IXGBE_VLVFB(vlvf_index*2),
+					bits);
 		} else {
-			/* clear the pool bit */
-			if (vind < 32) {
-				bits = IXGBE_READ_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2));
-				bits &= ~(1 << vind);
-				IXGBE_WRITE_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2),
-						bits);
-				bits |= IXGBE_READ_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1));
-			} else {
-				bits = IXGBE_READ_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1));
-				bits &= ~(1 << (vind-32));
-				IXGBE_WRITE_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1),
-						bits);
-				bits |= IXGBE_READ_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2));
-			}
+			bits = IXGBE_READ_REG(hw,
+					IXGBE_VLVFB((vlvf_index*2)+1));
+			bits |= (1 << (vind-32));
+			IXGBE_WRITE_REG(hw,
+					IXGBE_VLVFB((vlvf_index*2)+1),
+					bits);
 		}
-
-		/*
-		 * If there are still bits set in the VLVFB registers
-		 * for the VLAN ID indicated we need to see if the
-		 * caller is requesting that we clear the VFTA entry bit.
-		 * If the caller has requested that we clear the VFTA
-		 * entry bit but there are still pools/VFs using this VLAN
-		 * ID entry then ignore the request.  We're not worried
-		 * about the case where we're turning the VFTA VLAN ID
-		 * entry bit on, only when requested to turn it off as
-		 * there may be multiple pools and/or VFs using the
-		 * VLAN ID entry.  In that case we cannot clear the
-		 * VFTA bit until all pools/VFs using that VLAN ID have also
-		 * been cleared.  This will be indicated by "bits" being
-		 * zero.
-		 */
-		if (bits) {
-			IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
-					(IXGBE_VLVF_VIEN | vlan));
-
-			/* if someone wants to clear the vfta entry but
-			 * some pools/VFs are still using it.  Ignore it.
-			 */
-			if (!vlan_on)
-				vfta_delta = 0;
+	} else {
+		/* clear the pool bit */
+		if (vind < 32) {
+			bits = IXGBE_READ_REG(hw,
+					IXGBE_VLVFB(vlvf_index*2));
+			bits &= ~(1 << vind);
+			IXGBE_WRITE_REG(hw,
+					IXGBE_VLVFB(vlvf_index*2),
+					bits);
+			bits |= IXGBE_READ_REG(hw,
+					IXGBE_VLVFB((vlvf_index*2)+1));
 		} else {
-			IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
+			bits = IXGBE_READ_REG(hw,
+					IXGBE_VLVFB((vlvf_index*2)+1));
+			bits &= ~(1 << (vind-32));
+			IXGBE_WRITE_REG(hw,
+					IXGBE_VLVFB((vlvf_index*2)+1),
+					bits);
+			bits |= IXGBE_READ_REG(hw,
+					IXGBE_VLVFB(vlvf_index*2));
 		}
 	}
 
+	/* If there are still bits set in the VLVFB registers
+	 * for the VLAN ID indicated we need to see if the
+	 * caller is requesting that we clear the VFTA entry bit.
+	 * If the caller has requested that we clear the VFTA
+	 * entry bit but there are still pools/VFs using this VLAN
+	 * ID entry then ignore the request.  We're not worried
+	 * about the case where we're turning the VFTA VLAN ID
+	 * entry bit on, only when requested to turn it off as
+	 * there may be multiple pools and/or VFs using the
+	 * VLAN ID entry.  In that case we cannot clear the
+	 * VFTA bit until all pools/VFs using that VLAN ID have also
+	 * been cleared.  This will be indicated by "bits" being
+	 * zero.
+	 */
+	if (bits) {
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
+				(IXGBE_VLVF_VIEN | vlan));
+
+		/* if someone wants to clear the vfta entry but
+		 * some pools/VFs are still using it.  Ignore it.
+		 */
+		if (!vlan_on)
+			vfta_delta = 0;
+	} else {
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
+	}
+
+vfta_update:
 	if (vfta_delta)
 		IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
 

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 04/11] ixgbe: Reduce VT code indent in set_vfta by introducing jump label
@ 2015-11-03  1:09   ` Alexander Duyck
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:09 UTC (permalink / raw)
  To: intel-wired-lan

In order to clear the way for upcoming work I thought it best to drop the
level of indent in the ixgbe_set_vfta_generic function.  Most of the code
is held in the virtualization specific section.  So the easiest approach is
to just add a jump label and jump past the bulk of the code if it is not
enabled.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |  142 +++++++++++------------
 1 file changed, 70 insertions(+), 72 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 027c1ad3e8cb..f608973ae73e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -3051,8 +3051,8 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 			   bool vlan_on)
 {
 	u32 regidx, vfta_delta, vfta;
+	s32 vlvf_index;
 	u32 bits;
-	u32 vt;
 
 	if (vlan > 4095)
 		return IXGBE_ERR_PARAM;
@@ -3088,83 +3088,81 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 	 *   Or !vlan_on
 	 *     clear the pool bit and possibly the vind
 	 */
-	vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
-	if (vt & IXGBE_VT_CTL_VT_ENABLE) {
-		s32 vlvf_index;
-
-		vlvf_index = ixgbe_find_vlvf_slot(hw, vlan);
-		if (vlvf_index < 0)
-			return vlvf_index;
-
-		if (vlan_on) {
-			/* set the pool bit */
-			if (vind < 32) {
-				bits = IXGBE_READ_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2));
-				bits |= (1 << vind);
-				IXGBE_WRITE_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2),
-						bits);
-			} else {
-				bits = IXGBE_READ_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1));
-				bits |= (1 << (vind-32));
-				IXGBE_WRITE_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1),
-						bits);
-			}
+	if (!(IXGBE_READ_REG(hw, IXGBE_VT_CTL) & IXGBE_VT_CTL_VT_ENABLE))
+		goto vfta_update;
+
+	vlvf_index = ixgbe_find_vlvf_slot(hw, vlan);
+	if (vlvf_index < 0)
+		return vlvf_index;
+
+	if (vlan_on) {
+		/* set the pool bit */
+		if (vind < 32) {
+			bits = IXGBE_READ_REG(hw,
+					IXGBE_VLVFB(vlvf_index*2));
+			bits |= (1 << vind);
+			IXGBE_WRITE_REG(hw,
+					IXGBE_VLVFB(vlvf_index*2),
+					bits);
 		} else {
-			/* clear the pool bit */
-			if (vind < 32) {
-				bits = IXGBE_READ_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2));
-				bits &= ~(1 << vind);
-				IXGBE_WRITE_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2),
-						bits);
-				bits |= IXGBE_READ_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1));
-			} else {
-				bits = IXGBE_READ_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1));
-				bits &= ~(1 << (vind-32));
-				IXGBE_WRITE_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1),
-						bits);
-				bits |= IXGBE_READ_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2));
-			}
+			bits = IXGBE_READ_REG(hw,
+					IXGBE_VLVFB((vlvf_index*2)+1));
+			bits |= (1 << (vind-32));
+			IXGBE_WRITE_REG(hw,
+					IXGBE_VLVFB((vlvf_index*2)+1),
+					bits);
 		}
-
-		/*
-		 * If there are still bits set in the VLVFB registers
-		 * for the VLAN ID indicated we need to see if the
-		 * caller is requesting that we clear the VFTA entry bit.
-		 * If the caller has requested that we clear the VFTA
-		 * entry bit but there are still pools/VFs using this VLAN
-		 * ID entry then ignore the request.  We're not worried
-		 * about the case where we're turning the VFTA VLAN ID
-		 * entry bit on, only when requested to turn it off as
-		 * there may be multiple pools and/or VFs using the
-		 * VLAN ID entry.  In that case we cannot clear the
-		 * VFTA bit until all pools/VFs using that VLAN ID have also
-		 * been cleared.  This will be indicated by "bits" being
-		 * zero.
-		 */
-		if (bits) {
-			IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
-					(IXGBE_VLVF_VIEN | vlan));
-
-			/* if someone wants to clear the vfta entry but
-			 * some pools/VFs are still using it.  Ignore it.
-			 */
-			if (!vlan_on)
-				vfta_delta = 0;
+	} else {
+		/* clear the pool bit */
+		if (vind < 32) {
+			bits = IXGBE_READ_REG(hw,
+					IXGBE_VLVFB(vlvf_index*2));
+			bits &= ~(1 << vind);
+			IXGBE_WRITE_REG(hw,
+					IXGBE_VLVFB(vlvf_index*2),
+					bits);
+			bits |= IXGBE_READ_REG(hw,
+					IXGBE_VLVFB((vlvf_index*2)+1));
 		} else {
-			IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
+			bits = IXGBE_READ_REG(hw,
+					IXGBE_VLVFB((vlvf_index*2)+1));
+			bits &= ~(1 << (vind-32));
+			IXGBE_WRITE_REG(hw,
+					IXGBE_VLVFB((vlvf_index*2)+1),
+					bits);
+			bits |= IXGBE_READ_REG(hw,
+					IXGBE_VLVFB(vlvf_index*2));
 		}
 	}
 
+	/* If there are still bits set in the VLVFB registers
+	 * for the VLAN ID indicated we need to see if the
+	 * caller is requesting that we clear the VFTA entry bit.
+	 * If the caller has requested that we clear the VFTA
+	 * entry bit but there are still pools/VFs using this VLAN
+	 * ID entry then ignore the request.  We're not worried
+	 * about the case where we're turning the VFTA VLAN ID
+	 * entry bit on, only when requested to turn it off as
+	 * there may be multiple pools and/or VFs using the
+	 * VLAN ID entry.  In that case we cannot clear the
+	 * VFTA bit until all pools/VFs using that VLAN ID have also
+	 * been cleared.  This will be indicated by "bits" being
+	 * zero.
+	 */
+	if (bits) {
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
+				(IXGBE_VLVF_VIEN | vlan));
+
+		/* if someone wants to clear the vfta entry but
+		 * some pools/VFs are still using it.  Ignore it.
+		 */
+		if (!vlan_on)
+			vfta_delta = 0;
+	} else {
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
+	}
+
+vfta_update:
 	if (vfta_delta)
 		IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
 


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [next PATCH 05/11] ixgbe: Simplify configuration of setting VLVF and VLVFB
  2015-11-03  1:09 ` [Intel-wired-lan] " Alexander Duyck
@ 2015-11-03  1:09   ` Alexander Duyck
  -1 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:09 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: jeffrey.t.kirsher

This patch addresses several issues within the VLVF and VLVFB
configuration

First was the fact that code was overly complicated with multiple
conditional paths depending on if we adding or removing and which bit we
were going to add or remove.  Instead of messing with all that I have
simplified it by using (vid / 32) and (1 - vid / 32) to identify our
register and the other vlvfb register.

Second was the fact that we were likely leaking a few packets into the PF
in cases where we were deleting an entry and the VFTA filter for that entry
as the ordering was such that we deleted the pool and then the VLAN filter
instead of the other way around.  I have updated that by adding a check for
no bits being set and if that occurs we clear things up in the proper
order.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |   88 +++++++++--------------
 1 file changed, 34 insertions(+), 54 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index f608973ae73e..3f5fe60fdc11 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -3050,11 +3050,10 @@ static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
 s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 			   bool vlan_on)
 {
-	u32 regidx, vfta_delta, vfta;
+	u32 regidx, vfta_delta, vfta, bits;
 	s32 vlvf_index;
-	u32 bits;
 
-	if (vlan > 4095)
+	if ((vlan > 4095) || (vind > 63))
 		return IXGBE_ERR_PARAM;
 
 	/*
@@ -3095,44 +3094,30 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 	if (vlvf_index < 0)
 		return vlvf_index;
 
-	if (vlan_on) {
-		/* set the pool bit */
-		if (vind < 32) {
-			bits = IXGBE_READ_REG(hw,
-					IXGBE_VLVFB(vlvf_index*2));
-			bits |= (1 << vind);
-			IXGBE_WRITE_REG(hw,
-					IXGBE_VLVFB(vlvf_index*2),
-					bits);
-		} else {
-			bits = IXGBE_READ_REG(hw,
-					IXGBE_VLVFB((vlvf_index*2)+1));
-			bits |= (1 << (vind-32));
-			IXGBE_WRITE_REG(hw,
-					IXGBE_VLVFB((vlvf_index*2)+1),
-					bits);
-		}
-	} else {
-		/* clear the pool bit */
-		if (vind < 32) {
-			bits = IXGBE_READ_REG(hw,
-					IXGBE_VLVFB(vlvf_index*2));
-			bits &= ~(1 << vind);
-			IXGBE_WRITE_REG(hw,
-					IXGBE_VLVFB(vlvf_index*2),
-					bits);
-			bits |= IXGBE_READ_REG(hw,
-					IXGBE_VLVFB((vlvf_index*2)+1));
-		} else {
-			bits = IXGBE_READ_REG(hw,
-					IXGBE_VLVFB((vlvf_index*2)+1));
-			bits &= ~(1 << (vind-32));
-			IXGBE_WRITE_REG(hw,
-					IXGBE_VLVFB((vlvf_index*2)+1),
-					bits);
-			bits |= IXGBE_READ_REG(hw,
-					IXGBE_VLVFB(vlvf_index*2));
-		}
+	bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32));
+
+	/* set the pool bit */
+	bits |= 1 << (vind % 32);
+	if (vlan_on)
+		goto vlvf_update;
+
+	/* clear the pool bit */
+	bits ^= 1 << (vind % 32);
+
+	if (!bits &&
+	    !IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + 1 - vind / 32))) {
+		/* Clear VFTA first, then disable VLVF.  Otherwise
+		 * we run the risk of stray packets leaking into
+		 * the PF via the default pool
+		 */
+		if (vfta_delta)
+			IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
+
+		/* disable VLVF and clear remaining bit from pool */
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), 0);
+
+		return 0;
 	}
 
 	/* If there are still bits set in the VLVFB registers
@@ -3149,20 +3134,15 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 	 * been cleared.  This will be indicated by "bits" being
 	 * zero.
 	 */
-	if (bits) {
-		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
-				(IXGBE_VLVF_VIEN | vlan));
+	vfta_delta = 0;
 
-		/* if someone wants to clear the vfta entry but
-		 * some pools/VFs are still using it.  Ignore it.
-		 */
-		if (!vlan_on)
-			vfta_delta = 0;
-	} else {
-		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
-	}
+vlvf_update:
+	/* record pool change and enable VLAN ID if not already enabled */
+	IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), bits);
+	IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), IXGBE_VLVF_VIEN | vlan);
 
 vfta_update:
+	/* Update VFTA now that we are ready for traffic */
 	if (vfta_delta)
 		IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
 
@@ -3184,8 +3164,8 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw)
 
 	for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) {
 		IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0);
-		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset*2), 0);
-		IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset*2)+1), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2 + 1), 0);
 	}
 
 	return 0;

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 05/11] ixgbe: Simplify configuration of setting VLVF and VLVFB
@ 2015-11-03  1:09   ` Alexander Duyck
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:09 UTC (permalink / raw)
  To: intel-wired-lan

This patch addresses several issues within the VLVF and VLVFB
configuration

First was the fact that code was overly complicated with multiple
conditional paths depending on if we adding or removing and which bit we
were going to add or remove.  Instead of messing with all that I have
simplified it by using (vid / 32) and (1 - vid / 32) to identify our
register and the other vlvfb register.

Second was the fact that we were likely leaking a few packets into the PF
in cases where we were deleting an entry and the VFTA filter for that entry
as the ordering was such that we deleted the pool and then the VLAN filter
instead of the other way around.  I have updated that by adding a check for
no bits being set and if that occurs we clear things up in the proper
order.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |   88 +++++++++--------------
 1 file changed, 34 insertions(+), 54 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index f608973ae73e..3f5fe60fdc11 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -3050,11 +3050,10 @@ static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
 s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 			   bool vlan_on)
 {
-	u32 regidx, vfta_delta, vfta;
+	u32 regidx, vfta_delta, vfta, bits;
 	s32 vlvf_index;
-	u32 bits;
 
-	if (vlan > 4095)
+	if ((vlan > 4095) || (vind > 63))
 		return IXGBE_ERR_PARAM;
 
 	/*
@@ -3095,44 +3094,30 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 	if (vlvf_index < 0)
 		return vlvf_index;
 
-	if (vlan_on) {
-		/* set the pool bit */
-		if (vind < 32) {
-			bits = IXGBE_READ_REG(hw,
-					IXGBE_VLVFB(vlvf_index*2));
-			bits |= (1 << vind);
-			IXGBE_WRITE_REG(hw,
-					IXGBE_VLVFB(vlvf_index*2),
-					bits);
-		} else {
-			bits = IXGBE_READ_REG(hw,
-					IXGBE_VLVFB((vlvf_index*2)+1));
-			bits |= (1 << (vind-32));
-			IXGBE_WRITE_REG(hw,
-					IXGBE_VLVFB((vlvf_index*2)+1),
-					bits);
-		}
-	} else {
-		/* clear the pool bit */
-		if (vind < 32) {
-			bits = IXGBE_READ_REG(hw,
-					IXGBE_VLVFB(vlvf_index*2));
-			bits &= ~(1 << vind);
-			IXGBE_WRITE_REG(hw,
-					IXGBE_VLVFB(vlvf_index*2),
-					bits);
-			bits |= IXGBE_READ_REG(hw,
-					IXGBE_VLVFB((vlvf_index*2)+1));
-		} else {
-			bits = IXGBE_READ_REG(hw,
-					IXGBE_VLVFB((vlvf_index*2)+1));
-			bits &= ~(1 << (vind-32));
-			IXGBE_WRITE_REG(hw,
-					IXGBE_VLVFB((vlvf_index*2)+1),
-					bits);
-			bits |= IXGBE_READ_REG(hw,
-					IXGBE_VLVFB(vlvf_index*2));
-		}
+	bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32));
+
+	/* set the pool bit */
+	bits |= 1 << (vind % 32);
+	if (vlan_on)
+		goto vlvf_update;
+
+	/* clear the pool bit */
+	bits ^= 1 << (vind % 32);
+
+	if (!bits &&
+	    !IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + 1 - vind / 32))) {
+		/* Clear VFTA first, then disable VLVF.  Otherwise
+		 * we run the risk of stray packets leaking into
+		 * the PF via the default pool
+		 */
+		if (vfta_delta)
+			IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
+
+		/* disable VLVF and clear remaining bit from pool */
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), 0);
+
+		return 0;
 	}
 
 	/* If there are still bits set in the VLVFB registers
@@ -3149,20 +3134,15 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 	 * been cleared.  This will be indicated by "bits" being
 	 * zero.
 	 */
-	if (bits) {
-		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
-				(IXGBE_VLVF_VIEN | vlan));
+	vfta_delta = 0;
 
-		/* if someone wants to clear the vfta entry but
-		 * some pools/VFs are still using it.  Ignore it.
-		 */
-		if (!vlan_on)
-			vfta_delta = 0;
-	} else {
-		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
-	}
+vlvf_update:
+	/* record pool change and enable VLAN ID if not already enabled */
+	IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), bits);
+	IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), IXGBE_VLVF_VIEN | vlan);
 
 vfta_update:
+	/* Update VFTA now that we are ready for traffic */
 	if (vfta_delta)
 		IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
 
@@ -3184,8 +3164,8 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw)
 
 	for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) {
 		IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0);
-		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset*2), 0);
-		IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset*2)+1), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2 + 1), 0);
 	}
 
 	return 0;


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [next PATCH 06/11] ixgbe: Add support for adding/removing VLAN on PF bypassing the VLVF
  2015-11-03  1:09 ` [Intel-wired-lan] " Alexander Duyck
@ 2015-11-03  1:10   ` Alexander Duyck
  -1 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:10 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: jeffrey.t.kirsher

This patch adds support for bypassing the VLVF entry creation when the PF
is adding a new VLAN.  The advantage to doing this is that we can then save
the VLVF entries for the VFs which must have them in order to function,
versus the PF which can fall back on the default pool entry.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c  |    3 ++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |   21 +++++++++++++++------
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.h |    2 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c   |    4 ++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c  |   18 +++++++++++++++++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h   |    2 +-
 6 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
index 8f09d291a043..d8a9fb8a59e2 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -880,11 +880,12 @@ static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
  *  @vlan: VLAN id to write to VLAN filter
  *  @vind: VMDq output index that maps queue to VLAN id in VFTA
  *  @vlan_on: boolean flag to turn on/off VLAN in VFTA
+ *  @vlvf_bypass: boolean flag - unused
  *
  *  Turn on/off specified VLAN in the VLAN filter table.
  **/
 static s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind,
-				bool vlan_on)
+				bool vlan_on, bool vlvf_bypass)
 {
 	u32 regindex;
 	u32 bitindex;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 3f5fe60fdc11..5fd860a8d6f7 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -2999,16 +2999,21 @@ s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw)
  *  return the VLVF index where this VLAN id should be placed
  *
  **/
-static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
+static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass)
 {
+	s32 regindex, first_empty_slot;
 	u32 bits = 0;
-	u32 first_empty_slot = 0;
-	s32 regindex;
 
 	/* short cut the special case */
 	if (vlan == 0)
 		return 0;
 
+	/* if vlvf_bypass is set we don't want to use an empty slot, we
+	 * will simply bypass the VLVF if there are no entries present in the
+	 * VLVF that contain our VLAN
+	 */
+	first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0;
+
 	/*
 	  * Search for the vlan id in the VLVF entries. Save off the first empty
 	  * slot found along the way
@@ -3044,11 +3049,12 @@ static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
  *  @vlan: VLAN id to write to VLAN filter
  *  @vind: VMDq output index that maps queue to VLAN id in VFVFB
  *  @vlan_on: boolean flag to turn on/off VLAN in VFVF
+ *  @vlvf_bypass: boolean flag indicating updating default pool is okay
  *
  *  Turn on/off specified VLAN in the VLAN filter table.
  **/
 s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
-			   bool vlan_on)
+			   bool vlan_on, bool vlvf_bypass)
 {
 	u32 regidx, vfta_delta, vfta, bits;
 	s32 vlvf_index;
@@ -3090,9 +3096,12 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 	if (!(IXGBE_READ_REG(hw, IXGBE_VT_CTL) & IXGBE_VT_CTL_VT_ENABLE))
 		goto vfta_update;
 
-	vlvf_index = ixgbe_find_vlvf_slot(hw, vlan);
-	if (vlvf_index < 0)
+	vlvf_index = ixgbe_find_vlvf_slot(hw, vlan, vlvf_bypass);
+	if (vlvf_index < 0) {
+		if (vlvf_bypass)
+			goto vfta_update;
 		return vlvf_index;
+	}
 
 	bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32));
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
index a0044e4a8b90..2b9563137fd8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
@@ -92,7 +92,7 @@ s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq);
 s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
 s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw);
 s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan,
-			   u32 vind, bool vlan_on);
+			   u32 vind, bool vlan_on, bool vlvf_bypass);
 s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw);
 s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw,
 				 ixgbe_link_speed *speed,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index af5f367a1a22..742e0f84a925 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3899,7 +3899,7 @@ static int ixgbe_vlan_rx_add_vid(struct net_device *netdev,
 	struct ixgbe_hw *hw = &adapter->hw;
 
 	/* add VID to filter table */
-	hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), true);
+	hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), true, true);
 	set_bit(vid, adapter->active_vlans);
 
 	return 0;
@@ -3912,7 +3912,7 @@ static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev,
 	struct ixgbe_hw *hw = &adapter->hw;
 
 	/* remove VID from filter table */
-	hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), false);
+	hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), false, true);
 	clear_bit(vid, adapter->active_vlans);
 
 	return 0;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 61a054ace56d..3380f14517dc 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -452,11 +452,27 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
 static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
 			     u32 vf)
 {
+	struct ixgbe_hw *hw = &adapter->hw;
+	int err;
+
 	/* VLAN 0 is a special case, don't allow it to be removed */
 	if (!vid && !add)
 		return 0;
 
-	return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add);
+	/* If VLAN overlaps with one the PF is currently monitoring make
+	 * sure that we are able to allocate a VLVF entry.  This may be
+	 * redundant but it guarantees PF will maintain visibility to
+	 * the VLAN.
+	 */
+	if (add && test_bit(vid, adapter->active_vlans)) {
+		err = hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), true, false);
+		if (err)
+			return err;
+	}
+
+	err = hw->mac.ops.set_vfta(hw, vid, vf, !!add, false);
+
+	return err;
 }
 
 static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 1329eddfc9ce..06add27c8b8c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -3300,7 +3300,7 @@ struct ixgbe_mac_operations {
 	s32 (*enable_mc)(struct ixgbe_hw *);
 	s32 (*disable_mc)(struct ixgbe_hw *);
 	s32 (*clear_vfta)(struct ixgbe_hw *);
-	s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool);
+	s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool, bool);
 	s32 (*init_uta_tables)(struct ixgbe_hw *);
 	void (*set_mac_anti_spoofing)(struct ixgbe_hw *, bool, int);
 	void (*set_vlan_anti_spoofing)(struct ixgbe_hw *, bool, int);

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 06/11] ixgbe: Add support for adding/removing VLAN on PF bypassing the VLVF
@ 2015-11-03  1:10   ` Alexander Duyck
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:10 UTC (permalink / raw)
  To: intel-wired-lan

This patch adds support for bypassing the VLVF entry creation when the PF
is adding a new VLAN.  The advantage to doing this is that we can then save
the VLVF entries for the VFs which must have them in order to function,
versus the PF which can fall back on the default pool entry.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c  |    3 ++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |   21 +++++++++++++++------
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.h |    2 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c   |    4 ++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c  |   18 +++++++++++++++++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h   |    2 +-
 6 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
index 8f09d291a043..d8a9fb8a59e2 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -880,11 +880,12 @@ static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
  *  @vlan: VLAN id to write to VLAN filter
  *  @vind: VMDq output index that maps queue to VLAN id in VFTA
  *  @vlan_on: boolean flag to turn on/off VLAN in VFTA
+ *  @vlvf_bypass: boolean flag - unused
  *
  *  Turn on/off specified VLAN in the VLAN filter table.
  **/
 static s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind,
-				bool vlan_on)
+				bool vlan_on, bool vlvf_bypass)
 {
 	u32 regindex;
 	u32 bitindex;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 3f5fe60fdc11..5fd860a8d6f7 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -2999,16 +2999,21 @@ s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw)
  *  return the VLVF index where this VLAN id should be placed
  *
  **/
-static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
+static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass)
 {
+	s32 regindex, first_empty_slot;
 	u32 bits = 0;
-	u32 first_empty_slot = 0;
-	s32 regindex;
 
 	/* short cut the special case */
 	if (vlan == 0)
 		return 0;
 
+	/* if vlvf_bypass is set we don't want to use an empty slot, we
+	 * will simply bypass the VLVF if there are no entries present in the
+	 * VLVF that contain our VLAN
+	 */
+	first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0;
+
 	/*
 	  * Search for the vlan id in the VLVF entries. Save off the first empty
 	  * slot found along the way
@@ -3044,11 +3049,12 @@ static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
  *  @vlan: VLAN id to write to VLAN filter
  *  @vind: VMDq output index that maps queue to VLAN id in VFVFB
  *  @vlan_on: boolean flag to turn on/off VLAN in VFVF
+ *  @vlvf_bypass: boolean flag indicating updating default pool is okay
  *
  *  Turn on/off specified VLAN in the VLAN filter table.
  **/
 s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
-			   bool vlan_on)
+			   bool vlan_on, bool vlvf_bypass)
 {
 	u32 regidx, vfta_delta, vfta, bits;
 	s32 vlvf_index;
@@ -3090,9 +3096,12 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 	if (!(IXGBE_READ_REG(hw, IXGBE_VT_CTL) & IXGBE_VT_CTL_VT_ENABLE))
 		goto vfta_update;
 
-	vlvf_index = ixgbe_find_vlvf_slot(hw, vlan);
-	if (vlvf_index < 0)
+	vlvf_index = ixgbe_find_vlvf_slot(hw, vlan, vlvf_bypass);
+	if (vlvf_index < 0) {
+		if (vlvf_bypass)
+			goto vfta_update;
 		return vlvf_index;
+	}
 
 	bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32));
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
index a0044e4a8b90..2b9563137fd8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
@@ -92,7 +92,7 @@ s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq);
 s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
 s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw);
 s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan,
-			   u32 vind, bool vlan_on);
+			   u32 vind, bool vlan_on, bool vlvf_bypass);
 s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw);
 s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw,
 				 ixgbe_link_speed *speed,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index af5f367a1a22..742e0f84a925 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3899,7 +3899,7 @@ static int ixgbe_vlan_rx_add_vid(struct net_device *netdev,
 	struct ixgbe_hw *hw = &adapter->hw;
 
 	/* add VID to filter table */
-	hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), true);
+	hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), true, true);
 	set_bit(vid, adapter->active_vlans);
 
 	return 0;
@@ -3912,7 +3912,7 @@ static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev,
 	struct ixgbe_hw *hw = &adapter->hw;
 
 	/* remove VID from filter table */
-	hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), false);
+	hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), false, true);
 	clear_bit(vid, adapter->active_vlans);
 
 	return 0;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 61a054ace56d..3380f14517dc 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -452,11 +452,27 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
 static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
 			     u32 vf)
 {
+	struct ixgbe_hw *hw = &adapter->hw;
+	int err;
+
 	/* VLAN 0 is a special case, don't allow it to be removed */
 	if (!vid && !add)
 		return 0;
 
-	return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add);
+	/* If VLAN overlaps with one the PF is currently monitoring make
+	 * sure that we are able to allocate a VLVF entry.  This may be
+	 * redundant but it guarantees PF will maintain visibility to
+	 * the VLAN.
+	 */
+	if (add && test_bit(vid, adapter->active_vlans)) {
+		err = hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), true, false);
+		if (err)
+			return err;
+	}
+
+	err = hw->mac.ops.set_vfta(hw, vid, vf, !!add, false);
+
+	return err;
 }
 
 static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 1329eddfc9ce..06add27c8b8c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -3300,7 +3300,7 @@ struct ixgbe_mac_operations {
 	s32 (*enable_mc)(struct ixgbe_hw *);
 	s32 (*disable_mc)(struct ixgbe_hw *);
 	s32 (*clear_vfta)(struct ixgbe_hw *);
-	s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool);
+	s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool, bool);
 	s32 (*init_uta_tables)(struct ixgbe_hw *);
 	void (*set_mac_anti_spoofing)(struct ixgbe_hw *, bool, int);
 	void (*set_vlan_anti_spoofing)(struct ixgbe_hw *, bool, int);


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [next PATCH 07/11] ixgbe: Reorder search to work from the top down instead of bottom up
  2015-11-03  1:09 ` [Intel-wired-lan] " Alexander Duyck
@ 2015-11-03  1:10   ` Alexander Duyck
  -1 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:10 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: jeffrey.t.kirsher

This patch is meant to reduce the complexity of the search function used
for finding a VLVF entry associated with a given VLAN ID.  The previous
code was searching from bottom to top.  I reordered it to search from top
to bottom.  In addition I pulled an AND statement out of the loop and
instead replaced it with an OR statement outside the loop.  This should
help to reduce the overall size and complexity of the function.

There was also some formatting I cleaned up in regards to whitespace and
such.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |   42 ++++++++++-------------
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 5fd860a8d6f7..73dcc0aec6dc 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -3002,7 +3002,7 @@ s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw)
 static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass)
 {
 	s32 regindex, first_empty_slot;
-	u32 bits = 0;
+	u32 bits;
 
 	/* short cut the special case */
 	if (vlan == 0)
@@ -3014,33 +3014,29 @@ static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass)
 	 */
 	first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0;
 
-	/*
-	  * Search for the vlan id in the VLVF entries. Save off the first empty
-	  * slot found along the way
-	  */
-	for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
+	/* add VLAN enable bit for comparison */
+	vlan |= IXGBE_VLVF_VIEN;
+
+	/* Search for the vlan id in the VLVF entries. Save off the first empty
+	 * slot found along the way.
+	 *
+	 * pre-decrement loop covering (IXGBE_VLVF_ENTRIES - 1) .. 1
+	 */
+	for (regindex = IXGBE_VLVF_ENTRIES; --regindex;) {
 		bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
-		if (!bits && !(first_empty_slot))
+		if (bits == vlan)
+			return regindex;
+		if (!first_empty_slot && !bits)
 			first_empty_slot = regindex;
-		else if ((bits & 0x0FFF) == vlan)
-			break;
 	}
 
-	/*
-	  * If regindex is less than IXGBE_VLVF_ENTRIES, then we found the vlan
-	  * in the VLVF. Else use the first empty VLVF register for this
-	  * vlan id.
-	  */
-	if (regindex >= IXGBE_VLVF_ENTRIES) {
-		if (first_empty_slot)
-			regindex = first_empty_slot;
-		else {
-			hw_dbg(hw, "No space in VLVF.\n");
-			regindex = IXGBE_ERR_NO_SPACE;
-		}
-	}
+	/* If we are here then we didn't find the VLAN.  Return first empty
+	 * slot we found during our search, else error.
+	 */
+	if (!first_empty_slot)
+		hw_dbg(hw, "No space in VLVF.\n");
 
-	return regindex;
+	return first_empty_slot ? : IXGBE_ERR_NO_SPACE;
 }
 
 /**

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 07/11] ixgbe: Reorder search to work from the top down instead of bottom up
@ 2015-11-03  1:10   ` Alexander Duyck
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:10 UTC (permalink / raw)
  To: intel-wired-lan

This patch is meant to reduce the complexity of the search function used
for finding a VLVF entry associated with a given VLAN ID.  The previous
code was searching from bottom to top.  I reordered it to search from top
to bottom.  In addition I pulled an AND statement out of the loop and
instead replaced it with an OR statement outside the loop.  This should
help to reduce the overall size and complexity of the function.

There was also some formatting I cleaned up in regards to whitespace and
such.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |   42 ++++++++++-------------
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 5fd860a8d6f7..73dcc0aec6dc 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -3002,7 +3002,7 @@ s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw)
 static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass)
 {
 	s32 regindex, first_empty_slot;
-	u32 bits = 0;
+	u32 bits;
 
 	/* short cut the special case */
 	if (vlan == 0)
@@ -3014,33 +3014,29 @@ static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass)
 	 */
 	first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0;
 
-	/*
-	  * Search for the vlan id in the VLVF entries. Save off the first empty
-	  * slot found along the way
-	  */
-	for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
+	/* add VLAN enable bit for comparison */
+	vlan |= IXGBE_VLVF_VIEN;
+
+	/* Search for the vlan id in the VLVF entries. Save off the first empty
+	 * slot found along the way.
+	 *
+	 * pre-decrement loop covering (IXGBE_VLVF_ENTRIES - 1) .. 1
+	 */
+	for (regindex = IXGBE_VLVF_ENTRIES; --regindex;) {
 		bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
-		if (!bits && !(first_empty_slot))
+		if (bits == vlan)
+			return regindex;
+		if (!first_empty_slot && !bits)
 			first_empty_slot = regindex;
-		else if ((bits & 0x0FFF) == vlan)
-			break;
 	}
 
-	/*
-	  * If regindex is less than IXGBE_VLVF_ENTRIES, then we found the vlan
-	  * in the VLVF. Else use the first empty VLVF register for this
-	  * vlan id.
-	  */
-	if (regindex >= IXGBE_VLVF_ENTRIES) {
-		if (first_empty_slot)
-			regindex = first_empty_slot;
-		else {
-			hw_dbg(hw, "No space in VLVF.\n");
-			regindex = IXGBE_ERR_NO_SPACE;
-		}
-	}
+	/* If we are here then we didn't find the VLAN.  Return first empty
+	 * slot we found during our search, else error.
+	 */
+	if (!first_empty_slot)
+		hw_dbg(hw, "No space in VLVF.\n");
 
-	return regindex;
+	return first_empty_slot ? : IXGBE_ERR_NO_SPACE;
 }
 
 /**


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [next PATCH 08/11] ixgbe: Add support for VLAN promiscuous with SR-IOV
  2015-11-03  1:09 ` [Intel-wired-lan] " Alexander Duyck
@ 2015-11-03  1:10   ` Alexander Duyck
  -1 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:10 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: jeffrey.t.kirsher

This patch adds support for VLAN promiscuous with SR-IOV enabled.

The code prior to this patch was only adding the PF to VLANs that the VF
had added.  As such enabling promiscuous mode would actually not add any
additional VLAN filters so visibility was limited.  This lead to a number
of issues as the bridge and OVS would expect us to accept all VLAN tagged
packets when promiscuous mode was enabled, and instead we would filter out
most if not all depending on the configuration of the PF.

With this patch what we do is set all the bits in the VFTA and all of the
VLVF bits associated with the pool belonging to the PF.  By doing this the
PF is guaranteed to receive all VLAN tagged traffic associated with the RAR
filters assigned to the PF.  In addition we will clean up those same bits
in the event of promiscuous mode being disabled.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h      |    1 
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  140 +++++++++++++++++++++++--
 2 files changed, 129 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 445b4c9169b6..0269c0ca997c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -664,6 +664,7 @@ struct ixgbe_adapter {
 #ifdef CONFIG_IXGBE_VXLAN
 #define IXGBE_FLAG2_VXLAN_REREG_NEEDED		BIT(12)
 #endif
+#define IXGBE_FLAG2_VLAN_PROMISC		BIT(13)
 
 	/* Tx fast path data */
 	int num_tx_queues;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 742e0f84a925..f10337b1792c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3702,6 +3702,9 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
 	/* Map PF MAC address in RAR Entry 0 to first pool following VFs */
 	hw->mac.ops.set_vmdq(hw, 0, VMDQ_P(0));
 
+	/* clear VLAN promisc flag so VFTA will be updated if necessary */
+	adapter->flags2 &= ~IXGBE_FLAG2_VLAN_PROMISC;
+
 	/*
 	 * Set up VF register offsets for selected VT Mode,
 	 * i.e. 32 or 64 VFs for SR-IOV
@@ -3990,6 +3993,129 @@ static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter)
 	}
 }
 
+static void ixgbe_vlan_promisc_enable(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 vlnctrl, i;
+
+	switch (hw->mac.type) {
+	case ixgbe_mac_82599EB:
+	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
+	default:
+		if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)
+			break;
+		/* fall through */
+	case ixgbe_mac_82598EB:
+		/* legacy case, we can just disable VLAN filtering */
+		vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+		vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
+		IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+		return;
+	}
+
+	/* We are already in VLAN promisc, nothing to do */
+	if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)
+		return;
+
+	/* Set flag so we don't redo unnecessary work */
+	adapter->flags2 |= IXGBE_FLAG2_VLAN_PROMISC;
+
+	/* Add PF to all active pools */
+	for (i = IXGBE_VLVF_ENTRIES; --i;) {
+		u32 reg_offset = IXGBE_VLVFB(i * 2 + VMDQ_P(0) / 32);
+		u32 vlvfb = IXGBE_READ_REG(hw, reg_offset);
+
+		vlvfb |= 1 << (VMDQ_P(0) % 32);
+		IXGBE_WRITE_REG(hw, reg_offset, vlvfb);
+	}
+
+	/* Set all bits in the VLAN filter table array */
+	for (i = hw->mac.vft_size; i--;)
+		IXGBE_WRITE_REG(hw, IXGBE_VFTA(i), ~0U);
+}
+
+#define VFTA_BLOCK_SIZE 8
+static void ixgbe_scrub_vfta(struct ixgbe_adapter *adapter, u32 vfta_offset)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 vfta[VFTA_BLOCK_SIZE] = { 0 };
+	u32 vid_start = vfta_offset * 32;
+	u32 vid_end = vid_start + (VFTA_BLOCK_SIZE * 32);
+	u32 i, vid, word, bits;
+
+	for (i = IXGBE_VLVF_ENTRIES; --i;) {
+		u32 vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i));
+
+		/* pull VLAN ID from VLVF */
+		vid = vlvf & VLAN_VID_MASK;
+
+		/* only concern outselves with a certain range */
+		if (vid < vid_start || vid >= vid_end)
+			continue;
+
+		if (vlvf) {
+			/* record VLAN ID in VFTA */
+			vfta[(vid - vid_start) / 32] |= 1 << (vid % 32);
+
+			/* if PF is part of this then continue */
+			if (test_bit(vid, adapter->active_vlans))
+				continue;
+		}
+
+		/* remove PF from the pool */
+		word = i * 2 + VMDQ_P(0) / 32;
+		bits = ~(1 << (VMDQ_P(0) % 32));
+		bits &= IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), bits);
+	}
+
+	/* extract values from active_vlans and write back to VFTA */
+	for (i = VFTA_BLOCK_SIZE; i--;) {
+		vid = (vfta_offset + i) * 32;
+		word = vid / BITS_PER_LONG;
+		bits = vid % BITS_PER_LONG;
+
+		vfta[i] |= adapter->active_vlans[word] >> bits;
+
+		IXGBE_WRITE_REG(hw, IXGBE_VFTA(vfta_offset + i), vfta[i]);
+	}
+}
+
+static void ixgbe_vlan_promisc_disable(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 vlnctrl, i;
+
+	switch (hw->mac.type) {
+	case ixgbe_mac_82599EB:
+	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
+	default:
+		if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)
+			break;
+		/* fall through */
+	case ixgbe_mac_82598EB:
+		vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+		vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+		vlnctrl |= IXGBE_VLNCTRL_VFE;
+		IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+		return;
+	}
+
+	/* We are not in VLAN promisc, nothing to do */
+	if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
+		return;
+
+	/* Set flag so we don't redo unnecessary work */
+	adapter->flags2 &= ~IXGBE_FLAG2_VLAN_PROMISC;
+
+	for (i = 0; i < hw->mac.vft_size; i += VFTA_BLOCK_SIZE)
+		ixgbe_scrub_vfta(adapter, i);
+}
+
 static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
 {
 	u16 vid;
@@ -4246,12 +4372,10 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 fctrl, vmolr = IXGBE_VMOLR_BAM | IXGBE_VMOLR_AUPE;
-	u32 vlnctrl;
 	int count;
 
 	/* Check for Promiscuous and All Multicast modes */
 	fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
-	vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
 
 	/* set all bits that we expect to always be set */
 	fctrl &= ~IXGBE_FCTRL_SBP; /* disable store-bad-packets */
@@ -4261,25 +4385,18 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
 
 	/* clear the bits we are changing the status of */
 	fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
-	vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
 	if (netdev->flags & IFF_PROMISC) {
 		hw->addr_ctrl.user_set_promisc = true;
 		fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
 		vmolr |= IXGBE_VMOLR_MPE;
-		/* Only disable hardware filter vlans in promiscuous mode
-		 * if SR-IOV and VMDQ are disabled - otherwise ensure
-		 * that hardware VLAN filters remain enabled.
-		 */
-		if (adapter->flags & (IXGBE_FLAG_VMDQ_ENABLED |
-				      IXGBE_FLAG_SRIOV_ENABLED))
-			vlnctrl |= (IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
+		ixgbe_vlan_promisc_enable(adapter);
 	} else {
 		if (netdev->flags & IFF_ALLMULTI) {
 			fctrl |= IXGBE_FCTRL_MPE;
 			vmolr |= IXGBE_VMOLR_MPE;
 		}
-		vlnctrl |= IXGBE_VLNCTRL_VFE;
 		hw->addr_ctrl.user_set_promisc = false;
+		ixgbe_vlan_promisc_disable(adapter);
 	}
 
 	/*
@@ -4323,7 +4440,6 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
 		/* NOTE:  VLAN filtering is disabled by setting PROMISC */
 	}
 
-	IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
 
 	if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 08/11] ixgbe: Add support for VLAN promiscuous with SR-IOV
@ 2015-11-03  1:10   ` Alexander Duyck
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:10 UTC (permalink / raw)
  To: intel-wired-lan

This patch adds support for VLAN promiscuous with SR-IOV enabled.

The code prior to this patch was only adding the PF to VLANs that the VF
had added.  As such enabling promiscuous mode would actually not add any
additional VLAN filters so visibility was limited.  This lead to a number
of issues as the bridge and OVS would expect us to accept all VLAN tagged
packets when promiscuous mode was enabled, and instead we would filter out
most if not all depending on the configuration of the PF.

With this patch what we do is set all the bits in the VFTA and all of the
VLVF bits associated with the pool belonging to the PF.  By doing this the
PF is guaranteed to receive all VLAN tagged traffic associated with the RAR
filters assigned to the PF.  In addition we will clean up those same bits
in the event of promiscuous mode being disabled.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h      |    1 
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  140 +++++++++++++++++++++++--
 2 files changed, 129 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 445b4c9169b6..0269c0ca997c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -664,6 +664,7 @@ struct ixgbe_adapter {
 #ifdef CONFIG_IXGBE_VXLAN
 #define IXGBE_FLAG2_VXLAN_REREG_NEEDED		BIT(12)
 #endif
+#define IXGBE_FLAG2_VLAN_PROMISC		BIT(13)
 
 	/* Tx fast path data */
 	int num_tx_queues;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 742e0f84a925..f10337b1792c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3702,6 +3702,9 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
 	/* Map PF MAC address in RAR Entry 0 to first pool following VFs */
 	hw->mac.ops.set_vmdq(hw, 0, VMDQ_P(0));
 
+	/* clear VLAN promisc flag so VFTA will be updated if necessary */
+	adapter->flags2 &= ~IXGBE_FLAG2_VLAN_PROMISC;
+
 	/*
 	 * Set up VF register offsets for selected VT Mode,
 	 * i.e. 32 or 64 VFs for SR-IOV
@@ -3990,6 +3993,129 @@ static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter)
 	}
 }
 
+static void ixgbe_vlan_promisc_enable(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 vlnctrl, i;
+
+	switch (hw->mac.type) {
+	case ixgbe_mac_82599EB:
+	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
+	default:
+		if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)
+			break;
+		/* fall through */
+	case ixgbe_mac_82598EB:
+		/* legacy case, we can just disable VLAN filtering */
+		vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+		vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
+		IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+		return;
+	}
+
+	/* We are already in VLAN promisc, nothing to do */
+	if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)
+		return;
+
+	/* Set flag so we don't redo unnecessary work */
+	adapter->flags2 |= IXGBE_FLAG2_VLAN_PROMISC;
+
+	/* Add PF to all active pools */
+	for (i = IXGBE_VLVF_ENTRIES; --i;) {
+		u32 reg_offset = IXGBE_VLVFB(i * 2 + VMDQ_P(0) / 32);
+		u32 vlvfb = IXGBE_READ_REG(hw, reg_offset);
+
+		vlvfb |= 1 << (VMDQ_P(0) % 32);
+		IXGBE_WRITE_REG(hw, reg_offset, vlvfb);
+	}
+
+	/* Set all bits in the VLAN filter table array */
+	for (i = hw->mac.vft_size; i--;)
+		IXGBE_WRITE_REG(hw, IXGBE_VFTA(i), ~0U);
+}
+
+#define VFTA_BLOCK_SIZE 8
+static void ixgbe_scrub_vfta(struct ixgbe_adapter *adapter, u32 vfta_offset)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 vfta[VFTA_BLOCK_SIZE] = { 0 };
+	u32 vid_start = vfta_offset * 32;
+	u32 vid_end = vid_start + (VFTA_BLOCK_SIZE * 32);
+	u32 i, vid, word, bits;
+
+	for (i = IXGBE_VLVF_ENTRIES; --i;) {
+		u32 vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i));
+
+		/* pull VLAN ID from VLVF */
+		vid = vlvf & VLAN_VID_MASK;
+
+		/* only concern outselves with a certain range */
+		if (vid < vid_start || vid >= vid_end)
+			continue;
+
+		if (vlvf) {
+			/* record VLAN ID in VFTA */
+			vfta[(vid - vid_start) / 32] |= 1 << (vid % 32);
+
+			/* if PF is part of this then continue */
+			if (test_bit(vid, adapter->active_vlans))
+				continue;
+		}
+
+		/* remove PF from the pool */
+		word = i * 2 + VMDQ_P(0) / 32;
+		bits = ~(1 << (VMDQ_P(0) % 32));
+		bits &= IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), bits);
+	}
+
+	/* extract values from active_vlans and write back to VFTA */
+	for (i = VFTA_BLOCK_SIZE; i--;) {
+		vid = (vfta_offset + i) * 32;
+		word = vid / BITS_PER_LONG;
+		bits = vid % BITS_PER_LONG;
+
+		vfta[i] |= adapter->active_vlans[word] >> bits;
+
+		IXGBE_WRITE_REG(hw, IXGBE_VFTA(vfta_offset + i), vfta[i]);
+	}
+}
+
+static void ixgbe_vlan_promisc_disable(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 vlnctrl, i;
+
+	switch (hw->mac.type) {
+	case ixgbe_mac_82599EB:
+	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
+	default:
+		if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)
+			break;
+		/* fall through */
+	case ixgbe_mac_82598EB:
+		vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+		vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+		vlnctrl |= IXGBE_VLNCTRL_VFE;
+		IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+		return;
+	}
+
+	/* We are not in VLAN promisc, nothing to do */
+	if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
+		return;
+
+	/* Set flag so we don't redo unnecessary work */
+	adapter->flags2 &= ~IXGBE_FLAG2_VLAN_PROMISC;
+
+	for (i = 0; i < hw->mac.vft_size; i += VFTA_BLOCK_SIZE)
+		ixgbe_scrub_vfta(adapter, i);
+}
+
 static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
 {
 	u16 vid;
@@ -4246,12 +4372,10 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 fctrl, vmolr = IXGBE_VMOLR_BAM | IXGBE_VMOLR_AUPE;
-	u32 vlnctrl;
 	int count;
 
 	/* Check for Promiscuous and All Multicast modes */
 	fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
-	vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
 
 	/* set all bits that we expect to always be set */
 	fctrl &= ~IXGBE_FCTRL_SBP; /* disable store-bad-packets */
@@ -4261,25 +4385,18 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
 
 	/* clear the bits we are changing the status of */
 	fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
-	vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
 	if (netdev->flags & IFF_PROMISC) {
 		hw->addr_ctrl.user_set_promisc = true;
 		fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
 		vmolr |= IXGBE_VMOLR_MPE;
-		/* Only disable hardware filter vlans in promiscuous mode
-		 * if SR-IOV and VMDQ are disabled - otherwise ensure
-		 * that hardware VLAN filters remain enabled.
-		 */
-		if (adapter->flags & (IXGBE_FLAG_VMDQ_ENABLED |
-				      IXGBE_FLAG_SRIOV_ENABLED))
-			vlnctrl |= (IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
+		ixgbe_vlan_promisc_enable(adapter);
 	} else {
 		if (netdev->flags & IFF_ALLMULTI) {
 			fctrl |= IXGBE_FCTRL_MPE;
 			vmolr |= IXGBE_VMOLR_MPE;
 		}
-		vlnctrl |= IXGBE_VLNCTRL_VFE;
 		hw->addr_ctrl.user_set_promisc = false;
+		ixgbe_vlan_promisc_disable(adapter);
 	}
 
 	/*
@@ -4323,7 +4440,6 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
 		/* NOTE:  VLAN filtering is disabled by setting PROMISC */
 	}
 
-	IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
 
 	if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [next PATCH 09/11] ixgbe: Fix VLAN promisc in relation to SR-IOV
  2015-11-03  1:09 ` [Intel-wired-lan] " Alexander Duyck
@ 2015-11-03  1:10   ` Alexander Duyck
  -1 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:10 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: jeffrey.t.kirsher

From: Alexander Duyck <aduyck@mirantis.com>

This patch is a follow-on for enabling VLAN promiscuous and allowing the PF
to add VLANs without adding a VLVF entry.  What this patch does is go
through and free the VLVF registers if they are not needed as the VLAN
belongs only to the PF which is the default pool.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h       |    1 
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |   50 +++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c |   94 ++++++------------------
 3 files changed, 72 insertions(+), 73 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 0269c0ca997c..f4c9a42dafcf 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -898,6 +898,7 @@ int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter,
 			 const u8 *addr, u16 queue);
 int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter,
 			 const u8 *addr, u16 queue);
+void ixgbe_update_pf_promisc_vlvf(struct ixgbe_adapter *adapter, u32 vid);
 void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
 netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, struct ixgbe_adapter *,
 				  struct ixgbe_ring *);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index f10337b1792c..1a5719c53fde 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3908,6 +3908,50 @@ static int ixgbe_vlan_rx_add_vid(struct net_device *netdev,
 	return 0;
 }
 
+static int ixgbe_find_vlvf_entry(struct ixgbe_hw *hw, u32 vlan)
+{
+	u32 vlvf;
+	int idx;
+
+	/* short cut the special case */
+	if (vlan == 0)
+		return 0;
+
+	/* Search for the vlan id in the VLVF entries */
+	for (idx = IXGBE_VLVF_ENTRIES; --idx;) {
+		vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(idx));
+		if ((vlvf & VLAN_VID_MASK) == vlan)
+			break;
+	}
+
+	return idx;
+}
+
+void ixgbe_update_pf_promisc_vlvf(struct ixgbe_adapter *adapter, u32 vid)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 bits, word;
+	int idx;
+
+	idx = ixgbe_find_vlvf_entry(hw, vid);
+	if (!idx)
+		return;
+
+	/* See if any other pools are set for this VLAN filter
+	 * entry other than the PF.
+	 */
+	word = idx * 2 + (VMDQ_P(0) / 32);
+	bits = ~(1 << (VMDQ_P(0)) % 32);
+	bits &= IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
+
+	/* Disable the filter so this falls into the default pool. */
+	if (!bits && !IXGBE_READ_REG(hw, IXGBE_VLVFB(word ^ 1))) {
+		if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
+			IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(idx), 0);
+	}
+}
+
 static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev,
 				  __be16 proto, u16 vid)
 {
@@ -3915,7 +3959,11 @@ static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev,
 	struct ixgbe_hw *hw = &adapter->hw;
 
 	/* remove VID from filter table */
-	hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), false, true);
+	if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)
+		ixgbe_update_pf_promisc_vlvf(adapter, vid);
+	else
+		hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), false, true);
+
 	clear_bit(vid, adapter->active_vlans);
 
 	return 0;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 3380f14517dc..03d4e5c9d71d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -472,6 +472,17 @@ static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
 
 	err = hw->mac.ops.set_vfta(hw, vid, vf, !!add, false);
 
+	if (add && !err)
+		return err;
+
+	/* If we failed to add the VF VLAN or we are removing the VF VLAN
+	 * we may need to drop the PF pool bit in order to allow us to free
+	 * up the VLVF resources.
+	 */
+	if (test_bit(vid, adapter->active_vlans) ||
+	    (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
+		ixgbe_update_pf_promisc_vlvf(adapter, vid);
+
 	return err;
 }
 
@@ -830,40 +841,14 @@ static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter,
 	return ixgbe_set_vf_mac(adapter, vf, new_mac) < 0;
 }
 
-static int ixgbe_find_vlvf_entry(struct ixgbe_hw *hw, u32 vlan)
-{
-	u32 vlvf;
-	s32 regindex;
-
-	/* short cut the special case */
-	if (vlan == 0)
-		return 0;
-
-	/* Search for the vlan id in the VLVF entries */
-	for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
-		vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
-		if ((vlvf & VLAN_VID_MASK) == vlan)
-			break;
-	}
-
-	/* Return a negative value if not found */
-	if (regindex >= IXGBE_VLVF_ENTRIES)
-		regindex = -1;
-
-	return regindex;
-}
-
 static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
 				 u32 *msgbuf, u32 vf)
 {
+	u32 add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT;
+	u32 vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK);
+	u8 tcs = netdev_get_num_tc(adapter->netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
-	int add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT;
-	int vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK);
 	int err;
-	s32 reg_ndx;
-	u32 vlvf;
-	u32 bits;
-	u8 tcs = netdev_get_num_tc(adapter->netdev);
 
 	if (adapter->vfinfo[vf].pf_vlan || tcs) {
 		e_warn(drv,
@@ -873,54 +858,19 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
 		return -1;
 	}
 
+	err = ixgbe_set_vf_vlan(adapter, add, vid, vf);
+	if (err)
+		return err;
+
+	if (adapter->vfinfo[vf].spoofchk_enabled)
+		hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
+
 	if (add)
 		adapter->vfinfo[vf].vlan_count++;
 	else if (adapter->vfinfo[vf].vlan_count)
 		adapter->vfinfo[vf].vlan_count--;
 
-	/* in case of promiscuous mode any VLAN filter set for a VF must
-	 * also have the PF pool added to it.
-	 */
-	if (add && adapter->netdev->flags & IFF_PROMISC)
-		err = ixgbe_set_vf_vlan(adapter, add, vid, VMDQ_P(0));
-
-	err = ixgbe_set_vf_vlan(adapter, add, vid, vf);
-	if (!err && adapter->vfinfo[vf].spoofchk_enabled)
-		hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
-
-	/* Go through all the checks to see if the VLAN filter should
-	 * be wiped completely.
-	 */
-	if (!add && adapter->netdev->flags & IFF_PROMISC) {
-		reg_ndx = ixgbe_find_vlvf_entry(hw, vid);
-		if (reg_ndx < 0)
-			return err;
-		vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(reg_ndx));
-		/* See if any other pools are set for this VLAN filter
-		 * entry other than the PF.
-		 */
-		if (VMDQ_P(0) < 32) {
-			bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2));
-			bits &= ~(1 << VMDQ_P(0));
-			bits |= IXGBE_READ_REG(hw,
-					       IXGBE_VLVFB(reg_ndx * 2 + 1));
-		} else {
-			bits = IXGBE_READ_REG(hw,
-					      IXGBE_VLVFB(reg_ndx * 2 + 1));
-			bits &= ~(1 << (VMDQ_P(0) - 32));
-			bits |= IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2));
-		}
-
-		/* If the filter was removed then ensure PF pool bit
-		 * is cleared if the PF only added itself to the pool
-		 * because the PF is in promiscuous mode.
-		 */
-		if ((vlvf & VLAN_VID_MASK) == vid &&
-		    !test_bit(vid, adapter->active_vlans) && !bits)
-			ixgbe_set_vf_vlan(adapter, add, vid, VMDQ_P(0));
-	}
-
-	return err;
+	return 0;
 }
 
 static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter,

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 09/11] ixgbe: Fix VLAN promisc in relation to SR-IOV
@ 2015-11-03  1:10   ` Alexander Duyck
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:10 UTC (permalink / raw)
  To: intel-wired-lan

From: Alexander Duyck <aduyck@mirantis.com>

This patch is a follow-on for enabling VLAN promiscuous and allowing the PF
to add VLANs without adding a VLVF entry.  What this patch does is go
through and free the VLVF registers if they are not needed as the VLAN
belongs only to the PF which is the default pool.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h       |    1 
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |   50 +++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c |   94 ++++++------------------
 3 files changed, 72 insertions(+), 73 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 0269c0ca997c..f4c9a42dafcf 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -898,6 +898,7 @@ int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter,
 			 const u8 *addr, u16 queue);
 int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter,
 			 const u8 *addr, u16 queue);
+void ixgbe_update_pf_promisc_vlvf(struct ixgbe_adapter *adapter, u32 vid);
 void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
 netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, struct ixgbe_adapter *,
 				  struct ixgbe_ring *);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index f10337b1792c..1a5719c53fde 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3908,6 +3908,50 @@ static int ixgbe_vlan_rx_add_vid(struct net_device *netdev,
 	return 0;
 }
 
+static int ixgbe_find_vlvf_entry(struct ixgbe_hw *hw, u32 vlan)
+{
+	u32 vlvf;
+	int idx;
+
+	/* short cut the special case */
+	if (vlan == 0)
+		return 0;
+
+	/* Search for the vlan id in the VLVF entries */
+	for (idx = IXGBE_VLVF_ENTRIES; --idx;) {
+		vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(idx));
+		if ((vlvf & VLAN_VID_MASK) == vlan)
+			break;
+	}
+
+	return idx;
+}
+
+void ixgbe_update_pf_promisc_vlvf(struct ixgbe_adapter *adapter, u32 vid)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 bits, word;
+	int idx;
+
+	idx = ixgbe_find_vlvf_entry(hw, vid);
+	if (!idx)
+		return;
+
+	/* See if any other pools are set for this VLAN filter
+	 * entry other than the PF.
+	 */
+	word = idx * 2 + (VMDQ_P(0) / 32);
+	bits = ~(1 << (VMDQ_P(0)) % 32);
+	bits &= IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
+
+	/* Disable the filter so this falls into the default pool. */
+	if (!bits && !IXGBE_READ_REG(hw, IXGBE_VLVFB(word ^ 1))) {
+		if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
+			IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(idx), 0);
+	}
+}
+
 static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev,
 				  __be16 proto, u16 vid)
 {
@@ -3915,7 +3959,11 @@ static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev,
 	struct ixgbe_hw *hw = &adapter->hw;
 
 	/* remove VID from filter table */
-	hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), false, true);
+	if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)
+		ixgbe_update_pf_promisc_vlvf(adapter, vid);
+	else
+		hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), false, true);
+
 	clear_bit(vid, adapter->active_vlans);
 
 	return 0;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 3380f14517dc..03d4e5c9d71d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -472,6 +472,17 @@ static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
 
 	err = hw->mac.ops.set_vfta(hw, vid, vf, !!add, false);
 
+	if (add && !err)
+		return err;
+
+	/* If we failed to add the VF VLAN or we are removing the VF VLAN
+	 * we may need to drop the PF pool bit in order to allow us to free
+	 * up the VLVF resources.
+	 */
+	if (test_bit(vid, adapter->active_vlans) ||
+	    (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
+		ixgbe_update_pf_promisc_vlvf(adapter, vid);
+
 	return err;
 }
 
@@ -830,40 +841,14 @@ static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter,
 	return ixgbe_set_vf_mac(adapter, vf, new_mac) < 0;
 }
 
-static int ixgbe_find_vlvf_entry(struct ixgbe_hw *hw, u32 vlan)
-{
-	u32 vlvf;
-	s32 regindex;
-
-	/* short cut the special case */
-	if (vlan == 0)
-		return 0;
-
-	/* Search for the vlan id in the VLVF entries */
-	for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
-		vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
-		if ((vlvf & VLAN_VID_MASK) == vlan)
-			break;
-	}
-
-	/* Return a negative value if not found */
-	if (regindex >= IXGBE_VLVF_ENTRIES)
-		regindex = -1;
-
-	return regindex;
-}
-
 static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
 				 u32 *msgbuf, u32 vf)
 {
+	u32 add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT;
+	u32 vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK);
+	u8 tcs = netdev_get_num_tc(adapter->netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
-	int add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT;
-	int vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK);
 	int err;
-	s32 reg_ndx;
-	u32 vlvf;
-	u32 bits;
-	u8 tcs = netdev_get_num_tc(adapter->netdev);
 
 	if (adapter->vfinfo[vf].pf_vlan || tcs) {
 		e_warn(drv,
@@ -873,54 +858,19 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
 		return -1;
 	}
 
+	err = ixgbe_set_vf_vlan(adapter, add, vid, vf);
+	if (err)
+		return err;
+
+	if (adapter->vfinfo[vf].spoofchk_enabled)
+		hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
+
 	if (add)
 		adapter->vfinfo[vf].vlan_count++;
 	else if (adapter->vfinfo[vf].vlan_count)
 		adapter->vfinfo[vf].vlan_count--;
 
-	/* in case of promiscuous mode any VLAN filter set for a VF must
-	 * also have the PF pool added to it.
-	 */
-	if (add && adapter->netdev->flags & IFF_PROMISC)
-		err = ixgbe_set_vf_vlan(adapter, add, vid, VMDQ_P(0));
-
-	err = ixgbe_set_vf_vlan(adapter, add, vid, vf);
-	if (!err && adapter->vfinfo[vf].spoofchk_enabled)
-		hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
-
-	/* Go through all the checks to see if the VLAN filter should
-	 * be wiped completely.
-	 */
-	if (!add && adapter->netdev->flags & IFF_PROMISC) {
-		reg_ndx = ixgbe_find_vlvf_entry(hw, vid);
-		if (reg_ndx < 0)
-			return err;
-		vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(reg_ndx));
-		/* See if any other pools are set for this VLAN filter
-		 * entry other than the PF.
-		 */
-		if (VMDQ_P(0) < 32) {
-			bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2));
-			bits &= ~(1 << VMDQ_P(0));
-			bits |= IXGBE_READ_REG(hw,
-					       IXGBE_VLVFB(reg_ndx * 2 + 1));
-		} else {
-			bits = IXGBE_READ_REG(hw,
-					      IXGBE_VLVFB(reg_ndx * 2 + 1));
-			bits &= ~(1 << (VMDQ_P(0) - 32));
-			bits |= IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2));
-		}
-
-		/* If the filter was removed then ensure PF pool bit
-		 * is cleared if the PF only added itself to the pool
-		 * because the PF is in promiscuous mode.
-		 */
-		if ((vlvf & VLAN_VID_MASK) == vid &&
-		    !test_bit(vid, adapter->active_vlans) && !bits)
-			ixgbe_set_vf_vlan(adapter, add, vid, VMDQ_P(0));
-	}
-
-	return err;
+	return 0;
 }
 
 static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter,


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [next PATCH 10/11] ixgbe: Clear stale pool mappings
  2015-11-03  1:09 ` [Intel-wired-lan] " Alexander Duyck
@ 2015-11-03  1:10   ` Alexander Duyck
  -1 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:10 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: jeffrey.t.kirsher

From: Alexander Duyck <alexander.h.duyck@redhat.com>

This patch makes certain that we clear the pool mappings added when we
configure default MAC addresses for the interface.  Without this we run the
risk of leaking an address into pool 0 which really belongs to VF 0 when
SR-IOV is enabled.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c  |   10 +++++++---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |    7 ++++---
 drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c   |   10 +++++++---
 3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
index b8bd72589f72..fa8d4f40ac2a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
@@ -1083,12 +1083,16 @@ mac_reset_top:
 
 	/* Add the SAN MAC address to the RAR only if it's a valid address */
 	if (is_valid_ether_addr(hw->mac.san_addr)) {
-		hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
-				    hw->mac.san_addr, 0, IXGBE_RAH_AV);
-
 		/* Save the SAN MAC RAR index */
 		hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
 
+		hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index,
+				    hw->mac.san_addr, 0, IXGBE_RAH_AV);
+
+		/* clear VMDq pool/queue selection for this RAR */
+		hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index,
+				       IXGBE_CLEAR_VMDQ_ALL);
+
 		/* Reserve the last RAR for the SAN MAC address */
 		hw->mac.num_rar_entries--;
 	}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 73dcc0aec6dc..64045053e874 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -1884,10 +1884,11 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
 		hw_dbg(hw, " New MAC Addr =%pM\n", hw->mac.addr);
 
 		hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
-
-		/*  clear VMDq pool/queue selection for RAR 0 */
-		hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
 	}
+
+	/*  clear VMDq pool/queue selection for RAR 0 */
+	hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
+
 	hw->addr_ctrl.overflow_promisc = 0;
 
 	hw->addr_ctrl.rar_used_count = 1;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
index b9e9b0c17398..e44952eeab00 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
@@ -155,12 +155,16 @@ mac_reset_top:
 
 	/* Add the SAN MAC address to the RAR only if it's a valid address */
 	if (is_valid_ether_addr(hw->mac.san_addr)) {
-		hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
-				    hw->mac.san_addr, 0, IXGBE_RAH_AV);
-
 		/* Save the SAN MAC RAR index */
 		hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
 
+		hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index,
+				    hw->mac.san_addr, 0, IXGBE_RAH_AV);
+
+		/* clear VMDq pool/queue selection for this RAR */
+		hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index,
+				       IXGBE_CLEAR_VMDQ_ALL);
+
 		/* Reserve the last RAR for the SAN MAC address */
 		hw->mac.num_rar_entries--;
 	}

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 10/11] ixgbe: Clear stale pool mappings
@ 2015-11-03  1:10   ` Alexander Duyck
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:10 UTC (permalink / raw)
  To: intel-wired-lan

From: Alexander Duyck <alexander.h.duyck@redhat.com>

This patch makes certain that we clear the pool mappings added when we
configure default MAC addresses for the interface.  Without this we run the
risk of leaking an address into pool 0 which really belongs to VF 0 when
SR-IOV is enabled.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c  |   10 +++++++---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |    7 ++++---
 drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c   |   10 +++++++---
 3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
index b8bd72589f72..fa8d4f40ac2a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
@@ -1083,12 +1083,16 @@ mac_reset_top:
 
 	/* Add the SAN MAC address to the RAR only if it's a valid address */
 	if (is_valid_ether_addr(hw->mac.san_addr)) {
-		hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
-				    hw->mac.san_addr, 0, IXGBE_RAH_AV);
-
 		/* Save the SAN MAC RAR index */
 		hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
 
+		hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index,
+				    hw->mac.san_addr, 0, IXGBE_RAH_AV);
+
+		/* clear VMDq pool/queue selection for this RAR */
+		hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index,
+				       IXGBE_CLEAR_VMDQ_ALL);
+
 		/* Reserve the last RAR for the SAN MAC address */
 		hw->mac.num_rar_entries--;
 	}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 73dcc0aec6dc..64045053e874 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -1884,10 +1884,11 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
 		hw_dbg(hw, " New MAC Addr =%pM\n", hw->mac.addr);
 
 		hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
-
-		/*  clear VMDq pool/queue selection for RAR 0 */
-		hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
 	}
+
+	/*  clear VMDq pool/queue selection for RAR 0 */
+	hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
+
 	hw->addr_ctrl.overflow_promisc = 0;
 
 	hw->addr_ctrl.rar_used_count = 1;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
index b9e9b0c17398..e44952eeab00 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
@@ -155,12 +155,16 @@ mac_reset_top:
 
 	/* Add the SAN MAC address to the RAR only if it's a valid address */
 	if (is_valid_ether_addr(hw->mac.san_addr)) {
-		hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
-				    hw->mac.san_addr, 0, IXGBE_RAH_AV);
-
 		/* Save the SAN MAC RAR index */
 		hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
 
+		hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index,
+				    hw->mac.san_addr, 0, IXGBE_RAH_AV);
+
+		/* clear VMDq pool/queue selection for this RAR */
+		hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index,
+				       IXGBE_CLEAR_VMDQ_ALL);
+
 		/* Reserve the last RAR for the SAN MAC address */
 		hw->mac.num_rar_entries--;
 	}


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [next PATCH 11/11] ixgbe: Clean stale VLANs when changing port vlan or resetting
  2015-11-03  1:09 ` [Intel-wired-lan] " Alexander Duyck
@ 2015-11-03  1:10   ` Alexander Duyck
  -1 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:10 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: jeffrey.t.kirsher

This patch guarantees that the VFs do not have access to VLANs that they
were not supposed to.  What this patch does is add code so that we delete
the previous port VLAN after adding a new one, and if we reset the VF we
clear all of the filters associated with it.

Previously the code was leaving all previous VLANs mapped to the VF and
they didn't get deleted unless the VF specifically requested it or if the
PF itself was reset.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c |   77 ++++++++++++++++++++++--
 1 file changed, 72 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 03d4e5c9d71d..eeff3d075bf8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -455,10 +455,6 @@ static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
 	struct ixgbe_hw *hw = &adapter->hw;
 	int err;
 
-	/* VLAN 0 is a special case, don't allow it to be removed */
-	if (!vid && !add)
-		return 0;
-
 	/* If VLAN overlaps with one the PF is currently monitoring make
 	 * sure that we are able to allocate a VLVF entry.  This may be
 	 * redundant but it guarantees PF will maintain visibility to
@@ -589,13 +585,75 @@ static void ixgbe_clear_vmvir(struct ixgbe_adapter *adapter, u32 vf)
 
 	IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0);
 }
+
+static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 i;
+
+	/* post increment loop, covers VLVF_ENTRIES - 1 to 0 */
+	for (i = IXGBE_VLVF_ENTRIES; i--;) {
+		u32 word = IXGBE_VLVFB(i * 2 + vf / 32);
+		u32 bits[2], vlvfb, vid, vfta, vlvf;
+		u32 mask = 1 << (vf / 32);
+
+		vlvfb = IXGBE_READ_REG(hw, word);
+
+		/* if our bit isn't set we can skip it */
+		if (!(vlvfb & mask))
+			continue;
+
+		/* clear our bit from vlvfb */
+		vlvfb ^= mask;
+
+		/* create 64b mask to chedk to see if we should clear VLVF */
+		bits[word % 2] = vlvfb;
+		bits[(word % 2) ^ 1] = IXGBE_READ_REG(hw, word ^ 1);
+
+		/* if promisc is enabled, PF will be present, leave VFTA */
+		if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC) {
+			bits[VMDQ_P(0) / 32] &= ~(1 << (VMDQ_P(0) % 32));
+
+			if (bits[0] || bits[1])
+				goto update_vlvfb;
+			goto update_vlvf;
+		}
+
+		/* if other pools are present, just remove ourselves */
+		if (bits[0] || bits[1])
+			goto update_vlvfb;
+
+		/* if we cannot determine VLAN just remove ourselves */
+		vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i));
+		if (!vlvf)
+			goto update_vlvfb;
+
+		vid = vlvf & VLAN_VID_MASK;
+		mask = 1 << (vid % 32);
+
+		/* clear bit from VFTA */
+		vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(vid / 32));
+		if (vfta & mask)
+			IXGBE_WRITE_REG(hw, IXGBE_VFTA(vid / 32), vfta ^ mask);
+update_vlvf:
+		/* clear POOL selection enable */
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(i), 0);
+update_vlvfb:
+		/* clear pool bits */
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), vlvfb);
+	}
+}
+
 static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
 	u8 num_tcs = netdev_get_num_tc(adapter->netdev);
 
-	/* add PF assigned VLAN or VLAN 0 */
+	/* remove VLAN filters beloning to this VF */
+	ixgbe_clear_vf_vlans(adapter, vf);
+
+	/* add back PF assigned VLAN or VLAN 0 */
 	ixgbe_set_vf_vlan(adapter, true, vfinfo->pf_vlan, vf);
 
 	/* reset offloads to defaults */
@@ -858,6 +916,10 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
 		return -1;
 	}
 
+	/* VLAN 0 is a special case, don't allow it to be removed */
+	if (!vid && !add)
+		return 0;
+
 	err = ixgbe_set_vf_vlan(adapter, add, vid, vf);
 	if (err)
 		return err;
@@ -1251,6 +1313,9 @@ static int ixgbe_enable_port_vlan(struct ixgbe_adapter *adapter, int vf,
 	if (err)
 		goto out;
 
+	/* Revoke tagless access via VLAN 0 */
+	ixgbe_set_vf_vlan(adapter, false, 0, vf);
+
 	ixgbe_set_vmvir(adapter, vlan, qos, vf);
 	ixgbe_set_vmolr(hw, vf, false);
 	if (adapter->vfinfo[vf].spoofchk_enabled)
@@ -1284,6 +1349,8 @@ static int ixgbe_disable_port_vlan(struct ixgbe_adapter *adapter, int vf)
 
 	err = ixgbe_set_vf_vlan(adapter, false,
 				adapter->vfinfo[vf].pf_vlan, vf);
+	/* Restore tagless access via VLAN 0 */
+	ixgbe_set_vf_vlan(adapter, true, 0, vf);
 	ixgbe_clear_vmvir(adapter, vf);
 	ixgbe_set_vmolr(hw, vf, true);
 	hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf);

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 11/11] ixgbe: Clean stale VLANs when changing port vlan or resetting
@ 2015-11-03  1:10   ` Alexander Duyck
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Duyck @ 2015-11-03  1:10 UTC (permalink / raw)
  To: intel-wired-lan

This patch guarantees that the VFs do not have access to VLANs that they
were not supposed to.  What this patch does is add code so that we delete
the previous port VLAN after adding a new one, and if we reset the VF we
clear all of the filters associated with it.

Previously the code was leaving all previous VLANs mapped to the VF and
they didn't get deleted unless the VF specifically requested it or if the
PF itself was reset.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c |   77 ++++++++++++++++++++++--
 1 file changed, 72 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 03d4e5c9d71d..eeff3d075bf8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -455,10 +455,6 @@ static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
 	struct ixgbe_hw *hw = &adapter->hw;
 	int err;
 
-	/* VLAN 0 is a special case, don't allow it to be removed */
-	if (!vid && !add)
-		return 0;
-
 	/* If VLAN overlaps with one the PF is currently monitoring make
 	 * sure that we are able to allocate a VLVF entry.  This may be
 	 * redundant but it guarantees PF will maintain visibility to
@@ -589,13 +585,75 @@ static void ixgbe_clear_vmvir(struct ixgbe_adapter *adapter, u32 vf)
 
 	IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0);
 }
+
+static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 i;
+
+	/* post increment loop, covers VLVF_ENTRIES - 1 to 0 */
+	for (i = IXGBE_VLVF_ENTRIES; i--;) {
+		u32 word = IXGBE_VLVFB(i * 2 + vf / 32);
+		u32 bits[2], vlvfb, vid, vfta, vlvf;
+		u32 mask = 1 << (vf / 32);
+
+		vlvfb = IXGBE_READ_REG(hw, word);
+
+		/* if our bit isn't set we can skip it */
+		if (!(vlvfb & mask))
+			continue;
+
+		/* clear our bit from vlvfb */
+		vlvfb ^= mask;
+
+		/* create 64b mask to chedk to see if we should clear VLVF */
+		bits[word % 2] = vlvfb;
+		bits[(word % 2) ^ 1] = IXGBE_READ_REG(hw, word ^ 1);
+
+		/* if promisc is enabled, PF will be present, leave VFTA */
+		if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC) {
+			bits[VMDQ_P(0) / 32] &= ~(1 << (VMDQ_P(0) % 32));
+
+			if (bits[0] || bits[1])
+				goto update_vlvfb;
+			goto update_vlvf;
+		}
+
+		/* if other pools are present, just remove ourselves */
+		if (bits[0] || bits[1])
+			goto update_vlvfb;
+
+		/* if we cannot determine VLAN just remove ourselves */
+		vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i));
+		if (!vlvf)
+			goto update_vlvfb;
+
+		vid = vlvf & VLAN_VID_MASK;
+		mask = 1 << (vid % 32);
+
+		/* clear bit from VFTA */
+		vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(vid / 32));
+		if (vfta & mask)
+			IXGBE_WRITE_REG(hw, IXGBE_VFTA(vid / 32), vfta ^ mask);
+update_vlvf:
+		/* clear POOL selection enable */
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(i), 0);
+update_vlvfb:
+		/* clear pool bits */
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), vlvfb);
+	}
+}
+
 static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
 	u8 num_tcs = netdev_get_num_tc(adapter->netdev);
 
-	/* add PF assigned VLAN or VLAN 0 */
+	/* remove VLAN filters beloning to this VF */
+	ixgbe_clear_vf_vlans(adapter, vf);
+
+	/* add back PF assigned VLAN or VLAN 0 */
 	ixgbe_set_vf_vlan(adapter, true, vfinfo->pf_vlan, vf);
 
 	/* reset offloads to defaults */
@@ -858,6 +916,10 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
 		return -1;
 	}
 
+	/* VLAN 0 is a special case, don't allow it to be removed */
+	if (!vid && !add)
+		return 0;
+
 	err = ixgbe_set_vf_vlan(adapter, add, vid, vf);
 	if (err)
 		return err;
@@ -1251,6 +1313,9 @@ static int ixgbe_enable_port_vlan(struct ixgbe_adapter *adapter, int vf,
 	if (err)
 		goto out;
 
+	/* Revoke tagless access via VLAN 0 */
+	ixgbe_set_vf_vlan(adapter, false, 0, vf);
+
 	ixgbe_set_vmvir(adapter, vlan, qos, vf);
 	ixgbe_set_vmolr(hw, vf, false);
 	if (adapter->vfinfo[vf].spoofchk_enabled)
@@ -1284,6 +1349,8 @@ static int ixgbe_disable_port_vlan(struct ixgbe_adapter *adapter, int vf)
 
 	err = ixgbe_set_vf_vlan(adapter, false,
 				adapter->vfinfo[vf].pf_vlan, vf);
+	/* Restore tagless access via VLAN 0 */
+	ixgbe_set_vf_vlan(adapter, true, 0, vf);
 	ixgbe_clear_vmvir(adapter, vf);
 	ixgbe_set_vmolr(hw, vf, true);
 	hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf);


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* Re: [next PATCH 00/11] ixgbe: Add support for mixed PF/VF virtualization
  2015-11-03  1:09 ` [Intel-wired-lan] " Alexander Duyck
@ 2015-11-03 12:38   ` Jeff Kirsher
  -1 siblings, 0 replies; 48+ messages in thread
From: Jeff Kirsher @ 2015-11-03 12:38 UTC (permalink / raw)
  To: Alexander Duyck, netdev, intel-wired-lan

[-- Attachment #1: Type: text/plain, Size: 1775 bytes --]

On Mon, 2015-11-02 at 17:09 -0800, Alexander Duyck wrote:
> This patch series extends the abilities of the ixgbe driver so that
> we can
> now support VLAN trunking on top of the PF when SR-IOV is enabled. 
> By
> doing this we are able to extend the existing capabilities that were
> enabled with the "bridge fdb add" support that was added some time
> ago.  It
> had enabled the ability to have PF and VF mixed on a flat network,
> this
> makes it so that it also works on a VLAN enabled network.
> 
> The first few patches in this series are basically just cleanup. 
> They
> either fix bugs found in the code, or address complexity that was
> making it
> hard to either read or sort out exactly how the code was supposed to
> work.
> 
> The second half of the patch set is where we start adding features.
> Specifically with this patch set the VLAN behavior changes for the PF
> in
> two ways.  First we do not need to use the VLVF if the VFs have not
> already
> set up a pool list.  As such I added functionality so that we can
> skip that
> step when it is not needed.  Then I added support for VLAN
> promiscuous by
> simply setting all of the bits in the VFTA and letting the packets
> fall
> through to the default pool.  In addition when in promiscuous mode we
> set
> the pool bit for the PF in all of the VLVF entries.  This way if
> anyone
> adds a new entry it will automatically have the PF enabled.
> 
> The last few patches address some more issues I found during testing.
>   The
> issues were primarily related to stale entries floating around in
> either
> the RAR or VLVFB registers which were pointing to pools which were
> not
> valid for the given L2 address.

I have added these patches to my queue, Dave.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 00/11] ixgbe: Add support for mixed PF/VF virtualization
@ 2015-11-03 12:38   ` Jeff Kirsher
  0 siblings, 0 replies; 48+ messages in thread
From: Jeff Kirsher @ 2015-11-03 12:38 UTC (permalink / raw)
  To: intel-wired-lan

On Mon, 2015-11-02 at 17:09 -0800, Alexander Duyck wrote:
> This patch series extends the abilities of the ixgbe driver so that
> we can
> now support VLAN trunking on top of the PF when SR-IOV is enabled. 
> By
> doing this we are able to extend the existing capabilities that were
> enabled with the "bridge fdb add" support that was added some time
> ago.  It
> had enabled the ability to have PF and VF mixed on a flat network,
> this
> makes it so that it also works on a VLAN enabled network.
> 
> The first few patches in this series are basically just cleanup. 
> They
> either fix bugs found in the code, or address complexity that was
> making it
> hard to either read or sort out exactly how the code was supposed to
> work.
> 
> The second half of the patch set is where we start adding features.
> Specifically with this patch set the VLAN behavior changes for the PF
> in
> two ways.  First we do not need to use the VLVF if the VFs have not
> already
> set up a pool list.  As such I added functionality so that we can
> skip that
> step when it is not needed.  Then I added support for VLAN
> promiscuous by
> simply setting all of the bits in the VFTA and letting the packets
> fall
> through to the default pool.  In addition when in promiscuous mode we
> set
> the pool bit for the PF in all of the VLVF entries.  This way if
> anyone
> adds a new entry it will automatically have the PF enabled.
> 
> The last few patches address some more issues I found during testing.
>   The
> issues were primarily related to stale entries floating around in
> either
> the RAR or VLVFB registers which were pointing to pools which were
> not
> valid for the given L2 address.

I have added these patches to my queue, Dave.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.osuosl.org/pipermail/intel-wired-lan/attachments/20151103/1fa1ab25/attachment.asc>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* RE: [Intel-wired-lan] [next PATCH 01/11] ixgbe: Return error on failure to allocate mac_table
  2015-11-03  1:09   ` [Intel-wired-lan] " Alexander Duyck
@ 2015-12-10 22:51     ` Schmitt, Phillip J
  -1 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:51 UTC (permalink / raw)
  To: Alexander Duyck, netdev, intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:09 PM
> To: netdev@vger.kernel.org; intel-wired-lan@lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 01/11] ixgbe: Return error on failure to
> allocate mac_table
> 
> Add a check to make certain mac_table was actually allocated and is not NULL.
> If it is NULL return -ENOMEM and allow the probe routine to fail rather then
> causing a NULL pointer dereference further down the line.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 01/11] ixgbe: Return error on failure to allocate mac_table
@ 2015-12-10 22:51     ` Schmitt, Phillip J
  0 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:51 UTC (permalink / raw)
  To: intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:09 PM
> To: netdev at vger.kernel.org; intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 01/11] ixgbe: Return error on failure to
> allocate mac_table
> 
> Add a check to make certain mac_table was actually allocated and is not NULL.
> If it is NULL return -ENOMEM and allow the probe routine to fail rather then
> causing a NULL pointer dereference further down the line.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>


^ permalink raw reply	[flat|nested] 48+ messages in thread

* RE: [Intel-wired-lan] [next PATCH 02/11] ixgbe: Fix SR-IOV VLAN pool configuration
  2015-11-03  1:09   ` [Intel-wired-lan] " Alexander Duyck
@ 2015-12-10 22:52     ` Schmitt, Phillip J
  -1 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:52 UTC (permalink / raw)
  To: Alexander Duyck, netdev, intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev@vger.kernel.org; intel-wired-lan@lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 02/11] ixgbe: Fix SR-IOV VLAN pool
> configuration
> 
> The code for checking the PF bit in ixgbe_set_vf_vlan_msg was using the wrong
> offset and as a result it was pulling the VLAN off of the PF even if there were VFs
> numbered greater than 40 that still had the VLAN enabled.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 02/11] ixgbe: Fix SR-IOV VLAN pool configuration
@ 2015-12-10 22:52     ` Schmitt, Phillip J
  0 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:52 UTC (permalink / raw)
  To: intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev at vger.kernel.org; intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 02/11] ixgbe: Fix SR-IOV VLAN pool
> configuration
> 
> The code for checking the PF bit in ixgbe_set_vf_vlan_msg was using the wrong
> offset and as a result it was pulling the VLAN off of the PF even if there were VFs
> numbered greater than 40 that still had the VLAN enabled.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* RE: [Intel-wired-lan] [next PATCH 03/11] ixgbe: Simplify definitions for regidx and bit in set_vfta
  2015-11-03  1:09   ` [Intel-wired-lan] " Alexander Duyck
@ 2015-12-10 22:52     ` Schmitt, Phillip J
  -1 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:52 UTC (permalink / raw)
  To: Alexander Duyck, netdev, intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev@vger.kernel.org; intel-wired-lan@lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 03/11] ixgbe: Simplify definitions for
> regidx and bit in set_vfta
> 
> This patch simplifies the logic for setting the VFTA register by removing the
> number of conditional checks needed.  Instead we just use some boolean logic
> to generate vfta_delta, and if that is set then we xor the vfta by that value and
> write it back.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 03/11] ixgbe: Simplify definitions for regidx and bit in set_vfta
@ 2015-12-10 22:52     ` Schmitt, Phillip J
  0 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:52 UTC (permalink / raw)
  To: intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev at vger.kernel.org; intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 03/11] ixgbe: Simplify definitions for
> regidx and bit in set_vfta
> 
> This patch simplifies the logic for setting the VFTA register by removing the
> number of conditional checks needed.  Instead we just use some boolean logic
> to generate vfta_delta, and if that is set then we xor the vfta by that value and
> write it back.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* RE: [Intel-wired-lan] [next PATCH 04/11] ixgbe: Reduce VT code indent in set_vfta by introducing jump label
  2015-11-03  1:09   ` [Intel-wired-lan] " Alexander Duyck
@ 2015-12-10 22:52     ` Schmitt, Phillip J
  -1 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:52 UTC (permalink / raw)
  To: Alexander Duyck, netdev, intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev@vger.kernel.org; intel-wired-lan@lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 04/11] ixgbe: Reduce VT code indent in
> set_vfta by introducing jump label
> 
> In order to clear the way for upcoming work I thought it best to drop the level of
> indent in the ixgbe_set_vfta_generic function.  Most of the code is held in the
> virtualization specific section.  So the easiest approach is to just add a jump label
> and jump past the bulk of the code if it is not enabled.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 04/11] ixgbe: Reduce VT code indent in set_vfta by introducing jump label
@ 2015-12-10 22:52     ` Schmitt, Phillip J
  0 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:52 UTC (permalink / raw)
  To: intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev at vger.kernel.org; intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 04/11] ixgbe: Reduce VT code indent in
> set_vfta by introducing jump label
> 
> In order to clear the way for upcoming work I thought it best to drop the level of
> indent in the ixgbe_set_vfta_generic function.  Most of the code is held in the
> virtualization specific section.  So the easiest approach is to just add a jump label
> and jump past the bulk of the code if it is not enabled.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* RE: [Intel-wired-lan] [next PATCH 05/11] ixgbe: Simplify configuration of setting VLVF and VLVFB
  2015-11-03  1:09   ` [Intel-wired-lan] " Alexander Duyck
@ 2015-12-10 22:52     ` Schmitt, Phillip J
  -1 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:52 UTC (permalink / raw)
  To: Alexander Duyck, netdev, intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev@vger.kernel.org; intel-wired-lan@lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 05/11] ixgbe: Simplify configuration of
> setting VLVF and VLVFB
> 
> This patch addresses several issues within the VLVF and VLVFB configuration
> 
> First was the fact that code was overly complicated with multiple conditional
> paths depending on if we adding or removing and which bit we were going to
> add or remove.  Instead of messing with all that I have simplified it by using (vid /
> 32) and (1 - vid / 32) to identify our register and the other vlvfb register.
> 
> Second was the fact that we were likely leaking a few packets into the PF in
> cases where we were deleting an entry and the VFTA filter for that entry as the
> ordering was such that we deleted the pool and then the VLAN filter instead of
> the other way around.  I have updated that by adding a check for no bits being
> set and if that occurs we clear things up in the proper order.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 05/11] ixgbe: Simplify configuration of setting VLVF and VLVFB
@ 2015-12-10 22:52     ` Schmitt, Phillip J
  0 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:52 UTC (permalink / raw)
  To: intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev at vger.kernel.org; intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 05/11] ixgbe: Simplify configuration of
> setting VLVF and VLVFB
> 
> This patch addresses several issues within the VLVF and VLVFB configuration
> 
> First was the fact that code was overly complicated with multiple conditional
> paths depending on if we adding or removing and which bit we were going to
> add or remove.  Instead of messing with all that I have simplified it by using (vid /
> 32) and (1 - vid / 32) to identify our register and the other vlvfb register.
> 
> Second was the fact that we were likely leaking a few packets into the PF in
> cases where we were deleting an entry and the VFTA filter for that entry as the
> ordering was such that we deleted the pool and then the VLAN filter instead of
> the other way around.  I have updated that by adding a check for no bits being
> set and if that occurs we clear things up in the proper order.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* RE: [Intel-wired-lan] [next PATCH 06/11] ixgbe: Add support for adding/removing VLAN on PF bypassing the VLVF
  2015-11-03  1:10   ` [Intel-wired-lan] " Alexander Duyck
@ 2015-12-10 22:52     ` Schmitt, Phillip J
  -1 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:52 UTC (permalink / raw)
  To: Alexander Duyck, netdev, intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev@vger.kernel.org; intel-wired-lan@lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 06/11] ixgbe: Add support for
> adding/removing VLAN on PF bypassing the VLVF
> 
> This patch adds support for bypassing the VLVF entry creation when the PF is
> adding a new VLAN.  The advantage to doing this is that we can then save the
> VLVF entries for the VFs which must have them in order to function, versus the
> PF which can fall back on the default pool entry.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 06/11] ixgbe: Add support for adding/removing VLAN on PF bypassing the VLVF
@ 2015-12-10 22:52     ` Schmitt, Phillip J
  0 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:52 UTC (permalink / raw)
  To: intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev at vger.kernel.org; intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 06/11] ixgbe: Add support for
> adding/removing VLAN on PF bypassing the VLVF
> 
> This patch adds support for bypassing the VLVF entry creation when the PF is
> adding a new VLAN.  The advantage to doing this is that we can then save the
> VLVF entries for the VFs which must have them in order to function, versus the
> PF which can fall back on the default pool entry.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* RE: [Intel-wired-lan] [next PATCH 07/11] ixgbe: Reorder search to work from the top down instead of bottom up
  2015-11-03  1:10   ` [Intel-wired-lan] " Alexander Duyck
@ 2015-12-10 22:53     ` Schmitt, Phillip J
  -1 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:53 UTC (permalink / raw)
  To: Alexander Duyck, netdev, intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev@vger.kernel.org; intel-wired-lan@lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 07/11] ixgbe: Reorder search to work
> from the top down instead of bottom up
> 
> This patch is meant to reduce the complexity of the search function used for
> finding a VLVF entry associated with a given VLAN ID.  The previous code was
> searching from bottom to top.  I reordered it to search from top to bottom.  In
> addition I pulled an AND statement out of the loop and instead replaced it with
> an OR statement outside the loop.  This should help to reduce the overall size
> and complexity of the function.
> 
> There was also some formatting I cleaned up in regards to whitespace and such.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 07/11] ixgbe: Reorder search to work from the top down instead of bottom up
@ 2015-12-10 22:53     ` Schmitt, Phillip J
  0 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:53 UTC (permalink / raw)
  To: intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev at vger.kernel.org; intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 07/11] ixgbe: Reorder search to work
> from the top down instead of bottom up
> 
> This patch is meant to reduce the complexity of the search function used for
> finding a VLVF entry associated with a given VLAN ID.  The previous code was
> searching from bottom to top.  I reordered it to search from top to bottom.  In
> addition I pulled an AND statement out of the loop and instead replaced it with
> an OR statement outside the loop.  This should help to reduce the overall size
> and complexity of the function.
> 
> There was also some formatting I cleaned up in regards to whitespace and such.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* RE: [Intel-wired-lan] [next PATCH 08/11] ixgbe: Add support for VLAN promiscuous with SR-IOV
  2015-11-03  1:10   ` [Intel-wired-lan] " Alexander Duyck
@ 2015-12-10 22:53     ` Schmitt, Phillip J
  -1 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:53 UTC (permalink / raw)
  To: Alexander Duyck, netdev, intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev@vger.kernel.org; intel-wired-lan@lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 08/11] ixgbe: Add support for VLAN
> promiscuous with SR-IOV
> 
> This patch adds support for VLAN promiscuous with SR-IOV enabled.
> 
> The code prior to this patch was only adding the PF to VLANs that the VF had
> added.  As such enabling promiscuous mode would actually not add any
> additional VLAN filters so visibility was limited.  This lead to a number of issues
> as the bridge and OVS would expect us to accept all VLAN tagged packets when
> promiscuous mode was enabled, and instead we would filter out most if not all
> depending on the configuration of the PF.
> 
> With this patch what we do is set all the bits in the VFTA and all of the VLVF bits
> associated with the pool belonging to the PF.  By doing this the PF is guaranteed
> to receive all VLAN tagged traffic associated with the RAR filters assigned to the
> PF.  In addition we will clean up those same bits in the event of promiscuous
> mode being disabled.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 08/11] ixgbe: Add support for VLAN promiscuous with SR-IOV
@ 2015-12-10 22:53     ` Schmitt, Phillip J
  0 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:53 UTC (permalink / raw)
  To: intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev at vger.kernel.org; intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 08/11] ixgbe: Add support for VLAN
> promiscuous with SR-IOV
> 
> This patch adds support for VLAN promiscuous with SR-IOV enabled.
> 
> The code prior to this patch was only adding the PF to VLANs that the VF had
> added.  As such enabling promiscuous mode would actually not add any
> additional VLAN filters so visibility was limited.  This lead to a number of issues
> as the bridge and OVS would expect us to accept all VLAN tagged packets when
> promiscuous mode was enabled, and instead we would filter out most if not all
> depending on the configuration of the PF.
> 
> With this patch what we do is set all the bits in the VFTA and all of the VLVF bits
> associated with the pool belonging to the PF.  By doing this the PF is guaranteed
> to receive all VLAN tagged traffic associated with the RAR filters assigned to the
> PF.  In addition we will clean up those same bits in the event of promiscuous
> mode being disabled.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* RE: [Intel-wired-lan] [next PATCH 09/11] ixgbe: Fix VLAN promisc in relation to SR-IOV
  2015-11-03  1:10   ` [Intel-wired-lan] " Alexander Duyck
@ 2015-12-10 22:53     ` Schmitt, Phillip J
  -1 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:53 UTC (permalink / raw)
  To: Alexander Duyck, netdev, intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev@vger.kernel.org; intel-wired-lan@lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 09/11] ixgbe: Fix VLAN promisc in relation
> to SR-IOV
> 
> From: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 09/11] ixgbe: Fix VLAN promisc in relation to SR-IOV
@ 2015-12-10 22:53     ` Schmitt, Phillip J
  0 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:53 UTC (permalink / raw)
  To: intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev at vger.kernel.org; intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 09/11] ixgbe: Fix VLAN promisc in relation
> to SR-IOV
> 
> From: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* RE: [Intel-wired-lan] [next PATCH 10/11] ixgbe: Clear stale pool mappings
  2015-11-03  1:10   ` [Intel-wired-lan] " Alexander Duyck
@ 2015-12-10 22:53     ` Schmitt, Phillip J
  -1 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:53 UTC (permalink / raw)
  To: Alexander Duyck, netdev, intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev@vger.kernel.org; intel-wired-lan@lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 10/11] ixgbe: Clear stale pool mappings
> 
> From: Alexander Duyck <alexander.h.duyck@redhat.com>
> 
> This patch makes certain that we clear the pool mappings added when we
> configure default MAC addresses for the interface.  Without this we run the risk
> of leaking an address into pool 0 which really belongs to VF 0 when SR-IOV is
> enabled.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 10/11] ixgbe: Clear stale pool mappings
@ 2015-12-10 22:53     ` Schmitt, Phillip J
  0 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:53 UTC (permalink / raw)
  To: intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:10 PM
> To: netdev at vger.kernel.org; intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 10/11] ixgbe: Clear stale pool mappings
> 
> From: Alexander Duyck <alexander.h.duyck@redhat.com>
> 
> This patch makes certain that we clear the pool mappings added when we
> configure default MAC addresses for the interface.  Without this we run the risk
> of leaking an address into pool 0 which really belongs to VF 0 when SR-IOV is
> enabled.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* RE: [Intel-wired-lan] [next PATCH 11/11] ixgbe: Clean stale VLANs when changing port vlan or resetting
  2015-11-03  1:10   ` [Intel-wired-lan] " Alexander Duyck
@ 2015-12-10 22:54     ` Schmitt, Phillip J
  -1 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:54 UTC (permalink / raw)
  To: Alexander Duyck, netdev, intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:11 PM
> To: netdev@vger.kernel.org; intel-wired-lan@lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 11/11] ixgbe: Clean stale VLANs when
> changing port vlan or resetting
> 
> This patch guarantees that the VFs do not have access to VLANs that they were
> not supposed to.  What this patch does is add code so that we delete the
> previous port VLAN after adding a new one, and if we reset the VF we clear all of
> the filters associated with it.
> 
> Previously the code was leaving all previous VLANs mapped to the VF and they
> didn't get deleted unless the VF specifically requested it or if the PF itself was
> reset.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [Intel-wired-lan] [next PATCH 11/11] ixgbe: Clean stale VLANs when changing port vlan or resetting
@ 2015-12-10 22:54     ` Schmitt, Phillip J
  0 siblings, 0 replies; 48+ messages in thread
From: Schmitt, Phillip J @ 2015-12-10 22:54 UTC (permalink / raw)
  To: intel-wired-lan



> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at lists.osuosl.org] On
> Behalf Of Alexander Duyck
> Sent: Monday, November 02, 2015 5:11 PM
> To: netdev at vger.kernel.org; intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [next PATCH 11/11] ixgbe: Clean stale VLANs when
> changing port vlan or resetting
> 
> This patch guarantees that the VFs do not have access to VLANs that they were
> not supposed to.  What this patch does is add code so that we delete the
> previous port VLAN after adding a new one, and if we reset the VF we clear all of
> the filters associated with it.
> 
> Previously the code was leaving all previous VLANs mapped to the VF and they
> didn't get deleted unless the VF specifically requested it or if the PF itself was
> reset.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>

^ permalink raw reply	[flat|nested] 48+ messages in thread

end of thread, other threads:[~2015-12-10 22:54 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-03  1:09 [next PATCH 00/11] ixgbe: Add support for mixed PF/VF virtualization Alexander Duyck
2015-11-03  1:09 ` [Intel-wired-lan] " Alexander Duyck
2015-11-03  1:09 ` [next PATCH 01/11] ixgbe: Return error on failure to allocate mac_table Alexander Duyck
2015-11-03  1:09   ` [Intel-wired-lan] " Alexander Duyck
2015-12-10 22:51   ` Schmitt, Phillip J
2015-12-10 22:51     ` Schmitt, Phillip J
2015-11-03  1:09 ` [next PATCH 02/11] ixgbe: Fix SR-IOV VLAN pool configuration Alexander Duyck
2015-11-03  1:09   ` [Intel-wired-lan] " Alexander Duyck
2015-12-10 22:52   ` Schmitt, Phillip J
2015-12-10 22:52     ` Schmitt, Phillip J
2015-11-03  1:09 ` [next PATCH 03/11] ixgbe: Simplify definitions for regidx and bit in set_vfta Alexander Duyck
2015-11-03  1:09   ` [Intel-wired-lan] " Alexander Duyck
2015-12-10 22:52   ` Schmitt, Phillip J
2015-12-10 22:52     ` Schmitt, Phillip J
2015-11-03  1:09 ` [next PATCH 04/11] ixgbe: Reduce VT code indent in set_vfta by introducing jump label Alexander Duyck
2015-11-03  1:09   ` [Intel-wired-lan] " Alexander Duyck
2015-12-10 22:52   ` Schmitt, Phillip J
2015-12-10 22:52     ` Schmitt, Phillip J
2015-11-03  1:09 ` [next PATCH 05/11] ixgbe: Simplify configuration of setting VLVF and VLVFB Alexander Duyck
2015-11-03  1:09   ` [Intel-wired-lan] " Alexander Duyck
2015-12-10 22:52   ` Schmitt, Phillip J
2015-12-10 22:52     ` Schmitt, Phillip J
2015-11-03  1:10 ` [next PATCH 06/11] ixgbe: Add support for adding/removing VLAN on PF bypassing the VLVF Alexander Duyck
2015-11-03  1:10   ` [Intel-wired-lan] " Alexander Duyck
2015-12-10 22:52   ` Schmitt, Phillip J
2015-12-10 22:52     ` Schmitt, Phillip J
2015-11-03  1:10 ` [next PATCH 07/11] ixgbe: Reorder search to work from the top down instead of bottom up Alexander Duyck
2015-11-03  1:10   ` [Intel-wired-lan] " Alexander Duyck
2015-12-10 22:53   ` Schmitt, Phillip J
2015-12-10 22:53     ` Schmitt, Phillip J
2015-11-03  1:10 ` [next PATCH 08/11] ixgbe: Add support for VLAN promiscuous with SR-IOV Alexander Duyck
2015-11-03  1:10   ` [Intel-wired-lan] " Alexander Duyck
2015-12-10 22:53   ` Schmitt, Phillip J
2015-12-10 22:53     ` Schmitt, Phillip J
2015-11-03  1:10 ` [next PATCH 09/11] ixgbe: Fix VLAN promisc in relation to SR-IOV Alexander Duyck
2015-11-03  1:10   ` [Intel-wired-lan] " Alexander Duyck
2015-12-10 22:53   ` Schmitt, Phillip J
2015-12-10 22:53     ` Schmitt, Phillip J
2015-11-03  1:10 ` [next PATCH 10/11] ixgbe: Clear stale pool mappings Alexander Duyck
2015-11-03  1:10   ` [Intel-wired-lan] " Alexander Duyck
2015-12-10 22:53   ` Schmitt, Phillip J
2015-12-10 22:53     ` Schmitt, Phillip J
2015-11-03  1:10 ` [next PATCH 11/11] ixgbe: Clean stale VLANs when changing port vlan or resetting Alexander Duyck
2015-11-03  1:10   ` [Intel-wired-lan] " Alexander Duyck
2015-12-10 22:54   ` Schmitt, Phillip J
2015-12-10 22:54     ` Schmitt, Phillip J
2015-11-03 12:38 ` [next PATCH 00/11] ixgbe: Add support for mixed PF/VF virtualization Jeff Kirsher
2015-11-03 12:38   ` [Intel-wired-lan] " Jeff Kirsher

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.