net: hns3: fix VF promisc mode not update when mac table full
authorJian Shen <shenjian15@huawei.com>
Thu, 22 Dec 2022 06:43:43 +0000 (14:43 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 Jan 2023 11:02:01 +0000 (12:02 +0100)
[ Upstream commit 8ee57c7b8406c7aa8ca31e014440c87c6383f429 ]

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: 1e6e76101fd9 ("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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

index 4e54f91..6c2742f 100644 (file)
@@ -12754,60 +12754,71 @@ static int hclge_gro_en(struct hnae3_handle *handle, bool enable)
        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 hclge_dev *hdev = vport->back;
+       bool uc_en = false;
+       bool mc_en = false;
        u8 tmp_flags;
+       bool bc_en;
        int ret;
-       u16 i;
 
        if (vport->last_promisc_flags != vport->overflow_promisc_flags) {
                set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
                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;
                ret = hclge_set_promisc_mode(handle, tmp_flags & HNAE3_UPE,
                                             tmp_flags & HNAE3_MPE);
-               if (!ret) {
-                       clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
-                                 &vport->state);
+               if (!ret)
                        set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
                                &vport->state);
-               }
+               else
+                       set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
+                               &vport->state);
+               return ret;
        }
 
-       for (i = 1; i < hdev->num_alloc_vport; i++) {
-               bool uc_en = false;
-               bool mc_en = false;
-               bool bc_en;
+       /* 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;
 
-               vport = &hdev->vport[i];
+       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);
 
-               if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
-                                       &vport->state))
-                       continue;
+       return 0;
+}
 
-               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;
+static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
+{
+       struct hclge_vport *vport;
+       int ret;
+       u16 i;
 
-               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);
+       for (i = 0; i < hdev->num_alloc_vport; i++) {
+               vport = &hdev->vport[i];
+
+               ret = hclge_sync_vport_promisc_mode(vport);
+               if (ret)
                        return;
-               }
-               hclge_set_vport_vlan_fltr_change(vport);
        }
 }