]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net: hns3: PF add support for pushing link status to VFs
authorGuangbin Huang <huangguangbin2@huawei.com>
Thu, 15 Apr 2021 02:20:38 +0000 (10:20 +0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 15 Apr 2021 23:51:29 +0000 (16:51 -0700)
Previously, VF updates its link status every second by send query command
to PF in periodic service task. If link stats of PF is changed, VF may
need at most one second to update its link status.

To reduce delay of link status between PF and VFs, PF actively push its
link status to VFs when its link status is updated. And to let VF know
PF supports this new feature, the link status changed mailbox command
adds one bit to indicate it.

Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c

index 33defa4c180ae58031345881f2fbf639dfcd359a..a2c17af57fde750387838d3ca6da34bdbe51e67f 100644 (file)
@@ -172,4 +172,7 @@ struct hclgevf_mbx_arq_ring {
                (arq.tail = (arq.tail + 1) % HCLGE_MBX_MAX_ARQ_MSG_NUM)
 #define hclge_mbx_head_ptr_move_arq(arq) \
                (arq.head = (arq.head + 1) % HCLGE_MBX_MAX_ARQ_MSG_NUM)
+
+/* PF immediately push link status to VFs when link status changed */
+#define HCLGE_MBX_PUSH_LINK_STATUS_EN                  BIT(0)
 #endif
index 1c17fdc780e989a0966784c9b7120db99263de2d..dc06986055e44f232ae13c33470d44141722f46a 100644 (file)
@@ -2880,6 +2880,28 @@ static int hclge_get_mac_phy_link(struct hclge_dev *hdev, int *link_status)
        return hclge_get_mac_link_status(hdev, link_status);
 }
 
+static void hclge_push_link_status(struct hclge_dev *hdev)
+{
+       struct hclge_vport *vport;
+       int ret;
+       u16 i;
+
+       for (i = 0; i < pci_num_vf(hdev->pdev); i++) {
+               vport = &hdev->vport[i + HCLGE_VF_VPORT_START_NUM];
+
+               if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state) ||
+                   vport->vf_info.link_state != IFLA_VF_LINK_STATE_AUTO)
+                       continue;
+
+               ret = hclge_push_vf_link_status(vport);
+               if (ret) {
+                       dev_err(&hdev->pdev->dev,
+                               "failed to push link status to vf%u, ret = %d\n",
+                               i, ret);
+               }
+       }
+}
+
 static void hclge_update_link_status(struct hclge_dev *hdev)
 {
        struct hnae3_handle *rhandle = &hdev->vport[0].roce;
@@ -2908,6 +2930,7 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
                        rclient->ops->link_status_change(rhandle, state);
 
                hdev->hw.mac.link = state;
+               hclge_push_link_status(hdev);
        }
 
        clear_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state);
@@ -3246,14 +3269,24 @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf,
 {
        struct hclge_vport *vport = hclge_get_vport(handle);
        struct hclge_dev *hdev = vport->back;
+       int link_state_old;
+       int ret;
 
        vport = hclge_get_vf_vport(hdev, vf);
        if (!vport)
                return -EINVAL;
 
+       link_state_old = vport->vf_info.link_state;
        vport->vf_info.link_state = link_state;
 
-       return 0;
+       ret = hclge_push_vf_link_status(vport);
+       if (ret) {
+               vport->vf_info.link_state = link_state_old;
+               dev_err(&hdev->pdev->dev,
+                       "failed to push vf%d link status, ret = %d\n", vf, ret);
+       }
+
+       return ret;
 }
 
 static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
index c1aaf7c534c9ba34f8616c82b2fe7425591e5a80..ff1d47308c2d21a679a1bff7e47b7120ae93f0fb 100644 (file)
@@ -1089,4 +1089,5 @@ void hclge_report_hw_error(struct hclge_dev *hdev,
                           enum hnae3_hw_error_type type);
 void hclge_inform_vf_promisc_info(struct hclge_vport *vport);
 void hclge_dbg_dump_rst_info(struct hclge_dev *hdev);
+int hclge_push_vf_link_status(struct hclge_vport *vport);
 #endif
index c88607bdda59f56167e5dceade2e7225f018d3fd..5512ffe0a149696e2d9ccab4973580d12214c782 100644 (file)
@@ -490,16 +490,14 @@ static void hclge_get_vf_media_type(struct hclge_vport *vport,
        resp_msg->len = HCLGE_VF_MEDIA_TYPE_LENGTH;
 }
 
-static int hclge_get_link_info(struct hclge_vport *vport,
-                              struct hclge_mbx_vf_to_pf_cmd *mbx_req)
+int hclge_push_vf_link_status(struct hclge_vport *vport)
 {
 #define HCLGE_VF_LINK_STATE_UP         1U
 #define HCLGE_VF_LINK_STATE_DOWN       0U
 
        struct hclge_dev *hdev = vport->back;
        u16 link_status;
-       u8 msg_data[8];
-       u8 dest_vfid;
+       u8 msg_data[9];
        u16 duplex;
 
        /* mac.link can only be 0 or 1 */
@@ -520,11 +518,11 @@ static int hclge_get_link_info(struct hclge_vport *vport,
        memcpy(&msg_data[0], &link_status, sizeof(u16));
        memcpy(&msg_data[2], &hdev->hw.mac.speed, sizeof(u32));
        memcpy(&msg_data[6], &duplex, sizeof(u16));
-       dest_vfid = mbx_req->mbx_src_vfid;
+       msg_data[8] = HCLGE_MBX_PUSH_LINK_STATUS_EN;
 
        /* send this requested info to VF */
        return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
-                                 HCLGE_MBX_LINK_STAT_CHANGE, dest_vfid);
+                                 HCLGE_MBX_LINK_STAT_CHANGE, vport->vport_id);
 }
 
 static void hclge_get_link_mode(struct hclge_vport *vport,
@@ -794,7 +792,7 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
                        hclge_get_vf_tcinfo(vport, &resp_msg);
                        break;
                case HCLGE_MBX_GET_LINK_STATUS:
-                       ret = hclge_get_link_info(vport, req);
+                       ret = hclge_push_vf_link_status(vport);
                        if (ret)
                                dev_err(&hdev->pdev->dev,
                                        "failed to inform link stat to VF, ret = %d\n",