net: hns3: fix add VLAN fail issue
[linux-2.6-microblaze.git] / drivers / net / ethernet / hisilicon / hns3 / hns3vf / hclgevf_main.c
index a4d68fb..1c62e58 100644 (file)
@@ -1206,6 +1206,8 @@ static int hclgevf_set_vlan_filter(struct hnae3_handle *handle,
             test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) && is_kill) {
                set_bit(vlan_id, hdev->vlan_del_fail_bmap);
                return -EBUSY;
+       } else if (!is_kill && test_bit(vlan_id, hdev->vlan_del_fail_bmap)) {
+               clear_bit(vlan_id, hdev->vlan_del_fail_bmap);
        }
 
        hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN,
@@ -1233,20 +1235,25 @@ static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev)
        int ret, sync_cnt = 0;
        u16 vlan_id;
 
+       if (bitmap_empty(hdev->vlan_del_fail_bmap, VLAN_N_VID))
+               return;
+
+       rtnl_lock();
        vlan_id = find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID);
        while (vlan_id != VLAN_N_VID) {
                ret = hclgevf_set_vlan_filter(handle, htons(ETH_P_8021Q),
                                              vlan_id, true);
                if (ret)
-                       return;
+                       break;
 
                clear_bit(vlan_id, hdev->vlan_del_fail_bmap);
                sync_cnt++;
                if (sync_cnt >= HCLGEVF_MAX_SYNC_COUNT)
-                       return;
+                       break;
 
                vlan_id = find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID);
        }
+       rtnl_unlock();
 }
 
 static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)