summaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bnx2x')
-rw-r--r--drivers/net/bnx2x/bnx2x.c24
-rw-r--r--drivers/net/bnx2x/bnx2x.h1
-rw-r--r--drivers/net/bnx2x/bnx2x_ethdev.c214
-rw-r--r--drivers/net/bnx2x/bnx2x_ethdev.h3
4 files changed, 174 insertions, 68 deletions
diff --git a/drivers/net/bnx2x/bnx2x.c b/drivers/net/bnx2x/bnx2x.c
index 98b08d11..e58684d6 100644
--- a/drivers/net/bnx2x/bnx2x.c
+++ b/drivers/net/bnx2x/bnx2x.c
@@ -125,7 +125,6 @@ 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_periodic_stop(struct bnx2x_softc *sc);
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);
@@ -1971,9 +1970,6 @@ bnx2x_nic_unload(struct bnx2x_softc *sc, uint32_t unload_mode, uint8_t keep_link
PMD_DRV_LOG(DEBUG, "Starting NIC unload...");
- /* stop the periodic callout */
- bnx2x_periodic_stop(sc);
-
/* mark driver as unloaded in shmem2 */
if (IS_PF(sc) && SHMEM2_HAS(sc, drv_capabilities_flag)) {
val = SHMEM2_RD(sc, drv_capabilities_flag[SC_FW_MB_IDX(sc)]);
@@ -4492,6 +4488,8 @@ static void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp, int scan_fp)
struct bnx2x_softc *sc = fp->sc;
uint8_t more_rx = FALSE;
+ PMD_DRV_LOG(DEBUG, "---> FP TASK QUEUE (%d) <--", fp->index);
+
/* update the fastpath index */
bnx2x_update_fp_sb_idx(fp);
@@ -4508,7 +4506,7 @@ static void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp, int scan_fp)
}
bnx2x_ack_sb(sc, fp->igu_sb_id, USTORM_ID,
- le16toh(fp->fp_hc_idx), IGU_INT_DISABLE, 1);
+ le16toh(fp->fp_hc_idx), IGU_INT_ENABLE, 1);
}
/*
@@ -6999,16 +6997,6 @@ void bnx2x_link_status_update(struct bnx2x_softc *sc)
}
}
-static void bnx2x_periodic_start(struct bnx2x_softc *sc)
-{
- atomic_store_rel_long(&sc->periodic_flags, PERIODIC_GO);
-}
-
-static void bnx2x_periodic_stop(struct bnx2x_softc *sc)
-{
- atomic_store_rel_long(&sc->periodic_flags, PERIODIC_STOP);
-}
-
static int bnx2x_initial_phy_init(struct bnx2x_softc *sc, int load_mode)
{
int rc, cfg_idx = bnx2x_get_link_cfg_idx(sc);
@@ -7043,10 +7031,6 @@ static int bnx2x_initial_phy_init(struct bnx2x_softc *sc, int load_mode)
bnx2x_link_report(sc);
}
- if (!CHIP_REV_IS_SLOW(sc)) {
- bnx2x_periodic_start(sc);
- }
-
sc->link_params.req_line_speed[cfg_idx] = req_line_speed;
return rc;
}
@@ -7078,7 +7062,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(WARNING, "periodic callout exit (state=0x%x)",
+ PMD_DRV_LOG(INFO, "periodic callout exit (state=0x%x)",
sc->state);
return;
}
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 17075d38..c93f148b 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -1930,6 +1930,7 @@ 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);
void bnx2x_periodic_callout(struct bnx2x_softc *sc);
+void bnx2x_periodic_stop(void *param);
int bnx2x_vf_get_resources(struct bnx2x_softc *sc, uint8_t tx_count, uint8_t rx_count);
void bnx2x_vf_close(struct bnx2x_softc *sc);
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 95861a06..650d6ce6 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -13,6 +13,8 @@
#include <rte_dev.h>
#include <rte_ethdev_pci.h>
+#include <rte_alarm.h>
+#include <rte_atomic.h>
/*
* The set of PCI devices this driver supports
@@ -78,26 +80,87 @@ static const struct rte_bnx2x_xstats_name_off bnx2x_xstats_strings[] = {
offsetof(struct bnx2x_eth_stats, pfc_frames_received_lo)}
};
-static void
+/**
+ * Atomically reads the link status information from global
+ * structure rte_eth_dev.
+ *
+ * @param dev
+ * - Pointer to the structure rte_eth_dev to read from.
+ * - Pointer to the buffer to be saved with the link status.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, negative value.
+ */
+static inline int
+bnx2x_dev_atomic_read_link_status(struct rte_eth_dev *dev,
+ struct rte_eth_link *link)
+{
+ struct rte_eth_link *dst = link;
+ struct rte_eth_link *src = &dev->data->dev_link;
+
+ if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
+ *(uint64_t *)src) == 0)
+ return -1;
+
+ return 0;
+}
+
+/**
+ * Atomically writes the link status information into global
+ * structure rte_eth_dev.
+ *
+ * @param dev
+ * - Pointer to the structure rte_eth_dev to read from.
+ * - Pointer to the buffer to be saved with the link status.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, negative value.
+ */
+static inline int
+bnx2x_dev_atomic_write_link_status(struct rte_eth_dev *dev,
+ struct rte_eth_link *link)
+{
+ struct rte_eth_link *dst = &dev->data->dev_link;
+ struct rte_eth_link *src = link;
+
+ if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
+ *(uint64_t *)src) == 0)
+ return -1;
+
+ return 0;
+}
+
+static int
bnx2x_link_update(struct rte_eth_dev *dev)
{
struct bnx2x_softc *sc = dev->data->dev_private;
+ struct rte_eth_link orig;
+ struct rte_eth_link link;
PMD_INIT_FUNC_TRACE();
+
bnx2x_link_status_update(sc);
+ memset(&orig, 0, sizeof(orig));
+ memset(&link, 0, sizeof(link));
+ bnx2x_dev_atomic_read_link_status(dev, &orig);
mb();
- dev->data->dev_link.link_speed = sc->link_vars.line_speed;
+ link.link_speed = sc->link_vars.line_speed;
switch (sc->link_vars.duplex) {
case DUPLEX_FULL:
- dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+ link.link_duplex = ETH_LINK_FULL_DUPLEX;
break;
case DUPLEX_HALF:
- dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
+ link.link_duplex = ETH_LINK_HALF_DUPLEX;
break;
}
- dev->data->dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ link.link_autoneg = !(dev->data->dev_conf.link_speeds &
ETH_LINK_SPEED_FIXED);
- dev->data->dev_link.link_status = sc->link_vars.link_up;
+ link.link_status = sc->link_vars.link_up;
+ bnx2x_dev_atomic_write_link_status(dev, &link);
+
+ return (link.link_status == orig.link_status) ? -1 : 0;
}
static void
@@ -106,8 +169,6 @@ bnx2x_interrupt_action(struct rte_eth_dev *dev)
struct bnx2x_softc *sc = dev->data->dev_private;
uint32_t link_status;
- PMD_DEBUG_PERIODIC_LOG(INFO, "Interrupt handled");
-
bnx2x_intr_legacy(sc, 0);
if (sc->periodic_flags & PERIODIC_GO)
@@ -125,15 +186,74 @@ bnx2x_interrupt_handler(void *param)
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
struct bnx2x_softc *sc = dev->data->dev_private;
+ PMD_DEBUG_PERIODIC_LOG(INFO, "Interrupt handled");
+
bnx2x_interrupt_action(dev);
rte_intr_enable(&sc->pci_dev->intr_handle);
}
+static void bnx2x_periodic_start(void *param)
+{
+ struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+ struct bnx2x_softc *sc = dev->data->dev_private;
+ int ret = 0;
+
+ atomic_store_rel_long(&sc->periodic_flags, PERIODIC_GO);
+ bnx2x_interrupt_action(dev);
+ if (IS_PF(sc)) {
+ ret = rte_eal_alarm_set(BNX2X_SP_TIMER_PERIOD,
+ bnx2x_periodic_start, (void *)dev);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Unable to start periodic"
+ " timer rc %d", ret);
+ assert(false && "Unable to start periodic timer");
+ }
+ }
+}
+
+void bnx2x_periodic_stop(void *param)
+{
+ struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+ struct bnx2x_softc *sc = dev->data->dev_private;
+
+ atomic_store_rel_long(&sc->periodic_flags, PERIODIC_STOP);
+
+ rte_eal_alarm_cancel(bnx2x_periodic_start, (void *)dev);
+}
+
/*
* Devops - helper functions can be called from user application
*/
static int
+bnx2x_dev_link_update(struct rte_eth_dev *dev,
+ __rte_unused int wait_to_complete)
+{
+ PMD_INIT_FUNC_TRACE();
+
+ return bnx2x_link_update(dev);
+}
+
+static int
+bnx2xvf_dev_link_update(struct rte_eth_dev *dev,
+ __rte_unused int wait_to_complete)
+{
+ struct bnx2x_softc *sc = dev->data->dev_private;
+ int ret = 0;
+
+ ret = bnx2x_link_update(dev);
+
+ bnx2x_check_bull(sc);
+ if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
+ PMD_DRV_LOG(ERR, "PF indicated channel is down."
+ "VF device is no longer operational");
+ dev->data->dev_link.link_status = ETH_LINK_DOWN;
+ }
+
+ return ret;
+}
+
+static int
bnx2x_dev_configure(struct rte_eth_dev *dev)
{
struct bnx2x_softc *sc = dev->data->dev_private;
@@ -182,6 +302,10 @@ bnx2x_dev_start(struct rte_eth_dev *dev)
PMD_INIT_FUNC_TRACE();
+ /* start the periodic callout */
+ if (sc->periodic_flags & PERIODIC_STOP)
+ bnx2x_periodic_start(dev);
+
ret = bnx2x_init(sc);
if (ret) {
PMD_DRV_LOG(DEBUG, "bnx2x_init failed (%d)", ret);
@@ -222,12 +346,21 @@ bnx2x_dev_stop(struct rte_eth_dev *dev)
bnx2x_interrupt_handler, (void *)dev);
}
+ /* stop the periodic callout */
+ bnx2x_periodic_stop(dev);
+
ret = bnx2x_nic_unload(sc, UNLOAD_NORMAL, FALSE);
if (ret) {
PMD_DRV_LOG(DEBUG, "bnx2x_nic_unload failed (%d)", ret);
return;
}
+ /* Update device link status */
+ if (IS_PF(sc))
+ bnx2x_dev_link_update(dev, 0);
+ else
+ bnx2xvf_dev_link_update(dev, 0);
+
return;
}
@@ -300,36 +433,6 @@ bnx2x_dev_allmulticast_disable(struct rte_eth_dev *dev)
}
static int
-bnx2x_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
-{
- PMD_INIT_FUNC_TRACE();
-
- int old_link_status = dev->data->dev_link.link_status;
-
- bnx2x_link_update(dev);
-
- return old_link_status == dev->data->dev_link.link_status ? -1 : 0;
-}
-
-static int
-bnx2xvf_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
-{
- int old_link_status = dev->data->dev_link.link_status;
- struct bnx2x_softc *sc = dev->data->dev_private;
-
- bnx2x_link_update(dev);
-
- bnx2x_check_bull(sc);
- if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
- PMD_DRV_LOG(ERR, "PF indicated channel is down."
- "VF device is no longer operational");
- dev->data->dev_link.link_status = ETH_LINK_DOWN;
- }
-
- return old_link_status == dev->data->dev_link.link_status ? -1 : 0;
-}
-
-static int
bnx2x_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
{
struct bnx2x_softc *sc = dev->data->dev_private;
@@ -580,6 +683,17 @@ bnx2x_common_dev_init(struct rte_eth_dev *eth_dev, int is_vf)
return ret;
}
+ /* schedule periodic poll for slowpath link events */
+ if (IS_PF(sc)) {
+ ret = rte_eal_alarm_set(BNX2X_SP_TIMER_PERIOD,
+ bnx2x_periodic_start, (void *)eth_dev);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Unable to start periodic"
+ " timer rc %d", ret);
+ return -EINVAL;
+ }
+ }
+
eth_dev->data->mac_addrs = (struct ether_addr *)sc->link_params.mac_addr;
PMD_DRV_LOG(INFO, "pcie_bus=%d, pcie_device=%d",
@@ -594,18 +708,20 @@ bnx2x_common_dev_init(struct rte_eth_dev *eth_dev, int is_vf)
if (IS_VF(sc)) {
rte_spinlock_init(&sc->vf2pf_lock);
- if (bnx2x_dma_alloc(sc, sizeof(struct bnx2x_vf_mbx_msg),
- &sc->vf2pf_mbox_mapping, "vf2pf_mbox",
- RTE_CACHE_LINE_SIZE) != 0)
- return -ENOMEM;
+ ret = bnx2x_dma_alloc(sc, sizeof(struct bnx2x_vf_mbx_msg),
+ &sc->vf2pf_mbox_mapping, "vf2pf_mbox",
+ RTE_CACHE_LINE_SIZE);
+ if (ret)
+ goto out;
sc->vf2pf_mbox = (struct bnx2x_vf_mbx_msg *)
sc->vf2pf_mbox_mapping.vaddr;
- if (bnx2x_dma_alloc(sc, sizeof(struct bnx2x_vf_bulletin),
- &sc->pf2vf_bulletin_mapping, "vf2pf_bull",
- RTE_CACHE_LINE_SIZE) != 0)
- return -ENOMEM;
+ ret = bnx2x_dma_alloc(sc, sizeof(struct bnx2x_vf_bulletin),
+ &sc->pf2vf_bulletin_mapping, "vf2pf_bull",
+ RTE_CACHE_LINE_SIZE);
+ if (ret)
+ goto out;
sc->pf2vf_bulletin = (struct bnx2x_vf_bulletin *)
sc->pf2vf_bulletin_mapping.vaddr;
@@ -613,10 +729,14 @@ bnx2x_common_dev_init(struct rte_eth_dev *eth_dev, int is_vf)
ret = bnx2x_vf_get_resources(sc, sc->max_tx_queues,
sc->max_rx_queues);
if (ret)
- return ret;
+ goto out;
}
return 0;
+
+out:
+ bnx2x_periodic_stop(eth_dev);
+ return ret;
}
static int
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.h b/drivers/net/bnx2x/bnx2x_ethdev.h
index 967d6dc5..a53d437d 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.h
+++ b/drivers/net/bnx2x/bnx2x_ethdev.h
@@ -58,7 +58,6 @@
#define wmb() rte_wmb()
#define rmb() rte_rmb()
-
#define MAX_QUEUES sysconf(_SC_NPROCESSORS_CONF)
#define BNX2X_MIN_RX_BUF_SIZE 1024
@@ -72,6 +71,8 @@
/* Maximum number of Rx packets to process at a time */
#define BNX2X_RX_BUDGET 0xffffffff
+#define BNX2X_SP_TIMER_PERIOD US_PER_S /* 1 second */
+
#endif
/* MAC address operations */