diff mbox series

[03/22] net/ice/base: add interface to support configuring VLAN mode

Message ID 20210803083817.1243796-4-wenjun1.wu@intel.com (mailing list archive)
State Not Applicable, archived
Delegated to: Qi Zhang
Headers show
Series backport feature support to DPDK 20.11 | expand

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Wenjun Wu Aug. 3, 2021, 8:37 a.m. UTC
From: Qi Zhang <qi.z.zhang@intel.com>

[ upstream commit 4e4dc21e450b5860da650d255abb6e17c3e637a9 ]

The VLAN mode of the device has to be configured while the global
configuration lock is held while downloading the DDP, specifically after
the DDP has been downloaded. In order to support this a VLAN mode
interface was added. By default the device will stay in single VLAN
mode (SVM), which is the current implementation. However, this can be
changed by implementing the .set_dvm op.

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_adminq_cmd.h | 23 ++++++++++++++
 drivers/net/ice/base/ice_common.c     | 40 ++++++++++++++++++++++++
 drivers/net/ice/base/ice_common.h     |  4 +++
 drivers/net/ice/base/ice_flex_pipe.c  |  7 +++++
 drivers/net/ice/base/ice_type.h       |  2 ++
 drivers/net/ice/base/ice_vlan_mode.c  | 44 +++++++++++++++++++++++++++
 drivers/net/ice/base/ice_vlan_mode.h  | 32 +++++++++++++++++++
 drivers/net/ice/base/meson.build      |  1 +
 8 files changed, 153 insertions(+)
 create mode 100644 drivers/net/ice/base/ice_vlan_mode.c
 create mode 100644 drivers/net/ice/base/ice_vlan_mode.h
diff mbox series

Patch

diff --git a/drivers/net/ice/base/ice_adminq_cmd.h b/drivers/net/ice/base/ice_adminq_cmd.h
index 91d360be62..eebafee7c7 100644
--- a/drivers/net/ice/base/ice_adminq_cmd.h
+++ b/drivers/net/ice/base/ice_adminq_cmd.h
@@ -227,6 +227,27 @@  struct ice_aqc_get_sw_cfg_resp_elem {
 #define ICE_AQC_GET_SW_CONF_RESP_IS_VF		BIT(15)
 };
 
+/* Set Port parameters, (direct, 0x0203) */
+struct ice_aqc_set_port_params {
+	__le16 cmd_flags;
+#define ICE_AQC_SET_P_PARAMS_SAVE_BAD_PACKETS	BIT(0)
+#define ICE_AQC_SET_P_PARAMS_PAD_SHORT_PACKETS	BIT(1)
+#define ICE_AQC_SET_P_PARAMS_DOUBLE_VLAN_ENA	BIT(2)
+	__le16 bad_frame_vsi;
+#define ICE_AQC_SET_P_PARAMS_VSI_S	0
+#define ICE_AQC_SET_P_PARAMS_VSI_M	(0x3FF << ICE_AQC_SET_P_PARAMS_VSI_S)
+#define ICE_AQC_SET_P_PARAMS_VSI_VALID	BIT(15)
+	__le16 swid;
+#define ICE_AQC_SET_P_PARAMS_SWID_S	0
+#define ICE_AQC_SET_P_PARAMS_SWID_M	(0xFF << ICE_AQC_SET_P_PARAMS_SWID_S)
+#define ICE_AQC_SET_P_PARAMS_LOGI_PORT_ID_S	8
+#define ICE_AQC_SET_P_PARAMS_LOGI_PORT_ID_M	\
+				(0x3F << ICE_AQC_SET_P_PARAMS_LOGI_PORT_ID_S)
+#define ICE_AQC_SET_P_PARAMS_IS_LOGI_PORT	BIT(14)
+#define ICE_AQC_SET_P_PARAMS_SWID_VALID		BIT(15)
+	u8 reserved[10];
+};
+
 /* These resource type defines are used for all switch resource
  * commands where a resource type is required, such as:
  * Get Resource Allocation command (indirect 0x0204)
@@ -2713,6 +2734,7 @@  struct ice_aq_desc {
 		struct ice_aqc_sff_eeprom read_write_sff_param;
 		struct ice_aqc_set_port_id_led set_port_id_led;
 		struct ice_aqc_get_sw_cfg get_sw_conf;
+		struct ice_aqc_set_port_params set_port_params;
 		struct ice_aqc_sw_rules sw_rules;
 		struct ice_aqc_storm_cfg storm_conf;
 		struct ice_aqc_add_get_recipe add_get_recipe;
@@ -2876,6 +2898,7 @@  enum ice_adminq_opc {
 
 	/* internal switch commands */
 	ice_aqc_opc_get_sw_cfg				= 0x0200,
