Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux-2.6-microblaze.git] / drivers / net / ethernet / hisilicon / hns3 / hns3pf / hclge_main.c
index 16f7d0e..eb14c43 100644 (file)
@@ -55,6 +55,8 @@
 
 #define HCLGE_LINK_STATUS_MS   10
 
+#define HCLGE_VF_VPORT_START_NUM       1
+
 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);
@@ -323,8 +325,7 @@ static const struct hclge_mac_mgr_tbl_entry_cmd hclge_mgr_table[] = {
        {
                .flags = HCLGE_MAC_MGR_MASK_VLAN_B,
                .ethter_type = cpu_to_le16(ETH_P_LLDP),
-               .mac_addr_hi32 = cpu_to_le32(htonl(0x0180C200)),
-               .mac_addr_lo16 = cpu_to_le16(htons(0x000E)),
+               .mac_addr = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e},
                .i_port_bitmap = 0x1,
        },
 };
@@ -1194,6 +1195,35 @@ static void hclge_parse_link_mode(struct hclge_dev *hdev, u8 speed_ability)
                hclge_parse_backplane_link_mode(hdev, speed_ability);
 }
 
+static u32 hclge_get_max_speed(u8 speed_ability)
+{
+       if (speed_ability & HCLGE_SUPPORT_100G_BIT)
+               return HCLGE_MAC_SPEED_100G;
+
+       if (speed_ability & HCLGE_SUPPORT_50G_BIT)
+               return HCLGE_MAC_SPEED_50G;
+
+       if (speed_ability & HCLGE_SUPPORT_40G_BIT)
+               return HCLGE_MAC_SPEED_40G;
+
+       if (speed_ability & HCLGE_SUPPORT_25G_BIT)
+               return HCLGE_MAC_SPEED_25G;
+
+       if (speed_ability & HCLGE_SUPPORT_10G_BIT)
+               return HCLGE_MAC_SPEED_10G;
+
+       if (speed_ability & HCLGE_SUPPORT_1G_BIT)
+               return HCLGE_MAC_SPEED_1G;
+
+       if (speed_ability & HCLGE_SUPPORT_100M_BIT)
+               return HCLGE_MAC_SPEED_100M;
+
+       if (speed_ability & HCLGE_SUPPORT_10M_BIT)
+               return HCLGE_MAC_SPEED_10M;
+
+       return HCLGE_MAC_SPEED_1G;
+}
+
 static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc)
 {
        struct hclge_cfg_param_cmd *req;
@@ -1364,9 +1394,11 @@ static int hclge_configure(struct hclge_dev *hdev)
 
        hclge_parse_link_mode(hdev, cfg.speed_ability);
 
+       hdev->hw.mac.max_speed = hclge_get_max_speed(cfg.speed_ability);
+
        if ((hdev->tc_max > HNAE3_MAX_TC) ||
            (hdev->tc_max < 1)) {
-               dev_warn(&hdev->pdev->dev, "TC num = %d.\n",
+               dev_warn(&hdev->pdev->dev, "TC num = %u.\n",
                         hdev->tc_max);
                hdev->tc_max = 1;
        }
@@ -1626,7 +1658,7 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
        num_vport = hdev->num_vmdq_vport + hdev->num_req_vfs + 1;
 
        if (hdev->num_tqps < num_vport) {
-               dev_err(&hdev->pdev->dev, "tqps(%d) is less than vports(%d)",
+               dev_err(&hdev->pdev->dev, "tqps(%u) is less than vports(%d)",
                        hdev->num_tqps, num_vport);
                return -EINVAL;
        }
@@ -1649,6 +1681,7 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
        for (i = 0; i < num_vport; i++) {
                vport->back = hdev;
                vport->vport_id = i;
+               vport->vf_info.link_state = IFLA_VF_LINK_STATE_AUTO;
                vport->mps = HCLGE_MAC_DEFAULT_FRAME;
                vport->port_base_vlan_cfg.state = HNAE3_PORT_BASE_VLAN_DISABLE;
                vport->rxvlan_cfg.rx_vlan_offload_en = true;
@@ -2312,7 +2345,7 @@ static int hclge_init_msi(struct hclge_dev *hdev)
        }
        if (vectors < hdev->num_msi)
                dev_warn(&hdev->pdev->dev,
-                        "requested %d MSI/MSI-X, but allocated %d MSI/MSI-X\n",
+                        "requested %u MSI/MSI-X, but allocated %d MSI/MSI-X\n",
                         hdev->num_msi, vectors);
 
        hdev->num_msi = vectors;
@@ -2744,7 +2777,7 @@ static void hclge_update_port_capability(struct hclge_mac *mac)
        else if (mac->media_type == HNAE3_MEDIA_TYPE_COPPER)
                mac->module_type = HNAE3_MODULE_TYPE_TP;
 
-       if (mac->support_autoneg == true) {
+       if (mac->support_autoneg) {
                linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, mac->supported);
                linkmode_copy(mac->advertising, mac->supported);
        } else {
@@ -2871,6 +2904,62 @@ static int hclge_get_status(struct hnae3_handle *handle)
        return hdev->hw.mac.link;
 }
 
+static struct hclge_vport *hclge_get_vf_vport(struct hclge_dev *hdev, int vf)
+{
+       if (pci_num_vf(hdev->pdev) == 0) {
+               dev_err(&hdev->pdev->dev,
+                       "SRIOV is disabled, can not get vport(%d) info.\n", vf);
+               return NULL;
+       }
+
+       if (vf < 0 || vf >= pci_num_vf(hdev->pdev)) {
+               dev_err(&hdev->pdev->dev,
+                       "vf id(%d) is out of range(0 <= vfid < %d)\n",
+                       vf, pci_num_vf(hdev->pdev));
+               return NULL;
+       }
+
+       /* VF start from 1 in vport */
+       vf += HCLGE_VF_VPORT_START_NUM;
+       return &hdev->vport[vf];
+}
+
+static int hclge_get_vf_config(struct hnae3_handle *handle, int vf,
+                              struct ifla_vf_info *ivf)
+{
+       struct hclge_vport *vport = hclge_get_vport(handle);
+       struct hclge_dev *hdev = vport->back;
+
+       vport = hclge_get_vf_vport(hdev, vf);
+       if (!vport)
+               return -EINVAL;
+
+       ivf->vf = vf;
+       ivf->linkstate = vport->vf_info.link_state;
+       ivf->spoofchk = vport->vf_info.spoofchk;
+       ivf->trusted = vport->vf_info.trusted;
+       ivf->min_tx_rate = 0;
+       ivf->max_tx_rate = vport->vf_info.max_tx_rate;
+       ether_addr_copy(ivf->mac, vport->vf_info.mac);
+
+       return 0;
+}
+
+static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf,
+                                  int link_state)
+{
+       struct hclge_vport *vport = hclge_get_vport(handle);
+       struct hclge_dev *hdev = vport->back;
+
+       vport = hclge_get_vf_vport(hdev, vf);
+       if (!vport)
+               return -EINVAL;
+
+       vport->vf_info.link_state = link_state;
+
+       return 0;
+}
+
 static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
 {
        u32 rst_src_reg, cmdq_src_reg, msix_src_reg;
@@ -3191,7 +3280,7 @@ static int hclge_reset_wait(struct hclge_dev *hdev)
 
                if (!test_bit(HNAE3_FLR_DONE, &hdev->flr_state)) {
                        dev_err(&hdev->pdev->dev,
-                               "flr wait timeout: %d\n", cnt);
+                               "flr wait timeout: %u\n", cnt);
                        return -EBUSY;
                }
 
@@ -3241,7 +3330,7 @@ static int hclge_set_all_vf_rst(struct hclge_dev *hdev, bool reset)
                ret = hclge_set_vf_rst(hdev, vport->vport_id, reset);
                if (ret) {
                        dev_err(&hdev->pdev->dev,
-                               "set vf(%d) rst failed %d!\n",
+                               "set vf(%u) rst failed %d!\n",
                                vport->vport_id, ret);
                        return ret;
                }
@@ -3256,7 +3345,7 @@ static int hclge_set_all_vf_rst(struct hclge_dev *hdev, bool reset)
                ret = hclge_inform_reset_assert_to_vf(vport);
                if (ret)
                        dev_warn(&hdev->pdev->dev,
-                                "inform reset to vf(%d) failed %d!\n",
+                                "inform reset to vf(%u) failed %d!\n",
                                 vport->vport_id, ret);
        }
 
@@ -3569,7 +3658,7 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev)
                hdev->rst_stats.reset_fail_cnt++;
                set_bit(hdev->reset_type, &hdev->reset_pending);
                dev_info(&hdev->pdev->dev,
-                        "re-schedule reset task(%d)\n",
+                        "re-schedule reset task(%u)\n",
                         hdev->rst_stats.reset_fail_cnt);
                return true;
        }
