DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/2] improve i40e VF VLAN performance
@ 2018-05-28  2:01 Qi Zhang
  2018-05-28  2:01 ` [dpdk-dev] [PATCH 1/2] net/i40e: improve " Qi Zhang
  2018-05-28  2:01 ` [dpdk-dev] [PATCH 2/2] net/i40e: enable VF VLAN antispoof Qi Zhang
  0 siblings, 2 replies; 4+ messages in thread
From: Qi Zhang @ 2018-05-28  2:01 UTC (permalink / raw)
  To: beilei.xing; +Cc: dev, helin.zhang, liang-min.wang, Qi Zhang

(target for v18.08)

Add vlan to vlan prune table cost additinal firmware cycle
that cause significent performance downgrade (40~50%). While
remove this will cause vlan anti spoof does not work on 
VF.

The dicision is to take performance as high priority, since 40~50%
performance drop is unbearable for most cases, so code part for 
adding vlan to vlan prune table will be stripped out, while for vlan
anti-spoof, we take an alternative way as below:

Due to hardware limitation, there is no perfect solution to
enable VF vlan antispoof, to enable it means lost something else.
So the solution is to introduce devarg "support-vf-vlan-antispoof"
that turn on the feature to meet customer's specific requirement
while no impact on normal case when it is turned off. Below impact
is expected when support-vf-vlan-antispoof is turned on:

1. Multi-driver is not supported since some global register is
   changed in DPDK driver during init which is no expected by
   kernel driver.

2. Unicast / Multicase promiscuous mode can not be configured
   separately. So, function rte_pmd_i40e_set_vf_unicast_promics
   and rte_pmd_i40e_set_vf_multicast_promisc will fail and
   new funciton rte_pmd_i40e_set_vf_promics is introduced as a
   coarse-grain API.

3. VLAN anti-spoof and Mac anti-spoof are always enable/disable
   together. (rte_eth_set_vf_mac_anti_spoof and
   rte_eth_set_vf_vlan_anti_spoof do the same thing now.)

4. When VLAN/MAC anti-spoof is turned on, vlan tag will be added to
   vlan promisc table, so in the rx path, mac address match will
   be ignored, only vlan will be matched.


Qi Zhang (2):
  net/i40e: improve VF VLAN performance
  net/i40e: enable VF VLAN antispoof

 doc/guides/nics/i40e.rst                  |  28 ++++
 drivers/net/i40e/i40e_ethdev.c            | 122 +++++++++-----
 drivers/net/i40e/i40e_ethdev.h            |   2 +-
 drivers/net/i40e/i40e_pf.c                |  30 +++-
 drivers/net/i40e/rte_pmd_i40e.c           | 263 ++++++++++++++++--------------
 drivers/net/i40e/rte_pmd_i40e.h           |  22 +++
 drivers/net/i40e/rte_pmd_i40e_version.map |   8 +-
 7 files changed, 302 insertions(+), 173 deletions(-)

-- 
2.13.6

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

* [dpdk-dev] [PATCH 1/2] net/i40e: improve VF VLAN performance
  2018-05-28  2:01 [dpdk-dev] [PATCH 0/2] improve i40e VF VLAN performance Qi Zhang
