DPDK patches and discussions
 help / color / mirror / Atom feed
From: Qi Zhang <qi.z.zhang@intel.com>
To: qiming.yang@intel.com
Cc: dev@dpdk.org, Qi Zhang <qi.z.zhang@intel.com>,
	Dan Nowlin <dan.nowlin@intel.com>,
	Brett Creeley <brett.creeley@intel.com>,
	Jacob Keller <jacob.e.keller@intel.com>
Subject: [dpdk-dev] [PATCH 17/27] net/ice/base: add functionality to check if DVM is supported
Date: Tue, 15 Dec 2020 14:05:09 +0800	[thread overview]
Message-ID: <20201215060519.302145-18-qi.z.zhang@intel.com> (raw)
In-Reply-To: <20201215060519.302145-1-qi.z.zhang@intel.com>

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.

Signed-off-by: Dan Nowlin <dan.nowlin@intel.com>
Signed-off-by: Brett Creeley <brett.creeley@intel.com>
Suggested-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@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 7d0204fa50..08db7f2c9a 100644
--- a/drivers/net/ice/base/ice_flex_type.h
+++ b/drivers/net/ice/base/ice_flex_type.h
@@ -787,4 +787,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..363354ff3f 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_supports_dvm - determine 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.26.2


  parent reply	other threads:[~2020-12-15  6:07 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-15  6:04 [dpdk-dev] [PATCH 00/27] ice base code update Qi Zhang
2020-12-15  6:04 ` [dpdk-dev] [PATCH 01/27] net/ice/base: modify ptype map for UDP Qi Zhang
2020-12-15  6:04 ` [dpdk-dev] [PATCH 02/27] net/ice/base: increased control queue timeout Qi Zhang
2020-12-15  6:04 ` [dpdk-dev] [PATCH 03/27] net/ice/base: read more security revision options Qi Zhang
2020-12-15  6:04 ` [dpdk-dev] [PATCH 04/27] net/ice/base: refactor interface for flash read Qi Zhang
2020-12-15  6:04 ` [dpdk-dev] [PATCH 05/27] net/ice/base: allow reading inactive flash security revision Qi Zhang
2020-12-15  6:04 ` [dpdk-dev] [PATCH 06/27] net/ice/base: allow reading arbitrary size data with flash read Qi Zhang
2020-12-15  6:04 ` [dpdk-dev] [PATCH 07/27] net/ice/base: read Option ROM combo version from CIVD section Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 08/27] net/ice/base: implement inactive NVM version get Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 09/27] net/ice/base: support GTP filtering via advanced switch filter Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 10/27] net/ice/base: cleanup some macros Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 11/27] net/ice/base: add definitions for FW health status codes Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 12/27] net/ice/base: add function for NVM checksum verification Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 13/27] net/ice/base: add condition to copy module info into memory Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 14/27] net/ice/base: add interface to support configuring VLAN mode Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 15/27] net/ice/base: support VXLAN VNI field in FDIR Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 16/27] net/ice/base: fix incorrect tunnel destroy Qi Zhang
2020-12-15  6:05 ` Qi Zhang [this message]
2020-12-15  6:05 ` [dpdk-dev] [PATCH 18/27] net/ice/base: resend some AQ commands when EBUSY Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 19/27] net/ice/base: change get PHY capability error level Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 20/27] net/ice/base: modify recursive way of adding nodes Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 21/27] net/ice/base: fix for dereference of null pointer Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 22/27] net/ice/base: use Mode 4 to get PHY Abilites Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 23/27] net/ice/base: align macro names to the specification Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 24/27] net/ice/base: add eCPRI over MAC type 0 flow support Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 25/27] net/ice/base: add eCPRI over UDP " Qi Zhang
2021-01-05 16:24   ` Ferruh Yigit
2020-12-15  6:05 ` [dpdk-dev] [PATCH 26/27] net/ice/base: remove unused struct member Qi Zhang
2020-12-15  6:05 ` [dpdk-dev] [PATCH 27/27] net/ice/base: change a structure Qi Zhang
2020-12-24  3:16 ` [dpdk-dev] [PATCH 00/27] ice base code update Yang, Qiming
2020-12-28 10:34   ` Zhang, Qi Z
2021-01-05 16:22     ` Ferruh Yigit

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=20201215060519.302145-18-qi.z.zhang@intel.com \
    --to=qi.z.zhang@intel.com \
    --cc=brett.creeley@intel.com \
    --cc=dan.nowlin@intel.com \
    --cc=dev@dpdk.org \
    --cc=jacob.e.keller@intel.com \
    --cc=qiming.yang@intel.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).