#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
-#define BNX2X_PMD_VERSION_MINOR 0
-#define BNX2X_PMD_VERSION_REVISION 7
+#define BNX2X_PMD_VERSION_MINOR 1
+#define BNX2X_PMD_VERSION_REVISION 0
#define BNX2X_PMD_VERSION_PATCH 1
static inline const char *
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);
}
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);
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;
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;
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 */
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;
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 =
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));
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;
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;
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));
}
}
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;
/* 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);
}
* 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;
/* 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;
}
}
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
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 */
{
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.
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);
}
/*
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);
}
}
}
+ /* 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;
bnx2x_nic_load_error0:
bnx2x_free_fw_stats_mem(sc);
+ bnx2x_free_hsi_mem(sc);
bnx2x_free_mem(sc);
return rc;
~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);
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",
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",
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",
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",
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) {
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),
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;
+ }
}
/*
return -ENOMEM;
}
-#ifndef __FreeBSD__
+#ifndef RTE_EXEC_ENV_FREEBSD
pci_read(sc, PCI_STATUS, &status, 2);
if (!(status & PCI_STATUS_CAP_LIST)) {
#else
return -1;
}
-#ifndef __FreeBSD__
+#ifndef RTE_EXEC_ENV_FREEBSD
pci_read(sc, PCI_CAPABILITY_LIST, &pci_cap.next, 1);
#else
pci_read(sc, PCIR_CAP_PTR, &pci_cap.next, 1);
}
#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)
{
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);
/* 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);
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 */
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() */
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;
}