get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 75055,
    "url": "http://patches.dpdk.org/api/patches/75055/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1596138614-17409-4-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": "<1596138614-17409-4-git-send-email-timothy.mcdaniel@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1596138614-17409-4-git-send-email-timothy.mcdaniel@intel.com",
    "date": "2020-07-30T19:49:50",
    "name": "[03/27] event/dlb: add shared code version 10.7.9",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "1b0853715ca585b6c0b0d1ec629b4f0c7172f808",
    "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/1596138614-17409-4-git-send-email-timothy.mcdaniel@intel.com/mbox/",
    "series": [
        {
            "id": 11425,
            "url": "http://patches.dpdk.org/api/series/11425/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=11425",
            "date": "2020-07-30T19:49:47",
            "name": "Add Intel DLM PMD to 20.11",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/11425/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/75055/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/75055/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 F3F1DA052B;\n\tThu, 30 Jul 2020 21:53:37 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 3437B1C030;\n\tThu, 30 Jul 2020 21:53:13 +0200 (CEST)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n by dpdk.org (Postfix) with ESMTP id A0F1A1C027\n for <dev@dpdk.org>; Thu, 30 Jul 2020 21:53:07 +0200 (CEST)",
            "from orsmga005.jf.intel.com ([10.7.209.41])\n by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 30 Jul 2020 12:53:06 -0700",
            "from txasoft-yocto.an.intel.com ([10.123.72.192])\n by orsmga005.jf.intel.com with ESMTP; 30 Jul 2020 12:53:04 -0700"
        ],
        "IronPort-SDR": [
            "\n tOHa428HiL/BSeNQSZ7DXSvhBbLCsOCErnwCjhnqoZO9IcFsutZV4Ys2PUjNS9I4W+c2bEcaVx\n hAH6IZm/ARKQ==",
            "\n aOgk/KBjM87jmHBFk0e9XuqdXA17a3sOlWbqvTqBvz85Z/aL43lCJcdGZs99J9qa8Hu4zWyCsb\n 4gJa2/N2AaQQ=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9698\"; a=\"139672287\"",
            "E=Sophos;i=\"5.75,415,1589266800\"; d=\"scan'208\";a=\"139672287\"",
            "E=Sophos;i=\"5.75,415,1589266800\"; d=\"scan'208\";a=\"465378073\""
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "From": "\"McDaniel, Timothy\" <timothy.mcdaniel@intel.com>",
        "To": "jerinj@marvell.com",
        "Cc": "mattias.ronnblom@ericsson.com, dev@dpdk.org, gage.eads@intel.com,\n harry.van.haaren@intel.com,\n \"McDaniel, Timothy\" <timothy.mcdaniel@intel.com>",
        "Date": "Thu, 30 Jul 2020 14:49:50 -0500",
        "Message-Id": "<1596138614-17409-4-git-send-email-timothy.mcdaniel@intel.com>",
        "X-Mailer": "git-send-email 1.7.10",
        "In-Reply-To": "<1596138614-17409-1-git-send-email-timothy.mcdaniel@intel.com>",
        "References": "<1593232671-5690-0-git-send-email-timothy.mcdaniel@intel.com>\n <1596138614-17409-1-git-send-email-timothy.mcdaniel@intel.com>",
        "Subject": "[dpdk-dev] [PATCH 03/27] event/dlb: add shared code version 10.7.9",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: \"McDaniel, Timothy\" <timothy.mcdaniel@intel.com>\n\nThe DLB shared code is auto generated by Intel, and is being committed\nhere so that it can be built in the DPDK environment. The shared code\nshould not be modified. The shared code must be present in order to\nsuccessfully build the DLB PMD.\n\nChanges since v1 patch series\n1) convert C99 comment to standard C\n2) remove TODO and FIXME comments\n3) converted to use same log i/f as PMD\n4) disable PF->VF ISR pending access alarm\n5) disable VF->PF ISR pending access alarm\n\nSigned-off-by: McDaniel, Timothy <timothy.mcdaniel@intel.com>\n---\n drivers/event/dlb/pf/base/dlb_hw_types.h     |  360 +\n drivers/event/dlb/pf/base/dlb_mbox.h         |  645 ++\n drivers/event/dlb/pf/base/dlb_osdep.h        |  347 +\n drivers/event/dlb/pf/base/dlb_osdep_bitmap.h |  442 ++\n drivers/event/dlb/pf/base/dlb_osdep_list.h   |  131 +\n drivers/event/dlb/pf/base/dlb_osdep_types.h  |   31 +\n drivers/event/dlb/pf/base/dlb_regs.h         | 2678 +++++++\n drivers/event/dlb/pf/base/dlb_resource.c     | 9722 ++++++++++++++++++++++++++\n drivers/event/dlb/pf/base/dlb_resource.h     | 1639 +++++\n drivers/event/dlb/pf/base/dlb_user.h         | 1084 +++\n 10 files changed, 17079 insertions(+)\n create mode 100644 drivers/event/dlb/pf/base/dlb_hw_types.h\n create mode 100644 drivers/event/dlb/pf/base/dlb_mbox.h\n create mode 100644 drivers/event/dlb/pf/base/dlb_osdep.h\n create mode 100644 drivers/event/dlb/pf/base/dlb_osdep_bitmap.h\n create mode 100644 drivers/event/dlb/pf/base/dlb_osdep_list.h\n create mode 100644 drivers/event/dlb/pf/base/dlb_osdep_types.h\n create mode 100644 drivers/event/dlb/pf/base/dlb_regs.h\n create mode 100644 drivers/event/dlb/pf/base/dlb_resource.c\n create mode 100644 drivers/event/dlb/pf/base/dlb_resource.h\n create mode 100644 drivers/event/dlb/pf/base/dlb_user.h",
    "diff": "diff --git a/drivers/event/dlb/pf/base/dlb_hw_types.h b/drivers/event/dlb/pf/base/dlb_hw_types.h\nnew file mode 100644\nindex 0000000..d56590e\n--- /dev/null\n+++ b/drivers/event/dlb/pf/base/dlb_hw_types.h\n@@ -0,0 +1,360 @@\n+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)\n+ * Copyright(c) 2016-2020 Intel Corporation\n+ */\n+\n+#ifndef __DLB_HW_TYPES_H\n+#define __DLB_HW_TYPES_H\n+\n+#include \"dlb_user.h\"\n+#include \"dlb_osdep_types.h\"\n+#include \"dlb_osdep_list.h\"\n+\n+#define DLB_MAX_NUM_VFS 16\n+#define DLB_MAX_NUM_DOMAINS 32\n+#define DLB_MAX_NUM_LDB_QUEUES 128\n+#define DLB_MAX_NUM_LDB_PORTS 64\n+#define DLB_MAX_NUM_DIR_PORTS 128\n+#define DLB_MAX_NUM_LDB_CREDITS 16384\n+#define DLB_MAX_NUM_DIR_CREDITS 4096\n+#define DLB_MAX_NUM_LDB_CREDIT_POOLS 64\n+#define DLB_MAX_NUM_DIR_CREDIT_POOLS 64\n+#define DLB_MAX_NUM_HIST_LIST_ENTRIES 5120\n+#define DLB_MAX_NUM_AQOS_ENTRIES 2048\n+#define DLB_MAX_NUM_TOTAL_OUTSTANDING_COMPLETIONS 4096\n+#define DLB_MAX_NUM_QIDS_PER_LDB_CQ 8\n+#define DLB_MAX_NUM_SEQUENCE_NUMBER_GROUPS 4\n+#define DLB_MAX_NUM_SEQUENCE_NUMBER_MODES 6\n+#define DLB_QID_PRIORITIES 8\n+#define DLB_NUM_ARB_WEIGHTS 8\n+#define DLB_MAX_WEIGHT 255\n+#define DLB_MAX_PORT_CREDIT_QUANTUM 1023\n+#define DLB_MAX_CQ_COMP_CHECK_LOOPS 409600\n+#define DLB_MAX_QID_EMPTY_CHECK_LOOPS (32 * 64 * 1024 * (800 / 30))\n+#define DLB_HZ 800000000\n+\n+/* Used for DLB A-stepping workaround for hardware write buffer lock up issue */\n+#define DLB_A_STEP_MAX_PORTS 128\n+\n+#define DLB_PF_DEV_ID 0x270B\n+#define DLB_VF_DEV_ID 0x270C\n+\n+/* Interrupt related macros */\n+#define DLB_PF_NUM_NON_CQ_INTERRUPT_VECTORS 8\n+#define DLB_PF_NUM_CQ_INTERRUPT_VECTORS\t 64\n+#define DLB_PF_TOTAL_NUM_INTERRUPT_VECTORS \\\n+\t(DLB_PF_NUM_NON_CQ_INTERRUPT_VECTORS + \\\n+\t DLB_PF_NUM_CQ_INTERRUPT_VECTORS)\n+#define DLB_PF_NUM_COMPRESSED_MODE_VECTORS \\\n+\t(DLB_PF_NUM_NON_CQ_INTERRUPT_VECTORS + 1)\n+#define DLB_PF_NUM_PACKED_MODE_VECTORS\t DLB_PF_TOTAL_NUM_INTERRUPT_VECTORS\n+#define DLB_PF_COMPRESSED_MODE_CQ_VECTOR_ID DLB_PF_NUM_NON_CQ_INTERRUPT_VECTORS\n+\n+#define DLB_VF_NUM_NON_CQ_INTERRUPT_VECTORS 1\n+#define DLB_VF_NUM_CQ_INTERRUPT_VECTORS 31\n+#define DLB_VF_BASE_CQ_VECTOR_ID 0\n+#define DLB_VF_LAST_CQ_VECTOR_ID 30\n+#define DLB_VF_MBOX_VECTOR_ID 31\n+#define DLB_VF_TOTAL_NUM_INTERRUPT_VECTORS \\\n+\t(DLB_VF_NUM_NON_CQ_INTERRUPT_VECTORS + \\\n+\t DLB_VF_NUM_CQ_INTERRUPT_VECTORS)\n+\n+#define DLB_PF_NUM_ALARM_INTERRUPT_VECTORS 4\n+/* DLB ALARM interrupts */\n+#define DLB_INT_ALARM 0\n+/* VF to PF Mailbox Service Request */\n+#define DLB_INT_VF_TO_PF_MBOX 1\n+/* HCW Ingress Errors */\n+#define DLB_INT_INGRESS_ERROR 3\n+\n+#define DLB_ALARM_HW_SOURCE_SYS 0\n+#define DLB_ALARM_HW_SOURCE_DLB 1\n+\n+#define DLB_ALARM_HW_UNIT_CHP 1\n+#define DLB_ALARM_HW_UNIT_LSP 3\n+\n+#define DLB_ALARM_HW_CHP_AID_OUT_OF_CREDITS 6\n+#define DLB_ALARM_HW_CHP_AID_ILLEGAL_ENQ 7\n+#define DLB_ALARM_HW_LSP_AID_EXCESS_TOKEN_POPS 15\n+#define DLB_ALARM_SYS_AID_ILLEGAL_HCW 0\n+#define DLB_ALARM_SYS_AID_ILLEGAL_QID 3\n+#define DLB_ALARM_SYS_AID_DISABLED_QID 4\n+#define DLB_ALARM_SYS_AID_ILLEGAL_CQID 6\n+\n+/* Hardware-defined base addresses */\n+#define DLB_LDB_PP_BASE 0x2100000\n+#define DLB_LDB_PP_STRIDE 0x1000\n+#define DLB_LDB_PP_BOUND \\\n+\t(DLB_LDB_PP_BASE + DLB_LDB_PP_STRIDE * DLB_MAX_NUM_LDB_PORTS)\n+#define DLB_DIR_PP_BASE 0x2000000\n+#define DLB_DIR_PP_STRIDE 0x1000\n+#define DLB_DIR_PP_BOUND \\\n+\t(DLB_DIR_PP_BASE + DLB_DIR_PP_STRIDE * DLB_MAX_NUM_DIR_PORTS)\n+\n+struct dlb_resource_id {\n+\tu32 phys_id;\n+\tu32 virt_id;\n+\tu8 vf_owned;\n+\tu8 vf_id;\n+};\n+\n+struct dlb_freelist {\n+\tu32 base;\n+\tu32 bound;\n+\tu32 offset;\n+};\n+\n+static inline u32 dlb_freelist_count(struct dlb_freelist *list)\n+{\n+\treturn (list->bound - list->base) - list->offset;\n+}\n+\n+struct dlb_hcw {\n+\tu64 data;\n+\t/* Word 3 */\n+\tu16 opaque;\n+\tu8 qid;\n+\tu8 sched_type:2;\n+\tu8 priority:3;\n+\tu8 msg_type:3;\n+\t/* Word 4 */\n+\tu16 lock_id;\n+\tu8 meas_lat:1;\n+\tu8 rsvd1:2;\n+\tu8 no_dec:1;\n+\tu8 cmp_id:4;\n+\tu8 cq_token:1;\n+\tu8 qe_comp:1;\n+\tu8 qe_frag:1;\n+\tu8 qe_valid:1;\n+\tu8 int_arm:1;\n+\tu8 error:1;\n+\tu8 rsvd:2;\n+};\n+\n+struct dlb_ldb_queue {\n+\tstruct dlb_list_entry domain_list;\n+\tstruct dlb_list_entry func_list;\n+\tstruct dlb_resource_id id;\n+\tstruct dlb_resource_id domain_id;\n+\tu32 num_qid_inflights;\n+\tstruct dlb_freelist aqed_freelist;\n+\tu8 sn_cfg_valid;\n+\tu32 sn_group;\n+\tu32 sn_slot;\n+\tu32 num_mappings;\n+\tu8 num_pending_additions;\n+\tu8 owned;\n+\tu8 configured;\n+};\n+\n+/* Directed ports and queues are paired by nature, so the driver tracks them\n+ * with a single data structure.\n+ */\n+struct dlb_dir_pq_pair {\n+\tstruct dlb_list_entry domain_list;\n+\tstruct dlb_list_entry func_list;\n+\tstruct dlb_resource_id id;\n+\tstruct dlb_resource_id domain_id;\n+\tu8 ldb_pool_used;\n+\tu8 dir_pool_used;\n+\tu8 queue_configured;\n+\tu8 port_configured;\n+\tu8 owned;\n+\tu8 enabled;\n+\tu32 ref_cnt;\n+};\n+\n+enum dlb_qid_map_state {\n+\t/* The slot doesn't contain a valid queue mapping */\n+\tDLB_QUEUE_UNMAPPED,\n+\t/* The slot contains a valid queue mapping */\n+\tDLB_QUEUE_MAPPED,\n+\t/* The driver is mapping a queue into this slot */\n+\tDLB_QUEUE_MAP_IN_PROGRESS,\n+\t/* The driver is unmapping a queue from this slot */\n+\tDLB_QUEUE_UNMAP_IN_PROGRESS,\n+\t/* The driver is unmapping a queue from this slot, and once complete\n+\t * will replace it with another mapping.\n+\t */\n+\tDLB_QUEUE_UNMAP_IN_PROGRESS_PENDING_MAP,\n+};\n+\n+struct dlb_ldb_port_qid_map {\n+\tu16 qid;\n+\tu8 priority;\n+\tu16 pending_qid;\n+\tu8 pending_priority;\n+\tenum dlb_qid_map_state state;\n+};\n+\n+struct dlb_ldb_port {\n+\tstruct dlb_list_entry domain_list;\n+\tstruct dlb_list_entry func_list;\n+\tstruct dlb_resource_id id;\n+\tstruct dlb_resource_id domain_id;\n+\tu8 ldb_pool_used;\n+\tu8 dir_pool_used;\n+\tu8 init_tkn_cnt;\n+\tu32 hist_list_entry_base;\n+\tu32 hist_list_entry_limit;\n+\t/* The qid_map represents the hardware QID mapping state. */\n+\tstruct dlb_ldb_port_qid_map qid_map[DLB_MAX_NUM_QIDS_PER_LDB_CQ];\n+\tu32 ref_cnt;\n+\tu8 num_pending_removals;\n+\tu8 num_mappings;\n+\tu8 owned;\n+\tu8 enabled;\n+\tu8 configured;\n+};\n+\n+struct dlb_credit_pool {\n+\tstruct dlb_list_entry domain_list;\n+\tstruct dlb_list_entry func_list;\n+\tstruct dlb_resource_id id;\n+\tstruct dlb_resource_id domain_id;\n+\tu32 total_credits;\n+\tu32 avail_credits;\n+\tu8 owned;\n+\tu8 configured;\n+};\n+\n+struct dlb_sn_group {\n+\tu32 mode;\n+\tu32 sequence_numbers_per_queue;\n+\tu32 slot_use_bitmap;\n+\tu32 id;\n+};\n+\n+static inline bool dlb_sn_group_full(struct dlb_sn_group *group)\n+{\n+\tu32 mask[6] = {\n+\t\t0xffffffff,  /* 32 SNs per queue */\n+\t\t0x0000ffff,  /* 64 SNs per queue */\n+\t\t0x000000ff,  /* 128 SNs per queue */\n+\t\t0x0000000f,  /* 256 SNs per queue */\n+\t\t0x00000003,  /* 512 SNs per queue */\n+\t\t0x00000001}; /* 1024 SNs per queue */\n+\n+\treturn group->slot_use_bitmap == mask[group->mode];\n+}\n+\n+static inline int dlb_sn_group_alloc_slot(struct dlb_sn_group *group)\n+{\n+\tint bound[6] = {32, 16, 8, 4, 2, 1};\n+\tint i;\n+\n+\tfor (i = 0; i < bound[group->mode]; i++) {\n+\t\tif (!(group->slot_use_bitmap & (1 << i))) {\n+\t\t\tgroup->slot_use_bitmap |= 1 << i;\n+\t\t\treturn i;\n+\t\t}\n+\t}\n+\n+\treturn -1;\n+}\n+\n+static inline void dlb_sn_group_free_slot(struct dlb_sn_group *group, int slot)\n+{\n+\tgroup->slot_use_bitmap &= ~(1 << slot);\n+}\n+\n+static inline int dlb_sn_group_used_slots(struct dlb_sn_group *group)\n+{\n+\tint i, cnt = 0;\n+\n+\tfor (i = 0; i < 32; i++)\n+\t\tcnt += !!(group->slot_use_bitmap & (1 << i));\n+\n+\treturn cnt;\n+}\n+\n+struct dlb_domain {\n+\tstruct dlb_function_resources *parent_func;\n+\tstruct dlb_list_entry func_list;\n+\tstruct dlb_list_head used_ldb_queues;\n+\tstruct dlb_list_head used_ldb_ports;\n+\tstruct dlb_list_head used_dir_pq_pairs;\n+\tstruct dlb_list_head used_ldb_credit_pools;\n+\tstruct dlb_list_head used_dir_credit_pools;\n+\tstruct dlb_list_head avail_ldb_queues;\n+\tstruct dlb_list_head avail_ldb_ports;\n+\tstruct dlb_list_head avail_dir_pq_pairs;\n+\tstruct dlb_list_head avail_ldb_credit_pools;\n+\tstruct dlb_list_head avail_dir_credit_pools;\n+\tu32 total_hist_list_entries;\n+\tu32 avail_hist_list_entries;\n+\tu32 hist_list_entry_base;\n+\tu32 hist_list_entry_offset;\n+\tstruct dlb_freelist qed_freelist;\n+\tstruct dlb_freelist dqed_freelist;\n+\tstruct dlb_freelist aqed_freelist;\n+\tstruct dlb_resource_id id;\n+\tint num_pending_removals;\n+\tint num_pending_additions;\n+\tu8 configured;\n+\tu8 started;\n+};\n+\n+struct dlb_bitmap;\n+\n+struct dlb_function_resources {\n+\tu32 num_avail_domains;\n+\tstruct dlb_list_head avail_domains;\n+\tstruct dlb_list_head used_domains;\n+\tu32 num_avail_ldb_queues;\n+\tstruct dlb_list_head avail_ldb_queues;\n+\tu32 num_avail_ldb_ports;\n+\tstruct dlb_list_head avail_ldb_ports;\n+\tu32 num_avail_dir_pq_pairs;\n+\tstruct dlb_list_head avail_dir_pq_pairs;\n+\tstruct dlb_bitmap *avail_hist_list_entries;\n+\tstruct dlb_bitmap *avail_qed_freelist_entries;\n+\tstruct dlb_bitmap *avail_dqed_freelist_entries;\n+\tstruct dlb_bitmap *avail_aqed_freelist_entries;\n+\tu32 num_avail_ldb_credit_pools;\n+\tstruct dlb_list_head avail_ldb_credit_pools;\n+\tu32 num_avail_dir_credit_pools;\n+\tstruct dlb_list_head avail_dir_credit_pools;\n+\tu32 num_enabled_ldb_ports; /* (PF only) */\n+\tu8 locked; /* (VF only) */\n+};\n+\n+/* After initialization, each resource in dlb_hw_resources is located in one of\n+ * the following lists:\n+ * -- The PF's available resources list. These are unconfigured resources owned\n+ *\tby the PF and not allocated to a DLB scheduling domain.\n+ * -- A VF's available resources list. These are VF-owned unconfigured\n+ *\tresources not allocated to a DLB scheduling domain.\n+ * -- A domain's available resources list. These are domain-owned unconfigured\n+ *\tresources.\n+ * -- A domain's used resources list. These are are domain-owned configured\n+ *\tresources.\n+ *\n+ * A resource moves to a new list when a VF or domain is created or destroyed,\n+ * or when the resource is configured.\n+ */\n+struct dlb_hw_resources {\n+\tstruct dlb_ldb_queue ldb_queues[DLB_MAX_NUM_LDB_QUEUES];\n+\tstruct dlb_ldb_port ldb_ports[DLB_MAX_NUM_LDB_PORTS];\n+\tstruct dlb_dir_pq_pair dir_pq_pairs[DLB_MAX_NUM_DIR_PORTS];\n+\tstruct dlb_credit_pool ldb_credit_pools[DLB_MAX_NUM_LDB_CREDIT_POOLS];\n+\tstruct dlb_credit_pool dir_credit_pools[DLB_MAX_NUM_DIR_CREDIT_POOLS];\n+\tstruct dlb_sn_group sn_groups[DLB_MAX_NUM_SEQUENCE_NUMBER_GROUPS];\n+};\n+\n+struct dlb_hw {\n+\t/* BAR 0 address */\n+\tvoid  *csr_kva;\n+\tunsigned long csr_phys_addr;\n+\t/* BAR 2 address */\n+\tvoid  *func_kva;\n+\tunsigned long func_phys_addr;\n+\n+\t/* Resource tracking */\n+\tstruct dlb_hw_resources rsrcs;\n+\tstruct dlb_function_resources pf;\n+\tstruct dlb_function_resources vf[DLB_MAX_NUM_VFS];\n+\tstruct dlb_domain domains[DLB_MAX_NUM_DOMAINS];\n+};\n+\n+#endif /* __DLB_HW_TYPES_H */\ndiff --git a/drivers/event/dlb/pf/base/dlb_mbox.h b/drivers/event/dlb/pf/base/dlb_mbox.h\nnew file mode 100644\nindex 0000000..e195526\n--- /dev/null\n+++ b/drivers/event/dlb/pf/base/dlb_mbox.h\n@@ -0,0 +1,645 @@\n+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)\n+ * Copyright(c) 2016-2020 Intel Corporation\n+ */\n+\n+#ifndef __DLB_BASE_DLB_MBOX_H\n+#define __DLB_BASE_DLB_MBOX_H\n+\n+#include \"dlb_regs.h\"\n+#include \"dlb_osdep_types.h\"\n+\n+#define DLB_MBOX_INTERFACE_VERSION 1\n+\n+/* The PF uses its PF->VF mailbox to send responses to VF requests, as well as\n+ * to send requests of its own (e.g. notifying a VF of an impending FLR).\n+ * To avoid communication race conditions, e.g. the PF sends a response and then\n+ * sends a request before the VF reads the response, the PF->VF mailbox is\n+ * divided into two sections:\n+ * - Bytes 0-47: PF responses\n+ * - Bytes 48-63: PF requests\n+ *\n+ * Partitioning the PF->VF mailbox allows responses and requests to occupy the\n+ * mailbox simultaneously.\n+ */\n+#define DLB_PF2VF_RESP_BYTES 48\n+#define DLB_PF2VF_RESP_BASE 0\n+#define DLB_PF2VF_RESP_BASE_WORD (DLB_PF2VF_RESP_BASE / 4)\n+\n+#define DLB_PF2VF_REQ_BYTES \\\n+\t(DLB_FUNC_PF_PF2VF_MAILBOX_BYTES - DLB_PF2VF_RESP_BYTES)\n+#define DLB_PF2VF_REQ_BASE DLB_PF2VF_RESP_BYTES\n+#define DLB_PF2VF_REQ_BASE_WORD (DLB_PF2VF_REQ_BASE / 4)\n+\n+/* Similarly, the VF->PF mailbox is divided into two sections:\n+ * - Bytes 0-239: VF requests\n+ * - Bytes 240-255: VF responses\n+ */\n+#define DLB_VF2PF_REQ_BYTES 240\n+#define DLB_VF2PF_REQ_BASE 0\n+#define DLB_VF2PF_REQ_BASE_WORD (DLB_VF2PF_REQ_BASE / 4)\n+\n+#define DLB_VF2PF_RESP_BYTES \\\n+\t(DLB_FUNC_VF_VF2PF_MAILBOX_BYTES - DLB_VF2PF_REQ_BYTES)\n+#define DLB_VF2PF_RESP_BASE DLB_VF2PF_REQ_BYTES\n+#define DLB_VF2PF_RESP_BASE_WORD (DLB_VF2PF_RESP_BASE / 4)\n+\n+/* VF-initiated commands */\n+enum dlb_mbox_cmd_type {\n+\tDLB_MBOX_CMD_REGISTER,\n+\tDLB_MBOX_CMD_UNREGISTER,\n+\tDLB_MBOX_CMD_GET_NUM_RESOURCES,\n+\tDLB_MBOX_CMD_CREATE_SCHED_DOMAIN,\n+\tDLB_MBOX_CMD_RESET_SCHED_DOMAIN,\n+\tDLB_MBOX_CMD_CREATE_LDB_POOL,\n+\tDLB_MBOX_CMD_CREATE_DIR_POOL,\n+\tDLB_MBOX_CMD_CREATE_LDB_QUEUE,\n+\tDLB_MBOX_CMD_CREATE_DIR_QUEUE,\n+\tDLB_MBOX_CMD_CREATE_LDB_PORT,\n+\tDLB_MBOX_CMD_CREATE_DIR_PORT,\n+\tDLB_MBOX_CMD_ENABLE_LDB_PORT,\n+\tDLB_MBOX_CMD_DISABLE_LDB_PORT,\n+\tDLB_MBOX_CMD_ENABLE_DIR_PORT,\n+\tDLB_MBOX_CMD_DISABLE_DIR_PORT,\n+\tDLB_MBOX_CMD_LDB_PORT_OWNED_BY_DOMAIN,\n+\tDLB_MBOX_CMD_DIR_PORT_OWNED_BY_DOMAIN,\n+\tDLB_MBOX_CMD_MAP_QID,\n+\tDLB_MBOX_CMD_UNMAP_QID,\n+\tDLB_MBOX_CMD_START_DOMAIN,\n+\tDLB_MBOX_CMD_ENABLE_LDB_PORT_INTR,\n+\tDLB_MBOX_CMD_ENABLE_DIR_PORT_INTR,\n+\tDLB_MBOX_CMD_ARM_CQ_INTR,\n+\tDLB_MBOX_CMD_GET_NUM_USED_RESOURCES,\n+\tDLB_MBOX_CMD_INIT_CQ_SCHED_COUNT,\n+\tDLB_MBOX_CMD_COLLECT_CQ_SCHED_COUNT,\n+\tDLB_MBOX_CMD_ACK_VF_FLR_DONE,\n+\tDLB_MBOX_CMD_GET_SN_ALLOCATION,\n+\tDLB_MBOX_CMD_GET_LDB_QUEUE_DEPTH,\n+\tDLB_MBOX_CMD_GET_DIR_QUEUE_DEPTH,\n+\tDLB_MBOX_CMD_PENDING_PORT_UNMAPS,\n+\tDLB_MBOX_CMD_QUERY_CQ_POLL_MODE,\n+\tDLB_MBOX_CMD_GET_SN_OCCUPANCY,\n+\n+\t/* NUM_QE_CMD_TYPES must be last */\n+\tNUM_DLB_MBOX_CMD_TYPES,\n+};\n+\n+static const char dlb_mbox_cmd_type_strings[][128] = {\n+\t\"DLB_MBOX_CMD_REGISTER\",\n+\t\"DLB_MBOX_CMD_UNREGISTER\",\n+\t\"DLB_MBOX_CMD_GET_NUM_RESOURCES\",\n+\t\"DLB_MBOX_CMD_CREATE_SCHED_DOMAIN\",\n+\t\"DLB_MBOX_CMD_RESET_SCHED_DOMAIN\",\n+\t\"DLB_MBOX_CMD_CREATE_LDB_POOL\",\n+\t\"DLB_MBOX_CMD_CREATE_DIR_POOL\",\n+\t\"DLB_MBOX_CMD_CREATE_LDB_QUEUE\",\n+\t\"DLB_MBOX_CMD_CREATE_DIR_QUEUE\",\n+\t\"DLB_MBOX_CMD_CREATE_LDB_PORT\",\n+\t\"DLB_MBOX_CMD_CREATE_DIR_PORT\",\n+\t\"DLB_MBOX_CMD_ENABLE_LDB_PORT\",\n+\t\"DLB_MBOX_CMD_DISABLE_LDB_PORT\",\n+\t\"DLB_MBOX_CMD_ENABLE_DIR_PORT\",\n+\t\"DLB_MBOX_CMD_DISABLE_DIR_PORT\",\n+\t\"DLB_MBOX_CMD_LDB_PORT_OWNED_BY_DOMAIN\",\n+\t\"DLB_MBOX_CMD_DIR_PORT_OWNED_BY_DOMAIN\",\n+\t\"DLB_MBOX_CMD_MAP_QID\",\n+\t\"DLB_MBOX_CMD_UNMAP_QID\",\n+\t\"DLB_MBOX_CMD_START_DOMAIN\",\n+\t\"DLB_MBOX_CMD_ENABLE_LDB_PORT_INTR\",\n+\t\"DLB_MBOX_CMD_ENABLE_DIR_PORT_INTR\",\n+\t\"DLB_MBOX_CMD_ARM_CQ_INTR\",\n+\t\"DLB_MBOX_CMD_GET_NUM_USED_RESOURCES\",\n+\t\"DLB_MBOX_CMD_INIT_CQ_SCHED_COUNT\",\n+\t\"DLB_MBOX_CMD_COLLECT_CQ_SCHED_COUNT\",\n+\t\"DLB_MBOX_CMD_ACK_VF_FLR_DONE\",\n+\t\"DLB_MBOX_CMD_GET_SN_ALLOCATION\",\n+\t\"DLB_MBOX_CMD_GET_LDB_QUEUE_DEPTH\",\n+\t\"DLB_MBOX_CMD_GET_DIR_QUEUE_DEPTH\",\n+\t\"DLB_MBOX_CMD_PENDING_PORT_UNMAPS\",\n+\t\"DLB_MBOX_CMD_QUERY_CQ_POLL_MODE\",\n+\t\"DLB_MBOX_CMD_GET_SN_OCCUPANCY\",\n+};\n+\n+/* PF-initiated commands */\n+enum dlb_mbox_vf_cmd_type {\n+\tDLB_MBOX_VF_CMD_DOMAIN_ALERT,\n+\tDLB_MBOX_VF_CMD_NOTIFICATION,\n+\tDLB_MBOX_VF_CMD_IN_USE,\n+\n+\t/* NUM_DLB_MBOX_VF_CMD_TYPES must be last */\n+\tNUM_DLB_MBOX_VF_CMD_TYPES,\n+};\n+\n+static const char dlb_mbox_vf_cmd_type_strings[][128] = {\n+\t\"DLB_MBOX_VF_CMD_DOMAIN_ALERT\",\n+\t\"DLB_MBOX_VF_CMD_NOTIFICATION\",\n+\t\"DLB_MBOX_VF_CMD_IN_USE\",\n+};\n+\n+#define DLB_MBOX_CMD_TYPE(hdr) \\\n+\t(((struct dlb_mbox_req_hdr *)hdr)->type)\n+#define DLB_MBOX_CMD_STRING(hdr) \\\n+\tdlb_mbox_cmd_type_strings[DLB_MBOX_CMD_TYPE(hdr)]\n+\n+enum dlb_mbox_status_type {\n+\tDLB_MBOX_ST_SUCCESS,\n+\tDLB_MBOX_ST_INVALID_CMD_TYPE,\n+\tDLB_MBOX_ST_VERSION_MISMATCH,\n+\tDLB_MBOX_ST_EXPECTED_PHASE_ONE,\n+\tDLB_MBOX_ST_EXPECTED_PHASE_TWO,\n+\tDLB_MBOX_ST_INVALID_OWNER_VF,\n+};\n+\n+static const char dlb_mbox_status_type_strings[][128] = {\n+\t\"DLB_MBOX_ST_SUCCESS\",\n+\t\"DLB_MBOX_ST_INVALID_CMD_TYPE\",\n+\t\"DLB_MBOX_ST_VERSION_MISMATCH\",\n+\t\"DLB_MBOX_ST_EXPECTED_PHASE_ONE\",\n+\t\"DLB_MBOX_ST_EXPECTED_PHASE_TWO\",\n+\t\"DLB_MBOX_ST_INVALID_OWNER_VF\",\n+};\n+\n+#define DLB_MBOX_ST_TYPE(hdr) \\\n+\t(((struct dlb_mbox_resp_hdr *)hdr)->status)\n+#define DLB_MBOX_ST_STRING(hdr) \\\n+\tdlb_mbox_status_type_strings[DLB_MBOX_ST_TYPE(hdr)]\n+\n+/* This structure is always the first field in a request structure */\n+struct dlb_mbox_req_hdr {\n+\tu32 type;\n+};\n+\n+/* This structure is always the first field in a response structure */\n+struct dlb_mbox_resp_hdr {\n+\tu32 status;\n+};\n+\n+struct dlb_mbox_register_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu16 min_interface_version;\n+\tu16 max_interface_version;\n+};\n+\n+struct dlb_mbox_register_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 interface_version;\n+\tu8 pf_id;\n+\tu8 vf_id;\n+\tu8 is_auxiliary_vf;\n+\tu8 primary_vf_id;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_unregister_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_unregister_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_get_num_resources_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_get_num_resources_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu16 num_sched_domains;\n+\tu16 num_ldb_queues;\n+\tu16 num_ldb_ports;\n+\tu16 num_dir_ports;\n+\tu16 padding0;\n+\tu8 num_ldb_credit_pools;\n+\tu8 num_dir_credit_pools;\n+\tu32 num_atomic_inflights;\n+\tu32 max_contiguous_atomic_inflights;\n+\tu32 num_hist_list_entries;\n+\tu32 max_contiguous_hist_list_entries;\n+\tu16 num_ldb_credits;\n+\tu16 max_contiguous_ldb_credits;\n+\tu16 num_dir_credits;\n+\tu16 max_contiguous_dir_credits;\n+\tu32 padding1;\n+};\n+\n+struct dlb_mbox_create_sched_domain_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 num_ldb_queues;\n+\tu32 num_ldb_ports;\n+\tu32 num_dir_ports;\n+\tu32 num_atomic_inflights;\n+\tu32 num_hist_list_entries;\n+\tu32 num_ldb_credits;\n+\tu32 num_dir_credits;\n+\tu32 num_ldb_credit_pools;\n+\tu32 num_dir_credit_pools;\n+};\n+\n+struct dlb_mbox_create_sched_domain_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 id;\n+};\n+\n+struct dlb_mbox_reset_sched_domain_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 id;\n+};\n+\n+struct dlb_mbox_reset_sched_domain_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+};\n+\n+struct dlb_mbox_create_credit_pool_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 num_credits;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_create_credit_pool_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 id;\n+};\n+\n+struct dlb_mbox_create_ldb_queue_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 num_sequence_numbers;\n+\tu32 num_qid_inflights;\n+\tu32 num_atomic_inflights;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_create_ldb_queue_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 id;\n+};\n+\n+struct dlb_mbox_create_dir_queue_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 port_id;\n+\tu32 padding0;\n+};\n+\n+struct dlb_mbox_create_dir_queue_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 id;\n+};\n+\n+struct dlb_mbox_create_ldb_port_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 ldb_credit_pool_id;\n+\tu32 dir_credit_pool_id;\n+\tu64 pop_count_address;\n+\tu16 ldb_credit_high_watermark;\n+\tu16 ldb_credit_low_watermark;\n+\tu16 ldb_credit_quantum;\n+\tu16 dir_credit_high_watermark;\n+\tu16 dir_credit_low_watermark;\n+\tu16 dir_credit_quantum;\n+\tu32 padding0;\n+\tu16 cq_depth;\n+\tu16 cq_history_list_size;\n+\tu32 padding1;\n+\tu64 cq_base_address;\n+\tu64 nq_base_address;\n+\tu32 nq_size;\n+\tu32 padding2;\n+};\n+\n+struct dlb_mbox_create_ldb_port_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 id;\n+};\n+\n+struct dlb_mbox_create_dir_port_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 ldb_credit_pool_id;\n+\tu32 dir_credit_pool_id;\n+\tu64 pop_count_address;\n+\tu16 ldb_credit_high_watermark;\n+\tu16 ldb_credit_low_watermark;\n+\tu16 ldb_credit_quantum;\n+\tu16 dir_credit_high_watermark;\n+\tu16 dir_credit_low_watermark;\n+\tu16 dir_credit_quantum;\n+\tu16 cq_depth;\n+\tu16 padding0;\n+\tu64 cq_base_address;\n+\ts32 queue_id;\n+\tu32 padding1;\n+};\n+\n+struct dlb_mbox_create_dir_port_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 id;\n+};\n+\n+struct dlb_mbox_enable_ldb_port_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 port_id;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_enable_ldb_port_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_disable_ldb_port_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 port_id;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_disable_ldb_port_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_enable_dir_port_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 port_id;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_enable_dir_port_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_disable_dir_port_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 port_id;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_disable_dir_port_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_ldb_port_owned_by_domain_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 port_id;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_ldb_port_owned_by_domain_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\ts32 owned;\n+};\n+\n+struct dlb_mbox_dir_port_owned_by_domain_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 port_id;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_dir_port_owned_by_domain_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\ts32 owned;\n+};\n+\n+struct dlb_mbox_map_qid_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 port_id;\n+\tu32 qid;\n+\tu32 priority;\n+\tu32 padding0;\n+};\n+\n+struct dlb_mbox_map_qid_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 id;\n+};\n+\n+struct dlb_mbox_unmap_qid_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 port_id;\n+\tu32 qid;\n+};\n+\n+struct dlb_mbox_unmap_qid_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_start_domain_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+};\n+\n+struct dlb_mbox_start_domain_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_enable_ldb_port_intr_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu16 port_id;\n+\tu16 thresh;\n+\tu16 vector;\n+\tu16 owner_vf;\n+\tu16 reserved[2];\n+};\n+\n+struct dlb_mbox_enable_ldb_port_intr_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 padding0;\n+};\n+\n+struct dlb_mbox_enable_dir_port_intr_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu16 port_id;\n+\tu16 thresh;\n+\tu16 vector;\n+\tu16 owner_vf;\n+\tu16 reserved[2];\n+};\n+\n+struct dlb_mbox_enable_dir_port_intr_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 padding0;\n+};\n+\n+struct dlb_mbox_arm_cq_intr_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 port_id;\n+\tu32 is_ldb;\n+};\n+\n+struct dlb_mbox_arm_cq_intr_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 padding0;\n+};\n+\n+/* The alert_id and aux_alert_data follows the format of the alerts defined in\n+ * dlb_types.h. The alert id contains an enum dlb_domain_alert_id value, and\n+ * the aux_alert_data value varies depending on the alert.\n+ */\n+struct dlb_mbox_vf_alert_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 alert_id;\n+\tu32 aux_alert_data;\n+};\n+\n+enum dlb_mbox_vf_notification_type {\n+\tDLB_MBOX_VF_NOTIFICATION_PRE_RESET,\n+\tDLB_MBOX_VF_NOTIFICATION_POST_RESET,\n+\n+\t/* NUM_DLB_MBOX_VF_NOTIFICATION_TYPES must be last */\n+\tNUM_DLB_MBOX_VF_NOTIFICATION_TYPES,\n+};\n+\n+struct dlb_mbox_vf_notification_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 notification;\n+};\n+\n+struct dlb_mbox_vf_in_use_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_vf_in_use_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 in_use;\n+};\n+\n+struct dlb_mbox_ack_vf_flr_done_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_ack_vf_flr_done_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_get_sn_allocation_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 group_id;\n+};\n+\n+struct dlb_mbox_get_sn_allocation_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 num;\n+};\n+\n+struct dlb_mbox_get_ldb_queue_depth_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 queue_id;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_get_ldb_queue_depth_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 depth;\n+};\n+\n+struct dlb_mbox_get_dir_queue_depth_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 queue_id;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_get_dir_queue_depth_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 depth;\n+};\n+\n+struct dlb_mbox_pending_port_unmaps_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 domain_id;\n+\tu32 port_id;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_pending_port_unmaps_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 num;\n+};\n+\n+struct dlb_mbox_query_cq_poll_mode_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 padding;\n+};\n+\n+struct dlb_mbox_query_cq_poll_mode_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 error_code;\n+\tu32 status;\n+\tu32 mode;\n+};\n+\n+struct dlb_mbox_get_sn_occupancy_cmd_req {\n+\tstruct dlb_mbox_req_hdr hdr;\n+\tu32 group_id;\n+};\n+\n+struct dlb_mbox_get_sn_occupancy_cmd_resp {\n+\tstruct dlb_mbox_resp_hdr hdr;\n+\tu32 num;\n+};\n+\n+#endif /* __DLB_BASE_DLB_MBOX_H */\ndiff --git a/drivers/event/dlb/pf/base/dlb_osdep.h b/drivers/event/dlb/pf/base/dlb_osdep.h\nnew file mode 100644\nindex 0000000..36b0995\n--- /dev/null\n+++ b/drivers/event/dlb/pf/base/dlb_osdep.h\n@@ -0,0 +1,347 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2016-2020 Intel Corporation\n+ */\n+\n+#ifndef __DLB_OSDEP_H__\n+#define __DLB_OSDEP_H__\n+\n+#include <string.h>\n+#include <time.h>\n+#include <unistd.h>\n+#include <pthread.h>\n+#include <rte_string_fns.h>\n+#include <rte_cycles.h>\n+#include <rte_io.h>\n+#include <rte_log.h>\n+#include <rte_spinlock.h>\n+#include \"../dlb_main.h\"\n+#include \"dlb_resource.h\"\n+#include \"../../dlb_log.h\"\n+#include \"../../dlb_user.h\"\n+\n+\n+#define DLB_PCI_REG_READ(reg)        rte_read32((void *)reg)\n+#define DLB_PCI_REG_WRITE(reg, val)   rte_write32(val, (void *)reg)\n+\n+#define DLB_CSR_REG_ADDR(a, reg) ((void *)((uintptr_t)(a)->csr_kva + (reg)))\n+#define DLB_CSR_RD(hw, reg) \\\n+\tDLB_PCI_REG_READ(DLB_CSR_REG_ADDR((hw), (reg)))\n+#define DLB_CSR_WR(hw, reg, val) \\\n+\tDLB_PCI_REG_WRITE(DLB_CSR_REG_ADDR((hw), (reg)), (val))\n+\n+#define DLB_FUNC_REG_ADDR(a, reg) ((void *)((uintptr_t)(a)->func_kva + (reg)))\n+#define DLB_FUNC_RD(hw, reg) \\\n+\tDLB_PCI_REG_READ(DLB_FUNC_REG_ADDR((hw), (reg)))\n+#define DLB_FUNC_WR(hw, reg, val) \\\n+\tDLB_PCI_REG_WRITE(DLB_FUNC_REG_ADDR((hw), (reg)), (val))\n+\n+#define READ_ONCE(x) (x)\n+#define WRITE_ONCE(x, y) ((x) = (y))\n+\n+#define OS_READ_ONCE(x) READ_ONCE(x)\n+#define OS_WRITE_ONCE(x, y) WRITE_ONCE(x, y)\n+\n+\n+extern unsigned int dlb_unregister_timeout_s;\n+/**\n+ * os_queue_unregister_timeout_s() - timeout (in seconds) to wait for queue\n+ *                                   unregister acknowledgments.\n+ */\n+static inline unsigned int os_queue_unregister_timeout_s(void)\n+{\n+\treturn dlb_unregister_timeout_s;\n+}\n+\n+static inline size_t os_strlcpy(char *dst, const char *src, size_t sz)\n+{\n+\treturn rte_strlcpy(dst, src, sz);\n+}\n+\n+/**\n+ * os_udelay() - busy-wait for a number of microseconds\n+ * @usecs: delay duration.\n+ */\n+static inline void os_udelay(int usecs)\n+{\n+\trte_delay_us(usecs);\n+}\n+\n+/**\n+ * os_msleep() - sleep for a number of milliseconds\n+ * @usecs: delay duration.\n+ */\n+\n+static inline void os_msleep(int msecs)\n+{\n+\trte_delay_ms(msecs);\n+}\n+\n+/**\n+ * os_curtime_s() - get the current time (in seconds)\n+ * @usecs: delay duration.\n+ */\n+static inline unsigned long os_curtime_s(void)\n+{\n+\tstruct timespec tv;\n+\n+\tclock_gettime(CLOCK_MONOTONIC, &tv);\n+\n+\treturn (unsigned long)tv.tv_sec;\n+}\n+\n+#define DLB_PP_BASE(__is_ldb) ((__is_ldb) ? DLB_LDB_PP_BASE : DLB_DIR_PP_BASE)\n+/**\n+ * os_map_producer_port() - map a producer port into the caller's address space\n+ * @hw: dlb_hw handle for a particular device.\n+ * @port_id: port ID\n+ * @is_ldb: true for load-balanced port, false for a directed port\n+ *\n+ * This function maps the requested producer port memory into the caller's\n+ * address space.\n+ *\n+ * Return:\n+ * Returns the base address at which the PP memory was mapped, else NULL.\n+ */\n+static inline void *os_map_producer_port(struct dlb_hw *hw,\n+\t\t\t\t\t u8 port_id,\n+\t\t\t\t\t bool is_ldb)\n+{\n+\tuint64_t addr;\n+\tuint64_t pp_dma_base;\n+\n+\n+\tpp_dma_base = (uintptr_t)hw->func_kva + DLB_PP_BASE(is_ldb);\n+\taddr = (pp_dma_base + (PAGE_SIZE * port_id));\n+\n+\treturn (void *)(uintptr_t)addr;\n+\n+}\n+/**\n+ * os_unmap_producer_port() - unmap a producer port\n+ * @addr: mapped producer port address\n+ *\n+ * This function undoes os_map_producer_port() by unmapping the producer port\n+ * memory from the caller's address space.\n+ *\n+ * Return:\n+ * Returns the base address at which the PP memory was mapped, else NULL.\n+ */\n+\n+/* PFPMD - Nothing to do here, since memory was not actually mapped by us */\n+static inline void os_unmap_producer_port(struct dlb_hw *hw, void *addr)\n+{\n+\tRTE_SET_USED(hw);\n+\tRTE_SET_USED(addr);\n+}\n+/**\n+ * os_enqueue_four_hcws() - enqueue four HCWs to DLB\n+ * @hw: dlb_hw handle for a particular device.\n+ * @hcw: pointer to the 64B-aligned contiguous HCW memory\n+ * @addr: producer port address\n+ */\n+static inline void os_enqueue_four_hcws(struct dlb_hw *hw,\n+\t\t\t\t\tstruct dlb_hcw *hcw,\n+\t\t\t\t\tvoid *addr)\n+{\n+\tstruct dlb_dev *dlb_dev;\n+\n+\tdlb_dev = container_of(hw, struct dlb_dev, hw);\n+\n+\tdlb_dev->enqueue_four(hcw, addr);\n+}\n+\n+/**\n+ * os_fence_hcw() - fence an HCW to ensure it arrives at the device\n+ * @hw: dlb_hw handle for a particular device.\n+ * @pp_addr: producer port address\n+ */\n+static inline void os_fence_hcw(struct dlb_hw *hw, u64 *pp_addr)\n+{\n+\tRTE_SET_USED(hw);\n+\n+\t/* To ensure outstanding HCWs reach the device, read the PP address. IA\n+\t * memory ordering prevents reads from passing older writes, and the\n+\t * mfence also ensures this.\n+\t */\n+\trte_mb();\n+\n+\t*(volatile u64 *)pp_addr;\n+}\n+\n+/* Map to PMDs logging interface */\n+#define DLB_ERR(dev, fmt, args...) \\\n+\tDLB_LOG_ERR(fmt, ## args)\n+\n+#define DLB_INFO(dev, fmt, args...) \\\n+\tDLB_LOG_INFO(fmt, ## args)\n+\n+#define DLB_DEBUG(dev, fmt, args...) \\\n+\tDLB_LOG_DEBUG(fmt, ## args)\n+\n+/**\n+ * DLB_HW_ERR() - log an error message\n+ * @dlb: dlb_hw handle for a particular device.\n+ * @...: variable string args.\n+ */\n+#define DLB_HW_ERR(dlb, ...) do {\t\\\n+\tRTE_SET_USED(dlb);\t\t\\\n+\tDLB_ERR(dlb, __VA_ARGS__);\t\\\n+} while (0)\n+\n+/**\n+ * DLB_HW_INFO() - log an info message\n+ * @dlb: dlb_hw handle for a particular device.\n+ * @...: variable string args.\n+ */\n+#define DLB_HW_INFO(dlb, ...) do {\t\\\n+\tRTE_SET_USED(dlb);\t\t\\\n+\tDLB_INFO(dlb, __VA_ARGS__);\t\\\n+} while (0)\n+\n+/*** scheduling functions ***/\n+\n+/* The callback runs until it completes all outstanding QID->CQ\n+ * map and unmap requests. To prevent deadlock, this function gives other\n+ * threads a chance to grab the resource mutex and configure hardware.\n+ */\n+static void *dlb_complete_queue_map_unmap(void *__args)\n+{\n+\tstruct dlb_dev *dlb_dev = (struct dlb_dev *)__args;\n+\tint ret;\n+\n+\twhile (1) {\n+\t\trte_spinlock_lock(&dlb_dev->resource_mutex);\n+\n+\t\tret = dlb_finish_unmap_qid_procedures(&dlb_dev->hw);\n+\t\tret += dlb_finish_map_qid_procedures(&dlb_dev->hw);\n+\n+\t\tif (ret != 0) {\n+\t\t\trte_spinlock_unlock(&dlb_dev->resource_mutex);\n+\t\t\t/* Relinquish the CPU so the application can process\n+\t\t\t * its CQs, so this function doesn't deadlock.\n+\t\t\t */\n+\t\t\tsched_yield();\n+\t\t} else\n+\t\t\tbreak;\n+\t}\n+\n+\tdlb_dev->worker_launched = false;\n+\n+\trte_spinlock_unlock(&dlb_dev->resource_mutex);\n+\n+\treturn NULL;\n+}\n+\n+\n+/**\n+ * os_schedule_work() - launch a thread to process pending map and unmap work\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function launches a thread that will run until all pending\n+ * map and unmap procedures are complete.\n+ */\n+static inline void os_schedule_work(struct dlb_hw *hw)\n+{\n+\tstruct dlb_dev *dlb_dev;\n+\tpthread_t complete_queue_map_unmap_thread;\n+\tint ret;\n+\n+\tdlb_dev = container_of(hw, struct dlb_dev, hw);\n+\n+\tret = pthread_create(&complete_queue_map_unmap_thread,\n+\t\t\t     NULL,\n+\t\t\t     dlb_complete_queue_map_unmap,\n+\t\t\t     dlb_dev);\n+\tif (ret)\n+\t\tDLB_ERR(dlb_dev,\n+\t\t\"Could not create queue complete map /unmap thread, err=%d\\n\",\n+\t\t\t  ret);\n+\telse\n+\t\tdlb_dev->worker_launched = true;\n+}\n+\n+/**\n+ * os_worker_active() - query whether the map/unmap worker thread is active\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function returns a boolean indicating whether a thread (launched by\n+ * os_schedule_work()) is active. This function is used to determine\n+ * whether or not to launch a worker thread.\n+ */\n+static inline bool os_worker_active(struct dlb_hw *hw)\n+{\n+\tstruct dlb_dev *dlb_dev;\n+\n+\tdlb_dev = container_of(hw, struct dlb_dev, hw);\n+\n+\treturn dlb_dev->worker_launched;\n+}\n+\n+/**\n+ * os_notify_user_space() - notify user space\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: ID of domain to notify.\n+ * @alert_id: alert ID.\n+ * @aux_alert_data: additional alert data.\n+ *\n+ * This function notifies user space of an alert (such as a remote queue\n+ * unregister or hardware alarm).\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ */\n+static inline int os_notify_user_space(struct dlb_hw *hw,\n+\t\t\t\t       u32 domain_id,\n+\t\t\t\t       u64 alert_id,\n+\t\t\t\t       u64 aux_alert_data)\n+{\n+\tRTE_SET_USED(hw);\n+\tRTE_SET_USED(domain_id);\n+\tRTE_SET_USED(alert_id);\n+\tRTE_SET_USED(aux_alert_data);\n+\n+\trte_panic(\"internal_error: %s should never be called for DLB PF PMD\\n\",\n+\t\t  __func__);\n+\treturn -1;\n+}\n+\n+enum dlb_dev_revision {\n+\tDLB_A0,\n+\tDLB_A1,\n+\tDLB_A2,\n+\tDLB_A3,\n+\tDLB_B0,\n+};\n+\n+#include <cpuid.h>\n+\n+/**\n+ * os_get_dev_revision() - query the device_revision\n+ * @hw: dlb_hw handle for a particular device.\n+ */\n+static inline enum dlb_dev_revision os_get_dev_revision(struct dlb_hw *hw)\n+{\n+\tuint32_t a, b, c, d, stepping;\n+\n+\tRTE_SET_USED(hw);\n+\n+\t__cpuid(0x1, a, b, c, d);\n+\n+\tstepping = a & 0xf;\n+\n+\tswitch (stepping) {\n+\tcase 0:\n+\t\treturn DLB_A0;\n+\tcase 1:\n+\t\treturn DLB_A1;\n+\tcase 2:\n+\t\treturn DLB_A2;\n+\tcase 3:\n+\t\treturn DLB_A3;\n+\tdefault:\n+\t\t/* Treat all revisions >= 4 as B0 */\n+\t\treturn DLB_B0;\n+\t}\n+}\n+\n+#endif /*  __DLB_OSDEP_H__ */\ndiff --git a/drivers/event/dlb/pf/base/dlb_osdep_bitmap.h b/drivers/event/dlb/pf/base/dlb_osdep_bitmap.h\nnew file mode 100644\nindex 0000000..8df1d59\n--- /dev/null\n+++ b/drivers/event/dlb/pf/base/dlb_osdep_bitmap.h\n@@ -0,0 +1,442 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2016-2020 Intel Corporation\n+ */\n+\n+#ifndef __DLB_OSDEP_BITMAP_H__\n+#define __DLB_OSDEP_BITMAP_H__\n+\n+#include <stdint.h>\n+#include <stdbool.h>\n+#include <stdio.h>\n+#include <unistd.h>\n+#include <rte_bitmap.h>\n+#include <rte_string_fns.h>\n+#include <rte_malloc.h>\n+#include <rte_errno.h>\n+#include \"../dlb_main.h\"\n+\n+\n+/*************************/\n+/*** Bitmap operations ***/\n+/*************************/\n+struct dlb_bitmap {\n+\tstruct rte_bitmap *map;\n+\tunsigned int len;\n+\tstruct dlb_hw *hw;\n+};\n+\n+/**\n+ * dlb_bitmap_alloc() - alloc a bitmap data structure\n+ * @bitmap: pointer to dlb_bitmap structure pointer.\n+ * @len: number of entries in the bitmap.\n+ *\n+ * This function allocates a bitmap and initializes it with length @len. All\n+ * entries are initially zero.\n+ *\n+ * Return:\n+ * Returns 0 upon success, < 0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - bitmap is NULL or len is 0.\n+ * ENOMEM - could not allocate memory for the bitmap data structure.\n+ */\n+static inline int dlb_bitmap_alloc(struct dlb_hw *hw,\n+\t\t\t\t   struct dlb_bitmap **bitmap,\n+\t\t\t\t   unsigned int len)\n+{\n+\tstruct dlb_bitmap *bm;\n+\tvoid *mem;\n+\tuint32_t alloc_size;\n+\tuint32_t nbits = (uint32_t) len;\n+\tRTE_SET_USED(hw);\n+\n+\tif (!bitmap || nbits == 0)\n+\t\treturn -EINVAL;\n+\n+\t/* Allocate DLB bitmap control struct */\n+\tbm = rte_malloc(\"DLB_PF\",\n+\t\tsizeof(struct dlb_bitmap),\n+\t\tRTE_CACHE_LINE_SIZE);\n+\n+\tif (!bm)\n+\t\treturn -ENOMEM;\n+\n+\t/* Allocate bitmap memory */\n+\talloc_size = rte_bitmap_get_memory_footprint(nbits);\n+\tmem = rte_malloc(\"DLB_PF_BITMAP\", alloc_size, RTE_CACHE_LINE_SIZE);\n+\tif (!mem) {\n+\t\trte_free(bm);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tbm->map = rte_bitmap_init(len, mem, alloc_size);\n+\tif (!bm->map) {\n+\t\trte_free(mem);\n+\t\trte_free(bm);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tbm->len = len;\n+\n+\t*bitmap = bm;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * dlb_bitmap_free() - free a previously allocated bitmap data structure\n+ * @bitmap: pointer to dlb_bitmap structure.\n+ *\n+ * This function frees a bitmap that was allocated with dlb_bitmap_alloc().\n+ */\n+static inline void dlb_bitmap_free(struct dlb_bitmap *bitmap)\n+{\n+\tif (!bitmap)\n+\t\trte_panic(\"NULL dlb_bitmap in %s\\n\", __func__);\n+\n+\trte_free(bitmap->map);\n+\trte_free(bitmap);\n+}\n+\n+/**\n+ * dlb_bitmap_fill() - fill a bitmap with all 1s\n+ * @bitmap: pointer to dlb_bitmap structure.\n+ *\n+ * This function sets all bitmap values to 1.\n+ *\n+ * Return:\n+ * Returns 0 upon success, < 0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - bitmap is NULL or is uninitialized.\n+ */\n+static inline int dlb_bitmap_fill(struct dlb_bitmap *bitmap)\n+{\n+\tunsigned int i;\n+\n+\tif (!bitmap || !bitmap->map)\n+\t\treturn -EINVAL;\n+\n+\tfor (i = 0; i != bitmap->len; i++)\n+\t\trte_bitmap_set(bitmap->map, i);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * dlb_bitmap_fill() - fill a bitmap with all 0s\n+ * @bitmap: pointer to dlb_bitmap structure.\n+ *\n+ * This function sets all bitmap values to 0.\n+ *\n+ * Return:\n+ * Returns 0 upon success, < 0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - bitmap is NULL or is uninitialized.\n+ */\n+static inline int dlb_bitmap_zero(struct dlb_bitmap *bitmap)\n+{\n+\tif (!bitmap || !bitmap->map)\n+\t\treturn -EINVAL;\n+\n+\trte_bitmap_reset(bitmap->map);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * dlb_bitmap_set() - set a bitmap entry\n+ * @bitmap: pointer to dlb_bitmap structure.\n+ * @bit: bit index.\n+ *\n+ * Return:\n+ * Returns 0 upon success, < 0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - bitmap is NULL or is uninitialized, or bit is larger than the\n+ *\t    bitmap length.\n+ */\n+static inline int dlb_bitmap_set(struct dlb_bitmap *bitmap,\n+\t\t\t\t unsigned int bit)\n+{\n+\tif (!bitmap || !bitmap->map)\n+\t\treturn -EINVAL;\n+\n+\tif (bitmap->len <= bit)\n+\t\treturn -EINVAL;\n+\n+\trte_bitmap_set(bitmap->map, bit);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * dlb_bitmap_set_range() - set a range of bitmap entries\n+ * @bitmap: pointer to dlb_bitmap structure.\n+ * @bit: starting bit index.\n+ * @len: length of the range.\n+ *\n+ * Return:\n+ * Returns 0 upon success, < 0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - bitmap is NULL or is uninitialized, or the range exceeds the bitmap\n+ *\t    length.\n+ */\n+static inline int dlb_bitmap_set_range(struct dlb_bitmap *bitmap,\n+\t\t\t\t       unsigned int bit,\n+\t\t\t\t       unsigned int len)\n+{\n+\tunsigned int i;\n+\n+\tif (!bitmap || !bitmap->map)\n+\t\treturn -EINVAL;\n+\n+\tif (bitmap->len <= bit)\n+\t\treturn -EINVAL;\n+\n+\tfor (i = 0; i != len; i++)\n+\t\trte_bitmap_set(bitmap->map, bit + i);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * dlb_bitmap_clear() - clear a bitmap entry\n+ * @bitmap: pointer to dlb_bitmap structure.\n+ * @bit: bit index.\n+ *\n+ * Return:\n+ * Returns 0 upon success, < 0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - bitmap is NULL or is uninitialized, or bit is larger than the\n+ *\t    bitmap length.\n+ */\n+static inline int dlb_bitmap_clear(struct dlb_bitmap *bitmap,\n+\t\t\t\t   unsigned int bit)\n+{\n+\tif (!bitmap || !bitmap->map)\n+\t\treturn -EINVAL;\n+\n+\tif (bitmap->len <= bit)\n+\t\treturn -EINVAL;\n+\n+\trte_bitmap_clear(bitmap->map, bit);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * dlb_bitmap_clear_range() - clear a range of bitmap entries\n+ * @bitmap: pointer to dlb_bitmap structure.\n+ * @bit: starting bit index.\n+ * @len: length of the range.\n+ *\n+ * Return:\n+ * Returns 0 upon success, < 0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - bitmap is NULL or is uninitialized, or the range exceeds the bitmap\n+ *\t    length.\n+ */\n+static inline int dlb_bitmap_clear_range(struct dlb_bitmap *bitmap,\n+\t\t\t\t\t unsigned int bit,\n+\t\t\t\t\t unsigned int len)\n+{\n+\tunsigned int i;\n+\n+\tif (!bitmap || !bitmap->map)\n+\t\treturn -EINVAL;\n+\n+\tif (bitmap->len <= bit)\n+\t\treturn -EINVAL;\n+\n+\tfor (i = 0; i != len; i++)\n+\t\trte_bitmap_clear(bitmap->map, bit + i);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * dlb_bitmap_find_set_bit_range() - find a range of set bits\n+ * @bitmap: pointer to dlb_bitmap structure.\n+ * @len: length of the range.\n+ *\n+ * This function looks for a range of set bits of length @len.\n+ *\n+ * Return:\n+ * Returns the base bit index upon success, < 0 otherwise.\n+ *\n+ * Errors:\n+ * ENOENT - unable to find a length *len* range of set bits.\n+ * EINVAL - bitmap is NULL or is uninitialized, or len is invalid.\n+ */\n+static inline int dlb_bitmap_find_set_bit_range(struct dlb_bitmap *bitmap,\n+\t\t\t\t\t\tunsigned int len)\n+{\n+\tunsigned int i, j = 0;\n+\n+\tif (!bitmap || !bitmap->map || len == 0)\n+\t\treturn -EINVAL;\n+\n+\tif (bitmap->len < len)\n+\t\treturn -ENOENT;\n+\n+\tfor (i = 0; i != bitmap->len; i++) {\n+\t\tif  (rte_bitmap_get(bitmap->map, i)) {\n+\t\t\tif (++j == len)\n+\t\t\t\treturn i - j + 1;\n+\t\t} else\n+\t\t\tj = 0;\n+\t}\n+\n+\t/* No set bit range of length len? */\n+\treturn -ENOENT;\n+}\n+\n+/**\n+ * dlb_bitmap_find_set_bit() - find the first set bit\n+ * @bitmap: pointer to dlb_bitmap structure.\n+ *\n+ * This function looks for a single set bit.\n+ *\n+ * Return:\n+ * Returns the base bit index upon success, < 0 otherwise.\n+ *\n+ * Errors:\n+ * ENOENT - the bitmap contains no set bits.\n+ * EINVAL - bitmap is NULL or is uninitialized, or len is invalid.\n+ */\n+static inline int dlb_bitmap_find_set_bit(struct dlb_bitmap *bitmap)\n+{\n+\tunsigned int i;\n+\n+\tif (!bitmap)\n+\t\treturn -EINVAL;\n+\n+\tif (!bitmap->map)\n+\t\treturn -EINVAL;\n+\n+\tfor (i = 0; i != bitmap->len; i++) {\n+\t\tif  (rte_bitmap_get(bitmap->map, i))\n+\t\t\treturn i;\n+\t}\n+\n+\treturn -ENOENT;\n+}\n+\n+/**\n+ * dlb_bitmap_count() - returns the number of set bits\n+ * @bitmap: pointer to dlb_bitmap structure.\n+ *\n+ * This function looks for a single set bit.\n+ *\n+ * Return:\n+ * Returns the number of set bits upon success, <0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - bitmap is NULL or is uninitialized.\n+ */\n+static inline int dlb_bitmap_count(struct dlb_bitmap *bitmap)\n+{\n+\tint weight = 0;\n+\tunsigned int i;\n+\n+\tif (!bitmap)\n+\t\treturn -EINVAL;\n+\n+\tif (!bitmap->map)\n+\t\treturn -EINVAL;\n+\n+\tfor (i = 0; i != bitmap->len; i++) {\n+\t\tif  (rte_bitmap_get(bitmap->map, i))\n+\t\t\tweight++;\n+\t}\n+\treturn weight;\n+}\n+\n+/**\n+ * dlb_bitmap_longest_set_range() - returns longest contiguous range of set bits\n+ * @bitmap: pointer to dlb_bitmap structure.\n+ *\n+ * Return:\n+ * Returns the bitmap's longest contiguous range of of set bits upon success,\n+ * <0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - bitmap is NULL or is uninitialized.\n+ */\n+static inline int dlb_bitmap_longest_set_range(struct dlb_bitmap *bitmap)\n+{\n+\tint max_len = 0, len = 0;\n+\tunsigned int i;\n+\n+\tif (!bitmap)\n+\t\treturn -EINVAL;\n+\n+\tif (!bitmap->map)\n+\t\treturn -EINVAL;\n+\n+\tfor (i = 0; i != bitmap->len; i++) {\n+\t\tif  (rte_bitmap_get(bitmap->map, i)) {\n+\t\t\tlen++;\n+\t\t} else {\n+\t\t\tif (len > max_len)\n+\t\t\t\tmax_len = len;\n+\t\t\tlen = 0;\n+\t\t}\n+\t}\n+\n+\tif (len > max_len)\n+\t\tmax_len = len;\n+\n+\treturn max_len;\n+}\n+\n+/**\n+ * dlb_bitmap_or() - store the logical 'or' of two bitmaps into a third\n+ * @dest: pointer to dlb_bitmap structure, which will contain the results of\n+ *\t  the 'or' of src1 and src2.\n+ * @src1: pointer to dlb_bitmap structure, will be 'or'ed with src2.\n+ * @src2: pointer to dlb_bitmap structure, will be 'or'ed with src1.\n+ *\n+ * This function 'or's two bitmaps together and stores the result in a third\n+ * bitmap. The source and destination bitmaps can be the same.\n+ *\n+ * Return:\n+ * Returns the number of set bits upon success, <0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - One of the bitmaps is NULL or is uninitialized.\n+ */\n+static inline int dlb_bitmap_or(struct dlb_bitmap *dest,\n+\t\t\t\tstruct dlb_bitmap *src1,\n+\t\t\t\tstruct dlb_bitmap *src2)\n+{\n+\tunsigned int i, min;\n+\tint numset = 0;\n+\n+\tif (!dest || !dest->map ||\n+\t    !src1 || !src1->map ||\n+\t    !src2 || !src2->map)\n+\t\treturn -EINVAL;\n+\n+\tmin = dest->len;\n+\tmin = (min > src1->len) ? src1->len : min;\n+\tmin = (min > src2->len) ? src2->len : min;\n+\n+\tfor (i = 0; i != min; i++) {\n+\t\tif  (rte_bitmap_get(src1->map, i) ||\n+\t\t\t\trte_bitmap_get(src2->map, i)) {\n+\t\t\trte_bitmap_set(dest->map, i);\n+\t\t\tnumset++;\n+\t\t} else\n+\t\t\trte_bitmap_clear(dest->map, i);\n+\t}\n+\n+\treturn numset;\n+}\n+\n+#endif /*  __DLB_OSDEP_BITMAP_H__ */\ndiff --git a/drivers/event/dlb/pf/base/dlb_osdep_list.h b/drivers/event/dlb/pf/base/dlb_osdep_list.h\nnew file mode 100644\nindex 0000000..a53b362\n--- /dev/null\n+++ b/drivers/event/dlb/pf/base/dlb_osdep_list.h\n@@ -0,0 +1,131 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2016-2020 Intel Corporation\n+ */\n+\n+#ifndef __DLB_OSDEP_LIST_H__\n+#define __DLB_OSDEP_LIST_H__\n+\n+#include <rte_tailq.h>\n+\n+struct dlb_list_entry {\n+\tTAILQ_ENTRY(dlb_list_entry) node;\n+};\n+\n+/* Dummy - just a struct definition */\n+TAILQ_HEAD(dlb_list_head, dlb_list_entry);\n+\n+/* =================\n+ * TAILQ Supplements\n+ * =================\n+ */\n+\n+#ifndef TAILQ_FOREACH_ENTRY\n+#define TAILQ_FOREACH_ENTRY(ptr, head, name, iter)\t\t\\\n+\tfor ((iter) = TAILQ_FIRST(&head);\t\t\t\\\n+\t    (iter)\t\t\t\t\t\t\\\n+\t\t&& (ptr = container_of(iter, typeof(*(ptr)), name)); \\\n+\t    (iter) = TAILQ_NEXT((iter), node))\n+#endif\n+\n+#ifndef TAILQ_FOREACH_ENTRY_SAFE\n+#define TAILQ_FOREACH_ENTRY_SAFE(ptr, head, name, iter, tvar)\t\\\n+\tfor ((iter) = TAILQ_FIRST(&head);\t\t\t\\\n+\t    (iter) &&\t\t\t\t\t\t\\\n+\t\t(ptr = container_of(iter, typeof(*(ptr)), name)) &&\\\n+\t\t((tvar) = TAILQ_NEXT((iter), node), 1);\t\\\n+\t    (iter) = (tvar))\n+#endif\n+\n+/* =========\n+ * DLB Lists\n+ * =========\n+ */\n+\n+/**\n+ * dlb_list_init_head() - initialize the head of a list\n+ * @head: list head\n+ */\n+static inline void dlb_list_init_head(struct dlb_list_head *head)\n+{\n+\tTAILQ_INIT(head);\n+}\n+\n+/**\n+ * dlb_list_add() - add an entry to a list\n+ * @head: new entry will be added after this list header\n+ * @entry: new list entry to be added\n+ */\n+static inline void dlb_list_add(struct dlb_list_head *head,\n+\t\t\t\tstruct dlb_list_entry *entry)\n+{\n+\tTAILQ_INSERT_TAIL(head, entry, node);\n+}\n+\n+/**\n+ * @head: list head\n+ * @entry: list entry to be deleted\n+ */\n+static inline void dlb_list_del(struct dlb_list_head *head,\n+\t\t\t\tstruct dlb_list_entry *entry)\n+{\n+\tTAILQ_REMOVE(head, entry, node);\n+}\n+\n+/**\n+ * dlb_list_empty() - check if a list is empty\n+ * @head: list head\n+ *\n+ * Return:\n+ * Returns 1 if empty, 0 if not.\n+ */\n+static inline bool dlb_list_empty(struct dlb_list_head *head)\n+{\n+\treturn TAILQ_EMPTY(head);\n+}\n+\n+/**\n+ * dlb_list_empty() - check if a list is empty\n+ * @src_head: list to be added\n+ * @ head: where src_head will be inserted\n+ */\n+static inline void dlb_list_splice(struct dlb_list_head *src_head,\n+\t\t\t\t   struct dlb_list_head *head)\n+{\n+\tTAILQ_CONCAT(head, src_head, node);\n+}\n+\n+/**\n+ * DLB_LIST_HEAD() - retrieve the head of the list\n+ * @head: list head\n+ * @type: type of the list variable\n+ * @name: name of the dlb_list within the struct\n+ */\n+#define DLB_LIST_HEAD(head, type, name)\t\t\t\t\\\n+\t(TAILQ_FIRST(&head) ?\t\t\t\t\t\\\n+\t\tcontainer_of(TAILQ_FIRST(&head), type, name) :\t\\\n+\t\tNULL)\n+\n+/**\n+ * DLB_LIST_FOR_EACH() - iterate over a list\n+ * @head: list head\n+ * @ptr: pointer to struct containing a struct dlb_list_entry\n+ * @name: name of the dlb_list_entry field within the containing struct\n+ * @iter: iterator variable\n+ */\n+#define DLB_LIST_FOR_EACH(head, ptr, name, tmp_iter) \\\n+\tTAILQ_FOREACH_ENTRY(ptr, head, name, tmp_iter)\n+\n+/**\n+ * DLB_LIST_FOR_EACH_SAFE() - iterate over a list. This loop works even if\n+ * an element is removed from the list while processing it.\n+ * @ptr: pointer to struct containing a struct dlb_list_entry\n+ * @ptr_tmp: pointer to struct containing a struct dlb_list_entry (temporary)\n+ * @head: list head\n+ * @name: name of the dlb_list_entry field within the containing struct\n+ * @iter: iterator variable\n+ * @iter_tmp: iterator variable (temporary)\n+ */\n+#define DLB_LIST_FOR_EACH_SAFE(head, ptr, ptr_tmp, name, tmp_iter, saf_iter) \\\n+\tTAILQ_FOREACH_ENTRY_SAFE(ptr, head, name, tmp_iter, saf_iter)\n+\n+#endif /*  __DLB_OSDEP_LIST_H__ */\ndiff --git a/drivers/event/dlb/pf/base/dlb_osdep_types.h b/drivers/event/dlb/pf/base/dlb_osdep_types.h\nnew file mode 100644\nindex 0000000..2e9d7d8\n--- /dev/null\n+++ b/drivers/event/dlb/pf/base/dlb_osdep_types.h\n@@ -0,0 +1,31 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2016-2020 Intel Corporation\n+ */\n+\n+#ifndef __DLB_OSDEP_TYPES_H\n+#define __DLB_OSDEP_TYPES_H\n+\n+#include <linux/types.h>\n+\n+#include <inttypes.h>\n+#include <ctype.h>\n+#include <stdint.h>\n+#include <stdbool.h>\n+#include <string.h>\n+#include <unistd.h>\n+#include <errno.h>\n+\n+/* Types for user mode PF PMD */\n+typedef uint8_t         u8;\n+typedef int8_t          s8;\n+typedef uint16_t        u16;\n+typedef int16_t         s16;\n+typedef uint32_t        u32;\n+typedef int32_t         s32;\n+typedef uint64_t        u64;\n+\n+#define __iomem\n+\n+/* END types for user mode PF PMD */\n+\n+#endif /* __DLB_OSDEP_TYPES_H */\ndiff --git a/drivers/event/dlb/pf/base/dlb_regs.h b/drivers/event/dlb/pf/base/dlb_regs.h\nnew file mode 100644\nindex 0000000..fce5c0b\n--- /dev/null\n+++ b/drivers/event/dlb/pf/base/dlb_regs.h\n@@ -0,0 +1,2678 @@\n+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)\n+ * Copyright(c) 2016-2020 Intel Corporation\n+ */\n+\n+#ifndef __DLB_REGS_H\n+#define __DLB_REGS_H\n+\n+#include \"dlb_osdep_types.h\"\n+\n+#define DLB_FUNC_PF_VF2PF_MAILBOX_BYTES 256\n+#define DLB_FUNC_PF_VF2PF_MAILBOX(vf_id, x) \\\n+\t(0x1000 + 0x4 * (x) + (vf_id) * 0x10000)\n+#define DLB_FUNC_PF_VF2PF_MAILBOX_RST 0x0\n+union dlb_func_pf_vf2pf_mailbox {\n+\tstruct {\n+\t\tu32 msg : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_FUNC_PF_VF2PF_MAILBOX_ISR(vf_id) \\\n+\t(0x1f00 + (vf_id) * 0x10000)\n+#define DLB_FUNC_PF_VF2PF_MAILBOX_ISR_RST 0x0\n+union dlb_func_pf_vf2pf_mailbox_isr {\n+\tstruct {\n+\t\tu32 vf_isr : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_FUNC_PF_VF2PF_FLR_ISR(vf_id) \\\n+\t(0x1f04 + (vf_id) * 0x10000)\n+#define DLB_FUNC_PF_VF2PF_FLR_ISR_RST 0x0\n+union dlb_func_pf_vf2pf_flr_isr {\n+\tstruct {\n+\t\tu32 vf_isr : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_FUNC_PF_VF2PF_ISR_PEND(vf_id) \\\n+\t(0x1f10 + (vf_id) * 0x10000)\n+#define DLB_FUNC_PF_VF2PF_ISR_PEND_RST 0x0\n+union dlb_func_pf_vf2pf_isr_pend {\n+\tstruct {\n+\t\tu32 isr_pend : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_FUNC_PF_PF2VF_MAILBOX_BYTES 64\n+#define DLB_FUNC_PF_PF2VF_MAILBOX(vf_id, x) \\\n+\t(0x2000 + 0x4 * (x) + (vf_id) * 0x10000)\n+#define DLB_FUNC_PF_PF2VF_MAILBOX_RST 0x0\n+union dlb_func_pf_pf2vf_mailbox {\n+\tstruct {\n+\t\tu32 msg : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_FUNC_PF_PF2VF_MAILBOX_ISR(vf_id) \\\n+\t(0x2f00 + (vf_id) * 0x10000)\n+#define DLB_FUNC_PF_PF2VF_MAILBOX_ISR_RST 0x0\n+union dlb_func_pf_pf2vf_mailbox_isr {\n+\tstruct {\n+\t\tu32 isr : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_FUNC_PF_VF_RESET_IN_PROGRESS(vf_id) \\\n+\t(0x3000 + (vf_id) * 0x10000)\n+#define DLB_FUNC_PF_VF_RESET_IN_PROGRESS_RST 0xffff\n+union dlb_func_pf_vf_reset_in_progress {\n+\tstruct {\n+\t\tu32 reset_in_progress : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_MSIX_MEM_VECTOR_CTRL(x) \\\n+\t(0x100000c + (x) * 0x10)\n+#define DLB_MSIX_MEM_VECTOR_CTRL_RST 0x1\n+union dlb_msix_mem_vector_ctrl {\n+\tstruct {\n+\t\tu32 vec_mask : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_TOTAL_VAS 0x124\n+#define DLB_SYS_TOTAL_VAS_RST 0x20\n+union dlb_sys_total_vas {\n+\tstruct {\n+\t\tu32 total_vas : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_ALARM_PF_SYND2 0x508\n+#define DLB_SYS_ALARM_PF_SYND2_RST 0x0\n+union dlb_sys_alarm_pf_synd2 {\n+\tstruct {\n+\t\tu32 lock_id : 16;\n+\t\tu32 meas : 1;\n+\t\tu32 debug : 7;\n+\t\tu32 cq_pop : 1;\n+\t\tu32 qe_uhl : 1;\n+\t\tu32 qe_orsp : 1;\n+\t\tu32 qe_valid : 1;\n+\t\tu32 cq_int_rearm : 1;\n+\t\tu32 dsi_error : 1;\n+\t\tu32 rsvd0 : 2;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_ALARM_PF_SYND1 0x504\n+#define DLB_SYS_ALARM_PF_SYND1_RST 0x0\n+union dlb_sys_alarm_pf_synd1 {\n+\tstruct {\n+\t\tu32 dsi : 16;\n+\t\tu32 qid : 8;\n+\t\tu32 qtype : 2;\n+\t\tu32 qpri : 3;\n+\t\tu32 msg_type : 3;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_ALARM_PF_SYND0 0x500\n+#define DLB_SYS_ALARM_PF_SYND0_RST 0x0\n+union dlb_sys_alarm_pf_synd0 {\n+\tstruct {\n+\t\tu32 syndrome : 8;\n+\t\tu32 rtype : 2;\n+\t\tu32 rsvd0 : 2;\n+\t\tu32 from_dmv : 1;\n+\t\tu32 is_ldb : 1;\n+\t\tu32 cls : 2;\n+\t\tu32 aid : 6;\n+\t\tu32 unit : 4;\n+\t\tu32 source : 4;\n+\t\tu32 more : 1;\n+\t\tu32 valid : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_VF_LDB_VPP_V(x) \\\n+\t(0xf00 + (x) * 0x1000)\n+#define DLB_SYS_VF_LDB_VPP_V_RST 0x0\n+union dlb_sys_vf_ldb_vpp_v {\n+\tstruct {\n+\t\tu32 vpp_v : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_VF_LDB_VPP2PP(x) \\\n+\t(0xf08 + (x) * 0x1000)\n+#define DLB_SYS_VF_LDB_VPP2PP_RST 0x0\n+union dlb_sys_vf_ldb_vpp2pp {\n+\tstruct {\n+\t\tu32 pp : 6;\n+\t\tu32 rsvd0 : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_VF_DIR_VPP_V(x) \\\n+\t(0xf10 + (x) * 0x1000)\n+#define DLB_SYS_VF_DIR_VPP_V_RST 0x0\n+union dlb_sys_vf_dir_vpp_v {\n+\tstruct {\n+\t\tu32 vpp_v : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_VF_DIR_VPP2PP(x) \\\n+\t(0xf18 + (x) * 0x1000)\n+#define DLB_SYS_VF_DIR_VPP2PP_RST 0x0\n+union dlb_sys_vf_dir_vpp2pp {\n+\tstruct {\n+\t\tu32 pp : 7;\n+\t\tu32 rsvd0 : 25;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_VF_LDB_VQID_V(x) \\\n+\t(0xf20 + (x) * 0x1000)\n+#define DLB_SYS_VF_LDB_VQID_V_RST 0x0\n+union dlb_sys_vf_ldb_vqid_v {\n+\tstruct {\n+\t\tu32 vqid_v : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_VF_LDB_VQID2QID(x) \\\n+\t(0xf28 + (x) * 0x1000)\n+#define DLB_SYS_VF_LDB_VQID2QID_RST 0x0\n+union dlb_sys_vf_ldb_vqid2qid {\n+\tstruct {\n+\t\tu32 qid : 7;\n+\t\tu32 rsvd0 : 25;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_QID2VQID(x) \\\n+\t(0xf2c + (x) * 0x1000)\n+#define DLB_SYS_LDB_QID2VQID_RST 0x0\n+union dlb_sys_ldb_qid2vqid {\n+\tstruct {\n+\t\tu32 vqid : 7;\n+\t\tu32 rsvd0 : 25;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_VF_DIR_VQID_V(x) \\\n+\t(0xf30 + (x) * 0x1000)\n+#define DLB_SYS_VF_DIR_VQID_V_RST 0x0\n+union dlb_sys_vf_dir_vqid_v {\n+\tstruct {\n+\t\tu32 vqid_v : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_VF_DIR_VQID2QID(x) \\\n+\t(0xf38 + (x) * 0x1000)\n+#define DLB_SYS_VF_DIR_VQID2QID_RST 0x0\n+union dlb_sys_vf_dir_vqid2qid {\n+\tstruct {\n+\t\tu32 qid : 7;\n+\t\tu32 rsvd0 : 25;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_VASQID_V(x) \\\n+\t(0xf60 + (x) * 0x1000)\n+#define DLB_SYS_LDB_VASQID_V_RST 0x0\n+union dlb_sys_ldb_vasqid_v {\n+\tstruct {\n+\t\tu32 vasqid_v : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_VASQID_V(x) \\\n+\t(0xf68 + (x) * 0x1000)\n+#define DLB_SYS_DIR_VASQID_V_RST 0x0\n+union dlb_sys_dir_vasqid_v {\n+\tstruct {\n+\t\tu32 vasqid_v : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_WBUF_DIR_FLAGS(x) \\\n+\t(0xf70 + (x) * 0x1000)\n+#define DLB_SYS_WBUF_DIR_FLAGS_RST 0x0\n+union dlb_sys_wbuf_dir_flags {\n+\tstruct {\n+\t\tu32 wb_v : 4;\n+\t\tu32 cl : 1;\n+\t\tu32 busy : 1;\n+\t\tu32 opt : 1;\n+\t\tu32 rsvd0 : 25;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_WBUF_LDB_FLAGS(x) \\\n+\t(0xf78 + (x) * 0x1000)\n+#define DLB_SYS_WBUF_LDB_FLAGS_RST 0x0\n+union dlb_sys_wbuf_ldb_flags {\n+\tstruct {\n+\t\tu32 wb_v : 4;\n+\t\tu32 cl : 1;\n+\t\tu32 busy : 1;\n+\t\tu32 rsvd0 : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_ALARM_VF_SYND2(x) \\\n+\t(0x8000018 + (x) * 0x1000)\n+#define DLB_SYS_ALARM_VF_SYND2_RST 0x0\n+union dlb_sys_alarm_vf_synd2 {\n+\tstruct {\n+\t\tu32 lock_id : 16;\n+\t\tu32 meas : 1;\n+\t\tu32 debug : 7;\n+\t\tu32 cq_pop : 1;\n+\t\tu32 qe_uhl : 1;\n+\t\tu32 qe_orsp : 1;\n+\t\tu32 qe_valid : 1;\n+\t\tu32 cq_int_rearm : 1;\n+\t\tu32 dsi_error : 1;\n+\t\tu32 rsvd0 : 2;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_ALARM_VF_SYND1(x) \\\n+\t(0x8000014 + (x) * 0x1000)\n+#define DLB_SYS_ALARM_VF_SYND1_RST 0x0\n+union dlb_sys_alarm_vf_synd1 {\n+\tstruct {\n+\t\tu32 dsi : 16;\n+\t\tu32 qid : 8;\n+\t\tu32 qtype : 2;\n+\t\tu32 qpri : 3;\n+\t\tu32 msg_type : 3;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_ALARM_VF_SYND0(x) \\\n+\t(0x8000010 + (x) * 0x1000)\n+#define DLB_SYS_ALARM_VF_SYND0_RST 0x0\n+union dlb_sys_alarm_vf_synd0 {\n+\tstruct {\n+\t\tu32 syndrome : 8;\n+\t\tu32 rtype : 2;\n+\t\tu32 rsvd0 : 2;\n+\t\tu32 from_dmv : 1;\n+\t\tu32 is_ldb : 1;\n+\t\tu32 cls : 2;\n+\t\tu32 aid : 6;\n+\t\tu32 unit : 4;\n+\t\tu32 source : 4;\n+\t\tu32 more : 1;\n+\t\tu32 valid : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_QID_V(x) \\\n+\t(0x8000034 + (x) * 0x1000)\n+#define DLB_SYS_LDB_QID_V_RST 0x0\n+union dlb_sys_ldb_qid_v {\n+\tstruct {\n+\t\tu32 qid_v : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_QID_CFG_V(x) \\\n+\t(0x8000030 + (x) * 0x1000)\n+#define DLB_SYS_LDB_QID_CFG_V_RST 0x0\n+union dlb_sys_ldb_qid_cfg_v {\n+\tstruct {\n+\t\tu32 sn_cfg_v : 1;\n+\t\tu32 fid_cfg_v : 1;\n+\t\tu32 rsvd0 : 30;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_QID_V(x) \\\n+\t(0x8000040 + (x) * 0x1000)\n+#define DLB_SYS_DIR_QID_V_RST 0x0\n+union dlb_sys_dir_qid_v {\n+\tstruct {\n+\t\tu32 qid_v : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_POOL_ENBLD(x) \\\n+\t(0x8000070 + (x) * 0x1000)\n+#define DLB_SYS_LDB_POOL_ENBLD_RST 0x0\n+union dlb_sys_ldb_pool_enbld {\n+\tstruct {\n+\t\tu32 pool_enabled : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_POOL_ENBLD(x) \\\n+\t(0x8000080 + (x) * 0x1000)\n+#define DLB_SYS_DIR_POOL_ENBLD_RST 0x0\n+union dlb_sys_dir_pool_enbld {\n+\tstruct {\n+\t\tu32 pool_enabled : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_PP2VPP(x) \\\n+\t(0x8000090 + (x) * 0x1000)\n+#define DLB_SYS_LDB_PP2VPP_RST 0x0\n+union dlb_sys_ldb_pp2vpp {\n+\tstruct {\n+\t\tu32 vpp : 6;\n+\t\tu32 rsvd0 : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_PP2VPP(x) \\\n+\t(0x8000094 + (x) * 0x1000)\n+#define DLB_SYS_DIR_PP2VPP_RST 0x0\n+union dlb_sys_dir_pp2vpp {\n+\tstruct {\n+\t\tu32 vpp : 7;\n+\t\tu32 rsvd0 : 25;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_PP_V(x) \\\n+\t(0x8000128 + (x) * 0x1000)\n+#define DLB_SYS_LDB_PP_V_RST 0x0\n+union dlb_sys_ldb_pp_v {\n+\tstruct {\n+\t\tu32 pp_v : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_CQ_ISR(x) \\\n+\t(0x8000124 + (x) * 0x1000)\n+#define DLB_SYS_LDB_CQ_ISR_RST 0x0\n+/* CQ Interrupt Modes */\n+#define DLB_CQ_ISR_MODE_DIS  0\n+#define DLB_CQ_ISR_MODE_MSI  1\n+#define DLB_CQ_ISR_MODE_MSIX 2\n+union dlb_sys_ldb_cq_isr {\n+\tstruct {\n+\t\tu32 vector : 6;\n+\t\tu32 vf : 4;\n+\t\tu32 en_code : 2;\n+\t\tu32 rsvd0 : 20;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_CQ2VF_PF(x) \\\n+\t(0x8000120 + (x) * 0x1000)\n+#define DLB_SYS_LDB_CQ2VF_PF_RST 0x0\n+union dlb_sys_ldb_cq2vf_pf {\n+\tstruct {\n+\t\tu32 vf : 4;\n+\t\tu32 is_pf : 1;\n+\t\tu32 rsvd0 : 27;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_PP2VAS(x) \\\n+\t(0x800011c + (x) * 0x1000)\n+#define DLB_SYS_LDB_PP2VAS_RST 0x0\n+union dlb_sys_ldb_pp2vas {\n+\tstruct {\n+\t\tu32 vas : 5;\n+\t\tu32 rsvd0 : 27;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_PP2LDBPOOL(x) \\\n+\t(0x8000118 + (x) * 0x1000)\n+#define DLB_SYS_LDB_PP2LDBPOOL_RST 0x0\n+union dlb_sys_ldb_pp2ldbpool {\n+\tstruct {\n+\t\tu32 ldbpool : 6;\n+\t\tu32 rsvd0 : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_PP2DIRPOOL(x) \\\n+\t(0x8000114 + (x) * 0x1000)\n+#define DLB_SYS_LDB_PP2DIRPOOL_RST 0x0\n+union dlb_sys_ldb_pp2dirpool {\n+\tstruct {\n+\t\tu32 dirpool : 6;\n+\t\tu32 rsvd0 : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_PP2VF_PF(x) \\\n+\t(0x8000110 + (x) * 0x1000)\n+#define DLB_SYS_LDB_PP2VF_PF_RST 0x0\n+union dlb_sys_ldb_pp2vf_pf {\n+\tstruct {\n+\t\tu32 vf : 4;\n+\t\tu32 is_pf : 1;\n+\t\tu32 rsvd0 : 27;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_PP_ADDR_U(x) \\\n+\t(0x800010c + (x) * 0x1000)\n+#define DLB_SYS_LDB_PP_ADDR_U_RST 0x0\n+union dlb_sys_ldb_pp_addr_u {\n+\tstruct {\n+\t\tu32 addr_u : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_PP_ADDR_L(x) \\\n+\t(0x8000108 + (x) * 0x1000)\n+#define DLB_SYS_LDB_PP_ADDR_L_RST 0x0\n+union dlb_sys_ldb_pp_addr_l {\n+\tstruct {\n+\t\tu32 rsvd0 : 7;\n+\t\tu32 addr_l : 25;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_CQ_ADDR_U(x) \\\n+\t(0x8000104 + (x) * 0x1000)\n+#define DLB_SYS_LDB_CQ_ADDR_U_RST 0x0\n+union dlb_sys_ldb_cq_addr_u {\n+\tstruct {\n+\t\tu32 addr_u : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_CQ_ADDR_L(x) \\\n+\t(0x8000100 + (x) * 0x1000)\n+#define DLB_SYS_LDB_CQ_ADDR_L_RST 0x0\n+union dlb_sys_ldb_cq_addr_l {\n+\tstruct {\n+\t\tu32 rsvd0 : 6;\n+\t\tu32 addr_l : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_PP_V(x) \\\n+\t(0x8000228 + (x) * 0x1000)\n+#define DLB_SYS_DIR_PP_V_RST 0x0\n+union dlb_sys_dir_pp_v {\n+\tstruct {\n+\t\tu32 pp_v : 1;\n+\t\tu32 mb_dm : 1;\n+\t\tu32 rsvd0 : 30;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_CQ_ISR(x) \\\n+\t(0x8000224 + (x) * 0x1000)\n+#define DLB_SYS_DIR_CQ_ISR_RST 0x0\n+union dlb_sys_dir_cq_isr {\n+\tstruct {\n+\t\tu32 vector : 6;\n+\t\tu32 vf : 4;\n+\t\tu32 en_code : 2;\n+\t\tu32 rsvd0 : 20;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_CQ2VF_PF(x) \\\n+\t(0x8000220 + (x) * 0x1000)\n+#define DLB_SYS_DIR_CQ2VF_PF_RST 0x0\n+union dlb_sys_dir_cq2vf_pf {\n+\tstruct {\n+\t\tu32 vf : 4;\n+\t\tu32 is_pf : 1;\n+\t\tu32 rsvd0 : 27;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_PP2VAS(x) \\\n+\t(0x800021c + (x) * 0x1000)\n+#define DLB_SYS_DIR_PP2VAS_RST 0x0\n+union dlb_sys_dir_pp2vas {\n+\tstruct {\n+\t\tu32 vas : 5;\n+\t\tu32 rsvd0 : 27;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_PP2LDBPOOL(x) \\\n+\t(0x8000218 + (x) * 0x1000)\n+#define DLB_SYS_DIR_PP2LDBPOOL_RST 0x0\n+union dlb_sys_dir_pp2ldbpool {\n+\tstruct {\n+\t\tu32 ldbpool : 6;\n+\t\tu32 rsvd0 : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_PP2DIRPOOL(x) \\\n+\t(0x8000214 + (x) * 0x1000)\n+#define DLB_SYS_DIR_PP2DIRPOOL_RST 0x0\n+union dlb_sys_dir_pp2dirpool {\n+\tstruct {\n+\t\tu32 dirpool : 6;\n+\t\tu32 rsvd0 : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_PP2VF_PF(x) \\\n+\t(0x8000210 + (x) * 0x1000)\n+#define DLB_SYS_DIR_PP2VF_PF_RST 0x0\n+union dlb_sys_dir_pp2vf_pf {\n+\tstruct {\n+\t\tu32 vf : 4;\n+\t\tu32 is_pf : 1;\n+\t\tu32 is_hw_dsi : 1;\n+\t\tu32 rsvd0 : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_PP_ADDR_U(x) \\\n+\t(0x800020c + (x) * 0x1000)\n+#define DLB_SYS_DIR_PP_ADDR_U_RST 0x0\n+union dlb_sys_dir_pp_addr_u {\n+\tstruct {\n+\t\tu32 addr_u : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_PP_ADDR_L(x) \\\n+\t(0x8000208 + (x) * 0x1000)\n+#define DLB_SYS_DIR_PP_ADDR_L_RST 0x0\n+union dlb_sys_dir_pp_addr_l {\n+\tstruct {\n+\t\tu32 rsvd0 : 7;\n+\t\tu32 addr_l : 25;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_CQ_ADDR_U(x) \\\n+\t(0x8000204 + (x) * 0x1000)\n+#define DLB_SYS_DIR_CQ_ADDR_U_RST 0x0\n+union dlb_sys_dir_cq_addr_u {\n+\tstruct {\n+\t\tu32 addr_u : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_CQ_ADDR_L(x) \\\n+\t(0x8000200 + (x) * 0x1000)\n+#define DLB_SYS_DIR_CQ_ADDR_L_RST 0x0\n+union dlb_sys_dir_cq_addr_l {\n+\tstruct {\n+\t\tu32 rsvd0 : 6;\n+\t\tu32 addr_l : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_INGRESS_ALARM_ENBL 0x300\n+#define DLB_SYS_INGRESS_ALARM_ENBL_RST 0x0\n+union dlb_sys_ingress_alarm_enbl {\n+\tstruct {\n+\t\tu32 illegal_hcw : 1;\n+\t\tu32 illegal_pp : 1;\n+\t\tu32 disabled_pp : 1;\n+\t\tu32 illegal_qid : 1;\n+\t\tu32 disabled_qid : 1;\n+\t\tu32 illegal_ldb_qid_cfg : 1;\n+\t\tu32 illegal_cqid : 1;\n+\t\tu32 rsvd0 : 25;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_CQ_MODE 0x30c\n+#define DLB_SYS_CQ_MODE_RST 0x0\n+union dlb_sys_cq_mode {\n+\tstruct {\n+\t\tu32 ldb_cq64 : 1;\n+\t\tu32 dir_cq64 : 1;\n+\t\tu32 rsvd0 : 30;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_FUNC_VF_BAR_DSBL(x) \\\n+\t(0x310 + (x) * 0x4)\n+#define DLB_SYS_FUNC_VF_BAR_DSBL_RST 0x0\n+union dlb_sys_func_vf_bar_dsbl {\n+\tstruct {\n+\t\tu32 func_vf_bar_dis : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_MSIX_ACK 0x400\n+#define DLB_SYS_MSIX_ACK_RST 0x0\n+union dlb_sys_msix_ack {\n+\tstruct {\n+\t\tu32 msix_0_ack : 1;\n+\t\tu32 msix_1_ack : 1;\n+\t\tu32 msix_2_ack : 1;\n+\t\tu32 msix_3_ack : 1;\n+\t\tu32 msix_4_ack : 1;\n+\t\tu32 msix_5_ack : 1;\n+\t\tu32 msix_6_ack : 1;\n+\t\tu32 msix_7_ack : 1;\n+\t\tu32 msix_8_ack : 1;\n+\t\tu32 rsvd0 : 23;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_MSIX_PASSTHRU 0x404\n+#define DLB_SYS_MSIX_PASSTHRU_RST 0x0\n+union dlb_sys_msix_passthru {\n+\tstruct {\n+\t\tu32 msix_0_passthru : 1;\n+\t\tu32 msix_1_passthru : 1;\n+\t\tu32 msix_2_passthru : 1;\n+\t\tu32 msix_3_passthru : 1;\n+\t\tu32 msix_4_passthru : 1;\n+\t\tu32 msix_5_passthru : 1;\n+\t\tu32 msix_6_passthru : 1;\n+\t\tu32 msix_7_passthru : 1;\n+\t\tu32 msix_8_passthru : 1;\n+\t\tu32 rsvd0 : 23;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_MSIX_MODE 0x408\n+#define DLB_SYS_MSIX_MODE_RST 0x0\n+/* MSI-X Modes */\n+#define DLB_MSIX_MODE_PACKED     0\n+#define DLB_MSIX_MODE_COMPRESSED 1\n+union dlb_sys_msix_mode {\n+\tstruct {\n+\t\tu32 mode : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_CQ_31_0_OCC_INT_STS 0x440\n+#define DLB_SYS_DIR_CQ_31_0_OCC_INT_STS_RST 0x0\n+union dlb_sys_dir_cq_31_0_occ_int_sts {\n+\tstruct {\n+\t\tu32 cq_0_occ_int : 1;\n+\t\tu32 cq_1_occ_int : 1;\n+\t\tu32 cq_2_occ_int : 1;\n+\t\tu32 cq_3_occ_int : 1;\n+\t\tu32 cq_4_occ_int : 1;\n+\t\tu32 cq_5_occ_int : 1;\n+\t\tu32 cq_6_occ_int : 1;\n+\t\tu32 cq_7_occ_int : 1;\n+\t\tu32 cq_8_occ_int : 1;\n+\t\tu32 cq_9_occ_int : 1;\n+\t\tu32 cq_10_occ_int : 1;\n+\t\tu32 cq_11_occ_int : 1;\n+\t\tu32 cq_12_occ_int : 1;\n+\t\tu32 cq_13_occ_int : 1;\n+\t\tu32 cq_14_occ_int : 1;\n+\t\tu32 cq_15_occ_int : 1;\n+\t\tu32 cq_16_occ_int : 1;\n+\t\tu32 cq_17_occ_int : 1;\n+\t\tu32 cq_18_occ_int : 1;\n+\t\tu32 cq_19_occ_int : 1;\n+\t\tu32 cq_20_occ_int : 1;\n+\t\tu32 cq_21_occ_int : 1;\n+\t\tu32 cq_22_occ_int : 1;\n+\t\tu32 cq_23_occ_int : 1;\n+\t\tu32 cq_24_occ_int : 1;\n+\t\tu32 cq_25_occ_int : 1;\n+\t\tu32 cq_26_occ_int : 1;\n+\t\tu32 cq_27_occ_int : 1;\n+\t\tu32 cq_28_occ_int : 1;\n+\t\tu32 cq_29_occ_int : 1;\n+\t\tu32 cq_30_occ_int : 1;\n+\t\tu32 cq_31_occ_int : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_CQ_63_32_OCC_INT_STS 0x444\n+#define DLB_SYS_DIR_CQ_63_32_OCC_INT_STS_RST 0x0\n+union dlb_sys_dir_cq_63_32_occ_int_sts {\n+\tstruct {\n+\t\tu32 cq_32_occ_int : 1;\n+\t\tu32 cq_33_occ_int : 1;\n+\t\tu32 cq_34_occ_int : 1;\n+\t\tu32 cq_35_occ_int : 1;\n+\t\tu32 cq_36_occ_int : 1;\n+\t\tu32 cq_37_occ_int : 1;\n+\t\tu32 cq_38_occ_int : 1;\n+\t\tu32 cq_39_occ_int : 1;\n+\t\tu32 cq_40_occ_int : 1;\n+\t\tu32 cq_41_occ_int : 1;\n+\t\tu32 cq_42_occ_int : 1;\n+\t\tu32 cq_43_occ_int : 1;\n+\t\tu32 cq_44_occ_int : 1;\n+\t\tu32 cq_45_occ_int : 1;\n+\t\tu32 cq_46_occ_int : 1;\n+\t\tu32 cq_47_occ_int : 1;\n+\t\tu32 cq_48_occ_int : 1;\n+\t\tu32 cq_49_occ_int : 1;\n+\t\tu32 cq_50_occ_int : 1;\n+\t\tu32 cq_51_occ_int : 1;\n+\t\tu32 cq_52_occ_int : 1;\n+\t\tu32 cq_53_occ_int : 1;\n+\t\tu32 cq_54_occ_int : 1;\n+\t\tu32 cq_55_occ_int : 1;\n+\t\tu32 cq_56_occ_int : 1;\n+\t\tu32 cq_57_occ_int : 1;\n+\t\tu32 cq_58_occ_int : 1;\n+\t\tu32 cq_59_occ_int : 1;\n+\t\tu32 cq_60_occ_int : 1;\n+\t\tu32 cq_61_occ_int : 1;\n+\t\tu32 cq_62_occ_int : 1;\n+\t\tu32 cq_63_occ_int : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_CQ_95_64_OCC_INT_STS 0x448\n+#define DLB_SYS_DIR_CQ_95_64_OCC_INT_STS_RST 0x0\n+union dlb_sys_dir_cq_95_64_occ_int_sts {\n+\tstruct {\n+\t\tu32 cq_64_occ_int : 1;\n+\t\tu32 cq_65_occ_int : 1;\n+\t\tu32 cq_66_occ_int : 1;\n+\t\tu32 cq_67_occ_int : 1;\n+\t\tu32 cq_68_occ_int : 1;\n+\t\tu32 cq_69_occ_int : 1;\n+\t\tu32 cq_70_occ_int : 1;\n+\t\tu32 cq_71_occ_int : 1;\n+\t\tu32 cq_72_occ_int : 1;\n+\t\tu32 cq_73_occ_int : 1;\n+\t\tu32 cq_74_occ_int : 1;\n+\t\tu32 cq_75_occ_int : 1;\n+\t\tu32 cq_76_occ_int : 1;\n+\t\tu32 cq_77_occ_int : 1;\n+\t\tu32 cq_78_occ_int : 1;\n+\t\tu32 cq_79_occ_int : 1;\n+\t\tu32 cq_80_occ_int : 1;\n+\t\tu32 cq_81_occ_int : 1;\n+\t\tu32 cq_82_occ_int : 1;\n+\t\tu32 cq_83_occ_int : 1;\n+\t\tu32 cq_84_occ_int : 1;\n+\t\tu32 cq_85_occ_int : 1;\n+\t\tu32 cq_86_occ_int : 1;\n+\t\tu32 cq_87_occ_int : 1;\n+\t\tu32 cq_88_occ_int : 1;\n+\t\tu32 cq_89_occ_int : 1;\n+\t\tu32 cq_90_occ_int : 1;\n+\t\tu32 cq_91_occ_int : 1;\n+\t\tu32 cq_92_occ_int : 1;\n+\t\tu32 cq_93_occ_int : 1;\n+\t\tu32 cq_94_occ_int : 1;\n+\t\tu32 cq_95_occ_int : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_DIR_CQ_127_96_OCC_INT_STS 0x44c\n+#define DLB_SYS_DIR_CQ_127_96_OCC_INT_STS_RST 0x0\n+union dlb_sys_dir_cq_127_96_occ_int_sts {\n+\tstruct {\n+\t\tu32 cq_96_occ_int : 1;\n+\t\tu32 cq_97_occ_int : 1;\n+\t\tu32 cq_98_occ_int : 1;\n+\t\tu32 cq_99_occ_int : 1;\n+\t\tu32 cq_100_occ_int : 1;\n+\t\tu32 cq_101_occ_int : 1;\n+\t\tu32 cq_102_occ_int : 1;\n+\t\tu32 cq_103_occ_int : 1;\n+\t\tu32 cq_104_occ_int : 1;\n+\t\tu32 cq_105_occ_int : 1;\n+\t\tu32 cq_106_occ_int : 1;\n+\t\tu32 cq_107_occ_int : 1;\n+\t\tu32 cq_108_occ_int : 1;\n+\t\tu32 cq_109_occ_int : 1;\n+\t\tu32 cq_110_occ_int : 1;\n+\t\tu32 cq_111_occ_int : 1;\n+\t\tu32 cq_112_occ_int : 1;\n+\t\tu32 cq_113_occ_int : 1;\n+\t\tu32 cq_114_occ_int : 1;\n+\t\tu32 cq_115_occ_int : 1;\n+\t\tu32 cq_116_occ_int : 1;\n+\t\tu32 cq_117_occ_int : 1;\n+\t\tu32 cq_118_occ_int : 1;\n+\t\tu32 cq_119_occ_int : 1;\n+\t\tu32 cq_120_occ_int : 1;\n+\t\tu32 cq_121_occ_int : 1;\n+\t\tu32 cq_122_occ_int : 1;\n+\t\tu32 cq_123_occ_int : 1;\n+\t\tu32 cq_124_occ_int : 1;\n+\t\tu32 cq_125_occ_int : 1;\n+\t\tu32 cq_126_occ_int : 1;\n+\t\tu32 cq_127_occ_int : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_CQ_31_0_OCC_INT_STS 0x460\n+#define DLB_SYS_LDB_CQ_31_0_OCC_INT_STS_RST 0x0\n+union dlb_sys_ldb_cq_31_0_occ_int_sts {\n+\tstruct {\n+\t\tu32 cq_0_occ_int : 1;\n+\t\tu32 cq_1_occ_int : 1;\n+\t\tu32 cq_2_occ_int : 1;\n+\t\tu32 cq_3_occ_int : 1;\n+\t\tu32 cq_4_occ_int : 1;\n+\t\tu32 cq_5_occ_int : 1;\n+\t\tu32 cq_6_occ_int : 1;\n+\t\tu32 cq_7_occ_int : 1;\n+\t\tu32 cq_8_occ_int : 1;\n+\t\tu32 cq_9_occ_int : 1;\n+\t\tu32 cq_10_occ_int : 1;\n+\t\tu32 cq_11_occ_int : 1;\n+\t\tu32 cq_12_occ_int : 1;\n+\t\tu32 cq_13_occ_int : 1;\n+\t\tu32 cq_14_occ_int : 1;\n+\t\tu32 cq_15_occ_int : 1;\n+\t\tu32 cq_16_occ_int : 1;\n+\t\tu32 cq_17_occ_int : 1;\n+\t\tu32 cq_18_occ_int : 1;\n+\t\tu32 cq_19_occ_int : 1;\n+\t\tu32 cq_20_occ_int : 1;\n+\t\tu32 cq_21_occ_int : 1;\n+\t\tu32 cq_22_occ_int : 1;\n+\t\tu32 cq_23_occ_int : 1;\n+\t\tu32 cq_24_occ_int : 1;\n+\t\tu32 cq_25_occ_int : 1;\n+\t\tu32 cq_26_occ_int : 1;\n+\t\tu32 cq_27_occ_int : 1;\n+\t\tu32 cq_28_occ_int : 1;\n+\t\tu32 cq_29_occ_int : 1;\n+\t\tu32 cq_30_occ_int : 1;\n+\t\tu32 cq_31_occ_int : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_LDB_CQ_63_32_OCC_INT_STS 0x464\n+#define DLB_SYS_LDB_CQ_63_32_OCC_INT_STS_RST 0x0\n+union dlb_sys_ldb_cq_63_32_occ_int_sts {\n+\tstruct {\n+\t\tu32 cq_32_occ_int : 1;\n+\t\tu32 cq_33_occ_int : 1;\n+\t\tu32 cq_34_occ_int : 1;\n+\t\tu32 cq_35_occ_int : 1;\n+\t\tu32 cq_36_occ_int : 1;\n+\t\tu32 cq_37_occ_int : 1;\n+\t\tu32 cq_38_occ_int : 1;\n+\t\tu32 cq_39_occ_int : 1;\n+\t\tu32 cq_40_occ_int : 1;\n+\t\tu32 cq_41_occ_int : 1;\n+\t\tu32 cq_42_occ_int : 1;\n+\t\tu32 cq_43_occ_int : 1;\n+\t\tu32 cq_44_occ_int : 1;\n+\t\tu32 cq_45_occ_int : 1;\n+\t\tu32 cq_46_occ_int : 1;\n+\t\tu32 cq_47_occ_int : 1;\n+\t\tu32 cq_48_occ_int : 1;\n+\t\tu32 cq_49_occ_int : 1;\n+\t\tu32 cq_50_occ_int : 1;\n+\t\tu32 cq_51_occ_int : 1;\n+\t\tu32 cq_52_occ_int : 1;\n+\t\tu32 cq_53_occ_int : 1;\n+\t\tu32 cq_54_occ_int : 1;\n+\t\tu32 cq_55_occ_int : 1;\n+\t\tu32 cq_56_occ_int : 1;\n+\t\tu32 cq_57_occ_int : 1;\n+\t\tu32 cq_58_occ_int : 1;\n+\t\tu32 cq_59_occ_int : 1;\n+\t\tu32 cq_60_occ_int : 1;\n+\t\tu32 cq_61_occ_int : 1;\n+\t\tu32 cq_62_occ_int : 1;\n+\t\tu32 cq_63_occ_int : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_ALARM_HW_SYND 0x50c\n+#define DLB_SYS_ALARM_HW_SYND_RST 0x0\n+union dlb_sys_alarm_hw_synd {\n+\tstruct {\n+\t\tu32 syndrome : 8;\n+\t\tu32 rtype : 2;\n+\t\tu32 rsvd0 : 2;\n+\t\tu32 from_dmv : 1;\n+\t\tu32 is_ldb : 1;\n+\t\tu32 cls : 2;\n+\t\tu32 aid : 6;\n+\t\tu32 unit : 4;\n+\t\tu32 source : 4;\n+\t\tu32 more : 1;\n+\t\tu32 valid : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_SYS_SYS_ALARM_INT_ENABLE 0xc001048\n+#define DLB_SYS_SYS_ALARM_INT_ENABLE_RST 0x7fffff\n+union dlb_sys_sys_alarm_int_enable {\n+\tstruct {\n+\t\tu32 cq_addr_overflow_error : 1;\n+\t\tu32 ingress_perr : 1;\n+\t\tu32 egress_perr : 1;\n+\t\tu32 alarm_perr : 1;\n+\t\tu32 vf_to_pf_isr_pend_error : 1;\n+\t\tu32 pf_to_vf_isr_pend_error : 1;\n+\t\tu32 timeout_error : 1;\n+\t\tu32 dmvw_sm_error : 1;\n+\t\tu32 pptr_sm_par_error : 1;\n+\t\tu32 pptr_sm_len_error : 1;\n+\t\tu32 sch_sm_error : 1;\n+\t\tu32 wbuf_flag_error : 1;\n+\t\tu32 dmvw_cl_error : 1;\n+\t\tu32 dmvr_cl_error : 1;\n+\t\tu32 cmpl_data_error : 1;\n+\t\tu32 cmpl_error : 1;\n+\t\tu32 fifo_underflow : 1;\n+\t\tu32 fifo_overflow : 1;\n+\t\tu32 sb_ep_parity_err : 1;\n+\t\tu32 ti_parity_err : 1;\n+\t\tu32 ri_parity_err : 1;\n+\t\tu32 cfgm_ppw_err : 1;\n+\t\tu32 system_csr_perr : 1;\n+\t\tu32 rsvd0 : 9;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ_LDB_TOT_SCH_CNT_CTRL(x) \\\n+\t(0x20000000 + (x) * 0x1000)\n+#define DLB_LSP_CQ_LDB_TOT_SCH_CNT_CTRL_RST 0x0\n+union dlb_lsp_cq_ldb_tot_sch_cnt_ctrl {\n+\tstruct {\n+\t\tu32 count : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ_LDB_DSBL(x) \\\n+\t(0x20000124 + (x) * 0x1000)\n+#define DLB_LSP_CQ_LDB_DSBL_RST 0x1\n+union dlb_lsp_cq_ldb_dsbl {\n+\tstruct {\n+\t\tu32 disabled : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ_LDB_TOT_SCH_CNTH(x) \\\n+\t(0x20000120 + (x) * 0x1000)\n+#define DLB_LSP_CQ_LDB_TOT_SCH_CNTH_RST 0x0\n+union dlb_lsp_cq_ldb_tot_sch_cnth {\n+\tstruct {\n+\t\tu32 count : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ_LDB_TOT_SCH_CNTL(x) \\\n+\t(0x2000011c + (x) * 0x1000)\n+#define DLB_LSP_CQ_LDB_TOT_SCH_CNTL_RST 0x0\n+union dlb_lsp_cq_ldb_tot_sch_cntl {\n+\tstruct {\n+\t\tu32 count : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ_LDB_TKN_DEPTH_SEL(x) \\\n+\t(0x20000118 + (x) * 0x1000)\n+#define DLB_LSP_CQ_LDB_TKN_DEPTH_SEL_RST 0x0\n+union dlb_lsp_cq_ldb_tkn_depth_sel {\n+\tstruct {\n+\t\tu32 token_depth_select : 4;\n+\t\tu32 ignore_depth : 1;\n+\t\tu32 enab_shallow_cq : 1;\n+\t\tu32 rsvd0 : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ_LDB_TKN_CNT(x) \\\n+\t(0x20000114 + (x) * 0x1000)\n+#define DLB_LSP_CQ_LDB_TKN_CNT_RST 0x0\n+union dlb_lsp_cq_ldb_tkn_cnt {\n+\tstruct {\n+\t\tu32 token_count : 11;\n+\t\tu32 rsvd0 : 21;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ_LDB_INFL_LIM(x) \\\n+\t(0x20000110 + (x) * 0x1000)\n+#define DLB_LSP_CQ_LDB_INFL_LIM_RST 0x0\n+union dlb_lsp_cq_ldb_infl_lim {\n+\tstruct {\n+\t\tu32 limit : 13;\n+\t\tu32 rsvd0 : 19;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ_LDB_INFL_CNT(x) \\\n+\t(0x2000010c + (x) * 0x1000)\n+#define DLB_LSP_CQ_LDB_INFL_CNT_RST 0x0\n+union dlb_lsp_cq_ldb_infl_cnt {\n+\tstruct {\n+\t\tu32 count : 13;\n+\t\tu32 rsvd0 : 19;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ2QID(x, y) \\\n+\t(0x20000104 + (x) * 0x1000 + (y) * 0x4)\n+#define DLB_LSP_CQ2QID_RST 0x0\n+union dlb_lsp_cq2qid {\n+\tstruct {\n+\t\tu32 qid_p0 : 7;\n+\t\tu32 rsvd3 : 1;\n+\t\tu32 qid_p1 : 7;\n+\t\tu32 rsvd2 : 1;\n+\t\tu32 qid_p2 : 7;\n+\t\tu32 rsvd1 : 1;\n+\t\tu32 qid_p3 : 7;\n+\t\tu32 rsvd0 : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ2PRIOV(x) \\\n+\t(0x20000100 + (x) * 0x1000)\n+#define DLB_LSP_CQ2PRIOV_RST 0x0\n+union dlb_lsp_cq2priov {\n+\tstruct {\n+\t\tu32 prio : 24;\n+\t\tu32 v : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ_DIR_DSBL(x) \\\n+\t(0x20000310 + (x) * 0x1000)\n+#define DLB_LSP_CQ_DIR_DSBL_RST 0x1\n+union dlb_lsp_cq_dir_dsbl {\n+\tstruct {\n+\t\tu32 disabled : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ_DIR_TKN_DEPTH_SEL_DSI(x) \\\n+\t(0x2000030c + (x) * 0x1000)\n+#define DLB_LSP_CQ_DIR_TKN_DEPTH_SEL_DSI_RST 0x0\n+union dlb_lsp_cq_dir_tkn_depth_sel_dsi {\n+\tstruct {\n+\t\tu32 token_depth_select : 4;\n+\t\tu32 disable_wb_opt : 1;\n+\t\tu32 ignore_depth : 1;\n+\t\tu32 rsvd0 : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ_DIR_TOT_SCH_CNTH(x) \\\n+\t(0x20000308 + (x) * 0x1000)\n+#define DLB_LSP_CQ_DIR_TOT_SCH_CNTH_RST 0x0\n+union dlb_lsp_cq_dir_tot_sch_cnth {\n+\tstruct {\n+\t\tu32 count : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ_DIR_TOT_SCH_CNTL(x) \\\n+\t(0x20000304 + (x) * 0x1000)\n+#define DLB_LSP_CQ_DIR_TOT_SCH_CNTL_RST 0x0\n+union dlb_lsp_cq_dir_tot_sch_cntl {\n+\tstruct {\n+\t\tu32 count : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CQ_DIR_TKN_CNT(x) \\\n+\t(0x20000300 + (x) * 0x1000)\n+#define DLB_LSP_CQ_DIR_TKN_CNT_RST 0x0\n+union dlb_lsp_cq_dir_tkn_cnt {\n+\tstruct {\n+\t\tu32 count : 11;\n+\t\tu32 rsvd0 : 21;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_QID_LDB_QID2CQIDX(x, y) \\\n+\t(0x20000400 + (x) * 0x1000 + (y) * 0x4)\n+#define DLB_LSP_QID_LDB_QID2CQIDX_RST 0x0\n+union dlb_lsp_qid_ldb_qid2cqidx {\n+\tstruct {\n+\t\tu32 cq_p0 : 8;\n+\t\tu32 cq_p1 : 8;\n+\t\tu32 cq_p2 : 8;\n+\t\tu32 cq_p3 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_QID_LDB_QID2CQIDX2(x, y) \\\n+\t(0x20000500 + (x) * 0x1000 + (y) * 0x4)\n+#define DLB_LSP_QID_LDB_QID2CQIDX2_RST 0x0\n+union dlb_lsp_qid_ldb_qid2cqidx2 {\n+\tstruct {\n+\t\tu32 cq_p0 : 8;\n+\t\tu32 cq_p1 : 8;\n+\t\tu32 cq_p2 : 8;\n+\t\tu32 cq_p3 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_QID_ATQ_ENQUEUE_CNT(x) \\\n+\t(0x2000066c + (x) * 0x1000)\n+#define DLB_LSP_QID_ATQ_ENQUEUE_CNT_RST 0x0\n+union dlb_lsp_qid_atq_enqueue_cnt {\n+\tstruct {\n+\t\tu32 count : 15;\n+\t\tu32 rsvd0 : 17;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_QID_LDB_INFL_LIM(x) \\\n+\t(0x2000064c + (x) * 0x1000)\n+#define DLB_LSP_QID_LDB_INFL_LIM_RST 0x0\n+union dlb_lsp_qid_ldb_infl_lim {\n+\tstruct {\n+\t\tu32 limit : 13;\n+\t\tu32 rsvd0 : 19;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_QID_LDB_INFL_CNT(x) \\\n+\t(0x2000062c + (x) * 0x1000)\n+#define DLB_LSP_QID_LDB_INFL_CNT_RST 0x0\n+union dlb_lsp_qid_ldb_infl_cnt {\n+\tstruct {\n+\t\tu32 count : 13;\n+\t\tu32 rsvd0 : 19;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_QID_AQED_ACTIVE_LIM(x) \\\n+\t(0x20000628 + (x) * 0x1000)\n+#define DLB_LSP_QID_AQED_ACTIVE_LIM_RST 0x0\n+union dlb_lsp_qid_aqed_active_lim {\n+\tstruct {\n+\t\tu32 limit : 12;\n+\t\tu32 rsvd0 : 20;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_QID_AQED_ACTIVE_CNT(x) \\\n+\t(0x20000624 + (x) * 0x1000)\n+#define DLB_LSP_QID_AQED_ACTIVE_CNT_RST 0x0\n+union dlb_lsp_qid_aqed_active_cnt {\n+\tstruct {\n+\t\tu32 count : 12;\n+\t\tu32 rsvd0 : 20;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_QID_LDB_ENQUEUE_CNT(x) \\\n+\t(0x20000604 + (x) * 0x1000)\n+#define DLB_LSP_QID_LDB_ENQUEUE_CNT_RST 0x0\n+union dlb_lsp_qid_ldb_enqueue_cnt {\n+\tstruct {\n+\t\tu32 count : 15;\n+\t\tu32 rsvd0 : 17;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_QID_LDB_REPLAY_CNT(x) \\\n+\t(0x20000600 + (x) * 0x1000)\n+#define DLB_LSP_QID_LDB_REPLAY_CNT_RST 0x0\n+union dlb_lsp_qid_ldb_replay_cnt {\n+\tstruct {\n+\t\tu32 count : 15;\n+\t\tu32 rsvd0 : 17;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_QID_DIR_ENQUEUE_CNT(x) \\\n+\t(0x20000700 + (x) * 0x1000)\n+#define DLB_LSP_QID_DIR_ENQUEUE_CNT_RST 0x0\n+union dlb_lsp_qid_dir_enqueue_cnt {\n+\tstruct {\n+\t\tu32 count : 13;\n+\t\tu32 rsvd0 : 19;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CTRL_CONFIG_0 0x2800002c\n+#define DLB_LSP_CTRL_CONFIG_0_RST 0x12cc\n+union dlb_lsp_ctrl_config_0 {\n+\tstruct {\n+\t\tu32 atm_cq_qid_priority_prot : 1;\n+\t\tu32 ldb_arb_ignore_empty : 1;\n+\t\tu32 ldb_arb_mode : 2;\n+\t\tu32 ldb_arb_threshold : 18;\n+\t\tu32 cfg_cq_sla_upd_always : 1;\n+\t\tu32 cfg_cq_wcn_upd_always : 1;\n+\t\tu32 spare : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CFG_ARB_WEIGHT_ATM_NALB_QID_1 0x28000028\n+#define DLB_LSP_CFG_ARB_WEIGHT_ATM_NALB_QID_1_RST 0x0\n+union dlb_lsp_cfg_arb_weight_atm_nalb_qid_1 {\n+\tstruct {\n+\t\tu32 slot4_weight : 8;\n+\t\tu32 slot5_weight : 8;\n+\t\tu32 slot6_weight : 8;\n+\t\tu32 slot7_weight : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CFG_ARB_WEIGHT_ATM_NALB_QID_0 0x28000024\n+#define DLB_LSP_CFG_ARB_WEIGHT_ATM_NALB_QID_0_RST 0x0\n+union dlb_lsp_cfg_arb_weight_atm_nalb_qid_0 {\n+\tstruct {\n+\t\tu32 slot0_weight : 8;\n+\t\tu32 slot1_weight : 8;\n+\t\tu32 slot2_weight : 8;\n+\t\tu32 slot3_weight : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CFG_ARB_WEIGHT_LDB_QID_1 0x28000020\n+#define DLB_LSP_CFG_ARB_WEIGHT_LDB_QID_1_RST 0x0\n+union dlb_lsp_cfg_arb_weight_ldb_qid_1 {\n+\tstruct {\n+\t\tu32 slot4_weight : 8;\n+\t\tu32 slot5_weight : 8;\n+\t\tu32 slot6_weight : 8;\n+\t\tu32 slot7_weight : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_CFG_ARB_WEIGHT_LDB_QID_0 0x2800001c\n+#define DLB_LSP_CFG_ARB_WEIGHT_LDB_QID_0_RST 0x0\n+union dlb_lsp_cfg_arb_weight_ldb_qid_0 {\n+\tstruct {\n+\t\tu32 slot0_weight : 8;\n+\t\tu32 slot1_weight : 8;\n+\t\tu32 slot2_weight : 8;\n+\t\tu32 slot3_weight : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_LDB_SCHED_CTRL 0x28100000\n+#define DLB_LSP_LDB_SCHED_CTRL_RST 0x0\n+union dlb_lsp_ldb_sched_ctrl {\n+\tstruct {\n+\t\tu32 cq : 8;\n+\t\tu32 qidix : 3;\n+\t\tu32 value : 1;\n+\t\tu32 nalb_haswork_v : 1;\n+\t\tu32 rlist_haswork_v : 1;\n+\t\tu32 slist_haswork_v : 1;\n+\t\tu32 inflight_ok_v : 1;\n+\t\tu32 aqed_nfull_v : 1;\n+\t\tu32 spare0 : 15;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_DIR_SCH_CNT_H 0x2820000c\n+#define DLB_LSP_DIR_SCH_CNT_H_RST 0x0\n+union dlb_lsp_dir_sch_cnt_h {\n+\tstruct {\n+\t\tu32 count : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_DIR_SCH_CNT_L 0x28200008\n+#define DLB_LSP_DIR_SCH_CNT_L_RST 0x0\n+union dlb_lsp_dir_sch_cnt_l {\n+\tstruct {\n+\t\tu32 count : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_LDB_SCH_CNT_H 0x28200004\n+#define DLB_LSP_LDB_SCH_CNT_H_RST 0x0\n+union dlb_lsp_ldb_sch_cnt_h {\n+\tstruct {\n+\t\tu32 count : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_LSP_LDB_SCH_CNT_L 0x28200000\n+#define DLB_LSP_LDB_SCH_CNT_L_RST 0x0\n+union dlb_lsp_ldb_sch_cnt_l {\n+\tstruct {\n+\t\tu32 count : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_DP_DIR_CSR_CTRL 0x38000018\n+#define DLB_DP_DIR_CSR_CTRL_RST 0xc0000000\n+union dlb_dp_dir_csr_ctrl {\n+\tstruct {\n+\t\tu32 cfg_int_dis : 1;\n+\t\tu32 cfg_int_dis_sbe : 1;\n+\t\tu32 cfg_int_dis_mbe : 1;\n+\t\tu32 spare0 : 27;\n+\t\tu32 cfg_vasr_dis : 1;\n+\t\tu32 cfg_int_dis_synd : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_DP_CFG_CTRL_ARB_WEIGHTS_TQPRI_DIR_1 0x38000014\n+#define DLB_DP_CFG_CTRL_ARB_WEIGHTS_TQPRI_DIR_1_RST 0xfffefdfc\n+union dlb_dp_cfg_ctrl_arb_weights_tqpri_dir_1 {\n+\tstruct {\n+\t\tu32 pri4 : 8;\n+\t\tu32 pri5 : 8;\n+\t\tu32 pri6 : 8;\n+\t\tu32 pri7 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_DP_CFG_CTRL_ARB_WEIGHTS_TQPRI_DIR_0 0x38000010\n+#define DLB_DP_CFG_CTRL_ARB_WEIGHTS_TQPRI_DIR_0_RST 0xfbfaf9f8\n+union dlb_dp_cfg_ctrl_arb_weights_tqpri_dir_0 {\n+\tstruct {\n+\t\tu32 pri0 : 8;\n+\t\tu32 pri1 : 8;\n+\t\tu32 pri2 : 8;\n+\t\tu32 pri3 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_DP_CFG_CTRL_ARB_WEIGHTS_TQPRI_REPLAY_1 0x3800000c\n+#define DLB_DP_CFG_CTRL_ARB_WEIGHTS_TQPRI_REPLAY_1_RST 0xfffefdfc\n+union dlb_dp_cfg_ctrl_arb_weights_tqpri_replay_1 {\n+\tstruct {\n+\t\tu32 pri4 : 8;\n+\t\tu32 pri5 : 8;\n+\t\tu32 pri6 : 8;\n+\t\tu32 pri7 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_DP_CFG_CTRL_ARB_WEIGHTS_TQPRI_REPLAY_0 0x38000008\n+#define DLB_DP_CFG_CTRL_ARB_WEIGHTS_TQPRI_REPLAY_0_RST 0xfbfaf9f8\n+union dlb_dp_cfg_ctrl_arb_weights_tqpri_replay_0 {\n+\tstruct {\n+\t\tu32 pri0 : 8;\n+\t\tu32 pri1 : 8;\n+\t\tu32 pri2 : 8;\n+\t\tu32 pri3 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_NALB_PIPE_CTRL_ARB_WEIGHTS_TQPRI_NALB_1 0x6800001c\n+#define DLB_NALB_PIPE_CTRL_ARB_WEIGHTS_TQPRI_NALB_1_RST 0xfffefdfc\n+union dlb_nalb_pipe_ctrl_arb_weights_tqpri_nalb_1 {\n+\tstruct {\n+\t\tu32 pri4 : 8;\n+\t\tu32 pri5 : 8;\n+\t\tu32 pri6 : 8;\n+\t\tu32 pri7 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_NALB_PIPE_CTRL_ARB_WEIGHTS_TQPRI_NALB_0 0x68000018\n+#define DLB_NALB_PIPE_CTRL_ARB_WEIGHTS_TQPRI_NALB_0_RST 0xfbfaf9f8\n+union dlb_nalb_pipe_ctrl_arb_weights_tqpri_nalb_0 {\n+\tstruct {\n+\t\tu32 pri0 : 8;\n+\t\tu32 pri1 : 8;\n+\t\tu32 pri2 : 8;\n+\t\tu32 pri3 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_NALB_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_ATQ_1 0x68000014\n+#define DLB_NALB_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_ATQ_1_RST 0xfffefdfc\n+union dlb_nalb_pipe_cfg_ctrl_arb_weights_tqpri_atq_1 {\n+\tstruct {\n+\t\tu32 pri4 : 8;\n+\t\tu32 pri5 : 8;\n+\t\tu32 pri6 : 8;\n+\t\tu32 pri7 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_NALB_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_ATQ_0 0x68000010\n+#define DLB_NALB_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_ATQ_0_RST 0xfbfaf9f8\n+union dlb_nalb_pipe_cfg_ctrl_arb_weights_tqpri_atq_0 {\n+\tstruct {\n+\t\tu32 pri0 : 8;\n+\t\tu32 pri1 : 8;\n+\t\tu32 pri2 : 8;\n+\t\tu32 pri3 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_NALB_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_REPLAY_1 0x6800000c\n+#define DLB_NALB_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_REPLAY_1_RST 0xfffefdfc\n+union dlb_nalb_pipe_cfg_ctrl_arb_weights_tqpri_replay_1 {\n+\tstruct {\n+\t\tu32 pri4 : 8;\n+\t\tu32 pri5 : 8;\n+\t\tu32 pri6 : 8;\n+\t\tu32 pri7 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_NALB_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_REPLAY_0 0x68000008\n+#define DLB_NALB_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_REPLAY_0_RST 0xfbfaf9f8\n+union dlb_nalb_pipe_cfg_ctrl_arb_weights_tqpri_replay_0 {\n+\tstruct {\n+\t\tu32 pri0 : 8;\n+\t\tu32 pri1 : 8;\n+\t\tu32 pri2 : 8;\n+\t\tu32 pri3 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_ATM_PIPE_QID_LDB_QID2CQIDX(x, y) \\\n+\t(0x70000000 + (x) * 0x1000 + (y) * 0x4)\n+#define DLB_ATM_PIPE_QID_LDB_QID2CQIDX_RST 0x0\n+union dlb_atm_pipe_qid_ldb_qid2cqidx {\n+\tstruct {\n+\t\tu32 cq_p0 : 8;\n+\t\tu32 cq_p1 : 8;\n+\t\tu32 cq_p2 : 8;\n+\t\tu32 cq_p3 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_ATM_PIPE_CFG_CTRL_ARB_WEIGHTS_SCHED_BIN 0x7800000c\n+#define DLB_ATM_PIPE_CFG_CTRL_ARB_WEIGHTS_SCHED_BIN_RST 0xfffefdfc\n+union dlb_atm_pipe_cfg_ctrl_arb_weights_sched_bin {\n+\tstruct {\n+\t\tu32 bin0 : 8;\n+\t\tu32 bin1 : 8;\n+\t\tu32 bin2 : 8;\n+\t\tu32 bin3 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_ATM_PIPE_CTRL_ARB_WEIGHTS_RDY_BIN 0x78000008\n+#define DLB_ATM_PIPE_CTRL_ARB_WEIGHTS_RDY_BIN_RST 0xfffefdfc\n+union dlb_atm_pipe_ctrl_arb_weights_rdy_bin {\n+\tstruct {\n+\t\tu32 bin0 : 8;\n+\t\tu32 bin1 : 8;\n+\t\tu32 bin2 : 8;\n+\t\tu32 bin3 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_AQED_PIPE_QID_FID_LIM(x) \\\n+\t(0x80000014 + (x) * 0x1000)\n+#define DLB_AQED_PIPE_QID_FID_LIM_RST 0x7ff\n+union dlb_aqed_pipe_qid_fid_lim {\n+\tstruct {\n+\t\tu32 qid_fid_limit : 13;\n+\t\tu32 rsvd0 : 19;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_AQED_PIPE_FL_POP_PTR(x) \\\n+\t(0x80000010 + (x) * 0x1000)\n+#define DLB_AQED_PIPE_FL_POP_PTR_RST 0x0\n+union dlb_aqed_pipe_fl_pop_ptr {\n+\tstruct {\n+\t\tu32 pop_ptr : 11;\n+\t\tu32 generation : 1;\n+\t\tu32 rsvd0 : 20;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_AQED_PIPE_FL_PUSH_PTR(x) \\\n+\t(0x8000000c + (x) * 0x1000)\n+#define DLB_AQED_PIPE_FL_PUSH_PTR_RST 0x0\n+union dlb_aqed_pipe_fl_push_ptr {\n+\tstruct {\n+\t\tu32 push_ptr : 11;\n+\t\tu32 generation : 1;\n+\t\tu32 rsvd0 : 20;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_AQED_PIPE_FL_BASE(x) \\\n+\t(0x80000008 + (x) * 0x1000)\n+#define DLB_AQED_PIPE_FL_BASE_RST 0x0\n+union dlb_aqed_pipe_fl_base {\n+\tstruct {\n+\t\tu32 base : 11;\n+\t\tu32 rsvd0 : 21;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_AQED_PIPE_FL_LIM(x) \\\n+\t(0x80000004 + (x) * 0x1000)\n+#define DLB_AQED_PIPE_FL_LIM_RST 0x800\n+union dlb_aqed_pipe_fl_lim {\n+\tstruct {\n+\t\tu32 limit : 11;\n+\t\tu32 freelist_disable : 1;\n+\t\tu32 rsvd0 : 20;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_AQED_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_ATM_0 0x88000008\n+#define DLB_AQED_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_ATM_0_RST 0xfffe\n+union dlb_aqed_pipe_cfg_ctrl_arb_weights_tqpri_atm_0 {\n+\tstruct {\n+\t\tu32 pri0 : 8;\n+\t\tu32 pri1 : 8;\n+\t\tu32 pri2 : 8;\n+\t\tu32 pri3 : 8;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_RO_PIPE_QID2GRPSLT(x) \\\n+\t(0x90000000 + (x) * 0x1000)\n+#define DLB_RO_PIPE_QID2GRPSLT_RST 0x0\n+union dlb_ro_pipe_qid2grpslt {\n+\tstruct {\n+\t\tu32 slot : 5;\n+\t\tu32 rsvd1 : 3;\n+\t\tu32 group : 2;\n+\t\tu32 rsvd0 : 22;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_RO_PIPE_GRP_SN_MODE 0x98000008\n+#define DLB_RO_PIPE_GRP_SN_MODE_RST 0x0\n+union dlb_ro_pipe_grp_sn_mode {\n+\tstruct {\n+\t\tu32 sn_mode_0 : 3;\n+\t\tu32 reserved0 : 5;\n+\t\tu32 sn_mode_1 : 3;\n+\t\tu32 reserved1 : 5;\n+\t\tu32 sn_mode_2 : 3;\n+\t\tu32 reserved2 : 5;\n+\t\tu32 sn_mode_3 : 3;\n+\t\tu32 reserved3 : 5;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_CFG_DIR_PP_SW_ALARM_EN(x) \\\n+\t(0xa000003c + (x) * 0x1000)\n+#define DLB_CHP_CFG_DIR_PP_SW_ALARM_EN_RST 0x1\n+union dlb_chp_cfg_dir_pp_sw_alarm_en {\n+\tstruct {\n+\t\tu32 alarm_enable : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_CQ_WD_ENB(x) \\\n+\t(0xa0000038 + (x) * 0x1000)\n+#define DLB_CHP_DIR_CQ_WD_ENB_RST 0x0\n+union dlb_chp_dir_cq_wd_enb {\n+\tstruct {\n+\t\tu32 wd_enable : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_LDB_PP2POOL(x) \\\n+\t(0xa0000034 + (x) * 0x1000)\n+#define DLB_CHP_DIR_LDB_PP2POOL_RST 0x0\n+union dlb_chp_dir_ldb_pp2pool {\n+\tstruct {\n+\t\tu32 pool : 6;\n+\t\tu32 rsvd0 : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_DIR_PP2POOL(x) \\\n+\t(0xa0000030 + (x) * 0x1000)\n+#define DLB_CHP_DIR_DIR_PP2POOL_RST 0x0\n+union dlb_chp_dir_dir_pp2pool {\n+\tstruct {\n+\t\tu32 pool : 6;\n+\t\tu32 rsvd0 : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_PP_LDB_CRD_CNT(x) \\\n+\t(0xa000002c + (x) * 0x1000)\n+#define DLB_CHP_DIR_PP_LDB_CRD_CNT_RST 0x0\n+union dlb_chp_dir_pp_ldb_crd_cnt {\n+\tstruct {\n+\t\tu32 count : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_PP_DIR_CRD_CNT(x) \\\n+\t(0xa0000028 + (x) * 0x1000)\n+#define DLB_CHP_DIR_PP_DIR_CRD_CNT_RST 0x0\n+union dlb_chp_dir_pp_dir_crd_cnt {\n+\tstruct {\n+\t\tu32 count : 14;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_CQ_TMR_THRESHOLD(x) \\\n+\t(0xa0000024 + (x) * 0x1000)\n+#define DLB_CHP_DIR_CQ_TMR_THRESHOLD_RST 0x0\n+union dlb_chp_dir_cq_tmr_threshold {\n+\tstruct {\n+\t\tu32 timer_thrsh : 14;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_CQ_INT_ENB(x) \\\n+\t(0xa0000020 + (x) * 0x1000)\n+#define DLB_CHP_DIR_CQ_INT_ENB_RST 0x0\n+union dlb_chp_dir_cq_int_enb {\n+\tstruct {\n+\t\tu32 en_tim : 1;\n+\t\tu32 en_depth : 1;\n+\t\tu32 rsvd0 : 30;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_CQ_INT_DEPTH_THRSH(x) \\\n+\t(0xa000001c + (x) * 0x1000)\n+#define DLB_CHP_DIR_CQ_INT_DEPTH_THRSH_RST 0x0\n+union dlb_chp_dir_cq_int_depth_thrsh {\n+\tstruct {\n+\t\tu32 depth_threshold : 12;\n+\t\tu32 rsvd0 : 20;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_CQ_TKN_DEPTH_SEL(x) \\\n+\t(0xa0000018 + (x) * 0x1000)\n+#define DLB_CHP_DIR_CQ_TKN_DEPTH_SEL_RST 0x0\n+union dlb_chp_dir_cq_tkn_depth_sel {\n+\tstruct {\n+\t\tu32 token_depth_select : 4;\n+\t\tu32 rsvd0 : 28;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_PP_LDB_MIN_CRD_QNT(x) \\\n+\t(0xa0000014 + (x) * 0x1000)\n+#define DLB_CHP_DIR_PP_LDB_MIN_CRD_QNT_RST 0x1\n+union dlb_chp_dir_pp_ldb_min_crd_qnt {\n+\tstruct {\n+\t\tu32 quanta : 10;\n+\t\tu32 rsvd0 : 22;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_PP_DIR_MIN_CRD_QNT(x) \\\n+\t(0xa0000010 + (x) * 0x1000)\n+#define DLB_CHP_DIR_PP_DIR_MIN_CRD_QNT_RST 0x1\n+union dlb_chp_dir_pp_dir_min_crd_qnt {\n+\tstruct {\n+\t\tu32 quanta : 10;\n+\t\tu32 rsvd0 : 22;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_PP_LDB_CRD_LWM(x) \\\n+\t(0xa000000c + (x) * 0x1000)\n+#define DLB_CHP_DIR_PP_LDB_CRD_LWM_RST 0x0\n+union dlb_chp_dir_pp_ldb_crd_lwm {\n+\tstruct {\n+\t\tu32 lwm : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_PP_LDB_CRD_HWM(x) \\\n+\t(0xa0000008 + (x) * 0x1000)\n+#define DLB_CHP_DIR_PP_LDB_CRD_HWM_RST 0x0\n+union dlb_chp_dir_pp_ldb_crd_hwm {\n+\tstruct {\n+\t\tu32 hwm : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_PP_DIR_CRD_LWM(x) \\\n+\t(0xa0000004 + (x) * 0x1000)\n+#define DLB_CHP_DIR_PP_DIR_CRD_LWM_RST 0x0\n+union dlb_chp_dir_pp_dir_crd_lwm {\n+\tstruct {\n+\t\tu32 lwm : 14;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_PP_DIR_CRD_HWM(x) \\\n+\t(0xa0000000 + (x) * 0x1000)\n+#define DLB_CHP_DIR_PP_DIR_CRD_HWM_RST 0x0\n+union dlb_chp_dir_pp_dir_crd_hwm {\n+\tstruct {\n+\t\tu32 hwm : 14;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_CFG_LDB_PP_SW_ALARM_EN(x) \\\n+\t(0xa0000148 + (x) * 0x1000)\n+#define DLB_CHP_CFG_LDB_PP_SW_ALARM_EN_RST 0x1\n+union dlb_chp_cfg_ldb_pp_sw_alarm_en {\n+\tstruct {\n+\t\tu32 alarm_enable : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_CQ_WD_ENB(x) \\\n+\t(0xa0000144 + (x) * 0x1000)\n+#define DLB_CHP_LDB_CQ_WD_ENB_RST 0x0\n+union dlb_chp_ldb_cq_wd_enb {\n+\tstruct {\n+\t\tu32 wd_enable : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_SN_CHK_ENBL(x) \\\n+\t(0xa0000140 + (x) * 0x1000)\n+#define DLB_CHP_SN_CHK_ENBL_RST 0x0\n+union dlb_chp_sn_chk_enbl {\n+\tstruct {\n+\t\tu32 en : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_HIST_LIST_BASE(x) \\\n+\t(0xa000013c + (x) * 0x1000)\n+#define DLB_CHP_HIST_LIST_BASE_RST 0x0\n+union dlb_chp_hist_list_base {\n+\tstruct {\n+\t\tu32 base : 13;\n+\t\tu32 rsvd0 : 19;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_HIST_LIST_LIM(x) \\\n+\t(0xa0000138 + (x) * 0x1000)\n+#define DLB_CHP_HIST_LIST_LIM_RST 0x0\n+union dlb_chp_hist_list_lim {\n+\tstruct {\n+\t\tu32 limit : 13;\n+\t\tu32 rsvd0 : 19;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_LDB_PP2POOL(x) \\\n+\t(0xa0000134 + (x) * 0x1000)\n+#define DLB_CHP_LDB_LDB_PP2POOL_RST 0x0\n+union dlb_chp_ldb_ldb_pp2pool {\n+\tstruct {\n+\t\tu32 pool : 6;\n+\t\tu32 rsvd0 : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_DIR_PP2POOL(x) \\\n+\t(0xa0000130 + (x) * 0x1000)\n+#define DLB_CHP_LDB_DIR_PP2POOL_RST 0x0\n+union dlb_chp_ldb_dir_pp2pool {\n+\tstruct {\n+\t\tu32 pool : 6;\n+\t\tu32 rsvd0 : 26;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_PP_LDB_CRD_CNT(x) \\\n+\t(0xa000012c + (x) * 0x1000)\n+#define DLB_CHP_LDB_PP_LDB_CRD_CNT_RST 0x0\n+union dlb_chp_ldb_pp_ldb_crd_cnt {\n+\tstruct {\n+\t\tu32 count : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_PP_DIR_CRD_CNT(x) \\\n+\t(0xa0000128 + (x) * 0x1000)\n+#define DLB_CHP_LDB_PP_DIR_CRD_CNT_RST 0x0\n+union dlb_chp_ldb_pp_dir_crd_cnt {\n+\tstruct {\n+\t\tu32 count : 14;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_CQ_TMR_THRESHOLD(x) \\\n+\t(0xa0000124 + (x) * 0x1000)\n+#define DLB_CHP_LDB_CQ_TMR_THRESHOLD_RST 0x0\n+union dlb_chp_ldb_cq_tmr_threshold {\n+\tstruct {\n+\t\tu32 thrsh : 14;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_CQ_INT_ENB(x) \\\n+\t(0xa0000120 + (x) * 0x1000)\n+#define DLB_CHP_LDB_CQ_INT_ENB_RST 0x0\n+union dlb_chp_ldb_cq_int_enb {\n+\tstruct {\n+\t\tu32 en_tim : 1;\n+\t\tu32 en_depth : 1;\n+\t\tu32 rsvd0 : 30;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_CQ_INT_DEPTH_THRSH(x) \\\n+\t(0xa000011c + (x) * 0x1000)\n+#define DLB_CHP_LDB_CQ_INT_DEPTH_THRSH_RST 0x0\n+union dlb_chp_ldb_cq_int_depth_thrsh {\n+\tstruct {\n+\t\tu32 depth_threshold : 12;\n+\t\tu32 rsvd0 : 20;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_CQ_TKN_DEPTH_SEL(x) \\\n+\t(0xa0000118 + (x) * 0x1000)\n+#define DLB_CHP_LDB_CQ_TKN_DEPTH_SEL_RST 0x0\n+union dlb_chp_ldb_cq_tkn_depth_sel {\n+\tstruct {\n+\t\tu32 token_depth_select : 4;\n+\t\tu32 rsvd0 : 28;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_PP_LDB_MIN_CRD_QNT(x) \\\n+\t(0xa0000114 + (x) * 0x1000)\n+#define DLB_CHP_LDB_PP_LDB_MIN_CRD_QNT_RST 0x1\n+union dlb_chp_ldb_pp_ldb_min_crd_qnt {\n+\tstruct {\n+\t\tu32 quanta : 10;\n+\t\tu32 rsvd0 : 22;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_PP_DIR_MIN_CRD_QNT(x) \\\n+\t(0xa0000110 + (x) * 0x1000)\n+#define DLB_CHP_LDB_PP_DIR_MIN_CRD_QNT_RST 0x1\n+union dlb_chp_ldb_pp_dir_min_crd_qnt {\n+\tstruct {\n+\t\tu32 quanta : 10;\n+\t\tu32 rsvd0 : 22;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_PP_LDB_CRD_LWM(x) \\\n+\t(0xa000010c + (x) * 0x1000)\n+#define DLB_CHP_LDB_PP_LDB_CRD_LWM_RST 0x0\n+union dlb_chp_ldb_pp_ldb_crd_lwm {\n+\tstruct {\n+\t\tu32 lwm : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_PP_LDB_CRD_HWM(x) \\\n+\t(0xa0000108 + (x) * 0x1000)\n+#define DLB_CHP_LDB_PP_LDB_CRD_HWM_RST 0x0\n+union dlb_chp_ldb_pp_ldb_crd_hwm {\n+\tstruct {\n+\t\tu32 hwm : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_PP_DIR_CRD_LWM(x) \\\n+\t(0xa0000104 + (x) * 0x1000)\n+#define DLB_CHP_LDB_PP_DIR_CRD_LWM_RST 0x0\n+union dlb_chp_ldb_pp_dir_crd_lwm {\n+\tstruct {\n+\t\tu32 lwm : 14;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_PP_DIR_CRD_HWM(x) \\\n+\t(0xa0000100 + (x) * 0x1000)\n+#define DLB_CHP_LDB_PP_DIR_CRD_HWM_RST 0x0\n+union dlb_chp_ldb_pp_dir_crd_hwm {\n+\tstruct {\n+\t\tu32 hwm : 14;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_CQ_DEPTH(x) \\\n+\t(0xa0000218 + (x) * 0x1000)\n+#define DLB_CHP_DIR_CQ_DEPTH_RST 0x0\n+union dlb_chp_dir_cq_depth {\n+\tstruct {\n+\t\tu32 cq_depth : 11;\n+\t\tu32 rsvd0 : 21;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_CQ_WPTR(x) \\\n+\t(0xa0000214 + (x) * 0x1000)\n+#define DLB_CHP_DIR_CQ_WPTR_RST 0x0\n+union dlb_chp_dir_cq_wptr {\n+\tstruct {\n+\t\tu32 write_pointer : 10;\n+\t\tu32 rsvd0 : 22;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_PP_LDB_PUSH_PTR(x) \\\n+\t(0xa0000210 + (x) * 0x1000)\n+#define DLB_CHP_DIR_PP_LDB_PUSH_PTR_RST 0x0\n+union dlb_chp_dir_pp_ldb_push_ptr {\n+\tstruct {\n+\t\tu32 push_pointer : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_PP_DIR_PUSH_PTR(x) \\\n+\t(0xa000020c + (x) * 0x1000)\n+#define DLB_CHP_DIR_PP_DIR_PUSH_PTR_RST 0x0\n+union dlb_chp_dir_pp_dir_push_ptr {\n+\tstruct {\n+\t\tu32 push_pointer : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_PP_STATE_RESET(x) \\\n+\t(0xa0000204 + (x) * 0x1000)\n+#define DLB_CHP_DIR_PP_STATE_RESET_RST 0x0\n+union dlb_chp_dir_pp_state_reset {\n+\tstruct {\n+\t\tu32 rsvd1 : 7;\n+\t\tu32 dir_type : 1;\n+\t\tu32 rsvd0 : 23;\n+\t\tu32 reset_pp_state : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_PP_CRD_REQ_STATE(x) \\\n+\t(0xa0000200 + (x) * 0x1000)\n+#define DLB_CHP_DIR_PP_CRD_REQ_STATE_RST 0x0\n+union dlb_chp_dir_pp_crd_req_state {\n+\tstruct {\n+\t\tu32 dir_crd_req_active_valid : 1;\n+\t\tu32 dir_crd_req_active_check : 1;\n+\t\tu32 dir_crd_req_active_busy : 1;\n+\t\tu32 rsvd1 : 1;\n+\t\tu32 ldb_crd_req_active_valid : 1;\n+\t\tu32 ldb_crd_req_active_check : 1;\n+\t\tu32 ldb_crd_req_active_busy : 1;\n+\t\tu32 rsvd0 : 1;\n+\t\tu32 no_pp_credit_update : 1;\n+\t\tu32 crd_req_state : 23;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_CQ_DEPTH(x) \\\n+\t(0xa0000320 + (x) * 0x1000)\n+#define DLB_CHP_LDB_CQ_DEPTH_RST 0x0\n+union dlb_chp_ldb_cq_depth {\n+\tstruct {\n+\t\tu32 depth : 11;\n+\t\tu32 reserved : 2;\n+\t\tu32 rsvd0 : 19;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_CQ_WPTR(x) \\\n+\t(0xa000031c + (x) * 0x1000)\n+#define DLB_CHP_LDB_CQ_WPTR_RST 0x0\n+union dlb_chp_ldb_cq_wptr {\n+\tstruct {\n+\t\tu32 write_pointer : 10;\n+\t\tu32 rsvd0 : 22;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_PP_LDB_PUSH_PTR(x) \\\n+\t(0xa0000318 + (x) * 0x1000)\n+#define DLB_CHP_LDB_PP_LDB_PUSH_PTR_RST 0x0\n+union dlb_chp_ldb_pp_ldb_push_ptr {\n+\tstruct {\n+\t\tu32 push_pointer : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_PP_DIR_PUSH_PTR(x) \\\n+\t(0xa0000314 + (x) * 0x1000)\n+#define DLB_CHP_LDB_PP_DIR_PUSH_PTR_RST 0x0\n+union dlb_chp_ldb_pp_dir_push_ptr {\n+\tstruct {\n+\t\tu32 push_pointer : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_HIST_LIST_POP_PTR(x) \\\n+\t(0xa000030c + (x) * 0x1000)\n+#define DLB_CHP_HIST_LIST_POP_PTR_RST 0x0\n+union dlb_chp_hist_list_pop_ptr {\n+\tstruct {\n+\t\tu32 pop_ptr : 13;\n+\t\tu32 generation : 1;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_HIST_LIST_PUSH_PTR(x) \\\n+\t(0xa0000308 + (x) * 0x1000)\n+#define DLB_CHP_HIST_LIST_PUSH_PTR_RST 0x0\n+union dlb_chp_hist_list_push_ptr {\n+\tstruct {\n+\t\tu32 push_ptr : 13;\n+\t\tu32 generation : 1;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_PP_STATE_RESET(x) \\\n+\t(0xa0000304 + (x) * 0x1000)\n+#define DLB_CHP_LDB_PP_STATE_RESET_RST 0x0\n+union dlb_chp_ldb_pp_state_reset {\n+\tstruct {\n+\t\tu32 rsvd1 : 7;\n+\t\tu32 dir_type : 1;\n+\t\tu32 rsvd0 : 23;\n+\t\tu32 reset_pp_state : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_PP_CRD_REQ_STATE(x) \\\n+\t(0xa0000300 + (x) * 0x1000)\n+#define DLB_CHP_LDB_PP_CRD_REQ_STATE_RST 0x0\n+union dlb_chp_ldb_pp_crd_req_state {\n+\tstruct {\n+\t\tu32 dir_crd_req_active_valid : 1;\n+\t\tu32 dir_crd_req_active_check : 1;\n+\t\tu32 dir_crd_req_active_busy : 1;\n+\t\tu32 rsvd1 : 1;\n+\t\tu32 ldb_crd_req_active_valid : 1;\n+\t\tu32 ldb_crd_req_active_check : 1;\n+\t\tu32 ldb_crd_req_active_busy : 1;\n+\t\tu32 rsvd0 : 1;\n+\t\tu32 no_pp_credit_update : 1;\n+\t\tu32 crd_req_state : 23;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_ORD_QID_SN(x) \\\n+\t(0xa0000408 + (x) * 0x1000)\n+#define DLB_CHP_ORD_QID_SN_RST 0x0\n+union dlb_chp_ord_qid_sn {\n+\tstruct {\n+\t\tu32 sn : 12;\n+\t\tu32 rsvd0 : 20;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_ORD_QID_SN_MAP(x) \\\n+\t(0xa0000404 + (x) * 0x1000)\n+#define DLB_CHP_ORD_QID_SN_MAP_RST 0x0\n+union dlb_chp_ord_qid_sn_map {\n+\tstruct {\n+\t\tu32 mode : 3;\n+\t\tu32 slot : 5;\n+\t\tu32 grp : 2;\n+\t\tu32 rsvd0 : 22;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_POOL_CRD_CNT(x) \\\n+\t(0xa000050c + (x) * 0x1000)\n+#define DLB_CHP_LDB_POOL_CRD_CNT_RST 0x0\n+union dlb_chp_ldb_pool_crd_cnt {\n+\tstruct {\n+\t\tu32 count : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_QED_FL_BASE(x) \\\n+\t(0xa0000508 + (x) * 0x1000)\n+#define DLB_CHP_QED_FL_BASE_RST 0x0\n+union dlb_chp_qed_fl_base {\n+\tstruct {\n+\t\tu32 base : 14;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_QED_FL_LIM(x) \\\n+\t(0xa0000504 + (x) * 0x1000)\n+#define DLB_CHP_QED_FL_LIM_RST 0x8000\n+union dlb_chp_qed_fl_lim {\n+\tstruct {\n+\t\tu32 limit : 14;\n+\t\tu32 rsvd1 : 1;\n+\t\tu32 freelist_disable : 1;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_POOL_CRD_LIM(x) \\\n+\t(0xa0000500 + (x) * 0x1000)\n+#define DLB_CHP_LDB_POOL_CRD_LIM_RST 0x0\n+union dlb_chp_ldb_pool_crd_lim {\n+\tstruct {\n+\t\tu32 limit : 16;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_QED_FL_POP_PTR(x) \\\n+\t(0xa0000604 + (x) * 0x1000)\n+#define DLB_CHP_QED_FL_POP_PTR_RST 0x0\n+union dlb_chp_qed_fl_pop_ptr {\n+\tstruct {\n+\t\tu32 pop_ptr : 14;\n+\t\tu32 reserved0 : 1;\n+\t\tu32 generation : 1;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_QED_FL_PUSH_PTR(x) \\\n+\t(0xa0000600 + (x) * 0x1000)\n+#define DLB_CHP_QED_FL_PUSH_PTR_RST 0x0\n+union dlb_chp_qed_fl_push_ptr {\n+\tstruct {\n+\t\tu32 push_ptr : 14;\n+\t\tu32 reserved0 : 1;\n+\t\tu32 generation : 1;\n+\t\tu32 rsvd0 : 16;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_POOL_CRD_CNT(x) \\\n+\t(0xa000070c + (x) * 0x1000)\n+#define DLB_CHP_DIR_POOL_CRD_CNT_RST 0x0\n+union dlb_chp_dir_pool_crd_cnt {\n+\tstruct {\n+\t\tu32 count : 14;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DQED_FL_BASE(x) \\\n+\t(0xa0000708 + (x) * 0x1000)\n+#define DLB_CHP_DQED_FL_BASE_RST 0x0\n+union dlb_chp_dqed_fl_base {\n+\tstruct {\n+\t\tu32 base : 12;\n+\t\tu32 rsvd0 : 20;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DQED_FL_LIM(x) \\\n+\t(0xa0000704 + (x) * 0x1000)\n+#define DLB_CHP_DQED_FL_LIM_RST 0x2000\n+union dlb_chp_dqed_fl_lim {\n+\tstruct {\n+\t\tu32 limit : 12;\n+\t\tu32 rsvd1 : 1;\n+\t\tu32 freelist_disable : 1;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_POOL_CRD_LIM(x) \\\n+\t(0xa0000700 + (x) * 0x1000)\n+#define DLB_CHP_DIR_POOL_CRD_LIM_RST 0x0\n+union dlb_chp_dir_pool_crd_lim {\n+\tstruct {\n+\t\tu32 limit : 14;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DQED_FL_POP_PTR(x) \\\n+\t(0xa0000804 + (x) * 0x1000)\n+#define DLB_CHP_DQED_FL_POP_PTR_RST 0x0\n+union dlb_chp_dqed_fl_pop_ptr {\n+\tstruct {\n+\t\tu32 pop_ptr : 12;\n+\t\tu32 reserved0 : 1;\n+\t\tu32 generation : 1;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DQED_FL_PUSH_PTR(x) \\\n+\t(0xa0000800 + (x) * 0x1000)\n+#define DLB_CHP_DQED_FL_PUSH_PTR_RST 0x0\n+union dlb_chp_dqed_fl_push_ptr {\n+\tstruct {\n+\t\tu32 push_ptr : 12;\n+\t\tu32 reserved0 : 1;\n+\t\tu32 generation : 1;\n+\t\tu32 rsvd0 : 18;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_CTRL_DIAG_02 0xa8000154\n+#define DLB_CHP_CTRL_DIAG_02_RST 0x0\n+union dlb_chp_ctrl_diag_02 {\n+\tstruct {\n+\t\tu32 control : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_CFG_CHP_CSR_CTRL 0xa8000130\n+#define DLB_CHP_CFG_CHP_CSR_CTRL_RST 0xc0003fff\n+#define DLB_CHP_CFG_EXCESS_TOKENS_SHIFT 12\n+union dlb_chp_cfg_chp_csr_ctrl {\n+\tstruct {\n+\t\tu32 int_inf_alarm_enable_0 : 1;\n+\t\tu32 int_inf_alarm_enable_1 : 1;\n+\t\tu32 int_inf_alarm_enable_2 : 1;\n+\t\tu32 int_inf_alarm_enable_3 : 1;\n+\t\tu32 int_inf_alarm_enable_4 : 1;\n+\t\tu32 int_inf_alarm_enable_5 : 1;\n+\t\tu32 int_inf_alarm_enable_6 : 1;\n+\t\tu32 int_inf_alarm_enable_7 : 1;\n+\t\tu32 int_inf_alarm_enable_8 : 1;\n+\t\tu32 int_inf_alarm_enable_9 : 1;\n+\t\tu32 int_inf_alarm_enable_10 : 1;\n+\t\tu32 int_inf_alarm_enable_11 : 1;\n+\t\tu32 int_inf_alarm_enable_12 : 1;\n+\t\tu32 int_cor_alarm_enable : 1;\n+\t\tu32 csr_control_spare : 14;\n+\t\tu32 cfg_vasr_dis : 1;\n+\t\tu32 counter_clear : 1;\n+\t\tu32 blk_cor_report : 1;\n+\t\tu32 blk_cor_synd : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_CQ_INTR_ARMED1 0xa8000068\n+#define DLB_CHP_LDB_CQ_INTR_ARMED1_RST 0x0\n+union dlb_chp_ldb_cq_intr_armed1 {\n+\tstruct {\n+\t\tu32 armed : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_LDB_CQ_INTR_ARMED0 0xa8000064\n+#define DLB_CHP_LDB_CQ_INTR_ARMED0_RST 0x0\n+union dlb_chp_ldb_cq_intr_armed0 {\n+\tstruct {\n+\t\tu32 armed : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_CQ_INTR_ARMED3 0xa8000024\n+#define DLB_CHP_DIR_CQ_INTR_ARMED3_RST 0x0\n+union dlb_chp_dir_cq_intr_armed3 {\n+\tstruct {\n+\t\tu32 armed : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_CQ_INTR_ARMED2 0xa8000020\n+#define DLB_CHP_DIR_CQ_INTR_ARMED2_RST 0x0\n+union dlb_chp_dir_cq_intr_armed2 {\n+\tstruct {\n+\t\tu32 armed : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_CQ_INTR_ARMED1 0xa800001c\n+#define DLB_CHP_DIR_CQ_INTR_ARMED1_RST 0x0\n+union dlb_chp_dir_cq_intr_armed1 {\n+\tstruct {\n+\t\tu32 armed : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CHP_DIR_CQ_INTR_ARMED0 0xa8000018\n+#define DLB_CHP_DIR_CQ_INTR_ARMED0_RST 0x0\n+union dlb_chp_dir_cq_intr_armed0 {\n+\tstruct {\n+\t\tu32 armed : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CFG_MSTR_DIAG_RESET_STS 0xb8000004\n+#define DLB_CFG_MSTR_DIAG_RESET_STS_RST 0x1ff\n+union dlb_cfg_mstr_diag_reset_sts {\n+\tstruct {\n+\t\tu32 chp_pf_reset_done : 1;\n+\t\tu32 rop_pf_reset_done : 1;\n+\t\tu32 lsp_pf_reset_done : 1;\n+\t\tu32 nalb_pf_reset_done : 1;\n+\t\tu32 ap_pf_reset_done : 1;\n+\t\tu32 dp_pf_reset_done : 1;\n+\t\tu32 qed_pf_reset_done : 1;\n+\t\tu32 dqed_pf_reset_done : 1;\n+\t\tu32 aqed_pf_reset_done : 1;\n+\t\tu32 rsvd1 : 6;\n+\t\tu32 pf_reset_active : 1;\n+\t\tu32 chp_vf_reset_done : 1;\n+\t\tu32 rop_vf_reset_done : 1;\n+\t\tu32 lsp_vf_reset_done : 1;\n+\t\tu32 nalb_vf_reset_done : 1;\n+\t\tu32 ap_vf_reset_done : 1;\n+\t\tu32 dp_vf_reset_done : 1;\n+\t\tu32 qed_vf_reset_done : 1;\n+\t\tu32 dqed_vf_reset_done : 1;\n+\t\tu32 aqed_vf_reset_done : 1;\n+\t\tu32 rsvd0 : 6;\n+\t\tu32 vf_reset_active : 1;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_CFG_MSTR_BCAST_RESET_VF_START 0xc8100000\n+#define DLB_CFG_MSTR_BCAST_RESET_VF_START_RST 0x0\n+/* HW Reset Types */\n+#define VF_RST_TYPE_CQ_LDB   0\n+#define VF_RST_TYPE_QID_LDB  1\n+#define VF_RST_TYPE_POOL_LDB 2\n+#define VF_RST_TYPE_CQ_DIR   8\n+#define VF_RST_TYPE_QID_DIR  9\n+#define VF_RST_TYPE_POOL_DIR 10\n+union dlb_cfg_mstr_bcast_reset_vf_start {\n+\tstruct {\n+\t\tu32 vf_reset_start : 1;\n+\t\tu32 reserved : 3;\n+\t\tu32 vf_reset_type : 4;\n+\t\tu32 vf_reset_id : 24;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_FUNC_VF_VF2PF_MAILBOX_BYTES 256\n+#define DLB_FUNC_VF_VF2PF_MAILBOX(x) \\\n+\t(0x1000 + (x) * 0x4)\n+#define DLB_FUNC_VF_VF2PF_MAILBOX_RST 0x0\n+union dlb_func_vf_vf2pf_mailbox {\n+\tstruct {\n+\t\tu32 msg : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_FUNC_VF_VF2PF_MAILBOX_ISR 0x1f00\n+#define DLB_FUNC_VF_VF2PF_MAILBOX_ISR_RST 0x0\n+union dlb_func_vf_vf2pf_mailbox_isr {\n+\tstruct {\n+\t\tu32 isr : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_FUNC_VF_PF2VF_MAILBOX_BYTES 64\n+#define DLB_FUNC_VF_PF2VF_MAILBOX(x) \\\n+\t(0x2000 + (x) * 0x4)\n+#define DLB_FUNC_VF_PF2VF_MAILBOX_RST 0x0\n+union dlb_func_vf_pf2vf_mailbox {\n+\tstruct {\n+\t\tu32 msg : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_FUNC_VF_PF2VF_MAILBOX_ISR 0x2f00\n+#define DLB_FUNC_VF_PF2VF_MAILBOX_ISR_RST 0x0\n+union dlb_func_vf_pf2vf_mailbox_isr {\n+\tstruct {\n+\t\tu32 pf_isr : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_FUNC_VF_VF_MSI_ISR_PEND 0x2f10\n+#define DLB_FUNC_VF_VF_MSI_ISR_PEND_RST 0x0\n+union dlb_func_vf_vf_msi_isr_pend {\n+\tstruct {\n+\t\tu32 isr_pend : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_FUNC_VF_VF_RESET_IN_PROGRESS 0x3000\n+#define DLB_FUNC_VF_VF_RESET_IN_PROGRESS_RST 0x1\n+union dlb_func_vf_vf_reset_in_progress {\n+\tstruct {\n+\t\tu32 reset_in_progress : 1;\n+\t\tu32 rsvd0 : 31;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#define DLB_FUNC_VF_VF_MSI_ISR 0x4000\n+#define DLB_FUNC_VF_VF_MSI_ISR_RST 0x0\n+union dlb_func_vf_vf_msi_isr {\n+\tstruct {\n+\t\tu32 vf_msi_isr : 32;\n+\t} field;\n+\tu32 val;\n+};\n+\n+#endif /* __DLB_REGS_H */\ndiff --git a/drivers/event/dlb/pf/base/dlb_resource.c b/drivers/event/dlb/pf/base/dlb_resource.c\nnew file mode 100644\nindex 0000000..51265b9\n--- /dev/null\n+++ b/drivers/event/dlb/pf/base/dlb_resource.c\n@@ -0,0 +1,9722 @@\n+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)\n+ * Copyright(c) 2016-2020 Intel Corporation\n+ */\n+\n+#include \"dlb_hw_types.h\"\n+#include \"dlb_user.h\"\n+#include \"dlb_resource.h\"\n+#include \"dlb_osdep.h\"\n+#include \"dlb_osdep_bitmap.h\"\n+#include \"dlb_osdep_types.h\"\n+#include \"dlb_regs.h\"\n+#include \"dlb_mbox.h\"\n+\n+#define DLB_DOM_LIST_HEAD(head, type) \\\n+\tDLB_LIST_HEAD((head), type, domain_list)\n+\n+#define DLB_FUNC_LIST_HEAD(head, type) \\\n+\tDLB_LIST_HEAD((head), type, func_list)\n+\n+#define DLB_DOM_LIST_FOR(head, ptr, iter) \\\n+\tDLB_LIST_FOR_EACH(head, ptr, domain_list, iter)\n+\n+#define DLB_FUNC_LIST_FOR(head, ptr, iter) \\\n+\tDLB_LIST_FOR_EACH(head, ptr, func_list, iter)\n+\n+#define DLB_DOM_LIST_FOR_SAFE(head, ptr, ptr_tmp, it, it_tmp) \\\n+\tDLB_LIST_FOR_EACH_SAFE((head), ptr, ptr_tmp, domain_list, it, it_tmp)\n+\n+#define DLB_FUNC_LIST_FOR_SAFE(head, ptr, ptr_tmp, it, it_tmp) \\\n+\tDLB_LIST_FOR_EACH_SAFE((head), ptr, ptr_tmp, func_list, it, it_tmp)\n+\n+/* The PF driver cannot assume that a register write will affect subsequent HCW\n+ * writes. To ensure a write completes, the driver must read back a CSR. This\n+ * function only need be called for configuration that can occur after the\n+ * domain has started; prior to starting, applications can't send HCWs.\n+ */\n+static inline void dlb_flush_csr(struct dlb_hw *hw)\n+{\n+\tDLB_CSR_RD(hw, DLB_SYS_TOTAL_VAS);\n+}\n+\n+static void dlb_init_fn_rsrc_lists(struct dlb_function_resources *rsrc)\n+{\n+\tdlb_list_init_head(&rsrc->avail_domains);\n+\tdlb_list_init_head(&rsrc->used_domains);\n+\tdlb_list_init_head(&rsrc->avail_ldb_queues);\n+\tdlb_list_init_head(&rsrc->avail_ldb_ports);\n+\tdlb_list_init_head(&rsrc->avail_dir_pq_pairs);\n+\tdlb_list_init_head(&rsrc->avail_ldb_credit_pools);\n+\tdlb_list_init_head(&rsrc->avail_dir_credit_pools);\n+}\n+\n+static void dlb_init_domain_rsrc_lists(struct dlb_domain *domain)\n+{\n+\tdlb_list_init_head(&domain->used_ldb_queues);\n+\tdlb_list_init_head(&domain->used_ldb_ports);\n+\tdlb_list_init_head(&domain->used_dir_pq_pairs);\n+\tdlb_list_init_head(&domain->used_ldb_credit_pools);\n+\tdlb_list_init_head(&domain->used_dir_credit_pools);\n+\tdlb_list_init_head(&domain->avail_ldb_queues);\n+\tdlb_list_init_head(&domain->avail_ldb_ports);\n+\tdlb_list_init_head(&domain->avail_dir_pq_pairs);\n+\tdlb_list_init_head(&domain->avail_ldb_credit_pools);\n+\tdlb_list_init_head(&domain->avail_dir_credit_pools);\n+}\n+\n+int dlb_resource_init(struct dlb_hw *hw)\n+{\n+\tstruct dlb_list_entry *list;\n+\tunsigned int i;\n+\n+\t/* For optimal load-balancing, ports that map to one or more QIDs in\n+\t * common should not be in numerical sequence. This is application\n+\t * dependent, but the driver interleaves port IDs as much as possible\n+\t * to reduce the likelihood of this. This initial allocation maximizes\n+\t * the average distance between an ID and its immediate neighbors (i.e.\n+\t * the distance from 1 to 0 and to 2, the distance from 2 to 1 and to\n+\t * 3, etc.).\n+\t */\n+\tu32 init_ldb_port_allocation[DLB_MAX_NUM_LDB_PORTS] = {\n+\t\t0,  31, 62, 29, 60, 27, 58, 25, 56, 23, 54, 21, 52, 19, 50, 17,\n+\t\t48, 15, 46, 13, 44, 11, 42,  9, 40,  7, 38,  5, 36,  3, 34, 1,\n+\t\t32, 63, 30, 61, 28, 59, 26, 57, 24, 55, 22, 53, 20, 51, 18, 49,\n+\t\t16, 47, 14, 45, 12, 43, 10, 41,  8, 39,  6, 37,  4, 35,  2, 33\n+\t};\n+\n+\t/* Zero-out resource tracking data structures */\n+\tmemset(&hw->rsrcs, 0, sizeof(hw->rsrcs));\n+\tmemset(&hw->pf, 0, sizeof(hw->pf));\n+\n+\tdlb_init_fn_rsrc_lists(&hw->pf);\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_VFS; i++) {\n+\t\tmemset(&hw->vf[i], 0, sizeof(hw->vf[i]));\n+\t\tdlb_init_fn_rsrc_lists(&hw->vf[i]);\n+\t}\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_DOMAINS; i++) {\n+\t\tmemset(&hw->domains[i], 0, sizeof(hw->domains[i]));\n+\t\tdlb_init_domain_rsrc_lists(&hw->domains[i]);\n+\t\thw->domains[i].parent_func = &hw->pf;\n+\t}\n+\n+\t/* Give all resources to the PF driver */\n+\thw->pf.num_avail_domains = DLB_MAX_NUM_DOMAINS;\n+\tfor (i = 0; i < hw->pf.num_avail_domains; i++) {\n+\t\tlist = &hw->domains[i].func_list;\n+\n+\t\tdlb_list_add(&hw->pf.avail_domains, list);\n+\t}\n+\n+\thw->pf.num_avail_ldb_queues = DLB_MAX_NUM_LDB_QUEUES;\n+\tfor (i = 0; i < hw->pf.num_avail_ldb_queues; i++) {\n+\t\tlist = &hw->rsrcs.ldb_queues[i].func_list;\n+\n+\t\tdlb_list_add(&hw->pf.avail_ldb_queues, list);\n+\t}\n+\n+\thw->pf.num_avail_ldb_ports = DLB_MAX_NUM_LDB_PORTS;\n+\tfor (i = 0; i < hw->pf.num_avail_ldb_ports; i++) {\n+\t\tstruct dlb_ldb_port *port;\n+\n+\t\tport = &hw->rsrcs.ldb_ports[init_ldb_port_allocation[i]];\n+\n+\t\tdlb_list_add(&hw->pf.avail_ldb_ports, &port->func_list);\n+\t}\n+\n+\thw->pf.num_avail_dir_pq_pairs = DLB_MAX_NUM_DIR_PORTS;\n+\tfor (i = 0; i < hw->pf.num_avail_dir_pq_pairs; i++) {\n+\t\tlist = &hw->rsrcs.dir_pq_pairs[i].func_list;\n+\n+\t\tdlb_list_add(&hw->pf.avail_dir_pq_pairs, list);\n+\t}\n+\n+\thw->pf.num_avail_ldb_credit_pools = DLB_MAX_NUM_LDB_CREDIT_POOLS;\n+\tfor (i = 0; i < hw->pf.num_avail_ldb_credit_pools; i++) {\n+\t\tlist = &hw->rsrcs.ldb_credit_pools[i].func_list;\n+\n+\t\tdlb_list_add(&hw->pf.avail_ldb_credit_pools, list);\n+\t}\n+\n+\thw->pf.num_avail_dir_credit_pools = DLB_MAX_NUM_DIR_CREDIT_POOLS;\n+\tfor (i = 0; i < hw->pf.num_avail_dir_credit_pools; i++) {\n+\t\tlist = &hw->rsrcs.dir_credit_pools[i].func_list;\n+\n+\t\tdlb_list_add(&hw->pf.avail_dir_credit_pools, list);\n+\t}\n+\n+\t/* There are 5120 history list entries, which allows us to overprovision\n+\t * the inflight limit (4096) by 1k.\n+\t */\n+\tif (dlb_bitmap_alloc(hw,\n+\t\t\t     &hw->pf.avail_hist_list_entries,\n+\t\t\t     DLB_MAX_NUM_HIST_LIST_ENTRIES))\n+\t\treturn -1;\n+\n+\tif (dlb_bitmap_fill(hw->pf.avail_hist_list_entries))\n+\t\treturn -1;\n+\n+\tif (dlb_bitmap_alloc(hw,\n+\t\t\t     &hw->pf.avail_qed_freelist_entries,\n+\t\t\t     DLB_MAX_NUM_LDB_CREDITS))\n+\t\treturn -1;\n+\n+\tif (dlb_bitmap_fill(hw->pf.avail_qed_freelist_entries))\n+\t\treturn -1;\n+\n+\tif (dlb_bitmap_alloc(hw,\n+\t\t\t     &hw->pf.avail_dqed_freelist_entries,\n+\t\t\t     DLB_MAX_NUM_DIR_CREDITS))\n+\t\treturn -1;\n+\n+\tif (dlb_bitmap_fill(hw->pf.avail_dqed_freelist_entries))\n+\t\treturn -1;\n+\n+\tif (dlb_bitmap_alloc(hw,\n+\t\t\t     &hw->pf.avail_aqed_freelist_entries,\n+\t\t\t     DLB_MAX_NUM_AQOS_ENTRIES))\n+\t\treturn -1;\n+\n+\tif (dlb_bitmap_fill(hw->pf.avail_aqed_freelist_entries))\n+\t\treturn -1;\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_VFS; i++) {\n+\t\tif (dlb_bitmap_alloc(hw,\n+\t\t\t\t     &hw->vf[i].avail_hist_list_entries,\n+\t\t\t\t     DLB_MAX_NUM_HIST_LIST_ENTRIES))\n+\t\t\treturn -1;\n+\t\tif (dlb_bitmap_alloc(hw,\n+\t\t\t\t     &hw->vf[i].avail_qed_freelist_entries,\n+\t\t\t\t     DLB_MAX_NUM_LDB_CREDITS))\n+\t\t\treturn -1;\n+\t\tif (dlb_bitmap_alloc(hw,\n+\t\t\t\t     &hw->vf[i].avail_dqed_freelist_entries,\n+\t\t\t\t     DLB_MAX_NUM_DIR_CREDITS))\n+\t\t\treturn -1;\n+\t\tif (dlb_bitmap_alloc(hw,\n+\t\t\t\t     &hw->vf[i].avail_aqed_freelist_entries,\n+\t\t\t\t     DLB_MAX_NUM_AQOS_ENTRIES))\n+\t\t\treturn -1;\n+\n+\t\tif (dlb_bitmap_zero(hw->vf[i].avail_hist_list_entries))\n+\t\t\treturn -1;\n+\n+\t\tif (dlb_bitmap_zero(hw->vf[i].avail_qed_freelist_entries))\n+\t\t\treturn -1;\n+\n+\t\tif (dlb_bitmap_zero(hw->vf[i].avail_dqed_freelist_entries))\n+\t\t\treturn -1;\n+\n+\t\tif (dlb_bitmap_zero(hw->vf[i].avail_aqed_freelist_entries))\n+\t\t\treturn -1;\n+\t}\n+\n+\t/* Initialize the hardware resource IDs */\n+\tfor (i = 0; i < DLB_MAX_NUM_DOMAINS; i++) {\n+\t\thw->domains[i].id.phys_id = i;\n+\t\thw->domains[i].id.vf_owned = false;\n+\t}\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_LDB_QUEUES; i++) {\n+\t\thw->rsrcs.ldb_queues[i].id.phys_id = i;\n+\t\thw->rsrcs.ldb_queues[i].id.vf_owned = false;\n+\t}\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_LDB_PORTS; i++) {\n+\t\thw->rsrcs.ldb_ports[i].id.phys_id = i;\n+\t\thw->rsrcs.ldb_ports[i].id.vf_owned = false;\n+\t}\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_DIR_PORTS; i++) {\n+\t\thw->rsrcs.dir_pq_pairs[i].id.phys_id = i;\n+\t\thw->rsrcs.dir_pq_pairs[i].id.vf_owned = false;\n+\t}\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_LDB_CREDIT_POOLS; i++) {\n+\t\thw->rsrcs.ldb_credit_pools[i].id.phys_id = i;\n+\t\thw->rsrcs.ldb_credit_pools[i].id.vf_owned = false;\n+\t}\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_DIR_CREDIT_POOLS; i++) {\n+\t\thw->rsrcs.dir_credit_pools[i].id.phys_id = i;\n+\t\thw->rsrcs.dir_credit_pools[i].id.vf_owned = false;\n+\t}\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_SEQUENCE_NUMBER_GROUPS; i++) {\n+\t\thw->rsrcs.sn_groups[i].id = i;\n+\t\t/* Default mode (0) is 32 sequence numbers per queue */\n+\t\thw->rsrcs.sn_groups[i].mode = 0;\n+\t\thw->rsrcs.sn_groups[i].sequence_numbers_per_queue = 32;\n+\t\thw->rsrcs.sn_groups[i].slot_use_bitmap = 0;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void dlb_resource_free(struct dlb_hw *hw)\n+{\n+\tint i;\n+\n+\tdlb_bitmap_free(hw->pf.avail_hist_list_entries);\n+\n+\tdlb_bitmap_free(hw->pf.avail_qed_freelist_entries);\n+\n+\tdlb_bitmap_free(hw->pf.avail_dqed_freelist_entries);\n+\n+\tdlb_bitmap_free(hw->pf.avail_aqed_freelist_entries);\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_VFS; i++) {\n+\t\tdlb_bitmap_free(hw->vf[i].avail_hist_list_entries);\n+\t\tdlb_bitmap_free(hw->vf[i].avail_qed_freelist_entries);\n+\t\tdlb_bitmap_free(hw->vf[i].avail_dqed_freelist_entries);\n+\t\tdlb_bitmap_free(hw->vf[i].avail_aqed_freelist_entries);\n+\t}\n+}\n+\n+static struct dlb_domain *dlb_get_domain_from_id(struct dlb_hw *hw,\n+\t\t\t\t\t\t u32 id,\n+\t\t\t\t\t\t bool vf_request,\n+\t\t\t\t\t\t unsigned int vf_id)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_function_resources *rsrcs;\n+\tstruct dlb_domain *domain;\n+\n+\tif (id >= DLB_MAX_NUM_DOMAINS)\n+\t\treturn NULL;\n+\n+\tif (!vf_request)\n+\t\treturn &hw->domains[id];\n+\n+\trsrcs = &hw->vf[vf_id];\n+\n+\tDLB_FUNC_LIST_FOR(rsrcs->used_domains, domain, iter)\n+\t\tif (domain->id.virt_id == id)\n+\t\t\treturn domain;\n+\n+\treturn NULL;\n+}\n+\n+static struct dlb_credit_pool *\n+dlb_get_domain_ldb_pool(u32 id,\n+\t\t\tbool vf_request,\n+\t\t\tstruct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_credit_pool *pool;\n+\n+\tif (id >= DLB_MAX_NUM_LDB_CREDIT_POOLS)\n+\t\treturn NULL;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_credit_pools, pool, iter)\n+\t\tif ((!vf_request && pool->id.phys_id == id) ||\n+\t\t    (vf_request && pool->id.virt_id == id))\n+\t\t\treturn pool;\n+\n+\treturn NULL;\n+}\n+\n+static struct dlb_credit_pool *\n+dlb_get_domain_dir_pool(u32 id,\n+\t\t\tbool vf_request,\n+\t\t\tstruct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_credit_pool *pool;\n+\n+\tif (id >= DLB_MAX_NUM_DIR_CREDIT_POOLS)\n+\t\treturn NULL;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_credit_pools, pool, iter)\n+\t\tif ((!vf_request && pool->id.phys_id == id) ||\n+\t\t    (vf_request && pool->id.virt_id == id))\n+\t\t\treturn pool;\n+\n+\treturn NULL;\n+}\n+\n+static struct dlb_ldb_port *dlb_get_ldb_port_from_id(struct dlb_hw *hw,\n+\t\t\t\t\t\t     u32 id,\n+\t\t\t\t\t\t     bool vf_request,\n+\t\t\t\t\t\t     unsigned int vf_id)\n+{\n+\tstruct dlb_list_entry *iter1 __attribute__((unused));\n+\tstruct dlb_list_entry *iter2 __attribute__((unused));\n+\tstruct dlb_function_resources *rsrcs;\n+\tstruct dlb_ldb_port *port;\n+\tstruct dlb_domain *domain;\n+\n+\tif (id >= DLB_MAX_NUM_LDB_PORTS)\n+\t\treturn NULL;\n+\n+\trsrcs = (vf_request) ? &hw->vf[vf_id] : &hw->pf;\n+\n+\tif (!vf_request)\n+\t\treturn &hw->rsrcs.ldb_ports[id];\n+\n+\tDLB_FUNC_LIST_FOR(rsrcs->used_domains, domain, iter1) {\n+\t\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter2)\n+\t\t\tif (port->id.virt_id == id)\n+\t\t\t\treturn port;\n+\t}\n+\n+\tDLB_FUNC_LIST_FOR(rsrcs->avail_ldb_ports, port, iter1)\n+\t\tif (port->id.virt_id == id)\n+\t\t\treturn port;\n+\n+\treturn NULL;\n+}\n+\n+static struct dlb_ldb_port *\n+dlb_get_domain_used_ldb_port(u32 id,\n+\t\t\t     bool vf_request,\n+\t\t\t     struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_port *port;\n+\n+\tif (id >= DLB_MAX_NUM_LDB_PORTS)\n+\t\treturn NULL;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter)\n+\t\tif ((!vf_request && port->id.phys_id == id) ||\n+\t\t    (vf_request && port->id.virt_id == id))\n+\t\t\treturn port;\n+\n+\tDLB_DOM_LIST_FOR(domain->avail_ldb_ports, port, iter)\n+\t\tif ((!vf_request && port->id.phys_id == id) ||\n+\t\t    (vf_request && port->id.virt_id == id))\n+\t\t\treturn port;\n+\n+\treturn NULL;\n+}\n+\n+static struct dlb_ldb_port *dlb_get_domain_ldb_port(u32 id,\n+\t\t\t\t\t\t    bool vf_request,\n+\t\t\t\t\t\t    struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_port *port;\n+\n+\tif (id >= DLB_MAX_NUM_LDB_PORTS)\n+\t\treturn NULL;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter)\n+\t\tif ((!vf_request && port->id.phys_id == id) ||\n+\t\t    (vf_request && port->id.virt_id == id))\n+\t\t\treturn port;\n+\n+\tDLB_DOM_LIST_FOR(domain->avail_ldb_ports, port, iter)\n+\t\tif ((!vf_request && port->id.phys_id == id) ||\n+\t\t    (vf_request && port->id.virt_id == id))\n+\t\t\treturn port;\n+\n+\treturn NULL;\n+}\n+\n+static struct dlb_dir_pq_pair *dlb_get_dir_pq_from_id(struct dlb_hw *hw,\n+\t\t\t\t\t\t      u32 id,\n+\t\t\t\t\t\t      bool vf_request,\n+\t\t\t\t\t\t      unsigned int vf_id)\n+{\n+\tstruct dlb_list_entry *iter1 __attribute__((unused));\n+\tstruct dlb_list_entry *iter2 __attribute__((unused));\n+\tstruct dlb_function_resources *rsrcs;\n+\tstruct dlb_dir_pq_pair *port;\n+\tstruct dlb_domain *domain;\n+\n+\tif (id >= DLB_MAX_NUM_DIR_PORTS)\n+\t\treturn NULL;\n+\n+\trsrcs = (vf_request) ? &hw->vf[vf_id] : &hw->pf;\n+\n+\tif (!vf_request)\n+\t\treturn &hw->rsrcs.dir_pq_pairs[id];\n+\n+\tDLB_FUNC_LIST_FOR(rsrcs->used_domains, domain, iter1) {\n+\t\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, port, iter2)\n+\t\t\tif (port->id.virt_id == id)\n+\t\t\t\treturn port;\n+\t}\n+\n+\tDLB_FUNC_LIST_FOR(rsrcs->avail_dir_pq_pairs, port, iter1)\n+\t\tif (port->id.virt_id == id)\n+\t\t\treturn port;\n+\n+\treturn NULL;\n+}\n+\n+static struct dlb_dir_pq_pair *\n+dlb_get_domain_used_dir_pq(u32 id,\n+\t\t\t   bool vf_request,\n+\t\t\t   struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_dir_pq_pair *port;\n+\n+\tif (id >= DLB_MAX_NUM_DIR_PORTS)\n+\t\treturn NULL;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, port, iter)\n+\t\tif ((!vf_request && port->id.phys_id == id) ||\n+\t\t    (vf_request && port->id.virt_id == id))\n+\t\t\treturn port;\n+\n+\treturn NULL;\n+}\n+\n+static struct dlb_dir_pq_pair *dlb_get_domain_dir_pq(u32 id,\n+\t\t\t\t\t\t     bool vf_request,\n+\t\t\t\t\t\t     struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_dir_pq_pair *port;\n+\n+\tif (id >= DLB_MAX_NUM_DIR_PORTS)\n+\t\treturn NULL;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, port, iter)\n+\t\tif ((!vf_request && port->id.phys_id == id) ||\n+\t\t    (vf_request && port->id.virt_id == id))\n+\t\t\treturn port;\n+\n+\tDLB_DOM_LIST_FOR(domain->avail_dir_pq_pairs, port, iter)\n+\t\tif ((!vf_request && port->id.phys_id == id) ||\n+\t\t    (vf_request && port->id.virt_id == id))\n+\t\t\treturn port;\n+\n+\treturn NULL;\n+}\n+\n+static struct dlb_ldb_queue *dlb_get_ldb_queue_from_id(struct dlb_hw *hw,\n+\t\t\t\t\t\t       u32 id,\n+\t\t\t\t\t\t       bool vf_request,\n+\t\t\t\t\t\t       unsigned int vf_id)\n+{\n+\tstruct dlb_list_entry *iter1 __attribute__((unused));\n+\tstruct dlb_list_entry *iter2 __attribute__((unused));\n+\tstruct dlb_function_resources *rsrcs;\n+\tstruct dlb_ldb_queue *queue;\n+\tstruct dlb_domain *domain;\n+\n+\tif (id >= DLB_MAX_NUM_LDB_QUEUES)\n+\t\treturn NULL;\n+\n+\trsrcs = (vf_request) ? &hw->vf[vf_id] : &hw->pf;\n+\n+\tif (!vf_request)\n+\t\treturn &hw->rsrcs.ldb_queues[id];\n+\n+\tDLB_FUNC_LIST_FOR(rsrcs->used_domains, domain, iter1) {\n+\t\tDLB_DOM_LIST_FOR(domain->used_ldb_queues, queue, iter2)\n+\t\t\tif (queue->id.virt_id == id)\n+\t\t\t\treturn queue;\n+\t}\n+\n+\tDLB_FUNC_LIST_FOR(rsrcs->avail_ldb_queues, queue, iter1)\n+\t\tif (queue->id.virt_id == id)\n+\t\t\treturn queue;\n+\n+\treturn NULL;\n+}\n+\n+static struct dlb_ldb_queue *dlb_get_domain_ldb_queue(u32 id,\n+\t\t\t\t\t\t      bool vf_request,\n+\t\t\t\t\t\t      struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_queue *queue;\n+\n+\tif (id >= DLB_MAX_NUM_LDB_QUEUES)\n+\t\treturn NULL;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_queues, queue, iter)\n+\t\tif ((!vf_request && queue->id.phys_id == id) ||\n+\t\t    (vf_request && queue->id.virt_id == id))\n+\t\t\treturn queue;\n+\n+\treturn NULL;\n+}\n+\n+#define DLB_XFER_LL_RSRC(dst, src, num, type_t, name) ({\t\t    \\\n+\tstruct dlb_list_entry *it1 __attribute__((unused));\t\t    \\\n+\tstruct dlb_list_entry *it2 __attribute__((unused));\t\t    \\\n+\tstruct dlb_function_resources *_src = src;\t\t\t    \\\n+\tstruct dlb_function_resources *_dst = dst;\t\t\t    \\\n+\ttype_t *ptr, *tmp __attribute__((unused));\t\t\t    \\\n+\tunsigned int i = 0;\t\t\t\t\t\t    \\\n+\t\t\t\t\t\t\t\t\t    \\\n+\tDLB_FUNC_LIST_FOR_SAFE(_src->avail_##name##s, ptr, tmp, it1, it2) { \\\n+\t\tif (i++ == (num))\t\t\t\t\t    \\\n+\t\t\tbreak;\t\t\t\t\t\t    \\\n+\t\t\t\t\t\t\t\t\t    \\\n+\t\tdlb_list_del(&_src->avail_##name##s, &ptr->func_list);\t    \\\n+\t\tdlb_list_add(&_dst->avail_##name##s,  &ptr->func_list);     \\\n+\t\t_src->num_avail_##name##s--;\t\t\t\t    \\\n+\t\t_dst->num_avail_##name##s++;\t\t\t\t    \\\n+\t}\t\t\t\t\t\t\t\t    \\\n+})\n+\n+#define DLB_VF_ID_CLEAR(head, type_t) ({   \\\n+\tstruct dlb_list_entry *iter __attribute__((unused)); \\\n+\ttype_t *var;\t\t\t\t\t     \\\n+\t\t\t\t\t\t\t     \\\n+\tDLB_FUNC_LIST_FOR(head, var, iter)\t\t     \\\n+\t\tvar->id.vf_owned = false;\t\t     \\\n+})\n+\n+int dlb_update_vf_sched_domains(struct dlb_hw *hw, u32 vf_id, u32 num)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_function_resources *src, *dst;\n+\tstruct dlb_domain *domain;\n+\tunsigned int orig;\n+\tint ret;\n+\n+\tif (vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -EINVAL;\n+\n+\tsrc = &hw->pf;\n+\tdst = &hw->vf[vf_id];\n+\n+\t/* If the VF is locked, its resource assignment can't be changed */\n+\tif (dlb_vf_is_locked(hw, vf_id))\n+\t\treturn -EPERM;\n+\n+\torig = dst->num_avail_domains;\n+\n+\t/* Detach the destination VF's current resources before checking if\n+\t * enough are available, and set their IDs accordingly.\n+\t */\n+\tDLB_VF_ID_CLEAR(dst->avail_domains, struct dlb_domain);\n+\n+\tDLB_XFER_LL_RSRC(src, dst, orig, struct dlb_domain, domain);\n+\n+\t/* Are there enough available resources to satisfy the request? */\n+\tif (num > src->num_avail_domains) {\n+\t\tnum = orig;\n+\t\tret = -EINVAL;\n+\t} else {\n+\t\tret = 0;\n+\t}\n+\n+\tDLB_XFER_LL_RSRC(dst, src, num, struct dlb_domain, domain);\n+\n+\t/* Set the domains' VF backpointer */\n+\tDLB_FUNC_LIST_FOR(dst->avail_domains, domain, iter)\n+\t\tdomain->parent_func = dst;\n+\n+\treturn ret;\n+}\n+\n+int dlb_update_vf_ldb_queues(struct dlb_hw *hw, u32 vf_id, u32 num)\n+{\n+\tstruct dlb_function_resources *src, *dst;\n+\tunsigned int orig;\n+\tint ret;\n+\n+\tif (vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -EINVAL;\n+\n+\tsrc = &hw->pf;\n+\tdst = &hw->vf[vf_id];\n+\n+\t/* If the VF is locked, its resource assignment can't be changed */\n+\tif (dlb_vf_is_locked(hw, vf_id))\n+\t\treturn -EPERM;\n+\n+\torig = dst->num_avail_ldb_queues;\n+\n+\t/* Detach the destination VF's current resources before checking if\n+\t * enough are available, and set their IDs accordingly.\n+\t */\n+\tDLB_VF_ID_CLEAR(dst->avail_ldb_queues, struct dlb_ldb_queue);\n+\n+\tDLB_XFER_LL_RSRC(src, dst, orig, struct dlb_ldb_queue, ldb_queue);\n+\n+\t/* Are there enough available resources to satisfy the request? */\n+\tif (num > src->num_avail_ldb_queues) {\n+\t\tnum = orig;\n+\t\tret = -EINVAL;\n+\t} else {\n+\t\tret = 0;\n+\t}\n+\n+\tDLB_XFER_LL_RSRC(dst, src, num, struct dlb_ldb_queue, ldb_queue);\n+\n+\treturn ret;\n+}\n+\n+int dlb_update_vf_ldb_ports(struct dlb_hw *hw, u32 vf_id, u32 num)\n+{\n+\tstruct dlb_function_resources *src, *dst;\n+\tunsigned int orig;\n+\tint ret;\n+\n+\tif (vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -EINVAL;\n+\n+\tsrc = &hw->pf;\n+\tdst = &hw->vf[vf_id];\n+\n+\t/* If the VF is locked, its resource assignment can't be changed */\n+\tif (dlb_vf_is_locked(hw, vf_id))\n+\t\treturn -EPERM;\n+\n+\torig = dst->num_avail_ldb_ports;\n+\n+\t/* Detach the destination VF's current resources before checking if\n+\t * enough are available, and set their IDs accordingly.\n+\t */\n+\tDLB_VF_ID_CLEAR(dst->avail_ldb_ports, struct dlb_ldb_port);\n+\n+\tDLB_XFER_LL_RSRC(src, dst, orig, struct dlb_ldb_port, ldb_port);\n+\n+\t/* Are there enough available resources to satisfy the request? */\n+\tif (num > src->num_avail_ldb_ports) {\n+\t\tnum = orig;\n+\t\tret = -EINVAL;\n+\t} else {\n+\t\tret = 0;\n+\t}\n+\n+\tDLB_XFER_LL_RSRC(dst, src, num, struct dlb_ldb_port, ldb_port);\n+\n+\treturn ret;\n+}\n+\n+int dlb_update_vf_dir_ports(struct dlb_hw *hw, u32 vf_id, u32 num)\n+{\n+\tstruct dlb_function_resources *src, *dst;\n+\tunsigned int orig;\n+\tint ret;\n+\n+\tif (vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -EINVAL;\n+\n+\tsrc = &hw->pf;\n+\tdst = &hw->vf[vf_id];\n+\n+\t/* If the VF is locked, its resource assignment can't be changed */\n+\tif (dlb_vf_is_locked(hw, vf_id))\n+\t\treturn -EPERM;\n+\n+\torig = dst->num_avail_dir_pq_pairs;\n+\n+\t/* Detach the destination VF's current resources before checking if\n+\t * enough are available, and set their IDs accordingly.\n+\t */\n+\tDLB_VF_ID_CLEAR(dst->avail_dir_pq_pairs, struct dlb_dir_pq_pair);\n+\n+\tDLB_XFER_LL_RSRC(src, dst, orig, struct dlb_dir_pq_pair, dir_pq_pair);\n+\n+\t/* Are there enough available resources to satisfy the request? */\n+\tif (num > src->num_avail_dir_pq_pairs) {\n+\t\tnum = orig;\n+\t\tret = -EINVAL;\n+\t} else {\n+\t\tret = 0;\n+\t}\n+\n+\tDLB_XFER_LL_RSRC(dst, src, num, struct dlb_dir_pq_pair, dir_pq_pair);\n+\n+\treturn ret;\n+}\n+\n+int dlb_update_vf_ldb_credit_pools(struct dlb_hw *hw,\n+\t\t\t\t   u32 vf_id,\n+\t\t\t\t   u32 num)\n+{\n+\tstruct dlb_function_resources *src, *dst;\n+\tunsigned int orig;\n+\tint ret;\n+\n+\tif (vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -EINVAL;\n+\n+\tsrc = &hw->pf;\n+\tdst = &hw->vf[vf_id];\n+\n+\t/* If the VF is locked, its resource assignment can't be changed */\n+\tif (dlb_vf_is_locked(hw, vf_id))\n+\t\treturn -EPERM;\n+\n+\torig = dst->num_avail_ldb_credit_pools;\n+\n+\t/* Detach the destination VF's current resources before checking if\n+\t * enough are available, and set their IDs accordingly.\n+\t */\n+\tDLB_VF_ID_CLEAR(dst->avail_ldb_credit_pools, struct dlb_credit_pool);\n+\n+\tDLB_XFER_LL_RSRC(src,\n+\t\t\t dst,\n+\t\t\t orig,\n+\t\t\t struct dlb_credit_pool,\n+\t\t\t ldb_credit_pool);\n+\n+\t/* Are there enough available resources to satisfy the request? */\n+\tif (num > src->num_avail_ldb_credit_pools) {\n+\t\tnum = orig;\n+\t\tret = -EINVAL;\n+\t} else {\n+\t\tret = 0;\n+\t}\n+\n+\tDLB_XFER_LL_RSRC(dst,\n+\t\t\t src,\n+\t\t\t num,\n+\t\t\t struct dlb_credit_pool,\n+\t\t\t ldb_credit_pool);\n+\n+\treturn ret;\n+}\n+\n+int dlb_update_vf_dir_credit_pools(struct dlb_hw *hw,\n+\t\t\t\t   u32 vf_id,\n+\t\t\t\t   u32 num)\n+{\n+\tstruct dlb_function_resources *src, *dst;\n+\tunsigned int orig;\n+\tint ret;\n+\n+\tif (vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -EINVAL;\n+\n+\tsrc = &hw->pf;\n+\tdst = &hw->vf[vf_id];\n+\n+\t/* If the VF is locked, its resource assignment can't be changed */\n+\tif (dlb_vf_is_locked(hw, vf_id))\n+\t\treturn -EPERM;\n+\n+\torig = dst->num_avail_dir_credit_pools;\n+\n+\t/* Detach the VF's current resources before checking if enough are\n+\t * available, and set their IDs accordingly.\n+\t */\n+\tDLB_VF_ID_CLEAR(dst->avail_dir_credit_pools, struct dlb_credit_pool);\n+\n+\tDLB_XFER_LL_RSRC(src,\n+\t\t\t dst,\n+\t\t\t orig,\n+\t\t\t struct dlb_credit_pool,\n+\t\t\t dir_credit_pool);\n+\n+\t/* Are there enough available resources to satisfy the request? */\n+\tif (num > src->num_avail_dir_credit_pools) {\n+\t\tnum = orig;\n+\t\tret = -EINVAL;\n+\t} else {\n+\t\tret = 0;\n+\t}\n+\n+\tDLB_XFER_LL_RSRC(dst,\n+\t\t\t src,\n+\t\t\t num,\n+\t\t\t struct dlb_credit_pool,\n+\t\t\t dir_credit_pool);\n+\n+\treturn ret;\n+}\n+\n+static int dlb_transfer_bitmap_resources(struct dlb_bitmap *src,\n+\t\t\t\t\t struct dlb_bitmap *dst,\n+\t\t\t\t\t u32 num)\n+{\n+\tint orig, ret, base;\n+\n+\t/* Validate bitmaps before use */\n+\tif (dlb_bitmap_count(dst) < 0 || dlb_bitmap_count(src) < 0)\n+\t\treturn -EINVAL;\n+\n+\t/* Reassign the dest's bitmap entries to the source's before checking\n+\t * if a contiguous chunk of size 'num' is available. The reassignment\n+\t * may be necessary to create a sufficiently large contiguous chunk.\n+\t */\n+\torig = dlb_bitmap_count(dst);\n+\n+\tdlb_bitmap_or(src, src, dst);\n+\n+\tdlb_bitmap_zero(dst);\n+\n+\t/* Are there enough available resources to satisfy the request? */\n+\tbase = dlb_bitmap_find_set_bit_range(src, num);\n+\n+\tif (base == -ENOENT) {\n+\t\tnum = orig;\n+\t\tbase = dlb_bitmap_find_set_bit_range(src, num);\n+\t\tret = -EINVAL;\n+\t} else {\n+\t\tret = 0;\n+\t}\n+\n+\tdlb_bitmap_set_range(dst, base, num);\n+\n+\tdlb_bitmap_clear_range(src, base, num);\n+\n+\treturn ret;\n+}\n+\n+int dlb_update_vf_ldb_credits(struct dlb_hw *hw, u32 vf_id, u32 num)\n+{\n+\tstruct dlb_function_resources *src, *dst;\n+\n+\tif (vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -EINVAL;\n+\n+\tsrc = &hw->pf;\n+\tdst = &hw->vf[vf_id];\n+\n+\t/* If the VF is locked, its resource assignment can't be changed */\n+\tif (dlb_vf_is_locked(hw, vf_id))\n+\t\treturn -EPERM;\n+\n+\treturn dlb_transfer_bitmap_resources(src->avail_qed_freelist_entries,\n+\t\t\t\t\t     dst->avail_qed_freelist_entries,\n+\t\t\t\t\t     num);\n+}\n+\n+int dlb_update_vf_dir_credits(struct dlb_hw *hw, u32 vf_id, u32 num)\n+{\n+\tstruct dlb_function_resources *src, *dst;\n+\n+\tif (vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -EINVAL;\n+\n+\tsrc = &hw->pf;\n+\tdst = &hw->vf[vf_id];\n+\n+\t/* If the VF is locked, its resource assignment can't be changed */\n+\tif (dlb_vf_is_locked(hw, vf_id))\n+\t\treturn -EPERM;\n+\n+\treturn dlb_transfer_bitmap_resources(src->avail_dqed_freelist_entries,\n+\t\t\t\t\t     dst->avail_dqed_freelist_entries,\n+\t\t\t\t\t     num);\n+}\n+\n+int dlb_update_vf_hist_list_entries(struct dlb_hw *hw,\n+\t\t\t\t    u32 vf_id,\n+\t\t\t\t    u32 num)\n+{\n+\tstruct dlb_function_resources *src, *dst;\n+\n+\tif (vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -EINVAL;\n+\n+\tsrc = &hw->pf;\n+\tdst = &hw->vf[vf_id];\n+\n+\t/* If the VF is locked, its resource assignment can't be changed */\n+\tif (dlb_vf_is_locked(hw, vf_id))\n+\t\treturn -EPERM;\n+\n+\treturn dlb_transfer_bitmap_resources(src->avail_hist_list_entries,\n+\t\t\t\t\t     dst->avail_hist_list_entries,\n+\t\t\t\t\t     num);\n+}\n+\n+int dlb_update_vf_atomic_inflights(struct dlb_hw *hw,\n+\t\t\t\t   u32 vf_id,\n+\t\t\t\t   u32 num)\n+{\n+\tstruct dlb_function_resources *src, *dst;\n+\n+\tif (vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -EINVAL;\n+\n+\tsrc = &hw->pf;\n+\tdst = &hw->vf[vf_id];\n+\n+\t/* If the VF is locked, its resource assignment can't be changed */\n+\tif (dlb_vf_is_locked(hw, vf_id))\n+\t\treturn -EPERM;\n+\n+\treturn dlb_transfer_bitmap_resources(src->avail_aqed_freelist_entries,\n+\t\t\t\t\t     dst->avail_aqed_freelist_entries,\n+\t\t\t\t\t     num);\n+}\n+\n+static int dlb_attach_ldb_queues(struct dlb_hw *hw,\n+\t\t\t\t struct dlb_function_resources *rsrcs,\n+\t\t\t\t struct dlb_domain *domain,\n+\t\t\t\t u32 num_queues,\n+\t\t\t\t struct dlb_cmd_response *resp)\n+{\n+\tunsigned int i, j;\n+\n+\tif (rsrcs->num_avail_ldb_queues < num_queues) {\n+\t\tresp->status = DLB_ST_LDB_QUEUES_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\tfor (i = 0; i < num_queues; i++) {\n+\t\tstruct dlb_ldb_queue *queue;\n+\n+\t\tqueue = DLB_FUNC_LIST_HEAD(rsrcs->avail_ldb_queues,\n+\t\t\t\t\t   typeof(*queue));\n+\t\tif (!queue) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: domain validation failed\\n\",\n+\t\t\t\t   __func__);\n+\t\t\tgoto cleanup;\n+\t\t}\n+\n+\t\tdlb_list_del(&rsrcs->avail_ldb_queues, &queue->func_list);\n+\n+\t\tqueue->domain_id = domain->id;\n+\t\tqueue->owned = true;\n+\n+\t\tdlb_list_add(&domain->avail_ldb_queues, &queue->domain_list);\n+\t}\n+\n+\trsrcs->num_avail_ldb_queues -= num_queues;\n+\n+\treturn 0;\n+\n+cleanup:\n+\n+\t/* Return the assigned queues */\n+\tfor (j = 0; j < i; j++) {\n+\t\tstruct dlb_ldb_queue *queue;\n+\n+\t\tqueue = DLB_FUNC_LIST_HEAD(domain->avail_ldb_queues,\n+\t\t\t\t\t   typeof(*queue));\n+\t\t/* Unrecoverable internal error */\n+\t\tif (!queue)\n+\t\t\tbreak;\n+\n+\t\tqueue->owned = false;\n+\n+\t\tdlb_list_del(&domain->avail_ldb_queues, &queue->domain_list);\n+\n+\t\tdlb_list_add(&rsrcs->avail_ldb_queues, &queue->func_list);\n+\t}\n+\n+\treturn -EFAULT;\n+}\n+\n+static struct dlb_ldb_port *\n+dlb_get_next_ldb_port(struct dlb_hw *hw,\n+\t\t      struct dlb_function_resources *rsrcs,\n+\t\t      u32 domain_id)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_port *port;\n+\n+\t/* To reduce the odds of consecutive load-balanced ports mapping to the\n+\t * same queue(s), the driver attempts to allocate ports whose neighbors\n+\t * are owned by a different domain.\n+\t */\n+\tDLB_FUNC_LIST_FOR(rsrcs->avail_ldb_ports, port, iter) {\n+\t\tu32 next, prev;\n+\t\tu32 phys_id;\n+\n+\t\tphys_id = port->id.phys_id;\n+\t\tnext = phys_id + 1;\n+\t\tprev = phys_id - 1;\n+\n+\t\tif (phys_id == DLB_MAX_NUM_LDB_PORTS - 1)\n+\t\t\tnext = 0;\n+\t\tif (phys_id == 0)\n+\t\t\tprev = DLB_MAX_NUM_LDB_PORTS - 1;\n+\n+\t\tif (!hw->rsrcs.ldb_ports[next].owned ||\n+\t\t    hw->rsrcs.ldb_ports[next].domain_id.phys_id == domain_id)\n+\t\t\tcontinue;\n+\n+\t\tif (!hw->rsrcs.ldb_ports[prev].owned ||\n+\t\t    hw->rsrcs.ldb_ports[prev].domain_id.phys_id == domain_id)\n+\t\t\tcontinue;\n+\n+\t\treturn port;\n+\t}\n+\n+\t/* Failing that, the driver looks for a port with one neighbor owned by\n+\t * a different domain and the other unallocated.\n+\t */\n+\tDLB_FUNC_LIST_FOR(rsrcs->avail_ldb_ports, port, iter) {\n+\t\tu32 next, prev;\n+\t\tu32 phys_id;\n+\n+\t\tphys_id = port->id.phys_id;\n+\t\tnext = phys_id + 1;\n+\t\tprev = phys_id - 1;\n+\n+\t\tif (phys_id == DLB_MAX_NUM_LDB_PORTS - 1)\n+\t\t\tnext = 0;\n+\t\tif (phys_id == 0)\n+\t\t\tprev = DLB_MAX_NUM_LDB_PORTS - 1;\n+\n+\t\tif (!hw->rsrcs.ldb_ports[prev].owned &&\n+\t\t    hw->rsrcs.ldb_ports[next].owned &&\n+\t\t    hw->rsrcs.ldb_ports[next].domain_id.phys_id != domain_id)\n+\t\t\treturn port;\n+\n+\t\tif (!hw->rsrcs.ldb_ports[next].owned &&\n+\t\t    hw->rsrcs.ldb_ports[prev].owned &&\n+\t\t    hw->rsrcs.ldb_ports[prev].domain_id.phys_id != domain_id)\n+\t\t\treturn port;\n+\t}\n+\n+\t/* Failing that, the driver looks for a port with both neighbors\n+\t * unallocated.\n+\t */\n+\tDLB_FUNC_LIST_FOR(rsrcs->avail_ldb_ports, port, iter) {\n+\t\tu32 next, prev;\n+\t\tu32 phys_id;\n+\n+\t\tphys_id = port->id.phys_id;\n+\t\tnext = phys_id + 1;\n+\t\tprev = phys_id - 1;\n+\n+\t\tif (phys_id == DLB_MAX_NUM_LDB_PORTS - 1)\n+\t\t\tnext = 0;\n+\t\tif (phys_id == 0)\n+\t\t\tprev = DLB_MAX_NUM_LDB_PORTS - 1;\n+\n+\t\tif (!hw->rsrcs.ldb_ports[prev].owned &&\n+\t\t    !hw->rsrcs.ldb_ports[next].owned)\n+\t\t\treturn port;\n+\t}\n+\n+\t/* If all else fails, the driver returns the next available port. */\n+\treturn DLB_FUNC_LIST_HEAD(rsrcs->avail_ldb_ports, typeof(*port));\n+}\n+\n+static int dlb_attach_ldb_ports(struct dlb_hw *hw,\n+\t\t\t\tstruct dlb_function_resources *rsrcs,\n+\t\t\t\tstruct dlb_domain *domain,\n+\t\t\t\tu32 num_ports,\n+\t\t\t\tstruct dlb_cmd_response *resp)\n+{\n+\tunsigned int i, j;\n+\n+\tif (rsrcs->num_avail_ldb_ports < num_ports) {\n+\t\tresp->status = DLB_ST_LDB_PORTS_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\tfor (i = 0; i < num_ports; i++) {\n+\t\tstruct dlb_ldb_port *port;\n+\n+\t\tport = dlb_get_next_ldb_port(hw, rsrcs, domain->id.phys_id);\n+\n+\t\tif (!port) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: domain validation failed\\n\",\n+\t\t\t\t   __func__);\n+\t\t\tgoto cleanup;\n+\t\t}\n+\n+\t\tdlb_list_del(&rsrcs->avail_ldb_ports, &port->func_list);\n+\n+\t\tport->domain_id = domain->id;\n+\t\tport->owned = true;\n+\n+\t\tdlb_list_add(&domain->avail_ldb_ports, &port->domain_list);\n+\t}\n+\n+\trsrcs->num_avail_ldb_ports -= num_ports;\n+\n+\treturn 0;\n+\n+cleanup:\n+\n+\t/* Return the assigned ports */\n+\tfor (j = 0; j < i; j++) {\n+\t\tstruct dlb_ldb_port *port;\n+\n+\t\tport = DLB_FUNC_LIST_HEAD(domain->avail_ldb_ports,\n+\t\t\t\t\t  typeof(*port));\n+\t\t/* Unrecoverable internal error */\n+\t\tif (!port)\n+\t\t\tbreak;\n+\n+\t\tport->owned = false;\n+\n+\t\tdlb_list_del(&domain->avail_ldb_ports, &port->domain_list);\n+\n+\t\tdlb_list_add(&rsrcs->avail_ldb_ports, &port->func_list);\n+\t}\n+\n+\treturn -EFAULT;\n+}\n+\n+static int dlb_attach_dir_ports(struct dlb_hw *hw,\n+\t\t\t\tstruct dlb_function_resources *rsrcs,\n+\t\t\t\tstruct dlb_domain *domain,\n+\t\t\t\tu32 num_ports,\n+\t\t\t\tstruct dlb_cmd_response *resp)\n+{\n+\tunsigned int i, j;\n+\n+\tif (rsrcs->num_avail_dir_pq_pairs < num_ports) {\n+\t\tresp->status = DLB_ST_DIR_PORTS_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\tfor (i = 0; i < num_ports; i++) {\n+\t\tstruct dlb_dir_pq_pair *port;\n+\n+\t\tport = DLB_FUNC_LIST_HEAD(rsrcs->avail_dir_pq_pairs,\n+\t\t\t\t\t  typeof(*port));\n+\t\tif (!port) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: domain validation failed\\n\",\n+\t\t\t\t   __func__);\n+\t\t\tgoto cleanup;\n+\t\t}\n+\n+\t\tdlb_list_del(&rsrcs->avail_dir_pq_pairs, &port->func_list);\n+\n+\t\tport->domain_id = domain->id;\n+\t\tport->owned = true;\n+\n+\t\tdlb_list_add(&domain->avail_dir_pq_pairs, &port->domain_list);\n+\t}\n+\n+\trsrcs->num_avail_dir_pq_pairs -= num_ports;\n+\n+\treturn 0;\n+\n+cleanup:\n+\n+\t/* Return the assigned ports */\n+\tfor (j = 0; j < i; j++) {\n+\t\tstruct dlb_dir_pq_pair *port;\n+\n+\t\tport = DLB_FUNC_LIST_HEAD(domain->avail_dir_pq_pairs,\n+\t\t\t\t\t  typeof(*port));\n+\t\t/* Unrecoverable internal error */\n+\t\tif (!port)\n+\t\t\tbreak;\n+\n+\t\tport->owned = false;\n+\n+\t\tdlb_list_del(&domain->avail_dir_pq_pairs, &port->domain_list);\n+\n+\t\tdlb_list_add(&rsrcs->avail_dir_pq_pairs, &port->func_list);\n+\t}\n+\n+\treturn -EFAULT;\n+}\n+\n+static int dlb_attach_ldb_credits(struct dlb_function_resources *rsrcs,\n+\t\t\t\t  struct dlb_domain *domain,\n+\t\t\t\t  u32 num_credits,\n+\t\t\t\t  struct dlb_cmd_response *resp)\n+{\n+\tstruct dlb_bitmap *bitmap = rsrcs->avail_qed_freelist_entries;\n+\n+\tif (dlb_bitmap_count(bitmap) < (int)num_credits) {\n+\t\tresp->status = DLB_ST_LDB_CREDITS_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\tif (num_credits) {\n+\t\tint base;\n+\n+\t\tbase = dlb_bitmap_find_set_bit_range(bitmap, num_credits);\n+\t\tif (base < 0)\n+\t\t\tgoto error;\n+\n+\t\tdomain->qed_freelist.base = base;\n+\t\tdomain->qed_freelist.bound = base + num_credits;\n+\t\tdomain->qed_freelist.offset = 0;\n+\n+\t\tdlb_bitmap_clear_range(bitmap, base, num_credits);\n+\t}\n+\n+\treturn 0;\n+\n+error:\n+\tresp->status = DLB_ST_QED_FREELIST_ENTRIES_UNAVAILABLE;\n+\treturn -1;\n+}\n+\n+static int dlb_attach_dir_credits(struct dlb_function_resources *rsrcs,\n+\t\t\t\t  struct dlb_domain *domain,\n+\t\t\t\t  u32 num_credits,\n+\t\t\t\t  struct dlb_cmd_response *resp)\n+{\n+\tstruct dlb_bitmap *bitmap = rsrcs->avail_dqed_freelist_entries;\n+\n+\tif (dlb_bitmap_count(bitmap) < (int)num_credits) {\n+\t\tresp->status = DLB_ST_DIR_CREDITS_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\tif (num_credits) {\n+\t\tint base;\n+\n+\t\tbase = dlb_bitmap_find_set_bit_range(bitmap, num_credits);\n+\t\tif (base < 0)\n+\t\t\tgoto error;\n+\n+\t\tdomain->dqed_freelist.base = base;\n+\t\tdomain->dqed_freelist.bound = base + num_credits;\n+\t\tdomain->dqed_freelist.offset = 0;\n+\n+\t\tdlb_bitmap_clear_range(bitmap, base, num_credits);\n+\t}\n+\n+\treturn 0;\n+\n+error:\n+\tresp->status = DLB_ST_DQED_FREELIST_ENTRIES_UNAVAILABLE;\n+\treturn -1;\n+}\n+\n+static int dlb_attach_ldb_credit_pools(struct dlb_hw *hw,\n+\t\t\t\t       struct dlb_function_resources *rsrcs,\n+\t\t\t\t       struct dlb_domain *domain,\n+\t\t\t\t       u32 num_credit_pools,\n+\t\t\t\t       struct dlb_cmd_response *resp)\n+{\n+\tunsigned int i, j;\n+\n+\tif (rsrcs->num_avail_ldb_credit_pools < num_credit_pools) {\n+\t\tresp->status = DLB_ST_LDB_CREDIT_POOLS_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\tfor (i = 0; i < num_credit_pools; i++) {\n+\t\tstruct dlb_credit_pool *pool;\n+\n+\t\tpool = DLB_FUNC_LIST_HEAD(rsrcs->avail_ldb_credit_pools,\n+\t\t\t\t\t  typeof(*pool));\n+\t\tif (!pool) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: domain validation failed\\n\",\n+\t\t\t\t   __func__);\n+\t\t\tgoto cleanup;\n+\t\t}\n+\n+\t\tdlb_list_del(&rsrcs->avail_ldb_credit_pools,\n+\t\t\t     &pool->func_list);\n+\n+\t\tpool->domain_id = domain->id;\n+\t\tpool->owned = true;\n+\n+\t\tdlb_list_add(&domain->avail_ldb_credit_pools,\n+\t\t\t     &pool->domain_list);\n+\t}\n+\n+\trsrcs->num_avail_ldb_credit_pools -= num_credit_pools;\n+\n+\treturn 0;\n+\n+cleanup:\n+\n+\t/* Return the assigned credit pools */\n+\tfor (j = 0; j < i; j++) {\n+\t\tstruct dlb_credit_pool *pool;\n+\n+\t\tpool = DLB_FUNC_LIST_HEAD(domain->avail_ldb_credit_pools,\n+\t\t\t\t\t  typeof(*pool));\n+\t\t/* Unrecoverable internal error */\n+\t\tif (!pool)\n+\t\t\tbreak;\n+\n+\t\tpool->owned = false;\n+\n+\t\tdlb_list_del(&domain->avail_ldb_credit_pools,\n+\t\t\t     &pool->domain_list);\n+\n+\t\tdlb_list_add(&rsrcs->avail_ldb_credit_pools,\n+\t\t\t     &pool->func_list);\n+\t}\n+\n+\treturn -EFAULT;\n+}\n+\n+static int dlb_attach_dir_credit_pools(struct dlb_hw *hw,\n+\t\t\t\t       struct dlb_function_resources *rsrcs,\n+\t\t\t\t       struct dlb_domain *domain,\n+\t\t\t\t       u32 num_credit_pools,\n+\t\t\t\t       struct dlb_cmd_response *resp)\n+{\n+\tunsigned int i, j;\n+\n+\tif (rsrcs->num_avail_dir_credit_pools < num_credit_pools) {\n+\t\tresp->status = DLB_ST_DIR_CREDIT_POOLS_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\tfor (i = 0; i < num_credit_pools; i++) {\n+\t\tstruct dlb_credit_pool *pool;\n+\n+\t\tpool = DLB_FUNC_LIST_HEAD(rsrcs->avail_dir_credit_pools,\n+\t\t\t\t\t  typeof(*pool));\n+\t\tif (!pool) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: domain validation failed\\n\",\n+\t\t\t\t   __func__);\n+\t\t\tgoto cleanup;\n+\t\t}\n+\n+\t\tdlb_list_del(&rsrcs->avail_dir_credit_pools,\n+\t\t\t     &pool->func_list);\n+\n+\t\tpool->domain_id = domain->id;\n+\t\tpool->owned = true;\n+\n+\t\tdlb_list_add(&domain->avail_dir_credit_pools,\n+\t\t\t     &pool->domain_list);\n+\t}\n+\n+\trsrcs->num_avail_dir_credit_pools -= num_credit_pools;\n+\n+\treturn 0;\n+\n+cleanup:\n+\n+\t/* Return the assigned credit pools */\n+\tfor (j = 0; j < i; j++) {\n+\t\tstruct dlb_credit_pool *pool;\n+\n+\t\tpool = DLB_FUNC_LIST_HEAD(domain->avail_dir_credit_pools,\n+\t\t\t\t\t  typeof(*pool));\n+\t\t/* Unrecoverable internal error */\n+\t\tif (!pool)\n+\t\t\tbreak;\n+\n+\t\tpool->owned = false;\n+\n+\t\tdlb_list_del(&domain->avail_dir_credit_pools,\n+\t\t\t     &pool->domain_list);\n+\n+\t\tdlb_list_add(&rsrcs->avail_dir_credit_pools,\n+\t\t\t     &pool->func_list);\n+\t}\n+\n+\treturn -EFAULT;\n+}\n+\n+static int dlb_attach_atomic_inflights(struct dlb_function_resources *rsrcs,\n+\t\t\t\t       struct dlb_domain *domain,\n+\t\t\t\t       u32 num_atomic_inflights,\n+\t\t\t\t       struct dlb_cmd_response *resp)\n+{\n+\tif (num_atomic_inflights) {\n+\t\tstruct dlb_bitmap *bitmap =\n+\t\t\trsrcs->avail_aqed_freelist_entries;\n+\t\tint base;\n+\n+\t\tbase = dlb_bitmap_find_set_bit_range(bitmap,\n+\t\t\t\t\t\t     num_atomic_inflights);\n+\t\tif (base < 0)\n+\t\t\tgoto error;\n+\n+\t\tdomain->aqed_freelist.base = base;\n+\t\tdomain->aqed_freelist.bound = base + num_atomic_inflights;\n+\t\tdomain->aqed_freelist.offset = 0;\n+\n+\t\tdlb_bitmap_clear_range(bitmap, base, num_atomic_inflights);\n+\t}\n+\n+\treturn 0;\n+\n+error:\n+\tresp->status = DLB_ST_ATOMIC_INFLIGHTS_UNAVAILABLE;\n+\treturn -1;\n+}\n+\n+static int\n+dlb_attach_domain_hist_list_entries(struct dlb_function_resources *rsrcs,\n+\t\t\t\t    struct dlb_domain *domain,\n+\t\t\t\t    u32 num_hist_list_entries,\n+\t\t\t\t    struct dlb_cmd_response *resp)\n+{\n+\tstruct dlb_bitmap *bitmap;\n+\tint base;\n+\n+\tif (num_hist_list_entries) {\n+\t\tbitmap = rsrcs->avail_hist_list_entries;\n+\n+\t\tbase = dlb_bitmap_find_set_bit_range(bitmap,\n+\t\t\t\t\t\t     num_hist_list_entries);\n+\t\tif (base < 0)\n+\t\t\tgoto error;\n+\n+\t\tdomain->total_hist_list_entries = num_hist_list_entries;\n+\t\tdomain->avail_hist_list_entries = num_hist_list_entries;\n+\t\tdomain->hist_list_entry_base = base;\n+\t\tdomain->hist_list_entry_offset = 0;\n+\n+\t\tdlb_bitmap_clear_range(bitmap, base, num_hist_list_entries);\n+\t}\n+\treturn 0;\n+\n+error:\n+\tresp->status = DLB_ST_HIST_LIST_ENTRIES_UNAVAILABLE;\n+\treturn -1;\n+}\n+\n+static unsigned int\n+dlb_get_num_ports_in_use(struct dlb_hw *hw)\n+{\n+\tunsigned int i, n = 0;\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_LDB_PORTS; i++)\n+\t\tif (hw->rsrcs.ldb_ports[i].owned)\n+\t\t\tn++;\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_DIR_PORTS; i++)\n+\t\tif (hw->rsrcs.dir_pq_pairs[i].owned)\n+\t\t\tn++;\n+\n+\treturn n;\n+}\n+\n+static int\n+dlb_verify_create_sched_domain_args(struct dlb_hw *hw,\n+\t\t\t\t    struct dlb_function_resources *rsrcs,\n+\t\t\t\t    struct dlb_create_sched_domain_args *args,\n+\t\t\t\t    struct dlb_cmd_response *resp)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_bitmap *ldb_credit_freelist;\n+\tstruct dlb_bitmap *dir_credit_freelist;\n+\tunsigned int ldb_credit_freelist_count;\n+\tunsigned int dir_credit_freelist_count;\n+\tunsigned int max_contig_aqed_entries;\n+\tunsigned int max_contig_dqed_entries;\n+\tunsigned int max_contig_qed_entries;\n+\tunsigned int max_contig_hl_entries;\n+\tstruct dlb_bitmap *aqed_freelist;\n+\tenum dlb_dev_revision revision;\n+\n+\tldb_credit_freelist = rsrcs->avail_qed_freelist_entries;\n+\tdir_credit_freelist = rsrcs->avail_dqed_freelist_entries;\n+\taqed_freelist = rsrcs->avail_aqed_freelist_entries;\n+\n+\tldb_credit_freelist_count = dlb_bitmap_count(ldb_credit_freelist);\n+\tdir_credit_freelist_count = dlb_bitmap_count(dir_credit_freelist);\n+\n+\tmax_contig_hl_entries =\n+\t\tdlb_bitmap_longest_set_range(rsrcs->avail_hist_list_entries);\n+\tmax_contig_aqed_entries =\n+\t\tdlb_bitmap_longest_set_range(aqed_freelist);\n+\tmax_contig_qed_entries =\n+\t\tdlb_bitmap_longest_set_range(ldb_credit_freelist);\n+\tmax_contig_dqed_entries =\n+\t\tdlb_bitmap_longest_set_range(dir_credit_freelist);\n+\n+\tif (rsrcs->num_avail_domains < 1)\n+\t\tresp->status = DLB_ST_DOMAIN_UNAVAILABLE;\n+\telse if (rsrcs->num_avail_ldb_queues < args->num_ldb_queues)\n+\t\tresp->status = DLB_ST_LDB_QUEUES_UNAVAILABLE;\n+\telse if (rsrcs->num_avail_ldb_ports < args->num_ldb_ports)\n+\t\tresp->status = DLB_ST_LDB_PORTS_UNAVAILABLE;\n+\telse if (args->num_ldb_queues > 0 && args->num_ldb_ports == 0)\n+\t\tresp->status = DLB_ST_LDB_PORT_REQUIRED_FOR_LDB_QUEUES;\n+\telse if (rsrcs->num_avail_dir_pq_pairs < args->num_dir_ports)\n+\t\tresp->status = DLB_ST_DIR_PORTS_UNAVAILABLE;\n+\telse if (ldb_credit_freelist_count < args->num_ldb_credits)\n+\t\tresp->status = DLB_ST_LDB_CREDITS_UNAVAILABLE;\n+\telse if (dir_credit_freelist_count < args->num_dir_credits)\n+\t\tresp->status = DLB_ST_DIR_CREDITS_UNAVAILABLE;\n+\telse if (rsrcs->num_avail_ldb_credit_pools < args->num_ldb_credit_pools)\n+\t\tresp->status = DLB_ST_LDB_CREDIT_POOLS_UNAVAILABLE;\n+\telse if (rsrcs->num_avail_dir_credit_pools < args->num_dir_credit_pools)\n+\t\tresp->status = DLB_ST_DIR_CREDIT_POOLS_UNAVAILABLE;\n+\telse if (max_contig_hl_entries < args->num_hist_list_entries)\n+\t\tresp->status = DLB_ST_HIST_LIST_ENTRIES_UNAVAILABLE;\n+\telse if (max_contig_aqed_entries < args->num_atomic_inflights)\n+\t\tresp->status = DLB_ST_ATOMIC_INFLIGHTS_UNAVAILABLE;\n+\telse if (max_contig_qed_entries < args->num_ldb_credits)\n+\t\tresp->status = DLB_ST_QED_FREELIST_ENTRIES_UNAVAILABLE;\n+\telse if (max_contig_dqed_entries < args->num_dir_credits)\n+\t\tresp->status = DLB_ST_DQED_FREELIST_ENTRIES_UNAVAILABLE;\n+\n+\t/* DLB A-stepping workaround for hardware write buffer lock up issue:\n+\t * limit the maximum configured ports to less than 128 and disable CQ\n+\t * occupancy interrupts.\n+\t */\n+\trevision = os_get_dev_revision(hw);\n+\n+\tif (revision < DLB_B0) {\n+\t\tu32 n = dlb_get_num_ports_in_use(hw);\n+\n+\t\tn += args->num_ldb_ports + args->num_dir_ports;\n+\n+\t\tif (n >= DLB_A_STEP_MAX_PORTS)\n+\t\t\tresp->status = args->num_ldb_ports ?\n+\t\t\t\tDLB_ST_LDB_PORTS_UNAVAILABLE :\n+\t\t\t\tDLB_ST_DIR_PORTS_UNAVAILABLE;\n+\t}\n+\n+\tif (resp->status)\n+\t\treturn -1;\n+\n+\treturn 0;\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+\t\t\t\tbool vf_request,\n+\t\t\t\tunsigned int vf_id)\n+{\n+\tstruct dlb_freelist *qed_freelist;\n+\tstruct dlb_domain *domain;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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_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.phys_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.phys_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.phys_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.phys_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.phys_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.phys_id), r6.val);\n+\n+\tr0.field.pool_enabled = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_POOL_ENBLD(pool->id.phys_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_dir_pool_args(struct dlb_hw *hw,\n+\t\t\t\tu32 domain_id,\n+\t\t\t\tstruct dlb_create_dir_pool_args *args,\n+\t\t\t\tstruct dlb_cmd_response *resp,\n+\t\t\t\tbool vf_request,\n+\t\t\t\tunsigned int vf_id)\n+{\n+\tstruct dlb_freelist *dqed_freelist;\n+\tstruct dlb_domain *domain;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tdqed_freelist = &domain->dqed_freelist;\n+\n+\tif (dlb_freelist_count(dqed_freelist) < args->num_dir_credits) {\n+\t\tresp->status = DLB_ST_DIR_CREDITS_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\tif (dlb_list_empty(&domain->avail_dir_credit_pools)) {\n+\t\tresp->status = DLB_ST_DIR_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_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+\t\t\t      struct dlb_credit_pool *pool)\n+{\n+\tunion dlb_sys_dir_pool_enbld r0 = { {0} };\n+\tunion dlb_chp_dir_pool_crd_lim r1 = { {0} };\n+\tunion dlb_chp_dir_pool_crd_cnt r2 = { {0} };\n+\tunion dlb_chp_dqed_fl_base  r3 = { {0} };\n+\tunion dlb_chp_dqed_fl_lim r4 = { {0} };\n+\tunion dlb_chp_dqed_fl_push_ptr r5 = { {0} };\n+\tunion dlb_chp_dqed_fl_pop_ptr  r6 = { {0} };\n+\n+\tr1.field.limit = args->num_dir_credits;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_DIR_POOL_CRD_LIM(pool->id.phys_id), r1.val);\n+\n+\tr2.field.count = args->num_dir_credits;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_DIR_POOL_CRD_CNT(pool->id.phys_id), r2.val);\n+\n+\tr3.field.base = domain->dqed_freelist.base +\n+\t\t\tdomain->dqed_freelist.offset;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_DQED_FL_BASE(pool->id.phys_id), r3.val);\n+\n+\tr4.field.freelist_disable = 0;\n+\tr4.field.limit = r3.field.base + args->num_dir_credits - 1;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_DQED_FL_LIM(pool->id.phys_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_DQED_FL_PUSH_PTR(pool->id.phys_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_DQED_FL_POP_PTR(pool->id.phys_id), r6.val);\n+\n+\tr0.field.pool_enabled = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_DIR_POOL_ENBLD(pool->id.phys_id), r0.val);\n+\n+\tpool->avail_credits = args->num_dir_credits;\n+\tpool->total_credits = args->num_dir_credits;\n+\tdomain->dqed_freelist.offset += args->num_dir_credits;\n+\n+\tpool->configured = true;\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+\t\t\t\t bool vf_request,\n+\t\t\t\t unsigned int vf_id)\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, vf_request, vf_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 int\n+dlb_verify_create_dir_queue_args(struct dlb_hw *hw,\n+\t\t\t\t u32 domain_id,\n+\t\t\t\t struct dlb_create_dir_queue_args *args,\n+\t\t\t\t struct dlb_cmd_response *resp,\n+\t\t\t\t bool vf_request,\n+\t\t\t\t unsigned int vf_id)\n+{\n+\tstruct dlb_domain *domain;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\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 dlb_dir_pq_pair *port;\n+\n+\t\tport = dlb_get_domain_used_dir_pq(args->port_id,\n+\t\t\t\t\t\t  vf_request,\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 = DLB_ST_INVALID_PORT_ID;\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\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    dlb_list_empty(&domain->avail_dir_pq_pairs)) {\n+\t\tresp->status = DLB_ST_DIR_QUEUES_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\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+\t\t\t\t    bool vf_request,\n+\t\t\t\t    unsigned int vf_id)\n+{\n+\tunion dlb_sys_vf_ldb_vqid_v r0 = { {0} };\n+\tunion dlb_sys_vf_ldb_vqid2qid r1 = { {0} };\n+\tunion dlb_sys_ldb_qid2vqid r2 = { {0} };\n+\tunion dlb_sys_ldb_vasqid_v r3 = { {0} };\n+\tunion dlb_lsp_qid_ldb_infl_lim r4 = { {0} };\n+\tunion dlb_lsp_qid_aqed_active_lim r5 = { {0} };\n+\tunion dlb_aqed_pipe_fl_lim r6 = { {0} };\n+\tunion dlb_aqed_pipe_fl_base r7 = { {0} };\n+\tunion dlb_chp_ord_qid_sn_map r11 = { {0} };\n+\tunion dlb_sys_ldb_qid_cfg_v r12 = { {0} };\n+\tunion dlb_sys_ldb_qid_v r13 = { {0} };\n+\tunion dlb_aqed_pipe_fl_push_ptr r14 = { {0} };\n+\tunion dlb_aqed_pipe_fl_pop_ptr r15 = { {0} };\n+\tunion dlb_aqed_pipe_qid_fid_lim r16 = { {0} };\n+\tunion dlb_ro_pipe_qid2grpslt r17 = { {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+\tr3.field.vasqid_v = 0;\n+\n+\toffs = domain->id.phys_id * DLB_MAX_NUM_LDB_QUEUES + queue->id.phys_id;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_VASQID_V(offs), r3.val);\n+\n+\t/* Unordered QIDs get 4K inflights, ordered get as many as the number\n+\t * of sequence numbers.\n+\t */\n+\tr4.field.limit = args->num_qid_inflights;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_QID_LDB_INFL_LIM(queue->id.phys_id), r4.val);\n+\n+\tr5.field.limit = queue->aqed_freelist.bound -\n+\t\t\t queue->aqed_freelist.base;\n+\n+\tif (r5.field.limit > DLB_MAX_NUM_AQOS_ENTRIES)\n+\t\tr5.field.limit = DLB_MAX_NUM_AQOS_ENTRIES;\n+\n+\t/* AQOS */\n+\tDLB_CSR_WR(hw, DLB_LSP_QID_AQED_ACTIVE_LIM(queue->id.phys_id), r5.val);\n+\n+\tr6.field.freelist_disable = 0;\n+\tr6.field.limit = queue->aqed_freelist.bound - 1;\n+\n+\tDLB_CSR_WR(hw, DLB_AQED_PIPE_FL_LIM(queue->id.phys_id), r6.val);\n+\n+\tr7.field.base = queue->aqed_freelist.base;\n+\n+\tDLB_CSR_WR(hw, DLB_AQED_PIPE_FL_BASE(queue->id.phys_id), r7.val);\n+\n+\tr14.field.push_ptr = r7.field.base;\n+\tr14.field.generation = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_AQED_PIPE_FL_PUSH_PTR(queue->id.phys_id), r14.val);\n+\n+\tr15.field.pop_ptr = r7.field.base;\n+\tr15.field.generation = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_AQED_PIPE_FL_POP_PTR(queue->id.phys_id), r15.val);\n+\n+\t/* Configure SNs */\n+\tsn_group = &hw->rsrcs.sn_groups[queue->sn_group];\n+\tr11.field.mode = sn_group->mode;\n+\tr11.field.slot = queue->sn_slot;\n+\tr11.field.grp  = sn_group->id;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_ORD_QID_SN_MAP(queue->id.phys_id), r11.val);\n+\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+\tr16.field.qid_fid_limit = 512;\n+\n+\tDLB_CSR_WR(hw, DLB_AQED_PIPE_QID_FID_LIM(queue->id.phys_id), r16.val);\n+\n+\tr17.field.group = sn_group->id;\n+\tr17.field.slot = queue->sn_slot;\n+\n+\tDLB_CSR_WR(hw, DLB_RO_PIPE_QID2GRPSLT(queue->id.phys_id), r17.val);\n+\n+\tr12.field.sn_cfg_v = (args->num_sequence_numbers != 0);\n+\tr12.field.fid_cfg_v = (args->num_atomic_inflights != 0);\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_QID_CFG_V(queue->id.phys_id), r12.val);\n+\n+\tif (vf_request) {\n+\t\tunsigned int offs;\n+\n+\t\tr0.field.vqid_v = 1;\n+\n+\t\toffs = vf_id * DLB_MAX_NUM_LDB_QUEUES + queue->id.virt_id;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_VF_LDB_VQID_V(offs), r0.val);\n+\n+\t\tr1.field.qid = queue->id.phys_id;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_VF_LDB_VQID2QID(offs), r1.val);\n+\n+\t\tr2.field.vqid = queue->id.virt_id;\n+\n+\t\toffs = vf_id * DLB_MAX_NUM_LDB_QUEUES + queue->id.phys_id;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_LDB_QID2VQID(offs), r2.val);\n+\t}\n+\n+\tr13.field.qid_v = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_QID_V(queue->id.phys_id), r13.val);\n+}\n+\n+static void dlb_configure_dir_queue(struct dlb_hw *hw,\n+\t\t\t\t    struct dlb_domain *domain,\n+\t\t\t\t    struct dlb_dir_pq_pair *queue,\n+\t\t\t\t    bool vf_request,\n+\t\t\t\t    unsigned int vf_id)\n+{\n+\tunion dlb_sys_dir_vasqid_v r0 = { {0} };\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 * DLB_MAX_NUM_DIR_PORTS) + queue->id.phys_id;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_DIR_VASQID_V(offs), r0.val);\n+\n+\tif (vf_request) {\n+\t\tunion dlb_sys_vf_dir_vqid_v   r1 = { {0} };\n+\t\tunion dlb_sys_vf_dir_vqid2qid r2 = { {0} };\n+\n+\t\tr1.field.vqid_v = 1;\n+\n+\t\toffs = (vf_id * DLB_MAX_NUM_DIR_PORTS) + queue->id.virt_id;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_VF_DIR_VQID_V(offs), r1.val);\n+\n+\t\tr2.field.qid = queue->id.phys_id;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_VF_DIR_VQID2QID(offs), r2.val);\n+\t} else {\n+\t\tunion dlb_sys_dir_qid_v r3 = { {0} };\n+\n+\t\tr3.field.qid_v = 1;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_DIR_QID_V(queue->id.phys_id), r3.val);\n+\t}\n+\n+\tqueue->queue_configured = true;\n+}\n+\n+static int\n+dlb_verify_create_ldb_port_args(struct dlb_hw *hw,\n+\t\t\t\tu32 domain_id,\n+\t\t\t\tu64 pop_count_dma_base,\n+\t\t\t\tu64 cq_dma_base,\n+\t\t\t\tstruct dlb_create_ldb_port_args *args,\n+\t\t\t\tstruct dlb_cmd_response *resp,\n+\t\t\t\tbool vf_request,\n+\t\t\t\tunsigned int vf_id)\n+{\n+\tstruct dlb_domain *domain;\n+\tstruct dlb_credit_pool *pool;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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_ports)) {\n+\t\tresp->status = DLB_ST_LDB_PORTS_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\t/* If the scheduling domain has no LDB queues, we configure the\n+\t * hardware to not supply the port with any LDB credits. In that\n+\t * case, ignore the LDB credit arguments.\n+\t */\n+\tif (!dlb_list_empty(&domain->used_ldb_queues) ||\n+\t    !dlb_list_empty(&domain->avail_ldb_queues)) {\n+\t\tpool = dlb_get_domain_ldb_pool(args->ldb_credit_pool_id,\n+\t\t\t\t\t       vf_request,\n+\t\t\t\t\t       domain);\n+\n+\t\tif (!pool || !pool->configured ||\n+\t\t    pool->domain_id.phys_id != domain->id.phys_id) {\n+\t\t\tresp->status = DLB_ST_INVALID_LDB_CREDIT_POOL_ID;\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (args->ldb_credit_high_watermark > pool->avail_credits) {\n+\t\t\tresp->status = DLB_ST_LDB_CREDITS_UNAVAILABLE;\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (args->ldb_credit_low_watermark >=\n+\t\t    args->ldb_credit_high_watermark) {\n+\t\t\tresp->status = DLB_ST_INVALID_LDB_CREDIT_LOW_WATERMARK;\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (args->ldb_credit_quantum >=\n+\t\t    args->ldb_credit_high_watermark) {\n+\t\t\tresp->status = DLB_ST_INVALID_LDB_CREDIT_QUANTUM;\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (args->ldb_credit_quantum > DLB_MAX_PORT_CREDIT_QUANTUM) {\n+\t\t\tresp->status = DLB_ST_INVALID_LDB_CREDIT_QUANTUM;\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\t/* Likewise, if the scheduling domain has no DIR queues, we configure\n+\t * the hardware to not supply the port with any DIR credits. In that\n+\t * case, ignore the DIR credit arguments.\n+\t */\n+\tif (!dlb_list_empty(&domain->used_dir_pq_pairs) ||\n+\t    !dlb_list_empty(&domain->avail_dir_pq_pairs)) {\n+\t\tpool = dlb_get_domain_dir_pool(args->dir_credit_pool_id,\n+\t\t\t\t\t       vf_request,\n+\t\t\t\t\t       domain);\n+\n+\t\tif (!pool || !pool->configured ||\n+\t\t    pool->domain_id.phys_id != domain->id.phys_id) {\n+\t\t\tresp->status = DLB_ST_INVALID_DIR_CREDIT_POOL_ID;\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (args->dir_credit_high_watermark > pool->avail_credits) {\n+\t\t\tresp->status = DLB_ST_DIR_CREDITS_UNAVAILABLE;\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (args->dir_credit_low_watermark >=\n+\t\t    args->dir_credit_high_watermark) {\n+\t\t\tresp->status = DLB_ST_INVALID_DIR_CREDIT_LOW_WATERMARK;\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (args->dir_credit_quantum >=\n+\t\t    args->dir_credit_high_watermark) {\n+\t\t\tresp->status = DLB_ST_INVALID_DIR_CREDIT_QUANTUM;\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (args->dir_credit_quantum > DLB_MAX_PORT_CREDIT_QUANTUM) {\n+\t\t\tresp->status = DLB_ST_INVALID_DIR_CREDIT_QUANTUM;\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\t/* Check cache-line alignment */\n+\tif ((pop_count_dma_base & 0x3F) != 0) {\n+\t\tresp->status = DLB_ST_INVALID_POP_COUNT_VIRT_ADDR;\n+\t\treturn -1;\n+\t}\n+\n+\tif ((cq_dma_base & 0x3F) != 0) {\n+\t\tresp->status = DLB_ST_INVALID_CQ_VIRT_ADDR;\n+\t\treturn -1;\n+\t}\n+\n+\tif (args->cq_depth != 1 &&\n+\t    args->cq_depth != 2 &&\n+\t    args->cq_depth != 4 &&\n+\t    args->cq_depth != 8 &&\n+\t    args->cq_depth != 16 &&\n+\t    args->cq_depth != 32 &&\n+\t    args->cq_depth != 64 &&\n+\t    args->cq_depth != 128 &&\n+\t    args->cq_depth != 256 &&\n+\t    args->cq_depth != 512 &&\n+\t    args->cq_depth != 1024) {\n+\t\tresp->status = DLB_ST_INVALID_CQ_DEPTH;\n+\t\treturn -1;\n+\t}\n+\n+\t/* The history list size must be >= 1 */\n+\tif (!args->cq_history_list_size) {\n+\t\tresp->status = DLB_ST_INVALID_HIST_LIST_DEPTH;\n+\t\treturn -1;\n+\t}\n+\n+\tif (args->cq_history_list_size > domain->avail_hist_list_entries) {\n+\t\tresp->status = DLB_ST_HIST_LIST_ENTRIES_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+dlb_verify_create_dir_port_args(struct dlb_hw *hw,\n+\t\t\t\tu32 domain_id,\n+\t\t\t\tu64 pop_count_dma_base,\n+\t\t\t\tu64 cq_dma_base,\n+\t\t\t\tstruct dlb_create_dir_port_args *args,\n+\t\t\t\tstruct dlb_cmd_response *resp,\n+\t\t\t\tbool vf_request,\n+\t\t\t\tunsigned int vf_id)\n+{\n+\tstruct dlb_domain *domain;\n+\tstruct dlb_credit_pool *pool;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\t/* If the user claims the queue is already configured, validate\n+\t * the queue ID, its domain, and whether the queue is configured.\n+\t */\n+\tif (args->queue_id != -1) {\n+\t\tstruct dlb_dir_pq_pair *queue;\n+\n+\t\tqueue = dlb_get_domain_used_dir_pq(args->queue_id,\n+\t\t\t\t\t\t   vf_request,\n+\t\t\t\t\t\t   domain);\n+\n+\t\tif (!queue || queue->domain_id.phys_id != domain->id.phys_id ||\n+\t\t    !queue->queue_configured) {\n+\t\t\tresp->status = DLB_ST_INVALID_DIR_QUEUE_ID;\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\t/* If the port's queue is not configured, validate that a free\n+\t * port-queue pair is available.\n+\t */\n+\tif (args->queue_id == -1 &&\n+\t    dlb_list_empty(&domain->avail_dir_pq_pairs)) {\n+\t\tresp->status = DLB_ST_DIR_PORTS_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\t/* If the scheduling domain has no LDB queues, we configure the\n+\t * hardware to not supply the port with any LDB credits. In that\n+\t * case, ignore the LDB credit arguments.\n+\t */\n+\tif (!dlb_list_empty(&domain->used_ldb_queues) ||\n+\t    !dlb_list_empty(&domain->avail_ldb_queues)) {\n+\t\tpool = dlb_get_domain_ldb_pool(args->ldb_credit_pool_id,\n+\t\t\t\t\t       vf_request,\n+\t\t\t\t\t       domain);\n+\n+\t\tif (!pool || !pool->configured ||\n+\t\t    pool->domain_id.phys_id != domain->id.phys_id) {\n+\t\t\tresp->status = DLB_ST_INVALID_LDB_CREDIT_POOL_ID;\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (args->ldb_credit_high_watermark > pool->avail_credits) {\n+\t\t\tresp->status = DLB_ST_LDB_CREDITS_UNAVAILABLE;\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (args->ldb_credit_low_watermark >=\n+\t\t    args->ldb_credit_high_watermark) {\n+\t\t\tresp->status = DLB_ST_INVALID_LDB_CREDIT_LOW_WATERMARK;\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (args->ldb_credit_quantum >=\n+\t\t    args->ldb_credit_high_watermark) {\n+\t\t\tresp->status = DLB_ST_INVALID_LDB_CREDIT_QUANTUM;\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (args->ldb_credit_quantum > DLB_MAX_PORT_CREDIT_QUANTUM) {\n+\t\t\tresp->status = DLB_ST_INVALID_LDB_CREDIT_QUANTUM;\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\tpool = dlb_get_domain_dir_pool(args->dir_credit_pool_id,\n+\t\t\t\t       vf_request,\n+\t\t\t\t       domain);\n+\n+\tif (!pool || !pool->configured ||\n+\t    pool->domain_id.phys_id != domain->id.phys_id) {\n+\t\tresp->status = DLB_ST_INVALID_DIR_CREDIT_POOL_ID;\n+\t\treturn -1;\n+\t}\n+\n+\tif (args->dir_credit_high_watermark > pool->avail_credits) {\n+\t\tresp->status = DLB_ST_DIR_CREDITS_UNAVAILABLE;\n+\t\treturn -1;\n+\t}\n+\n+\tif (args->dir_credit_low_watermark >= args->dir_credit_high_watermark) {\n+\t\tresp->status = DLB_ST_INVALID_DIR_CREDIT_LOW_WATERMARK;\n+\t\treturn -1;\n+\t}\n+\n+\tif (args->dir_credit_quantum >= args->dir_credit_high_watermark) {\n+\t\tresp->status = DLB_ST_INVALID_DIR_CREDIT_QUANTUM;\n+\t\treturn -1;\n+\t}\n+\n+\tif (args->dir_credit_quantum > DLB_MAX_PORT_CREDIT_QUANTUM) {\n+\t\tresp->status = DLB_ST_INVALID_DIR_CREDIT_QUANTUM;\n+\t\treturn -1;\n+\t}\n+\n+\t/* Check cache-line alignment */\n+\tif ((pop_count_dma_base & 0x3F) != 0) {\n+\t\tresp->status = DLB_ST_INVALID_POP_COUNT_VIRT_ADDR;\n+\t\treturn -1;\n+\t}\n+\n+\tif ((cq_dma_base & 0x3F) != 0) {\n+\t\tresp->status = DLB_ST_INVALID_CQ_VIRT_ADDR;\n+\t\treturn -1;\n+\t}\n+\n+\tif (args->cq_depth != 8 &&\n+\t    args->cq_depth != 16 &&\n+\t    args->cq_depth != 32 &&\n+\t    args->cq_depth != 64 &&\n+\t    args->cq_depth != 128 &&\n+\t    args->cq_depth != 256 &&\n+\t    args->cq_depth != 512 &&\n+\t    args->cq_depth != 1024) {\n+\t\tresp->status = DLB_ST_INVALID_CQ_DEPTH;\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int dlb_verify_start_domain_args(struct dlb_hw *hw,\n+\t\t\t\t\tu32 domain_id,\n+\t\t\t\t\tstruct dlb_cmd_response *resp,\n+\t\t\t\t\tbool vf_request,\n+\t\t\t\t\tunsigned int vf_id)\n+{\n+\tstruct dlb_domain *domain;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\treturn 0;\n+}\n+\n+static int dlb_verify_map_qid_args(struct dlb_hw *hw,\n+\t\t\t\t   u32 domain_id,\n+\t\t\t\t   struct dlb_map_qid_args *args,\n+\t\t\t\t   struct dlb_cmd_response *resp,\n+\t\t\t\t   bool vf_request,\n+\t\t\t\t   unsigned int vf_id)\n+{\n+\tstruct dlb_domain *domain;\n+\tstruct dlb_ldb_port *port;\n+\tstruct dlb_ldb_queue *queue;\n+\tint id;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tid = args->port_id;\n+\n+\tport = dlb_get_domain_used_ldb_port(id, vf_request, domain);\n+\n+\tif (!port || !port->configured) {\n+\t\tresp->status = DLB_ST_INVALID_PORT_ID;\n+\t\treturn -1;\n+\t}\n+\n+\tif (args->priority >= DLB_QID_PRIORITIES) {\n+\t\tresp->status = DLB_ST_INVALID_PRIORITY;\n+\t\treturn -1;\n+\t}\n+\n+\tqueue = dlb_get_domain_ldb_queue(args->qid, vf_request, domain);\n+\n+\tif (!queue || !queue->configured) {\n+\t\tresp->status = DLB_ST_INVALID_QID;\n+\t\treturn -1;\n+\t}\n+\n+\tif (queue->domain_id.phys_id != domain->id.phys_id) {\n+\t\tresp->status = DLB_ST_INVALID_QID;\n+\t\treturn -1;\n+\t}\n+\n+\tif (port->domain_id.phys_id != domain->id.phys_id) {\n+\t\tresp->status = DLB_ST_INVALID_PORT_ID;\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static bool dlb_port_find_slot(struct dlb_ldb_port *port,\n+\t\t\t       enum dlb_qid_map_state state,\n+\t\t\t       int *slot)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_QIDS_PER_LDB_CQ; i++) {\n+\t\tif (port->qid_map[i].state == state)\n+\t\t\tbreak;\n+\t}\n+\n+\t*slot = i;\n+\n+\treturn (i < DLB_MAX_NUM_QIDS_PER_LDB_CQ);\n+}\n+\n+static bool dlb_port_find_slot_queue(struct dlb_ldb_port *port,\n+\t\t\t\t     enum dlb_qid_map_state state,\n+\t\t\t\t     struct dlb_ldb_queue *queue,\n+\t\t\t\t     int *slot)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_QIDS_PER_LDB_CQ; i++) {\n+\t\tif (port->qid_map[i].state == state &&\n+\t\t    port->qid_map[i].qid == queue->id.phys_id)\n+\t\t\tbreak;\n+\t}\n+\n+\t*slot = i;\n+\n+\treturn (i < DLB_MAX_NUM_QIDS_PER_LDB_CQ);\n+}\n+\n+static bool\n+dlb_port_find_slot_with_pending_map_queue(struct dlb_ldb_port *port,\n+\t\t\t\t\t  struct dlb_ldb_queue *queue,\n+\t\t\t\t\t  int *slot)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_QIDS_PER_LDB_CQ; i++) {\n+\t\tstruct dlb_ldb_port_qid_map *map = &port->qid_map[i];\n+\n+\t\tif (map->state == DLB_QUEUE_UNMAP_IN_PROGRESS_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 < DLB_MAX_NUM_QIDS_PER_LDB_CQ);\n+}\n+\n+static int dlb_port_slot_state_transition(struct dlb_hw *hw,\n+\t\t\t\t\t  struct dlb_ldb_port *port,\n+\t\t\t\t\t  struct dlb_ldb_queue *queue,\n+\t\t\t\t\t  int slot,\n+\t\t\t\t\t  enum dlb_qid_map_state new_state)\n+{\n+\tenum dlb_qid_map_state curr_state = port->qid_map[slot].state;\n+\tstruct dlb_domain *domain;\n+\n+\tdomain = dlb_get_domain_from_id(hw, port->domain_id.phys_id, false, 0);\n+\tif (!domain) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: unable to find domain %d\\n\",\n+\t\t\t   __func__, port->domain_id.phys_id);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tswitch (curr_state) {\n+\tcase DLB_QUEUE_UNMAPPED:\n+\t\tswitch (new_state) {\n+\t\tcase DLB_QUEUE_MAPPED:\n+\t\t\tqueue->num_mappings++;\n+\t\t\tport->num_mappings++;\n+\t\t\tbreak;\n+\t\tcase DLB_QUEUE_MAP_IN_PROGRESS:\n+\t\t\tqueue->num_pending_additions++;\n+\t\t\tdomain->num_pending_additions++;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tgoto error;\n+\t\t}\n+\t\tbreak;\n+\tcase DLB_QUEUE_MAPPED:\n+\t\tswitch (new_state) {\n+\t\tcase DLB_QUEUE_UNMAPPED:\n+\t\t\tqueue->num_mappings--;\n+\t\t\tport->num_mappings--;\n+\t\t\tbreak;\n+\t\tcase DLB_QUEUE_UNMAP_IN_PROGRESS:\n+\t\t\tport->num_pending_removals++;\n+\t\t\tdomain->num_pending_removals++;\n+\t\t\tbreak;\n+\t\tcase DLB_QUEUE_MAPPED:\n+\t\t\t/* Priority change, nothing to update */\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tgoto error;\n+\t\t}\n+\t\tbreak;\n+\tcase DLB_QUEUE_MAP_IN_PROGRESS:\n+\t\tswitch (new_state) {\n+\t\tcase DLB_QUEUE_UNMAPPED:\n+\t\t\tqueue->num_pending_additions--;\n+\t\t\tdomain->num_pending_additions--;\n+\t\t\tbreak;\n+\t\tcase DLB_QUEUE_MAPPED:\n+\t\t\tqueue->num_mappings++;\n+\t\t\tport->num_mappings++;\n+\t\t\tqueue->num_pending_additions--;\n+\t\t\tdomain->num_pending_additions--;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tgoto error;\n+\t\t}\n+\t\tbreak;\n+\tcase DLB_QUEUE_UNMAP_IN_PROGRESS:\n+\t\tswitch (new_state) {\n+\t\tcase DLB_QUEUE_UNMAPPED:\n+\t\t\tport->num_pending_removals--;\n+\t\t\tdomain->num_pending_removals--;\n+\t\t\tqueue->num_mappings--;\n+\t\t\tport->num_mappings--;\n+\t\t\tbreak;\n+\t\tcase DLB_QUEUE_MAPPED:\n+\t\t\tport->num_pending_removals--;\n+\t\t\tdomain->num_pending_removals--;\n+\t\t\tbreak;\n+\t\tcase DLB_QUEUE_UNMAP_IN_PROGRESS_PENDING_MAP:\n+\t\t\t/* Nothing to update */\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tgoto error;\n+\t\t}\n+\t\tbreak;\n+\tcase DLB_QUEUE_UNMAP_IN_PROGRESS_PENDING_MAP:\n+\t\tswitch (new_state) {\n+\t\tcase DLB_QUEUE_UNMAP_IN_PROGRESS:\n+\t\t\t/* Nothing to update */\n+\t\t\tbreak;\n+\t\tcase DLB_QUEUE_UNMAPPED:\n+\t\t\t/* An UNMAP_IN_PROGRESS_PENDING_MAP slot briefly\n+\t\t\t * becomes UNMAPPED before it transitions to\n+\t\t\t * MAP_IN_PROGRESS.\n+\t\t\t */\n+\t\t\tqueue->num_mappings--;\n+\t\t\tport->num_mappings--;\n+\t\t\tport->num_pending_removals--;\n+\t\t\tdomain->num_pending_removals--;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tgoto error;\n+\t\t}\n+\t\tbreak;\n+\tdefault:\n+\t\tgoto error;\n+\t}\n+\n+\tport->qid_map[slot].state = new_state;\n+\n+\tDLB_HW_INFO(hw,\n+\t\t    \"[%s()] queue %d -> port %d state transition (%d -> %d)\\n\",\n+\t\t    __func__, queue->id.phys_id, port->id.phys_id, curr_state,\n+\t\t    new_state);\n+\treturn 0;\n+\n+error:\n+\tDLB_HW_ERR(hw,\n+\t\t   \"[%s()] Internal error: invalid queue %d -> port %d state transition (%d -> %d)\\n\",\n+\t\t   __func__, queue->id.phys_id, port->id.phys_id, curr_state,\n+\t\t   new_state);\n+\treturn -EFAULT;\n+}\n+\n+static int dlb_verify_map_qid_slot_available(struct dlb_ldb_port *port,\n+\t\t\t\t\t     struct dlb_ldb_queue *queue,\n+\t\t\t\t\t     struct dlb_cmd_response *resp)\n+{\n+\tenum dlb_qid_map_state state;\n+\tint i;\n+\n+\t/* Unused slot available? */\n+\tif (port->num_mappings < DLB_MAX_NUM_QIDS_PER_LDB_CQ)\n+\t\treturn 0;\n+\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 = DLB_QUEUE_MAPPED;\n+\tif (dlb_port_find_slot_queue(port, state, queue, &i))\n+\t\treturn 0;\n+\n+\tstate = DLB_QUEUE_MAP_IN_PROGRESS;\n+\tif (dlb_port_find_slot_queue(port, state, queue, &i))\n+\t\treturn 0;\n+\n+\tif (dlb_port_find_slot_with_pending_map_queue(port, queue, &i))\n+\t\treturn 0;\n+\n+\t/* If the slot contains an unmap in progress, it's considered\n+\t * available.\n+\t */\n+\tstate = DLB_QUEUE_UNMAP_IN_PROGRESS;\n+\tif (dlb_port_find_slot(port, state, &i))\n+\t\treturn 0;\n+\n+\tstate = DLB_QUEUE_UNMAPPED;\n+\tif (dlb_port_find_slot(port, state, &i))\n+\t\treturn 0;\n+\n+\tresp->status = DLB_ST_NO_QID_SLOTS_AVAILABLE;\n+\treturn -EINVAL;\n+}\n+\n+static int dlb_verify_unmap_qid_args(struct dlb_hw *hw,\n+\t\t\t\t     u32 domain_id,\n+\t\t\t\t     struct dlb_unmap_qid_args *args,\n+\t\t\t\t     struct dlb_cmd_response *resp,\n+\t\t\t\t     bool vf_request,\n+\t\t\t\t     unsigned int vf_id)\n+{\n+\tenum dlb_qid_map_state state;\n+\tstruct dlb_domain *domain;\n+\tstruct dlb_ldb_port *port;\n+\tstruct dlb_ldb_queue *queue;\n+\tint slot;\n+\tint id;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tid = args->port_id;\n+\n+\tport = dlb_get_domain_used_ldb_port(id, vf_request, domain);\n+\n+\tif (!port || !port->configured) {\n+\t\tresp->status = DLB_ST_INVALID_PORT_ID;\n+\t\treturn -1;\n+\t}\n+\n+\tif (port->domain_id.phys_id != domain->id.phys_id) {\n+\t\tresp->status = DLB_ST_INVALID_PORT_ID;\n+\t\treturn -1;\n+\t}\n+\n+\tqueue = dlb_get_domain_ldb_queue(args->qid, vf_request, domain);\n+\n+\tif (!queue || !queue->configured) {\n+\t\tDLB_HW_ERR(hw, \"[%s()] Can't unmap unconfigured queue %d\\n\",\n+\t\t\t   __func__, args->qid);\n+\t\tresp->status = DLB_ST_INVALID_QID;\n+\t\treturn -1;\n+\t}\n+\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 = DLB_QUEUE_MAPPED;\n+\tif (dlb_port_find_slot_queue(port, state, queue, &slot))\n+\t\treturn 0;\n+\n+\tstate = DLB_QUEUE_MAP_IN_PROGRESS;\n+\tif (dlb_port_find_slot_queue(port, state, queue, &slot))\n+\t\treturn 0;\n+\n+\tif (dlb_port_find_slot_with_pending_map_queue(port, queue, &slot))\n+\t\treturn 0;\n+\n+\tresp->status = DLB_ST_INVALID_QID;\n+\treturn -1;\n+}\n+\n+static int\n+dlb_verify_enable_ldb_port_args(struct dlb_hw *hw,\n+\t\t\t\tu32 domain_id,\n+\t\t\t\tstruct dlb_enable_ldb_port_args *args,\n+\t\t\t\tstruct dlb_cmd_response *resp,\n+\t\t\t\tbool vf_request,\n+\t\t\t\tunsigned int vf_id)\n+{\n+\tstruct dlb_domain *domain;\n+\tstruct dlb_ldb_port *port;\n+\tint id;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tid = args->port_id;\n+\n+\tport = dlb_get_domain_used_ldb_port(id, vf_request, domain);\n+\n+\tif (!port || !port->configured) {\n+\t\tresp->status = DLB_ST_INVALID_PORT_ID;\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+dlb_verify_enable_dir_port_args(struct dlb_hw *hw,\n+\t\t\t\tu32 domain_id,\n+\t\t\t\tstruct dlb_enable_dir_port_args *args,\n+\t\t\t\tstruct dlb_cmd_response *resp,\n+\t\t\t\tbool vf_request,\n+\t\t\t\tunsigned int vf_id)\n+{\n+\tstruct dlb_domain *domain;\n+\tstruct dlb_dir_pq_pair *port;\n+\tint id;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tid = args->port_id;\n+\n+\tport = dlb_get_domain_used_dir_pq(id, vf_request, domain);\n+\n+\tif (!port || !port->port_configured) {\n+\t\tresp->status = DLB_ST_INVALID_PORT_ID;\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+dlb_verify_disable_ldb_port_args(struct dlb_hw *hw,\n+\t\t\t\t u32 domain_id,\n+\t\t\t\t struct dlb_disable_ldb_port_args *args,\n+\t\t\t\t struct dlb_cmd_response *resp,\n+\t\t\t\t bool vf_request,\n+\t\t\t\t unsigned int vf_id)\n+{\n+\tstruct dlb_domain *domain;\n+\tstruct dlb_ldb_port *port;\n+\tint id;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tid = args->port_id;\n+\n+\tport = dlb_get_domain_used_ldb_port(id, vf_request, domain);\n+\n+\tif (!port || !port->configured) {\n+\t\tresp->status = DLB_ST_INVALID_PORT_ID;\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+dlb_verify_disable_dir_port_args(struct dlb_hw *hw,\n+\t\t\t\t u32 domain_id,\n+\t\t\t\t struct dlb_disable_dir_port_args *args,\n+\t\t\t\t struct dlb_cmd_response *resp,\n+\t\t\t\t bool vf_request,\n+\t\t\t\t unsigned int vf_id)\n+{\n+\tstruct dlb_domain *domain;\n+\tstruct dlb_dir_pq_pair *port;\n+\tint id;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tid = args->port_id;\n+\n+\tport = dlb_get_domain_used_dir_pq(id, vf_request, domain);\n+\n+\tif (!port || !port->port_configured) {\n+\t\tresp->status = DLB_ST_INVALID_PORT_ID;\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+dlb_domain_attach_resources(struct dlb_hw *hw,\n+\t\t\t    struct dlb_function_resources *rsrcs,\n+\t\t\t    struct dlb_domain *domain,\n+\t\t\t    struct dlb_create_sched_domain_args *args,\n+\t\t\t    struct dlb_cmd_response *resp)\n+{\n+\tint ret;\n+\n+\tret = dlb_attach_ldb_queues(hw,\n+\t\t\t\t    rsrcs,\n+\t\t\t\t    domain,\n+\t\t\t\t    args->num_ldb_queues,\n+\t\t\t\t    resp);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_attach_ldb_ports(hw,\n+\t\t\t\t   rsrcs,\n+\t\t\t\t   domain,\n+\t\t\t\t   args->num_ldb_ports,\n+\t\t\t\t   resp);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_attach_dir_ports(hw,\n+\t\t\t\t   rsrcs,\n+\t\t\t\t   domain,\n+\t\t\t\t   args->num_dir_ports,\n+\t\t\t\t   resp);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_attach_ldb_credits(rsrcs,\n+\t\t\t\t     domain,\n+\t\t\t\t     args->num_ldb_credits,\n+\t\t\t\t     resp);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_attach_dir_credits(rsrcs,\n+\t\t\t\t     domain,\n+\t\t\t\t     args->num_dir_credits,\n+\t\t\t\t     resp);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_attach_ldb_credit_pools(hw,\n+\t\t\t\t\t  rsrcs,\n+\t\t\t\t\t  domain,\n+\t\t\t\t\t  args->num_ldb_credit_pools,\n+\t\t\t\t\t  resp);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_attach_dir_credit_pools(hw,\n+\t\t\t\t\t  rsrcs,\n+\t\t\t\t\t  domain,\n+\t\t\t\t\t  args->num_dir_credit_pools,\n+\t\t\t\t\t  resp);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_attach_domain_hist_list_entries(rsrcs,\n+\t\t\t\t\t\t  domain,\n+\t\t\t\t\t\t  args->num_hist_list_entries,\n+\t\t\t\t\t\t  resp);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_attach_atomic_inflights(rsrcs,\n+\t\t\t\t\t  domain,\n+\t\t\t\t\t  args->num_atomic_inflights,\n+\t\t\t\t\t  resp);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tdomain->configured = true;\n+\n+\tdomain->started = false;\n+\n+\trsrcs->num_avail_domains--;\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 void dlb_ldb_port_cq_enable(struct dlb_hw *hw,\n+\t\t\t\t   struct dlb_ldb_port *port)\n+{\n+\tunion dlb_lsp_cq_ldb_dsbl reg;\n+\n+\t/* Don't re-enable the port if a removal is pending. The caller should\n+\t * mark this port as enabled (if it isn't already), and when the\n+\t * removal completes the port will be enabled.\n+\t */\n+\tif (port->num_pending_removals)\n+\t\treturn;\n+\n+\treg.field.disabled = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_CQ_LDB_DSBL(port->id.phys_id), reg.val);\n+\n+\tdlb_flush_csr(hw);\n+}\n+\n+static void dlb_ldb_port_cq_disable(struct dlb_hw *hw,\n+\t\t\t\t    struct dlb_ldb_port *port)\n+{\n+\tunion dlb_lsp_cq_ldb_dsbl reg;\n+\n+\treg.field.disabled = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_CQ_LDB_DSBL(port->id.phys_id), reg.val);\n+\n+\tdlb_flush_csr(hw);\n+}\n+\n+static void dlb_dir_port_cq_enable(struct dlb_hw *hw,\n+\t\t\t\t   struct dlb_dir_pq_pair *port)\n+{\n+\tunion dlb_lsp_cq_dir_dsbl reg;\n+\n+\treg.field.disabled = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_CQ_DIR_DSBL(port->id.phys_id), reg.val);\n+\n+\tdlb_flush_csr(hw);\n+}\n+\n+static void dlb_dir_port_cq_disable(struct dlb_hw *hw,\n+\t\t\t\t    struct dlb_dir_pq_pair *port)\n+{\n+\tunion dlb_lsp_cq_dir_dsbl reg;\n+\n+\treg.field.disabled = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_CQ_DIR_DSBL(port->id.phys_id), reg.val);\n+\n+\tdlb_flush_csr(hw);\n+}\n+\n+static int dlb_ldb_port_configure_pp(struct dlb_hw *hw,\n+\t\t\t\t     struct dlb_domain *domain,\n+\t\t\t\t     struct dlb_ldb_port *port,\n+\t\t\t\t     struct dlb_create_ldb_port_args *args,\n+\t\t\t\t     bool vf_request,\n+\t\t\t\t     unsigned int vf_id)\n+{\n+\tunion dlb_sys_ldb_pp2ldbpool r0 = { {0} };\n+\tunion dlb_sys_ldb_pp2dirpool r1 = { {0} };\n+\tunion dlb_sys_ldb_pp2vf_pf r2 = { {0} };\n+\tunion dlb_sys_ldb_pp2vas r3 = { {0} };\n+\tunion dlb_sys_ldb_pp_v r4 = { {0} };\n+\tunion dlb_sys_ldb_pp2vpp r5 = { {0} };\n+\tunion dlb_chp_ldb_pp_ldb_crd_hwm r6 = { {0} };\n+\tunion dlb_chp_ldb_pp_dir_crd_hwm r7 = { {0} };\n+\tunion dlb_chp_ldb_pp_ldb_crd_lwm r8 = { {0} };\n+\tunion dlb_chp_ldb_pp_dir_crd_lwm r9 = { {0} };\n+\tunion dlb_chp_ldb_pp_ldb_min_crd_qnt r10 = { {0} };\n+\tunion dlb_chp_ldb_pp_dir_min_crd_qnt r11 = { {0} };\n+\tunion dlb_chp_ldb_pp_ldb_crd_cnt r12 = { {0} };\n+\tunion dlb_chp_ldb_pp_dir_crd_cnt r13 = { {0} };\n+\tunion dlb_chp_ldb_ldb_pp2pool r14 = { {0} };\n+\tunion dlb_chp_ldb_dir_pp2pool r15 = { {0} };\n+\tunion dlb_chp_ldb_pp_crd_req_state r16 = { {0} };\n+\tunion dlb_chp_ldb_pp_ldb_push_ptr r17 = { {0} };\n+\tunion dlb_chp_ldb_pp_dir_push_ptr r18 = { {0} };\n+\n+\tstruct dlb_credit_pool *ldb_pool = NULL;\n+\tstruct dlb_credit_pool *dir_pool = NULL;\n+\tunsigned int offs;\n+\n+\tif (port->ldb_pool_used) {\n+\t\tldb_pool = dlb_get_domain_ldb_pool(args->ldb_credit_pool_id,\n+\t\t\t\t\t\t   vf_request,\n+\t\t\t\t\t\t   domain);\n+\t\tif (!ldb_pool) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: port validation failed\\n\",\n+\t\t\t\t   __func__);\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\t}\n+\n+\tif (port->dir_pool_used) {\n+\t\tdir_pool = dlb_get_domain_dir_pool(args->dir_credit_pool_id,\n+\t\t\t\t\t\t   vf_request,\n+\t\t\t\t\t\t   domain);\n+\t\tif (!dir_pool) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: port validation failed\\n\",\n+\t\t\t\t   __func__);\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\t}\n+\n+\tr0.field.ldbpool = (port->ldb_pool_used) ? ldb_pool->id.phys_id : 0;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_PP2LDBPOOL(port->id.phys_id), r0.val);\n+\n+\tr1.field.dirpool = (port->dir_pool_used) ? dir_pool->id.phys_id : 0;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_PP2DIRPOOL(port->id.phys_id), r1.val);\n+\n+\tr2.field.vf = vf_id;\n+\tr2.field.is_pf = !vf_request;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_PP2VF_PF(port->id.phys_id), r2.val);\n+\n+\tr3.field.vas = domain->id.phys_id;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_PP2VAS(port->id.phys_id), r3.val);\n+\n+\tr5.field.vpp = port->id.virt_id;\n+\n+\toffs = (vf_id * DLB_MAX_NUM_LDB_PORTS) + port->id.phys_id;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_PP2VPP(offs), r5.val);\n+\n+\tr6.field.hwm = args->ldb_credit_high_watermark;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_LDB_PP_LDB_CRD_HWM(port->id.phys_id), r6.val);\n+\n+\tr7.field.hwm = args->dir_credit_high_watermark;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_LDB_PP_DIR_CRD_HWM(port->id.phys_id), r7.val);\n+\n+\tr8.field.lwm = args->ldb_credit_low_watermark;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_LDB_PP_LDB_CRD_LWM(port->id.phys_id), r8.val);\n+\n+\tr9.field.lwm = args->dir_credit_low_watermark;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_LDB_PP_DIR_CRD_LWM(port->id.phys_id), r9.val);\n+\n+\tr10.field.quanta = args->ldb_credit_quantum;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_PP_LDB_MIN_CRD_QNT(port->id.phys_id),\n+\t\t   r10.val);\n+\n+\tr11.field.quanta = args->dir_credit_quantum;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_PP_DIR_MIN_CRD_QNT(port->id.phys_id),\n+\t\t   r11.val);\n+\n+\tr12.field.count = args->ldb_credit_high_watermark;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_LDB_PP_LDB_CRD_CNT(port->id.phys_id), r12.val);\n+\n+\tr13.field.count = args->dir_credit_high_watermark;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_LDB_PP_DIR_CRD_CNT(port->id.phys_id), r13.val);\n+\n+\tr14.field.pool = (port->ldb_pool_used) ? ldb_pool->id.phys_id : 0;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_LDB_LDB_PP2POOL(port->id.phys_id), r14.val);\n+\n+\tr15.field.pool = (port->dir_pool_used) ? dir_pool->id.phys_id : 0;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_LDB_DIR_PP2POOL(port->id.phys_id), r15.val);\n+\n+\tr16.field.no_pp_credit_update = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_LDB_PP_CRD_REQ_STATE(port->id.phys_id), r16.val);\n+\n+\tr17.field.push_pointer = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_LDB_PP_LDB_PUSH_PTR(port->id.phys_id), r17.val);\n+\n+\tr18.field.push_pointer = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_LDB_PP_DIR_PUSH_PTR(port->id.phys_id), r18.val);\n+\n+\tif (vf_request) {\n+\t\tunion dlb_sys_vf_ldb_vpp2pp r16 = { {0} };\n+\t\tunion dlb_sys_vf_ldb_vpp_v r17 = { {0} };\n+\n+\t\tr16.field.pp = port->id.phys_id;\n+\n+\t\toffs = vf_id * DLB_MAX_NUM_LDB_PORTS + port->id.virt_id;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_VF_LDB_VPP2PP(offs), r16.val);\n+\n+\t\tr17.field.vpp_v = 1;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_VF_LDB_VPP_V(offs), r17.val);\n+\t}\n+\n+\tr4.field.pp_v = 1;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_PP_V(port->id.phys_id),\n+\t\t   r4.val);\n+\n+\treturn 0;\n+}\n+\n+static int dlb_ldb_port_configure_cq(struct dlb_hw *hw,\n+\t\t\t\t     struct dlb_ldb_port *port,\n+\t\t\t\t     u64 pop_count_dma_base,\n+\t\t\t\t     u64 cq_dma_base,\n+\t\t\t\t     struct dlb_create_ldb_port_args *args,\n+\t\t\t\t     bool vf_request,\n+\t\t\t\t     unsigned int vf_id)\n+{\n+\tint i;\n+\n+\tunion dlb_sys_ldb_cq_addr_l r0 = { {0} };\n+\tunion dlb_sys_ldb_cq_addr_u r1 = { {0} };\n+\tunion dlb_sys_ldb_cq2vf_pf r2 = { {0} };\n+\tunion dlb_chp_ldb_cq_tkn_depth_sel r3 = { {0} };\n+\tunion dlb_chp_hist_list_lim r4 = { {0} };\n+\tunion dlb_chp_hist_list_base r5 = { {0} };\n+\tunion dlb_lsp_cq_ldb_infl_lim r6 = { {0} };\n+\tunion dlb_lsp_cq2priov r7 = { {0} };\n+\tunion dlb_chp_hist_list_push_ptr r8 = { {0} };\n+\tunion dlb_chp_hist_list_pop_ptr r9 = { {0} };\n+\tunion dlb_lsp_cq_ldb_tkn_depth_sel r10 = { {0} };\n+\tunion dlb_sys_ldb_pp_addr_l r11 = { {0} };\n+\tunion dlb_sys_ldb_pp_addr_u r12 = { {0} };\n+\n+\t/* The CQ address is 64B-aligned, and the DLB only wants bits [63:6] */\n+\tr0.field.addr_l = cq_dma_base >> 6;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_CQ_ADDR_L(port->id.phys_id),\n+\t\t   r0.val);\n+\n+\tr1.field.addr_u = cq_dma_base >> 32;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_CQ_ADDR_U(port->id.phys_id),\n+\t\t   r1.val);\n+\n+\tr2.field.vf = vf_id;\n+\tr2.field.is_pf = !vf_request;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_CQ2VF_PF(port->id.phys_id),\n+\t\t   r2.val);\n+\n+\tif (args->cq_depth <= 8) {\n+\t\tr3.field.token_depth_select = 1;\n+\t} else if (args->cq_depth == 16) {\n+\t\tr3.field.token_depth_select = 2;\n+\t} else if (args->cq_depth == 32) {\n+\t\tr3.field.token_depth_select = 3;\n+\t} else if (args->cq_depth == 64) {\n+\t\tr3.field.token_depth_select = 4;\n+\t} else if (args->cq_depth == 128) {\n+\t\tr3.field.token_depth_select = 5;\n+\t} else if (args->cq_depth == 256) {\n+\t\tr3.field.token_depth_select = 6;\n+\t} else if (args->cq_depth == 512) {\n+\t\tr3.field.token_depth_select = 7;\n+\t} else if (args->cq_depth == 1024) {\n+\t\tr3.field.token_depth_select = 8;\n+\t} else {\n+\t\tDLB_HW_ERR(hw, \"[%s():%d] Internal error: invalid CQ depth\\n\",\n+\t\t\t   __func__, __LINE__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_CQ_TKN_DEPTH_SEL(port->id.phys_id),\n+\t\t   r3.val);\n+\n+\tr10.field.token_depth_select = r3.field.token_depth_select;\n+\tr10.field.ignore_depth = 0;\n+\t/* TDT algorithm: DLB must be able to write CQs with depth < 4 */\n+\tr10.field.enab_shallow_cq = 1;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_LSP_CQ_LDB_TKN_DEPTH_SEL(port->id.phys_id),\n+\t\t   r10.val);\n+\n+\t/* To support CQs with depth less than 8, program the token count\n+\t * register with a non-zero initial value. Operations such as domain\n+\t * reset must take this initial value into account when quiescing the\n+\t * CQ.\n+\t */\n+\tport->init_tkn_cnt = 0;\n+\n+\tif (args->cq_depth < 8) {\n+\t\tunion dlb_lsp_cq_ldb_tkn_cnt r12 = { {0} };\n+\n+\t\tport->init_tkn_cnt = 8 - args->cq_depth;\n+\n+\t\tr12.field.token_count = port->init_tkn_cnt;\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_LSP_CQ_LDB_TKN_CNT(port->id.phys_id),\n+\t\t\t   r12.val);\n+\t}\n+\n+\tr4.field.limit = port->hist_list_entry_limit - 1;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_HIST_LIST_LIM(port->id.phys_id), r4.val);\n+\n+\tr5.field.base = port->hist_list_entry_base;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_HIST_LIST_BASE(port->id.phys_id), r5.val);\n+\n+\tr8.field.push_ptr = r5.field.base;\n+\tr8.field.generation = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_HIST_LIST_PUSH_PTR(port->id.phys_id), r8.val);\n+\n+\tr9.field.pop_ptr = r5.field.base;\n+\tr9.field.generation = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_HIST_LIST_POP_PTR(port->id.phys_id), r9.val);\n+\n+\t/* The inflight limit sets a cap on the number of QEs for which this CQ\n+\t * can owe completions at one time.\n+\t */\n+\tr6.field.limit = args->cq_history_list_size;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_CQ_LDB_INFL_LIM(port->id.phys_id), r6.val);\n+\n+\t/* Disable the port's QID mappings */\n+\tr7.field.v = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_CQ2PRIOV(port->id.phys_id), r7.val);\n+\n+\t/* Two cache lines (128B) are dedicated for the port's pop counts */\n+\tr11.field.addr_l = pop_count_dma_base >> 7;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_PP_ADDR_L(port->id.phys_id), r11.val);\n+\n+\tr12.field.addr_u = pop_count_dma_base >> 32;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_PP_ADDR_U(port->id.phys_id), r12.val);\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_QIDS_PER_LDB_CQ; i++)\n+\t\tport->qid_map[i].state = DLB_QUEUE_UNMAPPED;\n+\n+\treturn 0;\n+}\n+\n+static void dlb_update_ldb_arb_threshold(struct dlb_hw *hw)\n+{\n+\tunion dlb_lsp_ctrl_config_0 r0 = { {0} };\n+\n+\t/* From the hardware spec:\n+\t * \"The optimal value for ldb_arb_threshold is in the region of {8 *\n+\t * #CQs}. It is expected therefore that the PF will change this value\n+\t * dynamically as the number of active ports changes.\"\n+\t */\n+\tr0.val = DLB_CSR_RD(hw, DLB_LSP_CTRL_CONFIG_0);\n+\n+\tr0.field.ldb_arb_threshold = hw->pf.num_enabled_ldb_ports * 8;\n+\tr0.field.ldb_arb_ignore_empty = 1;\n+\tr0.field.ldb_arb_mode = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_CTRL_CONFIG_0, r0.val);\n+\n+\tdlb_flush_csr(hw);\n+}\n+\n+static void dlb_ldb_pool_update_credit_count(struct dlb_hw *hw,\n+\t\t\t\t\t     u32 pool_id,\n+\t\t\t\t\t     u32 count)\n+{\n+\thw->rsrcs.ldb_credit_pools[pool_id].avail_credits -= count;\n+}\n+\n+static void dlb_dir_pool_update_credit_count(struct dlb_hw *hw,\n+\t\t\t\t\t     u32 pool_id,\n+\t\t\t\t\t     u32 count)\n+{\n+\thw->rsrcs.dir_credit_pools[pool_id].avail_credits -= count;\n+}\n+\n+static void dlb_ldb_pool_write_credit_count_reg(struct dlb_hw *hw,\n+\t\t\t\t\t\tu32 pool_id)\n+{\n+\tunion dlb_chp_ldb_pool_crd_cnt r0 = { {0} };\n+\tstruct dlb_credit_pool *pool;\n+\n+\tpool = &hw->rsrcs.ldb_credit_pools[pool_id];\n+\n+\tr0.field.count = pool->avail_credits;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_POOL_CRD_CNT(pool->id.phys_id),\n+\t\t   r0.val);\n+}\n+\n+static void dlb_dir_pool_write_credit_count_reg(struct dlb_hw *hw,\n+\t\t\t\t\t\tu32 pool_id)\n+{\n+\tunion dlb_chp_dir_pool_crd_cnt r0 = { {0} };\n+\tstruct dlb_credit_pool *pool;\n+\n+\tpool = &hw->rsrcs.dir_credit_pools[pool_id];\n+\n+\tr0.field.count = pool->avail_credits;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_POOL_CRD_CNT(pool->id.phys_id),\n+\t\t   r0.val);\n+}\n+\n+static int dlb_configure_ldb_port(struct dlb_hw *hw,\n+\t\t\t\t  struct dlb_domain *domain,\n+\t\t\t\t  struct dlb_ldb_port *port,\n+\t\t\t\t  u64 pop_count_dma_base,\n+\t\t\t\t  u64 cq_dma_base,\n+\t\t\t\t  struct dlb_create_ldb_port_args *args,\n+\t\t\t\t  bool vf_request,\n+\t\t\t\t  unsigned int vf_id)\n+{\n+\tstruct dlb_credit_pool *ldb_pool, *dir_pool;\n+\tint ret;\n+\n+\tport->hist_list_entry_base = domain->hist_list_entry_base +\n+\t\t\t\t     domain->hist_list_entry_offset;\n+\tport->hist_list_entry_limit = port->hist_list_entry_base +\n+\t\t\t\t      args->cq_history_list_size;\n+\n+\tdomain->hist_list_entry_offset += args->cq_history_list_size;\n+\tdomain->avail_hist_list_entries -= args->cq_history_list_size;\n+\n+\tport->ldb_pool_used = !dlb_list_empty(&domain->used_ldb_queues) ||\n+\t\t\t      !dlb_list_empty(&domain->avail_ldb_queues);\n+\tport->dir_pool_used = !dlb_list_empty(&domain->used_dir_pq_pairs) ||\n+\t\t\t      !dlb_list_empty(&domain->avail_dir_pq_pairs);\n+\n+\tif (port->ldb_pool_used) {\n+\t\tu32 cnt = args->ldb_credit_high_watermark;\n+\n+\t\tldb_pool = dlb_get_domain_ldb_pool(args->ldb_credit_pool_id,\n+\t\t\t\t\t\t   vf_request,\n+\t\t\t\t\t\t   domain);\n+\t\tif (!ldb_pool) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: port validation failed\\n\",\n+\t\t\t\t   __func__);\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\n+\t\tdlb_ldb_pool_update_credit_count(hw, ldb_pool->id.phys_id, cnt);\n+\t} else {\n+\t\targs->ldb_credit_high_watermark = 0;\n+\t\targs->ldb_credit_low_watermark = 0;\n+\t\targs->ldb_credit_quantum = 0;\n+\t}\n+\n+\tif (port->dir_pool_used) {\n+\t\tu32 cnt = args->dir_credit_high_watermark;\n+\n+\t\tdir_pool = dlb_get_domain_dir_pool(args->dir_credit_pool_id,\n+\t\t\t\t\t\t   vf_request,\n+\t\t\t\t\t\t   domain);\n+\t\tif (!dir_pool) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: port validation failed\\n\",\n+\t\t\t\t   __func__);\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\n+\t\tdlb_dir_pool_update_credit_count(hw, dir_pool->id.phys_id, cnt);\n+\t} else {\n+\t\targs->dir_credit_high_watermark = 0;\n+\t\targs->dir_credit_low_watermark = 0;\n+\t\targs->dir_credit_quantum = 0;\n+\t}\n+\n+\tret = dlb_ldb_port_configure_cq(hw,\n+\t\t\t\t\tport,\n+\t\t\t\t\tpop_count_dma_base,\n+\t\t\t\t\tcq_dma_base,\n+\t\t\t\t\targs,\n+\t\t\t\t\tvf_request,\n+\t\t\t\t\tvf_id);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_ldb_port_configure_pp(hw,\n+\t\t\t\t\tdomain,\n+\t\t\t\t\tport,\n+\t\t\t\t\targs,\n+\t\t\t\t\tvf_request,\n+\t\t\t\t\tvf_id);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tdlb_ldb_port_cq_enable(hw, port);\n+\n+\tport->num_mappings = 0;\n+\n+\tport->enabled = true;\n+\n+\thw->pf.num_enabled_ldb_ports++;\n+\n+\tdlb_update_ldb_arb_threshold(hw);\n+\n+\tport->configured = true;\n+\n+\treturn 0;\n+}\n+\n+static int dlb_dir_port_configure_pp(struct dlb_hw *hw,\n+\t\t\t\t     struct dlb_domain *domain,\n+\t\t\t\t     struct dlb_dir_pq_pair *port,\n+\t\t\t\t     struct dlb_create_dir_port_args *args,\n+\t\t\t\t     bool vf_request,\n+\t\t\t\t     unsigned int vf_id)\n+{\n+\tunion dlb_sys_dir_pp2ldbpool r0 = { {0} };\n+\tunion dlb_sys_dir_pp2dirpool r1 = { {0} };\n+\tunion dlb_sys_dir_pp2vf_pf r2 = { {0} };\n+\tunion dlb_sys_dir_pp2vas r3 = { {0} };\n+\tunion dlb_sys_dir_pp_v r4 = { {0} };\n+\tunion dlb_sys_dir_pp2vpp r5 = { {0} };\n+\tunion dlb_chp_dir_pp_ldb_crd_hwm r6 = { {0} };\n+\tunion dlb_chp_dir_pp_dir_crd_hwm r7 = { {0} };\n+\tunion dlb_chp_dir_pp_ldb_crd_lwm r8 = { {0} };\n+\tunion dlb_chp_dir_pp_dir_crd_lwm r9 = { {0} };\n+\tunion dlb_chp_dir_pp_ldb_min_crd_qnt r10 = { {0} };\n+\tunion dlb_chp_dir_pp_dir_min_crd_qnt r11 = { {0} };\n+\tunion dlb_chp_dir_pp_ldb_crd_cnt r12 = { {0} };\n+\tunion dlb_chp_dir_pp_dir_crd_cnt r13 = { {0} };\n+\tunion dlb_chp_dir_ldb_pp2pool r14 = { {0} };\n+\tunion dlb_chp_dir_dir_pp2pool r15 = { {0} };\n+\tunion dlb_chp_dir_pp_crd_req_state r16 = { {0} };\n+\tunion dlb_chp_dir_pp_ldb_push_ptr r17 = { {0} };\n+\tunion dlb_chp_dir_pp_dir_push_ptr r18 = { {0} };\n+\n+\tstruct dlb_credit_pool *ldb_pool = NULL;\n+\tstruct dlb_credit_pool *dir_pool = NULL;\n+\n+\tif (port->ldb_pool_used) {\n+\t\tldb_pool = dlb_get_domain_ldb_pool(args->ldb_credit_pool_id,\n+\t\t\t\t\t\t   vf_request,\n+\t\t\t\t\t\t   domain);\n+\t\tif (!ldb_pool) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: port validation failed\\n\",\n+\t\t\t\t   __func__);\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\t}\n+\n+\tif (port->dir_pool_used) {\n+\t\tdir_pool = dlb_get_domain_dir_pool(args->dir_credit_pool_id,\n+\t\t\t\t\t\t   vf_request,\n+\t\t\t\t\t\t   domain);\n+\t\tif (!dir_pool) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: port validation failed\\n\",\n+\t\t\t\t   __func__);\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\t}\n+\n+\tr0.field.ldbpool = (port->ldb_pool_used) ? ldb_pool->id.phys_id : 0;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_PP2LDBPOOL(port->id.phys_id),\n+\t\t   r0.val);\n+\n+\tr1.field.dirpool = (port->dir_pool_used) ? dir_pool->id.phys_id : 0;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_PP2DIRPOOL(port->id.phys_id),\n+\t\t   r1.val);\n+\n+\tr2.field.vf = vf_id;\n+\tr2.field.is_pf = !vf_request;\n+\tr2.field.is_hw_dsi = 0;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_PP2VF_PF(port->id.phys_id),\n+\t\t   r2.val);\n+\n+\tr3.field.vas = domain->id.phys_id;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_PP2VAS(port->id.phys_id),\n+\t\t   r3.val);\n+\n+\tr5.field.vpp = port->id.virt_id;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_PP2VPP((vf_id * DLB_MAX_NUM_DIR_PORTS) +\n+\t\t\t\t      port->id.phys_id),\n+\t\t   r5.val);\n+\n+\tr6.field.hwm = args->ldb_credit_high_watermark;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_LDB_CRD_HWM(port->id.phys_id),\n+\t\t   r6.val);\n+\n+\tr7.field.hwm = args->dir_credit_high_watermark;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_DIR_CRD_HWM(port->id.phys_id),\n+\t\t   r7.val);\n+\n+\tr8.field.lwm = args->ldb_credit_low_watermark;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_LDB_CRD_LWM(port->id.phys_id),\n+\t\t   r8.val);\n+\n+\tr9.field.lwm = args->dir_credit_low_watermark;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_DIR_CRD_LWM(port->id.phys_id),\n+\t\t   r9.val);\n+\n+\tr10.field.quanta = args->ldb_credit_quantum;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_LDB_MIN_CRD_QNT(port->id.phys_id),\n+\t\t   r10.val);\n+\n+\tr11.field.quanta = args->dir_credit_quantum;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_DIR_MIN_CRD_QNT(port->id.phys_id),\n+\t\t   r11.val);\n+\n+\tr12.field.count = args->ldb_credit_high_watermark;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_LDB_CRD_CNT(port->id.phys_id),\n+\t\t   r12.val);\n+\n+\tr13.field.count = args->dir_credit_high_watermark;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_DIR_CRD_CNT(port->id.phys_id),\n+\t\t   r13.val);\n+\n+\tr14.field.pool = (port->ldb_pool_used) ? ldb_pool->id.phys_id : 0;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_LDB_PP2POOL(port->id.phys_id),\n+\t\t   r14.val);\n+\n+\tr15.field.pool = (port->dir_pool_used) ? dir_pool->id.phys_id : 0;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_DIR_PP2POOL(port->id.phys_id),\n+\t\t   r15.val);\n+\n+\tr16.field.no_pp_credit_update = 0;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_CRD_REQ_STATE(port->id.phys_id),\n+\t\t   r16.val);\n+\n+\tr17.field.push_pointer = 0;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_LDB_PUSH_PTR(port->id.phys_id),\n+\t\t   r17.val);\n+\n+\tr18.field.push_pointer = 0;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_DIR_PUSH_PTR(port->id.phys_id),\n+\t\t   r18.val);\n+\n+\tif (vf_request) {\n+\t\tunion dlb_sys_vf_dir_vpp2pp r16 = { {0} };\n+\t\tunion dlb_sys_vf_dir_vpp_v r17 = { {0} };\n+\t\tunsigned int offs;\n+\n+\t\tr16.field.pp = port->id.phys_id;\n+\n+\t\toffs = vf_id * DLB_MAX_NUM_DIR_PORTS + port->id.virt_id;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_VF_DIR_VPP2PP(offs), r16.val);\n+\n+\t\tr17.field.vpp_v = 1;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_VF_DIR_VPP_V(offs), r17.val);\n+\t}\n+\n+\tr4.field.pp_v = 1;\n+\tr4.field.mb_dm = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_DIR_PP_V(port->id.phys_id), r4.val);\n+\n+\treturn 0;\n+}\n+\n+static int dlb_dir_port_configure_cq(struct dlb_hw *hw,\n+\t\t\t\t     struct dlb_dir_pq_pair *port,\n+\t\t\t\t     u64 pop_count_dma_base,\n+\t\t\t\t     u64 cq_dma_base,\n+\t\t\t\t     struct dlb_create_dir_port_args *args,\n+\t\t\t\t     bool vf_request,\n+\t\t\t\t     unsigned int vf_id)\n+{\n+\tunion dlb_sys_dir_cq_addr_l r0 = { {0} };\n+\tunion dlb_sys_dir_cq_addr_u r1 = { {0} };\n+\tunion dlb_sys_dir_cq2vf_pf r2 = { {0} };\n+\tunion dlb_chp_dir_cq_tkn_depth_sel r3 = { {0} };\n+\tunion dlb_lsp_cq_dir_tkn_depth_sel_dsi r4 = { {0} };\n+\tunion dlb_sys_dir_pp_addr_l r5 = { {0} };\n+\tunion dlb_sys_dir_pp_addr_u r6 = { {0} };\n+\n+\t/* The CQ address is 64B-aligned, and the DLB only wants bits [63:6] */\n+\tr0.field.addr_l = cq_dma_base >> 6;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_DIR_CQ_ADDR_L(port->id.phys_id), r0.val);\n+\n+\tr1.field.addr_u = cq_dma_base >> 32;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_DIR_CQ_ADDR_U(port->id.phys_id), r1.val);\n+\n+\tr2.field.vf = vf_id;\n+\tr2.field.is_pf = !vf_request;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_DIR_CQ2VF_PF(port->id.phys_id), r2.val);\n+\n+\tif (args->cq_depth == 8) {\n+\t\tr3.field.token_depth_select = 1;\n+\t} else if (args->cq_depth == 16) {\n+\t\tr3.field.token_depth_select = 2;\n+\t} else if (args->cq_depth == 32) {\n+\t\tr3.field.token_depth_select = 3;\n+\t} else if (args->cq_depth == 64) {\n+\t\tr3.field.token_depth_select = 4;\n+\t} else if (args->cq_depth == 128) {\n+\t\tr3.field.token_depth_select = 5;\n+\t} else if (args->cq_depth == 256) {\n+\t\tr3.field.token_depth_select = 6;\n+\t} else if (args->cq_depth == 512) {\n+\t\tr3.field.token_depth_select = 7;\n+\t} else if (args->cq_depth == 1024) {\n+\t\tr3.field.token_depth_select = 8;\n+\t} else {\n+\t\tDLB_HW_ERR(hw, \"[%s():%d] Internal error: invalid CQ depth\\n\",\n+\t\t\t   __func__, __LINE__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_CQ_TKN_DEPTH_SEL(port->id.phys_id),\n+\t\t   r3.val);\n+\n+\tr4.field.token_depth_select = r3.field.token_depth_select;\n+\tr4.field.disable_wb_opt = 0;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_LSP_CQ_DIR_TKN_DEPTH_SEL_DSI(port->id.phys_id),\n+\t\t   r4.val);\n+\n+\t/* Two cache lines (128B) are dedicated for the port's pop counts */\n+\tr5.field.addr_l = pop_count_dma_base >> 7;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_DIR_PP_ADDR_L(port->id.phys_id), r5.val);\n+\n+\tr6.field.addr_u = pop_count_dma_base >> 32;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_DIR_PP_ADDR_U(port->id.phys_id), r6.val);\n+\n+\treturn 0;\n+}\n+\n+static int dlb_configure_dir_port(struct dlb_hw *hw,\n+\t\t\t\t  struct dlb_domain *domain,\n+\t\t\t\t  struct dlb_dir_pq_pair *port,\n+\t\t\t\t  u64 pop_count_dma_base,\n+\t\t\t\t  u64 cq_dma_base,\n+\t\t\t\t  struct dlb_create_dir_port_args *args,\n+\t\t\t\t  bool vf_request,\n+\t\t\t\t  unsigned int vf_id)\n+{\n+\tstruct dlb_credit_pool *ldb_pool, *dir_pool;\n+\tint ret;\n+\n+\tport->ldb_pool_used = !dlb_list_empty(&domain->used_ldb_queues) ||\n+\t\t\t      !dlb_list_empty(&domain->avail_ldb_queues);\n+\n+\t/* Each directed port has a directed queue, hence this port requires\n+\t * directed credits.\n+\t */\n+\tport->dir_pool_used = true;\n+\n+\tif (port->ldb_pool_used) {\n+\t\tu32 cnt = args->ldb_credit_high_watermark;\n+\n+\t\tldb_pool = dlb_get_domain_ldb_pool(args->ldb_credit_pool_id,\n+\t\t\t\t\t\t   vf_request,\n+\t\t\t\t\t\t   domain);\n+\t\tif (!ldb_pool) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: port validation failed\\n\",\n+\t\t\t\t   __func__);\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\n+\t\tdlb_ldb_pool_update_credit_count(hw, ldb_pool->id.phys_id, cnt);\n+\t} else {\n+\t\targs->ldb_credit_high_watermark = 0;\n+\t\targs->ldb_credit_low_watermark = 0;\n+\t\targs->ldb_credit_quantum = 0;\n+\t}\n+\n+\tdir_pool = dlb_get_domain_dir_pool(args->dir_credit_pool_id,\n+\t\t\t\t\t   vf_request,\n+\t\t\t\t\t   domain);\n+\tif (!dir_pool) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: port validation failed\\n\",\n+\t\t\t   __func__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tdlb_dir_pool_update_credit_count(hw,\n+\t\t\t\t\t dir_pool->id.phys_id,\n+\t\t\t\t\t args->dir_credit_high_watermark);\n+\n+\tret = dlb_dir_port_configure_cq(hw,\n+\t\t\t\t\tport,\n+\t\t\t\t\tpop_count_dma_base,\n+\t\t\t\t\tcq_dma_base,\n+\t\t\t\t\targs,\n+\t\t\t\t\tvf_request,\n+\t\t\t\t\tvf_id);\n+\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_dir_port_configure_pp(hw,\n+\t\t\t\t\tdomain,\n+\t\t\t\t\tport,\n+\t\t\t\t\targs,\n+\t\t\t\t\tvf_request,\n+\t\t\t\t\tvf_id);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tdlb_dir_port_cq_enable(hw, port);\n+\n+\tport->enabled = true;\n+\n+\tport->port_configured = true;\n+\n+\treturn 0;\n+}\n+\n+static int dlb_ldb_port_map_qid_static(struct dlb_hw *hw,\n+\t\t\t\t       struct dlb_ldb_port *p,\n+\t\t\t\t       struct dlb_ldb_queue *q,\n+\t\t\t\t       u8 priority)\n+{\n+\tunion dlb_lsp_cq2priov r0;\n+\tunion dlb_lsp_cq2qid r1;\n+\tunion dlb_atm_pipe_qid_ldb_qid2cqidx r2;\n+\tunion dlb_lsp_qid_ldb_qid2cqidx r3;\n+\tunion dlb_lsp_qid_ldb_qid2cqidx2 r4;\n+\tenum dlb_qid_map_state state;\n+\tint i;\n+\n+\t/* Look for a pending or already mapped slot, else an unused slot */\n+\tif (!dlb_port_find_slot_queue(p, DLB_QUEUE_MAP_IN_PROGRESS, q, &i) &&\n+\t    !dlb_port_find_slot_queue(p, DLB_QUEUE_MAPPED, q, &i) &&\n+\t    !dlb_port_find_slot(p, DLB_QUEUE_UNMAPPED, &i)) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s():%d] Internal error: CQ has no available QID mapping slots\\n\",\n+\t\t\t   __func__, __LINE__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tif (i >= DLB_MAX_NUM_QIDS_PER_LDB_CQ) {\n+\t\tDLB_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/* Read-modify-write the priority and valid bit register */\n+\tr0.val = DLB_CSR_RD(hw, DLB_LSP_CQ2PRIOV(p->id.phys_id));\n+\n+\tr0.field.v |= 1 << i;\n+\tr0.field.prio |= (priority & 0x7) << i * 3;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_CQ2PRIOV(p->id.phys_id), r0.val);\n+\n+\t/* Read-modify-write the QID map register */\n+\tr1.val = DLB_CSR_RD(hw, DLB_LSP_CQ2QID(p->id.phys_id, i / 4));\n+\n+\tif (i == 0 || i == 4)\n+\t\tr1.field.qid_p0 = q->id.phys_id;\n+\tif (i == 1 || i == 5)\n+\t\tr1.field.qid_p1 = q->id.phys_id;\n+\tif (i == 2 || i == 6)\n+\t\tr1.field.qid_p2 = q->id.phys_id;\n+\tif (i == 3 || i == 7)\n+\t\tr1.field.qid_p3 = q->id.phys_id;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_CQ2QID(p->id.phys_id, i / 4), r1.val);\n+\n+\tr2.val = DLB_CSR_RD(hw,\n+\t\t\t    DLB_ATM_PIPE_QID_LDB_QID2CQIDX(q->id.phys_id,\n+\t\t\t\t\t\t\t   p->id.phys_id / 4));\n+\n+\tr3.val = DLB_CSR_RD(hw,\n+\t\t\t    DLB_LSP_QID_LDB_QID2CQIDX(q->id.phys_id,\n+\t\t\t\t\t\t      p->id.phys_id / 4));\n+\n+\tr4.val = DLB_CSR_RD(hw,\n+\t\t\t    DLB_LSP_QID_LDB_QID2CQIDX2(q->id.phys_id,\n+\t\t\t\t\t\t       p->id.phys_id / 4));\n+\n+\tswitch (p->id.phys_id % 4) {\n+\tcase 0:\n+\t\tr2.field.cq_p0 |= 1 << i;\n+\t\tr3.field.cq_p0 |= 1 << i;\n+\t\tr4.field.cq_p0 |= 1 << i;\n+\t\tbreak;\n+\n+\tcase 1:\n+\t\tr2.field.cq_p1 |= 1 << i;\n+\t\tr3.field.cq_p1 |= 1 << i;\n+\t\tr4.field.cq_p1 |= 1 << i;\n+\t\tbreak;\n+\n+\tcase 2:\n+\t\tr2.field.cq_p2 |= 1 << i;\n+\t\tr3.field.cq_p2 |= 1 << i;\n+\t\tr4.field.cq_p2 |= 1 << i;\n+\t\tbreak;\n+\n+\tcase 3:\n+\t\tr2.field.cq_p3 |= 1 << i;\n+\t\tr3.field.cq_p3 |= 1 << i;\n+\t\tr4.field.cq_p3 |= 1 << i;\n+\t\tbreak;\n+\t}\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_ATM_PIPE_QID_LDB_QID2CQIDX(q->id.phys_id,\n+\t\t\t\t\t\t  p->id.phys_id / 4),\n+\t\t   r2.val);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_LSP_QID_LDB_QID2CQIDX(q->id.phys_id,\n+\t\t\t\t\t     p->id.phys_id / 4),\n+\t\t   r3.val);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_LSP_QID_LDB_QID2CQIDX2(q->id.phys_id,\n+\t\t\t\t\t      p->id.phys_id / 4),\n+\t\t   r4.val);\n+\n+\tdlb_flush_csr(hw);\n+\n+\tp->qid_map[i].qid = q->id.phys_id;\n+\tp->qid_map[i].priority = priority;\n+\n+\tstate = DLB_QUEUE_MAPPED;\n+\n+\treturn dlb_port_slot_state_transition(hw, p, q, i, state);\n+}\n+\n+static void dlb_ldb_port_change_qid_priority(struct dlb_hw *hw,\n+\t\t\t\t\t     struct dlb_ldb_port *port,\n+\t\t\t\t\t     int slot,\n+\t\t\t\t\t     struct dlb_map_qid_args *args)\n+{\n+\tunion dlb_lsp_cq2priov r0;\n+\n+\t/* Read-modify-write the priority and valid bit register */\n+\tr0.val = DLB_CSR_RD(hw, DLB_LSP_CQ2PRIOV(port->id.phys_id));\n+\n+\tr0.field.v |= 1 << slot;\n+\tr0.field.prio |= (args->priority & 0x7) << slot * 3;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_CQ2PRIOV(port->id.phys_id), r0.val);\n+\n+\tdlb_flush_csr(hw);\n+\n+\tport->qid_map[slot].priority = args->priority;\n+}\n+\n+static int dlb_ldb_port_set_has_work_bits(struct dlb_hw *hw,\n+\t\t\t\t\t  struct dlb_ldb_port *port,\n+\t\t\t\t\t  struct dlb_ldb_queue *queue,\n+\t\t\t\t\t  int slot)\n+{\n+\tunion dlb_lsp_qid_aqed_active_cnt r0;\n+\tunion dlb_lsp_qid_ldb_enqueue_cnt r1;\n+\tunion dlb_lsp_ldb_sched_ctrl r2 = { {0} };\n+\n+\t/* Set the atomic scheduling haswork bit */\n+\tr0.val = DLB_CSR_RD(hw, DLB_LSP_QID_AQED_ACTIVE_CNT(queue->id.phys_id));\n+\n+\tr2.field.cq = port->id.phys_id;\n+\tr2.field.qidix = slot;\n+\tr2.field.value = 1;\n+\tr2.field.rlist_haswork_v = r0.field.count > 0;\n+\n+\t/* Set the non-atomic scheduling haswork bit */\n+\tDLB_CSR_WR(hw, DLB_LSP_LDB_SCHED_CTRL, r2.val);\n+\n+\tr1.val = DLB_CSR_RD(hw, DLB_LSP_QID_LDB_ENQUEUE_CNT(queue->id.phys_id));\n+\n+\tmemset(&r2, 0, sizeof(r2));\n+\n+\tr2.field.cq = port->id.phys_id;\n+\tr2.field.qidix = slot;\n+\tr2.field.value = 1;\n+\tr2.field.nalb_haswork_v = (r1.field.count > 0);\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_LDB_SCHED_CTRL, r2.val);\n+\n+\tdlb_flush_csr(hw);\n+\n+\treturn 0;\n+}\n+\n+static void dlb_ldb_port_clear_has_work_bits(struct dlb_hw *hw,\n+\t\t\t\t\t     struct dlb_ldb_port *port,\n+\t\t\t\t\t     u8 slot)\n+{\n+\tunion dlb_lsp_ldb_sched_ctrl r2 = { {0} };\n+\n+\tr2.field.cq = port->id.phys_id;\n+\tr2.field.qidix = slot;\n+\tr2.field.value = 0;\n+\tr2.field.rlist_haswork_v = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_LDB_SCHED_CTRL, r2.val);\n+\n+\tmemset(&r2, 0, sizeof(r2));\n+\n+\tr2.field.cq = port->id.phys_id;\n+\tr2.field.qidix = slot;\n+\tr2.field.value = 0;\n+\tr2.field.nalb_haswork_v = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_LDB_SCHED_CTRL, r2.val);\n+\n+\tdlb_flush_csr(hw);\n+}\n+\n+static void dlb_ldb_port_clear_queue_if_status(struct dlb_hw *hw,\n+\t\t\t\t\t       struct dlb_ldb_port *port,\n+\t\t\t\t\t       int slot)\n+{\n+\tunion dlb_lsp_ldb_sched_ctrl r0 = { {0} };\n+\n+\tr0.field.cq = port->id.phys_id;\n+\tr0.field.qidix = slot;\n+\tr0.field.value = 0;\n+\tr0.field.inflight_ok_v = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_LDB_SCHED_CTRL, r0.val);\n+\n+\tdlb_flush_csr(hw);\n+}\n+\n+static void dlb_ldb_port_set_queue_if_status(struct dlb_hw *hw,\n+\t\t\t\t\t     struct dlb_ldb_port *port,\n+\t\t\t\t\t     int slot)\n+{\n+\tunion dlb_lsp_ldb_sched_ctrl r0 = { {0} };\n+\n+\tr0.field.cq = port->id.phys_id;\n+\tr0.field.qidix = slot;\n+\tr0.field.value = 1;\n+\tr0.field.inflight_ok_v = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_LDB_SCHED_CTRL, r0.val);\n+\n+\tdlb_flush_csr(hw);\n+}\n+\n+static void dlb_ldb_queue_set_inflight_limit(struct dlb_hw *hw,\n+\t\t\t\t\t     struct dlb_ldb_queue *queue)\n+{\n+\tunion dlb_lsp_qid_ldb_infl_lim r0 = { {0} };\n+\n+\tr0.field.limit = queue->num_qid_inflights;\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_QID_LDB_INFL_LIM(queue->id.phys_id), r0.val);\n+}\n+\n+static void dlb_ldb_queue_clear_inflight_limit(struct dlb_hw *hw,\n+\t\t\t\t\t       struct dlb_ldb_queue *queue)\n+{\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_LSP_QID_LDB_INFL_LIM(queue->id.phys_id),\n+\t\t   DLB_LSP_QID_LDB_INFL_LIM_RST);\n+}\n+\n+/* dlb_ldb_queue_{enable, disable}_mapped_cqs() don't operate exactly as their\n+ * function names imply, and should only be called by the dynamic CQ mapping\n+ * code.\n+ */\n+static void dlb_ldb_queue_disable_mapped_cqs(struct dlb_hw *hw,\n+\t\t\t\t\t     struct dlb_domain *domain,\n+\t\t\t\t\t     struct dlb_ldb_queue *queue)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_port *port;\n+\tint slot;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter) {\n+\t\tenum dlb_qid_map_state state = DLB_QUEUE_MAPPED;\n+\n+\t\tif (!dlb_port_find_slot_queue(port, state, queue, &slot))\n+\t\t\tcontinue;\n+\n+\t\tif (port->enabled)\n+\t\t\tdlb_ldb_port_cq_disable(hw, port);\n+\t}\n+}\n+\n+static void dlb_ldb_queue_enable_mapped_cqs(struct dlb_hw *hw,\n+\t\t\t\t\t    struct dlb_domain *domain,\n+\t\t\t\t\t    struct dlb_ldb_queue *queue)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_port *port;\n+\tint slot;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter) {\n+\t\tenum dlb_qid_map_state state = DLB_QUEUE_MAPPED;\n+\n+\t\tif (!dlb_port_find_slot_queue(port, state, queue, &slot))\n+\t\t\tcontinue;\n+\n+\t\tif (port->enabled)\n+\t\t\tdlb_ldb_port_cq_enable(hw, port);\n+\t}\n+}\n+\n+static int dlb_ldb_port_finish_map_qid_dynamic(struct dlb_hw *hw,\n+\t\t\t\t\t       struct dlb_domain *domain,\n+\t\t\t\t\t       struct dlb_ldb_port *port,\n+\t\t\t\t\t       struct dlb_ldb_queue *queue)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tunion dlb_lsp_qid_ldb_infl_cnt r0;\n+\tenum dlb_qid_map_state state;\n+\tint slot, ret;\n+\tu8 prio;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_LSP_QID_LDB_INFL_CNT(queue->id.phys_id));\n+\n+\tif (r0.field.count) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: non-zero QID inflight count\\n\",\n+\t\t\t   __func__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\t/* For each port with a pending mapping to this queue, perform the\n+\t * static mapping and set the corresponding has_work bits.\n+\t */\n+\tstate = DLB_QUEUE_MAP_IN_PROGRESS;\n+\tif (!dlb_port_find_slot_queue(port, state, queue, &slot))\n+\t\treturn -EINVAL;\n+\n+\tif (slot >= DLB_MAX_NUM_QIDS_PER_LDB_CQ) {\n+\t\tDLB_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+\tprio = port->qid_map[slot].priority;\n+\n+\t/* Update the CQ2QID, CQ2PRIOV, and QID2CQIDX registers, and\n+\t * the port's qid_map state.\n+\t */\n+\tret = dlb_ldb_port_map_qid_static(hw, port, queue, prio);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = dlb_ldb_port_set_has_work_bits(hw, port, queue, slot);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* Ensure IF_status(cq,qid) is 0 before enabling the port to\n+\t * prevent spurious schedules to cause the queue's inflight\n+\t * count to increase.\n+\t */\n+\tdlb_ldb_port_clear_queue_if_status(hw, port, slot);\n+\n+\t/* Reset the queue's inflight status */\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter) {\n+\t\tstate = DLB_QUEUE_MAPPED;\n+\t\tif (!dlb_port_find_slot_queue(port, state, queue, &slot))\n+\t\t\tcontinue;\n+\n+\t\tdlb_ldb_port_set_queue_if_status(hw, port, slot);\n+\t}\n+\n+\tdlb_ldb_queue_set_inflight_limit(hw, queue);\n+\n+\t/* Re-enable CQs mapped to this queue */\n+\tdlb_ldb_queue_enable_mapped_cqs(hw, domain, queue);\n+\n+\t/* If this queue has other mappings pending, clear its inflight limit */\n+\tif (queue->num_pending_additions > 0)\n+\t\tdlb_ldb_queue_clear_inflight_limit(hw, queue);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * dlb_ldb_port_map_qid_dynamic() - perform a \"dynamic\" QID->CQ mapping\n+ * @hw: dlb_hw handle for a particular device.\n+ * @port: load-balanced port\n+ * @queue: load-balanced queue\n+ * @priority: queue servicing priority\n+ *\n+ * Returns 0 if the queue was mapped, 1 if the mapping is scheduled to occur\n+ * at a later point, and <0 if an error occurred.\n+ */\n+static int dlb_ldb_port_map_qid_dynamic(struct dlb_hw *hw,\n+\t\t\t\t\tstruct dlb_ldb_port *port,\n+\t\t\t\t\tstruct dlb_ldb_queue *queue,\n+\t\t\t\t\tu8 priority)\n+{\n+\tunion dlb_lsp_qid_ldb_infl_cnt r0 = { {0} };\n+\tenum dlb_qid_map_state state;\n+\tstruct dlb_domain *domain;\n+\tint slot, ret;\n+\n+\tdomain = dlb_get_domain_from_id(hw, port->domain_id.phys_id, false, 0);\n+\tif (!domain) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: unable to find domain %d\\n\",\n+\t\t\t   __func__, port->domain_id.phys_id);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\t/* Set the QID inflight limit to 0 to prevent further scheduling of the\n+\t * queue.\n+\t */\n+\tDLB_CSR_WR(hw, DLB_LSP_QID_LDB_INFL_LIM(queue->id.phys_id), 0);\n+\n+\tif (!dlb_port_find_slot(port, DLB_QUEUE_UNMAPPED, &slot)) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"Internal error: No available unmapped slots\\n\");\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tif (slot >= DLB_MAX_NUM_QIDS_PER_LDB_CQ) {\n+\t\tDLB_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+\tport->qid_map[slot].qid = queue->id.phys_id;\n+\tport->qid_map[slot].priority = priority;\n+\n+\tstate = DLB_QUEUE_MAP_IN_PROGRESS;\n+\tret = dlb_port_slot_state_transition(hw, port, queue, slot, state);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_LSP_QID_LDB_INFL_CNT(queue->id.phys_id));\n+\n+\tif (r0.field.count) {\n+\t\t/* The queue is owed completions so it's not safe to map it\n+\t\t * yet. Schedule a kernel thread to complete the mapping later,\n+\t\t * once software has completed all the queue's inflight events.\n+\t\t */\n+\t\tif (!os_worker_active(hw))\n+\t\t\tos_schedule_work(hw);\n+\n+\t\treturn 1;\n+\t}\n+\n+\t/* Disable the affected CQ, and the CQs already mapped to the QID,\n+\t * before reading the QID's inflight count a second time. There is an\n+\t * unlikely race in which the QID may schedule one more QE after we\n+\t * read an inflight count of 0, and disabling the CQs guarantees that\n+\t * the race will not occur after a re-read of the inflight count\n+\t * register.\n+\t */\n+\tif (port->enabled)\n+\t\tdlb_ldb_port_cq_disable(hw, port);\n+\n+\tdlb_ldb_queue_disable_mapped_cqs(hw, domain, queue);\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_LSP_QID_LDB_INFL_CNT(queue->id.phys_id));\n+\n+\tif (r0.field.count) {\n+\t\tif (port->enabled)\n+\t\t\tdlb_ldb_port_cq_enable(hw, port);\n+\n+\t\tdlb_ldb_queue_enable_mapped_cqs(hw, domain, queue);\n+\n+\t\t/* The queue is owed completions so it's not safe to map it\n+\t\t * yet. Schedule a kernel thread to complete the mapping later,\n+\t\t * once software has completed all the queue's inflight events.\n+\t\t */\n+\t\tif (!os_worker_active(hw))\n+\t\t\tos_schedule_work(hw);\n+\n+\t\treturn 1;\n+\t}\n+\n+\treturn dlb_ldb_port_finish_map_qid_dynamic(hw, domain, port, queue);\n+}\n+\n+static int dlb_ldb_port_map_qid(struct dlb_hw *hw,\n+\t\t\t\tstruct dlb_domain *domain,\n+\t\t\t\tstruct dlb_ldb_port *port,\n+\t\t\t\tstruct dlb_ldb_queue *queue,\n+\t\t\t\tu8 prio)\n+{\n+\tif (domain->started)\n+\t\treturn dlb_ldb_port_map_qid_dynamic(hw, port, queue, prio);\n+\telse\n+\t\treturn dlb_ldb_port_map_qid_static(hw, port, queue, prio);\n+}\n+\n+static int dlb_ldb_port_unmap_qid(struct dlb_hw *hw,\n+\t\t\t\t  struct dlb_ldb_port *port,\n+\t\t\t\t  struct dlb_ldb_queue *queue)\n+{\n+\tenum dlb_qid_map_state mapped, in_progress, pending_map, unmapped;\n+\tunion dlb_lsp_cq2priov r0;\n+\tunion dlb_atm_pipe_qid_ldb_qid2cqidx r1;\n+\tunion dlb_lsp_qid_ldb_qid2cqidx r2;\n+\tunion dlb_lsp_qid_ldb_qid2cqidx2 r3;\n+\tu32 queue_id;\n+\tu32 port_id;\n+\tint i;\n+\n+\t/* Find the queue's slot */\n+\tmapped = DLB_QUEUE_MAPPED;\n+\tin_progress = DLB_QUEUE_UNMAP_IN_PROGRESS;\n+\tpending_map = DLB_QUEUE_UNMAP_IN_PROGRESS_PENDING_MAP;\n+\n+\tif (!dlb_port_find_slot_queue(port, mapped, queue, &i) &&\n+\t    !dlb_port_find_slot_queue(port, in_progress, queue, &i) &&\n+\t    !dlb_port_find_slot_queue(port, pending_map, queue, &i)) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s():%d] Internal error: QID %d isn't mapped\\n\",\n+\t\t\t   __func__, __LINE__, queue->id.phys_id);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tif (i >= DLB_MAX_NUM_QIDS_PER_LDB_CQ) {\n+\t\tDLB_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+\tport_id = port->id.phys_id;\n+\tqueue_id = queue->id.phys_id;\n+\n+\t/* Read-modify-write the priority and valid bit register */\n+\tr0.val = DLB_CSR_RD(hw, DLB_LSP_CQ2PRIOV(port_id));\n+\n+\tr0.field.v &= ~(1 << i);\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_CQ2PRIOV(port_id), r0.val);\n+\n+\tr1.val = DLB_CSR_RD(hw,\n+\t\t\t    DLB_ATM_PIPE_QID_LDB_QID2CQIDX(queue_id,\n+\t\t\t\t\t\t\t   port_id / 4));\n+\n+\tr2.val = DLB_CSR_RD(hw,\n+\t\t\t    DLB_LSP_QID_LDB_QID2CQIDX(queue_id,\n+\t\t\t\t\t\t      port_id / 4));\n+\n+\tr3.val = DLB_CSR_RD(hw,\n+\t\t\t    DLB_LSP_QID_LDB_QID2CQIDX2(queue_id,\n+\t\t\t\t\t\t       port_id / 4));\n+\n+\tswitch (port_id % 4) {\n+\tcase 0:\n+\t\tr1.field.cq_p0 &= ~(1 << i);\n+\t\tr2.field.cq_p0 &= ~(1 << i);\n+\t\tr3.field.cq_p0 &= ~(1 << i);\n+\t\tbreak;\n+\n+\tcase 1:\n+\t\tr1.field.cq_p1 &= ~(1 << i);\n+\t\tr2.field.cq_p1 &= ~(1 << i);\n+\t\tr3.field.cq_p1 &= ~(1 << i);\n+\t\tbreak;\n+\n+\tcase 2:\n+\t\tr1.field.cq_p2 &= ~(1 << i);\n+\t\tr2.field.cq_p2 &= ~(1 << i);\n+\t\tr3.field.cq_p2 &= ~(1 << i);\n+\t\tbreak;\n+\n+\tcase 3:\n+\t\tr1.field.cq_p3 &= ~(1 << i);\n+\t\tr2.field.cq_p3 &= ~(1 << i);\n+\t\tr3.field.cq_p3 &= ~(1 << i);\n+\t\tbreak;\n+\t}\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_ATM_PIPE_QID_LDB_QID2CQIDX(queue_id, port_id / 4),\n+\t\t   r1.val);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_LSP_QID_LDB_QID2CQIDX(queue_id, port_id / 4),\n+\t\t   r2.val);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_LSP_QID_LDB_QID2CQIDX2(queue_id, port_id / 4),\n+\t\t   r3.val);\n+\n+\tdlb_flush_csr(hw);\n+\n+\tunmapped = DLB_QUEUE_UNMAPPED;\n+\n+\treturn dlb_port_slot_state_transition(hw, port, queue, i, unmapped);\n+}\n+\n+static void\n+dlb_log_create_sched_domain_args(struct dlb_hw *hw,\n+\t\t\t\t struct dlb_create_sched_domain_args *args,\n+\t\t\t\t bool vf_request,\n+\t\t\t\t unsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB create sched domain arguments:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\n+\tDLB_HW_INFO(hw, \"\\tNumber of LDB queues:        %d\\n\",\n+\t\t    args->num_ldb_queues);\n+\tDLB_HW_INFO(hw, \"\\tNumber of LDB ports:         %d\\n\",\n+\t\t    args->num_ldb_ports);\n+\tDLB_HW_INFO(hw, \"\\tNumber of DIR ports:         %d\\n\",\n+\t\t    args->num_dir_ports);\n+\tDLB_HW_INFO(hw, \"\\tNumber of ATM inflights:     %d\\n\",\n+\t\t    args->num_atomic_inflights);\n+\tDLB_HW_INFO(hw, \"\\tNumber of hist list entries: %d\\n\",\n+\t\t    args->num_hist_list_entries);\n+\tDLB_HW_INFO(hw, \"\\tNumber of LDB credits:       %d\\n\",\n+\t\t    args->num_ldb_credits);\n+\tDLB_HW_INFO(hw, \"\\tNumber of DIR credits:       %d\\n\",\n+\t\t    args->num_dir_credits);\n+\tDLB_HW_INFO(hw, \"\\tNumber of LDB credit pools:  %d\\n\",\n+\t\t    args->num_ldb_credit_pools);\n+\tDLB_HW_INFO(hw, \"\\tNumber of DIR credit pools:  %d\\n\",\n+\t\t    args->num_dir_credit_pools);\n+}\n+\n+/**\n+ * dlb_hw_create_sched_domain() - Allocate and initialize a DLB scheduling\n+ *\tdomain and its resources.\n+ * @hw:\t  Contains the current state of the DLB hardware.\n+ * @args: User-provided arguments.\n+ * @resp: Response to user.\n+ * @vf_request: Request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF'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 dlb_hw_create_sched_domain(struct dlb_hw *hw,\n+\t\t\t       struct dlb_create_sched_domain_args *args,\n+\t\t\t       struct dlb_cmd_response *resp,\n+\t\t\t       bool vf_request,\n+\t\t\t       unsigned int vf_id)\n+{\n+\tstruct dlb_domain *domain;\n+\tstruct dlb_function_resources *rsrcs;\n+\tint ret;\n+\n+\trsrcs = (vf_request) ? &hw->vf[vf_id] : &hw->pf;\n+\n+\tdlb_log_create_sched_domain_args(hw, args, vf_request, vf_id);\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_sched_domain_args(hw, rsrcs, args, resp))\n+\t\treturn -EINVAL;\n+\n+\tdomain = DLB_FUNC_LIST_HEAD(rsrcs->avail_domains, typeof(*domain));\n+\n+\t/* Verification should catch this. */\n+\tif (!domain) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s():%d] Internal error: no available domains\\n\",\n+\t\t\t   __func__, __LINE__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tif (domain->configured) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: avail_domains contains configured domains.\\n\",\n+\t\t\t   __func__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tdlb_init_domain_rsrc_lists(domain);\n+\n+\t/* Verification should catch this too. */\n+\tret = dlb_domain_attach_resources(hw, rsrcs, domain, args, resp);\n+\tif (ret < 0) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: failed to verify args.\\n\",\n+\t\t\t   __func__);\n+\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tdlb_list_del(&rsrcs->avail_domains, &domain->func_list);\n+\n+\tdlb_list_add(&rsrcs->used_domains, &domain->func_list);\n+\n+\tresp->id = (vf_request) ? domain->id.virt_id : domain->id.phys_id;\n+\tresp->status = 0;\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+\t\t\t     bool vf_request,\n+\t\t\t     unsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB create load-balanced credit pool arguments:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\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+\t\t\t   bool vf_request,\n+\t\t\t   unsigned int vf_id)\n+{\n+\tstruct dlb_credit_pool *pool;\n+\tstruct dlb_domain *domain;\n+\n+\tdlb_log_create_ldb_pool_args(hw, domain_id, args, vf_request, vf_id);\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,\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    vf_request,\n+\t\t\t\t\t    vf_id))\n+\t\treturn -EINVAL;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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 = (vf_request) ? pool->id.virt_id : pool->id.phys_id;\n+\n+\treturn 0;\n+}\n+\n+static void\n+dlb_log_create_dir_pool_args(struct dlb_hw *hw,\n+\t\t\t     u32 domain_id,\n+\t\t\t     struct dlb_create_dir_pool_args *args,\n+\t\t\t     bool vf_request,\n+\t\t\t     unsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB create directed credit pool arguments:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\n+\tDLB_HW_INFO(hw, \"\\tDomain ID:             %d\\n\", domain_id);\n+\tDLB_HW_INFO(hw, \"\\tNumber of DIR credits: %d\\n\",\n+\t\t    args->num_dir_credits);\n+}\n+\n+/**\n+ * dlb_hw_create_dir_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_dir_pool(struct dlb_hw *hw,\n+\t\t\t   u32 domain_id,\n+\t\t\t   struct dlb_create_dir_pool_args *args,\n+\t\t\t   struct dlb_cmd_response *resp,\n+\t\t\t   bool vf_request,\n+\t\t\t   unsigned int vf_id)\n+{\n+\tstruct dlb_credit_pool *pool;\n+\tstruct dlb_domain *domain;\n+\n+\tdlb_log_create_dir_pool_args(hw, domain_id, args, vf_request, vf_id);\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 pool */\n+\tif (dlb_verify_create_dir_pool_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    vf_request,\n+\t\t\t\t\t    vf_id))\n+\t\treturn -EINVAL;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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_dir_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 dir credit pools\\n\",\n+\t\t\t   __func__, __LINE__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tdlb_configure_dir_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_dir_credit_pools, &pool->domain_list);\n+\n+\tdlb_list_add(&domain->used_dir_credit_pools, &pool->domain_list);\n+\n+\tresp->status = 0;\n+\tresp->id = (vf_request) ? pool->id.virt_id : pool->id.phys_id;\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+\t\t\t      bool vf_request,\n+\t\t\t      unsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB create load-balanced queue arguments:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\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+\t\t\t    bool vf_request,\n+\t\t\t    unsigned int vf_id)\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, vf_request, vf_id);\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,\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     vf_request,\n+\t\t\t\t\t     vf_id))\n+\t\treturn -EINVAL;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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, vf_request, vf_id);\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 = (vf_request) ? queue->id.virt_id : queue->id.phys_id;\n+\n+\treturn 0;\n+}\n+\n+static void\n+dlb_log_create_dir_queue_args(struct dlb_hw *hw,\n+\t\t\t      u32 domain_id,\n+\t\t\t      struct dlb_create_dir_queue_args *args,\n+\t\t\t      bool vf_request,\n+\t\t\t      unsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB create directed queue arguments:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\n+\tDLB_HW_INFO(hw, \"\\tDomain ID: %d\\n\", domain_id);\n+\tDLB_HW_INFO(hw, \"\\tPort ID:   %d\\n\", args->port_id);\n+}\n+\n+/**\n+ * dlb_hw_create_dir_queue() - Allocate and initialize a DLB DIR 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_dir_queue(struct dlb_hw *hw,\n+\t\t\t    u32 domain_id,\n+\t\t\t    struct dlb_create_dir_queue_args *args,\n+\t\t\t    struct dlb_cmd_response *resp,\n+\t\t\t    bool vf_request,\n+\t\t\t    unsigned int vf_id)\n+{\n+\tstruct dlb_dir_pq_pair *queue;\n+\tstruct dlb_domain *domain;\n+\n+\tdlb_log_create_dir_queue_args(hw, domain_id, args, vf_request, vf_id);\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_dir_queue_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     vf_request,\n+\t\t\t\t\t     vf_id))\n+\t\treturn -EINVAL;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tif (args->port_id != -1)\n+\t\tqueue = dlb_get_domain_used_dir_pq(args->port_id,\n+\t\t\t\t\t\t   vf_request,\n+\t\t\t\t\t\t   domain);\n+\telse\n+\t\tqueue = DLB_DOM_LIST_HEAD(domain->avail_dir_pq_pairs,\n+\t\t\t\t\t  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 dir queues\\n\",\n+\t\t\t   __func__, __LINE__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tdlb_configure_dir_queue(hw, domain, queue, vf_request, vf_id);\n+\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\tdlb_list_del(&domain->avail_dir_pq_pairs, &queue->domain_list);\n+\n+\t\tdlb_list_add(&domain->used_dir_pq_pairs, &queue->domain_list);\n+\t}\n+\n+\tresp->status = 0;\n+\n+\tresp->id = (vf_request) ? queue->id.virt_id : queue->id.phys_id;\n+\n+\treturn 0;\n+}\n+\n+static void dlb_log_create_ldb_port_args(struct dlb_hw *hw,\n+\t\t\t\t\t u32 domain_id,\n+\t\t\t\t\t u64 pop_count_dma_base,\n+\t\t\t\t\t u64 cq_dma_base,\n+\t\t\t\t\t struct dlb_create_ldb_port_args *args,\n+\t\t\t\t\t bool vf_request,\n+\t\t\t\t\t unsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB create load-balanced port arguments:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\n+\tDLB_HW_INFO(hw, \"\\tDomain ID:                 %d\\n\",\n+\t\t    domain_id);\n+\tDLB_HW_INFO(hw, \"\\tLDB credit pool ID:        %d\\n\",\n+\t\t    args->ldb_credit_pool_id);\n+\tDLB_HW_INFO(hw, \"\\tLDB credit high watermark: %d\\n\",\n+\t\t    args->ldb_credit_high_watermark);\n+\tDLB_HW_INFO(hw, \"\\tLDB credit low watermark:  %d\\n\",\n+\t\t    args->ldb_credit_low_watermark);\n+\tDLB_HW_INFO(hw, \"\\tLDB credit quantum:        %d\\n\",\n+\t\t    args->ldb_credit_quantum);\n+\tDLB_HW_INFO(hw, \"\\tDIR credit pool ID:        %d\\n\",\n+\t\t    args->dir_credit_pool_id);\n+\tDLB_HW_INFO(hw, \"\\tDIR credit high watermark: %d\\n\",\n+\t\t    args->dir_credit_high_watermark);\n+\tDLB_HW_INFO(hw, \"\\tDIR credit low watermark:  %d\\n\",\n+\t\t    args->dir_credit_low_watermark);\n+\tDLB_HW_INFO(hw, \"\\tDIR credit quantum:        %d\\n\",\n+\t\t    args->dir_credit_quantum);\n+\tDLB_HW_INFO(hw, \"\\tpop_count_address:         0x%\"PRIx64\"\\n\",\n+\t\t    pop_count_dma_base);\n+\tDLB_HW_INFO(hw, \"\\tCQ depth:                  %d\\n\",\n+\t\t    args->cq_depth);\n+\tDLB_HW_INFO(hw, \"\\tCQ hist list size:         %d\\n\",\n+\t\t    args->cq_history_list_size);\n+\tDLB_HW_INFO(hw, \"\\tCQ base address:           0x%\"PRIx64\"\\n\",\n+\t\t    cq_dma_base);\n+}\n+\n+/**\n+ * dlb_hw_create_ldb_port() - Allocate and initialize a load-balanced port and\n+ *\tits resources.\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_port(struct dlb_hw *hw,\n+\t\t\t   u32 domain_id,\n+\t\t\t   struct dlb_create_ldb_port_args *args,\n+\t\t\t   u64 pop_count_dma_base,\n+\t\t\t   u64 cq_dma_base,\n+\t\t\t   struct dlb_cmd_response *resp,\n+\t\t\t   bool vf_request,\n+\t\t\t   unsigned int vf_id)\n+{\n+\tstruct dlb_ldb_port *port;\n+\tstruct dlb_domain *domain;\n+\tint ret;\n+\n+\tdlb_log_create_ldb_port_args(hw,\n+\t\t\t\t     domain_id,\n+\t\t\t\t     pop_count_dma_base,\n+\t\t\t\t     cq_dma_base,\n+\t\t\t\t     args,\n+\t\t\t\t     vf_request,\n+\t\t\t\t     vf_id);\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_port_args(hw,\n+\t\t\t\t\t    domain_id,\n+\t\t\t\t\t    pop_count_dma_base,\n+\t\t\t\t\t    cq_dma_base,\n+\t\t\t\t\t    args,\n+\t\t\t\t\t    resp,\n+\t\t\t\t\t    vf_request,\n+\t\t\t\t\t    vf_id))\n+\t\treturn -EINVAL;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tport = DLB_DOM_LIST_HEAD(domain->avail_ldb_ports, typeof(*port));\n+\n+\t/* Verification should catch this. */\n+\tif (!port) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s():%d] Internal error: no available ldb ports\\n\",\n+\t\t\t   __func__, __LINE__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tif (port->configured) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: avail_ldb_ports contains configured ports.\\n\",\n+\t\t\t   __func__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tret = dlb_configure_ldb_port(hw,\n+\t\t\t\t     domain,\n+\t\t\t\t     port,\n+\t\t\t\t     pop_count_dma_base,\n+\t\t\t\t     cq_dma_base,\n+\t\t\t\t     args,\n+\t\t\t\t     vf_request,\n+\t\t\t\t     vf_id);\n+\tif (ret < 0)\n+\t\treturn ret;\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_ports, &port->domain_list);\n+\n+\tdlb_list_add(&domain->used_ldb_ports, &port->domain_list);\n+\n+\tresp->status = 0;\n+\tresp->id = (vf_request) ? port->id.virt_id : port->id.phys_id;\n+\n+\treturn 0;\n+}\n+\n+static void dlb_log_create_dir_port_args(struct dlb_hw *hw,\n+\t\t\t\t\t u32 domain_id,\n+\t\t\t\t\t u64 pop_count_dma_base,\n+\t\t\t\t\t u64 cq_dma_base,\n+\t\t\t\t\t struct dlb_create_dir_port_args *args,\n+\t\t\t\t\t bool vf_request,\n+\t\t\t\t\t unsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB create directed port arguments:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\n+\tDLB_HW_INFO(hw, \"\\tDomain ID:                 %d\\n\",\n+\t\t    domain_id);\n+\tDLB_HW_INFO(hw, \"\\tLDB credit pool ID:        %d\\n\",\n+\t\t    args->ldb_credit_pool_id);\n+\tDLB_HW_INFO(hw, \"\\tLDB credit high watermark: %d\\n\",\n+\t\t    args->ldb_credit_high_watermark);\n+\tDLB_HW_INFO(hw, \"\\tLDB credit low watermark:  %d\\n\",\n+\t\t    args->ldb_credit_low_watermark);\n+\tDLB_HW_INFO(hw, \"\\tLDB credit quantum:        %d\\n\",\n+\t\t    args->ldb_credit_quantum);\n+\tDLB_HW_INFO(hw, \"\\tDIR credit pool ID:        %d\\n\",\n+\t\t    args->dir_credit_pool_id);\n+\tDLB_HW_INFO(hw, \"\\tDIR credit high watermark: %d\\n\",\n+\t\t    args->dir_credit_high_watermark);\n+\tDLB_HW_INFO(hw, \"\\tDIR credit low watermark:  %d\\n\",\n+\t\t    args->dir_credit_low_watermark);\n+\tDLB_HW_INFO(hw, \"\\tDIR credit quantum:        %d\\n\",\n+\t\t    args->dir_credit_quantum);\n+\tDLB_HW_INFO(hw, \"\\tpop_count_address:         0x%\"PRIx64\"\\n\",\n+\t\t    pop_count_dma_base);\n+\tDLB_HW_INFO(hw, \"\\tCQ depth:                  %d\\n\",\n+\t\t    args->cq_depth);\n+\tDLB_HW_INFO(hw, \"\\tCQ base address:           0x%\"PRIx64\"\\n\",\n+\t\t    cq_dma_base);\n+}\n+\n+/**\n+ * dlb_hw_create_dir_port() - Allocate and initialize a DLB directed port and\n+ *\tqueue. The port/queue pair have the same ID and name.\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_dir_port(struct dlb_hw *hw,\n+\t\t\t   u32 domain_id,\n+\t\t\t   struct dlb_create_dir_port_args *args,\n+\t\t\t   u64 pop_count_dma_base,\n+\t\t\t   u64 cq_dma_base,\n+\t\t\t   struct dlb_cmd_response *resp,\n+\t\t\t   bool vf_request,\n+\t\t\t   unsigned int vf_id)\n+{\n+\tstruct dlb_dir_pq_pair *port;\n+\tstruct dlb_domain *domain;\n+\tint ret;\n+\n+\tdlb_log_create_dir_port_args(hw,\n+\t\t\t\t     domain_id,\n+\t\t\t\t     pop_count_dma_base,\n+\t\t\t\t     cq_dma_base,\n+\t\t\t\t     args,\n+\t\t\t\t     vf_request,\n+\t\t\t\t     vf_id);\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_dir_port_args(hw,\n+\t\t\t\t\t    domain_id,\n+\t\t\t\t\t    pop_count_dma_base,\n+\t\t\t\t\t    cq_dma_base,\n+\t\t\t\t\t    args,\n+\t\t\t\t\t    resp,\n+\t\t\t\t\t    vf_request,\n+\t\t\t\t\t    vf_id))\n+\t\treturn -EINVAL;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tif (args->queue_id != -1)\n+\t\tport = dlb_get_domain_used_dir_pq(args->queue_id,\n+\t\t\t\t\t\t  vf_request,\n+\t\t\t\t\t\t  domain);\n+\telse\n+\t\tport = DLB_DOM_LIST_HEAD(domain->avail_dir_pq_pairs,\n+\t\t\t\t\t typeof(*port));\n+\n+\t/* Verification should catch this. */\n+\tif (!port) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s():%d] Internal error: no available dir ports\\n\",\n+\t\t\t   __func__, __LINE__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tret = dlb_configure_dir_port(hw,\n+\t\t\t\t     domain,\n+\t\t\t\t     port,\n+\t\t\t\t     pop_count_dma_base,\n+\t\t\t\t     cq_dma_base,\n+\t\t\t\t     args,\n+\t\t\t\t     vf_request,\n+\t\t\t\t     vf_id);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\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->queue_id == -1) {\n+\t\tdlb_list_del(&domain->avail_dir_pq_pairs, &port->domain_list);\n+\n+\t\tdlb_list_add(&domain->used_dir_pq_pairs, &port->domain_list);\n+\t}\n+\n+\tresp->status = 0;\n+\tresp->id = (vf_request) ? port->id.virt_id : port->id.phys_id;\n+\n+\treturn 0;\n+}\n+\n+static void dlb_log_start_domain(struct dlb_hw *hw,\n+\t\t\t\t u32 domain_id,\n+\t\t\t\t bool vf_request,\n+\t\t\t\t unsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB start domain arguments:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\n+\tDLB_HW_INFO(hw, \"\\tDomain ID: %d\\n\", domain_id);\n+}\n+\n+/**\n+ * dlb_hw_start_domain() - Lock the domain configuration\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_start_domain(struct dlb_hw *hw,\n+\t\t\tu32 domain_id,\n+\t\t\t__attribute((unused)) struct dlb_start_domain_args *arg,\n+\t\t\tstruct dlb_cmd_response *resp,\n+\t\t\tbool vf_request,\n+\t\t\tunsigned int vf_id)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_dir_pq_pair *dir_queue;\n+\tstruct dlb_ldb_queue *ldb_queue;\n+\tstruct dlb_credit_pool *pool;\n+\tstruct dlb_domain *domain;\n+\n+\tdlb_log_start_domain(hw, domain_id, vf_request, vf_id);\n+\n+\tif (dlb_verify_start_domain_args(hw,\n+\t\t\t\t\t domain_id,\n+\t\t\t\t\t resp,\n+\t\t\t\t\t vf_request,\n+\t\t\t\t\t vf_id))\n+\t\treturn -EINVAL;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\t/* Write the domain's pool credit counts, which have been updated\n+\t * during port configuration. The sum of the pool credit count plus\n+\t * each producer port's credit count must equal the pool's credit\n+\t * allocation *before* traffic is sent.\n+\t */\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_credit_pools, pool, iter)\n+\t\tdlb_ldb_pool_write_credit_count_reg(hw, pool->id.phys_id);\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_credit_pools, pool, iter)\n+\t\tdlb_dir_pool_write_credit_count_reg(hw, pool->id.phys_id);\n+\n+\t/* Enable load-balanced and directed queue write permissions for the\n+\t * queues this domain owns. Without this, the DLB will drop all\n+\t * incoming traffic to those queues.\n+\t */\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_queues, ldb_queue, iter) {\n+\t\tunion dlb_sys_ldb_vasqid_v r0 = { {0} };\n+\t\tunsigned int offs;\n+\n+\t\tr0.field.vasqid_v = 1;\n+\n+\t\toffs = domain->id.phys_id * DLB_MAX_NUM_LDB_QUEUES +\n+\t\t\tldb_queue->id.phys_id;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_LDB_VASQID_V(offs), r0.val);\n+\t}\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, dir_queue, iter) {\n+\t\tunion dlb_sys_dir_vasqid_v r0 = { {0} };\n+\t\tunsigned int offs;\n+\n+\t\tr0.field.vasqid_v = 1;\n+\n+\t\toffs = domain->id.phys_id * DLB_MAX_NUM_DIR_PORTS +\n+\t\t\tdir_queue->id.phys_id;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_DIR_VASQID_V(offs), r0.val);\n+\t}\n+\n+\tdlb_flush_csr(hw);\n+\n+\tdomain->started = true;\n+\n+\tresp->status = 0;\n+\n+\treturn 0;\n+}\n+\n+static void dlb_domain_finish_unmap_port_slot(struct dlb_hw *hw,\n+\t\t\t\t\t      struct dlb_domain *domain,\n+\t\t\t\t\t      struct dlb_ldb_port *port,\n+\t\t\t\t\t      int slot)\n+{\n+\tenum dlb_qid_map_state state;\n+\tstruct dlb_ldb_queue *queue;\n+\n+\tqueue = &hw->rsrcs.ldb_queues[port->qid_map[slot].qid];\n+\n+\tstate = port->qid_map[slot].state;\n+\n+\t/* Update the QID2CQIDX and CQ2QID vectors */\n+\tdlb_ldb_port_unmap_qid(hw, port, queue);\n+\n+\t/* Ensure the QID will not be serviced by this {CQ, slot} by clearing\n+\t * the has_work bits\n+\t */\n+\tdlb_ldb_port_clear_has_work_bits(hw, port, slot);\n+\n+\t/* Reset the {CQ, slot} to its default state */\n+\tdlb_ldb_port_set_queue_if_status(hw, port, slot);\n+\n+\t/* Re-enable the CQ if it wasn't manually disabled by the user */\n+\tif (port->enabled)\n+\t\tdlb_ldb_port_cq_enable(hw, port);\n+\n+\t/* If there is a mapping that is pending this slot's removal, perform\n+\t * the mapping now.\n+\t */\n+\tif (state == DLB_QUEUE_UNMAP_IN_PROGRESS_PENDING_MAP) {\n+\t\tstruct dlb_ldb_port_qid_map *map;\n+\t\tstruct dlb_ldb_queue *map_queue;\n+\t\tu8 prio;\n+\n+\t\tmap = &port->qid_map[slot];\n+\n+\t\tmap->qid = map->pending_qid;\n+\t\tmap->priority = map->pending_priority;\n+\n+\t\tmap_queue = &hw->rsrcs.ldb_queues[map->qid];\n+\t\tprio = map->priority;\n+\n+\t\tdlb_ldb_port_map_qid(hw, domain, port, map_queue, prio);\n+\t}\n+}\n+\n+static bool dlb_domain_finish_unmap_port(struct dlb_hw *hw,\n+\t\t\t\t\t struct dlb_domain *domain,\n+\t\t\t\t\t struct dlb_ldb_port *port)\n+{\n+\tunion dlb_lsp_cq_ldb_infl_cnt r0;\n+\tint i;\n+\n+\tif (port->num_pending_removals == 0)\n+\t\treturn false;\n+\n+\t/* The unmap requires all the CQ's outstanding inflights to be\n+\t * completed.\n+\t */\n+\tr0.val = DLB_CSR_RD(hw, DLB_LSP_CQ_LDB_INFL_CNT(port->id.phys_id));\n+\tif (r0.field.count > 0)\n+\t\treturn false;\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_QIDS_PER_LDB_CQ; i++) {\n+\t\tstruct dlb_ldb_port_qid_map *map;\n+\n+\t\tmap = &port->qid_map[i];\n+\n+\t\tif (map->state != DLB_QUEUE_UNMAP_IN_PROGRESS &&\n+\t\t    map->state != DLB_QUEUE_UNMAP_IN_PROGRESS_PENDING_MAP)\n+\t\t\tcontinue;\n+\n+\t\tdlb_domain_finish_unmap_port_slot(hw, domain, port, i);\n+\t}\n+\n+\treturn true;\n+}\n+\n+static unsigned int\n+dlb_domain_finish_unmap_qid_procedures(struct dlb_hw *hw,\n+\t\t\t\t       struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_port *port;\n+\n+\tif (!domain->configured || domain->num_pending_removals == 0)\n+\t\treturn 0;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter)\n+\t\tdlb_domain_finish_unmap_port(hw, domain, port);\n+\n+\treturn domain->num_pending_removals;\n+}\n+\n+unsigned int dlb_finish_unmap_qid_procedures(struct dlb_hw *hw)\n+{\n+\tint i, num = 0;\n+\n+\t/* Finish queue unmap jobs for any domain that needs it */\n+\tfor (i = 0; i < DLB_MAX_NUM_DOMAINS; i++) {\n+\t\tstruct dlb_domain *domain = &hw->domains[i];\n+\n+\t\tnum += dlb_domain_finish_unmap_qid_procedures(hw, domain);\n+\t}\n+\n+\treturn num;\n+}\n+\n+static void dlb_domain_finish_map_port(struct dlb_hw *hw,\n+\t\t\t\t       struct dlb_domain *domain,\n+\t\t\t\t       struct dlb_ldb_port *port)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_QIDS_PER_LDB_CQ; i++) {\n+\t\tunion dlb_lsp_qid_ldb_infl_cnt r0;\n+\t\tstruct dlb_ldb_queue *queue;\n+\t\tint qid;\n+\n+\t\tif (port->qid_map[i].state != DLB_QUEUE_MAP_IN_PROGRESS)\n+\t\t\tcontinue;\n+\n+\t\tqid = port->qid_map[i].qid;\n+\n+\t\tqueue = dlb_get_ldb_queue_from_id(hw, qid, false, 0);\n+\n+\t\tif (!queue) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: unable to find queue %d\\n\",\n+\t\t\t\t   __func__, qid);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tr0.val = DLB_CSR_RD(hw, DLB_LSP_QID_LDB_INFL_CNT(qid));\n+\n+\t\tif (r0.field.count)\n+\t\t\tcontinue;\n+\n+\t\t/* Disable the affected CQ, and the CQs already mapped to the\n+\t\t * QID, before reading the QID's inflight count a second time.\n+\t\t * There is an unlikely race in which the QID may schedule one\n+\t\t * more QE after we read an inflight count of 0, and disabling\n+\t\t * the CQs guarantees that the race will not occur after a\n+\t\t * re-read of the inflight count register.\n+\t\t */\n+\t\tif (port->enabled)\n+\t\t\tdlb_ldb_port_cq_disable(hw, port);\n+\n+\t\tdlb_ldb_queue_disable_mapped_cqs(hw, domain, queue);\n+\n+\t\tr0.val = DLB_CSR_RD(hw, DLB_LSP_QID_LDB_INFL_CNT(qid));\n+\n+\t\tif (r0.field.count) {\n+\t\t\tif (port->enabled)\n+\t\t\t\tdlb_ldb_port_cq_enable(hw, port);\n+\n+\t\t\tdlb_ldb_queue_enable_mapped_cqs(hw, domain, queue);\n+\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tdlb_ldb_port_finish_map_qid_dynamic(hw, domain, port, queue);\n+\t}\n+}\n+\n+static unsigned int\n+dlb_domain_finish_map_qid_procedures(struct dlb_hw *hw,\n+\t\t\t\t     struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_port *port;\n+\n+\tif (!domain->configured || domain->num_pending_additions == 0)\n+\t\treturn 0;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter)\n+\t\tdlb_domain_finish_map_port(hw, domain, port);\n+\n+\treturn domain->num_pending_additions;\n+}\n+\n+unsigned int dlb_finish_map_qid_procedures(struct dlb_hw *hw)\n+{\n+\tint i, num = 0;\n+\n+\t/* Finish queue map jobs for any domain that needs it */\n+\tfor (i = 0; i < DLB_MAX_NUM_DOMAINS; i++) {\n+\t\tstruct dlb_domain *domain = &hw->domains[i];\n+\n+\t\tnum += dlb_domain_finish_map_qid_procedures(hw, domain);\n+\t}\n+\n+\treturn num;\n+}\n+\n+static void dlb_log_map_qid(struct dlb_hw *hw,\n+\t\t\t    u32 domain_id,\n+\t\t\t    struct dlb_map_qid_args *args,\n+\t\t\t    bool vf_request,\n+\t\t\t    unsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB map QID arguments:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\n+\tDLB_HW_INFO(hw, \"\\tDomain ID: %d\\n\",\n+\t\t    domain_id);\n+\tDLB_HW_INFO(hw, \"\\tPort ID:   %d\\n\",\n+\t\t    args->port_id);\n+\tDLB_HW_INFO(hw, \"\\tQueue ID:  %d\\n\",\n+\t\t    args->qid);\n+\tDLB_HW_INFO(hw, \"\\tPriority:  %d\\n\",\n+\t\t    args->priority);\n+}\n+\n+int dlb_hw_map_qid(struct dlb_hw *hw,\n+\t\t   u32 domain_id,\n+\t\t   struct dlb_map_qid_args *args,\n+\t\t   struct dlb_cmd_response *resp,\n+\t\t   bool vf_request,\n+\t\t   unsigned int vf_id)\n+{\n+\tenum dlb_qid_map_state state;\n+\tstruct dlb_ldb_queue *queue;\n+\tstruct dlb_ldb_port *port;\n+\tstruct dlb_domain *domain;\n+\tint ret, i, id;\n+\tu8 prio;\n+\n+\tdlb_log_map_qid(hw, domain_id, args, vf_request, vf_id);\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_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    vf_request,\n+\t\t\t\t    vf_id))\n+\t\treturn -EINVAL;\n+\n+\tprio = args->priority;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tid = args->port_id;\n+\n+\tport = dlb_get_domain_used_ldb_port(id, vf_request, domain);\n+\tif (!port) {\n+\t\tDLB_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 = dlb_get_domain_ldb_queue(args->qid, vf_request, domain);\n+\tif (!queue) {\n+\t\tDLB_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/* 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\tdlb_domain_finish_unmap_port(hw, domain, port);\n+\n+\tret = dlb_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\tdlb_ldb_port_cq_disable(hw, port);\n+\n+\t/* If this is only a priority change, don't perform the full QID->CQ\n+\t * mapping procedure\n+\t */\n+\tstate = DLB_QUEUE_MAPPED;\n+\tif (dlb_port_find_slot_queue(port, state, queue, &i)) {\n+\t\tif (i >= DLB_MAX_NUM_QIDS_PER_LDB_CQ) {\n+\t\t\tDLB_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\tdlb_ldb_port_change_qid_priority(hw, port, i, args);\n+\t\t\tDLB_HW_INFO(hw, \"DLB map: priority change only\\n\");\n+\t\t}\n+\n+\t\tstate = DLB_QUEUE_MAPPED;\n+\t\tret = dlb_port_slot_state_transition(hw, port, queue, i, state);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tgoto map_qid_done;\n+\t}\n+\n+\tstate = DLB_QUEUE_UNMAP_IN_PROGRESS;\n+\tif (dlb_port_find_slot_queue(port, state, queue, &i)) {\n+\t\tif (i >= DLB_MAX_NUM_QIDS_PER_LDB_CQ) {\n+\t\t\tDLB_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\tdlb_ldb_port_change_qid_priority(hw, port, i, args);\n+\t\t\tDLB_HW_INFO(hw, \"DLB map: priority change only\\n\");\n+\t\t}\n+\n+\t\tstate = DLB_QUEUE_MAPPED;\n+\t\tret = dlb_port_slot_state_transition(hw, port, queue, i, state);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tgoto map_qid_done;\n+\t}\n+\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+\tstate = DLB_QUEUE_MAP_IN_PROGRESS;\n+\tif (dlb_port_find_slot_queue(port, state, queue, &i)) {\n+\t\tif (i >= DLB_MAX_NUM_QIDS_PER_LDB_CQ) {\n+\t\t\tDLB_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\tDLB_HW_INFO(hw, \"DLB map: priority change only\\n\");\n+\n+\t\tgoto map_qid_done;\n+\t}\n+\n+\t/* If this is a priority change on a pending mapping, update the\n+\t * pending priority\n+\t */\n+\tif (dlb_port_find_slot_with_pending_map_queue(port, queue, &i)) {\n+\t\tif (i >= DLB_MAX_NUM_QIDS_PER_LDB_CQ) {\n+\t\t\tDLB_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\tDLB_HW_INFO(hw, \"DLB map: priority change only\\n\");\n+\n+\t\tgoto map_qid_done;\n+\t}\n+\n+\t/* If all the CQ's slots are in use, then there's an unmap in progress\n+\t * (guaranteed by dlb_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 (!dlb_port_find_slot(port, DLB_QUEUE_UNMAPPED, &i)) {\n+\t\tif (dlb_port_find_slot(port, DLB_QUEUE_UNMAP_IN_PROGRESS, &i)) {\n+\t\t\tenum dlb_qid_map_state state;\n+\n+\t\t\tif (i >= DLB_MAX_NUM_QIDS_PER_LDB_CQ) {\n+\t\t\t\tDLB_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\tstate = DLB_QUEUE_UNMAP_IN_PROGRESS_PENDING_MAP;\n+\n+\t\t\tret = dlb_port_slot_state_transition(hw, port, queue,\n+\t\t\t\t\t\t\t     i, state);\n+\t\t\tif (ret)\n+\t\t\t\treturn ret;\n+\n+\t\t\tDLB_HW_INFO(hw, \"DLB map: map pending removal\\n\");\n+\n+\t\t\tgoto map_qid_done;\n+\t\t}\n+\t}\n+\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 = dlb_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\tdlb_ldb_port_cq_enable(hw, port);\n+\n+\tresp->status = 0;\n+\n+\treturn 0;\n+}\n+\n+static void dlb_log_unmap_qid(struct dlb_hw *hw,\n+\t\t\t      u32 domain_id,\n+\t\t\t      struct dlb_unmap_qid_args *args,\n+\t\t\t      bool vf_request,\n+\t\t\t      unsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB unmap QID arguments:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\n+\tDLB_HW_INFO(hw, \"\\tDomain ID: %d\\n\",\n+\t\t    domain_id);\n+\tDLB_HW_INFO(hw, \"\\tPort ID:   %d\\n\",\n+\t\t    args->port_id);\n+\tDLB_HW_INFO(hw, \"\\tQueue ID:  %d\\n\",\n+\t\t    args->qid);\n+\tif (args->qid < DLB_MAX_NUM_LDB_QUEUES)\n+\t\tDLB_HW_INFO(hw, \"\\tQueue's num mappings:  %d\\n\",\n+\t\t\t    hw->rsrcs.ldb_queues[args->qid].num_mappings);\n+}\n+\n+int dlb_hw_unmap_qid(struct dlb_hw *hw,\n+\t\t     u32 domain_id,\n+\t\t     struct dlb_unmap_qid_args *args,\n+\t\t     struct dlb_cmd_response *resp,\n+\t\t     bool vf_request,\n+\t\t     unsigned int vf_id)\n+{\n+\tenum dlb_qid_map_state state;\n+\tstruct dlb_ldb_queue *queue;\n+\tstruct dlb_ldb_port *port;\n+\tstruct dlb_domain *domain;\n+\tbool unmap_complete;\n+\tint i, ret, id;\n+\n+\tdlb_log_unmap_qid(hw, domain_id, args, vf_request, vf_id);\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_unmap_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      vf_request,\n+\t\t\t\t      vf_id))\n+\t\treturn -EINVAL;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tid = args->port_id;\n+\n+\tport = dlb_get_domain_used_ldb_port(id, vf_request, domain);\n+\tif (!port) {\n+\t\tDLB_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 = dlb_get_domain_ldb_queue(args->qid, vf_request, domain);\n+\tif (!queue) {\n+\t\tDLB_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/* 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+\tstate = DLB_QUEUE_MAP_IN_PROGRESS;\n+\tif (dlb_port_find_slot_queue(port, state, queue, &i)) {\n+\t\tif (i >= DLB_MAX_NUM_QIDS_PER_LDB_CQ) {\n+\t\t\tDLB_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/* 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\tdlb_ldb_queue_set_inflight_limit(hw, queue);\n+\n+\t\tstate = DLB_QUEUE_UNMAPPED;\n+\t\tret = dlb_port_slot_state_transition(hw, port, queue, i, state);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tgoto unmap_qid_done;\n+\t}\n+\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 (dlb_port_find_slot_with_pending_map_queue(port, queue, &i)) {\n+\t\tif (i >= DLB_MAX_NUM_QIDS_PER_LDB_CQ) {\n+\t\t\tDLB_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\tstate = DLB_QUEUE_UNMAP_IN_PROGRESS;\n+\t\tret = dlb_port_slot_state_transition(hw, port, queue, i, state);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tgoto unmap_qid_done;\n+\t}\n+\n+\tstate = DLB_QUEUE_MAPPED;\n+\tif (!dlb_port_find_slot_queue(port, state, queue, &i)) {\n+\t\tDLB_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 >= DLB_MAX_NUM_QIDS_PER_LDB_CQ) {\n+\t\tDLB_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/* QID->CQ mapping removal is an asychronous procedure. It requires\n+\t * stopping the DLB 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+\tdlb_ldb_port_cq_disable(hw, port);\n+\n+\tstate = DLB_QUEUE_UNMAP_IN_PROGRESS;\n+\tret = dlb_port_slot_state_transition(hw, port, queue, i, state);\n+\tif (ret)\n+\t\treturn ret;\n+\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 = dlb_domain_finish_unmap_port(hw, domain, port);\n+\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 dlb_log_enable_port(struct dlb_hw *hw,\n+\t\t\t\tu32 domain_id,\n+\t\t\t\tu32 port_id,\n+\t\t\t\tbool vf_request,\n+\t\t\t\tunsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB enable port arguments:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\n+\tDLB_HW_INFO(hw, \"\\tDomain ID: %d\\n\",\n+\t\t    domain_id);\n+\tDLB_HW_INFO(hw, \"\\tPort ID:   %d\\n\",\n+\t\t    port_id);\n+}\n+\n+int dlb_hw_enable_ldb_port(struct dlb_hw *hw,\n+\t\t\t   u32 domain_id,\n+\t\t\t   struct dlb_enable_ldb_port_args *args,\n+\t\t\t   struct dlb_cmd_response *resp,\n+\t\t\t   bool vf_request,\n+\t\t\t   unsigned int vf_id)\n+{\n+\tstruct dlb_ldb_port *port;\n+\tstruct dlb_domain *domain;\n+\tint id;\n+\n+\tdlb_log_enable_port(hw, domain_id, args->port_id, vf_request, vf_id);\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_enable_ldb_port_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    vf_request,\n+\t\t\t\t\t    vf_id))\n+\t\treturn -EINVAL;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tid = args->port_id;\n+\n+\tport = dlb_get_domain_used_ldb_port(id, vf_request, domain);\n+\tif (!port) {\n+\t\tDLB_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+\t/* Hardware requires disabling the CQ before unmapping QIDs. */\n+\tif (!port->enabled) {\n+\t\tdlb_ldb_port_cq_enable(hw, port);\n+\t\tport->enabled = true;\n+\n+\t\thw->pf.num_enabled_ldb_ports++;\n+\t\tdlb_update_ldb_arb_threshold(hw);\n+\t}\n+\n+\tresp->status = 0;\n+\n+\treturn 0;\n+}\n+\n+static void dlb_log_disable_port(struct dlb_hw *hw,\n+\t\t\t\t u32 domain_id,\n+\t\t\t\t u32 port_id,\n+\t\t\t\t bool vf_request,\n+\t\t\t\t unsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB disable port arguments:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\n+\tDLB_HW_INFO(hw, \"\\tDomain ID: %d\\n\",\n+\t\t    domain_id);\n+\tDLB_HW_INFO(hw, \"\\tPort ID:   %d\\n\",\n+\t\t    port_id);\n+}\n+\n+int dlb_hw_disable_ldb_port(struct dlb_hw *hw,\n+\t\t\t    u32 domain_id,\n+\t\t\t    struct dlb_disable_ldb_port_args *args,\n+\t\t\t    struct dlb_cmd_response *resp,\n+\t\t\t    bool vf_request,\n+\t\t\t    unsigned int vf_id)\n+{\n+\tstruct dlb_ldb_port *port;\n+\tstruct dlb_domain *domain;\n+\tint id;\n+\n+\tdlb_log_disable_port(hw, domain_id, args->port_id, vf_request, vf_id);\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_disable_ldb_port_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     vf_request,\n+\t\t\t\t\t     vf_id))\n+\t\treturn -EINVAL;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tid = args->port_id;\n+\n+\tport = dlb_get_domain_used_ldb_port(id, vf_request, domain);\n+\tif (!port) {\n+\t\tDLB_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+\t/* Hardware requires disabling the CQ before unmapping QIDs. */\n+\tif (port->enabled) {\n+\t\tdlb_ldb_port_cq_disable(hw, port);\n+\t\tport->enabled = false;\n+\n+\t\thw->pf.num_enabled_ldb_ports--;\n+\t\tdlb_update_ldb_arb_threshold(hw);\n+\t}\n+\n+\tresp->status = 0;\n+\n+\treturn 0;\n+}\n+\n+int dlb_hw_enable_dir_port(struct dlb_hw *hw,\n+\t\t\t   u32 domain_id,\n+\t\t\t   struct dlb_enable_dir_port_args *args,\n+\t\t\t   struct dlb_cmd_response *resp,\n+\t\t\t   bool vf_request,\n+\t\t\t   unsigned int vf_id)\n+{\n+\tstruct dlb_dir_pq_pair *port;\n+\tstruct dlb_domain *domain;\n+\tint id;\n+\n+\tdlb_log_enable_port(hw, domain_id, args->port_id, vf_request, vf_id);\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_enable_dir_port_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    vf_request,\n+\t\t\t\t\t    vf_id))\n+\t\treturn -EINVAL;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tid = args->port_id;\n+\n+\tport = dlb_get_domain_used_dir_pq(id, vf_request, domain);\n+\tif (!port) {\n+\t\tDLB_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+\t/* Hardware requires disabling the CQ before unmapping QIDs. */\n+\tif (!port->enabled) {\n+\t\tdlb_dir_port_cq_enable(hw, port);\n+\t\tport->enabled = true;\n+\t}\n+\n+\tresp->status = 0;\n+\n+\treturn 0;\n+}\n+\n+int dlb_hw_disable_dir_port(struct dlb_hw *hw,\n+\t\t\t    u32 domain_id,\n+\t\t\t    struct dlb_disable_dir_port_args *args,\n+\t\t\t    struct dlb_cmd_response *resp,\n+\t\t\t    bool vf_request,\n+\t\t\t    unsigned int vf_id)\n+{\n+\tstruct dlb_dir_pq_pair *port;\n+\tstruct dlb_domain *domain;\n+\tint id;\n+\n+\tdlb_log_disable_port(hw, domain_id, args->port_id, vf_request, vf_id);\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_disable_dir_port_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     vf_request,\n+\t\t\t\t\t     vf_id))\n+\t\treturn -EINVAL;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_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+\tid = args->port_id;\n+\n+\tport = dlb_get_domain_used_dir_pq(id, vf_request, domain);\n+\tif (!port) {\n+\t\tDLB_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+\t/* Hardware requires disabling the CQ before unmapping QIDs. */\n+\tif (port->enabled) {\n+\t\tdlb_dir_port_cq_disable(hw, port);\n+\t\tport->enabled = false;\n+\t}\n+\n+\tresp->status = 0;\n+\n+\treturn 0;\n+}\n+\n+int dlb_notify_vf(struct dlb_hw *hw,\n+\t\t  unsigned int vf_id,\n+\t\t  enum dlb_mbox_vf_notification_type notification)\n+{\n+\tstruct dlb_mbox_vf_notification_cmd_req req;\n+\tint retry_cnt;\n+\n+\treq.hdr.type = DLB_MBOX_VF_CMD_NOTIFICATION;\n+\treq.notification = notification;\n+\n+\tif (dlb_pf_write_vf_mbox_req(hw, vf_id, &req, sizeof(req)))\n+\t\treturn -1;\n+\n+\tdlb_send_async_pf_to_vf_msg(hw, vf_id);\n+\n+\t/* Timeout after 1 second of inactivity */\n+\tretry_cnt = 0;\n+\twhile (!dlb_pf_to_vf_complete(hw, vf_id)) {\n+\t\tos_msleep(1);\n+\t\tif (++retry_cnt >= 1000) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"PF driver timed out waiting for mbox response\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\t/* No response data expected for notifications. */\n+\n+\treturn 0;\n+}\n+\n+int dlb_vf_in_use(struct dlb_hw *hw, unsigned int vf_id)\n+{\n+\tstruct dlb_mbox_vf_in_use_cmd_resp resp;\n+\tstruct dlb_mbox_vf_in_use_cmd_req req;\n+\tint retry_cnt;\n+\n+\treq.hdr.type = DLB_MBOX_VF_CMD_IN_USE;\n+\n+\tif (dlb_pf_write_vf_mbox_req(hw, vf_id, &req, sizeof(req)))\n+\t\treturn -1;\n+\n+\tdlb_send_async_pf_to_vf_msg(hw, vf_id);\n+\n+\t/* Timeout after 1 second of inactivity */\n+\tretry_cnt = 0;\n+\twhile (!dlb_pf_to_vf_complete(hw, vf_id)) {\n+\t\tos_msleep(1);\n+\t\tif (++retry_cnt >= 1000) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"PF driver timed out waiting for mbox response\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\tif (dlb_pf_read_vf_mbox_resp(hw, vf_id, &resp, sizeof(resp)))\n+\t\treturn -1;\n+\n+\tif (resp.hdr.status != DLB_MBOX_ST_SUCCESS) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()]: failed with mailbox error: %s\\n\",\n+\t\t\t   __func__,\n+\t\t\t   DLB_MBOX_ST_STRING(&resp));\n+\n+\t\treturn -1;\n+\t}\n+\n+\treturn resp.in_use;\n+}\n+\n+static int dlb_vf_domain_alert(struct dlb_hw *hw,\n+\t\t\t       unsigned int vf_id,\n+\t\t\t       u32 domain_id,\n+\t\t\t       u32 alert_id,\n+\t\t\t       u32 aux_alert_data)\n+{\n+\tstruct dlb_mbox_vf_alert_cmd_req req;\n+\tint retry_cnt;\n+\n+\treq.hdr.type = DLB_MBOX_VF_CMD_DOMAIN_ALERT;\n+\treq.domain_id = domain_id;\n+\treq.alert_id = alert_id;\n+\treq.aux_alert_data = aux_alert_data;\n+\n+\tif (dlb_pf_write_vf_mbox_req(hw, vf_id, &req, sizeof(req)))\n+\t\treturn -1;\n+\n+\tdlb_send_async_pf_to_vf_msg(hw, vf_id);\n+\n+\t/* Timeout after 1 second of inactivity */\n+\tretry_cnt = 0;\n+\twhile (!dlb_pf_to_vf_complete(hw, vf_id)) {\n+\t\tos_msleep(1);\n+\t\tif (++retry_cnt >= 1000) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"PF driver timed out waiting for mbox response\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\t/* No response data expected for alarm notifications. */\n+\n+\treturn 0;\n+}\n+\n+void dlb_set_msix_mode(struct dlb_hw *hw, int mode)\n+{\n+\tunion dlb_sys_msix_mode r0 = { {0} };\n+\n+\tr0.field.mode = mode;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_MSIX_MODE, r0.val);\n+}\n+\n+int dlb_configure_ldb_cq_interrupt(struct dlb_hw *hw,\n+\t\t\t\t   int port_id,\n+\t\t\t\t   int vector,\n+\t\t\t\t   int mode,\n+\t\t\t\t   unsigned int vf,\n+\t\t\t\t   unsigned int owner_vf,\n+\t\t\t\t   u16 threshold)\n+{\n+\tunion dlb_chp_ldb_cq_int_depth_thrsh r0 = { {0} };\n+\tunion dlb_chp_ldb_cq_int_enb r1 = { {0} };\n+\tunion dlb_sys_ldb_cq_isr r2 = { {0} };\n+\tstruct dlb_ldb_port *port;\n+\tbool vf_request;\n+\n+\tvf_request = (mode == DLB_CQ_ISR_MODE_MSI);\n+\n+\tport = dlb_get_ldb_port_from_id(hw, port_id, vf_request, vf);\n+\tif (!port) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()]: Internal error: failed to enable LDB CQ int\\n\\tport_id: %u, vf_req: %u, vf: %u\\n\",\n+\t\t\t   __func__, port_id, vf_request, vf);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Trigger the interrupt when threshold or more QEs arrive in the CQ */\n+\tr0.field.depth_threshold = threshold - 1;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_CQ_INT_DEPTH_THRSH(port->id.phys_id),\n+\t\t   r0.val);\n+\n+\tr1.field.en_depth = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_LDB_CQ_INT_ENB(port->id.phys_id), r1.val);\n+\n+\tr2.field.vector = vector;\n+\tr2.field.vf = owner_vf;\n+\tr2.field.en_code = mode;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_LDB_CQ_ISR(port->id.phys_id), r2.val);\n+\n+\treturn 0;\n+}\n+\n+int dlb_configure_dir_cq_interrupt(struct dlb_hw *hw,\n+\t\t\t\t   int port_id,\n+\t\t\t\t   int vector,\n+\t\t\t\t   int mode,\n+\t\t\t\t   unsigned int vf,\n+\t\t\t\t   unsigned int owner_vf,\n+\t\t\t\t   u16 threshold)\n+{\n+\tunion dlb_chp_dir_cq_int_depth_thrsh r0 = { {0} };\n+\tunion dlb_chp_dir_cq_int_enb r1 = { {0} };\n+\tunion dlb_sys_dir_cq_isr r2 = { {0} };\n+\tstruct dlb_dir_pq_pair *port;\n+\tbool vf_request;\n+\n+\tvf_request = (mode == DLB_CQ_ISR_MODE_MSI);\n+\n+\tport = dlb_get_dir_pq_from_id(hw, port_id, vf_request, vf);\n+\tif (!port) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()]: Internal error: failed to enable DIR CQ int\\n\\tport_id: %u, vf_req: %u, vf: %u\\n\",\n+\t\t\t   __func__, port_id, vf_request, vf);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Trigger the interrupt when threshold or more QEs arrive in the CQ */\n+\tr0.field.depth_threshold = threshold - 1;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_CQ_INT_DEPTH_THRSH(port->id.phys_id),\n+\t\t   r0.val);\n+\n+\tr1.field.en_depth = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_DIR_CQ_INT_ENB(port->id.phys_id), r1.val);\n+\n+\tr2.field.vector = vector;\n+\tr2.field.vf = owner_vf;\n+\tr2.field.en_code = mode;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_DIR_CQ_ISR(port->id.phys_id), r2.val);\n+\n+\treturn 0;\n+}\n+\n+int dlb_arm_cq_interrupt(struct dlb_hw *hw,\n+\t\t\t int port_id,\n+\t\t\t bool is_ldb,\n+\t\t\t bool vf_request,\n+\t\t\t unsigned int vf_id)\n+{\n+\tu32 val;\n+\tu32 reg;\n+\n+\tif (vf_request && is_ldb) {\n+\t\tstruct dlb_ldb_port *ldb_port;\n+\n+\t\tldb_port = dlb_get_ldb_port_from_id(hw, port_id, true, vf_id);\n+\n+\t\tif (!ldb_port || !ldb_port->configured)\n+\t\t\treturn -EINVAL;\n+\n+\t\tport_id = ldb_port->id.phys_id;\n+\t} else if (vf_request && !is_ldb) {\n+\t\tstruct dlb_dir_pq_pair *dir_port;\n+\n+\t\tdir_port = dlb_get_dir_pq_from_id(hw, port_id, true, vf_id);\n+\n+\t\tif (!dir_port || !dir_port->port_configured)\n+\t\t\treturn -EINVAL;\n+\n+\t\tport_id = dir_port->id.phys_id;\n+\t}\n+\n+\tval = 1 << (port_id % 32);\n+\n+\tif (is_ldb && port_id < 32)\n+\t\treg = DLB_CHP_LDB_CQ_INTR_ARMED0;\n+\telse if (is_ldb && port_id < 64)\n+\t\treg = DLB_CHP_LDB_CQ_INTR_ARMED1;\n+\telse if (!is_ldb && port_id < 32)\n+\t\treg = DLB_CHP_DIR_CQ_INTR_ARMED0;\n+\telse if (!is_ldb && port_id < 64)\n+\t\treg = DLB_CHP_DIR_CQ_INTR_ARMED1;\n+\telse if (!is_ldb && port_id < 96)\n+\t\treg = DLB_CHP_DIR_CQ_INTR_ARMED2;\n+\telse\n+\t\treg = DLB_CHP_DIR_CQ_INTR_ARMED3;\n+\n+\tDLB_CSR_WR(hw, reg, val);\n+\n+\tdlb_flush_csr(hw);\n+\n+\treturn 0;\n+}\n+\n+void dlb_read_compressed_cq_intr_status(struct dlb_hw *hw,\n+\t\t\t\t\tu32 *ldb_interrupts,\n+\t\t\t\t\tu32 *dir_interrupts)\n+{\n+\t/* Read every CQ's interrupt status */\n+\n+\tldb_interrupts[0] = DLB_CSR_RD(hw, DLB_SYS_LDB_CQ_31_0_OCC_INT_STS);\n+\tldb_interrupts[1] = DLB_CSR_RD(hw, DLB_SYS_LDB_CQ_63_32_OCC_INT_STS);\n+\n+\tdir_interrupts[0] = DLB_CSR_RD(hw, DLB_SYS_DIR_CQ_31_0_OCC_INT_STS);\n+\tdir_interrupts[1] = DLB_CSR_RD(hw, DLB_SYS_DIR_CQ_63_32_OCC_INT_STS);\n+\tdir_interrupts[2] = DLB_CSR_RD(hw, DLB_SYS_DIR_CQ_95_64_OCC_INT_STS);\n+\tdir_interrupts[3] = DLB_CSR_RD(hw, DLB_SYS_DIR_CQ_127_96_OCC_INT_STS);\n+}\n+\n+static void dlb_ack_msix_interrupt(struct dlb_hw *hw, int vector)\n+{\n+\tunion dlb_sys_msix_ack r0 = { {0} };\n+\n+\tswitch (vector) {\n+\tcase 0:\n+\t\tr0.field.msix_0_ack = 1;\n+\t\tbreak;\n+\tcase 1:\n+\t\tr0.field.msix_1_ack = 1;\n+\t\tbreak;\n+\tcase 2:\n+\t\tr0.field.msix_2_ack = 1;\n+\t\tbreak;\n+\tcase 3:\n+\t\tr0.field.msix_3_ack = 1;\n+\t\tbreak;\n+\tcase 4:\n+\t\tr0.field.msix_4_ack = 1;\n+\t\tbreak;\n+\tcase 5:\n+\t\tr0.field.msix_5_ack = 1;\n+\t\tbreak;\n+\tcase 6:\n+\t\tr0.field.msix_6_ack = 1;\n+\t\tbreak;\n+\tcase 7:\n+\t\tr0.field.msix_7_ack = 1;\n+\t\tbreak;\n+\tcase 8:\n+\t\tr0.field.msix_8_ack = 1;\n+\t\t/*\n+\t\t * CSSY-1650\n+\t\t * workaround h/w bug for lost MSI-X interrupts\n+\t\t *\n+\t\t * The recommended workaround for acknowledging\n+\t\t * vector 8 interrupts is :\n+\t\t *   1: set   MSI-X mask\n+\t\t *   2: set   MSIX_PASSTHROUGH\n+\t\t *   3: clear MSIX_ACK\n+\t\t *   4: clear MSIX_PASSTHROUGH\n+\t\t *   5: clear MSI-X mask\n+\t\t *\n+\t\t * The MSIX-ACK (step 3) is cleared for all vectors\n+\t\t * below. We handle steps 1 & 2 for vector 8 here.\n+\t\t *\n+\t\t * The bitfields for MSIX_ACK and MSIX_PASSTHRU are\n+\t\t * defined the same, so we just use the MSIX_ACK\n+\t\t * value when writing to PASSTHRU.\n+\t\t */\n+\n+\t\t/* set MSI-X mask and passthrough for vector 8 */\n+\t\tDLB_FUNC_WR(hw, DLB_MSIX_MEM_VECTOR_CTRL(8), 1);\n+\t\tDLB_CSR_WR(hw, DLB_SYS_MSIX_PASSTHRU, r0.val);\n+\t\tbreak;\n+\t}\n+\n+\t/* clear MSIX_ACK (write one to clear) */\n+\tDLB_CSR_WR(hw, DLB_SYS_MSIX_ACK, r0.val);\n+\n+\tif (vector == 8) {\n+\t\t/*\n+\t\t * finish up steps 4 & 5 of the workaround -\n+\t\t * clear pasthrough and mask\n+\t\t */\n+\t\tDLB_CSR_WR(hw, DLB_SYS_MSIX_PASSTHRU, 0);\n+\t\tDLB_FUNC_WR(hw, DLB_MSIX_MEM_VECTOR_CTRL(8), 0);\n+\t}\n+\n+\tdlb_flush_csr(hw);\n+}\n+\n+void dlb_ack_compressed_cq_intr(struct dlb_hw *hw,\n+\t\t\t\tu32 *ldb_interrupts,\n+\t\t\t\tu32 *dir_interrupts)\n+{\n+\t/* Write back the status regs to ack the interrupts */\n+\tif (ldb_interrupts[0])\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_SYS_LDB_CQ_31_0_OCC_INT_STS,\n+\t\t\t   ldb_interrupts[0]);\n+\tif (ldb_interrupts[1])\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_SYS_LDB_CQ_63_32_OCC_INT_STS,\n+\t\t\t   ldb_interrupts[1]);\n+\n+\tif (dir_interrupts[0])\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_SYS_DIR_CQ_31_0_OCC_INT_STS,\n+\t\t\t   dir_interrupts[0]);\n+\tif (dir_interrupts[1])\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_SYS_DIR_CQ_63_32_OCC_INT_STS,\n+\t\t\t   dir_interrupts[1]);\n+\tif (dir_interrupts[2])\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_SYS_DIR_CQ_95_64_OCC_INT_STS,\n+\t\t\t   dir_interrupts[2]);\n+\tif (dir_interrupts[3])\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_SYS_DIR_CQ_127_96_OCC_INT_STS,\n+\t\t\t   dir_interrupts[3]);\n+\n+\tdlb_ack_msix_interrupt(hw, DLB_PF_COMPRESSED_MODE_CQ_VECTOR_ID);\n+}\n+\n+u32 dlb_read_vf_intr_status(struct dlb_hw *hw)\n+{\n+\treturn DLB_FUNC_RD(hw, DLB_FUNC_VF_VF_MSI_ISR);\n+}\n+\n+void dlb_ack_vf_intr_status(struct dlb_hw *hw, u32 interrupts)\n+{\n+\tDLB_FUNC_WR(hw, DLB_FUNC_VF_VF_MSI_ISR, interrupts);\n+}\n+\n+void dlb_ack_vf_msi_intr(struct dlb_hw *hw, u32 interrupts)\n+{\n+\tDLB_FUNC_WR(hw, DLB_FUNC_VF_VF_MSI_ISR_PEND, interrupts);\n+}\n+\n+void dlb_ack_pf_mbox_int(struct dlb_hw *hw)\n+{\n+\tunion dlb_func_vf_pf2vf_mailbox_isr r0;\n+\n+\tr0.field.pf_isr = 1;\n+\n+\tDLB_FUNC_WR(hw, DLB_FUNC_VF_PF2VF_MAILBOX_ISR, r0.val);\n+}\n+\n+u32 dlb_read_vf_to_pf_int_bitvec(struct dlb_hw *hw)\n+{\n+\t/* The PF has one VF->PF MBOX ISR register per VF space, but they all\n+\t * alias to the same physical register.\n+\t */\n+\treturn DLB_FUNC_RD(hw, DLB_FUNC_PF_VF2PF_MAILBOX_ISR(0));\n+}\n+\n+void dlb_ack_vf_mbox_int(struct dlb_hw *hw, u32 bitvec)\n+{\n+\t/* The PF has one VF->PF MBOX ISR register per VF space, but they all\n+\t * alias to the same physical register.\n+\t */\n+\tDLB_FUNC_WR(hw, DLB_FUNC_PF_VF2PF_MAILBOX_ISR(0), bitvec);\n+}\n+\n+u32 dlb_read_vf_flr_int_bitvec(struct dlb_hw *hw)\n+{\n+\t/* The PF has one VF->PF FLR ISR register per VF space, but they all\n+\t * alias to the same physical register.\n+\t */\n+\treturn DLB_FUNC_RD(hw, DLB_FUNC_PF_VF2PF_FLR_ISR(0));\n+}\n+\n+void dlb_set_vf_reset_in_progress(struct dlb_hw *hw, int vf)\n+{\n+\tu32 bitvec = DLB_FUNC_RD(hw, DLB_FUNC_PF_VF_RESET_IN_PROGRESS(0));\n+\n+\tbitvec |= (1 << vf);\n+\n+\tDLB_FUNC_WR(hw, DLB_FUNC_PF_VF_RESET_IN_PROGRESS(0), bitvec);\n+}\n+\n+void dlb_clr_vf_reset_in_progress(struct dlb_hw *hw, int vf)\n+{\n+\tu32 bitvec = DLB_FUNC_RD(hw, DLB_FUNC_PF_VF_RESET_IN_PROGRESS(0));\n+\n+\tbitvec &= ~(1 << vf);\n+\n+\tDLB_FUNC_WR(hw, DLB_FUNC_PF_VF_RESET_IN_PROGRESS(0), bitvec);\n+}\n+\n+void dlb_ack_vf_flr_int(struct dlb_hw *hw, u32 bitvec, bool a_stepping)\n+{\n+\tunion dlb_sys_func_vf_bar_dsbl r0 = { {0} };\n+\tu32 clear;\n+\tint i;\n+\n+\tif (!bitvec)\n+\t\treturn;\n+\n+\t/* Re-enable access to the VF BAR */\n+\tr0.field.func_vf_bar_dis = 0;\n+\tfor (i = 0; i < DLB_MAX_NUM_VFS; i++) {\n+\t\tif (!(bitvec & (1 << i)))\n+\t\t\tcontinue;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_FUNC_VF_BAR_DSBL(i), r0.val);\n+\t}\n+\n+\t/* Notify the VF driver that the reset has completed. This register is\n+\t * RW in A-stepping devices, WOCLR otherwise.\n+\t */\n+\tif (a_stepping) {\n+\t\tclear = DLB_FUNC_RD(hw, DLB_FUNC_PF_VF_RESET_IN_PROGRESS(0));\n+\t\tclear &= ~bitvec;\n+\t} else {\n+\t\tclear = bitvec;\n+\t}\n+\n+\tDLB_FUNC_WR(hw, DLB_FUNC_PF_VF_RESET_IN_PROGRESS(0), clear);\n+\n+\t/* Mark the FLR ISR as complete */\n+\tDLB_FUNC_WR(hw, DLB_FUNC_PF_VF2PF_FLR_ISR(0), bitvec);\n+}\n+\n+void dlb_ack_vf_to_pf_int(struct dlb_hw *hw,\n+\t\t\t  u32 mbox_bitvec,\n+\t\t\t  u32 flr_bitvec)\n+{\n+\tint i;\n+\n+\tdlb_ack_msix_interrupt(hw, DLB_INT_VF_TO_PF_MBOX);\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_VFS; i++) {\n+\t\tunion dlb_func_pf_vf2pf_isr_pend r0 = { {0} };\n+\n+\t\tif (!((mbox_bitvec & (1 << i)) || (flr_bitvec & (1 << i))))\n+\t\t\tcontinue;\n+\n+\t\t/* Unset the VF's ISR pending bit */\n+\t\tr0.field.isr_pend = 1;\n+\t\tDLB_FUNC_WR(hw, DLB_FUNC_PF_VF2PF_ISR_PEND(i), r0.val);\n+\t}\n+}\n+\n+void dlb_enable_alarm_interrupts(struct dlb_hw *hw)\n+{\n+\tunion dlb_sys_ingress_alarm_enbl r0;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_SYS_INGRESS_ALARM_ENBL);\n+\n+\tr0.field.illegal_hcw = 1;\n+\tr0.field.illegal_pp = 1;\n+\tr0.field.disabled_pp = 1;\n+\tr0.field.illegal_qid = 1;\n+\tr0.field.disabled_qid = 1;\n+\tr0.field.illegal_ldb_qid_cfg = 1;\n+\tr0.field.illegal_cqid = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_INGRESS_ALARM_ENBL, r0.val);\n+}\n+\n+void dlb_disable_alarm_interrupts(struct dlb_hw *hw)\n+{\n+\tunion dlb_sys_ingress_alarm_enbl r0;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_SYS_INGRESS_ALARM_ENBL);\n+\n+\tr0.field.illegal_hcw = 0;\n+\tr0.field.illegal_pp = 0;\n+\tr0.field.disabled_pp = 0;\n+\tr0.field.illegal_qid = 0;\n+\tr0.field.disabled_qid = 0;\n+\tr0.field.illegal_ldb_qid_cfg = 0;\n+\tr0.field.illegal_cqid = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_INGRESS_ALARM_ENBL, r0.val);\n+}\n+\n+static void dlb_log_alarm_syndrome(struct dlb_hw *hw,\n+\t\t\t\t   const char *str,\n+\t\t\t\t   union dlb_sys_alarm_hw_synd r0)\n+{\n+\tDLB_HW_ERR(hw, \"%s:\\n\", str);\n+\tDLB_HW_ERR(hw, \"\\tsyndrome: 0x%x\\n\", r0.field.syndrome);\n+\tDLB_HW_ERR(hw, \"\\trtype:    0x%x\\n\", r0.field.rtype);\n+\tDLB_HW_ERR(hw, \"\\tfrom_dmv: 0x%x\\n\", r0.field.from_dmv);\n+\tDLB_HW_ERR(hw, \"\\tis_ldb:   0x%x\\n\", r0.field.is_ldb);\n+\tDLB_HW_ERR(hw, \"\\tcls:      0x%x\\n\", r0.field.cls);\n+\tDLB_HW_ERR(hw, \"\\taid:      0x%x\\n\", r0.field.aid);\n+\tDLB_HW_ERR(hw, \"\\tunit:     0x%x\\n\", r0.field.unit);\n+\tDLB_HW_ERR(hw, \"\\tsource:   0x%x\\n\", r0.field.source);\n+\tDLB_HW_ERR(hw, \"\\tmore:     0x%x\\n\", r0.field.more);\n+\tDLB_HW_ERR(hw, \"\\tvalid:    0x%x\\n\", r0.field.valid);\n+}\n+\n+/* Note: this array's contents must match dlb_alert_id() */\n+static const char dlb_alert_strings[NUM_DLB_DOMAIN_ALERTS][128] = {\n+\t[DLB_DOMAIN_ALERT_PP_OUT_OF_CREDITS] = \"Insufficient credits\",\n+\t[DLB_DOMAIN_ALERT_PP_ILLEGAL_ENQ] = \"Illegal enqueue\",\n+\t[DLB_DOMAIN_ALERT_PP_EXCESS_TOKEN_POPS] = \"Excess token pops\",\n+\t[DLB_DOMAIN_ALERT_ILLEGAL_HCW] = \"Illegal HCW\",\n+\t[DLB_DOMAIN_ALERT_ILLEGAL_QID] = \"Illegal QID\",\n+\t[DLB_DOMAIN_ALERT_DISABLED_QID] = \"Disabled QID\",\n+};\n+\n+static void dlb_log_pf_vf_syndrome(struct dlb_hw *hw,\n+\t\t\t\t   const char *str,\n+\t\t\t\t   union dlb_sys_alarm_pf_synd0 r0,\n+\t\t\t\t   union dlb_sys_alarm_pf_synd1 r1,\n+\t\t\t\t   union dlb_sys_alarm_pf_synd2 r2,\n+\t\t\t\t   u32 alert_id)\n+{\n+\tDLB_HW_ERR(hw, \"%s:\\n\", str);\n+\tif (alert_id < NUM_DLB_DOMAIN_ALERTS)\n+\t\tDLB_HW_ERR(hw, \"Alert: %s\\n\", dlb_alert_strings[alert_id]);\n+\tDLB_HW_ERR(hw, \"\\tsyndrome:     0x%x\\n\", r0.field.syndrome);\n+\tDLB_HW_ERR(hw, \"\\trtype:        0x%x\\n\", r0.field.rtype);\n+\tDLB_HW_ERR(hw, \"\\tfrom_dmv:     0x%x\\n\", r0.field.from_dmv);\n+\tDLB_HW_ERR(hw, \"\\tis_ldb:       0x%x\\n\", r0.field.is_ldb);\n+\tDLB_HW_ERR(hw, \"\\tcls:          0x%x\\n\", r0.field.cls);\n+\tDLB_HW_ERR(hw, \"\\taid:          0x%x\\n\", r0.field.aid);\n+\tDLB_HW_ERR(hw, \"\\tunit:         0x%x\\n\", r0.field.unit);\n+\tDLB_HW_ERR(hw, \"\\tsource:       0x%x\\n\", r0.field.source);\n+\tDLB_HW_ERR(hw, \"\\tmore:         0x%x\\n\", r0.field.more);\n+\tDLB_HW_ERR(hw, \"\\tvalid:        0x%x\\n\", r0.field.valid);\n+\tDLB_HW_ERR(hw, \"\\tdsi:          0x%x\\n\", r1.field.dsi);\n+\tDLB_HW_ERR(hw, \"\\tqid:          0x%x\\n\", r1.field.qid);\n+\tDLB_HW_ERR(hw, \"\\tqtype:        0x%x\\n\", r1.field.qtype);\n+\tDLB_HW_ERR(hw, \"\\tqpri:         0x%x\\n\", r1.field.qpri);\n+\tDLB_HW_ERR(hw, \"\\tmsg_type:     0x%x\\n\", r1.field.msg_type);\n+\tDLB_HW_ERR(hw, \"\\tlock_id:      0x%x\\n\", r2.field.lock_id);\n+\tDLB_HW_ERR(hw, \"\\tmeas:         0x%x\\n\", r2.field.meas);\n+\tDLB_HW_ERR(hw, \"\\tdebug:        0x%x\\n\", r2.field.debug);\n+\tDLB_HW_ERR(hw, \"\\tcq_pop:       0x%x\\n\", r2.field.cq_pop);\n+\tDLB_HW_ERR(hw, \"\\tqe_uhl:       0x%x\\n\", r2.field.qe_uhl);\n+\tDLB_HW_ERR(hw, \"\\tqe_orsp:      0x%x\\n\", r2.field.qe_orsp);\n+\tDLB_HW_ERR(hw, \"\\tqe_valid:     0x%x\\n\", r2.field.qe_valid);\n+\tDLB_HW_ERR(hw, \"\\tcq_int_rearm: 0x%x\\n\", r2.field.cq_int_rearm);\n+\tDLB_HW_ERR(hw, \"\\tdsi_error:    0x%x\\n\", r2.field.dsi_error);\n+}\n+\n+static void dlb_clear_syndrome_register(struct dlb_hw *hw, u32 offset)\n+{\n+\tunion dlb_sys_alarm_hw_synd r0 = { {0} };\n+\n+\tr0.field.valid = 1;\n+\tr0.field.more = 1;\n+\n+\tDLB_CSR_WR(hw, offset, r0.val);\n+}\n+\n+void dlb_process_alarm_interrupt(struct dlb_hw *hw)\n+{\n+\tunion dlb_sys_alarm_hw_synd r0;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_SYS_ALARM_HW_SYND);\n+\n+\tdlb_log_alarm_syndrome(hw, \"HW alarm syndrome\", r0);\n+\n+\tdlb_clear_syndrome_register(hw, DLB_SYS_ALARM_HW_SYND);\n+\n+\tdlb_ack_msix_interrupt(hw, DLB_INT_ALARM);\n+}\n+\n+static void dlb_process_ingress_error(struct dlb_hw *hw,\n+\t\t\t\t      union dlb_sys_alarm_pf_synd0 r0,\n+\t\t\t\t      u32 alert_id,\n+\t\t\t\t      bool vf_error,\n+\t\t\t\t      unsigned int vf_id)\n+{\n+\tstruct dlb_domain *domain;\n+\tbool is_ldb;\n+\tu8 port_id;\n+\tint ret;\n+\n+\tport_id = r0.field.syndrome & 0x7F;\n+\tif (r0.field.source == DLB_ALARM_HW_SOURCE_SYS)\n+\t\tis_ldb = r0.field.is_ldb;\n+\telse\n+\t\tis_ldb = (r0.field.syndrome & 0x80) != 0;\n+\n+\t/* Get the domain ID and, if it's a VF domain, the virtual port ID */\n+\tif (is_ldb) {\n+\t\tstruct dlb_ldb_port *port;\n+\n+\t\tport = dlb_get_ldb_port_from_id(hw, port_id, vf_error, vf_id);\n+\n+\t\tif (!port) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()]: Internal error: unable to find LDB port\\n\\tport: %u, vf_error: %u, vf_id: %u\\n\",\n+\t\t\t\t   __func__, port_id, vf_error, vf_id);\n+\t\t\treturn;\n+\t\t}\n+\n+\t\tdomain = &hw->domains[port->domain_id.phys_id];\n+\t} else {\n+\t\tstruct dlb_dir_pq_pair *port;\n+\n+\t\tport = dlb_get_dir_pq_from_id(hw, port_id, vf_error, vf_id);\n+\n+\t\tif (!port) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()]: Internal error: unable to find DIR port\\n\\tport: %u, vf_error: %u, vf_id: %u\\n\",\n+\t\t\t\t   __func__, port_id, vf_error, vf_id);\n+\t\t\treturn;\n+\t\t}\n+\n+\t\tdomain = &hw->domains[port->domain_id.phys_id];\n+\t}\n+\n+\tif (vf_error)\n+\t\tret = dlb_vf_domain_alert(hw,\n+\t\t\t\t\t  vf_id,\n+\t\t\t\t\t  domain->id.virt_id,\n+\t\t\t\t\t  alert_id,\n+\t\t\t\t\t  (is_ldb << 8) | port_id);\n+\telse\n+\t\tret = os_notify_user_space(hw,\n+\t\t\t\t\t   domain->id.phys_id,\n+\t\t\t\t\t   alert_id,\n+\t\t\t\t\t   (is_ldb << 8) | port_id);\n+\n+\tif (ret)\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: failed to notify\\n\",\n+\t\t\t   __func__);\n+}\n+\n+static u32 dlb_alert_id(union dlb_sys_alarm_pf_synd0 r0)\n+{\n+\tif (r0.field.unit == DLB_ALARM_HW_UNIT_CHP &&\n+\t    r0.field.aid == DLB_ALARM_HW_CHP_AID_OUT_OF_CREDITS)\n+\t\treturn DLB_DOMAIN_ALERT_PP_OUT_OF_CREDITS;\n+\telse if (r0.field.unit == DLB_ALARM_HW_UNIT_CHP &&\n+\t\t r0.field.aid == DLB_ALARM_HW_CHP_AID_ILLEGAL_ENQ)\n+\t\treturn DLB_DOMAIN_ALERT_PP_ILLEGAL_ENQ;\n+\telse if (r0.field.unit == DLB_ALARM_HW_UNIT_LSP &&\n+\t\t r0.field.aid == DLB_ALARM_HW_LSP_AID_EXCESS_TOKEN_POPS)\n+\t\treturn DLB_DOMAIN_ALERT_PP_EXCESS_TOKEN_POPS;\n+\telse if (r0.field.source == DLB_ALARM_HW_SOURCE_SYS &&\n+\t\t r0.field.aid == DLB_ALARM_SYS_AID_ILLEGAL_HCW)\n+\t\treturn DLB_DOMAIN_ALERT_ILLEGAL_HCW;\n+\telse if (r0.field.source == DLB_ALARM_HW_SOURCE_SYS &&\n+\t\t r0.field.aid == DLB_ALARM_SYS_AID_ILLEGAL_QID)\n+\t\treturn DLB_DOMAIN_ALERT_ILLEGAL_QID;\n+\telse if (r0.field.source == DLB_ALARM_HW_SOURCE_SYS &&\n+\t\t r0.field.aid == DLB_ALARM_SYS_AID_DISABLED_QID)\n+\t\treturn DLB_DOMAIN_ALERT_DISABLED_QID;\n+\telse\n+\t\treturn NUM_DLB_DOMAIN_ALERTS;\n+}\n+\n+void dlb_process_ingress_error_interrupt(struct dlb_hw *hw)\n+{\n+\tunion dlb_sys_alarm_pf_synd0 r0;\n+\tunion dlb_sys_alarm_pf_synd1 r1;\n+\tunion dlb_sys_alarm_pf_synd2 r2;\n+\tu32 alert_id;\n+\tint i;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_SYS_ALARM_PF_SYND0);\n+\n+\tif (r0.field.valid) {\n+\t\tr1.val = DLB_CSR_RD(hw, DLB_SYS_ALARM_PF_SYND1);\n+\t\tr2.val = DLB_CSR_RD(hw, DLB_SYS_ALARM_PF_SYND2);\n+\n+\t\talert_id = dlb_alert_id(r0);\n+\n+\t\tdlb_log_pf_vf_syndrome(hw,\n+\t\t\t\t       \"PF Ingress error alarm\",\n+\t\t\t\t       r0, r1, r2, alert_id);\n+\n+\t\tdlb_clear_syndrome_register(hw, DLB_SYS_ALARM_PF_SYND0);\n+\n+\t\tdlb_process_ingress_error(hw, r0, alert_id, false, 0);\n+\t}\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_VFS; i++) {\n+\t\tr0.val = DLB_CSR_RD(hw, DLB_SYS_ALARM_VF_SYND0(i));\n+\n+\t\tif (!r0.field.valid)\n+\t\t\tcontinue;\n+\n+\t\tr1.val = DLB_CSR_RD(hw, DLB_SYS_ALARM_VF_SYND1(i));\n+\t\tr2.val = DLB_CSR_RD(hw, DLB_SYS_ALARM_VF_SYND2(i));\n+\n+\t\talert_id = dlb_alert_id(r0);\n+\n+\t\tdlb_log_pf_vf_syndrome(hw,\n+\t\t\t\t       \"VF Ingress error alarm\",\n+\t\t\t\t       r0, r1, r2, alert_id);\n+\n+\t\tdlb_clear_syndrome_register(hw,\n+\t\t\t\t\t    DLB_SYS_ALARM_VF_SYND0(i));\n+\n+\t\tdlb_process_ingress_error(hw, r0, alert_id, true, i);\n+\t}\n+\n+\tdlb_ack_msix_interrupt(hw, DLB_INT_INGRESS_ERROR);\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+void dlb_disable_dp_vasr_feature(struct dlb_hw *hw)\n+{\n+\tunion dlb_dp_dir_csr_ctrl r0;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_DP_DIR_CSR_CTRL);\n+\n+\tr0.field.cfg_vasr_dis = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_DP_DIR_CSR_CTRL, r0.val);\n+}\n+\n+void dlb_enable_excess_tokens_alarm(struct dlb_hw *hw)\n+{\n+\tunion dlb_chp_cfg_chp_csr_ctrl r0;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_CHP_CFG_CHP_CSR_CTRL);\n+\n+\tr0.val |= 1 << DLB_CHP_CFG_EXCESS_TOKENS_SHIFT;\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_CFG_CHP_CSR_CTRL, r0.val);\n+}\n+\n+void dlb_disable_excess_tokens_alarm(struct dlb_hw *hw)\n+{\n+\tunion dlb_chp_cfg_chp_csr_ctrl r0;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_CHP_CFG_CHP_CSR_CTRL);\n+\n+\tr0.val &= ~(1 << DLB_CHP_CFG_EXCESS_TOKENS_SHIFT);\n+\n+\tDLB_CSR_WR(hw, DLB_CHP_CFG_CHP_CSR_CTRL, r0.val);\n+}\n+\n+static int dlb_reset_hw_resource(struct dlb_hw *hw, int type, int id)\n+{\n+\tunion dlb_cfg_mstr_diag_reset_sts r0 = { {0} };\n+\tunion dlb_cfg_mstr_bcast_reset_vf_start r1 = { {0} };\n+\tint i;\n+\n+\tr1.field.vf_reset_start = 1;\n+\n+\tr1.field.vf_reset_type = type;\n+\tr1.field.vf_reset_id = id;\n+\n+\tDLB_CSR_WR(hw, DLB_CFG_MSTR_BCAST_RESET_VF_START, r1.val);\n+\n+\t/* Wait for hardware to complete. This is a finite time operation,\n+\t * but wait set a loop bound just in case.\n+\t */\n+\tfor (i = 0; i < 1024 * 1024; i++) {\n+\t\tr0.val = DLB_CSR_RD(hw, DLB_CFG_MSTR_DIAG_RESET_STS);\n+\n+\t\tif (r0.field.chp_vf_reset_done &&\n+\t\t    r0.field.rop_vf_reset_done &&\n+\t\t    r0.field.lsp_vf_reset_done &&\n+\t\t    r0.field.nalb_vf_reset_done &&\n+\t\t    r0.field.ap_vf_reset_done &&\n+\t\t    r0.field.dp_vf_reset_done &&\n+\t\t    r0.field.qed_vf_reset_done &&\n+\t\t    r0.field.dqed_vf_reset_done &&\n+\t\t    r0.field.aqed_vf_reset_done)\n+\t\t\treturn 0;\n+\n+\t\tos_udelay(1);\n+\t}\n+\n+\treturn -ETIMEDOUT;\n+}\n+\n+static int dlb_domain_reset_hw_resources(struct dlb_hw *hw,\n+\t\t\t\t\t struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_dir_pq_pair *dir_port;\n+\tstruct dlb_ldb_queue *ldb_queue;\n+\tstruct dlb_ldb_port *ldb_port;\n+\tstruct dlb_credit_pool *pool;\n+\tint ret;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_credit_pools, pool, iter) {\n+\t\tret = dlb_reset_hw_resource(hw,\n+\t\t\t\t\t    VF_RST_TYPE_POOL_LDB,\n+\t\t\t\t\t    pool->id.phys_id);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_credit_pools, pool, iter) {\n+\t\tret = dlb_reset_hw_resource(hw,\n+\t\t\t\t\t    VF_RST_TYPE_POOL_DIR,\n+\t\t\t\t\t    pool->id.phys_id);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_queues, ldb_queue, iter) {\n+\t\tret = dlb_reset_hw_resource(hw,\n+\t\t\t\t\t    VF_RST_TYPE_QID_LDB,\n+\t\t\t\t\t    ldb_queue->id.phys_id);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, dir_port, iter) {\n+\t\tret = dlb_reset_hw_resource(hw,\n+\t\t\t\t\t    VF_RST_TYPE_QID_DIR,\n+\t\t\t\t\t    dir_port->id.phys_id);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, ldb_port, iter) {\n+\t\tret = dlb_reset_hw_resource(hw,\n+\t\t\t\t\t    VF_RST_TYPE_CQ_LDB,\n+\t\t\t\t\t    ldb_port->id.phys_id);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, dir_port, iter) {\n+\t\tret = dlb_reset_hw_resource(hw,\n+\t\t\t\t\t    VF_RST_TYPE_CQ_DIR,\n+\t\t\t\t\t    dir_port->id.phys_id);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static u32 dlb_ldb_cq_inflight_count(struct dlb_hw *hw,\n+\t\t\t\t     struct dlb_ldb_port *port)\n+{\n+\tunion dlb_lsp_cq_ldb_infl_cnt r0;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_LSP_CQ_LDB_INFL_CNT(port->id.phys_id));\n+\n+\treturn r0.field.count;\n+}\n+\n+static u32 dlb_ldb_cq_token_count(struct dlb_hw *hw,\n+\t\t\t\t  struct dlb_ldb_port *port)\n+{\n+\tunion dlb_lsp_cq_ldb_tkn_cnt r0;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_LSP_CQ_LDB_TKN_CNT(port->id.phys_id));\n+\n+\treturn r0.field.token_count;\n+}\n+\n+static int dlb_drain_ldb_cq(struct dlb_hw *hw, struct dlb_ldb_port *port)\n+{\n+\tu32 infl_cnt, tkn_cnt;\n+\tunsigned int i;\n+\n+\tinfl_cnt = dlb_ldb_cq_inflight_count(hw, port);\n+\n+\t/* Account for the initial token count, which is used in order to\n+\t * provide a CQ with depth less than 8.\n+\t */\n+\ttkn_cnt = dlb_ldb_cq_token_count(hw, port) - port->init_tkn_cnt;\n+\n+\tif (infl_cnt || tkn_cnt) {\n+\t\tstruct dlb_hcw hcw_mem[8], *hcw;\n+\t\tvoid  *pp_addr;\n+\n+\t\tpp_addr = os_map_producer_port(hw, port->id.phys_id, true);\n+\n+\t\t/* Point hcw to a 64B-aligned location */\n+\t\thcw = (struct dlb_hcw *)((uintptr_t)&hcw_mem[4] & ~0x3F);\n+\n+\t\t/* Program the first HCW for a completion and token return and\n+\t\t * the other HCWs as NOOPS\n+\t\t */\n+\n+\t\tmemset(hcw, 0, 4 * sizeof(*hcw));\n+\t\thcw->qe_comp = (infl_cnt > 0);\n+\t\thcw->cq_token = (tkn_cnt > 0);\n+\t\thcw->lock_id = tkn_cnt - 1;\n+\n+\t\t/* Return tokens in the first HCW */\n+\t\tos_enqueue_four_hcws(hw, hcw, pp_addr);\n+\n+\t\thcw->cq_token = 0;\n+\n+\t\t/* Issue remaining completions (if any) */\n+\t\tfor (i = 1; i < infl_cnt; i++)\n+\t\t\tos_enqueue_four_hcws(hw, hcw, pp_addr);\n+\n+\t\tos_fence_hcw(hw, pp_addr);\n+\n+\t\tos_unmap_producer_port(hw, pp_addr);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int dlb_domain_wait_for_ldb_cqs_to_empty(struct dlb_hw *hw,\n+\t\t\t\t\t\tstruct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_port *port;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter) {\n+\t\tint i;\n+\n+\t\tfor (i = 0; i < DLB_MAX_CQ_COMP_CHECK_LOOPS; i++) {\n+\t\t\tif (dlb_ldb_cq_inflight_count(hw, port) == 0)\n+\t\t\t\tbreak;\n+\t\t}\n+\n+\t\tif (i == DLB_MAX_CQ_COMP_CHECK_LOOPS) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: failed to flush load-balanced port %d's completions.\\n\",\n+\t\t\t\t   __func__, port->id.phys_id);\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int dlb_domain_reset_software_state(struct dlb_hw *hw,\n+\t\t\t\t\t   struct dlb_domain *domain)\n+{\n+\tstruct dlb_ldb_queue *tmp_ldb_queue __attribute__((unused));\n+\tstruct dlb_dir_pq_pair *tmp_dir_port __attribute__((unused));\n+\tstruct dlb_ldb_port *tmp_ldb_port __attribute__((unused));\n+\tstruct dlb_credit_pool *tmp_pool __attribute__((unused));\n+\tstruct dlb_list_entry *iter1 __attribute__((unused));\n+\tstruct dlb_list_entry *iter2 __attribute__((unused));\n+\tstruct dlb_ldb_queue *ldb_queue;\n+\tstruct dlb_dir_pq_pair *dir_port;\n+\tstruct dlb_ldb_port *ldb_port;\n+\tstruct dlb_credit_pool *pool;\n+\n+\tstruct dlb_function_resources *rsrcs;\n+\tstruct dlb_list_head *list;\n+\tint ret;\n+\n+\trsrcs = domain->parent_func;\n+\n+\t/* Move the domain's ldb queues to the function's avail list */\n+\tlist = &domain->used_ldb_queues;\n+\tDLB_DOM_LIST_FOR_SAFE(*list, ldb_queue, tmp_ldb_queue, iter1, iter2) {\n+\t\tif (ldb_queue->sn_cfg_valid) {\n+\t\t\tstruct dlb_sn_group *grp;\n+\n+\t\t\tgrp = &hw->rsrcs.sn_groups[ldb_queue->sn_group];\n+\n+\t\t\tdlb_sn_group_free_slot(grp, ldb_queue->sn_slot);\n+\t\t\tldb_queue->sn_cfg_valid = false;\n+\t\t}\n+\n+\t\tldb_queue->owned = false;\n+\t\tldb_queue->num_mappings = 0;\n+\t\tldb_queue->num_pending_additions = 0;\n+\n+\t\tdlb_list_del(&domain->used_ldb_queues, &ldb_queue->domain_list);\n+\t\tdlb_list_add(&rsrcs->avail_ldb_queues, &ldb_queue->func_list);\n+\t\trsrcs->num_avail_ldb_queues++;\n+\t}\n+\n+\tlist = &domain->avail_ldb_queues;\n+\tDLB_DOM_LIST_FOR_SAFE(*list, ldb_queue, tmp_ldb_queue, iter1, iter2) {\n+\t\tldb_queue->owned = false;\n+\n+\t\tdlb_list_del(&domain->avail_ldb_queues,\n+\t\t\t     &ldb_queue->domain_list);\n+\t\tdlb_list_add(&rsrcs->avail_ldb_queues,\n+\t\t\t     &ldb_queue->func_list);\n+\t\trsrcs->num_avail_ldb_queues++;\n+\t}\n+\n+\t/* Move the domain's ldb ports to the function's avail list */\n+\tlist = &domain->used_ldb_ports;\n+\tDLB_DOM_LIST_FOR_SAFE(*list, ldb_port, tmp_ldb_port, iter1, iter2) {\n+\t\tint i;\n+\n+\t\tldb_port->owned = false;\n+\t\tldb_port->configured = false;\n+\t\tldb_port->num_pending_removals = 0;\n+\t\tldb_port->num_mappings = 0;\n+\t\tfor (i = 0; i < DLB_MAX_NUM_QIDS_PER_LDB_CQ; i++)\n+\t\t\tldb_port->qid_map[i].state = DLB_QUEUE_UNMAPPED;\n+\n+\t\tdlb_list_del(&domain->used_ldb_ports, &ldb_port->domain_list);\n+\t\tdlb_list_add(&rsrcs->avail_ldb_ports, &ldb_port->func_list);\n+\t\trsrcs->num_avail_ldb_ports++;\n+\t}\n+\n+\tlist = &domain->avail_ldb_ports;\n+\tDLB_DOM_LIST_FOR_SAFE(*list, ldb_port, tmp_ldb_port, iter1, iter2) {\n+\t\tldb_port->owned = false;\n+\n+\t\tdlb_list_del(&domain->avail_ldb_ports, &ldb_port->domain_list);\n+\t\tdlb_list_add(&rsrcs->avail_ldb_ports, &ldb_port->func_list);\n+\t\trsrcs->num_avail_ldb_ports++;\n+\t}\n+\n+\t/* Move the domain's dir ports to the function's avail list */\n+\tlist = &domain->used_dir_pq_pairs;\n+\tDLB_DOM_LIST_FOR_SAFE(*list, dir_port, tmp_dir_port, iter1, iter2) {\n+\t\tdir_port->owned = false;\n+\t\tdir_port->port_configured = false;\n+\n+\t\tdlb_list_del(&domain->used_dir_pq_pairs,\n+\t\t\t     &dir_port->domain_list);\n+\n+\t\tdlb_list_add(&rsrcs->avail_dir_pq_pairs,\n+\t\t\t     &dir_port->func_list);\n+\t\trsrcs->num_avail_dir_pq_pairs++;\n+\t}\n+\n+\tlist = &domain->avail_dir_pq_pairs;\n+\tDLB_DOM_LIST_FOR_SAFE(*list, dir_port, tmp_dir_port, iter1, iter2) {\n+\t\tdir_port->owned = false;\n+\n+\t\tdlb_list_del(&domain->avail_dir_pq_pairs,\n+\t\t\t     &dir_port->domain_list);\n+\n+\t\tdlb_list_add(&rsrcs->avail_dir_pq_pairs,\n+\t\t\t     &dir_port->func_list);\n+\t\trsrcs->num_avail_dir_pq_pairs++;\n+\t}\n+\n+\t/* Return hist list entries to the function */\n+\tret = dlb_bitmap_set_range(rsrcs->avail_hist_list_entries,\n+\t\t\t\t   domain->hist_list_entry_base,\n+\t\t\t\t   domain->total_hist_list_entries);\n+\tif (ret) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: domain hist list base doesn't match the function's bitmap.\\n\",\n+\t\t\t   __func__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tdomain->total_hist_list_entries = 0;\n+\tdomain->avail_hist_list_entries = 0;\n+\tdomain->hist_list_entry_base = 0;\n+\tdomain->hist_list_entry_offset = 0;\n+\n+\t/* Return QED entries to the function */\n+\tret = dlb_bitmap_set_range(rsrcs->avail_qed_freelist_entries,\n+\t\t\t\t   domain->qed_freelist.base,\n+\t\t\t\t   (domain->qed_freelist.bound -\n+\t\t\t\t\tdomain->qed_freelist.base));\n+\tif (ret) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: domain QED base doesn't match the function's bitmap.\\n\",\n+\t\t\t   __func__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tdomain->qed_freelist.base = 0;\n+\tdomain->qed_freelist.bound = 0;\n+\tdomain->qed_freelist.offset = 0;\n+\n+\t/* Return DQED entries back to the function */\n+\tret = dlb_bitmap_set_range(rsrcs->avail_dqed_freelist_entries,\n+\t\t\t\t   domain->dqed_freelist.base,\n+\t\t\t\t   (domain->dqed_freelist.bound -\n+\t\t\t\t\tdomain->dqed_freelist.base));\n+\tif (ret) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: domain DQED base doesn't match the function's bitmap.\\n\",\n+\t\t\t   __func__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tdomain->dqed_freelist.base = 0;\n+\tdomain->dqed_freelist.bound = 0;\n+\tdomain->dqed_freelist.offset = 0;\n+\n+\t/* Return AQED entries back to the function */\n+\tret = dlb_bitmap_set_range(rsrcs->avail_aqed_freelist_entries,\n+\t\t\t\t   domain->aqed_freelist.base,\n+\t\t\t\t   (domain->aqed_freelist.bound -\n+\t\t\t\t\tdomain->aqed_freelist.base));\n+\tif (ret) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: domain AQED base doesn't match the function's bitmap.\\n\",\n+\t\t\t   __func__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tdomain->aqed_freelist.base = 0;\n+\tdomain->aqed_freelist.bound = 0;\n+\tdomain->aqed_freelist.offset = 0;\n+\n+\t/* Return ldb credit pools back to the function's avail list */\n+\tlist = &domain->used_ldb_credit_pools;\n+\tDLB_DOM_LIST_FOR_SAFE(*list, pool, tmp_pool, iter1, iter2) {\n+\t\tpool->owned = false;\n+\t\tpool->configured = false;\n+\n+\t\tdlb_list_del(&domain->used_ldb_credit_pools,\n+\t\t\t     &pool->domain_list);\n+\t\tdlb_list_add(&rsrcs->avail_ldb_credit_pools,\n+\t\t\t     &pool->func_list);\n+\t\trsrcs->num_avail_ldb_credit_pools++;\n+\t}\n+\n+\tlist = &domain->avail_ldb_credit_pools;\n+\tDLB_DOM_LIST_FOR_SAFE(*list, pool, tmp_pool, iter1, iter2) {\n+\t\tpool->owned = false;\n+\n+\t\tdlb_list_del(&domain->avail_ldb_credit_pools,\n+\t\t\t     &pool->domain_list);\n+\t\tdlb_list_add(&rsrcs->avail_ldb_credit_pools,\n+\t\t\t     &pool->func_list);\n+\t\trsrcs->num_avail_ldb_credit_pools++;\n+\t}\n+\n+\t/* Move dir credit pools back to the function */\n+\tlist = &domain->used_dir_credit_pools;\n+\tDLB_DOM_LIST_FOR_SAFE(*list, pool, tmp_pool, iter1, iter2) {\n+\t\tpool->owned = false;\n+\t\tpool->configured = false;\n+\n+\t\tdlb_list_del(&domain->used_dir_credit_pools,\n+\t\t\t     &pool->domain_list);\n+\t\tdlb_list_add(&rsrcs->avail_dir_credit_pools,\n+\t\t\t     &pool->func_list);\n+\t\trsrcs->num_avail_dir_credit_pools++;\n+\t}\n+\n+\tlist = &domain->avail_dir_credit_pools;\n+\tDLB_DOM_LIST_FOR_SAFE(*list, pool, tmp_pool, iter1, iter2) {\n+\t\tpool->owned = false;\n+\n+\t\tdlb_list_del(&domain->avail_dir_credit_pools,\n+\t\t\t     &pool->domain_list);\n+\t\tdlb_list_add(&rsrcs->avail_dir_credit_pools,\n+\t\t\t     &pool->func_list);\n+\t\trsrcs->num_avail_dir_credit_pools++;\n+\t}\n+\n+\tdomain->num_pending_removals = 0;\n+\tdomain->num_pending_additions = 0;\n+\tdomain->configured = false;\n+\tdomain->started = false;\n+\n+\t/* Move the domain out of the used_domains list and back to the\n+\t * function's avail_domains list.\n+\t */\n+\tdlb_list_del(&rsrcs->used_domains, &domain->func_list);\n+\tdlb_list_add(&rsrcs->avail_domains, &domain->func_list);\n+\trsrcs->num_avail_domains++;\n+\n+\treturn 0;\n+}\n+\n+void dlb_resource_reset(struct dlb_hw *hw)\n+{\n+\tstruct dlb_domain *domain, *next __attribute__((unused));\n+\tstruct dlb_list_entry *iter1 __attribute__((unused));\n+\tstruct dlb_list_entry *iter2 __attribute__((unused));\n+\tint i;\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_VFS; i++) {\n+\t\tDLB_FUNC_LIST_FOR_SAFE(hw->vf[i].used_domains, domain,\n+\t\t\t\t       next, iter1, iter2)\n+\t\t\tdlb_domain_reset_software_state(hw, domain);\n+\t}\n+\n+\tDLB_FUNC_LIST_FOR_SAFE(hw->pf.used_domains, domain, next, iter1, iter2)\n+\t\tdlb_domain_reset_software_state(hw, domain);\n+}\n+\n+static u32 dlb_dir_queue_depth(struct dlb_hw *hw,\n+\t\t\t       struct dlb_dir_pq_pair *queue)\n+{\n+\tunion dlb_lsp_qid_dir_enqueue_cnt r0;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_LSP_QID_DIR_ENQUEUE_CNT(queue->id.phys_id));\n+\n+\treturn r0.field.count;\n+}\n+\n+static bool dlb_dir_queue_is_empty(struct dlb_hw *hw,\n+\t\t\t\t   struct dlb_dir_pq_pair *queue)\n+{\n+\treturn dlb_dir_queue_depth(hw, queue) == 0;\n+}\n+\n+static void dlb_log_get_dir_queue_depth(struct dlb_hw *hw,\n+\t\t\t\t\tu32 domain_id,\n+\t\t\t\t\tu32 queue_id,\n+\t\t\t\t\tbool vf_request,\n+\t\t\t\t\tunsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB get directed queue depth:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\n+\tDLB_HW_INFO(hw, \"\\tDomain ID: %d\\n\", domain_id);\n+\tDLB_HW_INFO(hw, \"\\tQueue ID: %d\\n\", queue_id);\n+}\n+\n+int dlb_hw_get_dir_queue_depth(struct dlb_hw *hw,\n+\t\t\t       u32 domain_id,\n+\t\t\t       struct dlb_get_dir_queue_depth_args *args,\n+\t\t\t       struct dlb_cmd_response *resp,\n+\t\t\t       bool vf_request,\n+\t\t\t       unsigned int vf_id)\n+{\n+\tstruct dlb_dir_pq_pair *queue;\n+\tstruct dlb_domain *domain;\n+\tint id;\n+\n+\tid = domain_id;\n+\n+\tdlb_log_get_dir_queue_depth(hw, domain_id, args->queue_id,\n+\t\t\t\t    vf_request, vf_id);\n+\n+\tdomain = dlb_get_domain_from_id(hw, id, vf_request, vf_id);\n+\tif (!domain) {\n+\t\tresp->status = DLB_ST_INVALID_DOMAIN_ID;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tid = args->queue_id;\n+\n+\tqueue = dlb_get_domain_used_dir_pq(id, vf_request, domain);\n+\tif (!queue) {\n+\t\tresp->status = DLB_ST_INVALID_QID;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tresp->id = dlb_dir_queue_depth(hw, queue);\n+\n+\treturn 0;\n+}\n+\n+static void\n+dlb_log_pending_port_unmaps_args(struct dlb_hw *hw,\n+\t\t\t\t struct dlb_pending_port_unmaps_args *args,\n+\t\t\t\t bool vf_request,\n+\t\t\t\t unsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB pending port unmaps arguments:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\n+\tDLB_HW_INFO(hw, \"\\tPort ID: %d\\n\", args->port_id);\n+}\n+\n+int dlb_hw_pending_port_unmaps(struct dlb_hw *hw,\n+\t\t\t       u32 domain_id,\n+\t\t\t       struct dlb_pending_port_unmaps_args *args,\n+\t\t\t       struct dlb_cmd_response *resp,\n+\t\t\t       bool vf_request,\n+\t\t\t       unsigned int vf_id)\n+{\n+\tstruct dlb_domain *domain;\n+\tstruct dlb_ldb_port *port;\n+\n+\tdlb_log_pending_port_unmaps_args(hw, args, vf_request, vf_id);\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_id);\n+\n+\tif (!domain) {\n+\t\tresp->status = DLB_ST_INVALID_DOMAIN_ID;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tport = dlb_get_domain_used_ldb_port(args->port_id, vf_request, domain);\n+\tif (!port || !port->configured) {\n+\t\tresp->status = DLB_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+/* Returns whether the queue is empty, including its inflight and replay\n+ * counts.\n+ */\n+static bool dlb_ldb_queue_is_empty(struct dlb_hw *hw,\n+\t\t\t\t   struct dlb_ldb_queue *queue)\n+{\n+\tunion dlb_lsp_qid_ldb_replay_cnt r0;\n+\tunion dlb_lsp_qid_aqed_active_cnt r1;\n+\tunion dlb_lsp_qid_atq_enqueue_cnt r2;\n+\tunion dlb_lsp_qid_ldb_enqueue_cnt r3;\n+\tunion dlb_lsp_qid_ldb_infl_cnt r4;\n+\n+\tr0.val = DLB_CSR_RD(hw,\n+\t\t\t    DLB_LSP_QID_LDB_REPLAY_CNT(queue->id.phys_id));\n+\tif (r0.val)\n+\t\treturn false;\n+\n+\tr1.val = DLB_CSR_RD(hw,\n+\t\t\t    DLB_LSP_QID_AQED_ACTIVE_CNT(queue->id.phys_id));\n+\tif (r1.val)\n+\t\treturn false;\n+\n+\tr2.val = DLB_CSR_RD(hw,\n+\t\t\t    DLB_LSP_QID_ATQ_ENQUEUE_CNT(queue->id.phys_id));\n+\tif (r2.val)\n+\t\treturn false;\n+\n+\tr3.val = DLB_CSR_RD(hw,\n+\t\t\t    DLB_LSP_QID_LDB_ENQUEUE_CNT(queue->id.phys_id));\n+\tif (r3.val)\n+\t\treturn false;\n+\n+\tr4.val = DLB_CSR_RD(hw,\n+\t\t\t    DLB_LSP_QID_LDB_INFL_CNT(queue->id.phys_id));\n+\tif (r4.val)\n+\t\treturn false;\n+\n+\treturn true;\n+}\n+\n+static void dlb_log_get_ldb_queue_depth(struct dlb_hw *hw,\n+\t\t\t\t\tu32 domain_id,\n+\t\t\t\t\tu32 queue_id,\n+\t\t\t\t\tbool vf_request,\n+\t\t\t\t\tunsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB get load-balanced queue depth:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\n+\tDLB_HW_INFO(hw, \"\\tDomain ID: %d\\n\", domain_id);\n+\tDLB_HW_INFO(hw, \"\\tQueue ID: %d\\n\", queue_id);\n+}\n+\n+int dlb_hw_get_ldb_queue_depth(struct dlb_hw *hw,\n+\t\t\t       u32 domain_id,\n+\t\t\t       struct dlb_get_ldb_queue_depth_args *args,\n+\t\t\t       struct dlb_cmd_response *resp,\n+\t\t\t       bool vf_req,\n+\t\t\t       unsigned int vf_id)\n+{\n+\tunion dlb_lsp_qid_aqed_active_cnt r0;\n+\tunion dlb_lsp_qid_atq_enqueue_cnt r1;\n+\tunion dlb_lsp_qid_ldb_enqueue_cnt r2;\n+\tstruct dlb_ldb_queue *queue;\n+\tstruct dlb_domain *domain;\n+\n+\tdlb_log_get_ldb_queue_depth(hw, domain_id, args->queue_id,\n+\t\t\t\t    vf_req, vf_id);\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_req, vf_id);\n+\tif (!domain) {\n+\t\tresp->status = DLB_ST_INVALID_DOMAIN_ID;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tqueue = dlb_get_domain_ldb_queue(args->queue_id, vf_req, domain);\n+\tif (!queue) {\n+\t\tresp->status = DLB_ST_INVALID_QID;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tr0.val = DLB_CSR_RD(hw,\n+\t\t\t    DLB_LSP_QID_AQED_ACTIVE_CNT(queue->id.phys_id));\n+\n+\tr1.val = DLB_CSR_RD(hw,\n+\t\t\t    DLB_LSP_QID_ATQ_ENQUEUE_CNT(queue->id.phys_id));\n+\n+\tr2.val = DLB_CSR_RD(hw,\n+\t\t\t    DLB_LSP_QID_LDB_ENQUEUE_CNT(queue->id.phys_id));\n+\n+\tresp->id = r0.val + r1.val + r2.val;\n+\n+\treturn 0;\n+}\n+\n+static u32 dlb_dir_cq_token_count(struct dlb_hw *hw,\n+\t\t\t\t  struct dlb_dir_pq_pair *port)\n+{\n+\tunion dlb_lsp_cq_dir_tkn_cnt r0;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_LSP_CQ_DIR_TKN_CNT(port->id.phys_id));\n+\n+\treturn r0.field.count;\n+}\n+\n+static int dlb_domain_verify_reset_success(struct dlb_hw *hw,\n+\t\t\t\t\t   struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_dir_pq_pair *dir_port;\n+\tstruct dlb_ldb_port *ldb_port;\n+\tstruct dlb_credit_pool *pool;\n+\tstruct dlb_ldb_queue *queue;\n+\n+\t/* Confirm that all credits are returned to the domain's credit pools */\n+\tDLB_DOM_LIST_FOR(domain->used_dir_credit_pools, pool, iter) {\n+\t\tunion dlb_chp_dqed_fl_pop_ptr r0;\n+\t\tunion dlb_chp_dqed_fl_push_ptr r1;\n+\n+\t\tr0.val = DLB_CSR_RD(hw,\n+\t\t\t\t    DLB_CHP_DQED_FL_POP_PTR(pool->id.phys_id));\n+\n+\t\tr1.val = DLB_CSR_RD(hw,\n+\t\t\t\t    DLB_CHP_DQED_FL_PUSH_PTR(pool->id.phys_id));\n+\n+\t\tif (r0.field.pop_ptr != r1.field.push_ptr ||\n+\t\t    r0.field.generation == r1.field.generation) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: failed to refill directed pool %d's credits.\\n\",\n+\t\t\t\t   __func__, pool->id.phys_id);\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\t}\n+\n+\t/* Confirm that all the domain's queue's inflight counts and AQED\n+\t * active counts are 0.\n+\t */\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_queues, queue, iter) {\n+\t\tif (!dlb_ldb_queue_is_empty(hw, queue)) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: failed to empty ldb queue %d\\n\",\n+\t\t\t\t   __func__, queue->id.phys_id);\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\t}\n+\n+\t/* Confirm that all the domain's CQs inflight and token counts are 0. */\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, ldb_port, iter) {\n+\t\tif (dlb_ldb_cq_inflight_count(hw, ldb_port) ||\n+\t\t    dlb_ldb_cq_token_count(hw, ldb_port)) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: failed to empty ldb port %d\\n\",\n+\t\t\t\t   __func__, ldb_port->id.phys_id);\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\t}\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, dir_port, iter) {\n+\t\tif (!dlb_dir_queue_is_empty(hw, dir_port)) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: failed to empty dir queue %d\\n\",\n+\t\t\t\t   __func__, dir_port->id.phys_id);\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\n+\t\tif (dlb_dir_cq_token_count(hw, dir_port)) {\n+\t\t\tDLB_HW_ERR(hw,\n+\t\t\t\t   \"[%s()] Internal error: failed to empty dir port %d\\n\",\n+\t\t\t\t   __func__, dir_port->id.phys_id);\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void __dlb_domain_reset_ldb_port_registers(struct dlb_hw *hw,\n+\t\t\t\t\t\t  struct dlb_ldb_port *port)\n+{\n+\tunion dlb_chp_ldb_pp_state_reset r0 = { {0} };\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_PP_CRD_REQ_STATE(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_PP_CRD_REQ_STATE_RST);\n+\n+\t/* Reset the port's load-balanced and directed credit state */\n+\tr0.field.dir_type = 0;\n+\tr0.field.reset_pp_state = 1;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_PP_STATE_RESET(port->id.phys_id),\n+\t\t   r0.val);\n+\n+\tr0.field.dir_type = 1;\n+\tr0.field.reset_pp_state = 1;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_PP_STATE_RESET(port->id.phys_id),\n+\t\t   r0.val);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_PP_DIR_PUSH_PTR(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_PP_DIR_PUSH_PTR_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_PP_LDB_PUSH_PTR(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_PP_LDB_PUSH_PTR_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_PP_LDB_MIN_CRD_QNT(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_PP_LDB_MIN_CRD_QNT_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_PP_LDB_CRD_LWM(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_PP_LDB_CRD_LWM_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_PP_LDB_CRD_HWM(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_PP_LDB_CRD_HWM_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_LDB_PP2POOL(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_LDB_PP2POOL_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_PP_DIR_MIN_CRD_QNT(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_PP_DIR_MIN_CRD_QNT_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_PP_DIR_CRD_LWM(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_PP_DIR_CRD_LWM_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_PP_DIR_CRD_HWM(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_PP_DIR_CRD_HWM_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_DIR_PP2POOL(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_DIR_PP2POOL_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_PP2LDBPOOL(port->id.phys_id),\n+\t\t   DLB_SYS_LDB_PP2LDBPOOL_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_PP2DIRPOOL(port->id.phys_id),\n+\t\t   DLB_SYS_LDB_PP2DIRPOOL_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_HIST_LIST_LIM(port->id.phys_id),\n+\t\t   DLB_CHP_HIST_LIST_LIM_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_HIST_LIST_BASE(port->id.phys_id),\n+\t\t   DLB_CHP_HIST_LIST_BASE_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_HIST_LIST_POP_PTR(port->id.phys_id),\n+\t\t   DLB_CHP_HIST_LIST_POP_PTR_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_HIST_LIST_PUSH_PTR(port->id.phys_id),\n+\t\t   DLB_CHP_HIST_LIST_PUSH_PTR_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_CQ_WPTR(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_CQ_WPTR_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_CQ_INT_DEPTH_THRSH(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_CQ_INT_DEPTH_THRSH_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_CQ_TMR_THRESHOLD(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_CQ_TMR_THRESHOLD_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_CQ_INT_ENB(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_CQ_INT_ENB_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_LSP_CQ_LDB_INFL_LIM(port->id.phys_id),\n+\t\t   DLB_LSP_CQ_LDB_INFL_LIM_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_LSP_CQ2PRIOV(port->id.phys_id),\n+\t\t   DLB_LSP_CQ2PRIOV_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_LSP_CQ_LDB_TOT_SCH_CNT_CTRL(port->id.phys_id),\n+\t\t   DLB_LSP_CQ_LDB_TOT_SCH_CNT_CTRL_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_LSP_CQ_LDB_TKN_DEPTH_SEL(port->id.phys_id),\n+\t\t   DLB_LSP_CQ_LDB_TKN_DEPTH_SEL_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_LDB_CQ_TKN_DEPTH_SEL(port->id.phys_id),\n+\t\t   DLB_CHP_LDB_CQ_TKN_DEPTH_SEL_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_LSP_CQ_LDB_DSBL(port->id.phys_id),\n+\t\t   DLB_LSP_CQ_LDB_DSBL_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_CQ2VF_PF(port->id.phys_id),\n+\t\t   DLB_SYS_LDB_CQ2VF_PF_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_PP2VF_PF(port->id.phys_id),\n+\t\t   DLB_SYS_LDB_PP2VF_PF_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_CQ_ADDR_L(port->id.phys_id),\n+\t\t   DLB_SYS_LDB_CQ_ADDR_L_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_CQ_ADDR_U(port->id.phys_id),\n+\t\t   DLB_SYS_LDB_CQ_ADDR_U_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_PP_ADDR_L(port->id.phys_id),\n+\t\t   DLB_SYS_LDB_PP_ADDR_L_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_PP_ADDR_U(port->id.phys_id),\n+\t\t   DLB_SYS_LDB_PP_ADDR_U_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_PP_V(port->id.phys_id),\n+\t\t   DLB_SYS_LDB_PP_V_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_PP2VAS(port->id.phys_id),\n+\t\t   DLB_SYS_LDB_PP2VAS_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_LDB_CQ_ISR(port->id.phys_id),\n+\t\t   DLB_SYS_LDB_CQ_ISR_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_WBUF_LDB_FLAGS(port->id.phys_id),\n+\t\t   DLB_SYS_WBUF_LDB_FLAGS_RST);\n+}\n+\n+static void dlb_domain_reset_ldb_port_registers(struct dlb_hw *hw,\n+\t\t\t\t\t\tstruct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_port *port;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter)\n+\t\t__dlb_domain_reset_ldb_port_registers(hw, port);\n+}\n+\n+static void __dlb_domain_reset_dir_port_registers(struct dlb_hw *hw,\n+\t\t\t\t\t\t  struct dlb_dir_pq_pair *port)\n+{\n+\tunion dlb_chp_dir_pp_state_reset r0 = { {0} };\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_CRD_REQ_STATE(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_PP_CRD_REQ_STATE_RST);\n+\n+\t/* Reset the port's load-balanced and directed credit state */\n+\tr0.field.dir_type = 0;\n+\tr0.field.reset_pp_state = 1;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_STATE_RESET(port->id.phys_id),\n+\t\t   r0.val);\n+\n+\tr0.field.dir_type = 1;\n+\tr0.field.reset_pp_state = 1;\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_STATE_RESET(port->id.phys_id),\n+\t\t   r0.val);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_DIR_PUSH_PTR(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_PP_DIR_PUSH_PTR_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_LDB_PUSH_PTR(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_PP_LDB_PUSH_PTR_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_LDB_MIN_CRD_QNT(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_PP_LDB_MIN_CRD_QNT_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_LDB_CRD_LWM(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_PP_LDB_CRD_LWM_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_LDB_CRD_HWM(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_PP_LDB_CRD_HWM_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_LDB_PP2POOL(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_LDB_PP2POOL_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_DIR_MIN_CRD_QNT(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_PP_DIR_MIN_CRD_QNT_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_DIR_CRD_LWM(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_PP_DIR_CRD_LWM_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_PP_DIR_CRD_HWM(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_PP_DIR_CRD_HWM_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_DIR_PP2POOL(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_DIR_PP2POOL_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_PP2LDBPOOL(port->id.phys_id),\n+\t\t   DLB_SYS_DIR_PP2LDBPOOL_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_PP2DIRPOOL(port->id.phys_id),\n+\t\t   DLB_SYS_DIR_PP2DIRPOOL_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_CQ_WPTR(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_CQ_WPTR_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_LSP_CQ_DIR_TKN_DEPTH_SEL_DSI(port->id.phys_id),\n+\t\t   DLB_LSP_CQ_DIR_TKN_DEPTH_SEL_DSI_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_CQ_TKN_DEPTH_SEL(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_CQ_TKN_DEPTH_SEL_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_LSP_CQ_DIR_DSBL(port->id.phys_id),\n+\t\t   DLB_LSP_CQ_DIR_DSBL_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_CQ_WPTR(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_CQ_WPTR_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_CQ_INT_DEPTH_THRSH(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_CQ_INT_DEPTH_THRSH_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_CQ_TMR_THRESHOLD(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_CQ_TMR_THRESHOLD_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_CHP_DIR_CQ_INT_ENB(port->id.phys_id),\n+\t\t   DLB_CHP_DIR_CQ_INT_ENB_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_CQ2VF_PF(port->id.phys_id),\n+\t\t   DLB_SYS_DIR_CQ2VF_PF_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_PP2VF_PF(port->id.phys_id),\n+\t\t   DLB_SYS_DIR_PP2VF_PF_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_CQ_ADDR_L(port->id.phys_id),\n+\t\t   DLB_SYS_DIR_CQ_ADDR_L_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_CQ_ADDR_U(port->id.phys_id),\n+\t\t   DLB_SYS_DIR_CQ_ADDR_U_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_PP_ADDR_L(port->id.phys_id),\n+\t\t   DLB_SYS_DIR_PP_ADDR_L_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_PP_ADDR_U(port->id.phys_id),\n+\t\t   DLB_SYS_DIR_PP_ADDR_U_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_PP_V(port->id.phys_id),\n+\t\t   DLB_SYS_DIR_PP_V_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_PP2VAS(port->id.phys_id),\n+\t\t   DLB_SYS_DIR_PP2VAS_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_DIR_CQ_ISR(port->id.phys_id),\n+\t\t   DLB_SYS_DIR_CQ_ISR_RST);\n+\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_SYS_WBUF_DIR_FLAGS(port->id.phys_id),\n+\t\t   DLB_SYS_WBUF_DIR_FLAGS_RST);\n+}\n+\n+static void dlb_domain_reset_dir_port_registers(struct dlb_hw *hw,\n+\t\t\t\t\t\tstruct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_dir_pq_pair *port;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, port, iter)\n+\t\t__dlb_domain_reset_dir_port_registers(hw, port);\n+}\n+\n+static void dlb_domain_reset_ldb_queue_registers(struct dlb_hw *hw,\n+\t\t\t\t\t\t struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_queue *queue;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_queues, queue, iter) {\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_AQED_PIPE_FL_LIM(queue->id.phys_id),\n+\t\t\t   DLB_AQED_PIPE_FL_LIM_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_AQED_PIPE_FL_BASE(queue->id.phys_id),\n+\t\t\t   DLB_AQED_PIPE_FL_BASE_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_AQED_PIPE_FL_POP_PTR(queue->id.phys_id),\n+\t\t\t   DLB_AQED_PIPE_FL_POP_PTR_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_AQED_PIPE_FL_PUSH_PTR(queue->id.phys_id),\n+\t\t\t   DLB_AQED_PIPE_FL_PUSH_PTR_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_AQED_PIPE_QID_FID_LIM(queue->id.phys_id),\n+\t\t\t   DLB_AQED_PIPE_QID_FID_LIM_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_LSP_QID_AQED_ACTIVE_LIM(queue->id.phys_id),\n+\t\t\t   DLB_LSP_QID_AQED_ACTIVE_LIM_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_LSP_QID_LDB_INFL_LIM(queue->id.phys_id),\n+\t\t\t   DLB_LSP_QID_LDB_INFL_LIM_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_SYS_LDB_QID_V(queue->id.phys_id),\n+\t\t\t   DLB_SYS_LDB_QID_V_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_SYS_LDB_QID_V(queue->id.phys_id),\n+\t\t\t   DLB_SYS_LDB_QID_V_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_ORD_QID_SN(queue->id.phys_id),\n+\t\t\t   DLB_CHP_ORD_QID_SN_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_ORD_QID_SN_MAP(queue->id.phys_id),\n+\t\t\t   DLB_CHP_ORD_QID_SN_MAP_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_RO_PIPE_QID2GRPSLT(queue->id.phys_id),\n+\t\t\t   DLB_RO_PIPE_QID2GRPSLT_RST);\n+\t}\n+}\n+\n+static void dlb_domain_reset_dir_queue_registers(struct dlb_hw *hw,\n+\t\t\t\t\t\t struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_dir_pq_pair *queue;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, queue, iter) {\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_SYS_DIR_QID_V(queue->id.phys_id),\n+\t\t\t   DLB_SYS_DIR_QID_V_RST);\n+\t}\n+}\n+\n+static void dlb_domain_reset_ldb_pool_registers(struct dlb_hw *hw,\n+\t\t\t\t\t\tstruct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_credit_pool *pool;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_credit_pools, pool, iter) {\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_LDB_POOL_CRD_LIM(pool->id.phys_id),\n+\t\t\t   DLB_CHP_LDB_POOL_CRD_LIM_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_LDB_POOL_CRD_CNT(pool->id.phys_id),\n+\t\t\t   DLB_CHP_LDB_POOL_CRD_CNT_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_QED_FL_BASE(pool->id.phys_id),\n+\t\t\t   DLB_CHP_QED_FL_BASE_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_QED_FL_LIM(pool->id.phys_id),\n+\t\t\t   DLB_CHP_QED_FL_LIM_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_QED_FL_PUSH_PTR(pool->id.phys_id),\n+\t\t\t   DLB_CHP_QED_FL_PUSH_PTR_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_QED_FL_POP_PTR(pool->id.phys_id),\n+\t\t\t   DLB_CHP_QED_FL_POP_PTR_RST);\n+\t}\n+}\n+\n+static void dlb_domain_reset_dir_pool_registers(struct dlb_hw *hw,\n+\t\t\t\t\t\tstruct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_credit_pool *pool;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_credit_pools, pool, iter) {\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_DIR_POOL_CRD_LIM(pool->id.phys_id),\n+\t\t\t   DLB_CHP_DIR_POOL_CRD_LIM_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_DIR_POOL_CRD_CNT(pool->id.phys_id),\n+\t\t\t   DLB_CHP_DIR_POOL_CRD_CNT_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_DQED_FL_BASE(pool->id.phys_id),\n+\t\t\t   DLB_CHP_DQED_FL_BASE_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_DQED_FL_LIM(pool->id.phys_id),\n+\t\t\t   DLB_CHP_DQED_FL_LIM_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_DQED_FL_PUSH_PTR(pool->id.phys_id),\n+\t\t\t   DLB_CHP_DQED_FL_PUSH_PTR_RST);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_DQED_FL_POP_PTR(pool->id.phys_id),\n+\t\t\t   DLB_CHP_DQED_FL_POP_PTR_RST);\n+\t}\n+}\n+\n+static void dlb_domain_reset_registers(struct dlb_hw *hw,\n+\t\t\t\t       struct dlb_domain *domain)\n+{\n+\tdlb_domain_reset_ldb_port_registers(hw, domain);\n+\n+\tdlb_domain_reset_dir_port_registers(hw, domain);\n+\n+\tdlb_domain_reset_ldb_queue_registers(hw, domain);\n+\n+\tdlb_domain_reset_dir_queue_registers(hw, domain);\n+\n+\tdlb_domain_reset_ldb_pool_registers(hw, domain);\n+\n+\tdlb_domain_reset_dir_pool_registers(hw, domain);\n+}\n+\n+static int dlb_domain_drain_ldb_cqs(struct dlb_hw *hw,\n+\t\t\t\t    struct dlb_domain *domain,\n+\t\t\t\t    bool toggle_port)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_port *port;\n+\tint ret;\n+\n+\t/* If the domain hasn't been started, there's no traffic to drain */\n+\tif (!domain->started)\n+\t\treturn 0;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter) {\n+\t\tif (toggle_port)\n+\t\t\tdlb_ldb_port_cq_disable(hw, port);\n+\n+\t\tret = dlb_drain_ldb_cq(hw, port);\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\n+\t\tif (toggle_port)\n+\t\t\tdlb_ldb_port_cq_enable(hw, port);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static bool dlb_domain_mapped_queues_empty(struct dlb_hw *hw,\n+\t\t\t\t\t   struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_queue *queue;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_queues, queue, iter) {\n+\t\tif (queue->num_mappings == 0)\n+\t\t\tcontinue;\n+\n+\t\tif (!dlb_ldb_queue_is_empty(hw, queue))\n+\t\t\treturn false;\n+\t}\n+\n+\treturn true;\n+}\n+\n+static int dlb_domain_drain_mapped_queues(struct dlb_hw *hw,\n+\t\t\t\t\t  struct dlb_domain *domain)\n+{\n+\tint i, ret;\n+\n+\t/* If the domain hasn't been started, there's no traffic to drain */\n+\tif (!domain->started)\n+\t\treturn 0;\n+\n+\tif (domain->num_pending_removals > 0) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: failed to unmap domain queues\\n\",\n+\t\t\t   __func__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tfor (i = 0; i < DLB_MAX_QID_EMPTY_CHECK_LOOPS; i++) {\n+\t\tret = dlb_domain_drain_ldb_cqs(hw, domain, true);\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\n+\t\tif (dlb_domain_mapped_queues_empty(hw, domain))\n+\t\t\tbreak;\n+\t}\n+\n+\tif (i == DLB_MAX_QID_EMPTY_CHECK_LOOPS) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: failed to empty queues\\n\",\n+\t\t\t   __func__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\t/* Drain the CQs one more time. For the queues to go empty, they would\n+\t * have scheduled one or more QEs.\n+\t */\n+\tret = dlb_domain_drain_ldb_cqs(hw, domain, true);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+\n+static int dlb_domain_drain_unmapped_queue(struct dlb_hw *hw,\n+\t\t\t\t\t   struct dlb_domain *domain,\n+\t\t\t\t\t   struct dlb_ldb_queue *queue)\n+{\n+\tstruct dlb_ldb_port *port;\n+\tint ret;\n+\n+\t/* If a domain has LDB queues, it must have LDB ports */\n+\tif (dlb_list_empty(&domain->used_ldb_ports)) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: No configured LDB ports\\n\",\n+\t\t\t   __func__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tport = DLB_DOM_LIST_HEAD(domain->used_ldb_ports, typeof(*port));\n+\n+\t/* If necessary, free up a QID slot in this CQ */\n+\tif (port->num_mappings == DLB_MAX_NUM_QIDS_PER_LDB_CQ) {\n+\t\tstruct dlb_ldb_queue *mapped_queue;\n+\n+\t\tmapped_queue = &hw->rsrcs.ldb_queues[port->qid_map[0].qid];\n+\n+\t\tret = dlb_ldb_port_unmap_qid(hw, port, mapped_queue);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\tret = dlb_ldb_port_map_qid_dynamic(hw, port, queue, 0);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn dlb_domain_drain_mapped_queues(hw, domain);\n+}\n+\n+static int dlb_domain_drain_unmapped_queues(struct dlb_hw *hw,\n+\t\t\t\t\t    struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_queue *queue;\n+\tint ret;\n+\n+\t/* If the domain hasn't been started, there's no traffic to drain */\n+\tif (!domain->started)\n+\t\treturn 0;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_queues, queue, iter) {\n+\t\tif (queue->num_mappings != 0 ||\n+\t\t    dlb_ldb_queue_is_empty(hw, queue))\n+\t\t\tcontinue;\n+\n+\t\tret = dlb_domain_drain_unmapped_queue(hw, domain, queue);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void dlb_drain_dir_cq(struct dlb_hw *hw, struct dlb_dir_pq_pair *port)\n+{\n+\tunsigned int port_id = port->id.phys_id;\n+\tu32 cnt;\n+\n+\t/* Return any outstanding tokens */\n+\tcnt = dlb_dir_cq_token_count(hw, port);\n+\n+\tif (cnt != 0) {\n+\t\tstruct dlb_hcw hcw_mem[8], *hcw;\n+\t\tvoid  *pp_addr;\n+\n+\t\tpp_addr = os_map_producer_port(hw, port_id, false);\n+\n+\t\t/* Point hcw to a 64B-aligned location */\n+\t\thcw = (struct dlb_hcw *)((uintptr_t)&hcw_mem[4] & ~0x3F);\n+\n+\t\t/* Program the first HCW for a batch token return and\n+\t\t * the rest as NOOPS\n+\t\t */\n+\t\tmemset(hcw, 0, 4 * sizeof(*hcw));\n+\t\thcw->cq_token = 1;\n+\t\thcw->lock_id = cnt - 1;\n+\n+\t\tos_enqueue_four_hcws(hw, hcw, pp_addr);\n+\n+\t\tos_fence_hcw(hw, pp_addr);\n+\n+\t\tos_unmap_producer_port(hw, pp_addr);\n+\t}\n+}\n+\n+static int dlb_domain_drain_dir_cqs(struct dlb_hw *hw,\n+\t\t\t\t    struct dlb_domain *domain,\n+\t\t\t\t    bool toggle_port)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_dir_pq_pair *port;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, port, iter) {\n+\t\t/* Can't drain a port if it's not configured, and there's\n+\t\t * nothing to drain if its queue is unconfigured.\n+\t\t */\n+\t\tif (!port->port_configured || !port->queue_configured)\n+\t\t\tcontinue;\n+\n+\t\tif (toggle_port)\n+\t\t\tdlb_dir_port_cq_disable(hw, port);\n+\n+\t\tdlb_drain_dir_cq(hw, port);\n+\n+\t\tif (toggle_port)\n+\t\t\tdlb_dir_port_cq_enable(hw, port);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static bool dlb_domain_dir_queues_empty(struct dlb_hw *hw,\n+\t\t\t\t\tstruct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_dir_pq_pair *queue;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, queue, iter) {\n+\t\tif (!dlb_dir_queue_is_empty(hw, queue))\n+\t\t\treturn false;\n+\t}\n+\n+\treturn true;\n+}\n+\n+static int dlb_domain_drain_dir_queues(struct dlb_hw *hw,\n+\t\t\t\t       struct dlb_domain *domain)\n+{\n+\tint i;\n+\n+\t/* If the domain hasn't been started, there's no traffic to drain */\n+\tif (!domain->started)\n+\t\treturn 0;\n+\n+\tfor (i = 0; i < DLB_MAX_QID_EMPTY_CHECK_LOOPS; i++) {\n+\t\tdlb_domain_drain_dir_cqs(hw, domain, true);\n+\n+\t\tif (dlb_domain_dir_queues_empty(hw, domain))\n+\t\t\tbreak;\n+\t}\n+\n+\tif (i == DLB_MAX_QID_EMPTY_CHECK_LOOPS) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: failed to empty queues\\n\",\n+\t\t\t   __func__);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\t/* Drain the CQs one more time. For the queues to go empty, they would\n+\t * have scheduled one or more QEs.\n+\t */\n+\tdlb_domain_drain_dir_cqs(hw, domain, true);\n+\n+\treturn 0;\n+}\n+\n+static void dlb_domain_disable_dir_producer_ports(struct dlb_hw *hw,\n+\t\t\t\t\t\t  struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_dir_pq_pair *port;\n+\tunion dlb_sys_dir_pp_v r1;\n+\n+\tr1.field.pp_v = 0;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, port, iter)\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_SYS_DIR_PP_V(port->id.phys_id),\n+\t\t\t   r1.val);\n+}\n+\n+static void dlb_domain_disable_ldb_producer_ports(struct dlb_hw *hw,\n+\t\t\t\t\t\t  struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tunion dlb_sys_ldb_pp_v r1;\n+\tstruct dlb_ldb_port *port;\n+\n+\tr1.field.pp_v = 0;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter) {\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_SYS_LDB_PP_V(port->id.phys_id),\n+\t\t\t   r1.val);\n+\n+\t\thw->pf.num_enabled_ldb_ports--;\n+\t}\n+}\n+\n+static void dlb_domain_disable_dir_vpps(struct dlb_hw *hw,\n+\t\t\t\t\tstruct dlb_domain *domain,\n+\t\t\t\t\tunsigned int vf_id)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tunion dlb_sys_vf_dir_vpp_v r1;\n+\tstruct dlb_dir_pq_pair *port;\n+\n+\tr1.field.vpp_v = 0;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, port, iter) {\n+\t\tunsigned int offs;\n+\n+\t\toffs = vf_id * DLB_MAX_NUM_DIR_PORTS + port->id.virt_id;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_VF_DIR_VPP_V(offs), r1.val);\n+\t}\n+}\n+\n+static void dlb_domain_disable_ldb_vpps(struct dlb_hw *hw,\n+\t\t\t\t\tstruct dlb_domain *domain,\n+\t\t\t\t\tunsigned int vf_id)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tunion dlb_sys_vf_ldb_vpp_v r1;\n+\tstruct dlb_ldb_port *port;\n+\n+\tr1.field.vpp_v = 0;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter) {\n+\t\tunsigned int offs;\n+\n+\t\toffs = vf_id * DLB_MAX_NUM_LDB_PORTS + port->id.virt_id;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_VF_LDB_VPP_V(offs), r1.val);\n+\t}\n+}\n+\n+static void dlb_domain_disable_dir_pools(struct dlb_hw *hw,\n+\t\t\t\t\t struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tunion dlb_sys_dir_pool_enbld r0 = { {0} };\n+\tstruct dlb_credit_pool *pool;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_credit_pools, pool, iter)\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_SYS_DIR_POOL_ENBLD(pool->id.phys_id),\n+\t\t\t   r0.val);\n+}\n+\n+static void dlb_domain_disable_ldb_pools(struct dlb_hw *hw,\n+\t\t\t\t\t struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tunion dlb_sys_ldb_pool_enbld r0 = { {0} };\n+\tstruct dlb_credit_pool *pool;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_credit_pools, pool, iter)\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_SYS_LDB_POOL_ENBLD(pool->id.phys_id),\n+\t\t\t   r0.val);\n+}\n+\n+static void dlb_domain_disable_ldb_seq_checks(struct dlb_hw *hw,\n+\t\t\t\t\t      struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tunion dlb_chp_sn_chk_enbl r1;\n+\tstruct dlb_ldb_port *port;\n+\n+\tr1.field.en = 0;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter)\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_SN_CHK_ENBL(port->id.phys_id),\n+\t\t\t   r1.val);\n+}\n+\n+static void dlb_domain_disable_ldb_port_crd_updates(struct dlb_hw *hw,\n+\t\t\t\t\t\t    struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tunion dlb_chp_ldb_pp_crd_req_state r0;\n+\tstruct dlb_ldb_port *port;\n+\n+\tr0.field.no_pp_credit_update = 1;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter)\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_LDB_PP_CRD_REQ_STATE(port->id.phys_id),\n+\t\t\t   r0.val);\n+}\n+\n+static void dlb_domain_disable_ldb_port_interrupts(struct dlb_hw *hw,\n+\t\t\t\t\t\t   struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tunion dlb_chp_ldb_cq_int_enb r0 = { {0} };\n+\tunion dlb_chp_ldb_cq_wd_enb r1 = { {0} };\n+\tstruct dlb_ldb_port *port;\n+\n+\tr0.field.en_tim = 0;\n+\tr0.field.en_depth = 0;\n+\n+\tr1.field.wd_enable = 0;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter) {\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_LDB_CQ_INT_ENB(port->id.phys_id),\n+\t\t\t   r0.val);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_LDB_CQ_WD_ENB(port->id.phys_id),\n+\t\t\t   r1.val);\n+\t}\n+}\n+\n+static void dlb_domain_disable_dir_port_interrupts(struct dlb_hw *hw,\n+\t\t\t\t\t\t   struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tunion dlb_chp_dir_cq_int_enb r0 = { {0} };\n+\tunion dlb_chp_dir_cq_wd_enb r1 = { {0} };\n+\tstruct dlb_dir_pq_pair *port;\n+\n+\tr0.field.en_tim = 0;\n+\tr0.field.en_depth = 0;\n+\n+\tr1.field.wd_enable = 0;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, port, iter) {\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_DIR_CQ_INT_ENB(port->id.phys_id),\n+\t\t\t   r0.val);\n+\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_DIR_CQ_WD_ENB(port->id.phys_id),\n+\t\t\t   r1.val);\n+\t}\n+}\n+\n+static void dlb_domain_disable_dir_port_crd_updates(struct dlb_hw *hw,\n+\t\t\t\t\t\t    struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tunion dlb_chp_dir_pp_crd_req_state r0;\n+\tstruct dlb_dir_pq_pair *port;\n+\n+\tr0.field.no_pp_credit_update = 1;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, port, iter)\n+\t\tDLB_CSR_WR(hw,\n+\t\t\t   DLB_CHP_DIR_PP_CRD_REQ_STATE(port->id.phys_id),\n+\t\t\t   r0.val);\n+}\n+\n+static void dlb_domain_disable_ldb_queue_write_perms(struct dlb_hw *hw,\n+\t\t\t\t\t\t     struct dlb_domain *domain)\n+{\n+\tint domain_offset = domain->id.phys_id * DLB_MAX_NUM_LDB_QUEUES;\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tunion dlb_sys_ldb_vasqid_v r0;\n+\tstruct dlb_ldb_queue *queue;\n+\n+\tr0.field.vasqid_v = 0;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_queues, queue, iter) {\n+\t\tint idx = domain_offset + queue->id.phys_id;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_LDB_VASQID_V(idx), r0.val);\n+\t}\n+}\n+\n+static void dlb_domain_disable_dir_queue_write_perms(struct dlb_hw *hw,\n+\t\t\t\t\t\t     struct dlb_domain *domain)\n+{\n+\tint domain_offset = domain->id.phys_id * DLB_MAX_NUM_DIR_PORTS;\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tunion dlb_sys_dir_vasqid_v r0;\n+\tstruct dlb_dir_pq_pair *port;\n+\n+\tr0.field.vasqid_v = 0;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, port, iter) {\n+\t\tint idx = domain_offset + port->id.phys_id;\n+\n+\t\tDLB_CSR_WR(hw, DLB_SYS_DIR_VASQID_V(idx), r0.val);\n+\t}\n+}\n+\n+static void dlb_domain_disable_dir_cqs(struct dlb_hw *hw,\n+\t\t\t\t       struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_dir_pq_pair *port;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, port, iter) {\n+\t\tport->enabled = false;\n+\n+\t\tdlb_dir_port_cq_disable(hw, port);\n+\t}\n+}\n+\n+static void dlb_domain_disable_ldb_cqs(struct dlb_hw *hw,\n+\t\t\t\t       struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_port *port;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter) {\n+\t\tport->enabled = false;\n+\n+\t\tdlb_ldb_port_cq_disable(hw, port);\n+\t}\n+}\n+\n+static void dlb_domain_enable_ldb_cqs(struct dlb_hw *hw,\n+\t\t\t\t      struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_ldb_port *port;\n+\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, port, iter) {\n+\t\tport->enabled = true;\n+\n+\t\tdlb_ldb_port_cq_enable(hw, port);\n+\t}\n+}\n+\n+static int dlb_domain_wait_for_ldb_pool_refill(struct dlb_hw *hw,\n+\t\t\t\t\t       struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_credit_pool *pool;\n+\n+\t/* Confirm that all credits are returned to the domain's credit pools */\n+\tDLB_DOM_LIST_FOR(domain->used_ldb_credit_pools, pool, iter) {\n+\t\tunion dlb_chp_qed_fl_push_ptr r0;\n+\t\tunion dlb_chp_qed_fl_pop_ptr r1;\n+\t\tunsigned long pop_offs, push_offs;\n+\t\tint i;\n+\n+\t\tpush_offs = DLB_CHP_QED_FL_PUSH_PTR(pool->id.phys_id);\n+\t\tpop_offs = DLB_CHP_QED_FL_POP_PTR(pool->id.phys_id);\n+\n+\t\tfor (i = 0; i < DLB_MAX_QID_EMPTY_CHECK_LOOPS; i++) {\n+\t\t\tr0.val = DLB_CSR_RD(hw, push_offs);\n+\n+\t\t\tr1.val = DLB_CSR_RD(hw, pop_offs);\n+\n+\t\t\t/* Break early if the freelist is replenished */\n+\t\t\tif (r1.field.pop_ptr == r0.field.push_ptr &&\n+\t\t\t    r1.field.generation != r0.field.generation) {\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\t/* Error if the freelist is not full */\n+\t\tif (r1.field.pop_ptr != r0.field.push_ptr ||\n+\t\t    r1.field.generation == r0.field.generation) {\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int dlb_domain_wait_for_dir_pool_refill(struct dlb_hw *hw,\n+\t\t\t\t\t       struct dlb_domain *domain)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_credit_pool *pool;\n+\n+\t/* Confirm that all credits are returned to the domain's credit pools */\n+\tDLB_DOM_LIST_FOR(domain->used_dir_credit_pools, pool, iter) {\n+\t\tunion dlb_chp_dqed_fl_push_ptr r0;\n+\t\tunion dlb_chp_dqed_fl_pop_ptr r1;\n+\t\tunsigned long pop_offs, push_offs;\n+\t\tint i;\n+\n+\t\tpush_offs = DLB_CHP_DQED_FL_PUSH_PTR(pool->id.phys_id);\n+\t\tpop_offs = DLB_CHP_DQED_FL_POP_PTR(pool->id.phys_id);\n+\n+\t\tfor (i = 0; i < DLB_MAX_QID_EMPTY_CHECK_LOOPS; i++) {\n+\t\t\tr0.val = DLB_CSR_RD(hw, push_offs);\n+\n+\t\t\tr1.val = DLB_CSR_RD(hw, pop_offs);\n+\n+\t\t\t/* Break early if the freelist is replenished */\n+\t\t\tif (r1.field.pop_ptr == r0.field.push_ptr &&\n+\t\t\t    r1.field.generation != r0.field.generation) {\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\t/* Error if the freelist is not full */\n+\t\tif (r1.field.pop_ptr != r0.field.push_ptr ||\n+\t\t    r1.field.generation == r0.field.generation) {\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void dlb_log_reset_domain(struct dlb_hw *hw,\n+\t\t\t\t u32 domain_id,\n+\t\t\t\t bool vf_request,\n+\t\t\t\t unsigned int vf_id)\n+{\n+\tDLB_HW_INFO(hw, \"DLB reset domain:\\n\");\n+\tif (vf_request)\n+\t\tDLB_HW_INFO(hw, \"(Request from VF %d)\\n\", vf_id);\n+\tDLB_HW_INFO(hw, \"\\tDomain ID: %d\\n\", domain_id);\n+}\n+\n+/**\n+ * dlb_reset_domain() - Reset a DLB scheduling domain and its associated\n+ *\thardware resources.\n+ * @hw:\t  Contains the current state of the DLB hardware.\n+ * @args: User-provided arguments.\n+ * @resp: Response to user.\n+ *\n+ * Note: User software *must* stop sending to this domain's producer ports\n+ * before invoking this function, otherwise undefined behavior will result.\n+ *\n+ * Return: returns < 0 on error, 0 otherwise.\n+ */\n+int dlb_reset_domain(struct dlb_hw *hw,\n+\t\t     u32 domain_id,\n+\t\t     bool vf_request,\n+\t\t     unsigned int vf_id)\n+{\n+\tstruct dlb_domain *domain;\n+\tint ret;\n+\n+\tdlb_log_reset_domain(hw, domain_id, vf_request, vf_id);\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_id);\n+\n+\tif (!domain || !domain->configured)\n+\t\treturn -EINVAL;\n+\n+\tif (vf_request) {\n+\t\tdlb_domain_disable_dir_vpps(hw, domain, vf_id);\n+\n+\t\tdlb_domain_disable_ldb_vpps(hw, domain, vf_id);\n+\t}\n+\n+\t/* For each queue owned by this domain, disable its write permissions to\n+\t * cause any traffic sent to it to be dropped. Well-behaved software\n+\t * should not be sending QEs at this point.\n+\t */\n+\tdlb_domain_disable_dir_queue_write_perms(hw, domain);\n+\n+\tdlb_domain_disable_ldb_queue_write_perms(hw, domain);\n+\n+\t/* Disable credit updates and turn off completion tracking on all the\n+\t * domain's PPs.\n+\t */\n+\tdlb_domain_disable_dir_port_crd_updates(hw, domain);\n+\n+\tdlb_domain_disable_ldb_port_crd_updates(hw, domain);\n+\n+\tdlb_domain_disable_dir_port_interrupts(hw, domain);\n+\n+\tdlb_domain_disable_ldb_port_interrupts(hw, domain);\n+\n+\tdlb_domain_disable_ldb_seq_checks(hw, domain);\n+\n+\t/* Disable the LDB CQs and drain them in order to complete the map and\n+\t * unmap procedures, which require zero CQ inflights and zero QID\n+\t * inflights respectively.\n+\t */\n+\tdlb_domain_disable_ldb_cqs(hw, domain);\n+\n+\tret = dlb_domain_drain_ldb_cqs(hw, domain, false);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_domain_wait_for_ldb_cqs_to_empty(hw, domain);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_domain_finish_unmap_qid_procedures(hw, domain);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_domain_finish_map_qid_procedures(hw, domain);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\t/* Re-enable the CQs in order to drain the mapped queues. */\n+\tdlb_domain_enable_ldb_cqs(hw, domain);\n+\n+\tret = dlb_domain_drain_mapped_queues(hw, domain);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_domain_drain_unmapped_queues(hw, domain);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = dlb_domain_wait_for_ldb_pool_refill(hw, domain);\n+\tif (ret) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: LDB credits failed to refill\\n\",\n+\t\t\t   __func__);\n+\t\treturn ret;\n+\t}\n+\n+\t/* Done draining LDB QEs, so disable the CQs. */\n+\tdlb_domain_disable_ldb_cqs(hw, domain);\n+\n+\t/* Directed queues are reset in dlb_domain_reset_hw_resources(), but\n+\t * that process doesn't decrement the directed queue size counters used\n+\t * by SMON for its average DQED depth measurement. So, we manually drain\n+\t * the directed queues here.\n+\t */\n+\tdlb_domain_drain_dir_queues(hw, domain);\n+\n+\tret = dlb_domain_wait_for_dir_pool_refill(hw, domain);\n+\tif (ret) {\n+\t\tDLB_HW_ERR(hw,\n+\t\t\t   \"[%s()] Internal error: DIR credits failed to refill\\n\",\n+\t\t\t   __func__);\n+\t\treturn ret;\n+\t}\n+\n+\t/* Done draining DIR QEs, so disable the CQs. */\n+\tdlb_domain_disable_dir_cqs(hw, domain);\n+\n+\tdlb_domain_disable_dir_producer_ports(hw, domain);\n+\n+\tdlb_domain_disable_ldb_producer_ports(hw, domain);\n+\n+\tdlb_domain_disable_dir_pools(hw, domain);\n+\n+\tdlb_domain_disable_ldb_pools(hw, domain);\n+\n+\t/* Reset the QID, credit pool, and CQ hardware.\n+\t *\n+\t * Note: DLB 1.0 A0 h/w does not disarm CQ interrupts during VAS reset.\n+\t * A spurious interrupt can occur on subsequent use of a reset CQ.\n+\t */\n+\tret = dlb_domain_reset_hw_resources(hw, domain);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = dlb_domain_verify_reset_success(hw, domain);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tdlb_domain_reset_registers(hw, domain);\n+\n+\t/* Hardware reset complete. Reset the domain's software state */\n+\tret = dlb_domain_reset_software_state(hw, domain);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+\n+int dlb_reset_vf(struct dlb_hw *hw, unsigned int vf_id)\n+{\n+\tstruct dlb_domain *domain, *next __attribute__((unused));\n+\tstruct dlb_list_entry *it1 __attribute__((unused));\n+\tstruct dlb_list_entry *it2 __attribute__((unused));\n+\tstruct dlb_function_resources *rsrcs;\n+\n+\tif (vf_id >= DLB_MAX_NUM_VFS) {\n+\t\tDLB_HW_ERR(hw, \"[%s()] Internal error: invalid VF ID %d\\n\",\n+\t\t\t   __func__, vf_id);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\trsrcs = &hw->vf[vf_id];\n+\n+\tDLB_FUNC_LIST_FOR_SAFE(rsrcs->used_domains, domain, next, it1, it2) {\n+\t\tint ret = dlb_reset_domain(hw,\n+\t\t\t\t\t   domain->id.virt_id,\n+\t\t\t\t\t   true,\n+\t\t\t\t\t   vf_id);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int dlb_ldb_port_owned_by_domain(struct dlb_hw *hw,\n+\t\t\t\t u32 domain_id,\n+\t\t\t\t u32 port_id,\n+\t\t\t\t bool vf_request,\n+\t\t\t\t unsigned int vf_id)\n+{\n+\tstruct dlb_ldb_port *port;\n+\tstruct dlb_domain *domain;\n+\n+\tif (vf_request && vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -1;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_id);\n+\n+\tif (!domain || !domain->configured)\n+\t\treturn -EINVAL;\n+\n+\tport = dlb_get_domain_ldb_port(port_id, vf_request, domain);\n+\n+\tif (!port)\n+\t\treturn -EINVAL;\n+\n+\treturn port->domain_id.phys_id == domain->id.phys_id;\n+}\n+\n+int dlb_dir_port_owned_by_domain(struct dlb_hw *hw,\n+\t\t\t\t u32 domain_id,\n+\t\t\t\t u32 port_id,\n+\t\t\t\t bool vf_request,\n+\t\t\t\t unsigned int vf_id)\n+{\n+\tstruct dlb_dir_pq_pair *port;\n+\tstruct dlb_domain *domain;\n+\n+\tif (vf_request && vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -1;\n+\n+\tdomain = dlb_get_domain_from_id(hw, domain_id, vf_request, vf_id);\n+\n+\tif (!domain || !domain->configured)\n+\t\treturn -EINVAL;\n+\n+\tport = dlb_get_domain_dir_pq(port_id, vf_request, domain);\n+\n+\tif (!port)\n+\t\treturn -EINVAL;\n+\n+\treturn port->domain_id.phys_id == domain->id.phys_id;\n+}\n+\n+int dlb_hw_get_num_resources(struct dlb_hw *hw,\n+\t\t\t     struct dlb_get_num_resources_args *arg,\n+\t\t\t     bool vf_request,\n+\t\t\t     unsigned int vf_id)\n+{\n+\tstruct dlb_function_resources *rsrcs;\n+\tstruct dlb_bitmap *map;\n+\n+\tif (vf_request && vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -1;\n+\n+\tif (vf_request)\n+\t\trsrcs = &hw->vf[vf_id];\n+\telse\n+\t\trsrcs = &hw->pf;\n+\n+\targ->num_sched_domains = rsrcs->num_avail_domains;\n+\n+\targ->num_ldb_queues = rsrcs->num_avail_ldb_queues;\n+\n+\targ->num_ldb_ports = rsrcs->num_avail_ldb_ports;\n+\n+\targ->num_dir_ports = rsrcs->num_avail_dir_pq_pairs;\n+\n+\tmap = rsrcs->avail_aqed_freelist_entries;\n+\n+\targ->num_atomic_inflights = dlb_bitmap_count(map);\n+\n+\targ->max_contiguous_atomic_inflights =\n+\t\tdlb_bitmap_longest_set_range(map);\n+\n+\tmap = rsrcs->avail_hist_list_entries;\n+\n+\targ->num_hist_list_entries = dlb_bitmap_count(map);\n+\n+\targ->max_contiguous_hist_list_entries =\n+\t\tdlb_bitmap_longest_set_range(map);\n+\n+\tmap = rsrcs->avail_qed_freelist_entries;\n+\n+\targ->num_ldb_credits = dlb_bitmap_count(map);\n+\n+\targ->max_contiguous_ldb_credits = dlb_bitmap_longest_set_range(map);\n+\n+\tmap = rsrcs->avail_dqed_freelist_entries;\n+\n+\targ->num_dir_credits = dlb_bitmap_count(map);\n+\n+\targ->max_contiguous_dir_credits = dlb_bitmap_longest_set_range(map);\n+\n+\targ->num_ldb_credit_pools = rsrcs->num_avail_ldb_credit_pools;\n+\n+\targ->num_dir_credit_pools = rsrcs->num_avail_dir_credit_pools;\n+\n+\treturn 0;\n+}\n+\n+int dlb_hw_get_num_used_resources(struct dlb_hw *hw,\n+\t\t\t\t  struct dlb_get_num_resources_args *arg,\n+\t\t\t\t  bool vf_request,\n+\t\t\t\t  unsigned int vf_id)\n+{\n+\tstruct dlb_list_entry *iter1 __attribute__((unused));\n+\tstruct dlb_list_entry *iter2 __attribute__((unused));\n+\tstruct dlb_function_resources *rsrcs;\n+\tstruct dlb_domain *domain;\n+\n+\tif (vf_request && vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -1;\n+\n+\trsrcs = (vf_request) ? &hw->vf[vf_id] : &hw->pf;\n+\n+\tmemset(arg, 0, sizeof(*arg));\n+\n+\tDLB_FUNC_LIST_FOR(rsrcs->used_domains, domain, iter1) {\n+\t\tstruct dlb_dir_pq_pair *dir_port;\n+\t\tstruct dlb_ldb_port *ldb_port;\n+\t\tstruct dlb_credit_pool *pool;\n+\t\tstruct dlb_ldb_queue *queue;\n+\n+\t\targ->num_sched_domains++;\n+\n+\t\targ->num_atomic_inflights +=\n+\t\t\tdomain->aqed_freelist.bound -\n+\t\t\tdomain->aqed_freelist.base;\n+\n+\t\tDLB_DOM_LIST_FOR(domain->used_ldb_queues, queue, iter2)\n+\t\t\targ->num_ldb_queues++;\n+\t\tDLB_DOM_LIST_FOR(domain->avail_ldb_queues, queue, iter2)\n+\t\t\targ->num_ldb_queues++;\n+\n+\t\tDLB_DOM_LIST_FOR(domain->used_ldb_ports, ldb_port, iter2)\n+\t\t\targ->num_ldb_ports++;\n+\t\tDLB_DOM_LIST_FOR(domain->avail_ldb_ports, ldb_port, iter2)\n+\t\t\targ->num_ldb_ports++;\n+\n+\t\tDLB_DOM_LIST_FOR(domain->used_dir_pq_pairs, dir_port, iter2)\n+\t\t\targ->num_dir_ports++;\n+\t\tDLB_DOM_LIST_FOR(domain->avail_dir_pq_pairs, dir_port, iter2)\n+\t\t\targ->num_dir_ports++;\n+\n+\t\targ->num_ldb_credits +=\n+\t\t\tdomain->qed_freelist.bound -\n+\t\t\tdomain->qed_freelist.base;\n+\n+\t\tDLB_DOM_LIST_FOR(domain->avail_ldb_credit_pools, pool, iter2)\n+\t\t\targ->num_ldb_credit_pools++;\n+\t\tDLB_DOM_LIST_FOR(domain->used_ldb_credit_pools, pool, iter2) {\n+\t\t\targ->num_ldb_credit_pools++;\n+\t\t\targ->num_ldb_credits += pool->total_credits;\n+\t\t}\n+\n+\t\targ->num_dir_credits +=\n+\t\t\tdomain->dqed_freelist.bound -\n+\t\t\tdomain->dqed_freelist.base;\n+\n+\t\tDLB_DOM_LIST_FOR(domain->avail_dir_credit_pools, pool, iter2)\n+\t\t\targ->num_dir_credit_pools++;\n+\t\tDLB_DOM_LIST_FOR(domain->used_dir_credit_pools, pool, iter2) {\n+\t\t\targ->num_dir_credit_pools++;\n+\t\t\targ->num_dir_credits += pool->total_credits;\n+\t\t}\n+\n+\t\targ->num_hist_list_entries += domain->total_hist_list_entries;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static inline bool dlb_ldb_port_owned_by_vf(struct dlb_hw *hw,\n+\t\t\t\t\t    u32 vf_id,\n+\t\t\t\t\t    u32 port_id)\n+{\n+\treturn (hw->rsrcs.ldb_ports[port_id].id.vf_owned &&\n+\t\thw->rsrcs.ldb_ports[port_id].id.vf_id == vf_id);\n+}\n+\n+static inline bool dlb_dir_port_owned_by_vf(struct dlb_hw *hw,\n+\t\t\t\t\t    u32 vf_id,\n+\t\t\t\t\t    u32 port_id)\n+{\n+\treturn (hw->rsrcs.dir_pq_pairs[port_id].id.vf_owned &&\n+\t\thw->rsrcs.dir_pq_pairs[port_id].id.vf_id == vf_id);\n+}\n+\n+void dlb_send_async_pf_to_vf_msg(struct dlb_hw *hw, unsigned int vf_id)\n+{\n+\tunion dlb_func_pf_pf2vf_mailbox_isr r0 = { {0} };\n+\n+\tr0.field.isr = 1 << vf_id;\n+\n+\tDLB_FUNC_WR(hw, DLB_FUNC_PF_PF2VF_MAILBOX_ISR(0), r0.val);\n+}\n+\n+bool dlb_pf_to_vf_complete(struct dlb_hw *hw, unsigned int vf_id)\n+{\n+\tunion dlb_func_pf_pf2vf_mailbox_isr r0;\n+\n+\tr0.val = DLB_FUNC_RD(hw, DLB_FUNC_PF_PF2VF_MAILBOX_ISR(vf_id));\n+\n+\treturn (r0.val & (1 << vf_id)) == 0;\n+}\n+\n+void dlb_send_async_vf_to_pf_msg(struct dlb_hw *hw)\n+{\n+\tunion dlb_func_vf_vf2pf_mailbox_isr r0 = { {0} };\n+\n+\tr0.field.isr = 1;\n+\tDLB_FUNC_WR(hw, DLB_FUNC_VF_VF2PF_MAILBOX_ISR, r0.val);\n+}\n+\n+bool dlb_vf_to_pf_complete(struct dlb_hw *hw)\n+{\n+\tunion dlb_func_vf_vf2pf_mailbox_isr r0;\n+\n+\tr0.val = DLB_FUNC_RD(hw, DLB_FUNC_VF_VF2PF_MAILBOX_ISR);\n+\n+\treturn (r0.field.isr == 0);\n+}\n+\n+bool dlb_vf_flr_complete(struct dlb_hw *hw)\n+{\n+\tunion dlb_func_vf_vf_reset_in_progress r0;\n+\n+\tr0.val = DLB_FUNC_RD(hw, DLB_FUNC_VF_VF_RESET_IN_PROGRESS);\n+\n+\treturn (r0.field.reset_in_progress == 0);\n+}\n+\n+int dlb_pf_read_vf_mbox_req(struct dlb_hw *hw,\n+\t\t\t    unsigned int vf_id,\n+\t\t\t    void *data,\n+\t\t\t    int len)\n+{\n+\tu32 buf[DLB_VF2PF_REQ_BYTES / 4];\n+\tint num_words;\n+\tint i;\n+\n+\tif (len > DLB_VF2PF_REQ_BYTES) {\n+\t\tDLB_HW_ERR(hw, \"[%s()] len (%d) > VF->PF mailbox req size\\n\",\n+\t\t\t   __func__, len);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (len == 0) {\n+\t\tDLB_HW_ERR(hw, \"[%s()] invalid len (0)\\n\", __func__);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Round up len to the nearest 4B boundary, since the mailbox registers\n+\t * are 32b wide.\n+\t */\n+\tnum_words = len / 4;\n+\tif (len % 4 != 0)\n+\t\tnum_words++;\n+\n+\tfor (i = 0; i < num_words; i++) {\n+\t\tu32 idx = i + DLB_VF2PF_REQ_BASE_WORD;\n+\n+\t\tbuf[i] = DLB_FUNC_RD(hw, DLB_FUNC_PF_VF2PF_MAILBOX(vf_id, idx));\n+\t}\n+\n+\tmemcpy(data, buf, len);\n+\n+\treturn 0;\n+}\n+\n+int dlb_pf_read_vf_mbox_resp(struct dlb_hw *hw,\n+\t\t\t     unsigned int vf_id,\n+\t\t\t     void *data,\n+\t\t\t     int len)\n+{\n+\tu32 buf[DLB_VF2PF_RESP_BYTES / 4];\n+\tint num_words;\n+\tint i;\n+\n+\tif (len > DLB_VF2PF_RESP_BYTES) {\n+\t\tDLB_HW_ERR(hw, \"[%s()] len (%d) > VF->PF mailbox resp size\\n\",\n+\t\t\t   __func__, len);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Round up len to the nearest 4B boundary, since the mailbox registers\n+\t * are 32b wide.\n+\t */\n+\tnum_words = len / 4;\n+\tif (len % 4 != 0)\n+\t\tnum_words++;\n+\n+\tfor (i = 0; i < num_words; i++) {\n+\t\tu32 idx = i + DLB_VF2PF_RESP_BASE_WORD;\n+\n+\t\tbuf[i] = DLB_FUNC_RD(hw, DLB_FUNC_PF_VF2PF_MAILBOX(vf_id, idx));\n+\t}\n+\n+\tmemcpy(data, buf, len);\n+\n+\treturn 0;\n+}\n+\n+int dlb_pf_write_vf_mbox_resp(struct dlb_hw *hw,\n+\t\t\t      unsigned int vf_id,\n+\t\t\t      void *data,\n+\t\t\t      int len)\n+{\n+\tu32 buf[DLB_PF2VF_RESP_BYTES / 4];\n+\tint num_words;\n+\tint i;\n+\n+\tif (len > DLB_PF2VF_RESP_BYTES) {\n+\t\tDLB_HW_ERR(hw, \"[%s()] len (%d) > PF->VF mailbox resp size\\n\",\n+\t\t\t   __func__, len);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemcpy(buf, data, len);\n+\n+\t/* Round up len to the nearest 4B boundary, since the mailbox registers\n+\t * are 32b wide.\n+\t */\n+\tnum_words = len / 4;\n+\tif (len % 4 != 0)\n+\t\tnum_words++;\n+\n+\tfor (i = 0; i < num_words; i++) {\n+\t\tu32 idx = i + DLB_PF2VF_RESP_BASE_WORD;\n+\n+\t\tDLB_FUNC_WR(hw, DLB_FUNC_PF_PF2VF_MAILBOX(vf_id, idx), buf[i]);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int dlb_pf_write_vf_mbox_req(struct dlb_hw *hw,\n+\t\t\t     unsigned int vf_id,\n+\t\t\t     void *data,\n+\t\t\t     int len)\n+{\n+\tu32 buf[DLB_PF2VF_REQ_BYTES / 4];\n+\tint num_words;\n+\tint i;\n+\n+\tif (len > DLB_PF2VF_REQ_BYTES) {\n+\t\tDLB_HW_ERR(hw, \"[%s()] len (%d) > PF->VF mailbox req size\\n\",\n+\t\t\t   __func__, len);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemcpy(buf, data, len);\n+\n+\t/* Round up len to the nearest 4B boundary, since the mailbox registers\n+\t * are 32b wide.\n+\t */\n+\tnum_words = len / 4;\n+\tif (len % 4 != 0)\n+\t\tnum_words++;\n+\n+\tfor (i = 0; i < num_words; i++) {\n+\t\tu32 idx = i + DLB_PF2VF_REQ_BASE_WORD;\n+\n+\t\tDLB_FUNC_WR(hw, DLB_FUNC_PF_PF2VF_MAILBOX(vf_id, idx), buf[i]);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int dlb_vf_read_pf_mbox_resp(struct dlb_hw *hw, void *data, int len)\n+{\n+\tu32 buf[DLB_PF2VF_RESP_BYTES / 4];\n+\tint num_words;\n+\tint i;\n+\n+\tif (len > DLB_PF2VF_RESP_BYTES) {\n+\t\tDLB_HW_ERR(hw, \"[%s()] len (%d) > PF->VF mailbox resp size\\n\",\n+\t\t\t   __func__, len);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (len == 0) {\n+\t\tDLB_HW_ERR(hw, \"[%s()] invalid len (0)\\n\", __func__);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Round up len to the nearest 4B boundary, since the mailbox registers\n+\t * are 32b wide.\n+\t */\n+\tnum_words = len / 4;\n+\tif (len % 4 != 0)\n+\t\tnum_words++;\n+\n+\tfor (i = 0; i < num_words; i++) {\n+\t\tu32 idx = i + DLB_PF2VF_RESP_BASE_WORD;\n+\n+\t\tbuf[i] = DLB_FUNC_RD(hw, DLB_FUNC_VF_PF2VF_MAILBOX(idx));\n+\t}\n+\n+\tmemcpy(data, buf, len);\n+\n+\treturn 0;\n+}\n+\n+int dlb_vf_read_pf_mbox_req(struct dlb_hw *hw, void *data, int len)\n+{\n+\tu32 buf[DLB_PF2VF_REQ_BYTES / 4];\n+\tint num_words;\n+\tint i;\n+\n+\tif (len > DLB_PF2VF_REQ_BYTES) {\n+\t\tDLB_HW_ERR(hw, \"[%s()] len (%d) > PF->VF mailbox req size\\n\",\n+\t\t\t   __func__, len);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Round up len to the nearest 4B boundary, since the mailbox registers\n+\t * are 32b wide.\n+\t */\n+\tnum_words = len / 4;\n+\tif ((len % 4) != 0)\n+\t\tnum_words++;\n+\n+\tfor (i = 0; i < num_words; i++) {\n+\t\tu32 idx = i + DLB_PF2VF_REQ_BASE_WORD;\n+\n+\t\tbuf[i] = DLB_FUNC_RD(hw, DLB_FUNC_VF_PF2VF_MAILBOX(idx));\n+\t}\n+\n+\tmemcpy(data, buf, len);\n+\n+\treturn 0;\n+}\n+\n+int dlb_vf_write_pf_mbox_req(struct dlb_hw *hw, void *data, int len)\n+{\n+\tu32 buf[DLB_VF2PF_REQ_BYTES / 4];\n+\tint num_words;\n+\tint i;\n+\n+\tif (len > DLB_VF2PF_REQ_BYTES) {\n+\t\tDLB_HW_ERR(hw, \"[%s()] len (%d) > VF->PF mailbox req size\\n\",\n+\t\t\t   __func__, len);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemcpy(buf, data, len);\n+\n+\t/* Round up len to the nearest 4B boundary, since the mailbox registers\n+\t * are 32b wide.\n+\t */\n+\tnum_words = len / 4;\n+\tif (len % 4 != 0)\n+\t\tnum_words++;\n+\n+\tfor (i = 0; i < num_words; i++) {\n+\t\tu32 idx = i + DLB_VF2PF_REQ_BASE_WORD;\n+\n+\t\tDLB_FUNC_WR(hw, DLB_FUNC_VF_VF2PF_MAILBOX(idx), buf[i]);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int dlb_vf_write_pf_mbox_resp(struct dlb_hw *hw, void *data, int len)\n+{\n+\tu32 buf[DLB_VF2PF_RESP_BYTES / 4];\n+\tint num_words;\n+\tint i;\n+\n+\tif (len > DLB_VF2PF_RESP_BYTES) {\n+\t\tDLB_HW_ERR(hw, \"[%s()] len (%d) > VF->PF mailbox resp size\\n\",\n+\t\t\t   __func__, len);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemcpy(buf, data, len);\n+\n+\t/* Round up len to the nearest 4B boundary, since the mailbox registers\n+\t * are 32b wide.\n+\t */\n+\tnum_words = len / 4;\n+\tif (len % 4 != 0)\n+\t\tnum_words++;\n+\n+\tfor (i = 0; i < num_words; i++) {\n+\t\tu32 idx = i + DLB_VF2PF_RESP_BASE_WORD;\n+\n+\t\tDLB_FUNC_WR(hw, DLB_FUNC_VF_VF2PF_MAILBOX(idx), buf[i]);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+bool dlb_vf_is_locked(struct dlb_hw *hw, unsigned int vf_id)\n+{\n+\treturn hw->vf[vf_id].locked;\n+}\n+\n+static void dlb_vf_set_rsrc_virt_ids(struct dlb_function_resources *rsrcs,\n+\t\t\t\t     unsigned int vf_id)\n+{\n+\tstruct dlb_list_entry *iter __attribute__((unused));\n+\tstruct dlb_dir_pq_pair *dir_port;\n+\tstruct dlb_ldb_queue *ldb_queue;\n+\tstruct dlb_ldb_port *ldb_port;\n+\tstruct dlb_credit_pool *pool;\n+\tstruct dlb_domain *domain;\n+\tint i;\n+\n+\ti = 0;\n+\tDLB_FUNC_LIST_FOR(rsrcs->avail_domains, domain, iter) {\n+\t\tdomain->id.virt_id = i;\n+\t\tdomain->id.vf_owned = true;\n+\t\tdomain->id.vf_id = vf_id;\n+\t\ti++;\n+\t}\n+\n+\ti = 0;\n+\tDLB_FUNC_LIST_FOR(rsrcs->avail_ldb_queues, ldb_queue, iter) {\n+\t\tldb_queue->id.virt_id = i;\n+\t\tldb_queue->id.vf_owned = true;\n+\t\tldb_queue->id.vf_id = vf_id;\n+\t\ti++;\n+\t}\n+\n+\ti = 0;\n+\tDLB_FUNC_LIST_FOR(rsrcs->avail_ldb_ports, ldb_port, iter) {\n+\t\tldb_port->id.virt_id = i;\n+\t\tldb_port->id.vf_owned = true;\n+\t\tldb_port->id.vf_id = vf_id;\n+\t\ti++;\n+\t}\n+\n+\ti = 0;\n+\tDLB_FUNC_LIST_FOR(rsrcs->avail_dir_pq_pairs, dir_port, iter) {\n+\t\tdir_port->id.virt_id = i;\n+\t\tdir_port->id.vf_owned = true;\n+\t\tdir_port->id.vf_id = vf_id;\n+\t\ti++;\n+\t}\n+\n+\ti = 0;\n+\tDLB_FUNC_LIST_FOR(rsrcs->avail_ldb_credit_pools, pool, iter) {\n+\t\tpool->id.virt_id = i;\n+\t\tpool->id.vf_owned = true;\n+\t\tpool->id.vf_id = vf_id;\n+\t\ti++;\n+\t}\n+\n+\ti = 0;\n+\tDLB_FUNC_LIST_FOR(rsrcs->avail_dir_credit_pools, pool, iter) {\n+\t\tpool->id.virt_id = i;\n+\t\tpool->id.vf_owned = true;\n+\t\tpool->id.vf_id = vf_id;\n+\t\ti++;\n+\t}\n+}\n+\n+void dlb_lock_vf(struct dlb_hw *hw, unsigned int vf_id)\n+{\n+\tstruct dlb_function_resources *rsrcs = &hw->vf[vf_id];\n+\n+\trsrcs->locked = true;\n+\n+\tdlb_vf_set_rsrc_virt_ids(rsrcs, vf_id);\n+}\n+\n+void dlb_unlock_vf(struct dlb_hw *hw, unsigned int vf_id)\n+{\n+\thw->vf[vf_id].locked = false;\n+}\n+\n+int dlb_reset_vf_resources(struct dlb_hw *hw, unsigned int vf_id)\n+{\n+\tif (vf_id >= DLB_MAX_NUM_VFS)\n+\t\treturn -EINVAL;\n+\n+\t/* If the VF is locked, its resource assignment can't be changed */\n+\tif (dlb_vf_is_locked(hw, vf_id))\n+\t\treturn -EPERM;\n+\n+\tdlb_update_vf_sched_domains(hw, vf_id, 0);\n+\tdlb_update_vf_ldb_queues(hw, vf_id, 0);\n+\tdlb_update_vf_ldb_ports(hw, vf_id, 0);\n+\tdlb_update_vf_dir_ports(hw, vf_id, 0);\n+\tdlb_update_vf_ldb_credit_pools(hw, vf_id, 0);\n+\tdlb_update_vf_dir_credit_pools(hw, vf_id, 0);\n+\tdlb_update_vf_ldb_credits(hw, vf_id, 0);\n+\tdlb_update_vf_dir_credits(hw, vf_id, 0);\n+\tdlb_update_vf_hist_list_entries(hw, vf_id, 0);\n+\tdlb_update_vf_atomic_inflights(hw, vf_id, 0);\n+\n+\treturn 0;\n+}\n+\n+void dlb_hw_enable_sparse_ldb_cq_mode(struct dlb_hw *hw)\n+{\n+\tunion dlb_sys_cq_mode r0;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_SYS_CQ_MODE);\n+\n+\tr0.field.ldb_cq64 = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_CQ_MODE, r0.val);\n+}\n+\n+void dlb_hw_enable_sparse_dir_cq_mode(struct dlb_hw *hw)\n+{\n+\tunion dlb_sys_cq_mode r0;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_SYS_CQ_MODE);\n+\n+\tr0.field.dir_cq64 = 1;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_CQ_MODE, r0.val);\n+}\n+\n+void dlb_hw_set_qe_arbiter_weights(struct dlb_hw *hw, u8 weight[8])\n+{\n+\tunion dlb_atm_pipe_ctrl_arb_weights_rdy_bin r0 = { {0} };\n+\tunion dlb_nalb_pipe_ctrl_arb_weights_tqpri_nalb_0 r1 = { {0} };\n+\tunion dlb_nalb_pipe_ctrl_arb_weights_tqpri_nalb_1 r2 = { {0} };\n+\tunion dlb_nalb_pipe_cfg_ctrl_arb_weights_tqpri_replay_0 r3 = { {0} };\n+\tunion dlb_nalb_pipe_cfg_ctrl_arb_weights_tqpri_replay_1 r4 = { {0} };\n+\tunion dlb_dp_cfg_ctrl_arb_weights_tqpri_replay_0 r5 = { {0} };\n+\tunion dlb_dp_cfg_ctrl_arb_weights_tqpri_replay_1 r6 = { {0} };\n+\tunion dlb_dp_cfg_ctrl_arb_weights_tqpri_dir_0 r7 =  { {0} };\n+\tunion dlb_dp_cfg_ctrl_arb_weights_tqpri_dir_1 r8 =  { {0} };\n+\tunion dlb_nalb_pipe_cfg_ctrl_arb_weights_tqpri_atq_0 r9 = { {0} };\n+\tunion dlb_nalb_pipe_cfg_ctrl_arb_weights_tqpri_atq_1 r10 = { {0} };\n+\tunion dlb_atm_pipe_cfg_ctrl_arb_weights_sched_bin r11 = { {0} };\n+\tunion dlb_aqed_pipe_cfg_ctrl_arb_weights_tqpri_atm_0 r12 = { {0} };\n+\n+\tr0.field.bin0 = weight[1];\n+\tr0.field.bin1 = weight[3];\n+\tr0.field.bin2 = weight[5];\n+\tr0.field.bin3 = weight[7];\n+\n+\tr1.field.pri0 = weight[0];\n+\tr1.field.pri1 = weight[1];\n+\tr1.field.pri2 = weight[2];\n+\tr1.field.pri3 = weight[3];\n+\tr2.field.pri4 = weight[4];\n+\tr2.field.pri5 = weight[5];\n+\tr2.field.pri6 = weight[6];\n+\tr2.field.pri7 = weight[7];\n+\n+\tr3.field.pri0 = weight[0];\n+\tr3.field.pri1 = weight[1];\n+\tr3.field.pri2 = weight[2];\n+\tr3.field.pri3 = weight[3];\n+\tr4.field.pri4 = weight[4];\n+\tr4.field.pri5 = weight[5];\n+\tr4.field.pri6 = weight[6];\n+\tr4.field.pri7 = weight[7];\n+\n+\tr5.field.pri0 = weight[0];\n+\tr5.field.pri1 = weight[1];\n+\tr5.field.pri2 = weight[2];\n+\tr5.field.pri3 = weight[3];\n+\tr6.field.pri4 = weight[4];\n+\tr6.field.pri5 = weight[5];\n+\tr6.field.pri6 = weight[6];\n+\tr6.field.pri7 = weight[7];\n+\n+\tr7.field.pri0 = weight[0];\n+\tr7.field.pri1 = weight[1];\n+\tr7.field.pri2 = weight[2];\n+\tr7.field.pri3 = weight[3];\n+\tr8.field.pri4 = weight[4];\n+\tr8.field.pri5 = weight[5];\n+\tr8.field.pri6 = weight[6];\n+\tr8.field.pri7 = weight[7];\n+\n+\tr9.field.pri0 = weight[0];\n+\tr9.field.pri1 = weight[1];\n+\tr9.field.pri2 = weight[2];\n+\tr9.field.pri3 = weight[3];\n+\tr10.field.pri4 = weight[4];\n+\tr10.field.pri5 = weight[5];\n+\tr10.field.pri6 = weight[6];\n+\tr10.field.pri7 = weight[7];\n+\n+\tr11.field.bin0 = weight[1];\n+\tr11.field.bin1 = weight[3];\n+\tr11.field.bin2 = weight[5];\n+\tr11.field.bin3 = weight[7];\n+\n+\tr12.field.pri0 = weight[1];\n+\tr12.field.pri1 = weight[3];\n+\tr12.field.pri2 = weight[5];\n+\tr12.field.pri3 = weight[7];\n+\n+\tDLB_CSR_WR(hw, DLB_ATM_PIPE_CTRL_ARB_WEIGHTS_RDY_BIN, r0.val);\n+\tDLB_CSR_WR(hw, DLB_NALB_PIPE_CTRL_ARB_WEIGHTS_TQPRI_NALB_0, r1.val);\n+\tDLB_CSR_WR(hw, DLB_NALB_PIPE_CTRL_ARB_WEIGHTS_TQPRI_NALB_1, r2.val);\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_NALB_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_REPLAY_0,\n+\t\t   r3.val);\n+\tDLB_CSR_WR(hw,\n+\t\t   DLB_NALB_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_REPLAY_1,\n+\t\t   r4.val);\n+\tDLB_CSR_WR(hw, DLB_DP_CFG_CTRL_ARB_WEIGHTS_TQPRI_REPLAY_0, r5.val);\n+\tDLB_CSR_WR(hw, DLB_DP_CFG_CTRL_ARB_WEIGHTS_TQPRI_REPLAY_1, r6.val);\n+\tDLB_CSR_WR(hw, DLB_DP_CFG_CTRL_ARB_WEIGHTS_TQPRI_DIR_0, r7.val);\n+\tDLB_CSR_WR(hw, DLB_DP_CFG_CTRL_ARB_WEIGHTS_TQPRI_DIR_1, r8.val);\n+\tDLB_CSR_WR(hw, DLB_NALB_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_ATQ_0, r9.val);\n+\tDLB_CSR_WR(hw, DLB_NALB_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_ATQ_1, r10.val);\n+\tDLB_CSR_WR(hw, DLB_ATM_PIPE_CFG_CTRL_ARB_WEIGHTS_SCHED_BIN, r11.val);\n+\tDLB_CSR_WR(hw, DLB_AQED_PIPE_CFG_CTRL_ARB_WEIGHTS_TQPRI_ATM_0, r12.val);\n+}\n+\n+void dlb_hw_set_qid_arbiter_weights(struct dlb_hw *hw, u8 weight[8])\n+{\n+\tunion dlb_lsp_cfg_arb_weight_ldb_qid_0 r0 = { {0} };\n+\tunion dlb_lsp_cfg_arb_weight_ldb_qid_1 r1 = { {0} };\n+\tunion dlb_lsp_cfg_arb_weight_atm_nalb_qid_0 r2 = { {0} };\n+\tunion dlb_lsp_cfg_arb_weight_atm_nalb_qid_1 r3 = { {0} };\n+\n+\tr0.field.slot0_weight = weight[0];\n+\tr0.field.slot1_weight = weight[1];\n+\tr0.field.slot2_weight = weight[2];\n+\tr0.field.slot3_weight = weight[3];\n+\tr1.field.slot4_weight = weight[4];\n+\tr1.field.slot5_weight = weight[5];\n+\tr1.field.slot6_weight = weight[6];\n+\tr1.field.slot7_weight = weight[7];\n+\n+\tr2.field.slot0_weight = weight[0];\n+\tr2.field.slot1_weight = weight[1];\n+\tr2.field.slot2_weight = weight[2];\n+\tr2.field.slot3_weight = weight[3];\n+\tr3.field.slot4_weight = weight[4];\n+\tr3.field.slot5_weight = weight[5];\n+\tr3.field.slot6_weight = weight[6];\n+\tr3.field.slot7_weight = weight[7];\n+\n+\tDLB_CSR_WR(hw, DLB_LSP_CFG_ARB_WEIGHT_LDB_QID_0, r0.val);\n+\tDLB_CSR_WR(hw, DLB_LSP_CFG_ARB_WEIGHT_LDB_QID_1, r1.val);\n+\tDLB_CSR_WR(hw, DLB_LSP_CFG_ARB_WEIGHT_ATM_NALB_QID_0, r2.val);\n+\tDLB_CSR_WR(hw, DLB_LSP_CFG_ARB_WEIGHT_ATM_NALB_QID_1, r3.val);\n+}\n+\n+void dlb_hw_enable_pp_sw_alarms(struct dlb_hw *hw)\n+{\n+\tunion dlb_chp_cfg_ldb_pp_sw_alarm_en r0 = { {0} };\n+\tunion dlb_chp_cfg_dir_pp_sw_alarm_en r1 = { {0} };\n+\tint i;\n+\n+\tr0.field.alarm_enable = 1;\n+\tr1.field.alarm_enable = 1;\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_LDB_PORTS; i++)\n+\t\tDLB_CSR_WR(hw, DLB_CHP_CFG_LDB_PP_SW_ALARM_EN(i), r0.val);\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_DIR_PORTS; i++)\n+\t\tDLB_CSR_WR(hw, DLB_CHP_CFG_DIR_PP_SW_ALARM_EN(i), r1.val);\n+}\n+\n+void dlb_hw_disable_pp_sw_alarms(struct dlb_hw *hw)\n+{\n+\tunion dlb_chp_cfg_ldb_pp_sw_alarm_en r0 = { {0} };\n+\tunion dlb_chp_cfg_dir_pp_sw_alarm_en r1 = { {0} };\n+\tint i;\n+\n+\tr0.field.alarm_enable = 0;\n+\tr1.field.alarm_enable = 0;\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_LDB_PORTS; i++)\n+\t\tDLB_CSR_WR(hw, DLB_CHP_CFG_LDB_PP_SW_ALARM_EN(i), r0.val);\n+\n+\tfor (i = 0; i < DLB_MAX_NUM_DIR_PORTS; i++)\n+\t\tDLB_CSR_WR(hw, DLB_CHP_CFG_DIR_PP_SW_ALARM_EN(i), r1.val);\n+}\n+\n+void dlb_hw_disable_pf_to_vf_isr_pend_err(struct dlb_hw *hw)\n+{\n+\tunion dlb_sys_sys_alarm_int_enable r0;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_SYS_SYS_ALARM_INT_ENABLE);\n+\n+\tr0.field.pf_to_vf_isr_pend_error = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_SYS_ALARM_INT_ENABLE, r0.val);\n+}\n+\n+void dlb_hw_disable_vf_to_pf_isr_pend_err(struct dlb_hw *hw)\n+{\n+\tunion dlb_sys_sys_alarm_int_enable r0;\n+\n+\tr0.val = DLB_CSR_RD(hw, DLB_SYS_SYS_ALARM_INT_ENABLE);\n+\n+\tr0.field.vf_to_pf_isr_pend_error = 0;\n+\n+\tDLB_CSR_WR(hw, DLB_SYS_SYS_ALARM_INT_ENABLE, r0.val);\n+}\ndiff --git a/drivers/event/dlb/pf/base/dlb_resource.h b/drivers/event/dlb/pf/base/dlb_resource.h\nnew file mode 100644\nindex 0000000..b67424a\n--- /dev/null\n+++ b/drivers/event/dlb/pf/base/dlb_resource.h\n@@ -0,0 +1,1639 @@\n+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)\n+ * Copyright(c) 2016-2020 Intel Corporation\n+ */\n+\n+#ifndef __DLB_RESOURCE_H\n+#define __DLB_RESOURCE_H\n+\n+#include \"dlb_hw_types.h\"\n+#include \"dlb_osdep_types.h\"\n+#include \"dlb_user.h\"\n+\n+/**\n+ * dlb_resource_init() - initialize the device\n+ * @hw: pointer to struct dlb_hw.\n+ *\n+ * This function initializes the device's software state (pointed to by the hw\n+ * argument) and programs global scheduling QoS registers. This function should\n+ * be called during driver initialization.\n+ *\n+ * The dlb_hw struct must be unique per DLB device and persist until the device\n+ * is reset.\n+ *\n+ * Return:\n+ * Returns 0 upon success, -1 otherwise.\n+ */\n+int dlb_resource_init(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_resource_free() - free device state memory\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function frees software state pointed to by dlb_hw. This function\n+ * should be called when resetting the device or unloading the driver.\n+ */\n+void dlb_resource_free(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_resource_reset() - reset in-use resources to their initial state\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function resets in-use resources, and makes them available for use.\n+ * All resources go back to their owning function, whether a PF or a VF.\n+ */\n+void dlb_resource_reset(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_hw_create_sched_domain() - create a scheduling domain\n+ * @hw: dlb_hw handle for a particular device.\n+ * @args: scheduling domain creation arguments.\n+ * @resp: response structure.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function creates a scheduling domain containing the resources specified\n+ * in args. The individual resources (queues, ports, credit pools) can be\n+ * configured after creating a scheduling domain.\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 dlb_error. If successful, resp->id\n+ * contains the domain ID.\n+ *\n+ * Note: resp->id contains a virtual ID if vf_request is true.\n+ *\n+ * Errors:\n+ * EINVAL - A requested resource is unavailable, or the requested domain name\n+ *\t    is already in use.\n+ * EFAULT - Internal error (resp->status not set).\n+ */\n+int dlb_hw_create_sched_domain(struct dlb_hw *hw,\n+\t\t\t       struct dlb_create_sched_domain_args *args,\n+\t\t\t       struct dlb_cmd_response *resp,\n+\t\t\t       bool vf_request,\n+\t\t\t       unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_create_ldb_pool() - create a load-balanced credit pool\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: credit pool creation arguments.\n+ * @resp: response structure.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function creates a load-balanced credit pool containing the number of\n+ * requested credits.\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 dlb_error. If successful, resp->id\n+ * contains the pool ID.\n+ *\n+ * Note: resp->id contains a virtual ID if vf_request is true.\n+ *\n+ * Errors:\n+ * EINVAL - A requested resource is unavailable, the domain is not configured,\n+ *\t    or the domain has already been started.\n+ * EFAULT - Internal error (resp->status not set).\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+\t\t\t   bool vf_request,\n+\t\t\t   unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_create_dir_pool() - create a directed credit pool\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: credit pool creation arguments.\n+ * @resp: response structure.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function creates a directed credit pool containing the number of\n+ * requested credits.\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 dlb_error. If successful, resp->id\n+ * contains the pool ID.\n+ *\n+ * Note: resp->id contains a virtual ID if vf_request is true.\n+ *\n+ * Errors:\n+ * EINVAL - A requested resource is unavailable, the domain is not configured,\n+ *\t    or the domain has already been started.\n+ * EFAULT - Internal error (resp->status not set).\n+ */\n+int dlb_hw_create_dir_pool(struct dlb_hw *hw,\n+\t\t\t   u32 domain_id,\n+\t\t\t   struct dlb_create_dir_pool_args *args,\n+\t\t\t   struct dlb_cmd_response *resp,\n+\t\t\t   bool vf_request,\n+\t\t\t   unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_create_ldb_queue() - create a load-balanced queue\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: queue creation arguments.\n+ * @resp: response structure.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function creates a load-balanced queue.\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 dlb_error. If successful, resp->id\n+ * contains the queue ID.\n+ *\n+ * Note: resp->id contains a virtual ID if vf_request is true.\n+ *\n+ * Errors:\n+ * EINVAL - A requested resource is unavailable, the domain is not configured,\n+ *\t    the domain has already been started, or the requested queue name is\n+ *\t    already in use.\n+ * EFAULT - Internal error (resp->status not set).\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+\t\t\t    bool vf_request,\n+\t\t\t    unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_create_dir_queue() - create a directed queue\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: queue creation arguments.\n+ * @resp: response structure.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function creates a directed queue.\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 dlb_error. If successful, resp->id\n+ * contains the queue ID.\n+ *\n+ * Note: resp->id contains a virtual ID if vf_request is true.\n+ *\n+ * Errors:\n+ * EINVAL - A requested resource is unavailable, the domain is not configured,\n+ *\t    or the domain has already been started.\n+ * EFAULT - Internal error (resp->status not set).\n+ */\n+int dlb_hw_create_dir_queue(struct dlb_hw *hw,\n+\t\t\t    u32 domain_id,\n+\t\t\t    struct dlb_create_dir_queue_args *args,\n+\t\t\t    struct dlb_cmd_response *resp,\n+\t\t\t    bool vf_request,\n+\t\t\t    unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_create_dir_port() - create a directed port\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: port creation arguments.\n+ * @pop_count_dma_base: base address of the pop count memory. This can be\n+ *\t\t\ta PA or an IOVA.\n+ * @cq_dma_base: base address of the CQ memory. This can be a PA or an IOVA.\n+ * @resp: response structure.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function creates a directed port.\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 dlb_error. If successful, resp->id\n+ * contains the port ID.\n+ *\n+ * Note: resp->id contains a virtual ID if vf_request is true.\n+ *\n+ * Errors:\n+ * EINVAL - A requested resource is unavailable, a credit setting is invalid, a\n+ *\t    pool ID is invalid, a pointer address is not properly aligned, the\n+ *\t    domain is not configured, or the domain has already been started.\n+ * EFAULT - Internal error (resp->status not set).\n+ */\n+int dlb_hw_create_dir_port(struct dlb_hw *hw,\n+\t\t\t   u32 domain_id,\n+\t\t\t   struct dlb_create_dir_port_args *args,\n+\t\t\t   u64 pop_count_dma_base,\n+\t\t\t   u64 cq_dma_base,\n+\t\t\t   struct dlb_cmd_response *resp,\n+\t\t\t   bool vf_request,\n+\t\t\t   unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_create_ldb_port() - create a load-balanced port\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: port creation arguments.\n+ * @pop_count_dma_base: base address of the pop count memory. This can be\n+ *\t\t\t a PA or an IOVA.\n+ * @cq_dma_base: base address of the CQ memory. This can be a PA or an IOVA.\n+ * @resp: response structure.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function creates a load-balanced port.\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 dlb_error. If successful, resp->id\n+ * contains the port ID.\n+ *\n+ * Note: resp->id contains a virtual ID if vf_request is true.\n+ *\n+ * Errors:\n+ * EINVAL - A requested resource is unavailable, a credit setting is invalid, a\n+ *\t    pool ID is invalid, a pointer address is not properly aligned, the\n+ *\t    domain is not configured, or the domain has already been started.\n+ * EFAULT - Internal error (resp->status not set).\n+ */\n+int dlb_hw_create_ldb_port(struct dlb_hw *hw,\n+\t\t\t   u32 domain_id,\n+\t\t\t   struct dlb_create_ldb_port_args *args,\n+\t\t\t   u64 pop_count_dma_base,\n+\t\t\t   u64 cq_dma_base,\n+\t\t\t   struct dlb_cmd_response *resp,\n+\t\t\t   bool vf_request,\n+\t\t\t   unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_start_domain() - start a scheduling domain\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: start domain arguments.\n+ * @resp: response structure.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function starts a scheduling domain, which allows applications to send\n+ * traffic through it. Once a domain is started, its resources can no longer be\n+ * configured (besides QID remapping and port enable/disable).\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 dlb_error.\n+ *\n+ * Errors:\n+ * EINVAL - the domain is not configured, or the domain is already started.\n+ */\n+int dlb_hw_start_domain(struct dlb_hw *hw,\n+\t\t\tu32 domain_id,\n+\t\t\tstruct dlb_start_domain_args *args,\n+\t\t\tstruct dlb_cmd_response *resp,\n+\t\t\tbool vf_request,\n+\t\t\tunsigned int vf_id);\n+\n+/**\n+ * dlb_hw_map_qid() - map a load-balanced queue to a load-balanced port\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: map QID arguments.\n+ * @resp: response structure.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function configures the DLB to schedule QEs from the specified queue to\n+ * the specified port. Each load-balanced port can be mapped to up to 8 queues;\n+ * each load-balanced queue can potentially map to all the load-balanced ports.\n+ *\n+ * A successful return does not necessarily mean the mapping was configured. If\n+ * this function is unable to immediately map the queue to the port, it will\n+ * 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. In a sense, this is\n+ * an asynchronous function.\n+ *\n+ * This asynchronicity creates two views of the state of hardware: the actual\n+ * hardware state and the requested state (as if every request completed\n+ * immediately). If there are any pending map/unmap operations, the requested\n+ * state will differ from the actual state. All validation is performed with\n+ * respect to the pending state; for instance, if there are 8 pending map\n+ * operations for port X, a request for a 9th will fail because a load-balanced\n+ * port can only map up to 8 queues.\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 dlb_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 dlb_hw_map_qid(struct dlb_hw *hw,\n+\t\t   u32 domain_id,\n+\t\t   struct dlb_map_qid_args *args,\n+\t\t   struct dlb_cmd_response *resp,\n+\t\t   bool vf_request,\n+\t\t   unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_unmap_qid() - Unmap a load-balanced queue from a load-balanced port\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: unmap QID arguments.\n+ * @resp: response structure.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF'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+ * dlb_hw_map_qid() for more details.\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 dlb_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 dlb_hw_unmap_qid(struct dlb_hw *hw,\n+\t\t     u32 domain_id,\n+\t\t     struct dlb_unmap_qid_args *args,\n+\t\t     struct dlb_cmd_response *resp,\n+\t\t     bool vf_request,\n+\t\t     unsigned int vf_id);\n+\n+/**\n+ * dlb_finish_unmap_qid_procedures() - finish any pending unmap procedures\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function attempts to finish any outstanding unmap procedures.\n+ * This function should be called by the kernel thread responsible for\n+ * finishing map/unmap procedures.\n+ *\n+ * Return:\n+ * Returns the number of procedures that weren't completed.\n+ */\n+unsigned int dlb_finish_unmap_qid_procedures(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_finish_map_qid_procedures() - finish any pending map procedures\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function attempts to finish any outstanding map procedures.\n+ * This function should be called by the kernel thread responsible for\n+ * finishing map/unmap procedures.\n+ *\n+ * Return:\n+ * Returns the number of procedures that weren't completed.\n+ */\n+unsigned int dlb_finish_map_qid_procedures(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_hw_enable_ldb_port() - enable a load-balanced port for scheduling\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: port enable arguments.\n+ * @resp: response structure.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function configures the DLB to schedule QEs to a load-balanced port.\n+ * Ports are enabled by default.\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 dlb_error.\n+ *\n+ * Errors:\n+ * EINVAL - The port ID is invalid or the domain is not configured.\n+ * EFAULT - Internal error (resp->status not set).\n+ */\n+int dlb_hw_enable_ldb_port(struct dlb_hw *hw,\n+\t\t\t   u32 domain_id,\n+\t\t\t   struct dlb_enable_ldb_port_args *args,\n+\t\t\t   struct dlb_cmd_response *resp,\n+\t\t\t   bool vf_request,\n+\t\t\t   unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_disable_ldb_port() - disable a load-balanced port for scheduling\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: port disable arguments.\n+ * @resp: response structure.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function configures the DLB to stop scheduling QEs to a load-balanced\n+ * port. Ports are enabled by default.\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 dlb_error.\n+ *\n+ * Errors:\n+ * EINVAL - The port ID is invalid or the domain is not configured.\n+ * EFAULT - Internal error (resp->status not set).\n+ */\n+int dlb_hw_disable_ldb_port(struct dlb_hw *hw,\n+\t\t\t    u32 domain_id,\n+\t\t\t    struct dlb_disable_ldb_port_args *args,\n+\t\t\t    struct dlb_cmd_response *resp,\n+\t\t\t    bool vf_request,\n+\t\t\t    unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_enable_dir_port() - enable a directed port for scheduling\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: port enable arguments.\n+ * @resp: response structure.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function configures the DLB to schedule QEs to a directed port.\n+ * Ports are enabled by default.\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 dlb_error.\n+ *\n+ * Errors:\n+ * EINVAL - The port ID is invalid or the domain is not configured.\n+ * EFAULT - Internal error (resp->status not set).\n+ */\n+int dlb_hw_enable_dir_port(struct dlb_hw *hw,\n+\t\t\t   u32 domain_id,\n+\t\t\t   struct dlb_enable_dir_port_args *args,\n+\t\t\t   struct dlb_cmd_response *resp,\n+\t\t\t   bool vf_request,\n+\t\t\t   unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_disable_dir_port() - disable a directed port for scheduling\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: port disable arguments.\n+ * @resp: response structure.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function configures the DLB to stop scheduling QEs to a directed port.\n+ * Ports are enabled by default.\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 dlb_error.\n+ *\n+ * Errors:\n+ * EINVAL - The port ID is invalid or the domain is not configured.\n+ * EFAULT - Internal error (resp->status not set).\n+ */\n+int dlb_hw_disable_dir_port(struct dlb_hw *hw,\n+\t\t\t    u32 domain_id,\n+\t\t\t    struct dlb_disable_dir_port_args *args,\n+\t\t\t    struct dlb_cmd_response *resp,\n+\t\t\t    bool vf_request,\n+\t\t\t    unsigned int vf_id);\n+\n+/**\n+ * dlb_configure_ldb_cq_interrupt() - configure load-balanced CQ for interrupts\n+ * @hw: dlb_hw handle for a particular device.\n+ * @port_id: load-balancd port ID.\n+ * @vector: interrupt vector ID. Should be 0 for MSI or compressed MSI-X mode,\n+ *\t    else a value up to 64.\n+ * @mode: interrupt type (DLB_CQ_ISR_MODE_MSI or DLB_CQ_ISR_MODE_MSIX)\n+ * @vf: If the port is VF-owned, the VF's ID. This is used for translating the\n+ *\tvirtual port ID to a physical port ID. Ignored if mode is not MSI.\n+ * @owner_vf: the VF to route the interrupt to. Ignore if mode is not MSI.\n+ * @threshold: the minimum CQ depth at which the interrupt can fire. Must be\n+ *\tgreater than 0.\n+ *\n+ * This function configures the DLB registers for load-balanced CQ's interrupts.\n+ * This doesn't enable the CQ's interrupt; that can be done with\n+ * dlb_arm_cq_interrupt() or through an interrupt arm QE.\n+ *\n+ * Return:\n+ * Returns 0 upon success, < 0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - The port ID is invalid.\n+ */\n+int dlb_configure_ldb_cq_interrupt(struct dlb_hw *hw,\n+\t\t\t\t   int port_id,\n+\t\t\t\t   int vector,\n+\t\t\t\t   int mode,\n+\t\t\t\t   unsigned int vf,\n+\t\t\t\t   unsigned int owner_vf,\n+\t\t\t\t   u16 threshold);\n+\n+/**\n+ * dlb_configure_dir_cq_interrupt() - configure directed CQ for interrupts\n+ * @hw: dlb_hw handle for a particular device.\n+ * @port_id: load-balancd port ID.\n+ * @vector: interrupt vector ID. Should be 0 for MSI or compressed MSI-X mode,\n+ *\t    else a value up to 64.\n+ * @mode: interrupt type (DLB_CQ_ISR_MODE_MSI or DLB_CQ_ISR_MODE_MSIX)\n+ * @vf: If the port is VF-owned, the VF's ID. This is used for translating the\n+ *\tvirtual port ID to a physical port ID. Ignored if mode is not MSI.\n+ * @owner_vf: the VF to route the interrupt to. Ignore if mode is not MSI.\n+ * @threshold: the minimum CQ depth at which the interrupt can fire. Must be\n+ *\tgreater than 0.\n+ *\n+ * This function configures the DLB registers for directed CQ's interrupts.\n+ * This doesn't enable the CQ's interrupt; that can be done with\n+ * dlb_arm_cq_interrupt() or through an interrupt arm QE.\n+ *\n+ * Return:\n+ * Returns 0 upon success, < 0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - The port ID is invalid.\n+ */\n+int dlb_configure_dir_cq_interrupt(struct dlb_hw *hw,\n+\t\t\t\t   int port_id,\n+\t\t\t\t   int vector,\n+\t\t\t\t   int mode,\n+\t\t\t\t   unsigned int vf,\n+\t\t\t\t   unsigned int owner_vf,\n+\t\t\t\t   u16 threshold);\n+\n+/**\n+ * dlb_enable_alarm_interrupts() - enable certain hardware alarm interrupts\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function configures the ingress error alarm. (Other alarms are enabled\n+ * by default.)\n+ */\n+void dlb_enable_alarm_interrupts(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_disable_alarm_interrupts() - disable certain hardware alarm interrupts\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function configures the ingress error alarm. (Other alarms are disabled\n+ * by default.)\n+ */\n+void dlb_disable_alarm_interrupts(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_set_msix_mode() - enable certain hardware alarm interrupts\n+ * @hw: dlb_hw handle for a particular device.\n+ * @mode: MSI-X mode (DLB_MSIX_MODE_PACKED or DLB_MSIX_MODE_COMPRESSED)\n+ *\n+ * This function configures the hardware to use either packed or compressed\n+ * mode. This function should not be called if using MSI interrupts.\n+ */\n+void dlb_set_msix_mode(struct dlb_hw *hw, int mode);\n+\n+/**\n+ * dlb_arm_cq_interrupt() - arm a CQ's interrupt\n+ * @hw: dlb_hw handle for a particular device.\n+ * @port_id: port ID\n+ * @is_ldb: true for load-balanced port, false for a directed port\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function arms the CQ's interrupt. The CQ must be configured prior to\n+ * calling this function.\n+ *\n+ * The function does no parameter validation; that is the caller's\n+ * responsibility.\n+ *\n+ * Return: returns 0 upon success, <0 otherwise.\n+ *\n+ * EINVAL - Invalid port ID.\n+ */\n+int dlb_arm_cq_interrupt(struct dlb_hw *hw,\n+\t\t\t int port_id,\n+\t\t\t bool is_ldb,\n+\t\t\t bool vf_request,\n+\t\t\t unsigned int vf_id);\n+\n+/**\n+ * dlb_read_compressed_cq_intr_status() - read compressed CQ interrupt status\n+ * @hw: dlb_hw handle for a particular device.\n+ * @ldb_interrupts: 2-entry array of u32 bitmaps\n+ * @dir_interrupts: 4-entry array of u32 bitmaps\n+ *\n+ * This function can be called from a compressed CQ interrupt handler to\n+ * determine which CQ interrupts have fired. The caller should take appropriate\n+ * (such as waking threads blocked on a CQ's interrupt) then ack the interrupts\n+ * with dlb_ack_compressed_cq_intr().\n+ */\n+void dlb_read_compressed_cq_intr_status(struct dlb_hw *hw,\n+\t\t\t\t\tu32 *ldb_interrupts,\n+\t\t\t\t\tu32 *dir_interrupts);\n+\n+/**\n+ * dlb_ack_compressed_cq_intr_status() - ack compressed CQ interrupts\n+ * @hw: dlb_hw handle for a particular device.\n+ * @ldb_interrupts: 2-entry array of u32 bitmaps\n+ * @dir_interrupts: 4-entry array of u32 bitmaps\n+ *\n+ * This function ACKs compressed CQ interrupts. Its arguments should be the\n+ * same ones passed to dlb_read_compressed_cq_intr_status().\n+ */\n+void dlb_ack_compressed_cq_intr(struct dlb_hw *hw,\n+\t\t\t\tu32 *ldb_interrupts,\n+\t\t\t\tu32 *dir_interrupts);\n+\n+/**\n+ * dlb_read_vf_intr_status() - read the VF interrupt status register\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function can be called from a VF's interrupt handler to determine\n+ * which interrupts have fired. The first 31 bits correspond to CQ interrupt\n+ * vectors, and the final bit is for the PF->VF mailbox interrupt vector.\n+ *\n+ * Return:\n+ * Returns a bit vector indicating which interrupt vectors are active.\n+ */\n+u32 dlb_read_vf_intr_status(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_ack_vf_intr_status() - ack VF interrupts\n+ * @hw: dlb_hw handle for a particular device.\n+ * @interrupts: 32-bit bitmap\n+ *\n+ * This function ACKs a VF's interrupts. Its interrupts argument should be the\n+ * value returned by dlb_read_vf_intr_status().\n+ */\n+void dlb_ack_vf_intr_status(struct dlb_hw *hw, u32 interrupts);\n+\n+/**\n+ * dlb_ack_vf_msi_intr() - ack VF MSI interrupt\n+ * @hw: dlb_hw handle for a particular device.\n+ * @interrupts: 32-bit bitmap\n+ *\n+ * This function clears the VF's MSI interrupt pending register. Its interrupts\n+ * argument should be contain the MSI vectors to ACK. For example, if MSI MME\n+ * is in mode 0, then one bit 0 should ever be set.\n+ */\n+void dlb_ack_vf_msi_intr(struct dlb_hw *hw, u32 interrupts);\n+\n+/**\n+ * dlb_ack_vf_mbox_int() - ack PF->VF mailbox interrupt\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * When done processing the PF mailbox request, this function unsets\n+ * the PF's mailbox ISR register.\n+ */\n+void dlb_ack_pf_mbox_int(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_read_vf_to_pf_int_bitvec() - return a bit vector of all requesting VFs\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * When the VF->PF ISR fires, this function can be called to determine which\n+ * VF(s) are requesting service. This bitvector must be passed to\n+ * dlb_ack_vf_to_pf_int() when processing is complete for all requesting VFs.\n+ *\n+ * Return:\n+ * Returns a bit vector indicating which VFs (0-15) have requested service.\n+ */\n+u32 dlb_read_vf_to_pf_int_bitvec(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_ack_vf_mbox_int() - ack processed VF->PF mailbox interrupt\n+ * @hw: dlb_hw handle for a particular device.\n+ * @bitvec: bit vector returned by dlb_read_vf_to_pf_int_bitvec()\n+ *\n+ * When done processing all VF mailbox requests, this function unsets the VF's\n+ * mailbox ISR register.\n+ */\n+void dlb_ack_vf_mbox_int(struct dlb_hw *hw, u32 bitvec);\n+\n+/**\n+ * dlb_read_vf_flr_int_bitvec() - return a bit vector of all VFs requesting FLR\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * When the VF FLR ISR fires, this function can be called to determine which\n+ * VF(s) are requesting FLRs. This bitvector must passed to\n+ * dlb_ack_vf_flr_int() when processing is complete for all requesting VFs.\n+ *\n+ * Return:\n+ * Returns a bit vector indicating which VFs (0-15) have requested FLRs.\n+ */\n+u32 dlb_read_vf_flr_int_bitvec(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_ack_vf_flr_int() - ack processed VF<->PF interrupt(s)\n+ * @hw: dlb_hw handle for a particular device.\n+ * @bitvec: bit vector returned by dlb_read_vf_flr_int_bitvec()\n+ * @a_stepping: device is A-stepping\n+ *\n+ * When done processing all VF FLR requests, this function unsets the VF's FLR\n+ * ISR register.\n+ *\n+ * Note: The caller must ensure dlb_set_vf_reset_in_progress(),\n+ * dlb_clr_vf_reset_in_progress(), and dlb_ack_vf_flr_int() are not executed in\n+ * parallel, because the reset-in-progress register does not support atomic\n+ * updates on A-stepping devices.\n+ */\n+void dlb_ack_vf_flr_int(struct dlb_hw *hw, u32 bitvec, bool a_stepping);\n+\n+/**\n+ * dlb_ack_vf_to_pf_int() - ack processed VF mbox and FLR interrupt(s)\n+ * @hw: dlb_hw handle for a particular device.\n+ * @mbox_bitvec: bit vector returned by dlb_read_vf_to_pf_int_bitvec()\n+ * @flr_bitvec: bit vector returned by dlb_read_vf_flr_int_bitvec()\n+ *\n+ * When done processing all VF requests, this function communicates to the\n+ * hardware that processing is complete. When this function completes, hardware\n+ * can immediately generate another VF mbox or FLR interrupt.\n+ */\n+void dlb_ack_vf_to_pf_int(struct dlb_hw *hw,\n+\t\t\t  u32 mbox_bitvec,\n+\t\t\t  u32 flr_bitvec);\n+\n+/**\n+ * dlb_process_alarm_interrupt() - process an alarm interrupt\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function reads the alarm syndrome, logs its, and acks the interrupt.\n+ * This function should be called from the alarm interrupt handler when\n+ * interrupt vector DLB_INT_ALARM fires.\n+ */\n+void dlb_process_alarm_interrupt(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_process_ingress_error_interrupt() - process ingress error interrupts\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function reads the alarm syndrome, logs it, notifies user-space, and\n+ * acks the interrupt. This function should be called from the alarm interrupt\n+ * handler when interrupt vector DLB_INT_INGRESS_ERROR fires.\n+ */\n+void dlb_process_ingress_error_interrupt(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_get_group_sequence_numbers() - return a group's number of SNs per queue\n+ * @hw: dlb_hw handle for a particular device.\n+ * @group_id: sequence number group ID.\n+ *\n+ * This function returns the configured number of sequence numbers per queue\n+ * for the specified group.\n+ *\n+ * Return:\n+ * Returns -EINVAL if group_id is invalid, else the group's SNs per queue.\n+ */\n+int dlb_get_group_sequence_numbers(struct dlb_hw *hw, unsigned int group_id);\n+\n+/**\n+ * dlb_get_group_sequence_number_occupancy() - return a group's in-use slots\n+ * @hw: dlb_hw handle for a particular device.\n+ * @group_id: sequence number group ID.\n+ *\n+ * This function returns the group's number of in-use slots (i.e. load-balanced\n+ * queues using the specified group).\n+ *\n+ * Return:\n+ * Returns -EINVAL if group_id is invalid, else the group's occupancy.\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+/**\n+ * dlb_set_group_sequence_numbers() - assign a group's number of SNs per queue\n+ * @hw: dlb_hw handle for a particular device.\n+ * @group_id: sequence number group ID.\n+ * @val: requested amount of sequence numbers per queue.\n+ *\n+ * This function configures the group's number of sequence numbers per queue.\n+ * val can be a power-of-two between 32 and 1024, inclusive. This setting can\n+ * be configured until the first ordered load-balanced queue is configured, at\n+ * which point the configuration is locked.\n+ *\n+ * Return:\n+ * Returns 0 upon success; -EINVAL if group_id or val is invalid, -EPERM if an\n+ * ordered queue is configured.\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+/**\n+ * dlb_reset_domain() - reset a scheduling domain\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function resets and frees a DLB scheduling domain and its associated\n+ * resources.\n+ *\n+ * Pre-condition: the driver must ensure software has stopped sending QEs\n+ * through this domain's producer ports before invoking this function, or\n+ * undefined behavior will result.\n+ *\n+ * Return:\n+ * Returns 0 upon success, -1 otherwise.\n+ *\n+ * EINVAL - Invalid domain ID, or the domain is not configured.\n+ * EFAULT - Internal error. (Possibly caused if software is the pre-condition\n+ *\t    is not met.)\n+ * ETIMEDOUT - Hardware component didn't reset in the expected time.\n+ */\n+int dlb_reset_domain(struct dlb_hw *hw,\n+\t\t     u32 domain_id,\n+\t\t     bool vf_request,\n+\t\t     unsigned int vf_id);\n+\n+/**\n+ * dlb_ldb_port_owned_by_domain() - query whether a port is owned by a domain\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @port_id: indicates whether this request came from a VF.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function returns whether a load-balanced port is owned by a specified\n+ * domain.\n+ *\n+ * Return:\n+ * Returns 0 if false, 1 if true, <0 otherwise.\n+ *\n+ * EINVAL - Invalid domain or port ID, or the domain is not configured.\n+ */\n+int dlb_ldb_port_owned_by_domain(struct dlb_hw *hw,\n+\t\t\t\t u32 domain_id,\n+\t\t\t\t u32 port_id,\n+\t\t\t\t bool vf_request,\n+\t\t\t\t unsigned int vf_id);\n+\n+/**\n+ * dlb_dir_port_owned_by_domain() - query whether a port is owned by a domain\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @port_id: indicates whether this request came from a VF.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function returns whether a directed port is owned by a specified\n+ * domain.\n+ *\n+ * Return:\n+ * Returns 0 if false, 1 if true, <0 otherwise.\n+ *\n+ * EINVAL - Invalid domain or port ID, or the domain is not configured.\n+ */\n+int dlb_dir_port_owned_by_domain(struct dlb_hw *hw,\n+\t\t\t\t u32 domain_id,\n+\t\t\t\t u32 port_id,\n+\t\t\t\t bool vf_request,\n+\t\t\t\t unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_get_num_resources() - query the PCI function's available resources\n+ * @arg: pointer to resource counts.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function returns the number of available resources for the PF or for a\n+ * VF.\n+ *\n+ * Return:\n+ * Returns 0 upon success, -1 if vf_request is true and vf_id is invalid.\n+ */\n+int dlb_hw_get_num_resources(struct dlb_hw *hw,\n+\t\t\t     struct dlb_get_num_resources_args *arg,\n+\t\t\t     bool vf_request,\n+\t\t\t     unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_get_num_used_resources() - query the PCI function's used resources\n+ * @arg: pointer to resource counts.\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function returns the number of resources in use by the PF or a VF. It\n+ * fills in the fields that args points to, except the following:\n+ * - max_contiguous_atomic_inflights\n+ * - max_contiguous_hist_list_entries\n+ * - max_contiguous_ldb_credits\n+ * - max_contiguous_dir_credits\n+ *\n+ * Return:\n+ * Returns 0 upon success, -1 if vf_request is true and vf_id is invalid.\n+ */\n+int dlb_hw_get_num_used_resources(struct dlb_hw *hw,\n+\t\t\t\t  struct dlb_get_num_resources_args *arg,\n+\t\t\t\t  bool vf_request,\n+\t\t\t\t  unsigned int vf_id);\n+\n+/**\n+ * dlb_send_async_vf_to_pf_msg() - (VF only) send a mailbox message to the PF\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function sends a VF->PF mailbox message. It is asynchronous, so it\n+ * returns once the message is sent but potentially before the PF has processed\n+ * the message. The caller must call dlb_vf_to_pf_complete() to determine when\n+ * the PF has finished processing the request.\n+ */\n+void dlb_send_async_vf_to_pf_msg(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_vf_to_pf_complete() - check the status of an asynchronous mailbox request\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function returns a boolean indicating whether the PF has finished\n+ * processing a VF->PF mailbox request. It should only be called after sending\n+ * an asynchronous request with dlb_send_async_vf_to_pf_msg().\n+ */\n+bool dlb_vf_to_pf_complete(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_vf_flr_complete() - check the status of a VF FLR\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function returns a boolean indicating whether the PF has finished\n+ * executing the VF FLR. It should only be called after setting the VF's FLR\n+ * bit.\n+ */\n+bool dlb_vf_flr_complete(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_set_vf_reset_in_progress() - set a VF's reset in progress bit\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID.\n+ *\n+ * Note: This function is only supported on A-stepping devices.\n+ *\n+ * Note: The caller must ensure dlb_set_vf_reset_in_progress(),\n+ * dlb_clr_vf_reset_in_progress(), and dlb_ack_vf_flr_int() are not executed in\n+ * parallel, because the reset-in-progress register does not support atomic\n+ * updates on A-stepping devices.\n+ */\n+void dlb_set_vf_reset_in_progress(struct dlb_hw *hw, int vf_id);\n+\n+/**\n+ * dlb_clr_vf_reset_in_progress() - clear a VF's reset in progress bit\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID.\n+ *\n+ * Note: This function is only supported on A-stepping devices.\n+ *\n+ * Note: The caller must ensure dlb_set_vf_reset_in_progress(),\n+ * dlb_clr_vf_reset_in_progress(), and dlb_ack_vf_flr_int() are not executed in\n+ * parallel, because the reset-in-progress register does not support atomic\n+ * updates on A-stepping devices.\n+ */\n+void dlb_clr_vf_reset_in_progress(struct dlb_hw *hw, int vf_id);\n+\n+/**\n+ * dlb_send_async_pf_to_vf_msg() - (PF only) send a mailbox message to the VF\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID.\n+ *\n+ * This function sends a PF->VF mailbox message. It is asynchronous, so it\n+ * returns once the message is sent but potentially before the VF has processed\n+ * the message. The caller must call dlb_pf_to_vf_complete() to determine when\n+ * the VF has finished processing the request.\n+ */\n+void dlb_send_async_pf_to_vf_msg(struct dlb_hw *hw, unsigned int vf_id);\n+\n+/**\n+ * dlb_pf_to_vf_complete() - check the status of an asynchronous mailbox request\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID.\n+ *\n+ * This function returns a boolean indicating whether the VF has finished\n+ * processing a PF->VF mailbox request. It should only be called after sending\n+ * an asynchronous request with dlb_send_async_pf_to_vf_msg().\n+ */\n+bool dlb_pf_to_vf_complete(struct dlb_hw *hw, unsigned int vf_id);\n+\n+/**\n+ * dlb_pf_read_vf_mbox_req() - (PF only) read a VF->PF mailbox request\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID.\n+ * @data: pointer to message data.\n+ * @len: size, in bytes, of the data array.\n+ *\n+ * This function copies one of the PF's VF->PF mailboxes into the array pointed\n+ * to by data.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * EINVAL - len >= DLB_VF2PF_REQ_BYTES.\n+ */\n+int dlb_pf_read_vf_mbox_req(struct dlb_hw *hw,\n+\t\t\t    unsigned int vf_id,\n+\t\t\t    void *data,\n+\t\t\t    int len);\n+\n+/**\n+ * dlb_pf_read_vf_mbox_resp() - (PF only) read a VF->PF mailbox response\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID.\n+ * @data: pointer to message data.\n+ * @len: size, in bytes, of the data array.\n+ *\n+ * This function copies one of the PF's VF->PF mailboxes into the array pointed\n+ * to by data.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * EINVAL - len >= DLB_VF2PF_RESP_BYTES.\n+ */\n+int dlb_pf_read_vf_mbox_resp(struct dlb_hw *hw,\n+\t\t\t     unsigned int vf_id,\n+\t\t\t     void *data,\n+\t\t\t     int len);\n+\n+/**\n+ * dlb_pf_write_vf_mbox_resp() - (PF only) write a PF->VF mailbox response\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID.\n+ * @data: pointer to message data.\n+ * @len: size, in bytes, of the data array.\n+ *\n+ * This function copies the user-provided message data into of the PF's VF->PF\n+ * mailboxes.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * EINVAL - len >= DLB_PF2VF_RESP_BYTES.\n+ */\n+int dlb_pf_write_vf_mbox_resp(struct dlb_hw *hw,\n+\t\t\t      unsigned int vf_id,\n+\t\t\t      void *data,\n+\t\t\t      int len);\n+\n+/**\n+ * dlb_pf_write_vf_mbox_req() - (PF only) write a PF->VF mailbox request\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID.\n+ * @data: pointer to message data.\n+ * @len: size, in bytes, of the data array.\n+ *\n+ * This function copies the user-provided message data into of the PF's VF->PF\n+ * mailboxes.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * EINVAL - len >= DLB_PF2VF_REQ_BYTES.\n+ */\n+int dlb_pf_write_vf_mbox_req(struct dlb_hw *hw,\n+\t\t\t     unsigned int vf_id,\n+\t\t\t     void *data,\n+\t\t\t     int len);\n+\n+/**\n+ * dlb_vf_read_pf_mbox_resp() - (VF only) read a PF->VF mailbox response\n+ * @hw: dlb_hw handle for a particular device.\n+ * @data: pointer to message data.\n+ * @len: size, in bytes, of the data array.\n+ *\n+ * This function copies the VF's PF->VF mailbox into the array pointed to by\n+ * data.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * EINVAL - len >= DLB_PF2VF_RESP_BYTES.\n+ */\n+int dlb_vf_read_pf_mbox_resp(struct dlb_hw *hw, void *data, int len);\n+\n+/**\n+ * dlb_vf_read_pf_mbox_req() - (VF only) read a PF->VF mailbox request\n+ * @hw: dlb_hw handle for a particular device.\n+ * @data: pointer to message data.\n+ * @len: size, in bytes, of the data array.\n+ *\n+ * This function copies the VF's PF->VF mailbox into the array pointed to by\n+ * data.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * EINVAL - len >= DLB_PF2VF_REQ_BYTES.\n+ */\n+int dlb_vf_read_pf_mbox_req(struct dlb_hw *hw, void *data, int len);\n+\n+/**\n+ * dlb_vf_write_pf_mbox_req() - (VF only) write a VF->PF mailbox request\n+ * @hw: dlb_hw handle for a particular device.\n+ * @data: pointer to message data.\n+ * @len: size, in bytes, of the data array.\n+ *\n+ * This function copies the user-provided message data into of the VF's PF->VF\n+ * mailboxes.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * EINVAL - len >= DLB_VF2PF_REQ_BYTES.\n+ */\n+int dlb_vf_write_pf_mbox_req(struct dlb_hw *hw, void *data, int len);\n+\n+/**\n+ * dlb_vf_write_pf_mbox_resp() - (VF only) write a VF->PF mailbox response\n+ * @hw: dlb_hw handle for a particular device.\n+ * @data: pointer to message data.\n+ * @len: size, in bytes, of the data array.\n+ *\n+ * This function copies the user-provided message data into of the VF's PF->VF\n+ * mailboxes.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * EINVAL - len >= DLB_VF2PF_RESP_BYTES.\n+ */\n+int dlb_vf_write_pf_mbox_resp(struct dlb_hw *hw, void *data, int len);\n+\n+/**\n+ * dlb_reset_vf() - reset the hardware owned by a VF\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ *\n+ * This function resets the hardware owned by a VF (if any), by resetting the\n+ * VF's domains one by one.\n+ */\n+int dlb_reset_vf(struct dlb_hw *hw, unsigned int vf_id);\n+\n+/**\n+ * dlb_vf_is_locked() - check whether the VF's resources are locked\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ *\n+ * This function returns whether or not the VF's resource assignments are\n+ * locked. If locked, no resources can be added to or subtracted from the\n+ * group.\n+ */\n+bool dlb_vf_is_locked(struct dlb_hw *hw, unsigned int vf_id);\n+\n+/**\n+ * dlb_lock_vf() - lock the VF's resources\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ *\n+ * This function sets a flag indicating that the VF is using its resources.\n+ * When VF is locked, its resource assignment cannot be changed.\n+ */\n+void dlb_lock_vf(struct dlb_hw *hw, unsigned int vf_id);\n+\n+/**\n+ * dlb_unlock_vf() - unlock the VF's resources\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ *\n+ * This function unlocks the VF's resource assignment, allowing it to be\n+ * modified.\n+ */\n+void dlb_unlock_vf(struct dlb_hw *hw, unsigned int vf_id);\n+\n+/**\n+ * dlb_update_vf_sched_domains() - update the domains assigned to a VF\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ * @num: number of scheduling domains to assign to this VF\n+ *\n+ * This function assigns num scheduling domains to the specified VF. If the VF\n+ * already has domains assigned, this existing assignment is adjusted\n+ * accordingly.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - vf_id is invalid, or the requested number of resources are\n+ *\t    unavailable.\n+ * EPERM  - The VF's resource assignment is locked and cannot be changed.\n+ */\n+int dlb_update_vf_sched_domains(struct dlb_hw *hw,\n+\t\t\t\tu32 vf_id,\n+\t\t\t\tu32 num);\n+\n+/**\n+ * dlb_update_vf_ldb_queues() - update the LDB queues assigned to a VF\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ * @num: number of LDB queues to assign to this VF\n+ *\n+ * This function assigns num LDB queues to the specified VF. If the VF already\n+ * has LDB queues assigned, this existing assignment is adjusted\n+ * accordingly.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - vf_id is invalid, or the requested number of resources are\n+ *\t    unavailable.\n+ * EPERM  - The VF's resource assignment is locked and cannot be changed.\n+ */\n+int dlb_update_vf_ldb_queues(struct dlb_hw *hw, u32 vf_id, u32 num);\n+\n+/**\n+ * dlb_update_vf_ldb_ports() - update the LDB ports assigned to a VF\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ * @num: number of LDB ports to assign to this VF\n+ *\n+ * This function assigns num LDB ports to the specified VF. If the VF already\n+ * has LDB ports assigned, this existing assignment is adjusted accordingly.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - vf_id is invalid, or the requested number of resources are\n+ *\t    unavailable.\n+ * EPERM  - The VF's resource assignment is locked and cannot be changed.\n+ */\n+int dlb_update_vf_ldb_ports(struct dlb_hw *hw, u32 vf_id, u32 num);\n+\n+/**\n+ * dlb_update_vf_dir_ports() - update the DIR ports assigned to a VF\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ * @num: number of DIR ports to assign to this VF\n+ *\n+ * This function assigns num DIR ports to the specified VF. If the VF already\n+ * has DIR ports assigned, this existing assignment is adjusted accordingly.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - vf_id is invalid, or the requested number of resources are\n+ *\t    unavailable.\n+ * EPERM  - The VF's resource assignment is locked and cannot be changed.\n+ */\n+int dlb_update_vf_dir_ports(struct dlb_hw *hw, u32 vf_id, u32 num);\n+\n+/**\n+ * dlb_update_vf_ldb_credit_pools() - update the VF's assigned LDB pools\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ * @num: number of LDB credit pools to assign to this VF\n+ *\n+ * This function assigns num LDB credit pools to the specified VF. If the VF\n+ * already has LDB credit pools assigned, this existing assignment is adjusted\n+ * accordingly.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - vf_id is invalid, or the requested number of resources are\n+ *\t    unavailable.\n+ * EPERM  - The VF's resource assignment is locked and cannot be changed.\n+ */\n+int dlb_update_vf_ldb_credit_pools(struct dlb_hw *hw,\n+\t\t\t\t   u32 vf_id,\n+\t\t\t\t   u32 num);\n+\n+/**\n+ * dlb_update_vf_dir_credit_pools() - update the VF's assigned DIR pools\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ * @num: number of DIR credit pools to assign to this VF\n+ *\n+ * This function assigns num DIR credit pools to the specified VF. If the VF\n+ * already has DIR credit pools assigned, this existing assignment is adjusted\n+ * accordingly.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - vf_id is invalid, or the requested number of resources are\n+ *\t    unavailable.\n+ * EPERM  - The VF's resource assignment is locked and cannot be changed.\n+ */\n+int dlb_update_vf_dir_credit_pools(struct dlb_hw *hw,\n+\t\t\t\t   u32 vf_id,\n+\t\t\t\t   u32 num);\n+\n+/**\n+ * dlb_update_vf_ldb_credits() - update the VF's assigned LDB credits\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ * @num: number of LDB credits to assign to this VF\n+ *\n+ * This function assigns num LDB credits to the specified VF. If the VF already\n+ * has LDB credits assigned, this existing assignment is adjusted accordingly.\n+ * VF's are assigned a contiguous chunk of credits, so this function may fail\n+ * if a sufficiently large contiguous chunk is not available.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - vf_id is invalid, or the requested number of resources are\n+ *\t    unavailable.\n+ * EPERM  - The VF's resource assignment is locked and cannot be changed.\n+ */\n+int dlb_update_vf_ldb_credits(struct dlb_hw *hw, u32 vf_id, u32 num);\n+\n+/**\n+ * dlb_update_vf_dir_credits() - update the VF's assigned DIR credits\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ * @num: number of DIR credits to assign to this VF\n+ *\n+ * This function assigns num DIR credits to the specified VF. If the VF already\n+ * has DIR credits assigned, this existing assignment is adjusted accordingly.\n+ * VF's are assigned a contiguous chunk of credits, so this function may fail\n+ * if a sufficiently large contiguous chunk is not available.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - vf_id is invalid, or the requested number of resources are\n+ *\t    unavailable.\n+ * EPERM  - The VF's resource assignment is locked and cannot be changed.\n+ */\n+int dlb_update_vf_dir_credits(struct dlb_hw *hw, u32 vf_id, u32 num);\n+\n+/**\n+ * dlb_update_vf_hist_list_entries() - update the VF's assigned HL entries\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ * @num: number of history list entries to assign to this VF\n+ *\n+ * This function assigns num history list entries to the specified VF. If the\n+ * VF already has history list entries assigned, this existing assignment is\n+ * adjusted accordingly. VF's are assigned a contiguous chunk of entries, so\n+ * this function may fail if a sufficiently large contiguous chunk is not\n+ * available.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - vf_id is invalid, or the requested number of resources are\n+ *\t    unavailable.\n+ * EPERM  - The VF's resource assignment is locked and cannot be changed.\n+ */\n+int dlb_update_vf_hist_list_entries(struct dlb_hw *hw,\n+\t\t\t\t    u32 vf_id,\n+\t\t\t\t    u32 num);\n+\n+/**\n+ * dlb_update_vf_atomic_inflights() - update the VF's atomic inflights\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ * @num: number of atomic inflights to assign to this VF\n+ *\n+ * This function assigns num atomic inflights to the specified VF. If the VF\n+ * already has atomic inflights assigned, this existing assignment is adjusted\n+ * accordingly. VF's are assigned a contiguous chunk of entries, so this\n+ * function may fail if a sufficiently large contiguous chunk is not available.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - vf_id is invalid, or the requested number of resources are\n+ *\t    unavailable.\n+ * EPERM  - The VF's resource assignment is locked and cannot be changed.\n+ */\n+int dlb_update_vf_atomic_inflights(struct dlb_hw *hw,\n+\t\t\t\t   u32 vf_id,\n+\t\t\t\t   u32 num);\n+\n+/**\n+ * dlb_reset_vf_resources() - reassign the VF's resources to the PF\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ *\n+ * This function takes any resources currently assigned to the VF and reassigns\n+ * them to the PF.\n+ *\n+ * Return:\n+ * Returns 0 upon success, <0 otherwise.\n+ *\n+ * Errors:\n+ * EINVAL - vf_id is invalid\n+ * EPERM  - The VF's resource assignment is locked and cannot be changed.\n+ */\n+int dlb_reset_vf_resources(struct dlb_hw *hw, unsigned int vf_id);\n+\n+/**\n+ * dlb_notify_vf() - send a notification to a VF\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ * @notification: notification\n+ *\n+ * This function sends a notification (as defined in dlb_mbox.h) to a VF.\n+ *\n+ * Return:\n+ * Returns 0 upon success, -1 if the VF doesn't ACK the PF->VF interrupt.\n+ */\n+int dlb_notify_vf(struct dlb_hw *hw,\n+\t\t  unsigned int vf_id,\n+\t\t  u32 notification);\n+\n+/**\n+ * dlb_vf_in_use() - query whether a VF is in use\n+ * @hw: dlb_hw handle for a particular device.\n+ * @vf_id: VF ID\n+ *\n+ * This function sends a mailbox request to the VF to query whether the VF is in\n+ * use.\n+ *\n+ * Return:\n+ * Returns 0 for false, 1 for true, and -1 if the mailbox request times out or\n+ * an internal error occurs.\n+ */\n+int dlb_vf_in_use(struct dlb_hw *hw, unsigned int vf_id);\n+\n+/**\n+ * dlb_disable_dp_vasr_feature() - disable directed pipe VAS reset hardware\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function disables certain hardware in the directed pipe,\n+ * necessary to workaround a DLB VAS reset issue.\n+ */\n+void dlb_disable_dp_vasr_feature(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_enable_excess_tokens_alarm() - enable interrupts for the excess token\n+ * pop alarm\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function enables the PF ingress error alarm interrupt to fire when an\n+ * excess token pop occurs.\n+ */\n+void dlb_enable_excess_tokens_alarm(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_disable_excess_tokens_alarm() - disable interrupts for the excess token\n+ * pop alarm\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function disables the PF ingress error alarm interrupt to fire when an\n+ * excess token pop occurs.\n+ */\n+void dlb_disable_excess_tokens_alarm(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_hw_get_ldb_queue_depth() - returns the depth of a load-balanced queue\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: queue depth args\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function returns the depth of a load-balanced queue.\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 dlb_error. If successful, resp->id\n+ * contains the depth.\n+ *\n+ * Errors:\n+ * EINVAL - Invalid domain ID or queue ID.\n+ */\n+int dlb_hw_get_ldb_queue_depth(struct dlb_hw *hw,\n+\t\t\t       u32 domain_id,\n+\t\t\t       struct dlb_get_ldb_queue_depth_args *args,\n+\t\t\t       struct dlb_cmd_response *resp,\n+\t\t\t       bool vf_request,\n+\t\t\t       unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_get_dir_queue_depth() - returns the depth of a directed queue\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: queue depth args\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF's ID.\n+ *\n+ * This function returns the depth of a directed queue.\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 dlb_error. If successful, resp->id\n+ * contains the depth.\n+ *\n+ * Errors:\n+ * EINVAL - Invalid domain ID or queue ID.\n+ */\n+int dlb_hw_get_dir_queue_depth(struct dlb_hw *hw,\n+\t\t\t       u32 domain_id,\n+\t\t\t       struct dlb_get_dir_queue_depth_args *args,\n+\t\t\t       struct dlb_cmd_response *resp,\n+\t\t\t       bool vf_request,\n+\t\t\t       unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_pending_port_unmaps() - returns the number of unmap operations in\n+ *\tprogress for a load-balanced port.\n+ * @hw: dlb_hw handle for a particular device.\n+ * @domain_id: domain ID.\n+ * @args: number of unmaps in progress args\n+ * @vf_request: indicates whether this request came from a VF.\n+ * @vf_id: If vf_request is true, this contains the VF'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 dlb_error. If successful, resp->id\n+ * contains the number of unmaps in progress.\n+ *\n+ * Errors:\n+ * EINVAL - Invalid port ID.\n+ */\n+int dlb_hw_pending_port_unmaps(struct dlb_hw *hw,\n+\t\t\t       u32 domain_id,\n+\t\t\t       struct dlb_pending_port_unmaps_args *args,\n+\t\t\t       struct dlb_cmd_response *resp,\n+\t\t\t       bool vf_request,\n+\t\t\t       unsigned int vf_id);\n+\n+/**\n+ * dlb_hw_enable_sparse_ldb_cq_mode() - enable sparse mode for load-balanced\n+ *\tports.\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function must be called prior to configuring scheduling domains.\n+ */\n+void dlb_hw_enable_sparse_ldb_cq_mode(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_hw_enable_sparse_dir_cq_mode() - enable sparse mode for directed ports\n+ * @hw: dlb_hw handle for a particular device.\n+ *\n+ * This function must be called prior to configuring scheduling domains.\n+ */\n+void dlb_hw_enable_sparse_dir_cq_mode(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_hw_set_qe_arbiter_weights() - program QE arbiter weights\n+ * @hw: dlb_hw handle for a particular device.\n+ * @weight: 8-entry array of arbiter weights.\n+ *\n+ * weight[N] programs priority N's weight. In cases where the 8 priorities are\n+ * reduced to 4 bins, the mapping is:\n+ * - weight[1] programs bin 0\n+ * - weight[3] programs bin 1\n+ * - weight[5] programs bin 2\n+ * - weight[7] programs bin 3\n+ */\n+void dlb_hw_set_qe_arbiter_weights(struct dlb_hw *hw, u8 weight[8]);\n+\n+/**\n+ * dlb_hw_set_qid_arbiter_weights() - program QID arbiter weights\n+ * @hw: dlb_hw handle for a particular device.\n+ * @weight: 8-entry array of arbiter weights.\n+ *\n+ * weight[N] programs priority N's weight. In cases where the 8 priorities are\n+ * reduced to 4 bins, the mapping is:\n+ * - weight[1] programs bin 0\n+ * - weight[3] programs bin 1\n+ * - weight[5] programs bin 2\n+ * - weight[7] programs bin 3\n+ */\n+void dlb_hw_set_qid_arbiter_weights(struct dlb_hw *hw, u8 weight[8]);\n+\n+/**\n+ * dlb_hw_enable_pp_sw_alarms() - enable out-of-credit alarm for all producer\n+ * ports\n+ * @hw: dlb_hw handle for a particular device.\n+ */\n+void dlb_hw_enable_pp_sw_alarms(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_hw_disable_pp_sw_alarms() - disable out-of-credit alarm for all producer\n+ * ports\n+ * @hw: dlb_hw handle for a particular device.\n+ */\n+void dlb_hw_disable_pp_sw_alarms(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_hw_disable_pf_to_vf_isr_pend_err() - disable alarm triggered by PF\n+ *\taccess to VF's ISR pending register\n+ * @hw: dlb_hw handle for a particular device.\n+ */\n+void dlb_hw_disable_pf_to_vf_isr_pend_err(struct dlb_hw *hw);\n+\n+/**\n+ * dlb_hw_disable_vf_to_pf_isr_pend_err() - disable alarm triggered by VF\n+ *\taccess to PF's ISR pending register\n+ * @hw: dlb_hw handle for a particular device.\n+ */\n+void dlb_hw_disable_vf_to_pf_isr_pend_err(struct dlb_hw *hw);\n+\n+#endif /* __DLB_RESOURCE_H */\ndiff --git a/drivers/event/dlb/pf/base/dlb_user.h b/drivers/event/dlb/pf/base/dlb_user.h\nnew file mode 100644\nindex 0000000..6e7ee2e\n--- /dev/null\n+++ b/drivers/event/dlb/pf/base/dlb_user.h\n@@ -0,0 +1,1084 @@\n+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)\n+ * Copyright(c) 2016-2020 Intel Corporation\n+ */\n+\n+#ifndef __DLB_USER_H\n+#define __DLB_USER_H\n+\n+#define DLB_MAX_NAME_LEN 64\n+\n+#include \"dlb_osdep_types.h\"\n+\n+enum dlb_error {\n+\tDLB_ST_SUCCESS = 0,\n+\tDLB_ST_NAME_EXISTS,\n+\tDLB_ST_DOMAIN_UNAVAILABLE,\n+\tDLB_ST_LDB_PORTS_UNAVAILABLE,\n+\tDLB_ST_DIR_PORTS_UNAVAILABLE,\n+\tDLB_ST_LDB_QUEUES_UNAVAILABLE,\n+\tDLB_ST_LDB_CREDITS_UNAVAILABLE,\n+\tDLB_ST_DIR_CREDITS_UNAVAILABLE,\n+\tDLB_ST_LDB_CREDIT_POOLS_UNAVAILABLE,\n+\tDLB_ST_DIR_CREDIT_POOLS_UNAVAILABLE,\n+\tDLB_ST_SEQUENCE_NUMBERS_UNAVAILABLE,\n+\tDLB_ST_INVALID_DOMAIN_ID,\n+\tDLB_ST_INVALID_QID_INFLIGHT_ALLOCATION,\n+\tDLB_ST_ATOMIC_INFLIGHTS_UNAVAILABLE,\n+\tDLB_ST_HIST_LIST_ENTRIES_UNAVAILABLE,\n+\tDLB_ST_INVALID_LDB_CREDIT_POOL_ID,\n+\tDLB_ST_INVALID_DIR_CREDIT_POOL_ID,\n+\tDLB_ST_INVALID_POP_COUNT_VIRT_ADDR,\n+\tDLB_ST_INVALID_LDB_QUEUE_ID,\n+\tDLB_ST_INVALID_CQ_DEPTH,\n+\tDLB_ST_INVALID_CQ_VIRT_ADDR,\n+\tDLB_ST_INVALID_PORT_ID,\n+\tDLB_ST_INVALID_QID,\n+\tDLB_ST_INVALID_PRIORITY,\n+\tDLB_ST_NO_QID_SLOTS_AVAILABLE,\n+\tDLB_ST_QED_FREELIST_ENTRIES_UNAVAILABLE,\n+\tDLB_ST_DQED_FREELIST_ENTRIES_UNAVAILABLE,\n+\tDLB_ST_INVALID_DIR_QUEUE_ID,\n+\tDLB_ST_DIR_QUEUES_UNAVAILABLE,\n+\tDLB_ST_INVALID_LDB_CREDIT_LOW_WATERMARK,\n+\tDLB_ST_INVALID_LDB_CREDIT_QUANTUM,\n+\tDLB_ST_INVALID_DIR_CREDIT_LOW_WATERMARK,\n+\tDLB_ST_INVALID_DIR_CREDIT_QUANTUM,\n+\tDLB_ST_DOMAIN_NOT_CONFIGURED,\n+\tDLB_ST_PID_ALREADY_ATTACHED,\n+\tDLB_ST_PID_NOT_ATTACHED,\n+\tDLB_ST_INTERNAL_ERROR,\n+\tDLB_ST_DOMAIN_IN_USE,\n+\tDLB_ST_IOMMU_MAPPING_ERROR,\n+\tDLB_ST_FAIL_TO_PIN_MEMORY_PAGE,\n+\tDLB_ST_UNABLE_TO_PIN_POPCOUNT_PAGES,\n+\tDLB_ST_UNABLE_TO_PIN_CQ_PAGES,\n+\tDLB_ST_DISCONTIGUOUS_CQ_MEMORY,\n+\tDLB_ST_DISCONTIGUOUS_POP_COUNT_MEMORY,\n+\tDLB_ST_DOMAIN_STARTED,\n+\tDLB_ST_LARGE_POOL_NOT_SPECIFIED,\n+\tDLB_ST_SMALL_POOL_NOT_SPECIFIED,\n+\tDLB_ST_NEITHER_POOL_SPECIFIED,\n+\tDLB_ST_DOMAIN_NOT_STARTED,\n+\tDLB_ST_INVALID_MEASUREMENT_DURATION,\n+\tDLB_ST_INVALID_PERF_METRIC_GROUP_ID,\n+\tDLB_ST_LDB_PORT_REQUIRED_FOR_LDB_QUEUES,\n+\tDLB_ST_DOMAIN_RESET_FAILED,\n+\tDLB_ST_MBOX_ERROR,\n+\tDLB_ST_INVALID_HIST_LIST_DEPTH,\n+\tDLB_ST_NO_MEMORY,\n+};\n+\n+static const char dlb_error_strings[][128] = {\n+\t\"DLB_ST_SUCCESS\",\n+\t\"DLB_ST_NAME_EXISTS\",\n+\t\"DLB_ST_DOMAIN_UNAVAILABLE\",\n+\t\"DLB_ST_LDB_PORTS_UNAVAILABLE\",\n+\t\"DLB_ST_DIR_PORTS_UNAVAILABLE\",\n+\t\"DLB_ST_LDB_QUEUES_UNAVAILABLE\",\n+\t\"DLB_ST_LDB_CREDITS_UNAVAILABLE\",\n+\t\"DLB_ST_DIR_CREDITS_UNAVAILABLE\",\n+\t\"DLB_ST_LDB_CREDIT_POOLS_UNAVAILABLE\",\n+\t\"DLB_ST_DIR_CREDIT_POOLS_UNAVAILABLE\",\n+\t\"DLB_ST_SEQUENCE_NUMBERS_UNAVAILABLE\",\n+\t\"DLB_ST_INVALID_DOMAIN_ID\",\n+\t\"DLB_ST_INVALID_QID_INFLIGHT_ALLOCATION\",\n+\t\"DLB_ST_ATOMIC_INFLIGHTS_UNAVAILABLE\",\n+\t\"DLB_ST_HIST_LIST_ENTRIES_UNAVAILABLE\",\n+\t\"DLB_ST_INVALID_LDB_CREDIT_POOL_ID\",\n+\t\"DLB_ST_INVALID_DIR_CREDIT_POOL_ID\",\n+\t\"DLB_ST_INVALID_POP_COUNT_VIRT_ADDR\",\n+\t\"DLB_ST_INVALID_LDB_QUEUE_ID\",\n+\t\"DLB_ST_INVALID_CQ_DEPTH\",\n+\t\"DLB_ST_INVALID_CQ_VIRT_ADDR\",\n+\t\"DLB_ST_INVALID_PORT_ID\",\n+\t\"DLB_ST_INVALID_QID\",\n+\t\"DLB_ST_INVALID_PRIORITY\",\n+\t\"DLB_ST_NO_QID_SLOTS_AVAILABLE\",\n+\t\"DLB_ST_QED_FREELIST_ENTRIES_UNAVAILABLE\",\n+\t\"DLB_ST_DQED_FREELIST_ENTRIES_UNAVAILABLE\",\n+\t\"DLB_ST_INVALID_DIR_QUEUE_ID\",\n+\t\"DLB_ST_DIR_QUEUES_UNAVAILABLE\",\n+\t\"DLB_ST_INVALID_LDB_CREDIT_LOW_WATERMARK\",\n+\t\"DLB_ST_INVALID_LDB_CREDIT_QUANTUM\",\n+\t\"DLB_ST_INVALID_DIR_CREDIT_LOW_WATERMARK\",\n+\t\"DLB_ST_INVALID_DIR_CREDIT_QUANTUM\",\n+\t\"DLB_ST_DOMAIN_NOT_CONFIGURED\",\n+\t\"DLB_ST_PID_ALREADY_ATTACHED\",\n+\t\"DLB_ST_PID_NOT_ATTACHED\",\n+\t\"DLB_ST_INTERNAL_ERROR\",\n+\t\"DLB_ST_DOMAIN_IN_USE\",\n+\t\"DLB_ST_IOMMU_MAPPING_ERROR\",\n+\t\"DLB_ST_FAIL_TO_PIN_MEMORY_PAGE\",\n+\t\"DLB_ST_UNABLE_TO_PIN_POPCOUNT_PAGES\",\n+\t\"DLB_ST_UNABLE_TO_PIN_CQ_PAGES\",\n+\t\"DLB_ST_DISCONTIGUOUS_CQ_MEMORY\",\n+\t\"DLB_ST_DISCONTIGUOUS_POP_COUNT_MEMORY\",\n+\t\"DLB_ST_DOMAIN_STARTED\",\n+\t\"DLB_ST_LARGE_POOL_NOT_SPECIFIED\",\n+\t\"DLB_ST_SMALL_POOL_NOT_SPECIFIED\",\n+\t\"DLB_ST_NEITHER_POOL_SPECIFIED\",\n+\t\"DLB_ST_DOMAIN_NOT_STARTED\",\n+\t\"DLB_ST_INVALID_MEASUREMENT_DURATION\",\n+\t\"DLB_ST_INVALID_PERF_METRIC_GROUP_ID\",\n+\t\"DLB_ST_LDB_PORT_REQUIRED_FOR_LDB_QUEUES\",\n+\t\"DLB_ST_DOMAIN_RESET_FAILED\",\n+\t\"DLB_ST_MBOX_ERROR\",\n+\t\"DLB_ST_INVALID_HIST_LIST_DEPTH\",\n+\t\"DLB_ST_NO_MEMORY\",\n+};\n+\n+struct dlb_cmd_response {\n+\t__u32 status; /* Interpret using enum dlb_error */\n+\t__u32 id;\n+};\n+\n+/******************************/\n+/* 'dlb' device file commands */\n+/******************************/\n+\n+#define DLB_DEVICE_VERSION(x) (((x) >> 8) & 0xFF)\n+#define DLB_DEVICE_REVISION(x) ((x) & 0xFF)\n+\n+enum dlb_revisions {\n+\tDLB_REV_A0 = 0,\n+\tDLB_REV_A1 = 1,\n+\tDLB_REV_A2 = 2,\n+\tDLB_REV_A3 = 3,\n+\tDLB_REV_B0 = 4,\n+};\n+\n+/*\n+ * DLB_CMD_GET_DEVICE_VERSION: Query the DLB device version.\n+ *\n+ *\tThis ioctl interface is the same in all driver versions and is always\n+ *\tthe first ioctl.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id[7:0]: Device revision.\n+ *\tresponse.id[15:8]: Device version.\n+ */\n+\n+struct dlb_get_device_version_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+};\n+\n+#define DLB_VERSION_MAJOR_NUMBER 10\n+#define DLB_VERSION_MINOR_NUMBER 7\n+#define DLB_VERSION_REVISION_NUMBER 9\n+#define DLB_VERSION (DLB_VERSION_MAJOR_NUMBER << 24 | \\\n+\t\t     DLB_VERSION_MINOR_NUMBER << 16 | \\\n+\t\t     DLB_VERSION_REVISION_NUMBER)\n+\n+#define DLB_VERSION_GET_MAJOR_NUMBER(x) (((x) >> 24) & 0xFF)\n+#define DLB_VERSION_GET_MINOR_NUMBER(x) (((x) >> 16) & 0xFF)\n+#define DLB_VERSION_GET_REVISION_NUMBER(x) ((x) & 0xFFFF)\n+\n+static inline __u8 dlb_version_incompatible(__u32 version)\n+{\n+\t__u8 inc;\n+\n+\tinc = DLB_VERSION_GET_MAJOR_NUMBER(version) != DLB_VERSION_MAJOR_NUMBER;\n+\tinc |= (int)DLB_VERSION_GET_MINOR_NUMBER(version) <\n+\t\tDLB_VERSION_MINOR_NUMBER;\n+\n+\treturn inc;\n+}\n+\n+/*\n+ * DLB_CMD_GET_DRIVER_VERSION: Query the DLB driver version. The major number\n+ *\tis changed when there is an ABI-breaking change, the minor number is\n+ *\tchanged if the API is changed in a backwards-compatible way, and the\n+ *\trevision number is changed for fixes that don't affect the API.\n+ *\n+ *\tIf the kernel driver's API version major number and the header's\n+ *\tDLB_VERSION_MAJOR_NUMBER differ, the two are incompatible, or if the\n+ *\tmajor numbers match but the kernel driver's minor number is less than\n+ *\tthe header file's, they are incompatible. The DLB_VERSION_INCOMPATIBLE\n+ *\tmacro should be used to check for compatibility.\n+ *\n+ *\tThis ioctl interface is the same in all driver versions. Applications\n+ *\tshould check the driver version before performing any other ioctl\n+ *\toperations.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id: Driver API version. Use the DLB_VERSION_GET_MAJOR_NUMBER,\n+ *\t\tDLB_VERSION_GET_MINOR_NUMBER, and\n+ *\t\tDLB_VERSION_GET_REVISION_NUMBER macros to interpret the field.\n+ */\n+\n+struct dlb_get_driver_version_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+};\n+\n+/*\n+ * DLB_CMD_CREATE_SCHED_DOMAIN: Create a DLB scheduling domain and reserve the\n+ *\tresources (queues, ports, etc.) that it contains.\n+ *\n+ * Input parameters:\n+ * - num_ldb_queues: Number of load-balanced queues.\n+ * - num_ldb_ports: Number of load-balanced ports.\n+ * - num_dir_ports: Number of directed ports. A directed port has one directed\n+ *\tqueue, so no num_dir_queues argument is necessary.\n+ * - num_atomic_inflights: This specifies the amount of temporary atomic QE\n+ *\tstorage for the domain. This storage is divided among the domain's\n+ *\tload-balanced queues that are configured for atomic scheduling.\n+ * - num_hist_list_entries: Amount of history list storage. This is divided\n+ *\tamong the domain's CQs.\n+ * - num_ldb_credits: Amount of load-balanced QE storage (QED). QEs occupy this\n+ *\tspace until they are scheduled to a load-balanced CQ. One credit\n+ *\trepresents the storage for one QE.\n+ * - num_dir_credits: Amount of directed QE storage (DQED). QEs occupy this\n+ *\tspace until they are scheduled to a directed CQ. One credit represents\n+ *\tthe storage for one QE.\n+ * - num_ldb_credit_pools: Number of pools into which the load-balanced credits\n+ *\tare placed.\n+ * - num_dir_credit_pools: Number of pools into which the directed credits are\n+ *\tplaced.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id: domain ID.\n+ */\n+struct dlb_create_sched_domain_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 num_ldb_queues;\n+\t__u32 num_ldb_ports;\n+\t__u32 num_dir_ports;\n+\t__u32 num_atomic_inflights;\n+\t__u32 num_hist_list_entries;\n+\t__u32 num_ldb_credits;\n+\t__u32 num_dir_credits;\n+\t__u32 num_ldb_credit_pools;\n+\t__u32 num_dir_credit_pools;\n+};\n+\n+/*\n+ * DLB_CMD_GET_NUM_RESOURCES: Return the number of available resources\n+ *\t(queues, ports, etc.) that this device owns.\n+ *\n+ * Output parameters:\n+ * - num_domains: Number of available scheduling domains.\n+ * - num_ldb_queues: Number of available load-balanced queues.\n+ * - num_ldb_ports: Number of available load-balanced ports.\n+ * - num_dir_ports: Number of available directed ports. There is one directed\n+ *\tqueue for every directed port.\n+ * - num_atomic_inflights: Amount of available temporary atomic QE storage.\n+ * - max_contiguous_atomic_inflights: When a domain is created, the temporary\n+ *\tatomic QE storage is allocated in a contiguous chunk. This return value\n+ *\tis the longest available contiguous range of atomic QE storage.\n+ * - num_hist_list_entries: Amount of history list storage.\n+ * - max_contiguous_hist_list_entries: History list storage is allocated in\n+ *\ta contiguous chunk, and this return value is the longest available\n+ *\tcontiguous range of history list entries.\n+ * - num_ldb_credits: Amount of available load-balanced QE storage.\n+ * - max_contiguous_ldb_credits: QED storage is allocated in a contiguous\n+ *\tchunk, and this return value is the longest available contiguous range\n+ *\tof load-balanced credit storage.\n+ * - num_dir_credits: Amount of available directed QE storage.\n+ * - max_contiguous_dir_credits: DQED storage is allocated in a contiguous\n+ *\tchunk, and this return value is the longest available contiguous range\n+ *\tof directed credit storage.\n+ * - num_ldb_credit_pools: Number of available load-balanced credit pools.\n+ * - num_dir_credit_pools: Number of available directed credit pools.\n+ * - padding0: Reserved for future use.\n+ */\n+struct dlb_get_num_resources_args {\n+\t/* Output parameters */\n+\t__u32 num_sched_domains;\n+\t__u32 num_ldb_queues;\n+\t__u32 num_ldb_ports;\n+\t__u32 num_dir_ports;\n+\t__u32 num_atomic_inflights;\n+\t__u32 max_contiguous_atomic_inflights;\n+\t__u32 num_hist_list_entries;\n+\t__u32 max_contiguous_hist_list_entries;\n+\t__u32 num_ldb_credits;\n+\t__u32 max_contiguous_ldb_credits;\n+\t__u32 num_dir_credits;\n+\t__u32 max_contiguous_dir_credits;\n+\t__u32 num_ldb_credit_pools;\n+\t__u32 num_dir_credit_pools;\n+\t__u32 padding0;\n+};\n+\n+/*\n+ * DLB_CMD_SET_SN_ALLOCATION: Configure a sequence number group\n+ *\n+ * Input parameters:\n+ * - group: Sequence number group ID.\n+ * - num: Number of sequence numbers per queue.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ */\n+struct dlb_set_sn_allocation_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 group;\n+\t__u32 num;\n+};\n+\n+/*\n+ * DLB_CMD_GET_SN_ALLOCATION: Get a sequence number group's configuration\n+ *\n+ * Input parameters:\n+ * - group: Sequence number group ID.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id: Specified group's number of sequence numbers per queue.\n+ */\n+struct dlb_get_sn_allocation_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 group;\n+\t__u32 padding0;\n+};\n+\n+/*\n+ * DLB_CMD_QUERY_CQ_POLL_MODE: Query the CQ poll mode the kernel driver is using\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id: CQ poll mode (see enum dlb_cq_poll_modes).\n+ */\n+struct dlb_query_cq_poll_mode_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+};\n+\n+enum dlb_cq_poll_modes {\n+\tDLB_CQ_POLL_MODE_STD,\n+\tDLB_CQ_POLL_MODE_SPARSE,\n+\n+\t/* NUM_DLB_CQ_POLL_MODE must be last */\n+\tNUM_DLB_CQ_POLL_MODE,\n+};\n+\n+/*\n+ * DLB_CMD_GET_SN_OCCUPANCY: Get a sequence number group's occupancy\n+ *\n+ * Each sequence number group has one or more slots, depending on its\n+ * configuration. I.e.:\n+ * - If configured for 1024 sequence numbers per queue, the group has 1 slot\n+ * - If configured for 512 sequence numbers per queue, the group has 2 slots\n+ *   ...\n+ * - If configured for 32 sequence numbers per queue, the group has 32 slots\n+ *\n+ * This ioctl returns the group's number of in-use slots. If its occupancy is\n+ * 0, the group's sequence number allocation can be reconfigured.\n+ *\n+ * Input parameters:\n+ * - group: Sequence number group ID.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id: Specified group's number of used slots.\n+ */\n+struct dlb_get_sn_occupancy_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 group;\n+\t__u32 padding0;\n+};\n+\n+enum dlb_user_interface_commands {\n+\tDLB_CMD_GET_DEVICE_VERSION,\n+\tDLB_CMD_CREATE_SCHED_DOMAIN,\n+\tDLB_CMD_GET_NUM_RESOURCES,\n+\tDLB_CMD_GET_DRIVER_VERSION,\n+\tDLB_CMD_SAMPLE_PERF_COUNTERS,\n+\tDLB_CMD_SET_SN_ALLOCATION,\n+\tDLB_CMD_GET_SN_ALLOCATION,\n+\tDLB_CMD_MEASURE_SCHED_COUNTS,\n+\tDLB_CMD_QUERY_CQ_POLL_MODE,\n+\tDLB_CMD_GET_SN_OCCUPANCY,\n+\n+\t/* NUM_DLB_CMD must be last */\n+\tNUM_DLB_CMD,\n+};\n+\n+/*******************************/\n+/* 'domain' device file alerts */\n+/*******************************/\n+\n+/* Scheduling domain device files can be read to receive domain-specific\n+ * notifications, for alerts such as hardware errors.\n+ *\n+ * Each alert is encoded in a 16B message. The first 8B contains the alert ID,\n+ * and the second 8B is optional and contains additional information.\n+ * Applications should cast read data to a struct dlb_domain_alert, and\n+ * interpret the struct's alert_id according to dlb_domain_alert_id. The read\n+ * length must be 16B, or the function will return -EINVAL.\n+ *\n+ * Reads are destructive, and in the case of multiple file descriptors for the\n+ * same domain device file, an alert will be read by only one of the file\n+ * descriptors.\n+ *\n+ * The driver stores alerts in a fixed-size alert ring until they are read. If\n+ * the alert ring fills completely, subsequent alerts will be dropped. It is\n+ * recommended that DLB applications dedicate a thread to perform blocking\n+ * reads on the device file.\n+ */\n+enum dlb_domain_alert_id {\n+\t/* A destination domain queue that this domain connected to has\n+\t * unregistered, and can no longer be sent to. The aux alert data\n+\t * contains the queue ID.\n+\t */\n+\tDLB_DOMAIN_ALERT_REMOTE_QUEUE_UNREGISTER,\n+\t/* A producer port in this domain attempted to send a QE without a\n+\t * credit. aux_alert_data[7:0] contains the port ID, and\n+\t * aux_alert_data[15:8] contains a flag indicating whether the port is\n+\t * load-balanced (1) or directed (0).\n+\t */\n+\tDLB_DOMAIN_ALERT_PP_OUT_OF_CREDITS,\n+\t/* Software issued an illegal enqueue for a port in this domain. An\n+\t * illegal enqueue could be:\n+\t * - Illegal (excess) completion\n+\t * - Illegal fragment\n+\t * - Illegal enqueue command\n+\t * aux_alert_data[7:0] contains the port ID, and aux_alert_data[15:8]\n+\t * contains a flag indicating whether the port is load-balanced (1) or\n+\t * directed (0).\n+\t */\n+\tDLB_DOMAIN_ALERT_PP_ILLEGAL_ENQ,\n+\t/* Software issued excess CQ token pops for a port in this domain.\n+\t * aux_alert_data[7:0] contains the port ID, and aux_alert_data[15:8]\n+\t * contains a flag indicating whether the port is load-balanced (1) or\n+\t * directed (0).\n+\t */\n+\tDLB_DOMAIN_ALERT_PP_EXCESS_TOKEN_POPS,\n+\t/* A enqueue contained either an invalid command encoding or a REL,\n+\t * REL_T, RLS, FWD, FWD_T, FRAG, or FRAG_T from a directed port.\n+\t *\n+\t * aux_alert_data[7:0] contains the port ID, and aux_alert_data[15:8]\n+\t * contains a flag indicating whether the port is load-balanced (1) or\n+\t * directed (0).\n+\t */\n+\tDLB_DOMAIN_ALERT_ILLEGAL_HCW,\n+\t/* The QID must be valid and less than 128.\n+\t *\n+\t * aux_alert_data[7:0] contains the port ID, and aux_alert_data[15:8]\n+\t * contains a flag indicating whether the port is load-balanced (1) or\n+\t * directed (0).\n+\t */\n+\tDLB_DOMAIN_ALERT_ILLEGAL_QID,\n+\t/* An enqueue went to a disabled QID.\n+\t *\n+\t * aux_alert_data[7:0] contains the port ID, and aux_alert_data[15:8]\n+\t * contains a flag indicating whether the port is load-balanced (1) or\n+\t * directed (0).\n+\t */\n+\tDLB_DOMAIN_ALERT_DISABLED_QID,\n+\t/* The device containing this domain was reset. All applications using\n+\t * the device need to exit for the driver to complete the reset\n+\t * procedure.\n+\t *\n+\t * aux_alert_data doesn't contain any information for this alert.\n+\t */\n+\tDLB_DOMAIN_ALERT_DEVICE_RESET,\n+\t/* User-space has enqueued an alert.\n+\t *\n+\t * aux_alert_data contains user-provided data.\n+\t */\n+\tDLB_DOMAIN_ALERT_USER,\n+\n+\t/* Number of DLB domain alerts */\n+\tNUM_DLB_DOMAIN_ALERTS\n+};\n+\n+static const char dlb_domain_alert_strings[][128] = {\n+\t\"DLB_DOMAIN_ALERT_REMOTE_QUEUE_UNREGISTER\",\n+\t\"DLB_DOMAIN_ALERT_PP_OUT_OF_CREDITS\",\n+\t\"DLB_DOMAIN_ALERT_PP_ILLEGAL_ENQ\",\n+\t\"DLB_DOMAIN_ALERT_PP_EXCESS_TOKEN_POPS\",\n+\t\"DLB_DOMAIN_ALERT_ILLEGAL_HCW\",\n+\t\"DLB_DOMAIN_ALERT_ILLEGAL_QID\",\n+\t\"DLB_DOMAIN_ALERT_DISABLED_QID\",\n+\t\"DLB_DOMAIN_ALERT_DEVICE_RESET\",\n+\t\"DLB_DOMAIN_ALERT_USER\",\n+};\n+\n+struct dlb_domain_alert {\n+\t__u64 alert_id;\n+\t__u64 aux_alert_data;\n+};\n+\n+/*********************************/\n+/* 'domain' device file commands */\n+/*********************************/\n+\n+/*\n+ * DLB_DOMAIN_CMD_CREATE_LDB_POOL: Configure a load-balanced credit pool.\n+ * Input parameters:\n+ * - num_ldb_credits: Number of load-balanced credits (QED space) for this\n+ *\tpool.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id: pool ID.\n+ */\n+struct dlb_create_ldb_pool_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 num_ldb_credits;\n+\t__u32 padding0;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_CREATE_DIR_POOL: Configure a directed credit pool.\n+ * Input parameters:\n+ * - num_dir_credits: Number of directed credits (DQED space) for this pool.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id: Pool ID.\n+ */\n+struct dlb_create_dir_pool_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 num_dir_credits;\n+\t__u32 padding0;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_CREATE_LDB_QUEUE: Configure a load-balanced queue.\n+ * Input parameters:\n+ * - num_atomic_inflights: This specifies the amount of temporary atomic QE\n+ *\tstorage for this queue. If zero, the queue will not support atomic\n+ *\tscheduling.\n+ * - num_sequence_numbers: This specifies the number of sequence numbers used\n+ *\tby this queue. If zero, the queue will not support ordered scheduling.\n+ *\tIf non-zero, the queue will not support unordered scheduling.\n+ * - num_qid_inflights: The maximum number of QEs that can be inflight\n+ *\t(scheduled to a CQ but not completed) at any time. If\n+ *\tnum_sequence_numbers is non-zero, num_qid_inflights must be set equal\n+ *\tto num_sequence_numbers.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id: Queue ID.\n+ */\n+struct dlb_create_ldb_queue_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 num_sequence_numbers;\n+\t__u32 num_qid_inflights;\n+\t__u32 num_atomic_inflights;\n+\t__u32 padding0;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_CREATE_DIR_QUEUE: Configure a directed queue.\n+ * Input parameters:\n+ * - port_id: Port ID. If the corresponding directed port is already created,\n+ *\tspecify its ID here. Else this argument must be 0xFFFFFFFF to indicate\n+ *\tthat the queue is being created before the port.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id: Queue ID.\n+ */\n+struct dlb_create_dir_queue_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__s32 port_id;\n+\t__u32 padding0;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_CREATE_LDB_PORT: Configure a load-balanced port.\n+ * Input parameters:\n+ * - ldb_credit_pool_id: Load-balanced credit pool this port will belong to.\n+ * - dir_credit_pool_id: Directed credit pool this port will belong to.\n+ * - ldb_credit_high_watermark: Number of load-balanced credits from the pool\n+ *\tthat this port will own.\n+ *\n+ *\tIf this port's scheduling domain doesn't have any load-balanced queues,\n+ *\tthis argument is ignored and the port is given no load-balanced\n+ *\tcredits.\n+ * - dir_credit_high_watermark: Number of directed credits from the pool that\n+ *\tthis port will own.\n+ *\n+ *\tIf this port's scheduling domain doesn't have any directed queues,\n+ *\tthis argument is ignored and the port is given no directed credits.\n+ * - ldb_credit_low_watermark: Load-balanced credit low watermark. When the\n+ *\tport's credits reach this watermark, they become eligible to be\n+ *\trefilled by the DLB as credits until the high watermark\n+ *\t(num_ldb_credits) is reached.\n+ *\n+ *\tIf this port's scheduling domain doesn't have any load-balanced queues,\n+ *\tthis argument is ignored and the port is given no load-balanced\n+ *\tcredits.\n+ * - dir_credit_low_watermark: Directed credit low watermark. When the port's\n+ *\tcredits reach this watermark, they become eligible to be refilled by\n+ *\tthe DLB as credits until the high watermark (num_dir_credits) is\n+ *\treached.\n+ *\n+ *\tIf this port's scheduling domain doesn't have any directed queues,\n+ *\tthis argument is ignored and the port is given no directed credits.\n+ * - ldb_credit_quantum: Number of load-balanced credits for the DLB to refill\n+ *\tper refill operation.\n+ *\n+ *\tIf this port's scheduling domain doesn't have any load-balanced queues,\n+ *\tthis argument is ignored and the port is given no load-balanced\n+ *\tcredits.\n+ * - dir_credit_quantum: Number of directed credits for the DLB to refill per\n+ *\trefill operation.\n+ *\n+ *\tIf this port's scheduling domain doesn't have any directed queues,\n+ *\tthis argument is ignored and the port is given no directed credits.\n+ * - padding0: Reserved for future use.\n+ * - cq_depth: Depth of the port's CQ. Must be a power-of-two between 8 and\n+ *\t1024, inclusive.\n+ * - cq_depth_threshold: CQ depth interrupt threshold. A value of N means that\n+ *\tthe CQ interrupt won't fire until there are N or more outstanding CQ\n+ *\ttokens.\n+ * - cq_history_list_size: Number of history list entries. This must be greater\n+ *\tthan or equal to cq_depth.\n+ * - padding1: Reserved for future use.\n+ * - padding2: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id: port ID.\n+ */\n+struct dlb_create_ldb_port_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 ldb_credit_pool_id;\n+\t__u32 dir_credit_pool_id;\n+\t__u16 ldb_credit_high_watermark;\n+\t__u16 ldb_credit_low_watermark;\n+\t__u16 ldb_credit_quantum;\n+\t__u16 dir_credit_high_watermark;\n+\t__u16 dir_credit_low_watermark;\n+\t__u16 dir_credit_quantum;\n+\t__u16 padding0;\n+\t__u16 cq_depth;\n+\t__u16 cq_depth_threshold;\n+\t__u16 cq_history_list_size;\n+\t__u32 padding1;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_CREATE_DIR_PORT: Configure a directed port.\n+ * Input parameters:\n+ * - ldb_credit_pool_id: Load-balanced credit pool this port will belong to.\n+ * - dir_credit_pool_id: Directed credit pool this port will belong to.\n+ * - ldb_credit_high_watermark: Number of load-balanced credits from the pool\n+ *\tthat this port will own.\n+ *\n+ *\tIf this port's scheduling domain doesn't have any load-balanced queues,\n+ *\tthis argument is ignored and the port is given no load-balanced\n+ *\tcredits.\n+ * - dir_credit_high_watermark: Number of directed credits from the pool that\n+ *\tthis port will own.\n+ * - ldb_credit_low_watermark: Load-balanced credit low watermark. When the\n+ *\tport's credits reach this watermark, they become eligible to be\n+ *\trefilled by the DLB as credits until the high watermark\n+ *\t(num_ldb_credits) is reached.\n+ *\n+ *\tIf this port's scheduling domain doesn't have any load-balanced queues,\n+ *\tthis argument is ignored and the port is given no load-balanced\n+ *\tcredits.\n+ * - dir_credit_low_watermark: Directed credit low watermark. When the port's\n+ *\tcredits reach this watermark, they become eligible to be refilled by\n+ *\tthe DLB as credits until the high watermark (num_dir_credits) is\n+ *\treached.\n+ * - ldb_credit_quantum: Number of load-balanced credits for the DLB to refill\n+ *\tper refill operation.\n+ *\n+ *\tIf this port's scheduling domain doesn't have any load-balanced queues,\n+ *\tthis argument is ignored and the port is given no load-balanced\n+ *\tcredits.\n+ * - dir_credit_quantum: Number of directed credits for the DLB to refill per\n+ *\trefill operation.\n+ * - cq_depth: Depth of the port's CQ. Must be a power-of-two between 8 and\n+ *\t1024, inclusive.\n+ * - cq_depth_threshold: CQ depth interrupt threshold. A value of N means that\n+ *\tthe CQ interrupt won't fire until there are N or more outstanding CQ\n+ *\ttokens.\n+ * - qid: Queue ID. If the corresponding directed queue is already created,\n+ *\tspecify its ID here. Else this argument must be 0xFFFFFFFF to indicate\n+ *\tthat the port is being created before the queue.\n+ * - padding1: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id: Port ID.\n+ */\n+struct dlb_create_dir_port_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 ldb_credit_pool_id;\n+\t__u32 dir_credit_pool_id;\n+\t__u16 ldb_credit_high_watermark;\n+\t__u16 ldb_credit_low_watermark;\n+\t__u16 ldb_credit_quantum;\n+\t__u16 dir_credit_high_watermark;\n+\t__u16 dir_credit_low_watermark;\n+\t__u16 dir_credit_quantum;\n+\t__u16 cq_depth;\n+\t__u16 cq_depth_threshold;\n+\t__s32 queue_id;\n+\t__u32 padding1;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_START_DOMAIN: Mark the end of the domain configuration. This\n+ *\tmust be called before passing QEs into the device, and no configuration\n+ *\tioctls can be issued once the domain has started. Sending QEs into the\n+ *\tdevice before calling this ioctl will result in undefined behavior.\n+ * Input parameters:\n+ * - (None)\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ */\n+struct dlb_start_domain_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_MAP_QID: Map a load-balanced queue to a load-balanced port.\n+ * Input parameters:\n+ * - port_id: Load-balanced port ID.\n+ * - qid: Load-balanced queue ID.\n+ * - priority: Queue->port service priority.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ */\n+struct dlb_map_qid_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 port_id;\n+\t__u32 qid;\n+\t__u32 priority;\n+\t__u32 padding0;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_UNMAP_QID: Unmap a load-balanced queue to a load-balanced\n+ *\tport.\n+ * Input parameters:\n+ * - port_id: Load-balanced port ID.\n+ * - qid: Load-balanced queue ID.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ */\n+struct dlb_unmap_qid_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 port_id;\n+\t__u32 qid;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_ENABLE_LDB_PORT: Enable scheduling to a load-balanced port.\n+ * Input parameters:\n+ * - port_id: Load-balanced port ID.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ */\n+struct dlb_enable_ldb_port_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 port_id;\n+\t__u32 padding0;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_ENABLE_DIR_PORT: Enable scheduling to a directed port.\n+ * Input parameters:\n+ * - port_id: Directed port ID.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ */\n+struct dlb_enable_dir_port_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 port_id;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_DISABLE_LDB_PORT: Disable scheduling to a load-balanced port.\n+ * Input parameters:\n+ * - port_id: Load-balanced port ID.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ */\n+struct dlb_disable_ldb_port_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 port_id;\n+\t__u32 padding0;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_DISABLE_DIR_PORT: Disable scheduling to a directed port.\n+ * Input parameters:\n+ * - port_id: Directed port ID.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ */\n+struct dlb_disable_dir_port_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 port_id;\n+\t__u32 padding0;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_BLOCK_ON_CQ_INTERRUPT: Block on a CQ interrupt until a QE\n+ *\tarrives for the specified port. If a QE is already present, the ioctl\n+ *\twill immediately return.\n+ *\n+ *\tNote: Only one thread can block on a CQ's interrupt at a time. Doing\n+ *\totherwise can result in hung threads.\n+ *\n+ * Input parameters:\n+ * - port_id: Port ID.\n+ * - is_ldb: True if the port is load-balanced, false otherwise.\n+ * - arm: Tell the driver to arm the interrupt.\n+ * - cq_gen: Current CQ generation bit.\n+ * - padding0: Reserved for future use.\n+ * - cq_va: VA of the CQ entry where the next QE will be placed.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ */\n+struct dlb_block_on_cq_interrupt_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 port_id;\n+\t__u8 is_ldb;\n+\t__u8 arm;\n+\t__u8 cq_gen;\n+\t__u8 padding0;\n+\t__u64 cq_va;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_ENQUEUE_DOMAIN_ALERT: Enqueue a domain alert that will be\n+ *\tread by one reader thread.\n+ *\n+ * Input parameters:\n+ * - aux_alert_data: user-defined auxiliary data.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ */\n+struct dlb_enqueue_domain_alert_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u64 aux_alert_data;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_GET_LDB_QUEUE_DEPTH: Get a load-balanced queue's depth.\n+ * Input parameters:\n+ * - queue_id: The load-balanced queue ID.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id: queue depth.\n+ */\n+struct dlb_get_ldb_queue_depth_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 queue_id;\n+\t__u32 padding0;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_GET_DIR_QUEUE_DEPTH: Get a directed queue's depth.\n+ * Input parameters:\n+ * - queue_id: The directed queue ID.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id: queue depth.\n+ */\n+struct dlb_get_dir_queue_depth_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 queue_id;\n+\t__u32 padding0;\n+};\n+\n+/*\n+ * DLB_DOMAIN_CMD_PENDING_PORT_UNMAPS: Get number of queue unmap operations in\n+ *\tprogress for a load-balanced port.\n+ *\n+ *\tNote: This is a snapshot; the number of unmap operations in progress\n+ *\tis subject to change at any time.\n+ *\n+ * Input parameters:\n+ * - port_id: Load-balanced port ID.\n+ * - padding0: Reserved for future use.\n+ *\n+ * Output parameters:\n+ * - response: pointer to a struct dlb_cmd_response.\n+ *\tresponse.status: Detailed error code. In certain cases, such as if the\n+ *\t\tresponse pointer is invalid, the driver won't set status.\n+ *\tresponse.id: number of unmaps in progress.\n+ */\n+struct dlb_pending_port_unmaps_args {\n+\t/* Output parameters */\n+\t__u64 response;\n+\t/* Input parameters */\n+\t__u32 port_id;\n+\t__u32 padding0;\n+};\n+\n+enum dlb_domain_user_interface_commands {\n+\tDLB_DOMAIN_CMD_CREATE_LDB_POOL,\n+\tDLB_DOMAIN_CMD_CREATE_DIR_POOL,\n+\tDLB_DOMAIN_CMD_CREATE_LDB_QUEUE,\n+\tDLB_DOMAIN_CMD_CREATE_DIR_QUEUE,\n+\tDLB_DOMAIN_CMD_CREATE_LDB_PORT,\n+\tDLB_DOMAIN_CMD_CREATE_DIR_PORT,\n+\tDLB_DOMAIN_CMD_START_DOMAIN,\n+\tDLB_DOMAIN_CMD_MAP_QID,\n+\tDLB_DOMAIN_CMD_UNMAP_QID,\n+\tDLB_DOMAIN_CMD_ENABLE_LDB_PORT,\n+\tDLB_DOMAIN_CMD_ENABLE_DIR_PORT,\n+\tDLB_DOMAIN_CMD_DISABLE_LDB_PORT,\n+\tDLB_DOMAIN_CMD_DISABLE_DIR_PORT,\n+\tDLB_DOMAIN_CMD_BLOCK_ON_CQ_INTERRUPT,\n+\tDLB_DOMAIN_CMD_ENQUEUE_DOMAIN_ALERT,\n+\tDLB_DOMAIN_CMD_GET_LDB_QUEUE_DEPTH,\n+\tDLB_DOMAIN_CMD_GET_DIR_QUEUE_DEPTH,\n+\tDLB_DOMAIN_CMD_PENDING_PORT_UNMAPS,\n+\n+\t/* NUM_DLB_DOMAIN_CMD must be last */\n+\tNUM_DLB_DOMAIN_CMD,\n+};\n+\n+/*\n+ * Base addresses for memory mapping the consumer queue (CQ) and popcount (PC)\n+ * memory space, and producer port (PP) MMIO space. The CQ, PC, and PP\n+ * addresses are per-port. Every address is page-separated (e.g. LDB PP 0 is at\n+ * 0x2100000 and LDB PP 1 is at 0x2101000).\n+ */\n+#define DLB_LDB_CQ_BASE 0x3000000\n+#define DLB_LDB_CQ_MAX_SIZE 65536\n+#define DLB_LDB_CQ_OFFS(id) (DLB_LDB_CQ_BASE + (id) * DLB_LDB_CQ_MAX_SIZE)\n+\n+#define DLB_DIR_CQ_BASE 0x3800000\n+#define DLB_DIR_CQ_MAX_SIZE 65536\n+#define DLB_DIR_CQ_OFFS(id) (DLB_DIR_CQ_BASE + (id) * DLB_DIR_CQ_MAX_SIZE)\n+\n+#define DLB_LDB_PC_BASE 0x2300000\n+#define DLB_LDB_PC_MAX_SIZE 4096\n+#define DLB_LDB_PC_OFFS(id) (DLB_LDB_PC_BASE + (id) * DLB_LDB_PC_MAX_SIZE)\n+\n+#define DLB_DIR_PC_BASE 0x2200000\n+#define DLB_DIR_PC_MAX_SIZE 4096\n+#define DLB_DIR_PC_OFFS(id) (DLB_DIR_PC_BASE + (id) * DLB_DIR_PC_MAX_SIZE)\n+\n+#define DLB_LDB_PP_BASE 0x2100000\n+#define DLB_LDB_PP_MAX_SIZE 4096\n+#define DLB_LDB_PP_OFFS(id) (DLB_LDB_PP_BASE + (id) * DLB_LDB_PP_MAX_SIZE)\n+\n+#define DLB_DIR_PP_BASE 0x2000000\n+#define DLB_DIR_PP_MAX_SIZE 4096\n+#define DLB_DIR_PP_OFFS(id) (DLB_DIR_PP_BASE + (id) * DLB_DIR_PP_MAX_SIZE)\n+\n+#endif /* __DLB_USER_H */\n",
    "prefixes": [
        "03/27"
    ]
}