提交 af21392d 编写于 作者: S shenjian 提交者: Xie XiuQi

net: hns3: sync vlan filter entries when kill vlan id failed

driver inclusion
category: bugfix
bugzilla: NA
CVE: NA

When hw is resetting, firmware is unable to handle commands
from driver. So if remove vlan device from stack at this time,
it will fail to remove the vlan id from from hw vlan filter,
then the vlan filter status is unsynced with stack.

This patch fixes it by recording the vlan id delete failed,
and remove them again when reset complete.
Signed-off-by: Nshenjian (K) <shenjian15@huawei.com>
Reviewed-by: Nlipeng <lipeng321@huawei.com>
Reviewed-by: NHanjun Guo <guohanjun@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 827fe0df
......@@ -36,6 +36,7 @@
static int hclge_set_mac_mtu(struct hclge_dev *hdev, int new_mps);
static int hclge_init_vlan_config(struct hclge_dev *hdev);
static void hclge_sync_vlan_filter(struct hclge_dev *hdev);
static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev);
static bool hclge_get_hw_reset_stat(struct hnae3_handle *handle);
static int hclge_set_umv_space(struct hclge_dev *hdev, u16 space_size,
......@@ -3502,6 +3503,7 @@ static void hclge_service_task(struct work_struct *work)
hclge_update_port_info(hdev);
hclge_update_link_status(hdev);
hclge_update_vport_alive(hdev);
hclge_sync_vlan_filter(hdev);
if (hdev->fd_arfs_expire_timer >= HCLGE_FD_ARFS_EXPIRE_TIMER_INTERVAL) {
hclge_rfs_filter_expire(hdev);
......@@ -7253,6 +7255,13 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
else
hclge_add_vport_vlan_table(vport, vlan_id,
writen_to_tbl);
} else if (is_kill) {
/* when remove hw vlan filter failed, record the vlan id,
* and try to remove it from hw later, to be consistence
* with stack
*/
hclge_rm_vport_vlan_table(vport, vlan_id, false);
set_bit(vlan_id, vport->vlan_del_fail_bmap);
}
return ret;
}
......@@ -7769,6 +7778,38 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
}
}
static void hclge_sync_vlan_filter(struct hclge_dev *hdev)
{
#define HCLGE_MAX_SYNC_COUNT 60
int sync_cnt = 0;
u16 vlan_id;
int ret;
int i;
/* start from vport 1 for PF is always alive */
for (i = 0; i < hdev->num_alloc_vport; i++) {
struct hclge_vport *vport = &hdev->vport[i];
vlan_id = find_first_bit(vport->vlan_del_fail_bmap,
VLAN_N_VID);
while (vlan_id != VLAN_N_VID) {
ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q),
vport->vport_id, vlan_id,
0, true);
if (!ret || ret == -EINVAL)
clear_bit(vlan_id, vport->vlan_del_fail_bmap);
sync_cnt++;
if (sync_cnt >= HCLGE_MAX_SYNC_COUNT)
return;
vlan_id = find_first_bit(vport->vlan_del_fail_bmap,
VLAN_N_VID);
}
}
}
static int hclge_set_mac_mtu(struct hclge_dev *hdev, int new_mps)
{
struct hclge_config_max_frm_size_cmd *req;
......
......@@ -873,6 +873,7 @@ struct hclge_vport {
u32 bw_limit; /* VSI BW Limit (0 = disabled) */
u8 dwrr;
unsigned long vlan_del_fail_bmap[BITS_TO_LONGS(VLAN_N_VID)];
struct list_head vlan_list; /* Store VF vlan table */
struct hclge_port_base_vlan_config port_base_vlan_cfg;
struct hclge_tx_vtag_cfg txvlan_cfg;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册