Skip to content

Commit 18b6e31

Browse files
Guangbin Huangdavem330
authored andcommitted
net: hns3: PF add support for pushing link status to VFs
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>
1 parent c329e5a commit 18b6e31

File tree

4 files changed

+43
-8
lines changed

4 files changed

+43
-8
lines changed

drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,7 @@ struct hclgevf_mbx_arq_ring {
172172
(arq.tail = (arq.tail + 1) % HCLGE_MBX_MAX_ARQ_MSG_NUM)
173173
#define hclge_mbx_head_ptr_move_arq(arq) \
174174
(arq.head = (arq.head + 1) % HCLGE_MBX_MAX_ARQ_MSG_NUM)
175+
176+
/* PF immediately push link status to VFs when link status changed */
177+
#define HCLGE_MBX_PUSH_LINK_STATUS_EN BIT(0)
175178
#endif

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2880,6 +2880,28 @@ static int hclge_get_mac_phy_link(struct hclge_dev *hdev, int *link_status)
28802880
return hclge_get_mac_link_status(hdev, link_status);
28812881
}
28822882

2883+
static void hclge_push_link_status(struct hclge_dev *hdev)
2884+
{
2885+
struct hclge_vport *vport;
2886+
int ret;
2887+
u16 i;
2888+
2889+
for (i = 0; i < pci_num_vf(hdev->pdev); i++) {
2890+
vport = &hdev->vport[i + HCLGE_VF_VPORT_START_NUM];
2891+
2892+
if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state) ||
2893+
vport->vf_info.link_state != IFLA_VF_LINK_STATE_AUTO)
2894+
continue;
2895+
2896+
ret = hclge_push_vf_link_status(vport);
2897+
if (ret) {
2898+
dev_err(&hdev->pdev->dev,
2899+
"failed to push link status to vf%u, ret = %d\n",
2900+
i, ret);
2901+
}
2902+
}
2903+
}
2904+
28832905
static void hclge_update_link_status(struct hclge_dev *hdev)
28842906
{
28852907
struct hnae3_handle *rhandle = &hdev->vport[0].roce;
@@ -2908,6 +2930,7 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
29082930
rclient->ops->link_status_change(rhandle, state);
29092931

29102932
hdev->hw.mac.link = state;
2933+
hclge_push_link_status(hdev);
29112934
}
29122935

29132936
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,
32463269
{
32473270
struct hclge_vport *vport = hclge_get_vport(handle);
32483271
struct hclge_dev *hdev = vport->back;
3272+
int link_state_old;
3273+
int ret;
32493274

32503275
vport = hclge_get_vf_vport(hdev, vf);
32513276
if (!vport)
32523277
return -EINVAL;
32533278

3279+
link_state_old = vport->vf_info.link_state;
32543280
vport->vf_info.link_state = link_state;
32553281

3256-
return 0;
3282+
ret = hclge_push_vf_link_status(vport);
3283+
if (ret) {
3284+
vport->vf_info.link_state = link_state_old;
3285+
dev_err(&hdev->pdev->dev,
3286+
"failed to push vf%d link status, ret = %d\n", vf, ret);
3287+
}
3288+
3289+
return ret;
32573290
}
32583291

32593292
static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,4 +1089,5 @@ void hclge_report_hw_error(struct hclge_dev *hdev,
10891089
enum hnae3_hw_error_type type);
10901090
void hclge_inform_vf_promisc_info(struct hclge_vport *vport);
10911091
void hclge_dbg_dump_rst_info(struct hclge_dev *hdev);
1092+
int hclge_push_vf_link_status(struct hclge_vport *vport);
10921093
#endif

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -490,16 +490,14 @@ static void hclge_get_vf_media_type(struct hclge_vport *vport,
490490
resp_msg->len = HCLGE_VF_MEDIA_TYPE_LENGTH;
491491
}
492492

493-
static int hclge_get_link_info(struct hclge_vport *vport,
494-
struct hclge_mbx_vf_to_pf_cmd *mbx_req)
493+
int hclge_push_vf_link_status(struct hclge_vport *vport)
495494
{
496495
#define HCLGE_VF_LINK_STATE_UP 1U
497496
#define HCLGE_VF_LINK_STATE_DOWN 0U
498497

499498
struct hclge_dev *hdev = vport->back;
500499
u16 link_status;
501-
u8 msg_data[8];
502-
u8 dest_vfid;
500+
u8 msg_data[9];
503501
u16 duplex;
504502

505503
/* mac.link can only be 0 or 1 */
@@ -520,11 +518,11 @@ static int hclge_get_link_info(struct hclge_vport *vport,
520518
memcpy(&msg_data[0], &link_status, sizeof(u16));
521519
memcpy(&msg_data[2], &hdev->hw.mac.speed, sizeof(u32));
522520
memcpy(&msg_data[6], &duplex, sizeof(u16));
523-
dest_vfid = mbx_req->mbx_src_vfid;
521+
msg_data[8] = HCLGE_MBX_PUSH_LINK_STATUS_EN;
524522

525523
/* send this requested info to VF */
526524
return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
527-
HCLGE_MBX_LINK_STAT_CHANGE, dest_vfid);
525+
HCLGE_MBX_LINK_STAT_CHANGE, vport->vport_id);
528526
}
529527

530528
static void hclge_get_link_mode(struct hclge_vport *vport,
@@ -794,7 +792,7 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
794792
hclge_get_vf_tcinfo(vport, &resp_msg);
795793
break;
796794
case HCLGE_MBX_GET_LINK_STATUS:
797-
ret = hclge_get_link_info(vport, req);
795+
ret = hclge_push_vf_link_status(vport);
798796
if (ret)
799797
dev_err(&hdev->pdev->dev,
800798
"failed to inform link stat to VF, ret = %d\n",

0 commit comments

Comments
 (0)