get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 73052,
    "url": "https://patches.dpdk.org/api/patches/73052/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20200703210210.40568-3-ajit.khaparde@broadcom.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20200703210210.40568-3-ajit.khaparde@broadcom.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200703210210.40568-3-ajit.khaparde@broadcom.com",
    "date": "2020-07-03T21:01:21",
    "name": "[v5,02/51] net/bnxt: add support for VF-reps data path",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "aa1664f6ca9610efd7f639761b97a7da61ef7f3d",
    "submitter": {
        "id": 501,
        "url": "https://patches.dpdk.org/api/people/501/?format=api",
        "name": "Ajit Khaparde",
        "email": "ajit.khaparde@broadcom.com"
    },
    "delegate": {
        "id": 1766,
        "url": "https://patches.dpdk.org/api/users/1766/?format=api",
        "username": "ajitkhaparde",
        "first_name": "Ajit",
        "last_name": "Khaparde",
        "email": "ajit.khaparde@broadcom.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20200703210210.40568-3-ajit.khaparde@broadcom.com/mbox/",
    "series": [
        {
            "id": 10785,
            "url": "https://patches.dpdk.org/api/series/10785/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=10785",
            "date": "2020-07-03T21:01:19",
            "name": "net/bnxt: add features for host-based flow management",
            "version": 5,
            "mbox": "https://patches.dpdk.org/series/10785/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/73052/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/73052/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id BA3F4A0524;\n\tFri,  3 Jul 2020 23:05:27 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id BF0061DC3C;\n\tFri,  3 Jul 2020 23:05:03 +0200 (CEST)",
            "from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com\n [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id 58A831DBED\n for <dev@dpdk.org>; Fri,  3 Jul 2020 23:04:57 +0200 (CEST)",
            "from mail-irv-17.broadcom.com (mail-irv-17.lvn.broadcom.net\n [10.75.242.48])\n by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id 4F79230C05A;\n Fri,  3 Jul 2020 14:04:56 -0700 (PDT)",
            "from localhost.localdomain (unknown [10.230.185.215])\n by mail-irv-17.broadcom.com (Postfix) with ESMTP id A328A14008E;\n Fri,  3 Jul 2020 14:04:55 -0700 (PDT)"
        ],
        "DKIM-Filter": "OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com 4F79230C05A",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com;\n s=dkimrelay; t=1593810296;\n bh=wWZEa+Z3l7DqC78S4TywQO24ztPbxd4CI9fk2a88kuI=;\n h=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n b=XgEsSNkLM0WkuP2lZXtP60WSxrJYhg0stnsJYee8ercDkt4RwO+yNOsY6vdh/Z1uF\n GpJ6NcXrJpzHUgdQLb2JW/7oKEmknpZDwjHrkcxRYZlsRqZMbsI3CSJ1tvV/0wx4Tk\n 3dGBPGm8OOzv3P6of4eUCT0U5QODtmVQpOotZ9rc=",
        "From": "Ajit Khaparde <ajit.khaparde@broadcom.com>",
        "To": "dev@dpdk.org",
        "Cc": "Somnath Kotur <somnath.kotur@broadcom.com>,\n Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>",
        "Date": "Fri,  3 Jul 2020 14:01:21 -0700",
        "Message-Id": "<20200703210210.40568-3-ajit.khaparde@broadcom.com>",
        "X-Mailer": "git-send-email 2.21.1 (Apple Git-122.3)",
        "In-Reply-To": "<20200703210210.40568-1-ajit.khaparde@broadcom.com>",
        "References": "<1f5421dc-0453-6dc8-09c2-ddfff6eb4888@intel.com>\n <20200703210210.40568-1-ajit.khaparde@broadcom.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v5 02/51] net/bnxt: add support for VF-reps data\n\tpath",
        "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 <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 <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Somnath Kotur <somnath.kotur@broadcom.com>\n\nAdded code to support Tx/Rx from a VF representor port.\nThe VF-reps use the RX/TX rings of the Trusted VF/PF.\nFor each VF-rep, the Trusted VF/PF driver issues a VFR_ALLOC FW cmd that\nreturns \"cfa_code\" and \"cfa_action\" values.\nThe FW sets up the filter tables in such a way that VF traffic by\ndefault (in absence of other rules) gets punted to the parent function\ni.e. either the Trusted VF or the PF.\nThe cfa_code value in the RX-compl informs the driver of the source VF.\nFor traffic being transmitted from the VF-rep, the TX BD is tagged with\na cfa_action value that informs the HW to punt it to the corresponding\nVF.\n\nSigned-off-by: Somnath Kotur <somnath.kotur@broadcom.com>\nSigned-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>\nReviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>\n---\n drivers/net/bnxt/bnxt.h        |  30 ++-\n drivers/net/bnxt/bnxt_ethdev.c | 150 ++++++++---\n drivers/net/bnxt/bnxt_reps.c   | 476 +++++++++++++++++++++++++++++++--\n drivers/net/bnxt/bnxt_reps.h   |  11 +\n drivers/net/bnxt/bnxt_rxr.c    |  22 +-\n drivers/net/bnxt/bnxt_rxr.h    |   1 +\n drivers/net/bnxt/bnxt_txq.h    |   1 +\n drivers/net/bnxt/bnxt_txr.c    |   4 +-\n 8 files changed, 616 insertions(+), 79 deletions(-)",
    "diff": "diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h\nindex 9b7b87cee..443d9fee4 100644\n--- a/drivers/net/bnxt/bnxt.h\n+++ b/drivers/net/bnxt/bnxt.h\n@@ -495,6 +495,7 @@ struct bnxt_mark_info {\n \n struct bnxt_rep_info {\n \tstruct rte_eth_dev\t*vfr_eth_dev;\n+\tpthread_mutex_t\t\tvfr_lock;\n };\n \n /* address space location of register */\n@@ -755,7 +756,8 @@ struct bnxt {\n \tuint16_t\t\tfw_reset_max_msecs;\n \tuint16_t\t\tswitch_domain_id;\n \tuint16_t\t\tnum_reps;\n-\tstruct bnxt_rep_info\trep_info[BNXT_MAX_VF_REPS];\n+\tstruct bnxt_rep_info\t*rep_info;\n+\tuint16_t                *cfa_code_map;\n \t/* Struct to hold adapter error recovery related info */\n \tstruct bnxt_error_recovery_info *recovery_info;\n #define BNXT_MARK_TABLE_SZ\t(sizeof(struct bnxt_mark_info)  * 64 * 1024)\n@@ -780,12 +782,28 @@ struct bnxt {\n  * Structure to store private data for each VF representor instance\n  */\n struct bnxt_vf_representor {\n-\tuint16_t switch_domain_id;\n-\tuint16_t vf_id;\n+\tuint16_t\t\tswitch_domain_id;\n+\tuint16_t\t\tvf_id;\n+\tuint16_t\t\ttx_cfa_action;\n+\tuint16_t\t\trx_cfa_code;\n \t/* Private data store of associated PF/Trusted VF */\n-\tstruct bnxt\t*parent_priv;\n-\tuint8_t\t\tmac_addr[RTE_ETHER_ADDR_LEN];\n-\tuint8_t\t\tdflt_mac_addr[RTE_ETHER_ADDR_LEN];\n+\tstruct rte_eth_dev\t*parent_dev;\n+\tuint8_t\t\t\tmac_addr[RTE_ETHER_ADDR_LEN];\n+\tuint8_t\t\t\tdflt_mac_addr[RTE_ETHER_ADDR_LEN];\n+\tstruct bnxt_rx_queue\t**rx_queues;\n+\tunsigned int\t\trx_nr_rings;\n+\tunsigned int\t\ttx_nr_rings;\n+\tuint64_t                tx_pkts[BNXT_MAX_VF_REP_RINGS];\n+\tuint64_t                tx_bytes[BNXT_MAX_VF_REP_RINGS];\n+\tuint64_t                rx_pkts[BNXT_MAX_VF_REP_RINGS];\n+\tuint64_t                rx_bytes[BNXT_MAX_VF_REP_RINGS];\n+\tuint64_t                rx_drop_pkts[BNXT_MAX_VF_REP_RINGS];\n+\tuint64_t                rx_drop_bytes[BNXT_MAX_VF_REP_RINGS];\n+};\n+\n+struct bnxt_vf_rep_tx_queue {\n+\tstruct bnxt_tx_queue *txq;\n+\tstruct bnxt_vf_representor *bp;\n };\n \n int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu);\ndiff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c\nindex 1455e60d7..cddba17bd 100644\n--- a/drivers/net/bnxt/bnxt_ethdev.c\n+++ b/drivers/net/bnxt/bnxt_ethdev.c\n@@ -136,6 +136,7 @@ static void bnxt_cancel_fw_health_check(struct bnxt *bp);\n static int bnxt_restore_vlan_filters(struct bnxt *bp);\n static void bnxt_dev_recover(void *arg);\n static void bnxt_free_error_recovery_info(struct bnxt *bp);\n+static void bnxt_free_rep_info(struct bnxt *bp);\n \n int is_bnxt_in_error(struct bnxt *bp)\n {\n@@ -5242,7 +5243,7 @@ bnxt_init_locks(struct bnxt *bp)\n \n static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev)\n {\n-\tint rc;\n+\tint rc = 0;\n \n \trc = bnxt_init_fw(bp);\n \tif (rc)\n@@ -5641,6 +5642,8 @@ bnxt_uninit_locks(struct bnxt *bp)\n {\n \tpthread_mutex_destroy(&bp->flow_lock);\n \tpthread_mutex_destroy(&bp->def_cp_lock);\n+\tif (bp->rep_info)\n+\t\tpthread_mutex_destroy(&bp->rep_info->vfr_lock);\n }\n \n static int\n@@ -5663,6 +5666,7 @@ bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev)\n \n \tbnxt_uninit_locks(bp);\n \tbnxt_free_flow_stats_info(bp);\n+\tbnxt_free_rep_info(bp);\n \trte_free(bp->ptp_cfg);\n \tbp->ptp_cfg = NULL;\n \treturn rc;\n@@ -5702,56 +5706,73 @@ static int bnxt_pci_remove_dev_with_reps(struct rte_eth_dev *eth_dev)\n \treturn ret;\n }\n \n-static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n-\tstruct rte_pci_device *pci_dev)\n+static void bnxt_free_rep_info(struct bnxt *bp)\n {\n-\tchar name[RTE_ETH_NAME_MAX_LEN];\n-\tstruct rte_eth_devargs eth_da = { .nb_representor_ports = 0 };\n-\tstruct rte_eth_dev *backing_eth_dev, *vf_rep_eth_dev;\n-\tuint16_t num_rep;\n-\tint i, ret = 0;\n-\tstruct bnxt *backing_bp;\n+\trte_free(bp->rep_info);\n+\tbp->rep_info = NULL;\n+\trte_free(bp->cfa_code_map);\n+\tbp->cfa_code_map = NULL;\n+}\n \n-\tif (pci_dev->device.devargs) {\n-\t\tret = rte_eth_devargs_parse(pci_dev->device.devargs->args,\n-\t\t\t\t\t    &eth_da);\n-\t\tif (ret)\n-\t\t\treturn ret;\n-\t}\n+static int bnxt_init_rep_info(struct bnxt *bp)\n+{\n+\tint i = 0, rc;\n \n-\tnum_rep = eth_da.nb_representor_ports;\n-\tPMD_DRV_LOG(DEBUG, \"nb_representor_ports = %d\\n\",\n-\t\t    num_rep);\n+\tif (bp->rep_info)\n+\t\treturn 0;\n \n-\t/* We could come here after first level of probe is already invoked\n-\t * as part of an application bringup(OVS-DPDK vswitchd), so first check\n-\t * for already allocated eth_dev for the backing device (PF/Trusted VF)\n-\t */\n-\tbacking_eth_dev = rte_eth_dev_allocated(pci_dev->device.name);\n-\tif (backing_eth_dev == NULL) {\n-\t\tret = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name,\n-\t\t\t\t\t sizeof(struct bnxt),\n-\t\t\t\t\t eth_dev_pci_specific_init, pci_dev,\n-\t\t\t\t\t bnxt_dev_init, NULL);\n+\tbp->rep_info = rte_zmalloc(\"bnxt_rep_info\",\n+\t\t\t\t   sizeof(bp->rep_info[0]) * BNXT_MAX_VF_REPS,\n+\t\t\t\t   0);\n+\tif (!bp->rep_info) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to alloc memory for rep info\\n\");\n+\t\treturn -ENOMEM;\n+\t}\n+\tbp->cfa_code_map = rte_zmalloc(\"bnxt_cfa_code_map\",\n+\t\t\t\t       sizeof(*bp->cfa_code_map) *\n+\t\t\t\t       BNXT_MAX_CFA_CODE, 0);\n+\tif (!bp->cfa_code_map) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to alloc memory for cfa_code_map\\n\");\n+\t\tbnxt_free_rep_info(bp);\n+\t\treturn -ENOMEM;\n+\t}\n \n-\t\tif (ret || !num_rep)\n-\t\t\treturn ret;\n+\tfor (i = 0; i < BNXT_MAX_CFA_CODE; i++)\n+\t\tbp->cfa_code_map[i] = BNXT_VF_IDX_INVALID;\n+\n+\trc = pthread_mutex_init(&bp->rep_info->vfr_lock, NULL);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Unable to initialize vfr_lock\\n\");\n+\t\tbnxt_free_rep_info(bp);\n+\t\treturn rc;\n \t}\n+\treturn rc;\n+}\n+\n+static int bnxt_rep_port_probe(struct rte_pci_device *pci_dev,\n+\t\t\t       struct rte_eth_devargs eth_da,\n+\t\t\t       struct rte_eth_dev *backing_eth_dev)\n+{\n+\tstruct rte_eth_dev *vf_rep_eth_dev;\n+\tchar name[RTE_ETH_NAME_MAX_LEN];\n+\tstruct bnxt *backing_bp;\n+\tuint16_t num_rep;\n+\tint i, ret = 0;\n \n+\tnum_rep = eth_da.nb_representor_ports;\n \tif (num_rep > BNXT_MAX_VF_REPS) {\n \t\tPMD_DRV_LOG(ERR, \"nb_representor_ports = %d > %d MAX VF REPS\\n\",\n-\t\t\t    eth_da.nb_representor_ports, BNXT_MAX_VF_REPS);\n-\t\tret = -EINVAL;\n-\t\treturn ret;\n+\t\t\t    num_rep, BNXT_MAX_VF_REPS);\n+\t\treturn -EINVAL;\n \t}\n \n-\t/* probe representor ports now */\n-\tif (!backing_eth_dev)\n-\t\tbacking_eth_dev = rte_eth_dev_allocated(pci_dev->device.name);\n-\tif (backing_eth_dev == NULL) {\n-\t\tret = -ENODEV;\n-\t\treturn ret;\n+\tif (num_rep > RTE_MAX_ETHPORTS) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"nb_representor_ports = %d > %d MAX ETHPORTS\\n\",\n+\t\t\t    num_rep, RTE_MAX_ETHPORTS);\n+\t\treturn -EINVAL;\n \t}\n+\n \tbacking_bp = backing_eth_dev->data->dev_private;\n \n \tif (!(BNXT_PF(backing_bp) || BNXT_VF_IS_TRUSTED(backing_bp))) {\n@@ -5760,14 +5781,17 @@ static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n \t\t/* Returning an error is not an option.\n \t\t * Applications are not handling this correctly\n \t\t */\n-\t\treturn ret;\n+\t\treturn 0;\n \t}\n \n-\tfor (i = 0; i < eth_da.nb_representor_ports; i++) {\n+\tif (bnxt_init_rep_info(backing_bp))\n+\t\treturn 0;\n+\n+\tfor (i = 0; i < num_rep; i++) {\n \t\tstruct bnxt_vf_representor representor = {\n \t\t\t.vf_id = eth_da.representor_ports[i],\n \t\t\t.switch_domain_id = backing_bp->switch_domain_id,\n-\t\t\t.parent_priv = backing_bp\n+\t\t\t.parent_dev = backing_eth_dev\n \t\t};\n \n \t\tif (representor.vf_id >= BNXT_MAX_VF_REPS) {\n@@ -5808,6 +5832,48 @@ static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n \treturn ret;\n }\n \n+static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n+\t\t\t  struct rte_pci_device *pci_dev)\n+{\n+\tstruct rte_eth_devargs eth_da = { .nb_representor_ports = 0 };\n+\tstruct rte_eth_dev *backing_eth_dev;\n+\tuint16_t num_rep;\n+\tint ret = 0;\n+\n+\tif (pci_dev->device.devargs) {\n+\t\tret = rte_eth_devargs_parse(pci_dev->device.devargs->args,\n+\t\t\t\t\t    &eth_da);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\tnum_rep = eth_da.nb_representor_ports;\n+\tPMD_DRV_LOG(DEBUG, \"nb_representor_ports = %d\\n\",\n+\t\t    num_rep);\n+\n+\t/* We could come here after first level of probe is already invoked\n+\t * as part of an application bringup(OVS-DPDK vswitchd), so first check\n+\t * for already allocated eth_dev for the backing device (PF/Trusted VF)\n+\t */\n+\tbacking_eth_dev = rte_eth_dev_allocated(pci_dev->device.name);\n+\tif (backing_eth_dev == NULL) {\n+\t\tret = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name,\n+\t\t\t\t\t sizeof(struct bnxt),\n+\t\t\t\t\t eth_dev_pci_specific_init, pci_dev,\n+\t\t\t\t\t bnxt_dev_init, NULL);\n+\n+\t\tif (ret || !num_rep)\n+\t\t\treturn ret;\n+\n+\t\tbacking_eth_dev = rte_eth_dev_allocated(pci_dev->device.name);\n+\t}\n+\n+\t/* probe representor ports now */\n+\tret = bnxt_rep_port_probe(pci_dev, eth_da, backing_eth_dev);\n+\n+\treturn ret;\n+}\n+\n static int bnxt_pci_remove(struct rte_pci_device *pci_dev)\n {\n \tstruct rte_eth_dev *eth_dev;\ndiff --git a/drivers/net/bnxt/bnxt_reps.c b/drivers/net/bnxt/bnxt_reps.c\nindex 21f1b0765..777179558 100644\n--- a/drivers/net/bnxt/bnxt_reps.c\n+++ b/drivers/net/bnxt/bnxt_reps.c\n@@ -6,6 +6,11 @@\n #include \"bnxt.h\"\n #include \"bnxt_ring.h\"\n #include \"bnxt_reps.h\"\n+#include \"bnxt_rxq.h\"\n+#include \"bnxt_rxr.h\"\n+#include \"bnxt_txq.h\"\n+#include \"bnxt_txr.h\"\n+#include \"bnxt_hwrm.h\"\n #include \"hsi_struct_def_dpdk.h\"\n \n static const struct eth_dev_ops bnxt_vf_rep_dev_ops = {\n@@ -13,25 +18,128 @@ static const struct eth_dev_ops bnxt_vf_rep_dev_ops = {\n \t.dev_configure = bnxt_vf_rep_dev_configure_op,\n \t.dev_start = bnxt_vf_rep_dev_start_op,\n \t.rx_queue_setup = bnxt_vf_rep_rx_queue_setup_op,\n+\t.rx_queue_release = bnxt_vf_rep_rx_queue_release_op,\n \t.tx_queue_setup = bnxt_vf_rep_tx_queue_setup_op,\n+\t.tx_queue_release = bnxt_vf_rep_tx_queue_release_op,\n \t.link_update = bnxt_vf_rep_link_update_op,\n \t.dev_close = bnxt_vf_rep_dev_close_op,\n-\t.dev_stop = bnxt_vf_rep_dev_stop_op\n+\t.dev_stop = bnxt_vf_rep_dev_stop_op,\n+\t.stats_get = bnxt_vf_rep_stats_get_op,\n+\t.stats_reset = bnxt_vf_rep_stats_reset_op,\n };\n \n-static uint16_t\n-bnxt_vf_rep_rx_burst(__rte_unused void *rx_queue,\n-\t\t     __rte_unused struct rte_mbuf **rx_pkts,\n-\t\t     __rte_unused uint16_t nb_pkts)\n+uint16_t\n+bnxt_vfr_recv(struct bnxt *bp, uint16_t cfa_code, uint16_t queue_id,\n+\t      struct rte_mbuf *mbuf)\n {\n+\tstruct bnxt_sw_rx_bd *prod_rx_buf;\n+\tstruct bnxt_rx_ring_info *rep_rxr;\n+\tstruct bnxt_rx_queue *rep_rxq;\n+\tstruct rte_eth_dev *vfr_eth_dev;\n+\tstruct bnxt_vf_representor *vfr_bp;\n+\tuint16_t vf_id;\n+\tuint16_t mask;\n+\tuint8_t que;\n+\n+\tvf_id = bp->cfa_code_map[cfa_code];\n+\t/* cfa_code is invalid OR vf_id > MAX REP. Assume normal Rx */\n+\tif (vf_id == BNXT_VF_IDX_INVALID || vf_id > BNXT_MAX_VF_REPS)\n+\t\treturn 1;\n+\tvfr_eth_dev = bp->rep_info[vf_id].vfr_eth_dev;\n+\tif (!vfr_eth_dev)\n+\t\treturn 1;\n+\tvfr_bp = vfr_eth_dev->data->dev_private;\n+\tif (vfr_bp->rx_cfa_code != cfa_code) {\n+\t\t/* cfa_code not meant for this VF rep!!?? */\n+\t\treturn 1;\n+\t}\n+\t/* If rxq_id happens to be > max rep_queue, use rxq0 */\n+\tque = queue_id < BNXT_MAX_VF_REP_RINGS ? queue_id : 0;\n+\trep_rxq = vfr_bp->rx_queues[que];\n+\trep_rxr = rep_rxq->rx_ring;\n+\tmask = rep_rxr->rx_ring_struct->ring_mask;\n+\n+\t/* Put this mbuf on the RxQ of the Representor */\n+\tprod_rx_buf =\n+\t\t&rep_rxr->rx_buf_ring[rep_rxr->rx_prod++ & mask];\n+\tif (!prod_rx_buf->mbuf) {\n+\t\tprod_rx_buf->mbuf = mbuf;\n+\t\tvfr_bp->rx_bytes[que] += mbuf->pkt_len;\n+\t\tvfr_bp->rx_pkts[que]++;\n+\t} else {\n+\t\tvfr_bp->rx_drop_bytes[que] += mbuf->pkt_len;\n+\t\tvfr_bp->rx_drop_pkts[que]++;\n+\t\trte_free(mbuf); /* Representor Rx ring full, drop pkt */\n+\t}\n+\n \treturn 0;\n }\n \n static uint16_t\n-bnxt_vf_rep_tx_burst(__rte_unused void *tx_queue,\n-\t\t     __rte_unused struct rte_mbuf **tx_pkts,\n+bnxt_vf_rep_rx_burst(void *rx_queue,\n+\t\t     struct rte_mbuf **rx_pkts,\n+\t\t     uint16_t nb_pkts)\n+{\n+\tstruct bnxt_rx_queue *rxq = rx_queue;\n+\tstruct bnxt_sw_rx_bd *cons_rx_buf;\n+\tstruct bnxt_rx_ring_info *rxr;\n+\tuint16_t nb_rx_pkts = 0;\n+\tuint16_t mask, i;\n+\n+\tif (!rxq)\n+\t\treturn 0;\n+\n+\trxr = rxq->rx_ring;\n+\tmask = rxr->rx_ring_struct->ring_mask;\n+\tfor (i = 0; i < nb_pkts; i++) {\n+\t\tcons_rx_buf = &rxr->rx_buf_ring[rxr->rx_cons & mask];\n+\t\tif (!cons_rx_buf->mbuf)\n+\t\t\treturn nb_rx_pkts;\n+\t\trx_pkts[nb_rx_pkts] = cons_rx_buf->mbuf;\n+\t\trx_pkts[nb_rx_pkts]->port = rxq->port_id;\n+\t\tcons_rx_buf->mbuf = NULL;\n+\t\tnb_rx_pkts++;\n+\t\trxr->rx_cons++;\n+\t}\n+\n+\treturn nb_rx_pkts;\n+}\n+\n+static uint16_t\n+bnxt_vf_rep_tx_burst(void *tx_queue,\n+\t\t     struct rte_mbuf **tx_pkts,\n \t\t     __rte_unused uint16_t nb_pkts)\n {\n+\tstruct bnxt_vf_rep_tx_queue *vfr_txq = tx_queue;\n+\tstruct bnxt_tx_queue *ptxq;\n+\tstruct bnxt *parent;\n+\tstruct  bnxt_vf_representor *vf_rep_bp;\n+\tint qid;\n+\tint rc;\n+\tint i;\n+\n+\tif (!vfr_txq)\n+\t\treturn 0;\n+\n+\tqid = vfr_txq->txq->queue_id;\n+\tvf_rep_bp = vfr_txq->bp;\n+\tparent = vf_rep_bp->parent_dev->data->dev_private;\n+\tpthread_mutex_lock(&parent->rep_info->vfr_lock);\n+\tptxq = parent->tx_queues[qid];\n+\n+\tptxq->tx_cfa_action = vf_rep_bp->tx_cfa_action;\n+\n+\tfor (i = 0; i < nb_pkts; i++) {\n+\t\tvf_rep_bp->tx_bytes[qid] += tx_pkts[i]->pkt_len;\n+\t\tvf_rep_bp->tx_pkts[qid]++;\n+\t}\n+\n+\trc = bnxt_xmit_pkts(ptxq, tx_pkts, nb_pkts);\n+\tptxq->tx_cfa_action = 0;\n+\tpthread_mutex_unlock(&parent->rep_info->vfr_lock);\n+\n+\treturn rc;\n+\n \treturn 0;\n }\n \n@@ -45,7 +153,7 @@ int bnxt_vf_representor_init(struct rte_eth_dev *eth_dev, void *params)\n \n \tvf_rep_bp->vf_id = rep_params->vf_id;\n \tvf_rep_bp->switch_domain_id = rep_params->switch_domain_id;\n-\tvf_rep_bp->parent_priv = rep_params->parent_priv;\n+\tvf_rep_bp->parent_dev = rep_params->parent_dev;\n \n \teth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;\n \teth_dev->data->representor_id = rep_params->vf_id;\n@@ -63,7 +171,7 @@ int bnxt_vf_representor_init(struct rte_eth_dev *eth_dev, void *params)\n \teth_dev->rx_pkt_burst = bnxt_vf_rep_rx_burst;\n \teth_dev->tx_pkt_burst = bnxt_vf_rep_tx_burst;\n \t/* Link state. Inherited from PF or trusted VF */\n-\tparent_bp = vf_rep_bp->parent_priv;\n+\tparent_bp = vf_rep_bp->parent_dev->data->dev_private;\n \tlink = &parent_bp->eth_dev->data->dev_link;\n \n \teth_dev->data->dev_link.link_speed = link->link_speed;\n@@ -94,18 +202,18 @@ int bnxt_vf_representor_uninit(struct rte_eth_dev *eth_dev)\n \tuint16_t vf_id;\n \n \teth_dev->data->mac_addrs = NULL;\n-\n-\tparent_bp = rep->parent_priv;\n-\tif (parent_bp) {\n-\t\tparent_bp->num_reps--;\n-\t\tvf_id = rep->vf_id;\n-\t\tif (parent_bp->rep_info) {\n-\t\t\tmemset(&parent_bp->rep_info[vf_id], 0,\n-\t\t\t       sizeof(parent_bp->rep_info[vf_id]));\n-\t\t\t/* mark that this representor has been freed */\n-\t\t}\n-\t}\n \teth_dev->dev_ops = NULL;\n+\n+\tparent_bp = rep->parent_dev->data->dev_private;\n+\tif (!parent_bp)\n+\t\treturn 0;\n+\n+\tparent_bp->num_reps--;\n+\tvf_id = rep->vf_id;\n+\tif (parent_bp->rep_info)\n+\t\tmemset(&parent_bp->rep_info[vf_id], 0,\n+\t\t       sizeof(parent_bp->rep_info[vf_id]));\n+\t\t/* mark that this representor has been freed */\n \treturn 0;\n }\n \n@@ -117,7 +225,7 @@ int bnxt_vf_rep_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_compl)\n \tstruct rte_eth_link *link;\n \tint rc;\n \n-\tparent_bp = rep->parent_priv;\n+\tparent_bp = rep->parent_dev->data->dev_private;\n \trc = bnxt_link_update_op(parent_bp->eth_dev, wait_to_compl);\n \n \t/* Link state. Inherited from PF or trusted VF */\n@@ -132,16 +240,134 @@ int bnxt_vf_rep_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_compl)\n \treturn rc;\n }\n \n+static int bnxt_vfr_alloc(struct bnxt_vf_representor *vfr)\n+{\n+\tint rc = 0;\n+\tstruct bnxt *parent_bp;\n+\n+\tif (!vfr || !vfr->parent_dev) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"No memory allocated for representor\\n\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tparent_bp = vfr->parent_dev->data->dev_private;\n+\n+\t/* Check if representor has been already allocated in FW */\n+\tif (vfr->tx_cfa_action && vfr->rx_cfa_code)\n+\t\treturn 0;\n+\n+\t/*\n+\t * Alloc VF rep rules in CFA after default VNIC is created.\n+\t * Otherwise the FW will create the VF-rep rules with\n+\t * default drop action.\n+\t */\n+\n+\t/*\n+\t * This is where we need to replace invoking an HWRM cmd\n+\t * with the new TFLIB ULP API to do more/less the same job\n+\trc = bnxt_hwrm_cfa_vfr_alloc(parent_bp,\n+\t\t\t\t     vfr->vf_id,\n+\t\t\t\t     &vfr->tx_cfa_action,\n+\t\t\t\t     &vfr->rx_cfa_code);\n+\t */\n+\tif (!rc) {\n+\t\tparent_bp->cfa_code_map[vfr->rx_cfa_code] = vfr->vf_id;\n+\t\tPMD_DRV_LOG(DEBUG, \"allocated representor %d in FW\\n\",\n+\t\t\t    vfr->vf_id);\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"Failed to alloc representor %d in FW\\n\",\n+\t\t\t    vfr->vf_id);\n+\t}\n+\n+\treturn rc;\n+}\n+\n+static void bnxt_vf_rep_free_rx_mbufs(struct bnxt_vf_representor *rep_bp)\n+{\n+\tstruct bnxt_rx_queue *rxq;\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < rep_bp->rx_nr_rings; i++) {\n+\t\trxq = rep_bp->rx_queues[i];\n+\t\tbnxt_rx_queue_release_mbufs(rxq);\n+\t}\n+}\n+\n int bnxt_vf_rep_dev_start_op(struct rte_eth_dev *eth_dev)\n {\n-\tbnxt_vf_rep_link_update_op(eth_dev, 1);\n+\tstruct bnxt_vf_representor *rep_bp = eth_dev->data->dev_private;\n+\tint rc;\n \n-\treturn 0;\n+\trc = bnxt_vfr_alloc(rep_bp);\n+\n+\tif (!rc) {\n+\t\teth_dev->rx_pkt_burst = &bnxt_vf_rep_rx_burst;\n+\t\teth_dev->tx_pkt_burst = &bnxt_vf_rep_tx_burst;\n+\n+\t\tbnxt_vf_rep_link_update_op(eth_dev, 1);\n+\t} else {\n+\t\teth_dev->data->dev_link.link_status = 0;\n+\t\tbnxt_vf_rep_free_rx_mbufs(rep_bp);\n+\t}\n+\n+\treturn rc;\n+}\n+\n+static int bnxt_vfr_free(struct bnxt_vf_representor *vfr)\n+{\n+\tint rc = 0;\n+\tstruct bnxt *parent_bp;\n+\n+\tif (!vfr || !vfr->parent_dev) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"No memory allocated for representor\\n\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tparent_bp = vfr->parent_dev->data->dev_private;\n+\n+\t/* Check if representor has been already freed in FW */\n+\tif (!vfr->tx_cfa_action && !vfr->rx_cfa_code)\n+\t\treturn 0;\n+\n+\t/*\n+\t * This is where we need to replace invoking an HWRM cmd\n+\t * with the new TFLIB ULP API to do more/less the same job\n+\trc = bnxt_hwrm_cfa_vfr_free(parent_bp,\n+\t\t\t\t    vfr->vf_id);\n+\t */\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"Failed to free representor %d in FW\\n\",\n+\t\t\t    vfr->vf_id);\n+\t\treturn rc;\n+\t}\n+\n+\tparent_bp->cfa_code_map[vfr->rx_cfa_code] = BNXT_VF_IDX_INVALID;\n+\tPMD_DRV_LOG(DEBUG, \"freed representor %d in FW\\n\",\n+\t\t    vfr->vf_id);\n+\tvfr->tx_cfa_action = 0;\n+\tvfr->rx_cfa_code = 0;\n+\n+\treturn rc;\n }\n \n void bnxt_vf_rep_dev_stop_op(struct rte_eth_dev *eth_dev)\n {\n-\teth_dev = eth_dev;\n+\tstruct bnxt_vf_representor *vfr_bp = eth_dev->data->dev_private;\n+\n+\t/* Avoid crashes as we are about to free queues */\n+\teth_dev->rx_pkt_burst = &bnxt_dummy_recv_pkts;\n+\teth_dev->tx_pkt_burst = &bnxt_dummy_xmit_pkts;\n+\n+\tbnxt_vfr_free(vfr_bp);\n+\n+\tif (eth_dev->data->dev_started)\n+\t\teth_dev->data->dev_link.link_status = 0;\n+\n+\tbnxt_vf_rep_free_rx_mbufs(vfr_bp);\n }\n \n void bnxt_vf_rep_dev_close_op(struct rte_eth_dev *eth_dev)\n@@ -159,7 +385,7 @@ int bnxt_vf_rep_dev_info_get_op(struct rte_eth_dev *eth_dev,\n \tint rc = 0;\n \n \t/* MAC Specifics */\n-\tparent_bp = rep_bp->parent_priv;\n+\tparent_bp = rep_bp->parent_dev->data->dev_private;\n \tif (!parent_bp) {\n \t\tPMD_DRV_LOG(ERR, \"Rep parent NULL!\\n\");\n \t\treturn rc;\n@@ -257,7 +483,13 @@ int bnxt_vf_rep_dev_info_get_op(struct rte_eth_dev *eth_dev,\n \n int bnxt_vf_rep_dev_configure_op(__rte_unused struct rte_eth_dev *eth_dev)\n {\n+\tstruct bnxt_vf_representor *rep_bp = eth_dev->data->dev_private;\n+\n \tPMD_DRV_LOG(DEBUG, \"Representor dev_configure_op\\n\");\n+\trep_bp->rx_queues = (void *)eth_dev->data->rx_queues;\n+\trep_bp->tx_nr_rings = eth_dev->data->nb_tx_queues;\n+\trep_bp->rx_nr_rings = eth_dev->data->nb_rx_queues;\n+\n \treturn 0;\n }\n \n@@ -269,9 +501,94 @@ int bnxt_vf_rep_rx_queue_setup_op(struct rte_eth_dev *eth_dev,\n \t\t\t\t  rx_conf,\n \t\t\t\t  __rte_unused struct rte_mempool *mp)\n {\n-\teth_dev = eth_dev;\n+\tstruct bnxt_vf_representor *rep_bp = eth_dev->data->dev_private;\n+\tstruct bnxt *parent_bp = rep_bp->parent_dev->data->dev_private;\n+\tstruct bnxt_rx_queue *parent_rxq;\n+\tstruct bnxt_rx_queue *rxq;\n+\tstruct bnxt_sw_rx_bd *buf_ring;\n+\tint rc = 0;\n+\n+\tif (queue_idx >= BNXT_MAX_VF_REP_RINGS) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"Cannot create Rx ring %d. %d rings available\\n\",\n+\t\t\t    queue_idx, BNXT_MAX_VF_REP_RINGS);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!nb_desc || nb_desc > MAX_RX_DESC_CNT) {\n+\t\tPMD_DRV_LOG(ERR, \"nb_desc %d is invalid\\n\", nb_desc);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tparent_rxq = parent_bp->rx_queues[queue_idx];\n+\tif (!parent_rxq) {\n+\t\tPMD_DRV_LOG(ERR, \"Parent RxQ has not been configured yet\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (nb_desc != parent_rxq->nb_rx_desc) {\n+\t\tPMD_DRV_LOG(ERR, \"nb_desc %d do not match parent rxq\", nb_desc);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (eth_dev->data->rx_queues) {\n+\t\trxq = eth_dev->data->rx_queues[queue_idx];\n+\t\tif (rxq)\n+\t\t\tbnxt_rx_queue_release_op(rxq);\n+\t}\n+\n+\trxq = rte_zmalloc_socket(\"bnxt_vfr_rx_queue\",\n+\t\t\t\t sizeof(struct bnxt_rx_queue),\n+\t\t\t\t RTE_CACHE_LINE_SIZE, socket_id);\n+\tif (!rxq) {\n+\t\tPMD_DRV_LOG(ERR, \"bnxt_vfr_rx_queue allocation failed!\\n\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\trxq->nb_rx_desc = nb_desc;\n+\n+\trc = bnxt_init_rx_ring_struct(rxq, socket_id);\n+\tif (rc)\n+\t\tgoto out;\n+\n+\tbuf_ring = rte_zmalloc_socket(\"bnxt_rx_vfr_buf_ring\",\n+\t\t\t\t      sizeof(struct bnxt_sw_rx_bd) *\n+\t\t\t\t      rxq->rx_ring->rx_ring_struct->ring_size,\n+\t\t\t\t      RTE_CACHE_LINE_SIZE, socket_id);\n+\tif (!buf_ring) {\n+\t\tPMD_DRV_LOG(ERR, \"bnxt_rx_vfr_buf_ring allocation failed!\\n\");\n+\t\trc = -ENOMEM;\n+\t\tgoto out;\n+\t}\n+\n+\trxq->rx_ring->rx_buf_ring = buf_ring;\n+\trxq->queue_id = queue_idx;\n+\trxq->port_id = eth_dev->data->port_id;\n+\teth_dev->data->rx_queues[queue_idx] = rxq;\n \n \treturn 0;\n+\n+out:\n+\tif (rxq)\n+\t\tbnxt_rx_queue_release_op(rxq);\n+\n+\treturn rc;\n+}\n+\n+void bnxt_vf_rep_rx_queue_release_op(void *rx_queue)\n+{\n+\tstruct bnxt_rx_queue *rxq = (struct bnxt_rx_queue *)rx_queue;\n+\n+\tif (!rxq)\n+\t\treturn;\n+\n+\tbnxt_rx_queue_release_mbufs(rxq);\n+\n+\tbnxt_free_ring(rxq->rx_ring->rx_ring_struct);\n+\tbnxt_free_ring(rxq->rx_ring->ag_ring_struct);\n+\tbnxt_free_ring(rxq->cp_ring->cp_ring_struct);\n+\n+\trte_free(rxq);\n }\n \n int bnxt_vf_rep_tx_queue_setup_op(struct rte_eth_dev *eth_dev,\n@@ -281,7 +598,112 @@ int bnxt_vf_rep_tx_queue_setup_op(struct rte_eth_dev *eth_dev,\n \t\t\t\t  __rte_unused const struct rte_eth_txconf *\n \t\t\t\t  tx_conf)\n {\n-\teth_dev = eth_dev;\n+\tstruct bnxt_vf_representor *rep_bp = eth_dev->data->dev_private;\n+\tstruct bnxt *parent_bp = rep_bp->parent_dev->data->dev_private;\n+\tstruct bnxt_tx_queue *parent_txq, *txq;\n+\tstruct bnxt_vf_rep_tx_queue *vfr_txq;\n+\n+\tif (queue_idx >= BNXT_MAX_VF_REP_RINGS) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"Cannot create Tx rings %d. %d rings available\\n\",\n+\t\t\t    queue_idx, BNXT_MAX_VF_REP_RINGS);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!nb_desc || nb_desc > MAX_TX_DESC_CNT) {\n+\t\tPMD_DRV_LOG(ERR, \"nb_desc %d is invalid\", nb_desc);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tparent_txq = parent_bp->tx_queues[queue_idx];\n+\tif (!parent_txq) {\n+\t\tPMD_DRV_LOG(ERR, \"Parent TxQ has not been configured yet\\n\");\n+\t\treturn -EINVAL;\n+\t}\n \n+\tif (nb_desc != parent_txq->nb_tx_desc) {\n+\t\tPMD_DRV_LOG(ERR, \"nb_desc %d do not match parent txq\", nb_desc);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (eth_dev->data->tx_queues) {\n+\t\tvfr_txq = eth_dev->data->tx_queues[queue_idx];\n+\t\tbnxt_vf_rep_tx_queue_release_op(vfr_txq);\n+\t\tvfr_txq = NULL;\n+\t}\n+\n+\tvfr_txq = rte_zmalloc_socket(\"bnxt_vfr_tx_queue\",\n+\t\t\t\t     sizeof(struct bnxt_vf_rep_tx_queue),\n+\t\t\t\t     RTE_CACHE_LINE_SIZE, socket_id);\n+\tif (!vfr_txq) {\n+\t\tPMD_DRV_LOG(ERR, \"bnxt_vfr_tx_queue allocation failed!\");\n+\t\treturn -ENOMEM;\n+\t}\n+\ttxq = rte_zmalloc_socket(\"bnxt_tx_queue\",\n+\t\t\t\t sizeof(struct bnxt_tx_queue),\n+\t\t\t\t RTE_CACHE_LINE_SIZE, socket_id);\n+\tif (!txq) {\n+\t\tPMD_DRV_LOG(ERR, \"bnxt_tx_queue allocation failed!\");\n+\t\trte_free(vfr_txq);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\ttxq->nb_tx_desc = nb_desc;\n+\ttxq->queue_id = queue_idx;\n+\ttxq->port_id = eth_dev->data->port_id;\n+\tvfr_txq->txq = txq;\n+\tvfr_txq->bp = rep_bp;\n+\teth_dev->data->tx_queues[queue_idx] = vfr_txq;\n+\n+\treturn 0;\n+}\n+\n+void bnxt_vf_rep_tx_queue_release_op(void *tx_queue)\n+{\n+\tstruct bnxt_vf_rep_tx_queue *vfr_txq = tx_queue;\n+\n+\tif (!vfr_txq)\n+\t\treturn;\n+\n+\trte_free(vfr_txq->txq);\n+\trte_free(vfr_txq);\n+}\n+\n+int bnxt_vf_rep_stats_get_op(struct rte_eth_dev *eth_dev,\n+\t\t\t     struct rte_eth_stats *stats)\n+{\n+\tstruct bnxt_vf_representor *rep_bp = eth_dev->data->dev_private;\n+\tint i;\n+\n+\tmemset(stats, 0, sizeof(*stats));\n+\tfor (i = 0; i < BNXT_MAX_VF_REP_RINGS; i++) {\n+\t\tstats->obytes += rep_bp->tx_bytes[i];\n+\t\tstats->opackets += rep_bp->tx_pkts[i];\n+\t\tstats->ibytes += rep_bp->rx_bytes[i];\n+\t\tstats->ipackets += rep_bp->rx_pkts[i];\n+\t\tstats->imissed += rep_bp->rx_drop_pkts[i];\n+\n+\t\tstats->q_ipackets[i] = rep_bp->rx_pkts[i];\n+\t\tstats->q_ibytes[i] = rep_bp->rx_bytes[i];\n+\t\tstats->q_opackets[i] = rep_bp->tx_pkts[i];\n+\t\tstats->q_obytes[i] = rep_bp->tx_bytes[i];\n+\t\tstats->q_errors[i] = rep_bp->rx_drop_pkts[i];\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int bnxt_vf_rep_stats_reset_op(struct rte_eth_dev *eth_dev)\n+{\n+\tstruct bnxt_vf_representor *rep_bp = eth_dev->data->dev_private;\n+\tint i;\n+\n+\tfor (i = 0; i < BNXT_MAX_VF_REP_RINGS; i++) {\n+\t\trep_bp->tx_pkts[i] = 0;\n+\t\trep_bp->tx_bytes[i] = 0;\n+\t\trep_bp->rx_pkts[i] = 0;\n+\t\trep_bp->rx_bytes[i] = 0;\n+\t\trep_bp->rx_drop_pkts[i] = 0;\n+\t}\n \treturn 0;\n }\ndiff --git a/drivers/net/bnxt/bnxt_reps.h b/drivers/net/bnxt/bnxt_reps.h\nindex 6048faf08..5c2e0a0b9 100644\n--- a/drivers/net/bnxt/bnxt_reps.h\n+++ b/drivers/net/bnxt/bnxt_reps.h\n@@ -9,6 +9,12 @@\n #include <rte_malloc.h>\n #include <rte_ethdev.h>\n \n+#define BNXT_MAX_CFA_CODE               65536\n+#define BNXT_VF_IDX_INVALID             0xffff\n+\n+uint16_t\n+bnxt_vfr_recv(struct bnxt *bp, uint16_t cfa_code, uint16_t queue_id,\n+\t      struct rte_mbuf *mbuf);\n int bnxt_vf_representor_init(struct rte_eth_dev *eth_dev, void *params);\n int bnxt_vf_representor_uninit(struct rte_eth_dev *eth_dev);\n int bnxt_vf_rep_dev_info_get_op(struct rte_eth_dev *eth_dev,\n@@ -30,6 +36,11 @@ int bnxt_vf_rep_tx_queue_setup_op(struct rte_eth_dev *eth_dev,\n \t\t\t\t  __rte_unused unsigned int socket_id,\n \t\t\t\t  __rte_unused const struct rte_eth_txconf *\n \t\t\t\t  tx_conf);\n+void bnxt_vf_rep_rx_queue_release_op(void *rx_queue);\n+void bnxt_vf_rep_tx_queue_release_op(void *tx_queue);\n void bnxt_vf_rep_dev_stop_op(struct rte_eth_dev *eth_dev);\n void bnxt_vf_rep_dev_close_op(struct rte_eth_dev *eth_dev);\n+int bnxt_vf_rep_stats_get_op(struct rte_eth_dev *eth_dev,\n+\t\t\t     struct rte_eth_stats *stats);\n+int bnxt_vf_rep_stats_reset_op(struct rte_eth_dev *eth_dev);\n #endif /* _BNXT_REPS_H_ */\ndiff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c\nindex 11807f409..37b534fc2 100644\n--- a/drivers/net/bnxt/bnxt_rxr.c\n+++ b/drivers/net/bnxt/bnxt_rxr.c\n@@ -12,6 +12,7 @@\n #include <rte_memory.h>\n \n #include \"bnxt.h\"\n+#include \"bnxt_reps.h\"\n #include \"bnxt_ring.h\"\n #include \"bnxt_rxr.h\"\n #include \"bnxt_rxq.h\"\n@@ -539,7 +540,7 @@ void bnxt_set_mark_in_mbuf(struct bnxt *bp,\n }\n \n static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,\n-\t\t\t    struct bnxt_rx_queue *rxq, uint32_t *raw_cons)\n+\t\t       struct bnxt_rx_queue *rxq, uint32_t *raw_cons)\n {\n \tstruct bnxt_cp_ring_info *cpr = rxq->cp_ring;\n \tstruct bnxt_rx_ring_info *rxr = rxq->rx_ring;\n@@ -735,6 +736,20 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,\n rx:\n \t*rx_pkt = mbuf;\n \n+\tif ((BNXT_VF_IS_TRUSTED(rxq->bp) || BNXT_PF(rxq->bp)) &&\n+\t    rxq->bp->cfa_code_map && rxcmp1->cfa_code) {\n+\t\tif (!bnxt_vfr_recv(rxq->bp, rxcmp1->cfa_code, rxq->queue_id,\n+\t\t\t\t   mbuf)) {\n+\t\t\t/* Now return an error so that nb_rx_pkts is not\n+\t\t\t * incremented.\n+\t\t\t * This packet was meant to be given to the representor.\n+\t\t\t * So no need to account the packet and give it to\n+\t\t\t * parent Rx burst function.\n+\t\t\t */\n+\t\t\trc = -ENODEV;\n+\t\t}\n+\t}\n+\n next_rx:\n \n \t*raw_cons = tmp_raw_cons;\n@@ -751,6 +766,7 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,\n \tuint32_t raw_cons = cpr->cp_raw_cons;\n \tuint32_t cons;\n \tint nb_rx_pkts = 0;\n+\tint nb_rep_rx_pkts = 0;\n \tstruct rx_pkt_cmpl *rxcmp;\n \tuint16_t prod = rxr->rx_prod;\n \tuint16_t ag_prod = rxr->ag_prod;\n@@ -784,6 +800,8 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,\n \t\t\t\tnb_rx_pkts++;\n \t\t\tif (rc == -EBUSY)\t/* partial completion */\n \t\t\t\tbreak;\n+\t\t\tif (rc == -ENODEV)\t/* completion for representor */\n+\t\t\t\tnb_rep_rx_pkts++;\n \t\t} else if (!BNXT_NUM_ASYNC_CPR(rxq->bp)) {\n \t\t\tevt =\n \t\t\tbnxt_event_hwrm_resp_handler(rxq->bp,\n@@ -802,7 +820,7 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,\n \t}\n \n \tcpr->cp_raw_cons = raw_cons;\n-\tif (!nb_rx_pkts && !evt) {\n+\tif (!nb_rx_pkts && !nb_rep_rx_pkts && !evt) {\n \t\t/*\n \t\t * For PMD, there is no need to keep on pushing to REARM\n \t\t * the doorbell if there are no new completions\ndiff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h\nindex 811dcd86b..e60c97fa1 100644\n--- a/drivers/net/bnxt/bnxt_rxr.h\n+++ b/drivers/net/bnxt/bnxt_rxr.h\n@@ -188,6 +188,7 @@ struct bnxt_sw_rx_bd {\n struct bnxt_rx_ring_info {\n \tuint16_t\t\trx_prod;\n \tuint16_t\t\tag_prod;\n+\tuint16_t                rx_cons; /* Needed for representor */\n \tstruct bnxt_db_info     rx_db;\n \tstruct bnxt_db_info     ag_db;\n \ndiff --git a/drivers/net/bnxt/bnxt_txq.h b/drivers/net/bnxt/bnxt_txq.h\nindex 37a3f9539..69ff89aab 100644\n--- a/drivers/net/bnxt/bnxt_txq.h\n+++ b/drivers/net/bnxt/bnxt_txq.h\n@@ -29,6 +29,7 @@ struct bnxt_tx_queue {\n \tstruct bnxt\t\t*bp;\n \tint\t\t\tindex;\n \tint\t\t\ttx_wake_thresh;\n+\tuint32_t                tx_cfa_action;\n \tstruct bnxt_tx_ring_info\t*tx_ring;\n \n \tunsigned int\t\tcp_nr_rings;\ndiff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c\nindex 16021407e..d7e193d38 100644\n--- a/drivers/net/bnxt/bnxt_txr.c\n+++ b/drivers/net/bnxt/bnxt_txr.c\n@@ -131,7 +131,7 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,\n \t\t\t\tPKT_TX_VLAN_PKT | PKT_TX_OUTER_IP_CKSUM |\n \t\t\t\tPKT_TX_TUNNEL_GRE | PKT_TX_TUNNEL_VXLAN |\n \t\t\t\tPKT_TX_TUNNEL_GENEVE | PKT_TX_IEEE1588_TMST |\n-\t\t\t\tPKT_TX_QINQ_PKT))\n+\t\t\t\tPKT_TX_QINQ_PKT) || txq->tx_cfa_action)\n \t\tlong_bd = true;\n \n \tnr_bds = long_bd + tx_pkt->nb_segs;\n@@ -184,7 +184,7 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,\n \tif (long_bd) {\n \t\ttxbd->flags_type |= TX_BD_LONG_TYPE_TX_BD_LONG;\n \t\tvlan_tag_flags = 0;\n-\t\tcfa_action = 0;\n+\t\tcfa_action = txq->tx_cfa_action;\n \t\t/* HW can accelerate only outer vlan in QinQ mode */\n \t\tif (tx_buf->mbuf->ol_flags & PKT_TX_QINQ_PKT) {\n \t\t\tvlan_tag_flags = TX_BD_LONG_CFA_META_KEY_VLAN_TAG |\n",
    "prefixes": [
        "v5",
        "02/51"
    ]
}