patches for DPDK stable branches
 help / color / mirror / Atom feed
From: Haiyue Wang <haiyue.wang@intel.com>
To: stable@dpdk.org
Cc: bluca@debian.org, xuemingl@nvidia.com, thomas@monjalon.net,
	christian.ehrhardt@canonical.com, ktraynor@redhat.com,
	qi.z.zhang@intel.com, haiyue.wang@intel.com,
	Qiming Yang <qiming.yang@intel.com>
Subject: [dpdk-stable] [PATCH 20.11 v2 16/18] net/ice: fix VLAN 0 adding based on VLAN mode
Date: Fri, 11 Jun 2021 15:15:28 +0800	[thread overview]
Message-ID: <20210611071531.48411-17-haiyue.wang@intel.com> (raw)
In-Reply-To: <20210611071531.48411-1-haiyue.wang@intel.com>

[ upstream commit 295b34f55b001bceb27d9177b55326ccda49351b ]

In Single VLAN Mode, single VLAN filters via ICE_SW_LKUP_VLAN are based
on the inner VLAN ID, so the VLAN TPID (i.e. 0x8100 or 0x888a8) doesn't
matter.

In Double VLAN Mode, outer/single VLAN filters via ICE_SW_LKUP_VLAN are
based on the outer/single VLAN ID + VLAN TPID.

For both modes, adding a VLAN 0 + no VLAN TPID filter to handle untagged
traffic when VLAN pruning is enabled. Also, this handles VLAN 0 priority
tagged traffic in Single VLAN Mode, since the VLAN TPID is not part of
filtering.

If Double VLAN Mode is enabled then an explicit VLAN 0 + VLAN TPID filter
needs to be added to allow VLAN 0 priority tagged traffic in DVM, since
the VLAN TPID is part of filtering.

Fixes: 14e7a4b37b4f ("net/ice/base: support configuring device in double VLAN mode")

Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
---
 drivers/net/ice/ice_ethdev.c | 136 +++++++++++++++++++++++++++++------
 drivers/net/ice/ice_ethdev.h |  10 ++-
 2 files changed, 123 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 9071bd5d4f..5a1e775718 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -944,12 +944,13 @@ ice_remove_mac_filter(struct ice_vsi *vsi, struct rte_ether_addr *mac_addr)
 
 /* Find out specific VLAN filter */
 static struct ice_vlan_filter *
-ice_find_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
+ice_find_vlan_filter(struct ice_vsi *vsi, struct ice_vlan *vlan)
 {
 	struct ice_vlan_filter *f;
 
 	TAILQ_FOREACH(f, &vsi->vlan_list, next) {
-		if (vlan_id == f->vlan_info.vlan_id)
+		if (vlan->tpid == f->vlan_info.vlan.tpid &&
+		    vlan->vid == f->vlan_info.vlan.vid)
 			return f;
 	}
 
@@ -957,7 +958,7 @@ ice_find_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
 }
 
 static int
-ice_add_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
+ice_add_vlan_filter(struct ice_vsi *vsi, struct ice_vlan *vlan)
 {
 	struct ice_fltr_list_entry *v_list_itr = NULL;
 	struct ice_vlan_filter *f;
@@ -965,13 +966,13 @@ ice_add_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
 	struct ice_hw *hw;
 	int ret = 0;
 
-	if (!vsi || vlan_id > RTE_ETHER_MAX_VLAN_ID)
+	if (!vsi || vlan->vid > RTE_ETHER_MAX_VLAN_ID)
 		return -EINVAL;
 
 	hw = ICE_VSI_TO_HW(vsi);
 
 	/* If it's added and configured, return. */
-	f = ice_find_vlan_filter(vsi, vlan_id);
+	f = ice_find_vlan_filter(vsi, vlan);
 	if (f) {
 		PMD_DRV_LOG(INFO, "This VLAN filter already exists.");
 		return 0;
@@ -988,7 +989,9 @@ ice_add_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
 		ret = -ENOMEM;
 		goto DONE;
 	}
-	v_list_itr->fltr_info.l_data.vlan.vlan_id = vlan_id;
+	v_list_itr->fltr_info.l_data.vlan.vlan_id = vlan->vid;
+	v_list_itr->fltr_info.l_data.vlan.tpid = vlan->tpid;
+	v_list_itr->fltr_info.l_data.vlan.tpid_valid = true;
 	v_list_itr->fltr_info.src_id = ICE_SRC_ID_VSI;
 	v_list_itr->fltr_info.fltr_act = ICE_FWD_TO_VSI;
 	v_list_itr->fltr_info.lkup_type = ICE_SW_LKUP_VLAN;
@@ -1012,7 +1015,8 @@ ice_add_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
 		ret = -ENOMEM;
 		goto DONE;
 	}
