net: hns3: fix get VF RSS issue
authorJian Shen <shenjian15@huawei.com>
Sat, 23 Feb 2019 09:22:17 +0000 (17:22 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 25 Feb 2019 04:27:50 +0000 (20:27 -0800)
For revision 0x20, VF shares the same RSS config with PF.
In original codes, it always return 0 when query RSS hash
key for VF. This patch fixes it by return the hash key
got from PF.

Fixes: 374ad291762a ("net: hns3: net: hns3: Add RSS general configuration support for VF")
Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c

index ca056b3a658938cd33f56f6925b15ded4577c554..306a23e486de522c6f910d05904dd0e35f3259d5 100644 (file)
@@ -490,6 +490,24 @@ static int hclge_get_queue_id_in_pf(struct hclge_vport *vport,
        return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data, 2);
 }
 
+static int hclge_get_rss_key(struct hclge_vport *vport,
+                            struct hclge_mbx_vf_to_pf_cmd *mbx_req)
+{
+#define HCLGE_RSS_MBX_RESP_LEN 8
+       u8 resp_data[HCLGE_RSS_MBX_RESP_LEN];
+       struct hclge_dev *hdev = vport->back;
+       u8 index;
+
+       index = mbx_req->msg[2];
+
+       memcpy(&resp_data[0],
+              &hdev->vport[0].rss_hash_key[index * HCLGE_RSS_MBX_RESP_LEN],
+              HCLGE_RSS_MBX_RESP_LEN);
+
+       return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data,
+                                   HCLGE_RSS_MBX_RESP_LEN);
+}
+
 static bool hclge_cmd_crq_empty(struct hclge_hw *hw)
 {
        u32 tail = hclge_read_dev(hw, HCLGE_NIC_CRQ_TAIL_REG);
@@ -625,6 +643,13 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
                                        "PF failed(%d) to get qid for VF\n",
                                        ret);
                        break;
+               case HCLGE_MBX_GET_RSS_KEY:
+                       ret = hclge_get_rss_key(vport, req);
+                       if (ret)
+                               dev_err(&hdev->pdev->dev,
+                                       "PF fail(%d) to get rss key for VF\n",
+                                       ret);
+                       break;
                case HCLGE_MBX_GET_LINK_MODE:
                        hclge_get_link_mode(vport, req);
                        break;
index 12f16b96e74667a18dfb3f7300f42c33b6c0215d..8bc28e6f465f1961fef7e7d070bee547dce6b9af 100644 (file)
@@ -620,12 +620,50 @@ static int hclgevf_set_rss_tc_mode(struct hclgevf_dev *hdev,  u16 rss_size)
        return status;
 }
 
+/* for revision 0x20, vf shared the same rss config with pf */
+static int hclgevf_get_rss_hash_key(struct hclgevf_dev *hdev)
+{
+#define HCLGEVF_RSS_MBX_RESP_LEN       8
+
+       struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg;
+       u8 resp_msg[HCLGEVF_RSS_MBX_RESP_LEN];
+       u16 msg_num, hash_key_index;
+       u8 index;
+       int ret;
+
+       msg_num = (HCLGEVF_RSS_KEY_SIZE + HCLGEVF_RSS_MBX_RESP_LEN - 1) /
+                       HCLGEVF_RSS_MBX_RESP_LEN;
+       for (index = 0; index < msg_num; index++) {
+               ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_RSS_KEY, 0,
+                                          &index, sizeof(index),
+                                          true, resp_msg,
+                                          HCLGEVF_RSS_MBX_RESP_LEN);
+               if (ret) {
+                       dev_err(&hdev->pdev->dev,
+                               "VF get rss hash key from PF failed, ret=%d",
+                               ret);
+                       return ret;
+               }
+
+               hash_key_index = HCLGEVF_RSS_MBX_RESP_LEN * index;
+               if (index == msg_num - 1)
+                       memcpy(&rss_cfg->rss_hash_key[hash_key_index],
+                              &resp_msg[0],
+                              HCLGEVF_RSS_KEY_SIZE - hash_key_index);
+               else
+                       memcpy(&rss_cfg->rss_hash_key[hash_key_index],
+                              &resp_msg[0], HCLGEVF_RSS_MBX_RESP_LEN);
+       }
+
+       return 0;
+}
+
 static int hclgevf_get_rss(struct hnae3_handle *handle, u32 *indir, u8 *key,
                           u8 *hfunc)
 {
        struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
        struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg;
-       int i;
+       int i, ret;
 
        if (handle->pdev->revision >= 0x21) {
                /* Get hash algorithm */
@@ -647,6 +685,16 @@ static int hclgevf_get_rss(struct hnae3_handle *handle, u32 *indir, u8 *key,
                if (key)
                        memcpy(key, rss_cfg->rss_hash_key,
                               HCLGEVF_RSS_KEY_SIZE);
+       } else {
+               if (hfunc)
+                       *hfunc = ETH_RSS_HASH_TOP;
+               if (key) {
+                       ret = hclgevf_get_rss_hash_key(hdev);
+                       if (ret)
+                               return ret;
+                       memcpy(key, rss_cfg->rss_hash_key,
+                              HCLGEVF_RSS_KEY_SIZE);
+               }
        }
 
        if (indir)