get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/60378/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 60378,
    "url": "http://patches.dpdk.org/api/patches/60378/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20191002012335.85324-3-ajit.khaparde@broadcom.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20191002012335.85324-3-ajit.khaparde@broadcom.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20191002012335.85324-3-ajit.khaparde@broadcom.com",
    "date": "2019-10-02T01:23:22",
    "name": "[v3,02/15] net/bnxt: prevent device access when device is in reset",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "fb04c5a8b42efffdd77a78fe5d563c63f9e830ce",
    "submitter": {
        "id": 501,
        "url": "http://patches.dpdk.org/api/people/501/?format=api",
        "name": "Ajit Khaparde",
        "email": "ajit.khaparde@broadcom.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20191002012335.85324-3-ajit.khaparde@broadcom.com/mbox/",
    "series": [
        {
            "id": 6660,
            "url": "http://patches.dpdk.org/api/series/6660/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=6660",
            "date": "2019-10-02T01:23:24",
            "name": "bnxt patchset to support device error recovery",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/6660/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/60378/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/60378/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 380A51BEAD;\n\tWed,  2 Oct 2019 03:23:57 +0200 (CEST)",
            "from rnd-relay.smtp.broadcom.com (unknown [192.19.229.170])\n\tby dpdk.org (Postfix) with ESMTP id B17AC4C90\n\tfor <dev@dpdk.org>; Wed,  2 Oct 2019 03:23:46 +0200 (CEST)",
            "from mail-irv-17.broadcom.com (mail-irv-17.lvn.broadcom.net\n\t[10.75.242.48])\n\tby rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id 28EA230CC4A;\n\tTue,  1 Oct 2019 18:22:30 -0700 (PDT)",
            "from localhost.localdomain (unknown [10.230.30.225])\n\tby mail-irv-17.broadcom.com (Postfix) with ESMTP id 5265614008B;\n\tTue,  1 Oct 2019 18:23:39 -0700 (PDT)"
        ],
        "DKIM-Filter": "OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com 28EA230CC4A",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com;\n\ts=dkimrelay; t=1569979350;\n\tbh=FbZWiccREa8I41tqVmoDh0I+x42LYBPX0QcuoZ2GrNc=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=EnqJo9r4wSVEjdMXi6X3sdQNVIaul/oPntVy6q8IOE6BjmjDpEuc+uJbkAS8ctlyo\n\tCFEpyv+prFVLT12l4K2OI4nWHNk7n1j9zNM1MzQtr5x6T6VoY2sty3w0wy6LEg+MrJ\n\tIQmhKIJraHGSGNg6VM9+7f7C4wqCCsYe0WKO3wl8=",
        "From": "Ajit Khaparde <ajit.khaparde@broadcom.com>",
        "To": "dev@dpdk.org",
        "Cc": "ferruh.yigit@intel.com, Kalesh AP <kalesh-anakkur.purayil@broadcom.com>, \n\tSantoshkumar Karanappa Rastapur <santosh.rastapur@broadcom.com>,\n\tSomnath Kotur <somnath.kotur@broadcom.com>",
        "Date": "Tue,  1 Oct 2019 18:23:22 -0700",
        "Message-Id": "<20191002012335.85324-3-ajit.khaparde@broadcom.com>",
        "X-Mailer": "git-send-email 2.20.1 (Apple Git-117)",
        "In-Reply-To": "<20191002012335.85324-1-ajit.khaparde@broadcom.com>",
        "References": "<7c08999f-13f3-5fb6-39a2-557a0884bfde@intel.com>\n\t<20191002012335.85324-1-ajit.khaparde@broadcom.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v3 02/15] net/bnxt: prevent device access when\n\tdevice is in reset",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>\n\nRefactor init and uninit functions so that the driver can fail\nthe eth_dev_ops callbacks and accessing Tx and Rx queues\nwhen device is in reset or in error state.\n\nTransmit and receive queues are freed during reset cleanup and\nreallocated during recovery. So we block all data path handling\nin this state. The eth_dev dev_started field is updated depending\non the status of the device.\n\nSigned-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>\nReviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>\nReviewed-by: Santoshkumar Karanappa Rastapur <santosh.rastapur@broadcom.com>\nReviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>\n---\n drivers/net/bnxt/bnxt.h        |   3 +\n drivers/net/bnxt/bnxt_cpr.c    |   3 +\n drivers/net/bnxt/bnxt_ethdev.c | 461 ++++++++++++++++++++++-----------\n drivers/net/bnxt/bnxt_hwrm.c   |   2 -\n drivers/net/bnxt/bnxt_ring.c   |  32 +++\n drivers/net/bnxt/bnxt_ring.h   |   1 +\n drivers/net/bnxt/bnxt_rxq.c    |  25 ++\n drivers/net/bnxt/bnxt_rxr.c    |  17 ++\n drivers/net/bnxt/bnxt_rxr.h    |   2 +\n drivers/net/bnxt/bnxt_stats.c  |  36 ++-\n drivers/net/bnxt/bnxt_txq.c    |   7 +\n drivers/net/bnxt/bnxt_txr.c    |  27 ++\n drivers/net/bnxt/bnxt_txr.h    |   2 +\n 13 files changed, 465 insertions(+), 153 deletions(-)",
    "diff": "diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h\nindex 0c9f994eaa..37b4c717d6 100644\n--- a/drivers/net/bnxt/bnxt.h\n+++ b/drivers/net/bnxt/bnxt.h\n@@ -358,6 +358,8 @@ struct bnxt {\n #define BNXT_FLAG_DFLT_VNIC_SET\t(1 << 12)\n #define BNXT_FLAG_THOR_CHIP\t(1 << 13)\n #define BNXT_FLAG_STINGRAY\t(1 << 14)\n+#define BNXT_FLAG_FW_RESET\t(1 << 15)\n+#define BNXT_FLAG_FATAL_ERROR\t(1 << 16)\n #define BNXT_FLAG_EXT_STATS_SUPPORTED\t(1 << 29)\n #define BNXT_FLAG_NEW_RM\t(1 << 30)\n #define BNXT_FLAG_INIT_DONE\t(1U << 31)\n@@ -465,6 +467,7 @@ struct bnxt {\n \n int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);\n int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);\n+int is_bnxt_in_error(struct bnxt *bp);\n \n bool is_bnxt_supported(struct rte_eth_dev *dev);\n bool bnxt_stratus_device(struct bnxt *bp);\ndiff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c\nindex 655bcf1a8d..bbcdb42f10 100644\n--- a/drivers/net/bnxt/bnxt_cpr.c\n+++ b/drivers/net/bnxt/bnxt_cpr.c\n@@ -142,6 +142,9 @@ int bnxt_event_hwrm_resp_handler(struct bnxt *bp, struct cmpl_base *cmp)\n \t\treturn evt;\n \t}\n \n+\tif (unlikely(is_bnxt_in_error(bp)))\n+\t\treturn 0;\n+\n \tswitch (CMP_TYPE(cmp)) {\n \tcase CMPL_BASE_TYPE_HWRM_ASYNC_EVENT:\n \t\t/* Handle any async event */\ndiff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c\nindex eb8701131a..d90a6e4202 100644\n--- a/drivers/net/bnxt/bnxt_ethdev.c\n+++ b/drivers/net/bnxt/bnxt_ethdev.c\n@@ -167,6 +167,16 @@ static void bnxt_print_link_info(struct rte_eth_dev *eth_dev);\n static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu);\n static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev);\n \n+int is_bnxt_in_error(struct bnxt *bp)\n+{\n+\tif (bp->flags & BNXT_FLAG_FATAL_ERROR)\n+\t\treturn -EIO;\n+\tif (bp->flags & BNXT_FLAG_FW_RESET)\n+\t\treturn -EBUSY;\n+\n+\treturn 0;\n+}\n+\n /***********************/\n \n /*\n@@ -207,6 +217,10 @@ static int bnxt_alloc_mem(struct bnxt *bp)\n {\n \tint rc;\n \n+\trc = bnxt_alloc_ring_grps(bp);\n+\tif (rc)\n+\t\tgoto alloc_mem_err;\n+\n \trc = bnxt_alloc_async_ring_struct(bp);\n \tif (rc)\n \t\tgoto alloc_mem_err;\n@@ -500,6 +514,11 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,\n \tstruct bnxt *bp = eth_dev->data->dev_private;\n \tuint16_t max_vnics, i, j, vpool, vrxq;\n \tunsigned int max_rx_rings;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \t/* MAC Specifics */\n \tdev_info->max_mac_addrs = bp->max_l2_ctx;\n@@ -604,6 +623,10 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)\n \tbp->tx_nr_rings = eth_dev->data->nb_tx_queues;\n \tbp->rx_nr_rings = eth_dev->data->nb_rx_queues;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tif (BNXT_VF(bp) && (bp->flags & BNXT_FLAG_NEW_RM)) {\n \t\trc = bnxt_hwrm_check_vf_rings(bp);\n \t\tif (rc) {\n@@ -793,8 +816,10 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)\n \n \teth_dev->rx_pkt_burst = bnxt_receive_function(eth_dev);\n \teth_dev->tx_pkt_burst = bnxt_transmit_function(eth_dev);\n+\n \tbnxt_enable_int(bp);\n \tbp->flags |= BNXT_FLAG_INIT_DONE;\n+\teth_dev->data->dev_started = 1;\n \tbp->dev_stopped = 0;\n \treturn 0;\n \n@@ -837,6 +862,11 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)\n \tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);\n \tstruct rte_intr_handle *intr_handle = &pci_dev->intr_handle;\n \n+\teth_dev->data->dev_started = 0;\n+\t/* Prevent crashes when queues are still in use */\n+\teth_dev->rx_pkt_burst = &bnxt_dummy_recv_pkts;\n+\teth_dev->tx_pkt_burst = &bnxt_dummy_xmit_pkts;\n+\n \tbnxt_disable_int(bp);\n \n \t/* disable uio/vfio intr/eventfd mapping */\n@@ -891,6 +921,9 @@ static void bnxt_mac_addr_remove_op(struct rte_eth_dev *eth_dev,\n \tstruct bnxt_filter_info *filter, *temp_filter;\n \tuint32_t i;\n \n+\tif (is_bnxt_in_error(bp))\n+\t\treturn;\n+\n \t/*\n \t * Loop through all VNICs from the specified filter flow pools to\n \t * remove the corresponding MAC addr filter\n@@ -926,6 +959,10 @@ static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev,\n \tstruct bnxt_filter_info *filter;\n \tint rc = 0;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tif (BNXT_VF(bp) & !BNXT_VF_IS_TRUSTED(bp)) {\n \t\tPMD_DRV_LOG(ERR, \"Cannot add MAC address to a VF interface\\n\");\n \t\treturn -ENOTSUP;\n@@ -971,6 +1008,10 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)\n \tstruct rte_eth_link new;\n \tunsigned int cnt = BNXT_LINK_WAIT_CNT;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tmemset(&new, 0, sizeof(new));\n \tdo {\n \t\t/* Retrieve link info from hardware */\n@@ -1013,6 +1054,10 @@ static int bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev)\n \tuint32_t old_flags;\n \tint rc;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tif (bp->vnic_info == NULL)\n \t\treturn 0;\n \n@@ -1034,6 +1079,10 @@ static int bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)\n \tuint32_t old_flags;\n \tint rc;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tif (bp->vnic_info == NULL)\n \t\treturn 0;\n \n@@ -1055,6 +1104,10 @@ static int bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)\n \tuint32_t old_flags;\n \tint rc;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tif (bp->vnic_info == NULL)\n \t\treturn 0;\n \n@@ -1076,6 +1129,10 @@ static int bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)\n \tuint32_t old_flags;\n \tint rc;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tif (bp->vnic_info == NULL)\n \t\treturn 0;\n \n@@ -1130,7 +1187,11 @@ static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,\n \tstruct bnxt_vnic_info *vnic = &bp->vnic_info[0];\n \tuint16_t tbl_size = bnxt_rss_hash_tbl_size(bp);\n \tuint16_t idx, sft;\n-\tint i;\n+\tint i, rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \tif (!vnic->rss_table)\n \t\treturn -EINVAL;\n@@ -1186,6 +1247,11 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,\n \tstruct bnxt_vnic_info *vnic = &bp->vnic_info[0];\n \tuint16_t tbl_size = bnxt_rss_hash_tbl_size(bp);\n \tuint16_t idx, sft, i;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \t/* Retrieve from the default VNIC */\n \tif (!vnic)\n@@ -1232,6 +1298,11 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev,\n \tstruct bnxt_vnic_info *vnic;\n \tuint16_t hash_type = 0;\n \tunsigned int i;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \t/*\n \t * If RSS enablement were different than dev_configure,\n@@ -1285,9 +1356,13 @@ static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev,\n {\n \tstruct bnxt *bp = eth_dev->data->dev_private;\n \tstruct bnxt_vnic_info *vnic = &bp->vnic_info[0];\n-\tint len;\n+\tint len, rc;\n \tuint32_t hash_types;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \t/* RSS configuration is the same for all VNICs */\n \tif (vnic && vnic->rss_hash_key) {\n \t\tif (rss_conf->rss_key) {\n@@ -1345,6 +1420,10 @@ static int bnxt_flow_ctrl_get_op(struct rte_eth_dev *dev,\n \tstruct rte_eth_link link_info;\n \tint rc;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \trc = bnxt_get_hwrm_link_config(bp, &link_info);\n \tif (rc)\n \t\treturn rc;\n@@ -1374,6 +1453,11 @@ static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev,\n \t\t\t       struct rte_eth_fc_conf *fc_conf)\n {\n \tstruct bnxt *bp = dev->data->dev_private;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \tif (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) {\n \t\tPMD_DRV_LOG(ERR, \"Flow Control Settings cannot be modified\\n\");\n@@ -1433,6 +1517,10 @@ bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,\n \tuint16_t tunnel_type = 0;\n \tint rc = 0;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tswitch (udp_tunnel->prot_type) {\n \tcase RTE_TUNNEL_TYPE_VXLAN:\n \t\tif (bp->vxlan_port_cnt) {\n@@ -1482,6 +1570,10 @@ bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,\n \tuint16_t port = 0;\n \tint rc = 0;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tswitch (udp_tunnel->prot_type) {\n \tcase RTE_TUNNEL_TYPE_VXLAN:\n \t\tif (!bp->vxlan_port_cnt) {\n@@ -1635,6 +1727,11 @@ static int bnxt_vlan_filter_set_op(struct rte_eth_dev *eth_dev,\n \t\tuint16_t vlan_id, int on)\n {\n \tstruct bnxt *bp = eth_dev->data->dev_private;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \t/* These operations apply to ALL existing MAC/VLAN filters */\n \tif (on)\n@@ -1649,6 +1746,11 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)\n \tstruct bnxt *bp = dev->data->dev_private;\n \tuint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;\n \tunsigned int i;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \tif (mask & ETH_VLAN_FILTER_MASK) {\n \t\tif (!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)) {\n@@ -1690,6 +1792,10 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev,\n \tstruct bnxt_filter_info *filter;\n \tint rc;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tif (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp))\n \t\treturn -EPERM;\n \n@@ -1729,6 +1835,11 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,\n \tchar *mc_addr_list = (char *)mc_addr_set;\n \tstruct bnxt_vnic_info *vnic;\n \tuint32_t off = 0, i = 0;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \tvnic = &bp->vnic_info[0];\n \n@@ -1814,6 +1925,10 @@ static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)\n \tuint32_t rc = 0;\n \tuint32_t i;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tnew_pkt_size = new_mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN +\n \t\t       VLAN_TAG_SIZE * BNXT_NUM_VLANS;\n \n@@ -1891,6 +2006,10 @@ bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on)\n \tuint16_t vlan = bp->vlan;\n \tint rc;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tif (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) {\n \t\tPMD_DRV_LOG(ERR,\n \t\t\t\"PVID cannot be modified for this function\\n\");\n@@ -1908,6 +2027,11 @@ static int\n bnxt_dev_led_on_op(struct rte_eth_dev *dev)\n {\n \tstruct bnxt *bp = dev->data->dev_private;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \treturn bnxt_hwrm_port_led_cfg(bp, true);\n }\n@@ -1916,6 +2040,11 @@ static int\n bnxt_dev_led_off_op(struct rte_eth_dev *dev)\n {\n \tstruct bnxt *bp = dev->data->dev_private;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \treturn bnxt_hwrm_port_led_cfg(bp, false);\n }\n@@ -1923,6 +2052,7 @@ bnxt_dev_led_off_op(struct rte_eth_dev *dev)\n static uint32_t\n bnxt_rx_queue_count_op(struct rte_eth_dev *dev, uint16_t rx_queue_id)\n {\n+\tstruct bnxt *bp = (struct bnxt *)dev->data->dev_private;\n \tuint32_t desc = 0, raw_cons = 0, cons;\n \tstruct bnxt_cp_ring_info *cpr;\n \tstruct bnxt_rx_queue *rxq;\n@@ -1930,6 +2060,11 @@ bnxt_rx_queue_count_op(struct rte_eth_dev *dev, uint16_t rx_queue_id)\n \tuint16_t cmp_type;\n \tuint8_t cmp = 1;\n \tbool valid;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \trxq = dev->data->rx_queues[rx_queue_id];\n \tcpr = rxq->cp_ring;\n@@ -1974,10 +2109,15 @@ bnxt_rx_descriptor_status_op(void *rx_queue, uint16_t offset)\n \tstruct bnxt_sw_rx_bd *rx_buf;\n \tstruct rx_pkt_cmpl *rxcmp;\n \tuint32_t cons, cp_cons;\n+\tint rc;\n \n \tif (!rxq)\n \t\treturn -EINVAL;\n \n+\trc = is_bnxt_in_error(rxq->bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tcpr = rxq->cp_ring;\n \trxr = rxq->rx_ring;\n \n@@ -2012,10 +2152,15 @@ bnxt_tx_descriptor_status_op(void *tx_queue, uint16_t offset)\n \tstruct bnxt_sw_tx_bd *tx_buf;\n \tstruct tx_pkt_cmpl *txcmp;\n \tuint32_t cons, cp_cons;\n+\tint rc;\n \n \tif (!txq)\n \t\treturn -EINVAL;\n \n+\trc = is_bnxt_in_error(txq->bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tcpr = txq->cp_ring;\n \ttxr = txq->tx_ring;\n \n@@ -2845,6 +2990,10 @@ bnxt_filter_ctrl_op(struct rte_eth_dev *dev __rte_unused,\n {\n \tint ret = 0;\n \n+\tret = is_bnxt_in_error(dev->data->dev_private);\n+\tif (ret)\n+\t\treturn ret;\n+\n \tswitch (filter_type) {\n \tcase RTE_ETH_FILTER_TUNNEL:\n \t\tPMD_DRV_LOG(ERR,\n@@ -3160,6 +3309,10 @@ bnxt_get_eeprom_length_op(struct rte_eth_dev *dev)\n \tuint32_t dir_entries;\n \tuint32_t entry_length;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tPMD_DRV_LOG(INFO, \"%04x:%02x:%02x:%02x\\n\",\n \t\tbp->pdev->addr.domain, bp->pdev->addr.bus,\n \t\tbp->pdev->addr.devid, bp->pdev->addr.function);\n@@ -3178,6 +3331,11 @@ bnxt_get_eeprom_op(struct rte_eth_dev *dev,\n \tstruct bnxt *bp = dev->data->dev_private;\n \tuint32_t index;\n \tuint32_t offset;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \tPMD_DRV_LOG(INFO, \"%04x:%02x:%02x:%02x in_eeprom->offset = %d \"\n \t\t\"len = %d\\n\", bp->pdev->addr.domain,\n@@ -3249,6 +3407,11 @@ bnxt_set_eeprom_op(struct rte_eth_dev *dev,\n \tstruct bnxt *bp = dev->data->dev_private;\n \tuint8_t index, dir_op;\n \tuint16_t type, ext, ordinal, attr;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \tPMD_DRV_LOG(INFO, \"%04x:%02x:%02x:%02x in_eeprom->offset = %d \"\n \t\t\"len = %d\\n\", bp->pdev->addr.domain,\n@@ -3802,19 +3965,139 @@ static int bnxt_setup_mac_addr(struct rte_eth_dev *eth_dev)\n \treturn rc;\n }\n \n+static void bnxt_config_vf_req_fwd(struct bnxt *bp)\n+{\n+\tif (!BNXT_PF(bp))\n+\t\treturn;\n+\n #define ALLOW_FUNC(x)\t\\\n \t{ \\\n \t\tuint32_t arg = (x); \\\n \t\tbp->pf.vf_req_fwd[((arg) >> 5)] &= \\\n \t\t~rte_cpu_to_le_32(1 << ((arg) & 0x1f)); \\\n \t}\n+\n+\t/* Forward all requests if firmware is new enough */\n+\tif (((bp->fw_ver >= ((20 << 24) | (6 << 16) | (100 << 8))) &&\n+\t     (bp->fw_ver < ((20 << 24) | (7 << 16)))) ||\n+\t    ((bp->fw_ver >= ((20 << 24) | (8 << 16))))) {\n+\t\tmemset(bp->pf.vf_req_fwd, 0xff, sizeof(bp->pf.vf_req_fwd));\n+\t} else {\n+\t\tPMD_DRV_LOG(WARNING,\n+\t\t\t    \"Firmware too old for VF mailbox functionality\\n\");\n+\t\tmemset(bp->pf.vf_req_fwd, 0, sizeof(bp->pf.vf_req_fwd));\n+\t}\n+\n+\t/*\n+\t * The following are used for driver cleanup. If we disallow these,\n+\t * VF drivers can't clean up cleanly.\n+\t */\n+\tALLOW_FUNC(HWRM_FUNC_DRV_UNRGTR);\n+\tALLOW_FUNC(HWRM_VNIC_FREE);\n+\tALLOW_FUNC(HWRM_RING_FREE);\n+\tALLOW_FUNC(HWRM_RING_GRP_FREE);\n+\tALLOW_FUNC(HWRM_VNIC_RSS_COS_LB_CTX_FREE);\n+\tALLOW_FUNC(HWRM_CFA_L2_FILTER_FREE);\n+\tALLOW_FUNC(HWRM_STAT_CTX_FREE);\n+\tALLOW_FUNC(HWRM_PORT_PHY_QCFG);\n+\tALLOW_FUNC(HWRM_VNIC_TPA_CFG);\n+}\n+\n+static int bnxt_init_fw(struct bnxt *bp)\n+{\n+\tuint16_t mtu;\n+\tint rc = 0;\n+\n+\trc = bnxt_hwrm_ver_get(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\trc = bnxt_hwrm_func_reset(bp);\n+\tif (rc)\n+\t\treturn -EIO;\n+\n+\trc = bnxt_hwrm_queue_qportcfg(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* Get the MAX capabilities for this function */\n+\trc = bnxt_hwrm_func_qcaps(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\trc = bnxt_hwrm_func_qcfg(bp, &mtu);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tif (mtu >= RTE_ETHER_MIN_MTU && mtu <= BNXT_MAX_MTU &&\n+\t    mtu != bp->eth_dev->data->mtu)\n+\t\tbp->eth_dev->data->mtu = mtu;\n+\n+\tbnxt_hwrm_port_led_qcaps(bp);\n+\n+\treturn 0;\n+}\n+\n+static int bnxt_init_resources(struct bnxt *bp)\n+{\n+\tint rc;\n+\n+\trc = bnxt_init_fw(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\trc = bnxt_setup_mac_addr(bp->eth_dev);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tbnxt_config_vf_req_fwd(bp);\n+\n+\trc = bnxt_hwrm_func_driver_register(bp);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to register driver\");\n+\t\treturn -EBUSY;\n+\t}\n+\n+\tif (BNXT_PF(bp)) {\n+\t\tif (bp->pdev->max_vfs) {\n+\t\t\trc = bnxt_hwrm_allocate_vfs(bp, bp->pdev->max_vfs);\n+\t\t\tif (rc) {\n+\t\t\t\tPMD_DRV_LOG(ERR, \"Failed to allocate VFs\\n\");\n+\t\t\t\treturn rc;\n+\t\t\t}\n+\t\t} else {\n+\t\t\trc = bnxt_hwrm_allocate_pf_only(bp);\n+\t\t\tif (rc) {\n+\t\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t\t    \"Failed to allocate PF resources\");\n+\t\t\t\treturn rc;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\trc = bnxt_alloc_mem(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\trc = bnxt_setup_int(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tbnxt_init_nic(bp);\n+\n+\trc = bnxt_request_int(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\treturn 0;\n+}\n+\n static int\n bnxt_dev_init(struct rte_eth_dev *eth_dev)\n {\n \tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);\n \tstatic int version_printed;\n \tstruct bnxt *bp;\n-\tuint16_t mtu;\n \tint rc;\n \n \tif (version_printed++ == 0)\n@@ -3856,166 +4139,50 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)\n \trc = bnxt_init_board(eth_dev);\n \tif (rc) {\n \t\tPMD_DRV_LOG(ERR,\n-\t\t\t\"Board initialization failed rc: %x\\n\", rc);\n-\t\tgoto error;\n+\t\t\t    \"Failed to initialize board rc: %x\\n\", rc);\n+\t\treturn rc;\n \t}\n \n \trc = bnxt_alloc_hwrm_resources(bp);\n \tif (rc) {\n \t\tPMD_DRV_LOG(ERR,\n-\t\t\t\"hwrm resource allocation failure rc: %x\\n\", rc);\n+\t\t\t    \"Failed to allocate hwrm resource rc: %x\\n\", rc);\n \t\tgoto error_free;\n \t}\n-\trc = bnxt_hwrm_ver_get(bp);\n+\trc = bnxt_init_resources(bp);\n \tif (rc)\n \t\tgoto error_free;\n \n-\trc = bnxt_hwrm_func_reset(bp);\n-\tif (rc) {\n-\t\tPMD_DRV_LOG(ERR, \"hwrm chip reset failure rc: %x\\n\", rc);\n-\t\trc = -EIO;\n-\t\tgoto error_free;\n-\t}\n-\n-\trc = bnxt_hwrm_queue_qportcfg(bp);\n-\tif (rc) {\n-\t\tPMD_DRV_LOG(ERR, \"hwrm queue qportcfg failed\\n\");\n-\t\tgoto error_free;\n-\t}\n-\t/* Get the MAX capabilities for this function */\n-\trc = bnxt_hwrm_func_qcaps(bp);\n-\tif (rc) {\n-\t\tPMD_DRV_LOG(ERR, \"hwrm query capability failure rc: %x\\n\", rc);\n-\t\tgoto error_free;\n-\t}\n-\n \trc = bnxt_alloc_stats_mem(bp);\n \tif (rc)\n \t\tgoto error_free;\n \n-\tif (bp->max_tx_rings == 0) {\n-\t\tPMD_DRV_LOG(ERR, \"No TX rings available!\\n\");\n-\t\trc = -EBUSY;\n-\t\tgoto error_free;\n-\t}\n-\n-\trc = bnxt_setup_mac_addr(eth_dev);\n-\tif (rc)\n-\t\tgoto error_free;\n-\n-\t/* THOR does not support ring groups.\n-\t * But we will use the array to save RSS context IDs.\n-\t */\n-\tif (BNXT_CHIP_THOR(bp)) {\n-\t\tbp->max_ring_grps = BNXT_MAX_RSS_CTXTS_THOR;\n-\t} else if (bp->max_ring_grps < bp->rx_cp_nr_rings) {\n-\t\t/* 1 ring is for default completion ring */\n-\t\tPMD_DRV_LOG(ERR, \"Insufficient resource: Ring Group\\n\");\n-\t\trc = -ENOSPC;\n-\t\tgoto error_free;\n-\t}\n-\n-\tif (BNXT_HAS_RING_GRPS(bp)) {\n-\t\tbp->grp_info = rte_zmalloc(\"bnxt_grp_info\",\n-\t\t\t\t\tsizeof(*bp->grp_info) *\n-\t\t\t\t\t\tbp->max_ring_grps, 0);\n-\t\tif (!bp->grp_info) {\n-\t\t\tPMD_DRV_LOG(ERR,\n-\t\t\t\t\"Failed to alloc %zu bytes for grp info tbl.\\n\",\n-\t\t\t\tsizeof(*bp->grp_info) * bp->max_ring_grps);\n-\t\t\trc = -ENOMEM;\n-\t\t\tgoto error_free;\n-\t\t}\n-\t}\n-\n-\t/* Forward all requests if firmware is new enough */\n-\tif (((bp->fw_ver >= ((20 << 24) | (6 << 16) | (100 << 8))) &&\n-\t    (bp->fw_ver < ((20 << 24) | (7 << 16)))) ||\n-\t    ((bp->fw_ver >= ((20 << 24) | (8 << 16))))) {\n-\t\tmemset(bp->pf.vf_req_fwd, 0xff, sizeof(bp->pf.vf_req_fwd));\n-\t} else {\n-\t\tPMD_DRV_LOG(WARNING,\n-\t\t\t\"Firmware too old for VF mailbox functionality\\n\");\n-\t\tmemset(bp->pf.vf_req_fwd, 0, sizeof(bp->pf.vf_req_fwd));\n-\t}\n-\n-\t/*\n-\t * The following are used for driver cleanup.  If we disallow these,\n-\t * VF drivers can't clean up cleanly.\n-\t */\n-\tALLOW_FUNC(HWRM_FUNC_DRV_UNRGTR);\n-\tALLOW_FUNC(HWRM_VNIC_FREE);\n-\tALLOW_FUNC(HWRM_RING_FREE);\n-\tALLOW_FUNC(HWRM_RING_GRP_FREE);\n-\tALLOW_FUNC(HWRM_VNIC_RSS_COS_LB_CTX_FREE);\n-\tALLOW_FUNC(HWRM_CFA_L2_FILTER_FREE);\n-\tALLOW_FUNC(HWRM_STAT_CTX_FREE);\n-\tALLOW_FUNC(HWRM_PORT_PHY_QCFG);\n-\tALLOW_FUNC(HWRM_VNIC_TPA_CFG);\n-\trc = bnxt_hwrm_func_driver_register(bp);\n-\tif (rc) {\n-\t\tPMD_DRV_LOG(ERR,\n-\t\t\t\"Failed to register driver\");\n-\t\trc = -EBUSY;\n-\t\tgoto error_free;\n-\t}\n-\n \tPMD_DRV_LOG(INFO,\n-\t\tDRV_MODULE_NAME \" found at mem %\" PRIx64 \", node addr %pM\\n\",\n-\t\tpci_dev->mem_resource[0].phys_addr,\n-\t\tpci_dev->mem_resource[0].addr);\n-\n-\trc = bnxt_hwrm_func_qcfg(bp, &mtu);\n-\tif (rc) {\n-\t\tPMD_DRV_LOG(ERR, \"hwrm func qcfg failed\\n\");\n-\t\tgoto error_free;\n-\t}\n-\n-\tif (mtu >= RTE_ETHER_MIN_MTU && mtu <= BNXT_MAX_MTU &&\n-\t    mtu != eth_dev->data->mtu)\n-\t\teth_dev->data->mtu = mtu;\n-\n-\tif (BNXT_PF(bp)) {\n-\t\t//if (bp->pf.active_vfs) {\n-\t\t\t// TODO: Deallocate VF resources?\n-\t\t//}\n-\t\tif (bp->pdev->max_vfs) {\n-\t\t\trc = bnxt_hwrm_allocate_vfs(bp, bp->pdev->max_vfs);\n-\t\t\tif (rc) {\n-\t\t\t\tPMD_DRV_LOG(ERR, \"Failed to allocate VFs\\n\");\n-\t\t\t\tgoto error_free;\n-\t\t\t}\n-\t\t} else {\n-\t\t\trc = bnxt_hwrm_allocate_pf_only(bp);\n-\t\t\tif (rc) {\n-\t\t\t\tPMD_DRV_LOG(ERR,\n-\t\t\t\t\t\"Failed to allocate PF resources\\n\");\n-\t\t\t\tgoto error_free;\n-\t\t\t}\n-\t\t}\n-\t}\n-\n-\tbnxt_hwrm_port_led_qcaps(bp);\n-\n-\trc = bnxt_setup_int(bp);\n-\tif (rc)\n-\t\tgoto error_free;\n-\n-\trc = bnxt_alloc_mem(bp);\n-\tif (rc)\n-\t\tgoto error_free;\n-\n-\tbnxt_init_nic(bp);\n-\n-\trc = bnxt_request_int(bp);\n-\tif (rc)\n-\t\tgoto error_free;\n+\t\t    DRV_MODULE_NAME \"found at mem %\" PRIX64 \", node addr %pM\\n\",\n+\t\t    pci_dev->mem_resource[0].phys_addr,\n+\t\t    pci_dev->mem_resource[0].addr);\n \n \treturn 0;\n \n error_free:\n \tbnxt_dev_uninit(eth_dev);\n-error:\n+\treturn rc;\n+}\n+\n+static int\n+bnxt_uninit_resources(struct bnxt *bp)\n+{\n+\tint rc;\n+\n+\tbnxt_disable_int(bp);\n+\tbnxt_free_int(bp);\n+\tbnxt_free_mem(bp);\n+\tbnxt_hwrm_func_buf_unrgtr(bp);\n+\trc = bnxt_hwrm_func_driver_unregister(bp, 0);\n+\tbp->flags &= ~BNXT_FLAG_REGISTERED;\n+\tbnxt_free_ctx_mem(bp);\n+\tbnxt_free_hwrm_resources(bp);\n+\n \treturn rc;\n }\n \n@@ -4029,18 +4196,13 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev)\n \t\treturn -EPERM;\n \n \tPMD_DRV_LOG(DEBUG, \"Calling Device uninit\\n\");\n-\tbnxt_disable_int(bp);\n-\tbnxt_free_int(bp);\n-\tbnxt_free_mem(bp);\n \n-\tbnxt_hwrm_func_buf_unrgtr(bp);\n+\trc = bnxt_uninit_resources(bp);\n \n \tif (bp->grp_info != NULL) {\n \t\trte_free(bp->grp_info);\n \t\tbp->grp_info = NULL;\n \t}\n-\trc = bnxt_hwrm_func_driver_unregister(bp, 0);\n-\tbnxt_free_hwrm_resources(bp);\n \n \tif (bp->tx_mem_zone) {\n \t\trte_memzone_free((const struct rte_memzone *)bp->tx_mem_zone);\n@@ -4056,7 +4218,6 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev)\n \t\tbnxt_dev_close_op(eth_dev);\n \tif (bp->pf.vf_info)\n \t\trte_free(bp->pf.vf_info);\n-\tbnxt_free_ctx_mem(bp);\n \teth_dev->dev_ops = NULL;\n \teth_dev->rx_pkt_burst = NULL;\n \teth_dev->tx_pkt_burst = NULL;\ndiff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c\nindex 9883fb5063..24a5a09147 100644\n--- a/drivers/net/bnxt/bnxt_hwrm.c\n+++ b/drivers/net/bnxt/bnxt_hwrm.c\n@@ -964,8 +964,6 @@ int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags)\n \tHWRM_CHECK_RESULT();\n \tHWRM_UNLOCK();\n \n-\tbp->flags &= ~BNXT_FLAG_REGISTERED;\n-\n \treturn rc;\n }\n \ndiff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c\nindex be15b4bd14..f19865c832 100644\n--- a/drivers/net/bnxt/bnxt_ring.c\n+++ b/drivers/net/bnxt/bnxt_ring.c\n@@ -50,6 +50,38 @@ int bnxt_init_ring_grps(struct bnxt *bp)\n \treturn 0;\n }\n \n+int bnxt_alloc_ring_grps(struct bnxt *bp)\n+{\n+\tif (bp->max_tx_rings == 0) {\n+\t\tPMD_DRV_LOG(ERR, \"No TX rings available!\\n\");\n+\t\treturn -EBUSY;\n+\t}\n+\n+\t/* THOR does not support ring groups.\n+\t * But we will use the array to save RSS context IDs.\n+\t */\n+\tif (BNXT_CHIP_THOR(bp)) {\n+\t\tbp->max_ring_grps = BNXT_MAX_RSS_CTXTS_THOR;\n+\t} else if (bp->max_ring_grps < bp->rx_cp_nr_rings) {\n+\t\t/* 1 ring is for default completion ring */\n+\t\tPMD_DRV_LOG(ERR, \"Insufficient resource: Ring Group\\n\");\n+\t\treturn -ENOSPC;\n+\t}\n+\n+\tif (BNXT_HAS_RING_GRPS(bp)) {\n+\t\tbp->grp_info = rte_zmalloc(\"bnxt_grp_info\",\n+\t\t\t\t\t   sizeof(*bp->grp_info) *\n+\t\t\t\t\t   bp->max_ring_grps, 0);\n+\t\tif (!bp->grp_info) {\n+\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t    \"Failed to alloc grp info tbl.\\n\");\n+\t\t\treturn -ENOMEM;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n /*\n  * Allocates a completion ring with vmem and stats optionally also allocating\n  * a TX and/or RX ring.  Passing NULL as tx_ring_info and/or rx_ring_info\ndiff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h\nindex 04c7b04b82..a31d59ea39 100644\n--- a/drivers/net/bnxt/bnxt_ring.h\n+++ b/drivers/net/bnxt/bnxt_ring.h\n@@ -67,6 +67,7 @@ struct bnxt_rx_ring_info;\n struct bnxt_cp_ring_info;\n void bnxt_free_ring(struct bnxt_ring *ring);\n int bnxt_init_ring_grps(struct bnxt *bp);\n+int bnxt_alloc_ring_grps(struct bnxt *bp);\n int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,\n \t\t\t    struct bnxt_tx_queue *txq,\n \t\t\t    struct bnxt_rx_queue *rxq,\ndiff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c\nindex 1d95f11394..d5fc5268db 100644\n--- a/drivers/net/bnxt/bnxt_rxq.c\n+++ b/drivers/net/bnxt/bnxt_rxq.c\n@@ -263,6 +263,9 @@ void bnxt_rx_queue_release_op(void *rx_queue)\n \tstruct bnxt_rx_queue *rxq = (struct bnxt_rx_queue *)rx_queue;\n \n \tif (rxq) {\n+\t\tif (is_bnxt_in_error(rxq->bp))\n+\t\t\treturn;\n+\n \t\tbnxt_rx_queue_release_mbufs(rxq);\n \n \t\t/* Free RX ring hardware descriptors */\n@@ -294,6 +297,10 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,\n \tint rc = 0;\n \tuint8_t queue_state;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tif (queue_idx >= bp->max_rx_rings) {\n \t\tPMD_DRV_LOG(ERR,\n \t\t\t\"Cannot create Rx ring %d. Only %d rings available\\n\",\n@@ -363,10 +370,15 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,\n int\n bnxt_rx_queue_intr_enable_op(struct rte_eth_dev *eth_dev, uint16_t queue_id)\n {\n+\tstruct bnxt *bp = eth_dev->data->dev_private;\n \tstruct bnxt_rx_queue *rxq;\n \tstruct bnxt_cp_ring_info *cpr;\n \tint rc = 0;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tif (eth_dev->data->rx_queues) {\n \t\trxq = eth_dev->data->rx_queues[queue_id];\n \t\tif (!rxq) {\n@@ -382,10 +394,15 @@ bnxt_rx_queue_intr_enable_op(struct rte_eth_dev *eth_dev, uint16_t queue_id)\n int\n bnxt_rx_queue_intr_disable_op(struct rte_eth_dev *eth_dev, uint16_t queue_id)\n {\n+\tstruct bnxt *bp = eth_dev->data->dev_private;\n \tstruct bnxt_rx_queue *rxq;\n \tstruct bnxt_cp_ring_info *cpr;\n \tint rc = 0;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tif (eth_dev->data->rx_queues) {\n \t\trxq = eth_dev->data->rx_queues[queue_id];\n \t\tif (!rxq) {\n@@ -406,6 +423,10 @@ int bnxt_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)\n \tstruct bnxt_vnic_info *vnic = NULL;\n \tint rc = 0;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tif (rxq == NULL) {\n \t\tPMD_DRV_LOG(ERR, \"Invalid Rx queue %d\\n\", rx_queue_id);\n \t\treturn -EINVAL;\n@@ -458,6 +479,10 @@ int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)\n \tstruct bnxt_rx_queue *rxq = NULL;\n \tint rc = 0;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \t/* For the stingray platform and other platforms needing tighter\n \t * control of resource utilization, Rx CQ 0 also works as\n \t * Default CQ for async notifications\ndiff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c\nindex 185a0e376b..12313dd53c 100644\n--- a/drivers/net/bnxt/bnxt_rxr.c\n+++ b/drivers/net/bnxt/bnxt_rxr.c\n@@ -539,6 +539,9 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,\n \tint rc = 0;\n \tbool evt = false;\n \n+\tif (unlikely(is_bnxt_in_error(rxq->bp)))\n+\t\treturn 0;\n+\n \t/* If Rx Q was stopped return. RxQ0 cannot be stopped. */\n \tif (unlikely(((rxq->rx_deferred_start ||\n \t\t       !rte_spinlock_trylock(&rxq->lock)) &&\n@@ -625,6 +628,20 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,\n \treturn nb_rx_pkts;\n }\n \n+/*\n+ * Dummy DPDK callback for RX.\n+ *\n+ * This function is used to temporarily replace the real callback during\n+ * unsafe control operations on the queue, or in case of error.\n+ */\n+uint16_t\n+bnxt_dummy_recv_pkts(void *rx_queue __rte_unused,\n+\t\t     struct rte_mbuf **rx_pkts __rte_unused,\n+\t\t     uint16_t nb_pkts __rte_unused)\n+{\n+\treturn 0;\n+}\n+\n void bnxt_free_rx_rings(struct bnxt *bp)\n {\n \tint i;\ndiff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h\nindex 6a80c37c81..493b754066 100644\n--- a/drivers/net/bnxt/bnxt_rxr.h\n+++ b/drivers/net/bnxt/bnxt_rxr.h\n@@ -185,6 +185,8 @@ struct bnxt_rx_ring_info {\n \n uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,\n \t\t\t       uint16_t nb_pkts);\n+uint16_t bnxt_dummy_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,\n+\t\t\t      uint16_t nb_pkts);\n void bnxt_free_rx_rings(struct bnxt *bp);\n int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id);\n int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq);\ndiff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c\nindex 049ad9e398..21012e1fee 100644\n--- a/drivers/net/bnxt/bnxt_stats.c\n+++ b/drivers/net/bnxt/bnxt_stats.c\n@@ -353,6 +353,10 @@ int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,\n \tstruct bnxt *bp = eth_dev->data->dev_private;\n \tunsigned int num_q_stats;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tmemset(bnxt_stats, 0, sizeof(*bnxt_stats));\n \tif (!(bp->flags & BNXT_FLAG_INIT_DONE)) {\n \t\tPMD_DRV_LOG(ERR, \"Device Initialization not complete!\\n\");\n@@ -398,6 +402,10 @@ int bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)\n \tunsigned int i;\n \tint ret;\n \n+\tret = is_bnxt_in_error(bp);\n+\tif (ret)\n+\t\treturn ret;\n+\n \tif (!(bp->flags & BNXT_FLAG_INIT_DONE)) {\n \t\tPMD_DRV_LOG(ERR, \"Device Initialization not complete!\\n\");\n \t\treturn -EINVAL;\n@@ -417,13 +425,17 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,\n \t\t\t   struct rte_eth_xstat *xstats, unsigned int n)\n {\n \tstruct bnxt *bp = eth_dev->data->dev_private;\n-\n \tunsigned int count, i;\n \tuint64_t tx_drop_pkts;\n \tunsigned int rx_port_stats_ext_cnt;\n \tunsigned int tx_port_stats_ext_cnt;\n \tunsigned int stat_size = sizeof(uint64_t);\n \tunsigned int stat_count;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \tmemset(xstats, 0, sizeof(*xstats));\n \n@@ -502,7 +514,13 @@ int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,\n \t\t\t\tRTE_DIM(bnxt_tx_stats_strings) + 1 +\n \t\t\t\tRTE_DIM(bnxt_rx_ext_stats_strings) +\n \t\t\t\tRTE_DIM(bnxt_tx_ext_stats_strings);\n+\tstruct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;\n \tunsigned int i, count;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \tif (xstats_names != NULL) {\n \t\tcount = 0;\n@@ -551,6 +569,10 @@ int bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev)\n \tstruct bnxt *bp = eth_dev->data->dev_private;\n \tint ret;\n \n+\tret = is_bnxt_in_error(bp);\n+\tif (ret)\n+\t\treturn ret;\n+\n \tif (bp->flags & BNXT_FLAG_PORT_STATS && BNXT_SINGLE_PF(bp)) {\n \t\tret = bnxt_hwrm_port_clr_stats(bp);\n \t\tif (ret != 0) {\n@@ -586,9 +608,15 @@ int bnxt_dev_xstats_get_by_id_op(struct rte_eth_dev *dev, const uint64_t *ids,\n \t\t\t\tRTE_DIM(bnxt_tx_stats_strings) + 1 +\n \t\t\t\tRTE_DIM(bnxt_rx_ext_stats_strings) +\n \t\t\t\tRTE_DIM(bnxt_tx_ext_stats_strings);\n+\tstruct bnxt *bp = dev->data->dev_private;\n \tstruct rte_eth_xstat xstats[stat_cnt];\n \tuint64_t values_copy[stat_cnt];\n \tuint16_t i;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \tif (!ids)\n \t\treturn bnxt_dev_xstats_get_op(dev, xstats, stat_cnt);\n@@ -614,7 +642,13 @@ int bnxt_dev_xstats_get_names_by_id_op(struct rte_eth_dev *dev,\n \t\t\t\tRTE_DIM(bnxt_rx_ext_stats_strings) +\n \t\t\t\tRTE_DIM(bnxt_tx_ext_stats_strings);\n \tstruct rte_eth_xstat_name xstats_names_copy[stat_cnt];\n+\tstruct bnxt *bp = dev->data->dev_private;\n \tuint16_t i;\n+\tint rc;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \tif (!ids)\n \t\treturn bnxt_dev_xstats_get_names_op(dev, xstats_names,\ndiff --git a/drivers/net/bnxt/bnxt_txq.c b/drivers/net/bnxt/bnxt_txq.c\nindex 43b3496c1e..0901324793 100644\n--- a/drivers/net/bnxt/bnxt_txq.c\n+++ b/drivers/net/bnxt/bnxt_txq.c\n@@ -58,6 +58,9 @@ void bnxt_tx_queue_release_op(void *tx_queue)\n \tstruct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue;\n \n \tif (txq) {\n+\t\tif (is_bnxt_in_error(txq->bp))\n+\t\t\treturn;\n+\n \t\t/* Free TX ring hardware descriptors */\n \t\tbnxt_tx_queue_release_mbufs(txq);\n \t\tbnxt_free_ring(txq->tx_ring->tx_ring_struct);\n@@ -84,6 +87,10 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,\n \tstruct bnxt_tx_queue *txq;\n \tint rc = 0;\n \n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n \tif (queue_idx >= bp->max_tx_rings) {\n \t\tPMD_DRV_LOG(ERR,\n \t\t\t\"Cannot create Tx ring %d. Only %d rings available\\n\",\ndiff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c\nindex c71e6f1892..35e7166bed 100644\n--- a/drivers/net/bnxt/bnxt_txr.c\n+++ b/drivers/net/bnxt/bnxt_txr.c\n@@ -148,6 +148,9 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,\n \t\tTX_BD_LONG_FLAGS_LHINT_LT2K\n \t};\n \n+\tif (unlikely(is_bnxt_in_error(txq->bp)))\n+\t\treturn -EIO;\n+\n \tif (tx_pkt->ol_flags & (PKT_TX_TCP_SEG | PKT_TX_TCP_CKSUM |\n \t\t\t\tPKT_TX_UDP_CKSUM | PKT_TX_IP_CKSUM |\n \t\t\t\tPKT_TX_VLAN_PKT | PKT_TX_OUTER_IP_CKSUM |\n@@ -485,10 +488,29 @@ uint16_t bnxt_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n \treturn nb_tx_pkts;\n }\n \n+/*\n+ * Dummy DPDK callback for TX.\n+ *\n+ * This function is used to temporarily replace the real callback during\n+ * unsafe control operations on the queue, or in case of error.\n+ */\n+uint16_t\n+bnxt_dummy_xmit_pkts(void *tx_queue __rte_unused,\n+\t\t     struct rte_mbuf **tx_pkts __rte_unused,\n+\t\t     uint16_t nb_pkts __rte_unused)\n+{\n+\treturn 0;\n+}\n+\n int bnxt_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)\n {\n \tstruct bnxt *bp = dev->data->dev_private;\n \tstruct bnxt_tx_queue *txq = bp->tx_queues[tx_queue_id];\n+\tint rc = 0;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \tdev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;\n \ttxq->tx_deferred_start = false;\n@@ -501,6 +523,11 @@ int bnxt_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)\n {\n \tstruct bnxt *bp = dev->data->dev_private;\n \tstruct bnxt_tx_queue *txq = bp->tx_queues[tx_queue_id];\n+\tint rc = 0;\n+\n+\trc = is_bnxt_in_error(bp);\n+\tif (rc)\n+\t\treturn rc;\n \n \t/* Handle TX completions */\n \tbnxt_handle_tx_cp(txq);\ndiff --git a/drivers/net/bnxt/bnxt_txr.h b/drivers/net/bnxt/bnxt_txr.h\nindex 08fd2e0142..e7f43f9d1d 100644\n--- a/drivers/net/bnxt/bnxt_txr.h\n+++ b/drivers/net/bnxt/bnxt_txr.h\n@@ -57,6 +57,8 @@ int bnxt_init_one_tx_ring(struct bnxt_tx_queue *txq);\n int bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq, unsigned int socket_id);\n uint16_t bnxt_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n \t\t\t       uint16_t nb_pkts);\n+uint16_t bnxt_dummy_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n+\t\t\t      uint16_t nb_pkts);\n #ifdef RTE_ARCH_X86\n uint16_t bnxt_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts,\n \t\t\t    uint16_t nb_pkts);\n",
    "prefixes": [
        "v3",
        "02/15"
    ]
}