Skip to content

Commit 5d64075

Browse files
committed
Merge branch 'hns3-fixes'
Jijie Shao says: ==================== There are some bugfix for the HNS3 ethernet driver There are some bugfix for the HNS3 ethernet driver --- ChangeLog: v1 -> v2: - net: hns3: fix add VLAN fail issue, net: hns3: fix VF reset fail issue are modified suggested by Paolo v1: https://lore.kernel.org/all/20231028025917.314305-1-shaojijie@huawei.com/ ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 2bd5b55 + dff655e commit 5d64075

6 files changed

Lines changed: 62 additions & 15 deletions

File tree

drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,11 +503,14 @@ static void hns3_get_coal_info(struct hns3_enet_tqp_vector *tqp_vector,
503503
}
504504

505505
sprintf(result[j++], "%d", i);
506-
sprintf(result[j++], "%s", dim_state_str[dim->state]);
506+
sprintf(result[j++], "%s", dim->state < ARRAY_SIZE(dim_state_str) ?
507+
dim_state_str[dim->state] : "unknown");
507508
sprintf(result[j++], "%u", dim->profile_ix);
508-
sprintf(result[j++], "%s", dim_cqe_mode_str[dim->mode]);
509+
sprintf(result[j++], "%s", dim->mode < ARRAY_SIZE(dim_cqe_mode_str) ?
510+
dim_cqe_mode_str[dim->mode] : "unknown");
509511
sprintf(result[j++], "%s",
510-
dim_tune_stat_str[dim->tune_state]);
512+
dim->tune_state < ARRAY_SIZE(dim_tune_stat_str) ?
513+
dim_tune_stat_str[dim->tune_state] : "unknown");
511514
sprintf(result[j++], "%u", dim->steps_left);
512515
sprintf(result[j++], "%u", dim->steps_right);
513516
sprintf(result[j++], "%u", dim->tired);

drivers/net/ethernet/hisilicon/hns3/hns3_enet.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5139,7 +5139,7 @@ static int hns3_init_mac_addr(struct net_device *netdev)
51395139
struct hns3_nic_priv *priv = netdev_priv(netdev);
51405140
char format_mac_addr[HNAE3_FORMAT_MAC_ADDR_LEN];
51415141
struct hnae3_handle *h = priv->ae_handle;
5142-
u8 mac_addr_temp[ETH_ALEN];
5142+
u8 mac_addr_temp[ETH_ALEN] = {0};
51435143
int ret = 0;
51445144

51455145
if (h->ae_algo->ops->get_mac_addr)

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

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ static void hclge_sync_fd_table(struct hclge_dev *hdev);
6161
static void hclge_update_fec_stats(struct hclge_dev *hdev);
6262
static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret,
6363
int wait_cnt);
64+
static int hclge_update_port_info(struct hclge_dev *hdev);
6465

6566
static struct hnae3_ae_algo ae_algo;
6667

@@ -3041,6 +3042,9 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
30413042

30423043
if (state != hdev->hw.mac.link) {
30433044
hdev->hw.mac.link = state;
3045+
if (state == HCLGE_LINK_STATUS_UP)
3046+
hclge_update_port_info(hdev);
3047+
30443048
client->ops->link_status_change(handle, state);
30453049
hclge_config_mac_tnl_int(hdev, state);
30463050
if (rclient && rclient->ops->link_status_change)
@@ -10025,8 +10029,6 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id,
1002510029
struct hclge_vport_vlan_cfg *vlan, *tmp;
1002610030
struct hclge_dev *hdev = vport->back;
1002710031

10028-
mutex_lock(&hdev->vport_lock);
10029-
1003010032
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
1003110033
if (vlan->vlan_id == vlan_id) {
1003210034
if (is_write_tbl && vlan->hd_tbl_status)
@@ -10041,8 +10043,6 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id,
1004110043
break;
1004210044
}
1004310045
}
10044-
10045-
mutex_unlock(&hdev->vport_lock);
1004610046
}
1004710047

