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,
	Jacob Keller <jacob.e.keller@intel.com>,
	Dan Nowlin <dan.nowlin@intel.com>,
	Brett Creeley <brett.creeley@intel.com>,
	Qiming Yang <qiming.yang@intel.com>
Subject: [dpdk-stable] [PATCH 20.11 v2 05/18] net/ice/base: support checking double VLAN mode
Date: Fri, 11 Jun 2021 15:15:17 +0800	[thread overview]
Message-ID: <20210611071531.48411-6-haiyue.wang@intel.com> (raw)
In-Reply-To: <20210611071531.48411-1-haiyue.wang@intel.com>

From: Qi Zhang <qi.z.zhang@intel.com>

[ upstream commit 67285599c9f413c59118379d1f7162031ea6acdc ]

If a driver wants to configure double VLAN mode (DVM) it needs to
first check if the DDP supports DVM. To do this the driver needs to read
the package metadata section via the upload section AQ (0x04C1).

If the DDP doesn't support configuring double VLAN mode (DVM), then
there is nothing to do regarding configuring the VLAN mode of the
device.

The set_svm() or set_dvm() ops should only be called if the current
configuration supports configuring the VLAN mode of the device.

Suggested-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Dan Nowlin <dan.nowlin@intel.com>
Signed-off-by: Brett Creeley <brett.creeley@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
Acked-by: Qiming Yang <qiming.yang@intel.com>
---
 drivers/net/ice/base/ice_bitops.h    | 45 ++++++++++++++++
 drivers/net/ice/base/ice_flex_pipe.c | 63 +++++++++++++++++++++-
 drivers/net/ice/base/ice_flex_pipe.h | 11 ++++
 drivers/net/ice/base/ice_flex_type.h | 26 ++++++++++
 drivers/net/ice/base/ice_vlan_mode.c | 78 ++++++++++++++++++++++++++++
 5 files changed, 221 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ice/base/ice_bitops.h b/drivers/net/ice/base/ice_bitops.h
index 39548967cc..b786bf7a18 100644
--- a/drivers/net/ice/base/ice_bitops.h
+++ b/drivers/net/ice/base/ice_bitops.h
@@ -449,4 +449,49 @@ ice_cmp_bitmap(ice_bitmap_t *bmp1, ice_bitmap_t *bmp2, u16 size)
 	return true;
 }
 
+/**
+ * ice_bitmap_from_array32 - copies u32 array source into bitmap destination
+ * @dst: the destination bitmap
+ * @src: the source u32 array
+ * @size: size of the bitmap (in bits)
+ *
+ * This function copies the src bitmap stored in an u32 array into the dst
+ * bitmap stored as an ice_bitmap_t.
+ */
+static inline void
+ice_bitmap_from_array32(ice_bitmap_t *dst, u32 *src, u16 size)
+{
+	u32 remaining_bits, i;
+
+#define BITS_PER_U32	(sizeof(u32) * BITS_PER_BYTE)
+	/* clear bitmap so we only have to set when iterating */
+	ice_zero_bitmap(dst, size);
+
+	for (i = 0; i < (u32)(size / BITS_PER_U32); i++) {
+		u32 bit_offset = i * BITS_PER_U32;
+		u32 entry = src[i];
+		u32 j;
+
+		for (j = 0; j < BITS_PER_U32; j++) {
+			if (entry & BIT(j))
+				ice_set_bit((u16)(j + bit_offset), dst);
+		}
+	}
+
+	/* still need to check the leftover bits (i.e. if size isn't evenly
+	 * divisible by BITS_PER_U32
+	 **/
+	remaining_bits = size % BITS_PER_U32;
+	if (remaining_bits) {
+		u32 bit_offset = i * BITS_PER_U32;
+		u32 entry = src[i];
+		u32 j;
+
+		for (j = 0; j < remaining_bits; j++) {
+			if (entry & BIT(j))
+				ice_set_bit((u16)(j + bit_offset), dst);
+		}
+	}
+}
+
 #endif /* _ICE_BITOPS_H_ */
diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index 6c7f83899d..e511b50a00 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -807,6 +807,28 @@ ice_aq_download_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,
 	return status;
 }
 
+/**
+ * ice_aq_upload_section
+ * @hw: pointer to the hardware structure
+ * @pkg_buf: the package buffer which will receive the section
+ * @buf_size: the size of the package buffer
+ * @cd: pointer to command details structure or NULL
+ *
+ * Upload Section (0x0C41)
+ */
+enum ice_status
+ice_aq_upload_section(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,
+		      u16 buf_size, struct ice_sq_cd *cd)
+{
+	struct ice_aq_desc desc;
+
+	ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
+	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_upload_section);
+	desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
+
+	return ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd);
+}
+
 /**
  * ice_aq_update_pkg
  * @hw: pointer to the hardware structure
@@ -1800,7 +1822,7 @@ void ice_init_prof_result_bm(struct ice_hw *hw)
  *
  * Frees a package buffer
  */
-static void ice_pkg_buf_free(struct ice_hw *hw, struct ice_buf_build *bld)
+void ice_pkg_buf_free(struct ice_hw *hw, struct ice_buf_build *bld)
 {
 	ice_free(hw, bld);
 }
@@ -1899,6 +1921,43 @@ ice_pkg_buf_alloc_section(struct ice_buf_build *bld, u32 type, u16 size)
 	return NULL;
 }
 
+/**
+ * ice_pkg_buf_alloc_single_section
+ * @hw: pointer to the HW structure
+ * @type: the section type value
+ * @size: the size of the section to reserve (in bytes)
+ * @section: returns pointer to the section
+ *
+ * Allocates a package buffer with a single section.
+ * Note: all package contents must be in Little Endian form.
+ */
+struct ice_buf_build *
+ice_pkg_buf_alloc_single_section(struct ice_hw *hw, u32 type, u16 size,
+				 void **section)
+{
+	struct ice_buf_build *buf;
+
+	if (!section)
+		return NULL;
+
+	buf = ice_pkg_buf_alloc(hw);
+	if (!buf)
+		return NULL;
+
+	if (ice_pkg_buf_reserve_section(buf, 1))
+		goto ice_pkg_buf_alloc_single_section_err;
+
+	*section = ice_pkg_buf_alloc_section(buf, type, size);
+	if (!*section)
+		goto ice_pkg_buf_alloc_single_section_err;
+
+	return buf;
+
+ice_pkg_buf_alloc_single_section_err:
+	ice_pkg_buf_free(hw, buf);
+	return NULL;
+}
+
 /**
  * ice_pkg_buf_get_active_sections
  * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())
@@ -1926,7 +1985,7 @@ static u16 ice_pkg_buf_get_active_sections(struct ice_buf_build *bld)
  *
  * Return a pointer to the buffer's header
  */
-static struct ice_buf *ice_pkg_buf(struct ice_buf_build *bld)
+struct ice_buf *ice_pkg_buf(struct ice_buf_build *bld)
 {
 	if (!bld)
 		return NULL;
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index 214c7a2837..d4679cc940 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -38,6 +38,12 @@ ice_init_prof_result_bm(struct ice_hw *hw);
 enum ice_status
 ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt,
 		   ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list);
+enum ice_status
+ice_pkg_buf_unreserve_section(struct ice_buf_build *bld, u16 count);
+u16 ice_pkg_buf_get_free_space(struct ice_buf_build *bld);
+enum ice_status
+ice_aq_upload_section(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,
+		      u16 buf_size, struct ice_sq_cd *cd);
 bool
 ice_get_open_tunnel_port(struct ice_hw *hw, enum ice_tunnel_type type,
 			 u16 *port);
@@ -75,6 +81,11 @@ void ice_clear_hw_tbls(struct ice_hw *hw);
 void ice_free_hw_tbls(struct ice_hw *hw);
 enum ice_status
 ice_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 id);
+struct ice_buf_build *
+ice_pkg_buf_alloc_single_section(struct ice_hw *hw, u32 type, u16 size,
+				 void **section);
+struct ice_buf *ice_pkg_buf(struct ice_buf_build *bld);
+void ice_pkg_buf_free(struct ice_hw *hw, struct ice_buf_build *bld);
 
 enum ice_status
 ice_set_key(u8 *key, u16 size, u8 *val, u8 *upd, u8 *dc, u8 *nm, u16 off,
diff --git a/drivers/net/ice/base/ice_flex_type.h b/drivers/net/ice/base/ice_flex_type.h
index 1dd57baccd..169476369b 100644
--- a/drivers/net/ice/base/ice_flex_type.h
+++ b/drivers/net/ice/base/ice_flex_type.h
@@ -786,4 +786,30 @@ enum ice_prof_type {
 	ICE_PROF_TUN_ALL = 0xE,
 	ICE_PROF_ALL = 0xFF,
 };
+
+/* Number of bits/bytes contained in meta init entry. Note, this should be a
+ * multiple of 32 bits.
+ */
+#define ICE_META_INIT_BITS	192
+#define ICE_META_INIT_DW_CNT	(ICE_META_INIT_BITS / (sizeof(__le32) * \
+				 BITS_PER_BYTE))
+
+/* The meta init Flag field starts at this bit */
+#define ICE_META_FLAGS_ST		123
+
+/* The entry and bit to check for Double VLAN Mode (DVM) support */
+#define ICE_META_VLAN_MODE_ENTRY	0
+#define ICE_META_FLAG_VLAN_MODE		60
+#define ICE_META_VLAN_MODE_BIT		(ICE_META_FLAGS_ST + \
+					 ICE_META_FLAG_VLAN_MODE)
+
+struct ice_meta_init_entry {
+	__le32 bm[ICE_META_INIT_DW_CNT];
+};
+
+struct ice_meta_init_section {
+	__le16 count;
+	__le16 offset;
+	struct ice_meta_init_entry entry[1];
+};
 #endif /* _ICE_FLEX_TYPE_H_ */
diff --git a/drivers/net/ice/base/ice_vlan_mode.c b/drivers/net/ice/base/ice_vlan_mode.c
index 603de74e25..c4e7a40295 100644
--- a/drivers/net/ice/base/ice_vlan_mode.c
+++ b/drivers/net/ice/base/ice_vlan_mode.c
@@ -5,6 +5,81 @@
 #include "ice_vlan_mode.h"
 #include "ice_common.h"
 
+/**
+ * ice_pkg_get_supported_vlan_mode - chk if DDP supports Double VLAN mode (DVM)
+ * @hw: pointer to the HW struct
+ * @dvm: output variable to determine if DDP supports DVM(true) or SVM(false)
+ */
+static enum ice_status
+ice_pkg_get_supported_vlan_mode(struct ice_hw *hw, bool *dvm)
+{
+	u16 meta_init_size = sizeof(struct ice_meta_init_section);
+	struct ice_meta_init_section *sect;
+	struct ice_buf_build *bld;
+	enum ice_status status;
+
+	/* if anything fails, we assume there is no DVM support */
+	*dvm = false;
+
+	bld = ice_pkg_buf_alloc_single_section(hw,
+					       ICE_SID_RXPARSER_METADATA_INIT,
+					       meta_init_size, (void **)&sect);
+	if (!bld)
+		return ICE_ERR_NO_MEMORY;
+
+	/* only need to read a single section */
+	sect->count = CPU_TO_LE16(1);
+	sect->offset = CPU_TO_LE16(ICE_META_VLAN_MODE_ENTRY);
+
+	status = ice_aq_upload_section(hw,
+				       (struct ice_buf_hdr *)ice_pkg_buf(bld),
+				       ICE_PKG_BUF_SIZE, NULL);
+	if (!status) {
+		ice_declare_bitmap(entry, ICE_META_INIT_BITS);
+		u32 arr[ICE_META_INIT_DW_CNT];
+		u16 i;
+
+		/* convert to host bitmap format */
+		for (i = 0; i < ICE_META_INIT_DW_CNT; i++)
+			arr[i] = LE32_TO_CPU(sect->entry[0].bm[i]);
+
+		ice_bitmap_from_array32(entry, arr, (u16)ICE_META_INIT_BITS);
+
+		/* check if DVM is supported */
+		*dvm = ice_is_bit_set(entry, ICE_META_VLAN_MODE_BIT);
+	}
+
+	ice_pkg_buf_free(hw, bld);
+
+	return status;
+}
+
+/**
+ * ice_is_dvm_supported - check if double VLAN mode is supported based on DDP
+ * @hw: pointer to the hardware structure
+ *
+ * Returns true if DVM is supported and false if only SVM is supported. This
+ * function should only be called while the global config lock is held and after
+ * the package has been successfully downloaded.
+ */
+static bool ice_is_dvm_supported(struct ice_hw *hw)
+{
+	enum ice_status status;
+	bool pkg_supports_dvm;
+
+	status = ice_pkg_get_supported_vlan_mode(hw, &pkg_supports_dvm);
+	if (status) {
+		ice_debug(hw, ICE_DBG_PKG, "Failed to get supported VLAN mode, err %d\n",
+			  status);
+		return false;
+	}
+
+	if (!pkg_supports_dvm)
+		return false;
+
+	return true;
+}
+
 /**
  * ice_set_svm - set single VLAN mode
  * @hw: pointer to the HW structure
@@ -34,6 +109,9 @@ enum ice_status ice_set_vlan_mode(struct ice_hw *hw)
 {
 	enum ice_status status = ICE_ERR_NOT_IMPL;
 
+	if (!ice_is_dvm_supported(hw))
+		return ICE_SUCCESS;
+
 	if (hw->vlan_mode_ops.set_dvm)
 		status = hw->vlan_mode_ops.set_dvm(hw);
 
-- 
2.32.0


  parent reply	other threads:[~2021-06-11  7:37 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   ` Haiyue Wang [this message]
2021-06-11  7:15   ` [dpdk-stable] [PATCH 20.11 v2 06/18] net/ice/base: support configuring device in double VLAN mode 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   ` [dpdk-stable] [PATCH 20.11 v2 16/18] net/ice: fix VLAN 0 adding based on VLAN mode Haiyue Wang
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-6-haiyue.wang@intel.com \
    --to=haiyue.wang@intel.com \
    --cc=bluca@debian.org \
    --cc=brett.creeley@intel.com \
    --cc=christian.ehrhardt@canonical.com \
    --cc=dan.nowlin@intel.com \
    --cc=jacob.e.keller@intel.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).