get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 77263,
    "url": "http://patches.dpdk.org/api/patches/77263/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200911015603.88359-2-ajit.khaparde@broadcom.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20200911015603.88359-2-ajit.khaparde@broadcom.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200911015603.88359-2-ajit.khaparde@broadcom.com",
    "date": "2020-09-11T01:55:39",
    "name": "[01/25] net/bnxt: fix port stop process and cleanup resources",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "7362b6b879e43d7dec91a181be415c9b287ede2c",
    "submitter": {
        "id": 501,
        "url": "http://patches.dpdk.org/api/people/501/?format=api",
        "name": "Ajit Khaparde",
        "email": "ajit.khaparde@broadcom.com"
    },
    "delegate": {
        "id": 1766,
        "url": "http://patches.dpdk.org/api/users/1766/?format=api",
        "username": "ajitkhaparde",
        "first_name": "Ajit",
        "last_name": "Khaparde",
        "email": "ajit.khaparde@broadcom.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20200911015603.88359-2-ajit.khaparde@broadcom.com/mbox/",
    "series": [
        {
            "id": 12116,
            "url": "http://patches.dpdk.org/api/series/12116/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=12116",
            "date": "2020-09-11T01:55:38",
            "name": "patchset for bnxt",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/12116/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/77263/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/77263/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id B42EAA04B5;\n\tFri, 11 Sep 2020 03:56:23 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 8966E1C0CA;\n\tFri, 11 Sep 2020 03:56:21 +0200 (CEST)",
            "from mail-pg1-f227.google.com (mail-pg1-f227.google.com\n [209.85.215.227]) by dpdk.org (Postfix) with ESMTP id 156511C0B9\n for <dev@dpdk.org>; Fri, 11 Sep 2020 03:56:20 +0200 (CEST)",
            "by mail-pg1-f227.google.com with SMTP id w186so5448446pgb.8\n for <dev@dpdk.org>; Thu, 10 Sep 2020 18:56:20 -0700 (PDT)",
            "from localhost.localdomain ([192.19.223.252])\n by smtp-relay.gmail.com with ESMTPS id cl6sm80986pjb.15.2020.09.10.18.56.14\n (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);\n Thu, 10 Sep 2020 18:56:18 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com;\n s=google;\n h=from:to:cc:subject:date:message-id:in-reply-to:references\n :mime-version:content-transfer-encoding;\n bh=f2kZ4Ago8y+WL5IZ/FD1OBtCQNLzQcN0yvWAOULsN4c=;\n b=RH+w5W7P7HGntPN2AKJaOgQ9qspR3z0fljdbQgMUtg1LPQ1KZm8TAEwrksu0nwfLSV\n iPxCTg3vQJmB5Jp8/1ZFm+MqB9s8n6JxOZh2m9RpQezVvGuwUwM9yw9vUHdfeUHA7zYY\n JDqqD9F2zYVys4fdCRinTRkGGP/oY/xxcGq/w=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20161025;\n h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n :references:mime-version:content-transfer-encoding;\n bh=f2kZ4Ago8y+WL5IZ/FD1OBtCQNLzQcN0yvWAOULsN4c=;\n b=btk0SuAAWqZ5ODfGrGbj3TN7HCGTusXtArHddy5M/nvBjASbsFIkE/Rca/GQxgDoe7\n lLVaCiPIKI1V0/L0EIkrSnbD7jIfpvl2RfSv2/Niej50dN1ojucYNqEl35POccSb3G1C\n 2knsQIMg+cXY4TV3WoTu5j0qzOdcWlyEr1YK32T3kmhOv4TOoPOtr8Ar8V9MLGDSD+28\n 29hEjxDVxDnC09XmggS2xRdVHDvRL2YILRZ29m7JJU6wlwkms7OGY0Gj62U9XI78bhxX\n PyHhsoTf1+j/NyrE7S/uqjJ2HZs1sm2qyCPjr5zOWO36pkngnY2zvm1yPM0iQMAVjV/T\n RozQ==",
        "X-Gm-Message-State": "AOAM531v6ZeGqsPVR8Ds0g7shCzavRrOft7NrALAkVtLxP9UBWsmG9eR\n 0thcMYyFHXisbKImEWVfnGCqrL+jfXIwOauWE0IzjoCxRp5iIBKyJ+COI8TZADkjucA7Da79bdW\n itiShf+wjIqND1TGGwrda/xxjq9G5Jawc2TFws16N+qHHeBkF8RymEJ/JJh04SWQe4icnEFZ92v\n huBA==",
        "X-Google-Smtp-Source": "\n ABdhPJxRSvQ4n8/gCaHzfwSGjkQrb0ZI0cB6EVUnHBz7sQ0a0mZkZkvGidi6DhIZkS8zPYUJYMgDXyqUWakT",
        "X-Received": "by 2002:a63:fc18:: with SMTP id j24mr6637285pgi.452.1599789378838;\n Thu, 10 Sep 2020 18:56:18 -0700 (PDT)",
        "X-Relaying-Domain": "broadcom.com",
        "From": "Ajit Khaparde <ajit.khaparde@broadcom.com>",
        "To": "dev@dpdk.org",
        "Cc": "Kishore Padmanabha <kishore.padmanabha@broadcom.com>,\n Mike Baucom <michael.baucom@broadcom.com>,\n Shahaji Bhosle <sbhosle@broadcom.com>",
        "Date": "Thu, 10 Sep 2020 18:55:39 -0700",
        "Message-Id": "<20200911015603.88359-2-ajit.khaparde@broadcom.com>",
        "X-Mailer": "git-send-email 2.21.1 (Apple Git-122.3)",
        "In-Reply-To": "<20200911015603.88359-1-ajit.khaparde@broadcom.com>",
        "References": "<20200911015603.88359-1-ajit.khaparde@broadcom.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH 01/25] net/bnxt: fix port stop process and\n\tcleanup resources",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>\n\nThe port deinitialization now cleans up all the resources\nproperly. If all the ports are stopped then ulp context is\nfreed.\nAdded fix to update the correct tfp pointer in the ulp context\nwith the changes to support multi control channels.\n\nFixes: 70e64b27af5b42 (\"net/bnxt: support ULP session manager cleanup\")\n\nSigned-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>\nReviewed-by: Mike Baucom <michael.baucom@broadcom.com>\nReviewed-by: Shahaji Bhosle <sbhosle@broadcom.com>\n---\n drivers/net/bnxt/bnxt.h                 |  12 +-\n drivers/net/bnxt/bnxt_ethdev.c          |  18 +-\n drivers/net/bnxt/bnxt_reps.c            | 106 ++---\n drivers/net/bnxt/tf_ulp/bnxt_ulp.c      | 494 ++++++++++++++----------\n drivers/net/bnxt/tf_ulp/bnxt_ulp.h      |  16 +-\n drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c |  19 +-\n drivers/net/bnxt/tf_ulp/ulp_def_rules.c | 131 ++++++-\n drivers/net/bnxt/tf_ulp/ulp_flow_db.c   |   4 +-\n drivers/net/bnxt/tf_ulp/ulp_flow_db.h   |   4 +-\n 9 files changed, 494 insertions(+), 310 deletions(-)",
    "diff": "diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h\nindex a190d78bd..d2944aa74 100644\n--- a/drivers/net/bnxt/bnxt.h\n+++ b/drivers/net/bnxt/bnxt.h\n@@ -823,8 +823,7 @@ struct bnxt_vf_representor {\n \tuint16_t\t\tdflt_vnic_id;\n \tuint16_t\t\tsvif;\n \tuint16_t\t\tvfr_tx_cfa_action;\n-\tuint32_t\t\trep2vf_flow_id;\n-\tuint32_t\t\tvf2rep_flow_id;\n+\tuint32_t\t\tdpdk_port_id;\n \t/* Private data store of associated PF/Trusted VF */\n \tstruct rte_eth_dev\t*parent_dev;\n \tuint8_t\t\t\tmac_addr[RTE_ETHER_ADDR_LEN];\n@@ -894,11 +893,14 @@ extern int bnxt_logtype_driver;\n \t  PMD_DRV_LOG_RAW(level, fmt, ## args)\n \n extern const struct rte_flow_ops bnxt_ulp_rte_flow_ops;\n-int32_t bnxt_ulp_init(struct bnxt *bp);\n-void bnxt_ulp_deinit(struct bnxt *bp);\n+int32_t bnxt_ulp_port_init(struct bnxt *bp);\n+void bnxt_ulp_port_deinit(struct bnxt *bp);\n int32_t bnxt_ulp_create_df_rules(struct bnxt *bp);\n void bnxt_ulp_destroy_df_rules(struct bnxt *bp, bool global);\n-\n+int32_t\n+bnxt_ulp_create_vfr_default_rules(struct rte_eth_dev *vfr_ethdev);\n+int32_t\n+bnxt_ulp_delete_vfr_default_rules(struct bnxt_vf_representor *vfr);\n uint16_t bnxt_get_vnic_id(uint16_t port, enum bnxt_ulp_intf_type type);\n uint16_t bnxt_get_svif(uint16_t port_id, bool func_svif,\n \t\t       enum bnxt_ulp_intf_type type);\ndiff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c\nindex 75d055be0..fdbd6ce58 100644\n--- a/drivers/net/bnxt/bnxt_ethdev.c\n+++ b/drivers/net/bnxt/bnxt_ethdev.c\n@@ -1236,6 +1236,11 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)\n \tif (rc)\n \t\tgoto error;\n \n+\t/* Initialize bnxt ULP port details */\n+\trc = bnxt_ulp_port_init(bp);\n+\tif (rc)\n+\t\tgoto error;\n+\n \teth_dev->rx_pkt_burst = bnxt_receive_function(eth_dev);\n \teth_dev->tx_pkt_burst = bnxt_transmit_function(eth_dev);\n \n@@ -1243,8 +1248,6 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)\n \tbnxt_schedule_fw_health_check(bp);\n \tpthread_mutex_unlock(&bp->def_cp_lock);\n \n-\tbnxt_ulp_init(bp);\n-\n \treturn 0;\n \n error:\n@@ -1304,8 +1307,8 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)\n \t/* disable uio/vfio intr/eventfd mapping */\n \trte_intr_disable(intr_handle);\n \n-\tbnxt_ulp_destroy_df_rules(bp, false);\n-\tbnxt_ulp_deinit(bp);\n+\t/* delete the bnxt ULP port details */\n+\tbnxt_ulp_port_deinit(bp);\n \n \tbnxt_cancel_fw_health_check(bp);\n \n@@ -1599,8 +1602,6 @@ static int bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)\n \tif (rc != 0)\n \t\tvnic->flags = old_flags;\n \n-\tbnxt_ulp_create_df_rules(bp);\n-\n \treturn rc;\n }\n \n@@ -3701,9 +3702,14 @@ bnxt_filter_ctrl_op(struct rte_eth_dev *dev,\n \tstruct bnxt *bp = dev->data->dev_private;\n \tint ret = 0;\n \n+\tif (!bp)\n+\t\treturn -EIO;\n+\n \tif (BNXT_ETH_DEV_IS_REPRESENTOR(dev)) {\n \t\tstruct bnxt_vf_representor *vfr = dev->data->dev_private;\n \t\tbp = vfr->parent_dev->data->dev_private;\n+\t\tif (!bp)\n+\t\t\treturn -EIO;\n \t}\n \n \tret = is_bnxt_in_error(bp);\ndiff --git a/drivers/net/bnxt/bnxt_reps.c b/drivers/net/bnxt/bnxt_reps.c\nindex 2f2af0d44..3101512c3 100644\n--- a/drivers/net/bnxt/bnxt_reps.c\n+++ b/drivers/net/bnxt/bnxt_reps.c\n@@ -268,66 +268,37 @@ static int bnxt_tf_vfr_alloc(struct rte_eth_dev *vfr_ethdev)\n \tstruct bnxt_vf_representor *vfr = vfr_ethdev->data->dev_private;\n \tstruct rte_eth_dev *parent_dev = vfr->parent_dev;\n \tstruct bnxt *parent_bp = parent_dev->data->dev_private;\n-\tuint16_t vfr_port_id = vfr_ethdev->data->port_id;\n-\tstruct ulp_tlv_param param_list[] = {\n-\t\t{\n-\t\t\t.type = BNXT_ULP_DF_PARAM_TYPE_DEV_PORT_ID,\n-\t\t\t.length = 2,\n-\t\t\t.value = {(vfr_port_id >> 8) & 0xff, vfr_port_id & 0xff}\n-\t\t},\n-\t\t{\n-\t\t\t.type = BNXT_ULP_DF_PARAM_TYPE_LAST,\n-\t\t\t.length = 0,\n-\t\t\t.value = {0}\n-\t\t}\n-\t};\n \n-\tulp_port_db_dev_port_intf_update(parent_bp->ulp_ctx, vfr_ethdev);\n+\tif (!parent_bp || !parent_bp->ulp_ctx) {\n+\t\tBNXT_TF_DBG(ERR, \"Invalid arguments\\n\");\n+\t\treturn 0;\n+\t}\n \n-\trc = ulp_default_flow_create(parent_dev, param_list,\n-\t\t\t\t     BNXT_ULP_DF_TPL_VFREP_TO_VF,\n-\t\t\t\t     &vfr->rep2vf_flow_id);\n+\t/* Update the ULP portdata base with the new VFR interface */\n+\trc = ulp_port_db_dev_port_intf_update(parent_bp->ulp_ctx, vfr_ethdev);\n \tif (rc) {\n-\t\tBNXT_TF_DBG(DEBUG,\n-\t\t\t    \"Default flow rule creation for VFR->VF failed!\\n\");\n-\t\tgoto err;\n+\t\tBNXT_TF_DBG(ERR, \"Failed to update ulp port details vfr:%u\\n\",\n+\t\t\t    vfr->vf_id);\n+\t\treturn rc;\n \t}\n \n-\tBNXT_TF_DBG(DEBUG, \"*** Default flow rule created for VFR->VF! ***\\n\");\n-\tBNXT_TF_DBG(DEBUG, \"rep2vf_flow_id = %d\\n\", vfr->rep2vf_flow_id);\n-\trc = ulp_default_flow_db_cfa_action_get(parent_bp->ulp_ctx,\n-\t\t\t\t\t\tvfr->rep2vf_flow_id,\n-\t\t\t\t\t\t&vfr->vfr_tx_cfa_action);\n-\tif (rc) {\n-\t\tBNXT_TF_DBG(DEBUG,\n-\t\t\t    \"Failed to get action_ptr for VFR->VF dflt rule\\n\");\n-\t\tgoto rep2vf_free;\n-\t}\n-\tBNXT_TF_DBG(DEBUG, \"tx_cfa_action = %d\\n\", vfr->vfr_tx_cfa_action);\n-\trc = ulp_default_flow_create(parent_dev, param_list,\n-\t\t\t\t     BNXT_ULP_DF_TPL_VF_TO_VFREP,\n-\t\t\t\t     &vfr->vf2rep_flow_id);\n+\t/* Create the default rules for the VFR */\n+\trc = bnxt_ulp_create_vfr_default_rules(vfr_ethdev);\n \tif (rc) {\n-\t\tBNXT_TF_DBG(DEBUG,\n-\t\t\t    \"Default flow rule creation for VF->VFR failed!\\n\");\n-\t\tgoto rep2vf_free;\n+\t\tBNXT_TF_DBG(ERR, \"Failed to create VFR default rules vfr:%u\\n\",\n+\t\t\t    vfr->vf_id);\n+\t\treturn rc;\n \t}\n-\n-\tBNXT_TF_DBG(DEBUG, \"*** Default flow rule created for VF->VFR! ***\\n\");\n-\tBNXT_TF_DBG(DEBUG, \"vfr2rep_flow_id = %d\\n\", vfr->vf2rep_flow_id);\n-\n+\t/* update the port id so you can backtrack to ethdev */\n+\tvfr->dpdk_port_id = vfr_ethdev->data->port_id;\n \trc = bnxt_hwrm_cfa_vfr_alloc(parent_bp, vfr->vf_id);\n-\tif (rc)\n-\t\tgoto vf2rep_free;\n-\n-\treturn 0;\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed in hwrm vfr alloc vfr:%u rc=%d\\n\",\n+\t\t\t    vfr->vf_id, rc);\n+\t\t(void)bnxt_ulp_delete_vfr_default_rules(vfr);\n+\t}\n \n-vf2rep_free:\n-\tulp_default_flow_destroy(vfr->parent_dev, vfr->vf2rep_flow_id);\n-rep2vf_free:\n-\tulp_default_flow_destroy(vfr->parent_dev, vfr->rep2vf_flow_id);\n-err:\n-\treturn -EIO;\n+\treturn rc;\n }\n \n static int bnxt_vfr_alloc(struct rte_eth_dev *vfr_ethdev)\n@@ -338,7 +309,7 @@ static int bnxt_vfr_alloc(struct rte_eth_dev *vfr_ethdev)\n \n \tif (!vfr || !vfr->parent_dev) {\n \t\tPMD_DRV_LOG(ERR,\n-\t\t\t    \"No memory allocated for representor\\n\");\n+\t\t\t\t\"No memory allocated for representor\\n\");\n \t\treturn -ENOMEM;\n \t}\n \n@@ -392,14 +363,12 @@ int bnxt_vf_rep_dev_start_op(struct rte_eth_dev *eth_dev)\n \trep_info = &parent_bp->rep_info[rep_bp->vf_id];\n \n \tpthread_mutex_lock(&rep_info->vfr_start_lock);\n-\tif (rep_info->conduit_valid) {\n-\t\tpthread_mutex_unlock(&rep_info->vfr_start_lock);\n-\t\treturn 0;\n-\t}\n-\trc = bnxt_get_dflt_vnic_svif(parent_bp, rep_bp);\n-\tif (rc || !rep_info->conduit_valid) {\n-\t\tpthread_mutex_unlock(&rep_info->vfr_start_lock);\n-\t\treturn rc;\n+\tif (!rep_info->conduit_valid) {\n+\t\trc = bnxt_get_dflt_vnic_svif(parent_bp, rep_bp);\n+\t\tif (rc || !rep_info->conduit_valid) {\n+\t\t\tpthread_mutex_unlock(&rep_info->vfr_start_lock);\n+\t\t\treturn rc;\n+\t\t}\n \t}\n \tpthread_mutex_unlock(&rep_info->vfr_start_lock);\n \n@@ -418,21 +387,7 @@ int bnxt_vf_rep_dev_start_op(struct rte_eth_dev *eth_dev)\n \n static int bnxt_tf_vfr_free(struct bnxt_vf_representor *vfr)\n {\n-\tint rc = 0;\n-\n-\trc = ulp_default_flow_destroy(vfr->parent_dev,\n-\t\t\t\t      vfr->rep2vf_flow_id);\n-\tif (rc)\n-\t\tPMD_DRV_LOG(ERR,\n-\t\t\t    \"default flow destroy failed rep2vf flowid: %d\\n\",\n-\t\t\t    vfr->rep2vf_flow_id);\n-\trc = ulp_default_flow_destroy(vfr->parent_dev,\n-\t\t\t\t      vfr->vf2rep_flow_id);\n-\tif (rc)\n-\t\tPMD_DRV_LOG(ERR,\n-\t\t\t    \"default flow destroy failed vf2rep flowid: %d\\n\",\n-\t\t\t    vfr->vf2rep_flow_id);\n-\treturn 0;\n+\treturn bnxt_ulp_delete_vfr_default_rules(vfr);\n }\n \n static int bnxt_vfr_free(struct bnxt_vf_representor *vfr)\n@@ -459,7 +414,6 @@ static int bnxt_vfr_free(struct bnxt_vf_representor *vfr)\n \t\tPMD_DRV_LOG(ERR,\n \t\t\t    \"Failed to free representor %d in FW\\n\",\n \t\t\t    vfr->vf_id);\n-\t\treturn rc;\n \t}\n \n \tPMD_DRV_LOG(DEBUG, \"freed representor %d in FW\\n\",\ndiff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c\nindex 0d4a45513..21baed048 100644\n--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c\n+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c\n@@ -32,23 +32,22 @@ static pthread_mutex_t bnxt_ulp_global_mutex = PTHREAD_MUTEX_INITIALIZER;\n \n /*\n  * Allow the deletion of context only for the bnxt device that\n- * created the session\n- * TBD - The implementation of the function should change to\n- * using the reference count once tf_session_attach functionality\n- * is fixed.\n+ * created the session.\n  */\n bool\n ulp_ctx_deinit_allowed(void *ptr)\n {\n \tstruct bnxt *bp = (struct bnxt *)ptr;\n \n-\tif (!bp)\n-\t\treturn 0;\n+\tif (!bp || !bp->ulp_ctx || !bp->ulp_ctx->cfg_data)\n+\t\treturn false;\n \n-\tif (&bp->tfp == bp->ulp_ctx->g_tfp)\n-\t\treturn 1;\n+\tif (!bp->ulp_ctx->cfg_data->ref_cnt) {\n+\t\tBNXT_TF_DBG(DEBUG, \"ulp ctx shall initiate deinit\\n\");\n+\t\treturn true;\n+\t}\n \n-\treturn 0;\n+\treturn false;\n }\n \n /*\n@@ -155,8 +154,10 @@ ulp_ctx_session_open(struct bnxt *bp,\n \t\t\t    params.ctrl_chan_name, rc);\n \t\treturn -EINVAL;\n \t}\n-\tsession->session_opened = 1;\n-\tsession->g_tfp = &bp->tfp;\n+\tif (!session->session_opened) {\n+\t\tsession->session_opened = 1;\n+\t\tsession->g_tfp = &bp->tfp;\n+\t}\n \treturn rc;\n }\n \n@@ -173,7 +174,6 @@ ulp_ctx_session_close(struct bnxt *bp,\n \t\ttf_close_session(&bp->tfp);\n \tsession->session_opened = 0;\n \tsession->g_tfp = NULL;\n-\tbp->ulp_ctx->g_tfp = NULL;\n }\n \n static void\n@@ -285,10 +285,6 @@ ulp_eem_tbl_scope_deinit(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx)\n \tif (!ulp_ctx || !ulp_ctx->cfg_data)\n \t\treturn -EINVAL;\n \n-\t/* Free the resources for the last device */\n-\tif (!ulp_ctx_deinit_allowed(bp))\n-\t\treturn rc;\n-\n \ttfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);\n \tif (!tfp) {\n \t\tBNXT_TF_DBG(ERR, \"Failed to get the truflow pointer\\n\");\n@@ -331,11 +327,6 @@ static int32_t\n ulp_ctx_deinit(struct bnxt *bp,\n \t       struct bnxt_ulp_session_state *session)\n {\n-\tif (!session || !bp) {\n-\t\tBNXT_TF_DBG(ERR, \"Invalid Arguments\\n\");\n-\t\treturn -EINVAL;\n-\t}\n-\n \t/* close the tf session */\n \tulp_ctx_session_close(bp, session);\n \n@@ -356,11 +347,6 @@ ulp_ctx_init(struct bnxt *bp,\n \tstruct bnxt_ulp_data\t*ulp_data;\n \tint32_t\t\t\trc = 0;\n \n-\tif (!session || !bp) {\n-\t\tBNXT_TF_DBG(ERR, \"Invalid Arguments\\n\");\n-\t\treturn -EINVAL;\n-\t}\n-\n \t/* Allocate memory to hold ulp context data. */\n \tulp_data = rte_zmalloc(\"bnxt_ulp_data\",\n \t\t\t       sizeof(struct bnxt_ulp_data), 0);\n@@ -378,11 +364,12 @@ ulp_ctx_init(struct bnxt *bp,\n \t/* Open the ulp session. */\n \trc = ulp_ctx_session_open(bp, session);\n \tif (rc) {\n+\t\tsession->session_opened = 1;\n \t\t(void)ulp_ctx_deinit(bp, session);\n \t\treturn rc;\n \t}\n \n-\tbnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, session->g_tfp);\n+\tbnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, &bp->tfp);\n \treturn rc;\n }\n \n@@ -395,7 +382,7 @@ ulp_dparms_init(struct bnxt *bp,\n \tuint32_t dev_id;\n \n \tif (!bp->max_num_kflows)\n-\t\treturn -EINVAL;\n+\t\treturn 0;\n \n \tif (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) {\n \t\tBNXT_TF_DBG(DEBUG, \"Failed to get device id\\n\");\n@@ -445,51 +432,37 @@ ulp_dparms_dev_port_intf_update(struct bnxt *bp,\n }\n \n static int32_t\n-ulp_ctx_attach(struct bnxt_ulp_context *ulp_ctx,\n+ulp_ctx_attach(struct bnxt *bp,\n \t       struct bnxt_ulp_session_state *session)\n {\n-\tif (!ulp_ctx || !session) {\n-\t\tBNXT_TF_DBG(ERR, \"Invalid Arguments\\n\");\n-\t\treturn -EINVAL;\n-\t}\n+\tint32_t rc = 0;\n \n \t/* Increment the ulp context data reference count usage. */\n-\tulp_ctx->cfg_data = session->cfg_data;\n-\tulp_ctx->cfg_data->ref_cnt++;\n+\tbp->ulp_ctx->cfg_data = session->cfg_data;\n+\tbp->ulp_ctx->cfg_data->ref_cnt++;\n \n-\t/* TBD call TF_session_attach. */\n-\tulp_ctx->g_tfp = session->g_tfp;\n-\treturn 0;\n-}\n-\n-static int32_t\n-ulp_ctx_detach(struct bnxt *bp,\n-\t       struct bnxt_ulp_session_state *session)\n-{\n-\tstruct bnxt_ulp_context *ulp_ctx;\n+\t/* update the session details in bnxt tfp */\n+\tbp->tfp.session = session->g_tfp->session;\n \n-\tif (!bp || !session) {\n-\t\tBNXT_TF_DBG(ERR, \"Invalid Arguments\\n\");\n-\t\treturn -EINVAL;\n+\t/* Create a TF Client */\n+\trc = ulp_ctx_session_open(bp, session);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to open ctxt session, rc:%d\\n\", rc);\n+\t\tbp->tfp.session = NULL;\n+\t\treturn rc;\n \t}\n-\tulp_ctx = bp->ulp_ctx;\n \n-\tif (!ulp_ctx->cfg_data)\n-\t\treturn 0;\n-\n-\t/* TBD call TF_session_detach */\n+\tbnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, &bp->tfp);\n+\treturn rc;\n+}\n \n-\t/* Increment the ulp context data reference count usage. */\n-\tif (ulp_ctx->cfg_data->ref_cnt >= 1) {\n-\t\tulp_ctx->cfg_data->ref_cnt--;\n-\t\tif (ulp_ctx_deinit_allowed(bp))\n-\t\t\tulp_ctx_deinit(bp, session);\n-\t\tulp_ctx->cfg_data = NULL;\n-\t\tulp_ctx->g_tfp = NULL;\n-\t\treturn 0;\n+static void\n+ulp_ctx_detach(struct bnxt *bp)\n+{\n+\tif (bp->tfp.session) {\n+\t\ttf_close_session(&bp->tfp);\n+\t\tbp->tfp.session = NULL;\n \t}\n-\tBNXT_TF_DBG(ERR, \"context deatach on invalid data\\n\");\n-\treturn 0;\n }\n \n /*\n@@ -542,6 +515,7 @@ ulp_session_init(struct bnxt *bp,\n \tstruct rte_pci_device\t\t*pci_dev;\n \tstruct rte_pci_addr\t\t*pci_addr;\n \tstruct bnxt_ulp_session_state\t*session;\n+\tint rc = 0;\n \n \tif (!bp)\n \t\treturn NULL;\n@@ -567,7 +541,12 @@ ulp_session_init(struct bnxt *bp,\n \t\t\t/* Add it to the queue */\n \t\t\tsession->pci_info.domain = pci_addr->domain;\n \t\t\tsession->pci_info.bus = pci_addr->bus;\n-\t\t\tpthread_mutex_init(&session->bnxt_ulp_mutex, NULL);\n+\t\t\trc = pthread_mutex_init(&session->bnxt_ulp_mutex, NULL);\n+\t\t\tif (rc) {\n+\t\t\t\tBNXT_TF_DBG(ERR, \"mutex create failed\\n\");\n+\t\t\t\tpthread_mutex_unlock(&bnxt_ulp_global_mutex);\n+\t\t\t\treturn NULL;\n+\t\t\t}\n \t\t\tSTAILQ_INSERT_TAIL(&bnxt_ulp_session_list,\n \t\t\t\t\t   session, next);\n \t\t}\n@@ -643,80 +622,122 @@ bnxt_ulp_global_cfg_update(struct bnxt *bp,\n \treturn rc;\n }\n \n+/* Internal function to delete all the flows belonging to the given port */\n+static void\n+bnxt_ulp_flush_port_flows(struct bnxt *bp)\n+{\n+\tuint16_t func_id;\n+\n+\tfunc_id = bnxt_get_fw_func_id(bp->eth_dev->data->port_id,\n+\t\t\t\t      BNXT_ULP_INTF_TYPE_INVALID);\n+\tulp_flow_db_function_flow_flush(bp->ulp_ctx, func_id);\n+}\n+\n+/* Internal function to delete the VFR default flows */\n+static void\n+bnxt_ulp_destroy_vfr_default_rules(struct bnxt *bp, bool global)\n+{\n+\tstruct bnxt_ulp_vfr_rule_info *info;\n+\tuint8_t port_id;\n+\tstruct rte_eth_dev *vfr_eth_dev;\n+\tstruct bnxt_vf_representor *vfr_bp;\n+\n+\tif (!BNXT_TRUFLOW_EN(bp) || BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev))\n+\t\treturn;\n+\n+\tif (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)\n+\t\treturn;\n+\n+\t/* Delete default rules for all ports */\n+\tfor (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {\n+\t\tinfo = &bp->ulp_ctx->cfg_data->vfr_rule_info[port_id];\n+\t\tif (!info->valid)\n+\t\t\tcontinue;\n+\n+\t\tif (!global && info->parent_port_id !=\n+\t\t    bp->eth_dev->data->port_id)\n+\t\t\tcontinue;\n+\n+\t\t/* Destroy the flows */\n+\t\tulp_default_flow_destroy(bp->eth_dev, info->rep2vf_flow_id);\n+\t\tulp_default_flow_destroy(bp->eth_dev, info->vf2rep_flow_id);\n+\t\t/* Clean up the tx action pointer */\n+\t\tvfr_eth_dev = &rte_eth_devices[port_id];\n+\t\tif (vfr_eth_dev) {\n+\t\t\tvfr_bp = vfr_eth_dev->data->dev_private;\n+\t\t\tvfr_bp->vfr_tx_cfa_action = 0;\n+\t\t}\n+\t\tmemset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));\n+\t}\n+}\n+\n /*\n- * When a port is initialized by dpdk. This functions is called\n- * and this function initializes the ULP context and rest of the\n+ * When a port is deinit'ed by dpdk. This function is called\n+ * and this function clears the ULP context and rest of the\n  * infrastructure associated with it.\n  */\n-int32_t\n-bnxt_ulp_init(struct bnxt *bp)\n+static void\n+bnxt_ulp_deinit(struct bnxt *bp,\n+\t\tstruct bnxt_ulp_session_state *session)\n {\n-\tstruct bnxt_ulp_session_state *session;\n-\tbool init;\n-\tint rc;\n+\tif (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)\n+\t\treturn;\n \n-\tif (!BNXT_TRUFLOW_EN(bp))\n-\t\treturn 0;\n+\t/* clean up default flows */\n+\tbnxt_ulp_destroy_df_rules(bp, true);\n \n-\tif (bp->ulp_ctx) {\n-\t\tBNXT_TF_DBG(DEBUG, \"ulp ctx already allocated\\n\");\n-\t\treturn -EINVAL;\n-\t}\n+\t/* clean up default VFR flows */\n+\tbnxt_ulp_destroy_vfr_default_rules(bp, true);\n \n-\t/*\n-\t * Multiple uplink ports can be associated with a single vswitch.\n-\t * Make sure only the port that is started first will initialize\n-\t * the TF session.\n-\t */\n-\tsession = ulp_session_init(bp, &init);\n-\tif (!session) {\n-\t\tBNXT_TF_DBG(ERR, \"Failed to initialize the tf session\\n\");\n-\t\treturn -EINVAL;\n-\t}\n+\t/* clean up regular flows */\n+\tulp_flow_db_flush_flows(bp->ulp_ctx, BNXT_ULP_REGULAR_FLOW_TABLE);\n \n-\tbp->ulp_ctx = rte_zmalloc(\"bnxt_ulp_ctx\",\n-\t\t\t\t  sizeof(struct bnxt_ulp_context), 0);\n-\tif (!bp->ulp_ctx) {\n-\t\tBNXT_TF_DBG(ERR, \"Failed to allocate ulp ctx\\n\");\n-\t\tulp_session_deinit(session);\n-\t\treturn -ENOMEM;\n-\t}\n+\t/* cleanup the eem table scope */\n+\tulp_eem_tbl_scope_deinit(bp, bp->ulp_ctx);\n \n-\t/*\n-\t * If ULP is already initialized for a specific domain then simply\n-\t * assign the ulp context to this rte_eth_dev.\n-\t */\n-\tif (init) {\n-\t\trc = ulp_ctx_attach(bp->ulp_ctx, session);\n-\t\tif (rc) {\n-\t\t\tBNXT_TF_DBG(ERR,\n-\t\t\t\t    \"Failed to attach the ulp context\\n\");\n-\t\t\tulp_session_deinit(session);\n-\t\t\trte_free(bp->ulp_ctx);\n-\t\t\treturn rc;\n-\t\t}\n+\t/* cleanup the flow database */\n+\tulp_flow_db_deinit(bp->ulp_ctx);\n \n-\t\t/* Update bnxt driver flags */\n-\t\trc = ulp_dparms_dev_port_intf_update(bp, bp->ulp_ctx);\n-\t\tif (rc) {\n-\t\t\tBNXT_TF_DBG(ERR, \"Failed to update driver flags\\n\");\n-\t\t\tulp_ctx_detach(bp, session);\n-\t\t\tulp_session_deinit(session);\n-\t\t\trte_free(bp->ulp_ctx);\n-\t\t\treturn rc;\n-\t\t}\n+\t/* Delete the Mark database */\n+\tulp_mark_db_deinit(bp->ulp_ctx);\n \n-\t\t/* update the port database */\n-\t\trc = ulp_port_db_dev_port_intf_update(bp->ulp_ctx, bp->eth_dev);\n-\t\tif (rc) {\n-\t\t\tBNXT_TF_DBG(ERR,\n-\t\t\t\t    \"Failed to update port database\\n\");\n-\t\t\tulp_ctx_detach(bp, session);\n-\t\t\tulp_session_deinit(session);\n-\t\t\trte_free(bp->ulp_ctx);\n-\t\t}\n-\t\treturn rc;\n-\t}\n+\t/* cleanup the ulp mapper */\n+\tulp_mapper_deinit(bp->ulp_ctx);\n+\n+\t/* Delete the Flow Counter Manager */\n+\tulp_fc_mgr_deinit(bp->ulp_ctx);\n+\n+\t/* Delete the Port database */\n+\tulp_port_db_deinit(bp->ulp_ctx);\n+\n+\t/* Disable NAT feature */\n+\t(void)bnxt_ulp_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP,\n+\t\t\t\t\t TF_TUNNEL_ENCAP_NAT,\n+\t\t\t\t\t (BNXT_ULP_NAT_INNER_L2_HEADER_SMAC |\n+\t\t\t\t\t  BNXT_ULP_NAT_INNER_L2_HEADER_DMAC),\n+\t\t\t\t\t 0);\n+\n+\t(void)bnxt_ulp_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP,\n+\t\t\t\t\t TF_TUNNEL_ENCAP_NAT,\n+\t\t\t\t\t (BNXT_ULP_NAT_INNER_L2_HEADER_SMAC |\n+\t\t\t\t\t  BNXT_ULP_NAT_INNER_L2_HEADER_DMAC),\n+\t\t\t\t\t 0);\n+\n+\t/* Delete the ulp context and tf session and free the ulp context */\n+\tulp_ctx_deinit(bp, session);\n+\tBNXT_TF_DBG(DEBUG, \"ulp ctx has been deinitialized\\n\");\n+}\n+\n+/*\n+ * When a port is initialized by dpdk. This functions is called\n+ * and this function initializes the ULP context and rest of the\n+ * infrastructure associated with it.\n+ */\n+static int32_t\n+bnxt_ulp_init(struct bnxt *bp,\n+\t      struct bnxt_ulp_session_state *session)\n+{\n+\tint rc;\n \n \t/* Allocate and Initialize the ulp context. */\n \trc = ulp_ctx_init(bp, session);\n@@ -727,25 +748,15 @@ bnxt_ulp_init(struct bnxt *bp)\n \n \t/* Initialize ulp dparms with values devargs passed */\n \trc = ulp_dparms_init(bp, bp->ulp_ctx);\n-\n-\t/* create the port database */\n-\trc = ulp_port_db_init(bp->ulp_ctx, bp->port_cnt);\n-\tif (rc) {\n-\t\tBNXT_TF_DBG(ERR, \"Failed to create the port database\\n\");\n-\t\tgoto jump_to_error;\n-\t}\n-\n-\t/* Update bnxt driver flags */\n-\trc = ulp_dparms_dev_port_intf_update(bp, bp->ulp_ctx);\n \tif (rc) {\n-\t\tBNXT_TF_DBG(ERR, \"Failed to update driver flags\\n\");\n+\t\tBNXT_TF_DBG(ERR, \"Failed to initialize the dparms\\n\");\n \t\tgoto jump_to_error;\n \t}\n \n-\t/* update the port database */\n-\trc = ulp_port_db_dev_port_intf_update(bp->ulp_ctx, bp->eth_dev);\n+\t/* create the port database */\n+\trc = ulp_port_db_init(bp->ulp_ctx, bp->port_cnt);\n \tif (rc) {\n-\t\tBNXT_TF_DBG(ERR, \"Failed to update port database\\n\");\n+\t\tBNXT_TF_DBG(ERR, \"Failed to create the port database\\n\");\n \t\tgoto jump_to_error;\n \t}\n \n@@ -804,32 +815,131 @@ bnxt_ulp_init(struct bnxt *bp)\n \t\tBNXT_TF_DBG(ERR, \"Failed to set tx global configuration\\n\");\n \t\tgoto jump_to_error;\n \t}\n-\n+\tBNXT_TF_DBG(DEBUG, \"ulp ctx has been initialized\\n\");\n \treturn rc;\n \n jump_to_error:\n-\tbnxt_ulp_deinit(bp);\n-\treturn -ENOMEM;\n+\tbnxt_ulp_deinit(bp, session);\n+\treturn rc;\n }\n \n-/* Below are the access functions to access internal data of ulp context. */\n+/*\n+ * When a port is initialized by dpdk. This functions sets up\n+ * the port specific details.\n+ */\n+int32_t\n+bnxt_ulp_port_init(struct bnxt *bp)\n+{\n+\tstruct bnxt_ulp_session_state *session;\n+\tbool initialized;\n+\tint32_t rc = 0;\n+\n+\tif (!bp || !BNXT_TRUFLOW_EN(bp))\n+\t\treturn rc;\n+\n+\tif (!BNXT_PF(bp) && !BNXT_VF_IS_TRUSTED(bp)) {\n+\t\tBNXT_TF_DBG(ERR,\n+\t\t\t    \"Skip ulp init for port: %d, not a TVF or PF\\n\",\n+\t\t\tbp->eth_dev->data->port_id);\n+\t\treturn rc;\n+\t}\n+\n+\tif (bp->ulp_ctx) {\n+\t\tBNXT_TF_DBG(DEBUG, \"ulp ctx already allocated\\n\");\n+\t\treturn rc;\n+\t}\n+\n+\tbp->ulp_ctx = rte_zmalloc(\"bnxt_ulp_ctx\",\n+\t\t\t\t  sizeof(struct bnxt_ulp_context), 0);\n+\tif (!bp->ulp_ctx) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to allocate ulp ctx\\n\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\t/*\n+\t * Multiple uplink ports can be associated with a single vswitch.\n+\t * Make sure only the port that is started first will initialize\n+\t * the TF session.\n+\t */\n+\tsession = ulp_session_init(bp, &initialized);\n+\tif (!session) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to initialize the tf session\\n\");\n+\t\trc = -EIO;\n+\t\tgoto jump_to_error;\n+\t}\n+\n+\tif (initialized) {\n+\t\t/*\n+\t\t * If ULP is already initialized for a specific domain then\n+\t\t * simply assign the ulp context to this rte_eth_dev.\n+\t\t */\n+\t\trc = ulp_ctx_attach(bp, session);\n+\t\tif (rc) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Failed to attach the ulp context\\n\");\n+\t\t\tgoto jump_to_error;\n+\t\t}\n+\t} else {\n+\t\trc = bnxt_ulp_init(bp, session);\n+\t\tif (rc) {\n+\t\t\tBNXT_TF_DBG(ERR, \"Failed to initialize the ulp init\\n\");\n+\t\t\tgoto jump_to_error;\n+\t\t}\n+\t}\n+\n+\t/* Update bnxt driver flags */\n+\trc = ulp_dparms_dev_port_intf_update(bp, bp->ulp_ctx);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to update driver flags\\n\");\n+\t\tgoto jump_to_error;\n+\t}\n+\n+\t/* update the port database for the given interface */\n+\trc = ulp_port_db_dev_port_intf_update(bp->ulp_ctx, bp->eth_dev);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to update port database\\n\");\n+\t\tgoto jump_to_error;\n+\t}\n+\t/* create the default rules */\n+\tbnxt_ulp_create_df_rules(bp);\n+\tBNXT_TF_DBG(DEBUG, \"ULP Port:%d created and initialized\\n\",\n+\t\t    bp->eth_dev->data->port_id);\n+\treturn rc;\n+\n+jump_to_error:\n+\tbnxt_ulp_port_deinit(bp);\n+\treturn rc;\n+}\n \n /*\n- * When a port is deinit'ed by dpdk. This function is called\n- * and this function clears the ULP context and rest of the\n- * infrastructure associated with it.\n+ * When a port is de-initialized by dpdk. This functions clears up\n+ * the port specific details.\n  */\n void\n-bnxt_ulp_deinit(struct bnxt *bp)\n+bnxt_ulp_port_deinit(struct bnxt *bp)\n {\n-\tstruct bnxt_ulp_session_state\t*session;\n-\tstruct rte_pci_device\t\t*pci_dev;\n-\tstruct rte_pci_addr\t\t*pci_addr;\n+\tstruct bnxt_ulp_session_state *session;\n+\tstruct rte_pci_device *pci_dev;\n+\tstruct rte_pci_addr *pci_addr;\n \n \tif (!BNXT_TRUFLOW_EN(bp))\n \t\treturn;\n \n-\t/* Get the session first */\n+\tif (!BNXT_PF(bp) && !BNXT_VF_IS_TRUSTED(bp)) {\n+\t\tBNXT_TF_DBG(ERR,\n+\t\t\t    \"Skip ULP deinit port:%d, not a TVF or PF\\n\",\n+\t\t\t    bp->eth_dev->data->port_id);\n+\t\treturn;\n+\t}\n+\n+\tif (!bp->ulp_ctx) {\n+\t\tBNXT_TF_DBG(DEBUG, \"ulp ctx already de-allocated\\n\");\n+\t\treturn;\n+\t}\n+\n+\tBNXT_TF_DBG(DEBUG, \"ULP Port:%d destroyed\\n\",\n+\t\t    bp->eth_dev->data->port_id);\n+\n+\t/* Get the session details  */\n \tpci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);\n \tpci_addr = &pci_dev->addr;\n \tpthread_mutex_lock(&bnxt_ulp_global_mutex);\n@@ -837,57 +947,42 @@ bnxt_ulp_deinit(struct bnxt *bp)\n \tpthread_mutex_unlock(&bnxt_ulp_global_mutex);\n \n \t/* session not found then just exit */\n-\tif (!session)\n+\tif (!session) {\n+\t\t/* Free the ulp context */\n+\t\trte_free(bp->ulp_ctx);\n+\t\tbp->ulp_ctx = NULL;\n \t\treturn;\n+\t}\n \n-\t/* clean up default flows */\n-\tbnxt_ulp_destroy_df_rules(bp, true);\n-\n-\t/* clean up regular flows */\n-\tulp_flow_db_flush_flows(bp->ulp_ctx, BNXT_ULP_REGULAR_FLOW_TABLE);\n-\n-\t/* cleanup the eem table scope */\n-\tulp_eem_tbl_scope_deinit(bp, bp->ulp_ctx);\n-\n-\t/* cleanup the flow database */\n-\tulp_flow_db_deinit(bp->ulp_ctx);\n-\n-\t/* Delete the Mark database */\n-\tulp_mark_db_deinit(bp->ulp_ctx);\n-\n-\t/* cleanup the ulp mapper */\n-\tulp_mapper_deinit(bp->ulp_ctx);\n-\n-\t/* Delete the Flow Counter Manager */\n-\tulp_fc_mgr_deinit(bp->ulp_ctx);\n-\n-\t/* Delete the Port database */\n-\tulp_port_db_deinit(bp->ulp_ctx);\n-\n-\t/* Disable NAT feature */\n-\t(void)bnxt_ulp_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP,\n-\t\t\t\t\t TF_TUNNEL_ENCAP_NAT,\n-\t\t\t\t\t (BNXT_ULP_NAT_INNER_L2_HEADER_SMAC |\n-\t\t\t\t\t  BNXT_ULP_NAT_INNER_L2_HEADER_DMAC),\n-\t\t\t\t\t 0);\n+\t/* Check the reference count to deinit or deattach*/\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 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+\t\t\tbnxt_ulp_destroy_vfr_default_rules(bp, false);\n \n-\t(void)bnxt_ulp_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP,\n-\t\t\t\t\t TF_TUNNEL_ENCAP_NAT,\n-\t\t\t\t\t (BNXT_ULP_NAT_INNER_L2_HEADER_SMAC |\n-\t\t\t\t\t  BNXT_ULP_NAT_INNER_L2_HEADER_DMAC),\n-\t\t\t\t\t 0);\n+\t\t\t/* free flows associated with this port */\n+\t\t\tbnxt_ulp_flush_port_flows(bp);\n \n-\t/* Delete the ulp context and tf session */\n-\tulp_ctx_detach(bp, session);\n+\t\t\t/* close the session associated with this port */\n+\t\t\tulp_ctx_detach(bp);\n+\t\t} else {\n+\t\t\t/* Perform ulp ctx deinit */\n+\t\t\tbnxt_ulp_deinit(bp, session);\n+\t\t}\n+\t}\n \n-\t/* Finally delete the bnxt session*/\n+\t/* clean up the session */\n \tulp_session_deinit(session);\n \n+\t/* Free the ulp context */\n \trte_free(bp->ulp_ctx);\n-\n \tbp->ulp_ctx = NULL;\n }\n \n+/* Below are the access functions to access internal data of ulp context. */\n /* Function to set the Mark DB into the context */\n int32_t\n bnxt_ulp_cntxt_ptr2_mark_db_set(struct bnxt_ulp_context *ulp_ctx,\n@@ -974,7 +1069,6 @@ bnxt_ulp_cntxt_tfp_set(struct bnxt_ulp_context *ulp, struct tf *tfp)\n \t\treturn -EINVAL;\n \t}\n \n-\t/* TBD The tfp should be removed once tf_attach is implemented. */\n \tulp->g_tfp = tfp;\n \treturn 0;\n }\n@@ -987,7 +1081,6 @@ bnxt_ulp_cntxt_tfp_get(struct bnxt_ulp_context *ulp)\n \t\tBNXT_TF_DBG(ERR, \"Invalid arguments\\n\");\n \t\treturn NULL;\n \t}\n-\t/* TBD The tfp should be removed once tf_attach is implemented. */\n \treturn ulp->g_tfp;\n }\n \n@@ -1129,3 +1222,14 @@ bnxt_ulp_cntxt_ptr2_ulp_flags_get(struct bnxt_ulp_context *ulp_ctx,\n \t*flags =  ulp_ctx->cfg_data->ulp_flags;\n \treturn 0;\n }\n+\n+/* Function to get the ulp vfr info from the ulp context. */\n+struct bnxt_ulp_vfr_rule_info*\n+bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(struct bnxt_ulp_context *ulp_ctx,\n+\t\t\t\t     uint32_t port_id)\n+{\n+\tif (!ulp_ctx || !ulp_ctx->cfg_data || port_id >= RTE_MAX_ETHPORTS)\n+\t\treturn NULL;\n+\n+\treturn &ulp_ctx->cfg_data->vfr_rule_info[port_id];\n+}\ndiff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.h b/drivers/net/bnxt/tf_ulp/bnxt_ulp.h\nindex d53245215..8a2825ae5 100644\n--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.h\n+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.h\n@@ -28,6 +28,13 @@ struct bnxt_ulp_df_rule_info {\n \tuint8_t\t\t\t\tvalid;\n };\n \n+struct bnxt_ulp_vfr_rule_info {\n+\tuint32_t\t\t\trep2vf_flow_id;\n+\tuint32_t\t\t\tvf2rep_flow_id;\n+\tuint16_t\t\t\tparent_port_id;\n+\tuint8_t\t\t\t\tvalid;\n+};\n+\n struct bnxt_ulp_data {\n \tuint32_t\t\t\ttbl_scope_id;\n \tstruct bnxt_ulp_mark_tbl\t*mark_tbl;\n@@ -38,12 +45,12 @@ struct bnxt_ulp_data {\n \tstruct bnxt_ulp_port_db\t\t*port_db;\n \tstruct bnxt_ulp_fc_info\t\t*fc_info;\n \tuint32_t\t\t\tulp_flags;\n-\tstruct bnxt_ulp_df_rule_info   df_rule_info[RTE_MAX_ETHPORTS];\n+\tstruct bnxt_ulp_df_rule_info\tdf_rule_info[RTE_MAX_ETHPORTS];\n+\tstruct bnxt_ulp_vfr_rule_info\tvfr_rule_info[RTE_MAX_ETHPORTS];\n };\n \n struct bnxt_ulp_context {\n \tstruct bnxt_ulp_data\t*cfg_data;\n-\t/* TBD The tfp should be removed once tf_attach is implemented. */\n \tstruct tf\t\t*g_tfp;\n };\n \n@@ -58,7 +65,6 @@ struct bnxt_ulp_session_state {\n \tpthread_mutex_t\t\t\t\tbnxt_ulp_mutex;\n \tstruct bnxt_ulp_pci_info\t\tpci_info;\n \tstruct bnxt_ulp_data\t\t\t*cfg_data;\n-\t/* TBD The tfp should be removed once tf_attach is implemented. */\n \tstruct tf\t\t\t\t*g_tfp;\n \tuint32_t\t\t\t\tsession_opened;\n };\n@@ -183,4 +189,8 @@ int32_t\n bnxt_ulp_get_df_rule_info(uint8_t port_id, struct bnxt_ulp_context *ulp_ctx,\n \t\t\t  struct bnxt_ulp_df_rule_info *info);\n \n+struct bnxt_ulp_vfr_rule_info*\n+bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(struct bnxt_ulp_context *ulp_ctx,\n+\t\t\t\t     uint32_t port_id);\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 89fffcf01..2ab00453a 100644\n--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c\n+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c\n@@ -87,19 +87,19 @@ bnxt_ulp_flow_create(struct rte_eth_dev *dev,\n \tuint32_t class_id, act_tmpl;\n \tstruct rte_flow *flow_id;\n \tuint32_t fid;\n-\tint ret;\n+\tint ret = BNXT_TF_RC_ERROR;\n \n \tif (bnxt_ulp_flow_validate_args(attr,\n \t\t\t\t\tpattern, actions,\n \t\t\t\t\terror) == BNXT_TF_RC_ERROR) {\n \t\tBNXT_TF_DBG(ERR, \"Invalid arguments being passed\\n\");\n-\t\treturn NULL;\n+\t\tgoto parse_error;\n \t}\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\treturn NULL;\n+\t\tgoto parse_error;\n \t}\n \n \t/* Initialize the parser params */\n@@ -173,20 +173,20 @@ bnxt_ulp_flow_validate(struct rte_eth_dev *dev,\n {\n \tstruct ulp_rte_parser_params\t\tparams;\n \tuint32_t class_id, act_tmpl;\n-\tint ret;\n+\tint ret = BNXT_TF_RC_ERROR;\n \tstruct bnxt_ulp_context *ulp_ctx;\n \n \tif (bnxt_ulp_flow_validate_args(attr,\n \t\t\t\t\tpattern, actions,\n \t\t\t\t\terror) == BNXT_TF_RC_ERROR) {\n \t\tBNXT_TF_DBG(ERR, \"Invalid arguments being passed\\n\");\n-\t\treturn -EINVAL;\n+\t\tgoto parse_error;\n \t}\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\treturn -EINVAL;\n+\t\tgoto parse_error;\n \t}\n \n \t/* Initialize the parser params */\n@@ -289,11 +289,8 @@ bnxt_ulp_flow_flush(struct rte_eth_dev *eth_dev,\n \n \tulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);\n \tif (!ulp_ctx) {\n-\t\tBNXT_TF_DBG(ERR, \"ULP context is not initialized\\n\");\n-\t\trte_flow_error_set(error, EINVAL,\n-\t\t\t\t   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,\n-\t\t\t\t   \"Failed to flush flow.\");\n-\t\treturn -EINVAL;\n+\t\tBNXT_TF_DBG(DEBUG, \"ULP context is not initialized\\n\");\n+\t\treturn ret;\n \t}\n \tbp = eth_dev->data->dev_private;\n \ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_def_rules.c b/drivers/net/bnxt/tf_ulp/ulp_def_rules.c\nindex 46acc1d65..2d0c3bccc 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_def_rules.c\n+++ b/drivers/net/bnxt/tf_ulp/ulp_def_rules.c\n@@ -377,7 +377,7 @@ int32_t\n ulp_default_flow_destroy(struct rte_eth_dev *eth_dev, uint32_t flow_id)\n {\n \tstruct bnxt_ulp_context *ulp_ctx;\n-\tint rc;\n+\tint rc = 0;\n \n \tulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);\n \tif (!ulp_ctx) {\n@@ -385,6 +385,11 @@ ulp_default_flow_destroy(struct rte_eth_dev *eth_dev, uint32_t flow_id)\n \t\treturn -EINVAL;\n \t}\n \n+\tif (!flow_id) {\n+\t\tBNXT_TF_DBG(DEBUG, \"invalid flow id zero\\n\");\n+\t\treturn rc;\n+\t}\n+\n \trc = ulp_mapper_flow_destroy(ulp_ctx, flow_id,\n \t\t\t\t     BNXT_ULP_DEFAULT_FLOW_TABLE);\n \tif (rc)\n@@ -417,7 +422,7 @@ bnxt_ulp_destroy_df_rules(struct bnxt *bp, bool global)\n \t\t\t\t\t info->port_to_app_flow_id);\n \t\tulp_default_flow_destroy(bp->eth_dev,\n \t\t\t\t\t info->app_to_port_flow_id);\n-\t\tinfo->valid = false;\n+\t\tmemset(info, 0, sizeof(struct bnxt_ulp_df_rule_info));\n \t\treturn;\n \t}\n \n@@ -431,7 +436,7 @@ bnxt_ulp_destroy_df_rules(struct bnxt *bp, bool global)\n \t\t\t\t\t info->port_to_app_flow_id);\n \t\tulp_default_flow_destroy(bp->eth_dev,\n \t\t\t\t\t info->app_to_port_flow_id);\n-\t\tinfo->valid = false;\n+\t\tmemset(info, 0, sizeof(struct bnxt_ulp_df_rule_info));\n \t}\n }\n \n@@ -470,22 +475,19 @@ bnxt_ulp_create_df_rules(struct bnxt *bp)\n \n \tport_id = bp->eth_dev->data->port_id;\n \tinfo = &bp->ulp_ctx->cfg_data->df_rule_info[port_id];\n-\tBNXT_TF_DBG(INFO, \"*** creating port to app default rule ***\\n\");\n \trc = bnxt_create_port_app_df_rule(bp, BNXT_ULP_DF_TPL_PORT_TO_VS,\n \t\t\t\t\t  &info->port_to_app_flow_id);\n \tif (rc) {\n-\t\tPMD_DRV_LOG(ERR,\n+\t\tBNXT_TF_DBG(ERR,\n \t\t\t    \"Failed to create port to app default rule\\n\");\n \t\treturn rc;\n \t}\n-\tBNXT_TF_DBG(INFO, \"*** created port to app default rule ***\\n\");\n \n \tbp->tx_cfa_action = 0;\n-\tBNXT_TF_DBG(INFO, \"*** creating app to port default rule ***\\n\");\n \trc = bnxt_create_port_app_df_rule(bp, BNXT_ULP_DF_TPL_VS_TO_PORT,\n \t\t\t\t\t  &info->app_to_port_flow_id);\n \tif (rc) {\n-\t\tPMD_DRV_LOG(ERR,\n+\t\tBNXT_TF_DBG(ERR,\n \t\t\t    \"Failed to create app to port default rule\\n\");\n \t\tgoto port_to_app_free;\n \t}\n@@ -497,7 +499,6 @@ bnxt_ulp_create_df_rules(struct bnxt *bp)\n \t\tgoto app_to_port_free;\n \n \tinfo->valid = true;\n-\tBNXT_TF_DBG(INFO, \"*** created app to port default rule ***\\n\");\n \treturn 0;\n \n app_to_port_free:\n@@ -508,3 +509,115 @@ bnxt_ulp_create_df_rules(struct bnxt *bp)\n \n \treturn rc;\n }\n+\n+static int32_t\n+bnxt_create_port_vfr_default_rule(struct bnxt *bp,\n+\t\t\t\t  uint8_t flow_type,\n+\t\t\t\t  uint16_t vfr_port_id,\n+\t\t\t\t  uint32_t *flow_id)\n+{\n+\tstruct ulp_tlv_param param_list[] = {\n+\t\t{\n+\t\t\t.type = BNXT_ULP_DF_PARAM_TYPE_DEV_PORT_ID,\n+\t\t\t.length = 2,\n+\t\t\t.value = {(vfr_port_id >> 8) & 0xff, vfr_port_id & 0xff}\n+\t\t},\n+\t\t{\n+\t\t\t.type = BNXT_ULP_DF_PARAM_TYPE_LAST,\n+\t\t\t.length = 0,\n+\t\t\t.value = {0}\n+\t\t}\n+\t};\n+\treturn ulp_default_flow_create(bp->eth_dev, param_list, flow_type,\n+\t\t\t\t       flow_id);\n+}\n+\n+int32_t\n+bnxt_ulp_create_vfr_default_rules(struct rte_eth_dev *vfr_ethdev)\n+{\n+\tstruct bnxt_ulp_vfr_rule_info *info;\n+\tstruct bnxt_vf_representor *vfr = vfr_ethdev->data->dev_private;\n+\tstruct rte_eth_dev *parent_dev = vfr->parent_dev;\n+\tstruct bnxt *bp = parent_dev->data->dev_private;\n+\tuint16_t vfr_port_id = vfr_ethdev->data->port_id;\n+\tuint8_t port_id;\n+\tint rc;\n+\n+\tif (!bp || !BNXT_TRUFLOW_EN(bp))\n+\t\treturn 0;\n+\n+\tport_id = vfr_ethdev->data->port_id;\n+\tinfo = bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(bp->ulp_ctx, port_id);\n+\n+\tif (!info) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to get vfr ulp context\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (info->valid) {\n+\t\tBNXT_TF_DBG(ERR, \"VFR already allocated\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));\n+\trc = bnxt_create_port_vfr_default_rule(bp, BNXT_ULP_DF_TPL_VFREP_TO_VF,\n+\t\t\t\t\t       vfr_port_id,\n+\t\t\t\t\t       &info->rep2vf_flow_id);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to create VFREP to VF default rule\\n\");\n+\t\tgoto error;\n+\t}\n+\trc = bnxt_create_port_vfr_default_rule(bp, BNXT_ULP_DF_TPL_VF_TO_VFREP,\n+\t\t\t\t\t       vfr_port_id,\n+\t\t\t\t\t       &info->vf2rep_flow_id);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to create VF to VFREP default rule\\n\");\n+\t\tgoto error;\n+\t}\n+\trc = ulp_default_flow_db_cfa_action_get(bp->ulp_ctx,\n+\t\t\t\t\t\tinfo->rep2vf_flow_id,\n+\t\t\t\t\t\t&vfr->vfr_tx_cfa_action);\n+\tif (rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to get the tx cfa action\\n\");\n+\t\tgoto error;\n+\t}\n+\n+\t/* Update the other details */\n+\tinfo->valid = true;\n+\tinfo->parent_port_id =  bp->eth_dev->data->port_id;\n+\treturn 0;\n+\n+error:\n+\tif (info->rep2vf_flow_id)\n+\t\tulp_default_flow_destroy(bp->eth_dev, info->rep2vf_flow_id);\n+\tif (info->vf2rep_flow_id)\n+\t\tulp_default_flow_destroy(bp->eth_dev, info->vf2rep_flow_id);\n+\treturn rc;\n+}\n+\n+int32_t\n+bnxt_ulp_delete_vfr_default_rules(struct bnxt_vf_representor *vfr)\n+{\n+\tstruct bnxt_ulp_vfr_rule_info *info;\n+\tstruct rte_eth_dev *parent_dev = vfr->parent_dev;\n+\tstruct bnxt *bp = parent_dev->data->dev_private;\n+\n+\tif (!bp || !BNXT_TRUFLOW_EN(bp))\n+\t\treturn 0;\n+\tinfo = bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(bp->ulp_ctx,\n+\t\t\t\t\t\t    vfr->dpdk_port_id);\n+\tif (!info) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed to get vfr ulp context\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!info->valid) {\n+\t\tBNXT_TF_DBG(ERR, \"VFR already freed\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\tulp_default_flow_destroy(bp->eth_dev, info->rep2vf_flow_id);\n+\tulp_default_flow_destroy(bp->eth_dev, info->vf2rep_flow_id);\n+\tvfr->vfr_tx_cfa_action = 0;\n+\tmemset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));\n+\treturn 0;\n+}\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_flow_db.c b/drivers/net/bnxt/tf_ulp/ulp_flow_db.c\nindex 714451740..cbdf5df68 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_flow_db.c\n+++ b/drivers/net/bnxt/tf_ulp/ulp_flow_db.c\n@@ -351,10 +351,8 @@ int32_t\tulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt)\n \tstruct bnxt_ulp_flow_db\t\t\t*flow_db;\n \n \tflow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);\n-\tif (!flow_db) {\n-\t\tBNXT_TF_DBG(ERR, \"Invalid Arguments\\n\");\n+\tif (!flow_db)\n \t\treturn -EINVAL;\n-\t}\n \n \t/* Detach the flow database from the ulp context. */\n \tbnxt_ulp_cntxt_ptr2_flow_db_set(ulp_ctxt, NULL);\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_flow_db.h b/drivers/net/bnxt/tf_ulp/ulp_flow_db.h\nindex 117e250d6..8c83664d0 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_flow_db.h\n+++ b/drivers/net/bnxt/tf_ulp/ulp_flow_db.h\n@@ -9,8 +9,8 @@\n #include \"bnxt_ulp.h\"\n #include \"ulp_template_db_enum.h\"\n \n-#define BNXT_FLOW_DB_DEFAULT_NUM_FLOWS\t\t128\n-#define BNXT_FLOW_DB_DEFAULT_NUM_RESOURCES\t5\n+#define BNXT_FLOW_DB_DEFAULT_NUM_FLOWS\t\t512\n+#define BNXT_FLOW_DB_DEFAULT_NUM_RESOURCES\t8\n \n /*\n  * Structure for the flow database resource information\n",
    "prefixes": [
        "01/25"
    ]
}