X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnx2x%2Fbnx2x.c;h=e1dfe602c87b0d86630dd5278a33c08d07c2b1f8;hb=3b307c55f2ac;hp=93f8586b555e9c4cf85f0367231853826756bfa0;hpb=ba7eeb035a5f442414f9dca6c12a9105a16576aa;p=dpdk.git diff --git a/drivers/net/bnx2x/bnx2x.c b/drivers/net/bnx2x/bnx2x.c index 93f8586b55..e1dfe602c8 100644 --- a/drivers/net/bnx2x/bnx2x.c +++ b/drivers/net/bnx2x/bnx2x.c @@ -25,11 +25,12 @@ #include #include #include +#include #define BNX2X_PMD_VER_PREFIX "BNX2X PMD" #define BNX2X_PMD_VERSION_MAJOR 1 -#define BNX2X_PMD_VERSION_MINOR 0 -#define BNX2X_PMD_VERSION_REVISION 6 +#define BNX2X_PMD_VERSION_MINOR 1 +#define BNX2X_PMD_VERSION_REVISION 0 #define BNX2X_PMD_VERSION_PATCH 1 static inline const char * @@ -112,6 +113,7 @@ static void bnx2x_pf_disable(struct bnx2x_softc *sc); static void bnx2x_update_rx_prod(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp, uint16_t rx_bd_prod, uint16_t rx_cq_prod); +static void bnx2x_link_report_locked(struct bnx2x_softc *sc); static void bnx2x_link_report(struct bnx2x_softc *sc); void bnx2x_link_status_update(struct bnx2x_softc *sc); static int bnx2x_alloc_mem(struct bnx2x_softc *sc); @@ -122,7 +124,7 @@ static __rte_noinline int bnx2x_nic_load(struct bnx2x_softc *sc); static int bnx2x_handle_sp_tq(struct bnx2x_softc *sc); -static void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp, int scan_fp); +static void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp); static void bnx2x_ack_sb(struct bnx2x_softc *sc, uint8_t igu_sb_id, uint8_t storm, uint16_t index, uint8_t op, uint8_t update); @@ -183,6 +185,7 @@ bnx2x_dma_alloc(struct bnx2x_softc *sc, size_t size, struct bnx2x_dma *dma, } dma->paddr = (uint64_t) z->iova; dma->vaddr = z->addr; + dma->mzone = (const void *)z; PMD_DRV_LOG(DEBUG, sc, "%s: virt=%p phys=%" PRIx64, msg, dma->vaddr, dma->paddr); @@ -190,6 +193,19 @@ bnx2x_dma_alloc(struct bnx2x_softc *sc, size_t size, struct bnx2x_dma *dma, return 0; } +void bnx2x_dma_free(struct bnx2x_dma *dma) +{ + if (dma->mzone == NULL) + return; + + rte_memzone_free((const struct rte_memzone *)dma->mzone); + dma->sc = NULL; + dma->paddr = 0; + dma->vaddr = NULL; + dma->nseg = 0; + dma->mzone = NULL; +} + static int bnx2x_acquire_hw_lock(struct bnx2x_softc *sc, uint32_t resource) { uint32_t lock_status; @@ -198,7 +214,12 @@ static int bnx2x_acquire_hw_lock(struct bnx2x_softc *sc, uint32_t resource) uint32_t hw_lock_control_reg; int cnt; +#ifndef RTE_LIBRTE_BNX2X_DEBUG_PERIODIC + if (resource) + PMD_INIT_FUNC_TRACE(sc); +#else PMD_INIT_FUNC_TRACE(sc); +#endif /* validate the resource is within range */ if (resource > HW_LOCK_MAX_RESOURCE_VALUE) { @@ -234,7 +255,8 @@ static int bnx2x_acquire_hw_lock(struct bnx2x_softc *sc, uint32_t resource) DELAY(5000); } - PMD_DRV_LOG(NOTICE, sc, "Resource lock timeout!"); + PMD_DRV_LOG(NOTICE, sc, "Resource 0x%x resource_bit 0x%x lock timeout!", + resource, resource_bit); return -1; } @@ -245,13 +267,18 @@ static int bnx2x_release_hw_lock(struct bnx2x_softc *sc, uint32_t resource) int func = SC_FUNC(sc); uint32_t hw_lock_control_reg; +#ifndef RTE_LIBRTE_BNX2X_DEBUG_PERIODIC + if (resource) + PMD_INIT_FUNC_TRACE(sc); +#else PMD_INIT_FUNC_TRACE(sc); +#endif /* validate the resource is within range */ if (resource > HW_LOCK_MAX_RESOURCE_VALUE) { PMD_DRV_LOG(NOTICE, sc, - "resource 0x%x > HW_LOCK_MAX_RESOURCE_VALUE", - resource); + "(resource 0x%x > HW_LOCK_MAX_RESOURCE_VALUE)" + " resource_bit 0x%x", resource, resource_bit); return -1; } @@ -275,6 +302,18 @@ static int bnx2x_release_hw_lock(struct bnx2x_softc *sc, uint32_t resource) return 0; } +static void bnx2x_acquire_phy_lock(struct bnx2x_softc *sc) +{ + BNX2X_PHY_LOCK(sc); + bnx2x_acquire_hw_lock(sc, HW_LOCK_RESOURCE_MDIO); +} + +static void bnx2x_release_phy_lock(struct bnx2x_softc *sc) +{ + bnx2x_release_hw_lock(sc, HW_LOCK_RESOURCE_MDIO); + BNX2X_PHY_UNLOCK(sc); +} + /* copy command into DMAE command memory and set DMAE command Go */ void bnx2x_post_dmae(struct bnx2x_softc *sc, struct dmae_command *dmae, int idx) { @@ -1075,6 +1114,12 @@ bnx2x_sp_post(struct bnx2x_softc *sc, int command, int cid, uint32_t data_hi, atomic_load_acq_long(&sc->cq_spq_left), atomic_load_acq_long(&sc->eq_spq_left)); + /* RAMROD completion is processed in bnx2x_intr_legacy() + * which can run from different contexts. + * Ask bnx2x_intr_intr() to process RAMROD + * completion whenever it gets scheduled. + */ + rte_atomic32_set(&sc->scan_fp, 1); bnx2x_sp_prod_update(sc); return 0; @@ -1970,6 +2015,8 @@ bnx2x_nic_unload(struct bnx2x_softc *sc, uint32_t unload_mode, uint8_t keep_link uint8_t global = FALSE; uint32_t val; + PMD_INIT_FUNC_TRACE(sc); + PMD_DRV_LOG(DEBUG, sc, "Starting NIC unload..."); /* mark driver as unloaded in shmem2 */ @@ -2073,6 +2120,9 @@ bnx2x_nic_unload(struct bnx2x_softc *sc, uint32_t unload_mode, uint8_t keep_link bnx2x_free_mem(sc); } + /* free the host hardware/software hsi structures */ + bnx2x_free_hsi_mem(sc); + bnx2x_free_fw_stats_mem(sc); sc->state = BNX2X_STATE_CLOSED; @@ -2132,8 +2182,10 @@ int bnx2x_tx_encap(struct bnx2x_tx_queue *txq, struct rte_mbuf *m0) tx_start_bd = &txq->tx_ring[TX_BD(bd_prod, txq)].start_bd; - tx_start_bd->addr = - rte_cpu_to_le_64(rte_mbuf_data_iova(m0)); + tx_start_bd->addr_lo = + rte_cpu_to_le_32(U64_LO(rte_mbuf_data_iova(m0))); + tx_start_bd->addr_hi = + rte_cpu_to_le_32(U64_HI(rte_mbuf_data_iova(m0))); tx_start_bd->nbytes = rte_cpu_to_le_16(m0->data_len); tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; tx_start_bd->general_data = @@ -2152,8 +2204,8 @@ int bnx2x_tx_encap(struct bnx2x_tx_queue *txq, struct rte_mbuf *m0) tx_start_bd->vlan_or_ethertype = rte_cpu_to_le_16(pkt_prod); else { - struct ether_hdr *eh = - rte_pktmbuf_mtod(m0, struct ether_hdr *); + struct rte_ether_hdr *eh = + rte_pktmbuf_mtod(m0, struct rte_ether_hdr *); tx_start_bd->vlan_or_ethertype = rte_cpu_to_le_16(rte_be_to_cpu_16(eh->ether_type)); @@ -2163,14 +2215,14 @@ int bnx2x_tx_encap(struct bnx2x_tx_queue *txq, struct rte_mbuf *m0) bd_prod = NEXT_TX_BD(bd_prod); if (IS_VF(sc)) { struct eth_tx_parse_bd_e2 *tx_parse_bd; - const struct ether_hdr *eh = - rte_pktmbuf_mtod(m0, struct ether_hdr *); + const struct rte_ether_hdr *eh = + rte_pktmbuf_mtod(m0, struct rte_ether_hdr *); uint8_t mac_type = UNICAST_ADDRESS; tx_parse_bd = &txq->tx_ring[TX_BD(bd_prod, txq)].parse_bd_e2; - if (is_multicast_ether_addr(&eh->d_addr)) { - if (is_broadcast_ether_addr(&eh->d_addr)) + if (rte_is_multicast_ether_addr(&eh->d_addr)) { + if (rte_is_broadcast_ether_addr(&eh->d_addr)) mac_type = BROADCAST_ADDRESS; else mac_type = MULTICAST_ADDRESS; @@ -2411,6 +2463,7 @@ static int bnx2x_alloc_mem(struct bnx2x_softc *sc) static void bnx2x_free_fw_stats_mem(struct bnx2x_softc *sc) { + bnx2x_dma_free(&sc->fw_stats_dma); sc->fw_stats_num = 0; sc->fw_stats_req_size = 0; @@ -2903,7 +2956,7 @@ static void bnx2x_link_attn(struct bnx2x_softc *sc) } } - bnx2x_link_report(sc); + bnx2x_link_report_locked(sc); if (IS_MF(sc)) { bnx2x_link_sync_notify(sc); @@ -2942,6 +2995,7 @@ static void bnx2x_attn_int_asserted(struct bnx2x_softc *sc, uint32_t asserted) if (asserted & ATTN_HARD_WIRED_MASK) { if (asserted & ATTN_NIG_FOR_FUNC) { + bnx2x_acquire_phy_lock(sc); /* save nig interrupt mask */ nig_mask = REG_RD(sc, nig_int_mask_addr); @@ -3039,6 +3093,7 @@ static void bnx2x_attn_int_asserted(struct bnx2x_softc *sc, uint32_t asserted) REG_WR(sc, nig_int_mask_addr, nig_mask); + bnx2x_release_phy_lock(sc); } } @@ -3838,8 +3893,10 @@ static void bnx2x_attn_int_deasserted3(struct bnx2x_softc *sc, uint32_t attn) if (sc->link_vars.periodic_flags & ELINK_PERIODIC_FLAGS_LINK_EVENT) { /* sync with link */ + bnx2x_acquire_phy_lock(sc); sc->link_vars.periodic_flags &= ~ELINK_PERIODIC_FLAGS_LINK_EVENT; + bnx2x_release_phy_lock(sc); if (IS_MF(sc)) { bnx2x_link_sync_notify(sc); } @@ -4029,7 +4086,9 @@ static void bnx2x_attn_int_deasserted0(struct bnx2x_softc *sc, uint32_t attn) } if ((attn & sc->link_vars.aeu_int_mask) && sc->port.pmf) { + bnx2x_acquire_phy_lock(sc); elink_handle_module_detect_int(&sc->link_params); + bnx2x_release_phy_lock(sc); } if (attn & HW_INTERRUT_ASSERT_SET_0) { @@ -4038,7 +4097,7 @@ static void bnx2x_attn_int_deasserted0(struct bnx2x_softc *sc, uint32_t attn) REG_WR(sc, reg_offset, val); rte_panic("FATAL HW block attention set0 0x%lx", - (attn & HW_INTERRUT_ASSERT_SET_0)); + (attn & (unsigned long)HW_INTERRUT_ASSERT_SET_0)); } } @@ -4171,6 +4230,9 @@ static uint16_t bnx2x_update_dsb_idx(struct bnx2x_softc *sc) struct host_sp_status_block *def_sb = sc->def_sb; uint16_t rc = 0; + if (!def_sb) + return 0; + mb(); /* status block is written to by the chip */ if (sc->def_att_idx != def_sb->atten_status_block.attn_bits_index) { @@ -4490,29 +4552,35 @@ static int bnx2x_handle_sp_tq(struct bnx2x_softc *sc) return rc; } -static void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp, int scan_fp) +static void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp) { struct bnx2x_softc *sc = fp->sc; uint8_t more_rx = FALSE; + /* Make sure FP is initialized */ + if (!fp->sb_running_index) + return; + PMD_DEBUG_PERIODIC_LOG(DEBUG, sc, "---> FP TASK QUEUE (%d) <--", fp->index); /* update the fastpath index */ bnx2x_update_fp_sb_idx(fp); - if (scan_fp) { + if (rte_atomic32_read(&sc->scan_fp) == 1) { if (bnx2x_has_rx_work(fp)) { more_rx = bnx2x_rxeof(sc, fp); } if (more_rx) { /* still more work to do */ - bnx2x_handle_fp_tq(fp, scan_fp); + bnx2x_handle_fp_tq(fp); return; } } + /* Assuming we have completed slow path completion, clear the flag */ + rte_atomic32_set(&sc->scan_fp, 0); bnx2x_ack_sb(sc, fp->igu_sb_id, USTORM_ID, le16toh(fp->fp_hc_idx), IGU_INT_ENABLE, 1); } @@ -4524,7 +4592,7 @@ static void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp, int scan_fp) * then calls a separate routine to handle the various * interrupt causes: link, RX, and TX. */ -int bnx2x_intr_legacy(struct bnx2x_softc *sc, int scan_fp) +int bnx2x_intr_legacy(struct bnx2x_softc *sc) { struct bnx2x_fastpath *fp; uint32_t status, mask; @@ -4553,12 +4621,18 @@ int bnx2x_intr_legacy(struct bnx2x_softc *sc, int scan_fp) fp = &sc->fp[i]; mask = (0x2 << (fp->index + CNIC_SUPPORT(sc))); if (status & mask) { - bnx2x_handle_fp_tq(fp, scan_fp); + /* acknowledge and disable further fastpath interrupts */ + bnx2x_ack_sb(sc, fp->igu_sb_id, USTORM_ID, + 0, IGU_INT_DISABLE, 0); + bnx2x_handle_fp_tq(fp); status &= ~mask; } } if (unlikely(status & 0x1)) { + /* acknowledge and disable further slowpath interrupts */ + bnx2x_ack_sb(sc, sc->igu_dsb_id, USTORM_ID, + 0, IGU_INT_DISABLE, 0); rc = bnx2x_handle_sp_tq(sc); status &= ~0x1; } @@ -4943,13 +5017,14 @@ static void bnx2x_update_rx_prod(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp, uint16_t rx_bd_prod, uint16_t rx_cq_prod) { - union ustorm_eth_rx_producers rx_prods; + struct ustorm_eth_rx_producers rx_prods; uint32_t i; + memset(&rx_prods, 0, sizeof(rx_prods)); + /* update producers */ - rx_prods.prod.bd_prod = rx_bd_prod; - rx_prods.prod.cqe_prod = rx_cq_prod; - rx_prods.prod.reserved = 0; + rx_prods.bd_prod = rx_bd_prod; + rx_prods.cqe_prod = rx_cq_prod; /* * Make sure that the BD and SGE data is updated before updating the @@ -4962,9 +5037,8 @@ bnx2x_update_rx_prod(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp, wmb(); for (i = 0; i < (sizeof(rx_prods) / 4); i++) { - REG_WR(sc, - (fp->ustorm_rx_prods_offset + (i * 4)), - rx_prods.raw_data[i]); + REG_WR(sc, (fp->ustorm_rx_prods_offset + (i * 4)), + ((uint32_t *)&rx_prods)[i]); } wmb(); /* keep prod updates ordered */ @@ -5157,20 +5231,6 @@ static void bnx2x_init_internal_common(struct bnx2x_softc *sc) { int i; - if (IS_MF_SI(sc)) { -/* - * In switch independent mode, the TSTORM needs to accept - * packets that failed classification, since approximate match - * mac addresses aren't written to NIG LLH. - */ - REG_WR8(sc, - (BAR_TSTRORM_INTMEM + - TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET), 2); - } else - REG_WR8(sc, - (BAR_TSTRORM_INTMEM + - TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET), 0); - /* * Zero this manually as its initialization is currently missing * in the initTool. @@ -5724,15 +5784,12 @@ static void bnx2x_init_objs(struct bnx2x_softc *sc) VNICS_PER_PATH(sc)); /* RSS configuration object */ - ecore_init_rss_config_obj(&sc->rss_conf_obj, - sc->fp[0].cl_id, - sc->fp[0].index, - SC_FUNC(sc), - SC_FUNC(sc), + ecore_init_rss_config_obj(sc, &sc->rss_conf_obj, sc->fp->cl_id, + sc->fp->index, SC_FUNC(sc), SC_FUNC(sc), BNX2X_SP(sc, rss_rdata), (rte_iova_t)BNX2X_SP_MAPPING(sc, rss_rdata), - ECORE_FILTER_RSS_CONF_PENDING, - &sc->sp_state, ECORE_OBJ_TYPE_RX); + ECORE_FILTER_RSS_CONF_PENDING, &sc->sp_state, + ECORE_OBJ_TYPE_RX); } /* @@ -5761,9 +5818,6 @@ static int bnx2x_func_start(struct bnx2x_softc *sc) start_params->network_cos_mode = FW_WRR; } - start_params->gre_tunnel_mode = 0; - start_params->gre_tunnel_rss = 0; - return ecore_func_state_change(sc, &func_params); } @@ -5773,7 +5827,7 @@ static int bnx2x_set_power_state(struct bnx2x_softc *sc, uint8_t state) /* If there is no power capability, silently succeed */ if (!(sc->devinfo.pcie_cap_flags & BNX2X_PM_CAPABLE_FLAG)) { - PMD_DRV_LOG(WARNING, sc, "No power capability"); + PMD_DRV_LOG(INFO, sc, "No power capability"); return 0; } @@ -6861,7 +6915,7 @@ bnx2x_fill_report_data(struct bnx2x_softc *sc, struct bnx2x_link_report_data *da } /* report link status to OS, should be called under phy_lock */ -static void bnx2x_link_report(struct bnx2x_softc *sc) +static void bnx2x_link_report_locked(struct bnx2x_softc *sc) { struct bnx2x_link_report_data cur_data; @@ -6882,14 +6936,19 @@ static void bnx2x_link_report(struct bnx2x_softc *sc) return; } + ELINK_DEBUG_P2(sc, "Change in link status : cur_data = %lx, last_reported_link = %lx", + cur_data.link_report_flags, + sc->last_reported_link.link_report_flags); + sc->link_cnt++; + ELINK_DEBUG_P1(sc, "link status change count = %x", sc->link_cnt); /* report new link params and remember the state for the next time */ rte_memcpy(&sc->last_reported_link, &cur_data, sizeof(cur_data)); if (bnx2x_test_bit(BNX2X_LINK_REPORT_LINK_DOWN, &cur_data.link_report_flags)) { - PMD_DRV_LOG(INFO, sc, "NIC Link is Down"); + ELINK_DEBUG_P0(sc, "NIC Link is Down"); } else { __rte_unused const char *duplex; __rte_unused const char *flow; @@ -6897,8 +6956,10 @@ static void bnx2x_link_report(struct bnx2x_softc *sc) if (bnx2x_test_and_clear_bit(BNX2X_LINK_REPORT_FULL_DUPLEX, &cur_data.link_report_flags)) { duplex = "full"; + ELINK_DEBUG_P0(sc, "link set to full duplex"); } else { duplex = "half"; + ELINK_DEBUG_P0(sc, "link set to half duplex"); } /* @@ -6935,6 +6996,14 @@ static void bnx2x_link_report(struct bnx2x_softc *sc) } } +static void +bnx2x_link_report(struct bnx2x_softc *sc) +{ + bnx2x_acquire_phy_lock(sc); + bnx2x_link_report_locked(sc); + bnx2x_release_phy_lock(sc); +} + void bnx2x_link_status_update(struct bnx2x_softc *sc) { if (sc->state != BNX2X_STATE_OPEN) { @@ -7000,7 +7069,7 @@ void bnx2x_link_status_update(struct bnx2x_softc *sc) } bnx2x_link_report(sc); } else { - bnx2x_link_report(sc); + bnx2x_link_report_locked(sc); bnx2x_stats_handle(sc, STATS_EVENT_LINK_UP); } } @@ -7013,6 +7082,8 @@ static int bnx2x_initial_phy_init(struct bnx2x_softc *sc, int load_mode) bnx2x_set_requested_fc(sc); + bnx2x_acquire_phy_lock(sc); + if (load_mode == LOAD_DIAG) { lp->loopback_mode = ELINK_LOOPBACK_XGXS; /* Prefer doing PHY loopback at 10G speed, if possible */ @@ -7032,6 +7103,8 @@ static int bnx2x_initial_phy_init(struct bnx2x_softc *sc, int load_mode) rc = elink_phy_init(&sc->link_params, &sc->link_vars); + bnx2x_release_phy_lock(sc); + bnx2x_calc_fc_adv(sc); if (sc->link_vars.link_up) { @@ -7070,7 +7143,7 @@ void bnx2x_periodic_callout(struct bnx2x_softc *sc) { if ((sc->state != BNX2X_STATE_OPEN) || (atomic_load_acq_long(&sc->periodic_flags) == PERIODIC_STOP)) { - PMD_DRV_LOG(INFO, sc, "periodic callout exit (state=0x%x)", + PMD_DRV_LOG(DEBUG, sc, "periodic callout exit (state=0x%x)", sc->state); return; } @@ -7082,7 +7155,9 @@ void bnx2x_periodic_callout(struct bnx2x_softc *sc) */ mb(); if (sc->port.pmf) { + bnx2x_acquire_phy_lock(sc); elink_period_func(&sc->link_params, &sc->link_vars); + bnx2x_release_phy_lock(sc); } } #ifdef BNX2X_PULSE @@ -7142,6 +7217,14 @@ int bnx2x_nic_load(struct bnx2x_softc *sc) } } + /* allocate the host hardware/software hsi structures */ + if (bnx2x_alloc_hsi_mem(sc) != 0) { + PMD_DRV_LOG(ERR, sc, "bnx2x_alloc_hsi_mem was failed"); + sc->state = BNX2X_STATE_CLOSED; + rc = -ENOMEM; + goto bnx2x_nic_load_error0; + } + if (bnx2x_alloc_fw_stats_mem(sc) != 0) { sc->state = BNX2X_STATE_CLOSED; rc = -ENOMEM; @@ -7357,6 +7440,7 @@ bnx2x_nic_load_error1: bnx2x_nic_load_error0: bnx2x_free_fw_stats_mem(sc); + bnx2x_free_hsi_mem(sc); bnx2x_free_mem(sc); return rc; @@ -8017,6 +8101,27 @@ static int bnx2x_get_shmem_info(struct bnx2x_softc *sc) ~ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED; } + val = sc->devinfo.bc_ver >> 8; + if (val < BNX2X_BC_VER) { + /* for now only warn later we might need to enforce this */ + PMD_DRV_LOG(NOTICE, sc, "This driver needs bc_ver %X but found %X, please upgrade BC\n", + BNX2X_BC_VER, val); + } + sc->link_params.feature_config_flags |= + (val >= REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL) ? + ELINK_FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : + 0; + + sc->link_params.feature_config_flags |= + (val >= REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL) ? + ELINK_FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY : 0; + sc->link_params.feature_config_flags |= + (val >= REQ_BC_VER_4_VRFY_AFEX_SUPPORTED) ? + ELINK_FEATURE_CONFIG_BC_SUPPORTS_AFEX : 0; + sc->link_params.feature_config_flags |= + (val >= REQ_BC_VER_4_SFP_TX_DISABLE_SUPPORTED) ? + ELINK_FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED : 0; + /* get the initial value of the link params */ sc->link_params.multi_phy_config = SHMEM_RD(sc, dev_info.port_hw_config[port].multi_phy_config); @@ -8262,7 +8367,7 @@ static int bnx2x_get_device_info(struct bnx2x_softc *sc) ((sc->devinfo.bc_ver >> 24) & 0xff), ((sc->devinfo.bc_ver >> 16) & 0xff), ((sc->devinfo.bc_ver >> 8) & 0xff)); - PMD_DRV_LOG(INFO, sc, "Bootcode version: %s", sc->devinfo.bc_ver_str); + PMD_DRV_LOG(DEBUG, sc, "Bootcode version: %s", sc->devinfo.bc_ver_str); /* get the bootcode shmem address */ sc->devinfo.mf_cfg_base = bnx2x_get_shmem_mf_cfg_base(sc); @@ -8781,9 +8886,9 @@ int bnx2x_alloc_hsi_mem(struct bnx2x_softc *sc) uint32_t i; if (IS_PF(sc)) { -/************************/ -/* DEFAULT STATUS BLOCK */ -/************************/ + /************************/ + /* DEFAULT STATUS BLOCK */ + /************************/ if (bnx2x_dma_alloc(sc, sizeof(struct host_sp_status_block), &sc->def_sb_dma, "def_sb", @@ -8793,9 +8898,9 @@ int bnx2x_alloc_hsi_mem(struct bnx2x_softc *sc) sc->def_sb = (struct host_sp_status_block *)sc->def_sb_dma.vaddr; -/***************/ -/* EVENT QUEUE */ -/***************/ + /***************/ + /* EVENT QUEUE */ + /***************/ if (bnx2x_dma_alloc(sc, BNX2X_PAGE_SIZE, &sc->eq_dma, "ev_queue", @@ -8806,9 +8911,9 @@ int bnx2x_alloc_hsi_mem(struct bnx2x_softc *sc) sc->eq = (union event_ring_elem *)sc->eq_dma.vaddr; -/*************/ -/* SLOW PATH */ -/*************/ + /*************/ + /* SLOW PATH */ + /*************/ if (bnx2x_dma_alloc(sc, sizeof(struct bnx2x_slowpath), &sc->sp_dma, "sp", @@ -8820,9 +8925,9 @@ int bnx2x_alloc_hsi_mem(struct bnx2x_softc *sc) sc->sp = (struct bnx2x_slowpath *)sc->sp_dma.vaddr; -/*******************/ -/* SLOW PATH QUEUE */ -/*******************/ + /*******************/ + /* SLOW PATH QUEUE */ + /*******************/ if (bnx2x_dma_alloc(sc, BNX2X_PAGE_SIZE, &sc->spq_dma, "sp_queue", @@ -8835,9 +8940,9 @@ int bnx2x_alloc_hsi_mem(struct bnx2x_softc *sc) sc->spq = (struct eth_spe *)sc->spq_dma.vaddr; -/***************************/ -/* FW DECOMPRESSION BUFFER */ -/***************************/ + /***************************/ + /* FW DECOMPRESSION BUFFER */ + /***************************/ if (bnx2x_dma_alloc(sc, FW_BUF_SIZE, &sc->gz_buf_dma, "fw_buf", RTE_CACHE_LINE_SIZE) != 0) { @@ -8861,9 +8966,9 @@ int bnx2x_alloc_hsi_mem(struct bnx2x_softc *sc) fp->sc = sc; fp->index = i; -/*******************/ -/* FP STATUS BLOCK */ -/*******************/ + /*******************/ + /* FP STATUS BLOCK */ + /*******************/ snprintf(buf, sizeof(buf), "fp_%d_sb", i); if (bnx2x_dma_alloc(sc, sizeof(union bnx2x_host_hc_status_block), @@ -8894,43 +8999,50 @@ void bnx2x_free_hsi_mem(struct bnx2x_softc *sc) for (i = 0; i < sc->num_queues; i++) { fp = &sc->fp[i]; -/*******************/ -/* FP STATUS BLOCK */ -/*******************/ + /*******************/ + /* FP STATUS BLOCK */ + /*******************/ memset(&fp->status_block, 0, sizeof(fp->status_block)); + bnx2x_dma_free(&fp->sb_dma); } - /***************************/ - /* FW DECOMPRESSION BUFFER */ - /***************************/ - - sc->gz_buf = NULL; + if (IS_PF(sc)) { + /***************************/ + /* FW DECOMPRESSION BUFFER */ + /***************************/ - /*******************/ - /* SLOW PATH QUEUE */ - /*******************/ + bnx2x_dma_free(&sc->gz_buf_dma); + sc->gz_buf = NULL; - sc->spq = NULL; + /*******************/ + /* SLOW PATH QUEUE */ + /*******************/ - /*************/ - /* SLOW PATH */ - /*************/ + bnx2x_dma_free(&sc->spq_dma); + sc->spq = NULL; - sc->sp = NULL; + /*************/ + /* SLOW PATH */ + /*************/ - /***************/ - /* EVENT QUEUE */ - /***************/ + bnx2x_dma_free(&sc->sp_dma); + sc->sp = NULL; - sc->eq = NULL; + /***************/ + /* EVENT QUEUE */ + /***************/ - /************************/ - /* DEFAULT STATUS BLOCK */ - /************************/ + bnx2x_dma_free(&sc->eq_dma); + sc->eq = NULL; - sc->def_sb = NULL; + /************************/ + /* DEFAULT STATUS BLOCK */ + /************************/ + bnx2x_dma_free(&sc->def_sb_dma); + sc->def_sb = NULL; + } } /* @@ -9341,6 +9453,8 @@ static int bnx2x_prev_unload(struct bnx2x_softc *sc) uint32_t fw, hw_lock_reg, hw_lock_val; uint32_t rc = 0; + PMD_INIT_FUNC_TRACE(sc); + /* * Clear HW from errors which may have resulted from an interrupted * DMAE transaction. @@ -9348,22 +9462,23 @@ static int bnx2x_prev_unload(struct bnx2x_softc *sc) bnx2x_prev_interrupted_dmae(sc); /* Release previously held locks */ - if (SC_FUNC(sc) <= 5) - hw_lock_reg = (MISC_REG_DRIVER_CONTROL_1 + SC_FUNC(sc) * 8); - else - hw_lock_reg = - (MISC_REG_DRIVER_CONTROL_7 + (SC_FUNC(sc) - 6) * 8); + hw_lock_reg = (SC_FUNC(sc) <= 5) ? + (MISC_REG_DRIVER_CONTROL_1 + SC_FUNC(sc) * 8) : + (MISC_REG_DRIVER_CONTROL_7 + (SC_FUNC(sc) - 6) * 8); hw_lock_val = (REG_RD(sc, hw_lock_reg)); if (hw_lock_val) { if (hw_lock_val & HW_LOCK_RESOURCE_NVRAM) { + PMD_DRV_LOG(DEBUG, sc, "Releasing previously held NVRAM lock\n"); REG_WR(sc, MCP_REG_MCPR_NVM_SW_ARB, (MCPR_NVM_SW_ARB_ARB_REQ_CLR1 << SC_PORT(sc))); } + PMD_DRV_LOG(DEBUG, sc, "Releasing previously held HW lock\n"); REG_WR(sc, hw_lock_reg, 0xffffffff); } if (MCPR_ACCESS_LOCK_LOCK & REG_RD(sc, MCP_REG_MCPR_ACCESS_LOCK)) { + PMD_DRV_LOG(DEBUG, sc, "Releasing previously held ALR\n"); REG_WR(sc, MCP_REG_MCPR_ACCESS_LOCK, 0); } @@ -9516,8 +9631,8 @@ static void bnx2x_init_rte(struct bnx2x_softc *sc) } #define FW_HEADER_LEN 104 -#define FW_NAME_57711 "/lib/firmware/bnx2x/bnx2x-e1h-7.2.51.0.fw" -#define FW_NAME_57810 "/lib/firmware/bnx2x/bnx2x-e2-7.2.51.0.fw" +#define FW_NAME_57711 "/lib/firmware/bnx2x/bnx2x-e1h-7.13.11.0.fw" +#define FW_NAME_57810 "/lib/firmware/bnx2x/bnx2x-e2-7.13.11.0.fw" void bnx2x_load_firmware(struct bnx2x_softc *sc) { @@ -9677,13 +9792,13 @@ int bnx2x_attach(struct bnx2x_softc *sc) bnx2x_get_phy_info(sc); } else { /* Left mac of VF unfilled, PF should set it for VF */ - memset(sc->link_params.mac_addr, 0, ETHER_ADDR_LEN); + memset(sc->link_params.mac_addr, 0, RTE_ETHER_ADDR_LEN); } sc->wol = 0; /* set the default MTU (changed via ifconfig) */ - sc->mtu = ETHER_MTU; + sc->mtu = RTE_ETHER_MTU; bnx2x_set_modes_bitmap(sc); @@ -9693,6 +9808,8 @@ int bnx2x_attach(struct bnx2x_softc *sc) sc->fw_seq = (SHMEM_RD(sc, func_mb[SC_FW_MB_IDX(sc)].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); + PMD_DRV_LOG(DEBUG, sc, "prev unload fw_seq 0x%04x", + sc->fw_seq); bnx2x_prev_unload(sc); } @@ -9834,8 +9951,10 @@ static void bnx2x_common_init_phy(struct bnx2x_softc *sc) shmem2_base[1] = SHMEM2_RD(sc, other_shmem2_base_addr); } + bnx2x_acquire_phy_lock(sc); elink_common_init_phy(sc, shmem_base, shmem2_base, sc->devinfo.chip_id, 0); + bnx2x_release_phy_lock(sc); } static void bnx2x_pf_disable(struct bnx2x_softc *sc) @@ -10229,7 +10348,7 @@ static int bnx2x_init_hw_common(struct bnx2x_softc *sc) /* clean the DMAE memory */ sc->dmae_ready = 1; - ecore_init_fill(sc, TSEM_REG_PRAM, 0, 8); + ecore_init_fill(sc, TSEM_REG_PRAM, 0, 8, 1); ecore_init_block(sc, BLOCK_TCM, PHASE_COMMON); @@ -10257,7 +10376,6 @@ static int bnx2x_init_hw_common(struct bnx2x_softc *sc) ecore_init_block(sc, BLOCK_TM, PHASE_COMMON); ecore_init_block(sc, BLOCK_DORQ, PHASE_COMMON); - REG_WR(sc, DORQ_REG_DPM_CID_OFST, BNX2X_DB_SHIFT); if (!CHIP_REV_IS_SLOW(sc)) { /* enable hw interrupt from doorbell Q */ @@ -11314,7 +11432,9 @@ static int bnx2x_init_hw_func(struct bnx2x_softc *sc) static void bnx2x_link_reset(struct bnx2x_softc *sc) { if (!BNX2X_NOMCP(sc)) { + bnx2x_acquire_phy_lock(sc); elink_lfa_reset(&sc->link_params, &sc->link_vars); + bnx2x_release_phy_lock(sc); } else { if (!CHIP_REV_IS_SLOW(sc)) { PMD_DRV_LOG(WARNING, sc, @@ -11440,7 +11560,7 @@ static void bnx2x_reset_func(struct bnx2x_softc *sc) ilt_cli.end = ILT_NUM_PAGE_ENTRIES - 1; ilt_cli.client_num = ILT_CLIENT_TM; - ecore_ilt_boundry_init_op(sc, &ilt_cli, 0); + ecore_ilt_boundary_init_op(sc, &ilt_cli, 0, INITOP_CLEAR); } /* this assumes that reset_port() called before reset_func() */ @@ -11668,53 +11788,47 @@ static const char *get_bnx2x_flags(uint32_t flags) for (i = 0; i < 5; i++) if (flags & (1 << i)) { - strcat(flag_str, flag[i]); + strlcat(flag_str, flag[i], sizeof(flag_str)); flags ^= (1 << i); } if (flags) { static char unknown[BNX2X_INFO_STR_MAX]; snprintf(unknown, 32, "Unknown flag mask %x", flags); - strcat(flag_str, unknown); + strlcat(flag_str, unknown, sizeof(flag_str)); } return flag_str; } -/* - * Prints useful adapter info. - */ +/* Prints useful adapter info. */ void bnx2x_print_adapter_info(struct bnx2x_softc *sc) { int i = 0; - __rte_unused uint32_t ext_phy_type; - PMD_INIT_FUNC_TRACE(sc); - if (sc->link_vars.phy_flags & PHY_XGXS_FLAG) - ext_phy_type = ELINK_XGXS_EXT_PHY_TYPE(REG_RD(sc, - sc-> - devinfo.shmem_base - + offsetof(struct - shmem_region, - dev_info.port_hw_config - [0].external_phy_config))); - else - ext_phy_type = ELINK_SERDES_EXT_PHY_TYPE(REG_RD(sc, - sc-> - devinfo.shmem_base - + - offsetof(struct - shmem_region, - dev_info.port_hw_config - [0].external_phy_config))); - - PMD_DRV_LOG(INFO, sc, "\n\n===================================\n"); + PMD_DRV_LOG(INFO, sc, "========================================"); + /* DPDK and Driver versions */ + PMD_DRV_LOG(INFO, sc, "%12s : %s", "DPDK", + rte_version()); + PMD_DRV_LOG(INFO, sc, "%12s : %s", "Driver", + bnx2x_pmd_version()); + /* Firmware versions. */ + PMD_DRV_LOG(INFO, sc, "%12s : %d.%d.%d", + "Firmware", + BNX2X_5710_FW_MAJOR_VERSION, + BNX2X_5710_FW_MINOR_VERSION, + BNX2X_5710_FW_REVISION_VERSION); + PMD_DRV_LOG(INFO, sc, "%12s : %s", + "Bootcode", sc->devinfo.bc_ver_str); /* Hardware chip info. */ PMD_DRV_LOG(INFO, sc, "%12s : %#08x", "ASIC", sc->devinfo.chip_id); PMD_DRV_LOG(INFO, sc, "%12s : %c%d", "Rev", (CHIP_REV(sc) >> 12) + 'A', (CHIP_METAL(sc) >> 4)); - - /* Bus info. */ - PMD_DRV_LOG(INFO, sc, - "%12s : %d, ", "Bus PCIe", sc->devinfo.pcie_link_width); + /* Bus PCIe info. */ + PMD_DRV_LOG(INFO, sc, "%12s : 0x%x", "Vendor Id", + sc->devinfo.vendor_id); + PMD_DRV_LOG(INFO, sc, "%12s : 0x%x", "Device Id", + sc->devinfo.device_id); + PMD_DRV_LOG(INFO, sc, "%12s : width x%d, ", "Bus PCIe", + sc->devinfo.pcie_link_width); switch (sc->devinfo.pcie_link_speed) { case 1: PMD_DRV_LOG(INFO, sc, "%23s", "2.5 Gbps"); @@ -11728,62 +11842,45 @@ void bnx2x_print_adapter_info(struct bnx2x_softc *sc) default: PMD_DRV_LOG(INFO, sc, "%33s", "Unknown link speed"); } - /* Device features. */ PMD_DRV_LOG(INFO, sc, "%12s : ", "Flags"); - /* Miscellaneous flags. */ if (sc->devinfo.pcie_cap_flags & BNX2X_MSI_CAPABLE_FLAG) { PMD_DRV_LOG(INFO, sc, "%18s", "MSI"); i++; } - if (sc->devinfo.pcie_cap_flags & BNX2X_MSIX_CAPABLE_FLAG) { if (i > 0) PMD_DRV_LOG(INFO, sc, "|"); PMD_DRV_LOG(INFO, sc, "%20s", "MSI-X"); i++; } + PMD_DRV_LOG(INFO, sc, "%12s : %s", "OVLAN", (OVLAN(sc) ? "YES" : "NO")); + PMD_DRV_LOG(INFO, sc, "%12s : %s", "MF", (IS_MF(sc) ? "YES" : "NO")); + PMD_DRV_LOG(INFO, sc, "========================================"); +} - if (IS_PF(sc)) { - PMD_DRV_LOG(INFO, sc, "%12s : ", "Queues"); - switch (sc->sp->rss_rdata.rss_mode) { - case ETH_RSS_MODE_DISABLED: - PMD_DRV_LOG(INFO, sc, "%19s", "None"); - break; - case ETH_RSS_MODE_REGULAR: - PMD_DRV_LOG(INFO, sc, - "%18s : %d", "RSS", sc->num_queues); - break; - default: - PMD_DRV_LOG(INFO, sc, "%22s", "Unknown"); - break; - } - } - - /* RTE and Driver versions */ - PMD_DRV_LOG(INFO, sc, "%12s : %s", "DPDK", - rte_version()); - PMD_DRV_LOG(INFO, sc, "%12s : %s", "Driver", - bnx2x_pmd_version()); +/* Prints useful device info. */ +void bnx2x_print_device_info(struct bnx2x_softc *sc) +{ + __rte_unused uint32_t ext_phy_type; + uint32_t offset, reg_val; - /* Firmware versions and device features. */ - PMD_DRV_LOG(INFO, sc, "%12s : %d.%d.%d", - "Firmware", - BNX2X_5710_FW_MAJOR_VERSION, - BNX2X_5710_FW_MINOR_VERSION, - BNX2X_5710_FW_REVISION_VERSION); - PMD_DRV_LOG(INFO, sc, "%12s : %s", - "Bootcode", sc->devinfo.bc_ver_str); + PMD_INIT_FUNC_TRACE(sc); + offset = offsetof(struct shmem_region, + dev_info.port_hw_config[0].external_phy_config); + reg_val = REG_RD(sc, sc->devinfo.shmem_base + offset); + if (sc->link_vars.phy_flags & PHY_XGXS_FLAG) + ext_phy_type = ELINK_XGXS_EXT_PHY_TYPE(reg_val); + else + ext_phy_type = ELINK_SERDES_EXT_PHY_TYPE(reg_val); - PMD_DRV_LOG(INFO, sc, "\n\n===================================\n"); + /* Device features. */ PMD_DRV_LOG(INFO, sc, "%12s : %u", "Bnx2x Func", sc->pcie_func); PMD_DRV_LOG(INFO, sc, "%12s : %s", "Bnx2x Flags", get_bnx2x_flags(sc->flags)); PMD_DRV_LOG(INFO, sc, "%12s : %s", "DMAE Is", (sc->dmae_ready ? "Ready" : "Not Ready")); - PMD_DRV_LOG(INFO, sc, "%12s : %s", "OVLAN", (OVLAN(sc) ? "YES" : "NO")); - PMD_DRV_LOG(INFO, sc, "%12s : %s", "MF", (IS_MF(sc) ? "YES" : "NO")); PMD_DRV_LOG(INFO, sc, "%12s : %u", "MTU", sc->mtu); PMD_DRV_LOG(INFO, sc, "%12s : %s", "PHY Type", get_ext_phy_type(ext_phy_type)); @@ -11799,9 +11896,30 @@ void bnx2x_print_adapter_info(struct bnx2x_softc *sc) if (sc->recovery_state) PMD_DRV_LOG(INFO, sc, "%12s : %s", "Recovery", get_recovery_state(sc->recovery_state)); + /* Queue info. */ + if (IS_PF(sc)) { + switch (sc->sp->rss_rdata.rss_mode) { + case ETH_RSS_MODE_DISABLED: + PMD_DRV_LOG(INFO, sc, "%12s : %s", "Queues", "RSS mode - None"); + break; + case ETH_RSS_MODE_REGULAR: + PMD_DRV_LOG(INFO, sc, "%12s : %s,", "Queues", "RSS mode - Regular"); + PMD_DRV_LOG(INFO, sc, "%16d", sc->num_queues); + break; + default: + PMD_DRV_LOG(INFO, sc, "%12s : %s", "Queues", "RSS mode - Unknown"); + break; + } + } PMD_DRV_LOG(INFO, sc, "%12s : CQ = %lx, EQ = %lx", "SPQ Left", sc->cq_spq_left, sc->eq_spq_left); + PMD_DRV_LOG(INFO, sc, "%12s : %x", "Switch", sc->link_params.switch_cfg); - PMD_DRV_LOG(INFO, sc, "\n\n===================================\n"); + PMD_DRV_LOG(INFO, sc, "pcie_bus=%d, pcie_device=%d", + sc->pcie_bus, sc->pcie_device); + PMD_DRV_LOG(INFO, sc, "bar0.addr=%p, bar1.addr=%p", + sc->bar[BAR0].base_addr, sc->bar[BAR1].base_addr); + PMD_DRV_LOG(INFO, sc, "port=%d, path=%d, vnic=%d, func=%d", + PORT_ID(sc), PATH_ID(sc), VNIC_ID(sc), FUNC_ID(sc)); }