From: Wenjun Wu <wenjun1.wu@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH 17/22] net/ice: fix VLAN 0 adding based on VLAN mode
Date: Tue, 3 Aug 2021 16:38:12 +0800 [thread overview]
Message-ID: <20210803083817.1243796-18-wenjun1.wu@intel.com> (raw)
In-Reply-To: <20210803083817.1243796-1-wenjun1.wu@intel.com>
From: Haiyue Wang <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 1d7e5ffbc4..60793f99c6 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;
}
@@ -3921,19 +3934,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;
@@ -3943,6 +3964,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)
@@ -3979,9 +4071,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 c1b432c1ef..2710a575ef 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.25.1
next prev parent reply other threads:[~2021-08-03 8:58 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-03 8:37 [dpdk-dev] [PATCH 00/22] backport feature support to DPDK 20.11 Wenjun Wu
2021-08-03 8:37 ` [dpdk-dev] [PATCH 01/22] net/ice: support RSS hash for IP fragment Wenjun Wu
2021-08-03 8:37 ` [dpdk-dev] [PATCH 02/22] net/ice/base: align add VSI and update VSI AQ command buffer Wenjun Wu
2021-08-03 8:37 ` [dpdk-dev] [PATCH 03/22] net/ice/base: add interface to support configuring VLAN mode Wenjun Wu
2021-08-03 8:37 ` [dpdk-dev] [PATCH 04/22] net/ice/base: fix outer VLAN related macro Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 05/22] net/ice/base: add VLAN TPID for VLAN filters Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 06/22] net/ice/base: support checking double VLAN mode Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 07/22] net/ice/base: support configuring device in " Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 08/22] net/ice/base: do not set VLAN mode in DCF mode Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 09/22] net/ice/base: update boost TCAM for DVM Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 10/22] net/ice/base: change protocol ID for VLAN in DVM Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 11/22] net/ice/base: refactor post DDP download VLAN mode config Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 12/22] net/ice/base: log if DDP/FW do not support QinQ Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 13/22] net/ice/base: add ethertype offset for QinQ dummy packet Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 14/22] net/ice/base: add inner VLAN protocol type for QinQ filter Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 15/22] net/ice/base: fix QinQ PPPoE dummy packet selection Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 16/22] net/ice: fix VLAN strip for double VLAN Wenjun Wu
2021-08-03 8:38 ` Wenjun Wu [this message]
2021-08-03 8:38 ` [dpdk-dev] [PATCH 18/22] net/ice: enable QinQ filter for switch Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 19/22] net/ice: update QinQ switch filter handling Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 20/22] net/ice/base: fix wrong ptype bitmap for IP fragment Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 21/22] net/ice: support flow priority for DCF switch filter Wenjun Wu
2021-08-03 8:38 ` [dpdk-dev] [PATCH 22/22] net/ice/base: add priority check of matching recipe Wenjun Wu
2021-08-04 1:20 ` [dpdk-dev] [PATCH 00/22] backport feature support to DPDK 20.11 Min Hu (Connor)
2021-08-04 7:54 ` Thomas Monjalon
2021-08-04 8:48 ` Min Hu (Connor)
2021-08-04 9:00 ` Thomas Monjalon
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=20210803083817.1243796-18-wenjun1.wu@intel.com \
--to=wenjun1.wu@intel.com \
--cc=dev@dpdk.org \
/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).