aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x/bnx2x_ethdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_ethdev.c')
-rw-r--r--drivers/net/bnx2x/bnx2x_ethdev.c148
1 files changed, 95 insertions, 53 deletions
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 483d5a17..575271a8 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -1,11 +1,8 @@
-/*
+/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2013-2015 Brocade Communications Systems, Inc.
- *
- * Copyright (c) 2015 QLogic Corporation.
+ * Copyright (c) 2015-2018 Cavium Inc.
* All rights reserved.
- * www.qlogic.com
- *
- * See LICENSE.bnx2x_pmd for copyright and licensing details.
+ * www.cavium.com
*/
#include "bnx2x.h"
@@ -13,6 +10,7 @@
#include <rte_dev.h>
#include <rte_ethdev_pci.h>
+#include <rte_alarm.h>
int bnx2x_logtype_init;
int bnx2x_logtype_driver;
@@ -81,26 +79,31 @@ static const struct rte_bnx2x_xstats_name_off bnx2x_xstats_strings[] = {
offsetof(struct bnx2x_eth_stats, pfc_frames_received_lo)}
};
-static void
+static int
bnx2x_link_update(struct rte_eth_dev *dev)
{
struct bnx2x_softc *sc = dev->data->dev_private;
+ struct rte_eth_link link;
PMD_INIT_FUNC_TRACE();
+
bnx2x_link_status_update(sc);
+ memset(&link, 0, sizeof(link));
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;
+
+ return rte_eth_linkstatus_set(dev, &link);
}
static void
@@ -109,8 +112,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)
@@ -128,10 +129,41 @@ 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
*/
@@ -140,11 +172,13 @@ static int
bnx2x_dev_configure(struct rte_eth_dev *dev)
{
struct bnx2x_softc *sc = dev->data->dev_private;
+ struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
+
int mp_ncpus = sysconf(_SC_NPROCESSORS_CONF);
PMD_INIT_FUNC_TRACE();
- if (dev->data->dev_conf.rxmode.jumbo_frame)
+ if (rxmode->offloads & DEV_RX_OFFLOAD_JUMBO_FRAME)
sc->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len;
if (dev->data->nb_tx_queues > dev->data->nb_rx_queues) {
@@ -185,6 +219,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);
@@ -225,6 +263,9 @@ 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);
@@ -307,20 +348,16 @@ 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;
+ return bnx2x_link_update(dev);
}
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;
+ int ret = 0;
- bnx2x_link_update(dev);
+ ret = bnx2x_link_update(dev);
bnx2x_check_bull(sc);
if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
@@ -329,7 +366,7 @@ bnx2xvf_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_comple
dev->data->dev_link.link_status = ETH_LINK_DOWN;
}
- return old_link_status == dev->data->dev_link.link_status ? -1 : 0;
+ return ret;
}
static int
@@ -447,13 +484,13 @@ static void
bnx2x_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
struct bnx2x_softc *sc = dev->data->dev_private;
- dev_info->pci_dev = RTE_ETH_DEV_TO_PCI(dev);
dev_info->max_rx_queues = sc->max_rx_queues;
dev_info->max_tx_queues = sc->max_tx_queues;
dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
dev_info->max_rx_pktlen = BNX2X_MAX_RX_PKT_LEN;
dev_info->max_mac_addrs = BNX2X_MAX_MAC_ADDRS;
dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G;
+ dev_info->rx_offload_capa = DEV_RX_OFFLOAD_JUMBO_FRAME;
}
static int
@@ -583,6 +620,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",
@@ -597,18 +645,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;
@@ -616,10 +666,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
@@ -642,24 +696,14 @@ static struct rte_pci_driver rte_bnx2xvf_pmd;
static int eth_bnx2x_pci_probe(struct rte_pci_driver *pci_drv,
struct rte_pci_device *pci_dev)
{
- struct rte_eth_dev *eth_dev;
- int ret;
-
- eth_dev = rte_eth_dev_pci_allocate(pci_dev, sizeof(struct bnx2x_softc));
- if (!eth_dev)
- return -ENOMEM;
-
if (pci_drv == &rte_bnx2x_pmd)
- ret = eth_bnx2x_dev_init(eth_dev);
+ return rte_eth_dev_pci_generic_probe(pci_dev,
+ sizeof(struct bnx2x_softc), eth_bnx2x_dev_init);
else if (pci_drv == &rte_bnx2xvf_pmd)
- ret = eth_bnx2xvf_dev_init(eth_dev);
+ return rte_eth_dev_pci_generic_probe(pci_dev,
+ sizeof(struct bnx2x_softc), eth_bnx2xvf_dev_init);
else
- ret = -EINVAL;
-
- if (ret)
- rte_eth_dev_pci_release(eth_dev);
-
- return ret;
+ return -EINVAL;
}
static int eth_bnx2x_pci_remove(struct rte_pci_device *pci_dev)
@@ -691,14 +735,12 @@ RTE_PMD_REGISTER_PCI(net_bnx2xvf, rte_bnx2xvf_pmd);
RTE_PMD_REGISTER_PCI_TABLE(net_bnx2xvf, pci_id_bnx2xvf_map);
RTE_PMD_REGISTER_KMOD_DEP(net_bnx2xvf, "* igb_uio | vfio-pci");
-RTE_INIT(bnx2x_init_log);
-static void
-bnx2x_init_log(void)
+RTE_INIT(bnx2x_init_log)
{
- bnx2x_logtype_init = rte_log_register("pmd.bnx2x.init");
+ bnx2x_logtype_init = rte_log_register("pmd.net.bnx2x.init");
if (bnx2x_logtype_init >= 0)
rte_log_set_level(bnx2x_logtype_init, RTE_LOG_NOTICE);
- bnx2x_logtype_driver = rte_log_register("pmd.bnx2x.driver");
+ bnx2x_logtype_driver = rte_log_register("pmd.net.bnx2x.driver");
if (bnx2x_logtype_driver >= 0)
rte_log_set_level(bnx2x_logtype_driver, RTE_LOG_NOTICE);
}