-	f->vlan_info.vlan_id = vlan_id;
+	f->vlan_info.vlan.tpid = vlan->tpid;
+	f->vlan_info.vlan.vid = vlan->vid;
 	TAILQ_INSERT_TAIL(&vsi->vlan_list, f, next);
 	vsi->vlan_num++;
 
@@ -1024,7 +1028,7 @@ ice_add_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
 }
 
 static int
-ice_remove_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
+ice_remove_vlan_filter(struct ice_vsi *vsi, struct ice_vlan *vlan)
 {
 	struct ice_fltr_list_entry *v_list_itr = NULL;
 	struct ice_vlan_filter *f;
@@ -1032,17 +1036,13 @@ ice_remove_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
 	struct ice_hw *hw;
 	int ret = 0;
 
-	/**
-	 * Vlan 0 is the generic filter for untagged packets
-	 * and can't be removed.
-	 */
-	if (!vsi || vlan_id == 0 || vlan_id > RTE_ETHER_MAX_VLAN_ID)
+	if (!vsi || vlan->vid > RTE_ETHER_MAX_VLAN_ID)
 		return -EINVAL;
 
 	hw = ICE_VSI_TO_HW(vsi);
 
 	/* Can't find it, return an error */
-	f = ice_find_vlan_filter(vsi, vlan_id);
+	f = ice_find_vlan_filter(vsi, vlan);
 	if (!f)
 		return -EINVAL;
 
@@ -1055,7 +1055,9 @@ ice_remove_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
 		goto DONE;
 	}
 
-	v_list_itr->fltr_info.l_data.vlan.vlan_id = vlan_id;
+	v_list_itr->fltr_info.l_data.vlan.vlan_id = vlan->vid;
+	v_list_itr->fltr_info.l_data.vlan.tpid = vlan->tpid;
+	v_list_itr->fltr_info.l_data.vlan.tpid_valid = true;
 	v_list_itr->fltr_info.src_id = ICE_SRC_ID_VSI;
 	v_list_itr->fltr_info.fltr_act = ICE_FWD_TO_VSI;
 	v_list_itr->fltr_info.lkup_type = ICE_SW_LKUP_VLAN;
@@ -1106,7 +1108,7 @@ ice_remove_all_mac_vlan_filters(struct ice_vsi *vsi)
 		return 0;
 
 	TAILQ_FOREACH_SAFE(v_f, &vsi->vlan_list, next, temp) {
-		ret = ice_remove_vlan_filter(vsi, v_f->vlan_info.vlan_id);
+		ret = ice_remove_vlan_filter(vsi, &v_f->vlan_info.vlan);
 		if (ret != ICE_SUCCESS) {
 			ret = -EINVAL;
 			goto DONE;
@@ -1463,6 +1465,16 @@ ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type)
 		vsi_ctx.info.inner_vlan_flags |= ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING;
 		vsi_ctx.info.q_opt_rss = ICE_AQ_VSI_Q_OPT_RSS_LUT_PF |
 					 ICE_AQ_VSI_Q_OPT_RSS_TPLZ;
+		if (ice_is_dvm_ena(hw)) {
+			vsi_ctx.info.outer_vlan_flags =
+				(ICE_AQ_VSI_OUTER_VLAN_TX_MODE_ALL <<
+				 ICE_AQ_VSI_OUTER_VLAN_TX_MODE_S) &
+				ICE_AQ_VSI_OUTER_VLAN_TX_MODE_M;
+			vsi_ctx.info.outer_vlan_flags |=
+				(ICE_AQ_VSI_OUTER_TAG_VLAN_8100 <<
+				 ICE_AQ_VSI_OUTER_TAG_TYPE_S) &
+				ICE_AQ_VSI_OUTER_TAG_TYPE_M;
+		}
 
 		/* FDIR */
 		cfg = ICE_AQ_VSI_PROP_SECURITY_VALID |
@@ -1696,10 +1708,11 @@ ice_load_pkg_type(struct ice_hw *hw)
 	else
 		package_type = ICE_PKG_TYPE_UNKNOWN;
 
-	PMD_INIT_LOG(NOTICE, "Active package is: %d.%d.%d.%d, %s",
+	PMD_INIT_LOG(NOTICE, "Active package is: %d.%d.%d.%d, %s (%s VLAN mode)",
 		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
 		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
-		hw->active_pkg_name);
+		hw->active_pkg_name,
+		ice_is_dvm_ena(hw) ? "double" : "single");
 
 	return package_type;
 }
