/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2014-2018 Broadcom
+ * Copyright(c) 2014-2021 Broadcom
* All rights reserved.
*/
#include <stdbool.h>
#include <rte_dev.h>
-#include <rte_ethdev_driver.h>
-#include <rte_ethdev_pci.h>
+#include <ethdev_driver.h>
+#include <ethdev_pci.h>
#include <rte_malloc.h>
#include <rte_cycles.h>
#include <rte_alarm.h>
return rc;
}
-static int bnxt_init_chip(struct bnxt *bp)
+static int bnxt_start_nic(struct bnxt *bp)
{
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(bp->eth_dev);
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
}
}
-/* Unload the driver, release resources */
-static int bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
+static int bnxt_dev_stop(struct rte_eth_dev *eth_dev)
{
struct bnxt *bp = eth_dev->data->dev_private;
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
return 0;
}
+/* Unload the driver, release resources */
+static int bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = eth_dev->data->dev_private;
+
+ pthread_mutex_lock(&bp->err_recovery_lock);
+ if (bp->flags & BNXT_FLAG_FW_RESET) {
+ PMD_DRV_LOG(ERR,
+ "Adapter recovering from error..Please retry\n");
+ pthread_mutex_unlock(&bp->err_recovery_lock);
+ return -EAGAIN;
+ }
+ pthread_mutex_unlock(&bp->err_recovery_lock);
+
+ return bnxt_dev_stop(eth_dev);
+}
+
static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
{
struct bnxt *bp = eth_dev->data->dev_private;
bnxt_enable_int(bp);
- rc = bnxt_init_chip(bp);
+ rc = bnxt_start_nic(bp);
if (rc)
goto error;
return 0;
error:
- bnxt_dev_stop_op(eth_dev);
+ bnxt_dev_stop(eth_dev);
return rc;
}
pthread_mutex_destroy(&bp->flow_lock);
pthread_mutex_destroy(&bp->def_cp_lock);
pthread_mutex_destroy(&bp->health_check_lock);
+ pthread_mutex_destroy(&bp->err_recovery_lock);
if (bp->rep_info) {
pthread_mutex_destroy(&bp->rep_info->vfr_lock);
pthread_mutex_destroy(&bp->rep_info->vfr_start_lock);
}
}
-static int bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
+static void bnxt_drv_uninit(struct bnxt *bp)
{
- struct bnxt *bp = eth_dev->data->dev_private;
- int ret = 0;
-
- if (rte_eal_process_type() != RTE_PROC_PRIMARY)
- return 0;
-
- /* cancel the recovery handler before remove dev */
- rte_eal_alarm_cancel(bnxt_dev_reset_and_resume, (void *)bp);
- rte_eal_alarm_cancel(bnxt_dev_recover, (void *)bp);
- bnxt_cancel_fc_thread(bp);
-
- if (eth_dev->data->dev_started)
- ret = bnxt_dev_stop_op(eth_dev);
-
bnxt_free_switch_domain(bp);
-
- bnxt_uninit_resources(bp, false);
-
bnxt_free_leds_info(bp);
bnxt_free_cos_queues(bp);
bnxt_free_link_info(bp);
rte_free(bp->grp_info);
bp->grp_info = NULL;
+}
+
+static int bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = eth_dev->data->dev_private;
+ int ret = 0;
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+
+ pthread_mutex_lock(&bp->err_recovery_lock);
+ if (bp->flags & BNXT_FLAG_FW_RESET) {
+ PMD_DRV_LOG(ERR,
+ "Adapter recovering from error...Please retry\n");
+ pthread_mutex_unlock(&bp->err_recovery_lock);
+ return -EAGAIN;
+ }
+ pthread_mutex_unlock(&bp->err_recovery_lock);
+
+ /* cancel the recovery handler before remove dev */
+ rte_eal_alarm_cancel(bnxt_dev_reset_and_resume, (void *)bp);
+ rte_eal_alarm_cancel(bnxt_dev_recover, (void *)bp);
+ bnxt_cancel_fc_thread(bp);
+
+ if (eth_dev->data->dev_started)
+ ret = bnxt_dev_stop(eth_dev);
+
+ bnxt_uninit_resources(bp, false);
+
+ bnxt_drv_uninit(bp);
return ret;
}
bp->eth_dev->data->dev_link.link_status = 0;
bp->link_info->link_up = 0;
if (bp->eth_dev->data->dev_started)
- bnxt_dev_stop_op(bp->eth_dev);
+ bnxt_dev_stop(bp->eth_dev);
bnxt_uninit_resources(bp, true);
}
int timeout = bp->fw_reset_max_msecs;
int rc = 0;
+ pthread_mutex_lock(&bp->err_recovery_lock);
/* Clear Error flag so that device re-init should happen */
bp->flags &= ~BNXT_FLAG_FATAL_ERROR;
goto err_start;
PMD_DRV_LOG(INFO, "Recovered from FW reset\n");
+ pthread_mutex_unlock(&bp->err_recovery_lock);
+
return;
err_start:
- bnxt_dev_stop_op(bp->eth_dev);
+ bnxt_dev_stop(bp->eth_dev);
err:
bp->flags |= BNXT_FLAG_FATAL_ERROR;
bnxt_uninit_resources(bp, false);
+ pthread_mutex_unlock(&bp->err_recovery_lock);
PMD_DRV_LOG(ERR, "Failed to recover from FW reset\n");
}
}
}
-static int bnxt_init_board(struct rte_eth_dev *eth_dev)
+static int bnxt_map_pci_bars(struct rte_eth_dev *eth_dev)
{
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
struct bnxt *bp = eth_dev->data->dev_private;
return 0;
}
-static int bnxt_init_fw(struct bnxt *bp)
+/* This function gets the FW version along with the
+ * capabilities(MAX and current) of the function, vnic,
+ * error recovery, phy and other chip related info
+ */
+static int bnxt_get_config(struct bnxt *bp)
{
uint16_t mtu;
int rc = 0;
}
err = pthread_mutex_init(&bp->health_check_lock, NULL);
- if (err)
+ if (err) {
PMD_DRV_LOG(ERR, "Unable to initialize health_check_lock\n");
+ return err;
+ }
+
+ err = pthread_mutex_init(&bp->err_recovery_lock, NULL);
+ if (err)
+ PMD_DRV_LOG(ERR, "Unable to initialize err_recovery_lock\n");
+
return err;
}
{
int rc = 0;
- rc = bnxt_init_fw(bp);
+ rc = bnxt_get_config(bp);
if (rc)
return rc;
return rc;
}
-static int
-bnxt_dev_init(struct rte_eth_dev *eth_dev, void *params __rte_unused)
+/* Allocate and initialize various fields in bnxt struct that
+ * need to be allocated/destroyed only once in the lifetime of the driver
+ */
+static int bnxt_drv_init(struct rte_eth_dev *eth_dev)
{
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
- static int version_printed;
- struct bnxt *bp;
- int rc;
-
- if (version_printed++ == 0)
- PMD_DRV_LOG(INFO, "%s\n", bnxt_version);
-
- eth_dev->dev_ops = &bnxt_dev_ops;
- eth_dev->rx_queue_count = bnxt_rx_queue_count_op;
- eth_dev->rx_descriptor_status = bnxt_rx_descriptor_status_op;
- eth_dev->tx_descriptor_status = bnxt_tx_descriptor_status_op;
- eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
- eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
-
- /*
- * For secondary processes, we don't initialise any further
- * as primary has already done this work.
- */
- if (rte_eal_process_type() != RTE_PROC_PRIMARY)
- return 0;
-
- rte_eth_copy_pci_info(eth_dev, pci_dev);
- eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
-
- bp = eth_dev->data->dev_private;
-
- /* Parse dev arguments passed on when starting the DPDK application. */
- bnxt_parse_dev_args(bp, pci_dev->device.devargs);
+ struct bnxt *bp = eth_dev->data->dev_private;
+ int rc = 0;
bp->flags &= ~BNXT_FLAG_RX_VECTOR_PKT_MODE;
}
}
- rc = bnxt_init_board(eth_dev);
+ rc = bnxt_map_pci_bars(eth_dev);
if (rc) {
PMD_DRV_LOG(ERR,
"Failed to initialize board rc: %x\n", rc);
rc = bnxt_alloc_pf_info(bp);
if (rc)
- goto error_free;
+ return rc;
rc = bnxt_alloc_link_info(bp);
if (rc)
- goto error_free;
+ return rc;
rc = bnxt_alloc_parent_info(bp);
if (rc)
- goto error_free;
+ return rc;
rc = bnxt_alloc_hwrm_resources(bp);
if (rc) {
PMD_DRV_LOG(ERR,
"Failed to allocate hwrm resource rc: %x\n", rc);
- goto error_free;
+ return rc;
}
rc = bnxt_alloc_leds_info(bp);
if (rc)
- goto error_free;
+ return rc;
rc = bnxt_alloc_cos_queues(bp);
if (rc)
- goto error_free;
+ return rc;
rc = bnxt_init_locks(bp);
+ if (rc)
+ return rc;
+
+ rc = bnxt_alloc_switch_domain(bp);
+ if (rc)
+ return rc;
+
+ return rc;
+}
+
+static int
+bnxt_dev_init(struct rte_eth_dev *eth_dev, void *params __rte_unused)
+{
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+ static int version_printed;
+ struct bnxt *bp;
+ int rc;
+
+ if (version_printed++ == 0)
+ PMD_DRV_LOG(INFO, "%s\n", bnxt_version);
+
+ eth_dev->dev_ops = &bnxt_dev_ops;
+ eth_dev->rx_queue_count = bnxt_rx_queue_count_op;
+ eth_dev->rx_descriptor_status = bnxt_rx_descriptor_status_op;
+ eth_dev->tx_descriptor_status = bnxt_tx_descriptor_status_op;
+ eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
+ eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
+
+ /*
+ * For secondary processes, we don't initialise any further
+ * as primary has already done this work.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+
+ rte_eth_copy_pci_info(eth_dev, pci_dev);
+ eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
+
+ bp = eth_dev->data->dev_private;
+
+ /* Parse dev arguments passed on when starting the DPDK application. */
+ bnxt_parse_dev_args(bp, pci_dev->device.devargs);
+
+ rc = bnxt_drv_init(eth_dev);
if (rc)
goto error_free;
if (rc)
goto error_free;
- bnxt_alloc_switch_domain(bp);
-
PMD_DRV_LOG(INFO,
DRV_MODULE_NAME "found at mem %" PRIX64 ", node addr %pM\n",
pci_dev->mem_resource[0].phys_addr,