get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 129064,
    "url": "http://patchwork.dpdk.org/api/patches/129064/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20230628162927.92858-7-ajit.khaparde@broadcom.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<20230628162927.92858-7-ajit.khaparde@broadcom.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230628162927.92858-7-ajit.khaparde@broadcom.com",
    "date": "2023-06-28T16:29:22",
    "name": "[v4,06/11] net/bnxt: add RSS and Queue action in TruFLow",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "bd3e945c8a0f9f2a64511c4a591ee1c3ff803ec9",
    "submitter": {
        "id": 501,
        "url": "http://patchwork.dpdk.org/api/people/501/?format=api",
        "name": "Ajit Khaparde",
        "email": "ajit.khaparde@broadcom.com"
    },
    "delegate": {
        "id": 1766,
        "url": "http://patchwork.dpdk.org/api/users/1766/?format=api",
        "username": "ajitkhaparde",
        "first_name": "Ajit",
        "last_name": "Khaparde",
        "email": "ajit.khaparde@broadcom.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20230628162927.92858-7-ajit.khaparde@broadcom.com/mbox/",
    "series": [
        {
            "id": 28693,
            "url": "http://patchwork.dpdk.org/api/series/28693/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=28693",
            "date": "2023-06-28T16:29:16",
            "name": "sync Truflow support with latest release",
            "version": 4,
            "mbox": "http://patchwork.dpdk.org/series/28693/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/129064/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/129064/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 mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 00B1142D82;\n\tWed, 28 Jun 2023 18:31:57 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id F047942D1D;\n\tWed, 28 Jun 2023 18:31:22 +0200 (CEST)",
            "from mail-pl1-f175.google.com (mail-pl1-f175.google.com\n [209.85.214.175])\n by mails.dpdk.org (Postfix) with ESMTP id 3546C42D1D\n for <dev@dpdk.org>; Wed, 28 Jun 2023 18:31:21 +0200 (CEST)",
            "by mail-pl1-f175.google.com with SMTP id\n d9443c01a7336-1b7ffab7ff1so889335ad.2\n for <dev@dpdk.org>; Wed, 28 Jun 2023 09:31:21 -0700 (PDT)",
            "from localhost.localdomain ([192.19.252.250])\n by smtp.gmail.com with ESMTPSA id\n h12-20020a170902f7cc00b001b8229942a0sm3092403plw.34.2023.06.28.09.31.12\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Wed, 28 Jun 2023 09:31:15 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=broadcom.com; s=google; t=1687969880; x=1690561880;\n h=mime-version:references:in-reply-to:message-id:date:subject:cc:to\n :from:from:to:cc:subject:date:message-id:reply-to;\n bh=y6//OmEj6sPH9L/tGeOKUquLuDPLgewPkmE73xm4Fio=;\n b=W3fJ+ksla4aUJoq53JiWC0LY/CDtpUiKi1tswF5r5HlmB+SUbXjlKdo+H6y8EPY1dU\n LTE/BCMYBQRG3MVpz/+EFC7cC1chA+JPXIGyU9fv8TR7w6kHcThzF+mYyo5NfnJoDwKs\n cSTZDZLoL3UR/xvO5GslHv1JglklhbWrI3Xwg=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20221208; t=1687969880; x=1690561880;\n h=mime-version:references:in-reply-to:message-id:date:subject:cc:to\n :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n bh=y6//OmEj6sPH9L/tGeOKUquLuDPLgewPkmE73xm4Fio=;\n b=lv2cphOcdNK6RF9gDRv19MObQdumiIvDtvc4lf0y1ki8FSUU+SeQtn0UsdvWRgDvOl\n dpK0LxcbYsspdO3bapIkL23yYcLFoEPobzesyBNR9JlXbr0IRKcTcrtwAD2IdeSLPXlv\n /Wij6uRNOtNZeQS1aIkQ6YS3uRe6siQ84XaJHK342hLzREEXW8LxI7jiveCHP/+wDeHl\n NjfmsKa0lh03basiZoLzLlsrrsXy//49lGPeGj1qxgLyNOqoLYUn9HWpRjTsrPl+YxfA\n d3IkEQTpznxorQ01p/fmAYrRw4cERiXYDtmqeKtApgn9gzkjjirSuEPmLjGXynFwIGui\n tdBA==",
        "X-Gm-Message-State": "AC+VfDzq0/G1ypZmqRHw51cvR8OnjFAvl3v+I6ibDig6+QdBJIAPUR0x\n 87hP7ikxYuh1YqyQLDVgmFl/XnvGnq2pCe/6jf8cDXJqvyzgBTpme/hxnxMv+NEGAbJPN7bg2te\n tDyJ4+I3JlhhdzGRweMnQ6vZUIganhLxbDVmHEzQVWZ8fXrTWmkXkZmIwg5iXM3zsFRjhWG8=",
        "X-Google-Smtp-Source": "\n ACHHUZ6TRu4f5gP4rSpd0zhOnPrOU0/dia9MLUvCXz1zrVJTKU4yN1VSaKTrUxGKHvhZB1019Q+CSQ==",
        "X-Received": "by 2002:a17:902:bb89:b0:1b5:67cd:4c9 with SMTP id\n m9-20020a170902bb8900b001b567cd04c9mr8583369pls.62.1687969877122;\n Wed, 28 Jun 2023 09:31:17 -0700 (PDT)",
        "From": "Ajit Khaparde <ajit.khaparde@broadcom.com>",
        "To": "dev@dpdk.org",
        "Cc": "ferruh.yigit@intel.com, thomas@monjalon.net,\n Randy Schacher <stuart.schacher@broadcom.com>,\n Kishore Padmanabha <kishore.padmanabha@broadcom.com>,\n Mike Baucom <michael.baucom@broadcom.com>,\n Shuanglin Wang <shuanglin.wang@broadcom.com>",
        "Subject": "[PATCH v4 06/11] net/bnxt: add RSS and Queue action in TruFLow",
        "Date": "Wed, 28 Jun 2023 09:29:22 -0700",
        "Message-Id": "<20230628162927.92858-7-ajit.khaparde@broadcom.com>",
        "X-Mailer": "git-send-email 2.39.2 (Apple Git-143)",
        "In-Reply-To": "<20230628162927.92858-1-ajit.khaparde@broadcom.com>",
        "References": "<1826961.atdPhlSkOF@thomas>\n <20230628162927.92858-1-ajit.khaparde@broadcom.com>",
        "MIME-Version": "1.0",
        "Content-Type": "multipart/signed; protocol=\"application/pkcs7-signature\";\n micalg=sha-256; boundary=\"0000000000001ba4b705ff331dd1\"",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "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"
    },
    "content": "From: Randy Schacher <stuart.schacher@broadcom.com>\n\n- Update ULP layer to support RSS/Queue action\n- Modify VNIC handling driver to support RSS action\n- Modify VNIC handling driver to support Queue action\nThis should allow to enable TruFlow path for all RTE_FLOW\nby default in future.\n\nSigned-off-by: Randy Schacher <stuart.schacher@broadcom.com>\nSigned-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>\nReviewed-by: Mike Baucom <michael.baucom@broadcom.com>\nReviewed-by: Shuanglin Wang <shuanglin.wang@broadcom.com>\nAcked-by: Ajit Khaparde <ajit.khaparde@broadcom.com>\n---\n doc/guides/nics/features/bnxt.ini             |   3 +\n drivers/net/bnxt/bnxt.h                       |  39 +-\n drivers/net/bnxt/bnxt_ethdev.c                | 154 +--\n drivers/net/bnxt/bnxt_filter.h                |   6 +-\n drivers/net/bnxt/bnxt_flow.c                  |  75 +-\n drivers/net/bnxt/bnxt_hwrm.c                  | 187 +++-\n drivers/net/bnxt/bnxt_hwrm.h                  |  30 +-\n drivers/net/bnxt/bnxt_ring.c                  |   4 +-\n drivers/net/bnxt/bnxt_rxq.c                   | 159 +--\n drivers/net/bnxt/bnxt_rxr.c                   |   9 +-\n drivers/net/bnxt/bnxt_txq.c                   |   2 +-\n drivers/net/bnxt/bnxt_txr.c                   |   2 +-\n drivers/net/bnxt/bnxt_txr.h                   |   2 +-\n drivers/net/bnxt/bnxt_vnic.c                  | 969 +++++++++++++++++-\n drivers/net/bnxt/bnxt_vnic.h                  |  80 +-\n drivers/net/bnxt/meson.build                  |   3 +-\n drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c    | 248 ++++-\n drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.h    |  35 +-\n drivers/net/bnxt/tf_ulp/bnxt_ulp.c            | 258 ++++-\n drivers/net/bnxt/tf_ulp/bnxt_ulp.h            |   1 +\n drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c       | 280 ++++-\n drivers/net/bnxt/tf_ulp/meson.build           |  25 +-\n drivers/net/bnxt/tf_ulp/ulp_fc_mgr.c          |  13 +-\n drivers/net/bnxt/tf_ulp/ulp_gen_tbl.c         |  37 +-\n drivers/net/bnxt/tf_ulp/ulp_gen_tbl.h         |   4 +-\n drivers/net/bnxt/tf_ulp/ulp_ha_mgr.c          | 121 ++-\n drivers/net/bnxt/tf_ulp/ulp_ha_mgr.h          |   5 +-\n drivers/net/bnxt/tf_ulp/ulp_mapper.c          | 449 +++++++-\n drivers/net/bnxt/tf_ulp/ulp_mapper.h          |   3 +-\n drivers/net/bnxt/tf_ulp/ulp_matcher.c         |  14 +-\n drivers/net/bnxt/tf_ulp/ulp_port_db.c         |  58 ++\n drivers/net/bnxt/tf_ulp/ulp_port_db.h         |  26 +\n drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c |  22 +-\n drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 338 +++++-\n drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  37 +-\n 35 files changed, 3281 insertions(+), 417 deletions(-)",
    "diff": "diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini\nindex 50a0b5bfa6..b225878a78 100644\n--- a/doc/guides/nics/features/bnxt.ini\n+++ b/doc/guides/nics/features/bnxt.ini\n@@ -84,11 +84,14 @@ of_set_vlan_vid      = Y\n pf                   = Y\n port_id              = Y\n port_representor     = Y\n+queue                = Y\n represented_port     = Y\n rss                  = Y\n sample               = Y\n set_ipv4_dst         = Y\n set_ipv4_src         = Y\n+set_mac_dst          = Y\n+set_mac_src          = Y\n set_tp_dst           = Y\n set_tp_src           = Y\n vf                   = Y\ndiff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h\nindex bb2e7fe003..6dd3c8b87c 100644\n--- a/drivers/net/bnxt/bnxt.h\n+++ b/drivers/net/bnxt/bnxt.h\n@@ -24,6 +24,7 @@\n #include \"tf_core.h\"\n #include \"bnxt_ulp.h\"\n #include \"bnxt_tf_common.h\"\n+#include \"bnxt_vnic.h\"\n \n /* Vendor ID */\n #define PCI_VENDOR_ID_BROADCOM\t\t0x14E4\n@@ -163,6 +164,8 @@\n #define BNXT_HWRM_CMD_TO_FORWARD(cmd)\t\\\n \t\t(bp->pf->vf_req_fwd[(cmd) / 32] |= (1 << ((cmd) % 32)))\n \n+#define BNXT_NTOHS              rte_be_to_cpu_16\n+\n struct bnxt_led_info {\n \tuint8_t\t     num_leds;\n \tuint8_t      led_id;\n@@ -238,11 +241,11 @@ struct bnxt_parent_info {\n struct bnxt_pf_info {\n #define BNXT_FIRST_PF_FID\t1\n #define BNXT_MAX_VFS(bp)\t((bp)->pf->max_vfs)\n-#define BNXT_MAX_VF_REPS_WH     64\n-#define BNXT_MAX_VF_REPS_TH     256\n+#define BNXT_MAX_VF_REPS_P4     64\n+#define BNXT_MAX_VF_REPS_P5     256\n #define BNXT_MAX_VF_REPS(bp) \\\n-\t\t\t\t(BNXT_CHIP_P5(bp) ? BNXT_MAX_VF_REPS_TH : \\\n-\t\t\t\tBNXT_MAX_VF_REPS_WH)\n+\t\t\t\t(BNXT_CHIP_P5(bp) ? BNXT_MAX_VF_REPS_P5 : \\\n+\t\t\t\tBNXT_MAX_VF_REPS_P4)\n #define BNXT_TOTAL_VFS(bp)\t((bp)->pf->total_vfs)\n #define BNXT_FIRST_VF_FID\t128\n #define BNXT_PF_RINGS_USED(bp)\tbnxt_get_num_queues(bp)\n@@ -366,7 +369,7 @@ struct bnxt_ptp_cfg {\n \tuint32_t\t\t\ttx_regs[BNXT_PTP_TX_REGS];\n \tuint32_t\t\t\ttx_mapped_regs[BNXT_PTP_TX_REGS];\n \n-\t/* On Thor, the Rx timestamp is present in the Rx completion record */\n+\t/* On P5, the Rx timestamp is present in the Rx completion record */\n \tuint64_t\t\t\trx_timestamp;\n \tuint64_t\t\t\tcurrent_time;\n };\n@@ -679,8 +682,8 @@ struct bnxt {\n #define BNXT_PF(bp)\t\t(!((bp)->flags & BNXT_FLAG_VF))\n #define BNXT_VF(bp)\t\t((bp)->flags & BNXT_FLAG_VF)\n #define BNXT_NPAR(bp)\t\t((bp)->flags & BNXT_FLAG_NPAR_PF)\n-#define BNXT_MH(bp)             ((bp)->flags & BNXT_FLAG_MULTI_HOST)\n-#define BNXT_SINGLE_PF(bp)      (BNXT_PF(bp) && !BNXT_NPAR(bp) && !BNXT_MH(bp))\n+#define BNXT_MH(bp)\t\t((bp)->flags & BNXT_FLAG_MULTI_HOST)\n+#define BNXT_SINGLE_PF(bp)\t(BNXT_PF(bp) && !BNXT_NPAR(bp) && !BNXT_MH(bp))\n #define BNXT_USE_CHIMP_MB\t0 //For non-CFA commands, everything uses Chimp.\n #define BNXT_USE_KONG(bp)\t((bp)->flags & BNXT_FLAG_KONG_MB_EN)\n #define BNXT_VF_IS_TRUSTED(bp)\t((bp)->flags & BNXT_FLAG_TRUSTED_VF_EN)\n@@ -689,7 +692,7 @@ struct bnxt {\n #define BNXT_HAS_NQ(bp)\t\tBNXT_CHIP_P5(bp)\n #define BNXT_HAS_RING_GRPS(bp)\t(!BNXT_CHIP_P5(bp))\n #define BNXT_FLOW_XSTATS_EN(bp)\t((bp)->flags & BNXT_FLAG_FLOW_XSTATS_EN)\n-#define BNXT_HAS_DFLT_MAC_SET(bp)      ((bp)->flags & BNXT_FLAG_DFLT_MAC_SET)\n+#define BNXT_HAS_DFLT_MAC_SET(bp)\t((bp)->flags & BNXT_FLAG_DFLT_MAC_SET)\n #define BNXT_GFID_ENABLED(bp)\t((bp)->flags & BNXT_FLAG_GFID_ENABLE)\n \n \tuint32_t\t\t\tflags2;\n@@ -697,8 +700,8 @@ struct bnxt {\n #define BNXT_FLAGS2_PTP_ALARM_SCHEDULED\t\tBIT(1)\n #define BNXT_P5_PTP_TIMESYNC_ENABLED(bp)\t\\\n \t((bp)->flags2 & BNXT_FLAGS2_PTP_TIMESYNC_ENABLED)\n-#define BNXT_FLAGS2_TESTPMD_EN                  BIT(3)\n-#define BNXT_TESTPMD_EN(bp)                     \\\n+#define BNXT_FLAGS2_TESTPMD_EN\t\t\tBIT(3)\n+#define BNXT_TESTPMD_EN(bp)\t\t\t\\\n \t((bp)->flags2 & BNXT_FLAGS2_TESTPMD_EN)\n \n \tuint16_t\t\tchip_num;\n@@ -719,7 +722,8 @@ struct bnxt {\n #define BNXT_FW_CAP_LINK_ADMIN\t\tBIT(7)\n #define BNXT_FW_CAP_TRUFLOW_EN\t\tBIT(8)\n #define BNXT_FW_CAP_VLAN_TX_INSERT\tBIT(9)\n-#define BNXT_TRUFLOW_EN(bp)\t((bp)->fw_cap & BNXT_FW_CAP_TRUFLOW_EN)\n+#define BNXT_TRUFLOW_EN(bp)\t((bp)->fw_cap & BNXT_FW_CAP_TRUFLOW_EN &&\\\n+\t\t\t\t (bp)->app_id != 0xFF)\n \n \tpthread_mutex_t         flow_lock;\n \n@@ -729,6 +733,7 @@ struct bnxt {\n #define BNXT_VNIC_CAP_RX_CMPL_V2\tBIT(2)\n #define BNXT_VNIC_CAP_VLAN_RX_STRIP\tBIT(3)\n #define BNXT_RX_VLAN_STRIP_EN(bp)\t((bp)->vnic_cap_flags & BNXT_VNIC_CAP_VLAN_RX_STRIP)\n+#define BNXT_VNIC_CAP_OUTER_RSS_TRUSTED_VF\tBIT(4)\n \tunsigned int\t\trx_nr_rings;\n \tunsigned int\t\trx_cp_nr_rings;\n \tunsigned int\t\trx_num_qs_per_vnic;\n@@ -758,7 +763,6 @@ struct bnxt {\n \n \tuint16_t\t\t\tnr_vnics;\n \n-#define BNXT_GET_DEFAULT_VNIC(bp)\t(&(bp)->vnic_info[0])\n \tstruct bnxt_vnic_info\t*vnic_info;\n \tSTAILQ_HEAD(, bnxt_vnic_info)\tfree_vnic_list;\n \n@@ -873,6 +877,7 @@ struct bnxt {\n \tuint16_t\t\ttx_cfa_action;\n \tstruct bnxt_ring_stats\t*prev_rx_ring_stats;\n \tstruct bnxt_ring_stats\t*prev_tx_ring_stats;\n+\tstruct bnxt_vnic_queue_db vnic_queue_db;\n \n #define BNXT_MAX_MC_ADDRS\t((bp)->max_mcast_addr)\n \tstruct rte_ether_addr\t*mcast_addr_list;\n@@ -905,7 +910,7 @@ inline uint16_t bnxt_max_rings(struct bnxt *bp)\n \t}\n \n \t/*\n-\t * RSS table size in Thor is 512.\n+\t * RSS table size in P5 is 512.\n \t * Cap max Rx rings to the same value for RSS.\n \t */\n \tif (BNXT_CHIP_P5(bp))\n@@ -997,9 +1002,16 @@ void bnxt_schedule_fw_health_check(struct bnxt *bp);\n bool is_bnxt_supported(struct rte_eth_dev *dev);\n bool bnxt_stratus_device(struct bnxt *bp);\n void bnxt_print_link_info(struct rte_eth_dev *eth_dev);\n+uint16_t bnxt_rss_ctxts(const struct bnxt *bp);\n uint16_t bnxt_rss_hash_tbl_size(const struct bnxt *bp);\n int bnxt_link_update_op(struct rte_eth_dev *eth_dev,\n \t\t\tint wait_to_complete);\n+int\n+bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,\n+\t\t\t    struct rte_eth_udp_tunnel *udp_tunnel);\n+int\n+bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,\n+\t\t\t    struct rte_eth_udp_tunnel *udp_tunnel);\n \n extern const struct rte_flow_ops bnxt_flow_ops;\n \n@@ -1053,5 +1065,6 @@ int bnxt_flow_ops_get_op(struct rte_eth_dev *dev,\n int bnxt_dev_start_op(struct rte_eth_dev *eth_dev);\n int bnxt_dev_stop_op(struct rte_eth_dev *eth_dev);\n void bnxt_handle_vf_cfg_change(void *arg);\n+struct bnxt_vnic_info *bnxt_get_default_vnic(struct bnxt *bp);\n struct tf *bnxt_get_tfp_session(struct bnxt *bp, enum bnxt_session_type type);\n #endif\ndiff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c\nindex bcde44bb14..4d84aaee0c 100644\n--- a/drivers/net/bnxt/bnxt_ethdev.c\n+++ b/drivers/net/bnxt/bnxt_ethdev.c\n@@ -202,7 +202,7 @@ int is_bnxt_in_error(struct bnxt *bp)\n  * High level utility functions\n  */\n \n-static uint16_t bnxt_rss_ctxts(const struct bnxt *bp)\n+uint16_t bnxt_rss_ctxts(const struct bnxt *bp)\n {\n \tunsigned int num_rss_rings = RTE_MIN(bp->rx_nr_rings,\n \t\t\t\t\t     BNXT_RSS_TBL_SIZE_P5);\n@@ -421,6 +421,10 @@ static int bnxt_setup_one_vnic(struct bnxt *bp, uint16_t vnic_id)\n \tPMD_DRV_LOG(DEBUG, \"vnic[%d] = %p vnic->fw_grp_ids = %p\\n\",\n \t\t    vnic_id, vnic, vnic->fw_grp_ids);\n \n+\t/* populate the fw group table */\n+\tbnxt_vnic_ring_grp_populate(bp, vnic);\n+\tbnxt_vnic_rules_init(vnic);\n+\n \trc = bnxt_hwrm_vnic_alloc(bp, vnic);\n \tif (rc)\n \t\tgoto err_out;\n@@ -429,7 +433,7 @@ static int bnxt_setup_one_vnic(struct bnxt *bp, uint16_t vnic_id)\n \tif (dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS) {\n \t\tint j, nr_ctxs = bnxt_rss_ctxts(bp);\n \n-\t\t/* RSS table size in Thor is 512.\n+\t\t/* RSS table size in P5 is 512.\n \t\t * Cap max Rx rings to same value\n \t\t */\n \t\tif (bp->rx_nr_rings > BNXT_RSS_TBL_SIZE_P5) {\n@@ -479,9 +483,7 @@ static int bnxt_setup_one_vnic(struct bnxt *bp, uint16_t vnic_id)\n \t\t\t    j, rxq->vnic, rxq->vnic->fw_grp_ids);\n \n \t\tif (BNXT_HAS_RING_GRPS(bp) && rxq->rx_deferred_start)\n-\t\t\trxq->vnic->fw_grp_ids[j] = INVALID_HW_RING_ID;\n-\t\telse\n-\t\t\tvnic->rx_queue_cnt++;\n+\t\t\tvnic->fw_grp_ids[j] = INVALID_HW_RING_ID;\n \t}\n \n \tPMD_DRV_LOG(DEBUG, \"vnic->rx_queue_cnt = %d\\n\", vnic->rx_queue_cnt);\n@@ -755,12 +757,18 @@ static int bnxt_start_nic(struct bnxt *bp)\n \telse\n \t\tbp->flags &= ~BNXT_FLAG_JUMBO;\n \n-\t/* THOR does not support ring groups.\n+\t/* P5 does not support ring groups.\n \t * But we will use the array to save RSS context IDs.\n \t */\n \tif (BNXT_CHIP_P5(bp))\n \t\tbp->max_ring_grps = BNXT_MAX_RSS_CTXTS_P5;\n \n+\trc = bnxt_vnic_queue_db_init(bp);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"could not allocate vnic db\\n\");\n+\t\tgoto err_out;\n+\t}\n+\n \trc = bnxt_alloc_hwrm_rings(bp);\n \tif (rc) {\n \t\tPMD_DRV_LOG(ERR, \"HWRM ring alloc failure rc: %x\\n\", rc);\n@@ -808,6 +816,9 @@ static int bnxt_start_nic(struct bnxt *bp)\n \t\t}\n \t}\n \n+\t/* setup the default vnic details*/\n+\tbnxt_vnic_queue_db_update_dlft_vnic(bp);\n+\n \t/* VNIC configuration */\n \tfor (i = 0; i < bp->nr_vnics; i++) {\n \t\trc = bnxt_setup_one_vnic(bp, i);\n@@ -901,6 +912,7 @@ static int bnxt_shutdown_nic(struct bnxt *bp)\n \tbnxt_free_all_hwrm_resources(bp);\n \tbnxt_free_all_filters(bp);\n \tbnxt_free_all_vnics(bp);\n+\tbnxt_vnic_queue_db_deinit(bp);\n \treturn 0;\n }\n \n@@ -1431,7 +1443,6 @@ static void bnxt_ptp_get_current_time(void *arg)\n \n \tbnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME,\n \t\t\t\t&ptp->current_time);\n-\n \trc = rte_eal_alarm_set(US_PER_S, bnxt_ptp_get_current_time, (void *)bp);\n \tif (rc != 0) {\n \t\tPMD_DRV_LOG(ERR, \"Failed to re-schedule PTP alarm\\n\");\n@@ -1450,6 +1461,7 @@ static int bnxt_schedule_ptp_alarm(struct bnxt *bp)\n \tbnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME,\n \t\t\t\t&ptp->current_time);\n \n+\n \trc = rte_eal_alarm_set(US_PER_S, bnxt_ptp_get_current_time, (void *)bp);\n \treturn rc;\n }\n@@ -1891,7 +1903,7 @@ static int bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev)\n \tif (bp->vnic_info == NULL)\n \t\treturn 0;\n \n-\tvnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tvnic = bnxt_get_default_vnic(bp);\n \n \told_flags = vnic->flags;\n \tvnic->flags |= BNXT_VNIC_INFO_PROMISC;\n@@ -1920,7 +1932,7 @@ static int bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)\n \tif (bp->vnic_info == NULL)\n \t\treturn 0;\n \n-\tvnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tvnic = bnxt_get_default_vnic(bp);\n \n \told_flags = vnic->flags;\n \tvnic->flags &= ~BNXT_VNIC_INFO_PROMISC;\n@@ -1949,7 +1961,7 @@ static int bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)\n \tif (bp->vnic_info == NULL)\n \t\treturn 0;\n \n-\tvnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tvnic = bnxt_get_default_vnic(bp);\n \n \told_flags = vnic->flags;\n \tvnic->flags |= BNXT_VNIC_INFO_ALLMULTI;\n@@ -1978,7 +1990,7 @@ static int bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)\n \tif (bp->vnic_info == NULL)\n \t\treturn 0;\n \n-\tvnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tvnic = bnxt_get_default_vnic(bp);\n \n \told_flags = vnic->flags;\n \tvnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;\n@@ -2026,7 +2038,7 @@ static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,\n {\n \tstruct bnxt *bp = eth_dev->data->dev_private;\n \tstruct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;\n-\tstruct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tstruct bnxt_vnic_info *vnic = bnxt_get_default_vnic(bp);\n \tuint16_t tbl_size = bnxt_rss_hash_tbl_size(bp);\n \tuint16_t idx, sft;\n \tint i, rc;\n@@ -2048,6 +2060,10 @@ static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,\n \t\treturn -EINVAL;\n \t}\n \n+\tif (bnxt_vnic_reta_config_update(bp, vnic, reta_conf, reta_size)) {\n+\t\tPMD_DRV_LOG(ERR, \"Error in setting the reta config\\n\");\n+\t\treturn -EINVAL;\n+\t}\n \tfor (i = 0; i < reta_size; i++) {\n \t\tstruct bnxt_rx_queue *rxq;\n \n@@ -2058,11 +2074,6 @@ static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,\n \t\t\tcontinue;\n \n \t\trxq = bnxt_qid_to_rxq(bp, reta_conf[idx].reta[sft]);\n-\t\tif (!rxq) {\n-\t\t\tPMD_DRV_LOG(ERR, \"Invalid ring in reta_conf.\\n\");\n-\t\t\treturn -EINVAL;\n-\t\t}\n-\n \t\tif (BNXT_CHIP_P5(bp)) {\n \t\t\tvnic->rss_table[i * 2] =\n \t\t\t\trxq->rx_ring->rx_ring_struct->fw_ring_id;\n@@ -2073,7 +2084,6 @@ static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,\n \t\t\t    vnic->fw_grp_ids[reta_conf[idx].reta[sft]];\n \t\t}\n \t}\n-\n \trc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);\n \treturn rc;\n }\n@@ -2083,7 +2093,7 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,\n \t\t\t      uint16_t reta_size)\n {\n \tstruct bnxt *bp = eth_dev->data->dev_private;\n-\tstruct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tstruct bnxt_vnic_info *vnic = bnxt_get_default_vnic(bp);\n \tuint16_t tbl_size = bnxt_rss_hash_tbl_size(bp);\n \tuint16_t idx, sft, i;\n \tint rc;\n@@ -2153,7 +2163,7 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev,\n \t}\n \n \t/* Update the default RSS VNIC(s) */\n-\tvnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tvnic = bnxt_get_default_vnic(bp);\n \tvnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_conf->rss_hf);\n \tvnic->hash_mode =\n \t\tbnxt_rte_to_hwrm_hash_level(bp, rss_conf->rss_hf,\n@@ -2189,7 +2199,7 @@ static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev,\n \t\t\t\t     struct rte_eth_rss_conf *rss_conf)\n {\n \tstruct bnxt *bp = eth_dev->data->dev_private;\n-\tstruct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tstruct bnxt_vnic_info *vnic = bnxt_get_default_vnic(bp);\n \tint len, rc;\n \tuint32_t hash_types;\n \n@@ -2348,7 +2358,7 @@ static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev,\n }\n \n /* Add UDP tunneling port */\n-static int\n+int\n bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,\n \t\t\t struct rte_eth_udp_tunnel *udp_tunnel)\n {\n@@ -2410,7 +2420,7 @@ bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,\n \treturn rc;\n }\n \n-static int\n+int\n bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,\n \t\t\t struct rte_eth_udp_tunnel *udp_tunnel)\n {\n@@ -2474,7 +2484,7 @@ static int bnxt_del_vlan_filter(struct bnxt *bp, uint16_t vlan_id)\n \tint rc = 0;\n \tuint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN;\n \n-\tvnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tvnic = bnxt_get_default_vnic(bp);\n \tfilter = STAILQ_FIRST(&vnic->filter);\n \twhile (filter) {\n \t\t/* Search for this matching MAC+VLAN filter */\n@@ -2513,7 +2523,7 @@ static int bnxt_add_vlan_filter(struct bnxt *bp, uint16_t vlan_id)\n \t * then the HWRM shall only create an l2 context id.\n \t */\n \n-\tvnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tvnic = bnxt_get_default_vnic(bp);\n \tfilter = STAILQ_FIRST(&vnic->filter);\n \t/* Check if the VLAN has already been added */\n \twhile (filter) {\n@@ -2618,7 +2628,7 @@ bnxt_config_vlan_hw_filter(struct bnxt *bp, uint64_t rx_offloads)\n \tunsigned int i;\n \tint rc;\n \n-\tvnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tvnic = bnxt_get_default_vnic(bp);\n \tif (!(rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER)) {\n \t\t/* Remove any VLAN filters programmed */\n \t\tfor (i = 0; i < RTE_ETHER_MAX_VLAN_ID; i++)\n@@ -2677,16 +2687,18 @@ static int bnxt_free_one_vnic(struct bnxt *bp, uint16_t vnic_id)\n static int\n bnxt_config_vlan_hw_stripping(struct bnxt *bp, uint64_t rx_offloads)\n {\n-\tstruct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tstruct bnxt_vnic_info *vnic = bnxt_get_default_vnic(bp);\n \tint rc;\n \n \t/* Destroy, recreate and reconfigure the default vnic */\n-\trc = bnxt_free_one_vnic(bp, 0);\n+\trc = bnxt_free_one_vnic(bp, bp->vnic_queue_db.dflt_vnic_id);\n \tif (rc)\n \t\treturn rc;\n \n-\t/* default vnic 0 */\n-\trc = bnxt_setup_one_vnic(bp, 0);\n+\t/* setup the default vnic details*/\n+\tbnxt_vnic_queue_db_update_dlft_vnic(bp);\n+\n+\trc = bnxt_setup_one_vnic(bp, bp->vnic_queue_db.dflt_vnic_id);\n \tif (rc)\n \t\treturn rc;\n \n@@ -2817,7 +2829,7 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev,\n {\n \tstruct bnxt *bp = dev->data->dev_private;\n \t/* Default Filter is tied to VNIC 0 */\n-\tstruct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tstruct bnxt_vnic_info *vnic = bnxt_get_default_vnic(bp);\n \tint rc;\n \n \trc = is_bnxt_in_error(bp);\n@@ -2867,7 +2879,7 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,\n \tif (rc)\n \t\treturn rc;\n \n-\tvnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tvnic = bnxt_get_default_vnic(bp);\n \n \tbp->nb_mc_addr = nb_mc_addr;\n \n@@ -3029,8 +3041,7 @@ bnxt_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,\n int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)\n {\n \tstruct bnxt *bp = eth_dev->data->dev_private;\n-\tuint32_t rc;\n-\tuint32_t i;\n+\tuint32_t rc = 0;\n \n \trc = is_bnxt_in_error(bp);\n \tif (rc)\n@@ -3048,30 +3059,17 @@ int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)\n \n \t/* Is there a change in mtu setting? */\n \tif (eth_dev->data->mtu == new_mtu)\n-\t\treturn 0;\n+\t\treturn rc;\n \n \tif (new_mtu > RTE_ETHER_MTU)\n \t\tbp->flags |= BNXT_FLAG_JUMBO;\n \telse\n \t\tbp->flags &= ~BNXT_FLAG_JUMBO;\n \n-\tfor (i = 0; i < bp->nr_vnics; i++) {\n-\t\tstruct bnxt_vnic_info *vnic = &bp->vnic_info[i];\n-\t\tuint16_t size = 0;\n-\n-\t\tvnic->mru = BNXT_VNIC_MRU(new_mtu);\n-\t\trc = bnxt_hwrm_vnic_cfg(bp, vnic);\n-\t\tif (rc)\n-\t\t\tbreak;\n-\n-\t\tsize = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);\n-\t\tsize -= RTE_PKTMBUF_HEADROOM;\n-\n-\t\tif (size < new_mtu) {\n-\t\t\trc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);\n-\t\t\tif (rc)\n-\t\t\t\treturn rc;\n-\t\t}\n+\trc = bnxt_vnic_mru_config(bp, new_mtu);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"failed to update mtu in vnic context\\n\");\n+\t\treturn rc;\n \t}\n \n \tif (bnxt_hwrm_config_host_mtu(bp))\n@@ -5312,9 +5310,11 @@ static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev)\n {\n \tint rc = 0;\n \n-\trc = bnxt_get_config(bp);\n-\tif (rc)\n-\t\treturn rc;\n+\tif (reconfig_dev) {\n+\t\trc = bnxt_get_config(bp);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\t}\n \n \trc = bnxt_alloc_switch_domain(bp);\n \tif (rc)\n@@ -5756,7 +5756,7 @@ static int\n bnxt_parse_dev_args(struct bnxt *bp, struct rte_devargs *devargs)\n {\n \tstruct rte_kvargs *kvlist;\n-\tint ret;\n+\tint ret = 0;\n \n \tif (devargs == NULL)\n \t\treturn 0;\n@@ -5825,22 +5825,6 @@ static int bnxt_drv_init(struct rte_eth_dev *eth_dev)\n \t    pci_dev->id.device_id == BROADCOM_DEV_ID_58802_VF)\n \t\tbp->flags |= BNXT_FLAG_STINGRAY;\n \n-\tif (BNXT_TRUFLOW_EN(bp)) {\n-\t\t/* extra mbuf field is required to store CFA code from mark */\n-\t\tstatic const struct rte_mbuf_dynfield bnxt_cfa_code_dynfield_desc = {\n-\t\t\t.name = RTE_PMD_BNXT_CFA_CODE_DYNFIELD_NAME,\n-\t\t\t.size = sizeof(bnxt_cfa_code_dynfield_t),\n-\t\t\t.align = __alignof__(bnxt_cfa_code_dynfield_t),\n-\t\t};\n-\t\tbnxt_cfa_code_dynfield_offset =\n-\t\t\trte_mbuf_dynfield_register(&bnxt_cfa_code_dynfield_desc);\n-\t\tif (bnxt_cfa_code_dynfield_offset < 0) {\n-\t\t\tPMD_DRV_LOG(ERR,\n-\t\t\t    \"Failed to register mbuf field for TruFlow mark\\n\");\n-\t\t\treturn -rte_errno;\n-\t\t}\n-\t}\n-\n \trc = bnxt_map_pci_bars(eth_dev);\n \tif (rc) {\n \t\tPMD_DRV_LOG(ERR,\n@@ -5878,6 +5862,26 @@ static int bnxt_drv_init(struct rte_eth_dev *eth_dev)\n \tif (rc)\n \t\treturn rc;\n \n+\trc = bnxt_get_config(bp);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tif (BNXT_TRUFLOW_EN(bp)) {\n+\t\t/* extra mbuf field is required to store CFA code from mark */\n+\t\tstatic const struct rte_mbuf_dynfield bnxt_cfa_code_dynfield_desc = {\n+\t\t\t.name = RTE_PMD_BNXT_CFA_CODE_DYNFIELD_NAME,\n+\t\t\t.size = sizeof(bnxt_cfa_code_dynfield_t),\n+\t\t\t.align = __alignof__(bnxt_cfa_code_dynfield_t),\n+\t\t};\n+\t\tbnxt_cfa_code_dynfield_offset =\n+\t\t\trte_mbuf_dynfield_register(&bnxt_cfa_code_dynfield_desc);\n+\t\tif (bnxt_cfa_code_dynfield_offset < 0) {\n+\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"Failed to register mbuf field for TruFlow mark\\n\");\n+\t\t\treturn -rte_errno;\n+\t\t}\n+\t}\n+\n \treturn rc;\n }\n \n@@ -5912,6 +5916,9 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev, void *params __rte_unused)\n \n \tbp = eth_dev->data->dev_private;\n \n+\t/* set the default app id */\n+\tbp->app_id = bnxt_ulp_default_app_id_get();\n+\n \t/* Parse dev arguments passed on when starting the DPDK application. */\n \trc = bnxt_parse_dev_args(bp, pci_dev->device.devargs);\n \tif (rc)\n@@ -5948,7 +5955,8 @@ static void bnxt_free_ctx_mem_buf(struct bnxt_ctx_mem_buf_info *ctx)\n \tif (!ctx)\n \t\treturn;\n \n-\trte_free(ctx->va);\n+\tif (ctx->va)\n+\t\trte_free(ctx->va);\n \n \tctx->va = NULL;\n \tctx->dma = RTE_BAD_IOVA;\ndiff --git a/drivers/net/bnxt/bnxt_filter.h b/drivers/net/bnxt/bnxt_filter.h\nindex 587932c96f..57d704d90b 100644\n--- a/drivers/net/bnxt/bnxt_filter.h\n+++ b/drivers/net/bnxt/bnxt_filter.h\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -173,4 +173,8 @@ struct bnxt_filter_info *bnxt_get_l2_filter(struct bnxt *bp,\n \tHWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_NUM_VLANS\n #define L2_FILTER_ALLOC_INPUT_EN_NUM_VLANS \\\n \tHWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_NUM_VLANS\n+#define CFA_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4 \\\n+\tHWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_IPV4\n+#define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_GENEVE\t\\\n+\tHWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE\n #endif\ndiff --git a/drivers/net/bnxt/bnxt_flow.c b/drivers/net/bnxt/bnxt_flow.c\nindex 4a107e81e9..28dd5ae6cb 100644\n--- a/drivers/net/bnxt/bnxt_flow.c\n+++ b/drivers/net/bnxt/bnxt_flow.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -677,7 +677,6 @@ bnxt_validate_and_parse_flow_type(const struct rte_flow_attr *attr,\n \t\t\t\tbreak;\n \t\t\t}\n \t\t\tbreak;\n-\n \t\tdefault:\n \t\t\tbreak;\n \t\t}\n@@ -728,7 +727,7 @@ bnxt_find_matching_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf)\n \tstruct bnxt_vnic_info *vnic0;\n \tint i;\n \n-\tvnic0 = BNXT_GET_DEFAULT_VNIC(bp);\n+\tvnic0 = bnxt_get_default_vnic(bp);\n \tf0 = STAILQ_FIRST(&vnic0->filter);\n \n \t/* This flow has same DST MAC as the port/l2 filter. */\n@@ -905,6 +904,10 @@ static int bnxt_vnic_prep(struct bnxt *bp, struct bnxt_vnic_info *vnic,\n \t\t\t\t\t  act,\n \t\t\t\t\t  \"Failed to alloc VNIC group\");\n \n+\t/* populate the fw group table */\n+\tbnxt_vnic_ring_grp_populate(bp, vnic);\n+\tbnxt_vnic_rules_init(vnic);\n+\n \trc = bnxt_hwrm_vnic_alloc(bp, vnic);\n \tif (rc) {\n \t\trte_flow_error_set(error, -rc,\n@@ -1345,7 +1348,7 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev,\n \t\t * The user specified redirect queue will be set while creating\n \t\t * the ntuple filter in hardware.\n \t\t */\n-\t\tvnic0 = BNXT_GET_DEFAULT_VNIC(bp);\n+\t\tvnic0 = bnxt_get_default_vnic(bp);\n \t\tif (use_ntuple)\n \t\t\tfilter1 = bnxt_get_l2_filter(bp, filter, vnic0);\n \t\telse\n@@ -1964,7 +1967,37 @@ bnxt_flow_create(struct rte_eth_dev *dev,\n \t * in such a case.\n \t */\n \tif (filter->filter_type == HWRM_CFA_TUNNEL_REDIRECT_FILTER &&\n-\t    filter->enables == filter->tunnel_type) {\n+\t    (filter->enables == filter->tunnel_type ||\n+\t     filter->tunnel_type == CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN ||\n+\t     filter->tunnel_type == CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_GENEVE)) {\n+\t\tif (filter->enables & NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT) {\n+\t\t\tstruct rte_eth_udp_tunnel tunnel = {0};\n+\n+\t\t\t/* hwrm_tunnel_dst_port_alloc converts to Big Endian */\n+\t\t\ttunnel.udp_port = BNXT_NTOHS(filter->dst_port);\n+\t\t\tif (filter->tunnel_type ==\n+\t\t\t    CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN) {\n+\t\t\t\ttunnel.prot_type = RTE_ETH_TUNNEL_TYPE_VXLAN;\n+\t\t\t} else if (filter->tunnel_type ==\n+\t\t\t\t CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_GENEVE) {\n+\t\t\t\ttunnel.prot_type = RTE_ETH_TUNNEL_TYPE_GENEVE;\n+\t\t\t} else {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_HANDLE,\n+\t\t\t\t\t\t   NULL,\n+\t\t\t\t\t\t   \"Invalid tunnel type\");\n+\t\t\t\tret = -EINVAL;\n+\t\t\t\tgoto free_filter;\n+\t\t\t}\n+\t\t\tret = bnxt_udp_tunnel_port_add_op(bp->eth_dev, &tunnel);\n+\t\t\tif (ret != 0) {\n+\t\t\t\trte_flow_error_set(error, -ret,\n+\t\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_HANDLE,\n+\t\t\t\t\t\t   NULL,\n+\t\t\t\t\t\t   \"Fail to add tunnel port\");\n+\t\t\t\tgoto free_filter;\n+\t\t\t}\n+\t\t}\n \t\tret = bnxt_hwrm_tunnel_redirect_query(bp, &tun_type);\n \t\tif (ret) {\n \t\t\trte_flow_error_set(error, -ret,\n@@ -2147,8 +2180,38 @@ _bnxt_flow_destroy(struct bnxt *bp,\n \tfilter = flow->filter;\n \tvnic = flow->vnic;\n \n+\t/* If tunnel redirection to a VF/PF is specified then only tunnel_type\n+\t * is set and enable is set to the tunnel type. Issue hwrm cmd directly\n+\t * in such a case.\n+\t */\n \tif (filter->filter_type == HWRM_CFA_TUNNEL_REDIRECT_FILTER &&\n-\t    filter->enables == filter->tunnel_type) {\n+\t    (filter->enables == filter->tunnel_type ||\n+\t     filter->tunnel_type == CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN ||\n+\t     filter->tunnel_type == CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_GENEVE)) {\n+\t\tif (filter->enables & NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT) {\n+\t\t\tstruct rte_eth_udp_tunnel tunnel = {0};\n+\n+\t\t\t/* hwrm_tunnel_dst_port_free converts to Big Endian */\n+\t\t\ttunnel.udp_port = BNXT_NTOHS(filter->dst_port);\n+\t\t\tif (filter->tunnel_type ==\n+\t\t\t    CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN) {\n+\t\t\t\ttunnel.prot_type = RTE_ETH_TUNNEL_TYPE_VXLAN;\n+\t\t\t} else if (filter->tunnel_type ==\n+\t\t\t\t CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_GENEVE) {\n+\t\t\t\ttunnel.prot_type = RTE_ETH_TUNNEL_TYPE_GENEVE;\n+\t\t\t} else {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_HANDLE,\n+\t\t\t\t\t\t   NULL,\n+\t\t\t\t\t\t   \"Invalid tunnel type\");\n+\t\t\t\treturn ret;\n+\t\t\t}\n+\n+\t\t\tret = bnxt_udp_tunnel_port_del_op(bp->eth_dev,\n+\t\t\t\t\t\t\t  &tunnel);\n+\t\t\tif (ret)\n+\t\t\t\treturn ret;\n+\t\t}\n \t\tret = bnxt_handle_tunnel_redirect_destroy(bp, filter, error);\n \t\tif (!ret)\n \t\t\tgoto done;\ndiff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c\nindex 3f273df6f3..77588bdf49 100644\n--- a/drivers/net/bnxt/bnxt_hwrm.c\n+++ b/drivers/net/bnxt/bnxt_hwrm.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -668,6 +668,7 @@ int bnxt_hwrm_ptp_cfg(struct bnxt *bp)\n \telse\n \t\tflags |=\n \t\t\tHWRM_PORT_MAC_CFG_INPUT_FLAGS_PTP_TX_TS_CAPTURE_DISABLE;\n+\n \treq.flags = rte_cpu_to_le_32(flags);\n \treq.enables = rte_cpu_to_le_32\n \t\t(HWRM_PORT_MAC_CFG_INPUT_ENABLES_RX_TS_CAPTURE_PTP_MSG_TYPE);\n@@ -858,9 +859,11 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)\n \tbp->max_stat_ctx = rte_le_to_cpu_16(resp->max_stat_ctx);\n \tbp->max_mcast_addr = rte_le_to_cpu_32(resp->max_mcast_filters);\n \n-\tif (BNXT_PF(bp)) {\n+\tif (BNXT_PF(bp))\n \t\tbp->pf->total_vnics = rte_le_to_cpu_16(resp->max_vnics);\n-\t\tif (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PTP_SUPPORTED) {\n+\n+\tif (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PTP_SUPPORTED) {\n+\t\tif (BNXT_CHIP_P5(bp) || BNXT_PF(bp)) {\n \t\t\tbp->flags |= BNXT_FLAG_PTP_SUPPORTED;\n \t\t\tPMD_DRV_LOG(DEBUG, \"PTP SUPPORTED\\n\");\n \t\t\tHWRM_UNLOCK();\n@@ -894,6 +897,7 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)\n \tif (bp->tunnel_disable_flag)\n \t\tPMD_DRV_LOG(DEBUG, \"Tunnel parsing capability is disabled, flags : %#x\\n\",\n \t\t\t    bp->tunnel_disable_flag);\n+\n unlock:\n \tHWRM_UNLOCK();\n \n@@ -951,6 +955,11 @@ int bnxt_hwrm_vnic_qcaps(struct bnxt *bp)\n \tif (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_OUTERMOST_RSS_CAP)\n \t\tbp->vnic_cap_flags |= BNXT_VNIC_CAP_OUTER_RSS;\n \n+\tif (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_OUTERMOST_RSS_TRUSTED_VF_CAP) {\n+\t\tbp->vnic_cap_flags |= BNXT_VNIC_CAP_OUTER_RSS_TRUSTED_VF;\n+\t\tPMD_DRV_LOG(DEBUG, \"Trusted VF's outer RSS capability is enabled\\n\");\n+\t}\n+\n \tif (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RX_CMPL_V2_CAP)\n \t\tbp->vnic_cap_flags |= BNXT_VNIC_CAP_RX_CMPL_V2;\n \n@@ -1097,7 +1106,16 @@ int bnxt_hwrm_func_reserve_vf_resc(struct bnxt *bp, bool test)\n \treq.num_cmpl_rings = rte_cpu_to_le_16(bp->rx_nr_rings +\n \t\t\t\t\t      bp->tx_nr_rings +\n \t\t\t\t\t      BNXT_NUM_ASYNC_CPR(bp));\n-\treq.num_vnics = rte_cpu_to_le_16(bp->rx_nr_rings);\n+\tif (BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp)) {\n+\t\treq.num_vnics = rte_cpu_to_le_16(RTE_MIN(BNXT_VNIC_MAX_SUPPORTED_ID,\n+\t\t\t\t\t\t\t bp->max_vnics));\n+\t\tenables |= HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS;\n+\t\treq.num_rsscos_ctxs = rte_cpu_to_le_16(RTE_MIN(BNXT_VNIC_MAX_SUPPORTED_ID,\n+\t\t\t\t\t\t\t       bp->max_rsscos_ctx));\n+\t} else {\n+\t\treq.num_vnics = rte_cpu_to_le_16(bp->rx_nr_rings);\n+\t}\n+\n \tif (bp->vf_resv_strategy ==\n \t    HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESV_STRATEGY_MINIMAL_STATIC) {\n \t\tenables |= HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_VNICS |\n@@ -1936,25 +1954,10 @@ static int bnxt_hwrm_stat_ctx_free(struct bnxt *bp, struct bnxt_cp_ring_info *cp\n \n int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)\n {\n-\tint rc = 0, i, j;\n+\tint rc = 0;\n \tstruct hwrm_vnic_alloc_input req = { 0 };\n \tstruct hwrm_vnic_alloc_output *resp = bp->hwrm_cmd_resp_addr;\n \n-\tif (!BNXT_HAS_RING_GRPS(bp))\n-\t\tgoto skip_ring_grps;\n-\n-\t/* map ring groups to this vnic */\n-\tPMD_DRV_LOG(DEBUG, \"Alloc VNIC. Start %x, End %x\\n\",\n-\t\tvnic->start_grp_id, vnic->end_grp_id);\n-\tfor (i = vnic->start_grp_id, j = 0; i < vnic->end_grp_id; i++, j++)\n-\t\tvnic->fw_grp_ids[j] = bp->grp_info[i].fw_grp_id;\n-\n-\tvnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;\n-\tvnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;\n-\tvnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;\n-\tvnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;\n-\n-skip_ring_grps:\n \tvnic->mru = BNXT_VNIC_MRU(bp->eth_dev->data->mtu);\n \tHWRM_PREP(&req, HWRM_VNIC_ALLOC, BNXT_USE_CHIMP_MB);\n \n@@ -2068,7 +2071,8 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)\n \t\t */\n \t\tfor (i = vnic->start_grp_id; i < vnic->end_grp_id; i++) {\n \t\t\trxq = bp->eth_dev->data->rx_queues[i];\n-\t\t\tif (rxq->rx_started) {\n+\t\t\tif (rxq->rx_started &&\n+\t\t\t    bnxt_vnic_queue_id_is_valid(vnic, i)) {\n \t\t\t\tdflt_rxq = i;\n \t\t\t\tbreak;\n \t\t\t}\n@@ -2298,14 +2302,22 @@ bnxt_hwrm_vnic_rss_cfg_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic)\n \n \t\treq.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);\n \t\treq.hash_type = rte_cpu_to_le_32(vnic->hash_type);\n-\t\treq.hash_mode_flags = vnic->hash_mode;\n+\t\t/* When the vnic_id in the request field is a valid\n+\t\t * one, the hash_mode_flags in the request field must\n+\t\t * be set to DEFAULT. And any request to change the\n+\t\t * default behavior must be done in a separate call\n+\t\t * to HWRM_VNIC_RSS_CFG by exclusively setting hash\n+\t\t * mode and vnic_id, rss_ctx_idx to INVALID.\n+\t\t */\n+\t\treq.hash_mode_flags = BNXT_HASH_MODE_DEFAULT;\n \n \t\treq.hash_key_tbl_addr =\n \t\t\trte_cpu_to_le_64(vnic->rss_hash_key_dma_addr);\n \n \t\treq.ring_grp_tbl_addr =\n \t\t\trte_cpu_to_le_64(vnic->rss_table_dma_addr +\n-\t\t\t\t\t i * HW_HASH_INDEX_SIZE);\n+\t\t\t\t\t i * BNXT_RSS_ENTRIES_PER_CTX_P5 *\n+\t\t\t\t\t 2 * sizeof(uint16_t));\n \t\treq.ring_table_pair_index = i;\n \t\treq.rss_ctx_idx = rte_cpu_to_le_16(vnic->fw_grp_ids[i]);\n \n@@ -2314,23 +2326,74 @@ bnxt_hwrm_vnic_rss_cfg_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic)\n \n \t\tHWRM_CHECK_RESULT();\n \t\tHWRM_UNLOCK();\n+\t\tPMD_DRV_LOG(DEBUG, \"RSS CFG: Hash level %d\\n\", req.hash_mode_flags);\n \t}\n \n \treturn rc;\n }\n \n-int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,\n-\t\t\t   struct bnxt_vnic_info *vnic)\n+static int\n+bnxt_hwrm_vnic_rss_cfg_hash_mode_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic)\n {\n-\tint rc = 0;\n-\tstruct hwrm_vnic_rss_cfg_input req = {.req_type = 0 };\n \tstruct hwrm_vnic_rss_cfg_output *resp = bp->hwrm_cmd_resp_addr;\n+\tstruct hwrm_vnic_rss_cfg_input req = {.req_type = 0 };\n+\tint rc = 0;\n \n-\tif (!vnic->rss_table)\n+\t/* The reason we are returning success here is that this\n+\t * call is in the context of user/stack RSS configuration.\n+\t * Even though OUTER RSS is not supported, the normal RSS\n+\t * configuration should continue to work.\n+\t */\n+\tif ((BNXT_CHIP_P5(bp) && BNXT_VNIC_OUTER_RSS_UNSUPPORTED(bp)) ||\n+\t    (!BNXT_CHIP_P5(bp) && !(bp->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS)))\n \t\treturn 0;\n \n-\tif (BNXT_CHIP_P5(bp))\n-\t\treturn bnxt_hwrm_vnic_rss_cfg_p5(bp, vnic);\n+\t/* Don't call RSS hash level configuration if the current\n+\t * hash level is the same as the hash level that is requested.\n+\t */\n+\tif (vnic->prev_hash_mode == vnic->hash_mode)\n+\t\treturn 0;\n+\n+\tHWRM_PREP(&req, HWRM_VNIC_RSS_CFG, BNXT_USE_CHIMP_MB);\n+\n+\t/* For FW, hash_mode == DEFAULT means that\n+\t * the FW is capable of doing INNER & OUTER RSS as well.\n+\t * DEFAULT doesn't mean that the FW is\n+\t * going to change the hash_mode to INNER. However, for\n+\t * the USER, DEFAULT means, change the hash mode to the\n+\t * NIC's DEFAULT hash mode which is INNER.\n+\t *\n+\t * Hence, driver should make the translation of hash_mode\n+\t * to INNERMOST when hash_mode from the dpdk stack is\n+\t * DEFAULT.\n+\t */\n+\tif (vnic->hash_mode == BNXT_HASH_MODE_DEFAULT)\n+\t\treq.hash_mode_flags = BNXT_HASH_MODE_INNERMOST;\n+\telse\n+\t\treq.hash_mode_flags = vnic->hash_mode;\n+\treq.vnic_id = rte_cpu_to_le_16(BNXT_DFLT_VNIC_ID_INVALID);\n+\treq.rss_ctx_idx = rte_cpu_to_le_16(BNXT_RSS_CTX_IDX_INVALID);\n+\n+\tPMD_DRV_LOG(DEBUG, \"RSS CFG: Hash level %d\\n\", req.hash_mode_flags);\n+\trc = bnxt_hwrm_send_message(bp, &req, sizeof(req),\n+\t\t\t\t    BNXT_USE_CHIMP_MB);\n+\n+\tHWRM_CHECK_RESULT();\n+\t/* Store the programmed hash_mode in prev_hash_mode so that\n+\t * it can checked against the next user requested hash mode.\n+\t */\n+\tif (!rc)\n+\t\tvnic->prev_hash_mode = vnic->hash_mode;\n+\tHWRM_UNLOCK();\n+\treturn rc;\n+}\n+\n+static int\n+bnxt_hwrm_vnic_rss_cfg_non_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic)\n+{\n+\tstruct hwrm_vnic_rss_cfg_input req = {.req_type = 0 };\n+\tstruct hwrm_vnic_rss_cfg_output *resp = bp->hwrm_cmd_resp_addr;\n+\tint rc = 0;\n \n \tHWRM_PREP(&req, HWRM_VNIC_RSS_CFG, BNXT_USE_CHIMP_MB);\n \n@@ -2352,6 +2415,39 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,\n \treturn rc;\n }\n \n+int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,\n+\t\t\t   struct bnxt_vnic_info *vnic)\n+{\n+\tint rc = 0;\n+\n+\tif (!vnic->rss_table)\n+\t\treturn 0;\n+\n+\tif (BNXT_CHIP_P5(bp)) {\n+\t\trc = bnxt_hwrm_vnic_rss_cfg_p5(bp, vnic);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\t\t/* Configuring the hash mode has to be done in a\n+\t\t * different VNIC_RSS_CFG HWRM command by setting\n+\t\t * vnic_id & rss_ctx_id to INVALID. The only\n+\t\t * exception to this is if the USER doesn't want\n+\t\t * to change the default behavior. So, ideally\n+\t\t * bnxt_hwrm_vnic_rss_cfg_hash_mode_p5 should be\n+\t\t * called when user is explicitly changing the hash\n+\t\t * mode. However, this logic will unconditionally\n+\t\t * call bnxt_hwrm_vnic_rss_cfg_hash_mode_p5 to\n+\t\t * simplify the logic as there is no harm in calling\n+\t\t * bnxt_hwrm_vnic_rss_cfg_hash_mode_p5 even when\n+\t\t * user is not setting it explicitly. Because, this\n+\t\t * routine will convert the default value to inner\n+\t\t * which is our adapter's default behavior.\n+\t\t */\n+\t\treturn bnxt_hwrm_vnic_rss_cfg_hash_mode_p5(bp, vnic);\n+\t}\n+\n+\treturn bnxt_hwrm_vnic_rss_cfg_non_p5(bp, vnic);\n+}\n+\n int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,\n \t\t\tstruct bnxt_vnic_info *vnic)\n {\n@@ -2893,6 +2989,7 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)\n \t\tbnxt_hwrm_vnic_free(bp, vnic);\n \n \t\trte_free(vnic->fw_grp_ids);\n+\t\tvnic->fw_grp_ids = NULL;\n \t}\n \t/* Ring resources */\n \tbnxt_free_all_hwrm_rings(bp);\n@@ -3977,6 +4074,36 @@ int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,\n \treturn rc;\n }\n \n+int bnxt_hwrm_tunnel_upar_id_get(struct bnxt *bp, uint8_t *upar_id,\n+\t\t\t\t uint8_t tunnel_type)\n+{\n+\tstruct hwrm_tunnel_dst_port_query_input req = {0};\n+\tstruct hwrm_tunnel_dst_port_query_output *resp = bp->hwrm_cmd_resp_addr;\n+\tint rc = 0;\n+\n+\tHWRM_PREP(&req, HWRM_TUNNEL_DST_PORT_QUERY, BNXT_USE_CHIMP_MB);\n+\treq.tunnel_type = tunnel_type;\n+\trc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);\n+\tHWRM_CHECK_RESULT();\n+\n+\tswitch (tunnel_type) {\n+\tcase HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_ECPRI:\n+\t\t*upar_id = resp->upar_in_use;\n+\t\tbreak;\n+\tcase HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_SRV6:\n+\t\t*upar_id = resp->upar_in_use;\n+\t\tbreak;\n+\tdefault:\n+\t\t/* INVALID UPAR Id if another tunnel type tries to retrieve */\n+\t\t*upar_id = 0xff;\n+\t\tbreak;\n+\t}\n+\n+\tHWRM_UNLOCK();\n+\n+\treturn rc;\n+}\n+\n int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,\n \t\t\t\tuint8_t tunnel_type)\n {\ndiff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h\nindex f9d9fe0ef2..68384bc757 100644\n--- a/drivers/net/bnxt/bnxt_hwrm.h\n+++ b/drivers/net/bnxt/bnxt_hwrm.h\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -109,7 +109,31 @@ struct bnxt_pf_resource_info {\n \tuint32_t num_hw_ring_grps;\n };\n \n-#define BNXT_CTX_VAL_INVAL\t0xFFFF\n+#define BNXT_CTX_VAL_INVAL\t\t0xFFFF\n+#define\tBNXT_RSS_CTX_IDX_INVALID\t0xFFFF\n+\n+#define BNXT_TUNNELED_OFFLOADS_CAP_VXLAN_EN(bp)\t\t\\\n+\t(!((bp)->tunnel_disable_flag & HWRM_FUNC_QCAPS_OUTPUT_TUNNEL_DISABLE_FLAG_DISABLE_VXLAN))\n+#define BNXT_TUNNELED_OFFLOADS_CAP_NGE_EN(bp)\t\t\\\n+\t(!((bp)->tunnel_disable_flag & HWRM_FUNC_QCAPS_OUTPUT_TUNNEL_DISABLE_FLAG_DISABLE_NGE))\n+#define BNXT_TUNNELED_OFFLOADS_CAP_GRE_EN(bp)\t\t\\\n+\t(!((bp)->tunnel_disable_flag & HWRM_FUNC_QCAPS_OUTPUT_TUNNEL_DISABLE_FLAG_DISABLE_GRE))\n+#define BNXT_TUNNELED_OFFLOADS_CAP_IPINIP_EN(bp)\t\\\n+\t(!((bp)->tunnel_disable_flag & HWRM_FUNC_QCAPS_OUTPUT_TUNNEL_DISABLE_FLAG_DISABLE_IPINIP))\n+\n+/*\n+ * If the device supports VXLAN, GRE, IPIP and GENEVE tunnel parsing, then report\n+ * RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM, RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM and\n+ * RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM in the Rx/Tx offload capabilities of the device.\n+ */\n+#define BNXT_TUNNELED_OFFLOADS_CAP_ALL_EN(bp)\t\t\t\\\n+\t(BNXT_TUNNELED_OFFLOADS_CAP_VXLAN_EN(bp) &&\t\t\\\n+\t BNXT_TUNNELED_OFFLOADS_CAP_NGE_EN(bp)   &&\t\t\\\n+\t BNXT_TUNNELED_OFFLOADS_CAP_GRE_EN(bp)   &&\t\t\\\n+\t BNXT_TUNNELED_OFFLOADS_CAP_IPINIP_EN(bp))\n+\n+#define BNXT_SIG_MODE_NRZ\tHWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_NRZ\n+#define BNXT_SIG_MODE_PAM4\tHWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_PAM4\n \n #define BNXT_TUNNELED_OFFLOADS_CAP_VXLAN_EN(bp)\t\t\\\n \t(!((bp)->tunnel_disable_flag & HWRM_FUNC_QCAPS_OUTPUT_TUNNEL_DISABLE_FLAG_DISABLE_VXLAN))\n@@ -227,6 +251,8 @@ int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,\n int bnxt_hwrm_func_qcfg_current_vf_vlan(struct bnxt *bp, int vf);\n int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,\n \t\t\t\tuint8_t tunnel_type);\n+int bnxt_hwrm_tunnel_upar_id_get(struct bnxt *bp, uint8_t *upar_id,\n+\t\t\t\t uint8_t tunnel_type);\n int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,\n \t\t\t\tuint8_t tunnel_type);\n int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf);\ndiff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c\nindex 4cdbb177d9..686c3af4da 100644\n--- a/drivers/net/bnxt/bnxt_ring.c\n+++ b/drivers/net/bnxt/bnxt_ring.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -54,7 +54,7 @@ int bnxt_alloc_ring_grps(struct bnxt *bp)\n \t\treturn -EBUSY;\n \t}\n \n-\t/* THOR does not support ring groups.\n+\t/* P5 does not support ring groups.\n \t * But we will use the array to save RSS context IDs.\n \t */\n \tif (BNXT_CHIP_P5(bp)) {\ndiff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c\nindex 99758dd304..0d0b5e28e4 100644\n--- a/drivers/net/bnxt/bnxt_rxq.c\n+++ b/drivers/net/bnxt/bnxt_rxq.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -400,7 +400,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,\n \t\trxq->rx_deferred_start = rx_conf->rx_deferred_start;\n \n \trxq->rx_started = rxq->rx_deferred_start ? false : true;\n-\trxq->vnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\trxq->vnic = bnxt_get_default_vnic(bp);\n \n \treturn 0;\n err:\n@@ -460,6 +460,8 @@ int bnxt_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)\n \tstruct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;\n \tstruct bnxt_rx_queue *rxq = bp->rx_queues[rx_queue_id];\n \tstruct bnxt_vnic_info *vnic = NULL;\n+\tuint16_t vnic_idx = 0;\n+\tuint16_t fw_grp_id = 0;\n \tint rc = 0;\n \n \trc = is_bnxt_in_error(bp);\n@@ -471,6 +473,13 @@ int bnxt_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)\n \t\treturn -EINVAL;\n \t}\n \n+\tvnic = bnxt_vnic_queue_id_get_next(bp, rx_queue_id, &vnic_idx);\n+\tif (vnic == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"VNIC not initialized for RxQ %d\\n\",\n+\t\t\t    rx_queue_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n \t/* reset the previous stats for the rx_queue since the counters\n \t * will be cleared when the queue is started.\n \t */\n@@ -490,29 +499,37 @@ int bnxt_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)\n \t\treturn rc;\n \n \tif (BNXT_HAS_RING_GRPS(bp))\n-\t\trxq->vnic->dflt_ring_grp = bp->grp_info[rx_queue_id].fw_grp_id;\n-\t/* Reconfigure default receive ring and MRU. */\n-\tbnxt_hwrm_vnic_cfg(bp, rxq->vnic);\n-\n-\tPMD_DRV_LOG(INFO, \"Rx queue started %d\\n\", rx_queue_id);\n+\t\tfw_grp_id = bp->grp_info[rx_queue_id].fw_grp_id;\n \n-\tif (dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) {\n-\t\tvnic = rxq->vnic;\n+\tdo {\n+\t\tif (BNXT_HAS_RING_GRPS(bp))\n+\t\t\tvnic->dflt_ring_grp = fw_grp_id;\n+\t\t/* Reconfigure default receive ring and MRU. */\n+\t\tbnxt_hwrm_vnic_cfg(bp, vnic);\n+\n+\t\tPMD_DRV_LOG(INFO, \"Rx queue started %d\\n\", rx_queue_id);\n+\n+\t\tif (dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) {\n+\t\t\tif (BNXT_HAS_RING_GRPS(bp)) {\n+\t\t\t\tif (vnic->fw_grp_ids[rx_queue_id] !=\n+\t\t\t\t    INVALID_HW_RING_ID) {\n+\t\t\t\t\tPMD_DRV_LOG(ERR, \"invalid ring id %d\\n\",\n+\t\t\t\t\t\t    rx_queue_id);\n+\t\t\t\t\treturn 0;\n+\t\t\t\t}\n \n-\t\tif (BNXT_HAS_RING_GRPS(bp)) {\n-\t\t\tif (vnic->fw_grp_ids[rx_queue_id] != INVALID_HW_RING_ID)\n-\t\t\t\treturn 0;\n+\t\t\t\tvnic->fw_grp_ids[rx_queue_id] = fw_grp_id;\n+\t\t\t\tPMD_DRV_LOG(DEBUG, \"vnic = %p fw_grp_id = %d\\n\",\n+\t\t\t\t\t    vnic, fw_grp_id);\n+\t\t\t}\n \n-\t\t\tvnic->fw_grp_ids[rx_queue_id] =\n-\t\t\t\t\tbp->grp_info[rx_queue_id].fw_grp_id;\n-\t\t\tPMD_DRV_LOG(DEBUG,\n-\t\t\t\t    \"vnic = %p fw_grp_id = %d\\n\",\n-\t\t\t\t    vnic, bp->grp_info[rx_queue_id].fw_grp_id);\n+\t\t\tPMD_DRV_LOG(DEBUG, \"Rx Queue Count %d\\n\",\n+\t\t\t\t    vnic->rx_queue_cnt);\n+\t\t\trc += bnxt_vnic_rss_queue_status_update(bp, vnic);\n \t\t}\n-\n-\t\tPMD_DRV_LOG(DEBUG, \"Rx Queue Count %d\\n\", vnic->rx_queue_cnt);\n-\t\trc = bnxt_vnic_rss_configure(bp, vnic);\n-\t}\n+\t\tvnic_idx++;\n+\t} while ((vnic = bnxt_vnic_queue_id_get_next(bp, rx_queue_id,\n+\t\t\t\t\t\t     &vnic_idx)) != NULL);\n \n \tif (rc != 0) {\n \t\tdev->data->rx_queue_state[rx_queue_id] =\n@@ -535,6 +552,7 @@ int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)\n \tstruct bnxt_vnic_info *vnic = NULL;\n \tstruct bnxt_rx_queue *rxq = NULL;\n \tint active_queue_cnt = 0;\n+\tuint16_t vnic_idx = 0, q_id = rx_queue_id;\n \tint i, rc = 0;\n \n \trc = is_bnxt_in_error(bp);\n@@ -556,61 +574,64 @@ int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)\n \t\treturn -EINVAL;\n \t}\n \n-\tvnic = rxq->vnic;\n+\tvnic = bnxt_vnic_queue_id_get_next(bp, q_id, &vnic_idx);\n \tif (!vnic) {\n-\t\tPMD_DRV_LOG(ERR, \"VNIC not initialized for RxQ %d\\n\",\n-\t\t\t    rx_queue_id);\n+\t\tPMD_DRV_LOG(ERR, \"VNIC not initialized for RxQ %d\\n\", q_id);\n \t\treturn -EINVAL;\n \t}\n \n-\tdev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;\n+\tdev->data->rx_queue_state[q_id] = RTE_ETH_QUEUE_STATE_STOPPED;\n \trxq->rx_started = false;\n \tPMD_DRV_LOG(DEBUG, \"Rx queue stopped\\n\");\n \n-\tif (dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) {\n-\t\tif (BNXT_HAS_RING_GRPS(bp))\n-\t\t\tvnic->fw_grp_ids[rx_queue_id] = INVALID_HW_RING_ID;\n-\n-\t\tPMD_DRV_LOG(DEBUG, \"Rx Queue Count %d\\n\", vnic->rx_queue_cnt);\n-\t\trc = bnxt_vnic_rss_configure(bp, vnic);\n-\t}\n-\n-\t/* Compute current number of active receive queues. */\n-\tfor (i = vnic->start_grp_id; i < vnic->end_grp_id; i++)\n-\t\tif (bp->rx_queues[i]->rx_started)\n-\t\t\tactive_queue_cnt++;\n+\tdo {\n+\t\tactive_queue_cnt = 0;\n+\t\tif (dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) {\n+\t\t\tif (BNXT_HAS_RING_GRPS(bp))\n+\t\t\t\tvnic->fw_grp_ids[q_id] = INVALID_HW_RING_ID;\n \n-\tif (BNXT_CHIP_P5(bp)) {\n-\t\t/*\n-\t\t * For Thor, we need to ensure that the VNIC default receive\n-\t\t * ring corresponds to an active receive queue. When no queue\n-\t\t * is active, we need to temporarily set the MRU to zero so\n-\t\t * that packets are dropped early in the receive pipeline in\n-\t\t * order to prevent the VNIC default receive ring from being\n-\t\t * accessed.\n-\t\t */\n-\t\tif (active_queue_cnt == 0) {\n-\t\t\tuint16_t saved_mru = vnic->mru;\n-\n-\t\t\t/* clear RSS setting on vnic. */\n-\t\t\tbnxt_vnic_rss_clear_p5(bp, vnic);\n-\n-\t\t\tvnic->mru = 0;\n-\t\t\t/* Reconfigure default receive ring and MRU. */\n-\t\t\tbnxt_hwrm_vnic_cfg(bp, vnic);\n-\t\t\tvnic->mru = saved_mru;\n-\t\t} else {\n-\t\t\t/* Reconfigure default receive ring. */\n-\t\t\tbnxt_hwrm_vnic_cfg(bp, vnic);\n+\t\t\tPMD_DRV_LOG(DEBUG, \"Rx Queue Count %d\\n\",\n+\t\t\t\t    vnic->rx_queue_cnt);\n+\t\t\trc = bnxt_vnic_rss_queue_status_update(bp, vnic);\n \t\t}\n-\t} else if (active_queue_cnt) {\n-\t\t/*\n-\t\t * If the queue being stopped is the current default queue and\n-\t\t * there are other active queues, pick one of them as the\n-\t\t * default and reconfigure the vnic.\n-\t\t */\n-\t\tif (vnic->dflt_ring_grp == bp->grp_info[rx_queue_id].fw_grp_id) {\n-\t\t\tfor (i = vnic->start_grp_id; i < vnic->end_grp_id; i++) {\n+\n+\t\t/* Compute current number of active receive queues. */\n+\t\tfor (i = vnic->start_grp_id; i < vnic->end_grp_id; i++)\n+\t\t\tif (bp->rx_queues[i]->rx_started)\n+\t\t\t\tactive_queue_cnt++;\n+\n+\t\tif (BNXT_CHIP_P5(bp)) {\n+\t\t\t/*\n+\t\t\t * For P5, we need to ensure that the VNIC default\n+\t\t\t * receive ring corresponds to an active receive queue.\n+\t\t\t * When no queue is active, we need to temporarily set\n+\t\t\t * the MRU to zero so that packets are dropped early in\n+\t\t\t * the receive pipeline in order to prevent the VNIC\n+\t\t\t * default receive ring from being accessed.\n+\t\t\t */\n+\t\t\tif (active_queue_cnt == 0) {\n+\t\t\t\tuint16_t saved_mru = vnic->mru;\n+\n+\t\t\t\t/* clear RSS setting on vnic. */\n+\t\t\t\tbnxt_vnic_rss_clear_p5(bp, vnic);\n+\n+\t\t\t\tvnic->mru = 0;\n+\t\t\t\t/* Reconfigure default receive ring and MRU. */\n+\t\t\t\tbnxt_hwrm_vnic_cfg(bp, vnic);\n+\t\t\t\tvnic->mru = saved_mru;\n+\t\t\t} else {\n+\t\t\t\t/* Reconfigure default receive ring. */\n+\t\t\t\tbnxt_hwrm_vnic_cfg(bp, vnic);\n+\t\t\t}\n+\t\t} else if (active_queue_cnt && vnic->dflt_ring_grp ==\n+\t\t\t   bp->grp_info[q_id].fw_grp_id) {\n+\t\t\t/*\n+\t\t\t * If the queue being stopped is the current default\n+\t\t\t * queue and there are other active queues, pick one of\n+\t\t\t * them as the default and reconfigure the vnic.\n+\t\t\t */\n+\t\t\tfor (i = vnic->start_grp_id; i < vnic->end_grp_id;\n+\t\t\t      i++) {\n \t\t\t\tif (bp->rx_queues[i]->rx_started) {\n \t\t\t\t\tvnic->dflt_ring_grp =\n \t\t\t\t\t\tbp->grp_info[i].fw_grp_id;\n@@ -619,7 +640,9 @@ int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)\n \t\t\t\t}\n \t\t\t}\n \t\t}\n-\t}\n+\t\tvnic_idx++;\n+\t} while ((vnic = bnxt_vnic_queue_id_get_next(bp, q_id,\n+\t\t\t\t\t\t     &vnic_idx)) != NULL);\n \n \tif (rc == 0)\n \t\tbnxt_rx_queue_release_mbufs(rxq);\ndiff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c\nindex a067278dca..1ab0ef2f5d 100644\n--- a/drivers/net/bnxt/bnxt_rxr.c\n+++ b/drivers/net/bnxt/bnxt_rxr.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -691,7 +691,7 @@ static void\n bnxt_get_rx_ts_p5(struct bnxt *bp, uint32_t rx_ts_cmpl)\n {\n \tstruct bnxt_ptp_cfg *ptp = bp->ptp_cfg;\n-\tuint64_t last_hwrm_time;\n+\tuint64_t last_hwrm_time = 0;\n \tuint64_t pkt_time = 0;\n \n \tif (!BNXT_CHIP_P5(bp) || !ptp)\n@@ -705,7 +705,6 @@ bnxt_get_rx_ts_p5(struct bnxt *bp, uint32_t rx_ts_cmpl)\n \t * from the HWRM response with the lower 32 bits in the\n \t * Rx completion to produce the 48 bit timestamp for the Rx packet\n \t */\n-\tlast_hwrm_time = ptp->current_time;\n \tpkt_time = (last_hwrm_time & BNXT_PTP_CURRENT_TIME_MASK) | rx_ts_cmpl;\n \tif (rx_ts_cmpl < (uint32_t)last_hwrm_time) {\n \t\t/* timer has rolled over */\n@@ -923,7 +922,7 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,\n \n \tif (unlikely((rte_le_to_cpu_16(rxcmp->flags_type) &\n \t\t      RX_PKT_CMPL_FLAGS_MASK) ==\n-\t\t     RX_PKT_CMPL_FLAGS_ITYPE_PTP_W_TIMESTAMP))\n+\t\t      RX_PKT_CMPL_FLAGS_ITYPE_PTP_W_TIMESTAMP))\n \t\tbnxt_get_rx_ts_p5(rxq->bp, rxcmp1->reorder);\n \n \tif (cmp_type == CMPL_BASE_TYPE_RX_L2_V2) {\n@@ -1089,6 +1088,7 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,\n \t\t\tbreak;\n \t}\n \n+\tcpr->cp_raw_cons = raw_cons;\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@@ -1097,7 +1097,6 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,\n \t\tgoto done;\n \t}\n \n-\tcpr->cp_raw_cons = raw_cons;\n \t/* Ring the completion queue doorbell. */\n \tbnxt_db_cq(cpr);\n \ndiff --git a/drivers/net/bnxt/bnxt_txq.c b/drivers/net/bnxt/bnxt_txq.c\nindex c8745add5e..d1d1fe8f1f 100644\n--- a/drivers/net/bnxt/bnxt_txq.c\n+++ b/drivers/net/bnxt/bnxt_txq.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \ndiff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c\nindex 21c2217092..10b716a00b 100644\n--- a/drivers/net/bnxt/bnxt_txr.c\n+++ b/drivers/net/bnxt/bnxt_txr.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \ndiff --git a/drivers/net/bnxt/bnxt_txr.h b/drivers/net/bnxt/bnxt_txr.h\nindex 75456df5bd..b9b8a9b1a2 100644\n--- a/drivers/net/bnxt/bnxt_txr.h\n+++ b/drivers/net/bnxt/bnxt_txr.h\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \ndiff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c\nindex b3c03a2af5..be9c127b64 100644\n--- a/drivers/net/bnxt/bnxt_vnic.c\n+++ b/drivers/net/bnxt/bnxt_vnic.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -9,8 +9,26 @@\n #include <rte_malloc.h>\n \n #include \"bnxt.h\"\n+#include \"bnxt_rxq.h\"\n+#include \"bnxt_rxr.h\"\n+#include \"bnxt_ring.h\"\n #include \"bnxt_vnic.h\"\n #include \"hsi_struct_def_dpdk.h\"\n+#include \"bnxt_hwrm.h\"\n+\n+/* Macros to manipulate vnic bitmaps*/\n+#define BNXT_VNIC_BITMAP_SIZE\t64\n+#define BNXT_VNIC_BITMAP_SET(b, i)\t((b[(i) / BNXT_VNIC_BITMAP_SIZE]) |= \\\n+\t\t\t(1UL << ((BNXT_VNIC_BITMAP_SIZE - 1) - \\\n+\t\t\t((i) % BNXT_VNIC_BITMAP_SIZE))))\n+\n+#define BNXT_VNIC_BITMAP_RESET(b, i)\t((b[(i) / BNXT_VNIC_BITMAP_SIZE]) &= \\\n+\t\t\t(~(1UL << ((BNXT_VNIC_BITMAP_SIZE - 1) - \\\n+\t\t\t((i) % BNXT_VNIC_BITMAP_SIZE)))))\n+\n+#define BNXT_VNIC_BITMAP_GET(b, i)\t(((b[(i) / BNXT_VNIC_BITMAP_SIZE]) >> \\\n+\t\t\t((BNXT_VNIC_BITMAP_SIZE - 1) - \\\n+\t\t\t((i) % BNXT_VNIC_BITMAP_SIZE))) & 1)\n \n /*\n  * VNIC Functions\n@@ -51,6 +69,8 @@ static void bnxt_init_vnics(struct bnxt *bp)\n \t\tvnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;\n \t\tvnic->hash_mode =\n \t\t\tHWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT;\n+\t\tvnic->prev_hash_mode =\n+\t\t\tHWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT;\n \t\tvnic->rx_queue_cnt = 0;\n \n \t\tSTAILQ_INIT(&vnic->filter);\n@@ -84,6 +104,11 @@ void bnxt_free_all_vnics(struct bnxt *bp)\n \tfor (i = 0; i < bp->max_vnics; i++) {\n \t\tvnic = &bp->vnic_info[i];\n \t\tSTAILQ_INSERT_TAIL(&bp->free_vnic_list, vnic, next);\n+\t\tif (vnic->ref_cnt) {\n+\t\t\t/* clean up the default vnic details */\n+\t\t\tbnxt_vnic_rss_action_free(bp, i);\n+\t\t}\n+\n \t\tvnic->rx_queue_cnt = 0;\n \t}\n }\n@@ -212,6 +237,7 @@ int bnxt_alloc_vnic_mem(struct bnxt *bp)\n int bnxt_vnic_grp_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)\n {\n \tuint32_t size = sizeof(*vnic->fw_grp_ids) * bp->max_ring_grps;\n+\tuint32_t i;\n \n \tvnic->fw_grp_ids = rte_zmalloc(\"vnic_fw_grp_ids\", size, 0);\n \tif (!vnic->fw_grp_ids) {\n@@ -220,7 +246,10 @@ int bnxt_vnic_grp_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)\n \t\t\t    size);\n \t\treturn -ENOMEM;\n \t}\n-\tmemset(vnic->fw_grp_ids, -1, size);\n+\n+\t/* Initialize to invalid ring id */\n+\tfor (i = 0; i < bp->max_ring_grps; i++)\n+\t\tvnic->fw_grp_ids[i] = INVALID_HW_RING_ID;\n \n \treturn 0;\n }\n@@ -259,30 +288,27 @@ int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t hash_f, uint32_t lvl)\n \t/* If FW has not advertised capability to configure outer/inner\n \t * RSS hashing , just log a message. HW will work in default RSS mode.\n \t */\n-\tif (!(bp->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS)) {\n-\t\tPMD_DRV_LOG(ERR, \"RSS hash level cannot be configured\\n\");\n+\tif ((BNXT_CHIP_P5(bp) && BNXT_VNIC_OUTER_RSS_UNSUPPORTED(bp)) ||\n+\t    (!BNXT_CHIP_P5(bp) && !(bp->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS))) {\n+\t\tif (lvl)\n+\t\t\tPMD_DRV_LOG(INFO,\n+\t\t\t\t    \"Given RSS level is unsupported, using default RSS level\\n\");\n \t\treturn mode;\n \t}\n \n \tswitch (lvl) {\n \tcase BNXT_RSS_LEVEL_INNERMOST:\n-\t\tif (l3_and_l4 || l4)\n-\t\t\tmode =\n-\t\t\tHWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_4;\n-\t\telse if (l3_only)\n-\t\t\tmode =\n-\t\t\tHWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_2;\n+\t\t/* Irrespective of what RTE says, FW always does 4 tuple */\n+\t\tif (l3_and_l4 || l4 || l3_only)\n+\t\t\tmode = BNXT_HASH_MODE_INNERMOST;\n \t\tbreak;\n \tcase BNXT_RSS_LEVEL_OUTERMOST:\n-\t\tif (l3_and_l4 || l4)\n-\t\t\tmode =\n-\t\t\tHWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_4;\n-\t\telse if (l3_only)\n-\t\t\tmode =\n-\t\t\tHWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_2;\n+\t\t/* Irrespective of what RTE says, FW always does 4 tuple */\n+\t\tif (l3_and_l4 || l4 || l3_only)\n+\t\t\tmode = BNXT_HASH_MODE_OUTERMOST;\n \t\tbreak;\n \tdefault:\n-\t\tmode = HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT;\n+\t\tmode = BNXT_HASH_MODE_DEFAULT;\n \t\tbreak;\n \t}\n \n@@ -296,7 +322,8 @@ uint64_t bnxt_hwrm_to_rte_rss_level(struct bnxt *bp, uint32_t mode)\n \t/* If FW has not advertised capability to configure inner/outer RSS\n \t * return default hash mode.\n \t */\n-\tif (!(bp->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS))\n+\tif ((BNXT_CHIP_P5(bp) && BNXT_VNIC_OUTER_RSS_UNSUPPORTED(bp)) ||\n+\t    (!BNXT_CHIP_P5(bp) && !(bp->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS)))\n \t\treturn RTE_ETH_RSS_LEVEL_PMD_DEFAULT;\n \n \tif (mode == HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_2 ||\n@@ -310,3 +337,909 @@ uint64_t bnxt_hwrm_to_rte_rss_level(struct bnxt *bp, uint32_t mode)\n \n \treturn rss_level;\n }\n+\n+static\n+int32_t bnxt_vnic_populate_rss_table_p5(struct bnxt *bp,\n+\t\t\t\t\tstruct bnxt_vnic_info *vnic)\n+{\n+\tuint32_t ctx_idx = 0, rss_idx = 0, cnt = 0;\n+\tuint32_t q_id = -1;\n+\tstruct bnxt_rx_queue *rxq;\n+\tuint16_t *ring_tbl = vnic->rss_table;\n+\tuint8_t *rx_queue_state = bp->eth_dev->data->rx_queue_state;\n+\tuint16_t ring_id;\n+\n+\t/* For P5 platform */\n+\tfor (ctx_idx = 0; ctx_idx < vnic->num_lb_ctxts; ctx_idx++) {\n+\t\tfor (rss_idx = 0; rss_idx < BNXT_RSS_ENTRIES_PER_CTX_P5;\n+\t\t      rss_idx++) {\n+\t\t\t/* Find next active ring. */\n+\t\t\tfor (cnt = 0; cnt < BNXT_VNIC_MAX_QUEUE_SIZE; cnt++) {\n+\t\t\t\tif (++q_id == bp->rx_nr_rings)\n+\t\t\t\t\tq_id = 0; /* reset the q_id */\n+\t\t\t\tif (BNXT_VNIC_BITMAP_GET(vnic->queue_bitmap,\n+\t\t\t\t\t\t\t q_id) &&\n+\t\t\t\t    rx_queue_state[q_id] !=\n+\t\t\t\t\t\tRTE_ETH_QUEUE_STATE_STOPPED)\n+\t\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\t/* no active queues exit */\n+\t\t\tif (cnt == BNXT_VNIC_MAX_QUEUE_SIZE)\n+\t\t\t\treturn 0;\n+\n+\t\t\trxq = bp->rx_queues[q_id];\n+\t\t\tring_id = rxq->rx_ring->rx_ring_struct->fw_ring_id;\n+\t\t\t*ring_tbl++ = rte_cpu_to_le_16(ring_id);\n+\t\t\tring_id = rxq->cp_ring->cp_ring_struct->fw_ring_id;\n+\t\t\t*ring_tbl++ = rte_cpu_to_le_16(ring_id);\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+static\n+int32_t bnxt_vnic_populate_rss_table_p4(struct bnxt *bp,\n+\t\t\t\t\tstruct bnxt_vnic_info *vnic)\n+{\n+\tuint32_t rss_idx = 0, cnt = 0;\n+\tuint32_t q_id = -1;\n+\tuint16_t *ring_tbl = vnic->rss_table;\n+\tuint8_t *rx_queue_state = bp->eth_dev->data->rx_queue_state;\n+\tuint16_t ring_id;\n+\n+\t/* For Wh+ platform */\n+\tfor (rss_idx = 0; rss_idx < bnxt_rss_hash_tbl_size(bp); rss_idx++) {\n+\t\t/* Find next active ring. */\n+\t\tfor (cnt = 0; cnt < BNXT_VNIC_MAX_QUEUE_SIZE; cnt++) {\n+\t\t\tif (++q_id == bp->rx_nr_rings)\n+\t\t\t\tq_id = 0; /* reset the q_id */\n+\t\t\tif (BNXT_VNIC_BITMAP_GET(vnic->queue_bitmap,\n+\t\t\t\t\t\t q_id) &&\n+\t\t\t    rx_queue_state[q_id] !=\n+\t\t\t\t\tRTE_ETH_QUEUE_STATE_STOPPED)\n+\t\t\t\tbreak;\n+\t\t}\n+\n+\t\t/* no active queues exit */\n+\t\tif (cnt == BNXT_VNIC_MAX_QUEUE_SIZE)\n+\t\t\treturn 0;\n+\n+\t\tring_id = vnic->fw_grp_ids[q_id];\n+\t\t*ring_tbl++ = rte_cpu_to_le_16(ring_id);\n+\t}\n+\treturn 0;\n+}\n+\n+static\n+int32_t bnxt_vnic_populate_rss_table(struct bnxt *bp,\n+\t\t\t\t     struct bnxt_vnic_info *vnic)\n+{\n+\t/* RSS table population is different for p4 and p5 platforms */\n+\tif (BNXT_CHIP_P5(bp))\n+\t\treturn bnxt_vnic_populate_rss_table_p5(bp, vnic);\n+\n+\treturn bnxt_vnic_populate_rss_table_p4(bp, vnic);\n+}\n+\n+static void\n+bnxt_vnic_queue_delete(struct bnxt *bp, uint16_t vnic_idx)\n+{\n+\tstruct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_idx];\n+\n+\tif (bnxt_hwrm_vnic_free(bp, vnic))\n+\t\tPMD_DRV_LOG(ERR, \"Failed to delete queue\\n\");\n+\n+\tif (vnic->fw_grp_ids) {\n+\t\trte_free(vnic->fw_grp_ids);\n+\t\tvnic->fw_grp_ids = NULL;\n+\t}\n+\n+\tvnic->rx_queue_cnt = 0;\n+\tif (bp->nr_vnics)\n+\t\tbp->nr_vnics--;\n+\n+\t/* reset the queue_bitmap */\n+\tmemset(vnic->queue_bitmap, 0, sizeof(vnic->queue_bitmap));\n+}\n+\n+static struct bnxt_vnic_info*\n+bnxt_vnic_queue_create(struct bnxt *bp, int32_t vnic_id, uint16_t q_index)\n+{\n+\tuint8_t *rx_queue_state = bp->eth_dev->data->rx_queue_state;\n+\tstruct bnxt_vnic_info *vnic;\n+\tstruct bnxt_rx_queue *rxq = NULL;\n+\tint32_t rc = -EINVAL;\n+\tuint16_t saved_mru = 0;\n+\n+\tvnic = &bp->vnic_info[vnic_id];\n+\tif (vnic->rx_queue_cnt) {\n+\t\tPMD_DRV_LOG(ERR, \"invalid queue configuration %d\\n\", vnic_id);\n+\t\treturn NULL;\n+\t}\n+\n+\t/* set the queue_bitmap */\n+\tBNXT_VNIC_BITMAP_SET(vnic->queue_bitmap, q_index);\n+\n+\trxq = bp->rx_queues[q_index];\n+\tif (rx_queue_state[q_index] == RTE_ETH_QUEUE_STATE_STOPPED)\n+\t\trxq->rx_started = 0;\n+\telse\n+\t\trxq->rx_started = 1;\n+\n+\tvnic->rx_queue_cnt++;\n+\tvnic->start_grp_id = q_index;\n+\tvnic->end_grp_id = q_index + 1;\n+\tvnic->func_default = 0;\t/* This is not a default VNIC. */\n+\tbp->nr_vnics++;\n+\n+\t/* Allocate vnic group for p4 platform */\n+\trc = bnxt_vnic_grp_alloc(bp, vnic);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Failed to allocate vnic groups\\n\");\n+\t\tgoto cleanup;\n+\t}\n+\n+\t/* populate the fw group table */\n+\tbnxt_vnic_ring_grp_populate(bp, vnic);\n+\tbnxt_vnic_rules_init(vnic);\n+\n+\trc = bnxt_hwrm_vnic_alloc(bp, vnic);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Failed to allocate vnic %d\\n\", q_index);\n+\t\tgoto cleanup;\n+\t}\n+\n+\t/* store the mru so we can set it to zero in hw */\n+\tif (rxq->rx_started == 0) {\n+\t\tsaved_mru = vnic->mru;\n+\t\tvnic->mru = 0;\n+\t}\n+\n+\trc = bnxt_hwrm_vnic_cfg(bp, vnic);\n+\tif (rxq->rx_started == 0)\n+\t\tvnic->mru = saved_mru;\n+\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Failed to configure vnic %d\\n\", q_index);\n+\t\tgoto cleanup;\n+\t}\n+\n+\trc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Failed to configure vnic plcmode %d\\n\",\n+\t\t\t    q_index);\n+\t\tgoto cleanup;\n+\t}\n+\n+\tvnic->ref_cnt++;\n+\treturn vnic;\n+\n+cleanup:\n+\tbnxt_vnic_queue_delete(bp, vnic_id);\n+\treturn NULL;\n+}\n+\n+static inline int32_t\n+bnxt_vnic_queue_db_lookup(struct bnxt *bp, uint64_t *q_list)\n+{\n+\t/* lookup in the database to check if it is in use */\n+\treturn rte_hash_lookup(bp->vnic_queue_db.rss_q_db,\n+\t\t\t       (const void *)q_list);\n+}\n+\n+static inline int32_t\n+bnxt_vnic_queue_db_del(struct bnxt *bp, uint64_t *q_list)\n+{\n+\treturn rte_hash_del_key(bp->vnic_queue_db.rss_q_db,\n+\t\t\t\t(const void *)q_list);\n+}\n+\n+static int32_t\n+bnxt_vnic_queue_db_add(struct bnxt *bp, uint64_t *q_list)\n+{\n+\tstruct bnxt_vnic_info *vnic_info;\n+\tint32_t vnic_id, rc = -1;\n+\n+\tvnic_id = rte_hash_add_key(bp->vnic_queue_db.rss_q_db,\n+\t\t\t\t   (const void *)q_list);\n+\n+\tif (vnic_id < 0 || vnic_id >= bp->max_vnics) {\n+\t\tPMD_DRV_LOG(DEBUG, \"unable to assign vnic index %d\\n\",\n+\t\t\t    vnic_id);\n+\t\treturn rc;\n+\t}\n+\n+\tvnic_info = &bp->vnic_info[vnic_id];\n+\tif (vnic_info->fw_vnic_id != INVALID_HW_RING_ID) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Invalid ring id for %d.\\n\", vnic_id);\n+\t\treturn rc;\n+\t}\n+\treturn vnic_id;\n+}\n+\n+/* Function to validate the incoming rss configuration */\n+static\n+int32_t bnxt_vnic_queue_db_rss_validate(struct bnxt *bp,\n+\t\t\t\t\tstruct bnxt_vnic_rss_info *rss_info,\n+\t\t\t\t\tint32_t *vnic_idx)\n+{\n+\tstruct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;\n+\tint32_t rc = -EINVAL;\n+\tuint32_t idx = 0;\n+\tint32_t out_idx;\n+\n+\tif (!(dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS)) {\n+\t\tPMD_DRV_LOG(ERR, \"Error Rss is not supported on this port\\n\");\n+\t\treturn rc;\n+\t}\n+\n+\t/* rss queue is zero then use the default vnic */\n+\tif (rss_info->queue_num == 0) {\n+\t\t*vnic_idx = 0;\n+\t\treturn 0;\n+\t}\n+\n+\t/* Check to see if the queues id are in supported range */\n+\tif (rss_info->queue_num > bp->rx_nr_rings) {\n+\t\tPMD_DRV_LOG(ERR, \"Error unsupported queue num.\\n\");\n+\t\treturn rc;\n+\t}\n+\n+\t/* validate the queue ids are in correct range */\n+\tfor (idx = 0; idx < BNXT_VNIC_MAX_QUEUE_SIZE; idx++) {\n+\t\tif (BNXT_VNIC_BITMAP_GET(rss_info->queue_list, idx)) {\n+\t\t\tif (idx >= bp->rx_nr_rings) {\n+\t\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t\t    \"Error %d beyond support size %u\\n\",\n+\t\t\t\t\t    idx, bp->rx_nr_rings);\n+\t\t\t\treturn rc;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\t/* check if the vnic already exist */\n+\tout_idx = bnxt_vnic_queue_db_lookup(bp, rss_info->queue_list);\n+\tif (out_idx < 0 || out_idx >= bp->max_vnics)\n+\t\treturn -ENOENT; /* entry not found */\n+\n+\t/* found an entry */\n+\t*vnic_idx = out_idx;\n+\treturn 0;\n+}\n+\n+static void\n+bnxt_vnic_rss_delete(struct bnxt *bp, uint16_t q_index)\n+{\n+\tstruct bnxt_vnic_info *vnic;\n+\n+\tvnic = &bp->vnic_info[q_index];\n+\tif (vnic->rx_queue_cnt >= 1)\n+\t\tbnxt_hwrm_vnic_ctx_free(bp, vnic);\n+\n+\tif (vnic->fw_vnic_id != INVALID_HW_RING_ID)\n+\t\tbnxt_hwrm_vnic_free(bp, vnic);\n+\n+\tif (vnic->fw_grp_ids) {\n+\t\trte_free(vnic->fw_grp_ids);\n+\t\tvnic->fw_grp_ids = NULL;\n+\t}\n+\n+\t/* Update the vnic details for all the rx queues */\n+\tvnic->rx_queue_cnt = 0;\n+\tmemset(vnic->queue_bitmap, 0, sizeof(vnic->queue_bitmap));\n+\n+\tif (bp->nr_vnics)\n+\t\tbp->nr_vnics--;\n+}\n+\n+/* The validation of the rss_info should be done before calling this function*/\n+\n+static struct bnxt_vnic_info *\n+bnxt_vnic_rss_create(struct bnxt *bp,\n+\t\t     struct bnxt_vnic_rss_info *rss_info,\n+\t\t     uint16_t vnic_id)\n+{\n+\tuint8_t *rx_queue_state = bp->eth_dev->data->rx_queue_state;\n+\tstruct bnxt_vnic_info *vnic;\n+\tstruct bnxt_rx_queue *rxq = NULL;\n+\tuint32_t idx, nr_ctxs, config_rss = 0;\n+\tuint16_t saved_mru = 0;\n+\tuint16_t active_q_cnt = 0;\n+\tint16_t first_q = -1;\n+\tint16_t end_q = -1;\n+\tint32_t rc = 0;\n+\n+\t/* Assign the vnic to be used for this rss configuration */\n+\tvnic = &bp->vnic_info[vnic_id];\n+\n+\t/* Update the vnic details for all the rx queues */\n+\tfor (idx = 0; idx < BNXT_VNIC_MAX_QUEUE_SIZE; idx++) {\n+\t\tif (BNXT_VNIC_BITMAP_GET(rss_info->queue_list, idx)) {\n+\t\t\trxq = bp->rx_queues[idx];\n+\t\t\tif (rx_queue_state[idx] ==\n+\t\t\t    RTE_ETH_QUEUE_STATE_STOPPED) {\n+\t\t\t\trxq->rx_started = 0;\n+\t\t\t} else {\n+\t\t\t\trxq->rx_started = 1;\n+\t\t\t\tactive_q_cnt++;\n+\t\t\t}\n+\t\t\tvnic->rx_queue_cnt++;\n+\n+\t\t\t/* Update the queue list */\n+\t\t\tBNXT_VNIC_BITMAP_SET(vnic->queue_bitmap, idx);\n+\t\t\tif (first_q == -1)\n+\t\t\t\tfirst_q = idx;\n+\t\t\tend_q = idx;\n+\t\t}\n+\t}\n+\tvnic->start_grp_id = first_q;\n+\tvnic->end_grp_id = end_q + 1;\n+\tvnic->func_default = 0;\t/* This is not a default VNIC. */\n+\tbp->nr_vnics++;\n+\n+\t/* Allocate vnic group for p4 platform */\n+\trc = bnxt_vnic_grp_alloc(bp, vnic);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to allocate vnic groups\\n\");\n+\t\tgoto fail_cleanup;\n+\t}\n+\n+\t/* populate the fw group table */\n+\tbnxt_vnic_ring_grp_populate(bp, vnic);\n+\tbnxt_vnic_rules_init(vnic);\n+\n+\t/* Allocate the vnic in the firmware */\n+\trc = bnxt_hwrm_vnic_alloc(bp, vnic);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to allocate vnic %d\\n\", idx);\n+\t\tgoto fail_cleanup;\n+\t}\n+\n+\t/* Allocate the vnic rss context */\n+\t/* RSS table size in P5 is 512. Cap max Rx rings to same value */\n+\tnr_ctxs = bnxt_rss_ctxts(bp);\n+\tfor (idx = 0; idx < nr_ctxs; idx++) {\n+\t\trc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic, idx);\n+\t\tif (rc)\n+\t\t\tbreak;\n+\t}\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"HWRM ctx %d alloc failure rc: %x\\n\", idx, rc);\n+\t\tgoto fail_cleanup;\n+\t}\n+\tvnic->num_lb_ctxts = nr_ctxs;\n+\n+\tsaved_mru = vnic->mru;\n+\tif (!active_q_cnt)\n+\t\tvnic->mru = 0;\n+\n+\t/* configure the vnic details in firmware */\n+\trc = bnxt_hwrm_vnic_cfg(bp, vnic);\n+\tvnic->mru = saved_mru;\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to configure vnic %d\\n\", idx);\n+\t\tgoto fail_cleanup;\n+\t}\n+\n+\trc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to configure vnic plcmode %d\\n\",\n+\t\t\t    idx);\n+\t\tgoto fail_cleanup;\n+\t}\n+\n+\t/* hwrm_type conversion */\n+\tvnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_info->rss_types);\n+\tvnic->hash_mode = bnxt_rte_to_hwrm_hash_level(bp, rss_info->rss_types,\n+\t\t\t\t\t\t      rss_info->rss_level);\n+\n+\t/* configure the key */\n+\tif (!rss_info->key_len)\n+\t\t/* If hash key has not been specified, use random hash key.*/\n+\t\tbnxt_prandom_bytes(vnic->rss_hash_key, HW_HASH_KEY_SIZE);\n+\telse\n+\t\tmemcpy(vnic->rss_hash_key, rss_info->key, rss_info->key_len);\n+\n+\t/* Prepare the indirection table */\n+\tbnxt_vnic_populate_rss_table(bp, vnic);\n+\n+\t/* check to see if there is at least one queue that is active */\n+\tfor (idx = vnic->start_grp_id; idx < vnic->end_grp_id; idx++) {\n+\t\tif (bnxt_vnic_queue_id_is_valid(vnic, idx) &&\n+\t\t    bp->rx_queues[idx]->rx_started) {\n+\t\t\tconfig_rss = 1;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\t/* configure the rss table */\n+\tif (config_rss) {\n+\t\trc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);\n+\t\tif (rc) {\n+\t\t\tmemset(vnic->rss_hash_key, 0, HW_HASH_KEY_SIZE);\n+\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t    \"Failed to configure vnic rss details %d\\n\",\n+\t\t\t\t    idx);\n+\t\t\tgoto fail_cleanup;\n+\t\t}\n+\t}\n+\n+\tvnic->ref_cnt++;\n+\treturn vnic;\n+\n+fail_cleanup:\n+\tbnxt_vnic_rss_delete(bp, idx);\n+\treturn NULL;\n+}\n+\n+int32_t\n+bnxt_vnic_rss_queue_status_update(struct bnxt *bp, struct bnxt_vnic_info *vnic)\n+{\n+\tif (vnic->fw_vnic_id == INVALID_HW_RING_ID)\n+\t\treturn 0;\n+\n+\tif (!(vnic->rss_table && vnic->hash_type))\n+\t\treturn 0;\n+\n+\t/* Prepare the indirection table */\n+\tbnxt_vnic_populate_rss_table(bp, vnic);\n+\n+\t/* configure the rss table */\n+\tif (bnxt_hwrm_vnic_rss_cfg(bp, vnic)) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Failed to update vnic rss details\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\treturn 0;\n+}\n+\n+static int32_t\n+bnxt_vnic_rss_hash_algo_update(struct bnxt *bp,\n+\t\t\t       struct bnxt_vnic_info *vnic,\n+\t\t\t       struct bnxt_vnic_rss_info *rss_info)\n+{\n+\tuint8_t old_rss_hash_key[HW_HASH_KEY_SIZE] = { 0 };\n+\tuint16_t\thash_type;\n+\tuint8_t\t\thash_mode;\n+\tuint32_t apply = 0;\n+\n+\t/* validate key length */\n+\tif (rss_info->key_len != 0 && rss_info->key_len != HW_HASH_KEY_SIZE) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"Invalid hashkey length, should be %d bytes\\n\",\n+\t\t\t    HW_HASH_KEY_SIZE);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* hwrm_type conversion */\n+\thash_type = bnxt_rte_to_hwrm_hash_types(rss_info->rss_types);\n+\thash_mode = bnxt_rte_to_hwrm_hash_level(bp, rss_info->rss_types,\n+\t\t\t\t\t\trss_info->rss_level);\n+\tif (vnic->hash_mode != hash_mode ||\n+\t    vnic->hash_type != hash_type) {\n+\t\tapply = 1;\n+\t\tvnic->hash_mode = hash_mode;\n+\t\tvnic->hash_type = hash_type;\n+\t}\n+\t/* Store the old hash key before programming the new one. It will\n+\t * be used to restore the old hash key when HWRM_VNIC_RSS_CFG\n+\t * fails.\n+\t */\n+\tmemcpy(old_rss_hash_key, vnic->rss_hash_key, HW_HASH_KEY_SIZE);\n+\tif (rss_info->key_len != 0 && memcmp(rss_info->key, vnic->rss_hash_key,\n+\t\t\t\t\t     HW_HASH_KEY_SIZE)) {\n+\t\tapply = 1;\n+\t\tmemcpy(vnic->rss_hash_key, rss_info->key, HW_HASH_KEY_SIZE);\n+\t}\n+\n+\tif (apply) {\n+\t\tif (bnxt_hwrm_vnic_rss_cfg(bp, vnic)) {\n+\t\t\tmemcpy(vnic->rss_hash_key, old_rss_hash_key, HW_HASH_KEY_SIZE);\n+\t\t\tBNXT_TF_DBG(ERR, \"Error configuring vnic RSS config\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tBNXT_TF_DBG(INFO, \"Rss config successfully applied\\n\");\n+\t}\n+\treturn 0;\n+}\n+\n+int32_t bnxt_vnic_queue_db_deinit(struct bnxt *bp)\n+{\n+\tif (bp->vnic_queue_db.rss_q_db != NULL)\n+\t\trte_hash_free(bp->vnic_queue_db.rss_q_db);\n+\treturn 0;\n+}\n+\n+int32_t bnxt_vnic_queue_db_init(struct bnxt *bp)\n+{\n+\tstruct rte_hash_parameters hash_tbl_params = {0};\n+\tchar hash_tbl_name[64] = {0};\n+\n+\t/* choose the least supported value */\n+\tif (bp->rx_nr_rings > BNXT_VNIC_MAX_QUEUE_SIZE)\n+\t\tbp->vnic_queue_db.num_queues = BNXT_VNIC_MAX_QUEUE_SIZE;\n+\telse\n+\t\tbp->vnic_queue_db.num_queues = bp->rx_nr_rings;\n+\n+\t/* create the hash table for the rss hash entries */\n+\tsnprintf(hash_tbl_name, sizeof(hash_tbl_name),\n+\t\t \"bnxt_rss_hash_%d\", bp->eth_dev->data->port_id);\n+\thash_tbl_params.name = hash_tbl_name;\n+\thash_tbl_params.entries = (bp->max_vnics > BNXT_VNIC_MAX_SUPPORTED_ID) ?\n+\t\tBNXT_VNIC_MAX_SUPPORTED_ID : bp->max_vnics;\n+\thash_tbl_params.key_len = BNXT_VNIC_MAX_QUEUE_SZ_IN_8BITS;\n+\thash_tbl_params.socket_id = rte_socket_id();\n+\tbp->vnic_queue_db.rss_q_db = rte_hash_create(&hash_tbl_params);\n+\tif (bp->vnic_queue_db.rss_q_db == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to create rss hash tbl\\n\");\n+\t\treturn -ENOMEM;\n+\t}\n+\treturn 0;\n+}\n+\n+void bnxt_vnic_queue_db_update_dlft_vnic(struct bnxt *bp)\n+{\n+\tstruct bnxt_vnic_info *dflt_vnic;\n+\tuint64_t bitmap[BNXT_VNIC_MAX_QUEUE_SZ_IN_64BITS];\n+\tuint32_t idx;\n+\tint32_t vnic_id;\n+\n+\t/* populate all the queue ids in the default vnic */\n+\tmemset(bitmap, 0, sizeof(bitmap));\n+\tfor (idx = 0; idx < bp->vnic_queue_db.num_queues; idx++)\n+\t\tBNXT_VNIC_BITMAP_SET(bitmap, idx);\n+\n+\tvnic_id  = bnxt_vnic_queue_db_add(bp, bitmap);\n+\tif (vnic_id < 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Unable to alloc vnic for default rss\\n\");\n+\t\treturn;\n+\t}\n+\n+\tdflt_vnic  = bnxt_vnic_queue_db_get_vnic(bp, vnic_id);\n+\tif (dflt_vnic == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid vnic for default rss %d\\n\", vnic_id);\n+\t\treturn;\n+\t}\n+\t/* Update the default vnic structure */\n+\tbp->vnic_queue_db.dflt_vnic_id = vnic_id;\n+\tmemcpy(dflt_vnic->queue_bitmap, bitmap, sizeof(bitmap));\n+\tdflt_vnic->rx_queue_cnt = bp->vnic_queue_db.num_queues;\n+\tdflt_vnic->ref_cnt++;\n+}\n+\n+int32_t bnxt_vnic_queue_action_alloc(struct bnxt *bp,\n+\t\t\t\t     uint16_t q_index,\n+\t\t\t\t     uint16_t *vnic_idx,\n+\t\t\t\t     uint16_t *vnicid)\n+{\n+\tuint64_t queue_list[BNXT_VNIC_MAX_QUEUE_SZ_IN_64BITS] = {0};\n+\tstruct bnxt_vnic_info *vnic_info;\n+\tint32_t idx;\n+\tint32_t rc = -EINVAL;\n+\n+\t/* validate the given queue id */\n+\tif (q_index >= bp->rx_nr_rings || q_index >= BNXT_VNIC_MAX_QUEUE_SIZE) {\n+\t\tPMD_DRV_LOG(ERR, \"invalid queue id should be less than %d\\n\",\n+\t\t\t    bp->rx_nr_rings);\n+\t\treturn rc;\n+\t}\n+\n+\t/* Populate the queue list */\n+\tBNXT_VNIC_BITMAP_SET(queue_list, q_index);\n+\n+\t/* check to see if the q_index is already in use */\n+\tidx = bnxt_vnic_queue_db_lookup(bp, queue_list);\n+\tif (idx < 0) {\n+\t\t/* Assign the vnic slot */\n+\t\tidx = bnxt_vnic_queue_db_add(bp, queue_list);\n+\t\tif (idx < 0) {\n+\t\t\tPMD_DRV_LOG(DEBUG, \"Unable to alloc vnic for queue\\n\");\n+\t\t\treturn rc;\n+\t\t}\n+\n+\t\t/* Allocate a new one */\n+\t\tvnic_info = bnxt_vnic_queue_create(bp, idx, q_index);\n+\t\tif (!vnic_info) {\n+\t\t\tPMD_DRV_LOG(ERR, \"failed to create vnic - %d\\n\",\n+\t\t\t\t    q_index);\n+\t\t\tbnxt_vnic_queue_db_del(bp, queue_list);\n+\t\t\treturn rc; /* failed */\n+\t\t}\n+\t} else {\n+\t\tvnic_info = bnxt_vnic_queue_db_get_vnic(bp, idx);\n+\t\tif (vnic_info == NULL) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Unable to lookup vnic for queue %d\\n\",\n+\t\t\t\t    q_index);\n+\t\t\treturn rc;\n+\t\t}\n+\t\t/* increment the reference count and return the vnic id */\n+\t\tvnic_info->ref_cnt++;\n+\t}\n+\t*vnic_idx = (uint16_t)idx;\n+\t*vnicid = vnic_info->fw_vnic_id;\n+\treturn 0;\n+}\n+\n+int32_t\n+bnxt_vnic_queue_action_free(struct bnxt *bp, uint16_t vnic_id)\n+{\n+\tstruct bnxt_vnic_info *vnic_info;\n+\tint32_t rc = -EINVAL;\n+\tint32_t vnic_idx = vnic_id, idx;\n+\n+\t/* validate the given vnic idx */\n+\tif (vnic_idx >= bp->max_vnics) {\n+\t\tPMD_DRV_LOG(ERR, \"invalid vnic idx %d\\n\", vnic_idx);\n+\t\treturn rc;\n+\t}\n+\n+\t/* validate the vnic info */\n+\tvnic_info = &bp->vnic_info[vnic_idx];\n+\tif (!vnic_info->rx_queue_cnt) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid vnic idx, no queues being used\\n\");\n+\t\treturn rc;\n+\t}\n+\tif (vnic_info->ref_cnt) {\n+\t\tvnic_info->ref_cnt--;\n+\t\tif (!vnic_info->ref_cnt) {\n+\t\t\tidx  = bnxt_vnic_queue_db_del(bp,\n+\t\t\t\t\t\t      vnic_info->queue_bitmap);\n+\t\t\t/* Check to ensure there is no corruption */\n+\t\t\tif (idx != vnic_idx)\n+\t\t\t\tPMD_DRV_LOG(ERR, \"bad vnic idx %d\\n\", vnic_idx);\n+\n+\t\t\tbnxt_vnic_queue_delete(bp, vnic_idx);\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+int32_t\n+bnxt_vnic_rss_action_alloc(struct bnxt *bp,\n+\t\t\t\t   struct bnxt_vnic_rss_info *rss_info,\n+\t\t\t\t   uint16_t *vnic_idx,\n+\t\t\t\t   uint16_t *vnicid)\n+{\n+\tstruct bnxt_vnic_info *vnic_info = NULL;\n+\tint32_t rc = -EINVAL;\n+\tint32_t idx;\n+\n+\t/* validate the given parameters */\n+\trc = bnxt_vnic_queue_db_rss_validate(bp, rss_info, &idx);\n+\tif (rc == -EINVAL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to apply the rss action.\\n\");\n+\t\treturn rc;\n+\t} else if (rc == -ENOENT) {\n+\t\t/* Allocate a new entry */\n+\t\tidx = bnxt_vnic_queue_db_add(bp, rss_info->queue_list);\n+\t\tif (idx < 0) {\n+\t\t\tPMD_DRV_LOG(DEBUG, \"Unable to alloc vnic for rss\\n\");\n+\t\t\treturn rc;\n+\t\t}\n+\t\t/* create the rss vnic */\n+\t\tvnic_info = bnxt_vnic_rss_create(bp, rss_info, idx);\n+\t\tif (!vnic_info) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Failed to create rss action.\\n\");\n+\t\t\tbnxt_vnic_queue_db_del(bp, rss_info->queue_list);\n+\t\t\treturn rc;\n+\t\t}\n+\t} else {\n+\t\tvnic_info = bnxt_vnic_queue_db_get_vnic(bp, idx);\n+\t\tif (vnic_info == NULL) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Unable to lookup vnic for idx %d\\n\",\n+\t\t\t\t    idx);\n+\t\t\treturn rc;\n+\t\t}\n+\t\t/* increment the reference count and return the vnic id */\n+\t\tvnic_info->ref_cnt++;\n+\n+\t\t/* check configuration has changed then update hash details */\n+\t\trc = bnxt_vnic_rss_hash_algo_update(bp, vnic_info, rss_info);\n+\t\tif (rc) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Failed to update the rss action.\\n\");\n+\t\t\treturn rc;\n+\t\t}\n+\t}\n+\t*vnic_idx = idx;\n+\t*vnicid = vnic_info->fw_vnic_id;\n+\treturn 0;\n+}\n+\n+/* Delete the vnic associated with the given rss action index */\n+int32_t\n+bnxt_vnic_rss_action_free(struct bnxt *bp, uint16_t vnic_id)\n+{\n+\tuint64_t bitmap[BNXT_VNIC_MAX_QUEUE_SZ_IN_64BITS];\n+\tstruct bnxt_vnic_info *vnic_info;\n+\tint32_t rc = -EINVAL;\n+\tuint64_t *q_list;\n+\tint32_t idx = 0;\n+\n+\t/* validate the given vnic id */\n+\tif (vnic_id >= bp->max_vnics) {\n+\t\tPMD_DRV_LOG(ERR, \"invalid vnic id %d\\n\", vnic_id);\n+\t\treturn rc;\n+\t}\n+\n+\t/* validate vnic info */\n+\tvnic_info = &bp->vnic_info[vnic_id];\n+\tif (!vnic_info->rx_queue_cnt) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid vnic id, not using any queues\\n\");\n+\t\treturn rc;\n+\t}\n+\n+\tif (vnic_info->ref_cnt) {\n+\t\tvnic_info->ref_cnt--;\n+\t\tif (!vnic_info->ref_cnt) {\n+\t\t\tif (bp->vnic_queue_db.dflt_vnic_id == vnic_id) {\n+\t\t\t\t/* in case of default queue, list can be\n+\t\t\t\t * changed by reta config so need a list\n+\t\t\t\t * with all queues populated.\n+\t\t\t\t */\n+\t\t\t\tmemset(bitmap, 0, sizeof(bitmap));\n+\t\t\t\tfor (idx = 0;\n+\t\t\t\t      idx < bp->vnic_queue_db.num_queues;\n+\t\t\t\t      idx++)\n+\t\t\t\t\tBNXT_VNIC_BITMAP_SET(bitmap, idx);\n+\t\t\t\tq_list = bitmap;\n+\t\t\t} else {\n+\t\t\t\tq_list = vnic_info->queue_bitmap;\n+\t\t\t}\n+\t\t\tidx  = bnxt_vnic_queue_db_del(bp, q_list);\n+\n+\t\t\t/* check to ensure there is no corruption */\n+\t\t\tif (idx != vnic_id)\n+\t\t\t\tPMD_DRV_LOG(ERR, \"bad vnic idx %d\\n\", vnic_id);\n+\t\t\tbnxt_vnic_rss_delete(bp, vnic_id);\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+int32_t\n+bnxt_vnic_reta_config_update(struct bnxt *bp,\n+\t\t\t\t     struct bnxt_vnic_info *vnic_info,\n+\t\t\t\t     struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t\t     uint16_t reta_size)\n+{\n+\tuint64_t l_bitmap[BNXT_VNIC_MAX_QUEUE_SZ_IN_64BITS] = {0};\n+\tuint16_t i, sft, idx;\n+\tuint16_t q_id;\n+\n+\tfor (i = 0; i < reta_size; i++) {\n+\t\tidx = i / RTE_ETH_RETA_GROUP_SIZE;\n+\t\tsft = i % RTE_ETH_RETA_GROUP_SIZE;\n+\n+\t\tif (!(reta_conf[idx].mask & (1ULL << sft)))\n+\t\t\tcontinue;\n+\n+\t\tq_id = reta_conf[idx].reta[sft];\n+\t\tif (q_id >= bp->vnic_queue_db.num_queues ||\n+\t\t    !bp->eth_dev->data->rx_queues[q_id]) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Queue id %d is invalid\\n\", q_id);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tBNXT_VNIC_BITMAP_SET(l_bitmap, q_id);\n+\t}\n+\t/* update the queue bitmap after the validation */\n+\tmemcpy(vnic_info->queue_bitmap, l_bitmap, sizeof(l_bitmap));\n+\treturn 0;\n+}\n+\n+int32_t\n+bnxt_vnic_queue_id_is_valid(struct bnxt_vnic_info *vnic_info,\n+\t\t\t\t    uint16_t queue_id)\n+{\n+\tif (BNXT_VNIC_BITMAP_GET(vnic_info->queue_bitmap, queue_id))\n+\t\treturn 1;\n+\treturn 0;\n+}\n+\n+void\n+bnxt_vnic_ring_grp_populate(struct bnxt *bp, struct bnxt_vnic_info *vnic)\n+{\n+\tuint32_t i;\n+\n+\t/* check if ring group is supported */\n+\tif (!BNXT_HAS_RING_GRPS(bp))\n+\t\treturn;\n+\n+\t/* map ring groups to this vnic */\n+\tfor (i = vnic->start_grp_id; i < vnic->end_grp_id; i++)\n+\t\tif (bnxt_vnic_queue_id_is_valid(vnic, i) &&\n+\t\t\tbp->rx_queues[i]->rx_started)\n+\t\t\tvnic->fw_grp_ids[i] = bp->grp_info[i].fw_grp_id;\n+\n+\tvnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;\n+}\n+\n+void\n+bnxt_vnic_rules_init(struct bnxt_vnic_info *vnic)\n+{\n+\tvnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;\n+\tvnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;\n+\tvnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;\n+}\n+\n+int32_t\n+bnxt_vnic_mru_config(struct bnxt *bp, uint16_t new_mtu)\n+{\n+\tstruct bnxt_vnic_info *vnic;\n+\tuint16_t size = 0;\n+\tint32_t rc = 0;\n+\tuint32_t i;\n+\n+\tfor (i = 0; i < bp->max_vnics; i++) {\n+\t\tvnic = &bp->vnic_info[i];\n+\t\tif (vnic->fw_vnic_id == INVALID_VNIC_ID)\n+\t\t\tcontinue;\n+\n+\t\tvnic->mru = BNXT_VNIC_MRU(new_mtu);\n+\t\trc = bnxt_hwrm_vnic_cfg(bp, vnic);\n+\t\tif (rc)\n+\t\t\tbreak;\n+\n+\t\tsize = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);\n+\t\tsize -= RTE_PKTMBUF_HEADROOM;\n+\n+\t\tif (size < new_mtu) {\n+\t\t\trc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);\n+\t\t\tif (rc)\n+\t\t\t\tbreak;\n+\t\t}\n+\t}\n+\treturn rc;\n+}\n+\n+struct bnxt_vnic_info *\n+bnxt_vnic_queue_db_get_vnic(struct bnxt *bp, uint16_t vnic_idx)\n+{\n+\tstruct bnxt_vnic_info *vnic_info;\n+\n+\tif (vnic_idx >= bp->max_vnics) {\n+\t\tPMD_DRV_LOG(ERR, \"invalid vnic index %u\\n\", vnic_idx);\n+\t\treturn NULL;\n+\t}\n+\tvnic_info = &bp->vnic_info[vnic_idx];\n+\treturn vnic_info;\n+}\n+\n+struct bnxt_vnic_info *\n+bnxt_vnic_queue_id_get_next(struct bnxt *bp, uint16_t queue_id,\n+\t\t\t    uint16_t *vnic_idx)\n+{\n+\tstruct bnxt_vnic_info *vnic = NULL;\n+\tuint16_t i = *vnic_idx;\n+\n+\twhile (i < bp->max_vnics) {\n+\t\tvnic = &bp->vnic_info[i];\n+\t\tif (vnic->ref_cnt && BNXT_VNIC_BITMAP_GET(vnic->queue_bitmap,\n+\t\t\t\t\t\t\t  queue_id)) {\n+\t\t\t/* found a vnic that has the queue id */\n+\t\t\t*vnic_idx = i;\n+\t\t\treturn vnic;\n+\t\t}\n+\t\ti++;\n+\t}\n+\treturn NULL;\n+}\n+\n+void\n+bnxt_vnic_tpa_cfg(struct bnxt *bp, uint16_t queue_id, bool flag)\n+{\n+\tstruct bnxt_vnic_info *vnic = NULL;\n+\tuint16_t vnic_idx = 0;\n+\n+\twhile ((vnic = bnxt_vnic_queue_id_get_next(bp, queue_id,\n+\t\t\t\t\t\t   &vnic_idx)) != NULL) {\n+\t\tbnxt_hwrm_vnic_tpa_cfg(bp, vnic, flag);\n+\t\tvnic_idx++;\n+\t}\n+}\n+\n+inline struct bnxt_vnic_info *\n+bnxt_get_default_vnic(struct bnxt *bp)\n+{\n+\treturn &bp->vnic_info[bp->vnic_queue_db.dflt_vnic_id];\n+}\ndiff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h\nindex 9055b93c4b..4396d95bda 100644\n--- a/drivers/net/bnxt/bnxt_vnic.h\n+++ b/drivers/net/bnxt/bnxt_vnic.h\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -8,11 +8,29 @@\n \n #include <sys/queue.h>\n #include <stdbool.h>\n+#include <rte_hash.h>\n \n-#define INVALID_VNIC_ID\t\t((uint16_t)-1)\n+#define INVALID_VNIC_ID\t\t\t((uint16_t)-1)\n+#define BNXT_RSS_LEVEL_INNERMOST\t0x2\n+#define BNXT_RSS_LEVEL_OUTERMOST\t0x1\n+#define BNXT_VNIC_MAX_QUEUE_SIZE\t256\n+#define BNXT_VNIC_MAX_QUEUE_SZ_IN_8BITS\t(BNXT_VNIC_MAX_QUEUE_SIZE / 8)\n+#define BNXT_VNIC_MAX_QUEUE_SZ_IN_64BITS (BNXT_VNIC_MAX_QUEUE_SIZE / 64)\n+/* Limit the number of vnic creations*/\n+#define BNXT_VNIC_MAX_SUPPORTED_ID\t64\n \n-#define BNXT_RSS_LEVEL_INNERMOST        0x2\n-#define BNXT_RSS_LEVEL_OUTERMOST        0x1\n+#define\tBNXT_HASH_MODE_DEFAULT\tHWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT\n+#define\tBNXT_HASH_MODE_INNERMOST\t\\\n+\t\t(HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_4 |\t\\\n+\t\tHWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_2)\n+#define\tBNXT_HASH_MODE_OUTERMOST\t\\\n+\t\t(HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_4 |\t\\\n+\t\tHWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_2)\n+#define\tBNXT_VNIC_OUTER_RSS_UNSUPPORTED(bp)\t\t\t\t\t\\\n+\t((BNXT_PF(bp) && !((bp)->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS)) ||\t\\\n+\t (BNXT_VF(bp) && BNXT_VF_IS_TRUSTED(bp) &&\t\t\t\t\\\n+\t  !((bp)->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS_TRUSTED_VF)) ||\t\\\n+\t (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp)))\n \n struct bnxt_vnic_info {\n \tSTAILQ_ENTRY(bnxt_vnic_info)\tnext;\n@@ -28,6 +46,7 @@ struct bnxt_vnic_info {\n \tuint16_t\tmru;\n \tuint16_t\thash_type;\n \tuint8_t\t\thash_mode;\n+\tuint8_t\t\tprev_hash_mode;\n \tconst struct rte_memzone *rss_mz;\n \trte_iova_t\trss_table_dma_addr;\n \tuint16_t\t*rss_table;\n@@ -50,11 +69,29 @@ struct bnxt_vnic_info {\n \tbool\t\tfunc_default;\n \tbool\t\tbd_stall;\n \tbool\t\trss_dflt_cr;\n+\tuint16_t\tref_cnt;\n+\tuint64_t\tqueue_bitmap[BNXT_VNIC_MAX_QUEUE_SZ_IN_64BITS];\n \n \tSTAILQ_HEAD(, bnxt_filter_info)\tfilter;\n \tSTAILQ_HEAD(, rte_flow)\tflow_list;\n };\n \n+struct bnxt_vnic_queue_db {\n+\tuint16_t\tnum_queues;\n+\tuint16_t\tdflt_vnic_id;\n+\tstruct rte_hash *rss_q_db;\n+};\n+\n+/* RSS structure to pass values as an structure argument*/\n+struct bnxt_vnic_rss_info {\n+\tuint32_t rss_level;\n+\tuint64_t rss_types;\n+\tuint32_t key_len; /**< Hash key length in bytes. */\n+\tconst uint8_t *key; /**< Hash key. */\n+\tuint32_t queue_num; /**< Number of entries in @p queue. */\n+\tuint64_t queue_list[BNXT_VNIC_MAX_QUEUE_SZ_IN_64BITS];\n+};\n+\n struct bnxt;\n int bnxt_free_vnic(struct bnxt *bp, struct bnxt_vnic_info *vnic,\n \t\t\t  int pool);\n@@ -69,4 +106,39 @@ void bnxt_prandom_bytes(void *dest_ptr, size_t len);\n uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type);\n int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t hash_f, uint32_t lvl);\n uint64_t bnxt_hwrm_to_rte_rss_level(struct bnxt *bp, uint32_t mode);\n+\n+int32_t bnxt_vnic_queue_db_init(struct bnxt *bp);\n+int32_t bnxt_vnic_queue_db_deinit(struct bnxt *bp);\n+\n+void bnxt_vnic_queue_db_update_dlft_vnic(struct bnxt *bp);\n+int32_t\n+bnxt_vnic_rss_queue_status_update(struct bnxt *bp, struct bnxt_vnic_info *vnic);\n+\n+int32_t bnxt_vnic_queue_action_alloc(struct bnxt *bp, uint16_t q_index,\n+\t\t\t\t     uint16_t *vnic_idx,\n+\t\t\t\t     uint16_t *vnicid);\n+int32_t bnxt_vnic_queue_action_free(struct bnxt *bp, uint16_t q_index);\n+\n+int32_t bnxt_vnic_rss_action_alloc(struct bnxt *bp,\n+\t\t\t\t   struct bnxt_vnic_rss_info *rss_info,\n+\t\t\t\t   uint16_t *queue_id,\n+\t\t\t\t   uint16_t *vnicid);\n+int32_t bnxt_vnic_rss_action_free(struct bnxt *bp, uint16_t q_index);\n+\n+int32_t bnxt_vnic_reta_config_update(struct bnxt *bp,\n+\t\t\t\t     struct bnxt_vnic_info *vnic_info,\n+\t\t\t\t     struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t\t     uint16_t reta_size);\n+int32_t bnxt_vnic_queue_id_is_valid(struct bnxt_vnic_info *vnic_info,\n+\t\t\t\t    uint16_t queue_id);\n+void bnxt_vnic_ring_grp_populate(struct bnxt *bp, struct bnxt_vnic_info *vnic);\n+void bnxt_vnic_rules_init(struct bnxt_vnic_info *vnic);\n+int32_t bnxt_vnic_mru_config(struct bnxt *bp, uint16_t new_mtu);\n+struct bnxt_vnic_info *bnxt_vnic_queue_db_get_vnic(struct bnxt *bp,\n+\t\t\t\t\t\t   uint16_t vnic_idx);\n+struct bnxt_vnic_info *\n+bnxt_vnic_queue_id_get_next(struct bnxt *bp, uint16_t queue_id,\n+\t\t\t    uint16_t *vnic_idx);\n+void bnxt_vnic_tpa_cfg(struct bnxt *bp, uint16_t queue_id, bool flag);\n+\n #endif\ndiff --git a/drivers/net/bnxt/meson.build b/drivers/net/bnxt/meson.build\nindex ead03a5ea3..c7a0d5f6c9 100644\n--- a/drivers/net/bnxt/meson.build\n+++ b/drivers/net/bnxt/meson.build\n@@ -25,6 +25,8 @@ endforeach\n \n headers = files('rte_pmd_bnxt.h')\n \n+deps += ['hash']\n+\n sources = files(\n         'bnxt_cpr.c',\n         'bnxt_ethdev.c',\n@@ -41,7 +43,6 @@ sources = files(\n         'bnxt_util.c',\n         'bnxt_vnic.c',\n         'bnxt_reps.c',\n-\n         'rte_pmd_bnxt.c',\n )\n \ndiff --git a/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c b/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c\nindex b09cccedf5..474854d59b 100644\n--- a/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c\n+++ b/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2021-2021 Broadcom\n+ * Copyright(c) 2021-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -17,6 +17,36 @@\n #include \"bnxt_tf_common.h\"\n #include \"bnxt_tf_pmd_shim.h\"\n \n+int\n+bnxt_tunnel_dst_port_free(struct bnxt *bp,\n+\t\t\t  uint16_t port,\n+\t\t\t  uint8_t type)\n+{\n+\treturn bnxt_hwrm_tunnel_dst_port_free(bp,\n+\t\t\t\t\t      port,\n+\t\t\t\t\t      type);\n+}\n+\n+int\n+bnxt_tunnel_dst_port_alloc(struct bnxt *bp,\n+\t\t\t   uint16_t port,\n+\t\t\t   uint8_t type)\n+{\n+\treturn bnxt_hwrm_tunnel_dst_port_alloc(bp,\n+\t\t\t\t\t       port,\n+\t\t\t\t\t       type);\n+}\n+\n+int\n+bnxt_tunnel_upar_id_get(struct bnxt *bp,\n+\t\t\tuint8_t type,\n+\t\t\tuint8_t *upar_id)\n+{\n+\treturn bnxt_hwrm_tunnel_upar_id_get(bp,\n+\t\t\t\t\t    upar_id,\n+\t\t\t\t\t    type);\n+}\n+\n struct bnxt *\n bnxt_pmd_get_bp(uint16_t port)\n {\n@@ -59,7 +89,7 @@ int32_t bnxt_rss_config_action_apply(struct bnxt_ulp_mapper_parms *parms)\n \t\tBNXT_TF_DBG(ERR, \"Invalid bp for port_id %u\\n\", parms->port_id);\n \t\treturn rc;\n \t}\n-\tvnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tvnic = bnxt_get_default_vnic(bp);\n \tif (vnic == NULL) {\n \t\tBNXT_TF_DBG(ERR, \"default vnic not available for %u\\n\",\n \t\t\t    parms->port_id);\n@@ -108,7 +138,6 @@ static int32_t glob_error_fn(const char *epath, int32_t eerrno)\n \treturn 0;\n }\n \n-\n static int32_t ulp_pmd_get_mac_by_pci(const char *pci_name, uint8_t *mac)\n {\n \tchar path[ULP_FILE_PATH_SIZE], dev_str[ULP_FILE_PATH_SIZE];\n@@ -244,7 +273,7 @@ bnxt_pmd_get_vnic_id(uint16_t port, enum bnxt_ulp_intf_type type)\n \n \tbp = eth_dev->data->dev_private;\n \n-\tvnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tvnic = bnxt_get_default_vnic(bp);\n \n \treturn vnic->fw_vnic_id;\n }\n@@ -343,7 +372,6 @@ bnxt_pmd_get_vport(uint16_t port_id)\n \treturn (1 << bnxt_pmd_get_phy_port_id(port_id));\n }\n \n-\n int32_t\n bnxt_pmd_set_unicast_rxmask(struct rte_eth_dev *eth_dev)\n {\n@@ -363,7 +391,7 @@ bnxt_pmd_set_unicast_rxmask(struct rte_eth_dev *eth_dev)\n \tif (bp->vnic_info == NULL)\n \t\treturn 0;\n \n-\tvnic = BNXT_GET_DEFAULT_VNIC(bp);\n+\tvnic = bnxt_get_default_vnic(bp);\n \n \told_flags = vnic->flags;\n \tvnic->flags |= BNXT_VNIC_INFO_UCAST;\n@@ -376,3 +404,211 @@ bnxt_pmd_set_unicast_rxmask(struct rte_eth_dev *eth_dev)\n \n \treturn rc;\n }\n+\n+int32_t bnxt_pmd_queue_action_create(struct bnxt_ulp_mapper_parms *parms,\n+\t\t\t\t     uint16_t *vnic_idx, uint16_t *vnic_id)\n+{\n+\tstruct bnxt *bp = NULL;\n+\tuint16_t q_index;\n+\tstruct ulp_rte_act_prop *ap = parms->act_prop;\n+\n+\tbp = bnxt_pmd_get_bp(parms->port_id);\n+\tif (bp == NULL) {\n+\t\tBNXT_TF_DBG(ERR, \"Invalid bp for port_id %u\\n\", parms->port_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemcpy(&q_index, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_QUEUE_INDEX],\n+\t       BNXT_ULP_ACT_PROP_SZ_QUEUE_INDEX);\n+\n+\treturn bnxt_vnic_queue_action_alloc(bp, q_index, vnic_idx, vnic_id);\n+}\n+\n+int32_t bnxt_pmd_queue_action_delete(struct tf *tfp, uint16_t vnic_idx)\n+{\n+\tstruct bnxt *bp = NULL;\n+\n+\tbp = tfp->bp;\n+\tif (bp == NULL) {\n+\t\tBNXT_TF_DBG(ERR, \"Invalid bp\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\treturn bnxt_vnic_queue_action_free(bp, vnic_idx);\n+}\n+\n+int32_t bnxt_pmd_rss_action_create(struct bnxt_ulp_mapper_parms *parms,\n+\t\t\t\t   uint16_t *vnic_idx, uint16_t *vnic_id)\n+{\n+\tstruct bnxt *bp = NULL;\n+\tstruct bnxt_vnic_rss_info rss_info = {0};\n+\tstruct ulp_rte_act_prop *ap = parms->act_prop;\n+\n+\tbp = bnxt_pmd_get_bp(parms->port_id);\n+\tif (bp == NULL) {\n+\t\tBNXT_TF_DBG(ERR, \"Invalid bp for port_id %u\\n\", parms->port_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* get the details */\n+\tmemset(&rss_info, 0, sizeof(rss_info));\n+\tmemcpy(&rss_info.rss_types,\n+\t       &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_TYPES],\n+\t       BNXT_ULP_ACT_PROP_SZ_RSS_TYPES);\n+\tmemcpy(&rss_info.rss_level,\n+\t       &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_LEVEL],\n+\t       BNXT_ULP_ACT_PROP_SZ_RSS_LEVEL);\n+\tmemcpy(&rss_info.key_len,\n+\t       &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY_LEN],\n+\t       BNXT_ULP_ACT_PROP_SZ_RSS_KEY_LEN);\n+\tif (rss_info.key_len)\n+\t\trss_info.key = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY];\n+\tmemcpy(&rss_info.queue_num,\n+\t       &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_QUEUE_NUM],\n+\t       BNXT_ULP_ACT_PROP_SZ_RSS_QUEUE_NUM);\n+\n+\t/* Validate the size of the queue list */\n+\tif (sizeof(rss_info.queue_list) < BNXT_ULP_ACT_PROP_SZ_RSS_QUEUE) {\n+\t\tBNXT_TF_DBG(ERR, \"Mismatch of RSS queue size in template\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\tmemcpy(rss_info.queue_list,\n+\t       &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_QUEUE],\n+\t       BNXT_ULP_ACT_PROP_SZ_RSS_QUEUE);\n+\n+\treturn bnxt_vnic_rss_action_alloc(bp, &rss_info, vnic_idx, vnic_id);\n+}\n+\n+int32_t bnxt_pmd_rss_action_delete(struct tf *tfp, uint16_t vnic_idx)\n+{\n+\tstruct bnxt *bp = tfp->bp;\n+\n+\tif (bp == NULL) {\n+\t\tBNXT_TF_DBG(ERR, \"Invalid bp\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\treturn bnxt_vnic_rss_action_free(bp, vnic_idx);\n+}\n+\n+#define ULP_GLOBAL_TUNNEL_PORT_ID_SHIFT  16\n+#define ULP_GLOBAL_TUNNEL_PORT_ID_MASK   ((uint16_t)0xffff)\n+#define ULP_GLOBAL_TUNNEL_UPARID_SHIFT   8\n+#define ULP_GLOBAL_TUNNEL_UPARID_MASK    ((uint16_t)0xff)\n+#define ULP_GLOBAL_TUNNEL_TYPE_SHIFT     0\n+#define ULP_GLOBAL_TUNNEL_TYPE_MASK      ((uint16_t)0xffff)\n+\n+/* Extracts the dpdk port id and tunnel type from the handle */\n+static void\n+bnxt_pmd_global_reg_hndl_to_data(uint32_t handle, uint16_t *port,\n+\t\t\t\t uint8_t *upar_id, uint8_t *type)\n+{\n+\t*type    = (handle >> ULP_GLOBAL_TUNNEL_TYPE_SHIFT) &\n+\t\t   ULP_GLOBAL_TUNNEL_TYPE_MASK;\n+\t*upar_id = (handle >> ULP_GLOBAL_TUNNEL_UPARID_SHIFT) &\n+\t\t   ULP_GLOBAL_TUNNEL_UPARID_MASK;\n+\t*port    = (handle >> ULP_GLOBAL_TUNNEL_PORT_ID_SHIFT) &\n+\t\t   ULP_GLOBAL_TUNNEL_PORT_ID_MASK;\n+}\n+\n+/* Packs the dpdk port id and tunnel type in the handle */\n+static void\n+bnxt_pmd_global_reg_data_to_hndl(uint16_t port_id, uint8_t upar_id,\n+\t\t\t\t uint8_t type, uint32_t *handle)\n+{\n+\t*handle\t=  (port_id & ULP_GLOBAL_TUNNEL_PORT_ID_MASK) <<\n+\t\t   ULP_GLOBAL_TUNNEL_PORT_ID_SHIFT;\n+\t*handle\t|= (upar_id & ULP_GLOBAL_TUNNEL_UPARID_MASK) <<\n+\t\t   ULP_GLOBAL_TUNNEL_UPARID_SHIFT;\n+\t*handle |= (type & ULP_GLOBAL_TUNNEL_TYPE_MASK) <<\n+\t\t   ULP_GLOBAL_TUNNEL_TYPE_SHIFT;\n+}\n+\n+static struct bnxt_global_tunnel_info\n+\t      ulp_global_tunnel_db[BNXT_GLOBAL_REGISTER_TUNNEL_MAX] = {{0}};\n+/* Sets or resets the tunnel ports.\n+ * If dport == 0, then the port_id and type are retrieved from the handle.\n+ * otherwise, the incoming port_id, type, and dport are used.\n+ * The type is enum ulp_mapper_ulp_global_tunnel_type\n+ */\n+int32_t\n+bnxt_pmd_global_tunnel_set(uint16_t port_id, uint8_t type,\n+\t\t\t   uint16_t udp_port, uint32_t *handle)\n+{\n+\tuint16_t lport_id, ldport;\n+\tuint8_t hwtype, ltype, lupar_id;\n+\tstruct bnxt *bp;\n+\tint32_t rc = 0;\n+\n+\t/* convert to HWRM type */\n+\tswitch (type) {\n+\tcase BNXT_GLOBAL_REGISTER_TUNNEL_VXLAN:\n+\t\thwtype = HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN;\n+\t\tbreak;\n+\tdefault:\n+\t\tBNXT_TF_DBG(ERR, \"Tunnel Type (%d) invalid\\n\", type);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!udp_port) {\n+\t\t/* Free based on the handle */\n+\t\tif (!handle) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Free with invalid handle\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tbnxt_pmd_global_reg_hndl_to_data(*handle, &lport_id,\n+\t\t\t\t\t\t  &lupar_id, &ltype);\n+\n+\t\tbp = bnxt_pmd_get_bp(lport_id);\n+\t\tif (!bp) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Unable to get dev by port %d\\n\",\n+\t\t\t\t    lport_id);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tif (!ulp_global_tunnel_db[ltype].ref_cnt)\n+\t\t\treturn 0;\n+\t\tldport = ulp_global_tunnel_db[ltype].dport;\n+\t\trc = bnxt_hwrm_tunnel_dst_port_free(bp, ldport, hwtype);\n+\t\tif (rc) {\n+\t\t\tBNXT_TF_DBG(ERR,\n+\t\t\t\t    \"Unable to free tunnel dst port (%d)\\n\",\n+\t\t\t\t    ldport);\n+\t\t\treturn rc;\n+\t\t}\n+\t\tulp_global_tunnel_db[ltype].ref_cnt--;\n+\t\tif (ulp_global_tunnel_db[ltype].ref_cnt == 0)\n+\t\t\tulp_global_tunnel_db[ltype].dport = 0;\n+\t} else {\n+\t\tbp = bnxt_pmd_get_bp(port_id);\n+\t\tif (!bp) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Unable to get dev by port %d\\n\",\n+\t\t\t\t    port_id);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\trc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_port, hwtype);\n+\t\tif (!rc) {\n+\t\t\tulp_global_tunnel_db[type].ref_cnt++;\n+\t\t\tulp_global_tunnel_db[type].dport = udp_port;\n+\t\t\tbnxt_pmd_global_reg_data_to_hndl(port_id, 0,\n+\t\t\t\t\t\t\t type, handle);\n+\t\t}\n+\t}\n+\treturn rc;\n+}\n+\n+#define BNXT_ULP_HOT_UP_DYNAMIC_ENV_VAR \"BNXT_ULP_T_HA_SUPPORT\"\n+/* This function queries the linux shell variable to determine\n+ * whether Hot upgrade should be disabled or not.\n+ * If BNXT_ULP_T_HA_SUPPORT is set to zero explicitly then\n+ * hotupgrade is disabled.\n+ */\n+int32_t bnxt_pmd_get_hot_upgrade_env(void)\n+{\n+\tchar *env;\n+\tint32_t hot_up = 1;\n+\n+\tenv = getenv(BNXT_ULP_HOT_UP_DYNAMIC_ENV_VAR);\n+\tif (env && strcmp(env, \"0\") == 0)\n+\t\thot_up = 0;\n+\treturn hot_up;\n+}\ndiff --git a/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.h b/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.h\nindex d6d7a1f0af..b76e4b849d 100644\n--- a/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.h\n+++ b/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.h\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2021-2021 Broadcom\n+ * Copyright(c) 2021-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -9,6 +9,19 @@\n #include \"bnxt_tf_common.h\"\n #include \"ulp_mapper.h\"\n \n+/* Simple structure to manage the custom global tunnel */\n+struct bnxt_global_tunnel_info {\n+\tuint16_t dport;\n+\tuint16_t ref_cnt;\n+};\n+\n+/* Internal Tunnel type, */\n+enum bnxt_global_register_tunnel_type {\n+\tBNXT_GLOBAL_REGISTER_TUNNEL_UNUSED = 0,\n+\tBNXT_GLOBAL_REGISTER_TUNNEL_VXLAN,\n+\tBNXT_GLOBAL_REGISTER_TUNNEL_MAX\n+};\n+\n int32_t bnxt_rss_config_action_apply(struct bnxt_ulp_mapper_parms *parms);\n int32_t bnxt_pmd_get_parent_mac_addr(struct bnxt_ulp_mapper_parms *parms,\n \t\t\t\t     uint8_t *mac);\n@@ -25,4 +38,24 @@ uint16_t bnxt_pmd_get_phy_port_id(uint16_t port);\n uint16_t bnxt_pmd_get_vport(uint16_t port);\n enum bnxt_ulp_intf_type bnxt_pmd_get_interface_type(uint16_t port);\n int32_t bnxt_pmd_set_unicast_rxmask(struct rte_eth_dev *eth_dev);\n+int32_t bnxt_pmd_queue_action_create(struct bnxt_ulp_mapper_parms *parms,\n+\t\t\t\t     uint16_t *vnic_idx, uint16_t *vnic_id);\n+int32_t bnxt_pmd_queue_action_delete(struct tf *tfp, uint16_t vnic_idx);\n+int32_t bnxt_pmd_rss_action_create(struct bnxt_ulp_mapper_parms *parms,\n+\t\t\t\t   uint16_t *vnic_idx, uint16_t *vnic_id);\n+int32_t bnxt_pmd_rss_action_delete(struct tf *tfp, uint16_t vnic_idx);\n+int32_t bnxt_tunnel_dst_port_free(struct bnxt *bp,\n+\t\t\t\t  uint16_t port,\n+\t\t\t\t  uint8_t type);\n+int32_t bnxt_tunnel_dst_port_alloc(struct bnxt *bp,\n+\t\t\t\t   uint16_t port,\n+\t\t\t\t   uint8_t type);\n+int32_t\n+bnxt_pmd_global_tunnel_set(uint16_t port_id, uint8_t type,\n+\t\t\t   uint16_t udp_port, uint32_t *handle);\n+int32_t\n+bnxt_tunnel_upar_id_get(struct bnxt *bp,\n+\t\t\tuint8_t type,\n+\t\t\tuint8_t *upar_id);\n+int32_t bnxt_pmd_get_hot_upgrade_env(void);\n #endif /* _BNXT_TF_PMD_ABSTRACT_H_ */\ndiff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c\nindex 109bd0652a..08eb0c6063 100644\n--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c\n+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c\n@@ -78,7 +78,7 @@ bnxt_ulp_devid_get(struct bnxt *bp,\n \tif (BNXT_STINGRAY(bp))\n \t\t*ulp_dev_id = BNXT_ULP_DEVICE_ID_STINGRAY;\n \telse\n-\t\t/* Assuming Whitney */\n+\t\t/* Assuming P4 */\n \t\t*ulp_dev_id = BNXT_ULP_DEVICE_ID_WH_PLUS;\n \n \treturn 0;\n@@ -340,12 +340,62 @@ bnxt_ulp_tf_shared_session_resources_get(struct bnxt_ulp_context *ulp_ctx,\n \treturn rc;\n }\n \n+/* Function to set the hot upgrade support into the context */\n+static int\n+bnxt_ulp_multi_shared_session_support_set(struct bnxt *bp,\n+\t\t\t\t\t  enum bnxt_ulp_device_id devid,\n+\t\t\t\t\t  uint32_t fw_hu_update)\n+{\n+\tstruct bnxt_ulp_context *ulp_ctx = bp->ulp_ctx;\n+\tstruct tf_get_version_parms v_params = { 0 };\n+\tstruct tf *tfp;\n+\tint32_t rc = 0;\n+\tint32_t new_fw = 0;\n+\n+\tv_params.device_type = bnxt_ulp_cntxt_convert_dev_id(devid);\n+\tv_params.bp = bp;\n+\n+\ttfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);\n+\trc = tf_get_version(tfp, &v_params);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Unable to get tf version.\\n\");\n+\t\treturn rc;\n+\t}\n+\n+\tif (v_params.major == 1 && v_params.minor == 0 &&\n+\t    v_params.update == 1) {\n+\t\tnew_fw = 1;\n+\t}\n+\t/* if the version update is greater than 0 then set support for\n+\t * multiple version\n+\t */\n+\tif (new_fw) {\n+\t\tulp_ctx->cfg_data->ulp_flags |= BNXT_ULP_MULTI_SHARED_SUPPORT;\n+\t\tulp_ctx->cfg_data->hu_session_type =\n+\t\t\tBNXT_ULP_SESSION_TYPE_SHARED;\n+\t}\n+\tif (!new_fw && fw_hu_update) {\n+\t\tulp_ctx->cfg_data->ulp_flags &= ~BNXT_ULP_HIGH_AVAIL_ENABLED;\n+\t\tulp_ctx->cfg_data->hu_session_type =\n+\t\t\tBNXT_ULP_SESSION_TYPE_SHARED |\n+\t\t\tBNXT_ULP_SESSION_TYPE_SHARED_OWC;\n+\t}\n+\n+\tif (!new_fw && !fw_hu_update) {\n+\t\tulp_ctx->cfg_data->hu_session_type =\n+\t\t\tBNXT_ULP_SESSION_TYPE_SHARED |\n+\t\t\tBNXT_ULP_SESSION_TYPE_SHARED_OWC;\n+\t}\n+\n+\treturn rc;\n+}\n+\n int32_t\n bnxt_ulp_cntxt_app_caps_init(struct bnxt *bp,\n \t\t\t     uint8_t app_id, uint32_t dev_id)\n {\n \tstruct bnxt_ulp_app_capabilities_info *info;\n-\tuint32_t num = 0;\n+\tuint32_t num = 0, fw = 0;\n \tuint16_t i;\n \tbool found = false;\n \tstruct bnxt_ulp_context *ulp_ctx = bp->ulp_ctx;\n@@ -375,15 +425,49 @@ bnxt_ulp_cntxt_app_caps_init(struct bnxt *bp,\n \t\tif (info[i].flags & BNXT_ULP_APP_CAP_UNICAST_ONLY)\n \t\t\tulp_ctx->cfg_data->ulp_flags |=\n \t\t\t\tBNXT_ULP_APP_UNICAST_ONLY;\n+\t\tif (info[i].flags & BNXT_ULP_APP_CAP_IP_TOS_PROTO_SUPPORT)\n+\t\t\tulp_ctx->cfg_data->ulp_flags |=\n+\t\t\t\tBNXT_ULP_APP_TOS_PROTO_SUPPORT;\n+\t\tif (info[i].flags & BNXT_ULP_APP_CAP_BC_MC_SUPPORT)\n+\t\t\tulp_ctx->cfg_data->ulp_flags |=\n+\t\t\t\tBNXT_ULP_APP_BC_MC_SUPPORT;\n \t\tif (info[i].flags & BNXT_ULP_APP_CAP_SOCKET_DIRECT) {\n \t\t\t/* Enable socket direction only if MR is enabled in fw*/\n \t\t\tif (BNXT_MULTIROOT_EN(bp)) {\n \t\t\t\tulp_ctx->cfg_data->ulp_flags |=\n \t\t\t\t\tBNXT_ULP_APP_SOCKET_DIRECT;\n-\t\t\t\tBNXT_TF_DBG(DEBUG,\n-\t\t\t\t\t    \"Socket Direct feature is enabled\");\n+\t\t\t\tBNXT_TF_DBG(INFO,\n+\t\t\t\t\t    \"Socket Direct feature is enabled\\n\");\n \t\t\t}\n \t\t}\n+\t\tif (info[i].flags & BNXT_ULP_APP_CAP_HA_DYNAMIC) {\n+\t\t\t/* Read the environment variable to determine hot up */\n+\t\t\tif (!bnxt_pmd_get_hot_upgrade_env()) {\n+\t\t\t\tulp_ctx->cfg_data->ulp_flags |=\n+\t\t\t\t\tBNXT_ULP_APP_HA_DYNAMIC;\n+\t\t\t\t/* reset Hot upgrade, dynamically disabled */\n+\t\t\t\tulp_ctx->cfg_data->ulp_flags &=\n+\t\t\t\t\t~BNXT_ULP_HIGH_AVAIL_ENABLED;\n+\t\t\t\tulp_ctx->cfg_data->def_session_type =\n+\t\t\t\t\tBNXT_ULP_SESSION_TYPE_DEFAULT_NON_HA;\n+\t\t\t\tBNXT_TF_DBG(INFO, \"Hot upgrade disabled.\\n\");\n+\t\t\t}\n+\t\t}\n+\n+\t\tbnxt_ulp_vxlan_ip_port_set(ulp_ctx, info[i].vxlan_ip_port);\n+\t\tbnxt_ulp_vxlan_port_set(ulp_ctx, info[i].vxlan_port);\n+\n+\t\t/* set the shared session support from firmware */\n+\t\tfw = info[i].upgrade_fw_update;\n+\t\tif (ULP_HIGH_AVAIL_IS_ENABLED(ulp_ctx->cfg_data->ulp_flags) &&\n+\t\t    bnxt_ulp_multi_shared_session_support_set(bp, dev_id, fw)) {\n+\t\t\tBNXT_TF_DBG(ERR,\n+\t\t\t\t    \"Unable to get shared session support\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tbnxt_ulp_ha_reg_set(ulp_ctx, info[i].ha_reg_state,\n+\t\t\t\t    info[i].ha_reg_cnt);\n+\t\tulp_ctx->cfg_data->ha_pool_id = info[i].ha_pool_id;\n \t}\n \tif (!found) {\n \t\tBNXT_TF_DBG(ERR, \"APP ID %d, Device ID: 0x%x not supported.\\n\",\n@@ -1027,6 +1111,11 @@ ulp_ctx_init(struct bnxt *bp,\n \t\tgoto error_deinit;\n \t}\n \n+\tif (BNXT_TESTPMD_EN(bp)) {\n+\t\tulp_data->ulp_flags &= ~BNXT_ULP_VF_REP_ENABLED;\n+\t\tBNXT_TF_DBG(ERR, \"Enabled Testpmd forward mode\\n\");\n+\t}\n+\n \t/*\n \t * Shared session must be created before first regular session but after\n \t * the ulp_ctx is valid.\n@@ -1055,7 +1144,6 @@ ulp_ctx_init(struct bnxt *bp,\n \t}\n \tbnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, true);\n \n-\n \t/* Open the ulp session. */\n \trc = ulp_ctx_session_open(bp, session);\n \tif (rc)\n@@ -1181,7 +1269,7 @@ ulp_ctx_attach(struct bnxt *bp,\n \t\ttfp->session = NULL;\n \t\treturn rc;\n \t}\n-\n+\ttfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);\n \tbnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT, tfp);\n \treturn rc;\n }\n@@ -1427,7 +1515,8 @@ bnxt_ulp_deinit(struct bnxt *bp,\n \t\treturn;\n \n \tha_enabled = bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx);\n-\tif (ha_enabled && session->session_opened) {\n+\tif (ha_enabled &&\n+\t    bnxt_ulp_session_is_open(session, BNXT_ULP_SESSION_TYPE_DEFAULT)) {\n \t\tint32_t rc = ulp_ha_mgr_close(bp->ulp_ctx);\n \t\tif (rc)\n \t\t\tBNXT_TF_DBG(ERR, \"Failed to close HA (%d)\\n\", rc);\n@@ -1490,6 +1579,7 @@ bnxt_ulp_init(struct bnxt *bp,\n \t      struct bnxt_ulp_session_state *session)\n {\n \tint rc;\n+\tuint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST;\n \n \t/* Allocate and Initialize the ulp context. */\n \trc = ulp_ctx_init(bp, session);\n@@ -1584,6 +1674,13 @@ bnxt_ulp_init(struct bnxt *bp,\n \t\t\tgoto jump_to_error;\n \t\t}\n \t}\n+\n+\trc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Unable to get device id from ulp.\\n\");\n+\t\treturn rc;\n+\t}\n+\n \tBNXT_TF_DBG(DEBUG, \"ulp ctx has been initialized\\n\");\n \treturn rc;\n \n@@ -1592,6 +1689,30 @@ bnxt_ulp_init(struct bnxt *bp,\n \treturn rc;\n }\n \n+static int\n+ulp_cust_vxlan_alloc(struct bnxt *bp)\n+{\n+\tint rc = 0;\n+\n+\tif (ULP_APP_CUST_VXLAN_SUPPORT(bp->ulp_ctx)) {\n+\t\trc = bnxt_tunnel_dst_port_alloc(bp,\n+\t\t\t\t\t\tbp->ulp_ctx->cfg_data->vxlan_port,\n+\t\t\t\t\tHWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN);\n+\t\tif (rc)\n+\t\t\tBNXT_TF_DBG(ERR, \"Failed to set global vxlan port\\n\");\n+\t}\n+\n+\tif (ULP_APP_CUST_VXLAN_IP_SUPPORT(bp->ulp_ctx)) {\n+\t\trc = bnxt_tunnel_dst_port_alloc(bp,\n+\t\t\t\t\t\tbp->ulp_ctx->cfg_data->vxlan_ip_port,\n+\t\t\t\t\tHWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_V4);\n+\t\tif (rc)\n+\t\t\tBNXT_TF_DBG(ERR, \"Failed to set global custom vxlan_ip port\\n\");\n+\t}\n+\n+\treturn rc;\n+}\n+\n /*\n  * When a port is initialized by dpdk. This functions sets up\n  * the port specific details.\n@@ -1686,6 +1807,7 @@ bnxt_ulp_port_init(struct bnxt *bp)\n \t\tBNXT_TF_DBG(ERR, \"Failed to update port database\\n\");\n \t\tgoto jump_to_error;\n \t}\n+\n \t/* create the default rules */\n \trc = bnxt_ulp_create_df_rules(bp);\n \tif (rc) {\n@@ -1711,6 +1833,10 @@ bnxt_ulp_port_init(struct bnxt *bp)\n \t\t}\n \t}\n \n+\trc = ulp_cust_vxlan_alloc(bp);\n+\tif (rc)\n+\t\tgoto jump_to_error;\n+\n \treturn rc;\n \n jump_to_error:\n@@ -1718,6 +1844,28 @@ bnxt_ulp_port_init(struct bnxt *bp)\n \treturn rc;\n }\n \n+static void\n+ulp_cust_vxlan_free(struct bnxt *bp)\n+{\n+\tint rc;\n+\n+\tif (ULP_APP_CUST_VXLAN_SUPPORT(bp->ulp_ctx)) {\n+\t\trc = bnxt_tunnel_dst_port_free(bp,\n+\t\t\t\t\t       bp->ulp_ctx->cfg_data->vxlan_port,\n+\t\t\t\t     HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN);\n+\t\tif (rc)\n+\t\t\tBNXT_TF_DBG(ERR, \"Failed to clear global vxlan port\\n\");\n+\t}\n+\n+\tif (ULP_APP_CUST_VXLAN_IP_SUPPORT(bp->ulp_ctx)) {\n+\t\trc = bnxt_tunnel_dst_port_free(bp,\n+\t\t\t\t\t       bp->ulp_ctx->cfg_data->vxlan_ip_port,\n+\t\t\t\t     HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_V4);\n+\t\tif (rc)\n+\t\t\tBNXT_TF_DBG(ERR, \"Failed to clear global custom vxlan port\\n\");\n+\t}\n+}\n+\n /*\n  * When a port is de-initialized by dpdk. This functions clears up\n  * the port specific details.\n@@ -1770,6 +1918,9 @@ bnxt_ulp_port_deinit(struct bnxt *bp)\n \tif (bp->ulp_ctx->cfg_data && bp->ulp_ctx->cfg_data->ref_cnt) {\n \t\tbp->ulp_ctx->cfg_data->ref_cnt--;\n \t\tif (bp->ulp_ctx->cfg_data->ref_cnt) {\n+\t\t\t/* Free tunnel configurations */\n+\t\t\tulp_cust_vxlan_free(bp);\n+\n \t\t\t/* free the port details */\n \t\t\t/* Free the default flow rule associated to this port */\n \t\t\tbnxt_ulp_destroy_df_rules(bp, false);\n@@ -2201,6 +2352,45 @@ bnxt_ulp_cntxt_release_fdb_lock(struct bnxt_ulp_context\t*ulp_ctx)\n \tpthread_mutex_unlock(&ulp_ctx->cfg_data->flow_db_lock);\n }\n \n+/* Function to extract the action type from the shared action handle. */\n+int32_t\n+bnxt_get_action_handle_type(const struct rte_flow_action_handle *handle,\n+\t\t\t    uint32_t *action_handle_type)\n+{\n+\tif (!action_handle_type)\n+\t\treturn -EINVAL;\n+\n+\t*action_handle_type = (uint32_t)(((uint64_t)handle >> 32) & 0xffffffff);\n+\tif (*action_handle_type >= BNXT_ULP_GEN_TBL_MAX_SZ)\n+\t\treturn -EINVAL;\n+\n+\treturn 0;\n+}\n+\n+/* Function to extract the direction from the shared action handle. */\n+int32_t\n+bnxt_get_action_handle_direction(const struct rte_flow_action_handle *handle,\n+\t\t\t\t uint32_t *dir)\n+{\n+\tuint32_t shared_type;\n+\tint32_t ret = 0;\n+\n+\tret = bnxt_get_action_handle_type(handle, &shared_type);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t*dir = shared_type & 0x1 ? BNXT_ULP_DIR_EGRESS : BNXT_ULP_DIR_INGRESS;\n+\n+\treturn ret;\n+}\n+\n+/* Function to extract the action index from the shared action handle. */\n+uint32_t\n+bnxt_get_action_handle_index(const struct rte_flow_action_handle *handle)\n+{\n+\treturn (uint32_t)((uint64_t)handle & 0xffffffff);\n+}\n+\n /* Function to set the ha info into the context */\n int32_t\n bnxt_ulp_cntxt_ptr2_ha_info_set(struct bnxt_ulp_context *ulp_ctx,\n@@ -2306,6 +2496,13 @@ bnxt_ulp_cntxt_ptr2_app_tun_list_get(struct bnxt_ulp_context *ulp)\n \treturn ulp->cfg_data->app_tun;\n }\n \n+/* Function to get the truflow app id. This defined in the build file */\n+uint32_t\n+bnxt_ulp_default_app_id_get(void)\n+{\n+\treturn BNXT_TF_APP_ID;\n+}\n+\n /* Function to convert ulp dev id to regular dev id. */\n uint32_t\n bnxt_ulp_cntxt_convert_dev_id(uint32_t ulp_dev_id)\n@@ -2329,6 +2526,53 @@ bnxt_ulp_cntxt_convert_dev_id(uint32_t ulp_dev_id)\n \treturn type;\n }\n \n+/* This function sets the IF table index for the\n+ * Application to poll to get the hot upgrade state and count details from\n+ * the firmware.\n+ */\n+int32_t\n+bnxt_ulp_ha_reg_set(struct bnxt_ulp_context *ulp_ctx,\n+\t\t    uint8_t state, uint8_t cnt)\n+{\n+\tif (!ulp_ctx || !ulp_ctx->cfg_data)\n+\t\treturn -EINVAL;\n+\n+\tif (ULP_MULTI_SHARED_IS_SUPPORTED(ulp_ctx)) {\n+\t\tulp_ctx->cfg_data->hu_reg_state = state;\n+\t\tulp_ctx->cfg_data->hu_reg_cnt = cnt;\n+\t} else {\n+\t\tulp_ctx->cfg_data->hu_reg_state = ULP_HA_IF_TBL_IDX;\n+\t\tulp_ctx->cfg_data->hu_reg_cnt = ULP_HA_CLIENT_CNT_IF_TBL_IDX;\n+\t}\n+\treturn 0;\n+}\n+\n+/* This function gets the IF table index for the\n+ * application to poll to get the application hot upgrade state from\n+ * the firmware.\n+ */\n+uint32_t\n+bnxt_ulp_ha_reg_state_get(struct bnxt_ulp_context *ulp_ctx)\n+{\n+\tif (!ulp_ctx || !ulp_ctx->cfg_data)\n+\t\treturn 0;\n+\n+\treturn (uint32_t)ulp_ctx->cfg_data->hu_reg_state;\n+}\n+\n+/* This function gets the IF table index for the\n+ * Application to poll to get the application count from\n+ * the firmware.\n+ */\n+uint32_t\n+bnxt_ulp_ha_reg_cnt_get(struct bnxt_ulp_context *ulp_ctx)\n+{\n+\tif (!ulp_ctx || !ulp_ctx->cfg_data)\n+\t\treturn 0;\n+\n+\treturn (uint32_t)ulp_ctx->cfg_data->hu_reg_cnt;\n+}\n+\n struct tf*\n bnxt_ulp_bp_tfp_get(struct bnxt *bp, enum bnxt_ulp_session_type type)\n {\ndiff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.h b/drivers/net/bnxt/tf_ulp/bnxt_ulp.h\nindex 9b30851b13..53d76e1465 100644\n--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.h\n+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.h\n@@ -386,4 +386,5 @@ bnxt_ulp_ha_reg_cnt_get(struct bnxt_ulp_context *ulp_ctx);\n \n struct tf*\n bnxt_ulp_bp_tfp_get(struct bnxt *bp, enum bnxt_ulp_session_type type);\n+\n #endif /* _BNXT_ULP_H_ */\ndiff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c\nindex 55885d1b8c..ad04644db4 100644\n--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c\n+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -14,6 +14,8 @@\n #include \"ulp_ha_mgr.h\"\n #include \"ulp_tun.h\"\n #include <rte_malloc.h>\n+#include \"ulp_template_db_tbl.h\"\n+#include \"tfp.h\"\n \n static int32_t\n bnxt_ulp_flow_validate_args(const struct rte_flow_attr *attr,\n@@ -78,6 +80,17 @@ bnxt_ulp_set_dir_attributes(struct ulp_rte_parser_params *params,\n #endif\n }\n \n+static inline void\n+bnxt_ulp_init_parser_cf_defaults(struct ulp_rte_parser_params *params,\n+\t\t\t\t uint16_t port_id)\n+{\n+\t/* Set up defaults for Comp field */\n+\tULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_INCOMING_IF, port_id);\n+\tULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_DEV_PORT_ID, port_id);\n+\tULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_SVIF_FLAG,\n+\t\t\t    BNXT_ULP_INVALID_SVIF_VAL);\n+}\n+\n void\n bnxt_ulp_init_mapper_params(struct bnxt_ulp_mapper_create_parms *mapper_cparms,\n \t\t\t    struct ulp_rte_parser_params *params,\n@@ -130,6 +143,10 @@ bnxt_ulp_init_mapper_params(struct bnxt_ulp_mapper_create_parms *mapper_cparms,\n \t\t\tULP_COMP_FLD_IDX_WR(params,\n \t\t\t\t\t    BNXT_ULP_CF_IDX_WC_IS_HA_HIGH_REG,\n \t\t\t\t\t    1);\n+\t} else {\n+\t\tULP_COMP_FLD_IDX_WR(params,\n+\t\t\t\t    BNXT_ULP_CF_IDX_HA_SUPPORT_DISABLED,\n+\t\t\t\t    1);\n \t}\n \n \t/* Update the socket direct flag */\n@@ -197,13 +214,7 @@ bnxt_ulp_flow_create(struct rte_eth_dev *dev,\n \t/* Set the flow attributes */\n \tbnxt_ulp_set_dir_attributes(&params, attr);\n \n-\t/* copy the device port id and direction for further processing */\n-\tULP_COMP_FLD_IDX_WR(&params, BNXT_ULP_CF_IDX_INCOMING_IF,\n-\t\t\t    dev->data->port_id);\n-\tULP_COMP_FLD_IDX_WR(&params, BNXT_ULP_CF_IDX_DEV_PORT_ID,\n-\t\t\t    dev->data->port_id);\n-\tULP_COMP_FLD_IDX_WR(&params, BNXT_ULP_CF_IDX_SVIF_FLAG,\n-\t\t\t    BNXT_ULP_INVALID_SVIF_VAL);\n+\tbnxt_ulp_init_parser_cf_defaults(&params, dev->data->port_id);\n \n \t/* Get the function id */\n \tif (ulp_port_db_port_func_id_get(ulp_ctx,\n@@ -320,6 +331,7 @@ bnxt_ulp_flow_validate(struct rte_eth_dev *dev,\n \n \t/* Set the flow attributes */\n \tbnxt_ulp_set_dir_attributes(&params, attr);\n+\tbnxt_ulp_init_parser_cf_defaults(&params, dev->data->port_id);\n \n \t/* Parse the rte flow pattern */\n \tret = bnxt_ulp_rte_parser_hdr_parse(pattern, &params);\n@@ -494,6 +506,256 @@ bnxt_ulp_flow_query(struct rte_eth_dev *eth_dev,\n \treturn rc;\n }\n \n+static int32_t\n+bnxt_ulp_action_handle_chk_args(const struct rte_flow_action *action,\n+\t\t\t\tconst struct rte_flow_indir_action_conf *conf)\n+{\n+\tif (!action || !conf)\n+\t\treturn BNXT_TF_RC_ERROR;\n+\t/* shared action only allowed to have one direction */\n+\tif (conf->ingress == 1 && conf->egress ==  1)\n+\t\treturn BNXT_TF_RC_ERROR;\n+\t/* shared action must have at least one direction */\n+\tif (conf->ingress == 0 && conf->egress ==  0)\n+\t\treturn BNXT_TF_RC_ERROR;\n+\treturn BNXT_TF_RC_SUCCESS;\n+}\n+\n+static inline void\n+bnxt_ulp_set_action_handle_dir_attr(struct ulp_rte_parser_params *params,\n+\t\t\t\t    const struct rte_flow_indir_action_conf *conf)\n+{\n+\tif (conf->ingress == 1)\n+\t\tparams->dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;\n+\telse if (conf->egress == 1)\n+\t\tparams->dir_attr |= BNXT_ULP_FLOW_ATTR_EGRESS;\n+}\n+\n+static struct rte_flow_action_handle *\n+bnxt_ulp_action_handle_create(struct rte_eth_dev *dev,\n+\t\t\t      const struct rte_flow_indir_action_conf *conf,\n+\t\t\t      const struct rte_flow_action *action,\n+\t\t\t      struct rte_flow_error *error)\n+{\n+\tenum bnxt_ulp_intf_type port_type = BNXT_ULP_INTF_TYPE_INVALID;\n+\tstruct bnxt_ulp_mapper_create_parms mparms = { 0 };\n+\tstruct ulp_rte_parser_params params;\n+\tstruct bnxt_ulp_context *ulp_ctx;\n+\tuint32_t act_tid;\n+\tuint16_t func_id;\n+\tuint32_t ifindex;\n+\tint ret = BNXT_TF_RC_ERROR;\n+\tconst struct rte_flow_action actions[2] = {\n+\t\t{\n+\t\t\t.type = action->type,\n+\t\t\t.conf = action->conf\n+\t\t},\n+\t\t{\n+\t\t\t.type = RTE_FLOW_ACTION_TYPE_END\n+\t\t}\n+\t};\n+\n+\tif (bnxt_ulp_action_handle_chk_args(action, conf) != BNXT_TF_RC_SUCCESS)\n+\t\tgoto parse_error;\n+\n+\tulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);\n+\tif (!ulp_ctx) {\n+\t\tBNXT_TF_DBG(ERR, \"ULP context is not initialized\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\t/* Initialize the parser params */\n+\tmemset(&params, 0, sizeof(struct ulp_rte_parser_params));\n+\tparams.ulp_ctx = ulp_ctx;\n+\n+\tULP_BITMAP_SET(params.act_bitmap.bits, BNXT_ULP_ACT_BIT_SHARED);\n+\n+\t/* Set the shared action direction attribute */\n+\tbnxt_ulp_set_action_handle_dir_attr(&params, conf);\n+\n+\t/* perform the conversion from dpdk port to bnxt ifindex */\n+\tif (ulp_port_db_dev_port_to_ulp_index(ulp_ctx,\n+\t\t\t\t\t      dev->data->port_id,\n+\t\t\t\t\t      &ifindex)) {\n+\t\tBNXT_TF_DBG(ERR, \"Port id is not valid\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\tport_type = ulp_port_db_port_type_get(ulp_ctx, ifindex);\n+\tif (port_type == BNXT_ULP_INTF_TYPE_INVALID) {\n+\t\tBNXT_TF_DBG(ERR, \"Port type is not valid\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\tbnxt_ulp_init_parser_cf_defaults(&params, dev->data->port_id);\n+\n+\t/* Emulating the match port for direction processing */\n+\tULP_COMP_FLD_IDX_WR(&params, BNXT_ULP_CF_IDX_MATCH_PORT_TYPE,\n+\t\t\t    port_type);\n+\n+\tif ((params.dir_attr & BNXT_ULP_FLOW_ATTR_INGRESS) &&\n+\t    port_type == BNXT_ULP_INTF_TYPE_VF_REP) {\n+\t\tULP_COMP_FLD_IDX_WR(&params, BNXT_ULP_CF_IDX_DIRECTION,\n+\t\t\t\t    BNXT_ULP_DIR_EGRESS);\n+\t} else {\n+\t\t/* Assign the input direction */\n+\t\tif (params.dir_attr & BNXT_ULP_FLOW_ATTR_INGRESS)\n+\t\t\tULP_COMP_FLD_IDX_WR(&params, BNXT_ULP_CF_IDX_DIRECTION,\n+\t\t\t\t\t    BNXT_ULP_DIR_INGRESS);\n+\t\telse\n+\t\t\tULP_COMP_FLD_IDX_WR(&params, BNXT_ULP_CF_IDX_DIRECTION,\n+\t\t\t\t\t    BNXT_ULP_DIR_EGRESS);\n+\t}\n+\n+\t/* Parse the shared action */\n+\tret = bnxt_ulp_rte_parser_act_parse(actions, &params);\n+\tif (ret != BNXT_TF_RC_SUCCESS)\n+\t\tgoto parse_error;\n+\n+\t/* Perform the rte flow post process */\n+\tbnxt_ulp_rte_parser_post_process(&params);\n+\n+\t/* do the tunnel offload process if any */\n+\tret = ulp_tunnel_offload_process(&params);\n+\tif (ret == BNXT_TF_RC_ERROR)\n+\t\tgoto parse_error;\n+\n+\tret = ulp_matcher_action_match(&params, &act_tid);\n+\tif (ret != BNXT_TF_RC_SUCCESS)\n+\t\tgoto parse_error;\n+\n+\tbnxt_ulp_init_mapper_params(&mparms, &params,\n+\t\t\t\t    BNXT_ULP_FDB_TYPE_REGULAR);\n+\tmparms.act_tid = act_tid;\n+\n+\t/* Get the function id */\n+\tif (ulp_port_db_port_func_id_get(ulp_ctx,\n+\t\t\t\t\t dev->data->port_id,\n+\t\t\t\t\t &func_id)) {\n+\t\tBNXT_TF_DBG(ERR, \"conversion of port to func id failed\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\t/* Protect flow creation */\n+\tif (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {\n+\t\tBNXT_TF_DBG(ERR, \"Flow db lock acquire failed\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\tret = ulp_mapper_flow_create(params.ulp_ctx, &mparms);\n+\tbnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);\n+\n+\tif (ret)\n+\t\tgoto parse_error;\n+\n+\treturn (struct rte_flow_action_handle *)((uintptr_t)mparms.shared_hndl);\n+\n+parse_error:\n+\trte_flow_error_set(error, ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,\n+\t\t\t   \"Failed to create shared action.\");\n+\treturn NULL;\n+}\n+\n+static int\n+bnxt_ulp_action_handle_destroy(struct rte_eth_dev *dev,\n+\t\t\t       struct rte_flow_action_handle *shared_hndl,\n+\t\t\t       struct rte_flow_error *error)\n+{\n+\tstruct bnxt_ulp_mapper_create_parms mparms = { 0 };\n+\tstruct bnxt_ulp_shared_act_info *act_info;\n+\tstruct ulp_rte_parser_params params;\n+\tstruct ulp_rte_act_prop *act_prop;\n+\tstruct bnxt_ulp_context *ulp_ctx;\n+\tenum bnxt_ulp_direction_type dir;\n+\tuint32_t act_tid, act_info_entries;\n+\tint ret = BNXT_TF_RC_ERROR;\n+\tuint32_t shared_action_type;\n+\tuint64_t tmp64;\n+\n+\tulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);\n+\tif (!ulp_ctx) {\n+\t\tBNXT_TF_DBG(ERR, \"ULP context is not initialized\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\tif (!shared_hndl) {\n+\t\tBNXT_TF_DBG(ERR, \"Invalid argument of shared handle\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\tact_prop = &params.act_prop;\n+\tmemset(&params, 0, sizeof(struct ulp_rte_parser_params));\n+\tparams.ulp_ctx = ulp_ctx;\n+\n+\tif (bnxt_ulp_cntxt_app_id_get(ulp_ctx, &params.app_id)) {\n+\t\tBNXT_TF_DBG(ERR, \"failed to get the app id\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\t/* The template will delete the entry if there are no references */\n+\tif (bnxt_get_action_handle_type(shared_hndl, &shared_action_type)) {\n+\t\tBNXT_TF_DBG(ERR, \"Invalid shared handle\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\tact_info_entries = 0;\n+\tact_info = bnxt_ulp_shared_act_info_get(&act_info_entries);\n+\tif (shared_action_type >= act_info_entries || !act_info) {\n+\t\tBNXT_TF_DBG(ERR, \"Invalid shared handle\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\tULP_BITMAP_SET(params.act_bitmap.bits,\n+\t\t       act_info[shared_action_type].act_bitmask);\n+\tULP_BITMAP_SET(params.act_bitmap.bits, BNXT_ULP_ACT_BIT_DELETE);\n+\n+\tret = bnxt_get_action_handle_direction(shared_hndl, &dir);\n+\tif (ret) {\n+\t\tBNXT_TF_DBG(ERR, \"Invalid shared handle dir\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\tif (dir == BNXT_ULP_DIR_EGRESS) {\n+\t\tparams.dir_attr = BNXT_ULP_FLOW_ATTR_EGRESS;\n+\t\tULP_BITMAP_SET(params.act_bitmap.bits,\n+\t\t\t       BNXT_ULP_FLOW_DIR_BITMASK_EGR);\n+\t} else {\n+\t\tparams.dir_attr = BNXT_ULP_FLOW_ATTR_INGRESS;\n+\t\tULP_BITMAP_SET(params.act_bitmap.bits,\n+\t\t\t       BNXT_ULP_FLOW_DIR_BITMASK_ING);\n+\t}\n+\n+\ttmp64 = tfp_cpu_to_be_64((uint64_t)\n+\t\t\t\t bnxt_get_action_handle_index(shared_hndl));\n+\n+\tmemcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_SHARED_HANDLE],\n+\t       &tmp64, BNXT_ULP_ACT_PROP_SZ_SHARED_HANDLE);\n+\n+\tret = ulp_matcher_action_match(&params, &act_tid);\n+\tif (ret != BNXT_TF_RC_SUCCESS)\n+\t\tgoto parse_error;\n+\n+\tbnxt_ulp_init_mapper_params(&mparms, &params,\n+\t\t\t\t    BNXT_ULP_FDB_TYPE_REGULAR);\n+\tmparms.act_tid = act_tid;\n+\n+\tif (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {\n+\t\tBNXT_TF_DBG(ERR, \"Flow db lock acquire failed\\n\");\n+\t\tgoto parse_error;\n+\t}\n+\n+\tret = ulp_mapper_flow_create(ulp_ctx, &mparms);\n+\tbnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);\n+\tif (ret)\n+\t\tgoto parse_error;\n+\n+\treturn 0;\n+\n+parse_error:\n+\trte_flow_error_set(error, BNXT_TF_RC_ERROR,\n+\t\t\t   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,\n+\t\t\t   \"Failed to destroy shared action.\");\n+\treturn -EINVAL;\n+}\n+\n /* Tunnel offload Apis */\n #define BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS\t1\n \n@@ -685,6 +947,8 @@ const struct rte_flow_ops bnxt_ulp_rte_flow_ops = {\n \t.flush = bnxt_ulp_flow_flush,\n \t.query = bnxt_ulp_flow_query,\n \t.isolate = NULL,\n+\t.action_handle_create = bnxt_ulp_action_handle_create,\n+\t.action_handle_destroy = bnxt_ulp_action_handle_destroy,\n \t/* Tunnel offload callbacks */\n \t.tunnel_decap_set = bnxt_ulp_tunnel_decap_set,\n \t.tunnel_match = bnxt_ulp_tunnel_match,\ndiff --git a/drivers/net/bnxt/tf_ulp/meson.build b/drivers/net/bnxt/tf_ulp/meson.build\nindex 71094b9974..c7df7e42f1 100644\n--- a/drivers/net/bnxt/tf_ulp/meson.build\n+++ b/drivers/net/bnxt/tf_ulp/meson.build\n@@ -1,28 +1,29 @@\n # SPDX-License-Identifier: BSD-3-Clause\n # Copyright(c) 2018 Intel Corporation\n-# Copyright(c) 2021 Broadcom\n+# Copyright(c) 2023 Broadcom\n \n #Include the folder for headers\n includes += include_directories('.')\n+cflags += '-DBNXT_TF_APP_ID=0'\n \n #Add the source files\n sources += files(\n+        'bnxt_tf_pmd_shim.c',\n         'bnxt_ulp.c',\n-        'ulp_mark_mgr.c',\n-        'ulp_flow_db.c',\n-        'ulp_utils.c',\n-        'ulp_mapper.c',\n-        'ulp_matcher.c',\n-        'ulp_rte_parser.c',\n         'bnxt_ulp_flow.c',\n-        'ulp_port_db.c',\n         'ulp_def_rules.c',\n         'ulp_fc_mgr.c',\n-        'ulp_tun.c',\n-        'bnxt_tf_pmd_shim.c',\n-        'ulp_gen_tbl.c',\n+        'ulp_flow_db.c',\n         'ulp_gen_hash.c',\n+        'ulp_gen_tbl.c',\n         'ulp_ha_mgr.c',\n-        'ulp_rte_handler_tbl.c')\n+        'ulp_mapper.c',\n+        'ulp_mark_mgr.c',\n+        'ulp_matcher.c',\n+        'ulp_port_db.c',\n+        'ulp_rte_handler_tbl.c',\n+        'ulp_rte_parser.c',\n+        'ulp_tun.c',\n+        'ulp_utils.c')\n \n subdir('generic_templates')\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_fc_mgr.c b/drivers/net/bnxt/tf_ulp/ulp_fc_mgr.c\nindex dee2c04b24..c39cde39aa 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_fc_mgr.c\n+++ b/drivers/net/bnxt/tf_ulp/ulp_fc_mgr.c\n@@ -438,8 +438,8 @@ void\n ulp_fc_mgr_alarm_cb(void *arg)\n {\n \tint rc = 0;\n-\tunsigned int j = 0;\n-\tenum tf_dir i = 0;\n+\tunsigned int j;\n+\tenum tf_dir i;\n \tstruct bnxt_ulp_context *ctxt;\n \tstruct bnxt_ulp_fc_info *ulp_fc_info;\n \tstruct bnxt_ulp_device_params *dparms;\n@@ -473,14 +473,6 @@ ulp_fc_mgr_alarm_cb(void *arg)\n \t\treturn;\n \t}\n \n-\ttfp = bnxt_ulp_cntxt_tfp_get(ctxt,\n-\t\t\t\t     ulp_fc_info->sw_acc_tbl[i][j].session_type);\n-\tif (!tfp) {\n-\t\tBNXT_TF_DBG(ERR, \"Failed to get the truflow pointer\\n\");\n-\t\tbnxt_ulp_cntxt_entry_release();\n-\t\treturn;\n-\t}\n-\n \t/*\n \t * Take the fc_lock to ensure no flow is destroyed\n \t * during the bulk get\n@@ -667,6 +659,7 @@ int32_t ulp_fc_mgr_cntr_reset(struct bnxt_ulp_context *ctxt, enum tf_dir dir,\n \tsw_cntr_idx = hw_cntr_id - ulp_fc_info->shadow_hw_tbl[dir].start_idx;\n \tulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].valid = false;\n \tulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].hw_cntr_id = 0;\n+\tulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].session_type = 0;\n \tulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].pkt_count = 0;\n \tulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].byte_count = 0;\n \tulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].pc_flow_idx = 0;\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_gen_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_gen_tbl.c\nindex 5279beb764..ebf32d6702 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_gen_tbl.c\n+++ b/drivers/net/bnxt/tf_ulp/ulp_gen_tbl.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -259,23 +259,26 @@ ulp_mapper_gen_tbl_entry_free(struct bnxt_ulp_context *ulp_ctx,\n \t\t\t      uint32_t tbl_idx, uint32_t ckey)\n {\n \tstruct ulp_flow_db_res_params res;\n+\tuint32_t fid = 0; /* not using for this case */\n \n \tres.direction = tbl_idx & 0x1;\n \tres.resource_sub_type = tbl_idx >> 1;\n \tres.resource_hndl = ckey;\n \n-\treturn ulp_mapper_gen_tbl_res_free(ulp_ctx, &res);\n+\treturn ulp_mapper_gen_tbl_res_free(ulp_ctx, fid, &res);\n }\n \n /* Free the generic table list resource\n  *\n  * ulp_ctx [in] - Pointer to the ulp context\n+ * fid [in] - The fid the generic table is associated with\n  * res [in] - Pointer to flow db resource entry\n  *\n  * returns 0 on success\n  */\n int32_t\n ulp_mapper_gen_tbl_res_free(struct bnxt_ulp_context *ulp_ctx,\n+\t\t\t    uint32_t fid,\n \t\t\t    struct ulp_flow_db_res_params *res)\n {\n \tstruct bnxt_ulp_mapper_data *mapper_data;\n@@ -283,7 +286,7 @@ ulp_mapper_gen_tbl_res_free(struct bnxt_ulp_context *ulp_ctx,\n \tstruct ulp_mapper_gen_tbl_entry entry;\n \tstruct ulp_gen_hash_entry_params hash_entry;\n \tint32_t tbl_idx;\n-\tuint32_t fid = 0;\n+\tuint32_t rid = 0;\n \tuint32_t key_idx;\n \n \t/* Extract the resource sub type and direction */\n@@ -326,9 +329,10 @@ ulp_mapper_gen_tbl_res_free(struct bnxt_ulp_context *ulp_ctx,\n \n \t/* Decrement the reference count */\n \tif (!ULP_GEN_TBL_REF_CNT(&entry)) {\n-\t\tBNXT_TF_DBG(ERR, \"generic table corrupt %x:%\" PRIX64 \"\\n\",\n+\t\tBNXT_TF_DBG(DEBUG,\n+\t\t\t    \"generic table entry already free %x:%\" PRIX64 \"\\n\",\n \t\t\t    tbl_idx, res->resource_hndl);\n-\t\treturn -EINVAL;\n+\t\treturn 0;\n \t}\n \tULP_GEN_TBL_REF_CNT_DEC(&entry);\n \n@@ -336,24 +340,27 @@ ulp_mapper_gen_tbl_res_free(struct bnxt_ulp_context *ulp_ctx,\n \tif (ULP_GEN_TBL_REF_CNT(&entry))\n \t\treturn 0;\n \n-\t/* Delete the generic table entry. First extract the fid */\n+\t/* Delete the generic table entry. First extract the rid */\n \tif (ulp_mapper_gen_tbl_entry_data_get(&entry, ULP_GEN_TBL_FID_OFFSET,\n \t\t\t\t\t      ULP_GEN_TBL_FID_SIZE_BITS,\n-\t\t\t\t\t      (uint8_t *)&fid,\n-\t\t\t\t\t      sizeof(fid))) {\n-\t\tBNXT_TF_DBG(ERR, \"Unable to get fid %x:%\" PRIX64 \"\\n\",\n+\t\t\t\t\t      (uint8_t *)&rid,\n+\t\t\t\t\t      sizeof(rid))) {\n+\t\tBNXT_TF_DBG(ERR, \"Unable to get rid %x:%\" PRIX64 \"\\n\",\n \t\t\t    tbl_idx, res->resource_hndl);\n \t\treturn -EINVAL;\n \t}\n-\tfid = tfp_be_to_cpu_32(fid);\n-\t/* no need to del if fid is 0 since there is no associated resource */\n-\tif (fid) {\n+\trid = tfp_be_to_cpu_32(rid);\n+\t/* no need to del if rid is 0 since there is no associated resource\n+\t * if rid from the entry is equal to the incoming fid, then we have a\n+\t * recursive delete, so don't follow the rid.\n+\t */\n+\tif (rid && rid != fid) {\n \t\t/* Destroy the flow associated with the shared flow id */\n \t\tif (ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_RID,\n-\t\t\t\t\t    fid))\n+\t\t\t\t\t    rid))\n \t\t\tBNXT_TF_DBG(ERR,\n-\t\t\t\t    \"Error in deleting shared flow id %x\\n\",\n-\t\t\t\t    fid);\n+\t\t\t\t    \"Error in deleting shared resource id %x\\n\",\n+\t\t\t\t    rid);\n \t}\n \n \t/* Delete the entry from the hash table */\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_gen_tbl.h b/drivers/net/bnxt/tf_ulp/ulp_gen_tbl.h\nindex 3060072967..4c5a6e176f 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_gen_tbl.h\n+++ b/drivers/net/bnxt/tf_ulp/ulp_gen_tbl.h\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -134,12 +134,14 @@ ulp_mapper_gen_tbl_entry_data_get(struct ulp_mapper_gen_tbl_entry *entry,\n  * Free the generic table list resource\n  *\n  * ulp_ctx [in] - Pointer to the ulp context\n+ * fid [in] - The fid the generic table is associated with\n  * res [in] - Pointer to flow db resource entry\n  *\n  * returns 0 on success\n  */\n int32_t\n ulp_mapper_gen_tbl_res_free(struct bnxt_ulp_context *ulp_ctx,\n+\t\t\t    uint32_t fid,\n \t\t\t    struct ulp_flow_db_res_params *res);\n \n /* Free the generic table list entry\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_ha_mgr.c b/drivers/net/bnxt/tf_ulp/ulp_ha_mgr.c\nindex 42482b596f..f3f5bda890 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_ha_mgr.c\n+++ b/drivers/net/bnxt/tf_ulp/ulp_ha_mgr.c\n@@ -23,8 +23,6 @@\n \n #define ULP_HA_IF_TBL_DIR\tTF_DIR_RX\n #define ULP_HA_IF_TBL_TYPE\tTF_IF_TBL_TYPE_PROF_PARIF_ERR_ACT_REC_PTR\n-#define ULP_HA_IF_TBL_IDX 10\n-#define ULP_HA_CLIENT_CNT_IF_TBL_IDX 9\n \n static void ulp_ha_mgr_timer_cancel(struct bnxt_ulp_context *ulp_ctx);\n static int32_t ulp_ha_mgr_timer_start(void *arg);\n@@ -42,8 +40,8 @@ static int32_t\n ulp_ha_mgr_tf_client_num_get(struct bnxt_ulp_context *ulp_ctx, uint32_t *cnt);\n \n static int32_t\n-ulp_ha_mgr_state_set(struct bnxt_ulp_context *ulp_ctx,\n-\t\t     enum ulp_ha_mgr_state state)\n+ulp_ha_mgr_state_set_v1(struct bnxt_ulp_context *ulp_ctx,\n+\t\t\tenum ulp_ha_mgr_state state)\n {\n \tstruct tf_set_if_tbl_entry_parms set_parms = { 0 };\n \tstruct tf *tfp;\n@@ -66,7 +64,7 @@ ulp_ha_mgr_state_set(struct bnxt_ulp_context *ulp_ctx,\n \tset_parms.type = ULP_HA_IF_TBL_TYPE;\n \tset_parms.data = (uint8_t *)&val;\n \tset_parms.data_sz_in_bytes = sizeof(val);\n-\tset_parms.idx = ULP_HA_IF_TBL_IDX;\n+\tset_parms.idx = bnxt_ulp_ha_reg_state_get(ulp_ctx);\n \n \trc = tf_set_if_tbl_entry(tfp, &set_parms);\n \tif (rc)\n@@ -76,8 +74,82 @@ ulp_ha_mgr_state_set(struct bnxt_ulp_context *ulp_ctx,\n }\n \n static int32_t\n-ulp_ha_mgr_tf_client_num_get(struct bnxt_ulp_context *ulp_ctx,\n-\t\t\t     uint32_t *cnt)\n+ulp_ha_mgr_state_set_v2(struct bnxt_ulp_context *ulp_ctx,\n+\t\t\tenum ulp_ha_mgr_state state)\n+{\n+\tstruct tf_set_session_hotup_state_parms parms = { 0 };\n+\tstruct tf *tfp;\n+\tint32_t rc = 0;\n+\n+\tif (ulp_ctx == NULL) {\n+\t\tBNXT_TF_DBG(ERR, \"Invalid parms in state get.\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\ttfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, BNXT_ULP_SESSION_TYPE_SHARED_WC);\n+\tif (tfp == NULL) {\n+\t\tBNXT_TF_DBG(ERR, \"Unable to get the TFP.\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tparms.state = (uint16_t)state;\n+\trc = tf_set_session_hotup_state(tfp, &parms);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to write the HA state\\n\");\n+\t\treturn rc;\n+\t}\n+\n+\treturn rc;\n+}\n+\n+static int32_t\n+ulp_ha_mgr_state_set(struct bnxt_ulp_context *ulp_ctx,\n+\t\t     enum ulp_ha_mgr_state state)\n+{\n+\tif (bnxt_ulp_cntxt_multi_shared_session_enabled(ulp_ctx))\n+\t\treturn ulp_ha_mgr_state_set_v2(ulp_ctx, state);\n+\telse\n+\t\treturn ulp_ha_mgr_state_set_v1(ulp_ctx, state);\n+}\n+\n+static int32_t\n+ulp_ha_mgr_tf_state_get(struct bnxt_ulp_context *ulp_ctx,\n+\t\t\tuint32_t *state,\n+\t\t\tuint32_t *cnt)\n+{\n+\tstruct tf_get_session_hotup_state_parms parms = { 0 };\n+\tstruct tf *tfp;\n+\tint32_t rc = 0;\n+\n+\tif (ulp_ctx == NULL) {\n+\t\tBNXT_TF_DBG(ERR, \"Invalid parms in client num get.\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\ttfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, BNXT_ULP_SESSION_TYPE_SHARED_WC);\n+\tif (tfp == NULL) {\n+\t\tBNXT_TF_DBG(ERR, \"Unable to get the TFP.\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\trc = tf_get_session_hotup_state(tfp, &parms);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to read the HA state\\n\");\n+\t\treturn rc;\n+\t}\n+\n+\tif (state)\n+\t\t*state = parms.state;\n+\n+\tif (cnt)\n+\t\t*cnt = parms.ref_cnt;\n+\n+\treturn rc;\n+}\n+\n+static int32_t\n+ulp_ha_mgr_tf_client_num_get_v1(struct bnxt_ulp_context *ulp_ctx,\n+\t\t\t\tuint32_t *cnt)\n {\n \tstruct tf_get_if_tbl_entry_parms get_parms = { 0 };\n \tstruct tf *tfp;\n@@ -96,7 +168,7 @@ ulp_ha_mgr_tf_client_num_get(struct bnxt_ulp_context *ulp_ctx,\n \n \tget_parms.dir = ULP_HA_IF_TBL_DIR;\n \tget_parms.type = ULP_HA_IF_TBL_TYPE;\n-\tget_parms.idx = ULP_HA_CLIENT_CNT_IF_TBL_IDX;\n+\tget_parms.idx = bnxt_ulp_ha_reg_cnt_get(ulp_ctx);\n \tget_parms.data = (uint8_t *)&val;\n \tget_parms.data_sz_in_bytes = sizeof(val);\n \n@@ -108,6 +180,16 @@ ulp_ha_mgr_tf_client_num_get(struct bnxt_ulp_context *ulp_ctx,\n \treturn rc;\n }\n \n+static int32_t\n+ulp_ha_mgr_tf_client_num_get(struct bnxt_ulp_context *ulp_ctx,\n+\t\t\t     uint32_t *cnt)\n+{\n+\tif (bnxt_ulp_cntxt_multi_shared_session_enabled(ulp_ctx))\n+\t\treturn ulp_ha_mgr_tf_state_get(ulp_ctx, NULL, cnt);\n+\telse\n+\t\treturn ulp_ha_mgr_tf_client_num_get_v1(ulp_ctx, cnt);\n+}\n+\n static int32_t\n ulp_ha_mgr_region_set(struct bnxt_ulp_context *ulp_ctx,\n \t\t      enum ulp_ha_mgr_region region)\n@@ -386,9 +468,9 @@ ulp_ha_mgr_app_type_get(struct bnxt_ulp_context *ulp_ctx,\n \treturn 0;\n }\n \n-int32_t\n-ulp_ha_mgr_state_get(struct bnxt_ulp_context *ulp_ctx,\n-\t\t     enum ulp_ha_mgr_state *state)\n+static int32_t\n+ulp_ha_mgr_state_get_v1(struct bnxt_ulp_context *ulp_ctx,\n+\t\t\tenum ulp_ha_mgr_state *state)\n {\n \tstruct tf_get_if_tbl_entry_parms get_parms = { 0 };\n \tstruct tf *tfp;\n@@ -407,7 +489,7 @@ ulp_ha_mgr_state_get(struct bnxt_ulp_context *ulp_ctx,\n \n \tget_parms.dir = ULP_HA_IF_TBL_DIR;\n \tget_parms.type = ULP_HA_IF_TBL_TYPE;\n-\tget_parms.idx = ULP_HA_IF_TBL_IDX;\n+\tget_parms.idx = bnxt_ulp_ha_reg_state_get(ulp_ctx);\n \tget_parms.data = (uint8_t *)&val;\n \tget_parms.data_sz_in_bytes = sizeof(val);\n \n@@ -419,6 +501,16 @@ ulp_ha_mgr_state_get(struct bnxt_ulp_context *ulp_ctx,\n \treturn rc;\n }\n \n+int32_t\n+ulp_ha_mgr_state_get(struct bnxt_ulp_context *ulp_ctx,\n+\t\t     enum ulp_ha_mgr_state *state)\n+{\n+\tif (bnxt_ulp_cntxt_multi_shared_session_enabled(ulp_ctx))\n+\t\treturn ulp_ha_mgr_tf_state_get(ulp_ctx, state, NULL);\n+\telse\n+\t\treturn ulp_ha_mgr_state_get_v1(ulp_ctx, state);\n+}\n+\n int32_t\n ulp_ha_mgr_open(struct bnxt_ulp_context *ulp_ctx)\n {\n@@ -607,10 +699,9 @@ ulp_ha_mgr_close(struct bnxt_ulp_context *ulp_ctx)\n \t\tBNXT_TF_DBG(INFO,\n \t\t\t    \"On Close: SEC[COPY] => [INIT] after %d ms\\n\",\n \t\t\t    ULP_HA_WAIT_TIMEOUT - timeout);\n-\t} else {\n-\t\tBNXT_TF_DBG(ERR, \"On Close: Invalid type/state %d/%d\\n\",\n-\t\t\t    curr_state, app_type);\n \t}\n+\t/* else do nothing just return*/\n+\n cleanup:\n \treturn rc;\n }\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_ha_mgr.h b/drivers/net/bnxt/tf_ulp/ulp_ha_mgr.h\nindex ded967a0af..c39a1371d9 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_ha_mgr.h\n+++ b/drivers/net/bnxt/tf_ulp/ulp_ha_mgr.h\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -8,6 +8,9 @@\n \n #include \"bnxt_ulp.h\"\n \n+#define ULP_HA_IF_TBL_IDX 10\n+#define ULP_HA_CLIENT_CNT_IF_TBL_IDX 9\n+\n enum ulp_ha_mgr_state {\n \tULP_HA_STATE_INIT,\n \tULP_HA_STATE_PRIM_RUN,\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.c b/drivers/net/bnxt/tf_ulp/ulp_mapper.c\nindex 1f459c52a4..e5f1d266d7 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_mapper.c\n+++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.c\n@@ -149,7 +149,7 @@ ulp_mapper_resource_ident_allocate(struct bnxt_ulp_context *ulp_ctx,\n \t * Shared resources are never allocated through this method, so the\n \t * shared flag is always false.\n \t */\n-\trc = ulp_mapper_glb_resource_write(mapper_data, glb_res, regval, false);\n+\trc = ulp_mapper_glb_resource_write(mapper_data, glb_res, regval, shared);\n \tif (rc) {\n \t\tBNXT_TF_DBG(ERR, \"Failed to write to global resource id\\n\");\n \t\t/* Free the identifier when update failed */\n@@ -212,7 +212,7 @@ ulp_mapper_resource_index_tbl_alloc(struct bnxt_ulp_context *ulp_ctx,\n \t * Shared resources are never allocated through this method, so the\n \t * shared flag is always false.\n \t */\n-\trc = ulp_mapper_glb_resource_write(mapper_data, glb_res, regval, false);\n+\trc = ulp_mapper_glb_resource_write(mapper_data, glb_res, regval, shared);\n \tif (rc) {\n \t\tBNXT_TF_DBG(ERR, \"Failed to write to global resource id\\n\");\n \t\t/* Free the identifier when update failed */\n@@ -442,6 +442,7 @@ ulp_mapper_dyn_tbl_type_get(struct bnxt_ulp_mapper_parms *mparms,\n \t\tcase TF_TBL_TYPE_ACT_ENCAP_16B:\n \t\tcase TF_TBL_TYPE_ACT_ENCAP_32B:\n \t\tcase TF_TBL_TYPE_ACT_ENCAP_64B:\n+\t\tcase TF_TBL_TYPE_ACT_ENCAP_128B:\n \t\t\tsize_map = d_params->dyn_encap_sizes;\n \t\t\tfor (i = 0; i < d_params->dyn_encap_list_size; i++) {\n \t\t\t\tif (blob_len <= size_map[i].slab_size) {\n@@ -534,6 +535,41 @@ ulp_mapper_tcam_entry_free(struct bnxt_ulp_context *ulp,\n \treturn tf_free_tcam_entry(tfp, &fparms);\n }\n \n+static int32_t\n+ulp_mapper_clear_full_action_record(struct tf *tfp,\n+\t\t\t\t    struct bnxt_ulp_context *ulp_ctx,\n+\t\t\t\t    struct tf_free_tbl_entry_parms *fparms)\n+{\n+\tstruct tf_set_tbl_entry_parms sparms = { 0 };\n+\tuint32_t dev_id = BNXT_ULP_DEVICE_ID_LAST;\n+\tint32_t rc = 0;\n+\n+\trc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Unable to get the dev id from ulp.\\n\");\n+\t\treturn rc;\n+\t}\n+\n+\tif (dev_id == BNXT_ULP_DEVICE_ID_THOR) {\n+\t\tsparms.dir = fparms->dir;\n+\t\tsparms.data = mapper_fld_zeros;\n+\t\tsparms.type = fparms->type;\n+\t\tsparms.data_sz_in_bytes = 16; /* FULL ACT REC SIZE - THOR */\n+\t\tsparms.idx = fparms->idx;\n+\t\tsparms.tbl_scope_id = fparms->tbl_scope_id;\n+\t\trc = tf_set_tbl_entry(tfp, &sparms);\n+\t\tif (rc) {\n+\t\t\tBNXT_TF_DBG(ERR,\n+\t\t\t\t    \"Index table[%s][%s][%x] write fail rc=%d\\n\",\n+\t\t\t\t    tf_tbl_type_2_str(sparms.type),\n+\t\t\t\t    tf_dir_2_str(sparms.dir),\n+\t\t\t\t    sparms.idx, rc);\n+\t\t\treturn rc;\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n static inline int32_t\n ulp_mapper_index_entry_free(struct bnxt_ulp_context *ulp,\n \t\t\t    struct tf *tfp,\n@@ -551,6 +587,9 @@ ulp_mapper_index_entry_free(struct bnxt_ulp_context *ulp,\n \t */\n \t(void)bnxt_ulp_cntxt_tbl_scope_id_get(ulp, &fparms.tbl_scope_id);\n \n+\tif (fparms.type == TF_TBL_TYPE_FULL_ACT_RECORD)\n+\t\t(void)ulp_mapper_clear_full_action_record(tfp, ulp, &fparms);\n+\n \treturn tf_free_tbl_entry(tfp, &fparms);\n }\n \n@@ -665,6 +704,10 @@ ulp_mapper_fdb_opc_alloc_rid(struct bnxt_ulp_mapper_parms *parms,\n \t\t\t\t     BNXT_ULP_FDB_TYPE_RID, rid);\n \t\treturn -EINVAL;\n \t}\n+\t/* save the rid into the parms in case a flow fails before pushing the\n+\t * rid into the fid\n+\t */\n+\tparms->rid = rid;\n \treturn 0;\n }\n \n@@ -845,7 +888,7 @@ ulp_mapper_ident_process(struct bnxt_ulp_mapper_parms *parms,\n \t\t\t    tf_ident_2_str(iparms.ident_type));\n \t\treturn rc;\n \t}\n-\tBNXT_TF_INF(\"Alloc ident %s:%s.success.\\n\",\n+\tBNXT_TF_DBG(DEBUG, \"Alloc ident %s:%s.success.\\n\",\n \t\t    tf_dir_2_str(iparms.dir),\n \t\t    tf_ident_2_str(iparms.ident_type));\n \n@@ -941,9 +984,9 @@ ulp_mapper_ident_extract(struct bnxt_ulp_mapper_parms *parms,\n \t\t\t    sparms.search_id);\n \t\treturn rc;\n \t}\n-\tBNXT_TF_INF(\"Search ident %s:%s:%x.success.\\n\",\n+\tBNXT_TF_DBG(DEBUG, \"Search ident %s:%s:%x.success.\\n\",\n \t\t    tf_dir_2_str(sparms.dir),\n-\t\t    tf_tbl_type_2_str(sparms.ident_type),\n+\t\t    tf_ident_2_str(sparms.ident_type),\n \t\t    sparms.search_id);\n \n \t/* Write it to the regfile */\n@@ -1016,6 +1059,20 @@ ulp_mapper_field_port_db_process(struct bnxt_ulp_mapper_parms *parms,\n \t\t\treturn -EINVAL;\n \t\t}\n \t\tbreak;\n+\tcase BNXT_ULP_PORT_TABLE_PORT_IS_PF:\n+\t\tif (ulp_port_db_port_is_pf_get(parms->ulp_ctx, port_id,\n+\t\t\t\t\t       val)) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Invalid port id %u\\n\", port_id);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tbreak;\n+\tcase BNXT_ULP_PORT_TABLE_VF_FUNC_METADATA:\n+\t\tif (ulp_port_db_port_meta_data_get(parms->ulp_ctx, port_id,\n+\t\t\t\t\t\t   val)) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Invalid port id %u\\n\", port_id);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tbreak;\n \tdefault:\n \t\tBNXT_TF_DBG(ERR, \"Invalid port_data %d\\n\", port_data);\n \t\treturn -EINVAL;\n@@ -1042,6 +1099,7 @@ ulp_mapper_field_src_process(struct bnxt_ulp_mapper_parms *parms,\n \tuint8_t *buffer;\n \tuint64_t lregval;\n \tbool shared;\n+\tuint8_t i = 0;\n \n \t*val_len = bitlen;\n \t*value = 0;\n@@ -1111,6 +1169,11 @@ ulp_mapper_field_src_process(struct bnxt_ulp_mapper_parms *parms,\n \t\t\treturn -EINVAL;\n \t\t}\n \t\t*val = &buffer[field_size - bytelen];\n+\t\tif (sizeof(*value) >= field_size) {\n+\t\t\t*value = buffer[0];\n+\t\t\tfor (i = 1; i < field_size; i++)\n+\t\t\t\t*value = (*value <<  8) | buffer[i];\n+\t\t}\n \t\tbreak;\n \tcase BNXT_ULP_FIELD_SRC_ACT_PROP_SZ:\n \t\tif (!ulp_operand_read(field_opr,\n@@ -1254,11 +1317,22 @@ ulp_mapper_field_src_process(struct bnxt_ulp_mapper_parms *parms,\n \t\t}\n \t\tbreak;\n \tcase BNXT_ULP_FIELD_SRC_PORT_TABLE:\n+\t\tif (!ulp_operand_read(field_opr,\n+\t\t\t\t      (uint8_t *)&idx, sizeof(uint16_t))) {\n+\t\t\tBNXT_TF_DBG(ERR, \"CF operand read failed\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tidx = tfp_be_to_cpu_16(idx);\n+\t\tif (idx >= BNXT_ULP_CF_IDX_LAST || bytelen > sizeof(uint64_t)) {\n+\t\t\tBNXT_TF_DBG(ERR, \"comp field [%d] read oob %d\\n\", idx,\n+\t\t\t\t    bytelen);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n \t\t/* The port id is present in the comp field list */\n-\t\tport_id = ULP_COMP_FLD_IDX_RD(parms,\n-\t\t\t\t\t      BNXT_ULP_CF_IDX_DEV_PORT_ID);\n+\t\tport_id = ULP_COMP_FLD_IDX_RD(parms, idx);\n \t\t/* get the port table enum  */\n-\t\tif (!ulp_operand_read(field_opr,\n+\t\tif (!ulp_operand_read(field_opr + sizeof(uint16_t),\n \t\t\t\t      (uint8_t *)&idx, sizeof(uint16_t))) {\n \t\t\tBNXT_TF_DBG(ERR, \"Port table enum read failed\\n\");\n \t\t\treturn -EINVAL;\n@@ -1557,9 +1631,8 @@ ulp_mapper_field_opc_process(struct bnxt_ulp_mapper_parms *parms,\n \t\tbreak;\n \t}\n \n-\tif (!rc) {\n+\tif (!rc)\n \t\treturn rc;\n-\t}\n error:\n \tBNXT_TF_DBG(ERR, \"Error in %s:%s process %u:%u\\n\", name,\n \t\t    fld->description, (val) ? write_idx : 0, val_len);\n@@ -1878,7 +1951,7 @@ ulp_mapper_tcam_tbl_entry_write(struct bnxt_ulp_mapper_parms *parms,\n \t\t\t    tf_dir_2_str(sparms.dir), sparms.idx);\n \t\treturn -EIO;\n \t}\n-\tBNXT_TF_INF(\"tcam[%s][%s][%x] write success.\\n\",\n+\tBNXT_TF_DBG(DEBUG, \"tcam[%s][%s][%x] write success.\\n\",\n \t\t    tf_tcam_tbl_2_str(sparms.tcam_tbl_type),\n \t\t    tf_dir_2_str(sparms.dir), sparms.idx);\n \n@@ -2168,7 +2241,7 @@ ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n \n \t\trc = tf_search_tcam_entry(tfp, &searchparms);\n \t\tif (rc) {\n-\t\t\tBNXT_TF_DBG(ERR, \"tcam search failed rc=%d\\n\", rc);\n+\t\t\tBNXT_TF_DBG(ERR, \"entry priority process failed\\n\");\n \t\t\treturn rc;\n \t\t}\n \n@@ -2546,7 +2619,7 @@ ulp_mapper_index_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n \t\tgparms.dir = tbl->direction;\n \t\tgparms.type = tbl->resource_type;\n \t\tgparms.data = ulp_blob_data_get(&data, &tmplen);\n-\t\tgparms.data_sz_in_bytes = ULP_BITS_2_BYTE(tmplen);\n+\t\tgparms.data_sz_in_bytes = ULP_BITS_2_BYTE(tbl->result_bit_size);\n \t\tgparms.idx = index;\n \t\trc = tf_get_tbl_entry(tfp, &gparms);\n \t\tif (rc) {\n@@ -2651,7 +2724,6 @@ ulp_mapper_index_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n \t\tif (shared)\n \t\t\ttfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx,\n \t\t\t\t\t\t     tbl->session_type);\n-\n \t\trc = tf_set_tbl_entry(tfp, &sparms);\n \t\tif (rc) {\n \t\t\tBNXT_TF_DBG(ERR,\n@@ -2661,7 +2733,7 @@ ulp_mapper_index_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n \t\t\t\t    sparms.idx, rc);\n \t\t\tgoto error;\n \t\t}\n-\t\tBNXT_TF_INF(\"Index table[%s][%s][%x] write successful.\\n\",\n+\t\tBNXT_TF_DBG(DEBUG, \"Index table[%s][%s][%x] write successful\\n\",\n \t\t\t    tf_tbl_type_2_str(sparms.type),\n \t\t\t    tf_dir_2_str(sparms.dir), sparms.idx);\n \n@@ -2832,6 +2904,61 @@ ulp_mapper_if_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n \treturn rc;\n }\n \n+static int32_t\n+ulp_mapper_gen_tbl_ref_cnt_process(struct bnxt_ulp_mapper_parms *parms,\n+\t\t\t\t   struct bnxt_ulp_mapper_tbl_info *tbl,\n+\t\t\t\t   struct ulp_mapper_gen_tbl_entry *entry)\n+{\n+\tint32_t rc = 0;\n+\tuint64_t val64;\n+\n+\t/* Allow the template to manage the reference count */\n+\tswitch (tbl->ref_cnt_opcode) {\n+\tcase BNXT_ULP_REF_CNT_OPC_INC:\n+\t\tULP_GEN_TBL_REF_CNT_INC(entry);\n+\t\tbreak;\n+\tcase BNXT_ULP_REF_CNT_OPC_DEC:\n+\t\t/* writes never decrement the ref count */\n+\t\tif (tbl->tbl_opcode == BNXT_ULP_GENERIC_TBL_OPC_WRITE)\n+\t\t\treturn -EINVAL;\n+\n+\t\tULP_GEN_TBL_REF_CNT_DEC(entry);\n+\t\tbreak;\n+\tcase BNXT_ULP_REF_CNT_OPC_NOP:\n+\t\t/* Nothing to be done, generally used when\n+\t\t * template gets the ref_cnt to make a decision\n+\t\t */\n+\t\tbreak;\n+\tcase BNXT_ULP_REF_CNT_OPC_DEFAULT:\n+\t\t/* This is the default case and is backward\n+\t\t * compatible with older templates\n+\t\t */\n+\t\tif (tbl->fdb_opcode != BNXT_ULP_FDB_OPC_NOP)\n+\t\t\tULP_GEN_TBL_REF_CNT_INC(entry);\n+\t\tbreak;\n+\tdefault:\n+\t\tBNXT_TF_DBG(ERR, \"Invalid REF_CNT_OPC %d\\n\",\n+\t\t\t    tbl->ref_cnt_opcode);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (tbl->tbl_opcode == BNXT_ULP_GENERIC_TBL_OPC_READ) {\n+\t\t/* Add ref_cnt to the regfile for template to use. */\n+\t\tval64 = (uint32_t)ULP_GEN_TBL_REF_CNT(entry);\n+\t\tval64 = tfp_cpu_to_be_64(val64);\n+\t\trc = ulp_regfile_write(parms->regfile,\n+\t\t\t\t       BNXT_ULP_RF_IDX_REF_CNT,\n+\t\t\t\t       val64);\n+\t\tif (rc) {\n+\t\t\tBNXT_TF_DBG(ERR,\n+\t\t\t\t    \"Failed to write regfile[ref_cnt]\\n\");\n+\t\t\treturn rc;\n+\t\t}\n+\t}\n+\n+\treturn rc;\n+}\n+\n static int32_t\n ulp_mapper_gen_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n \t\t\t   struct bnxt_ulp_mapper_tbl_info *tbl)\n@@ -2886,6 +3013,7 @@ ulp_mapper_gen_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n \n \t/* The_key is a byte array convert it to a search index */\n \tcache_key = ulp_blob_data_get(&key, &tmplen);\n+\n \t/* get the generic table  */\n \tgen_tbl_list = &parms->mapper_data->gen_tbl_list[tbl_idx];\n \n@@ -2949,10 +3077,6 @@ ulp_mapper_gen_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n \t\t\t\t\t    \"Failed to scan ident list\\n\");\n \t\t\t\treturn -EINVAL;\n \t\t\t}\n-\t\t\tif (tbl->fdb_opcode != BNXT_ULP_FDB_OPC_NOP) {\n-\t\t\t\t/* increment the reference count */\n-\t\t\t\tULP_GEN_TBL_REF_CNT_INC(&gen_tbl_ent);\n-\t\t\t}\n \n \t\t\t/* it is a hit */\n \t\t\tgen_tbl_miss = 0;\n@@ -2969,8 +3093,13 @@ ulp_mapper_gen_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n \t\t\t/* store the hash index in the fdb */\n \t\t\tkey_index = hash_entry.hash_index;\n \t\t}\n-\t\t/* check the reference count */\n-\t\tif (ULP_GEN_TBL_REF_CNT(&gen_tbl_ent)) {\n+\n+\t\t/* check the reference count and ignore ref_cnt if NOP.\n+\t\t * NOP allows a write as an update.\n+\t\t */\n+\n+\t\tif (tbl->ref_cnt_opcode != BNXT_ULP_REF_CNT_OPC_NOP &&\n+\t\t    ULP_GEN_TBL_REF_CNT(&gen_tbl_ent)) {\n \t\t\t/* a hit then error */\n \t\t\tBNXT_TF_DBG(ERR, \"generic entry already present\\n\");\n \t\t\treturn -EINVAL; /* success */\n@@ -2999,8 +3128,6 @@ ulp_mapper_gen_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n \t\t\treturn -EINVAL;\n \t\t}\n \n-\t\t/* increment the reference count */\n-\t\tULP_GEN_TBL_REF_CNT_INC(&gen_tbl_ent);\n \t\tfdb_write = 1;\n \t\tparms->shared_hndl = (uint64_t)tbl_idx << 32 | key_index;\n \t\tbreak;\n@@ -3030,9 +3157,24 @@ ulp_mapper_gen_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n \t\tulp_flow_db_shared_session_set(&fid_parms, tbl->session_type);\n \n \t\trc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms);\n-\t\tif (rc)\n+\t\tif (rc) {\n \t\t\tBNXT_TF_DBG(ERR, \"Fail to add gen ent flowdb %d\\n\", rc);\n+\t\t\treturn rc;\n+\t\t}\n+\n+\t\t/* Reset the in-flight RID when generic table is written and the\n+\t\t * rid has been pushed into a handle (rid or fid).  Once it has\n+\t\t * been written, we have persistent accounting of the resources.\n+\t\t */\n+\t\tif (tbl->tbl_opcode == BNXT_ULP_GENERIC_TBL_OPC_WRITE &&\n+\t\t    (tbl->fdb_opcode == BNXT_ULP_FDB_OPC_PUSH_RID_REGFILE ||\n+\t\t     tbl->fdb_opcode == BNXT_ULP_FDB_OPC_PUSH_FID))\n+\t\t\tparms->rid = 0;\n+\n+\t\trc = ulp_mapper_gen_tbl_ref_cnt_process(parms, tbl,\n+\t\t\t\t\t\t\t&gen_tbl_ent);\n \t}\n+\n \treturn rc;\n }\n \n@@ -3041,6 +3183,8 @@ ulp_mapper_ctrl_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n \t\t\t    struct bnxt_ulp_mapper_tbl_info *tbl)\n {\n \tint32_t rc = 0;\n+\tuint64_t val64 = 0;\n+\tuint32_t rid;\n \n \t/* process the fdb opcode for alloc push */\n \tif (tbl->fdb_opcode == BNXT_ULP_FDB_OPC_ALLOC_RID_REGFILE) {\n@@ -3049,7 +3193,204 @@ ulp_mapper_ctrl_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n \t\t\tBNXT_TF_DBG(ERR, \"Failed to do fdb alloc\\n\");\n \t\t\treturn rc;\n \t\t}\n+\t} else if (tbl->fdb_opcode == BNXT_ULP_FDB_OPC_DELETE_RID_REGFILE) {\n+\t\trc = ulp_regfile_read(parms->regfile, tbl->fdb_operand, &val64);\n+\t\tif (!rc) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Failed to get RID from regfile\\n\");\n+\t\t\treturn rc;\n+\t\t}\n+\t\trid = (uint32_t)tfp_be_to_cpu_64(val64);\n+\t\trc = ulp_mapper_resources_free(parms->ulp_ctx,\n+\t\t\t\t\t       BNXT_ULP_FDB_TYPE_RID,\n+\t\t\t\t\t       rid);\n+\t}\n+\n+\treturn rc;\n+}\n+\n+static int32_t\n+ulp_mapper_vnic_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n+\t\t\t    struct bnxt_ulp_mapper_tbl_info *tbl)\n+{\n+\tstruct ulp_flow_db_res_params fid_parms;\n+\tuint16_t vnic_idx = 0, vnic_id = 0;\n+\tint32_t rc = 0;\n+\n+\tswitch (tbl->resource_sub_type) {\n+\tcase BNXT_ULP_RESOURCE_SUB_TYPE_VNIC_TABLE_RSS:\n+\t\tif (tbl->tbl_opcode != BNXT_ULP_VNIC_TBL_OPC_ALLOC_WR_REGFILE) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Invalid vnic table opcode\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\trc = bnxt_pmd_rss_action_create(parms, &vnic_idx, &vnic_id);\n+\t\tif (rc) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Failed create rss action\\n\");\n+\t\t\treturn rc;\n+\t\t}\n+\t\tbreak;\n+\tcase BNXT_ULP_RESOURCE_SUB_TYPE_VNIC_TABLE_QUEUE:\n+\t\tif (tbl->tbl_opcode != BNXT_ULP_VNIC_TBL_OPC_ALLOC_WR_REGFILE) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Invalid vnic table opcode\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\trc = bnxt_pmd_queue_action_create(parms, &vnic_idx, &vnic_id);\n+\t\tif (rc) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Failed create queue action\\n\");\n+\t\t\treturn rc;\n+\t\t}\n+\t\tbreak;\n+\tdefault:\n+\t\tBNXT_TF_DBG(ERR, \"Invalid vnic table sub type\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Link the created vnic to the flow in the flow db */\n+\tmemset(&fid_parms, 0, sizeof(fid_parms));\n+\tfid_parms.direction\t= tbl->direction;\n+\tfid_parms.resource_func\t= tbl->resource_func;\n+\tfid_parms.resource_type\t= tbl->resource_type;\n+\tfid_parms.resource_sub_type = tbl->resource_sub_type;\n+\tfid_parms.resource_hndl\t= vnic_idx;\n+\tfid_parms.critical_resource = tbl->critical_resource;\n+\trc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to link resource to flow rc = %d\\n\",\n+\t\t\t    rc);\n+\t\treturn rc;\n+\t}\n+\trc = ulp_regfile_write(parms->regfile, tbl->tbl_operand,\n+\t\t\t       (uint64_t)tfp_cpu_to_be_64(vnic_id));\n+\tif (rc)\n+\t\tBNXT_TF_DBG(ERR, \"Failed to write regfile[%d] rc=%d\\n\",\n+\t\t\t    tbl->tbl_operand, rc);\n+\n+\treturn rc;\n+}\n+\n+/* Free the vnic resource */\n+static int32_t\n+ulp_mapper_vnic_tbl_res_free(struct bnxt_ulp_context *ulp __rte_unused,\n+\t\t\t     struct tf *tfp,\n+\t\t\t     struct ulp_flow_db_res_params *res)\n+{\n+\tuint16_t vnic_idx = res->resource_hndl;\n+\n+\tif (res->resource_sub_type ==\n+\t    BNXT_ULP_RESOURCE_SUB_TYPE_VNIC_TABLE_QUEUE)\n+\t\treturn bnxt_pmd_queue_action_delete(tfp, vnic_idx);\n+\telse\n+\t\treturn bnxt_pmd_rss_action_delete(tfp, vnic_idx);\n+}\n+\n+static int32_t\n+ulp_mapper_global_res_free(struct bnxt_ulp_context *ulp __rte_unused,\n+\t\t\t   struct tf *tfp __rte_unused,\n+\t\t\t   struct ulp_flow_db_res_params *res)\n+{\n+\tuint16_t port_id = 0, dport = 0; /* Not needed for free */\n+\tint32_t rc = 0;\n+\tuint8_t ttype;\n+\tuint32_t handle = res->resource_hndl;\n+\n+\tswitch (res->resource_sub_type) {\n+\tcase BNXT_ULP_RESOURCE_SUB_TYPE_GLOBAL_REGISTER_CUST_VXLAN:\n+\t\tttype = BNXT_GLOBAL_REGISTER_TUNNEL_VXLAN;\n+\t\trc = bnxt_pmd_global_tunnel_set(port_id, ttype, dport,\n+\t\t\t\t\t\t&handle);\n+\t\tbreak;\n+\tdefault:\n+\t\trc = -EINVAL;\n+\t\tBNXT_TF_DBG(ERR, \"Invalid ulp global resource type %d\\n\",\n+\t\t\t    res->resource_sub_type);\n+\t\tbreak;\n+\t}\n+\n+\treturn rc;\n+}\n+\n+static int32_t\n+ulp_mapper_global_register_tbl_process(struct bnxt_ulp_mapper_parms *parms,\n+\t\t\t\t       struct bnxt_ulp_mapper_tbl_info *tbl)\n+{\n+\tstruct ulp_flow_db_res_params fid_parms\t= { 0 };\n+\tstruct ulp_blob\tdata;\n+\tuint16_t data_len = 0;\n+\tuint8_t *tmp_data;\n+\tuint16_t udp_port;\n+\tuint32_t handle;\n+\tint32_t rc = 0, write_reg = 0;\n+\tuint8_t ttype;\n+\n+\t/* Initialize the blob data */\n+\tif (!ulp_blob_init(&data, tbl->result_bit_size,\n+\t\t\t   BNXT_ULP_BYTE_ORDER_BE)) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed initial ulp_global table blob\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* read the arguments from the result table */\n+\trc = ulp_mapper_tbl_result_build(parms, tbl, &data,\n+\t\t\t\t\t \"ULP Global Result\");\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to build the result blob\\n\");\n+\t\treturn rc;\n+\t}\n+\n+\tswitch (tbl->tbl_opcode) {\n+\tcase BNXT_ULP_GLOBAL_REGISTER_TBL_OPC_WR_REGFILE:\n+\t\twrite_reg = 1;\n+\t\tbreak;\n+\tcase BNXT_ULP_GLOBAL_REGISTER_TBL_OPC_NOT_USED:\n+\t\tbreak;\n+\tdefault:\n+\t\tBNXT_TF_DBG(ERR, \"Invalid global table opcode %d\\n\",\n+\t\t\t    tbl->tbl_opcode);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tswitch (tbl->resource_sub_type) {\n+\tcase BNXT_ULP_RESOURCE_SUB_TYPE_GLOBAL_REGISTER_CUST_VXLAN:\n+\t\ttmp_data = ulp_blob_data_get(&data, &data_len);\n+\t\tudp_port = *((uint16_t *)tmp_data);\n+\t\tudp_port = tfp_be_to_cpu_16(udp_port);\n+\t\tttype = BNXT_GLOBAL_REGISTER_TUNNEL_VXLAN;\n+\n+\t\trc = bnxt_pmd_global_tunnel_set(parms->port_id, ttype,\n+\t\t\t\t\t\tudp_port, &handle);\n+\t\tif (rc) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Unable to set VXLAN UDP port\\n\");\n+\t\t\treturn rc;\n+\t\t}\n+\t\tbreak;\n+\tdefault:\n+\t\trc = -EINVAL;\n+\t\tBNXT_TF_DBG(ERR, \"Invalid ulp global resource type %d\\n\",\n+\t\t\t    tbl->resource_sub_type);\n+\t\treturn rc;\n \t}\n+\n+\t/* Set the common pieces of fid parms */\n+\tfid_parms.direction = tbl->direction;\n+\tfid_parms.resource_func\t= tbl->resource_func;\n+\tfid_parms.resource_sub_type = tbl->resource_sub_type;\n+\tfid_parms.critical_resource = tbl->critical_resource;\n+\tfid_parms.resource_hndl = handle;\n+\n+\trc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms);\n+\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* write to the regfile if opcode is set */\n+\tif (write_reg) {\n+\t\trc = ulp_regfile_write(parms->regfile,\n+\t\t\t\t       tbl->tbl_operand,\n+\t\t\t\t       (uint64_t)tfp_cpu_to_be_64(handle));\n+\t\tif (rc)\n+\t\t\tBNXT_TF_DBG(ERR, \"Regfile[%d] write failed.\\n\",\n+\t\t\t\t    tbl->tbl_operand);\n+\t}\n+\n \treturn rc;\n }\n \n@@ -3112,36 +3453,33 @@ ulp_mapper_glb_resource_info_init(struct bnxt_ulp_context *ulp_ctx,\n \treturn rc;\n }\n \n-/*\n- * Iterate over the shared resources assigned during tf_open_session and store\n- * them in the global regfile with the shared flag.\n- */\n static int32_t\n ulp_mapper_app_glb_resource_info_init(struct bnxt_ulp_context *ulp_ctx,\n-\t\t\t\t      struct bnxt_ulp_mapper_data *mapper_data)\n+\t\t\t\t  struct bnxt_ulp_mapper_data *mapper_data)\n {\n \tstruct bnxt_ulp_glb_resource_info *glb_res;\n \tuint32_t num_glb_res_ids, idx, dev_id;\n \tuint8_t app_id;\n-\tuint32_t rc = 0;\n+\tint32_t rc = 0;\n \n \tglb_res = bnxt_ulp_app_glb_resource_info_list_get(&num_glb_res_ids);\n \tif (!glb_res || !num_glb_res_ids) {\n \t\tBNXT_TF_DBG(ERR, \"Invalid Arguments\\n\");\n \t\treturn -EINVAL;\n \t}\n+\n \trc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id);\n \tif (rc) {\n-\t\tBNXT_TF_DBG(ERR, \"Failed to get device_id for glb init (%d)\\n\",\n+\t\tBNXT_TF_DBG(ERR, \"Failed to get device id for glb init (%d)\\n\",\n \t\t\t    rc);\n-\t\treturn -EINVAL;\n+\t\treturn rc;\n \t}\n \n \trc = bnxt_ulp_cntxt_app_id_get(ulp_ctx, &app_id);\n \tif (rc) {\n-\t\tBNXT_TF_DBG(ERR, \"Failed to get app_id for glb init (%d)\\n\",\n+\t\tBNXT_TF_DBG(ERR, \"Failed to get app id for glb init (%d)\\n\",\n \t\t\t    rc);\n-\t\treturn -EINVAL;\n+\t\treturn rc;\n \t}\n \n \t/* Iterate the global resources and process each one */\n@@ -3154,13 +3492,13 @@ ulp_mapper_app_glb_resource_info_init(struct bnxt_ulp_context *ulp_ctx,\n \t\t\trc = ulp_mapper_resource_ident_allocate(ulp_ctx,\n \t\t\t\t\t\t\t\tmapper_data,\n \t\t\t\t\t\t\t\t&glb_res[idx],\n-\t\t\t\t\t\t\t\tfalse);\n+\t\t\t\t\t\t\t\ttrue);\n \t\t\tbreak;\n \t\tcase BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:\n \t\t\trc = ulp_mapper_resource_index_tbl_alloc(ulp_ctx,\n \t\t\t\t\t\t\t\t mapper_data,\n \t\t\t\t\t\t\t\t &glb_res[idx],\n-\t\t\t\t\t\t\t\t false);\n+\t\t\t\t\t\t\t\t true);\n \t\t\tbreak;\n \t\tdefault:\n \t\t\tBNXT_TF_DBG(ERR, \"Global resource %x not supported\\n\",\n@@ -3726,6 +4064,12 @@ ulp_mapper_tbls_process(struct bnxt_ulp_mapper_parms *parms, uint32_t tid)\n \t\tcase BNXT_ULP_RESOURCE_FUNC_CTRL_TABLE:\n \t\t\trc = ulp_mapper_ctrl_tbl_process(parms, tbl);\n \t\t\tbreak;\n+\t\tcase BNXT_ULP_RESOURCE_FUNC_VNIC_TABLE:\n+\t\t\trc = ulp_mapper_vnic_tbl_process(parms, tbl);\n+\t\t\tbreak;\n+\t\tcase BNXT_ULP_RESOURCE_FUNC_GLOBAL_REGISTER_TABLE:\n+\t\t\trc = ulp_mapper_global_register_tbl_process(parms, tbl);\n+\t\t\tbreak;\n \t\tcase BNXT_ULP_RESOURCE_FUNC_INVALID:\n \t\t\trc = 0;\n \t\t\tbreak;\n@@ -3781,7 +4125,7 @@ ulp_mapper_tbls_process(struct bnxt_ulp_mapper_parms *parms, uint32_t tid)\n \n \treturn rc;\n error:\n-\tBNXT_TF_DBG(ERR, \"%s tables failed creation for %d:%d\\n\",\n+\tBNXT_TF_DBG(ERR, \"%s tables failed operation for %d:%d\\n\",\n \t\t    ulp_mapper_tmpl_name_str(parms->tmpl_type),\n \t\t    parms->dev_id, tid);\n \treturn rc;\n@@ -3828,7 +4172,13 @@ ulp_mapper_resource_free(struct bnxt_ulp_context *ulp,\n \t\trc = ulp_mapper_child_flow_free(ulp, fid, res);\n \t\tbreak;\n \tcase BNXT_ULP_RESOURCE_FUNC_GENERIC_TABLE:\n-\t\trc = ulp_mapper_gen_tbl_res_free(ulp, res);\n+\t\trc = ulp_mapper_gen_tbl_res_free(ulp, fid, res);\n+\t\tbreak;\n+\tcase BNXT_ULP_RESOURCE_FUNC_VNIC_TABLE:\n+\t\trc = ulp_mapper_vnic_tbl_res_free(ulp, tfp, res);\n+\t\tbreak;\n+\tcase BNXT_ULP_RESOURCE_FUNC_GLOBAL_REGISTER_TABLE:\n+\t\trc = ulp_mapper_global_res_free(ulp, tfp, res);\n \t\tbreak;\n \tdefault:\n \t\tbreak;\n@@ -4045,11 +4395,26 @@ ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx,\n \treturn rc;\n \n flow_error:\n+\tif (parms.rid) {\n+\t\t/* An RID was in-flight but not pushed, free the resources */\n+\t\ttrc = ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_RID,\n+\t\t\t\t\t      parms.rid);\n+\t\tif (trc)\n+\t\t\tBNXT_TF_DBG(ERR,\n+\t\t\t\t    \"Failed to free resources rid=0x%08x rc=%d\\n\",\n+\t\t\t\t    parms.rid, trc);\n+\t\tparms.rid = 0;\n+\t}\n+\n \t/* Free all resources that were allocated during flow creation */\n-\ttrc = ulp_mapper_flow_destroy(ulp_ctx, parms.flow_type,\n-\t\t\t\t      parms.fid);\n-\tif (trc)\n-\t\tBNXT_TF_DBG(ERR, \"Failed to free all resources rc=%d\\n\", trc);\n+\tif (parms.fid) {\n+\t\ttrc = ulp_mapper_flow_destroy(ulp_ctx, parms.flow_type,\n+\t\t\t\t\t      parms.fid);\n+\t\tif (trc)\n+\t\t\tBNXT_TF_DBG(ERR,\n+\t\t\t\t    \"Failed to free resources fid=0x%08x rc=%d\\n\",\n+\t\t\t\t    parms.fid, trc);\n+\t}\n \n \treturn rc;\n }\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.h b/drivers/net/bnxt/tf_ulp/ulp_mapper.h\nindex b7e6f3ada2..225a14ccfa 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_mapper.h\n+++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.h\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -52,6 +52,7 @@ struct bnxt_ulp_mapper_parms {\n \tstruct ulp_regfile\t\t\t*regfile;\n \tstruct bnxt_ulp_context\t\t\t*ulp_ctx;\n \tuint32_t\t\t\t\tfid;\n+\tuint32_t\t\t\t\trid;\n \tenum bnxt_ulp_fdb_type\t\t\tflow_type;\n \tstruct bnxt_ulp_mapper_data\t\t*mapper_data;\n \tstruct bnxt_ulp_device_params\t\t*device_params;\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_matcher.c b/drivers/net/bnxt/tf_ulp/ulp_matcher.c\nindex 67fa61fc7c..8c90998a7d 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_matcher.c\n+++ b/drivers/net/bnxt/tf_ulp/ulp_matcher.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -29,8 +29,8 @@ ulp_matcher_action_hash_calculate(uint64_t hi_sig, uint64_t app_id)\n \n \thi_sig |= ((hi_sig % BNXT_ULP_ACT_HID_HIGH_PRIME) <<\n \t\t   BNXT_ULP_ACT_HID_SHFTL);\n-\tapp_id |= ((app_id % BNXT_ULP_CLASS_HID_LOW_PRIME) <<\n-\t\t   (BNXT_ULP_CLASS_HID_SHFTL + 2));\n+\tapp_id |= ((app_id % BNXT_ULP_ACT_HID_LOW_PRIME) <<\n+\t\t   (BNXT_ULP_ACT_HID_SHFTL + 2));\n \thash = hi_sig ^ app_id;\n \thash = (hash >> BNXT_ULP_ACT_HID_SHFTR) & BNXT_ULP_ACT_HID_MASK;\n \treturn (uint32_t)hash;\n@@ -46,12 +46,8 @@ ulp_matcher_pattern_match(struct ulp_rte_parser_params *params,\n {\n \tstruct bnxt_ulp_class_match_info *class_match;\n \tuint32_t class_hid;\n-\tuint8_t vf_to_vf;\n \tuint16_t tmpl_id;\n \n-\t/* Get vf to vf flow */\n-\tvf_to_vf = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_VF_TO_VF);\n-\n \t/* calculate the hash of the given flow */\n \tclass_hid = ulp_matcher_class_hash_calculate((params->hdr_bitmap.bits ^\n \t\t\t\t\t\t     params->app_id),\n@@ -81,10 +77,6 @@ ulp_matcher_pattern_match(struct ulp_rte_parser_params *params,\n \t\tgoto error;\n \t}\n \n-\tif (vf_to_vf != class_match->act_vnic) {\n-\t\tBNXT_TF_DBG(DEBUG, \"Vnic Match failed\\n\");\n-\t\tgoto error;\n-\t}\n \tBNXT_TF_DBG(DEBUG, \"Found matching pattern template %d\\n\",\n \t\t    class_match->class_tid);\n \t*class_id = class_match->class_tid;\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_port_db.c b/drivers/net/bnxt/tf_ulp/ulp_port_db.c\nindex 57c9e7d175..ba1f966ec3 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_port_db.c\n+++ b/drivers/net/bnxt/tf_ulp/ulp_port_db.c\n@@ -150,6 +150,11 @@ int32_t\tulp_port_db_port_update(struct bnxt_ulp_context *ulp_ctxt,\n \tintf = &port_db->ulp_intf_list[ifindex];\n \n \tintf->type = bnxt_pmd_get_interface_type(port_id);\n+\tif (intf->type == BNXT_ULP_INTF_TYPE_PF)\n+\t\tintf->type_is_pf = 1;\n+\telse\n+\t\tintf->type_is_pf = 0;\n+\n \tintf->drv_func_id = bnxt_pmd_get_fw_func_id(port_id,\n \t\t\t\t\t\tBNXT_ULP_INTF_TYPE_INVALID);\n \n@@ -182,6 +187,9 @@ int32_t\tulp_port_db_port_update(struct bnxt_ulp_context *ulp_ctxt,\n \t\t\tbnxt_pmd_get_vnic_id(port_id, BNXT_ULP_INTF_TYPE_VF_REP);\n \t\tfunc->phy_port_id = bnxt_pmd_get_phy_port_id(port_id);\n \t\tfunc->ifindex = ifindex;\n+\t\tfunc->func_valid = true;\n+\t\tfunc->vf_meta_data = tfp_cpu_to_be_16(BNXT_ULP_META_VF_FLAG |\n+\t\t\t\t\t\t      intf->vf_func_id);\n \t}\n \n \t/* When there is no match, the default action is to send the packet to\n@@ -702,3 +710,53 @@ ulp_port_db_phy_port_get(struct bnxt_ulp_context *ulp_ctxt,\n \t}\n \treturn -EINVAL;\n }\n+\n+/*\n+ * Api to get the port type for a given port id.\n+ *\n+ * ulp_ctxt [in] Ptr to ulp context\n+ * port_id [in] device port id\n+ * type [out] type if pf or not\n+ *\n+ * Returns 0 on success or negative number on failure.\n+ */\n+int32_t\n+ulp_port_db_port_is_pf_get(struct bnxt_ulp_context *ulp_ctxt,\n+\t\t\t   uint32_t port_id, uint8_t **type)\n+{\n+\tstruct ulp_func_if_info *info;\n+\tstruct bnxt_ulp_port_db *port_db;\n+\tuint16_t pid;\n+\n+\tport_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);\n+\tinfo = ulp_port_db_func_if_info_get(ulp_ctxt, port_id);\n+\tif (info) {\n+\t\tpid = info->ifindex;\n+\t\t*type = &port_db->ulp_intf_list[pid].type_is_pf;\n+\t\treturn 0;\n+\t}\n+\treturn -EINVAL;\n+}\n+\n+/*\n+ * Api to get the meta data for a given port id.\n+ *\n+ * ulp_ctxt [in] Ptr to ulp context\n+ * port_id [in] dpdk port id\n+ * meta data [out] the meta data of the given port\n+ *\n+ * Returns 0 on success or negative number on failure.\n+ */\n+int32_t\n+ulp_port_db_port_meta_data_get(struct bnxt_ulp_context *ulp_ctxt,\n+\t\t\t       uint16_t port_id, uint8_t **meta_data)\n+{\n+\tstruct ulp_func_if_info *info;\n+\n+\tinfo = ulp_port_db_func_if_info_get(ulp_ctxt, port_id);\n+\tif (info) {\n+\t\t*meta_data = (uint8_t *)&info->vf_meta_data;\n+\t\treturn 0;\n+\t}\n+\treturn -EINVAL;\n+}\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_port_db.h b/drivers/net/bnxt/tf_ulp/ulp_port_db.h\nindex 784b93f8b3..d4efe0a3d5 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_port_db.h\n+++ b/drivers/net/bnxt/tf_ulp/ulp_port_db.h\n@@ -328,4 +328,30 @@ ulp_port_db_parent_vnic_get(struct bnxt_ulp_context *ulp_ctxt,\n int32_t\n ulp_port_db_phy_port_get(struct bnxt_ulp_context *ulp_ctxt,\n \t\t\t uint32_t port_id, uint16_t *phy_port);\n+\n+/*\n+ * Api to get the port type for a given port id.\n+ *\n+ * ulp_ctxt [in] Ptr to ulp context\n+ * port_id [in] device port id\n+ * type [out] type if pf or not\n+ *\n+ * Returns 0 on success or negative number on failure.\n+ */\n+int32_t\n+ulp_port_db_port_is_pf_get(struct bnxt_ulp_context *ulp_ctxt,\n+\t\t\t   uint32_t port_id, uint8_t **type);\n+\n+/*\n+ * Api to get the meta data for a given port id.\n+ *\n+ * ulp_ctxt [in] Ptr to ulp context\n+ * port_id [in] dpdk port id\n+ * meta data [out] the meta data of the given port\n+ *\n+ * Returns 0 on success or negative number on failure.\n+ */\n+int32_t\n+ulp_port_db_port_meta_data_get(struct bnxt_ulp_context *ulp_ctxt,\n+\t\t\t       uint16_t port_id, uint8_t **meta_data);\n #endif /* _ULP_PORT_DB_H_ */\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c\nindex 9cf1ebfe1d..1fbfe18db3 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c\n+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -38,8 +38,8 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {\n \t.proto_act_func          = NULL\n \t},\n \t[RTE_FLOW_ACTION_TYPE_QUEUE] = {\n-\t.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,\n-\t.proto_act_func          = NULL\n+\t.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,\n+\t.proto_act_func          = ulp_rte_queue_act_handler\n \t},\n \t[RTE_FLOW_ACTION_TYPE_DROP] = {\n \t.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,\n@@ -162,12 +162,12 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {\n \t.proto_act_func          = NULL\n \t},\n \t[RTE_FLOW_ACTION_TYPE_SET_MAC_SRC] = {\n-\t.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,\n-\t.proto_act_func          = NULL\n+\t.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,\n+\t.proto_act_func          = ulp_rte_set_mac_src_act_handler\n \t},\n \t[RTE_FLOW_ACTION_TYPE_SET_MAC_DST] = {\n-\t.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,\n-\t.proto_act_func          = NULL\n+\t.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,\n+\t.proto_act_func          = ulp_rte_set_mac_dst_act_handler\n \t},\n \t[RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ] = {\n \t.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,\n@@ -197,6 +197,14 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {\n \t.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,\n \t.proto_act_func          = ulp_rte_port_act_handler\n \t},\n+\t[RTE_FLOW_ACTION_TYPE_INDIRECT] = {\n+\t.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,\n+\t.proto_act_func          = ulp_rte_action_hdlr_handler\n+\t},\n+\t[RTE_FLOW_ACTION_TYPE_INDIRECT + 1] = {\n+\t.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,\n+\t.proto_act_func          = NULL\n+\t}\n };\n \n struct bnxt_ulp_rte_act_info ulp_vendor_act_info[] = {\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c\nindex 3566f3000b..d7450b92ff 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c\n+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c\n@@ -24,6 +24,7 @@\n #define ULP_VLAN_PRIORITY_MASK\t\t0x700\n #define ULP_VLAN_TAG_MASK\t\t0xFFF /* Last 12 bits*/\n #define ULP_UDP_PORT_VXLAN\t\t4789\n+#define ULP_UDP_PORT_VXLAN_MASK\t 0XFFFF\n \n /* Utility function to skip the void items. */\n static inline int32_t\n@@ -190,7 +191,7 @@ bnxt_ulp_rte_parser_act_parse(const struct rte_flow_action actions[],\n \t\t\thdr_info = &ulp_vendor_act_info[action_item->type -\n \t\t\t\tBNXT_RTE_FLOW_ACTION_TYPE_END];\n \t\t} else {\n-\t\t\tif (action_item->type > RTE_FLOW_ACTION_TYPE_SHARED)\n+\t\t\tif (action_item->type > RTE_FLOW_ACTION_TYPE_INDIRECT)\n \t\t\t\tgoto act_parser_error;\n \t\t\t/* get the header information from the act info table */\n \t\t\thdr_info = &ulp_act_info[action_item->type];\n@@ -227,7 +228,7 @@ static void\n bnxt_ulp_comp_fld_intf_update(struct ulp_rte_parser_params *params)\n {\n \tuint32_t ifindex;\n-\tuint16_t port_id, parif;\n+\tuint16_t port_id, parif, svif;\n \tuint32_t mtype;\n \tenum bnxt_ulp_direction_type dir;\n \n@@ -252,6 +253,14 @@ bnxt_ulp_comp_fld_intf_update(struct ulp_rte_parser_params *params)\n \t\t}\n \t\tULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_PHY_PORT_PARIF,\n \t\t\t\t    parif);\n+\t\t/* Set port SVIF */\n+\t\tif (ulp_port_db_svif_get(params->ulp_ctx, ifindex,\n+\t\t\t\t\t  BNXT_ULP_PHY_PORT_SVIF, &svif)) {\n+\t\t\tBNXT_TF_DBG(ERR, \"ParseErr:ifindex is not valid\\n\");\n+\t\t\treturn;\n+\t\t}\n+\t\tULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_PHY_PORT_SVIF,\n+\t\t\t\t    svif);\n \t} else {\n \t\t/* Get the match port type */\n \t\tmtype = ULP_COMP_FLD_IDX_RD(params,\n@@ -317,10 +326,11 @@ ulp_post_process_normal_flow(struct ulp_rte_parser_params *params)\n \t\t\t       BNXT_ULP_FLOW_DIR_BITMASK_EGR);\n \t}\n \n-\t/* calculate the VF to VF flag */\n+\t/* Evaluate the VF to VF flag */\n \tif (act_port_set && act_port_type == BNXT_ULP_INTF_TYPE_VF_REP &&\n \t    match_port_type == BNXT_ULP_INTF_TYPE_VF_REP)\n-\t\tULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_VF_TO_VF, 1);\n+\t\tULP_BITMAP_SET(params->act_bitmap.bits,\n+\t\t\t       BNXT_ULP_ACT_BIT_VF_TO_VF);\n \n \t/* Update the decrement ttl computational fields */\n \tif (ULP_BITMAP_ISSET(params->act_bitmap.bits,\n@@ -438,8 +448,7 @@ ulp_rte_parser_svif_set(struct ulp_rte_parser_params *params,\n \t\telse\n \t\t\tsvif_type = BNXT_ULP_DRV_FUNC_SVIF;\n \t}\n-\tulp_port_db_svif_get(params->ulp_ctx, ifindex, svif_type,\n-\t\t\t     &svif);\n+\tulp_port_db_svif_get(params->ulp_ctx, ifindex, svif_type, &svif);\n \tsvif = rte_cpu_to_be_16(svif);\n \thdr_field = &params->hdr_field[BNXT_ULP_PROTO_HDR_FIELD_SVIF_IDX];\n \tmemcpy(hdr_field->spec, &svif, sizeof(svif));\n@@ -575,8 +584,11 @@ ulp_rte_port_hdr_handler(const struct rte_flow_item *item,\n /* Function to handle the update of proto header based on field values */\n static void\n ulp_rte_l2_proto_type_update(struct ulp_rte_parser_params *param,\n-\t\t\t     uint16_t type, uint32_t in_flag)\n+\t\t\t     uint16_t type, uint32_t in_flag,\n+\t\t\t     uint32_t has_vlan, uint32_t has_vlan_mask)\n {\n+#define ULP_RTE_ETHER_TYPE_ROE\t0xfc3d\n+\n \tif (type == tfp_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) {\n \t\tif (in_flag) {\n \t\t\tULP_BITMAP_SET(param->hdr_fp_bit.bits,\n@@ -587,7 +599,7 @@ ulp_rte_l2_proto_type_update(struct ulp_rte_parser_params *param,\n \t\t\t\t       BNXT_ULP_HDR_BIT_O_IPV4);\n \t\t\tULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_O_L3, 1);\n \t\t}\n-\t} else if (type == tfp_cpu_to_be_16(RTE_ETHER_TYPE_IPV6))  {\n+\t} else if (type == tfp_cpu_to_be_16(RTE_ETHER_TYPE_IPV6)) {\n \t\tif (in_flag) {\n \t\t\tULP_BITMAP_SET(param->hdr_fp_bit.bits,\n \t\t\t\t       BNXT_ULP_HDR_BIT_I_IPV6);\n@@ -597,6 +609,29 @@ ulp_rte_l2_proto_type_update(struct ulp_rte_parser_params *param,\n \t\t\t\t       BNXT_ULP_HDR_BIT_O_IPV6);\n \t\t\tULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_O_L3, 1);\n \t\t}\n+\t} else if (type == tfp_cpu_to_be_16(RTE_ETHER_TYPE_VLAN)) {\n+\t\thas_vlan_mask = 1;\n+\t\thas_vlan = 1;\n+\t} else if (type == tfp_cpu_to_be_16(ULP_RTE_ETHER_TYPE_ROE)) {\n+\t\t/* Update the hdr_bitmap with RoE */\n+\t\tULP_BITMAP_SET(param->hdr_fp_bit.bits,\n+\t\t\t\tBNXT_ULP_HDR_BIT_O_ROE);\n+\t}\n+\n+\tif (has_vlan_mask) {\n+\t\tif (in_flag) {\n+\t\t\tULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_I_HAS_VTAG,\n+\t\t\t\t\t    has_vlan);\n+\t\t\tULP_COMP_FLD_IDX_WR(param,\n+\t\t\t\t\t    BNXT_ULP_CF_IDX_I_VLAN_NO_IGNORE,\n+\t\t\t\t\t    1);\n+\t\t} else {\n+\t\t\tULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_O_HAS_VTAG,\n+\t\t\t\t\t    has_vlan);\n+\t\t\tULP_COMP_FLD_IDX_WR(param,\n+\t\t\t\t\t    BNXT_ULP_CF_IDX_O_VLAN_NO_IGNORE,\n+\t\t\t\t\t    1);\n+\t\t}\n \t}\n }\n \n@@ -624,17 +659,25 @@ ulp_rte_eth_hdr_handler(const struct rte_flow_item *item,\n \tuint32_t size;\n \tuint16_t eth_type = 0;\n \tuint32_t inner_flag = 0;\n+\tuint32_t has_vlan = 0, has_vlan_mask = 0;\n \n \t/* Perform validations */\n \tif (eth_spec) {\n-\t\t/* Todo: work around to avoid multicast and broadcast addr */\n-\t\tif (ulp_rte_parser_is_bcmc_addr(&eth_spec->hdr.dst_addr))\n+\t\t/* Avoid multicast and broadcast addr */\n+\t\tif (!ULP_APP_BC_MC_SUPPORT(params->ulp_ctx) &&\n+\t\t    ulp_rte_parser_is_bcmc_addr(&eth_spec->hdr.dst_addr))\n \t\t\treturn BNXT_TF_RC_PARSE_ERR;\n \n-\t\tif (ulp_rte_parser_is_bcmc_addr(&eth_spec->hdr.src_addr))\n+\t\tif (!ULP_APP_BC_MC_SUPPORT(params->ulp_ctx) &&\n+\t\t    ulp_rte_parser_is_bcmc_addr(&eth_spec->hdr.src_addr))\n \t\t\treturn BNXT_TF_RC_PARSE_ERR;\n \n \t\teth_type = eth_spec->hdr.ether_type;\n+\t\thas_vlan = eth_spec->has_vlan;\n+\t}\n+\tif (eth_mask) {\n+\t\teth_type &= eth_mask->hdr.ether_type;\n+\t\thas_vlan_mask = eth_mask->has_vlan;\n \t}\n \n \tif (ulp_rte_prsr_fld_size_validate(params, &idx,\n@@ -663,7 +706,8 @@ ulp_rte_eth_hdr_handler(const struct rte_flow_item *item,\n \tulp_rte_prsr_fld_mask(params, &idx, size,\n \t\t\t      ulp_deference_struct(eth_spec, hdr.ether_type),\n \t\t\t      ulp_deference_struct(eth_mask, hdr.ether_type),\n-\t\t\t      ULP_PRSR_ACT_MATCH_IGNORE);\n+\t\t\t      (ULP_APP_TOS_PROTO_SUPPORT(params->ulp_ctx)) ?\n+\t\t\t      ULP_PRSR_ACT_DEFAULT : ULP_PRSR_ACT_MATCH_IGNORE);\n \n \t/* Update the protocol hdr bitmap */\n \tif (ULP_BITMAP_ISSET(params->hdr_bitmap.bits,\n@@ -684,7 +728,8 @@ ulp_rte_eth_hdr_handler(const struct rte_flow_item *item,\n \t\t\t\t    dmac_idx);\n \t}\n \t/* Update the field protocol hdr bitmap */\n-\tulp_rte_l2_proto_type_update(params, eth_type, inner_flag);\n+\tulp_rte_l2_proto_type_update(params, eth_type, inner_flag,\n+\t\t\t\t     has_vlan, has_vlan_mask);\n \n \treturn BNXT_TF_RC_SUCCESS;\n }\n@@ -837,7 +882,7 @@ ulp_rte_vlan_hdr_handler(const struct rte_flow_item *item,\n \t\treturn BNXT_TF_RC_ERROR;\n \t}\n \t/* Update the field protocol hdr bitmap */\n-\tulp_rte_l2_proto_type_update(params, eth_type, inner_flag);\n+\tulp_rte_l2_proto_type_update(params, eth_type, inner_flag, 1, 1);\n \treturn BNXT_TF_RC_SUCCESS;\n }\n \n@@ -876,22 +921,21 @@ ulp_rte_l3_proto_type_update(struct ulp_rte_parser_params *param,\n \t\t\tULP_BITMAP_SET(param->hdr_bitmap.bits,\n \t\t\t\t       BNXT_ULP_HDR_BIT_O_ICMP);\n \t}\n-\tif (proto) {\n-\t\tif (in_flag) {\n-\t\t\tULP_COMP_FLD_IDX_WR(param,\n-\t\t\t\t\t    BNXT_ULP_CF_IDX_I_L3_FB_PROTO_ID,\n-\t\t\t\t\t    1);\n-\t\t\tULP_COMP_FLD_IDX_WR(param,\n-\t\t\t\t\t    BNXT_ULP_CF_IDX_I_L3_PROTO_ID,\n-\t\t\t\t\t    proto);\n-\t\t} else {\n-\t\t\tULP_COMP_FLD_IDX_WR(param,\n-\t\t\t\t\t    BNXT_ULP_CF_IDX_O_L3_FB_PROTO_ID,\n-\t\t\t\t\t    1);\n-\t\t\tULP_COMP_FLD_IDX_WR(param,\n-\t\t\t\t\t    BNXT_ULP_CF_IDX_O_L3_PROTO_ID,\n-\t\t\t\t\t    proto);\n-\t\t}\n+\n+\tif (in_flag) {\n+\t\tULP_COMP_FLD_IDX_WR(param,\n+\t\t\t\t    BNXT_ULP_CF_IDX_I_L3_FB_PROTO_ID,\n+\t\t\t\t    1);\n+\t\tULP_COMP_FLD_IDX_WR(param,\n+\t\t\t\t    BNXT_ULP_CF_IDX_I_L3_PROTO_ID,\n+\t\t\t\t    proto);\n+\t} else {\n+\t\tULP_COMP_FLD_IDX_WR(param,\n+\t\t\t\t    BNXT_ULP_CF_IDX_O_L3_FB_PROTO_ID,\n+\t\t\t\t    1);\n+\t\tULP_COMP_FLD_IDX_WR(param,\n+\t\t\t\t    BNXT_ULP_CF_IDX_O_L3_PROTO_ID,\n+\t\t\t\t    proto);\n \t}\n }\n \n@@ -906,6 +950,7 @@ ulp_rte_ipv4_hdr_handler(const struct rte_flow_item *item,\n \tuint32_t idx = 0, dip_idx = 0;\n \tuint32_t size;\n \tuint8_t proto = 0;\n+\tuint8_t proto_mask = 0;\n \tuint32_t inner_flag = 0;\n \tuint32_t cnt;\n \n@@ -934,8 +979,7 @@ ulp_rte_ipv4_hdr_handler(const struct rte_flow_item *item,\n \n \t/*\n \t * The tos field is ignored since OVS is setting it as wild card\n-\t * match and it is not supported. This is a work around and\n-\t * shall be addressed in the future.\n+\t * match and it is not supported. An application can enable tos support.\n \t */\n \tsize = sizeof(((struct rte_flow_item_ipv4 *)NULL)->hdr.type_of_service);\n \tulp_rte_prsr_fld_mask(params, &idx, size,\n@@ -943,7 +987,8 @@ ulp_rte_ipv4_hdr_handler(const struct rte_flow_item *item,\n \t\t\t\t\t\t   hdr.type_of_service),\n \t\t\t      ulp_deference_struct(ipv4_mask,\n \t\t\t\t\t\t   hdr.type_of_service),\n-\t\t\t      ULP_PRSR_ACT_MASK_IGNORE);\n+\t\t\t      (ULP_APP_TOS_PROTO_SUPPORT(params->ulp_ctx)) ?\n+\t\t\t      ULP_PRSR_ACT_DEFAULT : ULP_PRSR_ACT_MASK_IGNORE);\n \n \tsize = sizeof(((struct rte_flow_item_ipv4 *)NULL)->hdr.total_length);\n \tulp_rte_prsr_fld_mask(params, &idx, size,\n@@ -978,7 +1023,9 @@ ulp_rte_ipv4_hdr_handler(const struct rte_flow_item *item,\n \t\t\t\t\t\t   hdr.next_proto_id),\n \t\t\t      ulp_deference_struct(ipv4_mask,\n \t\t\t\t\t\t   hdr.next_proto_id),\n-\t\t\t      ULP_PRSR_ACT_MATCH_IGNORE);\n+\t\t\t      (ULP_APP_TOS_PROTO_SUPPORT(params->ulp_ctx)) ?\n+\t\t\t      ULP_PRSR_ACT_DEFAULT : ULP_PRSR_ACT_MATCH_IGNORE);\n+\n \tif (ipv4_spec)\n \t\tproto = ipv4_spec->hdr.next_proto_id;\n \n@@ -1020,11 +1067,14 @@ ulp_rte_ipv4_hdr_handler(const struct rte_flow_item *item,\n \t * in the IPv4 spec but don't set the mask. So, consider\n \t * the mask in the proto value calculation.\n \t */\n-\tif (ipv4_mask)\n+\tif (ipv4_mask) {\n \t\tproto &= ipv4_mask->hdr.next_proto_id;\n+\t\tproto_mask = ipv4_mask->hdr.next_proto_id;\n+\t}\n \n \t/* Update the field protocol hdr bitmap */\n-\tulp_rte_l3_proto_type_update(params, proto, inner_flag);\n+\tif (proto_mask)\n+\t\tulp_rte_l3_proto_type_update(params, proto, inner_flag);\n \tULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L3_HDR_CNT, ++cnt);\n \treturn BNXT_TF_RC_SUCCESS;\n }\n@@ -1038,11 +1088,12 @@ ulp_rte_ipv6_hdr_handler(const struct rte_flow_item *item,\n \tconst struct rte_flow_item_ipv6\t*ipv6_mask = item->mask;\n \tstruct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;\n \tuint32_t idx = 0, dip_idx = 0;\n-\tuint32_t size;\n+\tuint32_t size, vtc_flow;\n \tuint32_t ver_spec = 0, ver_mask = 0;\n \tuint32_t tc_spec = 0, tc_mask = 0;\n \tuint32_t lab_spec = 0, lab_mask = 0;\n \tuint8_t proto = 0;\n+\tuint8_t proto_mask = 0;\n \tuint32_t inner_flag = 0;\n \tuint32_t cnt;\n \n@@ -1064,22 +1115,25 @@ ulp_rte_ipv6_hdr_handler(const struct rte_flow_item *item,\n \t * header fields\n \t */\n \tif (ipv6_spec) {\n-\t\tver_spec = BNXT_ULP_GET_IPV6_VER(ipv6_spec->hdr.vtc_flow);\n-\t\ttc_spec = BNXT_ULP_GET_IPV6_TC(ipv6_spec->hdr.vtc_flow);\n-\t\tlab_spec = BNXT_ULP_GET_IPV6_FLOWLABEL(ipv6_spec->hdr.vtc_flow);\n+\t\tvtc_flow = ntohl(ipv6_spec->hdr.vtc_flow);\n+\t\tver_spec = htonl(BNXT_ULP_GET_IPV6_VER(vtc_flow));\n+\t\ttc_spec = htonl(BNXT_ULP_GET_IPV6_TC(vtc_flow));\n+\t\tlab_spec = htonl(BNXT_ULP_GET_IPV6_FLOWLABEL(vtc_flow));\n \t\tproto = ipv6_spec->hdr.proto;\n \t}\n \n \tif (ipv6_mask) {\n-\t\tver_mask = BNXT_ULP_GET_IPV6_VER(ipv6_mask->hdr.vtc_flow);\n-\t\ttc_mask = BNXT_ULP_GET_IPV6_TC(ipv6_mask->hdr.vtc_flow);\n-\t\tlab_mask = BNXT_ULP_GET_IPV6_FLOWLABEL(ipv6_mask->hdr.vtc_flow);\n+\t\tvtc_flow = ntohl(ipv6_mask->hdr.vtc_flow);\n+\t\tver_mask = htonl(BNXT_ULP_GET_IPV6_VER(vtc_flow));\n+\t\ttc_mask = htonl(BNXT_ULP_GET_IPV6_TC(vtc_flow));\n+\t\tlab_mask = htonl(BNXT_ULP_GET_IPV6_FLOWLABEL(vtc_flow));\n \n \t\t/* Some of the PMD applications may set the protocol field\n \t\t * in the IPv6 spec but don't set the mask. So, consider\n \t\t * the mask in proto value calculation.\n \t\t */\n \t\tproto &= ipv6_mask->hdr.proto;\n+\t\tproto_mask = ipv6_mask->hdr.proto;\n \t}\n \n \tsize = sizeof(((struct rte_flow_item_ipv6 *)NULL)->hdr.vtc_flow);\n@@ -1092,7 +1146,8 @@ ulp_rte_ipv6_hdr_handler(const struct rte_flow_item *item,\n \t * shall be addressed in the future.\n \t */\n \tulp_rte_prsr_fld_mask(params, &idx, size, &tc_spec, &tc_mask,\n-\t\t\t      ULP_PRSR_ACT_MASK_IGNORE);\n+\t\t\t      (ULP_APP_TOS_PROTO_SUPPORT(params->ulp_ctx)) ?\n+\t\t\t      ULP_PRSR_ACT_DEFAULT : ULP_PRSR_ACT_MASK_IGNORE);\n \tulp_rte_prsr_fld_mask(params, &idx, size, &lab_spec, &lab_mask,\n \t\t\t      ULP_PRSR_ACT_MASK_IGNORE);\n \n@@ -1107,7 +1162,8 @@ ulp_rte_ipv6_hdr_handler(const struct rte_flow_item *item,\n \tulp_rte_prsr_fld_mask(params, &idx, size,\n \t\t\t      ulp_deference_struct(ipv6_spec, hdr.proto),\n \t\t\t      ulp_deference_struct(ipv6_mask, hdr.proto),\n-\t\t\t      ULP_PRSR_ACT_MATCH_IGNORE);\n+\t\t\t      (ULP_APP_TOS_PROTO_SUPPORT(params->ulp_ctx)) ?\n+\t\t\t      ULP_PRSR_ACT_DEFAULT : ULP_PRSR_ACT_MATCH_IGNORE);\n \n \tsize = sizeof(((struct rte_flow_item_ipv6 *)NULL)->hdr.hop_limits);\n \tulp_rte_prsr_fld_mask(params, &idx, size,\n@@ -1144,7 +1200,8 @@ ulp_rte_ipv6_hdr_handler(const struct rte_flow_item *item,\n \t}\n \n \t/* Update the field protocol hdr bitmap */\n-\tulp_rte_l3_proto_type_update(params, proto, inner_flag);\n+\tif (proto_mask)\n+\t\tulp_rte_l3_proto_type_update(params, proto, inner_flag);\n \tULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L3_HDR_CNT, ++cnt);\n \n \treturn BNXT_TF_RC_SUCCESS;\n@@ -1280,7 +1337,8 @@ ulp_rte_udp_hdr_handler(const struct rte_flow_item *item,\n \n \t/* Set the udp header bitmap and computed l4 header bitmaps */\n \tif (ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_UDP) ||\n-\t    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_TCP))\n+\t    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_TCP) ||\n+\t    ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_L3_TUN))\n \t\tout_l4 = BNXT_ULP_HDR_BIT_I_UDP;\n \n \tulp_rte_l4_proto_type_update(params, sport, sport_mask, dport,\n@@ -1385,7 +1443,8 @@ ulp_rte_tcp_hdr_handler(const struct rte_flow_item *item,\n \n \t/* Set the udp header bitmap and computed l4 header bitmaps */\n \tif (ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_UDP) ||\n-\t    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_TCP))\n+\t    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_TCP) ||\n+\t    ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_L3_TUN))\n \t\tout_l4 = BNXT_ULP_HDR_BIT_I_TCP;\n \n \tulp_rte_l4_proto_type_update(params, sport, sport_mask, dport,\n@@ -1403,6 +1462,7 @@ ulp_rte_vxlan_hdr_handler(const struct rte_flow_item *item,\n \tconst struct rte_flow_item_vxlan *vxlan_mask = item->mask;\n \tstruct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;\n \tuint32_t idx = 0;\n+\tuint16_t dport;\n \tuint32_t size;\n \n \tif (ulp_rte_prsr_fld_size_validate(params, &idx,\n@@ -1442,6 +1502,15 @@ ulp_rte_vxlan_hdr_handler(const struct rte_flow_item *item,\n \t/* Update the hdr_bitmap with vxlan */\n \tULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_T_VXLAN);\n \tULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L3_TUN, 1);\n+\n+\tdport = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_O_L4_DST_PORT);\n+\tif (!dport) {\n+\t\tULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L4_DST_PORT,\n+\t\t\t\t    ULP_UDP_PORT_VXLAN);\n+\t\tULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L4_DST_PORT_MASK,\n+\t\t\t\t    ULP_UDP_PORT_VXLAN_MASK);\n+\t}\n+\n \treturn BNXT_TF_RC_SUCCESS;\n }\n \n@@ -1637,6 +1706,8 @@ ulp_rte_rss_act_handler(const struct rte_flow_action *action_item,\n {\n \tconst struct rte_flow_action_rss *rss;\n \tstruct ulp_rte_act_prop *ap = &param->act_prop;\n+\tuint64_t queue_list[BNXT_ULP_ACT_PROP_SZ_RSS_QUEUE / sizeof(uint64_t)];\n+\tuint32_t idx = 0, id;\n \n \tif (action_item == NULL || action_item->conf == NULL) {\n \t\tBNXT_TF_DBG(ERR, \"Parse Err: invalid rss configuration\\n\");\n@@ -1652,12 +1723,50 @@ ulp_rte_rss_act_handler(const struct rte_flow_action *action_item,\n \tmemcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY_LEN],\n \t       &rss->key_len, BNXT_ULP_ACT_PROP_SZ_RSS_KEY_LEN);\n \n-\tif (rss->key_len > BNXT_ULP_ACT_PROP_SZ_RSS_KEY) {\n-\t\tBNXT_TF_DBG(ERR, \"Parse Err: RSS key too big\\n\");\n+\tif (rss->key_len != 0 && rss->key_len != BNXT_ULP_ACT_PROP_SZ_RSS_KEY) {\n+\t\tBNXT_TF_DBG(ERR, \"Parse Err: RSS key length must be 40 bytes\\n\");\n+\t\treturn BNXT_TF_RC_ERROR;\n+\t}\n+\n+\t/* User may specify only key length. In that case, rss->key will be NULL.\n+\t * So, reject the flow if key_length is valid but rss->key is NULL.\n+\t * Also, copy the RSS hash key only when rss->key is valid.\n+\t */\n+\tif (rss->key_len != 0 && rss->key == NULL) {\n+\t\tBNXT_TF_DBG(ERR,\n+\t\t\t    \"Parse Err: A valid RSS key must be provided with a valid key len.\\n\");\n+\t\treturn BNXT_TF_RC_ERROR;\n+\t}\n+\tif (rss->key)\n+\t\tmemcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY], rss->key, rss->key_len);\n+\n+\tmemcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_QUEUE_NUM],\n+\t       &rss->queue_num, BNXT_ULP_ACT_PROP_SZ_RSS_QUEUE_NUM);\n+\n+\tif (rss->queue_num >= ULP_BYTE_2_BITS(BNXT_ULP_ACT_PROP_SZ_RSS_QUEUE)) {\n+\t\tBNXT_TF_DBG(ERR, \"Parse Err: RSS queue num too big\\n\");\n \t\treturn BNXT_TF_RC_ERROR;\n \t}\n-\tmemcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY], rss->key,\n-\t       rss->key_len);\n+\n+\t/* Queues converted into a bitmap format */\n+\tmemset(queue_list, 0, sizeof(queue_list));\n+\tfor (idx = 0; idx < rss->queue_num; idx++) {\n+\t\tid = rss->queue[idx];\n+\t\tif (id >= ULP_BYTE_2_BITS(BNXT_ULP_ACT_PROP_SZ_RSS_QUEUE)) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Parse Err: RSS queue id too big\\n\");\n+\t\t\treturn BNXT_TF_RC_ERROR;\n+\t\t}\n+\t\tif ((queue_list[id / ULP_INDEX_BITMAP_SIZE] >>\n+\t\t    ((ULP_INDEX_BITMAP_SIZE - 1) -\n+\t\t     (id % ULP_INDEX_BITMAP_SIZE)) & 1)) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Parse Err: duplicate queue ids\\n\");\n+\t\t\treturn BNXT_TF_RC_ERROR;\n+\t\t}\n+\t\tqueue_list[id / ULP_INDEX_BITMAP_SIZE] |= (1UL <<\n+\t\t((ULP_INDEX_BITMAP_SIZE - 1) - (id % ULP_INDEX_BITMAP_SIZE)));\n+\t}\n+\tmemcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_QUEUE],\n+\t       (uint8_t *)queue_list, BNXT_ULP_ACT_PROP_SZ_RSS_QUEUE);\n \n \t/* set the RSS action header bit */\n \tULP_BITMAP_SET(param->act_bitmap.bits, BNXT_ULP_ACT_BIT_RSS);\n@@ -2253,6 +2362,8 @@ ulp_rte_port_act_handler(const struct rte_flow_action *act_item,\n \n \t/* Set the action port */\n \tULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);\n+\tULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_DEV_ACT_PORT_ID,\n+\t\t\t    ethdev_id);\n \treturn ulp_rte_parser_act_port_set(param, ifindex, act_dir);\n }\n \n@@ -2484,6 +2595,63 @@ ulp_rte_sample_act_handler(const struct rte_flow_action *action_item,\n \treturn ret;\n }\n \n+int32_t\n+ulp_rte_action_hdlr_handler(const struct rte_flow_action *action_item,\n+\t\t\t   struct ulp_rte_parser_params *params)\n+{\n+\tconst struct rte_flow_action_handle *handle;\n+\tstruct bnxt_ulp_shared_act_info *act_info;\n+\tuint64_t action_bitmask;\n+\tuint32_t shared_action_type;\n+\tstruct ulp_rte_act_prop *act = &params->act_prop;\n+\tuint64_t tmp64;\n+\tenum bnxt_ulp_direction_type dir, handle_dir;\n+\tuint32_t act_info_entries = 0;\n+\tint32_t ret;\n+\n+\thandle = action_item->conf;\n+\n+\t/* Have to use the computed direction since the params->dir_attr\n+\t * can be different (transfer, ingress, egress)\n+\t */\n+\tdir = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);\n+\n+\t/* direction of shared action must match direction of flow */\n+\tret = bnxt_get_action_handle_direction(handle, &handle_dir);\n+\tif (ret || dir != handle_dir) {\n+\t\tBNXT_TF_DBG(ERR, \"Invalid shared handle or direction\\n\");\n+\t\treturn BNXT_TF_RC_ERROR;\n+\t}\n+\n+\tif (bnxt_get_action_handle_type(handle, &shared_action_type)) {\n+\t\tBNXT_TF_DBG(ERR, \"Invalid shared handle\\n\");\n+\t\treturn BNXT_TF_RC_ERROR;\n+\t}\n+\n+\tact_info = bnxt_ulp_shared_act_info_get(&act_info_entries);\n+\tif (shared_action_type >= act_info_entries || !act_info) {\n+\t\tBNXT_TF_DBG(ERR, \"Invalid shared handle\\n\");\n+\t\treturn BNXT_TF_RC_ERROR;\n+\t}\n+\n+\taction_bitmask = act_info[shared_action_type].act_bitmask;\n+\n+\t/* shared actions of the same type cannot be repeated */\n+\tif (params->act_bitmap.bits & action_bitmask) {\n+\t\tBNXT_TF_DBG(ERR, \"indirect actions cannot be repeated\\n\");\n+\t\treturn BNXT_TF_RC_ERROR;\n+\t}\n+\n+\ttmp64 = tfp_cpu_to_be_64((uint64_t)bnxt_get_action_handle_index(handle));\n+\n+\tmemcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SHARED_HANDLE],\n+\t       &tmp64, BNXT_ULP_ACT_PROP_SZ_SHARED_HANDLE);\n+\n+\tULP_BITMAP_SET(params->act_bitmap.bits, action_bitmask);\n+\n+\treturn BNXT_TF_RC_SUCCESS;\n+}\n+\n /* Function to handle the parsing of bnxt vendor Flow action vxlan Header. */\n int32_t\n ulp_vendor_vxlan_decap_act_handler(const struct rte_flow_action *action_item,\n@@ -2504,3 +2672,69 @@ ulp_rte_vendor_vxlan_decap_hdr_handler(const struct rte_flow_item *item,\n \tULP_BITMAP_SET(params->hdr_bitmap.bits, BNXT_ULP_HDR_BIT_F2);\n \treturn ulp_rte_vxlan_decap_act_handler(NULL, params);\n }\n+\n+/* Function to handle the parsing of RTE Flow action queue. */\n+int32_t\n+ulp_rte_queue_act_handler(const struct rte_flow_action *action_item,\n+\t\t\t  struct ulp_rte_parser_params *param)\n+{\n+\tconst struct rte_flow_action_queue *q_info;\n+\tstruct ulp_rte_act_prop *ap = &param->act_prop;\n+\n+\tif (action_item == NULL || action_item->conf == NULL) {\n+\t\tBNXT_TF_DBG(ERR, \"Parse Err: invalid queue configuration\\n\");\n+\t\treturn BNXT_TF_RC_ERROR;\n+\t}\n+\n+\tq_info = action_item->conf;\n+\t/* Copy the queue into the specific action properties */\n+\tmemcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_QUEUE_INDEX],\n+\t       &q_info->index, BNXT_ULP_ACT_PROP_SZ_QUEUE_INDEX);\n+\n+\t/* set the queue action header bit */\n+\tULP_BITMAP_SET(param->act_bitmap.bits, BNXT_ULP_ACT_BIT_QUEUE);\n+\n+\treturn BNXT_TF_RC_SUCCESS;\n+}\n+\n+/* Function to handle the parsing of RTE Flow action set mac src.*/\n+int32_t\n+ulp_rte_set_mac_src_act_handler(const struct rte_flow_action *action_item,\n+\t\t\t\tstruct ulp_rte_parser_params *params)\n+{\n+\tconst struct rte_flow_action_set_mac *set_mac;\n+\tstruct ulp_rte_act_prop *act = &params->act_prop;\n+\n+\tset_mac = action_item->conf;\n+\tif (set_mac) {\n+\t\tmemcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SET_MAC_SRC],\n+\t\t       set_mac->mac_addr, BNXT_ULP_ACT_PROP_SZ_SET_MAC_SRC);\n+\t\t/* Update the hdr_bitmap with set mac src */\n+\t\tULP_BITMAP_SET(params->act_bitmap.bits,\n+\t\t\t       BNXT_ULP_ACT_BIT_SET_MAC_SRC);\n+\t\treturn BNXT_TF_RC_SUCCESS;\n+\t}\n+\tBNXT_TF_DBG(ERR, \"Parse Error: set mac src arg is invalid\\n\");\n+\treturn BNXT_TF_RC_ERROR;\n+}\n+\n+/* Function to handle the parsing of RTE Flow action set mac dst.*/\n+int32_t\n+ulp_rte_set_mac_dst_act_handler(const struct rte_flow_action *action_item,\n+\t\t\t\tstruct ulp_rte_parser_params *params)\n+{\n+\tconst struct rte_flow_action_set_mac *set_mac;\n+\tstruct ulp_rte_act_prop *act = &params->act_prop;\n+\n+\tset_mac = action_item->conf;\n+\tif (set_mac) {\n+\t\tmemcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SET_MAC_DST],\n+\t\t       set_mac->mac_addr, BNXT_ULP_ACT_PROP_SZ_SET_MAC_DST);\n+\t\t/* Update the hdr_bitmap with set ipv4 dst */\n+\t\tULP_BITMAP_SET(params->act_bitmap.bits,\n+\t\t\t       BNXT_ULP_ACT_BIT_SET_MAC_DST);\n+\t\treturn BNXT_TF_RC_SUCCESS;\n+\t}\n+\tBNXT_TF_DBG(ERR, \"Parse Error: set mac dst arg is invalid\\n\");\n+\treturn BNXT_TF_RC_ERROR;\n+}\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h\nindex b0b2b4f33f..401ce4885d 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h\n+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2014-2021 Broadcom\n+ * Copyright(c) 2014-2023 Broadcom\n  * All rights reserved.\n  */\n \n@@ -80,6 +80,16 @@ bnxt_ulp_rte_parser_act_parse(const struct rte_flow_action actions[],\n void\n bnxt_ulp_rte_parser_post_process(struct ulp_rte_parser_params *params);\n \n+/* Function to handle the parsing of RTE Flow item PF Header. */\n+int32_t\n+ulp_rte_pf_hdr_handler(const struct rte_flow_item *item,\n+\t\t       struct ulp_rte_parser_params *params);\n+\n+/* Function to handle the parsing of RTE Flow item VF Header. */\n+int32_t\n+ulp_rte_vf_hdr_handler(const struct rte_flow_item *item,\n+\t\t       struct ulp_rte_parser_params *params);\n+\n /* Parse items PORT_ID, PORT_REPRESENTOR and REPRESENTED_PORT. */\n int32_t\n ulp_rte_port_hdr_handler(const struct rte_flow_item *item,\n@@ -238,6 +248,15 @@ ulp_rte_set_tp_dst_act_handler(const struct rte_flow_action *action_item,\n int32_t\n ulp_rte_dec_ttl_act_handler(const struct rte_flow_action *action_item,\n \t\t\t    struct ulp_rte_parser_params *params);\n+/* Function to handle the parsing of RTE Flow action set mac src.*/\n+int32_t\n+ulp_rte_set_mac_src_act_handler(const struct rte_flow_action *action_item,\n+\t\t\t\tstruct ulp_rte_parser_params *params);\n+\n+/* Function to handle the parsing of RTE Flow action set mac dst.*/\n+int32_t\n+ulp_rte_set_mac_dst_act_handler(const struct rte_flow_action *action_item,\n+\t\t\t\tstruct ulp_rte_parser_params *params);\n \n /* Function to handle the parsing of RTE Flow action JUMP .*/\n int32_t\n@@ -249,7 +268,7 @@ ulp_rte_sample_act_handler(const struct rte_flow_action *action_item,\n \t\t\t   struct ulp_rte_parser_params *params);\n \n int32_t\n-ulp_rte_shared_act_handler(const struct rte_flow_action *action_item,\n+ulp_rte_action_hdlr_handler(const struct rte_flow_action *action_item,\n \t\t\t   struct ulp_rte_parser_params *params);\n \n int32_t\n@@ -259,4 +278,18 @@ ulp_vendor_vxlan_decap_act_handler(const struct rte_flow_action *action_item,\n int32_t\n ulp_rte_vendor_vxlan_decap_hdr_handler(const struct rte_flow_item *item,\n \t\t\t\t       struct ulp_rte_parser_params *params);\n+\n+int32_t\n+ulp_rte_queue_act_handler(const struct rte_flow_action *act_item,\n+\t\t\t  struct ulp_rte_parser_params *param);\n+\n+/* Function to handle the parsing of RTE Flow action set mac src.*/\n+int32_t\n+ulp_rte_set_mac_src_act_handler(const struct rte_flow_action *action_item,\n+\t\t\t\tstruct ulp_rte_parser_params *params);\n+\n+/* Function to handle the parsing of RTE Flow action set mac dst.*/\n+int32_t\n+ulp_rte_set_mac_dst_act_handler(const struct rte_flow_action *action_item,\n+\t\t\t\tstruct ulp_rte_parser_params *params);\n #endif /* _ULP_RTE_PARSER_H_ */\n",
    "prefixes": [
        "v4",
        "06/11"
    ]
}