1004810048
void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list)
@@ -10451,11 +10451,16 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
1045110451
* handle mailbox. Just record the vlan id, and remove it after
1045210452
* reset finished.
1045310453
*/
10454+
mutex_lock(&hdev->vport_lock);
1045410455
if ((test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) ||
1045510456
test_bit(HCLGE_STATE_RST_FAIL, &hdev->state)) && is_kill) {
1045610457
set_bit(vlan_id, vport->vlan_del_fail_bmap);
10458+
mutex_unlock(&hdev->vport_lock);
1045710459
return -EBUSY;
10460+
} else if (!is_kill && test_bit(vlan_id, vport->vlan_del_fail_bmap)) {
10461+
clear_bit(vlan_id, vport->vlan_del_fail_bmap);
1045810462
}
10463+
mutex_unlock(&hdev->vport_lock);
1045910464

1046010465
/* when port base vlan enabled, we use port base vlan as the vlan
1046110466
* filter entry. In this case, we don't update vlan filter table
@@ -10470,17 +10475,22 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
1047010475
}
1047110476

1047210477
if (!ret) {
10473-
if (!is_kill)
10478+
if (!is_kill) {
1047410479
hclge_add_vport_vlan_table(vport, vlan_id,
1047510480
writen_to_tbl);
10476-
else if (is_kill && vlan_id != 0)
10481+
} else if (is_kill && vlan_id != 0) {
10482+
mutex_lock(&hdev->vport_lock);
1047710483
hclge_rm_vport_vlan_table(vport, vlan_id, false);
10484+
mutex_unlock(&hdev->vport_lock);
10485+
}
1047810486
} else if (is_kill) {
1047910487
/* when remove hw vlan filter failed, record the vlan id,
1048010488
* and try to remove it from hw later, to be consistence
1048110489
* with stack
1048210490
*/
10491+
mutex_lock(&hdev->vport_lock);
1048310492
set_bit(vlan_id, vport->vlan_del_fail_bmap);
10493+
mutex_unlock(&hdev->vport_lock);
1048410494
}
1048510495

1048610496
hclge_set_vport_vlan_fltr_change(vport);
@@ -10520,6 +10530,7 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev)
1052010530
int i, ret, sync_cnt = 0;
1052110531
u16 vlan_id;
1052210532

10533+
mutex_lock(&hdev->vport_lock);
1052310534
/* start from vport 1 for PF is always alive */
1052410535
for (i = 0; i < hdev->num_alloc_vport; i++) {
1052510536
struct hclge_vport *vport = &hdev->vport[i];
@@ -10530,21 +10541,26 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev)
1053010541
ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q),
1053110542
vport->vport_id, vlan_id,
1053210543
true);
10533-
if (ret && ret != -EINVAL)
10544+
if (ret && ret != -EINVAL) {
10545+
mutex_unlock(&hdev->vport_lock);
1053410546
return;
10547+
}
1053510548

1053610549
clear_bit(vlan_id, vport->vlan_del_fail_bmap);
1053710550
hclge_rm_vport_vlan_table(vport, vlan_id, false);
1053810551
hclge_set_vport_vlan_fltr_change(vport);
1053910552

1054010553
sync_cnt++;
10541-
if (sync_cnt >= HCLGE_MAX_SYNC_COUNT)
10554+
if (sync_cnt >= HCLGE_MAX_SYNC_COUNT) {
10555+
mutex_unlock(&hdev->vport_lock);
1054210556
return;
10557+
}
1054310558

1054410559
vlan_id = find_first_bit(vport->vlan_del_fail_bmap,
1054510560
VLAN_N_VID);
1054610561
}
1054710562
}
10563+
mutex_unlock(&hdev->vport_lock);
1054810564

1054910565
hclge_sync_vlan_fltr_state(hdev);
1055010566
}
@@ -11651,6 +11667,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
1165111667
goto err_msi_irq_uninit;
1165211668

1165311669
if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER) {
11670+
clear_bit(HNAE3_DEV_SUPPORT_FEC_B, ae_dev->caps);
1165411671
if (hnae3_dev_phy_imp_supported(hdev))
1165511672
ret = hclge_update_tp_port_info(hdev);
1165611673
else

drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,8 @@ static int hclgevf_set_vlan_filter(struct hnae3_handle *handle,
12061206
test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) && is_kill) {
12071207
set_bit(vlan_id, hdev->vlan_del_fail_bmap);
12081208
return -EBUSY;
1209+
} else if (!is_kill && test_bit(vlan_id, hdev->vlan_del_fail_bmap)) {
1210+
clear_bit(vlan_id, hdev->vlan_del_fail_bmap);
12091211
}
12101212