@@ -3898,19 +3911,27 @@ static int
 ice_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 {
 	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct ice_vlan vlan = ICE_VLAN(RTE_ETHER_TYPE_VLAN, vlan_id);
 	struct ice_vsi *vsi = pf->main_vsi;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 
+	/**
+	 * Vlan 0 is the generic filter for untagged packets
+	 * and can't be removed or added by user.
+	 */
+	if (vlan_id == 0)
+		return 0;
+
 	if (on) {
-		ret = ice_add_vlan_filter(vsi, vlan_id);
+		ret = ice_add_vlan_filter(vsi, &vlan);
 		if (ret < 0) {
 			PMD_DRV_LOG(ERR, "Failed to add vlan filter");
 			return -EINVAL;
 		}
 	} else {
-		ret = ice_remove_vlan_filter(vsi, vlan_id);
+		ret = ice_remove_vlan_filter(vsi, &vlan);
 		if (ret < 0) {
 			PMD_DRV_LOG(ERR, "Failed to remove vlan filter");
 			return -EINVAL;
@@ -3920,6 +3941,77 @@ ice_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 	return 0;
 }
 
+/* In Single VLAN Mode (SVM), single VLAN filters via ICE_SW_LKUP_VLAN are
+ * based on the inner VLAN ID, so the VLAN TPID (i.e. 0x8100 or 0x888a8)
+ * doesn't matter. In Double VLAN Mode (DVM), outer/single VLAN filters via
+ * ICE_SW_LKUP_VLAN are based on the outer/single VLAN ID + VLAN TPID.
+ *
+ * For both modes add a VLAN 0 + no VLAN TPID filter to handle untagged traffic
+ * when VLAN pruning is enabled. Also, this handles VLAN 0 priority tagged
+ * traffic in SVM, since the VLAN TPID isn't part of filtering.
+ *
+ * If DVM is enabled then an explicit VLAN 0 + VLAN TPID filter needs to be
+ * added to allow VLAN 0 priority tagged traffic in DVM, since the VLAN TPID is
+ * part of filtering.
+ */
+static int
+ice_vsi_add_vlan_zero(struct ice_vsi *vsi)
+{
+	struct ice_vlan vlan;
+	int err;
+
+	vlan = ICE_VLAN(0, 0);
+	err = ice_add_vlan_filter(vsi, &vlan);
+	if (err) {
+		PMD_DRV_LOG(DEBUG, "Failed to add VLAN ID 0");
+		return err;
+	}
+
+	/* in SVM both VLAN 0 filters are identical */
+	if (!ice_is_dvm_ena(&vsi->adapter->hw))
+		return 0;
+
+	vlan = ICE_VLAN(RTE_ETHER_TYPE_VLAN, 0);
+	err = ice_add_vlan_filter(vsi, &vlan);
+	if (err) {
+		PMD_DRV_LOG(DEBUG, "Failed to add VLAN ID 0 in double VLAN mode");
+		return err;
+	}
+
+	return 0;
+}
+
+/*
+ * Delete the VLAN 0 filters in the same manner that they were added in
+ * ice_vsi_add_vlan_zero.
+ */
+static int
+ice_vsi_del_vlan_zero(struct ice_vsi *vsi)
+{
+	struct ice_vlan vlan;
+	int err;
+
+	vlan = ICE_VLAN(0, 0);
+	err = ice_remove_vlan_filter(vsi, &vlan);
+	if (err) {
+		PMD_DRV_LOG(DEBUG, "Failed to remove VLAN ID 0");
+		return err;
+	}
+
+	/* in SVM both VLAN 0 filters are identical */
+	if (!ice_is_dvm_ena(&vsi->adapter->hw))
+		return 0;
+
+	vlan = ICE_VLAN(RTE_ETHER_TYPE_VLAN, 0);
+	err = ice_remove_vlan_filter(vsi, &vlan);
+	if (err) {
+		PMD_DRV_LOG(DEBUG, "Failed to remove VLAN ID 0 in double VLAN mode");
+		return err;
+	}
+
+	return 0;
+}
+
 /* Configure vlan filter on or off */
 static int
 ice_vsi_config_vlan_filter(struct ice_vsi *vsi, bool on)
@@ -3956,9 +4048,9 @@ ice_vsi_config_vlan_filter(struct ice_vsi *vsi, bool on)
 
 	/* consist with other drivers, allow untagged packet when vlan filter on */
 	if (on)
-		ret = ice_add_vlan_filter(vsi, 0);
+		ret = ice_vsi_add_vlan_zero(vsi);
 	else
-		ret = ice_remove_vlan_filter(vsi, 0);
+		ret = ice_vsi_del_vlan_zero(vsi);
 
 	return 0;
 }
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 2b03c59671..f96625f43a 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -167,11 +167,19 @@ struct ice_mac_filter {
 	struct ice_mac_filter_info mac_info;
 };
 
+struct ice_vlan {
+	uint16_t tpid;
+	uint16_t vid;
+};
+
+#define ICE_VLAN(tpid, vid) \
+	((struct ice_vlan){ tpid, vid })
+
 /**
  * VLAN filter structure
  */
 struct ice_vlan_filter_info {
-	uint16_t vlan_id;
+	struct ice_vlan vlan;
 };
 
 TAILQ_HEAD(ice_vlan_filter_list, ice_vlan_filter);
-- 
2.32.0


  parent reply	other threads:[~2021-06-11  7:38 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-11  6:58 [PATCH 20.11 v1 00/18] Backport the new VLAN design for Intel ice PMD Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 01/18] net/ice/base: align add VSI and update VSI AQ command buffer Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 02/18] net/ice/base: add interface to support configuring VLAN mode Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 03/18] net/ice/base: fix outer VLAN related macro Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 04/18] net/ice/base: add VLAN TPID for VLAN filters Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 05/18] net/ice/base: support checking double VLAN mode Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 06/18] net/ice/base: support configuring device in " Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 07/18] net/ice/base: do not set VLAN mode in DCF mode Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 08/18] net/ice/base: update boost TCAM for DVM Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 09/18] net/ice/base: change protocol ID for VLAN in DVM Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 10/18] net/ice/base: refactor post DDP download VLAN mode config Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 11/18] net/ice/base: log if DDP/FW do not support QinQ Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 12/18] net/ice/base: add ethertype offset for QinQ dummy packet Haiyue Wang
