X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fhns3%2Fhns3_ethdev.c;h=62d87582da767539277ead71bf1254e8b6b67504;hb=1256805dd54d;hp=86676390fec995c6a6e0ce17ce53f2d116ddd73c;hpb=5e782bc2570c5746b8190d1b5c717de8ee77d0bd;p=dpdk.git diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c index 86676390fe..62d87582da 100644 --- a/drivers/net/hns3/hns3_ethdev.c +++ b/drivers/net/hns3/hns3_ethdev.c @@ -35,8 +35,6 @@ #define HNS3_DEFAULT_PORT_CONF_QUEUES_NUM 1 #define HNS3_SERVICE_INTERVAL 1000000 /* us */ -#define HNS3_PORT_BASE_VLAN_DISABLE 0 -#define HNS3_PORT_BASE_VLAN_ENABLE 1 #define HNS3_INVLID_PVID 0xFFFF #define HNS3_FILTER_TYPE_VF 0 @@ -79,6 +77,11 @@ static int hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid, int on); static int hns3_update_speed_duplex(struct rte_eth_dev *eth_dev); +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 void hns3_pf_disable_irq0(struct hns3_hw *hw) { @@ -308,15 +311,14 @@ static int hns3_restore_vlan_table(struct hns3_adapter *hns) { struct hns3_user_vlan_table *vlan_entry; + struct hns3_hw *hw = &hns->hw; struct hns3_pf *pf = &hns->pf; uint16_t vlan_id; int ret = 0; - if (pf->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_ENABLE) { - ret = hns3_vlan_pvid_configure(hns, pf->port_base_vlan_cfg.pvid, - 1); - return ret; - } + if (hw->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_ENABLE) + return hns3_vlan_pvid_configure(hns, + hw->port_base_vlan_cfg.pvid, 1); LIST_FOREACH(vlan_entry, &pf->vlan_list, next) { if (vlan_entry->hd_tbl_status) { @@ -333,7 +335,7 @@ hns3_restore_vlan_table(struct hns3_adapter *hns) static int hns3_vlan_filter_configure(struct hns3_adapter *hns, uint16_t vlan_id, int on) { - struct hns3_pf *pf = &hns->pf; + struct hns3_hw *hw = &hns->hw; bool writen_to_tbl = false; int ret = 0; @@ -351,7 +353,7 @@ hns3_vlan_filter_configure(struct hns3_adapter *hns, uint16_t vlan_id, int on) * vlan list. The vlan id in vlan list will be writen in vlan filter * table until port base vlan disabled */ - if (pf->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_DISABLE) { + if (hw->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_DISABLE) { ret = hns3_set_port_vlan_filter(hns, vlan_id, on); writen_to_tbl = true; } @@ -471,10 +473,9 @@ hns3_set_vlan_rx_offload_cfg(struct hns3_adapter *hns, /* * In current version VF is not supported when PF is driven by DPDK - * driver, the PF-related vf_id is 0, just need to configure parameters - * for vport_id 0. + * driver, just need to configure parameters for PF vport. */ - vport_id = 0; + vport_id = HNS3_PF_FUNC_ID; req->vf_offset = vport_id / HNS3_VF_NUM_PER_CMD; bitmap = 1 << (vport_id % HNS3_VF_NUM_PER_BYTE); req->vf_bitmap[req->vf_offset] = bitmap; @@ -505,11 +506,10 @@ static int hns3_en_hw_strip_rxvtag(struct hns3_adapter *hns, bool enable) { struct hns3_rx_vtag_cfg rxvlan_cfg; - struct hns3_pf *pf = &hns->pf; struct hns3_hw *hw = &hns->hw; int ret; - if (pf->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_DISABLE) { + if (hw->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_DISABLE) { rxvlan_cfg.strip_tag1_en = false; rxvlan_cfg.strip_tag2_en = enable; } else { @@ -555,22 +555,40 @@ hns3_set_vlan_filter_ctrl(struct hns3_hw *hw, uint8_t vlan_type, } static int -hns3_enable_vlan_filter(struct hns3_adapter *hns, bool enable) +hns3_vlan_filter_init(struct hns3_adapter *hns) { struct hns3_hw *hw = &hns->hw; int ret; ret = hns3_set_vlan_filter_ctrl(hw, HNS3_FILTER_TYPE_VF, - HNS3_FILTER_FE_EGRESS, false, 0); + HNS3_FILTER_FE_EGRESS, false, + HNS3_PF_FUNC_ID); if (ret) { - hns3_err(hw, "hns3 enable filter fail, ret =%d", ret); + hns3_err(hw, "failed to init vf vlan filter, ret = %d", ret); return ret; } ret = hns3_set_vlan_filter_ctrl(hw, HNS3_FILTER_TYPE_PORT, - HNS3_FILTER_FE_INGRESS, enable, 0); + HNS3_FILTER_FE_INGRESS, false, + HNS3_PF_FUNC_ID); if (ret) - hns3_err(hw, "hns3 enable filter fail, ret =%d", ret); + hns3_err(hw, "failed to init port vlan filter, ret = %d", ret); + + return ret; +} + +static int +hns3_enable_vlan_filter(struct hns3_adapter *hns, bool enable) +{ + struct hns3_hw *hw = &hns->hw; + int ret; + + ret = hns3_set_vlan_filter_ctrl(hw, HNS3_FILTER_TYPE_PORT, + HNS3_FILTER_FE_INGRESS, enable, + HNS3_PF_FUNC_ID); + if (ret) + hns3_err(hw, "failed to %s port vlan filter, ret = %d", + enable ? "enable" : "disable", ret); return ret; } @@ -588,6 +606,23 @@ 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) { + /* ignore vlan filter configuration during promiscuous mode */ + if (!dev->data->promiscuous) { + /* Enable or disable VLAN filter */ + enable = rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER ? + true : false; + + ret = hns3_enable_vlan_filter(hns, enable); + if (ret) { + rte_spinlock_unlock(&hw->lock); + hns3_err(hw, "failed to %s rx filter, ret = %d", + enable ? "enable" : "disable", ret); + return ret; + } + } + } + if (tmp_mask & ETH_VLAN_STRIP_MASK) { /* Enable or disable VLAN stripping */ enable = rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP ? @@ -596,7 +631,8 @@ hns3_vlan_offload_set(struct rte_eth_dev *dev, int mask) ret = hns3_en_hw_strip_rxvtag(hns, enable); if (ret) { rte_spinlock_unlock(&hw->lock); - hns3_err(hw, "failed to enable rx strip, ret =%d", ret); + hns3_err(hw, "failed to %s rx strip, ret = %d", + enable ? "enable" : "disable", ret); return ret; } } @@ -638,10 +674,9 @@ hns3_set_vlan_tx_offload_cfg(struct hns3_adapter *hns, /* * In current version VF is not supported when PF is driven by DPDK - * driver, the PF-related vf_id is 0, just need to configure parameters - * for vport_id 0. + * driver, just need to configure parameters for PF vport. */ - vport_id = 0; + vport_id = HNS3_PF_FUNC_ID; req->vf_offset = vport_id / HNS3_VF_NUM_PER_CMD; bitmap = 1 << (vport_id % HNS3_VF_NUM_PER_BYTE); req->vf_bitmap[req->vf_offset] = bitmap; @@ -691,12 +726,12 @@ hns3_vlan_txvlan_cfg(struct hns3_adapter *hns, uint16_t port_base_vlan_state, static void hns3_store_port_base_vlan_info(struct hns3_adapter *hns, uint16_t pvid, int on) { - struct hns3_pf *pf = &hns->pf; + struct hns3_hw *hw = &hns->hw; - pf->port_base_vlan_cfg.state = on ? + hw->port_base_vlan_cfg.state = on ? HNS3_PORT_BASE_VLAN_ENABLE : HNS3_PORT_BASE_VLAN_DISABLE; - pf->port_base_vlan_cfg.pvid = pvid; + hw->port_base_vlan_cfg.pvid = pvid; } static void @@ -740,13 +775,12 @@ static void hns3_remove_all_vlan_table(struct hns3_adapter *hns) { struct hns3_hw *hw = &hns->hw; - struct hns3_pf *pf = &hns->pf; int ret; hns3_rm_all_vlan_table(hns, true); - if (pf->port_base_vlan_cfg.pvid != HNS3_INVLID_PVID) { + if (hw->port_base_vlan_cfg.pvid != HNS3_INVLID_PVID) { ret = hns3_set_port_vlan_filter(hns, - pf->port_base_vlan_cfg.pvid, 0); + hw->port_base_vlan_cfg.pvid, 0); if (ret) { hns3_err(hw, "Failed to remove all vlan table, ret =%d", ret); @@ -760,7 +794,6 @@ hns3_update_vlan_filter_entries(struct hns3_adapter *hns, uint16_t port_base_vlan_state, uint16_t new_pvid, uint16_t old_pvid) { - struct hns3_pf *pf = &hns->pf; struct hns3_hw *hw = &hns->hw; int ret = 0; @@ -788,32 +821,35 @@ hns3_update_vlan_filter_entries(struct hns3_adapter *hns, } } - if (new_pvid == pf->port_base_vlan_cfg.pvid) + if (new_pvid == hw->port_base_vlan_cfg.pvid) hns3_add_all_vlan_table(hns); return ret; } static int -hns3_en_rx_strip_all(struct hns3_adapter *hns, int on) +hns3_en_pvid_strip(struct hns3_adapter *hns, int on) { + struct hns3_rx_vtag_cfg *old_cfg = &hns->pf.vtag_config.rx_vcfg; struct hns3_rx_vtag_cfg rx_vlan_cfg; - struct hns3_hw *hw = &hns->hw; bool rx_strip_en; int ret; - rx_strip_en = on ? true : false; - rx_vlan_cfg.strip_tag1_en = rx_strip_en; - rx_vlan_cfg.strip_tag2_en = rx_strip_en; + rx_strip_en = old_cfg->rx_vlan_offload_en ? true : false; + if (on) { + rx_vlan_cfg.strip_tag1_en = rx_strip_en; + rx_vlan_cfg.strip_tag2_en = true; + } else { + rx_vlan_cfg.strip_tag1_en = false; + rx_vlan_cfg.strip_tag2_en = rx_strip_en; + } rx_vlan_cfg.vlan1_vlan_prionly = false; rx_vlan_cfg.vlan2_vlan_prionly = false; - rx_vlan_cfg.rx_vlan_offload_en = rx_strip_en; + rx_vlan_cfg.rx_vlan_offload_en = old_cfg->rx_vlan_offload_en; ret = hns3_set_vlan_rx_offload_cfg(hns, &rx_vlan_cfg); - if (ret) { - hns3_err(hw, "enable strip rx failed, ret =%d", ret); + if (ret) return ret; - } hns3_update_rx_offload_cfg(hns, &rx_vlan_cfg); return ret; @@ -822,17 +858,16 @@ hns3_en_rx_strip_all(struct hns3_adapter *hns, int on) static int hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid, int on) { - struct hns3_pf *pf = &hns->pf; struct hns3_hw *hw = &hns->hw; uint16_t port_base_vlan_state; uint16_t old_pvid; int ret; - if (on == 0 && pvid != pf->port_base_vlan_cfg.pvid) { - if (pf->port_base_vlan_cfg.pvid != HNS3_INVLID_PVID) + if (on == 0 && pvid != hw->port_base_vlan_cfg.pvid) { + if (hw->port_base_vlan_cfg.pvid != HNS3_INVLID_PVID) hns3_warn(hw, "Invalid operation! As current pvid set " "is %u, disable pvid %u is invalid", - pf->port_base_vlan_cfg.pvid, pvid); + hw->port_base_vlan_cfg.pvid, pvid); return 0; } @@ -840,19 +875,21 @@ hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid, int on) HNS3_PORT_BASE_VLAN_DISABLE; ret = hns3_vlan_txvlan_cfg(hns, port_base_vlan_state, pvid); if (ret) { - hns3_err(hw, "Failed to config tx vlan, ret =%d", ret); + hns3_err(hw, "failed to config tx vlan for pvid, ret = %d", + ret); return ret; } - ret = hns3_en_rx_strip_all(hns, on); + ret = hns3_en_pvid_strip(hns, on); if (ret) { - hns3_err(hw, "Failed to config rx vlan strip, ret =%d", ret); + hns3_err(hw, "failed to config rx vlan strip for pvid, " + "ret = %d", ret); return ret; } if (pvid == HNS3_INVLID_PVID) goto out; - old_pvid = pf->port_base_vlan_cfg.pvid; + old_pvid = hw->port_base_vlan_cfg.pvid; ret = hns3_update_vlan_filter_entries(hns, port_base_vlan_state, pvid, old_pvid); if (ret) { @@ -888,11 +925,8 @@ hns3_vlan_pvid_set(struct rte_eth_dev *dev, uint16_t pvid, int on) static void init_port_base_vlan_info(struct hns3_hw *hw) { - struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); - struct hns3_pf *pf = &hns->pf; - - pf->port_base_vlan_cfg.state = HNS3_PORT_BASE_VLAN_DISABLE; - pf->port_base_vlan_cfg.pvid = HNS3_INVLID_PVID; + hw->port_base_vlan_cfg.state = HNS3_PORT_BASE_VLAN_DISABLE; + hw->port_base_vlan_cfg.pvid = HNS3_INVLID_PVID; } static int @@ -923,7 +957,7 @@ hns3_init_vlan_config(struct hns3_adapter *hns) if (rte_atomic16_read(&hw->reset.resetting) == 0) init_port_base_vlan_info(hw); - ret = hns3_enable_vlan_filter(hns, true); + ret = hns3_vlan_filter_init(hns); if (ret) { hns3_err(hw, "vlan init fail in pf, ret =%d", ret); return ret; @@ -965,17 +999,31 @@ hns3_restore_vlan_conf(struct hns3_adapter *hns) { struct hns3_pf *pf = &hns->pf; struct hns3_hw *hw = &hns->hw; + uint64_t offloads; + bool enable; int ret; + if (!hw->data->promiscuous) { + /* restore vlan filter states */ + offloads = hw->data->dev_conf.rxmode.offloads; + enable = offloads & DEV_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, " + "ret = %d", ret); + return ret; + } + } + ret = hns3_set_vlan_rx_offload_cfg(hns, &pf->vtag_config.rx_vcfg); if (ret) { - hns3_err(hw, "hns3 restore vlan rx conf fail, ret =%d", ret); + hns3_err(hw, "failed to restore vlan rx conf, ret = %d", ret); return ret; } ret = hns3_set_vlan_tx_offload_cfg(hns, &pf->vtag_config.tx_vcfg); if (ret) - hns3_err(hw, "hns3 restore vlan tx conf fail, ret =%d", ret); + hns3_err(hw, "failed to restore vlan tx conf, ret = %d", ret); return ret; } @@ -987,6 +1035,7 @@ hns3_dev_configure_vlan(struct rte_eth_dev *dev) struct rte_eth_dev_data *data = dev->data; struct rte_eth_txmode *txmode; struct hns3_hw *hw = &hns->hw; + int mask; int ret; txmode = &data->dev_conf.txmode; @@ -1000,17 +1049,26 @@ hns3_dev_configure_vlan(struct rte_eth_dev *dev) txmode->hw_vlan_reject_untagged); /* Apply vlan offload setting */ - ret = hns3_vlan_offload_set(dev, ETH_VLAN_STRIP_MASK); + mask = ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK; + ret = hns3_vlan_offload_set(dev, mask); if (ret) { - hns3_err(hw, "dev config vlan Strip failed, ret =%d", ret); + hns3_err(hw, "dev config rx vlan offload failed, ret = %d", + ret); return ret; } + /* + * If pvid config is not set in rte_eth_conf, driver needn't to set + * VLAN pvid related configuration to hardware. + */ + if (txmode->pvid == 0 && txmode->hw_vlan_insert_pvid == 0) + return 0; + /* Apply pvid setting */ ret = hns3_vlan_pvid_set(dev, txmode->pvid, txmode->hw_vlan_insert_pvid); if (ret) - hns3_err(hw, "dev config vlan pvid(%d) failed, ret =%d", + hns3_err(hw, "dev config vlan pvid(%d) failed, ret = %d", txmode->pvid, ret); return ret; @@ -1365,10 +1423,9 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) /* * In current version VF is not supported when PF is driven by DPDK - * driver, the PF-related vf_id is 0, just need to configure parameters - * for vf_id 0. + * driver, just need to configure parameters for PF vport. */ - vf_id = 0; + vf_id = HNS3_PF_FUNC_ID; hns3_set_field(egress_port, HNS3_MAC_EPORT_VFID_M, HNS3_MAC_EPORT_VFID_S, vf_id); @@ -1409,6 +1466,53 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) return ret; } +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)) { + rte_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) { + rte_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) { + rte_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) @@ -1418,12 +1522,27 @@ hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, int ret; rte_spinlock_lock(&hw->lock); - ret = hns3_add_uc_addr_common(hw, mac_addr); + + /* + * 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); rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, mac_addr); - hns3_err(hw, "Failed to add mac addr(%s): %d", mac_str, ret); + hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str, + ret); return ret; } @@ -1445,7 +1564,7 @@ hns3_remove_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) if (!rte_is_valid_assigned_ether_addr(mac_addr)) { rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, mac_addr); - hns3_err(hw, "Remove unicast mac addr err! addr(%s) invalid", + hns3_err(hw, "remove unicast mac addr err! addr(%s) invalid", mac_str); return -EINVAL; } @@ -1472,16 +1591,18 @@ hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx) int ret; rte_spinlock_lock(&hw->lock); - ret = hns3_remove_uc_addr_common(hw, mac_addr); + + 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) { - rte_spinlock_unlock(&hw->lock); rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, mac_addr); - hns3_err(hw, "Failed to remove mac addr(%s): %d", mac_str, ret); - return; + hns3_err(hw, "failed to remove mac addr(%s), ret = %d", mac_str, + ret); } - - rte_spinlock_unlock(&hw->lock); } static int @@ -1577,19 +1698,22 @@ hns3_configure_all_mac_addr(struct hns3_adapter *hns, bool del) for (i = 0; i < HNS3_UC_MACADDR_NUM; i++) { addr = &hw->data->mac_addrs[i]; - if (!rte_is_valid_assigned_ether_addr(addr)) + if (rte_is_zero_ether_addr(addr)) continue; - if (del) - ret = hns3_remove_uc_addr_common(hw, addr); + if (rte_is_multicast_ether_addr(addr)) + ret = del ? hns3_remove_mc_addr(hw, addr) : + hns3_add_mc_addr(hw, addr); else - ret = hns3_add_uc_addr_common(hw, addr); + ret = del ? hns3_remove_uc_addr_common(hw, addr) : + hns3_add_uc_addr_common(hw, addr); + if (ret) { err = ret; rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, addr); - hns3_dbg(hw, - "Failed to %s mac addr(%s). ret:%d i:%d", - del ? "remove" : "restore", mac_str, ret, i); + hns3_err(hw, "failed to %s mac addr(%s) index:%d " + "ret = %d.", del ? "remove" : "restore", + mac_str, i, ret); } } return err; @@ -1636,7 +1760,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) if (!rte_is_multicast_ether_addr(mac_addr)) { rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, mac_addr); - hns3_err(hw, "Failed to add mc mac addr, addr(%s) invalid", + hns3_err(hw, "failed to add mc mac addr, addr(%s) invalid", mac_str); return -EINVAL; } @@ -1654,10 +1778,9 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) /* * In current version VF is not supported when PF is driven by DPDK - * driver, the PF-related vf_id is 0, just need to configure parameters - * for vf_id 0. + * driver, just need to configure parameters for PF vport. */ - vf_id = 0; + vf_id = HNS3_PF_FUNC_ID; hns3_update_desc_vfid(desc, vf_id, false); ret = hns3_add_mac_vlan_tbl(hw, &req, desc); if (ret) { @@ -1665,7 +1788,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) hns3_err(hw, "mc mac vlan table is full"); rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, mac_addr); - hns3_err(hw, "Failed to add mc mac addr(%s): %d", mac_str, ret); + hns3_err(hw, "failed to add mc mac addr(%s): %d", mac_str, ret); } return ret; @@ -1697,10 +1820,9 @@ hns3_remove_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) /* * This mac addr exist, remove this handle's VFID for it. * In current version VF is not supported when PF is driven by - * DPDK driver, the PF-related vf_id is 0, just need to - * configure parameters for vf_id 0. + * DPDK driver, just need to configure parameters for PF vport. */ - vf_id = 0; + vf_id = HNS3_PF_FUNC_ID; hns3_update_desc_vfid(desc, vf_id, true); /* All the vfid is zero, so need to delete this entry */ @@ -1730,7 +1852,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw, uint32_t j; if (nb_mc_addr > HNS3_MC_MACADDR_NUM) { - hns3_err(hw, "Failed to set mc mac addr, nb_mc_addr(%d) " + hns3_err(hw, "failed to set mc mac addr, nb_mc_addr(%d) " "invalid. valid range: 0~%d", nb_mc_addr, HNS3_MC_MACADDR_NUM); return -EINVAL; @@ -1743,7 +1865,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw, rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, addr); hns3_err(hw, - "Failed to set mc mac addr, addr(%s) invalid.", + "failed to set mc mac addr, addr(%s) invalid.", mac_str); return -EINVAL; } @@ -1754,12 +1876,30 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw, rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, addr); - hns3_err(hw, "Failed to set mc mac 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])) { + rte_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; @@ -1926,8 +2066,8 @@ hns3_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del) err = ret; rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, addr); - hns3_dbg(hw, "%s mc mac addr: %s failed", - del ? "Remove" : "Restore", mac_str); + hns3_dbg(hw, "%s mc mac addr: %s failed for pf: ret = %d", + del ? "Remove" : "Restore", mac_str, ret); } } return err; @@ -2091,7 +2231,8 @@ hns3_init_ring_with_vector(struct hns3_hw *hw) * Rx interrupt. */ vec = hw->num_msi - 1; /* vector 0 for misc interrupt, not for queue */ - hw->intr_tqps_num = vec - 1; /* the last interrupt is reserved */ + /* vec - 1: the last interrupt is reserved */ + hw->intr_tqps_num = vec > hw->tqps_num ? hw->tqps_num : vec - 1; for (i = 0; i < hw->intr_tqps_num; i++) { /* * Set gap limiter and rate limiter configuration of queue's @@ -2168,6 +2309,7 @@ hns3_dev_configure(struct rte_eth_dev *dev) /* 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; rss_conf = conf->rx_adv_conf.rss_conf; if (rss_conf.rss_key == NULL) { rss_conf.rss_key = rss_cfg->key; @@ -2238,12 +2380,10 @@ hns3_config_mtu(struct hns3_hw *hw, uint16_t mps) } ret = hns3_buffer_alloc(hw); - if (ret) { + if (ret) hns3_err(hw, "Failed to allocate buffer, ret = %d", ret); - return ret; - } - return 0; + return ret; } static int @@ -2318,10 +2458,9 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) DEV_RX_OFFLOAD_KEEP_CRC | DEV_RX_OFFLOAD_SCATTER | DEV_RX_OFFLOAD_VLAN_STRIP | - DEV_RX_OFFLOAD_QINQ_STRIP | DEV_RX_OFFLOAD_VLAN_FILTER | - DEV_RX_OFFLOAD_VLAN_EXTEND | - DEV_RX_OFFLOAD_JUMBO_FRAME); + DEV_RX_OFFLOAD_JUMBO_FRAME | + DEV_RX_OFFLOAD_RSS_HASH); info->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE; info->tx_offload_capa = (DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | DEV_TX_OFFLOAD_IPV4_CKSUM | @@ -2371,9 +2510,18 @@ hns3_fw_version_get(struct rte_eth_dev *eth_dev, char *fw_version, { 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, "0x%08x", hw->fw_version); + 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; @@ -2472,7 +2620,6 @@ hns3_query_pf_resource(struct hns3_hw *hw) struct hns3_pf *pf = &hns->pf; struct hns3_pf_res_cmd *req; struct hns3_cmd_desc desc; - uint16_t num_msi; int ret; hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_PF_RSRC, true); @@ -2504,9 +2651,9 @@ hns3_query_pf_resource(struct hns3_hw *hw) pf->dv_buf_size = roundup(pf->dv_buf_size, HNS3_BUF_SIZE_UNIT); - num_msi = hns3_get_field(rte_le_to_cpu_16(req->pf_intr_vector_number), - HNS3_VEC_NUM_M, HNS3_VEC_NUM_S); - hw->num_msi = (num_msi > hw->tqps_num + 1) ? hw->tqps_num + 1 : num_msi; + hw->num_msi = + hns3_get_field(rte_le_to_cpu_16(req->pf_intr_vector_number), + HNS3_VEC_NUM_M, HNS3_VEC_NUM_S); return 0; } @@ -2725,12 +2872,10 @@ hns3_get_configuration(struct hns3_hw *hw) } ret = hns3_get_board_configuration(hw); - if (ret) { + if (ret) PMD_INIT_LOG(ERR, "Failed to get board configuration: %d", ret); - return ret; - } - return 0; + return ret; } static int @@ -2775,8 +2920,8 @@ hns3_map_tqp(struct hns3_hw *hw) */ tqp_id = 0; num = DIV_ROUND_UP(hw->total_tqps_num, HNS3_MAX_TQP_NUM_PER_FUNC); - for (func_id = 0; func_id < num; func_id++) { - is_pf = func_id == 0 ? true : false; + for (func_id = HNS3_PF_FUNC_ID; func_id < num; func_id++) { + is_pf = func_id == HNS3_PF_FUNC_ID ? true : false; for (i = 0; i < HNS3_MAX_TQP_NUM_PER_FUNC && tqp_id < tqps_num; i++) { ret = hns3_map_tqps_to_func(hw, func_id, tqp_id++, i, @@ -3547,6 +3692,7 @@ hns3_get_mac_ethertype_cmd_status(uint16_t cmdq_resp, uint8_t resp_code) "add mac ethertype failed for undefined, code=%d.", resp_code); return_status = -EIO; + break; } return return_status; @@ -3664,25 +3810,19 @@ hns3_set_promisc_mode(struct hns3_hw *hw, bool en_uc_pmc, bool en_mc_pmc) struct hns3_promisc_param param; bool en_bc_pmc = true; uint8_t vf_id; - int ret; /* * In current version VF is not supported when PF is driven by DPDK - * driver, the PF-related vf_id is 0, just need to configure parameters - * for vf_id 0. + * driver, just need to configure parameters for PF vport. */ - vf_id = 0; + vf_id = HNS3_PF_FUNC_ID; hns3_promisc_param_init(¶m, en_uc_pmc, en_mc_pmc, en_bc_pmc, vf_id); - ret = hns3_cmd_set_promisc_mode(hw, ¶m); - if (ret) - return ret; - - return 0; + return hns3_cmd_set_promisc_mode(hw, ¶m); } static int -hns3_clear_all_vfs_promisc_mode(struct hns3_hw *hw) +hns3_promisc_init(struct hns3_hw *hw) { struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); struct hns3_pf *pf = &hns->pf; @@ -3690,30 +3830,94 @@ hns3_clear_all_vfs_promisc_mode(struct hns3_hw *hw) uint16_t func_id; int ret; - /* func_id 0 is denoted PF, the VFs start from 1 */ - for (func_id = 1; func_id < pf->func_num; func_id++) { + ret = hns3_set_promisc_mode(hw, false, false); + if (ret) { + PMD_INIT_LOG(ERR, "failed to set promisc mode, ret = %d", ret); + return ret; + } + + /* + * In current version VFs are not supported when PF is driven by DPDK + * driver. After PF has been taken over by DPDK, the original VF will + * be invalid. So, there is a possibility of entry residues. It should + * clear VFs's promisc mode to avoid unnecessary bandwidth usage + * during init. + */ + for (func_id = HNS3_1ST_VF_FUNC_ID; func_id < pf->func_num; func_id++) { hns3_promisc_param_init(¶m, false, false, false, func_id); ret = hns3_cmd_set_promisc_mode(hw, ¶m); - if (ret) + if (ret) { + PMD_INIT_LOG(ERR, "failed to clear vf:%d promisc mode," + " ret = %d", func_id, ret); return ret; + } } return 0; } +static void +hns3_promisc_uninit(struct hns3_hw *hw) +{ + struct hns3_promisc_param param; + uint16_t func_id; + int ret; + + func_id = HNS3_PF_FUNC_ID; + + /* + * In current version VFs are not supported when PF is driven by + * DPDK driver, and VFs' promisc mode status has been cleared during + * init and their status will not change. So just clear PF's promisc + * mode status during uninit. + */ + hns3_promisc_param_init(¶m, false, false, false, func_id); + ret = hns3_cmd_set_promisc_mode(hw, ¶m); + if (ret) + PMD_INIT_LOG(ERR, "failed to clear promisc status during" + " uninit, ret = %d", ret); +} + static int hns3_dev_promiscuous_enable(struct rte_eth_dev *dev) { + bool allmulti = dev->data->all_multicast ? true : false; struct hns3_adapter *hns = dev->data->dev_private; struct hns3_hw *hw = &hns->hw; + uint64_t offloads; + int err; int ret; rte_spinlock_lock(&hw->lock); ret = hns3_set_promisc_mode(hw, true, true); - rte_spinlock_unlock(&hw->lock); - if (ret) - hns3_err(hw, "Failed to enable promiscuous mode, ret = %d", + if (ret) { + rte_spinlock_unlock(&hw->lock); + hns3_err(hw, "failed to enable promiscuous mode, ret = %d", ret); + return ret; + } + + /* + * When promiscuous mode was enabled, disable the vlan filter to let + * all packets coming in in the receiving direction. + */ + offloads = dev->data->dev_conf.rxmode.offloads; + if (offloads & DEV_RX_OFFLOAD_VLAN_FILTER) { + ret = hns3_enable_vlan_filter(hns, false); + if (ret) { + hns3_err(hw, "failed to enable promiscuous mode due to " + "failure to disable vlan filter, ret = %d", + ret); + err = hns3_set_promisc_mode(hw, false, allmulti); + if (err) + hns3_err(hw, "failed to restore promiscuous " + "status after disable vlan filter " + "failed during enabling promiscuous " + "mode, ret = %d", ret); + } + } + + rte_spinlock_unlock(&hw->lock); return ret; } @@ -3724,15 +3928,36 @@ hns3_dev_promiscuous_disable(struct rte_eth_dev *dev) bool allmulti = dev->data->all_multicast ? true : false; struct hns3_adapter *hns = dev->data->dev_private; struct hns3_hw *hw = &hns->hw; + uint64_t offloads; + int err; int ret; /* If now in all_multicast mode, must remain in all_multicast mode. */ rte_spinlock_lock(&hw->lock); ret = hns3_set_promisc_mode(hw, false, allmulti); - rte_spinlock_unlock(&hw->lock); - if (ret) - hns3_err(hw, "Failed to disable promiscuous mode, ret = %d", + if (ret) { + rte_spinlock_unlock(&hw->lock); + hns3_err(hw, "failed to disable promiscuous mode, ret = %d", ret); + return ret; + } + /* when promiscuous mode was disabled, restore the vlan filter status */ + offloads = dev->data->dev_conf.rxmode.offloads; + if (offloads & DEV_RX_OFFLOAD_VLAN_FILTER) { + ret = hns3_enable_vlan_filter(hns, true); + if (ret) { + hns3_err(hw, "failed to disable promiscuous mode due to" + " failure to restore vlan filter, ret = %d", + ret); + err = hns3_set_promisc_mode(hw, true, true); + if (err) + hns3_err(hw, "failed to restore promiscuous " + "status after enabling vlan filter " + "failed during disabling promiscuous " + "mode, ret = %d", ret); + } + } + rte_spinlock_unlock(&hw->lock); return ret; } @@ -3751,7 +3976,7 @@ hns3_dev_allmulticast_enable(struct rte_eth_dev *dev) ret = hns3_set_promisc_mode(hw, false, true); rte_spinlock_unlock(&hw->lock); if (ret) - hns3_err(hw, "Failed to enable allmulticast mode, ret = %d", + hns3_err(hw, "failed to enable allmulticast mode, ret = %d", ret); return ret; @@ -3772,7 +3997,7 @@ hns3_dev_allmulticast_disable(struct rte_eth_dev *dev) ret = hns3_set_promisc_mode(hw, false, false); rte_spinlock_unlock(&hw->lock); if (ret) - hns3_err(hw, "Failed to disable allmulticast mode, ret = %d", + hns3_err(hw, "failed to disable allmulticast mode, ret = %d", ret); return ret; @@ -3783,11 +4008,21 @@ hns3_dev_promisc_restore(struct hns3_adapter *hns) { struct hns3_hw *hw = &hns->hw; bool allmulti = hw->data->all_multicast ? true : false; + int ret; - if (hw->data->promiscuous) - return hns3_set_promisc_mode(hw, true, true); + if (hw->data->promiscuous) { + ret = hns3_set_promisc_mode(hw, true, true); + if (ret) + hns3_err(hw, "failed to restore promiscuous mode, " + "ret = %d", ret); + return ret; + } - return hns3_set_promisc_mode(hw, false, allmulti); + ret = hns3_set_promisc_mode(hw, false, allmulti); + if (ret) + hns3_err(hw, "failed to restore allmulticast mode, ret = %d", + ret); + return ret; } static int @@ -3985,15 +4220,9 @@ hns3_init_hardware(struct hns3_adapter *hns) goto err_mac_init; } - ret = hns3_set_promisc_mode(hw, false, false); - if (ret) { - PMD_INIT_LOG(ERR, "Failed to set promisc mode: %d", ret); - goto err_mac_init; - } - - ret = hns3_clear_all_vfs_promisc_mode(hw); + ret = hns3_promisc_init(hw); if (ret) { - PMD_INIT_LOG(ERR, "Failed to clear all vfs promisc mode: %d", + PMD_INIT_LOG(ERR, "Failed to init promisc: %d", ret); goto err_mac_init; } @@ -4027,6 +4256,19 @@ hns3_init_hardware(struct hns3_adapter *hns) PMD_INIT_LOG(ERR, "Failed to config gro: %d", ret); goto err_mac_init; } + + /* + * 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 interrupt, can be avoid. + */ + ret = hns3_init_ring_with_vector(hw); + if (ret) { + PMD_INIT_LOG(ERR, "Failed to init ring intr vector: %d", ret); + goto err_mac_init; + } + return 0; err_mac_init: @@ -4105,16 +4347,6 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) goto err_fdir; } - /* - * 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 interrupt, can be avoid. - */ - ret = hns3_init_ring_with_vector(hw); - if (ret) - goto err_fdir; - return 0; err_fdir: @@ -4149,6 +4381,7 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev) hns3_enable_hw_error_intr(hns, false); hns3_rss_uninit(hns); + hns3_promisc_uninit(hw); hns3_fdir_filter_uninit(hns); hns3_uninit_umv_space(hw); hns3_pf_disable_irq0(hw); @@ -4196,9 +4429,9 @@ hns3_map_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_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint8_t base = RTE_INTR_VEC_ZERO_OFFSET; + uint8_t vec = RTE_INTR_VEC_ZERO_OFFSET; uint32_t intr_vector; - uint8_t base = 0; - uint8_t vec = 0; uint16_t q_id; int ret; @@ -4259,6 +4492,31 @@ alloc_intr_vec_error: return ret; } +static int +hns3_restore_rx_interrupt(struct hns3_hw *hw) +{ + 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) + 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 0; +} + static void hns3_restore_filter(struct rte_eth_dev *dev) { @@ -4285,19 +4543,30 @@ hns3_dev_start(struct rte_eth_dev *dev) rte_spinlock_unlock(&hw->lock); return ret; } + ret = hns3_map_rx_interrupt(dev); + if (ret) { + hw->adapter_state = HNS3_NIC_CONFIGURED; + rte_spinlock_unlock(&hw->lock); + return ret; + } hw->adapter_state = HNS3_NIC_STARTED; rte_spinlock_unlock(&hw->lock); - ret = hns3_map_rx_interrupt(dev); - if (ret) - return ret; hns3_set_rxtx_function(dev); hns3_mp_req_start_rxtx(dev); rte_eal_alarm_set(HNS3_SERVICE_INTERVAL, hns3_service_handler, dev); hns3_restore_filter(dev); + /* Enable interrupt of all rx queues before enabling queues */ + hns3_dev_all_rx_queue_intr_enable(hw, true); + /* + * When finished the initialization, enable queues to receive/transmit + * packets. + */ + hns3_enable_all_queues(hw, true); + hns3_info(hw, "hns3 dev start successful!"); return 0; } @@ -4330,8 +4599,8 @@ hns3_unmap_rx_interrupt(struct rte_eth_dev *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 = 0; - uint8_t vec = 0; + 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) @@ -4378,12 +4647,12 @@ hns3_dev_stop(struct rte_eth_dev *dev) rte_spinlock_lock(&hw->lock); if (rte_atomic16_read(&hw->reset.resetting) == 0) { hns3_do_stop(hns); + hns3_unmap_rx_interrupt(dev); hns3_dev_release_mbufs(hns); hw->adapter_state = HNS3_NIC_CONFIGURED; } rte_eal_alarm_cancel(hns3_service_handler, dev); rte_spinlock_unlock(&hw->lock); - hns3_unmap_rx_interrupt(dev); } static void @@ -4812,7 +5081,7 @@ hns3_prepare_reset(struct hns3_adapter *hns) switch (hw->reset.level) { case HNS3_FUNC_RESET: - ret = hns3_func_reset_cmd(hw, 0); + ret = hns3_func_reset_cmd(hw, HNS3_PF_FUNC_ID); if (ret) return ret; @@ -4897,9 +5166,18 @@ hns3_start_service(struct hns3_adapter *hns) eth_dev = &rte_eth_devices[hw->data->port_id]; hns3_set_rxtx_function(eth_dev); hns3_mp_req_start_rxtx(eth_dev); - if (hw->adapter_state == HNS3_NIC_STARTED) + if (hw->adapter_state == HNS3_NIC_STARTED) { hns3_service_handler(eth_dev); + /* Enable interrupt of all rx queues before enabling queues */ + hns3_dev_all_rx_queue_intr_enable(hw, true); + /* + * When finished the initialization, enable queues to receive + * and transmit packets. + */ + hns3_enable_all_queues(hw, true); + } + return 0; } @@ -4933,6 +5211,10 @@ hns3_restore_conf(struct hns3_adapter *hns) if (ret) goto err_promisc; + ret = hns3_restore_rx_interrupt(hw); + if (ret) + goto err_promisc; + if (hns->hw.adapter_state == HNS3_NIC_STARTED) { ret = hns3_do_start(hns, false); if (ret) @@ -5076,9 +5358,21 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) struct hns3_adapter *hns = eth_dev->data->dev_private; struct hns3_hw *hw = &hns->hw; uint16_t device_id = pci_dev->id.device_id; + uint8_t revision; int ret; PMD_INIT_FUNC_TRACE(); + + /* 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; + eth_dev->process_private = (struct hns3_process_private *) rte_zmalloc_socket("hns3_filter_list", sizeof(struct hns3_process_private),