@ 2018-05-28  2:01 ` Qi Zhang
  2018-06-20  6:23   ` Xing, Beilei
  2018-05-28  2:01 ` [dpdk-dev] [PATCH 2/2] net/i40e: enable VF VLAN antispoof Qi Zhang
  1 sibling, 1 reply; 4+ messages in thread
From: Qi Zhang @ 2018-05-28  2:01 UTC (permalink / raw)
  To: beilei.xing; +Cc: dev, helin.zhang, liang-min.wang, Qi Zhang

Add vlan to vlan prune table cost additinal firmware cycle
that cause significent performance downgrade. This patch
remove related code when enable vlan filter, the side effect
is vlan anti spoof will not work, following patch will deal
with it.

Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c  |  23 ---------
 drivers/net/i40e/i40e_ethdev.h  |   1 -
 drivers/net/i40e/rte_pmd_i40e.c | 110 +---------------------------------------
 3 files changed, 2 insertions(+), 132 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 7d4f1c9da..f0c17a439 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -5337,7 +5337,6 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
 	vsi->user_param = user_param;
 	vsi->vlan_anti_spoof_on = 0;
-	vsi->vlan_filter_on = 0;
 	/* Allocate queues */
 	switch (vsi->type) {
 	case I40E_VSI_MAIN  :
@@ -6710,32 +6709,10 @@ void
 i40e_set_vlan_filter(struct i40e_vsi *vsi,
 		     uint16_t vlan_id, bool on)
 {
-	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
-	struct i40e_aqc_add_remove_vlan_element_data vlan_data = {0};
-	int ret;
-
 	if (vlan_id > ETH_VLAN_ID_MAX)
 		return;
 
 	i40e_store_vlan_filter(vsi, vlan_id, on);
-
-	if ((!vsi->vlan_anti_spoof_on && !vsi->vlan_filter_on) || !vlan_id)
-		return;
-
-	vlan_data.vlan_tag = rte_cpu_to_le_16(vlan_id);
-
-	if (on) {
-		ret = i40e_aq_add_vlan(hw, vsi->seid,
-				       &vlan_data, 1, NULL);
-		if (ret != I40E_SUCCESS)
-			PMD_DRV_LOG(ERR, "Failed to add vlan filter");
-	} else {
-		ret = i40e_aq_remove_vlan(hw, vsi->seid,
-					  &vlan_data, 1, NULL);
-		if (ret != I40E_SUCCESS)
-			PMD_DRV_LOG(ERR,
-				    "Failed to remove vlan filter");
-	}
 }
 
 /**
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 11c4c76bd..12c0645a7 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -378,7 +378,6 @@ struct i40e_vsi {
 	uint16_t nb_msix;   /* The max number of msix vector */
 	uint8_t enabled_tc; /* The traffic class enabled */
 	uint8_t vlan_anti_spoof_on; /* The VLAN anti-spoofing enabled */
-	uint8_t vlan_filter_on; /* The VLAN filter enabled */
 	struct i40e_bw_info bw_info; /* VSI bandwidth information */
 };
 
diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c
index 7aa1a7518..e5e4c44ba 100644
--- a/drivers/net/i40e/rte_pmd_i40e.c
+++ b/drivers/net/i40e/rte_pmd_i40e.c
@@ -102,45 +102,6 @@ rte_pmd_i40e_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on)
 	return ret;
 }
 
-static int
-i40e_add_rm_all_vlan_filter(struct i40e_vsi *vsi, uint8_t add)
-{
-	uint32_t j, k;
-	uint16_t vlan_id;
-	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
-	struct i40e_aqc_add_remove_vlan_element_data vlan_data = {0};
-	int ret;
-
-	for (j = 0; j < I40E_VFTA_SIZE; j++) {
-		if (!vsi->vfta[j])
-			continue;
-
-		for (k = 0; k < I40E_UINT32_BIT_SIZE; k++) {
-			if (!(vsi->vfta[j] & (1 << k)))
-				continue;
-
-			vlan_id = j * I40E_UINT32_BIT_SIZE + k;
-			if (!vlan_id)
-				continue;
-
-			vlan_data.vlan_tag = rte_cpu_to_le_16(vlan_id);
-			if (add)
-				ret = i40e_aq_add_vlan(hw, vsi->seid,
-						       &vlan_data, 1, NULL);
-			else
-				ret = i40e_aq_remove_vlan(hw, vsi->seid,
-							  &vlan_data, 1, NULL);
-			if (ret != I40E_SUCCESS) {
-				PMD_DRV_LOG(ERR,
-					    "Failed to add/rm vlan filter");
-				return ret;
-			}
-		}
-	}
-
-	return I40E_SUCCESS;
-}
-
 int
 rte_pmd_i40e_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on)
 {
@@ -176,14 +137,6 @@ rte_pmd_i40e_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on)
 		return 0; /* already on or off */
 
 	vsi->vlan_anti_spoof_on = on;
-	if (!vsi->vlan_filter_on) {
-		ret = i40e_add_rm_all_vlan_filter(vsi, on);
-		if (ret) {
-			PMD_DRV_LOG(ERR, "Failed to add/remove VLAN filters.");
-			return -ENOTSUP;
-		}
-	}
-
 	vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SECURITY_VALID);
 	if (on)
 		vsi->info.sec_flags |= I40E_AQ_VSI_SEC_FLAG_ENABLE_VLAN_CHK;
@@ -364,13 +317,6 @@ i40e_vsi_set_tx_loopback(struct i40e_vsi *vsi, uint8_t on)
 		PMD_INIT_LOG(ERR, "Failed to remove MAC filters.");
 		return ret;
 	}
-	if (vsi->vlan_anti_spoof_on || vsi->vlan_filter_on) {
-		ret = i40e_add_rm_all_vlan_filter(vsi, 0);
-		if (ret) {
-			PMD_INIT_LOG(ERR, "Failed to remove VLAN filters.");
-			return ret;
-		}
-	}
 
 	vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
 	if (on)
@@ -390,13 +336,6 @@ i40e_vsi_set_tx_loopback(struct i40e_vsi *vsi, uint8_t on)
 
 	/* add all the MAC and VLAN back */
 	ret = i40e_vsi_restore_mac_filter(vsi);
-	if (ret)
-		return ret;
-	if (vsi->vlan_anti_spoof_on || vsi->vlan_filter_on) {
-		ret = i40e_add_rm_all_vlan_filter(vsi, 1);
-		if (ret)
-			return ret;
-	}
 
 	return ret;
 }
@@ -849,32 +788,6 @@ int rte_pmd_i40e_set_vf_vlan_tag(uint16_t port, uint16_t vf_id, uint8_t on)
 	return ret;
 }
 
-static int
-i40e_vlan_filter_count(struct i40e_vsi *vsi)
-{
-	uint32_t j, k;
-	uint16_t vlan_id;
-	int count = 0;
-
-	for (j = 0; j < I40E_VFTA_SIZE; j++) {
-		if (!vsi->vfta[j])
-			continue;
-
-		for (k = 0; k < I40E_UINT32_BIT_SIZE; k++) {
-			if (!(vsi->vfta[j] & (1 << k)))
-				continue;
-
-			vlan_id = j * I40E_UINT32_BIT_SIZE + k;
-			if (!vlan_id)
-				continue;
-
-			count++;
-		}
-	}
-
-	return count;
-}
-
 int rte_pmd_i40e_set_vf_vlan_filter(uint16_t port, uint16_t vlan_id,
 				    uint64_t vf_mask, uint8_t on)
 {
@@ -923,29 +836,10 @@ int rte_pmd_i40e_set_vf_vlan_filter(uint16_t port, uint16_t vlan_id,
 	for (vf_idx = 0; vf_idx < pf->vf_num && ret == I40E_SUCCESS; vf_idx++) {
 		if (vf_mask & ((uint64_t)(1ULL << vf_idx))) {
 			vsi = pf->vfs[vf_idx].vsi;
-			if (on) {
-				if (!vsi->vlan_filter_on) {
-					vsi->vlan_filter_on = true;
-					i40e_aq_set_vsi_vlan_promisc(hw,
-								     vsi->seid,
-								     false,
-								     NULL);
-					if (!vsi->vlan_anti_spoof_on)
-						i40e_add_rm_all_vlan_filter(
-							vsi, true);
-				}
+			if (on)
 				ret = i40e_vsi_add_vlan(vsi, vlan_id);
-			} else {
+			else
 				ret = i40e_vsi_delete_vlan(vsi, vlan_id);
-
-				if (!i40e_vlan_filter_count(vsi)) {
-					vsi->vlan_filter_on = false;
-					i40e_aq_set_vsi_vlan_promisc(hw,
-								     vsi->seid,
-								     true,
-								     NULL);
-				}
-			}
 		}
 	}
 
-- 
2.13.6

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

* [dpdk-dev] [PATCH 2/2] net/i40e: enable VF VLAN antispoof
  2018-05-28  2:01 [dpdk-dev] [PATCH 0/2] improve i40e VF VLAN performance Qi Zhang
  2018-05-28  2:01 ` [dpdk-dev] [PATCH 1/2] net/i40e: improve " Qi Zhang
