ice: virtchnl rss hena support
authorMd Fahad Iqbal Polash <md.fahad.iqbal.polash@intel.com>
Thu, 10 Nov 2022 13:03:53 +0000 (14:03 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 14 Nov 2022 10:44:38 +0000 (10:44 +0000)
Add support for 2 virtchnl msgs:
VIRTCHNL_OP_SET_RSS_HENA
VIRTCHNL_OP_GET_RSS_HENA_CAPS

The first one allows VFs to clear all previously programmed
RSS configuration and customize it. The second one returns
the RSS HENA bits allowed by the hardware.

Introduce ice_err_to_virt_err which converts kernel
specific errors to virtchnl errors.

Signed-off-by: Md Fahad Iqbal Polash <md.fahad.iqbal.polash@intel.com>
Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/intel/ice/ice_vf_lib.c
drivers/net/ethernet/intel/ice/ice_vf_lib_private.h
drivers/net/ethernet/intel/ice/ice_virtchnl.c
drivers/net/ethernet/intel/ice/ice_virtchnl.h

index 1c51778..375eb64 100644 (file)
@@ -700,6 +700,30 @@ void ice_dis_vf_qs(struct ice_vf *vf)
 }
 
 /**
+ * ice_err_to_virt_err - translate errors for VF return code
+ * @err: error return code
+ */
+enum virtchnl_status_code ice_err_to_virt_err(int err)
+{
+       switch (err) {
+       case 0:
+               return VIRTCHNL_STATUS_SUCCESS;
+       case -EINVAL:
+       case -ENODEV:
+               return VIRTCHNL_STATUS_ERR_PARAM;
+       case -ENOMEM:
+               return VIRTCHNL_STATUS_ERR_NO_MEMORY;
+       case -EALREADY:
+       case -EBUSY:
+       case -EIO:
+       case -ENOSPC:
+               return VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR;
+       default:
+               return VIRTCHNL_STATUS_ERR_NOT_SUPPORTED;
+       }
+}
+
+/**
  * ice_check_vf_init - helper to check if VF init complete
  * @vf: the pointer to the VF to check
  */
index 15887e7..9c8ef2b 100644 (file)
@@ -25,6 +25,7 @@
 
 void ice_dis_vf_qs(struct ice_vf *vf);
 int ice_check_vf_init(struct ice_vf *vf);
+enum virtchnl_status_code ice_err_to_virt_err(int err);
 struct ice_port_info *ice_vf_get_port_info(struct ice_vf *vf);
 int ice_vsi_apply_spoofchk(struct ice_vsi *vsi, bool enable);
 bool ice_is_vf_trusted(struct ice_vf *vf);
