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;
|
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
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
|
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
|
||||||
&vport->state);
|
&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;
|
return;
|
||||||
}
|
|
||||||
hclge_set_vport_vlan_fltr_change(vport);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче