get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 77517,
    "url": "http://patches.dpdk.org/api/patches/77517/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1599855987-25976-13-git-send-email-timothy.mcdaniel@intel.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": "<1599855987-25976-13-git-send-email-timothy.mcdaniel@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1599855987-25976-13-git-send-email-timothy.mcdaniel@intel.com",
    "date": "2020-09-11T20:26:17",
    "name": "[12/22] event/dlb2: add port link",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "e1e48cd0b91d67fcd6b8d4a300fe6560cddc6092",
    "submitter": {
        "id": 826,
        "url": "http://patches.dpdk.org/api/people/826/?format=api",
        "name": "Timothy McDaniel",
        "email": "timothy.mcdaniel@intel.com"
    },
    "delegate": {
        "id": 310,
        "url": "http://patches.dpdk.org/api/users/310/?format=api",
        "username": "jerin",
        "first_name": "Jerin",
        "last_name": "Jacob",
        "email": "jerinj@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1599855987-25976-13-git-send-email-timothy.mcdaniel@intel.com/mbox/",
    "series": [
        {
            "id": 12164,
            "url": "http://patches.dpdk.org/api/series/12164/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=12164",
            "date": "2020-09-11T20:26:05",
            "name": "Add DLB2 PMD",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/12164/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/77517/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/77517/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 53182A04C1;\n\tFri, 11 Sep 2020 22:32:05 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 6BB8A1C201;\n\tFri, 11 Sep 2020 22:30:33 +0200 (CEST)",
            "from mga04.intel.com (mga04.intel.com [192.55.52.120])\n by dpdk.org (Postfix) with ESMTP id AD2941C194\n for <dev@dpdk.org>; Fri, 11 Sep 2020 22:30:02 +0200 (CEST)",
            "from orsmga005.jf.intel.com ([10.7.209.41])\n by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 11 Sep 2020 13:30:02 -0700",
            "from txasoft-yocto.an.intel.com ([10.123.72.192])\n by orsmga005.jf.intel.com with ESMTP; 11 Sep 2020 13:30:01 -0700"
        ],
        "IronPort-SDR": [
            "\n s1Hbf1GyZE6hRrIJPuScgwqUYfm3BzxpnZFDA2SmHtGPBUN1Mx8NIhf9FqpLZlqIRLsOABwhfr\n Bdo2SdQd8F9A==",
            "\n loT5/mqis4DiD6NzOlORj2DWqMAFX6Q6ITOP/qK6CODscUUtIkXfLLWdQkqDN6JQV9N1PD5qCY\n Z96qnXGAIb6g=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9741\"; a=\"156244365\"",
            "E=Sophos;i=\"5.76,417,1592895600\"; d=\"scan'208\";a=\"156244365\"",
            "E=Sophos;i=\"5.76,417,1592895600\"; d=\"scan'208\";a=\"481453591\""
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "From": "Timothy McDaniel <timothy.mcdaniel@intel.com>",
        "To": "",
        "Cc": "dev@dpdk.org, erik.g.carrillo@intel.com, gage.eads@intel.com,\n harry.van.haaren@intel.com, jerinj@marvell.com",
        "Date": "Fri, 11 Sep 2020 15:26:17 -0500",
        "Message-Id": "<1599855987-25976-13-git-send-email-timothy.mcdaniel@intel.com>",
        "X-Mailer": "git-send-email 1.7.10",
        "In-Reply-To": "<1599855987-25976-1-git-send-email-timothy.mcdaniel@intel.com>",
        "References": "<1599855987-25976-1-git-send-email-timothy.mcdaniel@intel.com>",
        "Subject": "[dpdk-dev] [PATCH 12/22] event/dlb2: add port link",
        "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": "Add port link entry point. Directed queues are identified and created\nat this stage. Their setup deferred until link-time, at which\npoint we know the directed port ID. Directed queue setup\nwill only fail if this queue is already setup or there are\nno directed queues left to configure.\n\nSigned-off-by: Timothy McDaniel <timothy.mcdaniel@intel.com>\n---\n drivers/event/dlb2/dlb2.c                  | 305 ++++++++++++++\n drivers/event/dlb2/dlb2_iface.c            |   6 +\n drivers/event/dlb2/dlb2_iface.h            |   6 +\n drivers/event/dlb2/pf/base/dlb2_resource.c | 633 +++++++++++++++++++++++++++++\n drivers/event/dlb2/pf/dlb2_main.c          |  10 +\n drivers/event/dlb2/pf/dlb2_pf.c            |  50 +++\n 6 files changed, 1010 insertions(+)",
    "diff": "diff --git a/drivers/event/dlb2/dlb2.c b/drivers/event/dlb2/dlb2.c\nindex a4c8833..bf50758 100644\n--- a/drivers/event/dlb2/dlb2.c\n+++ b/drivers/event/dlb2/dlb2.c\n@@ -1569,6 +1569,310 @@ dlb2_eventdev_port_setup(struct rte_eventdev *dev,\n \treturn 0;\n }\n \n+static int16_t\n+dlb2_hw_map_ldb_qid_to_port(struct dlb2_hw_dev *handle,\n+\t\t\t    uint32_t qm_port_id,\n+\t\t\t    uint16_t qm_qid,\n+\t\t\t    uint8_t priority)\n+{\n+\tstruct dlb2_map_qid_args cfg;\n+\tint32_t ret;\n+\n+\tif (handle == NULL)\n+\t\treturn -EINVAL;\n+\n+\t/* Build message */\n+\tcfg.port_id = qm_port_id;\n+\tcfg.qid = qm_qid;\n+\tcfg.priority = EV_TO_DLB2_PRIO(priority);\n+\n+\tret = dlb2_iface_map_qid(handle, &cfg);\n+\tif (ret < 0) {\n+\t\tDLB2_LOG_ERR(\"dlb2: map qid error, ret=%d (driver status: %s)\\n\",\n+\t\t\t     ret, dlb2_error_strings[cfg.response.status]);\n+\t\tDLB2_LOG_ERR(\"dlb2: device_id=%d grp=%d, qm_port=%d, qm_qid=%d prio=%d\\n\",\n+\t\t\t     handle->device_id,\n+\t\t\t     handle->domain_id, cfg.port_id,\n+\t\t\t     cfg.qid,\n+\t\t\t     cfg.priority);\n+\t} else {\n+\t\tDLB2_LOG_DBG(\"dlb2: mapped queue %d to qm_port %d\\n\",\n+\t\t\t     qm_qid, qm_port_id);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static int\n+dlb2_event_queue_join_ldb(struct dlb2_eventdev *dlb2,\n+\t\t\t  struct dlb2_eventdev_port *ev_port,\n+\t\t\t  struct dlb2_eventdev_queue *ev_queue,\n+\t\t\t  uint8_t priority)\n+{\n+\tint first_avail = -1;\n+\tint ret, i;\n+\n+\tfor (i = 0; i < DLB2_MAX_NUM_QIDS_PER_LDB_CQ; i++) {\n+\t\tif (ev_port->link[i].valid) {\n+\t\t\tif (ev_port->link[i].queue_id == ev_queue->id &&\n+\t\t\t    ev_port->link[i].priority == priority) {\n+\t\t\t\tif (ev_port->link[i].mapped)\n+\t\t\t\t\treturn 0; /* already mapped */\n+\t\t\t\tfirst_avail = i;\n+\t\t\t}\n+\t\t} else if (first_avail == -1) {\n+\t\t\tfirst_avail = i;\n+\t\t}\n+\t}\n+\tif (first_avail == -1) {\n+\t\tDLB2_LOG_ERR(\"dlb2: qm_port %d has no available QID slots.\\n\",\n+\t\t\t     ev_port->qm_port.id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tret = dlb2_hw_map_ldb_qid_to_port(&dlb2->qm_instance,\n+\t\t\t\t\t  ev_port->qm_port.id,\n+\t\t\t\t\t  ev_queue->qm_queue.id,\n+\t\t\t\t\t  priority);\n+\n+\tif (!ret)\n+\t\tev_port->link[first_avail].mapped = true;\n+\n+\treturn ret;\n+}\n+\n+static int32_t\n+dlb2_hw_create_dir_queue(struct dlb2_eventdev *dlb2,\n+\t\t\t struct dlb2_eventdev_queue *ev_queue,\n+\t\t\t int32_t qm_port_id)\n+{\n+\tstruct dlb2_hw_dev *handle = &dlb2->qm_instance;\n+\tstruct dlb2_create_dir_queue_args cfg;\n+\tint32_t ret;\n+\n+\t/* The directed port is always configured before its queue */\n+\tcfg.port_id = qm_port_id;\n+\n+\tif (ev_queue->depth_threshold == 0) {\n+\t\tcfg.depth_threshold = RTE_PMD_DLB2_DEFAULT_DEPTH_THRESH;\n+\t\tev_queue->depth_threshold = RTE_PMD_DLB2_DEFAULT_DEPTH_THRESH;\n+\t} else {\n+\t\tcfg.depth_threshold = ev_queue->depth_threshold;\n+\t}\n+\n+\tret = dlb2_iface_dir_queue_create(handle, &cfg);\n+\tif (ret < 0) {\n+\t\tDLB2_LOG_ERR(\"dlb2: create DIR event queue error, ret=%d (driver status: %s)\\n\",\n+\t\t\t     ret, dlb2_error_strings[cfg.response.status]);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn cfg.response.id;\n+}\n+\n+static int\n+dlb2_eventdev_dir_queue_setup(struct dlb2_eventdev *dlb2,\n+\t\t\t      struct dlb2_eventdev_queue *ev_queue,\n+\t\t\t      struct dlb2_eventdev_port *ev_port)\n+{\n+\tint32_t qm_qid;\n+\n+\tqm_qid = dlb2_hw_create_dir_queue(dlb2, ev_queue, ev_port->qm_port.id);\n+\n+\tif (qm_qid < 0) {\n+\t\tDLB2_LOG_ERR(\"Failed to create the DIR queue\\n\");\n+\t\treturn qm_qid;\n+\t}\n+\n+\tdlb2->qm_dir_to_ev_queue_id[qm_qid] = ev_queue->id;\n+\n+\tev_queue->qm_queue.id = qm_qid;\n+\n+\treturn 0;\n+}\n+\n+static int\n+dlb2_do_port_link(struct rte_eventdev *dev,\n+\t\t  struct dlb2_eventdev_queue *ev_queue,\n+\t\t  struct dlb2_eventdev_port *ev_port,\n+\t\t  uint8_t prio)\n+{\n+\tstruct dlb2_eventdev *dlb2 = dlb2_pmd_priv(dev);\n+\tint err;\n+\n+\t/* Don't link until start time. */\n+\tif (dlb2->run_state == DLB2_RUN_STATE_STOPPED)\n+\t\treturn 0;\n+\n+\tif (ev_queue->qm_queue.is_directed)\n+\t\terr = dlb2_eventdev_dir_queue_setup(dlb2, ev_queue, ev_port);\n+\telse\n+\t\terr = dlb2_event_queue_join_ldb(dlb2, ev_port, ev_queue, prio);\n+\n+\tif (err) {\n+\t\tDLB2_LOG_ERR(\"port link failure for %s ev_q %d, ev_port %d\\n\",\n+\t\t\t     ev_queue->qm_queue.is_directed ? \"DIR\" : \"LDB\",\n+\t\t\t     ev_queue->id, ev_port->id);\n+\n+\t\trte_errno = err;\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+dlb2_validate_port_link(struct dlb2_eventdev_port *ev_port,\n+\t\t\tuint8_t queue_id,\n+\t\t\tbool link_exists,\n+\t\t\tint index)\n+{\n+\tstruct dlb2_eventdev *dlb2 = ev_port->dlb2;\n+\tstruct dlb2_eventdev_queue *ev_queue;\n+\tbool port_is_dir, queue_is_dir;\n+\n+\tif (queue_id > dlb2->num_queues) {\n+\t\trte_errno = -EINVAL;\n+\t\treturn -1;\n+\t}\n+\n+\tev_queue = &dlb2->ev_queues[queue_id];\n+\n+\tif (!ev_queue->setup_done &&\n+\t    ev_queue->qm_queue.config_state != DLB2_PREV_CONFIGURED) {\n+\t\trte_errno = -EINVAL;\n+\t\treturn -1;\n+\t}\n+\n+\tport_is_dir = ev_port->qm_port.is_directed;\n+\tqueue_is_dir = ev_queue->qm_queue.is_directed;\n+\n+\tif (port_is_dir != queue_is_dir) {\n+\t\tDLB2_LOG_ERR(\"%s queue %u can't link to %s port %u\\n\",\n+\t\t\t     queue_is_dir ? \"DIR\" : \"LDB\", ev_queue->id,\n+\t\t\t     port_is_dir ? \"DIR\" : \"LDB\", ev_port->id);\n+\n+\t\trte_errno = -EINVAL;\n+\t\treturn -1;\n+\t}\n+\n+\t/* Check if there is space for the requested link */\n+\tif (!link_exists && index == -1) {\n+\t\tDLB2_LOG_ERR(\"no space for new link\\n\");\n+\t\trte_errno = -ENOSPC;\n+\t\treturn -1;\n+\t}\n+\n+\t/* Check if the directed port is already linked */\n+\tif (ev_port->qm_port.is_directed && ev_port->num_links > 0 &&\n+\t    !link_exists) {\n+\t\tDLB2_LOG_ERR(\"Can't link DIR port %d to >1 queues\\n\",\n+\t\t\t     ev_port->id);\n+\t\trte_errno = -EINVAL;\n+\t\treturn -1;\n+\t}\n+\n+\t/* Check if the directed queue is already linked */\n+\tif (ev_queue->qm_queue.is_directed && ev_queue->num_links > 0 &&\n+\t    !link_exists) {\n+\t\tDLB2_LOG_ERR(\"Can't link DIR queue %d to >1 ports\\n\",\n+\t\t\t     ev_queue->id);\n+\t\trte_errno = -EINVAL;\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+dlb2_eventdev_port_link(struct rte_eventdev *dev, void *event_port,\n+\t\t\tconst uint8_t queues[], const uint8_t priorities[],\n+\t\t\tuint16_t nb_links)\n+\n+{\n+\tstruct dlb2_eventdev_port *ev_port = event_port;\n+\tstruct dlb2_eventdev *dlb2;\n+\tint i, j;\n+\n+\tRTE_SET_USED(dev);\n+\n+\tif (!ev_port) {\n+\t\tDLB2_LOG_ERR(\"dlb2: evport not setup\\n\");\n+\t\trte_errno = -EINVAL;\n+\t\treturn 0;\n+\t}\n+\n+\tif (!ev_port->setup_done &&\n+\t    ev_port->qm_port.config_state != DLB2_PREV_CONFIGURED) {\n+\t\tDLB2_LOG_ERR(\"dlb2: evport not setup\\n\");\n+\t\trte_errno = -EINVAL;\n+\t\treturn 0;\n+\t}\n+\n+\t/* Note: rte_event_port_link() ensures the PMD won't receive a NULL\n+\t * queues pointer.\n+\t */\n+\tif (nb_links == 0) {\n+\t\tDLB2_LOG_DBG(\"dlb2: nb_links is 0\\n\");\n+\t\treturn 0; /* Ignore and return success */\n+\t}\n+\n+\tdlb2 = ev_port->dlb2;\n+\n+\tDLB2_LOG_DBG(\"Linking %u queues to %s port %d\\n\",\n+\t\t     nb_links,\n+\t\t     ev_port->qm_port.is_directed ? \"DIR\" : \"LDB\",\n+\t\t     ev_port->id);\n+\n+\tfor (i = 0; i < nb_links; i++) {\n+\t\tstruct dlb2_eventdev_queue *ev_queue;\n+\t\tuint8_t queue_id, prio;\n+\t\tbool found = false;\n+\t\tint index = -1;\n+\n+\t\tqueue_id = queues[i];\n+\t\tprio = priorities[i];\n+\n+\t\t/* Check if the link already exists. */\n+\t\tfor (j = 0; j < DLB2_MAX_NUM_QIDS_PER_LDB_CQ; j++)\n+\t\t\tif (ev_port->link[j].valid) {\n+\t\t\t\tif (ev_port->link[j].queue_id == queue_id) {\n+\t\t\t\t\tfound = true;\n+\t\t\t\t\tindex = j;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t} else if (index == -1) {\n+\t\t\t\tindex = j;\n+\t\t\t}\n+\n+\t\t/* could not link */\n+\t\tif (index == -1)\n+\t\t\tbreak;\n+\n+\t\t/* Check if already linked at the requested priority */\n+\t\tif (found && ev_port->link[j].priority == prio)\n+\t\t\tcontinue;\n+\n+\t\tif (dlb2_validate_port_link(ev_port, queue_id, found, index))\n+\t\t\tbreak; /* return index of offending queue */\n+\n+\t\tev_queue = &dlb2->ev_queues[queue_id];\n+\n+\t\tif (dlb2_do_port_link(dev, ev_queue, ev_port, prio))\n+\t\t\tbreak; /* return index of offending queue */\n+\n+\t\tev_queue->num_links++;\n+\n+\t\tev_port->link[index].queue_id = queue_id;\n+\t\tev_port->link[index].priority = prio;\n+\t\tev_port->link[index].valid = true;\n+\t\t/* Entry already exists?  If so, then must be prio change */\n+\t\tif (!found)\n+\t\t\tev_port->num_links++;\n+\t}\n+\treturn i;\n+}\n+\n static void\n dlb2_entry_points_init(struct rte_eventdev *dev)\n {\n@@ -1580,6 +1884,7 @@ dlb2_entry_points_init(struct rte_eventdev *dev)\n \t\t.queue_setup      = dlb2_eventdev_queue_setup,\n \t\t.port_def_conf    = dlb2_eventdev_port_default_conf_get,\n \t\t.port_setup       = dlb2_eventdev_port_setup,\n+\t\t.port_link        = dlb2_eventdev_port_link,\n \t\t.dump             = dlb2_eventdev_dump,\n \t\t.xstats_get       = dlb2_eventdev_xstats_get,\n \t\t.xstats_get_names = dlb2_eventdev_xstats_get_names,\ndiff --git a/drivers/event/dlb2/dlb2_iface.c b/drivers/event/dlb2/dlb2_iface.c\nindex 84cbf25..79f939f 100644\n--- a/drivers/event/dlb2/dlb2_iface.c\n+++ b/drivers/event/dlb2/dlb2_iface.c\n@@ -66,3 +66,9 @@ int (*dlb2_iface_dir_port_create)(struct dlb2_hw_dev *handle,\n \t\t\t\t  struct dlb2_create_dir_port_args *cfg,\n \t\t\t\t  enum dlb2_cq_poll_modes poll_mode);\n \n+int (*dlb2_iface_dir_queue_create)(struct dlb2_hw_dev *handle,\n+\t\t\t\t   struct dlb2_create_dir_queue_args *cfg);\n+\n+int (*dlb2_iface_map_qid)(struct dlb2_hw_dev *handle,\n+\t\t\t  struct dlb2_map_qid_args *cfg);\n+\ndiff --git a/drivers/event/dlb2/dlb2_iface.h b/drivers/event/dlb2/dlb2_iface.h\nindex a090a54..90f7b8a 100644\n--- a/drivers/event/dlb2/dlb2_iface.h\n+++ b/drivers/event/dlb2/dlb2_iface.h\n@@ -51,4 +51,10 @@ extern int (*dlb2_iface_dir_port_create)(struct dlb2_hw_dev *handle,\n \t\t\t\t\t struct dlb2_create_dir_port_args *cfg,\n \t\t\t\t\t enum dlb2_cq_poll_modes poll_mode);\n \n+extern int (*dlb2_iface_dir_queue_create)(struct dlb2_hw_dev *handle,\n+\t\t\t\t\tstruct dlb2_create_dir_queue_args *cfg);\n+\n+extern int (*dlb2_iface_map_qid)(struct dlb2_hw_dev *handle,\n+\t\t\t\t struct dlb2_map_qid_args *cfg);\n+\n #endif /* _DLB2_IFACE_H_ */\ndiff --git a/drivers/event/dlb2/pf/base/dlb2_resource.c b/drivers/event/dlb2/pf/base/dlb2_resource.c\nindex bb8683c..45abda1 100644\n--- a/drivers/event/dlb2/pf/base/dlb2_resource.c\n+++ b/drivers/event/dlb2/pf/base/dlb2_resource.c\n@@ -4891,3 +4891,636 @@ int dlb2_hw_create_dir_port(struct dlb2_hw *hw,\n \n \treturn 0;\n }\n+\n+static void dlb2_configure_dir_queue(struct dlb2_hw *hw,\n+\t\t\t\t     struct dlb2_hw_domain *domain,\n+\t\t\t\t     struct dlb2_dir_pq_pair *queue,\n+\t\t\t\t     struct dlb2_create_dir_queue_args *args,\n+\t\t\t\t     bool vdev_req,\n+\t\t\t\t     unsigned int vdev_id)\n+{\n+\tunion dlb2_sys_dir_vasqid_v r0 = { {0} };\n+\tunion dlb2_sys_dir_qid_its r1 = { {0} };\n+\tunion dlb2_lsp_qid_dir_depth_thrsh r2 = { {0} };\n+\tunion dlb2_sys_dir_qid_v r5 = { {0} };\n+\n+\tunsigned int offs;\n+\n+\t/* QID write permissions are turned on when the domain is started */\n+\tr0.field.vasqid_v = 0;\n+\n+\toffs = domain->id.phys_id * DLB2_MAX_NUM_DIR_QUEUES +\n+\t\tqueue->id.phys_id;\n+\n+\tDLB2_CSR_WR(hw, DLB2_SYS_DIR_VASQID_V(offs), r0.val);\n+\n+\t/* Don't timestamp QEs that pass through this queue */\n+\tr1.field.qid_its = 0;\n+\n+\tDLB2_CSR_WR(hw,\n+\t\t    DLB2_SYS_DIR_QID_ITS(queue->id.phys_id),\n+\t\t    r1.val);\n+\n+\tr2.field.thresh = args->depth_threshold;\n+\n+\tDLB2_CSR_WR(hw,\n+\t\t    DLB2_LSP_QID_DIR_DEPTH_THRSH(queue->id.phys_id),\n+\t\t    r2.val);\n+\n+\tif (vdev_req) {\n+\t\tunion dlb2_sys_vf_dir_vqid_v r3 = { {0} };\n+\t\tunion dlb2_sys_vf_dir_vqid2qid r4 = { {0} };\n+\n+\t\toffs = vdev_id * DLB2_MAX_NUM_DIR_QUEUES + queue->id.virt_id;\n+\n+\t\tr3.field.vqid_v = 1;\n+\n+\t\tDLB2_CSR_WR(hw, DLB2_SYS_VF_DIR_VQID_V(offs), r3.val);\n+\n+\t\tr4.field.qid = queue->id.phys_id;\n+\n+\t\tDLB2_CSR_WR(hw, DLB2_SYS_VF_DIR_VQID2QID(offs), r4.val);\n+\t}\n+\n+\tr5.field.qid_v = 1;\n+\n+\tDLB2_CSR_WR(hw, DLB2_SYS_DIR_QID_V(queue->id.phys_id), r5.val);\n+\n+\tqueue->queue_configured = true;\n+}\n+\n+static void\n+dlb2_log_create_dir_queue_args(struct dlb2_hw *hw,\n+\t\t\t       u32 domain_id,\n+\t\t\t       struct dlb2_create_dir_queue_args *args,\n+\t\t\t       bool vdev_req,\n+\t\t\t       unsigned int vdev_id)\n+{\n+\tDLB2_HW_DBG(hw, \"DLB2 create directed queue 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\", domain_id);\n+\tDLB2_HW_DBG(hw, \"\\tPort ID:   %d\\n\", args->port_id);\n+}\n+\n+static int\n+dlb2_verify_create_dir_queue_args(struct dlb2_hw *hw,\n+\t\t\t\t  u32 domain_id,\n+\t\t\t\t  struct dlb2_create_dir_queue_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+\tstruct dlb2_hw_domain *domain;\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+\tif (domain->started) {\n+\t\tresp->status = DLB2_ST_DOMAIN_STARTED;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/*\n+\t * If the user claims the port is already configured, validate the port\n+\t * ID, its domain, and whether the port is configured.\n+\t */\n+\tif (args->port_id != -1) {\n+\t\tstruct dlb2_dir_pq_pair *port;\n+\n+\t\tport = dlb2_get_domain_used_dir_pq(args->port_id,\n+\t\t\t\t\t\t   vdev_req,\n+\t\t\t\t\t\t   domain);\n+\n+\t\tif (!port || port->domain_id.phys_id != domain->id.phys_id ||\n+\t\t    !port->port_configured) {\n+\t\t\tresp->status = DLB2_ST_INVALID_PORT_ID;\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * If the queue's port is not configured, validate that a free\n+\t * port-queue pair is available.\n+\t */\n+\tif (args->port_id == -1 &&\n+\t    dlb2_list_empty(&domain->avail_dir_pq_pairs)) {\n+\t\tresp->status = DLB2_ST_DIR_QUEUES_UNAVAILABLE;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * dlb2_hw_create_dir_queue() - Allocate and initialize a DLB DIR queue.\n+ * @hw:\tContains the current state of the DLB2 hardware.\n+ * @domain_id: Domain ID\n+ * @args: User-provided arguments.\n+ * @resp: Response to user.\n+ * @vdev_req: Request came from a virtual device.\n+ * @vdev_id: If vdev_req is true, this contains the virtual device's ID.\n+ *\n+ * Return: returns < 0 on error, 0 otherwise. If the driver is unable to\n+ * satisfy a request, resp->status will be set accordingly.\n+ */\n+int dlb2_hw_create_dir_queue(struct dlb2_hw *hw,\n+\t\t\t     u32 domain_id,\n+\t\t\t     struct dlb2_create_dir_queue_args *args,\n+\t\t\t     struct dlb2_cmd_response *resp,\n+\t\t\t     bool vdev_req,\n+\t\t\t     unsigned int vdev_id)\n+{\n+\tstruct dlb2_dir_pq_pair *queue;\n+\tstruct dlb2_hw_domain *domain;\n+\tint ret;\n+\n+\tdlb2_log_create_dir_queue_args(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_create_dir_queue_args(hw,\n+\t\t\t\t\t\tdomain_id,\n+\t\t\t\t\t\targs,\n+\t\t\t\t\t\tresp,\n+\t\t\t\t\t\tvdev_req,\n+\t\t\t\t\t\tvdev_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) {\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+\tif (args->port_id != -1)\n+\t\tqueue = dlb2_get_domain_used_dir_pq(args->port_id,\n+\t\t\t\t\t\t    vdev_req,\n+\t\t\t\t\t\t    domain);\n+\telse\n+\t\tqueue = DLB2_DOM_LIST_HEAD(domain->avail_dir_pq_pairs,\n+\t\t\t\t\t   typeof(*queue));\n+\tif (!queue) {\n+\t\tDLB2_HW_ERR(hw,\n+\t\t\t    \"[%s():%d] Internal error: no available dir queues\\n\",\n+\t\t\t    __func__, __LINE__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tdlb2_configure_dir_queue(hw, domain, queue, args, vdev_req, vdev_id);\n+\n+\t/*\n+\t * Configuration succeeded, so move the resource from the 'avail' to\n+\t * the 'used' list (if it's not already there).\n+\t */\n+\tif (args->port_id == -1) {\n+\t\tdlb2_list_del(&domain->avail_dir_pq_pairs,\n+\t\t\t      &queue->domain_list);\n+\n+\t\tdlb2_list_add(&domain->used_dir_pq_pairs,\n+\t\t\t      &queue->domain_list);\n+\t}\n+\n+\tresp->status = 0;\n+\n+\tresp->id = (vdev_req) ? queue->id.virt_id : queue->id.phys_id;\n+\n+\treturn 0;\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 void dlb2_ldb_port_change_qid_priority(struct dlb2_hw *hw,\n+\t\t\t\t\t      struct dlb2_ldb_port *port,\n+\t\t\t\t\t      int slot,\n+\t\t\t\t\t      struct dlb2_map_qid_args *args)\n+{\n+\tunion dlb2_lsp_cq2priov r0;\n+\n+\t/* Read-modify-write the priority and valid bit register */\n+\tr0.val = DLB2_CSR_RD(hw, DLB2_LSP_CQ2PRIOV(port->id.phys_id));\n+\n+\tr0.field.v |= 1 << slot;\n+\tr0.field.prio |= (args->priority & 0x7) << slot * 3;\n+\n+\tDLB2_CSR_WR(hw, DLB2_LSP_CQ2PRIOV(port->id.phys_id), r0.val);\n+\n+\tdlb2_flush_csr(hw);\n+\n+\tport->qid_map[slot].priority = args->priority;\n+}\n+\n+static int dlb2_verify_map_qid_slot_available(struct dlb2_ldb_port *port,\n+\t\t\t\t\t      struct dlb2_ldb_queue *queue,\n+\t\t\t\t\t      struct dlb2_cmd_response *resp)\n+{\n+\tenum dlb2_qid_map_state state;\n+\tint i;\n+\n+\t/* Unused slot available? */\n+\tif (port->num_mappings < DLB2_MAX_NUM_QIDS_PER_LDB_CQ)\n+\t\treturn 0;\n+\n+\t/*\n+\t * If the queue is already mapped (from the application's perspective),\n+\t * this is simply a priority update.\n+\t */\n+\tstate = DLB2_QUEUE_MAPPED;\n+\tif (dlb2_port_find_slot_queue(port, state, queue, &i))\n+\t\treturn 0;\n+\n+\tstate = DLB2_QUEUE_MAP_IN_PROG;\n+\tif (dlb2_port_find_slot_queue(port, state, queue, &i))\n+\t\treturn 0;\n+\n+\tif (dlb2_port_find_slot_with_pending_map_queue(port, queue, &i))\n+\t\treturn 0;\n+\n+\t/*\n+\t * If the slot contains an unmap in progress, it's considered\n+\t * available.\n+\t */\n+\tstate = DLB2_QUEUE_UNMAP_IN_PROG;\n+\tif (dlb2_port_find_slot(port, state, &i))\n+\t\treturn 0;\n+\n+\tstate = DLB2_QUEUE_UNMAPPED;\n+\tif (dlb2_port_find_slot(port, state, &i))\n+\t\treturn 0;\n+\n+\tresp->status = DLB2_ST_NO_QID_SLOTS_AVAILABLE;\n+\treturn -EINVAL;\n+}\n+\n+static struct dlb2_ldb_queue *\n+dlb2_get_domain_ldb_queue(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_queue *queue;\n+\tRTE_SET_USED(iter);\n+\n+\tif (id >= DLB2_MAX_NUM_LDB_QUEUES)\n+\t\treturn NULL;\n+\n+\tDLB2_DOM_LIST_FOR(domain->used_ldb_queues, queue, iter)\n+\t\tif ((!vdev_req && queue->id.phys_id == id) ||\n+\t\t    (vdev_req && queue->id.virt_id == id))\n+\t\t\treturn queue;\n+\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 int dlb2_verify_map_qid_args(struct dlb2_hw *hw,\n+\t\t\t\t    u32 domain_id,\n+\t\t\t\t    struct dlb2_map_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+\tstruct dlb2_hw_domain *domain;\n+\tstruct dlb2_ldb_port *port;\n+\tstruct dlb2_ldb_queue *queue;\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 (args->priority >= DLB2_QID_PRIORITIES) {\n+\t\tresp->status = DLB2_ST_INVALID_PRIORITY;\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\tresp->status = DLB2_ST_INVALID_QID;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (queue->domain_id.phys_id != domain->id.phys_id) {\n+\t\tresp->status = DLB2_ST_INVALID_QID;\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+\treturn 0;\n+}\n+\n+static void dlb2_log_map_qid(struct dlb2_hw *hw,\n+\t\t\t     u32 domain_id,\n+\t\t\t     struct dlb2_map_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 map 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+\tDLB2_HW_DBG(hw, \"\\tPriority:  %d\\n\",\n+\t\t    args->priority);\n+}\n+\n+int dlb2_hw_map_qid(struct dlb2_hw *hw,\n+\t\t    u32 domain_id,\n+\t\t    struct dlb2_map_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+\tint ret, i, id;\n+\tu8 prio;\n+\n+\tdlb2_log_map_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_map_qid_args(hw,\n+\t\t\t\t       domain_id,\n+\t\t\t\t       args,\n+\t\t\t\t       resp,\n+\t\t\t\t       vdev_req,\n+\t\t\t\t       vdev_id);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tprio = args->priority;\n+\n+\tdomain = dlb2_get_domain_from_id(hw, domain_id, vdev_req, vdev_id);\n+\tif (!domain) {\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) {\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) {\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 there are any outstanding detach operations for this port,\n+\t * attempt to complete them. This may be necessary to free up a QID\n+\t * slot for this requested mapping.\n+\t */\n+\tif (port->num_pending_removals)\n+\t\tdlb2_domain_finish_unmap_port(hw, domain, port);\n+\n+\tret = dlb2_verify_map_qid_slot_available(port, queue, resp);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* Hardware requires disabling the CQ before mapping QIDs. */\n+\tif (port->enabled)\n+\t\tdlb2_ldb_port_cq_disable(hw, port);\n+\n+\t/*\n+\t * If this is only a priority change, don't perform the full QID->CQ\n+\t * mapping procedure\n+\t */\n+\tst = DLB2_QUEUE_MAPPED;\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\tif (prio != port->qid_map[i].priority) {\n+\t\t\tdlb2_ldb_port_change_qid_priority(hw, port, i, args);\n+\t\t\tDLB2_HW_DBG(hw, \"DLB2 map: priority change\\n\");\n+\t\t}\n+\n+\t\tst = DLB2_QUEUE_MAPPED;\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 map_qid_done;\n+\t}\n+\n+\tst = DLB2_QUEUE_UNMAP_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\tif (prio != port->qid_map[i].priority) {\n+\t\t\tdlb2_ldb_port_change_qid_priority(hw, port, i, args);\n+\t\t\tDLB2_HW_DBG(hw, \"DLB2 map: priority change\\n\");\n+\t\t}\n+\n+\t\tst = DLB2_QUEUE_MAPPED;\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 map_qid_done;\n+\t}\n+\n+\t/*\n+\t * If this is a priority change on an in-progress mapping, don't\n+\t * perform the full QID->CQ mapping procedure.\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\tport->qid_map[i].priority = prio;\n+\n+\t\tDLB2_HW_DBG(hw, \"DLB2 map: priority change only\\n\");\n+\n+\t\tgoto map_qid_done;\n+\t}\n+\n+\t/*\n+\t * If this is a priority change on a pending mapping, update the\n+\t * pending priority\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\tport->qid_map[i].pending_priority = prio;\n+\n+\t\tDLB2_HW_DBG(hw, \"DLB2 map: priority change only\\n\");\n+\n+\t\tgoto map_qid_done;\n+\t}\n+\n+\t/*\n+\t * If all the CQ's slots are in use, then there's an unmap in progress\n+\t * (guaranteed by dlb2_verify_map_qid_slot_available()), so add this\n+\t * mapping to pending_map and return. When the removal is completed for\n+\t * the slot's current occupant, this mapping will be performed.\n+\t */\n+\tif (!dlb2_port_find_slot(port, DLB2_QUEUE_UNMAPPED, &i)) {\n+\t\tif (dlb2_port_find_slot(port, DLB2_QUEUE_UNMAP_IN_PROG, &i)) {\n+\t\t\tenum dlb2_qid_map_state st;\n+\n+\t\t\tif (i >= DLB2_MAX_NUM_QIDS_PER_LDB_CQ) {\n+\t\t\t\tDLB2_HW_ERR(hw,\n+\t\t\t\t\t    \"[%s():%d] Internal error: port slot tracking failed\\n\",\n+\t\t\t\t\t    __func__, __LINE__);\n+\t\t\t\treturn -EFAULT;\n+\t\t\t}\n+\n+\t\t\tport->qid_map[i].pending_qid = queue->id.phys_id;\n+\t\t\tport->qid_map[i].pending_priority = prio;\n+\n+\t\t\tst = DLB2_QUEUE_UNMAP_IN_PROG_PENDING_MAP;\n+\n+\t\t\tret = dlb2_port_slot_state_transition(hw, port, queue,\n+\t\t\t\t\t\t\t      i, st);\n+\t\t\tif (ret)\n+\t\t\t\treturn ret;\n+\n+\t\t\tDLB2_HW_DBG(hw, \"DLB2 map: map pending removal\\n\");\n+\n+\t\t\tgoto map_qid_done;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * If the domain has started, a special \"dynamic\" CQ->queue mapping\n+\t * procedure is required in order to safely update the CQ<->QID tables.\n+\t * The \"static\" procedure cannot be used when traffic is flowing,\n+\t * because the CQ<->QID tables cannot be updated atomically and the\n+\t * scheduler won't see the new mapping unless the queue's if_status\n+\t * changes, which isn't guaranteed.\n+\t */\n+\tret = dlb2_ldb_port_map_qid(hw, domain, port, queue, prio);\n+\n+\t/* If ret is less than zero, it's due to an internal error */\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+map_qid_done:\n+\tif (port->enabled)\n+\t\tdlb2_ldb_port_cq_enable(hw, port);\n+\n+\tresp->status = 0;\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/event/dlb2/pf/dlb2_main.c b/drivers/event/dlb2/pf/dlb2_main.c\nindex 582ef53..efa7c1c 100644\n--- a/drivers/event/dlb2/pf/dlb2_main.c\n+++ b/drivers/event/dlb2/pf/dlb2_main.c\n@@ -670,3 +670,13 @@ dlb2_pf_create_dir_port(struct dlb2_hw *hw,\n \t\t\t\t       NOT_VF_REQ,\n \t\t\t\t       PF_ID_ZERO);\n }\n+\n+int\n+dlb2_pf_create_dir_queue(struct dlb2_hw *hw,\n+\t\t\t u32 id,\n+\t\t\t struct dlb2_create_dir_queue_args *args,\n+\t\t\t struct dlb2_cmd_response *resp)\n+{\n+\treturn dlb2_hw_create_dir_queue(hw, id, args, resp, NOT_VF_REQ,\n+\t\t\t\t\tPF_ID_ZERO);\n+}\ndiff --git a/drivers/event/dlb2/pf/dlb2_pf.c b/drivers/event/dlb2/pf/dlb2_pf.c\nindex a6824b1..2541842 100644\n--- a/drivers/event/dlb2/pf/dlb2_pf.c\n+++ b/drivers/event/dlb2/pf/dlb2_pf.c\n@@ -411,6 +411,54 @@ dlb2_pf_dir_port_create(struct dlb2_hw_dev *handle,\n \treturn ret;\n }\n \n+static int\n+dlb2_pf_dir_queue_create(struct dlb2_hw_dev *handle,\n+\t\t\t struct dlb2_create_dir_queue_args *cfg)\n+{\n+\tstruct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;\n+\tstruct dlb2_cmd_response response = {0};\n+\tint ret;\n+\n+\tDLB2_INFO(dev->dlb2_device, \"Entering %s()\\n\", __func__);\n+\n+\tret = dlb2_pf_create_dir_queue(&dlb2_dev->hw,\n+\t\t\t\t       handle->domain_id,\n+\t\t\t\t       cfg,\n+\t\t\t\t       &response);\n+\n+\tcfg->response = response;\n+\n+\tDLB2_INFO(dev->dlb2_device, \"Exiting %s() with ret=%d\\n\",\n+\t\t  __func__, ret);\n+\n+\treturn ret;\n+}\n+\n+static int\n+dlb2_pf_map_qid(struct dlb2_hw_dev *handle,\n+\t\tstruct dlb2_map_qid_args *cfg)\n+{\n+\tstruct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;\n+\tstruct dlb2_cmd_response response = {0};\n+\tint ret;\n+\n+\tDLB2_INFO(dev->dlb2_device, \"Entering %s()\\n\", __func__);\n+\n+\tret = dlb2_hw_map_qid(&dlb2_dev->hw,\n+\t\t\t      handle->domain_id,\n+\t\t\t      cfg,\n+\t\t\t      &response,\n+\t\t\t      false,\n+\t\t\t      0);\n+\n+\tcfg->response = response;\n+\n+\tDLB2_INFO(dev->dlb2_device, \"Exiting %s() with ret=%d\\n\",\n+\t\t  __func__, ret);\n+\n+\treturn ret;\n+}\n+\n static void\n dlb2_pf_iface_fn_ptrs_init(void)\n {\n@@ -425,7 +473,9 @@ dlb2_pf_iface_fn_ptrs_init(void)\n \tdlb2_iface_sched_domain_create = dlb2_pf_sched_domain_create;\n \tdlb2_iface_ldb_queue_create = dlb2_pf_ldb_queue_create;\n \tdlb2_iface_ldb_port_create = dlb2_pf_ldb_port_create;\n+\tdlb2_iface_dir_queue_create = dlb2_pf_dir_queue_create;\n \tdlb2_iface_dir_port_create = dlb2_pf_dir_port_create;\n+\tdlb2_iface_map_qid = dlb2_pf_map_qid;\n \tdlb2_iface_get_sn_allocation = dlb2_pf_get_sn_allocation;\n \tdlb2_iface_set_sn_allocation = dlb2_pf_set_sn_allocation;\n \tdlb2_iface_get_sn_occupancy = dlb2_pf_get_sn_occupancy;\n",
    "prefixes": [
        "12/22"
    ]
}