ice: Refactor promiscuous functions
[platform/kernel/linux-starfive.git] / drivers / net / ethernet / intel / ice / ice_virtchnl_pf.c
index 596d354..8a1a336 100644 (file)
@@ -203,37 +203,6 @@ static int ice_check_vf_init(struct ice_pf *pf, struct ice_vf *vf)
 }
 
 /**
- * ice_err_to_virt_err - translate errors for VF return code
- * @ice_err: error return code
- */
-static enum virtchnl_status_code ice_err_to_virt_err(enum ice_status ice_err)
-{
-       switch (ice_err) {
-       case ICE_SUCCESS:
-               return VIRTCHNL_STATUS_SUCCESS;
-       case ICE_ERR_BAD_PTR:
-       case ICE_ERR_INVAL_SIZE:
-       case ICE_ERR_DEVICE_NOT_SUPPORTED:
-       case ICE_ERR_PARAM:
-       case ICE_ERR_CFG:
-               return VIRTCHNL_STATUS_ERR_PARAM;
-       case ICE_ERR_NO_MEMORY:
-               return VIRTCHNL_STATUS_ERR_NO_MEMORY;
-       case ICE_ERR_NOT_READY:
-       case ICE_ERR_RESET_FAILED:
-       case ICE_ERR_FW_API_VER:
-       case ICE_ERR_AQ_ERROR:
-       case ICE_ERR_AQ_TIMEOUT:
-       case ICE_ERR_AQ_FULL:
-       case ICE_ERR_AQ_NO_WORK:
-       case ICE_ERR_AQ_EMPTY:
-               return VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR;
-       default:
-               return VIRTCHNL_STATUS_ERR_NOT_SUPPORTED;
-       }
-}
-
-/**
  * ice_vc_vf_broadcast - Broadcast a message to all VFs on PF
  * @pf: pointer to the PF structure
  * @v_opcode: operation code
@@ -1255,45 +1224,50 @@ static void ice_clear_vf_reset_trigger(struct ice_vf *vf)
        ice_flush(hw);
 }
 
-/**
- * ice_vf_set_vsi_promisc - set given VF VSI to given promiscuous mode(s)
- * @vf: pointer to the VF info
- * @vsi: the VSI being configured
- * @promisc_m: mask of promiscuous config bits
- * @rm_promisc: promisc flag request from the VF to remove or add filter
- *
- * This function configures VF VSI promiscuous mode, based on the VF requests,
- * for Unicast, Multicast and VLAN
- */
-static enum ice_status
-ice_vf_set_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m,
-                      bool rm_promisc)
+static int
+ice_vf_set_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m)
 {
-       struct ice_pf *pf = vf->pf;
-       enum ice_status status = 0;
-       struct ice_hw *hw;
+       struct ice_hw *hw = &vsi->back->hw;
+       enum ice_status status;
 
-       hw = &pf->hw;
-       if (vsi->num_vlan) {
-               status = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_m,
-                                                 rm_promisc);
-       } else if (vf->port_vlan_info) {
-               if (rm_promisc)
-                       status = ice_clear_vsi_promisc(hw, vsi->idx, promisc_m,
-                                                      vf->port_vlan_info);
-               else
-                       status = ice_set_vsi_promisc(hw, vsi->idx, promisc_m,
-                                                    vf->port_vlan_info);
-       } else {
-               if (rm_promisc)
-                       status = ice_clear_vsi_promisc(hw, vsi->idx, promisc_m,
-                                                      0);
-               else
-                       status = ice_set_vsi_promisc(hw, vsi->idx, promisc_m,
-                                                    0);
+       if (vf->port_vlan_info)
+               status = ice_fltr_set_vsi_promisc(hw, vsi->idx, promisc_m,
+                                                 vf->port_vlan_info & VLAN_VID_MASK);
+       else if (vsi->num_vlan > 1)
+               status = ice_fltr_set_vlan_vsi_promisc(hw, vsi, promisc_m);
+       else
+               status = ice_fltr_set_vsi_promisc(hw, vsi->idx, promisc_m, 0);
+
+       if (status && status != ICE_ERR_ALREADY_EXISTS) {
+               dev_err(ice_pf_to_dev(vsi->back), "enable Tx/Rx filter promiscuous mode on VF-%u failed, error: %s\n",
+                       vf->vf_id, ice_stat_str(status));
+               return ice_status_to_errno(status);
+       }
+
+       return 0;
+}
+
+static int
+ice_vf_clear_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m)
+{
+       struct ice_hw *hw = &vsi->back->hw;
+       enum ice_status status;
+
+       if (vf->port_vlan_info)
+               status = ice_fltr_clear_vsi_promisc(hw, vsi->idx, promisc_m,
+                                                   vf->port_vlan_info & VLAN_VID_MASK);
+       else if (vsi->num_vlan > 1)
+               status = ice_fltr_clear_vlan_vsi_promisc(hw, vsi, promisc_m);
+       else
+               status = ice_fltr_clear_vsi_promisc(hw, vsi->idx, promisc_m, 0);
+
+       if (status && status != ICE_ERR_DOES_NOT_EXIST) {
+               dev_err(ice_pf_to_dev(vsi->back), "disable Tx/Rx filter promiscuous mode on VF-%u failed, error: %s\n",
+                       vf->vf_id, ice_stat_str(status));
+               return ice_status_to_errno(status);
        }
 
-       return status;
+       return 0;
 }
 
 static void ice_vf_clear_counters(struct ice_vf *vf)
