diff options
Diffstat (limited to 'drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c')
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 180 |
1 files changed, 150 insertions, 30 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index d553ed7ee64c..1f026408ad38 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -84,6 +84,7 @@ static const struct pci_device_id ae_algo_pci_tbl[] = { {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA), 0}, {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA_MACSEC), 0}, {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_MACSEC), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_200G_RDMA), 0}, /* required last entry */ {0, } }; @@ -622,7 +623,7 @@ static u8 *hclge_tqps_get_strings(struct hnae3_handle *handle, u8 *data) { struct hnae3_knic_private_info *kinfo = &handle->kinfo; u8 *buff = data; - int i = 0; + int i; for (i = 0; i < kinfo->num_tqps; i++) { struct hclge_tqp *tqp = container_of(handle->kinfo.tqp[i], @@ -739,7 +740,7 @@ static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset) if (stringset == ETH_SS_TEST) { /* clear loopback bit flags at first */ handle->flags = (handle->flags & (~HCLGE_LOOPBACK_TEST_FLAGS)); - if (hdev->pdev->revision >= 0x21 || + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2 || hdev->hw.mac.speed == HCLGE_MAC_SPEED_10M || hdev->hw.mac.speed == HCLGE_MAC_SPEED_100M || hdev->hw.mac.speed == HCLGE_MAC_SPEED_1G) { @@ -965,6 +966,9 @@ static int hclge_parse_speed(int speed_cmd, int *speed) case 5: *speed = HCLGE_MAC_SPEED_100G; break; + case 8: + *speed = HCLGE_MAC_SPEED_200G; + break; default: return -EINVAL; } @@ -1004,6 +1008,9 @@ static int hclge_check_port_speed(struct hnae3_handle *handle, u32 speed) case HCLGE_MAC_SPEED_100G: speed_bit = HCLGE_SUPPORT_100G_BIT; break; + case HCLGE_MAC_SPEED_200G: + speed_bit = HCLGE_SUPPORT_200G_BIT; + break; default: return -EINVAL; } @@ -1014,7 +1021,7 @@ static int hclge_check_port_speed(struct hnae3_handle *handle, u32 speed) return -EINVAL; } -static void hclge_convert_setting_sr(struct hclge_mac *mac, u8 speed_ability) +static void hclge_convert_setting_sr(struct hclge_mac *mac, u16 speed_ability) { if (speed_ability & HCLGE_SUPPORT_10G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, @@ -1031,9 +1038,12 @@ static void hclge_convert_setting_sr(struct hclge_mac *mac, u8 speed_ability) if (speed_ability & HCLGE_SUPPORT_100G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, mac->supported); + if (speed_ability & HCLGE_SUPPORT_200G_BIT) + linkmode_set_bit(ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT, + mac->supported); } -static void hclge_convert_setting_lr(struct hclge_mac *mac, u8 speed_ability) +static void hclge_convert_setting_lr(struct hclge_mac *mac, u16 speed_ability) { if (speed_ability & HCLGE_SUPPORT_10G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, @@ -1050,9 +1060,13 @@ static void hclge_convert_setting_lr(struct hclge_mac *mac, u8 speed_ability) if (speed_ability & HCLGE_SUPPORT_100G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, mac->supported); + if (speed_ability & HCLGE_SUPPORT_200G_BIT) + linkmode_set_bit( + ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT, + mac->supported); } -static void hclge_convert_setting_cr(struct hclge_mac *mac, u8 speed_ability) +static void hclge_convert_setting_cr(struct hclge_mac *mac, u16 speed_ability) { if (speed_ability & HCLGE_SUPPORT_10G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseCR_Full_BIT, @@ -1069,9 +1083,12 @@ static void hclge_convert_setting_cr(struct hclge_mac *mac, u8 speed_ability) if (speed_ability & HCLGE_SUPPORT_100G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, mac->supported); + if (speed_ability & HCLGE_SUPPORT_200G_BIT) + linkmode_set_bit(ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, + mac->supported); } -static void hclge_convert_setting_kr(struct hclge_mac *mac, u8 speed_ability) +static void hclge_convert_setting_kr(struct hclge_mac *mac, u16 speed_ability) { if (speed_ability & HCLGE_SUPPORT_1G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, @@ -1091,6 +1108,9 @@ static void hclge_convert_setting_kr(struct hclge_mac *mac, u8 speed_ability) if (speed_ability & HCLGE_SUPPORT_100G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, mac->supported); + if (speed_ability & HCLGE_SUPPORT_200G_BIT) + linkmode_set_bit(ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT, + mac->supported); } static void hclge_convert_setting_fec(struct hclge_mac *mac) @@ -1115,6 +1135,7 @@ static void hclge_convert_setting_fec(struct hclge_mac *mac) BIT(HNAE3_FEC_AUTO); break; case HCLGE_MAC_SPEED_100G: + case HCLGE_MAC_SPEED_200G: linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT, mac->supported); mac->fec_ability = BIT(HNAE3_FEC_RS) | BIT(HNAE3_FEC_AUTO); break; @@ -1125,7 +1146,7 @@ static void hclge_convert_setting_fec(struct hclge_mac *mac) } static void hclge_parse_fiber_link_mode(struct hclge_dev *hdev, - u8 speed_ability) + u16 speed_ability) { struct hclge_mac *mac = &hdev->hw.mac; @@ -1136,7 +1157,7 @@ static void hclge_parse_fiber_link_mode(struct hclge_dev *hdev, hclge_convert_setting_sr(mac, speed_ability); hclge_convert_setting_lr(mac, speed_ability); hclge_convert_setting_cr(mac, speed_ability); - if (hdev->pdev->revision >= 0x21) + if (hnae3_dev_fec_supported(hdev)) hclge_convert_setting_fec(mac); linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, mac->supported); @@ -1145,12 +1166,12 @@ static void hclge_parse_fiber_link_mode(struct hclge_dev *hdev, } static void hclge_parse_backplane_link_mode(struct hclge_dev *hdev, - u8 speed_ability) + u16 speed_ability) { struct hclge_mac *mac = &hdev->hw.mac; hclge_convert_setting_kr(mac, speed_ability); - if (hdev->pdev->revision >= 0x21) + if (hnae3_dev_fec_supported(hdev)) hclge_convert_setting_fec(mac); linkmode_set_bit(ETHTOOL_LINK_MODE_Backplane_BIT, mac->supported); linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, mac->supported); @@ -1158,7 +1179,7 @@ static void hclge_parse_backplane_link_mode(struct hclge_dev *hdev, } static void hclge_parse_copper_link_mode(struct hclge_dev *hdev, - u8 speed_ability) + u16 speed_ability) { unsigned long *supported = hdev->hw.mac.supported; @@ -1188,7 +1209,7 @@ static void hclge_parse_copper_link_mode(struct hclge_dev *hdev, linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, supported); } -static void hclge_parse_link_mode(struct hclge_dev *hdev, u8 speed_ability) +static void hclge_parse_link_mode(struct hclge_dev *hdev, u16 speed_ability) { u8 media_type = hdev->hw.mac.media_type; @@ -1200,8 +1221,11 @@ 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) +static u32 hclge_get_max_speed(u16 speed_ability) { + if (speed_ability & HCLGE_SUPPORT_200G_BIT) + return HCLGE_MAC_SPEED_200G; + if (speed_ability & HCLGE_SUPPORT_100G_BIT) return HCLGE_MAC_SPEED_100G; @@ -1231,8 +1255,11 @@ static u32 hclge_get_max_speed(u8 speed_ability) static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc) { +#define SPEED_ABILITY_EXT_SHIFT 8 + struct hclge_cfg_param_cmd *req; u64 mac_addr_tmp_high; + u16 speed_ability_ext; u64 mac_addr_tmp; unsigned int i; @@ -1281,6 +1308,11 @@ static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc) cfg->speed_ability = hnae3_get_field(__le32_to_cpu(req->param[1]), HCLGE_CFG_SPEED_ABILITY_M, HCLGE_CFG_SPEED_ABILITY_S); + speed_ability_ext = hnae3_get_field(__le32_to_cpu(req->param[1]), + HCLGE_CFG_SPEED_ABILITY_EXT_M, + HCLGE_CFG_SPEED_ABILITY_EXT_S); + cfg->speed_ability |= speed_ability_ext << SPEED_ABILITY_EXT_SHIFT; + cfg->umv_space = hnae3_get_field(__le32_to_cpu(req->param[1]), HCLGE_CFG_UMV_TBL_SPACE_M, HCLGE_CFG_UMV_TBL_SPACE_S); @@ -1324,6 +1356,78 @@ static int hclge_get_cfg(struct hclge_dev *hdev, struct hclge_cfg *hcfg) return 0; } +static void hclge_set_default_dev_specs(struct hclge_dev *hdev) +{ +#define HCLGE_MAX_NON_TSO_BD_NUM 8U + + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); + + ae_dev->dev_specs.max_non_tso_bd_num = HCLGE_MAX_NON_TSO_BD_NUM; + ae_dev->dev_specs.rss_ind_tbl_size = HCLGE_RSS_IND_TBL_SIZE; + ae_dev->dev_specs.rss_key_size = HCLGE_RSS_KEY_SIZE; + ae_dev->dev_specs.max_tm_rate = HCLGE_ETHER_MAX_RATE; +} + +static void hclge_parse_dev_specs(struct hclge_dev *hdev, + struct hclge_desc *desc) +{ + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); + struct hclge_dev_specs_0_cmd *req0; + + req0 = (struct hclge_dev_specs_0_cmd *)desc[0].data; + + ae_dev->dev_specs.max_non_tso_bd_num = req0->max_non_tso_bd_num; + ae_dev->dev_specs.rss_ind_tbl_size = + le16_to_cpu(req0->rss_ind_tbl_size); + ae_dev->dev_specs.rss_key_size = le16_to_cpu(req0->rss_key_size); + ae_dev->dev_specs.max_tm_rate = le32_to_cpu(req0->max_tm_rate); +} + +static void hclge_check_dev_specs(struct hclge_dev *hdev) +{ + struct hnae3_dev_specs *dev_specs = &hdev->ae_dev->dev_specs; + + if (!dev_specs->max_non_tso_bd_num) + dev_specs->max_non_tso_bd_num = HCLGE_MAX_NON_TSO_BD_NUM; + if (!dev_specs->rss_ind_tbl_size) + dev_specs->rss_ind_tbl_size = HCLGE_RSS_IND_TBL_SIZE; + if (!dev_specs->rss_key_size) + dev_specs->rss_key_size = HCLGE_RSS_KEY_SIZE; + if (!dev_specs->max_tm_rate) + dev_specs->max_tm_rate = HCLGE_ETHER_MAX_RATE; +} + +static int hclge_query_dev_specs(struct hclge_dev *hdev) +{ + struct hclge_desc desc[HCLGE_QUERY_DEV_SPECS_BD_NUM]; + int ret; + int i; + + /* set default specifications as devices lower than version V3 do not + * support querying specifications from firmware. + */ + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3) { + hclge_set_default_dev_specs(hdev); + return 0; + } + + for (i = 0; i < HCLGE_QUERY_DEV_SPECS_BD_NUM - 1; i++) { + hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_QUERY_DEV_SPECS, + true); + desc[i].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT); + } + hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_QUERY_DEV_SPECS, true); + + ret = hclge_cmd_send(&hdev->hw, desc, HCLGE_QUERY_DEV_SPECS_BD_NUM); + if (ret) + return ret; + + hclge_parse_dev_specs(hdev, desc); + hclge_check_dev_specs(hdev); + + return 0; +} + static int hclge_get_cap(struct hclge_dev *hdev) { int ret; @@ -2422,6 +2526,10 @@ static int hclge_cfg_mac_speed_dup_hw(struct hclge_dev *hdev, int speed, hnae3_set_field(req->speed_dup, HCLGE_CFG_SPEED_M, HCLGE_CFG_SPEED_S, 5); break; + case HCLGE_MAC_SPEED_200G: + hnae3_set_field(req->speed_dup, HCLGE_CFG_SPEED_M, + HCLGE_CFG_SPEED_S, 8); + break; default: dev_err(&hdev->pdev->dev, "invalid speed (%d)\n", speed); return -EINVAL; @@ -2856,7 +2964,7 @@ static int hclge_update_port_info(struct hclge_dev *hdev) if (!hdev->support_sfp_query) return 0; - if (hdev->pdev->revision >= 0x21) + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) ret = hclge_get_sfp_info(hdev, mac); else ret = hclge_get_sfp_speed(hdev, &speed); @@ -2868,7 +2976,7 @@ static int hclge_update_port_info(struct hclge_dev *hdev) return ret; } - if (hdev->pdev->revision >= 0x21) { + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { if (mac->speed_type == QUERY_ACTIVE_SPEED) { hclge_update_port_capability(mac); return 0; @@ -3211,7 +3319,7 @@ static int hclge_notify_roce_client(struct hclge_dev *hdev, enum hnae3_reset_notify_type type) { struct hnae3_client *client = hdev->roce_client; - int ret = 0; + int ret; u16 i; if (!test_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state) || !client) @@ -3533,7 +3641,7 @@ static void hclge_clear_reset_cause(struct hclge_dev *hdev) /* For revision 0x20, the reset interrupt source * can only be cleared after hardware reset done */ - if (hdev->pdev->revision == 0x20) + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, clearval); @@ -3944,6 +4052,9 @@ static void hclge_periodic_service_task(struct hclge_dev *hdev) { unsigned long delta = round_jiffies_relative(HZ); + if (test_bit(HCLGE_STATE_RST_FAIL, &hdev->state)) + return; + /* Always handle the link updating to make sure link state is * updated when it is triggered by mbx. */ @@ -4537,7 +4648,7 @@ static void hclge_rss_init_cfg(struct hclge_dev *hdev) int i, rss_algo = HCLGE_RSS_HASH_ALGO_TOEPLITZ; struct hclge_vport *vport = hdev->vport; - if (hdev->pdev->revision >= 0x21) + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) rss_algo = HCLGE_RSS_HASH_ALGO_SIMPLE; for (i = 0; i < hdev->num_vmdq_vport + 1; i++) { @@ -4737,13 +4848,14 @@ 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; bool en_bc_pmc = true; - /* For revision 0x20, if broadcast promisc enabled, vlan filter is - * always bypassed. So broadcast promisc should be disabled until - * user enable promisc mode + /* For device whose version below V2, if broadcast promisc enabled, + * vlan filter is always bypassed. So broadcast promisc should be + * disabled until user enable promisc mode */ - if (handle->pdev->revision == 0x20) + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) en_bc_pmc = handle->netdev_flags & HNAE3_BPE ? true : false; return hclge_set_vport_promisc_mode(vport, en_uc_pmc, en_mc_pmc, @@ -6758,7 +6870,7 @@ static int hclge_set_loopback(struct hnae3_handle *handle, * the same, the packets are looped back in the SSU. If SSU loopback * is disabled, packets can reach MAC even if SMAC is the same as DMAC. */ - if (hdev->pdev->revision >= 0x21) { + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { u8 switch_param = en ? 0 : BIT(HCLGE_SWITCH_ALW_LPBK_B); ret = hclge_config_switch_param(hdev, PF_VPORT_ID, switch_param, @@ -8260,7 +8372,7 @@ static void hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable) struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; - if (hdev->pdev->revision >= 0x21) { + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, HCLGE_FILTER_FE_EGRESS, enable, 0); hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT, @@ -8620,7 +8732,7 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) int ret; int i; - if (hdev->pdev->revision >= 0x21) { + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { /* for revision 0x21, vf vlan filter is per function */ for (i = 0; i < hdev->num_alloc_vport; i++) { vport = &hdev->vport[i]; @@ -8975,7 +9087,7 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid, u16 state; int ret; - if (hdev->pdev->revision == 0x20) + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) return -EOPNOTSUPP; vport = hclge_get_vf_vport(hdev, vfid); @@ -9950,6 +10062,13 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) if (ret) goto err_cmd_uninit; + ret = hclge_query_dev_specs(hdev); + if (ret) { + dev_err(&pdev->dev, "failed to query dev specifications, ret = %d.\n", + ret); + goto err_cmd_uninit; + } + ret = hclge_configure(hdev); if (ret) { dev_err(&pdev->dev, "Configure dev error, ret = %d.\n", ret); @@ -10147,7 +10266,7 @@ static int hclge_set_vf_spoofchk(struct hnae3_handle *handle, int vf, u32 new_spoofchk = enable ? 1 : 0; int ret; - if (hdev->pdev->revision == 0x20) + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) return -EOPNOTSUPP; vport = hclge_get_vf_vport(hdev, vf); @@ -10180,7 +10299,7 @@ static int hclge_reset_vport_spoofchk(struct hclge_dev *hdev) int ret; int i; - if (hdev->pdev->revision == 0x20) + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) return 0; /* resume the vf spoof check state after reset */ @@ -10200,6 +10319,7 @@ 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; + struct hnae3_ae_dev *ae_dev = hdev->ae_dev; u32 new_trusted = enable ? 1 : 0; bool en_bc_pmc; int ret; @@ -10213,7 +10333,7 @@ static int hclge_set_vf_trust(struct hnae3_handle *handle, int vf, bool enable) /* 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; + en_bc_pmc = ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2; ret = hclge_set_vport_promisc_mode(vport, false, false, en_bc_pmc); if (ret) @@ -11090,7 +11210,7 @@ static void hclge_sync_promisc_mode(struct hclge_dev *hdev) { struct hclge_vport *vport = &hdev->vport[0]; struct hnae3_handle *handle = &vport->nic; - u8 tmp_flags = 0; + u8 tmp_flags; int ret; if (vport->last_promisc_flags != vport->overflow_promisc_flags) { |