get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 92602,
    "url": "https://patches.dpdk.org/api/patches/92602/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1619895841-7467-14-git-send-email-timothy.mcdaniel@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1619895841-7467-14-git-send-email-timothy.mcdaniel@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1619895841-7467-14-git-send-email-timothy.mcdaniel@intel.com",
    "date": "2021-05-01T19:03:48",
    "name": "[v5,13/26] event/dlb2: add v2.5 unmap queue",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "31228fe9503085ef2244a4afc5f3da3c4c99f9b8",
    "submitter": {
        "id": 826,
        "url": "https://patches.dpdk.org/api/people/826/?format=api",
        "name": "Timothy McDaniel",
        "email": "timothy.mcdaniel@intel.com"
    },
    "delegate": {
        "id": 310,
        "url": "https://patches.dpdk.org/api/users/310/?format=api",
        "username": "jerin",
        "first_name": "Jerin",
        "last_name": "Jacob",
        "email": "jerinj@marvell.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1619895841-7467-14-git-send-email-timothy.mcdaniel@intel.com/mbox/",
    "series": [
        {
            "id": 16784,
            "url": "https://patches.dpdk.org/api/series/16784/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=16784",
            "date": "2021-05-01T19:03:37",
            "name": "Add DLB v2.5",
            "version": 5,
            "mbox": "https://patches.dpdk.org/series/16784/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/92602/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/92602/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 29CCCA0546;\n\tSat,  1 May 2021 21:07:19 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id BAB82411BB;\n\tSat,  1 May 2021 21:05:53 +0200 (CEST)",
            "from mga05.intel.com (mga05.intel.com [192.55.52.43])\n by mails.dpdk.org (Postfix) with ESMTP id C5C504110A\n for <dev@dpdk.org>; Sat,  1 May 2021 21:05:37 +0200 (CEST)",
            "from fmsmga002.fm.intel.com ([10.253.24.26])\n by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 01 May 2021 12:05:36 -0700",
            "from txasoft-yocto.an.intel.com ([10.123.72.192])\n by fmsmga002.fm.intel.com with ESMTP; 01 May 2021 12:05:35 -0700"
        ],
        "IronPort-SDR": [
            "\n uuyYFR8UcVwqgooPm0mhnyxFLL/h9byQY23eJ5YGqphFROx+YZ8hBqhYoYDo/b73CkvXon7Qmo\n j230m6D4BRFA==",
            "\n 7D7AZzMRwBng+gpM18YQcZq5nY/aSHco8E+838nFwBvATudLIgozZEOz6eTwFK4q/klrtxIGdU\n O4JOhGQmC2lA=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6200,9189,9971\"; a=\"282865189\"",
            "E=Sophos;i=\"5.82,266,1613462400\"; d=\"scan'208\";a=\"282865189\"",
            "E=Sophos;i=\"5.82,266,1613462400\"; d=\"scan'208\";a=\"460767053\""
        ],
        "X-ExtLoop1": "1",
        "From": "\"McDaniel, Timothy\" <timothy.mcdaniel@intel.com>",
        "To": "",
        "Cc": "dev@dpdk.org, erik.g.carrillo@intel.com, harry.van.haaren@intel.com,\n jerinj@marvell.com, thomas@monjalon.net,\n Timothy McDaniel <timothy.mcdaniel@intel.com>",
        "Date": "Sat,  1 May 2021 14:03:48 -0500",
        "Message-Id": "<1619895841-7467-14-git-send-email-timothy.mcdaniel@intel.com>",
        "X-Mailer": "git-send-email 1.7.10",
        "In-Reply-To": "<1619895841-7467-1-git-send-email-timothy.mcdaniel@intel.com>",
        "References": "<20210316221857.2254-2-timothy.mcdaniel@intel.com>\n <1619895841-7467-1-git-send-email-timothy.mcdaniel@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v5 13/26] event/dlb2: add v2.5 unmap queue",
        "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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Timothy McDaniel <timothy.mcdaniel@intel.com>\n\nUpdate the low level HW functions responsible for\nremoving the linkage between a queue and a load\nbalanced port. Runtime checks are performed on the\nport and queue to make sure the state is appropriate\nfor the unmap operation, and the unmap arguments\nare also validated.\n\nThe logic is very similar to what was done for v2.0,\nbut the new combined register map for v2.0 and v2.5\nuses new register names and bit names.  Additionally,\nnew register access macros are used so that the code\ncan perform the correct action, based on the hardware.\n\nSigned-off-by: Timothy McDaniel <timothy.mcdaniel@intel.com>\n---\n drivers/event/dlb2/pf/base/dlb2_resource.c    | 331 ------------------\n .../event/dlb2/pf/base/dlb2_resource_new.c    | 298 ++++++++++++++++\n 2 files changed, 298 insertions(+), 331 deletions(-)",
    "diff": "diff --git a/drivers/event/dlb2/pf/base/dlb2_resource.c b/drivers/event/dlb2/pf/base/dlb2_resource.c\nindex d59df5e39..ab5b080c1 100644\n--- a/drivers/event/dlb2/pf/base/dlb2_resource.c\n+++ b/drivers/event/dlb2/pf/base/dlb2_resource.c\n@@ -1225,26 +1225,6 @@ dlb2_get_domain_used_dir_pq(struct dlb2_hw *hw,\n \treturn NULL;\n }\n \n-static bool\n-dlb2_port_find_slot_with_pending_map_queue(struct dlb2_ldb_port *port,\n-\t\t\t\t\t   struct dlb2_ldb_queue *queue,\n-\t\t\t\t\t   int *slot)\n-{\n-\tint i;\n-\n-\tfor (i = 0; i < DLB2_MAX_NUM_QIDS_PER_LDB_CQ; i++) {\n-\t\tstruct dlb2_ldb_port_qid_map *map = &port->qid_map[i];\n-\n-\t\tif (map->state == DLB2_QUEUE_UNMAP_IN_PROG_PENDING_MAP &&\n-\t\t    map->pending_qid == queue->id.phys_id)\n-\t\t\tbreak;\n-\t}\n-\n-\t*slot = i;\n-\n-\treturn (i < DLB2_MAX_NUM_QIDS_PER_LDB_CQ);\n-}\n-\n static struct dlb2_ldb_queue *\n dlb2_get_domain_ldb_queue(u32 id,\n \t\t\t  bool vdev_req,\n@@ -1265,317 +1245,6 @@ dlb2_get_domain_ldb_queue(u32 id,\n \treturn NULL;\n }\n \n-static struct dlb2_ldb_port *\n-dlb2_get_domain_used_ldb_port(u32 id,\n-\t\t\t      bool vdev_req,\n-\t\t\t      struct dlb2_hw_domain *domain)\n-{\n-\tstruct dlb2_list_entry *iter;\n-\tstruct dlb2_ldb_port *port;\n-\tint i;\n-\tRTE_SET_USED(iter);\n-\n-\tif (id >= DLB2_MAX_NUM_LDB_PORTS)\n-\t\treturn NULL;\n-\n-\tfor (i = 0; i < DLB2_NUM_COS_DOMAINS; i++) {\n-\t\tDLB2_DOM_LIST_FOR(domain->used_ldb_ports[i], port, iter)\n-\t\t\tif ((!vdev_req && port->id.phys_id == id) ||\n-\t\t\t    (vdev_req && port->id.virt_id == id))\n-\t\t\t\treturn port;\n-\n-\t\tDLB2_DOM_LIST_FOR(domain->avail_ldb_ports[i], port, iter)\n-\t\t\tif ((!vdev_req && port->id.phys_id == id) ||\n-\t\t\t    (vdev_req && port->id.virt_id == id))\n-\t\t\t\treturn port;\n-\t}\n-\n-\treturn NULL;\n-}\n-\n-static void dlb2_log_unmap_qid(struct dlb2_hw *hw,\n-\t\t\t       u32 domain_id,\n-\t\t\t       struct dlb2_unmap_qid_args *args,\n-\t\t\t       bool vdev_req,\n-\t\t\t       unsigned int vdev_id)\n-{\n-\tDLB2_HW_DBG(hw, \"DLB2 unmap QID arguments:\\n\");\n-\tif (vdev_req)\n-\t\tDLB2_HW_DBG(hw, \"(Request from vdev %d)\\n\", vdev_id);\n-\tDLB2_HW_DBG(hw, \"\\tDomain ID: %d\\n\",\n-\t\t    domain_id);\n-\tDLB2_HW_DBG(hw, \"\\tPort ID:   %d\\n\",\n-\t\t    args->port_id);\n-\tDLB2_HW_DBG(hw, \"\\tQueue ID:  %d\\n\",\n-\t\t    args->qid);\n-\tif (args->qid < DLB2_MAX_NUM_LDB_QUEUES)\n-\t\tDLB2_HW_DBG(hw, \"\\tQueue's num mappings:  %d\\n\",\n-\t\t\t    hw->rsrcs.ldb_queues[args->qid].num_mappings);\n-}\n-\n-static int dlb2_verify_unmap_qid_args(struct dlb2_hw *hw,\n-\t\t\t\t      u32 domain_id,\n-\t\t\t\t      struct dlb2_unmap_qid_args *args,\n-\t\t\t\t      struct dlb2_cmd_response *resp,\n-\t\t\t\t      bool vdev_req,\n-\t\t\t\t      unsigned int vdev_id)\n-{\n-\tenum dlb2_qid_map_state state;\n-\tstruct dlb2_hw_domain *domain;\n-\tstruct dlb2_ldb_queue *queue;\n-\tstruct dlb2_ldb_port *port;\n-\tint slot;\n-\tint id;\n-\n-\tdomain = dlb2_get_domain_from_id(hw, domain_id, vdev_req, vdev_id);\n-\n-\tif (domain == NULL) {\n-\t\tresp->status = DLB2_ST_INVALID_DOMAIN_ID;\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tif (!domain->configured) {\n-\t\tresp->status = DLB2_ST_DOMAIN_NOT_CONFIGURED;\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tid = args->port_id;\n-\n-\tport = dlb2_get_domain_used_ldb_port(id, vdev_req, domain);\n-\n-\tif (port == NULL || !port->configured) {\n-\t\tresp->status = DLB2_ST_INVALID_PORT_ID;\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tif (port->domain_id.phys_id != domain->id.phys_id) {\n-\t\tresp->status = DLB2_ST_INVALID_PORT_ID;\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tqueue = dlb2_get_domain_ldb_queue(args->qid, vdev_req, domain);\n-\n-\tif (queue == NULL || !queue->configured) {\n-\t\tDLB2_HW_ERR(hw, \"[%s()] Can't unmap unconfigured queue %d\\n\",\n-\t\t\t    __func__, args->qid);\n-\t\tresp->status = DLB2_ST_INVALID_QID;\n-\t\treturn -EINVAL;\n-\t}\n-\n-\t/*\n-\t * Verify that the port has the queue mapped. From the application's\n-\t * perspective a queue is mapped if it is actually mapped, the map is\n-\t * in progress, or the map is blocked pending an unmap.\n-\t */\n-\tstate = DLB2_QUEUE_MAPPED;\n-\tif (dlb2_port_find_slot_queue(port, state, queue, &slot))\n-\t\treturn 0;\n-\n-\tstate = DLB2_QUEUE_MAP_IN_PROG;\n-\tif (dlb2_port_find_slot_queue(port, state, queue, &slot))\n-\t\treturn 0;\n-\n-\tif (dlb2_port_find_slot_with_pending_map_queue(port, queue, &slot))\n-\t\treturn 0;\n-\n-\tresp->status = DLB2_ST_INVALID_QID;\n-\treturn -EINVAL;\n-}\n-\n-int dlb2_hw_unmap_qid(struct dlb2_hw *hw,\n-\t\t      u32 domain_id,\n-\t\t      struct dlb2_unmap_qid_args *args,\n-\t\t      struct dlb2_cmd_response *resp,\n-\t\t      bool vdev_req,\n-\t\t      unsigned int vdev_id)\n-{\n-\tstruct dlb2_hw_domain *domain;\n-\tstruct dlb2_ldb_queue *queue;\n-\tenum dlb2_qid_map_state st;\n-\tstruct dlb2_ldb_port *port;\n-\tbool unmap_complete;\n-\tint i, ret, id;\n-\n-\tdlb2_log_unmap_qid(hw, domain_id, args, vdev_req, vdev_id);\n-\n-\t/*\n-\t * Verify that hardware resources are available before attempting to\n-\t * satisfy the request. This simplifies the error unwinding code.\n-\t */\n-\tret = dlb2_verify_unmap_qid_args(hw,\n-\t\t\t\t\t domain_id,\n-\t\t\t\t\t args,\n-\t\t\t\t\t resp,\n-\t\t\t\t\t vdev_req,\n-\t\t\t\t\t vdev_id);\n-\tif (ret)\n-\t\treturn ret;\n-\n-\tdomain = dlb2_get_domain_from_id(hw, domain_id, vdev_req, vdev_id);\n-\tif (domain == NULL) {\n-\t\tDLB2_HW_ERR(hw,\n-\t\t\t    \"[%s():%d] Internal error: domain not found\\n\",\n-\t\t\t    __func__, __LINE__);\n-\t\treturn -EFAULT;\n-\t}\n-\n-\tid = args->port_id;\n-\n-\tport = dlb2_get_domain_used_ldb_port(id, vdev_req, domain);\n-\tif (port == NULL) {\n-\t\tDLB2_HW_ERR(hw,\n-\t\t\t    \"[%s():%d] Internal error: port not found\\n\",\n-\t\t\t    __func__, __LINE__);\n-\t\treturn -EFAULT;\n-\t}\n-\n-\tqueue = dlb2_get_domain_ldb_queue(args->qid, vdev_req, domain);\n-\tif (queue == NULL) {\n-\t\tDLB2_HW_ERR(hw,\n-\t\t\t    \"[%s():%d] Internal error: queue not found\\n\",\n-\t\t\t    __func__, __LINE__);\n-\t\treturn -EFAULT;\n-\t}\n-\n-\t/*\n-\t * If the queue hasn't been mapped yet, we need to update the slot's\n-\t * state and re-enable the queue's inflights.\n-\t */\n-\tst = DLB2_QUEUE_MAP_IN_PROG;\n-\tif (dlb2_port_find_slot_queue(port, st, queue, &i)) {\n-\t\tif (i >= DLB2_MAX_NUM_QIDS_PER_LDB_CQ) {\n-\t\t\tDLB2_HW_ERR(hw,\n-\t\t\t\t    \"[%s():%d] Internal error: port slot tracking failed\\n\",\n-\t\t\t\t    __func__, __LINE__);\n-\t\t\treturn -EFAULT;\n-\t\t}\n-\n-\t\t/*\n-\t\t * Since the in-progress map was aborted, re-enable the QID's\n-\t\t * inflights.\n-\t\t */\n-\t\tif (queue->num_pending_additions == 0)\n-\t\t\tdlb2_ldb_queue_set_inflight_limit(hw, queue);\n-\n-\t\tst = DLB2_QUEUE_UNMAPPED;\n-\t\tret = dlb2_port_slot_state_transition(hw, port, queue, i, st);\n-\t\tif (ret)\n-\t\t\treturn ret;\n-\n-\t\tgoto unmap_qid_done;\n-\t}\n-\n-\t/*\n-\t * If the queue mapping is on hold pending an unmap, we simply need to\n-\t * update the slot's state.\n-\t */\n-\tif (dlb2_port_find_slot_with_pending_map_queue(port, queue, &i)) {\n-\t\tif (i >= DLB2_MAX_NUM_QIDS_PER_LDB_CQ) {\n-\t\t\tDLB2_HW_ERR(hw,\n-\t\t\t\t    \"[%s():%d] Internal error: port slot tracking failed\\n\",\n-\t\t\t\t    __func__, __LINE__);\n-\t\t\treturn -EFAULT;\n-\t\t}\n-\n-\t\tst = DLB2_QUEUE_UNMAP_IN_PROG;\n-\t\tret = dlb2_port_slot_state_transition(hw, port, queue, i, st);\n-\t\tif (ret)\n-\t\t\treturn ret;\n-\n-\t\tgoto unmap_qid_done;\n-\t}\n-\n-\tst = DLB2_QUEUE_MAPPED;\n-\tif (!dlb2_port_find_slot_queue(port, st, queue, &i)) {\n-\t\tDLB2_HW_ERR(hw,\n-\t\t\t    \"[%s()] Internal error: no available CQ slots\\n\",\n-\t\t\t    __func__);\n-\t\treturn -EFAULT;\n-\t}\n-\n-\tif (i >= DLB2_MAX_NUM_QIDS_PER_LDB_CQ) {\n-\t\tDLB2_HW_ERR(hw,\n-\t\t\t    \"[%s():%d] Internal error: port slot tracking failed\\n\",\n-\t\t\t    __func__, __LINE__);\n-\t\treturn -EFAULT;\n-\t}\n-\n-\t/*\n-\t * QID->CQ mapping removal is an asynchronous procedure. It requires\n-\t * stopping the DLB2 from scheduling this CQ, draining all inflights\n-\t * from the CQ, then unmapping the queue from the CQ. This function\n-\t * simply marks the port as needing the queue unmapped, and (if\n-\t * necessary) starts the unmapping worker thread.\n-\t */\n-\tdlb2_ldb_port_cq_disable(hw, port);\n-\n-\tst = DLB2_QUEUE_UNMAP_IN_PROG;\n-\tret = dlb2_port_slot_state_transition(hw, port, queue, i, st);\n-\tif (ret)\n-\t\treturn ret;\n-\n-\t/*\n-\t * Attempt to finish the unmapping now, in case the port has no\n-\t * outstanding inflights. If that's not the case, this will fail and\n-\t * the unmapping will be completed at a later time.\n-\t */\n-\tunmap_complete = dlb2_domain_finish_unmap_port(hw, domain, port);\n-\n-\t/*\n-\t * If the unmapping couldn't complete immediately, launch the worker\n-\t * thread (if it isn't already launched) to finish it later.\n-\t */\n-\tif (!unmap_complete && !os_worker_active(hw))\n-\t\tos_schedule_work(hw);\n-\n-unmap_qid_done:\n-\tresp->status = 0;\n-\n-\treturn 0;\n-}\n-\n-static void\n-dlb2_log_pending_port_unmaps_args(struct dlb2_hw *hw,\n-\t\t\t\t  struct dlb2_pending_port_unmaps_args *args,\n-\t\t\t\t  bool vdev_req,\n-\t\t\t\t  unsigned int vdev_id)\n-{\n-\tDLB2_HW_DBG(hw, \"DLB unmaps in progress arguments:\\n\");\n-\tif (vdev_req)\n-\t\tDLB2_HW_DBG(hw, \"(Request from VF %d)\\n\", vdev_id);\n-\tDLB2_HW_DBG(hw, \"\\tPort ID: %d\\n\", args->port_id);\n-}\n-\n-int dlb2_hw_pending_port_unmaps(struct dlb2_hw *hw,\n-\t\t\t\tu32 domain_id,\n-\t\t\t\tstruct dlb2_pending_port_unmaps_args *args,\n-\t\t\t\tstruct dlb2_cmd_response *resp,\n-\t\t\t\tbool vdev_req,\n-\t\t\t\tunsigned int vdev_id)\n-{\n-\tstruct dlb2_hw_domain *domain;\n-\tstruct dlb2_ldb_port *port;\n-\n-\tdlb2_log_pending_port_unmaps_args(hw, args, vdev_req, vdev_id);\n-\n-\tdomain = dlb2_get_domain_from_id(hw, domain_id, vdev_req, vdev_id);\n-\n-\tif (domain == NULL) {\n-\t\tresp->status = DLB2_ST_INVALID_DOMAIN_ID;\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tport = dlb2_get_domain_used_ldb_port(args->port_id, vdev_req, domain);\n-\tif (port == NULL || !port->configured) {\n-\t\tresp->status = DLB2_ST_INVALID_PORT_ID;\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tresp->id = port->num_pending_removals;\n-\n-\treturn 0;\n-}\n-\n static int dlb2_verify_start_domain_args(struct dlb2_hw *hw,\n \t\t\t\t\t u32 domain_id,\n \t\t\t\t\t struct dlb2_cmd_response *resp,\ndiff --git a/drivers/event/dlb2/pf/base/dlb2_resource_new.c b/drivers/event/dlb2/pf/base/dlb2_resource_new.c\nindex 5277a2643..181922fe3 100644\n--- a/drivers/event/dlb2/pf/base/dlb2_resource_new.c\n+++ b/drivers/event/dlb2/pf/base/dlb2_resource_new.c\n@@ -5476,3 +5476,301 @@ int dlb2_hw_map_qid(struct dlb2_hw *hw,\n \n \treturn 0;\n }\n+\n+static void dlb2_log_unmap_qid(struct dlb2_hw *hw,\n+\t\t\t       u32 domain_id,\n+\t\t\t       struct dlb2_unmap_qid_args *args,\n+\t\t\t       bool vdev_req,\n+\t\t\t       unsigned int vdev_id)\n+{\n+\tDLB2_HW_DBG(hw, \"DLB2 unmap QID arguments:\\n\");\n+\tif (vdev_req)\n+\t\tDLB2_HW_DBG(hw, \"(Request from vdev %d)\\n\", vdev_id);\n+\tDLB2_HW_DBG(hw, \"\\tDomain ID: %d\\n\",\n+\t\t    domain_id);\n+\tDLB2_HW_DBG(hw, \"\\tPort ID:   %d\\n\",\n+\t\t    args->port_id);\n+\tDLB2_HW_DBG(hw, \"\\tQueue ID:  %d\\n\",\n+\t\t    args->qid);\n+\tif (args->qid < DLB2_MAX_NUM_LDB_QUEUES)\n+\t\tDLB2_HW_DBG(hw, \"\\tQueue's num mappings:  %d\\n\",\n+\t\t\t    hw->rsrcs.ldb_queues[args->qid].num_mappings);\n+}\n+\n+static int dlb2_verify_unmap_qid_args(struct dlb2_hw *hw,\n+\t\t\t\t      u32 domain_id,\n+\t\t\t\t      struct dlb2_unmap_qid_args *args,\n+\t\t\t\t      struct dlb2_cmd_response *resp,\n+\t\t\t\t      bool vdev_req,\n+\t\t\t\t      unsigned int vdev_id,\n+\t\t\t\t      struct dlb2_hw_domain **out_domain,\n+\t\t\t\t      struct dlb2_ldb_port **out_port,\n+\t\t\t\t      struct dlb2_ldb_queue **out_queue)\n+{\n+\tenum dlb2_qid_map_state state;\n+\tstruct dlb2_hw_domain *domain;\n+\tstruct dlb2_ldb_queue *queue;\n+\tstruct dlb2_ldb_port *port;\n+\tint slot;\n+\tint id;\n+\n+\tdomain = dlb2_get_domain_from_id(hw, domain_id, vdev_req, vdev_id);\n+\n+\tif (!domain) {\n+\t\tresp->status = DLB2_ST_INVALID_DOMAIN_ID;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!domain->configured) {\n+\t\tresp->status = DLB2_ST_DOMAIN_NOT_CONFIGURED;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tid = args->port_id;\n+\n+\tport = dlb2_get_domain_used_ldb_port(id, vdev_req, domain);\n+\n+\tif (!port || !port->configured) {\n+\t\tresp->status = DLB2_ST_INVALID_PORT_ID;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (port->domain_id.phys_id != domain->id.phys_id) {\n+\t\tresp->status = DLB2_ST_INVALID_PORT_ID;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tqueue = dlb2_get_domain_ldb_queue(args->qid, vdev_req, domain);\n+\n+\tif (!queue || !queue->configured) {\n+\t\tDLB2_HW_ERR(hw, \"[%s()] Can't unmap unconfigured queue %d\\n\",\n+\t\t\t    __func__, args->qid);\n+\t\tresp->status = DLB2_ST_INVALID_QID;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/*\n+\t * Verify that the port has the queue mapped. From the application's\n+\t * perspective a queue is mapped if it is actually mapped, the map is\n+\t * in progress, or the map is blocked pending an unmap.\n+\t */\n+\tstate = DLB2_QUEUE_MAPPED;\n+\tif (dlb2_port_find_slot_queue(port, state, queue, &slot))\n+\t\tgoto done;\n+\n+\tstate = DLB2_QUEUE_MAP_IN_PROG;\n+\tif (dlb2_port_find_slot_queue(port, state, queue, &slot))\n+\t\tgoto done;\n+\n+\tif (dlb2_port_find_slot_with_pending_map_queue(port, queue, &slot))\n+\t\tgoto done;\n+\n+\tresp->status = DLB2_ST_INVALID_QID;\n+\treturn -EINVAL;\n+\n+done:\n+\t*out_domain = domain;\n+\t*out_port = port;\n+\t*out_queue = queue;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * dlb2_hw_unmap_qid() - Unmap a load-balanced queue from a load-balanced port\n+ * @hw: dlb2_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: unmap QID arguments.\n+ * @resp: response structure.\n+ * @vdev_req: indicates whether this request came from a vdev.\n+ * @vdev_id: If vdev_req is true, this contains the vdev's ID.\n+ *\n+ * This function configures the DLB to stop scheduling QEs from the specified\n+ * queue to the specified port.\n+ *\n+ * A successful return does not necessarily mean the mapping was removed. If\n+ * this function is unable to immediately unmap the queue from the port, it\n+ * will add the requested operation to a per-port list of pending map/unmap\n+ * operations, and (if it's not already running) launch a kernel thread that\n+ * periodically attempts to process all pending operations. See\n+ * dlb2_hw_map_qid() for more details.\n+ *\n+ * A vdev can be either an SR-IOV virtual function or a Scalable IOV virtual\n+ * device.\n+ *\n+ * Return:\n+ * Returns 0 upon success, < 0 otherwise. If an error occurs, resp->status is\n+ * assigned a detailed error code from enum dlb2_error.\n+ *\n+ * Errors:\n+ * EINVAL - A requested resource is unavailable, invalid port or queue ID, or\n+ *\t    the domain is not configured.\n+ * EFAULT - Internal error (resp->status not set).\n+ */\n+int dlb2_hw_unmap_qid(struct dlb2_hw *hw,\n+\t\t      u32 domain_id,\n+\t\t      struct dlb2_unmap_qid_args *args,\n+\t\t      struct dlb2_cmd_response *resp,\n+\t\t      bool vdev_req,\n+\t\t      unsigned int vdev_id)\n+{\n+\tstruct dlb2_hw_domain *domain;\n+\tstruct dlb2_ldb_queue *queue;\n+\tenum dlb2_qid_map_state st;\n+\tstruct dlb2_ldb_port *port;\n+\tbool unmap_complete;\n+\tint i, ret;\n+\n+\tdlb2_log_unmap_qid(hw, domain_id, args, vdev_req, vdev_id);\n+\n+\t/*\n+\t * Verify that hardware resources are available before attempting to\n+\t * satisfy the request. This simplifies the error unwinding code.\n+\t */\n+\tret = dlb2_verify_unmap_qid_args(hw,\n+\t\t\t\t\t domain_id,\n+\t\t\t\t\t args,\n+\t\t\t\t\t resp,\n+\t\t\t\t\t vdev_req,\n+\t\t\t\t\t vdev_id,\n+\t\t\t\t\t &domain,\n+\t\t\t\t\t &port,\n+\t\t\t\t\t &queue);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/*\n+\t * If the queue hasn't been mapped yet, we need to update the slot's\n+\t * state and re-enable the queue's inflights.\n+\t */\n+\tst = DLB2_QUEUE_MAP_IN_PROG;\n+\tif (dlb2_port_find_slot_queue(port, st, queue, &i)) {\n+\t\t/*\n+\t\t * Since the in-progress map was aborted, re-enable the QID's\n+\t\t * inflights.\n+\t\t */\n+\t\tif (queue->num_pending_additions == 0)\n+\t\t\tdlb2_ldb_queue_set_inflight_limit(hw, queue);\n+\n+\t\tst = DLB2_QUEUE_UNMAPPED;\n+\t\tret = dlb2_port_slot_state_transition(hw, port, queue, i, st);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tgoto unmap_qid_done;\n+\t}\n+\n+\t/*\n+\t * If the queue mapping is on hold pending an unmap, we simply need to\n+\t * update the slot's state.\n+\t */\n+\tif (dlb2_port_find_slot_with_pending_map_queue(port, queue, &i)) {\n+\t\tst = DLB2_QUEUE_UNMAP_IN_PROG;\n+\t\tret = dlb2_port_slot_state_transition(hw, port, queue, i, st);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tgoto unmap_qid_done;\n+\t}\n+\n+\tst = DLB2_QUEUE_MAPPED;\n+\tif (!dlb2_port_find_slot_queue(port, st, queue, &i)) {\n+\t\tDLB2_HW_ERR(hw,\n+\t\t\t    \"[%s()] Internal error: no available CQ slots\\n\",\n+\t\t\t    __func__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\t/*\n+\t * QID->CQ mapping removal is an asynchronous procedure. It requires\n+\t * stopping the DLB2 from scheduling this CQ, draining all inflights\n+\t * from the CQ, then unmapping the queue from the CQ. This function\n+\t * simply marks the port as needing the queue unmapped, and (if\n+\t * necessary) starts the unmapping worker thread.\n+\t */\n+\tdlb2_ldb_port_cq_disable(hw, port);\n+\n+\tst = DLB2_QUEUE_UNMAP_IN_PROG;\n+\tret = dlb2_port_slot_state_transition(hw, port, queue, i, st);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/*\n+\t * Attempt to finish the unmapping now, in case the port has no\n+\t * outstanding inflights. If that's not the case, this will fail and\n+\t * the unmapping will be completed at a later time.\n+\t */\n+\tunmap_complete = dlb2_domain_finish_unmap_port(hw, domain, port);\n+\n+\t/*\n+\t * If the unmapping couldn't complete immediately, launch the worker\n+\t * thread (if it isn't already launched) to finish it later.\n+\t */\n+\tif (!unmap_complete && !os_worker_active(hw))\n+\t\tos_schedule_work(hw);\n+\n+unmap_qid_done:\n+\tresp->status = 0;\n+\n+\treturn 0;\n+}\n+\n+static void\n+dlb2_log_pending_port_unmaps_args(struct dlb2_hw *hw,\n+\t\t\t\t  struct dlb2_pending_port_unmaps_args *args,\n+\t\t\t\t  bool vdev_req,\n+\t\t\t\t  unsigned int vdev_id)\n+{\n+\tDLB2_HW_DBG(hw, \"DLB unmaps in progress arguments:\\n\");\n+\tif (vdev_req)\n+\t\tDLB2_HW_DBG(hw, \"(Request from VF %d)\\n\", vdev_id);\n+\tDLB2_HW_DBG(hw, \"\\tPort ID: %d\\n\", args->port_id);\n+}\n+\n+/**\n+ * dlb2_hw_pending_port_unmaps() - returns the number of unmap operations in\n+ *\tprogress.\n+ * @hw: dlb2_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: number of unmaps in progress args\n+ * @resp: response structure.\n+ * @vdev_req: indicates whether this request came from a vdev.\n+ * @vdev_id: If vdev_req is true, this contains the vdev's ID.\n+ *\n+ * Return:\n+ * Returns 0 upon success, < 0 otherwise. If an error occurs, resp->status is\n+ * assigned a detailed error code from enum dlb2_error. If successful, resp->id\n+ * contains the number of unmaps in progress.\n+ *\n+ * Errors:\n+ * EINVAL - Invalid port ID.\n+ */\n+int dlb2_hw_pending_port_unmaps(struct dlb2_hw *hw,\n+\t\t\t\tu32 domain_id,\n+\t\t\t\tstruct dlb2_pending_port_unmaps_args *args,\n+\t\t\t\tstruct dlb2_cmd_response *resp,\n+\t\t\t\tbool vdev_req,\n+\t\t\t\tunsigned int vdev_id)\n+{\n+\tstruct dlb2_hw_domain *domain;\n+\tstruct dlb2_ldb_port *port;\n+\n+\tdlb2_log_pending_port_unmaps_args(hw, args, vdev_req, vdev_id);\n+\n+\tdomain = dlb2_get_domain_from_id(hw, domain_id, vdev_req, vdev_id);\n+\n+\tif (!domain) {\n+\t\tresp->status = DLB2_ST_INVALID_DOMAIN_ID;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tport = dlb2_get_domain_used_ldb_port(args->port_id, vdev_req, domain);\n+\tif (!port || !port->configured) {\n+\t\tresp->status = DLB2_ST_INVALID_PORT_ID;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tresp->id = port->num_pending_removals;\n+\n+\treturn 0;\n+}\n",
    "prefixes": [
        "v5",
        "13/26"
    ]
}