X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fhns3%2Fhns3_ethdev.c;h=0b565a561479cc594fbfff691c61a5ecc24183a4;hb=ae5f21f287aa680843363fe526920b70fb8e1fb5;hp=fe46d78f9c48214316fbc748b66f1b5f3483f5e5;hpb=09e0de1f411b36e204233357fc04e520c6a1f892;p=dpdk.git diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c index fe46d78f9c..0b565a5614 100644 --- a/drivers/net/hns3/hns3_ethdev.c +++ b/drivers/net/hns3/hns3_ethdev.c @@ -5,19 +5,16 @@ #include #include #include -#include -#include #include "hns3_ethdev.h" +#include "hns3_common.h" #include "hns3_logs.h" #include "hns3_rxtx.h" #include "hns3_intr.h" #include "hns3_regs.h" #include "hns3_dcb.h" #include "hns3_mp.h" - -#define HNS3_DEFAULT_PORT_CONF_BURST_SIZE 32 -#define HNS3_DEFAULT_PORT_CONF_QUEUES_NUM 1 +#include "hns3_flow.h" #define HNS3_SERVICE_INTERVAL 1000000 /* us */ #define HNS3_SERVICE_QUICK_INTERVAL 10 @@ -63,29 +60,29 @@ enum hns3_evt_cause { }; static const struct rte_eth_fec_capa speed_fec_capa_tbl[] = { - { ETH_SPEED_NUM_10G, RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | + { RTE_ETH_SPEED_NUM_10G, RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) | RTE_ETH_FEC_MODE_CAPA_MASK(BASER) }, - { ETH_SPEED_NUM_25G, RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | + { RTE_ETH_SPEED_NUM_25G, RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) | RTE_ETH_FEC_MODE_CAPA_MASK(BASER) | RTE_ETH_FEC_MODE_CAPA_MASK(RS) }, - { ETH_SPEED_NUM_40G, RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | + { RTE_ETH_SPEED_NUM_40G, RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) | RTE_ETH_FEC_MODE_CAPA_MASK(BASER) }, - { ETH_SPEED_NUM_50G, RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | + { RTE_ETH_SPEED_NUM_50G, RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) | RTE_ETH_FEC_MODE_CAPA_MASK(BASER) | RTE_ETH_FEC_MODE_CAPA_MASK(RS) }, - { ETH_SPEED_NUM_100G, RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | + { RTE_ETH_SPEED_NUM_100G, RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) | RTE_ETH_FEC_MODE_CAPA_MASK(RS) }, - { ETH_SPEED_NUM_200G, RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | + { RTE_ETH_SPEED_NUM_200G, RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) | RTE_ETH_FEC_MODE_CAPA_MASK(RS) } }; @@ -98,22 +95,16 @@ static int hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid, static int hns3_update_link_info(struct rte_eth_dev *eth_dev); static bool hns3_update_link_status(struct hns3_hw *hw); -static int hns3_add_mc_addr(struct hns3_hw *hw, - struct rte_ether_addr *mac_addr); -static int hns3_remove_mc_addr(struct hns3_hw *hw, - struct rte_ether_addr *mac_addr); +static int hns3_add_mc_mac_addr(struct hns3_hw *hw, + struct rte_ether_addr *mac_addr); +static int hns3_remove_mc_mac_addr(struct hns3_hw *hw, + struct rte_ether_addr *mac_addr); static int hns3_restore_fec(struct hns3_hw *hw); static int hns3_query_dev_fec_info(struct hns3_hw *hw); static int hns3_do_stop(struct hns3_adapter *hns); +static int hns3_check_port_speed(struct hns3_hw *hw, uint32_t link_speeds); +static int hns3_cfg_mac_mode(struct hns3_hw *hw, bool enable); -void hns3_ether_format_addr(char *buf, uint16_t size, - const struct rte_ether_addr *ether_addr) -{ - snprintf(buf, size, "%02X:**:**:**:%02X:%02X", - ether_addr->addr_bytes[0], - ether_addr->addr_bytes[4], - ether_addr->addr_bytes[5]); -} static void hns3_pf_disable_irq0(struct hns3_hw *hw) @@ -235,17 +226,11 @@ out: return ret; } -static bool -hns3_is_1588_event_type(uint32_t event_type) -{ - return (event_type == HNS3_VECTOR0_EVENT_PTP); -} - static void hns3_clear_event_cause(struct hns3_hw *hw, uint32_t event_type, uint32_t regclr) { if (event_type == HNS3_VECTOR0_EVENT_RST || - hns3_is_1588_event_type(event_type)) + event_type == HNS3_VECTOR0_EVENT_PTP) hns3_write_dev(hw, HNS3_MISC_RESET_STS_REG, regclr); else if (event_type == HNS3_VECTOR0_EVENT_MBX) hns3_write_dev(hw, HNS3_VECTOR0_CMDQ_SRC_REG, regclr); @@ -255,8 +240,8 @@ static void hns3_clear_all_event_cause(struct hns3_hw *hw) { uint32_t vector0_int_stats; - vector0_int_stats = hns3_read_dev(hw, HNS3_VECTOR0_OTHER_INT_STS_REG); + vector0_int_stats = hns3_read_dev(hw, HNS3_VECTOR0_OTHER_INT_STS_REG); if (BIT(HNS3_VECTOR0_IMPRESET_INT_B) & vector0_int_stats) hns3_warn(hw, "Probe during IMP reset interrupt"); @@ -279,7 +264,7 @@ hns3_handle_mac_tnl(struct hns3_hw *hw) uint32_t status; int ret; - /* query and clear mac tnl interruptions */ + /* query and clear mac tnl interrupt */ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_MAC_TNL_INT, true); ret = hns3_cmd_send(hw, &desc, 1); if (ret) { @@ -319,15 +304,14 @@ hns3_interrupt_handler(void *param) vector0_int = hns3_read_dev(hw, HNS3_VECTOR0_OTHER_INT_STS_REG); ras_int = hns3_read_dev(hw, HNS3_RAS_PF_OTHER_INT_STS_REG); cmdq_int = hns3_read_dev(hw, HNS3_VECTOR0_CMDQ_SRC_REG); + hns3_clear_event_cause(hw, event_cause, clearval); /* vector 0 interrupt is shared with reset and mailbox source events. */ if (event_cause == HNS3_VECTOR0_EVENT_ERR) { hns3_warn(hw, "received interrupt: vector0_int_stat:0x%x " "ras_int_stat:0x%x cmdq_int_stat:0x%x", vector0_int, ras_int, cmdq_int); - hns3_handle_msix_error(hns, &hw->reset.request); - hns3_handle_ras_error(hns, &hw->reset.request); hns3_handle_mac_tnl(hw); - hns3_schedule_reset(hns); + hns3_handle_error(hns); } else if (event_cause == HNS3_VECTOR0_EVENT_RST) { hns3_warn(hw, "received reset interrupt"); hns3_schedule_reset(hns); @@ -339,7 +323,6 @@ hns3_interrupt_handler(void *param) vector0_int, ras_int, cmdq_int); } - hns3_clear_event_cause(hw, event_cause, clearval); /* Enable interrupt if it is not cause by reset */ hns3_pf_enable_irq0(hw); } @@ -463,7 +446,7 @@ hns3_vlan_filter_configure(struct hns3_adapter *hns, uint16_t vlan_id, int on) * When port base vlan enabled, we use port base vlan as the vlan * filter condition. In this case, we don't update vlan filter table * when user add new vlan or remove exist vlan, just update the - * vlan list. The vlan id in vlan list will be writen in vlan filter + * vlan list. The vlan id in vlan list will be written in vlan filter * table until port base vlan disabled */ if (hw->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_DISABLE) { @@ -503,8 +486,8 @@ hns3_vlan_tpid_configure(struct hns3_adapter *hns, enum rte_vlan_type vlan_type, struct hns3_cmd_desc desc; int ret; - if ((vlan_type != ETH_VLAN_TYPE_INNER && - vlan_type != ETH_VLAN_TYPE_OUTER)) { + if ((vlan_type != RTE_ETH_VLAN_TYPE_INNER && + vlan_type != RTE_ETH_VLAN_TYPE_OUTER)) { hns3_err(hw, "Unsupported vlan type, vlan_type =%d", vlan_type); return -EINVAL; } @@ -517,10 +500,10 @@ hns3_vlan_tpid_configure(struct hns3_adapter *hns, enum rte_vlan_type vlan_type, hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_MAC_VLAN_TYPE_ID, false); rx_req = (struct hns3_rx_vlan_type_cfg_cmd *)desc.data; - if (vlan_type == ETH_VLAN_TYPE_OUTER) { + if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER) { rx_req->ot_fst_vlan_type = rte_cpu_to_le_16(tpid); rx_req->ot_sec_vlan_type = rte_cpu_to_le_16(tpid); - } else if (vlan_type == ETH_VLAN_TYPE_INNER) { + } else if (vlan_type == RTE_ETH_VLAN_TYPE_INNER) { rx_req->ot_fst_vlan_type = rte_cpu_to_le_16(tpid); rx_req->ot_sec_vlan_type = rte_cpu_to_le_16(tpid); rx_req->in_fst_vlan_type = rte_cpu_to_le_16(tpid); @@ -584,7 +567,7 @@ hns3_set_vlan_rx_offload_cfg(struct hns3_adapter *hns, hns3_set_bit(req->vport_vlan_cfg, HNS3_SHOW_TAG2_EN_B, vcfg->vlan2_vlan_prionly ? 1 : 0); - /* firmwall will ignore this configuration for PCI_REVISION_ID_HIP08 */ + /* firmware will ignore this configuration for PCI_REVISION_ID_HIP08 */ hns3_set_bit(req->vport_vlan_cfg, HNS3_DISCARD_TAG1_EN_B, vcfg->strip_tag1_discard_en ? 1 : 0); hns3_set_bit(req->vport_vlan_cfg, HNS3_DISCARD_TAG2_EN_B, @@ -604,22 +587,6 @@ hns3_set_vlan_rx_offload_cfg(struct hns3_adapter *hns, return ret; } -static void -hns3_update_rx_offload_cfg(struct hns3_adapter *hns, - struct hns3_rx_vtag_cfg *vcfg) -{ - struct hns3_pf *pf = &hns->pf; - memcpy(&pf->vtag_config.rx_vcfg, vcfg, sizeof(pf->vtag_config.rx_vcfg)); -} - -static void -hns3_update_tx_offload_cfg(struct hns3_adapter *hns, - struct hns3_tx_vtag_cfg *vcfg) -{ - struct hns3_pf *pf = &hns->pf; - memcpy(&pf->vtag_config.tx_vcfg, vcfg, sizeof(pf->vtag_config.tx_vcfg)); -} - static int hns3_en_hw_strip_rxvtag(struct hns3_adapter *hns, bool enable) { @@ -644,11 +611,13 @@ hns3_en_hw_strip_rxvtag(struct hns3_adapter *hns, bool enable) ret = hns3_set_vlan_rx_offload_cfg(hns, &rxvlan_cfg); if (ret) { - hns3_err(hw, "enable strip rx vtag failed, ret =%d", ret); + hns3_err(hw, "%s strip rx vtag failed, ret = %d.", + enable ? "enable" : "disable", ret); return ret; } - hns3_update_rx_offload_cfg(hns, &rxvlan_cfg); + memcpy(&hns->pf.vtag_config.rx_vcfg, &rxvlan_cfg, + sizeof(struct hns3_rx_vtag_cfg)); return ret; } @@ -727,11 +696,11 @@ hns3_vlan_offload_set(struct rte_eth_dev *dev, int mask) rte_spinlock_lock(&hw->lock); rxmode = &dev->data->dev_conf.rxmode; tmp_mask = (unsigned int)mask; - if (tmp_mask & ETH_VLAN_FILTER_MASK) { + if (tmp_mask & RTE_ETH_VLAN_FILTER_MASK) { /* ignore vlan filter configuration during promiscuous mode */ if (!dev->data->promiscuous) { /* Enable or disable VLAN filter */ - enable = rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER ? + enable = rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER ? true : false; ret = hns3_enable_vlan_filter(hns, enable); @@ -744,9 +713,9 @@ hns3_vlan_offload_set(struct rte_eth_dev *dev, int mask) } } - if (tmp_mask & ETH_VLAN_STRIP_MASK) { + if (tmp_mask & RTE_ETH_VLAN_STRIP_MASK) { /* Enable or disable VLAN stripping */ - enable = rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP ? + enable = rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP ? true : false; ret = hns3_en_hw_strip_rxvtag(hns, enable); @@ -793,7 +762,7 @@ hns3_set_vlan_tx_offload_cfg(struct hns3_adapter *hns, vcfg->insert_tag2_en ? 1 : 0); hns3_set_bit(req->vport_vlan_cfg, HNS3_CFG_NIC_ROCE_SEL_B, 0); - /* firmwall will ignore this configuration for PCI_REVISION_ID_HIP08 */ + /* firmware will ignore this configuration for PCI_REVISION_ID_HIP08 */ hns3_set_bit(req->vport_vlan_cfg, HNS3_TAG_SHIFT_MODE_EN_B, vcfg->tag_shift_mode_en ? 1 : 0); @@ -846,7 +815,9 @@ hns3_vlan_txvlan_cfg(struct hns3_adapter *hns, uint16_t port_base_vlan_state, return ret; } - hns3_update_tx_offload_cfg(hns, &txvlan_cfg); + memcpy(&hns->pf.vtag_config.tx_vcfg, &txvlan_cfg, + sizeof(struct hns3_tx_vtag_cfg)); + return ret; } @@ -972,7 +943,9 @@ hns3_en_pvid_strip(struct hns3_adapter *hns, int on) if (ret) return ret; - hns3_update_rx_offload_cfg(hns, &rx_vlan_cfg); + memcpy(&hns->pf.vtag_config.rx_vcfg, &rx_vlan_cfg, + sizeof(struct hns3_rx_vtag_cfg)); + return ret; } @@ -1069,7 +1042,7 @@ hns3_vlan_pvid_set(struct rte_eth_dev *dev, uint16_t pvid, int on) return ret; /* * Only in HNS3_SW_SHIFT_AND_MODE the PVID related operation in Tx/Rx - * need be processed by PMD driver. + * need be processed by PMD. */ if (pvid_en_state_change && hw->vlan_mode == HNS3_SW_SHIFT_AND_DISCARD_MODE) @@ -1120,7 +1093,7 @@ hns3_init_vlan_config(struct hns3_adapter *hns) return ret; } - ret = hns3_vlan_tpid_configure(hns, ETH_VLAN_TYPE_INNER, + ret = hns3_vlan_tpid_configure(hns, RTE_ETH_VLAN_TYPE_INNER, RTE_ETHER_TYPE_VLAN); if (ret) { hns3_err(hw, "tpid set fail in pf, ret =%d", ret); @@ -1163,7 +1136,7 @@ hns3_restore_vlan_conf(struct hns3_adapter *hns) if (!hw->data->promiscuous) { /* restore vlan filter states */ offloads = hw->data->dev_conf.rxmode.offloads; - enable = offloads & DEV_RX_OFFLOAD_VLAN_FILTER ? true : false; + enable = offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER ? true : false; ret = hns3_enable_vlan_filter(hns, enable); if (ret) { hns3_err(hw, "failed to restore vlan rx filter conf, " @@ -1206,7 +1179,7 @@ hns3_dev_configure_vlan(struct rte_eth_dev *dev) txmode->hw_vlan_reject_untagged); /* Apply vlan offload setting */ - mask = ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK; + mask = RTE_ETH_VLAN_STRIP_MASK | RTE_ETH_VLAN_FILTER_MASK; ret = hns3_vlan_offload_set(dev, mask); if (ret) { hns3_err(hw, "dev config rx vlan offload failed, ret = %d", @@ -1429,28 +1402,31 @@ hns3_get_mac_vlan_cmd_status(struct hns3_hw *hw, uint16_t cmdq_resp, static int hns3_lookup_mac_vlan_tbl(struct hns3_hw *hw, struct hns3_mac_vlan_tbl_entry_cmd *req, - struct hns3_cmd_desc *desc, bool is_mc) + struct hns3_cmd_desc *desc, uint8_t desc_num) { uint8_t resp_code; uint16_t retval; int ret; + int i; - hns3_cmd_setup_basic_desc(&desc[0], HNS3_OPC_MAC_VLAN_ADD, true); - if (is_mc) { - desc[0].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); - memcpy(desc[0].data, req, - sizeof(struct hns3_mac_vlan_tbl_entry_cmd)); - hns3_cmd_setup_basic_desc(&desc[1], HNS3_OPC_MAC_VLAN_ADD, - true); - desc[1].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); - hns3_cmd_setup_basic_desc(&desc[2], HNS3_OPC_MAC_VLAN_ADD, + if (desc_num == HNS3_MC_MAC_VLAN_OPS_DESC_NUM) { + for (i = 0; i < desc_num - 1; i++) { + hns3_cmd_setup_basic_desc(&desc[i], + HNS3_OPC_MAC_VLAN_ADD, true); + desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); + if (i == 0) + memcpy(desc[i].data, req, + sizeof(struct hns3_mac_vlan_tbl_entry_cmd)); + } + hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_MAC_VLAN_ADD, true); - ret = hns3_cmd_send(hw, desc, HNS3_MC_MAC_VLAN_ADD_DESC_NUM); } else { + hns3_cmd_setup_basic_desc(&desc[0], HNS3_OPC_MAC_VLAN_ADD, + true); memcpy(desc[0].data, req, sizeof(struct hns3_mac_vlan_tbl_entry_cmd)); - ret = hns3_cmd_send(hw, desc, 1); } + ret = hns3_cmd_send(hw, desc, desc_num); if (ret) { hns3_err(hw, "lookup mac addr failed for cmd_send, ret =%d.", ret); @@ -1466,38 +1442,40 @@ hns3_lookup_mac_vlan_tbl(struct hns3_hw *hw, static int hns3_add_mac_vlan_tbl(struct hns3_hw *hw, struct hns3_mac_vlan_tbl_entry_cmd *req, - struct hns3_cmd_desc *mc_desc) + struct hns3_cmd_desc *desc, uint8_t desc_num) { uint8_t resp_code; uint16_t retval; int cfg_status; int ret; + int i; - if (mc_desc == NULL) { - struct hns3_cmd_desc desc; - - hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_MAC_VLAN_ADD, false); - memcpy(desc.data, req, + if (desc_num == HNS3_UC_MAC_VLAN_OPS_DESC_NUM) { + hns3_cmd_setup_basic_desc(desc, HNS3_OPC_MAC_VLAN_ADD, false); + memcpy(desc->data, req, sizeof(struct hns3_mac_vlan_tbl_entry_cmd)); - ret = hns3_cmd_send(hw, &desc, 1); - resp_code = (rte_le_to_cpu_32(desc.data[0]) >> 8) & 0xff; - retval = rte_le_to_cpu_16(desc.retval); + ret = hns3_cmd_send(hw, desc, desc_num); + resp_code = (rte_le_to_cpu_32(desc->data[0]) >> 8) & 0xff; + retval = rte_le_to_cpu_16(desc->retval); cfg_status = hns3_get_mac_vlan_cmd_status(hw, retval, resp_code, HNS3_MAC_VLAN_ADD); } else { - hns3_cmd_reuse_desc(&mc_desc[0], false); - mc_desc[0].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); - hns3_cmd_reuse_desc(&mc_desc[1], false); - mc_desc[1].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); - hns3_cmd_reuse_desc(&mc_desc[2], false); - mc_desc[2].flag &= rte_cpu_to_le_16(~HNS3_CMD_FLAG_NEXT); - memcpy(mc_desc[0].data, req, + for (i = 0; i < desc_num; i++) { + hns3_cmd_reuse_desc(&desc[i], false); + if (i == desc_num - 1) + desc[i].flag &= + rte_cpu_to_le_16(~HNS3_CMD_FLAG_NEXT); + else + desc[i].flag |= + rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); + } + memcpy(desc[0].data, req, sizeof(struct hns3_mac_vlan_tbl_entry_cmd)); - mc_desc[0].retval = 0; - ret = hns3_cmd_send(hw, mc_desc, HNS3_MC_MAC_VLAN_ADD_DESC_NUM); - resp_code = (rte_le_to_cpu_32(mc_desc[0].data[0]) >> 8) & 0xff; - retval = rte_le_to_cpu_16(mc_desc[0].retval); + desc[0].retval = 0; + ret = hns3_cmd_send(hw, desc, desc_num); + resp_code = (rte_le_to_cpu_32(desc[0].data[0]) >> 8) & 0xff; + retval = rte_le_to_cpu_16(desc[0].retval); cfg_status = hns3_get_mac_vlan_cmd_status(hw, retval, resp_code, HNS3_MAC_VLAN_ADD); @@ -1537,12 +1515,12 @@ hns3_remove_mac_vlan_tbl(struct hns3_hw *hw, } static int -hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) +hns3_add_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) { struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); struct hns3_mac_vlan_tbl_entry_cmd req; struct hns3_pf *pf = &hns->pf; - struct hns3_cmd_desc desc[3]; + struct hns3_cmd_desc desc; char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; uint16_t egress_port = 0; uint8_t vf_id; @@ -1576,10 +1554,12 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) * it if the entry is inexistent. Repeated unicast entry * is not allowed in the mac vlan table. */ - ret = hns3_lookup_mac_vlan_tbl(hw, &req, desc, false); + ret = hns3_lookup_mac_vlan_tbl(hw, &req, &desc, + HNS3_UC_MAC_VLAN_OPS_DESC_NUM); if (ret == -ENOENT) { if (!hns3_is_umv_space_full(hw)) { - ret = hns3_add_mac_vlan_tbl(hw, &req, NULL); + ret = hns3_add_mac_vlan_tbl(hw, &req, &desc, + HNS3_UC_MAC_VLAN_OPS_DESC_NUM); if (!ret) hns3_update_umv_space(hw, false); return ret; @@ -1605,94 +1585,7 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) } static int -hns3_add_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) -{ - char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; - struct rte_ether_addr *addr; - int ret; - int i; - - for (i = 0; i < hw->mc_addrs_num; i++) { - addr = &hw->mc_addrs[i]; - /* Check if there are duplicate addresses */ - if (rte_is_same_ether_addr(addr, mac_addr)) { - hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, - addr); - hns3_err(hw, "failed to add mc mac addr, same addrs" - "(%s) is added by the set_mc_mac_addr_list " - "API", mac_str); - return -EINVAL; - } - } - - ret = hns3_add_mc_addr(hw, mac_addr); - if (ret) { - hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, - mac_addr); - hns3_err(hw, "failed to add mc mac addr(%s), ret = %d", - mac_str, ret); - } - return ret; -} - -static int -hns3_remove_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) -{ - char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; - int ret; - - ret = hns3_remove_mc_addr(hw, mac_addr); - if (ret) { - hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, - mac_addr); - hns3_err(hw, "failed to remove mc mac addr(%s), ret = %d", - mac_str, ret); - } - return ret; -} - -static int -hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, - uint32_t idx, __rte_unused uint32_t pool) -{ - struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); - char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; - int ret; - - rte_spinlock_lock(&hw->lock); - - /* - * In hns3 network engine adding UC and MC mac address with different - * commands with firmware. We need to determine whether the input - * address is a UC or a MC address to call different commands. - * By the way, it is recommended calling the API function named - * rte_eth_dev_set_mc_addr_list to set the MC mac address, because - * using the rte_eth_dev_mac_addr_add API function to set MC mac address - * may affect the specifications of UC mac addresses. - */ - if (rte_is_multicast_ether_addr(mac_addr)) - ret = hns3_add_mc_addr_common(hw, mac_addr); - else - ret = hns3_add_uc_addr_common(hw, mac_addr); - - if (ret) { - rte_spinlock_unlock(&hw->lock); - hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, - mac_addr); - hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str, - ret); - return ret; - } - - if (idx == 0) - hw->mac.default_addr_setted = true; - rte_spinlock_unlock(&hw->lock); - - return ret; -} - -static int -hns3_remove_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) +hns3_remove_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) { struct hns3_mac_vlan_tbl_entry_cmd req; char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; @@ -1719,30 +1612,6 @@ hns3_remove_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) return ret; } -static void -hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx) -{ - struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); - /* index will be checked by upper level rte interface */ - struct rte_ether_addr *mac_addr = &dev->data->mac_addrs[idx]; - char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; - int ret; - - rte_spinlock_lock(&hw->lock); - - if (rte_is_multicast_ether_addr(mac_addr)) - ret = hns3_remove_mc_addr_common(hw, mac_addr); - else - ret = hns3_remove_uc_addr_common(hw, mac_addr); - rte_spinlock_unlock(&hw->lock); - if (ret) { - hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, - mac_addr); - hns3_err(hw, "failed to remove mac addr(%s), ret = %d", mac_str, - ret); - } -} - static int hns3_set_default_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr) @@ -1750,33 +1619,22 @@ hns3_set_default_mac_addr(struct rte_eth_dev *dev, struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct rte_ether_addr *oaddr; char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; - bool default_addr_setted; - bool rm_succes = false; int ret, ret_val; - /* - * It has been guaranteed that input parameter named mac_addr is valid - * address in the rte layer of DPDK framework. - */ + rte_spinlock_lock(&hw->lock); oaddr = (struct rte_ether_addr *)hw->mac.mac_addr; - default_addr_setted = hw->mac.default_addr_setted; - if (default_addr_setted && !!rte_is_same_ether_addr(mac_addr, oaddr)) - return 0; + ret = hw->ops.del_uc_mac_addr(hw, oaddr); + if (ret) { + hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + oaddr); + hns3_warn(hw, "Remove old uc mac address(%s) fail: %d", + mac_str, ret); - rte_spinlock_lock(&hw->lock); - if (default_addr_setted) { - ret = hns3_remove_uc_addr_common(hw, oaddr); - if (ret) { - hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, - oaddr); - hns3_warn(hw, "Remove old uc mac address(%s) fail: %d", - mac_str, ret); - rm_succes = false; - } else - rm_succes = true; + rte_spinlock_unlock(&hw->lock); + return ret; } - ret = hns3_add_uc_addr_common(hw, mac_addr); + ret = hw->ops.add_uc_mac_addr(hw, mac_addr); if (ret) { hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, mac_addr); @@ -1792,13 +1650,12 @@ hns3_set_default_mac_addr(struct rte_eth_dev *dev, rte_ether_addr_copy(mac_addr, (struct rte_ether_addr *)hw->mac.mac_addr); - hw->mac.default_addr_setted = true; rte_spinlock_unlock(&hw->lock); return 0; err_pause_addr_cfg: - ret_val = hns3_remove_uc_addr_common(hw, mac_addr); + ret_val = hw->ops.del_uc_mac_addr(hw, mac_addr); if (ret_val) { hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, mac_addr); @@ -1808,55 +1665,17 @@ err_pause_addr_cfg: } err_add_uc_addr: - if (rm_succes) { - ret_val = hns3_add_uc_addr_common(hw, oaddr); - if (ret_val) { - hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, - oaddr); - hns3_warn(hw, - "Failed to restore old uc mac addr(%s): %d", + ret_val = hw->ops.add_uc_mac_addr(hw, oaddr); + if (ret_val) { + hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, oaddr); + hns3_warn(hw, "Failed to restore old uc mac addr(%s): %d", mac_str, ret_val); - hw->mac.default_addr_setted = false; - } } rte_spinlock_unlock(&hw->lock); return ret; } -static int -hns3_configure_all_mac_addr(struct hns3_adapter *hns, bool del) -{ - char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; - struct hns3_hw *hw = &hns->hw; - struct rte_ether_addr *addr; - int err = 0; - int ret; - int i; - - for (i = 0; i < HNS3_UC_MACADDR_NUM; i++) { - addr = &hw->data->mac_addrs[i]; - if (rte_is_zero_ether_addr(addr)) - continue; - if (rte_is_multicast_ether_addr(addr)) - ret = del ? hns3_remove_mc_addr(hw, addr) : - hns3_add_mc_addr(hw, addr); - else - ret = del ? hns3_remove_uc_addr_common(hw, addr) : - hns3_add_uc_addr_common(hw, addr); - - if (ret) { - err = ret; - hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, - addr); - hns3_err(hw, "failed to %s mac addr(%s) index:%d " - "ret = %d.", del ? "remove" : "restore", - mac_str, i, ret); - } - } - return err; -} - static void hns3_update_desc_vfid(struct hns3_cmd_desc *desc, uint8_t vfid, bool clr) { @@ -1886,10 +1705,10 @@ hns3_update_desc_vfid(struct hns3_cmd_desc *desc, uint8_t vfid, bool clr) } static int -hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) +hns3_add_mc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) { + struct hns3_cmd_desc desc[HNS3_MC_MAC_VLAN_OPS_DESC_NUM]; struct hns3_mac_vlan_tbl_entry_cmd req; - struct hns3_cmd_desc desc[3]; char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; uint8_t vf_id; int ret; @@ -1906,7 +1725,8 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) memset(&req, 0, sizeof(req)); hns3_set_bit(req.entry_type, HNS3_MAC_VLAN_BIT0_EN_B, 0); hns3_prepare_mac_addr(&req, mac_addr->addr_bytes, true); - ret = hns3_lookup_mac_vlan_tbl(hw, &req, desc, true); + ret = hns3_lookup_mac_vlan_tbl(hw, &req, desc, + HNS3_MC_MAC_VLAN_OPS_DESC_NUM); if (ret) { /* This mac addr do not exist, add new entry for it */ memset(desc[0].data, 0, sizeof(desc[0].data)); @@ -1920,7 +1740,8 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) */ vf_id = HNS3_PF_FUNC_ID; hns3_update_desc_vfid(desc, vf_id, false); - ret = hns3_add_mac_vlan_tbl(hw, &req, desc); + ret = hns3_add_mac_vlan_tbl(hw, &req, desc, + HNS3_MC_MAC_VLAN_OPS_DESC_NUM); if (ret) { if (ret == -ENOSPC) hns3_err(hw, "mc mac vlan table is full"); @@ -1933,7 +1754,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) } static int -hns3_remove_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) +hns3_remove_mc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) { struct hns3_mac_vlan_tbl_entry_cmd req; struct hns3_cmd_desc desc[3]; @@ -1953,7 +1774,8 @@ hns3_remove_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) memset(&req, 0, sizeof(req)); hns3_set_bit(req.entry_type, HNS3_MAC_VLAN_BIT0_EN_B, 0); hns3_prepare_mac_addr(&req, mac_addr->addr_bytes, true); - ret = hns3_lookup_mac_vlan_tbl(hw, &req, desc, true); + ret = hns3_lookup_mac_vlan_tbl(hw, &req, desc, + HNS3_MC_MAC_VLAN_OPS_DESC_NUM); if (ret == 0) { /* * This mac addr exist, remove this handle's VFID for it. @@ -1979,238 +1801,6 @@ hns3_remove_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) return ret; } -static int -hns3_set_mc_addr_chk_param(struct hns3_hw *hw, - struct rte_ether_addr *mc_addr_set, - uint32_t nb_mc_addr) -{ - char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; - struct rte_ether_addr *addr; - uint32_t i; - uint32_t j; - - if (nb_mc_addr > HNS3_MC_MACADDR_NUM) { - hns3_err(hw, "failed to set mc mac addr, nb_mc_addr(%u) " - "invalid. valid range: 0~%d", - nb_mc_addr, HNS3_MC_MACADDR_NUM); - return -EINVAL; - } - - /* Check if input mac addresses are valid */ - for (i = 0; i < nb_mc_addr; i++) { - addr = &mc_addr_set[i]; - if (!rte_is_multicast_ether_addr(addr)) { - hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, - addr); - hns3_err(hw, - "failed to set mc mac addr, addr(%s) invalid.", - mac_str); - return -EINVAL; - } - - /* Check if there are duplicate addresses */ - for (j = i + 1; j < nb_mc_addr; j++) { - if (rte_is_same_ether_addr(addr, &mc_addr_set[j])) { - hns3_ether_format_addr(mac_str, - RTE_ETHER_ADDR_FMT_SIZE, - addr); - hns3_err(hw, "failed to set mc mac addr, " - "addrs invalid. two same addrs(%s).", - mac_str); - return -EINVAL; - } - } - - /* - * Check if there are duplicate addresses between mac_addrs - * and mc_addr_set - */ - for (j = 0; j < HNS3_UC_MACADDR_NUM; j++) { - if (rte_is_same_ether_addr(addr, - &hw->data->mac_addrs[j])) { - hns3_ether_format_addr(mac_str, - RTE_ETHER_ADDR_FMT_SIZE, - addr); - hns3_err(hw, "failed to set mc mac addr, " - "addrs invalid. addrs(%s) has already " - "configured in mac_addr add API", - mac_str); - return -EINVAL; - } - } - } - - return 0; -} - -static void -hns3_set_mc_addr_calc_addr(struct hns3_hw *hw, - struct rte_ether_addr *mc_addr_set, - int mc_addr_num, - struct rte_ether_addr *reserved_addr_list, - int *reserved_addr_num, - struct rte_ether_addr *add_addr_list, - int *add_addr_num, - struct rte_ether_addr *rm_addr_list, - int *rm_addr_num) -{ - struct rte_ether_addr *addr; - int current_addr_num; - int reserved_num = 0; - int add_num = 0; - int rm_num = 0; - int num; - int i; - int j; - bool same_addr; - - /* Calculate the mc mac address list that should be removed */ - current_addr_num = hw->mc_addrs_num; - for (i = 0; i < current_addr_num; i++) { - addr = &hw->mc_addrs[i]; - same_addr = false; - for (j = 0; j < mc_addr_num; j++) { - if (rte_is_same_ether_addr(addr, &mc_addr_set[j])) { - same_addr = true; - break; - } - } - - if (!same_addr) { - rte_ether_addr_copy(addr, &rm_addr_list[rm_num]); - rm_num++; - } else { - rte_ether_addr_copy(addr, - &reserved_addr_list[reserved_num]); - reserved_num++; - } - } - - /* Calculate the mc mac address list that should be added */ - for (i = 0; i < mc_addr_num; i++) { - addr = &mc_addr_set[i]; - same_addr = false; - for (j = 0; j < current_addr_num; j++) { - if (rte_is_same_ether_addr(addr, &hw->mc_addrs[j])) { - same_addr = true; - break; - } - } - - if (!same_addr) { - rte_ether_addr_copy(addr, &add_addr_list[add_num]); - add_num++; - } - } - - /* Reorder the mc mac address list maintained by driver */ - for (i = 0; i < reserved_num; i++) - rte_ether_addr_copy(&reserved_addr_list[i], &hw->mc_addrs[i]); - - for (i = 0; i < rm_num; i++) { - num = reserved_num + i; - rte_ether_addr_copy(&rm_addr_list[i], &hw->mc_addrs[num]); - } - - *reserved_addr_num = reserved_num; - *add_addr_num = add_num; - *rm_addr_num = rm_num; -} - -static int -hns3_set_mc_mac_addr_list(struct rte_eth_dev *dev, - struct rte_ether_addr *mc_addr_set, - uint32_t nb_mc_addr) -{ - struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); - struct rte_ether_addr reserved_addr_list[HNS3_MC_MACADDR_NUM]; - struct rte_ether_addr add_addr_list[HNS3_MC_MACADDR_NUM]; - struct rte_ether_addr rm_addr_list[HNS3_MC_MACADDR_NUM]; - struct rte_ether_addr *addr; - int reserved_addr_num; - int add_addr_num; - int rm_addr_num; - int mc_addr_num; - int num; - int ret; - int i; - - /* Check if input parameters are valid */ - ret = hns3_set_mc_addr_chk_param(hw, mc_addr_set, nb_mc_addr); - if (ret) - return ret; - - rte_spinlock_lock(&hw->lock); - - /* - * Calculate the mc mac address lists those should be removed and be - * added, Reorder the mc mac address list maintained by driver. - */ - mc_addr_num = (int)nb_mc_addr; - hns3_set_mc_addr_calc_addr(hw, mc_addr_set, mc_addr_num, - reserved_addr_list, &reserved_addr_num, - add_addr_list, &add_addr_num, - rm_addr_list, &rm_addr_num); - - /* Remove mc mac addresses */ - for (i = 0; i < rm_addr_num; i++) { - num = rm_addr_num - i - 1; - addr = &rm_addr_list[num]; - ret = hns3_remove_mc_addr(hw, addr); - if (ret) { - rte_spinlock_unlock(&hw->lock); - return ret; - } - hw->mc_addrs_num--; - } - - /* Add mc mac addresses */ - for (i = 0; i < add_addr_num; i++) { - addr = &add_addr_list[i]; - ret = hns3_add_mc_addr(hw, addr); - if (ret) { - rte_spinlock_unlock(&hw->lock); - return ret; - } - - num = reserved_addr_num + i; - rte_ether_addr_copy(addr, &hw->mc_addrs[num]); - hw->mc_addrs_num++; - } - rte_spinlock_unlock(&hw->lock); - - return 0; -} - -static int -hns3_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del) -{ - char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; - struct hns3_hw *hw = &hns->hw; - struct rte_ether_addr *addr; - int err = 0; - int ret; - int i; - - for (i = 0; i < hw->mc_addrs_num; i++) { - addr = &hw->mc_addrs[i]; - if (!rte_is_multicast_ether_addr(addr)) - continue; - if (del) - ret = hns3_remove_mc_addr(hw, addr); - else - ret = hns3_add_mc_addr(hw, addr); - if (ret) { - err = ret; - hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, - addr); - hns3_dbg(hw, "%s mc mac addr: %s failed for pf: ret = %d", - del ? "Remove" : "Restore", mac_str, ret); - } - } - return err; -} - static int hns3_check_mq_mode(struct rte_eth_dev *dev) { @@ -2224,24 +1814,17 @@ hns3_check_mq_mode(struct rte_eth_dev *dev) int max_tc = 0; int i; - dcb_rx_conf = &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf; - dcb_tx_conf = &dev->data->dev_conf.tx_adv_conf.dcb_tx_conf; - - if (rx_mq_mode == ETH_MQ_RX_VMDQ_DCB_RSS) { - hns3_err(hw, "ETH_MQ_RX_VMDQ_DCB_RSS is not supported. " - "rx_mq_mode = %d", rx_mq_mode); - return -EINVAL; - } - - if (rx_mq_mode == ETH_MQ_RX_VMDQ_DCB || - tx_mq_mode == ETH_MQ_TX_VMDQ_DCB) { - hns3_err(hw, "ETH_MQ_RX_VMDQ_DCB and ETH_MQ_TX_VMDQ_DCB " - "is not supported. rx_mq_mode = %d, tx_mq_mode = %d", + if (((uint32_t)rx_mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) || + (tx_mq_mode == RTE_ETH_MQ_TX_VMDQ_DCB || + tx_mq_mode == RTE_ETH_MQ_TX_VMDQ_ONLY)) { + hns3_err(hw, "VMDQ is not supported, rx_mq_mode = %d, tx_mq_mode = %d.", rx_mq_mode, tx_mq_mode); - return -EINVAL; + return -EOPNOTSUPP; } - if (rx_mq_mode == ETH_MQ_RX_DCB_RSS) { + dcb_rx_conf = &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf; + dcb_tx_conf = &dev->data->dev_conf.tx_adv_conf.dcb_tx_conf; + if ((uint32_t)rx_mq_mode & RTE_ETH_MQ_RX_DCB_FLAG) { if (dcb_rx_conf->nb_tcs > pf->tc_max) { hns3_err(hw, "nb_tcs(%u) > max_tc(%u) driver supported.", dcb_rx_conf->nb_tcs, pf->tc_max); @@ -2250,7 +1833,7 @@ hns3_check_mq_mode(struct rte_eth_dev *dev) if (!(dcb_rx_conf->nb_tcs == HNS3_4_TCS || dcb_rx_conf->nb_tcs == HNS3_8_TCS)) { - hns3_err(hw, "on ETH_MQ_RX_DCB_RSS mode, " + hns3_err(hw, "on RTE_ETH_MQ_RX_DCB_RSS mode, " "nb_tcs(%d) != %d or %d in rx direction.", dcb_rx_conf->nb_tcs, HNS3_4_TCS, HNS3_8_TCS); return -EINVAL; @@ -2284,25 +1867,6 @@ hns3_check_mq_mode(struct rte_eth_dev *dev) return 0; } -static int -hns3_check_dcb_cfg(struct rte_eth_dev *dev) -{ - struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - if (!hns3_dev_dcb_supported(hw)) { - hns3_err(hw, "this port does not support dcb configurations."); - return -EOPNOTSUPP; - } - - if (hw->current_fc_status == HNS3_FC_STATUS_MAC_PAUSE) { - hns3_err(hw, "MAC pause enabled, cannot config dcb info."); - return -EOPNOTSUPP; - } - - /* Check multiple queue mode */ - return hns3_check_mq_mode(dev); -} - static int hns3_bind_ring_with_vector(struct hns3_hw *hw, uint16_t vector_id, bool en, enum hns3_ring_type queue_type, uint16_t queue_id) @@ -2348,94 +1912,64 @@ hns3_bind_ring_with_vector(struct hns3_hw *hw, uint16_t vector_id, bool en, } static int -hns3_init_ring_with_vector(struct hns3_hw *hw) +hns3_setup_dcb(struct rte_eth_dev *dev) { - uint16_t vec; + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; int ret; - int i; - - /* - * In hns3 network engine, vector 0 is always the misc interrupt of this - * function, vector 1~N can be used respectively for the queues of the - * function. Tx and Rx queues with the same number share the interrupt - * vector. In the initialization clearing the all hardware mapping - * relationship configurations between queues and interrupt vectors is - * needed, so some error caused by the residual configurations, such as - * the unexpected Tx interrupt, can be avoid. - */ - vec = hw->num_msi - 1; /* vector 0 for misc interrupt, not for queue */ - if (hw->intr.mapping_mode == HNS3_INTR_MAPPING_VEC_RSV_ONE) - vec = vec - 1; /* the last interrupt is reserved */ - hw->intr_tqps_num = RTE_MIN(vec, hw->tqps_num); - for (i = 0; i < hw->intr_tqps_num; i++) { - /* - * Set gap limiter/rate limiter/quanity limiter algorithm - * configuration for interrupt coalesce of queue's interrupt. - */ - hns3_set_queue_intr_gl(hw, i, HNS3_RING_GL_RX, - HNS3_TQP_INTR_GL_DEFAULT); - hns3_set_queue_intr_gl(hw, i, HNS3_RING_GL_TX, - HNS3_TQP_INTR_GL_DEFAULT); - hns3_set_queue_intr_rl(hw, i, HNS3_TQP_INTR_RL_DEFAULT); - /* - * QL(quantity limiter) is not used currently, just set 0 to - * close it. - */ - hns3_set_queue_intr_ql(hw, i, HNS3_TQP_INTR_QL_DEFAULT); - ret = hns3_bind_ring_with_vector(hw, vec, false, - HNS3_RING_TYPE_TX, i); - if (ret) { - PMD_INIT_LOG(ERR, "PF fail to unbind TX ring(%d) with " - "vector: %u, ret=%d", i, vec, ret); - return ret; - } + if (!hns3_dev_get_support(hw, DCB)) { + hns3_err(hw, "this port does not support dcb configurations."); + return -EOPNOTSUPP; + } - ret = hns3_bind_ring_with_vector(hw, vec, false, - HNS3_RING_TYPE_RX, i); - if (ret) { - PMD_INIT_LOG(ERR, "PF fail to unbind RX ring(%d) with " - "vector: %u, ret=%d", i, vec, ret); - return ret; - } + if (hw->current_fc_status == HNS3_FC_STATUS_MAC_PAUSE) { + hns3_err(hw, "MAC pause enabled, cannot config dcb info."); + return -EOPNOTSUPP; } - return 0; + ret = hns3_dcb_configure(hns); + if (ret) + hns3_err(hw, "failed to config dcb: %d", ret); + + return ret; } static int -hns3_refresh_mtu(struct rte_eth_dev *dev, struct rte_eth_conf *conf) +hns3_check_link_speed(struct hns3_hw *hw, uint32_t link_speeds) { - struct hns3_adapter *hns = dev->data->dev_private; - struct hns3_hw *hw = &hns->hw; - uint32_t max_rx_pkt_len; - uint16_t mtu; int ret; - if (!(conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME)) - return 0; - /* - * If jumbo frames are enabled, MTU needs to be refreshed - * according to the maximum RX packet length. + * Some hardware doesn't support auto-negotiation, but users may not + * configure link_speeds (default 0), which means auto-negotiation. + * In this case, it should return success. */ - max_rx_pkt_len = conf->rxmode.max_rx_pkt_len; - if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN || - max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) { - hns3_err(hw, "maximum Rx packet length must be greater than %u " - "and no more than %u when jumbo frame enabled.", - (uint16_t)HNS3_DEFAULT_FRAME_LEN, - (uint16_t)HNS3_MAX_FRAME_LEN); - return -EINVAL; + if (link_speeds == RTE_ETH_LINK_SPEED_AUTONEG && + hw->mac.support_autoneg == 0) + return 0; + + if (link_speeds != RTE_ETH_LINK_SPEED_AUTONEG) { + ret = hns3_check_port_speed(hw, link_speeds); + if (ret) + return ret; } - mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len); - ret = hns3_dev_mtu_set(dev, mtu); + return 0; +} + +static int +hns3_check_dev_conf(struct rte_eth_dev *dev) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct rte_eth_conf *conf = &dev->data->dev_conf; + int ret; + + ret = hns3_check_mq_mode(dev); if (ret) return ret; - dev->data->mtu = mtu; - return 0; + return hns3_check_link_speed(hw, conf->link_speeds); } static int @@ -2463,40 +1997,34 @@ hns3_dev_configure(struct rte_eth_dev *dev) * work as usual. But these fake queues are imperceptible, and can not * be used by upper applications. */ - if (!hns3_dev_indep_txrx_supported(hw)) { - ret = hns3_set_fake_rx_or_tx_queues(dev, nb_rx_q, nb_tx_q); - if (ret) { - hns3_err(hw, "fail to set Rx/Tx fake queues, ret = %d.", - ret); - return ret; - } + ret = hns3_set_fake_rx_or_tx_queues(dev, nb_rx_q, nb_tx_q); + if (ret) { + hns3_err(hw, "fail to set Rx/Tx fake queues, ret = %d.", ret); + hw->cfg_max_queues = 0; + return ret; } hw->adapter_state = HNS3_NIC_CONFIGURING; - if (conf->link_speeds & ETH_LINK_SPEED_FIXED) { - hns3_err(hw, "setting link speed/duplex not supported"); - ret = -EINVAL; + ret = hns3_check_dev_conf(dev); + if (ret) goto cfg_err; - } - if ((uint32_t)mq_mode & ETH_MQ_RX_DCB_FLAG) { - ret = hns3_check_dcb_cfg(dev); + if ((uint32_t)mq_mode & RTE_ETH_MQ_RX_DCB_FLAG) { + ret = hns3_setup_dcb(dev); if (ret) goto cfg_err; } - /* When RSS is not configured, redirect the packet queue 0 */ - if ((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG) { - conf->rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH; + if ((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) { + conf->rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH; rss_conf = conf->rx_adv_conf.rss_conf; - hw->rss_dis_flag = false; ret = hns3_dev_rss_hash_update(dev, &rss_conf); if (ret) goto cfg_err; } - ret = hns3_refresh_mtu(dev, conf); - if (ret) + ret = hns3_dev_mtu_set(dev, conf->rxmode.mtu); + if (ret != 0) goto cfg_err; ret = hns3_mbuf_dyn_rx_timestamp_register(dev, conf); @@ -2508,7 +2036,7 @@ hns3_dev_configure(struct rte_eth_dev *dev) goto cfg_err; /* config hardware GRO */ - gro_en = conf->rxmode.offloads & DEV_RX_OFFLOAD_TCP_LRO ? true : false; + gro_en = conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO ? true : false; ret = hns3_config_gro(hw, gro_en); if (ret) goto cfg_err; @@ -2519,6 +2047,7 @@ hns3_dev_configure(struct rte_eth_dev *dev) return 0; cfg_err: + hw->cfg_max_queues = 0; (void)hns3_set_fake_rx_or_tx_queues(dev, 0, 0); hw->adapter_state = HNS3_NIC_INITIALIZED; @@ -2544,7 +2073,6 @@ static int hns3_config_mtu(struct hns3_hw *hw, uint16_t mps) { struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); - uint16_t original_mps = hns->pf.mps; int err; int ret; @@ -2554,22 +2082,20 @@ hns3_config_mtu(struct hns3_hw *hw, uint16_t mps) return ret; } - hns->pf.mps = mps; ret = hns3_buffer_alloc(hw); if (ret) { hns3_err(hw, "failed to allocate buffer, ret = %d", ret); goto rollback; } + hns->pf.mps = mps; + return 0; rollback: - err = hns3_set_mac_mtu(hw, original_mps); - if (err) { + err = hns3_set_mac_mtu(hw, hns->pf.mps); + if (err) hns3_err(hw, "fail to rollback MTU, err = %d", err); - return ret; - } - hns->pf.mps = original_mps; return ret; } @@ -2580,7 +2106,6 @@ hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) struct hns3_adapter *hns = dev->data->dev_private; uint32_t frame_size = mtu + HNS3_ETH_OVERHEAD; struct hns3_hw *hw = &hns->hw; - bool is_jumbo_frame; int ret; if (dev->data->dev_started) { @@ -2590,7 +2115,6 @@ hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) } rte_spinlock_lock(&hw->lock); - is_jumbo_frame = frame_size > HNS3_DEFAULT_FRAME_LEN ? true : false; frame_size = RTE_MAX(frame_size, HNS3_DEFAULT_FRAME_LEN); /* @@ -2605,13 +2129,6 @@ hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) return ret; } - if (is_jumbo_frame) - dev->data->dev_conf.rxmode.offloads |= - DEV_RX_OFFLOAD_JUMBO_FRAME; - else - dev->data->dev_conf.rxmode.offloads &= - ~DEV_RX_OFFLOAD_JUMBO_FRAME; - dev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size; rte_spinlock_unlock(&hw->lock); return 0; @@ -2623,15 +2140,15 @@ hns3_get_copper_port_speed_capa(uint32_t supported_speed) uint32_t speed_capa = 0; if (supported_speed & HNS3_PHY_LINK_SPEED_10M_HD_BIT) - speed_capa |= ETH_LINK_SPEED_10M_HD; + speed_capa |= RTE_ETH_LINK_SPEED_10M_HD; if (supported_speed & HNS3_PHY_LINK_SPEED_10M_BIT) - speed_capa |= ETH_LINK_SPEED_10M; + speed_capa |= RTE_ETH_LINK_SPEED_10M; if (supported_speed & HNS3_PHY_LINK_SPEED_100M_HD_BIT) - speed_capa |= ETH_LINK_SPEED_100M_HD; + speed_capa |= RTE_ETH_LINK_SPEED_100M_HD; if (supported_speed & HNS3_PHY_LINK_SPEED_100M_BIT) - speed_capa |= ETH_LINK_SPEED_100M; + speed_capa |= RTE_ETH_LINK_SPEED_100M; if (supported_speed & HNS3_PHY_LINK_SPEED_1000M_BIT) - speed_capa |= ETH_LINK_SPEED_1G; + speed_capa |= RTE_ETH_LINK_SPEED_1G; return speed_capa; } @@ -2642,24 +2159,24 @@ hns3_get_firber_port_speed_capa(uint32_t supported_speed) uint32_t speed_capa = 0; if (supported_speed & HNS3_FIBER_LINK_SPEED_1G_BIT) - speed_capa |= ETH_LINK_SPEED_1G; + speed_capa |= RTE_ETH_LINK_SPEED_1G; if (supported_speed & HNS3_FIBER_LINK_SPEED_10G_BIT) - speed_capa |= ETH_LINK_SPEED_10G; + speed_capa |= RTE_ETH_LINK_SPEED_10G; if (supported_speed & HNS3_FIBER_LINK_SPEED_25G_BIT) - speed_capa |= ETH_LINK_SPEED_25G; + speed_capa |= RTE_ETH_LINK_SPEED_25G; if (supported_speed & HNS3_FIBER_LINK_SPEED_40G_BIT) - speed_capa |= ETH_LINK_SPEED_40G; + speed_capa |= RTE_ETH_LINK_SPEED_40G; if (supported_speed & HNS3_FIBER_LINK_SPEED_50G_BIT) - speed_capa |= ETH_LINK_SPEED_50G; + speed_capa |= RTE_ETH_LINK_SPEED_50G; if (supported_speed & HNS3_FIBER_LINK_SPEED_100G_BIT) - speed_capa |= ETH_LINK_SPEED_100G; + speed_capa |= RTE_ETH_LINK_SPEED_100G; if (supported_speed & HNS3_FIBER_LINK_SPEED_200G_BIT) - speed_capa |= ETH_LINK_SPEED_200G; + speed_capa |= RTE_ETH_LINK_SPEED_200G; return speed_capa; } -static uint32_t +uint32_t hns3_get_speed_capa(struct hns3_hw *hw) { struct hns3_mac *mac = &hw->mac; @@ -2673,139 +2190,11 @@ hns3_get_speed_capa(struct hns3_hw *hw) hns3_get_firber_port_speed_capa(mac->supported_speed); if (mac->support_autoneg == 0) - speed_capa |= ETH_LINK_SPEED_FIXED; + speed_capa |= RTE_ETH_LINK_SPEED_FIXED; return speed_capa; } -int -hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) -{ - struct hns3_adapter *hns = eth_dev->data->dev_private; - struct hns3_hw *hw = &hns->hw; - uint16_t queue_num = hw->tqps_num; - - /* - * In interrupt mode, 'max_rx_queues' is set based on the number of - * MSI-X interrupt resources of the hardware. - */ - if (hw->data->dev_conf.intr_conf.rxq == 1) - queue_num = hw->intr_tqps_num; - - info->max_rx_queues = queue_num; - info->max_tx_queues = hw->tqps_num; - info->max_rx_pktlen = HNS3_MAX_FRAME_LEN; /* CRC included */ - info->min_rx_bufsize = HNS3_MIN_BD_BUF_SIZE; - info->max_mac_addrs = HNS3_UC_MACADDR_NUM; - info->max_mtu = info->max_rx_pktlen - HNS3_ETH_OVERHEAD; - info->max_lro_pkt_size = HNS3_MAX_LRO_SIZE; - info->rx_offload_capa = (DEV_RX_OFFLOAD_IPV4_CKSUM | - DEV_RX_OFFLOAD_TCP_CKSUM | - DEV_RX_OFFLOAD_UDP_CKSUM | - DEV_RX_OFFLOAD_SCTP_CKSUM | - DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | - DEV_RX_OFFLOAD_OUTER_UDP_CKSUM | - DEV_RX_OFFLOAD_KEEP_CRC | - DEV_RX_OFFLOAD_SCATTER | - DEV_RX_OFFLOAD_VLAN_STRIP | - DEV_RX_OFFLOAD_VLAN_FILTER | - DEV_RX_OFFLOAD_JUMBO_FRAME | - DEV_RX_OFFLOAD_RSS_HASH | - DEV_RX_OFFLOAD_TCP_LRO); - info->tx_offload_capa = (DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | - DEV_TX_OFFLOAD_IPV4_CKSUM | - DEV_TX_OFFLOAD_TCP_CKSUM | - DEV_TX_OFFLOAD_UDP_CKSUM | - DEV_TX_OFFLOAD_SCTP_CKSUM | - DEV_TX_OFFLOAD_MULTI_SEGS | - DEV_TX_OFFLOAD_TCP_TSO | - DEV_TX_OFFLOAD_VXLAN_TNL_TSO | - DEV_TX_OFFLOAD_GRE_TNL_TSO | - DEV_TX_OFFLOAD_GENEVE_TNL_TSO | - DEV_TX_OFFLOAD_MBUF_FAST_FREE | - hns3_txvlan_cap_get(hw)); - - if (hns3_dev_outer_udp_cksum_supported(hw)) - info->tx_offload_capa |= DEV_TX_OFFLOAD_OUTER_UDP_CKSUM; - - if (hns3_dev_indep_txrx_supported(hw)) - info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | - RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; - - if (hns3_dev_ptp_supported(hw)) - info->rx_offload_capa |= DEV_RX_OFFLOAD_TIMESTAMP; - - info->rx_desc_lim = (struct rte_eth_desc_lim) { - .nb_max = HNS3_MAX_RING_DESC, - .nb_min = HNS3_MIN_RING_DESC, - .nb_align = HNS3_ALIGN_RING_DESC, - }; - - info->tx_desc_lim = (struct rte_eth_desc_lim) { - .nb_max = HNS3_MAX_RING_DESC, - .nb_min = HNS3_MIN_RING_DESC, - .nb_align = HNS3_ALIGN_RING_DESC, - .nb_seg_max = HNS3_MAX_TSO_BD_PER_PKT, - .nb_mtu_seg_max = hw->max_non_tso_bd_num, - }; - - info->speed_capa = hns3_get_speed_capa(hw); - info->default_rxconf = (struct rte_eth_rxconf) { - .rx_free_thresh = HNS3_DEFAULT_RX_FREE_THRESH, - /* - * If there are no available Rx buffer descriptors, incoming - * packets are always dropped by hardware based on hns3 network - * engine. - */ - .rx_drop_en = 1, - .offloads = 0, - }; - info->default_txconf = (struct rte_eth_txconf) { - .tx_rs_thresh = HNS3_DEFAULT_TX_RS_THRESH, - .offloads = 0, - }; - - info->vmdq_queue_num = 0; - - info->reta_size = hw->rss_ind_tbl_size; - info->hash_key_size = HNS3_RSS_KEY_SIZE; - info->flow_type_rss_offloads = HNS3_ETH_RSS_SUPPORT; - - info->default_rxportconf.burst_size = HNS3_DEFAULT_PORT_CONF_BURST_SIZE; - info->default_txportconf.burst_size = HNS3_DEFAULT_PORT_CONF_BURST_SIZE; - info->default_rxportconf.nb_queues = HNS3_DEFAULT_PORT_CONF_QUEUES_NUM; - info->default_txportconf.nb_queues = HNS3_DEFAULT_PORT_CONF_QUEUES_NUM; - info->default_rxportconf.ring_size = HNS3_DEFAULT_RING_DESC; - info->default_txportconf.ring_size = HNS3_DEFAULT_RING_DESC; - - return 0; -} - -static int -hns3_fw_version_get(struct rte_eth_dev *eth_dev, char *fw_version, - size_t fw_size) -{ - struct hns3_adapter *hns = eth_dev->data->dev_private; - struct hns3_hw *hw = &hns->hw; - uint32_t version = hw->fw_version; - int ret; - - ret = snprintf(fw_version, fw_size, "%lu.%lu.%lu.%lu", - hns3_get_field(version, HNS3_FW_VERSION_BYTE3_M, - HNS3_FW_VERSION_BYTE3_S), - hns3_get_field(version, HNS3_FW_VERSION_BYTE2_M, - HNS3_FW_VERSION_BYTE2_S), - hns3_get_field(version, HNS3_FW_VERSION_BYTE1_M, - HNS3_FW_VERSION_BYTE1_S), - hns3_get_field(version, HNS3_FW_VERSION_BYTE0_M, - HNS3_FW_VERSION_BYTE0_S)); - ret += 1; /* add the size of '\0' */ - if (fw_size < (uint32_t)ret) - return ret; - else - return 0; -} - static int hns3_update_port_link_info(struct rte_eth_dev *eth_dev) { @@ -2816,7 +2205,7 @@ hns3_update_port_link_info(struct rte_eth_dev *eth_dev) ret = hns3_update_link_info(eth_dev); if (ret) - hw->mac.link_status = ETH_LINK_DOWN; + hw->mac.link_status = RTE_ETH_LINK_DOWN; return ret; } @@ -2829,29 +2218,30 @@ hns3_setup_linkstatus(struct rte_eth_dev *eth_dev, struct hns3_mac *mac = &hw->mac; switch (mac->link_speed) { - case ETH_SPEED_NUM_10M: - case ETH_SPEED_NUM_100M: - case ETH_SPEED_NUM_1G: - case ETH_SPEED_NUM_10G: - case ETH_SPEED_NUM_25G: - case ETH_SPEED_NUM_40G: - case ETH_SPEED_NUM_50G: - case ETH_SPEED_NUM_100G: - case ETH_SPEED_NUM_200G: - new_link->link_speed = mac->link_speed; + case RTE_ETH_SPEED_NUM_10M: + case RTE_ETH_SPEED_NUM_100M: + case RTE_ETH_SPEED_NUM_1G: + case RTE_ETH_SPEED_NUM_10G: + case RTE_ETH_SPEED_NUM_25G: + case RTE_ETH_SPEED_NUM_40G: + case RTE_ETH_SPEED_NUM_50G: + case RTE_ETH_SPEED_NUM_100G: + case RTE_ETH_SPEED_NUM_200G: + if (mac->link_status) + new_link->link_speed = mac->link_speed; break; default: if (mac->link_status) - new_link->link_speed = ETH_SPEED_NUM_UNKNOWN; - else - new_link->link_speed = ETH_SPEED_NUM_NONE; + new_link->link_speed = RTE_ETH_SPEED_NUM_UNKNOWN; break; } + if (!mac->link_status) + new_link->link_speed = RTE_ETH_SPEED_NUM_NONE; + new_link->link_duplex = mac->link_duplex; - new_link->link_status = mac->link_status ? ETH_LINK_UP : ETH_LINK_DOWN; - new_link->link_autoneg = - !(eth_dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED); + new_link->link_status = mac->link_status ? RTE_ETH_LINK_UP : RTE_ETH_LINK_DOWN; + new_link->link_autoneg = mac->link_autoneg; } static int @@ -2866,6 +2256,15 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete) struct rte_eth_link new_link; int ret; + /* When port is stopped, report link down. */ + if (eth_dev->data->dev_started == 0) { + new_link.link_autoneg = mac->link_autoneg; + new_link.link_duplex = mac->link_duplex; + new_link.link_speed = RTE_ETH_SPEED_NUM_NONE; + new_link.link_status = RTE_ETH_LINK_DOWN; + goto out; + } + do { ret = hns3_update_port_link_info(eth_dev); if (ret) { @@ -2874,7 +2273,7 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete) break; } - if (!wait_to_complete || mac->link_status == ETH_LINK_UP) + if (!wait_to_complete || mac->link_status == RTE_ETH_LINK_UP) break; rte_delay_ms(HNS3_LINK_CHECK_INTERVAL); @@ -2883,9 +2282,92 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete) memset(&new_link, 0, sizeof(new_link)); hns3_setup_linkstatus(eth_dev, &new_link); +out: return rte_eth_linkstatus_set(eth_dev, &new_link); } +static int +hns3_dev_set_link_up(struct rte_eth_dev *dev) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + int ret; + + /* + * The "tx_pkt_burst" will be restored. But the secondary process does + * not support the mechanism for notifying the primary process. + */ + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { + hns3_err(hw, "secondary process does not support to set link up."); + return -ENOTSUP; + } + + /* + * If device isn't started Rx/Tx function is still disabled, setting + * link up is not allowed. But it is probably better to return success + * to reduce the impact on the upper layer. + */ + if (hw->adapter_state != HNS3_NIC_STARTED) { + hns3_info(hw, "device isn't started, can't set link up."); + return 0; + } + + if (!hw->set_link_down) + return 0; + + rte_spinlock_lock(&hw->lock); + ret = hns3_cfg_mac_mode(hw, true); + if (ret) { + rte_spinlock_unlock(&hw->lock); + hns3_err(hw, "failed to set link up, ret = %d", ret); + return ret; + } + + hw->set_link_down = false; + hns3_start_tx_datapath(dev); + rte_spinlock_unlock(&hw->lock); + + return 0; +} + +static int +hns3_dev_set_link_down(struct rte_eth_dev *dev) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + int ret; + + /* + * The "tx_pkt_burst" will be set to dummy function. But the secondary + * process does not support the mechanism for notifying the primary + * process. + */ + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { + hns3_err(hw, "secondary process does not support to set link down."); + return -ENOTSUP; + } + + /* + * If device isn't started or the API has been called, link status is + * down, return success. + */ + if (hw->adapter_state != HNS3_NIC_STARTED || hw->set_link_down) + return 0; + + rte_spinlock_lock(&hw->lock); + hns3_stop_tx_datapath(dev); + ret = hns3_cfg_mac_mode(hw, false); + if (ret) { + hns3_start_tx_datapath(dev); + rte_spinlock_unlock(&hw->lock); + hns3_err(hw, "failed to set link down, ret = %d", ret); + return ret; + } + + hw->set_link_down = true; + rte_spinlock_unlock(&hw->lock); + + return 0; +} + static int hns3_parse_func_status(struct hns3_hw *hw, struct hns3_func_status_cmd *status) { @@ -3035,13 +2517,8 @@ hns3_parse_cfg(struct hns3_cfg *cfg, struct hns3_cmd_desc *desc) req = (struct hns3_cfg_param_cmd *)desc[0].data; /* get the configuration */ - cfg->vmdq_vport_num = hns3_get_field(rte_le_to_cpu_32(req->param[0]), - HNS3_CFG_VMDQ_M, HNS3_CFG_VMDQ_S); cfg->tc_num = hns3_get_field(rte_le_to_cpu_32(req->param[0]), HNS3_CFG_TC_NUM_M, HNS3_CFG_TC_NUM_S); - cfg->tqp_desc_num = hns3_get_field(rte_le_to_cpu_32(req->param[0]), - HNS3_CFG_TQP_DESC_N_M, - HNS3_CFG_TQP_DESC_N_S); cfg->phy_addr = hns3_get_field(rte_le_to_cpu_32(req->param[1]), HNS3_CFG_PHY_ADDR_M, @@ -3049,9 +2526,6 @@ hns3_parse_cfg(struct hns3_cfg *cfg, struct hns3_cmd_desc *desc) cfg->media_type = hns3_get_field(rte_le_to_cpu_32(req->param[1]), HNS3_CFG_MEDIA_TP_M, HNS3_CFG_MEDIA_TP_S); - cfg->rx_buf_len = hns3_get_field(rte_le_to_cpu_32(req->param[1]), - HNS3_CFG_RX_BUF_LEN_M, - HNS3_CFG_RX_BUF_LEN_S); /* get mac address */ mac_addr_tmp = rte_le_to_cpu_32(req->param[2]); mac_addr_tmp_high = hns3_get_field(rte_le_to_cpu_32(req->param[3]), @@ -3085,12 +2559,11 @@ hns3_parse_cfg(struct hns3_cfg *cfg, struct hns3_cmd_desc *desc) ext_rss_size_max = hns3_get_field(rte_le_to_cpu_32(req->param[2]), HNS3_CFG_EXT_RSS_SIZE_M, HNS3_CFG_EXT_RSS_SIZE_S); - /* * Field ext_rss_size_max obtained from firmware will be more flexible * for future changes and expansions, which is an exponent of 2, instead * of reading out directly. If this field is not zero, hns3 PF PMD - * driver uses it as rss_size_max under one TC. Device, whose revision + * uses it as rss_size_max under one TC. Device, whose revision * id is greater than or equal to PCI_REVISION_ID_HIP09_A, obtains the * maximum number of queues supported under a TC through this field. */ @@ -3140,31 +2613,31 @@ hns3_parse_speed(int speed_cmd, uint32_t *speed) { switch (speed_cmd) { case HNS3_CFG_SPEED_10M: - *speed = ETH_SPEED_NUM_10M; + *speed = RTE_ETH_SPEED_NUM_10M; break; case HNS3_CFG_SPEED_100M: - *speed = ETH_SPEED_NUM_100M; + *speed = RTE_ETH_SPEED_NUM_100M; break; case HNS3_CFG_SPEED_1G: - *speed = ETH_SPEED_NUM_1G; + *speed = RTE_ETH_SPEED_NUM_1G; break; case HNS3_CFG_SPEED_10G: - *speed = ETH_SPEED_NUM_10G; + *speed = RTE_ETH_SPEED_NUM_10G; break; case HNS3_CFG_SPEED_25G: - *speed = ETH_SPEED_NUM_25G; + *speed = RTE_ETH_SPEED_NUM_25G; break; case HNS3_CFG_SPEED_40G: - *speed = ETH_SPEED_NUM_40G; + *speed = RTE_ETH_SPEED_NUM_40G; break; case HNS3_CFG_SPEED_50G: - *speed = ETH_SPEED_NUM_50G; + *speed = RTE_ETH_SPEED_NUM_50G; break; case HNS3_CFG_SPEED_100G: - *speed = ETH_SPEED_NUM_100G; + *speed = RTE_ETH_SPEED_NUM_100G; break; case HNS3_CFG_SPEED_200G: - *speed = ETH_SPEED_NUM_200G; + *speed = RTE_ETH_SPEED_NUM_200G; break; default: return -EINVAL; @@ -3242,7 +2715,6 @@ hns3_get_capability(struct hns3_hw *hw) struct hns3_pf *pf = &hns->pf; struct rte_eth_dev *eth_dev; uint16_t device_id; - uint8_t revision; int ret; eth_dev = &rte_eth_devices[hw->data->port_id]; @@ -3255,17 +2727,15 @@ hns3_get_capability(struct hns3_hw *hw) device_id == HNS3_DEV_ID_200G_RDMA) hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_DCB_B, 1); - /* Get PCI revision id */ - ret = rte_pci_read_config(pci_dev, &revision, HNS3_PCI_REVISION_ID_LEN, - HNS3_PCI_REVISION_ID); - if (ret != HNS3_PCI_REVISION_ID_LEN) { - PMD_INIT_LOG(ERR, "failed to read pci revision id, ret = %d", - ret); - return -EIO; - } - hw->revision = revision; + ret = hns3_get_pci_revision_id(hw, &hw->revision); + if (ret) + return ret; + + ret = hns3_query_mac_stats_reg_num(hw); + if (ret) + return ret; - if (revision < PCI_REVISION_ID_HIP09_A) { + if (hw->revision < PCI_REVISION_ID_HIP09_A) { hns3_set_default_dev_specifications(hw); hw->intr.mapping_mode = HNS3_INTR_MAPPING_VEC_RSV_ONE; hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_2US; @@ -3276,6 +2746,7 @@ hns3_get_capability(struct hns3_hw *hw) pf->tqp_config_mode = HNS3_FIXED_MAX_TQP_NUM_MODE; hw->rss_info.ipv6_sctp_offload_supported = false; hw->udp_cksum_mode = HNS3_SPECIAL_PORT_SW_CKSUM_MODE; + pf->support_multi_tc_pause = false; return 0; } @@ -3296,6 +2767,7 @@ hns3_get_capability(struct hns3_hw *hw) pf->tqp_config_mode = HNS3_FLEX_MAX_TQP_NUM_MODE; hw->rss_info.ipv6_sctp_offload_supported = true; hw->udp_cksum_mode = HNS3_SPECIAL_PORT_HW_CKSUM_MODE; + pf->support_multi_tc_pause = true; return 0; } @@ -3307,7 +2779,7 @@ hns3_check_media_type(struct hns3_hw *hw, uint8_t media_type) switch (media_type) { case HNS3_MEDIA_TYPE_COPPER: - if (!hns3_dev_copper_supported(hw)) { + if (!hns3_dev_get_support(hw, COPPER)) { PMD_INIT_LOG(ERR, "Media type is copper, not supported."); ret = -EOPNOTSUPP; @@ -3351,12 +2823,8 @@ hns3_get_board_configuration(struct hns3_hw *hw) hw->mac.media_type = cfg.media_type; hw->rss_size_max = cfg.rss_size_max; - hw->rss_dis_flag = false; memcpy(hw->mac.mac_addr, cfg.mac_addr, RTE_ETHER_ADDR_LEN); hw->mac.phy_addr = cfg.phy_addr; - hw->mac.default_addr_setted = false; - hw->num_tx_desc = cfg.tqp_desc_num; - hw->num_rx_desc = cfg.tqp_desc_num; hw->dcb_info.num_pg = 1; hw->dcb_info.hw_pfc_map = 0; @@ -3376,7 +2844,7 @@ hns3_get_board_configuration(struct hns3_hw *hw) } /* Dev does not support DCB */ - if (!hns3_dev_dcb_supported(hw)) { + if (!hns3_dev_get_support(hw, DCB)) { pf->tc_max = 1; pf->pfc_max = 0; } else @@ -3491,39 +2959,39 @@ hns3_cfg_mac_speed_dup_hw(struct hns3_hw *hw, uint32_t speed, uint8_t duplex) hns3_set_bit(req->speed_dup, HNS3_CFG_DUPLEX_B, !!duplex ? 1 : 0); switch (speed) { - case ETH_SPEED_NUM_10M: + case RTE_ETH_SPEED_NUM_10M: hns3_set_field(req->speed_dup, HNS3_CFG_SPEED_M, HNS3_CFG_SPEED_S, HNS3_CFG_SPEED_10M); break; - case ETH_SPEED_NUM_100M: + case RTE_ETH_SPEED_NUM_100M: hns3_set_field(req->speed_dup, HNS3_CFG_SPEED_M, HNS3_CFG_SPEED_S, HNS3_CFG_SPEED_100M); break; - case ETH_SPEED_NUM_1G: + case RTE_ETH_SPEED_NUM_1G: hns3_set_field(req->speed_dup, HNS3_CFG_SPEED_M, HNS3_CFG_SPEED_S, HNS3_CFG_SPEED_1G); break; - case ETH_SPEED_NUM_10G: + case RTE_ETH_SPEED_NUM_10G: hns3_set_field(req->speed_dup, HNS3_CFG_SPEED_M, HNS3_CFG_SPEED_S, HNS3_CFG_SPEED_10G); break; - case ETH_SPEED_NUM_25G: + case RTE_ETH_SPEED_NUM_25G: hns3_set_field(req->speed_dup, HNS3_CFG_SPEED_M, HNS3_CFG_SPEED_S, HNS3_CFG_SPEED_25G); break; - case ETH_SPEED_NUM_40G: + case RTE_ETH_SPEED_NUM_40G: hns3_set_field(req->speed_dup, HNS3_CFG_SPEED_M, HNS3_CFG_SPEED_S, HNS3_CFG_SPEED_40G); break; - case ETH_SPEED_NUM_50G: + case RTE_ETH_SPEED_NUM_50G: hns3_set_field(req->speed_dup, HNS3_CFG_SPEED_M, HNS3_CFG_SPEED_S, HNS3_CFG_SPEED_50G); break; - case ETH_SPEED_NUM_100G: + case RTE_ETH_SPEED_NUM_100G: hns3_set_field(req->speed_dup, HNS3_CFG_SPEED_M, HNS3_CFG_SPEED_S, HNS3_CFG_SPEED_100G); break; - case ETH_SPEED_NUM_200G: + case RTE_ETH_SPEED_NUM_200G: hns3_set_field(req->speed_dup, HNS3_CFG_SPEED_M, HNS3_CFG_SPEED_S, HNS3_CFG_SPEED_200G); break; @@ -3689,7 +3157,7 @@ hns3_is_rx_buf_ok(struct hns3_hw *hw, struct hns3_pkt_buf_alloc *buf_alloc, tc_num = hns3_get_tc_num(hw); aligned_mps = roundup(pf->mps, HNS3_BUF_SIZE_UNIT); - if (hns3_dev_dcb_supported(hw)) + if (hns3_dev_get_support(hw, DCB)) shared_buf_min = HNS3_BUF_MUL_BY * aligned_mps + pf->dv_buf_size; else @@ -3706,7 +3174,7 @@ hns3_is_rx_buf_ok(struct hns3_hw *hw, struct hns3_pkt_buf_alloc *buf_alloc, shared_buf = rounddown(rx_all - rx_priv, HNS3_BUF_SIZE_UNIT); buf_alloc->s_buf.buf_size = shared_buf; - if (hns3_dev_dcb_supported(hw)) { + if (hns3_dev_get_support(hw, DCB)) { buf_alloc->s_buf.self.high = shared_buf - pf->dv_buf_size; buf_alloc->s_buf.self.low = buf_alloc->s_buf.self.high - roundup(aligned_mps / HNS3_BUF_DIV_BY, @@ -3717,7 +3185,7 @@ hns3_is_rx_buf_ok(struct hns3_hw *hw, struct hns3_pkt_buf_alloc *buf_alloc, buf_alloc->s_buf.self.low = aligned_mps; } - if (hns3_dev_dcb_supported(hw)) { + if (hns3_dev_get_support(hw, DCB)) { hi_thrd = shared_buf - pf->dv_buf_size; if (tc_num <= NEED_RESERVE_TC_NUM) @@ -3804,7 +3272,6 @@ hns3_drop_nopfc_buf_till_fit(struct hns3_hw *hw, for (i = HNS3_MAX_TC_NUM - 1; i >= 0; i--) { priv = &buf_alloc->priv_buf[i]; mask = BIT((uint8_t)i); - if (hw->hw_tc_map & mask && !(hw->dcb_info.hw_pfc_map & mask)) { /* Clear the no pfc TC private buffer */ @@ -3890,7 +3357,6 @@ hns3_only_alloc_priv_buff(struct hns3_hw *hw, COMPENSATE_HALF_MPS_NUM * half_mps; min_rx_priv = roundup(min_rx_priv, HNS3_BUF_SIZE_UNIT); rx_priv = rounddown(rx_priv, HNS3_BUF_SIZE_UNIT); - if (rx_priv < min_rx_priv) return false; @@ -3919,13 +3385,13 @@ hns3_only_alloc_priv_buff(struct hns3_hw *hw, * hns3_rx_buffer_calc: calculate the rx private buffer size for all TCs * @hw: pointer to struct hns3_hw * @buf_alloc: pointer to buffer calculation data - * @return: 0: calculate sucessful, negative: fail + * @return: 0: calculate successful, negative: fail */ static int hns3_rx_buffer_calc(struct hns3_hw *hw, struct hns3_pkt_buf_alloc *buf_alloc) { /* When DCB is not supported, rx private buffer is not allocated. */ - if (!hns3_dev_dcb_supported(hw)) { + if (!hns3_dev_get_support(hw, DCB)) { struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); struct hns3_pf *pf = &hns->pf; uint32_t rx_all = pf->pkt_buf_size; @@ -3955,8 +3421,8 @@ hns3_rx_buffer_calc(struct hns3_hw *hw, struct hns3_pkt_buf_alloc *buf_alloc) * For different application scenes, the enabled port number, TC number * and no_drop TC number are different. In order to obtain the better * performance, software could allocate the buffer size and configure - * the waterline by tring to decrease the private buffer size according - * to the order, namely, waterline of valided tc, pfc disabled tc, pfc + * the waterline by trying to decrease the private buffer size according + * to the order, namely, waterline of valid tc, pfc disabled tc, pfc * enabled tc. */ if (hns3_rx_buf_calc_all(hw, false, buf_alloc)) @@ -4153,7 +3619,7 @@ hns3_buffer_alloc(struct hns3_hw *hw) return ret; } - if (hns3_dev_dcb_supported(hw)) { + if (hns3_dev_get_support(hw, DCB)) { ret = hns3_rx_priv_wl_config(hw, &pkt_buf); if (ret) { PMD_INIT_LOG(ERR, @@ -4188,14 +3654,14 @@ hns3_mac_init(struct hns3_hw *hw) int ret; pf->support_sfp_query = true; - mac->link_duplex = ETH_LINK_FULL_DUPLEX; + mac->link_duplex = RTE_ETH_LINK_FULL_DUPLEX; ret = hns3_cfg_mac_speed_dup_hw(hw, mac->link_speed, mac->link_duplex); if (ret) { PMD_INIT_LOG(ERR, "Config mac speed dup fail ret = %d", ret); return ret; } - mac->link_status = ETH_LINK_DOWN; + mac->link_status = RTE_ETH_LINK_DOWN; return hns3_config_mtu(hw, pf->mps); } @@ -4445,7 +3911,7 @@ hns3_dev_promiscuous_enable(struct rte_eth_dev *dev) * all packets coming in in the receiving direction. */ offloads = dev->data->dev_conf.rxmode.offloads; - if (offloads & DEV_RX_OFFLOAD_VLAN_FILTER) { + if (offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) { ret = hns3_enable_vlan_filter(hns, false); if (ret) { hns3_err(hw, "failed to enable promiscuous mode due to " @@ -4486,7 +3952,7 @@ hns3_dev_promiscuous_disable(struct rte_eth_dev *dev) } /* when promiscuous mode was disabled, restore the vlan filter status */ offloads = dev->data->dev_conf.rxmode.offloads; - if (offloads & DEV_RX_OFFLOAD_VLAN_FILTER) { + if (offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) { ret = hns3_enable_vlan_filter(hns, true); if (ret) { hns3_err(hw, "failed to disable promiscuous mode due to" @@ -4605,6 +4071,9 @@ hns3_get_sfp_info(struct hns3_hw *hw, struct hns3_mac *mac_info) mac_info->query_type = HNS3_ACTIVE_QUERY; mac_info->supported_speed = rte_le_to_cpu_32(resp->supported_speed); + mac_info->support_autoneg = resp->autoneg_ability; + mac_info->link_autoneg = (resp->autoneg == 0) ? RTE_ETH_LINK_FIXED + : RTE_ETH_LINK_AUTONEG; } else { mac_info->query_type = HNS3_DEFAULT_QUERY; } @@ -4615,8 +4084,8 @@ hns3_get_sfp_info(struct hns3_hw *hw, struct hns3_mac *mac_info) static uint8_t hns3_check_speed_dup(uint8_t duplex, uint32_t speed) { - if (!(speed == ETH_SPEED_NUM_10M || speed == ETH_SPEED_NUM_100M)) - duplex = ETH_LINK_FULL_DUPLEX; + if (!(speed == RTE_ETH_SPEED_NUM_10M || speed == RTE_ETH_SPEED_NUM_100M)) + duplex = RTE_ETH_LINK_FULL_DUPLEX; return duplex; } @@ -4666,7 +4135,7 @@ hns3_update_fiber_link_info(struct hns3_hw *hw) return ret; /* Do nothing if no SFP */ - if (mac_info.link_speed == ETH_SPEED_NUM_NONE) + if (mac_info.link_speed == RTE_ETH_SPEED_NUM_NONE) return 0; /* @@ -4685,13 +4154,15 @@ hns3_update_fiber_link_info(struct hns3_hw *hw) mac->link_speed = mac_info.link_speed; mac->supported_speed = mac_info.supported_speed; + mac->support_autoneg = mac_info.support_autoneg; + mac->link_autoneg = mac_info.link_autoneg; return 0; } /* Config full duplex for SFP */ return hns3_cfg_mac_speed_dup(hw, mac_info.link_speed, - ETH_LINK_FULL_DUPLEX); + RTE_ETH_LINK_FULL_DUPLEX); } static void @@ -4810,10 +4281,10 @@ hns3_cfg_mac_mode(struct hns3_hw *hw, bool enable) hns3_set_bit(loop_en, HNS3_MAC_RX_FCS_B, val); /* - * If DEV_RX_OFFLOAD_KEEP_CRC offload is set, MAC will not strip CRC + * If RTE_ETH_RX_OFFLOAD_KEEP_CRC offload is set, MAC will not strip CRC * when receiving frames. Otherwise, CRC will be stripped. */ - if (hw->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_KEEP_CRC) + if (hw->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC) hns3_set_bit(loop_en, HNS3_MAC_RX_FCS_STRIP_B, 0); else hns3_set_bit(loop_en, HNS3_MAC_RX_FCS_STRIP_B, val); @@ -4841,7 +4312,7 @@ hns3_get_mac_link_status(struct hns3_hw *hw) ret = hns3_cmd_send(hw, &desc, 1); if (ret) { hns3_err(hw, "get link status cmd failed %d", ret); - return ETH_LINK_DOWN; + return RTE_ETH_LINK_DOWN; } req = (struct hns3_link_status_cmd *)desc.data; @@ -4859,8 +4330,6 @@ hns3_update_link_status(struct hns3_hw *hw) if (state != hw->mac.link_status) { hw->mac.link_status = state; hns3_warn(hw, "Link status change to %s!", state ? "up" : "down"); - hns3_config_mac_tnl_int(hw, - state == ETH_LINK_UP ? true : false); return true; } @@ -4892,10 +4361,12 @@ hns3_service_handler(void *param) struct hns3_adapter *hns = eth_dev->data->dev_private; struct hns3_hw *hw = &hns->hw; - if (!hns3_is_reset_pending(hns)) + if (!hns3_is_reset_pending(hns)) { hns3_update_linkstatus_and_event(hw, true); - else + hns3_update_hw_stats(hw); + } else { hns3_warn(hw, "Cancel the query when reset is pending"); + } rte_eal_alarm_set(HNS3_SERVICE_INTERVAL, hns3_service_handler, eth_dev); } @@ -4906,6 +4377,10 @@ hns3_init_hardware(struct hns3_adapter *hns) struct hns3_hw *hw = &hns->hw; int ret; + /* + * All queue-related HW operations must be performed after the TCAM + * table is configured. + */ ret = hns3_map_tqp(hw); if (ret) { PMD_INIT_LOG(ERR, "Failed to map tqp: %d", ret); @@ -5012,7 +4487,7 @@ hns3_config_all_msix_error(struct hns3_hw *hw, bool enable) * and belong to a different type from the MSI-x errors processed * by the network driver. * - * Network driver should open the new error report on initialition + * Network driver should open the new error report on initialization. */ val = hns3_read_dev(hw, HNS3_VECTOR0_OTER_EN_REG); hns3_set_bit(val, HNS3_VECTOR0_ALL_MSIX_ERR_B, enable ? 1 : 0); @@ -5025,19 +4500,19 @@ hns3_set_firber_default_support_speed(struct hns3_hw *hw) struct hns3_mac *mac = &hw->mac; switch (mac->link_speed) { - case ETH_SPEED_NUM_1G: + case RTE_ETH_SPEED_NUM_1G: return HNS3_FIBER_LINK_SPEED_1G_BIT; - case ETH_SPEED_NUM_10G: + case RTE_ETH_SPEED_NUM_10G: return HNS3_FIBER_LINK_SPEED_10G_BIT; - case ETH_SPEED_NUM_25G: + case RTE_ETH_SPEED_NUM_25G: return HNS3_FIBER_LINK_SPEED_25G_BIT; - case ETH_SPEED_NUM_40G: + case RTE_ETH_SPEED_NUM_40G: return HNS3_FIBER_LINK_SPEED_40G_BIT; - case ETH_SPEED_NUM_50G: + case RTE_ETH_SPEED_NUM_50G: return HNS3_FIBER_LINK_SPEED_50G_BIT; - case ETH_SPEED_NUM_100G: + case RTE_ETH_SPEED_NUM_100G: return HNS3_FIBER_LINK_SPEED_100G_BIT; - case ETH_SPEED_NUM_200G: + case RTE_ETH_SPEED_NUM_200G: return HNS3_FIBER_LINK_SPEED_200G_BIT; default: hns3_warn(hw, "invalid speed %u Mbps.", mac->link_speed); @@ -5046,14 +4521,14 @@ hns3_set_firber_default_support_speed(struct hns3_hw *hw) } /* - * Validity of supported_speed for firber and copper media type can be + * Validity of supported_speed for fiber and copper media type can be * guaranteed by the following policy: * Copper: * Although the initialization of the phy in the firmware may not be * completed, the firmware can guarantees that the supported_speed is * an valid value. * Firber: - * If the version of firmware supports the acitive query way of the + * If the version of firmware supports the active query way of the * HNS3_OPC_GET_SFP_INFO opcode, the supported_speed can be obtained * through it. If unsupported, use the SFP's speed as the value of the * supported_speed. @@ -5084,6 +4559,24 @@ hns3_get_port_supported_speed(struct rte_eth_dev *eth_dev) return 0; } +static void +hns3_get_fc_autoneg_capability(struct hns3_adapter *hns) +{ + struct hns3_mac *mac = &hns->hw.mac; + + if (mac->media_type == HNS3_MEDIA_TYPE_COPPER) { + hns->pf.support_fc_autoneg = true; + return; + } + + /* + * Flow control auto-negotiation requires the cooperation of the driver + * and firmware. Currently, the optical port does not support flow + * control auto-negotiation. + */ + hns->pf.support_fc_autoneg = false; +} + static int hns3_init_pf(struct rte_eth_dev *eth_dev) { @@ -5114,6 +4607,8 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) goto err_cmd_init; } + hns3_tx_push_init(eth_dev); + /* * To ensure that the hardware environment is clean during * initialization, the driver actively clear the hardware environment @@ -5126,16 +4621,9 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) goto err_cmd_init; } - /* Hardware statistics of imissed registers cleared. */ - ret = hns3_update_imissed_stats(hw, true); - if (ret) { - hns3_err(hw, "clear imissed stats failed, ret = %d", ret); - goto err_cmd_init; - } - hns3_config_all_msix_error(hw, true); - ret = rte_intr_callback_register(&pci_dev->intr_handle, + ret = rte_intr_callback_register(pci_dev->intr_handle, hns3_interrupt_handler, eth_dev); if (ret) { @@ -5148,7 +4636,7 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) goto err_get_config; /* Enable interrupt */ - rte_intr_enable(&pci_dev->intr_handle); + rte_intr_enable(pci_dev->intr_handle); hns3_pf_enable_irq0(hw); /* Get configuration */ @@ -5158,7 +4646,7 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) goto err_get_config; } - ret = hns3_tqp_stats_init(hw); + ret = hns3_stats_init(hw); if (ret) goto err_get_config; @@ -5191,6 +4679,8 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) goto err_supported_speed; } + hns3_get_fc_autoneg_capability(hns); + hns3_tm_conf_init(eth_dev); return 0; @@ -5202,11 +4692,11 @@ err_enable_intr: err_fdir: hns3_uninit_umv_space(hw); err_init_hw: - hns3_tqp_stats_uninit(hw); + hns3_stats_uninit(hw); err_get_config: hns3_pf_disable_irq0(hw); - rte_intr_disable(&pci_dev->intr_handle); - hns3_intr_unregister(&pci_dev->intr_handle, hns3_interrupt_handler, + rte_intr_disable(pci_dev->intr_handle); + hns3_intr_unregister(pci_dev->intr_handle, hns3_interrupt_handler, eth_dev); err_intr_callback_register: err_cmd_init: @@ -5233,13 +4723,14 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev) hns3_rss_uninit(hns); (void)hns3_config_gro(hw, false); hns3_promisc_uninit(hw); + hns3_flow_uninit(eth_dev); hns3_fdir_filter_uninit(hns); hns3_uninit_umv_space(hw); - hns3_tqp_stats_uninit(hw); + hns3_stats_uninit(hw); hns3_config_mac_tnl_int(hw, false); hns3_pf_disable_irq0(hw); - rte_intr_disable(&pci_dev->intr_handle); - hns3_intr_unregister(&pci_dev->intr_handle, hns3_interrupt_handler, + rte_intr_disable(pci_dev->intr_handle); + hns3_intr_unregister(pci_dev->intr_handle, hns3_interrupt_handler, eth_dev); hns3_config_all_msix_error(hw, false); hns3_cmd_uninit(hw); @@ -5247,146 +4738,328 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev) hw->io_base = NULL; } -static int -hns3_do_start(struct hns3_adapter *hns, bool reset_queue) +static uint32_t +hns3_convert_link_speeds2bitmap_copper(uint32_t link_speeds) { - struct hns3_hw *hw = &hns->hw; - int ret; - - ret = hns3_dcb_cfg_update(hns); - if (ret) - return ret; + uint32_t speed_bit; - /* - * The hns3_dcb_cfg_update may configure TM module, so - * hns3_tm_conf_update must called later. - */ - ret = hns3_tm_conf_update(hw); - if (ret) { - PMD_INIT_LOG(ERR, "failed to update tm conf, ret = %d.", ret); - return ret; + switch (link_speeds & ~RTE_ETH_LINK_SPEED_FIXED) { + case RTE_ETH_LINK_SPEED_10M: + speed_bit = HNS3_PHY_LINK_SPEED_10M_BIT; + break; + case RTE_ETH_LINK_SPEED_10M_HD: + speed_bit = HNS3_PHY_LINK_SPEED_10M_HD_BIT; + break; + case RTE_ETH_LINK_SPEED_100M: + speed_bit = HNS3_PHY_LINK_SPEED_100M_BIT; + break; + case RTE_ETH_LINK_SPEED_100M_HD: + speed_bit = HNS3_PHY_LINK_SPEED_100M_HD_BIT; + break; + case RTE_ETH_LINK_SPEED_1G: + speed_bit = HNS3_PHY_LINK_SPEED_1000M_BIT; + break; + default: + speed_bit = 0; + break; } - hns3_enable_rxd_adv_layout(hw); + return speed_bit; +} - ret = hns3_init_queues(hns, reset_queue); - if (ret) { - PMD_INIT_LOG(ERR, "failed to init queues, ret = %d.", ret); - return ret; - } +static uint32_t +hns3_convert_link_speeds2bitmap_fiber(uint32_t link_speeds) +{ + uint32_t speed_bit; - ret = hns3_cfg_mac_mode(hw, true); - if (ret) { - PMD_INIT_LOG(ERR, "failed to enable MAC, ret = %d", ret); - goto err_config_mac_mode; + switch (link_speeds & ~RTE_ETH_LINK_SPEED_FIXED) { + case RTE_ETH_LINK_SPEED_1G: + speed_bit = HNS3_FIBER_LINK_SPEED_1G_BIT; + break; + case RTE_ETH_LINK_SPEED_10G: + speed_bit = HNS3_FIBER_LINK_SPEED_10G_BIT; + break; + case RTE_ETH_LINK_SPEED_25G: + speed_bit = HNS3_FIBER_LINK_SPEED_25G_BIT; + break; + case RTE_ETH_LINK_SPEED_40G: + speed_bit = HNS3_FIBER_LINK_SPEED_40G_BIT; + break; + case RTE_ETH_LINK_SPEED_50G: + speed_bit = HNS3_FIBER_LINK_SPEED_50G_BIT; + break; + case RTE_ETH_LINK_SPEED_100G: + speed_bit = HNS3_FIBER_LINK_SPEED_100G_BIT; + break; + case RTE_ETH_LINK_SPEED_200G: + speed_bit = HNS3_FIBER_LINK_SPEED_200G_BIT; + break; + default: + speed_bit = 0; + break; } - return 0; -err_config_mac_mode: - hns3_dev_release_mbufs(hns); - /* - * Here is exception handling, hns3_reset_all_tqps will have the - * corresponding error message if it is handled incorrectly, so it is - * not necessary to check hns3_reset_all_tqps return value, here keep - * ret as the error code causing the exception. - */ - (void)hns3_reset_all_tqps(hns); - return ret; + return speed_bit; } static int -hns3_map_rx_interrupt(struct rte_eth_dev *dev) +hns3_check_port_speed(struct hns3_hw *hw, uint32_t link_speeds) { - struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); - struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; - struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); - uint16_t base = RTE_INTR_VEC_ZERO_OFFSET; - uint16_t vec = RTE_INTR_VEC_ZERO_OFFSET; - uint32_t intr_vector; - uint16_t q_id; - int ret; + struct hns3_mac *mac = &hw->mac; + uint32_t supported_speed = mac->supported_speed; + uint32_t speed_bit = 0; - /* - * hns3 needs a separate interrupt to be used as event interrupt which - * could not be shared with task queue pair, so KERNEL drivers need - * support multiple interrupt vectors. - */ - if (dev->data->dev_conf.intr_conf.rxq == 0 || - !rte_intr_cap_multiple(intr_handle)) - return 0; + if (mac->media_type == HNS3_MEDIA_TYPE_COPPER) + speed_bit = hns3_convert_link_speeds2bitmap_copper(link_speeds); + else if (mac->media_type == HNS3_MEDIA_TYPE_FIBER) + speed_bit = hns3_convert_link_speeds2bitmap_fiber(link_speeds); - rte_intr_disable(intr_handle); - intr_vector = hw->used_rx_queues; - /* creates event fd for each intr vector when MSIX is used */ - if (rte_intr_efd_enable(intr_handle, intr_vector)) + if (!(speed_bit & supported_speed)) { + hns3_err(hw, "link_speeds(0x%x) exceeds the supported speed capability or is incorrect.", + link_speeds); return -EINVAL; - - if (intr_handle->intr_vec == NULL) { - intr_handle->intr_vec = - rte_zmalloc("intr_vec", - hw->used_rx_queues * sizeof(int), 0); - if (intr_handle->intr_vec == NULL) { - hns3_err(hw, "failed to allocate %u rx_queues intr_vec", - hw->used_rx_queues); - ret = -ENOMEM; - goto alloc_intr_vec_error; - } - } - - if (rte_intr_allow_others(intr_handle)) { - vec = RTE_INTR_VEC_RXTX_OFFSET; - base = RTE_INTR_VEC_RXTX_OFFSET; } - for (q_id = 0; q_id < hw->used_rx_queues; q_id++) { - ret = hns3_bind_ring_with_vector(hw, vec, true, - HNS3_RING_TYPE_RX, q_id); - if (ret) - goto bind_vector_error; - intr_handle->intr_vec[q_id] = vec; - /* - * If there are not enough efds (e.g. not enough interrupt), - * remaining queues will be bond to the last interrupt. - */ - if (vec < base + intr_handle->nb_efd - 1) - vec++; - } - rte_intr_enable(intr_handle); return 0; +} -bind_vector_error: - rte_free(intr_handle->intr_vec); - intr_handle->intr_vec = NULL; -alloc_intr_vec_error: - rte_intr_efd_disable(intr_handle); - return ret; +static uint32_t +hns3_get_link_speed(uint32_t link_speeds) +{ + uint32_t speed = RTE_ETH_SPEED_NUM_NONE; + + if (link_speeds & RTE_ETH_LINK_SPEED_10M || + link_speeds & RTE_ETH_LINK_SPEED_10M_HD) + speed = RTE_ETH_SPEED_NUM_10M; + if (link_speeds & RTE_ETH_LINK_SPEED_100M || + link_speeds & RTE_ETH_LINK_SPEED_100M_HD) + speed = RTE_ETH_SPEED_NUM_100M; + if (link_speeds & RTE_ETH_LINK_SPEED_1G) + speed = RTE_ETH_SPEED_NUM_1G; + if (link_speeds & RTE_ETH_LINK_SPEED_10G) + speed = RTE_ETH_SPEED_NUM_10G; + if (link_speeds & RTE_ETH_LINK_SPEED_25G) + speed = RTE_ETH_SPEED_NUM_25G; + if (link_speeds & RTE_ETH_LINK_SPEED_40G) + speed = RTE_ETH_SPEED_NUM_40G; + if (link_speeds & RTE_ETH_LINK_SPEED_50G) + speed = RTE_ETH_SPEED_NUM_50G; + if (link_speeds & RTE_ETH_LINK_SPEED_100G) + speed = RTE_ETH_SPEED_NUM_100G; + if (link_speeds & RTE_ETH_LINK_SPEED_200G) + speed = RTE_ETH_SPEED_NUM_200G; + + return speed; } -static int -hns3_restore_rx_interrupt(struct hns3_hw *hw) +static uint8_t +hns3_get_link_duplex(uint32_t link_speeds) +{ + if ((link_speeds & RTE_ETH_LINK_SPEED_10M_HD) || + (link_speeds & RTE_ETH_LINK_SPEED_100M_HD)) + return RTE_ETH_LINK_HALF_DUPLEX; + else + return RTE_ETH_LINK_FULL_DUPLEX; +} + +static int +hns3_set_copper_port_link_speed(struct hns3_hw *hw, + struct hns3_set_link_speed_cfg *cfg) +{ + struct hns3_cmd_desc desc[HNS3_PHY_PARAM_CFG_BD_NUM]; + struct hns3_phy_params_bd0_cmd *req; + uint16_t i; + + for (i = 0; i < HNS3_PHY_PARAM_CFG_BD_NUM - 1; i++) { + hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_PHY_PARAM_CFG, + false); + desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); + } + hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_PHY_PARAM_CFG, false); + req = (struct hns3_phy_params_bd0_cmd *)desc[0].data; + req->autoneg = cfg->autoneg; + + /* + * The full speed capability is used to negotiate when + * auto-negotiation is enabled. + */ + if (cfg->autoneg) { + req->advertising = HNS3_PHY_LINK_SPEED_10M_BIT | + HNS3_PHY_LINK_SPEED_10M_HD_BIT | + HNS3_PHY_LINK_SPEED_100M_BIT | + HNS3_PHY_LINK_SPEED_100M_HD_BIT | + HNS3_PHY_LINK_SPEED_1000M_BIT; + } else { + req->speed = cfg->speed; + req->duplex = cfg->duplex; + } + + return hns3_cmd_send(hw, desc, HNS3_PHY_PARAM_CFG_BD_NUM); +} + +static int +hns3_set_autoneg(struct hns3_hw *hw, bool enable) +{ + struct hns3_config_auto_neg_cmd *req; + struct hns3_cmd_desc desc; + uint32_t flag = 0; + int ret; + + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_CONFIG_AN_MODE, false); + + req = (struct hns3_config_auto_neg_cmd *)desc.data; + if (enable) + hns3_set_bit(flag, HNS3_MAC_CFG_AN_EN_B, 1); + req->cfg_an_cmd_flag = rte_cpu_to_le_32(flag); + + ret = hns3_cmd_send(hw, &desc, 1); + if (ret) + hns3_err(hw, "autoneg set cmd failed, ret = %d.", ret); + + return ret; +} + +static int +hns3_set_fiber_port_link_speed(struct hns3_hw *hw, + struct hns3_set_link_speed_cfg *cfg) { - struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id]; - struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); - struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; - uint16_t q_id; int ret; - if (dev->data->dev_conf.intr_conf.rxq == 0) + if (hw->mac.support_autoneg) { + ret = hns3_set_autoneg(hw, cfg->autoneg); + if (ret) { + hns3_err(hw, "failed to configure auto-negotiation."); + return ret; + } + + /* + * To enable auto-negotiation, we only need to open the switch + * of auto-negotiation, then firmware sets all speed + * capabilities. + */ + if (cfg->autoneg) + return 0; + } + + /* + * Some hardware doesn't support auto-negotiation, but users may not + * configure link_speeds (default 0), which means auto-negotiation. + * In this case, a warning message need to be printed, instead of + * an error. + */ + if (cfg->autoneg) { + hns3_warn(hw, "auto-negotiation is not supported, use default fixed speed!"); return 0; + } - if (rte_intr_dp_is_en(intr_handle)) { - for (q_id = 0; q_id < hw->used_rx_queues; q_id++) { - ret = hns3_bind_ring_with_vector(hw, - intr_handle->intr_vec[q_id], true, - HNS3_RING_TYPE_RX, q_id); - if (ret) - return ret; + return hns3_cfg_mac_speed_dup(hw, cfg->speed, cfg->duplex); +} + +static int +hns3_set_port_link_speed(struct hns3_hw *hw, + struct hns3_set_link_speed_cfg *cfg) +{ + int ret; + + if (hw->mac.media_type == HNS3_MEDIA_TYPE_COPPER) { +#if defined(RTE_HNS3_ONLY_1630_FPGA) + struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); + if (pf->is_tmp_phy) + return 0; +#endif + + ret = hns3_set_copper_port_link_speed(hw, cfg); + if (ret) { + hns3_err(hw, "failed to set copper port link speed," + "ret = %d.", ret); + return ret; + } + } else if (hw->mac.media_type == HNS3_MEDIA_TYPE_FIBER) { + ret = hns3_set_fiber_port_link_speed(hw, cfg); + if (ret) { + hns3_err(hw, "failed to set fiber port link speed," + "ret = %d.", ret); + return ret; } } return 0; } +static int +hns3_apply_link_speed(struct hns3_hw *hw) +{ + struct rte_eth_conf *conf = &hw->data->dev_conf; + struct hns3_set_link_speed_cfg cfg; + + memset(&cfg, 0, sizeof(struct hns3_set_link_speed_cfg)); + cfg.autoneg = (conf->link_speeds == RTE_ETH_LINK_SPEED_AUTONEG) ? + RTE_ETH_LINK_AUTONEG : RTE_ETH_LINK_FIXED; + if (cfg.autoneg != RTE_ETH_LINK_AUTONEG) { + cfg.speed = hns3_get_link_speed(conf->link_speeds); + cfg.duplex = hns3_get_link_duplex(conf->link_speeds); + } + + return hns3_set_port_link_speed(hw, &cfg); +} + +static int +hns3_do_start(struct hns3_adapter *hns, bool reset_queue) +{ + struct hns3_hw *hw = &hns->hw; + bool link_en; + int ret; + + ret = hns3_update_queue_map_configure(hns); + if (ret) { + hns3_err(hw, "failed to update queue mapping configuration, ret = %d", + ret); + return ret; + } + + /* Note: hns3_tm_conf_update must be called after configuring DCB. */ + ret = hns3_tm_conf_update(hw); + if (ret) { + PMD_INIT_LOG(ERR, "failed to update tm conf, ret = %d.", ret); + return ret; + } + + hns3_enable_rxd_adv_layout(hw); + + ret = hns3_init_queues(hns, reset_queue); + if (ret) { + PMD_INIT_LOG(ERR, "failed to init queues, ret = %d.", ret); + return ret; + } + + link_en = hw->set_link_down ? false : true; + ret = hns3_cfg_mac_mode(hw, link_en); + if (ret) { + PMD_INIT_LOG(ERR, "failed to enable MAC, ret = %d", ret); + goto err_config_mac_mode; + } + + ret = hns3_apply_link_speed(hw); + if (ret) + goto err_set_link_speed; + + return 0; + +err_set_link_speed: + (void)hns3_cfg_mac_mode(hw, false); + +err_config_mac_mode: + hns3_dev_release_mbufs(hns); + /* + * Here is exception handling, hns3_reset_all_tqps will have the + * corresponding error message if it is handled incorrectly, so it is + * not necessary to check hns3_reset_all_tqps return value, here keep + * ret as the error code causing the exception. + */ + (void)hns3_reset_all_tqps(hns); + return ret; +} + static void hns3_restore_filter(struct rte_eth_dev *dev) { @@ -5398,6 +5071,7 @@ hns3_dev_start(struct rte_eth_dev *dev) { struct hns3_adapter *hns = dev->data->dev_private; struct hns3_hw *hw = &hns->hw; + bool old_state = hw->set_link_down; int ret; PMD_INIT_FUNC_TRACE(); @@ -5407,12 +5081,17 @@ hns3_dev_start(struct rte_eth_dev *dev) rte_spinlock_lock(&hw->lock); hw->adapter_state = HNS3_NIC_STARTING; + /* + * If the dev_set_link_down() API has been called, the "set_link_down" + * flag can be cleared by dev_start() API. In addition, the flag should + * also be cleared before calling hns3_do_start() so that MAC can be + * enabled in dev_start stage. + */ + hw->set_link_down = false; ret = hns3_do_start(hns, true); - if (ret) { - hw->adapter_state = HNS3_NIC_CONFIGURED; - rte_spinlock_unlock(&hw->lock); - return ret; - } + if (ret) + goto do_start_fail; + ret = hns3_map_rx_interrupt(dev); if (ret) goto map_rx_inter_err; @@ -5468,6 +5147,8 @@ start_all_rxqs_fail: hns3_stop_all_txqs(dev); map_rx_inter_err: (void)hns3_do_stop(hns); +do_start_fail: + hw->set_link_down = old_state; hw->adapter_state = HNS3_NIC_CONFIGURED; rte_spinlock_unlock(&hw->lock); @@ -5494,7 +5175,7 @@ hns3_do_stop(struct hns3_adapter *hns) ret = hns3_cfg_mac_mode(hw, false); if (ret) return ret; - hw->mac.link_status = ETH_LINK_DOWN; + hw->mac.link_status = RTE_ETH_LINK_DOWN; if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED) == 0) { hns3_configure_all_mac_addr(hns, true); @@ -5505,44 +5186,8 @@ hns3_do_stop(struct hns3_adapter *hns) return ret; } } - hw->mac.default_addr_setted = false; - return 0; -} - -static void -hns3_unmap_rx_interrupt(struct rte_eth_dev *dev) -{ - struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); - struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; - struct hns3_adapter *hns = dev->data->dev_private; - struct hns3_hw *hw = &hns->hw; - uint8_t base = RTE_INTR_VEC_ZERO_OFFSET; - uint8_t vec = RTE_INTR_VEC_ZERO_OFFSET; - uint16_t q_id; - - if (dev->data->dev_conf.intr_conf.rxq == 0) - return; - /* unmap the ring with vector */ - if (rte_intr_allow_others(intr_handle)) { - vec = RTE_INTR_VEC_RXTX_OFFSET; - base = RTE_INTR_VEC_RXTX_OFFSET; - } - if (rte_intr_dp_is_en(intr_handle)) { - for (q_id = 0; q_id < hw->used_rx_queues; q_id++) { - (void)hns3_bind_ring_with_vector(hw, vec, false, - HNS3_RING_TYPE_RX, - q_id); - if (vec < base + intr_handle->nb_efd - 1) - vec++; - } - } - /* Clean datapath event and queue/vec mapping */ - rte_intr_efd_disable(intr_handle); - if (intr_handle->intr_vec) { - rte_free(intr_handle->intr_vec); - intr_handle->intr_vec = NULL; - } + return 0; } static int @@ -5560,7 +5205,7 @@ hns3_dev_stop(struct rte_eth_dev *dev) /* Disable datapath on secondary process. */ hns3_mp_req_stop_rxtx(dev); /* Prevent crashes when queues are still in use. */ - rte_delay_ms(hw->tqps_num); + rte_delay_ms(hw->cfg_max_queues); rte_spinlock_lock(&hw->lock); if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) { @@ -5587,8 +5232,7 @@ hns3_dev_close(struct rte_eth_dev *eth_dev) int ret = 0; if (rte_eal_process_type() != RTE_PROC_PRIMARY) { - rte_free(eth_dev->process_private); - eth_dev->process_private = NULL; + hns3_mp_uninit(eth_dev); return 0; } @@ -5605,73 +5249,169 @@ hns3_dev_close(struct rte_eth_dev *eth_dev) hns3_uninit_pf(eth_dev); hns3_free_all_queues(eth_dev); rte_free(hw->reset.wait_data); - rte_free(eth_dev->process_private); - eth_dev->process_private = NULL; - hns3_mp_uninit_primary(); + hns3_mp_uninit(eth_dev); hns3_warn(hw, "Close port %u finished", hw->data->port_id); return ret; } -static int -hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) +static void +hns3_get_autoneg_rxtx_pause_copper(struct hns3_hw *hw, bool *rx_pause, + bool *tx_pause) +{ + struct hns3_mac *mac = &hw->mac; + uint32_t advertising = mac->advertising; + uint32_t lp_advertising = mac->lp_advertising; + *rx_pause = false; + *tx_pause = false; + + if (advertising & lp_advertising & HNS3_PHY_LINK_MODE_PAUSE_BIT) { + *rx_pause = true; + *tx_pause = true; + } else if (advertising & lp_advertising & + HNS3_PHY_LINK_MODE_ASYM_PAUSE_BIT) { + if (advertising & HNS3_PHY_LINK_MODE_PAUSE_BIT) + *rx_pause = true; + else if (lp_advertising & HNS3_PHY_LINK_MODE_PAUSE_BIT) + *tx_pause = true; + } +} + +static enum hns3_fc_mode +hns3_get_autoneg_fc_mode(struct hns3_hw *hw) +{ + enum hns3_fc_mode current_mode; + bool rx_pause = false; + bool tx_pause = false; + + switch (hw->mac.media_type) { + case HNS3_MEDIA_TYPE_COPPER: + hns3_get_autoneg_rxtx_pause_copper(hw, &rx_pause, &tx_pause); + break; + + /* + * Flow control auto-negotiation is not supported for fiber and + * backplane media type. + */ + case HNS3_MEDIA_TYPE_FIBER: + case HNS3_MEDIA_TYPE_BACKPLANE: + hns3_err(hw, "autoneg FC mode can't be obtained, but flow control auto-negotiation is enabled."); + current_mode = hw->requested_fc_mode; + goto out; + default: + hns3_err(hw, "autoneg FC mode can't be obtained for unknown media type(%u).", + hw->mac.media_type); + current_mode = HNS3_FC_NONE; + goto out; + } + + if (rx_pause && tx_pause) + current_mode = HNS3_FC_FULL; + else if (rx_pause) + current_mode = HNS3_FC_RX_PAUSE; + else if (tx_pause) + current_mode = HNS3_FC_TX_PAUSE; + else + current_mode = HNS3_FC_NONE; + +out: + return current_mode; +} + +static enum hns3_fc_mode +hns3_get_current_fc_mode(struct rte_eth_dev *dev) { struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct hns3_mac *mac = &hw->mac; - fc_conf->pause_time = pf->pause_time; + /* + * When the flow control mode is obtained, the device may not complete + * auto-negotiation. It is necessary to wait for link establishment. + */ + (void)hns3_dev_link_update(dev, 1); /* - * If fc auto-negotiation is not supported, the configured fc mode - * from user is the current fc mode. + * If the link auto-negotiation of the nic is disabled, or the flow + * control auto-negotiation is not supported, the forced flow control + * mode is used. */ - switch (hw->requested_fc_mode) { + if (mac->link_autoneg == 0 || !pf->support_fc_autoneg) + return hw->requested_fc_mode; + + return hns3_get_autoneg_fc_mode(hw); +} + +int +hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); + enum hns3_fc_mode current_mode; + + current_mode = hns3_get_current_fc_mode(dev); + switch (current_mode) { case HNS3_FC_FULL: - fc_conf->mode = RTE_FC_FULL; + fc_conf->mode = RTE_ETH_FC_FULL; break; case HNS3_FC_TX_PAUSE: - fc_conf->mode = RTE_FC_TX_PAUSE; + fc_conf->mode = RTE_ETH_FC_TX_PAUSE; break; case HNS3_FC_RX_PAUSE: - fc_conf->mode = RTE_FC_RX_PAUSE; + fc_conf->mode = RTE_ETH_FC_RX_PAUSE; break; case HNS3_FC_NONE: default: - fc_conf->mode = RTE_FC_NONE; + fc_conf->mode = RTE_ETH_FC_NONE; break; } + fc_conf->pause_time = pf->pause_time; + fc_conf->autoneg = pf->support_fc_autoneg ? hw->mac.link_autoneg : 0; + return 0; } -static void -hns3_get_fc_mode(struct hns3_hw *hw, enum rte_eth_fc_mode mode) +static int +hns3_check_fc_autoneg_valid(struct hns3_hw *hw, uint8_t autoneg) { - switch (mode) { - case RTE_FC_NONE: - hw->requested_fc_mode = HNS3_FC_NONE; - break; - case RTE_FC_RX_PAUSE: - hw->requested_fc_mode = HNS3_FC_RX_PAUSE; - break; - case RTE_FC_TX_PAUSE: - hw->requested_fc_mode = HNS3_FC_TX_PAUSE; - break; - case RTE_FC_FULL: - hw->requested_fc_mode = HNS3_FC_FULL; - break; - default: - hw->requested_fc_mode = HNS3_FC_NONE; - hns3_warn(hw, "fc_mode(%u) exceeds member scope and is " - "configured to RTE_FC_NONE", mode); - break; + struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); + + if (!pf->support_fc_autoneg) { + if (autoneg != 0) { + hns3_err(hw, "unsupported fc auto-negotiation setting."); + return -EOPNOTSUPP; + } + + /* + * Flow control auto-negotiation of the NIC is not supported, + * but other auto-negotiation features may be supported. + */ + if (autoneg != hw->mac.link_autoneg) { + hns3_err(hw, "please use 'link_speeds' in struct rte_eth_conf to disable autoneg!"); + return -EOPNOTSUPP; + } + + return 0; + } + + /* + * If flow control auto-negotiation of the NIC is supported, all + * auto-negotiation features are supported. + */ + if (autoneg != hw->mac.link_autoneg) { + hns3_err(hw, "please use 'link_speeds' in struct rte_eth_conf to change autoneg!"); + return -EOPNOTSUPP; } + + return 0; } static int hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) { struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); int ret; if (fc_conf->high_water || fc_conf->low_water || @@ -5683,10 +5423,11 @@ hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) fc_conf->send_xon, fc_conf->mac_ctrl_frame_fwd); return -EINVAL; } - if (fc_conf->autoneg) { - hns3_err(hw, "Unsupported fc auto-negotiation setting."); - return -EINVAL; - } + + ret = hns3_check_fc_autoneg_valid(hw, fc_conf->autoneg); + if (ret) + return ret; + if (!fc_conf->pause_time) { hns3_err(hw, "Invalid pause time %u setting.", fc_conf->pause_time); @@ -5700,13 +5441,11 @@ hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) return -EOPNOTSUPP; } - if (hw->num_tc > 1) { + if (hw->num_tc > 1 && !pf->support_multi_tc_pause) { hns3_err(hw, "in multi-TC scenarios, MAC pause is not supported."); return -EOPNOTSUPP; } - hns3_get_fc_mode(hw, fc_conf->mode); - rte_spinlock_lock(&hw->lock); ret = hns3_fc_enable(dev, fc_conf); rte_spinlock_unlock(&hw->lock); @@ -5721,7 +5460,7 @@ hns3_priority_flow_ctrl_set(struct rte_eth_dev *dev, struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); int ret; - if (!hns3_dev_dcb_supported(hw)) { + if (!hns3_dev_get_support(hw, DCB)) { hns3_err(hw, "This port does not support dcb configurations."); return -EOPNOTSUPP; } @@ -5753,8 +5492,6 @@ hns3_priority_flow_ctrl_set(struct rte_eth_dev *dev, return -EOPNOTSUPP; } - hns3_get_fc_mode(hw, pfc_conf->fc.mode); - rte_spinlock_lock(&hw->lock); ret = hns3_dcb_pfc_enable(dev, pfc_conf); rte_spinlock_unlock(&hw->lock); @@ -5771,7 +5508,7 @@ hns3_get_dcb_info(struct rte_eth_dev *dev, struct rte_eth_dcb_info *dcb_info) int i; rte_spinlock_lock(&hw->lock); - if ((uint32_t)mq_mode & ETH_MQ_RX_DCB_FLAG) + if ((uint32_t)mq_mode & RTE_ETH_MQ_RX_DCB_FLAG) dcb_info->nb_tcs = pf->local_max_tc; else dcb_info->nb_tcs = 1; @@ -5806,15 +5543,15 @@ hns3_reinit_dev(struct hns3_adapter *hns) return ret; } - ret = hns3_reset_all_tqps(hns); + ret = hns3_init_hardware(hns); if (ret) { - hns3_err(hw, "Failed to reset all queues: %d", ret); + hns3_err(hw, "Failed to init hardware: %d", ret); return ret; } - ret = hns3_init_hardware(hns); + ret = hns3_reset_all_tqps(hns); if (ret) { - hns3_err(hw, "Failed to init hardware: %d", ret); + hns3_err(hw, "Failed to reset all queues: %d", ret); return ret; } @@ -5868,12 +5605,14 @@ hns3_is_reset_pending(struct hns3_adapter *hns) hns3_check_event_cause(hns, NULL); reset = hns3_get_reset_level(hns, &hw->reset.pending); - if (hw->reset.level != HNS3_NONE_RESET && hw->reset.level < reset) { + if (reset != HNS3_NONE_RESET && hw->reset.level != HNS3_NONE_RESET && + hw->reset.level < reset) { hns3_warn(hw, "High level reset %d is pending", reset); return true; } reset = hns3_get_reset_level(hns, &hw->reset.request); - if (hw->reset.level != HNS3_NONE_RESET && hw->reset.level < reset) { + if (reset != HNS3_NONE_RESET && hw->reset.level != HNS3_NONE_RESET && + hw->reset.level < reset) { hns3_warn(hw, "High level reset %d is request", reset); return true; } @@ -5890,7 +5629,7 @@ hns3_wait_hardware_ready(struct hns3_adapter *hns) if (wait_data->result == HNS3_WAIT_SUCCESS) return 0; else if (wait_data->result == HNS3_WAIT_TIMEOUT) { - gettimeofday(&tv, NULL); + hns3_clock_gettime(&tv); hns3_warn(hw, "Reset step4 hardware not ready after reset time=%ld.%.6ld", tv.tv_sec, tv.tv_usec); return -ETIME; @@ -5900,7 +5639,7 @@ hns3_wait_hardware_ready(struct hns3_adapter *hns) wait_data->hns = hns; wait_data->check_completion = is_pf_reset_done; wait_data->end_ms = (uint64_t)HNS3_RESET_WAIT_CNT * - HNS3_RESET_WAIT_MS + get_timeofday_ms(); + HNS3_RESET_WAIT_MS + hns3_clock_gettime_ms(); wait_data->interval = HNS3_RESET_WAIT_MS * USEC_PER_MSEC; wait_data->count = HNS3_RESET_WAIT_CNT; wait_data->result = HNS3_WAIT_REQUEST; @@ -5939,7 +5678,7 @@ hns3_msix_process(struct hns3_adapter *hns, enum hns3_reset_level reset_level) struct timeval tv; uint32_t val; - gettimeofday(&tv, NULL); + hns3_clock_gettime(&tv); if (hns3_read_dev(hw, HNS3_GLOBAL_RESET_REG) || hns3_read_dev(hw, HNS3_FUN_RST_ING)) { hns3_warn(hw, "Don't process msix during resetting time=%ld.%.6ld", @@ -6069,7 +5808,7 @@ hns3_stop_service(struct hns3_adapter *hns) struct rte_eth_dev *eth_dev; eth_dev = &rte_eth_devices[hw->data->port_id]; - hw->mac.link_status = ETH_LINK_DOWN; + hw->mac.link_status = RTE_ETH_LINK_DOWN; if (hw->adapter_state == HNS3_NIC_STARTED) { rte_eal_alarm_cancel(hns3_service_handler, eth_dev); hns3_update_linkstatus_and_event(hw, false); @@ -6079,7 +5818,7 @@ hns3_stop_service(struct hns3_adapter *hns) rte_wmb(); /* Disable datapath on secondary process. */ hns3_mp_req_stop_rxtx(eth_dev); - rte_delay_ms(hw->tqps_num); + rte_delay_ms(hw->cfg_max_queues); rte_spinlock_lock(&hw->lock); if (hns->hw.adapter_state == HNS3_NIC_STARTED || @@ -6247,14 +5986,13 @@ hns3_reset_service(void *param) */ reset_level = hns3_get_reset_level(hns, &hw->reset.pending); if (reset_level != HNS3_NONE_RESET) { - gettimeofday(&tv_start, NULL); + hns3_clock_gettime(&tv_start); ret = hns3_reset_process(hns, reset_level); - gettimeofday(&tv, NULL); + hns3_clock_gettime(&tv); timersub(&tv, &tv_start, &tv_delta); - msec = tv_delta.tv_sec * MSEC_PER_SEC + - tv_delta.tv_usec / USEC_PER_MSEC; + msec = hns3_clock_calctime_ms(&tv_delta); if (msec > HNS3_RESET_PROCESS_MS) - hns3_err(hw, "%d handle long time delta %" PRIx64 + hns3_err(hw, "%d handle long time delta %" PRIu64 " ms time=%ld.%.6ld", hw->reset.level, msec, tv.tv_sec, tv.tv_usec); @@ -6360,7 +6098,7 @@ get_current_fec_auto_state(struct hns3_hw *hw, uint8_t *state) * in device of link speed * below 10 Gbps. */ - if (hw->mac.link_speed < ETH_SPEED_NUM_10G) { + if (hw->mac.link_speed < RTE_ETH_SPEED_NUM_10G) { *state = 0; return 0; } @@ -6392,7 +6130,7 @@ hns3_fec_get_internal(struct hns3_hw *hw, uint32_t *fec_capa) * configured FEC mode is returned. * If link is up, current FEC mode is returned. */ - if (hw->mac.link_status == ETH_LINK_DOWN) { + if (hw->mac.link_status == RTE_ETH_LINK_DOWN) { ret = get_current_fec_auto_state(hw, &auto_state); if (ret) return ret; @@ -6417,7 +6155,7 @@ hns3_fec_get_internal(struct hns3_hw *hw, uint32_t *fec_capa) } /* - * FEC mode order defined in hns3 hardware is inconsistend with + * FEC mode order defined in hns3 hardware is inconsistent with * that defined in the ethdev library. So the sequence needs * to be converted. */ @@ -6491,12 +6229,12 @@ get_current_speed_fec_cap(struct hns3_hw *hw, struct rte_eth_fec_capa *fec_capa) uint32_t cur_capa; switch (mac->link_speed) { - case ETH_SPEED_NUM_10G: + case RTE_ETH_SPEED_NUM_10G: cur_capa = fec_capa[1].capa; break; - case ETH_SPEED_NUM_25G: - case ETH_SPEED_NUM_100G: - case ETH_SPEED_NUM_200G: + case RTE_ETH_SPEED_NUM_25G: + case RTE_ETH_SPEED_NUM_100G: + case RTE_ETH_SPEED_NUM_200G: cur_capa = fec_capa[0].capa; break; default: @@ -6527,7 +6265,6 @@ hns3_fec_set(struct rte_eth_dev *dev, uint32_t mode) struct hns3_adapter *hns = dev->data->dev_private; struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(hns); struct hns3_pf *pf = &hns->pf; - struct rte_eth_fec_capa fec_capa[FEC_CAPA_NUM]; uint32_t cur_capa; uint32_t num = FEC_CAPA_NUM; @@ -6537,10 +6274,12 @@ hns3_fec_set(struct rte_eth_dev *dev, uint32_t mode) if (ret < 0) return ret; - /* HNS3 PMD driver only support one bit set mode, e.g. 0x1, 0x4 */ - if (!is_fec_mode_one_bit_set(mode)) - hns3_err(hw, "FEC mode(0x%x) not supported in HNS3 PMD," + /* HNS3 PMD only support one bit set mode, e.g. 0x1, 0x4 */ + if (!is_fec_mode_one_bit_set(mode)) { + hns3_err(hw, "FEC mode(0x%x) not supported in HNS3 PMD, " "FEC mode should be only one bit set", mode); + return -EINVAL; + } /* * Check whether the configured mode is within the FEC capability. @@ -6752,78 +6491,6 @@ hns3_get_module_info(struct rte_eth_dev *dev, return 0; } -static int -hns3_parse_io_hint_func(const char *key, const char *value, void *extra_args) -{ - uint32_t hint = HNS3_IO_FUNC_HINT_NONE; - - RTE_SET_USED(key); - - if (strcmp(value, "vec") == 0) - hint = HNS3_IO_FUNC_HINT_VEC; - else if (strcmp(value, "sve") == 0) - hint = HNS3_IO_FUNC_HINT_SVE; - else if (strcmp(value, "simple") == 0) - hint = HNS3_IO_FUNC_HINT_SIMPLE; - else if (strcmp(value, "common") == 0) - hint = HNS3_IO_FUNC_HINT_COMMON; - - /* If the hint is valid then update output parameters */ - if (hint != HNS3_IO_FUNC_HINT_NONE) - *(uint32_t *)extra_args = hint; - - return 0; -} - -static const char * -hns3_get_io_hint_func_name(uint32_t hint) -{ - switch (hint) { - case HNS3_IO_FUNC_HINT_VEC: - return "vec"; - case HNS3_IO_FUNC_HINT_SVE: - return "sve"; - case HNS3_IO_FUNC_HINT_SIMPLE: - return "simple"; - case HNS3_IO_FUNC_HINT_COMMON: - return "common"; - default: - return "none"; - } -} - -void -hns3_parse_devargs(struct rte_eth_dev *dev) -{ - struct hns3_adapter *hns = dev->data->dev_private; - uint32_t rx_func_hint = HNS3_IO_FUNC_HINT_NONE; - uint32_t tx_func_hint = HNS3_IO_FUNC_HINT_NONE; - struct hns3_hw *hw = &hns->hw; - struct rte_kvargs *kvlist; - - if (dev->device->devargs == NULL) - return; - - kvlist = rte_kvargs_parse(dev->device->devargs->args, NULL); - if (!kvlist) - return; - - rte_kvargs_process(kvlist, HNS3_DEVARG_RX_FUNC_HINT, - &hns3_parse_io_hint_func, &rx_func_hint); - rte_kvargs_process(kvlist, HNS3_DEVARG_TX_FUNC_HINT, - &hns3_parse_io_hint_func, &tx_func_hint); - rte_kvargs_free(kvlist); - - if (rx_func_hint != HNS3_IO_FUNC_HINT_NONE) - hns3_warn(hw, "parsed %s = %s.", HNS3_DEVARG_RX_FUNC_HINT, - hns3_get_io_hint_func_name(rx_func_hint)); - hns->rx_func_hint = rx_func_hint; - if (tx_func_hint != HNS3_IO_FUNC_HINT_NONE) - hns3_warn(hw, "parsed %s = %s.", HNS3_DEVARG_TX_FUNC_HINT, - hns3_get_io_hint_func_name(tx_func_hint)); - hns->tx_func_hint = tx_func_hint; -} - static const struct eth_dev_ops hns3_eth_dev_ops = { .dev_configure = hns3_dev_configure, .dev_start = hns3_dev_start, @@ -6865,6 +6532,8 @@ static const struct eth_dev_ops hns3_eth_dev_ops = { .mac_addr_set = hns3_set_default_mac_addr, .set_mc_addr_list = hns3_set_mc_mac_addr_list, .link_update = hns3_dev_link_update, + .dev_set_link_up = hns3_dev_set_link_up, + .dev_set_link_down = hns3_dev_set_link_down, .rss_hash_update = hns3_dev_rss_hash_update, .rss_hash_conf_get = hns3_dev_rss_hash_conf_get, .reta_update = hns3_dev_rss_reta_update, @@ -6891,6 +6560,7 @@ static const struct eth_dev_ops hns3_eth_dev_ops = { .timesync_adjust_time = hns3_timesync_adjust_time, .timesync_read_time = hns3_timesync_read_time, .timesync_write_time = hns3_timesync_write_time, + .eth_dev_priv_dump = hns3_eth_dev_priv_dump, }; static const struct hns3_reset_ops hns3_reset_ops = { @@ -6903,51 +6573,39 @@ static const struct hns3_reset_ops hns3_reset_ops = { .start_service = hns3_start_service, }; +static void +hns3_init_hw_ops(struct hns3_hw *hw) +{ + hw->ops.add_mc_mac_addr = hns3_add_mc_mac_addr; + hw->ops.del_mc_mac_addr = hns3_remove_mc_mac_addr; + hw->ops.add_uc_mac_addr = hns3_add_uc_mac_addr; + hw->ops.del_uc_mac_addr = hns3_remove_uc_mac_addr; + hw->ops.bind_ring_with_vector = hns3_bind_ring_with_vector; +} + static int hns3_dev_init(struct rte_eth_dev *eth_dev) { struct hns3_adapter *hns = eth_dev->data->dev_private; - char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; - struct rte_ether_addr *eth_addr; struct hns3_hw *hw = &hns->hw; int ret; PMD_INIT_FUNC_TRACE(); - eth_dev->process_private = (struct hns3_process_private *) - rte_zmalloc_socket("hns3_filter_list", - sizeof(struct hns3_process_private), - RTE_CACHE_LINE_SIZE, eth_dev->device->numa_node); - if (eth_dev->process_private == NULL) { - PMD_INIT_LOG(ERR, "Failed to alloc memory for process private"); - return -ENOMEM; - } - /* initialize flow filter lists */ - hns3_filterlist_init(eth_dev); + hns3_flow_init(eth_dev); hns3_set_rxtx_function(eth_dev); eth_dev->dev_ops = &hns3_eth_dev_ops; eth_dev->rx_queue_count = hns3_rx_queue_count; - if (rte_eal_process_type() != RTE_PROC_PRIMARY) { - ret = hns3_mp_init_secondary(); - if (ret) { - PMD_INIT_LOG(ERR, "Failed to init for secondary " - "process, ret = %d", ret); - goto err_mp_init_secondary; - } + ret = hns3_mp_init(eth_dev); + if (ret) + goto err_mp_init; - hw->secondary_cnt++; + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { + hns3_tx_push_init(eth_dev); return 0; } - ret = hns3_mp_init_primary(); - if (ret) { - PMD_INIT_LOG(ERR, - "Failed to init for primary process, ret = %d", - ret); - goto err_mp_init_primary; - } - hw->adapter_state = HNS3_NIC_UNINITIALIZED; hns->is_vf = false; hw->data = eth_dev->data; @@ -6964,36 +6622,16 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) goto err_init_reset; hw->reset.ops = &hns3_reset_ops; + hns3_init_hw_ops(hw); ret = hns3_init_pf(eth_dev); if (ret) { PMD_INIT_LOG(ERR, "Failed to init pf: %d", ret); goto err_init_pf; } - /* Allocate memory for storing MAC addresses */ - eth_dev->data->mac_addrs = rte_zmalloc("hns3-mac", - sizeof(struct rte_ether_addr) * - HNS3_UC_MACADDR_NUM, 0); - if (eth_dev->data->mac_addrs == NULL) { - PMD_INIT_LOG(ERR, "Failed to allocate %zx bytes needed " - "to store MAC addresses", - sizeof(struct rte_ether_addr) * - HNS3_UC_MACADDR_NUM); - ret = -ENOMEM; - goto err_rte_zmalloc; - } - - eth_addr = (struct rte_ether_addr *)hw->mac.mac_addr; - if (!rte_is_valid_assigned_ether_addr(eth_addr)) { - rte_eth_random_addr(hw->mac.mac_addr); - hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, - (struct rte_ether_addr *)hw->mac.mac_addr); - hns3_warn(hw, "default mac_addr from firmware is an invalid " - "unicast address, using random MAC address %s", - mac_str); - } - rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.mac_addr, - ð_dev->data->mac_addrs[0]); + ret = hns3_init_mac_addrs(eth_dev); + if (ret != 0) + goto err_init_mac_addrs; hw->adapter_state = HNS3_NIC_INITIALIZED; @@ -7009,25 +6647,22 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) hns3_info(hw, "hns3 dev initialization successful!"); return 0; -err_rte_zmalloc: +err_init_mac_addrs: hns3_uninit_pf(eth_dev); err_init_pf: rte_free(hw->reset.wait_data); err_init_reset: - hns3_mp_uninit_primary(); + hns3_mp_uninit(eth_dev); -err_mp_init_primary: -err_mp_init_secondary: +err_mp_init: eth_dev->dev_ops = NULL; eth_dev->rx_pkt_burst = NULL; eth_dev->rx_descriptor_status = NULL; eth_dev->tx_pkt_burst = NULL; eth_dev->tx_pkt_prepare = NULL; eth_dev->tx_descriptor_status = NULL; - rte_free(eth_dev->process_private); - eth_dev->process_private = NULL; return ret; } @@ -7040,8 +6675,7 @@ hns3_dev_uninit(struct rte_eth_dev *eth_dev) PMD_INIT_FUNC_TRACE(); if (rte_eal_process_type() != RTE_PROC_PRIMARY) { - rte_free(eth_dev->process_private); - eth_dev->process_private = NULL; + hns3_mp_uninit(eth_dev); return 0; } @@ -7089,6 +6723,8 @@ RTE_PMD_REGISTER_PCI_TABLE(net_hns3, pci_id_hns3_map); RTE_PMD_REGISTER_KMOD_DEP(net_hns3, "* igb_uio | vfio-pci"); RTE_PMD_REGISTER_PARAM_STRING(net_hns3, HNS3_DEVARG_RX_FUNC_HINT "=vec|sve|simple|common " - HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common "); -RTE_LOG_REGISTER(hns3_logtype_init, pmd.net.hns3.init, NOTICE); -RTE_LOG_REGISTER(hns3_logtype_driver, pmd.net.hns3.driver, NOTICE); + HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common " + HNS3_DEVARG_DEV_CAPS_MASK "=<1-65535> " + HNS3_DEVARG_MBX_TIME_LIMIT_MS "= "); +RTE_LOG_REGISTER_SUFFIX(hns3_logtype_init, init, NOTICE); +RTE_LOG_REGISTER_SUFFIX(hns3_logtype_driver, driver, NOTICE);