@ 2018-05-28  2:01 ` Qi Zhang
  1 sibling, 0 replies; 4+ messages in thread
From: Qi Zhang @ 2018-05-28  2:01 UTC (permalink / raw)
  To: beilei.xing; +Cc: dev, helin.zhang, liang-min.wang, Qi Zhang

Due to hardware limitation, there is no perfect solution to
enable VF vlan antispoof, to enable it means lost something else.
So the solution is to introduce devarg "support-vf-vlan-antispoof"
that turn on the feature to meet customer's specific requirement
while no impact on normal case when it is turned off. Below impact
is expected when support-vf-vlan-antispoof is turned on:

1. Multi-driver is not supported since some global register is
   changed in DPDK driver during init which is no expected by
   kernel driver.

2. Unicast / Multicase promiscuous mode can not be configured
   separately. So, function rte_pmd_i40e_set_vf_unicast_promics
   and rte_pmd_i40e_set_vf_multicast_promisc will fail and
   new funciton rte_pmd_i40e_set_vf_promics is introduced as a
   coarse-grain API.

3. VLAN anti-spoof and Mac anti-spoof are always enable/disable
   together. (rte_eth_set_vf_mac_anti_spoof and
   rte_eth_set_vf_vlan_anti_spoof do the same thing now.)

4. When VLAN/MAC anti-spoof is turned on, vlan tag will be added to
   vlan promisc table, so in the rx path, mac address match will
   be ignored, only vlan will be matched.

Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
 doc/guides/nics/i40e.rst                  |  28 +++++
 drivers/net/i40e/i40e_ethdev.c            |  99 +++++++++++++----
 drivers/net/i40e/i40e_ethdev.h            |   1 +
 drivers/net/i40e/i40e_pf.c                |  30 ++++--
 drivers/net/i40e/rte_pmd_i40e.c           | 171 ++++++++++++++++++++++++++----
 drivers/net/i40e/rte_pmd_i40e.h           |  22 ++++
 drivers/net/i40e/rte_pmd_i40e_version.map |   8 +-
 7 files changed, 309 insertions(+), 50 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 18549bf5a..ff054f3c4 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -124,6 +124,34 @@ Runtime Config Options
   will switch PF interrupt from IntN to Int0 to avoid interrupt conflict between
   DPDK and Linux Kernel.
 
+- ``Support VF VLAN anti-spoof`` (default ``disable``)
+
+  This is a work around to enable vlan antispoof on VF to support customer with
+  this specific requirement, the reason not make it as a default config is:
+  due to hardware limitation, when turn on this feature, some global register will
+  be re-write and some device default behaviour will be changed. (see below for
+  more detail). ``devargs`` parameter ``support-vf-vlan-antispoof`` is introduced,
+  for example::
+
+    -w 84:00.0,support-vf-vlan-antispoof=1
+
+  By default its off, when it turn on, will have below impact:
+
+  Multi-driver is not supported since some global register is changed in DPDK driver
+  during init which is no expected by kernel driver.
+
+  Unicast / Multicase promiscuous mode can not be configured separately. So, function
+  ``rte_pmd_i40e_set_vf_unicast_promics`` and ``rte_pmd_i40e_set_vf_multicast_promisc``
+  will fail and new funciton rte_pmd_i40e_set_vf_promics is introduced as a coarse-grain
+  API.
+
+  VLAN anti-spoof and Mac anti-spoof are always enable/disable together.
+  (``rte_eth_set_vf_mac_anti_spoof`` and ``rte_eth_set_vf_vlan_anti_spoof`` now do the
+  same thing).
+
+  When VLAN/MAC anti-spoof is turn on, vlan tag will be added to vlan promisc table, so 
+  in the rx path, mac address match will be ignored, only vlan will be matched.
+
 - ``Support VF Port Representor`` (default ``not enabled``)
 
   The i40e PF PMD supports the creation of VF port representors for the control
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index f0c17a439..486124dfa 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -327,7 +327,7 @@ static int i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
 static int i40e_dev_get_dcb_info(struct rte_eth_dev *dev,
 				  struct rte_eth_dcb_info *dcb_info);
 static int i40e_dev_sync_phy_type(struct i40e_hw *hw);
-static void i40e_configure_registers(struct i40e_hw *hw);
+static void i40e_configure_registers(struct rte_eth_dev *dev);
 static void i40e_hw_init(struct rte_eth_dev *dev);
 static int i40e_config_qinq(struct i40e_hw *hw, struct i40e_vsi *vsi);
 static enum i40e_status_code i40e_aq_del_mirror_rule(struct i40e_hw *hw,
@@ -1097,45 +1097,54 @@ i40e_init_queue_region_conf(struct rte_eth_dev *dev)
 	memset(info, 0, sizeof(struct i40e_queue_regions));
 }
 
-#define ETH_I40E_SUPPORT_MULTI_DRIVER	"support-multi-driver"
+#define ETH_I40E_SUPPORT_MULTI_DRIVER		"support-multi-driver"
+#define ETH_I40E_SUPPORT_VF_VLAN_ANTI_SPOOF	"support-vf-vlan-antispoof"
 
 static int
-i40e_parse_multi_drv_handler(__rte_unused const char *key,
-			       const char *value,
-			       void *opaque)
+i40e_parse_config_handler(__rte_unused const char *key,
+			  const char *value,
+			  void *opaque)
 {
 	struct i40e_pf *pf;
-	unsigned long support_multi_driver;
+	unsigned long flag;
 	char *end;
 
 	pf = (struct i40e_pf *)opaque;
 
 	errno = 0;
-	support_multi_driver = strtoul(value, &end, 10);
+	flag = strtoul(value, &end, 10);
 	if (errno != 0 || end == value || *end != 0) {
 		PMD_DRV_LOG(WARNING, "Wrong global configuration");
 		return -(EINVAL);
 	}
 
-	if (support_multi_driver == 1 || support_multi_driver == 0)
-		pf->support_multi_driver = (bool)support_multi_driver;
-	else
-		PMD_DRV_LOG(WARNING, "%s must be 1 or 0,",
-			    "enable global configuration by default."
-			    ETH_I40E_SUPPORT_MULTI_DRIVER);
+	if (flag == 1 || flag == 0) {
+		if (!strcmp(ETH_I40E_SUPPORT_MULTI_DRIVER, key))
+			pf->support_multi_driver = (bool)flag;
+		else if (!strcmp(ETH_I40E_SUPPORT_VF_VLAN_ANTI_SPOOF, key))
+			pf->support_vf_vlan_antispoof = (bool)flag;
+	} else {
+		PMD_DRV_LOG(WARNING, "%s must be 1 or 0, use default config 0",
+			    key);
+	}
+
 	return 0;
 }
 
 static int
-i40e_support_multi_driver(struct rte_eth_dev *dev)
+i40e_parse_device_args(struct rte_eth_dev *dev)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	static const char *const valid_keys[] = {
-		ETH_I40E_SUPPORT_MULTI_DRIVER, NULL};
+		ETH_I40E_SUPPORT_MULTI_DRIVER,
+		ETH_I40E_SUPPORT_VF_VLAN_ANTI_SPOOF,
+		NULL};
 	struct rte_kvargs *kvlist;
 
 	/* Enable global configuration by default */
 	pf->support_multi_driver = false;
+	/* vlan antispoof is not supported by default */
+	pf->support_vf_vlan_antispoof = false;
 
 	if (!dev->device->devargs)
 		return 0;
@@ -1150,7 +1159,18 @@ i40e_support_multi_driver(struct rte_eth_dev *dev)
 			    ETH_I40E_SUPPORT_MULTI_DRIVER);
 
 	if (rte_kvargs_process(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER,
-			       i40e_parse_multi_drv_handler, pf) < 0) {
+			       i40e_parse_config_handler, pf) < 0) {
+		rte_kvargs_free(kvlist);
+		return -EINVAL;
+	}
+
+	if (rte_kvargs_count(kvlist, ETH_I40E_SUPPORT_VF_VLAN_ANTI_SPOOF) > 1)
+		PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only "
+			    "the first invalid or last valid one is used !",
+			    ETH_I40E_SUPPORT_VF_VLAN_ANTI_SPOOF);
+
+	if (rte_kvargs_process(kvlist, ETH_I40E_SUPPORT_VF_VLAN_ANTI_SPOOF,
+			       i40e_parse_config_handler, pf) < 0) {
 		rte_kvargs_free(kvlist);
 		return -EINVAL;
 	}
@@ -1236,8 +1256,12 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
 	hw->bus.func = pci_dev->addr.function;
 	hw->adapter_stopped = 0;
 
-	/* Check if need to support multi-driver */
-	i40e_support_multi_driver(dev);
+	/* check multi driver and vlan anti-spoof in devargs */
+	i40e_parse_device_args(dev);
+
+	/* vf vlan anti spoof is conflict with multi driver support */
+	if (pf->support_multi_driver && pf->support_vf_vlan_antispoof)
+		return -ENOTSUP;
 
 	/* Make sure all is clean before doing PF reset */
 	i40e_clear_hw(hw);
@@ -1316,7 +1340,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
 	 * registers. Note that the workaround can be removed when it is fixed
 	 * in firmware in the future.
 	 */
-	i40e_configure_registers(hw);
+	i40e_configure_registers(dev);
 
 	/* Get hw capabilities */
 	ret = i40e_get_cap(hw);
@@ -2436,6 +2460,13 @@ i40e_dev_promiscuous_enable(struct rte_eth_dev *dev)
 	struct i40e_vsi *vsi = pf->main_vsi;
 	int status;
 
+	if (pf->support_vf_vlan_antispoof) {
+		status = i40e_aq_set_default_vsi(hw, vsi->seid, NULL);
+		if (status != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to enable promiscuous");
+		return;
+	}
+
 	status = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
 						     true, NULL, true);
 	if (status != I40E_SUCCESS)
@@ -2456,6 +2487,13 @@ i40e_dev_promiscuous_disable(struct rte_eth_dev *dev)
 	struct i40e_vsi *vsi = pf->main_vsi;
 	int status;
 
+	if (pf->support_vf_vlan_antispoof) {
+		status = i40e_aq_clear_default_vsi(hw, vsi->seid, NULL);
+		if (status != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to disable promiscuous");
+		return;
+	}
+
 	status = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
 						     false, NULL, true);
 	if (status != I40E_SUCCESS)
@@ -10006,8 +10044,11 @@ i40e_dev_sync_phy_type(struct i40e_hw *hw)
 }
 
 static void
-i40e_configure_registers(struct i40e_hw *hw)
+i40e_configure_registers(struct rte_eth_dev *dev)
 {
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
 	static struct {
 		uint32_t addr;
 		uint64_t val;
@@ -10076,6 +10117,21 @@ i40e_configure_registers(struct i40e_hw *hw)
 		PMD_DRV_LOG(DEBUG, "Write 0x%"PRIx64" to the address of "
 			"0x%"PRIx32, reg_table[i].val, reg_table[i].addr);
 	}
+
+	if (pf->support_vf_vlan_antispoof) {
+		/**
+		 * To enable vlan antispoof, we need write some undocumented
+		 * glboal registers, cast below spell to trigger the magic.
+		 */
+		i40e_aq_debug_write_register(hw, 0x00269624, 0xa0C38886, NULL);
+		i40e_aq_debug_write_register(hw, 0x00269EA4, 0x00003FE0, NULL);
+		i40e_aq_debug_write_register(hw, 0x002696A4, 0xA0C18886, NULL);
+		i40e_aq_debug_write_register(hw, 0x00269EE4, 0x0FFF1FFF, NULL);
+		i40e_aq_debug_write_register(hw, 0x00269F24, 0x00008000, NULL);
+		i40e_aq_debug_write_register(hw, 0x00269BE8, 0x07000200, NULL);
+		i40e_aq_debug_write_register(hw, 0x0026CDC8, 0x01010000, NULL);
+		i40e_aq_debug_write_register(hw, 0x0026CE08, 0x013F0000, NULL);
+	}
 }
 
 #define I40E_VSI_TSR(_i)            (0x00050800 + ((_i) * 4))
@@ -12390,4 +12446,5 @@ i40e_init_log(void)
 
 RTE_PMD_REGISTER_PARAM_STRING(net_i40e,
 			      QUEUE_NUM_PER_VF_ARG "=1|2|4|8|16"
-			      ETH_I40E_SUPPORT_MULTI_DRIVER "=1");
+			      ETH_I40E_SUPPORT_MULTI_DRIVER "=1"
+			      ETH_I40E_SUPPORT_VF_VLAN_ANTI_SPOOF "=1");
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 12c0645a7..b06d6051b 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -960,6 +960,7 @@ struct i40e_pf {
 	bool qinq_replace_flag;  /* QINQ filter replace is done */
 	struct i40e_tm_conf tm_conf;
 	bool support_multi_driver; /* 1 - support multiple driver */
+	bool support_vf_vlan_antispoof; /* 1 - support vf's vlan antispoof */
 
 	/* Dynamic Device Personalization */
 	bool gtp_support; /* 1 - support GTP-C and GTP-U */
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index dd3962d38..cb6dac10a 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -1009,15 +1009,31 @@ i40e_pf_host_process_cmd_config_promisc_mode(
 
 	if (promisc->flags & FLAG_VF_UNICAST_PROMISC)
 		unicast = TRUE;
-	ret = i40e_aq_set_vsi_unicast_promiscuous(hw,
-			vf->vsi->seid, unicast, NULL, true);
-	if (ret != I40E_SUCCESS)
-		goto send_msg;
-
 	if (promisc->flags & FLAG_VF_MULTICAST_PROMISC)
 		multicast = TRUE;
-	ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vf->vsi->seid,
-						multicast, NULL);
+
+	if (vf->pf->support_vf_vlan_antispoof) {
+		if (unicast && multicast)
+			ret = i40e_aq_set_default_vsi(hw, vf->vsi->seid, NULL);
+		else if (!unicast && !multicast)
+			ret = i40e_aq_clear_default_vsi(hw,
+							vf->vsi->seid,
+							NULL);
+		else
+			ret = I40E_ERR_DEVICE_NOT_SUPPORTED;
+
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR,
+				    "Failed to enable/disable promiscuous");
+	} else {
+		ret = i40e_aq_set_vsi_unicast_promiscuous(hw,
+				vf->vsi->seid, unicast, NULL, true);
+		if (ret != I40E_SUCCESS)
+			goto send_msg;
+
+		ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vf->vsi->seid,
+							multicast, NULL);
+	}
 
 send_msg:
 	i40e_pf_host_send_msg_to_vf(vf,
diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c
index e5e4c44ba..171bdc82c 100644
--- a/drivers/net/i40e/rte_pmd_i40e.c
+++ b/drivers/net/i40e/rte_pmd_i40e.c
@@ -37,36 +37,71 @@ rte_pmd_i40e_ping_vfs(uint16_t port, uint16_t vf)
 	return 0;
 }
 
-int
-rte_pmd_i40e_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on)
+static int
+set_vlan_promisc(struct i40e_hw *hw,
+		 uint16_t seid,
+		 uint16_t vid,
+		 bool enable)
 {
-	struct rte_eth_dev *dev;
-	struct i40e_pf *pf;
-	struct i40e_vsi *vsi;
-	struct i40e_hw *hw;
-	struct i40e_vsi_context ctxt;
-	int ret;
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+	i40e_fill_default_direct_cmd_desc(&desc,
+	i40e_aqc_opc_set_vsi_promiscuous_modes);
 
-	dev = &rte_eth_devices[port];
+	if (enable)
+		cmd->promiscuous_flags = CPU_TO_LE16(0x8011);
 
-	if (!is_i40e_supported(dev))
-		return -ENOTSUP;
+	cmd->valid_flags = CPU_TO_LE16(0x8011);
+	cmd->seid = CPU_TO_LE16(seid);
+	cmd->vlan_tag = CPU_TO_LE16(vid | 0x8000);
 
-	pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	return i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
+}
 
-	if (vf_id >= pf->vf_num || !pf->vfs) {
-		PMD_DRV_LOG(ERR, "Invalid argument.");
-		return -EINVAL;
-	}
+static int
+set_all_vlan_promisc(struct i40e_vsi *vsi, uint8_t enable)
+{
+	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+	uint32_t j, k;
+	uint16_t vlan_id;
+	int ret;
 
-	vsi = pf->vfs[vf_id].vsi;
-	if (!vsi) {
-		PMD_DRV_LOG(ERR, "Invalid VSI.");
-		return -EINVAL;
+	for (j = 0; j < I40E_VFTA_SIZE; j++) {
+		if (!vsi->vfta[j])
+			continue;
+
+		for (k = 0; k < I40E_UINT32_BIT_SIZE; k++) {
+			if (!(vsi->vfta[j] & (1 << k)))
+				continue;
+
+			vlan_id = j * I40E_UINT32_BIT_SIZE + k;
+				if (!vlan_id)
+					continue;
+
+			ret = set_vlan_promisc(hw, vsi->seid, vlan_id, enable);
+			if (ret != I40E_SUCCESS) {
+				PMD_DRV_LOG(ERR,
+					"Failed to set vlan antispoof: vid=%d",
+					vlan_id);
+				return ret;
+			}
+		}
 	}
 
+	return I40E_SUCCESS;
+}
+
+static int
+_i40e_set_vf_mac_anti_spoof(struct i40e_pf *pf,
+			    struct i40e_vsi *vsi,
+			    uint8_t on)
+{
+	struct i40e_hw *hw;
+	struct i40e_vsi_context ctxt;
+	int ret;
+
 	/* Check if it has been already on or off */
 	if (vsi->info.valid_sections &
 		rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SECURITY_VALID)) {
@@ -88,6 +123,11 @@ rte_pmd_i40e_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on)
 	else
 		vsi->info.sec_flags &= ~I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK;
 
+	if (pf->support_vf_vlan_antispoof) {
+		vsi->vlan_anti_spoof_on = on;
+		set_all_vlan_promisc(vsi, on);
+	}
+
 	memset(&ctxt, 0, sizeof(ctxt));
 	rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
 	ctxt.seid = vsi->seid;
@@ -103,6 +143,36 @@ rte_pmd_i40e_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on)
 }
 
 int
+rte_pmd_i40e_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_pf *pf;
+	struct i40e_vsi *vsi;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+	if (vf_id >= pf->vf_num || !pf->vfs) {
+		PMD_DRV_LOG(ERR, "Invalid argument.");
+		return -EINVAL;
+	}
+
+	vsi = pf->vfs[vf_id].vsi;
+	if (!vsi) {
+		PMD_DRV_LOG(ERR, "Invalid VSI.");
+		return -EINVAL;
+	}
+
+	return _i40e_set_vf_mac_anti_spoof(pf, vsi, on);
+}
+
+int
 rte_pmd_i40e_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on)
 {
 	struct rte_eth_dev *dev;
@@ -132,6 +202,9 @@ rte_pmd_i40e_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on)
 		return -EINVAL;
 	}
 
+	if (pf->support_vf_vlan_antispoof)
+		return _i40e_set_vf_mac_anti_spoof(pf, vsi, on);
+
 	/* Check if it has been already on or off */
 	if (vsi->vlan_anti_spoof_on == on)
 		return 0; /* already on or off */
@@ -384,6 +457,53 @@ rte_pmd_i40e_set_tx_loopback(uint16_t port, uint8_t on)
 }
 
 int
+rte_pmd_i40e_set_vf_promisc(uint16_t port, uint16_t vf_id, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_pf *pf;
+	struct i40e_vsi *vsi;
+	struct i40e_hw *hw;
+	int ret;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+	if (vf_id >= pf->vf_num || !pf->vfs) {
+		PMD_DRV_LOG(ERR, "Invalid argument.");
+		return -EINVAL;
+	}
+
+	vsi = pf->vfs[vf_id].vsi;
+	if (!vsi) {
+		PMD_DRV_LOG(ERR, "Invalid VSI.");
+		return -EINVAL;
+	}
+
+	if (!pf->support_vf_vlan_antispoof)
+		return -ENOTSUP;
+
+	hw = I40E_VSI_TO_HW(vsi);
+
+	if (on)
+		ret = i40e_aq_set_default_vsi(hw, vsi->seid, NULL);
+	else
+		ret = i40e_aq_clear_default_vsi(hw, vsi->seid, NULL);
+
+	if (ret != I40E_SUCCESS) {
+		ret = -ENOTSUP;
+		PMD_DRV_LOG(ERR, "Failed to set promiscuous mode");
+	}
+
+	return ret;
+}
+
+int
 rte_pmd_i40e_set_vf_unicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on)
 {
 	struct rte_eth_dev *dev;
@@ -412,6 +532,9 @@ rte_pmd_i40e_set_vf_unicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on)
 		return -EINVAL;
 	}
 
+	if (pf->support_vf_vlan_antispoof)
+		return -ENOTSUP;
+
 	hw = I40E_VSI_TO_HW(vsi);
 
 	ret = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
@@ -453,6 +576,9 @@ rte_pmd_i40e_set_vf_multicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on)
 		return -EINVAL;
 	}
 
+	if (pf->support_vf_vlan_antispoof)
+		return -ENOTSUP;
+
 	hw = I40E_VSI_TO_HW(vsi);
 
 	ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid,
@@ -840,6 +966,9 @@ int rte_pmd_i40e_set_vf_vlan_filter(uint16_t port, uint16_t vlan_id,
 				ret = i40e_vsi_add_vlan(vsi, vlan_id);
 			else
 				ret = i40e_vsi_delete_vlan(vsi, vlan_id);
+			if (vsi->vlan_anti_spoof_on)
+				ret = set_vlan_promisc(hw, vsi->seid,
+						       vlan_id, on);
 		}
 	}
 
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index be4a6024a..9e99d60b4 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -395,6 +395,26 @@ int rte_pmd_i40e_set_tx_loopback(uint16_t port,
 				 uint8_t on);
 
 /**
+ * Enable/Disable VF promiscuous mode.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to set.
+ * @param on
+ *    1 - Enable.
+ *    0 - Disable.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENOTSUP) if support-vf-anti-spoof is off.
+ */
+int rte_pmd_i40e_set_vf_promisc(uint16_t port,
+				uint16_t vf_id,
+				uint8_t on);
+
+/**
  * Enable/Disable VF unicast promiscuous mode.
  *
  * @param port
@@ -408,6 +428,7 @@ int rte_pmd_i40e_set_tx_loopback(uint16_t port,
  *   - (0) if successful.
  *   - (-ENODEV) if *port* invalid.
  *   - (-EINVAL) if bad parameter.
+ *   - (-ENOTSUP) if support-vf-anti-spoof is on.
  */
 int rte_pmd_i40e_set_vf_unicast_promisc(uint16_t port,
 					uint16_t vf_id,
@@ -427,6 +448,7 @@ int rte_pmd_i40e_set_vf_unicast_promisc(uint16_t port,
  *   - (0) if successful.
  *   - (-ENODEV) if *port* invalid.
  *   - (-EINVAL) if bad parameter.
+ *   - (-ENOTSUP) if support-vf-anti-spoof is on.
  */
 int rte_pmd_i40e_set_vf_multicast_promisc(uint16_t port,
 					  uint16_t vf_id,
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index cccd5768c..3df095c73 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -64,4 +64,10 @@ DPDK_18.02 {
 
 	rte_pmd_i40e_inset_get;
 	rte_pmd_i40e_inset_set;
-} DPDK_17.11;
\ No newline at end of file
+} DPDK_17.11;
+
+DPDK_18.08 {
+	global:
+
+	rte_pmd_i40e_set_vf_promisc;
+} DPDK_18.2;
-- 
2.13.6

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

* Re: [dpdk-dev] [PATCH 1/2] net/i40e: improve VF VLAN performance
  2018-05-28  2:01 ` [dpdk-dev] [PATCH 1/2] net/i40e: improve " Qi Zhang