12111213
hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN,
@@ -1233,20 +1235,25 @@ static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev)
12331235
int ret, sync_cnt = 0;
12341236
u16 vlan_id;
12351237

1238+
if (bitmap_empty(hdev->vlan_del_fail_bmap, VLAN_N_VID))
1239+
return;
1240+
1241+
rtnl_lock();
12361242
vlan_id = find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID);
12371243
while (vlan_id != VLAN_N_VID) {
12381244
ret = hclgevf_set_vlan_filter(handle, htons(ETH_P_8021Q),
12391245
vlan_id, true);
12401246
if (ret)
1241-
return;
1247+
break;
12421248

12431249
clear_bit(vlan_id, hdev->vlan_del_fail_bmap);
12441250
sync_cnt++;
12451251
if (sync_cnt >= HCLGEVF_MAX_SYNC_COUNT)
1246-
return;
1252+
break;
12471253

12481254
vlan_id = find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID);
12491255
}
1256+
rtnl_unlock();
12501257
}
12511258

12521259
static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
@@ -1974,8 +1981,18 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev,
19741981
return HCLGEVF_VECTOR0_EVENT_OTHER;
19751982
}
19761983

1984+
static void hclgevf_reset_timer(struct timer_list *t)
1985+
{
1986+
struct hclgevf_dev *hdev = from_timer(hdev, t, reset_timer);
1987+
1988+
hclgevf_clear_event_cause(hdev, HCLGEVF_VECTOR0_EVENT_RST);
1989+
hclgevf_reset_task_schedule(hdev);
1990+
}
1991+
19771992
static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data)
19781993
{
1994+
#define HCLGEVF_RESET_DELAY 5
1995+
19791996
enum hclgevf_evt_cause event_cause;
19801997
struct hclgevf_dev *hdev = data;
19811998
u32 clearval;
@@ -1987,7 +2004,8 @@ static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data)
19872004

19882005
switch (event_cause) {
19892006
case HCLGEVF_VECTOR0_EVENT_RST:
1990-
hclgevf_reset_task_schedule(hdev);
2007+
mod_timer(&hdev->reset_timer,
2008+
jiffies + msecs_to_jiffies(HCLGEVF_RESET_DELAY));
19912009
break;
19922010
case HCLGEVF_VECTOR0_EVENT_MBX:
19932011
hclgevf_mbx_handler(hdev);
@@ -2930,6 +2948,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
29302948
HCLGEVF_DRIVER_NAME);
29312949

29322950
hclgevf_task_schedule(hdev, round_jiffies_relative(HZ));
2951+
timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0);
29332952

29342953
return 0;
29352954

drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ struct hclgevf_dev {
219219
enum hnae3_reset_type reset_level;
220220
unsigned long reset_pending;
221221
enum hnae3_reset_type reset_type;
222+
struct timer_list reset_timer;
222223

223224
#define HCLGEVF_RESET_REQUESTED 0
224225
#define HCLGEVF_RESET_PENDING 1

drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ static int hclgevf_get_mbx_resp(struct hclgevf_dev *hdev, u16 code0, u16 code1,
6363
i++;
6464
}
6565

66+
/* ensure additional_info will be seen after received_resp */
67+
smp_rmb();
68+
6669
if (i >= HCLGEVF_MAX_TRY_TIMES) {
6770
dev_err(&hdev->pdev->dev,
6871
"VF could not get mbx(%u,%u) resp(=%d) from PF in %d tries\n",
@@ -178,6 +181,10 @@ static void hclgevf_handle_mbx_response(struct hclgevf_dev *hdev,
178181
resp->resp_status = hclgevf_resp_to_errno(resp_status);
179182
memcpy(resp->additional_info, req->msg.resp_data,
180183
HCLGE_MBX_MAX_RESP_DATA_SIZE * sizeof(u8));
184+
185+
/* ensure additional_info will be seen before setting received_resp */
186+
smp_wmb();
187+
181188
if (match_id) {
182189
/* If match_id is not zero, it means PF support match_id.
183190
* if the match_id is right, VF get the right response, or

0 commit comments

Comments
 (0)