@@ -3580,6 +3669,9 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev)
        hclge_reset_handshake(hdev, true);
 
        dev_err(&hdev->pdev->dev, "Reset fail!\n");
+
+       hclge_dbg_dump_rst_info(hdev);
+
        return false;
 }
 
@@ -3779,12 +3871,13 @@ static void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle)
                                  HCLGE_RESET_INTERVAL))) {
                mod_timer(&hdev->reset_timer, jiffies + HCLGE_RESET_INTERVAL);
                return;
-       } else if (hdev->default_reset_request)
+       } else if (hdev->default_reset_request) {
                hdev->reset_level =
                        hclge_get_reset_level(ae_dev,
                                              &hdev->default_reset_request);
-       else if (time_after(jiffies, (hdev->last_reset_time + 4 * 5 * HZ)))
+       } else if (time_after(jiffies, (hdev->last_reset_time + 4 * 5 * HZ))) {
                hdev->reset_level = HNAE3_FUNC_RESET;
+       }
 
        dev_info(&hdev->pdev->dev, "received reset event, reset type is %d\n",
                 hdev->reset_level);
@@ -3909,6 +4002,7 @@ static void hclge_service_task(struct work_struct *work)
        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);
                hdev->fd_arfs_expire_timer = 0;
@@ -4415,7 +4509,7 @@ int hclge_rss_init_hw(struct hclge_dev *hdev)
         */
        if (rss_size > HCLGE_RSS_TC_SIZE_7 || rss_size == 0) {
                dev_err(&hdev->pdev->dev,
-                       "Configure rss tc size failed, invalid TC_SIZE = %d\n",
+                       "Configure rss tc size failed, invalid TC_SIZE = %u\n",
                        rss_size);
                return -EINVAL;
        }