@ 2018-06-20  6:23   ` Xing, Beilei
  0 siblings, 0 replies; 4+ messages in thread
From: Xing, Beilei @ 2018-06-20  6:23 UTC (permalink / raw)
  To: Zhang, Qi Z; +Cc: dev, Zhang, Helin, Wang, Liang-min, Zhang, Qi Z



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Qi Zhang
> Sent: Monday, May 28, 2018 10:01 AM
> To: Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Zhang, Helin <helin.zhang@intel.com>; Wang, Liang-min
> <liang-min.wang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>
> Subject: [dpdk-dev] [PATCH 1/2] net/i40e: improve VF VLAN performance
> 
> Add vlan to vlan prune table cost additinal firmware cycle that cause
> significent performance downgrade. This patch remove related code when

The patch looks OK for me, just some typo: 
additinal->additional
Significent-> significant

> enable vlan filter, the side effect is vlan anti spoof will not work, following
> patch will deal with it.
> 
> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> ---

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

end of thread, other threads:[~2018-06-20  6:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-28  2:01 [dpdk-dev] [PATCH 0/2] improve i40e VF VLAN performance Qi Zhang
2018-05-28  2:01 ` [dpdk-dev] [PATCH 1/2] net/i40e: improve " Qi Zhang
2018-06-20  6:23   ` Xing, Beilei
2018-05-28  2:01 ` [dpdk-dev] [PATCH 2/2] net/i40e: enable VF VLAN antispoof Qi Zhang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).