+	ice_aqc_opc_set_port_params			= 0x0203,
 
 	/* Alloc/Free/Get Resources */
 	ice_aqc_opc_get_res_alloc			= 0x0204,
diff --git a/drivers/net/ice/base/ice_common.c b/drivers/net/ice/base/ice_common.c
index 304e55e210..b5f1d8cce5 100644
--- a/drivers/net/ice/base/ice_common.c
+++ b/drivers/net/ice/base/ice_common.c
@@ -830,6 +830,9 @@  enum ice_status ice_init_hw(struct ice_hw *hw)
 	if (status)
 		goto err_unroll_fltr_mgmt_struct;
 	ice_init_lock(&hw->tnl_lock);
+
+	ice_init_vlan_mode_ops(hw);
+
 	return ICE_SUCCESS;
 
 err_unroll_fltr_mgmt_struct:
@@ -2370,6 +2373,43 @@  void ice_clear_pxe_mode(struct ice_hw *hw)
 		ice_aq_clear_pxe_mode(hw);
 }
 
+/**
+ * ice_aq_set_port_params - set physical port parameters.
+ * @pi: pointer to the port info struct
+ * @bad_frame_vsi: defines the VSI to which bad frames are forwarded
+ * @save_bad_pac: if set packets with errors are forwarded to the bad frames VSI
+ * @pad_short_pac: if set transmit packets smaller than 60 bytes are padded
+ * @double_vlan: if set double VLAN is enabled
+ * @cd: pointer to command details structure or NULL
+ *
+ * Set Physical port parameters (0x0203)
+ */
+enum ice_status
+ice_aq_set_port_params(struct ice_port_info *pi, u16 bad_frame_vsi,
+		       bool save_bad_pac, bool pad_short_pac, bool double_vlan,
+		       struct ice_sq_cd *cd)
+
+{
+	struct ice_aqc_set_port_params *cmd;
+	struct ice_hw *hw = pi->hw;
+	struct ice_aq_desc desc;
+	u16 cmd_flags = 0;
+
+	cmd = &desc.params.set_port_params;
+
+	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_port_params);
+	cmd->bad_frame_vsi = CPU_TO_LE16(bad_frame_vsi);
+	if (save_bad_pac)
+		cmd_flags |= ICE_AQC_SET_P_PARAMS_SAVE_BAD_PACKETS;
+	if (pad_short_pac)
+		cmd_flags |= ICE_AQC_SET_P_PARAMS_PAD_SHORT_PACKETS;
+	if (double_vlan)
+		cmd_flags |= ICE_AQC_SET_P_PARAMS_DOUBLE_VLAN_ENA;
+	cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
+
+	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
+}
+
 /**
  * ice_get_link_speed_based_on_phy_type - returns link speed
  * @phy_type_low: lower part of phy_type
diff --git a/drivers/net/ice/base/ice_common.h b/drivers/net/ice/base/ice_common.h
index 8c16c7a024..765dc3054f 100644
--- a/drivers/net/ice/base/ice_common.h
+++ b/drivers/net/ice/base/ice_common.h
@@ -123,6 +123,10 @@  enum ice_status
 ice_aq_send_driver_ver(struct ice_hw *hw, struct ice_driver_ver *dv,
 		       struct ice_sq_cd *cd);
 enum ice_status
+ice_aq_set_port_params(struct ice_port_info *pi, u16 bad_frame_vsi,
+		       bool save_bad_pac, bool pad_short_pac, bool double_vlan,
+		       struct ice_sq_cd *cd);
+enum ice_status
 ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
 		    struct ice_aqc_get_phy_caps_data *caps,
 		    struct ice_sq_cd *cd);
diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index d74fecbf5b..6c7f83899d 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -1006,6 +1006,13 @@  ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
 			break;
 	}
 
+	if (!status) {
+		status = ice_set_vlan_mode(hw);
+		if (status)
+			ice_debug(hw, ICE_DBG_PKG, "Failed to set VLAN mode: err %d\n",
+				  status);
+	}
+
 	ice_release_global_cfg_lock(hw);
 
 	return status;
diff --git a/drivers/net/ice/base/ice_type.h b/drivers/net/ice/base/ice_type.h
index 6b8d44f0b4..996b58b743 100644
--- a/drivers/net/ice/base/ice_type.h
+++ b/drivers/net/ice/base/ice_type.h
@@ -57,6 +57,7 @@ 
 #include "ice_lan_tx_rx.h"
 #include "ice_flex_type.h"
 #include "ice_protocol_type.h"
+#include "ice_vlan_mode.h"
 
 /**
  * ice_is_pow2 - check if integer value is a power of 2
@@ -985,6 +986,7 @@  struct ice_hw {
 	ice_declare_bitmap(fdir_perfect_fltr, ICE_FLTR_PTYPE_MAX);
 	struct ice_lock rss_locks;	/* protect RSS configuration */
 	struct LIST_HEAD_TYPE rss_list_head;
