get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 77493,
    "url": "http://patches.dpdk.org/api/patches/77493/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1599851920-16802-11-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": "<1599851920-16802-11-git-send-email-timothy.mcdaniel@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1599851920-16802-11-git-send-email-timothy.mcdaniel@intel.com",
    "date": "2020-09-11T19:18:28",
    "name": "[v4,10/22] event/dlb: add queue setup",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "7e9480da44009039c819852a2cf44a5dd247d501",
    "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/1599851920-16802-11-git-send-email-timothy.mcdaniel@intel.com/mbox/",
    "series": [
        {
            "id": 12163,
            "url": "http://patches.dpdk.org/api/series/12163/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=12163",
            "date": "2020-09-11T19:18:18",
            "name": "Add DLB PMD",
            "version": 4,
            "mbox": "http://patches.dpdk.org/series/12163/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/77493/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/77493/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 A3E42A04C1;\n\tFri, 11 Sep 2020 21:23:43 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 32CE91C1DB;\n\tFri, 11 Sep 2020 21:22:22 +0200 (CEST)",
            "from mga12.intel.com (mga12.intel.com [192.55.52.136])\n by dpdk.org (Postfix) with ESMTP id 41FF91C133\n for <dev@dpdk.org>; Fri, 11 Sep 2020 21:22:10 +0200 (CEST)",
            "from fmsmga005.fm.intel.com ([10.253.24.32])\n by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 11 Sep 2020 12:22:09 -0700",
            "from txasoft-yocto.an.intel.com ([10.123.72.192])\n by fmsmga005.fm.intel.com with ESMTP; 11 Sep 2020 12:22:09 -0700"
        ],
        "IronPort-SDR": [
            "\n IuwRzhX3rBc0U/l3SmbGfhFgBBTUoSUn0TLGSqIQ1fu45J6IyMBNCCJXYQZqhGGbNaZakmFmR6\n o0+tWDLed7iA==",
            "\n 2ZH+mXuQBrUlM2nDrAOBf6W9KXeqq8eKRPniNfzoq+xdqQyBcWJZPlUnzewlHQ0ebvliYWgSTV\n LtuUdzOU51kQ=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9741\"; a=\"138352268\"",
            "E=Sophos;i=\"5.76,416,1592895600\"; d=\"scan'208\";a=\"138352268\"",
            "E=Sophos;i=\"5.76,416,1592895600\"; d=\"scan'208\";a=\"506375672\""
        ],
        "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 14:18:28 -0500",
        "Message-Id": "<1599851920-16802-11-git-send-email-timothy.mcdaniel@intel.com>",
        "X-Mailer": "git-send-email 1.7.10",
        "In-Reply-To": "<1599851920-16802-1-git-send-email-timothy.mcdaniel@intel.com>",
        "References": "<1599851920-16802-1-git-send-email-timothy.mcdaniel@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v4 10/22] event/dlb: add queue setup",
        "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": "Load balanced (ldb) queues are setup here.\nDirected queues are not set up 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/dlb/dlb.c                  | 294 +++++++++++++\n drivers/event/dlb/dlb_iface.c            |  12 +\n drivers/event/dlb/dlb_iface.h            |  12 +\n drivers/event/dlb/pf/base/dlb_resource.c | 710 ++++++++++++++++++++++++-------\n drivers/event/dlb/pf/dlb_pf.c            |  81 ++++\n 5 files changed, 947 insertions(+), 162 deletions(-)",
    "diff": "diff --git a/drivers/event/dlb/dlb.c b/drivers/event/dlb/dlb.c\nindex fa9213c..0b474a5 100644\n--- a/drivers/event/dlb/dlb.c\n+++ b/drivers/event/dlb/dlb.c\n@@ -662,6 +662,299 @@ dlb_eventdev_queue_default_conf_get(struct rte_eventdev *dev,\n \tqueue_conf->priority = 0;\n }\n \n+static int32_t\n+dlb_hw_create_ldb_queue(struct dlb_eventdev *dlb,\n+\t\t\tstruct dlb_queue *queue,\n+\t\t\tconst struct rte_event_queue_conf *evq_conf)\n+{\n+\tstruct dlb_hw_dev *handle = &dlb->qm_instance;\n+\tstruct dlb_create_ldb_queue_args cfg;\n+\tstruct dlb_cmd_response response;\n+\tint32_t ret;\n+\tuint32_t qm_qid;\n+\tint sched_type = -1;\n+\n+\tif (evq_conf == NULL)\n+\t\treturn -EINVAL;\n+\n+\tif (evq_conf->event_queue_cfg & RTE_EVENT_QUEUE_CFG_ALL_TYPES) {\n+\t\tif (evq_conf->nb_atomic_order_sequences != 0)\n+\t\t\tsched_type = RTE_SCHED_TYPE_ORDERED;\n+\t\telse\n+\t\t\tsched_type = RTE_SCHED_TYPE_PARALLEL;\n+\t} else {\n+\t\tsched_type = evq_conf->schedule_type;\n+\t}\n+\n+\tcfg.response = (uintptr_t)&response;\n+\tcfg.num_atomic_inflights = dlb->num_atm_inflights_per_queue;\n+\tcfg.num_sequence_numbers = evq_conf->nb_atomic_order_sequences;\n+\tcfg.num_qid_inflights = evq_conf->nb_atomic_order_sequences;\n+\n+\tif (sched_type != RTE_SCHED_TYPE_ORDERED) {\n+\t\tcfg.num_sequence_numbers = 0;\n+\t\tcfg.num_qid_inflights = DLB_DEF_UNORDERED_QID_INFLIGHTS;\n+\t}\n+\n+\tret = dlb_iface_ldb_queue_create(handle, &cfg);\n+\tif (ret < 0) {\n+\t\tDLB_LOG_ERR(\"dlb: create LB event queue error, ret=%d (driver status: %s)\\n\",\n+\t\t\t    ret, dlb_error_strings[response.status]);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tqm_qid = response.id;\n+\n+\t/* Save off queue config for debug, resource lookups, and reconfig */\n+\tqueue->num_qid_inflights = cfg.num_qid_inflights;\n+\tqueue->num_atm_inflights = cfg.num_atomic_inflights;\n+\n+\tqueue->sched_type = sched_type;\n+\tqueue->config_state = DLB_CONFIGURED;\n+\n+\tDLB_LOG_DBG(\"Created LB event queue %d, nb_inflights=%d, nb_seq=%d, qid inflights=%d\\n\",\n+\t\t    qm_qid,\n+\t\t    cfg.num_atomic_inflights,\n+\t\t    cfg.num_sequence_numbers,\n+\t\t    cfg.num_qid_inflights);\n+\n+\treturn qm_qid;\n+}\n+\n+static int32_t\n+dlb_get_sn_allocation(struct dlb_eventdev *dlb, int group)\n+{\n+\tstruct dlb_hw_dev *handle = &dlb->qm_instance;\n+\tstruct dlb_get_sn_allocation_args cfg;\n+\tstruct dlb_cmd_response response;\n+\tint ret;\n+\n+\tcfg.group = group;\n+\tcfg.response = (uintptr_t)&response;\n+\n+\tret = dlb_iface_get_sn_allocation(handle, &cfg);\n+\tif (ret < 0) {\n+\t\tDLB_LOG_ERR(\"dlb: get_sn_allocation ret=%d (driver status: %s)\\n\",\n+\t\t\t    ret, dlb_error_strings[response.status]);\n+\t\treturn ret;\n+\t}\n+\n+\treturn response.id;\n+}\n+\n+static int\n+dlb_set_sn_allocation(struct dlb_eventdev *dlb, int group, int num)\n+{\n+\tstruct dlb_hw_dev *handle = &dlb->qm_instance;\n+\tstruct dlb_set_sn_allocation_args cfg;\n+\tstruct dlb_cmd_response response;\n+\tint ret;\n+\n+\tcfg.num = num;\n+\tcfg.group = group;\n+\tcfg.response = (uintptr_t)&response;\n+\n+\tret = dlb_iface_set_sn_allocation(handle, &cfg);\n+\tif (ret < 0) {\n+\t\tDLB_LOG_ERR(\"dlb: set_sn_allocation ret=%d (driver status: %s)\\n\",\n+\t\t\t    ret, dlb_error_strings[response.status]);\n+\t\treturn ret;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static int32_t\n+dlb_get_sn_occupancy(struct dlb_eventdev *dlb, int group)\n+{\n+\tstruct dlb_hw_dev *handle = &dlb->qm_instance;\n+\tstruct dlb_get_sn_occupancy_args cfg;\n+\tstruct dlb_cmd_response response;\n+\tint ret;\n+\n+\tcfg.group = group;\n+\tcfg.response = (uintptr_t)&response;\n+\n+\tret = dlb_iface_get_sn_occupancy(handle, &cfg);\n+\tif (ret < 0) {\n+\t\tDLB_LOG_ERR(\"dlb: get_sn_occupancy ret=%d (driver status: %s)\\n\",\n+\t\t\t    ret, dlb_error_strings[response.status]);\n+\t\treturn ret;\n+\t}\n+\n+\treturn response.id;\n+}\n+\n+/* Query the current sequence number allocations and, if they conflict with the\n+ * requested LDB queue configuration, attempt to re-allocate sequence numbers.\n+ * This is best-effort; if it fails, the PMD will attempt to configure the\n+ * load-balanced queue and return an error.\n+ */\n+static void\n+dlb_program_sn_allocation(struct dlb_eventdev *dlb,\n+\t\t\t  const struct rte_event_queue_conf *queue_conf)\n+{\n+\tint grp_occupancy[DLB_NUM_SN_GROUPS];\n+\tint grp_alloc[DLB_NUM_SN_GROUPS];\n+\tint i, sequence_numbers;\n+\n+\tsequence_numbers = (int)queue_conf->nb_atomic_order_sequences;\n+\n+\tfor (i = 0; i < DLB_NUM_SN_GROUPS; i++) {\n+\t\tint total_slots;\n+\n+\t\tgrp_alloc[i] = dlb_get_sn_allocation(dlb, i);\n+\t\tif (grp_alloc[i] < 0)\n+\t\t\treturn;\n+\n+\t\ttotal_slots = DLB_MAX_LDB_SN_ALLOC / grp_alloc[i];\n+\n+\t\tgrp_occupancy[i] = dlb_get_sn_occupancy(dlb, i);\n+\t\tif (grp_occupancy[i] < 0)\n+\t\t\treturn;\n+\n+\t\t/* DLB has at least one available slot for the requested\n+\t\t * sequence numbers, so no further configuration required.\n+\t\t */\n+\t\tif (grp_alloc[i] == sequence_numbers &&\n+\t\t    grp_occupancy[i] < total_slots)\n+\t\t\treturn;\n+\t}\n+\n+\t/* None of the sequence number groups are configured for the requested\n+\t * sequence numbers, so we have to reconfigure one of them. This is\n+\t * only possible if a group is not in use.\n+\t */\n+\tfor (i = 0; i < DLB_NUM_SN_GROUPS; i++) {\n+\t\tif (grp_occupancy[i] == 0)\n+\t\t\tbreak;\n+\t}\n+\n+\tif (i == DLB_NUM_SN_GROUPS) {\n+\t\tprintf(\"[%s()] No groups with %d sequence_numbers are available or have free slots\\n\",\n+\t\t       __func__, sequence_numbers);\n+\t\treturn;\n+\t}\n+\n+\t/* Attempt to configure slot i with the requested number of sequence\n+\t * numbers. Ignore the return value -- if this fails, the error will be\n+\t * caught during subsequent queue configuration.\n+\t */\n+\tdlb_set_sn_allocation(dlb, i, sequence_numbers);\n+}\n+\n+static int\n+dlb_eventdev_ldb_queue_setup(struct rte_eventdev *dev,\n+\t\t\t     struct dlb_eventdev_queue *ev_queue,\n+\t\t\t     const struct rte_event_queue_conf *queue_conf)\n+{\n+\tstruct dlb_eventdev *dlb = dlb_pmd_priv(dev);\n+\tint32_t qm_qid;\n+\n+\tif (queue_conf->nb_atomic_order_sequences)\n+\t\tdlb_program_sn_allocation(dlb, queue_conf);\n+\n+\tqm_qid = dlb_hw_create_ldb_queue(dlb,\n+\t\t\t\t\t &ev_queue->qm_queue,\n+\t\t\t\t\t queue_conf);\n+\tif (qm_qid < 0) {\n+\t\tDLB_LOG_ERR(\"Failed to create the load-balanced queue\\n\");\n+\n+\t\treturn qm_qid;\n+\t}\n+\n+\tdlb->qm_ldb_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 dlb_num_dir_queues_setup(struct dlb_eventdev *dlb)\n+{\n+\tint i, num = 0;\n+\n+\tfor (i = 0; i < dlb->num_queues; i++) {\n+\t\tif (dlb->ev_queues[i].setup_done &&\n+\t\t    dlb->ev_queues[i].qm_queue.is_directed)\n+\t\t\tnum++;\n+\t}\n+\n+\treturn num;\n+}\n+\n+static void\n+dlb_queue_link_teardown(struct dlb_eventdev *dlb,\n+\t\t\tstruct dlb_eventdev_queue *ev_queue)\n+{\n+\tstruct dlb_eventdev_port *ev_port;\n+\tint i, j;\n+\n+\tfor (i = 0; i < dlb->num_ports; i++) {\n+\t\tev_port = &dlb->ev_ports[i];\n+\n+\t\tfor (j = 0; j < DLB_MAX_NUM_QIDS_PER_LDB_CQ; j++) {\n+\t\t\tif (!ev_port->link[j].valid ||\n+\t\t\t    ev_port->link[j].queue_id != ev_queue->id)\n+\t\t\t\tcontinue;\n+\n+\t\t\tev_port->link[j].valid = false;\n+\t\t\tev_port->num_links--;\n+\t\t}\n+\t}\n+\n+\tev_queue->num_links = 0;\n+}\n+\n+static int\n+dlb_eventdev_queue_setup(struct rte_eventdev *dev,\n+\t\t\t uint8_t ev_qid,\n+\t\t\t const struct rte_event_queue_conf *queue_conf)\n+{\n+\tstruct dlb_eventdev *dlb = dlb_pmd_priv(dev);\n+\tstruct dlb_eventdev_queue *ev_queue;\n+\tint ret;\n+\n+\tif (!queue_conf)\n+\t\treturn -EINVAL;\n+\n+\tif (ev_qid >= dlb->num_queues)\n+\t\treturn -EINVAL;\n+\n+\tev_queue = &dlb->ev_queues[ev_qid];\n+\n+\tev_queue->qm_queue.is_directed = queue_conf->event_queue_cfg &\n+\t\tRTE_EVENT_QUEUE_CFG_SINGLE_LINK;\n+\tev_queue->id = ev_qid;\n+\tev_queue->conf = *queue_conf;\n+\n+\tif (!ev_queue->qm_queue.is_directed) {\n+\t\tret = dlb_eventdev_ldb_queue_setup(dev, ev_queue, queue_conf);\n+\t} else {\n+\t\t/* The directed queue isn't setup until link time, at which\n+\t\t * point we know its directed port ID. Directed queue setup\n+\t\t * will only fail if this queue is already setup or there are\n+\t\t * no directed queues left to configure.\n+\t\t */\n+\t\tret = 0;\n+\n+\t\tev_queue->qm_queue.config_state = DLB_NOT_CONFIGURED;\n+\n+\t\tif (ev_queue->setup_done ||\n+\t\t    dlb_num_dir_queues_setup(dlb) == dlb->num_dir_queues)\n+\t\t\tret = -EINVAL;\n+\t}\n+\n+\t/* Tear down pre-existing port->queue links */\n+\tif (!ret && dlb->run_state == DLB_RUN_STATE_STOPPED)\n+\t\tdlb_queue_link_teardown(dlb, ev_queue);\n+\n+\tif (!ret)\n+\t\tev_queue->setup_done = true;\n+\n+\treturn ret;\n+}\n+\n static int\n set_dev_id(const char *key __rte_unused,\n \t   const char *value,\n@@ -740,6 +1033,7 @@ dlb_entry_points_init(struct rte_eventdev *dev)\n \t\t.dev_configure    = dlb_eventdev_configure,\n \t\t.queue_def_conf   = dlb_eventdev_queue_default_conf_get,\n \t\t.port_def_conf    = dlb_eventdev_port_default_conf_get,\n+\t\t.queue_setup      = dlb_eventdev_queue_setup,\n \t\t.dump             = dlb_eventdev_dump,\n \t\t.xstats_get       = dlb_eventdev_xstats_get,\n \t\t.xstats_get_names = dlb_eventdev_xstats_get_names,\ndiff --git a/drivers/event/dlb/dlb_iface.c b/drivers/event/dlb/dlb_iface.c\nindex 9f74d43..b5757c9 100644\n--- a/drivers/event/dlb/dlb_iface.c\n+++ b/drivers/event/dlb/dlb_iface.c\n@@ -47,6 +47,18 @@ int (*dlb_iface_ldb_credit_pool_create)(struct dlb_hw_dev *handle,\n int (*dlb_iface_dir_credit_pool_create)(struct dlb_hw_dev *handle,\n \t\t\t\t\tstruct dlb_create_dir_pool_args *cfg);\n \n+int (*dlb_iface_ldb_queue_create)(struct dlb_hw_dev *handle,\n+\t\t\t\t  struct dlb_create_ldb_queue_args *cfg);\n+\n int (*dlb_iface_get_cq_poll_mode)(struct dlb_hw_dev *handle,\n \t\t\t\t  enum dlb_cq_poll_modes *mode);\n \n+int (*dlb_iface_get_sn_allocation)(struct dlb_hw_dev *handle,\n+\t\t\t\t   struct dlb_get_sn_allocation_args *args);\n+\n+int (*dlb_iface_set_sn_allocation)(struct dlb_hw_dev *handle,\n+\t\t\t\t   struct dlb_set_sn_allocation_args *args);\n+\n+int (*dlb_iface_get_sn_occupancy)(struct dlb_hw_dev *handle,\n+\t\t\t\t  struct dlb_get_sn_occupancy_args *args);\n+\ndiff --git a/drivers/event/dlb/dlb_iface.h b/drivers/event/dlb/dlb_iface.h\nindex d576232..af1416d 100644\n--- a/drivers/event/dlb/dlb_iface.h\n+++ b/drivers/event/dlb/dlb_iface.h\n@@ -32,7 +32,19 @@ extern int (*dlb_iface_ldb_credit_pool_create)(struct dlb_hw_dev *handle,\n extern int (*dlb_iface_dir_credit_pool_create)(struct dlb_hw_dev *handle,\n \t\t\t\t\tstruct dlb_create_dir_pool_args *cfg);\n \n+extern int (*dlb_iface_ldb_queue_create)(struct dlb_hw_dev *handle,\n+\t\t\t\t  struct dlb_create_ldb_queue_args *cfg);\n+\n extern int (*dlb_iface_get_cq_poll_mode)(struct dlb_hw_dev *handle,\n \t\t\t\t\t enum dlb_cq_poll_modes *mode);\n \n+extern int (*dlb_iface_get_sn_allocation)(struct dlb_hw_dev *handle,\n+\t\t\t\t  struct dlb_get_sn_allocation_args *args);\n+\n+extern int (*dlb_iface_set_sn_allocation)(struct dlb_hw_dev *handle,\n+\t\t\t\t  struct dlb_set_sn_allocation_args *args);\n+\n+extern int (*dlb_iface_get_sn_occupancy)(struct dlb_hw_dev *handle,\n+\t\t\t\t  struct dlb_get_sn_occupancy_args *args);\n+\n #endif /* _DLB_IFACE_H */\ndiff --git a/drivers/event/dlb/pf/base/dlb_resource.c b/drivers/event/dlb/pf/base/dlb_resource.c\nindex 0d0bbf9..2b80e03 100644\n--- a/drivers/event/dlb/pf/base/dlb_resource.c\n+++ b/drivers/event/dlb/pf/base/dlb_resource.c\n@@ -1823,168 +1823,6 @@ int dlb_hw_create_sched_domain(struct dlb_hw *hw,\n }\n \n static void\n-dlb_configure_ldb_credit_pool(struct dlb_hw *hw,\n-\t\t\t      struct dlb_domain *domain,\n-\t\t\t      struct dlb_create_ldb_pool_args *args,\n-\t\t\t      struct dlb_credit_pool *pool)\n-{\n-\tunion dlb_sys_ldb_pool_enbld r0 = { {0} };\n-\tunion dlb_chp_ldb_pool_crd_lim r1 = { {0} };\n-\tunion dlb_chp_ldb_pool_crd_cnt r2 = { {0} };\n-\tunion dlb_chp_qed_fl_base  r3 = { {0} };\n-\tunion dlb_chp_qed_fl_lim r4 = { {0} };\n-\tunion dlb_chp_qed_fl_push_ptr r5 = { {0} };\n-\tunion dlb_chp_qed_fl_pop_ptr  r6 = { {0} };\n-\n-\tr1.field.limit = args->num_ldb_credits;\n-\n-\tDLB_CSR_WR(hw, DLB_CHP_LDB_POOL_CRD_LIM(pool->id), r1.val);\n-\n-\tr2.field.count = args->num_ldb_credits;\n-\n-\tDLB_CSR_WR(hw, DLB_CHP_LDB_POOL_CRD_CNT(pool->id), r2.val);\n-\n-\tr3.field.base = domain->qed_freelist.base + domain->qed_freelist.offset;\n-\n-\tDLB_CSR_WR(hw, DLB_CHP_QED_FL_BASE(pool->id), r3.val);\n-\n-\tr4.field.freelist_disable = 0;\n-\tr4.field.limit = r3.field.base + args->num_ldb_credits - 1;\n-\n-\tDLB_CSR_WR(hw, DLB_CHP_QED_FL_LIM(pool->id), r4.val);\n-\n-\tr5.field.push_ptr = r3.field.base;\n-\tr5.field.generation = 1;\n-\n-\tDLB_CSR_WR(hw, DLB_CHP_QED_FL_PUSH_PTR(pool->id), r5.val);\n-\n-\tr6.field.pop_ptr = r3.field.base;\n-\tr6.field.generation = 0;\n-\n-\tDLB_CSR_WR(hw, DLB_CHP_QED_FL_POP_PTR(pool->id), r6.val);\n-\n-\tr0.field.pool_enabled = 1;\n-\n-\tDLB_CSR_WR(hw, DLB_SYS_LDB_POOL_ENBLD(pool->id), r0.val);\n-\n-\tpool->avail_credits = args->num_ldb_credits;\n-\tpool->total_credits = args->num_ldb_credits;\n-\tdomain->qed_freelist.offset += args->num_ldb_credits;\n-\n-\tpool->configured = true;\n-}\n-\n-static int\n-dlb_verify_create_ldb_pool_args(struct dlb_hw *hw,\n-\t\t\t\tu32 domain_id,\n-\t\t\t\tstruct dlb_create_ldb_pool_args *args,\n-\t\t\t\tstruct dlb_cmd_response *resp)\n-{\n-\tstruct dlb_freelist *qed_freelist;\n-\tstruct dlb_domain *domain;\n-\n-\tdomain = dlb_get_domain_from_id(hw, domain_id);\n-\n-\tif (!domain) {\n-\t\tresp->status = DLB_ST_INVALID_DOMAIN_ID;\n-\t\treturn -1;\n-\t}\n-\n-\tif (!domain->configured) {\n-\t\tresp->status = DLB_ST_DOMAIN_NOT_CONFIGURED;\n-\t\treturn -1;\n-\t}\n-\n-\tqed_freelist = &domain->qed_freelist;\n-\n-\tif (dlb_freelist_count(qed_freelist) < args->num_ldb_credits) {\n-\t\tresp->status = DLB_ST_LDB_CREDITS_UNAVAILABLE;\n-\t\treturn -1;\n-\t}\n-\n-\tif (dlb_list_empty(&domain->avail_ldb_credit_pools)) {\n-\t\tresp->status = DLB_ST_LDB_CREDIT_POOLS_UNAVAILABLE;\n-\t\treturn -1;\n-\t}\n-\n-\tif (domain->started) {\n-\t\tresp->status = DLB_ST_DOMAIN_STARTED;\n-\t\treturn -1;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-static void\n-dlb_log_create_ldb_pool_args(struct dlb_hw *hw,\n-\t\t\t     u32 domain_id,\n-\t\t\t     struct dlb_create_ldb_pool_args *args)\n-{\n-\tDLB_HW_INFO(hw, \"DLB create load-balanced credit pool arguments:\\n\");\n-\tDLB_HW_INFO(hw, \"\\tDomain ID:             %d\\n\", domain_id);\n-\tDLB_HW_INFO(hw, \"\\tNumber of LDB credits: %d\\n\",\n-\t\t    args->num_ldb_credits);\n-}\n-\n-/**\n- * dlb_hw_create_ldb_pool() - Allocate and initialize a DLB credit pool.\n- * @hw:\t  Contains the current state of the DLB hardware.\n- * @args: User-provided arguments.\n- * @resp: Response to user.\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 dlb_hw_create_ldb_pool(struct dlb_hw *hw,\n-\t\t\t   u32 domain_id,\n-\t\t\t   struct dlb_create_ldb_pool_args *args,\n-\t\t\t   struct dlb_cmd_response *resp)\n-{\n-\tstruct dlb_credit_pool *pool;\n-\tstruct dlb_domain *domain;\n-\n-\tdlb_log_create_ldb_pool_args(hw, domain_id, args);\n-\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-\tif (dlb_verify_create_ldb_pool_args(hw, domain_id, args, resp))\n-\t\treturn -EINVAL;\n-\n-\tdomain = dlb_get_domain_from_id(hw, domain_id);\n-\tif (!domain) {\n-\t\tDLB_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-\tpool = DLB_DOM_LIST_HEAD(domain->avail_ldb_credit_pools, typeof(*pool));\n-\n-\t/* Verification should catch this. */\n-\tif (!pool) {\n-\t\tDLB_HW_ERR(hw,\n-\t\t\t   \"[%s():%d] Internal error: no available ldb credit pools\\n\",\n-\t\t\t   __func__, __LINE__);\n-\t\treturn -EFAULT;\n-\t}\n-\n-\tdlb_configure_ldb_credit_pool(hw, domain, args, pool);\n-\n-\t/* Configuration succeeded, so move the resource from the 'avail' to\n-\t * the 'used' list.\n-\t */\n-\tdlb_list_del(&domain->avail_ldb_credit_pools, &pool->domain_list);\n-\n-\tdlb_list_add(&domain->used_ldb_credit_pools, &pool->domain_list);\n-\n-\tresp->status = 0;\n-\tresp->id = pool->id;\n-\n-\treturn 0;\n-}\n-\n-static void\n dlb_configure_dir_credit_pool(struct dlb_hw *hw,\n \t\t\t      struct dlb_domain *domain,\n \t\t\t      struct dlb_create_dir_pool_args *args,\n@@ -4212,3 +4050,551 @@ void dlb_hw_disable_vf_to_pf_isr_pend_err(struct dlb_hw *hw)\n \n \tDLB_CSR_WR(hw, DLB_SYS_SYS_ALARM_INT_ENABLE, r0.val);\n }\n+\n+static void\n+dlb_configure_ldb_credit_pool(struct dlb_hw *hw,\n+\t\t\t      struct dlb_domain *domain,\n+\t\t\t      struct dlb_create_ldb_pool_args *args,\n+\t\t\t      struct dlb_credit_pool *pool)\n+{\n+\tunion dlb_sys_ldb_pool_enbld r0 = { {0} };\n+\tunion dlb_chp_ldb_pool_crd_lim r1 = { {0} };\n+\tunion dlb_chp_ldb_pool_crd_cnt r2 = { {0} };\n+\tunion dlb_chp_qed_fl_base  r3 = { {0} };\n+\tunion dlb_chp_qed_fl_lim r4 = { {0} };\n+\tunion dlb_chp_qed_fl_push_ptr r5 = { {0} };\n+\tunion dlb_chp_qed_fl_pop_ptr  r6 = { {0} };\n+\n+\tr1.field.limit = args->num_ldb_credits;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_LDB_POOL_CRD_LIM(pool->id), r1.val);\n+\n+\tr2.field.count = args->num_ldb_credits;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_LDB_POOL_CRD_CNT(pool->id), r2.val);\n+\n+\tr3.field.base = domain->qed_freelist.base + domain->qed_freelist.offset;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_QED_FL_BASE(pool->id), r3.val);\n+\n+\tr4.field.freelist_disable = 0;\n+\tr4.field.limit = r3.field.base + args->num_ldb_credits - 1;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_QED_FL_LIM(pool->id), r4.val);\n+\n+\tr5.field.push_ptr = r3.field.base;\n+\tr5.field.generation = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_QED_FL_PUSH_PTR(pool->id), r5.val);\n+\n+\tr6.field.pop_ptr = r3.field.base;\n+\tr6.field.generation = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_QED_FL_POP_PTR(pool->id), r6.val);\n+\n+\tr0.field.pool_enabled = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_POOL_ENBLD(pool->id), r0.val);\n+\n+\tpool->avail_credits = args->num_ldb_credits;\n+\tpool->total_credits = args->num_ldb_credits;\n+\tdomain->qed_freelist.offset += args->num_ldb_credits;\n+\n+\tpool->configured = true;\n+}\n+\n+static int\n+dlb_verify_create_ldb_pool_args(struct dlb_hw *hw,\n+\t\t\t\tu32 domain_id,\n+\t\t\t\tstruct dlb_create_ldb_pool_args *args,\n+\t\t\t\tstruct dlb_cmd_response *resp)\n+{\n+\tstruct dlb_freelist *qed_freelist;\n+\tstruct dlb_domain *domain;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id);\n+\n+\tif (!domain) {\n+\t\tresp->status = DLB_ST_INVALID_DOMAIN_ID;\n+\t\treturn -1;\n+\t}\n+\n+\tif (!domain->configured) {\n+\t\tresp->status = DLB_ST_DOMAIN_NOT_CONFIGURED;\n+\t\treturn -1;\n+\t}\n+\n+\tqed_freelist = &domain->qed_freelist;\n+\n+\tif (dlb_freelist_count(qed_freelist) < args->num_ldb_credits) {\n+\t\tresp->status = DLB_ST_LDB_CREDITS_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\tif (dlb_list_empty(&domain->avail_ldb_credit_pools)) {\n+\t\tresp->status = DLB_ST_LDB_CREDIT_POOLS_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\tif (domain->started) {\n+\t\tresp->status = DLB_ST_DOMAIN_STARTED;\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void\n+dlb_log_create_ldb_pool_args(struct dlb_hw *hw,\n+\t\t\t     u32 domain_id,\n+\t\t\t     struct dlb_create_ldb_pool_args *args)\n+{\n+\tDLB_HW_INFO(hw, \"DLB create load-balanced credit pool arguments:\\n\");\n+\tDLB_HW_INFO(hw, \"\\tDomain ID:             %d\\n\", domain_id);\n+\tDLB_HW_INFO(hw, \"\\tNumber of LDB credits: %d\\n\",\n+\t\t    args->num_ldb_credits);\n+}\n+\n+static void dlb_configure_ldb_queue(struct dlb_hw *hw,\n+\t\t\t\t    struct dlb_domain *domain,\n+\t\t\t\t    struct dlb_ldb_queue *queue,\n+\t\t\t\t    struct dlb_create_ldb_queue_args *args)\n+{\n+\tunion dlb_sys_ldb_vasqid_v r0 = { {0} };\n+\tunion dlb_lsp_qid_ldb_infl_lim r1 = { {0} };\n+\tunion dlb_lsp_qid_aqed_active_lim r2 = { {0} };\n+\tunion dlb_aqed_pipe_fl_lim r3 = { {0} };\n+\tunion dlb_aqed_pipe_fl_base r4 = { {0} };\n+\tunion dlb_chp_ord_qid_sn_map r7 = { {0} };\n+\tunion dlb_sys_ldb_qid_cfg_v r10 = { {0} };\n+\tunion dlb_sys_ldb_qid_v r11 = { {0} };\n+\tunion dlb_aqed_pipe_fl_push_ptr r5 = { {0} };\n+\tunion dlb_aqed_pipe_fl_pop_ptr r6 = { {0} };\n+\tunion dlb_aqed_pipe_qid_fid_lim r8 = { {0} };\n+\tunion dlb_ro_pipe_qid2grpslt r9 = { {0} };\n+\tstruct dlb_sn_group *sn_group;\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 * DLB_MAX_NUM_LDB_QUEUES + queue->id;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_VASQID_V(offs), r0.val);\n+\n+\t/*\n+\t * Unordered QIDs get 4K inflights, ordered get as many as the number\n+\t * of sequence numbers.\n+\t */\n+\tr1.field.limit = args->num_qid_inflights;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_QID_LDB_INFL_LIM(queue->id), r1.val);\n+\n+\tr2.field.limit = queue->aqed_freelist.bound -\n+\t\t\t queue->aqed_freelist.base;\n+\n+\tif (r2.field.limit > DLB_MAX_NUM_AQOS_ENTRIES)\n+\t\tr2.field.limit = DLB_MAX_NUM_AQOS_ENTRIES;\n+\n+\t/* AQOS */\n+\tDLB_CSR_WR(hw, DLB_LSP_QID_AQED_ACTIVE_LIM(queue->id), r2.val);\n+\n+\tr3.field.freelist_disable = 0;\n+\tr3.field.limit = queue->aqed_freelist.bound - 1;\n+\n+\tDLB_CSR_WR(hw, DLB_AQED_PIPE_FL_LIM(queue->id), r3.val);\n+\n+\tr4.field.base = queue->aqed_freelist.base;\n+\n+\tDLB_CSR_WR(hw, DLB_AQED_PIPE_FL_BASE(queue->id), r4.val);\n+\n+\tr5.field.push_ptr = r4.field.base;\n+\tr5.field.generation = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_AQED_PIPE_FL_PUSH_PTR(queue->id), r5.val);\n+\n+\tr6.field.pop_ptr = r4.field.base;\n+\tr6.field.generation = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_AQED_PIPE_FL_POP_PTR(queue->id), r6.val);\n+\n+\t/* Configure SNs */\n+\tsn_group = &hw->rsrcs.sn_groups[queue->sn_group];\n+\tr7.field.mode = sn_group->mode;\n+\tr7.field.slot = queue->sn_slot;\n+\tr7.field.grp  = sn_group->id;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_ORD_QID_SN_MAP(queue->id), r7.val);\n+\n+\t/*\n+\t * This register limits the number of inflight flows a queue can have\n+\t * at one time.  It has an upper bound of 2048, but can be\n+\t * over-subscribed. 512 is chosen so that a single queue doesn't use\n+\t * the entire atomic storage, but can use a substantial portion if\n+\t * needed.\n+\t */\n+\tr8.field.qid_fid_limit = 512;\n+\n+\tDLB_CSR_WR(hw, DLB_AQED_PIPE_QID_FID_LIM(queue->id), r8.val);\n+\n+\tr9.field.group = sn_group->id;\n+\tr9.field.slot = queue->sn_slot;\n+\n+\tDLB_CSR_WR(hw, DLB_RO_PIPE_QID2GRPSLT(queue->id), r9.val);\n+\n+\tr10.field.sn_cfg_v = (args->num_sequence_numbers != 0);\n+\tr10.field.fid_cfg_v = (args->num_atomic_inflights != 0);\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_QID_CFG_V(queue->id), r10.val);\n+\n+\tr11.field.qid_v = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_QID_V(queue->id), r11.val);\n+}\n+\n+/**\n+ * dlb_hw_create_ldb_pool() - Allocate and initialize a DLB credit pool.\n+ * @hw:\t  Contains the current state of the DLB hardware.\n+ * @args: User-provided arguments.\n+ * @resp: Response to user.\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 dlb_hw_create_ldb_pool(struct dlb_hw *hw,\n+\t\t\t   u32 domain_id,\n+\t\t\t   struct dlb_create_ldb_pool_args *args,\n+\t\t\t   struct dlb_cmd_response *resp)\n+{\n+\tstruct dlb_credit_pool *pool;\n+\tstruct dlb_domain *domain;\n+\n+\tdlb_log_create_ldb_pool_args(hw, domain_id, args);\n+\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+\tif (dlb_verify_create_ldb_pool_args(hw, domain_id, args, resp))\n+\t\treturn -EINVAL;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id);\n+\tif (!domain) {\n+\t\tDLB_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+\tpool = DLB_DOM_LIST_HEAD(domain->avail_ldb_credit_pools, typeof(*pool));\n+\n+\t/* Verification should catch this. */\n+\tif (!pool) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s():%d] Internal error: no available ldb credit pools\\n\",\n+\t\t\t   __func__, __LINE__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tdlb_configure_ldb_credit_pool(hw, domain, args, pool);\n+\n+\t/* Configuration succeeded, so move the resource from the 'avail' to\n+\t * the 'used' list.\n+\t */\n+\tdlb_list_del(&domain->avail_ldb_credit_pools, &pool->domain_list);\n+\n+\tdlb_list_add(&domain->used_ldb_credit_pools, &pool->domain_list);\n+\n+\tresp->status = 0;\n+\tresp->id = pool->id;\n+\n+\treturn 0;\n+}\n+\n+int dlb_get_group_sequence_numbers(struct dlb_hw *hw, unsigned int group_id)\n+{\n+\tif (group_id >= DLB_MAX_NUM_SEQUENCE_NUMBER_GROUPS)\n+\t\treturn -EINVAL;\n+\n+\treturn hw->rsrcs.sn_groups[group_id].sequence_numbers_per_queue;\n+}\n+\n+int dlb_get_group_sequence_number_occupancy(struct dlb_hw *hw,\n+\t\t\t\t\t    unsigned int group_id)\n+{\n+\tif (group_id >= DLB_MAX_NUM_SEQUENCE_NUMBER_GROUPS)\n+\t\treturn -EINVAL;\n+\n+\treturn dlb_sn_group_used_slots(&hw->rsrcs.sn_groups[group_id]);\n+}\n+\n+static void dlb_log_set_group_sequence_numbers(struct dlb_hw *hw,\n+\t\t\t\t\t       unsigned int group_id,\n+\t\t\t\t\t       unsigned long val)\n+{\n+\tDLB_HW_INFO(hw, \"DLB set group sequence numbers:\\n\");\n+\tDLB_HW_INFO(hw, \"\\tGroup ID: %u\\n\", group_id);\n+\tDLB_HW_INFO(hw, \"\\tValue:    %lu\\n\", val);\n+}\n+\n+int dlb_set_group_sequence_numbers(struct dlb_hw *hw,\n+\t\t\t\t   unsigned int group_id,\n+\t\t\t\t   unsigned long val)\n+{\n+\tu32 valid_allocations[6] = {32, 64, 128, 256, 512, 1024};\n+\tunion dlb_ro_pipe_grp_sn_mode r0 = { {0} };\n+\tstruct dlb_sn_group *group;\n+\tint mode;\n+\n+\tif (group_id >= DLB_MAX_NUM_SEQUENCE_NUMBER_GROUPS)\n+\t\treturn -EINVAL;\n+\n+\tgroup = &hw->rsrcs.sn_groups[group_id];\n+\n+\t/* Once the first load-balanced queue using an SN group is configured,\n+\t * the group cannot be changed.\n+\t */\n+\tif (group->slot_use_bitmap != 0)\n+\t\treturn -EPERM;\n+\n+\tfor (mode = 0; mode < DLB_MAX_NUM_SEQUENCE_NUMBER_MODES; mode++)\n+\t\tif (val == valid_allocations[mode])\n+\t\t\tbreak;\n+\n+\tif (mode == DLB_MAX_NUM_SEQUENCE_NUMBER_MODES)\n+\t\treturn -EINVAL;\n+\n+\tgroup->mode = mode;\n+\tgroup->sequence_numbers_per_queue = val;\n+\n+\tr0.field.sn_mode_0 = hw->rsrcs.sn_groups[0].mode;\n+\tr0.field.sn_mode_1 = hw->rsrcs.sn_groups[1].mode;\n+\tr0.field.sn_mode_2 = hw->rsrcs.sn_groups[2].mode;\n+\tr0.field.sn_mode_3 = hw->rsrcs.sn_groups[3].mode;\n+\n+\tDLB_CSR_WR(hw, DLB_RO_PIPE_GRP_SN_MODE, r0.val);\n+\n+\tdlb_log_set_group_sequence_numbers(hw, group_id, val);\n+\n+\treturn 0;\n+}\n+\n+static int\n+dlb_ldb_queue_attach_to_sn_group(struct dlb_hw *hw,\n+\t\t\t\t struct dlb_ldb_queue *queue,\n+\t\t\t\t struct dlb_create_ldb_queue_args *args)\n+{\n+\tint slot = -1;\n+\tint i;\n+\n+\tqueue->sn_cfg_valid = false;\n+\n+\tif (args->num_sequence_numbers == 0)\n+\t\treturn 0;\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_SEQUENCE_NUMBER_GROUPS; i++) {\n+\t\tstruct dlb_sn_group *group = &hw->rsrcs.sn_groups[i];\n+\n+\t\tif (group->sequence_numbers_per_queue ==\n+\t\t    args->num_sequence_numbers &&\n+\t\t    !dlb_sn_group_full(group)) {\n+\t\t\tslot = dlb_sn_group_alloc_slot(group);\n+\t\t\tif (slot >= 0)\n+\t\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tif (slot == -1) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s():%d] Internal error: no sequence number slots available\\n\",\n+\t\t\t   __func__, __LINE__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tqueue->sn_cfg_valid = true;\n+\tqueue->sn_group = i;\n+\tqueue->sn_slot = slot;\n+\treturn 0;\n+}\n+\n+static int\n+dlb_ldb_queue_attach_resources(struct dlb_hw *hw,\n+\t\t\t       struct dlb_domain *domain,\n+\t\t\t       struct dlb_ldb_queue *queue,\n+\t\t\t       struct dlb_create_ldb_queue_args *args)\n+{\n+\tint ret;\n+\n+\tret = dlb_ldb_queue_attach_to_sn_group(hw, queue, args);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* Attach QID inflights */\n+\tqueue->num_qid_inflights = args->num_qid_inflights;\n+\n+\t/* Attach atomic inflights */\n+\tqueue->aqed_freelist.base = domain->aqed_freelist.base +\n+\t\t\t\t    domain->aqed_freelist.offset;\n+\tqueue->aqed_freelist.bound = queue->aqed_freelist.base +\n+\t\t\t\t     args->num_atomic_inflights;\n+\tdomain->aqed_freelist.offset += args->num_atomic_inflights;\n+\n+\treturn 0;\n+}\n+\n+static int\n+dlb_verify_create_ldb_queue_args(struct dlb_hw *hw,\n+\t\t\t\t u32 domain_id,\n+\t\t\t\t struct dlb_create_ldb_queue_args *args,\n+\t\t\t\t struct dlb_cmd_response *resp)\n+{\n+\tstruct dlb_freelist *aqed_freelist;\n+\tstruct dlb_domain *domain;\n+\tint i;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id);\n+\n+\tif (!domain) {\n+\t\tresp->status = DLB_ST_INVALID_DOMAIN_ID;\n+\t\treturn -1;\n+\t}\n+\n+\tif (!domain->configured) {\n+\t\tresp->status = DLB_ST_DOMAIN_NOT_CONFIGURED;\n+\t\treturn -1;\n+\t}\n+\n+\tif (domain->started) {\n+\t\tresp->status = DLB_ST_DOMAIN_STARTED;\n+\t\treturn -1;\n+\t}\n+\n+\tif (dlb_list_empty(&domain->avail_ldb_queues)) {\n+\t\tresp->status = DLB_ST_LDB_QUEUES_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\tif (args->num_sequence_numbers) {\n+\t\tfor (i = 0; i < DLB_MAX_NUM_SEQUENCE_NUMBER_GROUPS; i++) {\n+\t\t\tstruct dlb_sn_group *group = &hw->rsrcs.sn_groups[i];\n+\n+\t\t\tif (group->sequence_numbers_per_queue ==\n+\t\t\t    args->num_sequence_numbers &&\n+\t\t\t    !dlb_sn_group_full(group))\n+\t\t\t\tbreak;\n+\t\t}\n+\n+\t\tif (i == DLB_MAX_NUM_SEQUENCE_NUMBER_GROUPS) {\n+\t\t\tresp->status = DLB_ST_SEQUENCE_NUMBERS_UNAVAILABLE;\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\tif (args->num_qid_inflights > 4096) {\n+\t\tresp->status = DLB_ST_INVALID_QID_INFLIGHT_ALLOCATION;\n+\t\treturn -1;\n+\t}\n+\n+\t/* Inflights must be <= number of sequence numbers if ordered */\n+\tif (args->num_sequence_numbers != 0 &&\n+\t    args->num_qid_inflights > args->num_sequence_numbers) {\n+\t\tresp->status = DLB_ST_INVALID_QID_INFLIGHT_ALLOCATION;\n+\t\treturn -1;\n+\t}\n+\n+\taqed_freelist = &domain->aqed_freelist;\n+\n+\tif (dlb_freelist_count(aqed_freelist) < args->num_atomic_inflights) {\n+\t\tresp->status = DLB_ST_ATOMIC_INFLIGHTS_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void\n+dlb_log_create_ldb_queue_args(struct dlb_hw *hw,\n+\t\t\t      u32 domain_id,\n+\t\t\t      struct dlb_create_ldb_queue_args *args)\n+{\n+\tDLB_HW_INFO(hw, \"DLB create load-balanced queue arguments:\\n\");\n+\tDLB_HW_INFO(hw, \"\\tDomain ID:                  %d\\n\",\n+\t\t    domain_id);\n+\tDLB_HW_INFO(hw, \"\\tNumber of sequence numbers: %d\\n\",\n+\t\t    args->num_sequence_numbers);\n+\tDLB_HW_INFO(hw, \"\\tNumber of QID inflights:    %d\\n\",\n+\t\t    args->num_qid_inflights);\n+\tDLB_HW_INFO(hw, \"\\tNumber of ATM inflights:    %d\\n\",\n+\t\t    args->num_atomic_inflights);\n+}\n+\n+/**\n+ * dlb_hw_create_ldb_queue() - Allocate and initialize a DLB LDB queue.\n+ * @hw:\t  Contains the current state of the DLB hardware.\n+ * @args: User-provided arguments.\n+ * @resp: Response to user.\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 dlb_hw_create_ldb_queue(struct dlb_hw *hw,\n+\t\t\t    u32 domain_id,\n+\t\t\t    struct dlb_create_ldb_queue_args *args,\n+\t\t\t    struct dlb_cmd_response *resp)\n+{\n+\tstruct dlb_ldb_queue *queue;\n+\tstruct dlb_domain *domain;\n+\tint ret;\n+\n+\tdlb_log_create_ldb_queue_args(hw, domain_id, args);\n+\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+\t/* At least one available queue */\n+\tif (dlb_verify_create_ldb_queue_args(hw, domain_id, args, resp))\n+\t\treturn -EINVAL;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id);\n+\tif (!domain) {\n+\t\tDLB_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+\tqueue = DLB_DOM_LIST_HEAD(domain->avail_ldb_queues, typeof(*queue));\n+\n+\t/* Verification should catch this. */\n+\tif (!queue) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s():%d] Internal error: no available ldb queues\\n\",\n+\t\t\t   __func__, __LINE__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tret = dlb_ldb_queue_attach_resources(hw, domain, queue, args);\n+\tif (ret < 0) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s():%d] Internal error: failed to attach the ldb queue resources\\n\",\n+\t\t\t   __func__, __LINE__);\n+\t\treturn ret;\n+\t}\n+\n+\tdlb_configure_ldb_queue(hw, domain, queue, args);\n+\n+\tqueue->num_mappings = 0;\n+\n+\tqueue->configured = true;\n+\n+\t/* Configuration succeeded, so move the resource from the 'avail' to\n+\t * the 'used' list.\n+\t */\n+\tdlb_list_del(&domain->avail_ldb_queues, &queue->domain_list);\n+\n+\tdlb_list_add(&domain->used_ldb_queues, &queue->domain_list);\n+\n+\tresp->status = 0;\n+\tresp->id = queue->id;\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/event/dlb/pf/dlb_pf.c b/drivers/event/dlb/pf/dlb_pf.c\nindex 57a150c..fffb88b 100644\n--- a/drivers/event/dlb/pf/dlb_pf.c\n+++ b/drivers/event/dlb/pf/dlb_pf.c\n@@ -198,6 +198,83 @@ dlb_pf_get_cq_poll_mode(struct dlb_hw_dev *handle,\n \treturn 0;\n }\n \n+static int\n+dlb_pf_ldb_queue_create(struct dlb_hw_dev *handle,\n+\t\t\tstruct dlb_create_ldb_queue_args *cfg)\n+{\n+\tstruct dlb_dev *dlb_dev = (struct dlb_dev *)handle->pf_dev;\n+\tstruct dlb_cmd_response response = {0};\n+\tint ret;\n+\n+\tDLB_INFO(dev->dlb_device, \"Entering %s()\\n\", __func__);\n+\n+\tret = dlb_hw_create_ldb_queue(&dlb_dev->hw,\n+\t\t\t\t      handle->domain_id,\n+\t\t\t\t      cfg,\n+\t\t\t\t      &response);\n+\n+\t*(struct dlb_cmd_response *)cfg->response = response;\n+\n+\tDLB_INFO(dev->dlb_device, \"Exiting %s() with ret=%d\\n\", __func__, ret);\n+\n+\treturn ret;\n+}\n+\n+static int\n+dlb_pf_get_sn_allocation(struct dlb_hw_dev *handle,\n+\t\t\t struct dlb_get_sn_allocation_args *args)\n+{\n+\tstruct dlb_dev *dlb_dev = (struct dlb_dev *)handle->pf_dev;\n+\tstruct dlb_cmd_response response = {0};\n+\tint ret;\n+\n+\tret = dlb_get_group_sequence_numbers(&dlb_dev->hw, args->group);\n+\n+\tresponse.id = ret;\n+\tresponse.status = 0;\n+\n+\t*(struct dlb_cmd_response *)args->response = response;\n+\n+\treturn ret;\n+}\n+\n+static int\n+dlb_pf_set_sn_allocation(struct dlb_hw_dev *handle,\n+\t\t\t struct dlb_set_sn_allocation_args *args)\n+{\n+\tstruct dlb_dev *dlb_dev = (struct dlb_dev *)handle->pf_dev;\n+\tstruct dlb_cmd_response response = {0};\n+\tint ret;\n+\n+\tret = dlb_set_group_sequence_numbers(&dlb_dev->hw, args->group,\n+\t\t\t\t\t     args->num);\n+\n+\tresponse.status = 0;\n+\n+\t*(struct dlb_cmd_response *)args->response = response;\n+\n+\treturn ret;\n+}\n+\n+static int\n+dlb_pf_get_sn_occupancy(struct dlb_hw_dev *handle,\n+\t\t\tstruct dlb_get_sn_occupancy_args *args)\n+{\n+\tstruct dlb_dev *dlb_dev = (struct dlb_dev *)handle->pf_dev;\n+\tstruct dlb_cmd_response response = {0};\n+\tint ret;\n+\n+\tret = dlb_get_group_sequence_number_occupancy(&dlb_dev->hw,\n+\t\t\t\t\t\t      args->group);\n+\n+\tresponse.id = ret;\n+\tresponse.status = 0;\n+\n+\t*(struct dlb_cmd_response *)args->response = response;\n+\n+\treturn ret;\n+}\n+\n static void\n dlb_pf_iface_fn_ptrs_init(void)\n {\n@@ -209,7 +286,11 @@ dlb_pf_iface_fn_ptrs_init(void)\n \tdlb_iface_sched_domain_create = dlb_pf_sched_domain_create;\n \tdlb_iface_ldb_credit_pool_create = dlb_pf_ldb_credit_pool_create;\n \tdlb_iface_dir_credit_pool_create = dlb_pf_dir_credit_pool_create;\n+\tdlb_iface_ldb_queue_create = dlb_pf_ldb_queue_create;\n \tdlb_iface_get_cq_poll_mode = dlb_pf_get_cq_poll_mode;\n+\tdlb_iface_get_sn_allocation = dlb_pf_get_sn_allocation;\n+\tdlb_iface_set_sn_allocation = dlb_pf_set_sn_allocation;\n+\tdlb_iface_get_sn_occupancy = dlb_pf_get_sn_occupancy;\n }\n \n /* PCI DEV HOOKS */\n",
    "prefixes": [
        "v4",
        "10/22"
    ]
}