@@ -4593,8 +4687,8 @@ static int hclge_unmap_ring_frm_vector(struct hnae3_handle *handle, int vector,
        return ret;
 }
 
-int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
-                              struct hclge_promisc_param *param)
+static int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
+                                     struct hclge_promisc_param *param)
 {
        struct hclge_promisc_cfg_cmd *req;
        struct hclge_desc desc;
@@ -4621,8 +4715,9 @@ int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
        return ret;
 }
 
-void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc,
-                             bool en_mc, bool en_bc, int vport_id)
+static void hclge_promisc_param_init(struct hclge_promisc_param *param,
+                                    bool en_uc, bool en_mc, bool en_bc,
+                                    int vport_id)
 {
        if (!param)
                return;
@@ -4637,12 +4732,21 @@ void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc,
        param->vf_id = vport_id;
 }
 
+int hclge_set_vport_promisc_mode(struct hclge_vport *vport, bool en_uc_pmc,
+                                bool en_mc_pmc, bool en_bc_pmc)
+{
+       struct hclge_dev *hdev = vport->back;
+       struct hclge_promisc_param param;
+
+       hclge_promisc_param_init(&param, en_uc_pmc, en_mc_pmc, en_bc_pmc,
+                                vport->vport_id);
+       return hclge_cmd_set_promisc_mode(hdev, &param);
+}
+
 static int hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
                                  bool en_mc_pmc)
 {
        struct hclge_vport *vport = hclge_get_vport(handle);
-       struct hclge_dev *hdev = vport->back;
-       struct hclge_promisc_param param;
        bool en_bc_pmc = true;
 
        /* For revision 0x20, if broadcast promisc enabled, vlan filter is
@@ -4652,9 +4756,8 @@ static int hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
        if (handle->pdev->revision == 0x20)
                en_bc_pmc = handle->netdev_flags & HNAE3_BPE ? true : false;
 
-       hclge_promisc_param_init(&param, en_uc_pmc, en_mc_pmc, en_bc_pmc,
-                                vport->vport_id);
-       return hclge_cmd_set_promisc_mode(hdev, &param);
+       return hclge_set_vport_promisc_mode(vport, en_uc_pmc, en_mc_pmc,
+                                           en_bc_pmc);
 }
 
 static int hclge_get_fd_mode(struct hclge_dev *hdev, u8 *fd_mode)
@@ -4756,7 +4859,7 @@ static int hclge_init_fd_config(struct hclge_dev *hdev)
                break;
        default:
                dev_err(&hdev->pdev->dev,
-                       "Unsupported flow director mode %d\n",
+                       "Unsupported flow director mode %u\n",
                        hdev->fd_cfg.fd_mode);
                return -EOPNOTSUPP;
        }
@@ -5086,7 +5189,7 @@ static int hclge_config_key(struct hclge_dev *hdev, u8 stage,
                                   true);
        if (ret) {
                dev_err(&hdev->pdev->dev,
-                       "fd key_y config fail, loc=%d, ret=%d\n",
+                       "fd key_y config fail, loc=%u, ret=%d\n",
                        rule->queue_id, ret);
                return ret;
        }
@@ -5095,7 +5198,7 @@ static int hclge_config_key(struct hclge_dev *hdev, u8 stage,
                                   true);
        if (ret)
                dev_err(&hdev->pdev->dev,
-                       "fd key_x config fail, loc=%d, ret=%d\n",
+                       "fd key_x config fail, loc=%u, ret=%d\n",
                        rule->queue_id, ret);
        return ret;
 }
@@ -5344,7 +5447,7 @@ static int hclge_fd_update_rule_list(struct hclge_dev *hdev,
                }
        } else if (!is_add) {
                dev_err(&hdev->pdev->dev,
-                       "delete fail, rule %d is inexistent\n",
+                       "delete fail, rule %u is inexistent\n",
                        location);
                return -EINVAL;
        }
@@ -5584,7 +5687,7 @@ static int hclge_add_fd_entry(struct hnae3_handle *handle,
 
                if (vf > hdev->num_req_vfs) {
                        dev_err(&hdev->pdev->dev,
-                               "Error: vf id (%d) > max vf num (%d)\n",
+                               "Error: vf id (%u) > max vf num (%u)\n",
                                vf, hdev->num_req_vfs);
                        return -EINVAL;
                }
@@ -5594,7 +5697,7 @@ static int hclge_add_fd_entry(struct hnae3_handle *handle,
 
                if (ring >= tqps) {
                        dev_err(&hdev->pdev->dev,
-                               "Error: queue id (%d) > max tqp num (%d)\n",
+                               "Error: queue id (%u) > max tqp num (%u)\n",
                                ring, tqps - 1);
                        return -EINVAL;
                }
@@ -5653,7 +5756,7 @@ static int hclge_del_fd_entry(struct hnae3_handle *handle,
 
        if (!hclge_fd_rule_exist(hdev, fs->location)) {
                dev_err(&hdev->pdev->dev,
-                       "Delete fail, rule %d is inexistent\n", fs->location);
+                       "Delete fail, rule %u is inexistent\n", fs->location);
                return -ENOENT;
        }
 
@@ -5730,7 +5833,7 @@ static int hclge_restore_fd_entries(struct hnae3_handle *handle)
 
                if (ret) {
                        dev_warn(&hdev->pdev->dev,
-                                "Restore rule %d failed, remove it\n",
+                                "Restore rule %u failed, remove it\n",
                                 rule->location);
                        clear_bit(rule->location, hdev->fd_bmap);
                        hlist_del(&rule->rule_node);
@@ -6723,7 +6826,7 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
 
        if (cmdq_resp) {
                dev_err(&hdev->pdev->dev,
-                       "cmdq execute failed for get_mac_vlan_cmd_status,status=%d.\n",
+                       "cmdq execute failed for get_mac_vlan_cmd_status,status=%u.\n",
                        cmdq_resp);
                return -EIO;
        }
@@ -6975,7 +7078,7 @@ static int hclge_init_umv_space(struct hclge_dev *hdev)
 
        if (allocated_size < hdev->wanted_umv_size)
                dev_warn(&hdev->pdev->dev,
-                        "Alloc umv space failed, want %d, get %d\n",
+                        "Alloc umv space failed, want %u, get %u\n",
                         hdev->wanted_umv_size, allocated_size);
 
        mutex_init(&hdev->umv_mutex);
@@ -7143,7 +7246,7 @@ int hclge_add_uc_addr_common(struct hclge_vport *vport,
 
        /* check if we just hit the duplicate */
        if (!ret) {
-               dev_warn(&hdev->pdev->dev, "VF %d mac(%pM) exists\n",
+               dev_warn(&hdev->pdev->dev, "VF %u mac(%pM) exists\n",
                         vport->vport_id, addr);
                return 0;
        }
@@ -7324,7 +7427,7 @@ void hclge_rm_vport_mac_table(struct hclge_vport *vport, const u8 *mac_addr,
        mc_flag = is_write_tbl && mac_type == HCLGE_MAC_ADDR_MC;
 
        list_for_each_entry_safe(mac_cfg, tmp, list, node) {
-               if (strncmp(mac_cfg->mac_addr, mac_addr, ETH_ALEN) == 0) {
+               if (ether_addr_equal(mac_cfg->mac_addr, mac_addr)) {
                        if (uc_flag && mac_cfg->hd_tbl_status)
                                hclge_rm_uc_addr_common(vport, mac_addr);
 
@@ -7396,7 +7499,7 @@ static int hclge_get_mac_ethertype_cmd_status(struct hclge_dev *hdev,
 
        if (cmdq_resp) {
                dev_err(&hdev->pdev->dev,
-                       "cmdq execute failed for get_mac_ethertype_cmd_status, status=%d.\n",
+                       "cmdq execute failed for get_mac_ethertype_cmd_status, status=%u.\n",
                        cmdq_resp);
                return -EIO;
        }
@@ -7418,7 +7521,7 @@ static int hclge_get_mac_ethertype_cmd_status(struct hclge_dev *hdev,
                break;
        default:
                dev_err(&hdev->pdev->dev,
-                       "add mac ethertype failed for undefined, code=%d.\n",
+                       "add mac ethertype failed for undefined, code=%u.\n",
                        resp_code);
                return_status = -EIO;
        }
@@ -7426,6 +7529,67 @@ static int hclge_get_mac_ethertype_cmd_status(struct hclge_dev *hdev,
        return return_status;
 }
 
+static bool hclge_check_vf_mac_exist(struct hclge_vport *vport, int vf_idx,
+                                    u8 *mac_addr)
+{
+       struct hclge_mac_vlan_tbl_entry_cmd req;
+       struct hclge_dev *hdev = vport->back;
+       struct hclge_desc desc;
+       u16 egress_port = 0;
+       int i;
+
+       if (is_zero_ether_addr(mac_addr))
+               return false;
+
+       memset(&req, 0, sizeof(req));
+       hnae3_set_field(egress_port, HCLGE_MAC_EPORT_VFID_M,
+                       HCLGE_MAC_EPORT_VFID_S, vport->vport_id);
+       req.egress_port = cpu_to_le16(egress_port);
+       hclge_prepare_mac_addr(&req, mac_addr, false);
+
+       if (hclge_lookup_mac_vlan_tbl(vport, &req, &desc, false) != -ENOENT)
+               return true;
+
+       vf_idx += HCLGE_VF_VPORT_START_NUM;
+       for (i = hdev->num_vmdq_vport + 1; i < hdev->num_alloc_vport; i++)
+               if (i != vf_idx &&
+                   ether_addr_equal(mac_addr, hdev->vport[i].vf_info.mac))
+                       return true;
+
+       return false;
+}
+
+static int hclge_set_vf_mac(struct hnae3_handle *handle, int vf,
+                           u8 *mac_addr)
+{
+       struct hclge_vport *vport = hclge_get_vport(handle);
+       struct hclge_dev *hdev = vport->back;
+
+       vport = hclge_get_vf_vport(hdev, vf);
+       if (!vport)
+               return -EINVAL;
+
+       if (ether_addr_equal(mac_addr, vport->vf_info.mac)) {
+               dev_info(&hdev->pdev->dev,
+                        "Specified MAC(=%pM) is same as before, no change committed!\n",
+                        mac_addr);
+               return 0;
+       }
+
+       if (hclge_check_vf_mac_exist(vport, vf, mac_addr)) {
+               dev_err(&hdev->pdev->dev, "Specified MAC(=%pM) exists!\n",
+                       mac_addr);
+               return -EEXIST;
+       }
+
+       ether_addr_copy(vport->vf_info.mac, mac_addr);
+       dev_info(&hdev->pdev->dev,
+                "MAC of VF %d has been set to %pM, and it will be reinitialized!\n",
+                vf, mac_addr);
+
+       return hclge_inform_reset_assert_to_vf(vport);
+}
+
 static int hclge_add_mgr_tbl(struct hclge_dev *hdev,
                             const struct hclge_mac_mgr_tbl_entry_cmd *req)
 {
@@ -7598,7 +7762,7 @@ static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, u16 vfid,
                                    bool is_kill, u16 vlan,
                                    __be16 proto)
 {
-#define HCLGE_MAX_VF_BYTES  16
+       struct hclge_vport *vport = &hdev->vport[vfid];
        struct hclge_vlan_filter_vf_cfg_cmd *req0;
        struct hclge_vlan_filter_vf_cfg_cmd *req1;
        struct hclge_desc desc[2];
@@ -7607,10 +7771,18 @@ static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, u16 vfid,
        int ret;
 
        /* if vf vlan table is full, firmware will close vf vlan filter, it
-        * is unable and unnecessary to add new vlan id to vf vlan filter
+        * is unable and unnecessary to add new vlan id to vf vlan filter.
+        * If spoof check is enable, and vf vlan is full, it shouldn't add
+        * new vlan, because tx packets with these vlan id will be dropped.
         */
-       if (test_bit(vfid, hdev->vf_vlan_full) && !is_kill)
+       if (test_bit(vfid, hdev->vf_vlan_full) && !is_kill) {
+               if (vport->vf_info.spoofchk && vlan) {
+                       dev_err(&hdev->pdev->dev,
+                               "Can't add vlan due to spoof check is on and vf vlan table is full\n");
+                       return -EPERM;
+               }
                return 0;
+       }
 
        hclge_cmd_setup_basic_desc(&desc[0],
                                   HCLGE_OPC_VLAN_FILTER_VF_CFG, false);
@@ -7654,7 +7826,7 @@ static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, u16 vfid,
                }
 
                dev_err(&hdev->pdev->dev,
-                       "Add vf vlan filter fail, ret =%d.\n",
+                       "Add vf vlan filter fail, ret =%u.\n",
                        req0->resp_code);
        } else {
 #define HCLGE_VF_VLAN_DEL_NO_FOUND     1
@@ -7670,7 +7842,7 @@ static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, u16 vfid,
                        return 0;
 
                dev_err(&hdev->pdev->dev,
-                       "Kill vf vlan filter fail, ret =%d.\n",
+                       "Kill vf vlan filter fail, ret =%u.\n",
                        req0->resp_code);
        }
 
@@ -7689,9 +7861,10 @@ static int hclge_set_port_vlan_filter(struct hclge_dev *hdev, __be16 proto,
 
        hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_FILTER_PF_CFG, false);
 
-       vlan_offset_160 = vlan_id / 160;
-       vlan_offset_byte = (vlan_id % 160) / 8;
-       vlan_offset_byte_val = 1 << (vlan_id % 8);
+       vlan_offset_160 = vlan_id / HCLGE_VLAN_ID_OFFSET_STEP;
+       vlan_offset_byte = (vlan_id % HCLGE_VLAN_ID_OFFSET_STEP) /
+                          HCLGE_VLAN_BYTE_SIZE;
+       vlan_offset_byte_val = 1 << (vlan_id % HCLGE_VLAN_BYTE_SIZE);
 
        req = (struct hclge_vlan_filter_pf_cfg_cmd *)desc.data;
        req->vlan_offset = vlan_offset_160;
@@ -7719,7 +7892,7 @@ static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto,
                                       proto);
        if (ret) {
                dev_err(&hdev->pdev->dev,
-                       "Set %d vport vlan filter config fail, ret =%d.\n",
+                       "Set %u vport vlan filter config fail, ret =%d.\n",
                        vport_id, ret);
                return ret;
        }
@@ -7731,7 +7904,7 @@ static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto,
 
        if (!is_kill && test_and_set_bit(vport_id, hdev->vlan_table[vlan_id])) {
                dev_err(&hdev->pdev->dev,
-                       "Add port vlan failed, vport %d is already in vlan %d\n",
+                       "Add port vlan failed, vport %u is already in vlan %u\n",
                        vport_id, vlan_id);
                return -EINVAL;
        }
@@ -7739,7 +7912,7 @@ static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto,
        if (is_kill &&
            !test_and_clear_bit(vport_id, hdev->vlan_table[vlan_id])) {
                dev_err(&hdev->pdev->dev,
-                       "Delete port vlan failed, vport %d is not in vlan %d\n",
+                       "Delete port vlan failed, vport %u is not in vlan %u\n",
                        vport_id, vlan_id);
                return -EINVAL;
        }
@@ -8107,12 +8280,15 @@ static void hclge_restore_vlan_table(struct hnae3_handle *handle)
                }
 
                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,
-                                                        false);
+                       int ret;
+
+                       if (!vlan->hd_tbl_status)
+                               continue;
+                       ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q),
+                                                      vport->vport_id,
+                                                      vlan->vlan_id, false);
+                       if (ret)
+                               break;
                }
        }
 