+	struct ice_vlan_mode_ops vlan_mode_ops;
 };
 
 /* Statistics collected by each port, VSI, VEB, and S-channel */
diff --git a/drivers/net/ice/base/ice_vlan_mode.c b/drivers/net/ice/base/ice_vlan_mode.c
new file mode 100644
index 0000000000..603de74e25
--- /dev/null
+++ b/drivers/net/ice/base/ice_vlan_mode.c
@@ -0,0 +1,44 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2001-2020 Intel Corporation
+ */
+
+#include "ice_vlan_mode.h"
+#include "ice_common.h"
+
+/**
+ * ice_set_svm - set single VLAN mode
+ * @hw: pointer to the HW structure
+ */
+static enum ice_status ice_set_svm_dflt(struct ice_hw *hw)
+{
+	ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
+
+	return ice_aq_set_port_params(hw->port_info, 0, false, false, false, NULL);
+}
+
+/**
+ * ice_init_vlan_mode_ops - initialize VLAN mode configuration ops
+ * @hw: pointer to the HW structure
+ */
+void ice_init_vlan_mode_ops(struct ice_hw *hw)
+{
+	hw->vlan_mode_ops.set_dvm = NULL;
+	hw->vlan_mode_ops.set_svm = ice_set_svm_dflt;
+}
+
+/**
+ * ice_set_vlan_mode
+ * @hw: pointer to the HW structure
+ */
+enum ice_status ice_set_vlan_mode(struct ice_hw *hw)
+{
+	enum ice_status status = ICE_ERR_NOT_IMPL;
+
+	if (hw->vlan_mode_ops.set_dvm)
+		status = hw->vlan_mode_ops.set_dvm(hw);
+
+	if (status)
+		return hw->vlan_mode_ops.set_svm(hw);
+
+	return ICE_SUCCESS;
+}
diff --git a/drivers/net/ice/base/ice_vlan_mode.h b/drivers/net/ice/base/ice_vlan_mode.h
new file mode 100644
index 0000000000..1b9db4d36f
--- /dev/null
+++ b/drivers/net/ice/base/ice_vlan_mode.h
@@ -0,0 +1,32 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2001-2020 Intel Corporation
+ */
+
+#ifndef _ICE_VLAN_MODE_H_
+#define _ICE_VLAN_MODE_H_
+
+struct ice_hw;
+
+enum ice_status ice_set_vlan_mode(struct ice_hw *hw);
+void ice_init_vlan_mode_ops(struct ice_hw *hw);
+
+/* This structure defines the VLAN mode configuration interface. It is used to set the VLAN mode.
+ *
+ * Note: These operations will be called while the global configuration lock is held.
+ *
+ * enum ice_status (*set_svm)(struct ice_hw *hw);
+ *	This function is called when the DDP and/or Firmware don't support double VLAN mode (DVM) or
+ *	if the set_dvm op is not implemented and/or returns failure. It will set the device in
+ *	single VLAN mode (SVM).
+ *
+ * enum ice_status (*set_dvm)(struct ice_hw *hw);
+ *	This function is called when the DDP and Firmware support double VLAN mode (DVM). It should
+ *	be implemented to set double VLAN mode. If it fails or remains unimplemented, set_svm will
+ *	be called as a fallback plan.
+ */
+struct ice_vlan_mode_ops {
+	enum ice_status (*set_svm)(struct ice_hw *hw);
+	enum ice_status (*set_dvm)(struct ice_hw *hw);
+};
+
+#endif /* _ICE_VLAN_MODE_H */
diff --git a/drivers/net/ice/base/meson.build b/drivers/net/ice/base/meson.build
index 8f7d4384e7..6483ea0298 100644
--- a/drivers/net/ice/base/meson.build
+++ b/drivers/net/ice/base/meson.build
@@ -13,6 +13,7 @@  sources = [
 	'ice_fdir.c',
 	'ice_acl.c',
 	'ice_acl_ctrl.c',
+	'ice_vlan_mode.c',
 ]
 
 error_cflags = ['-Wno-unused-value',