i40e: support VFs on PFs other than 0
authorMitch Williams <mitch.a.williams@intel.com>
Thu, 28 Nov 2013 06:39:41 +0000 (06:39 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Mon, 6 Jan 2014 10:46:49 +0000 (02:46 -0800)
When communicating with VF devices over the AQ, the FW refers to the
VF by its global VF ID, not local the VF ID with reference to its
parent PF. Since the global and local VF IDs are identical for PF 0,
the code worked correctly on PF 0.

However, we cannot just use global IDs throughout the code as most of
the other references to the VF (VSI setup, register offsets, etc.)
require the local VF ID. Instead, we just add or subtract our base VF
ID when sending and receiving AQ messages.

Change-Id: I92f4332b4876bc68b2f9af9ebf48761f63b6bd97
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c

index e91f9d73dc4834c182379f190833ae3ec48a84dd..a983858c45ce501008e82b4ba5785e78fbca3384 100644 (file)
@@ -903,6 +903,7 @@ static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode,
 {
        struct i40e_pf *pf = vf->pf;
        struct i40e_hw *hw = &pf->hw;
+       int true_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
        i40e_status aq_ret;
 
        /* single place to detect unsuccessful return values */
@@ -922,8 +923,8 @@ static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode,
                vf->num_valid_msgs++;
        }
 
-       aq_ret = i40e_aq_send_msg_to_vf(hw, vf->vf_id, v_opcode, v_retval,
-                                    msg, msglen, NULL);
+       aq_ret = i40e_aq_send_msg_to_vf(hw, true_vf_id, v_opcode, v_retval,
+                                       msg, msglen, NULL);
        if (aq_ret) {
                dev_err(&pf->pdev->dev,
                        "Unable to send the message to VF %d aq_err %d\n",
@@ -1664,22 +1665,23 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, u16 vf_id, u32 v_opcode,
                           u32 v_retval, u8 *msg, u16 msglen)
 {
        struct i40e_hw *hw = &pf->hw;
+       int local_vf_id = vf_id - hw->func_caps.vf_base_id;
        struct i40e_vf *vf;
        int ret;
 
        pf->vf_aq_requests++;
-       if (vf_id >= pf->num_alloc_vfs)
+       if (local_vf_id >= pf->num_alloc_vfs)
                return -EINVAL;
-       vf = &(pf->vf[vf_id]);
+       vf = &(pf->vf[local_vf_id]);
        /* perform basic checks on the msg */
        ret = i40e_vc_validate_vf_msg(vf, v_opcode, v_retval, msg, msglen);
 
        if (ret) {
                dev_err(&pf->pdev->dev, "Invalid message from vf %d, opcode %d, len %d\n",
-                       vf_id, v_opcode, msglen);
+                       local_vf_id, v_opcode, msglen);
                return ret;
        }
-       wr32(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_VFR_VFACTIVE);
+       wr32(hw, I40E_VFGEN_RSTAT1(local_vf_id), I40E_VFR_VFACTIVE);
        switch (v_opcode) {
        case I40E_VIRTCHNL_OP_VERSION:
                ret = i40e_vc_get_version_msg(vf);
@@ -1723,8 +1725,8 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, u16 vf_id, u32 v_opcode,
                break;
        case I40E_VIRTCHNL_OP_UNKNOWN:
        default:
-               dev_err(&pf->pdev->dev,
-                       "Unsupported opcode %d from vf %d\n", v_opcode, vf_id);
+               dev_err(&pf->pdev->dev, "Unsupported opcode %d from vf %d\n",
+                       v_opcode, local_vf_id);
                ret = i40e_vc_send_resp_to_vf(vf, v_opcode,
                                              I40E_ERR_NOT_IMPLEMENTED);
                break;