@@ -2340,10 +2340,11 @@ static void hclgevf_periodic_service_task(struct hclgevf_dev *hdev)
if (!(hdev->serv_processed_cnt % HCLGEVF_STATS_TIMER_INTERVAL))
hclgevf_tqps_update_stats(handle);
- /* request the link status from the PF. PF would be able to tell VF
- * about such updates in future so we might remove this later
+ /* VF does not need to request link status when this bit is set, because
+ * PF will push its link status to VFs when link status changed.
*/
- hclgevf_request_link_info(hdev);
+ if (!test_bit(HCLGEVF_STATE_PF_PUSH_LINK_STATUS, &hdev->state))
+ hclgevf_request_link_info(hdev);
hclgevf_update_link_mode(hdev);
@@ -2657,6 +2658,7 @@ static int hclgevf_ae_start(struct hnae3_handle *handle)
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
clear_bit(HCLGEVF_STATE_DOWN, &hdev->state);
+ clear_bit(HCLGEVF_STATE_PF_PUSH_LINK_STATUS, &hdev->state);
hclgevf_reset_tqp_stats(handle);
@@ -152,6 +152,7 @@ enum hclgevf_states {
HCLGEVF_STATE_LINK_UPDATING,
HCLGEVF_STATE_PROMISC_CHANGED,
HCLGEVF_STATE_RST_FAIL,
+ HCLGEVF_STATE_PF_PUSH_LINK_STATUS,
};
struct hclgevf_mac {
@@ -276,6 +276,7 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
u8 duplex;
u32 speed;
u32 tail;
+ u8 flag;
u8 idx;
/* we can safely clear it now as we are at start of the async message
@@ -300,11 +301,16 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
link_status = msg_q[1];
memcpy(&speed, &msg_q[2], sizeof(speed));
duplex = (u8)msg_q[4];
+ flag = (u8)msg_q[5];
/* update upper layer with new link link status */
hclgevf_update_link_status(hdev, link_status);
hclgevf_update_speed_duplex(hdev, speed, duplex);
+ if (flag & HCLGE_MBX_PUSH_LINK_STATUS_EN)
+ set_bit(HCLGEVF_STATE_PF_PUSH_LINK_STATUS,
+ &hdev->state);
+
break;
case HCLGE_MBX_LINK_STAT_MODE:
idx = (u8)msg_q[1];