2021-06-11  6:58 ` [PATCH 20.11 v1 13/18] net/ice/base: add inner VLAN protocol type for QinQ filter Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 14/18] net/ice/base: fix QinQ PPPoE dummy packet selection Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 15/18] net/ice: fix VLAN strip for double VLAN Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 16/18] net/ice: fix VLAN 0 adding based on VLAN mode Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 17/18] net/ice: enable QinQ filter for switch Haiyue Wang
2021-06-11  6:58 ` [dpdk-stable] [PATCH 20.11 v1 18/18] net/ice: update QinQ switch filter handling Haiyue Wang
2021-06-11  7:15 ` [dpdk-stable] [PATCH 20.11 v2 00/18] Backport the new VLAN design for Intel ice PMD Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 01/18] net/ice/base: align add VSI and update VSI AQ command buffer Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 02/18] net/ice/base: add interface to support configuring VLAN mode Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 03/18] net/ice/base: fix outer VLAN related macro Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 04/18] net/ice/base: add VLAN TPID for VLAN filters Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 05/18] net/ice/base: support checking double VLAN mode Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 06/18] net/ice/base: support configuring device in " Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 07/18] net/ice/base: do not set VLAN mode in DCF mode Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 08/18] net/ice/base: update boost TCAM for DVM Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 09/18] net/ice/base: change protocol ID for VLAN in DVM Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 10/18] net/ice/base: refactor post DDP download VLAN mode config Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 11/18] net/ice/base: log if DDP/FW do not support QinQ Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 12/18] net/ice/base: add ethertype offset for QinQ dummy packet Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 13/18] net/ice/base: add inner VLAN protocol type for QinQ filter Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 14/18] net/ice/base: fix QinQ PPPoE dummy packet selection Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 15/18] net/ice: fix VLAN strip for double VLAN Haiyue Wang
2021-06-11  7:15   ` Haiyue Wang [this message]
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 17/18] net/ice: enable QinQ filter for switch Haiyue Wang
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 18/18] net/ice: update QinQ switch filter handling Haiyue Wang
2021-06-16 15:47   ` [dpdk-stable] [PATCH 20.11 v2 00/18] Backport the new VLAN design for Intel ice PMD Luca Boccassi
2021-06-17  1:16     ` Wang, Haiyue
2021-06-17  8:53       ` Xueming(Steven) Li
2021-06-17 10:04         ` Kevin Traynor
2021-06-18  3:22           ` Wang, Haiyue
2021-06-18 10:12             ` Kevin Traynor
2021-06-18 11:46               ` Wang, Haiyue
2021-06-21  8:28             ` Thomas Monjalon
2021-06-21  8:34               ` Wang, Haiyue
2021-06-21  8:59                 ` Kevin Traynor
2021-06-21 10:28               ` Kevin Traynor
2021-06-22  1:41                 ` Wang, Haiyue
2021-06-18  1:56         ` Wang, Haiyue
2021-06-20 13:47           ` Xueming(Steven) Li
2021-06-21  1:35             ` Wang, Haiyue

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210611071531.48411-17-haiyue.wang@intel.com \
    --to=haiyue.wang@intel.com \
    --cc=bluca@debian.org \
    --cc=christian.ehrhardt@canonical.com \
    --cc=ktraynor@redhat.com \
    --cc=qi.z.zhang@intel.com \
    --cc=qiming.yang@intel.com \
    --cc=stable@dpdk.org \
    --cc=thomas@monjalon.net \
    --cc=xuemingl@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).