@@ -8392,6 +8568,7 @@ int hclge_set_vport_mtu(struct hclge_vport *vport, int new_mtu)
        struct hclge_dev *hdev = vport->back;
        int i, max_frm_size, ret;
 
+       /* HW supprt 2 layer vlan */
        max_frm_size = new_mtu + ETH_HLEN + ETH_FCS_LEN + 2 * VLAN_HLEN;
        if (max_frm_size < HCLGE_MAC_MIN_FRAME ||
            max_frm_size > HCLGE_MAC_MAX_FRAME)
@@ -8807,16 +8984,16 @@ static void hclge_info_show(struct hclge_dev *hdev)
 
        dev_info(dev, "PF info begin:\n");
 
-       dev_info(dev, "Task queue pairs numbers: %d\n", hdev->num_tqps);
-       dev_info(dev, "Desc num per TX queue: %d\n", hdev->num_tx_desc);
-       dev_info(dev, "Desc num per RX queue: %d\n", hdev->num_rx_desc);
-       dev_info(dev, "Numbers of vports: %d\n", hdev->num_alloc_vport);
-       dev_info(dev, "Numbers of vmdp vports: %d\n", hdev->num_vmdq_vport);
-       dev_info(dev, "Numbers of VF for this PF: %d\n", hdev->num_req_vfs);
-       dev_info(dev, "HW tc map: %d\n", hdev->hw_tc_map);
-       dev_info(dev, "Total buffer size for TX/RX: %d\n", hdev->pkt_buf_size);
-       dev_info(dev, "TX buffer size for each TC: %d\n", hdev->tx_buf_size);
-       dev_info(dev, "DV buffer size for each TC: %d\n", hdev->dv_buf_size);
+       dev_info(dev, "Task queue pairs numbers: %u\n", hdev->num_tqps);
+       dev_info(dev, "Desc num per TX queue: %u\n", hdev->num_tx_desc);
+       dev_info(dev, "Desc num per RX queue: %u\n", hdev->num_rx_desc);
+       dev_info(dev, "Numbers of vports: %u\n", hdev->num_alloc_vport);
+       dev_info(dev, "Numbers of vmdp vports: %u\n", hdev->num_vmdq_vport);
+       dev_info(dev, "Numbers of VF for this PF: %u\n", hdev->num_req_vfs);
+       dev_info(dev, "HW tc map: 0x%x\n", hdev->hw_tc_map);
+       dev_info(dev, "Total buffer size for TX/RX: %u\n", hdev->pkt_buf_size);
+       dev_info(dev, "TX buffer size for each TC: %u\n", hdev->tx_buf_size);
+       dev_info(dev, "DV buffer size for each TC: %u\n", hdev->dv_buf_size);
        dev_info(dev, "This is %s PF\n",
                 hdev->flag & HCLGE_FLAG_MAIN ? "main" : "not main");
        dev_info(dev, "DCB %s\n",
@@ -8832,10 +9009,9 @@ static int hclge_init_nic_client_instance(struct hnae3_ae_dev *ae_dev,
 {
        struct hnae3_client *client = vport->nic.client;
        struct hclge_dev *hdev = ae_dev->priv;
-       int rst_cnt;
+       int rst_cnt = hdev->rst_stats.reset_cnt;
        int ret;
 
-       rst_cnt = hdev->rst_stats.reset_cnt;
        ret = client->ops->init_instance(&vport->nic);
        if (ret)
                return ret;
@@ -8935,7 +9111,6 @@ static int hclge_init_client_instance(struct hnae3_client *client,
 
                switch (client->type) {
                case HNAE3_CLIENT_KNIC:
-
                        hdev->nic_client = client;
                        vport->nic.client = client;
                        ret = hclge_init_nic_client_instance(ae_dev, vport);
@@ -9134,7 +9309,7 @@ static void hclge_clear_resetting_state(struct hclge_dev *hdev)
                ret = hclge_set_vf_rst(hdev, vport->vport_id, false);
                if (ret)
                        dev_warn(&hdev->pdev->dev,
-                                "clear vf(%d) rst failed %d!\n",
+                                "clear vf(%u) rst failed %d!\n",
                                 vport->vport_id, ret);
        }
 }
@@ -9156,6 +9331,8 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
        hdev->reset_type = HNAE3_NONE_RESET;
        hdev->reset_level = HNAE3_FUNC_RESET;
        ae_dev->priv = hdev;
+
+       /* HW supprt 2 layer vlan */
        hdev->mps = ETH_FRAME_LEN + ETH_FCS_LEN + 2 * VLAN_HLEN;
 
        mutex_init(&hdev->vport_lock);
@@ -9354,6 +9531,219 @@ static void hclge_stats_clear(struct hclge_dev *hdev)
        memset(&hdev->hw_stats, 0, sizeof(hdev->hw_stats));
 }
 
+static int hclge_set_mac_spoofchk(struct hclge_dev *hdev, int vf, bool enable)
+{
+       return hclge_config_switch_param(hdev, vf, enable,
+                                        HCLGE_SWITCH_ANTI_SPOOF_MASK);
+}
+
+static int hclge_set_vlan_spoofchk(struct hclge_dev *hdev, int vf, bool enable)
+{
+       return hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
+                                         HCLGE_FILTER_FE_NIC_INGRESS_B,
+                                         enable, vf);
+}
+
+static int hclge_set_vf_spoofchk_hw(struct hclge_dev *hdev, int vf, bool enable)
+{
+       int ret;
+
+       ret = hclge_set_mac_spoofchk(hdev, vf, enable);
+       if (ret) {
+               dev_err(&hdev->pdev->dev,
+                       "Set vf %d mac spoof check %s failed, ret=%d\n",
+                       vf, enable ? "on" : "off", ret);
+               return ret;
+       }
+
+       ret = hclge_set_vlan_spoofchk(hdev, vf, enable);
+       if (ret)
+               dev_err(&hdev->pdev->dev,
+                       "Set vf %d vlan spoof check %s failed, ret=%d\n",
+                       vf, enable ? "on" : "off", ret);
+
+       return ret;
+}
+
+static int hclge_set_vf_spoofchk(struct hnae3_handle *handle, int vf,
+                                bool enable)
+{
+       struct hclge_vport *vport = hclge_get_vport(handle);
+       struct hclge_dev *hdev = vport->back;
+       u32 new_spoofchk = enable ? 1 : 0;
+       int ret;
+
+       if (hdev->pdev->revision == 0x20)
+               return -EOPNOTSUPP;
+
+       vport = hclge_get_vf_vport(hdev, vf);
+       if (!vport)
+               return -EINVAL;
+
+       if (vport->vf_info.spoofchk == new_spoofchk)
+               return 0;
+
+       if (enable && test_bit(vport->vport_id, hdev->vf_vlan_full))
+               dev_warn(&hdev->pdev->dev,
+                        "vf %d vlan table is full, enable spoof check may cause its packet send fail\n",
+                        vf);
+       else if (enable && hclge_is_umv_space_full(vport))
+               dev_warn(&hdev->pdev->dev,
+                        "vf %d mac table is full, enable spoof check may cause its packet send fail\n",
+                        vf);
+
+       ret = hclge_set_vf_spoofchk_hw(hdev, vport->vport_id, enable);
+       if (ret)
+               return ret;
+
+       vport->vf_info.spoofchk = new_spoofchk;
+       return 0;
+}
+
+static int hclge_reset_vport_spoofchk(struct hclge_dev *hdev)
+{
+       struct hclge_vport *vport = hdev->vport;
+       int ret;
+       int i;
+
+       if (hdev->pdev->revision == 0x20)
+               return 0;
+
+       /* resume the vf spoof check state after reset */
+       for (i = 0; i < hdev->num_alloc_vport; i++) {
+               ret = hclge_set_vf_spoofchk_hw(hdev, vport->vport_id,
+                                              vport->vf_info.spoofchk);
+               if (ret)
+                       return ret;
+
+               vport++;
+       }
+
+       return 0;
+}
+
+static int hclge_set_vf_trust(struct hnae3_handle *handle, int vf, bool enable)
+{
+       struct hclge_vport *vport = hclge_get_vport(handle);
+       struct hclge_dev *hdev = vport->back;
+       u32 new_trusted = enable ? 1 : 0;
+       bool en_bc_pmc;
+       int ret;
+
+       vport = hclge_get_vf_vport(hdev, vf);
+       if (!vport)
+               return -EINVAL;
+
+       if (vport->vf_info.trusted == new_trusted)
+               return 0;
+
+       /* Disable promisc mode for VF if it is not trusted any more. */
+       if (!enable && vport->vf_info.promisc_enable) {
+               en_bc_pmc = hdev->pdev->revision != 0x20;
+               ret = hclge_set_vport_promisc_mode(vport, false, false,
+                                                  en_bc_pmc);
+               if (ret)
+                       return ret;
+               vport->vf_info.promisc_enable = 0;
+               hclge_inform_vf_promisc_info(vport);
+       }
+
+       vport->vf_info.trusted = new_trusted;
+
+       return 0;
+}
+
+static void hclge_reset_vf_rate(struct hclge_dev *hdev)
+{
+       int ret;
+       int vf;
+
+       /* reset vf rate to default value */
+       for (vf = HCLGE_VF_VPORT_START_NUM; vf < hdev->num_alloc_vport; vf++) {
+               struct hclge_vport *vport = &hdev->vport[vf];
+
+               vport->vf_info.max_tx_rate = 0;
+               ret = hclge_tm_qs_shaper_cfg(vport, vport->vf_info.max_tx_rate);
+               if (ret)
+                       dev_err(&hdev->pdev->dev,
+                               "vf%d failed to reset to default, ret=%d\n",
+                               vf - HCLGE_VF_VPORT_START_NUM, ret);
+       }
+}
+
+static int hclge_vf_rate_param_check(struct hclge_dev *hdev, int vf,
+                                    int min_tx_rate, int max_tx_rate)
+{
+       if (min_tx_rate != 0 ||
+           max_tx_rate < 0 || max_tx_rate > hdev->hw.mac.max_speed) {
+               dev_err(&hdev->pdev->dev,
+                       "min_tx_rate:%d [0], max_tx_rate:%d [0, %u]\n",
+                       min_tx_rate, max_tx_rate, hdev->hw.mac.max_speed);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int hclge_set_vf_rate(struct hnae3_handle *handle, int vf,
+                            int min_tx_rate, int max_tx_rate, bool force)
+{
+       struct hclge_vport *vport = hclge_get_vport(handle);
+       struct hclge_dev *hdev = vport->back;
+       int ret;
+
+       ret = hclge_vf_rate_param_check(hdev, vf, min_tx_rate, max_tx_rate);
+       if (ret)
+               return ret;
+
+       vport = hclge_get_vf_vport(hdev, vf);
+       if (!vport)
+               return -EINVAL;
+
+       if (!force && max_tx_rate == vport->vf_info.max_tx_rate)
+               return 0;
+
+       ret = hclge_tm_qs_shaper_cfg(vport, max_tx_rate);
+       if (ret)
+               return ret;
+
+       vport->vf_info.max_tx_rate = max_tx_rate;
+
+       return 0;
+}
+
+static int hclge_resume_vf_rate(struct hclge_dev *hdev)
+{
+       struct hnae3_handle *handle = &hdev->vport->nic;
+       struct hclge_vport *vport;
+       int ret;
+       int vf;
+
+       /* resume the vf max_tx_rate after reset */
+       for (vf = 0; vf < pci_num_vf(hdev->pdev); vf++) {
+               vport = hclge_get_vf_vport(hdev, vf);
+               if (!vport)
+                       return -EINVAL;
+
+               /* zero means max rate, after reset, firmware already set it to
+                * max rate, so just continue.
+                */
+               if (!vport->vf_info.max_tx_rate)
+                       continue;
+
+               ret = hclge_set_vf_rate(handle, vf, 0,
+                                       vport->vf_info.max_tx_rate, true);
+               if (ret) {
+                       dev_err(&hdev->pdev->dev,
+                               "vf%d failed to resume tx_rate:%u, ret=%d\n",
+                               vf, vport->vf_info.max_tx_rate, ret);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
 static void hclge_reset_vport_state(struct hclge_dev *hdev)
 {
        struct hclge_vport *vport = hdev->vport;
@@ -9431,6 +9821,9 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev)
                return ret;
        }
 
+       /* Log and clear the hw errors those already occurred */
+       hclge_handle_all_hns_hw_errors(ae_dev);
+
        /* Re-enable the hw error interrupts because
         * the interrupts get disabled on global reset.
         */
@@ -9453,6 +9846,13 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev)
        }
 
        hclge_reset_vport_state(hdev);
+       ret = hclge_reset_vport_spoofchk(hdev);
+       if (ret)
+               return ret;
+
+       ret = hclge_resume_vf_rate(hdev);
+       if (ret)
+               return ret;
 
        dev_info(&pdev->dev, "Reset done, %s driver initialization finished.\n",
                 HCLGE_DRIVER_NAME);
@@ -9465,6 +9865,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
        struct hclge_dev *hdev = ae_dev->priv;
        struct hclge_mac *mac = &hdev->hw.mac;
 
+       hclge_reset_vf_rate(hdev);
        hclge_misc_affinity_teardown(hdev);
        hclge_state_uninit(hdev);
 
@@ -9529,8 +9930,8 @@ static int hclge_set_channels(struct hnae3_handle *handle, u32 new_tqps_num,
        u16 tc_offset[HCLGE_MAX_TC_NUM] = {0};
        struct hclge_dev *hdev = vport->back;
        u16 tc_size[HCLGE_MAX_TC_NUM] = {0};
-       int cur_rss_size = kinfo->rss_size;
-       int cur_tqps = kinfo->num_tqps;
+       u16 cur_rss_size = kinfo->rss_size;
+       u16 cur_tqps = kinfo->num_tqps;
        u16 tc_valid[HCLGE_MAX_TC_NUM];
        u16 roundup_size;
        u32 *rss_indir;
@@ -9584,7 +9985,7 @@ static int hclge_set_channels(struct hnae3_handle *handle, u32 new_tqps_num,
 out:
        if (!ret)
                dev_info(&hdev->pdev->dev,
-                        "Channels changed, rss_size from %d to %d, tqps from %d to %d",
+                        "Channels changed, rss_size from %u to %u, tqps from %u to %u",
                         cur_rss_size, kinfo->rss_size,
                         cur_tqps, kinfo->rss_size * kinfo->num_tc);
 
@@ -10187,6 +10588,12 @@ static const struct hnae3_ae_ops hclge_ops = {
        .mac_connect_phy = hclge_mac_connect_phy,
        .mac_disconnect_phy = hclge_mac_disconnect_phy,
        .restore_vlan_table = hclge_restore_vlan_table,
+       .get_vf_config = hclge_get_vf_config,
+       .set_vf_link_state = hclge_set_vf_link_state,
+       .set_vf_spoofchk = hclge_set_vf_spoofchk,
+       .set_vf_trust = hclge_set_vf_trust,
+       .set_vf_rate = hclge_set_vf_rate,
+       .set_vf_mac = hclge_set_vf_mac,
 };
 
 static struct hnae3_ae_algo ae_algo = {