@@ -1657,7 +1631,7 @@ bool ice_reset_vf(struct ice_vf *vf, bool is_vflr)
                else
                        promisc_m = ICE_UCAST_PROMISC_BITS;
 
-               if (ice_vf_set_vsi_promisc(vf, vsi, promisc_m, true))
+               if (ice_vf_clear_vsi_promisc(vf, vsi, promisc_m))
                        dev_err(dev, "disabling promiscuous mode failed\n");
        }
 
@@ -3026,10 +3000,10 @@ bool ice_is_any_vf_in_promisc(struct ice_pf *pf)
 static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg)
 {
        enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
-       enum ice_status mcast_status = 0, ucast_status = 0;
        bool rm_promisc, alluni = false, allmulti = false;
        struct virtchnl_promisc_info *info =
            (struct virtchnl_promisc_info *)msg;
+       int mcast_err = 0, ucast_err = 0;
        struct ice_pf *pf = vf->pf;
        struct ice_vsi *vsi;
        struct device *dev;
@@ -3111,24 +3085,21 @@ static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg)
                        ucast_m = ICE_UCAST_PROMISC_BITS;
                }
 
-               ucast_status = ice_vf_set_vsi_promisc(vf, vsi, ucast_m,
-                                                     !alluni);
-               if (ucast_status) {
-                       dev_err(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d failed\n",
-                               alluni ? "en" : "dis", vf->vf_id);
-                       v_ret = ice_err_to_virt_err(ucast_status);
-               }
+               if (alluni)
+                       ucast_err = ice_vf_set_vsi_promisc(vf, vsi, ucast_m);
+               else
+                       ucast_err = ice_vf_clear_vsi_promisc(vf, vsi, ucast_m);
 
-               mcast_status = ice_vf_set_vsi_promisc(vf, vsi, mcast_m,
-                                                     !allmulti);
-               if (mcast_status) {
-                       dev_err(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d failed\n",
-                               allmulti ? "en" : "dis", vf->vf_id);
-                       v_ret = ice_err_to_virt_err(mcast_status);
-               }
+               if (allmulti)
+                       mcast_err = ice_vf_set_vsi_promisc(vf, vsi, mcast_m);
+               else
+                       mcast_err = ice_vf_clear_vsi_promisc(vf, vsi, mcast_m);
+
+               if (ucast_err || mcast_err)
+                       v_ret = VIRTCHNL_STATUS_ERR_PARAM;
        }
 
-       if (!mcast_status) {
+       if (!mcast_err) {
                if (allmulti &&
                    !test_and_set_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states))
                        dev_info(dev, "VF %u successfully set multicast promiscuous mode\n",
@@ -3138,7 +3109,7 @@ static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg)
                                 vf->vf_id);
        }
 
-       if (!ucast_status) {
+       if (!ucast_err) {
                if (alluni && !test_and_set_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states))
                        dev_info(dev, "VF %u successfully set unicast promiscuous mode\n",
                                 vf->vf_id);