X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fhns3%2Fhns3_ethdev.c;h=0add73d2f304beb7170d56c7f278f49abdc9e8e8;hb=31cdde02f0be730fc1b9b12a8b53f8a04fa423fc;hp=a7153545735f63274b963dbf54e2edd02cd8439c;hpb=d33fb7f939e6fb9c7882b57e9c3c0fab68c16874;p=dpdk.git diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c index a715354573..0add73d2f3 100644 --- a/drivers/net/hns3/hns3_ethdev.c +++ b/drivers/net/hns3/hns3_ethdev.c @@ -79,6 +79,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) { @@ -312,11 +317,9 @@ hns3_restore_vlan_table(struct hns3_adapter *hns) 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 (pf->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_ENABLE) + return hns3_vlan_pvid_configure(hns, + pf->port_base_vlan_cfg.pvid, 1); LIST_FOREACH(vlan_entry, &pf->vlan_list, next) { if (vlan_entry->hd_tbl_status) { @@ -1409,6 +1412,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 +1468,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 +1510,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 +1537,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 +1644,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 +1706,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; } @@ -1665,7 +1735,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; @@ -1730,7 +1800,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 +1813,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 +1824,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; @@ -2238,12 +2326,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 @@ -2663,6 +2749,7 @@ 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; hw->rx_buf_len = cfg.rx_buf_len; memcpy(hw->mac.mac_addr, cfg.mac_addr, RTE_ETHER_ADDR_LEN); hw->mac.phy_addr = cfg.phy_addr; @@ -2724,12 +2811,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 @@ -3546,6 +3631,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; @@ -3663,7 +3749,6 @@ 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 @@ -3673,11 +3758,7 @@ hns3_set_promisc_mode(struct hns3_hw *hw, bool en_uc_pmc, bool en_mc_pmc) vf_id = 0; 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 @@ -4026,6 +4107,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: @@ -4104,16 +4198,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: @@ -4126,13 +4210,10 @@ err_get_config: rte_intr_disable(&pci_dev->intr_handle); hns3_intr_unregister(&pci_dev->intr_handle, hns3_interrupt_handler, eth_dev); - err_intr_callback_register: - hns3_cmd_uninit(hw); - err_cmd_init: + hns3_cmd_uninit(hw); hns3_cmd_destroy_queue(hw); - err_cmd_init_queue: hw->io_base = NULL; @@ -4198,9 +4279,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; @@ -4261,6 +4342,37 @@ 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) +{ + hns3_restore_rss_filter(dev); +} + static int hns3_dev_start(struct rte_eth_dev *dev) { @@ -4281,17 +4393,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; } @@ -4324,8 +4449,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) @@ -4372,12 +4497,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 @@ -4610,31 +4735,24 @@ hns3_reinit_dev(struct hns3_adapter *hns) ret = hns3_reset_all_queues(hns); if (ret) { hns3_err(hw, "Failed to reset all queues: %d", ret); - goto err_init; + return ret; } ret = hns3_init_hardware(hns); if (ret) { hns3_err(hw, "Failed to init hardware: %d", ret); - goto err_init; + return ret; } ret = hns3_enable_hw_error_intr(hns, true); if (ret) { hns3_err(hw, "fail to enable hw error interrupts: %d", ret); - goto err_mac_init; + return ret; } hns3_info(hw, "Reset done, driver initialization finished."); return 0; - -err_mac_init: - hns3_uninit_umv_space(hw); -err_init: - hns3_cmd_uninit(hw); - - return ret; } static bool @@ -4898,9 +5016,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; } @@ -4934,6 +5061,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)