X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Fbnxt_ethdev.c;h=181de42d15dcffd0dae73090a5dea0ac045d8f86;hb=0a90c56eacd5e345b42c7f152d33ca4c39343a52;hp=4413b5d72e28f0a9a3c43cceeba155a6939694d2;hpb=9ba1e1671613a60897ce34713e0b07b0f27a5f82;p=dpdk.git diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index 4413b5d72e..181de42d15 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -368,7 +368,7 @@ static int bnxt_alloc_mem(struct bnxt *bp, bool reconfig) if (rc) goto alloc_mem_err; - rc = bnxt_alloc_vnic_attributes(bp); + rc = bnxt_alloc_vnic_attributes(bp, reconfig); if (rc) goto alloc_mem_err; @@ -786,17 +786,11 @@ skip_cosq_cfg: } } - /* default vnic 0 */ - rc = bnxt_setup_one_vnic(bp, 0); - if (rc) - goto err_out; /* VNIC configuration */ - if (BNXT_RFS_NEEDS_VNIC(bp)) { - for (i = 1; i < bp->nr_vnics; i++) { - rc = bnxt_setup_one_vnic(bp, i); - if (rc) - goto err_out; - } + for (i = 0; i < bp->nr_vnics; i++) { + rc = bnxt_setup_one_vnic(bp, i); + if (rc) + goto err_out; } for (j = 0; j < bp->tx_nr_rings; j++) { @@ -954,7 +948,7 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, return rc; /* MAC Specifics */ - dev_info->max_mac_addrs = bp->max_l2_ctx; + dev_info->max_mac_addrs = RTE_MIN(bp->max_l2_ctx, RTE_ETH_NUM_RECEIVE_MAC_ADDR); dev_info->max_hash_mac_addrs = 0; /* PF/VF specifics */ @@ -977,16 +971,10 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, dev_info->min_rx_bufsize = 1; dev_info->max_rx_pktlen = BNXT_MAX_PKT_LEN; - dev_info->rx_offload_capa = BNXT_DEV_RX_OFFLOAD_SUPPORT; - if (bp->flags & BNXT_FLAG_PTP_SUPPORTED) - dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP; - if (bp->vnic_cap_flags & BNXT_VNIC_CAP_VLAN_RX_STRIP) - dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP; + dev_info->rx_offload_capa = bnxt_get_rx_port_offloads(bp); dev_info->tx_queue_offload_capa = RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE; - dev_info->tx_offload_capa = BNXT_DEV_TX_OFFLOAD_SUPPORT | + dev_info->tx_offload_capa = bnxt_get_tx_port_offloads(bp) | dev_info->tx_queue_offload_capa; - if (bp->fw_cap & BNXT_FW_CAP_VLAN_TX_INSERT) - dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_VLAN_INSERT; dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT; dev_info->speed_capa = bnxt_get_speed_capabilities(bp); @@ -1067,6 +1055,7 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) { struct bnxt *bp = eth_dev->data->dev_private; uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads; + struct rte_eth_rss_conf *rss_conf = ð_dev->data->dev_conf.rx_adv_conf.rss_conf; int rc; bp->rx_queues = (void *)eth_dev->data->rx_queues; @@ -1141,6 +1130,17 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) rx_offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH; eth_dev->data->dev_conf.rxmode.offloads = rx_offloads; + /* application provides the hash key to program */ + if (rss_conf->rss_key != NULL) { + if (rss_conf->rss_key_len != HW_HASH_KEY_SIZE) + PMD_DRV_LOG(WARNING, "port %u RSS key len must be %d bytes long", + eth_dev->data->port_id, HW_HASH_KEY_SIZE); + else + memcpy(bp->rss_conf.rss_key, rss_conf->rss_key, HW_HASH_KEY_SIZE); + } + bp->rss_conf.rss_key_len = HW_HASH_KEY_SIZE; + bp->rss_conf.rss_hf = rss_conf->rss_hf; + bnxt_mtu_set_op(eth_dev, eth_dev->data->mtu); return 0; @@ -1465,8 +1465,7 @@ static int bnxt_dev_stop(struct rte_eth_dev *eth_dev) eth_dev->data->dev_started = 0; /* Prevent crashes when queues are still in use */ - eth_dev->rx_pkt_burst = &bnxt_dummy_recv_pkts; - eth_dev->tx_pkt_burst = &bnxt_dummy_xmit_pkts; + bnxt_stop_rxtx(eth_dev); bnxt_disable_int(bp); @@ -1525,7 +1524,7 @@ static int bnxt_dev_stop(struct rte_eth_dev *eth_dev) } /* Unload the driver, release resources */ -static int bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) +int bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) { struct bnxt *bp = eth_dev->data->dev_private; @@ -1541,7 +1540,7 @@ static int bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) return bnxt_dev_stop(eth_dev); } -static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) +int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) { struct bnxt *bp = eth_dev->data->dev_private; uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads; @@ -1673,6 +1672,7 @@ static int bnxt_dev_close_op(struct rte_eth_dev *eth_dev) rte_eal_alarm_cancel(bnxt_dev_reset_and_resume, (void *)bp); rte_eal_alarm_cancel(bnxt_dev_recover, (void *)bp); bnxt_cancel_fc_thread(bp); + rte_eal_alarm_cancel(bnxt_handle_vf_cfg_change, (void *)bp); if (eth_dev->data->dev_started) ret = bnxt_dev_stop(eth_dev); @@ -2125,11 +2125,6 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev, return -EINVAL; } - bp->flags |= BNXT_FLAG_UPDATE_HASH; - memcpy(ð_dev->data->dev_conf.rx_adv_conf.rss_conf, - rss_conf, - sizeof(*rss_conf)); - /* Update the default RSS VNIC(s) */ vnic = BNXT_GET_DEFAULT_VNIC(bp); vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_conf->rss_hf); @@ -2137,6 +2132,9 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev, bnxt_rte_to_hwrm_hash_level(bp, rss_conf->rss_hf, RTE_ETH_RSS_LEVEL(rss_conf->rss_hf)); + /* Cache the hash function */ + bp->rss_conf.rss_hf = rss_conf->rss_hf; + /* * If hashkey is not specified, use the previously configured * hashkey @@ -2152,6 +2150,9 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev, } memcpy(vnic->rss_hash_key, rss_conf->rss_key, rss_conf->rss_key_len); + /* Cache the hash key */ + memcpy(bp->rss_conf.rss_key, rss_conf->rss_key, HW_HASH_KEY_SIZE); + rss_config: rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic); return rc; @@ -2831,9 +2832,8 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev, uint32_t nb_mc_addr) { struct bnxt *bp = eth_dev->data->dev_private; - char *mc_addr_list = (char *)mc_addr_set; struct bnxt_vnic_info *vnic; - uint32_t off = 0, i = 0; + uint32_t i = 0; int rc; rc = is_bnxt_in_error(bp); @@ -2842,6 +2842,8 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev, vnic = BNXT_GET_DEFAULT_VNIC(bp); + bp->nb_mc_addr = nb_mc_addr; + if (nb_mc_addr > BNXT_MAX_MC_ADDRS) { vnic->flags |= BNXT_VNIC_INFO_ALLMULTI; goto allmulti; @@ -2849,14 +2851,10 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev, /* TODO Check for Duplicate mcast addresses */ vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI; - for (i = 0; i < nb_mc_addr; i++) { - memcpy(vnic->mc_list + off, &mc_addr_list[i], - RTE_ETHER_ADDR_LEN); - off += RTE_ETHER_ADDR_LEN; - } + for (i = 0; i < nb_mc_addr; i++) + rte_ether_addr_copy(&mc_addr_set[i], &bp->mcast_addr_list[i]); - vnic->mc_addr_cnt = i; - if (vnic->mc_addr_cnt) + if (bp->nb_mc_addr) vnic->flags |= BNXT_VNIC_INFO_MCAST; else vnic->flags &= ~BNXT_VNIC_INFO_MCAST; @@ -4264,6 +4262,18 @@ static int bnxt_restore_mac_filters(struct bnxt *bp) return 0; } +static int bnxt_restore_mcast_mac_filters(struct bnxt *bp) +{ + int ret = 0; + + ret = bnxt_dev_set_mc_addr_list_op(bp->eth_dev, bp->mcast_addr_list, + bp->nb_mc_addr); + if (ret) + PMD_DRV_LOG(ERR, "Failed to restore multicast MAC addreeses\n"); + + return ret; +} + static int bnxt_restore_filters(struct bnxt *bp) { struct rte_eth_dev *dev = bp->eth_dev; @@ -4284,8 +4294,15 @@ static int bnxt_restore_filters(struct bnxt *bp) if (ret) return ret; + /* if vlans are already programmed, this can fail with -EEXIST */ ret = bnxt_restore_vlan_filters(bp); - /* TODO restore other filters as well */ + if (ret && ret != -EEXIST) + return ret; + + ret = bnxt_restore_mcast_mac_filters(bp); + if (ret) + return ret; + return ret; } @@ -4323,6 +4340,8 @@ static void bnxt_dev_recover(void *arg) /* Clear Error flag so that device re-init should happen */ bp->flags &= ~BNXT_FLAG_FATAL_ERROR; + PMD_DRV_LOG(INFO, "Port: %u Starting recovery...\n", + bp->eth_dev->data->port_id); rc = bnxt_check_fw_ready(bp); if (rc) @@ -4347,7 +4366,14 @@ static void bnxt_dev_recover(void *arg) if (rc) goto err_start; - PMD_DRV_LOG(INFO, "Recovered from FW reset\n"); + rte_eth_fp_ops[bp->eth_dev->data->port_id].rx_pkt_burst = + bp->eth_dev->rx_pkt_burst; + rte_eth_fp_ops[bp->eth_dev->data->port_id].tx_pkt_burst = + bp->eth_dev->tx_pkt_burst; + rte_mb(); + + PMD_DRV_LOG(INFO, "Port: %u Recovered from FW reset\n", + bp->eth_dev->data->port_id); pthread_mutex_unlock(&bp->err_recovery_lock); return; @@ -4361,7 +4387,8 @@ err: RTE_ETH_EVENT_INTR_RMV, NULL); pthread_mutex_unlock(&bp->err_recovery_lock); - PMD_DRV_LOG(ERR, "Failed to recover from FW reset\n"); + PMD_DRV_LOG(ERR, "Port %u: Failed to recover from FW reset\n", + bp->eth_dev->data->port_id); } void bnxt_dev_reset_and_resume(void *arg) @@ -4372,6 +4399,8 @@ void bnxt_dev_reset_and_resume(void *arg) int rc; bnxt_dev_cleanup(bp); + PMD_DRV_LOG(INFO, "Port: %u Finished bnxt_dev_cleanup\n", + bp->eth_dev->data->port_id); bnxt_wait_for_device_shutdown(bp); @@ -4395,7 +4424,8 @@ void bnxt_dev_reset_and_resume(void *arg) rc = rte_eal_alarm_set(us, bnxt_dev_recover, (void *)bp); if (rc) - PMD_DRV_LOG(ERR, "Error setting recovery alarm"); + PMD_DRV_LOG(ERR, "Port %u: Error setting recovery alarm", + bp->eth_dev->data->port_id); } uint32_t bnxt_read_fw_status_reg(struct bnxt *bp, uint32_t index) @@ -4519,7 +4549,7 @@ reset: bp->flags |= BNXT_FLAG_FATAL_ERROR; bp->flags |= BNXT_FLAG_FW_RESET; - bnxt_stop_rxtx(bp); + bnxt_stop_rxtx(bp->eth_dev); PMD_DRV_LOG(ERR, "Detected FW dead condition\n"); @@ -4974,11 +5004,15 @@ static int bnxt_alloc_stats_mem(struct bnxt *bp) static int bnxt_setup_mac_addr(struct rte_eth_dev *eth_dev) { struct bnxt *bp = eth_dev->data->dev_private; + size_t max_mac_addr = RTE_MIN(bp->max_l2_ctx, RTE_ETH_NUM_RECEIVE_MAC_ADDR); int rc = 0; + if (bp->max_l2_ctx > RTE_ETH_NUM_RECEIVE_MAC_ADDR) + PMD_DRV_LOG(INFO, "Max number of MAC addrs supported is %d, but will be limited to %d\n", + bp->max_l2_ctx, RTE_ETH_NUM_RECEIVE_MAC_ADDR); + eth_dev->data->mac_addrs = rte_zmalloc("bnxt_mac_addr_tbl", - RTE_ETHER_ADDR_LEN * - bp->max_l2_ctx, + RTE_ETHER_ADDR_LEN * max_mac_addr, 0); if (eth_dev->data->mac_addrs == NULL) { PMD_DRV_LOG(ERR, "Failed to alloc MAC addr tbl\n"); @@ -5005,6 +5039,23 @@ static int bnxt_setup_mac_addr(struct rte_eth_dev *eth_dev) /* Copy the permanent MAC from the FUNC_QCAPS response */ memcpy(ð_dev->data->mac_addrs[0], bp->mac_addr, RTE_ETHER_ADDR_LEN); + /* + * Allocate memory to hold multicast mac addresses added. + * Used to restore them during reset recovery + */ + bp->mcast_addr_list = rte_zmalloc("bnxt_mcast_addr_tbl", + sizeof(struct rte_ether_addr) * + BNXT_MAX_MC_ADDRS, 0); + if (bp->mcast_addr_list == NULL) { + PMD_DRV_LOG(ERR, "Failed to allocate multicast addr table\n"); + return -ENOMEM; + } + bp->mc_list_dma_addr = rte_malloc_virt2iova(bp->mcast_addr_list); + if (bp->mc_list_dma_addr == RTE_BAD_IOVA) { + PMD_DRV_LOG(ERR, "Fail to map mcast_addr_list to physical memory\n"); + return -ENOMEM; + } + return rc; } @@ -5167,10 +5218,6 @@ static int bnxt_get_config(struct bnxt *bp) if (rc) return rc; - rc = bnxt_hwrm_cfa_adv_flow_mgmt_qcaps(bp); - if (rc) - return rc; - bnxt_hwrm_port_mac_qcfg(bp); bnxt_hwrm_parent_pf_qcfg(bp); @@ -5261,6 +5308,16 @@ static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev) } } + if (!reconfig_dev) { + bp->rss_conf.rss_key = rte_zmalloc("bnxt_rss_key", + HW_HASH_KEY_SIZE, 0); + if (bp->rss_conf.rss_key == NULL) { + PMD_DRV_LOG(ERR, "port %u cannot allocate RSS hash key memory", + bp->eth_dev->data->port_id); + return -ENOMEM; + } + } + rc = bnxt_alloc_mem(bp, reconfig_dev); if (rc) return rc; @@ -5822,8 +5879,7 @@ static void bnxt_free_ctx_mem_buf(struct bnxt_ctx_mem_buf_info *ctx) if (!ctx) return; - if (ctx->va) - rte_free(ctx->va); + rte_free(ctx->va); ctx->va = NULL; ctx->dma = RTE_BAD_IOVA; @@ -5905,6 +5961,10 @@ bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev) if (!reconfig_dev) { bnxt_free_hwrm_resources(bp); bnxt_free_error_recovery_info(bp); + rte_free(bp->mcast_addr_list); + bp->mcast_addr_list = NULL; + rte_free(bp->rss_conf.rss_key); + bp->rss_conf.rss_key = NULL; } bnxt_uninit_ctx_mem(bp); @@ -6291,4 +6351,4 @@ bool is_bnxt_supported(struct rte_eth_dev *dev) RTE_LOG_REGISTER_SUFFIX(bnxt_logtype_driver, driver, NOTICE); RTE_PMD_REGISTER_PCI(net_bnxt, bnxt_rte_pmd); RTE_PMD_REGISTER_PCI_TABLE(net_bnxt, bnxt_pci_id_map); - +RTE_PMD_REGISTER_KMOD_DEP(net_bnxt, "* igb_uio | uio_pci_generic | vfio-pci");