Mon, Jun 03, 2024 at 02:31:46PM CEST, wojciech.dre...@intel.com wrote: >From: Pawel Kaminski <pawel.kamin...@intel.com> > >Add support for driver-specific devlink local_forwarding param. >Supported values are "enabled", "disabled" and "prioritized". >Default configuration is set to "enabled". > >Add documentation in networking/devlink/ice.rst. > >In previous generations of Intel NICs the transmit scheduler was only >limited by PCIe bandwidth when scheduling/assigning hairpin-badwidth >between VFs. Changes to E810 HW design introduced scheduler limitation, >so that available hairpin-bandwidth is bound to external port speed. >In order to address this limitation and enable NFV services such as >"service chaining" a knob to adjust the scheduler config was created. >Driver can send a configuration message to the FW over admin queue and >internal FW logic will reconfigure HW to prioritize and add more BW to >VF to VF traffic. As end result for example 10G port will no longer limit >hairpin-badwith to 10G and much higher speeds can be achieved. > >Devlink local_forwarding param set to "prioritized" enables higher >hairpin-badwitdh on related PFs. Configuration is applicable only to >8x10G and 4x25G cards. > >Changing local_forwarding configuration will trigger CORER reset in >order to take effect. > >Example command to change current value: >devlink dev param set pci/0000:b2:00.3 name local_forwarding \ > value prioritized \ > cmode runtime > >Co-developed-by: Michal Wilczynski <michal.wilczyn...@intel.com> >Signed-off-by: Michal Wilczynski <michal.wilczyn...@intel.com> >Reviewed-by: Przemek Kitszel <przemyslaw.kits...@intel.com> >Signed-off-by: Pawel Kaminski <pawel.kamin...@intel.com> >Signed-off-by: Wojciech Drewek <wojciech.dre...@intel.com> >--- >v2: Extend documentation >v3: rename loopback to local_forwarding >--- > Documentation/networking/devlink/ice.rst | 23 ++++ > .../net/ethernet/intel/ice/devlink/devlink.c | 126 ++++++++++++++++++ > .../net/ethernet/intel/ice/ice_adminq_cmd.h | 11 +- > drivers/net/ethernet/intel/ice/ice_common.c | 4 + > drivers/net/ethernet/intel/ice/ice_type.h | 1 + > 5 files changed, 164 insertions(+), 1 deletion(-) > >diff --git a/Documentation/networking/devlink/ice.rst >b/Documentation/networking/devlink/ice.rst >index 830c04354222..0eb64bd4710f 100644 >--- a/Documentation/networking/devlink/ice.rst >+++ b/Documentation/networking/devlink/ice.rst >@@ -11,6 +11,7 @@ Parameters > ========== > > .. list-table:: Generic parameters implemented >+ :widths: 5 5 90 > > * - Name > - Mode >@@ -68,6 +69,28 @@ Parameters > > To verify that value has been set: > $ devlink dev param show pci/0000:16:00.0 name tx_scheduling_layers >+.. list-table:: Driver specific parameters implemented >+ :widths: 5 5 90 >+ >+ * - Name >+ - Mode >+ - Description >+ * - ``local_forwarding`` >+ - runtime >+ - Controls loopback behavior by tuning scheduler bandwidth. >+ Supported values are: >+ >+ ``enabled`` - VF to VF traffic is allowed on port >+ >+ ``disabled`` - VF to VF traffic is not allowed on this port >+ >+ ``prioritized`` - VF to VF traffic is prioritized on this port
Does this apply on SFs too? >+ >+ Default value of ``local_forwarding`` parameter is ``enabled``. >+ ``prioritized`` provides ability to adjust VF to VF traffic rate to >increase >+ one port capacity at cost of the another. User needs to disable >+ local forwarding on one of the ports in order have increased capacity >+ on the ``prioritized`` port. > > Info versions > ============= >diff --git a/drivers/net/ethernet/intel/ice/devlink/devlink.c >b/drivers/net/ethernet/intel/ice/devlink/devlink.c >index f774781ab514..810a901d7afd 100644 >--- a/drivers/net/ethernet/intel/ice/devlink/devlink.c >+++ b/drivers/net/ethernet/intel/ice/devlink/devlink.c >@@ -1381,9 +1381,129 @@ ice_devlink_enable_iw_validate(struct devlink >*devlink, u32 id, > return 0; > } > >+#define DEVLINK_LOCAL_FWD_DISABLED_STR "disabled" >+#define DEVLINK_LOCAL_FWD_ENABLED_STR "enabled" >+#define DEVLINK_LOCAL_FWD_PRIORITIZED_STR "prioritized" >+ >+/** >+ * ice_devlink_local_fwd_mode_to_str - Get string for local_fwd mode. >+ * @mode: local forwarding for mode used in port_info struct. >+ * >+ * Return: Mode respective string or "Invalid". >+ */ >+static const char * >+ice_devlink_local_fwd_mode_to_str(enum ice_local_fwd_mode mode) >+{ >+ switch (mode) { >+ case ICE_LOCAL_FWD_MODE_ENABLED: >+ return DEVLINK_LOCAL_FWD_ENABLED_STR; >+ case ICE_LOCAL_FWD_MODE_PRIORITIZED: >+ return DEVLINK_LOCAL_FWD_PRIORITIZED_STR; >+ case ICE_LOCAL_FWD_MODE_DISABLED: >+ return DEVLINK_LOCAL_FWD_DISABLED_STR; >+ } >+ >+ return "Invalid"; >+} >+ >+/** >+ * ice_devlink_local_fwd_str_to_mode - Get local_fwd mode from string name. >+ * @mode_str: local forwarding mode string. >+ * >+ * Return: Mode value or negative number if invalid. >+ */ >+static int ice_devlink_local_fwd_str_to_mode(const char *mode_str) >+{ >+ if (!strcmp(mode_str, DEVLINK_LOCAL_FWD_ENABLED_STR)) >+ return ICE_LOCAL_FWD_MODE_ENABLED; >+ else if (!strcmp(mode_str, DEVLINK_LOCAL_FWD_PRIORITIZED_STR)) >+ return ICE_LOCAL_FWD_MODE_PRIORITIZED; >+ else if (!strcmp(mode_str, DEVLINK_LOCAL_FWD_DISABLED_STR)) >+ return ICE_LOCAL_FWD_MODE_DISABLED; >+ >+ return -EINVAL; >+} >+ >+/** >+ * ice_devlink_local_fwd_get - Get local_fwd parameter. >+ * @devlink: Pointer to the devlink instance. >+ * @id: The parameter ID to set. >+ * @ctx: Context to store the parameter value. >+ * >+ * Return: Zero. >+ */ >+static int ice_devlink_local_fwd_get(struct devlink *devlink, u32 id, >+ struct devlink_param_gset_ctx *ctx) >+{ >+ struct ice_pf *pf = devlink_priv(devlink); >+ struct ice_port_info *pi; >+ const char *mode_str; >+ >+ pi = pf->hw.port_info; >+ mode_str = ice_devlink_local_fwd_mode_to_str(pi->local_fwd_mode); >+ snprintf(ctx->val.vstr, sizeof(ctx->val.vstr), "%s", mode_str); >+ >+ return 0; >+} >+ >+/** >+ * ice_devlink_local_fwd_set - Set local_fwd parameter. >+ * @devlink: Pointer to the devlink instance. >+ * @id: The parameter ID to set. >+ * @ctx: Context to get the parameter value. >+ * @extack: Netlink extended ACK structure. >+ * >+ * Return: Zero. >+ */ >+static int ice_devlink_local_fwd_set(struct devlink *devlink, u32 id, >+ struct devlink_param_gset_ctx *ctx, >+ struct netlink_ext_ack *extack) >+{ >+ int new_local_fwd_mode = >ice_devlink_local_fwd_str_to_mode(ctx->val.vstr); >+ struct ice_pf *pf = devlink_priv(devlink); >+ struct device *dev = ice_pf_to_dev(pf); >+ struct ice_port_info *pi; >+ >+ pi = pf->hw.port_info; >+ if (pi->local_fwd_mode != new_local_fwd_mode) { >+ pi->local_fwd_mode = new_local_fwd_mode; >+ dev_info(dev, "Setting local_fwd to %s\n", ctx->val.vstr); >+ ice_schedule_reset(pf, ICE_RESET_CORER); >+ } >+ >+ return 0; >+} >+ >+/** >+ * ice_devlink_local_fwd_validate - Validate passed local_fwd parameter value. >+ * @devlink: Unused pointer to devlink instance. >+ * @id: The parameter ID to validate. >+ * @val: Value to validate. >+ * @extack: Netlink extended ACK structure. >+ * >+ * Supported values are: >+ * "enabled" - local_fwd is enabled, "disabled" - local_fwd is disabled >+ * "prioritized" - local_fwd traffic is prioritized in scheduling. >+ * >+ * Return: Zero when passed parameter value is supported. Negative value on >+ * error. >+ */ >+static int ice_devlink_local_fwd_validate(struct devlink *devlink, u32 id, >+ union devlink_param_value val, >+ struct netlink_ext_ack *extack) >+{ >+ if (ice_devlink_local_fwd_str_to_mode(val.vstr) < 0) { >+ NL_SET_ERR_MSG_MOD(extack, "Error: Requested value is not >supported."); >+ return -EINVAL; >+ } >+ >+ return 0; >+} >+ > enum ice_param_id { > ICE_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, > ICE_DEVLINK_PARAM_ID_TX_SCHED_LAYERS, >+ ICE_DEVLINK_PARAM_ID_LOCAL_FWD, > }; > > static const struct devlink_param ice_dvl_rdma_params[] = { >@@ -1405,6 +1525,12 @@ static const struct devlink_param >ice_dvl_sched_params[] = { > ice_devlink_tx_sched_layers_get, > ice_devlink_tx_sched_layers_set, > ice_devlink_tx_sched_layers_validate), >+ DEVLINK_PARAM_DRIVER(ICE_DEVLINK_PARAM_ID_LOCAL_FWD, >+ "local_forwarding", DEVLINK_PARAM_TYPE_STRING, >+ BIT(DEVLINK_PARAM_CMODE_RUNTIME), >+ ice_devlink_local_fwd_get, >+ ice_devlink_local_fwd_set, >+ ice_devlink_local_fwd_validate), > }; > > static void ice_devlink_free(void *devlink_ptr) >diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h >b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h >index 621a2ca7093e..9683842f8880 100644 >--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h >+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h >@@ -232,6 +232,13 @@ struct ice_aqc_get_sw_cfg_resp_elem { > #define ICE_AQC_GET_SW_CONF_RESP_IS_VF BIT(15) > }; > >+/* Loopback port parameter mode values. */ >+enum ice_local_fwd_mode { >+ ICE_LOCAL_FWD_MODE_ENABLED = 0, >+ ICE_LOCAL_FWD_MODE_DISABLED = 1, >+ ICE_LOCAL_FWD_MODE_PRIORITIZED = 2, >+}; >+ > /* Set Port parameters, (direct, 0x0203) */ > struct ice_aqc_set_port_params { > __le16 cmd_flags; >@@ -240,7 +247,9 @@ struct ice_aqc_set_port_params { > __le16 swid; > #define ICE_AQC_PORT_SWID_VALID BIT(15) > #define ICE_AQC_PORT_SWID_M 0xFF >- u8 reserved[10]; >+ u8 local_fwd_mode; >+#define ICE_AQC_SET_P_PARAMS_LOCAL_FWD_MODE_VALID BIT(2) >+ u8 reserved[9]; > }; > > /* These resource type defines are used for all switch resource >diff --git a/drivers/net/ethernet/intel/ice/ice_common.c >b/drivers/net/ethernet/intel/ice/ice_common.c >index 9ae61cd8923e..60ad7774812c 100644 >--- a/drivers/net/ethernet/intel/ice/ice_common.c >+++ b/drivers/net/ethernet/intel/ice/ice_common.c >@@ -1086,6 +1086,7 @@ int ice_init_hw(struct ice_hw *hw) > goto err_unroll_cqinit; > } > >+ hw->port_info->local_fwd_mode = ICE_LOCAL_FWD_MODE_ENABLED; > /* set the back pointer to HW */ > hw->port_info->hw = hw; > >@@ -3070,6 +3071,9 @@ ice_aq_set_port_params(struct ice_port_info *pi, bool >double_vlan, > cmd_flags |= ICE_AQC_SET_P_PARAMS_DOUBLE_VLAN_ENA; > cmd->cmd_flags = cpu_to_le16(cmd_flags); > >+ cmd->local_fwd_mode = pi->local_fwd_mode | >+ ICE_AQC_SET_P_PARAMS_LOCAL_FWD_MODE_VALID; >+ > return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); > } > >diff --git a/drivers/net/ethernet/intel/ice/ice_type.h >b/drivers/net/ethernet/intel/ice/ice_type.h >index aac59c85a911..f3e4d8030f43 100644 >--- a/drivers/net/ethernet/intel/ice/ice_type.h >+++ b/drivers/net/ethernet/intel/ice/ice_type.h >@@ -730,6 +730,7 @@ struct ice_port_info { > u16 sw_id; /* Initial switch ID belongs to port */ > u16 pf_vf_num; > u8 port_state; >+ u8 local_fwd_mode; > #define ICE_SCHED_PORT_STATE_INIT 0x0 > #define ICE_SCHED_PORT_STATE_READY 0x1 > u8 lport; >-- >2.40.1 > >