diff options
Diffstat (limited to 'drivers/net/bnx2x')
-rw-r--r-- | drivers/net/bnx2x/bnx2x.c | 59 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x.h | 9 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_ethdev.c | 32 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_rxtx.c | 21 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_rxtx.h | 3 | ||||
-rw-r--r-- | drivers/net/bnx2x/ecore_hsi.h | 2 | ||||
-rw-r--r-- | drivers/net/bnx2x/ecore_reg.h | 2 | ||||
-rw-r--r-- | drivers/net/bnx2x/ecore_sp.c | 12 | ||||
-rw-r--r-- | drivers/net/bnx2x/ecore_sp.h | 17 | ||||
-rw-r--r-- | drivers/net/bnx2x/elink.h | 2 |
10 files changed, 115 insertions, 44 deletions
diff --git a/drivers/net/bnx2x/bnx2x.c b/drivers/net/bnx2x/bnx2x.c index 26b3828e..3e705c7a 100644 --- a/drivers/net/bnx2x/bnx2x.c +++ b/drivers/net/bnx2x/bnx2x.c @@ -25,6 +25,7 @@ #include <sys/stat.h> #include <fcntl.h> #include <zlib.h> +#include <rte_string_fns.h> #define BNX2X_PMD_VER_PREFIX "BNX2X PMD" #define BNX2X_PMD_VERSION_MAJOR 1 @@ -123,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); @@ -184,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); @@ -191,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; @@ -1099,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; @@ -2435,6 +2456,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; @@ -4523,7 +4545,7 @@ 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; @@ -4538,14 +4560,14 @@ static void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp, int scan_fp) /* 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; } } @@ -4561,7 +4583,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; @@ -4593,7 +4615,7 @@ int bnx2x_intr_legacy(struct bnx2x_softc *sc, int 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, scan_fp); + bnx2x_handle_fp_tq(fp); status &= ~mask; } } @@ -8081,6 +8103,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); @@ -11741,13 +11784,13 @@ 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; } diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 32a12294..ef1688ff 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -119,6 +119,8 @@ int bnx2x_ilog2(int x) #define ilog2(x) bnx2x_ilog2(x) #endif +#define BNX2X_BC_VER 0x040200 + #include "ecore_sp.h" struct bnx2x_device_type { @@ -319,6 +321,7 @@ struct bnx2x_dma { rte_iova_t paddr; void *vaddr; int nseg; + const void *mzone; char msg[RTE_MEMZONE_NAMESIZE - 6]; }; @@ -1089,7 +1092,7 @@ struct bnx2x_softc { #define PERIODIC_STOP 0 #define PERIODIC_GO 1 volatile unsigned long periodic_flags; - + rte_atomic32_t scan_fp; struct bnx2x_fastpath fp[MAX_RSS_CHAINS]; struct bnx2x_sp_objs sp_objs[MAX_RSS_CHAINS]; @@ -1753,7 +1756,7 @@ int bnx2x_cmpxchg(volatile int *addr, int old, int new); int bnx2x_dma_alloc(struct bnx2x_softc *sc, size_t size, struct bnx2x_dma *dma, const char *msg, uint32_t align); - +void bnx2x_dma_free(struct bnx2x_dma *dma); uint32_t bnx2x_dmae_opcode_add_comp(uint32_t opcode, uint8_t comp_type); uint32_t bnx2x_dmae_opcode_clr_src_reset(uint32_t opcode); uint32_t bnx2x_dmae_opcode(struct bnx2x_softc *sc, uint8_t src_type, @@ -1938,7 +1941,7 @@ int bnx2x_tx_encap(struct bnx2x_tx_queue *txq, struct rte_mbuf *m0); uint8_t bnx2x_txeof(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp); void bnx2x_print_adapter_info(struct bnx2x_softc *sc); void bnx2x_print_device_info(struct bnx2x_softc *sc); -int bnx2x_intr_legacy(struct bnx2x_softc *sc, int scan_fp); +int bnx2x_intr_legacy(struct bnx2x_softc *sc); void bnx2x_link_status_update(struct bnx2x_softc *sc); int bnx2x_complete_sp(struct bnx2x_softc *sc); int bnx2x_set_storm_rx_mode(struct bnx2x_softc *sc); diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c index cc7816dd..c628cdc0 100644 --- a/drivers/net/bnx2x/bnx2x_ethdev.c +++ b/drivers/net/bnx2x/bnx2x_ethdev.c @@ -107,14 +107,15 @@ bnx2x_link_update(struct rte_eth_dev *dev) } static void -bnx2x_interrupt_action(struct rte_eth_dev *dev) +bnx2x_interrupt_action(struct rte_eth_dev *dev, int intr_cxt) { struct bnx2x_softc *sc = dev->data->dev_private; uint32_t link_status; - bnx2x_intr_legacy(sc, 0); + bnx2x_intr_legacy(sc); - if (sc->periodic_flags & PERIODIC_GO) + if ((atomic_load_acq_long(&sc->periodic_flags) == PERIODIC_GO) && + !intr_cxt) bnx2x_periodic_callout(sc); link_status = REG_RD(sc, sc->link_params.shmem_base + offsetof(struct shmem_region, @@ -131,9 +132,7 @@ bnx2x_interrupt_handler(void *param) PMD_DEBUG_PERIODIC_LOG(INFO, sc, "Interrupt handled"); - atomic_store_rel_long(&sc->periodic_flags, PERIODIC_STOP); - bnx2x_interrupt_action(dev); - atomic_store_rel_long(&sc->periodic_flags, PERIODIC_GO); + bnx2x_interrupt_action(dev, 1); rte_intr_enable(&sc->pci_dev->intr_handle); } @@ -144,7 +143,7 @@ static void bnx2x_periodic_start(void *param) int ret = 0; atomic_store_rel_long(&sc->periodic_flags, PERIODIC_GO); - bnx2x_interrupt_action(dev); + bnx2x_interrupt_action(dev, 0); if (IS_PF(sc)) { ret = rte_eal_alarm_set(BNX2X_SP_TIMER_PERIOD, bnx2x_periodic_start, (void *)dev); @@ -164,6 +163,8 @@ void bnx2x_periodic_stop(void *param) atomic_store_rel_long(&sc->periodic_flags, PERIODIC_STOP); rte_eal_alarm_cancel(bnx2x_periodic_start, (void *)dev); + + PMD_DRV_LOG(DEBUG, sc, "Periodic poll stopped"); } /* @@ -180,8 +181,10 @@ bnx2x_dev_configure(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(sc); - if (rxmode->offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) + if (rxmode->offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { sc->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len; + dev->data->mtu = sc->mtu; + } if (dev->data->nb_tx_queues > dev->data->nb_rx_queues) { PMD_DRV_LOG(ERR, sc, "The number of TX queues is greater than number of RX queues"); @@ -210,6 +213,7 @@ bnx2x_dev_configure(struct rte_eth_dev *dev) return -ENXIO; } + bnx2x_dev_rxtx_init_dummy(dev); return 0; } @@ -222,8 +226,10 @@ bnx2x_dev_start(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(sc); /* start the periodic callout */ - if (sc->periodic_flags & PERIODIC_STOP) + if (atomic_load_acq_long(&sc->periodic_flags) == PERIODIC_STOP) { bnx2x_periodic_start(dev); + PMD_DRV_LOG(DEBUG, sc, "Periodic poll re-started"); + } ret = bnx2x_init(sc); if (ret) { @@ -239,11 +245,7 @@ bnx2x_dev_start(struct rte_eth_dev *dev) PMD_DRV_LOG(ERR, sc, "rte_intr_enable failed"); } - ret = bnx2x_dev_rx_init(dev); - if (ret != 0) { - PMD_DRV_LOG(DEBUG, sc, "bnx2x_dev_rx_init returned error code"); - return -3; - } + bnx2x_dev_rxtx_init(dev); bnx2x_print_device_info(sc); @@ -258,6 +260,8 @@ bnx2x_dev_stop(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(sc); + bnx2x_dev_rxtx_init_dummy(dev); + if (IS_PF(sc)) { rte_intr_disable(&sc->pci_dev->intr_handle); rte_intr_callback_unregister(&sc->pci_dev->intr_handle, diff --git a/drivers/net/bnx2x/bnx2x_rxtx.c b/drivers/net/bnx2x/bnx2x_rxtx.c index ca28aacc..e5a2b25b 100644 --- a/drivers/net/bnx2x/bnx2x_rxtx.c +++ b/drivers/net/bnx2x/bnx2x_rxtx.c @@ -311,7 +311,6 @@ bnx2x_dev_tx_queue_setup(struct rte_eth_dev *dev, txq->tx_bd_tail = 0; txq->tx_bd_head = 0; txq->nb_tx_avail = txq->nb_tx_desc; - dev->tx_pkt_burst = bnx2x_xmit_pkts; dev->data->tx_queues[queue_idx] = txq; if (!sc->tx_queues) sc->tx_queues = dev->data->tx_queues; @@ -441,14 +440,26 @@ next_rx: return nb_rx; } -int -bnx2x_dev_rx_init(struct rte_eth_dev *dev) +static uint16_t +bnx2x_rxtx_pkts_dummy(__rte_unused void *p_rxq, + __rte_unused struct rte_mbuf **rx_pkts, + __rte_unused uint16_t nb_pkts) { - dev->rx_pkt_burst = bnx2x_recv_pkts; - return 0; } +void bnx2x_dev_rxtx_init_dummy(struct rte_eth_dev *dev) +{ + dev->rx_pkt_burst = bnx2x_rxtx_pkts_dummy; + dev->tx_pkt_burst = bnx2x_rxtx_pkts_dummy; +} + +void bnx2x_dev_rxtx_init(struct rte_eth_dev *dev) +{ + dev->rx_pkt_burst = bnx2x_recv_pkts; + dev->tx_pkt_burst = bnx2x_xmit_pkts; +} + void bnx2x_dev_clear_queues(struct rte_eth_dev *dev) { diff --git a/drivers/net/bnx2x/bnx2x_rxtx.h b/drivers/net/bnx2x/bnx2x_rxtx.h index 6ad4928c..3f4692b4 100644 --- a/drivers/net/bnx2x/bnx2x_rxtx.h +++ b/drivers/net/bnx2x/bnx2x_rxtx.h @@ -74,7 +74,8 @@ int bnx2x_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id, void bnx2x_dev_rx_queue_release(void *rxq); void bnx2x_dev_tx_queue_release(void *txq); -int bnx2x_dev_rx_init(struct rte_eth_dev *dev); +void bnx2x_dev_rxtx_init(struct rte_eth_dev *dev); +void bnx2x_dev_rxtx_init_dummy(struct rte_eth_dev *dev); void bnx2x_dev_clear_queues(struct rte_eth_dev *dev); #endif /* _BNX2X_RXTX_H_ */ diff --git a/drivers/net/bnx2x/ecore_hsi.h b/drivers/net/bnx2x/ecore_hsi.h index 1192e5dd..74189eed 100644 --- a/drivers/net/bnx2x/ecore_hsi.h +++ b/drivers/net/bnx2x/ecore_hsi.h @@ -3545,7 +3545,7 @@ struct igu_regular #define IGU_REGULAR_CLEANUP_TYPE_SHIFT 28 #define IGU_REGULAR_CLEANUP_SET (0x1<<30) /* BitField sb_id_and_flags */ #define IGU_REGULAR_CLEANUP_SET_SHIFT 30 -#define IGU_REGULAR_BCLEANUP (0x1<<31) /* BitField sb_id_and_flags */ +#define IGU_REGULAR_BCLEANUP (0x1U<<31) /* BitField sb_id_and_flags */ #define IGU_REGULAR_BCLEANUP_SHIFT 31 uint32_t reserved_2; }; diff --git a/drivers/net/bnx2x/ecore_reg.h b/drivers/net/bnx2x/ecore_reg.h index d69e857b..7af9a2d8 100644 --- a/drivers/net/bnx2x/ecore_reg.h +++ b/drivers/net/bnx2x/ecore_reg.h @@ -1981,7 +1981,7 @@ #define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR (0x1<<5) #define AEU_INPUTS_ATTN_BITS_BRB_HW_INTERRUPT (0x1<<19) #define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (0x1<<18) -#define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (0x1<<31) +#define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (0x1U<<31) #define AEU_INPUTS_ATTN_BITS_CCM_PARITY_ERROR (0x1<<30) #define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (0x1<<9) #define AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR (0x1<<8) diff --git a/drivers/net/bnx2x/ecore_sp.c b/drivers/net/bnx2x/ecore_sp.c index 6d2bb815..43194095 100644 --- a/drivers/net/bnx2x/ecore_sp.c +++ b/drivers/net/bnx2x/ecore_sp.c @@ -291,25 +291,33 @@ static int ecore_state_wait(struct bnx2x_softc *sc, int state, cnt *= 20; ECORE_MSG(sc, "waiting for state to become %d", state); + /* being over protective to remind bnx2x_intr_legacy() to + * process RAMROD + */ + rte_atomic32_set(&sc->scan_fp, 1); ECORE_MIGHT_SLEEP(); while (cnt--) { - bnx2x_intr_legacy(sc, 1); + bnx2x_intr_legacy(sc); if (!ECORE_TEST_BIT(state, pstate)) { #ifdef ECORE_STOP_ON_ERROR ECORE_MSG(sc, "exit (cnt %d)", 5000 - cnt); #endif + rte_atomic32_set(&sc->scan_fp, 0); return ECORE_SUCCESS; } ECORE_WAIT(sc, delay_us); - if (sc->panic) + if (sc->panic) { + rte_atomic32_set(&sc->scan_fp, 0); return ECORE_IO; + } } /* timeout! */ PMD_DRV_LOG(ERR, sc, "timeout waiting for state %d", state); + rte_atomic32_set(&sc->scan_fp, 0); #ifdef ECORE_STOP_ON_ERROR ecore_panic(); #endif diff --git a/drivers/net/bnx2x/ecore_sp.h b/drivers/net/bnx2x/ecore_sp.h index f295bf5a..7126097d 100644 --- a/drivers/net/bnx2x/ecore_sp.h +++ b/drivers/net/bnx2x/ecore_sp.h @@ -151,14 +151,15 @@ typedef rte_spinlock_t ECORE_MUTEX_SPIN; } \ } while (0) -#define ECORE_ILT_FREE(x, y, size) \ - do { \ - if (x) { \ - rte_free(x); \ - x = NULL; \ - y = 0; \ - } \ - } while (0) +#define ECORE_ILT_FREE(x, y, size) \ + do { \ + if (x) { \ + bnx2x_dma_free((struct bnx2x_dma *)x); \ + rte_free(x); \ + x = NULL; \ + y = 0; \ + } \ + } while (0) #define ECORE_IS_VALID_ETHER_ADDR(_mac) TRUE diff --git a/drivers/net/bnx2x/elink.h b/drivers/net/bnx2x/elink.h index c8b08bc3..dd70ac6c 100644 --- a/drivers/net/bnx2x/elink.h +++ b/drivers/net/bnx2x/elink.h @@ -440,7 +440,7 @@ struct elink_params { #define ELINK_EEE_MODE_OUTPUT_TIME (1 << 28) #define ELINK_EEE_MODE_OVERRIDE_NVRAM (1 << 29) #define ELINK_EEE_MODE_ENABLE_LPI (1 << 30) -#define ELINK_EEE_MODE_ADV_LPI (1 << 31) +#define ELINK_EEE_MODE_ADV_LPI (1U << 31) uint16_t hw_led_mode; /* part of the hw_config read from the shmem */ uint32_t multi_phy_config; |