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: 1e6e76101f
("net: hns3: configure promisc mode for VF asynchronously")
Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Hao Lan <lanhao@huawei.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Родитель
7d89b53cea
Коммит
8ee57c7b84
|
@ -12754,60 +12754,71 @@ static int hclge_gro_en(struct hnae3_handle *handle, bool enable)
|
|||
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 hclge_dev *hdev = vport->back;
|
||||
bool uc_en = false;
|
||||
bool mc_en = false;
|
||||
u8 tmp_flags;
|
||||
bool bc_en;
|
||||
int ret;
|
||||
u16 i;
|
||||
|
||||
if (vport->last_promisc_flags != vport->overflow_promisc_flags) {
|
||||
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
|
||||
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;
|
||||
ret = hclge_set_promisc_mode(handle, tmp_flags & HNAE3_UPE,
|
||||
tmp_flags & HNAE3_MPE);
|
||||
if (!ret) {
|
||||
clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
|
||||
&vport->state);
|
||||
if (!ret)
|
||||
set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
|
||||
&vport->state);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i < hdev->num_alloc_vport; i++) {
|
||||
bool uc_en = false;
|
||||
bool mc_en = false;
|
||||
bool bc_en;
|
||||
|
||||
vport = &hdev->vport[i];
|
||||
|
||||
if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
|
||||
&vport->state))
|
||||
continue;
|
||||
|
||||
if (vport->vf_info.trusted) {
|
||||
uc_en = vport->vf_info.request_uc_en > 0 ||
|
||||
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;
|
||||
|
||||
ret = hclge_cmd_set_promisc_mode(hdev, vport->vport_id, uc_en,
|
||||
mc_en, bc_en);
|
||||
if (ret) {
|
||||
else
|
||||
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
|
||||
&vport->state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* for VF */
|
||||
if (vport->vf_info.trusted) {
|
||||
uc_en = vport->vf_info.request_uc_en > 0 ||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
|
||||
{
|
||||
struct hclge_vport *vport;
|
||||
int ret;
|
||||
u16 i;
|
||||
|
||||
for (i = 0; i < hdev->num_alloc_vport; i++) {
|
||||
vport = &hdev->vport[i];
|
||||
|
||||
ret = hclge_sync_vport_promisc_mode(vport);
|
||||
if (ret)
|
||||
return;
|
||||
}
|
||||
hclge_set_vport_vlan_fltr_change(vport);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче