diff options
author | Jian Shen <shenjian15@huawei.com> | 2019-06-03 10:09:15 +0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-06-03 15:32:50 -0700 |
commit | b524b38ff6320f58f5d0e95640eec82fae850887 (patch) | |
tree | 7b8e818fe1dc902d9cc45830435042cf6164e690 /drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | |
parent | net: hns3: don't configure new VLAN ID into VF VLAN table when it's full (diff) | |
download | linux-dev-b524b38ff6320f58f5d0e95640eec82fae850887.tar.xz linux-dev-b524b38ff6320f58f5d0e95640eec82fae850887.zip |
net: hns3: fix VLAN filter restore issue after reset
In orginal codes, the driver only restore VLAN filter entries
for PF after reset, the VLAN entries of VF will lose in this
case.
This patch fixes it by recording VLAN IDs for each function
when add VLAN, and restore the VLAN IDs after reset.
Fixes: 681ec3999b3d ("net: hns3: fix for vlan table lost problem when resetting")
Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to '')
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 12154550a15f..4873a8e83662 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -7401,10 +7401,6 @@ static void hclge_add_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id, { struct hclge_vport_vlan_cfg *vlan; - /* vlan 0 is reserved */ - if (!vlan_id) - return; - vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); if (!vlan) return; @@ -7499,6 +7495,43 @@ void hclge_uninit_vport_vlan_table(struct hclge_dev *hdev) mutex_unlock(&hdev->vport_cfg_mutex); } +static void hclge_restore_vlan_table(struct hnae3_handle *handle) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_vport_vlan_cfg *vlan, *tmp; + struct hclge_dev *hdev = vport->back; + u16 vlan_proto, qos; + u16 state, vlan_id; + int i; + + mutex_lock(&hdev->vport_cfg_mutex); + for (i = 0; i < hdev->num_alloc_vport; i++) { + vport = &hdev->vport[i]; + vlan_proto = vport->port_base_vlan_cfg.vlan_info.vlan_proto; + vlan_id = vport->port_base_vlan_cfg.vlan_info.vlan_tag; + qos = vport->port_base_vlan_cfg.vlan_info.qos; + state = vport->port_base_vlan_cfg.state; + + if (state != HNAE3_PORT_BASE_VLAN_DISABLE) { + hclge_set_vlan_filter_hw(hdev, htons(vlan_proto), + vport->vport_id, vlan_id, qos, + false); + continue; + } + + list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) { + if (vlan->hd_tbl_status) + hclge_set_vlan_filter_hw(hdev, + htons(ETH_P_8021Q), + vport->vport_id, + vlan->vlan_id, 0, + false); + } + } + + mutex_unlock(&hdev->vport_cfg_mutex); +} + int hclge_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) { struct hclge_vport *vport = hclge_get_vport(handle); @@ -9206,6 +9239,7 @@ static const struct hnae3_ae_ops hclge_ops = { .set_timer_task = hclge_set_timer_task, .mac_connect_phy = hclge_mac_connect_phy, .mac_disconnect_phy = hclge_mac_disconnect_phy, + .restore_vlan_table = hclge_restore_vlan_table, }; static struct hnae3_ae_algo ae_algo = { |