Merge tag 'hisi-arm64-dt-for-6.8' of https://github.com/hisilicon/linux-hisi into...
[linux-2.6-microblaze.git] / drivers / net / ethernet / hisilicon / hns3 / hns3pf / hclge_main.c
index 66e5807..5ea9e59 100644 (file)
@@ -61,6 +61,7 @@ static void hclge_sync_fd_table(struct hclge_dev *hdev);
 static void hclge_update_fec_stats(struct hclge_dev *hdev);
 static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret,
                                      int wait_cnt);
+static int hclge_update_port_info(struct hclge_dev *hdev);
 
 static struct hnae3_ae_algo ae_algo;
 
@@ -3041,6 +3042,9 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
 
        if (state != hdev->hw.mac.link) {
                hdev->hw.mac.link = state;
+               if (state == HCLGE_LINK_STATUS_UP)
+                       hclge_update_port_info(hdev);
+
                client->ops->link_status_change(handle, state);
                hclge_config_mac_tnl_int(hdev, state);
                if (rclient && rclient->ops->link_status_change)
@@ -10025,8 +10029,6 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id,
        struct hclge_vport_vlan_cfg *vlan, *tmp;
        struct hclge_dev *hdev = vport->back;
 
-       mutex_lock(&hdev->vport_lock);
-
        list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
                if (vlan->vlan_id == vlan_id) {
                        if (is_write_tbl && vlan->hd_tbl_status)
@@ -10041,8 +10043,6 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id,
                        break;
                }
        }
-
-       mutex_unlock(&hdev->vport_lock);
 }
 
 void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list)
@@ -10451,11 +10451,16 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
         * handle mailbox. Just record the vlan id, and remove it after
         * reset finished.
         */
+       mutex_lock(&hdev->vport_lock);
        if ((test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) ||
             test_bit(HCLGE_STATE_RST_FAIL, &hdev->state)) && is_kill) {
                set_bit(vlan_id, vport->vlan_del_fail_bmap);
+               mutex_unlock(&hdev->vport_lock);
                return -EBUSY;
+       } else if (!is_kill && test_bit(vlan_id, vport->vlan_del_fail_bmap)) {
+               clear_bit(vlan_id, vport->vlan_del_fail_bmap);
        }
+       mutex_unlock(&hdev->vport_lock);
 
        /* when port base vlan enabled, we use port base vlan as the vlan
         * filter entry. In this case, we don't update vlan filter table
@@ -10470,17 +10475,22 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
        }
 
        if (!ret) {
-               if (!is_kill)
+               if (!is_kill) {
                        hclge_add_vport_vlan_table(vport, vlan_id,
                                                   writen_to_tbl);
-               else if (is_kill && vlan_id != 0)
+               } else if (is_kill && vlan_id != 0) {
+                       mutex_lock(&hdev->vport_lock);
                        hclge_rm_vport_vlan_table(vport, vlan_id, false);
+                       mutex_unlock(&hdev->vport_lock);
+               }
        } 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
                 */
+               mutex_lock(&hdev->vport_lock);
                set_bit(vlan_id, vport->vlan_del_fail_bmap);
+               mutex_unlock(&hdev->vport_lock);
        }
 
        hclge_set_vport_vlan_fltr_change(vport);
@@ -10520,6 +10530,7 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev)
        int i, ret, sync_cnt = 0;
        u16 vlan_id;
 
+       mutex_lock(&hdev->vport_lock);
        /* 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];
@@ -10530,21 +10541,26 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev)
                        ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q),
                                                       vport->vport_id, vlan_id,
                                                       true);
-                       if (ret && ret != -EINVAL)
+                       if (ret && ret != -EINVAL) {
+                               mutex_unlock(&hdev->vport_lock);
                                return;
+                       }
 
                        clear_bit(vlan_id, vport->vlan_del_fail_bmap);
                        hclge_rm_vport_vlan_table(vport, vlan_id, false);
                        hclge_set_vport_vlan_fltr_change(vport);
 
                        sync_cnt++;
-                       if (sync_cnt >= HCLGE_MAX_SYNC_COUNT)
+                       if (sync_cnt >= HCLGE_MAX_SYNC_COUNT) {
+                               mutex_unlock(&hdev->vport_lock);
                                return;
+                       }
 
                        vlan_id = find_first_bit(vport->vlan_del_fail_bmap,
                                                 VLAN_N_VID);
                }
        }
+       mutex_unlock(&hdev->vport_lock);
 
        hclge_sync_vlan_fltr_state(hdev);
 }
@@ -11651,6 +11667,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
                goto err_msi_irq_uninit;
 
        if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER) {
+               clear_bit(HNAE3_DEV_SUPPORT_FEC_B, ae_dev->caps);
                if (hnae3_dev_phy_imp_supported(hdev))
                        ret = hclge_update_tp_port_info(hdev);
                else