index c1fa943..ec90e59 100644 (file)
@@ -2482,6 +2482,108 @@ error_param:
 }
 
 /**
+ * ice_vc_get_rss_hena - return the RSS HENA bits allowed by the hardware
+ * @vf: pointer to the VF info
+ */
+static int ice_vc_get_rss_hena(struct ice_vf *vf)
+{
+       enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
+       struct virtchnl_rss_hena *vrh = NULL;
+       int len = 0, ret;
+
+       if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
+               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+               goto err;
+       }
+
+       if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) {
+               dev_err(ice_pf_to_dev(vf->pf), "RSS not supported by PF\n");
+               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+               goto err;
+       }
+
+       len = sizeof(struct virtchnl_rss_hena);
+       vrh = kzalloc(len, GFP_KERNEL);
+       if (!vrh) {
+               v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
+               len = 0;
+               goto err;
+       }
+
+       vrh->hena = ICE_DEFAULT_RSS_HENA;
+err:
+       /* send the response back to the VF */
+       ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_RSS_HENA_CAPS, v_ret,
+                                   (u8 *)vrh, len);
+       kfree(vrh);
+       return ret;
+}
+
+/**
+ * ice_vc_set_rss_hena - set RSS HENA bits for the VF
+ * @vf: pointer to the VF info
+ * @msg: pointer to the msg buffer
+ */
+static int ice_vc_set_rss_hena(struct ice_vf *vf, u8 *msg)
+{
+       struct virtchnl_rss_hena *vrh = (struct virtchnl_rss_hena *)msg;
+       enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
+       struct ice_pf *pf = vf->pf;
+       struct ice_vsi *vsi;
+       struct device *dev;
+       int status;
+
+       dev = ice_pf_to_dev(pf);
+
+       if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
+               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+               goto err;
+       }
+
+       if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) {
+               dev_err(dev, "RSS not supported by PF\n");
+               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+               goto err;
+       }
+
+       vsi = ice_get_vf_vsi(vf);
+       if (!vsi) {
+               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+               goto err;
+       }
+
+       /* clear all previously programmed RSS configuration to allow VF drivers
+        * the ability to customize the RSS configuration and/or completely
+        * disable RSS
+        */
+       status = ice_rem_vsi_rss_cfg(&pf->hw, vsi->idx);
+       if (status && !vrh->hena) {
+               /* only report failure to clear the current RSS configuration if
+                * that was clearly the VF's intention (i.e. vrh->hena = 0)
+                */
+               v_ret = ice_err_to_virt_err(status);
+               goto err;
+       } else if (status) {
+               /* allow the VF to update the RSS configuration even on failure
+                * to clear the current RSS confguration in an attempt to keep
+                * RSS in a working state
+                */
+               dev_warn(dev, "Failed to clear the RSS configuration for VF %u\n",
+                        vf->vf_id);
+       }
+
+       if (vrh->hena) {
+               status = ice_add_avf_rss_cfg(&pf->hw, vsi->idx, vrh->hena);
+               v_ret = ice_err_to_virt_err(status);
+       }
+
+       /* send the response to the VF */
+err:
+       return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_SET_RSS_HENA, v_ret,
+                                    NULL, 0);
+}
+
+/**
  * ice_vc_query_rxdid - query RXDID supported by DDP package
  * @vf: pointer to VF info
  *
@@ -3572,6 +3674,8 @@ static const struct ice_virtchnl_ops ice_virtchnl_dflt_ops = {
        .add_vlan_msg = ice_vc_add_vlan_msg,
        .remove_vlan_msg = ice_vc_remove_vlan_msg,
        .query_rxdid = ice_vc_query_rxdid,
+       .get_rss_hena = ice_vc_get_rss_hena,
+       .set_rss_hena_msg = ice_vc_set_rss_hena,
        .ena_vlan_stripping = ice_vc_ena_vlan_stripping,
        .dis_vlan_stripping = ice_vc_dis_vlan_stripping,
        .handle_rss_cfg_msg = ice_vc_handle_rss_cfg,
@@ -3707,6 +3811,8 @@ static const struct ice_virtchnl_ops ice_virtchnl_repr_ops = {
        .add_vlan_msg = ice_vc_add_vlan_msg,
        .remove_vlan_msg = ice_vc_remove_vlan_msg,
        .query_rxdid = ice_vc_query_rxdid,
+       .get_rss_hena = ice_vc_get_rss_hena,
+       .set_rss_hena_msg = ice_vc_set_rss_hena,
        .ena_vlan_stripping = ice_vc_ena_vlan_stripping,
        .dis_vlan_stripping = ice_vc_dis_vlan_stripping,
        .handle_rss_cfg_msg = ice_vc_handle_rss_cfg,
@@ -3850,6 +3956,12 @@ error_handler:
        case VIRTCHNL_OP_GET_SUPPORTED_RXDIDS:
                err = ops->query_rxdid(vf);
                break;
+       case VIRTCHNL_OP_GET_RSS_HENA_CAPS:
+               err = ops->get_rss_hena(vf);
+               break;
+       case VIRTCHNL_OP_SET_RSS_HENA:
+               err = ops->set_rss_hena_msg(vf, msg);
+               break;
        case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
                err = ops->ena_vlan_stripping(vf);
                break;
index 4867a92..b454654 100644 (file)
@@ -37,6 +37,8 @@ struct ice_virtchnl_ops {
        int (*add_vlan_msg)(struct ice_vf *vf, u8 *msg);
        int (*remove_vlan_msg)(struct ice_vf *vf, u8 *msg);
        int (*query_rxdid)(struct ice_vf *vf);
+       int (*get_rss_hena)(struct ice_vf *vf);
+       int (*set_rss_hena_msg)(struct ice_vf *vf, u8 *msg);
        int (*ena_vlan_stripping)(struct ice_vf *vf);
        int (*dis_vlan_stripping)(struct ice_vf *vf);
        int (*handle_rss_cfg_msg)(struct ice_vf *vf, u8 *msg, bool add);