Commit 8ee57c7b authored by Jian Shen's avatar Jian Shen Committed by Jakub Kicinski

net: hns3: fix VF promisc mode not update when mac table full

Currently, it missed set HCLGE_VPORT_STATE_PROMISC_CHANGE
flag for VF when vport->overflow_promisc_flags changed.
So the VF won't check whether to update promisc mode in
this case. So add it.

Fixes: 1e6e7610 ("net: hns3: configure promisc mode for VF asynchronously")
Signed-off-by: default avatarJian Shen <shenjian15@huawei.com>
Signed-off-by: default avatarHao Lan <lanhao@huawei.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 7d89b53c
...@@ -12754,60 +12754,71 @@ static int hclge_gro_en(struct hnae3_handle *handle, bool enable) ...@@ -12754,60 +12754,71 @@ static int hclge_gro_en(struct hnae3_handle *handle, bool enable)
return ret; return ret;
} }
static void hclge_sync_promisc_mode(struct hclge_dev *hdev) static int hclge_sync_vport_promisc_mode(struct hclge_vport *vport)
{ {
struct hclge_vport *vport = &hdev->vport[0];
struct hnae3_handle *handle = &vport->nic; struct hnae3_handle *handle = &vport->nic;
struct hclge_dev *hdev = vport->back;
bool uc_en = false;
bool mc_en = false;
u8 tmp_flags; u8 tmp_flags;
bool bc_en;
int ret; int ret;
u16 i;
if (vport->last_promisc_flags != vport->overflow_promisc_flags) { if (vport->last_promisc_flags != vport->overflow_promisc_flags) {
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state); set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
vport->last_promisc_flags = vport->overflow_promisc_flags; vport->last_promisc_flags = vport->overflow_promisc_flags;
} }
if (test_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state)) { if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
&vport->state))
return 0;
/* for PF */
if (!vport->vport_id) {
tmp_flags = handle->netdev_flags | vport->last_promisc_flags; tmp_flags = handle->netdev_flags | vport->last_promisc_flags;
ret = hclge_set_promisc_mode(handle, tmp_flags & HNAE3_UPE, ret = hclge_set_promisc_mode(handle, tmp_flags & HNAE3_UPE,
tmp_flags & HNAE3_MPE); tmp_flags & HNAE3_MPE);
if (!ret) { if (!ret)
clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
&vport->state);
set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE, set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
&vport->state); &vport->state);
} else
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
&vport->state);
return ret;
} }
for (i = 1; i < hdev->num_alloc_vport; i++) { /* for VF */
bool uc_en = false; if (vport->vf_info.trusted) {
bool mc_en = false; uc_en = vport->vf_info.request_uc_en > 0 ||
bool bc_en; vport->overflow_promisc_flags & HNAE3_OVERFLOW_UPE;
mc_en = vport->vf_info.request_mc_en > 0 ||
vport->overflow_promisc_flags & HNAE3_OVERFLOW_MPE;
}
bc_en = vport->vf_info.request_bc_en > 0;
vport = &hdev->vport[i]; ret = hclge_cmd_set_promisc_mode(hdev, vport->vport_id, uc_en,
mc_en, bc_en);
if (ret) {
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
return ret;
}
hclge_set_vport_vlan_fltr_change(vport);
if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, return 0;
&vport->state)) }
continue;
if (vport->vf_info.trusted) { static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
uc_en = vport->vf_info.request_uc_en > 0 || {
vport->overflow_promisc_flags & struct hclge_vport *vport;
HNAE3_OVERFLOW_UPE; int ret;
mc_en = vport->vf_info.request_mc_en > 0 || u16 i;
vport->overflow_promisc_flags &
HNAE3_OVERFLOW_MPE;
}
bc_en = vport->vf_info.request_bc_en > 0;
ret = hclge_cmd_set_promisc_mode(hdev, vport->vport_id, uc_en, for (i = 0; i < hdev->num_alloc_vport; i++) {
mc_en, bc_en); vport = &hdev->vport[i];
if (ret) {
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, ret = hclge_sync_vport_promisc_mode(vport);
&vport->state); if (ret)
return; return;
}
hclge_set_vport_vlan_fltr_change(vport);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment