get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 54477,
    "url": "http://patches.dpdk.org/api/patches/54477/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/4f346071d6d54fd81bf90dc54d4782ec6d0d5cbd.1559818024.git.xuanziyang2@huawei.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": "<4f346071d6d54fd81bf90dc54d4782ec6d0d5cbd.1559818024.git.xuanziyang2@huawei.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/4f346071d6d54fd81bf90dc54d4782ec6d0d5cbd.1559818024.git.xuanziyang2@huawei.com",
    "date": "2019-06-06T11:15:57",
    "name": "[v4,04/11] net/hinic/base: add code about hardware operation",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "51db6fe618d3335576c6ccfc058f9edde68f465e",
    "submitter": {
        "id": 1321,
        "url": "http://patches.dpdk.org/api/people/1321/?format=api",
        "name": "Ziyang Xuan",
        "email": "xuanziyang2@huawei.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/4f346071d6d54fd81bf90dc54d4782ec6d0d5cbd.1559818024.git.xuanziyang2@huawei.com/mbox/",
    "series": [
        {
            "id": 4924,
            "url": "http://patches.dpdk.org/api/series/4924/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=4924",
            "date": "2019-06-06T11:04:33",
            "name": "A new net PMD - hinic",
            "version": 4,
            "mbox": "http://patches.dpdk.org/series/4924/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/54477/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/54477/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 874661B95A;\n\tThu,  6 Jun 2019 13:04:41 +0200 (CEST)",
            "from huawei.com (szxga07-in.huawei.com [45.249.212.35])\n\tby dpdk.org (Postfix) with ESMTP id 63F011B958\n\tfor <dev@dpdk.org>; Thu,  6 Jun 2019 13:04:39 +0200 (CEST)",
            "from DGGEMS408-HUB.china.huawei.com (unknown [172.30.72.58])\n\tby Forcepoint Email with ESMTP id 21DA74D043E27EF11658;\n\tThu,  6 Jun 2019 19:04:38 +0800 (CST)",
            "from tester_149.localdomain (10.175.119.39) by\n\tDGGEMS408-HUB.china.huawei.com (10.3.19.208) with Microsoft SMTP\n\tServer id 14.3.439.0; Thu, 6 Jun 2019 19:04:28 +0800"
        ],
        "From": "Ziyang Xuan <xuanziyang2@huawei.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<ferruh.yigit@intel.com>, <cloud.wangxiaoyun@huawei.com>,\n\t<zhouguoyang@huawei.com>, <shahar.belkar@huawei.com>,\n\t<stephen@networkplumber.org>, <luoxianjun@huawei.com>, Ziyang Xuan\n\t<xuanziyang2@huawei.com>",
        "Date": "Thu, 6 Jun 2019 19:15:57 +0800",
        "Message-ID": "<4f346071d6d54fd81bf90dc54d4782ec6d0d5cbd.1559818024.git.xuanziyang2@huawei.com>",
        "X-Mailer": "git-send-email 2.18.0",
        "In-Reply-To": "<cover.1559818024.git.xuanziyang2@huawei.com>",
        "References": "<cover.1559818024.git.xuanziyang2@huawei.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.175.119.39]",
        "X-CFilter-Loop": "Reflected",
        "Subject": "[dpdk-dev] [PATCH v4 04/11] net/hinic/base: add code about hardware\n\toperation",
        "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\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Add code for hardware operation, including configuration,\nquery and so on.\n\nSigned-off-by: Ziyang Xuan <xuanziyang2@huawei.com>\n---\n drivers/net/hinic/base/hinic_pmd_cfg.c   |  269 ++++\n drivers/net/hinic/base/hinic_pmd_cfg.h   |  264 ++++\n drivers/net/hinic/base/hinic_pmd_hw.h    |   49 +\n drivers/net/hinic/base/hinic_pmd_hwdev.c | 1544 ++++++++++++++++++++++\n drivers/net/hinic/base/hinic_pmd_hwdev.h |  205 +++\n drivers/net/hinic/base/hinic_pmd_hwif.c  |  542 ++++++++\n drivers/net/hinic/base/hinic_pmd_hwif.h  |   90 ++\n 7 files changed, 2963 insertions(+)\n create mode 100644 drivers/net/hinic/base/hinic_pmd_cfg.c\n create mode 100644 drivers/net/hinic/base/hinic_pmd_cfg.h\n create mode 100644 drivers/net/hinic/base/hinic_pmd_hw.h\n create mode 100644 drivers/net/hinic/base/hinic_pmd_hwdev.c\n create mode 100644 drivers/net/hinic/base/hinic_pmd_hwdev.h\n create mode 100644 drivers/net/hinic/base/hinic_pmd_hwif.c\n create mode 100644 drivers/net/hinic/base/hinic_pmd_hwif.h",
    "diff": "diff --git a/drivers/net/hinic/base/hinic_pmd_cfg.c b/drivers/net/hinic/base/hinic_pmd_cfg.c\nnew file mode 100644\nindex 000000000..d4106995a\n--- /dev/null\n+++ b/drivers/net/hinic/base/hinic_pmd_cfg.c\n@@ -0,0 +1,269 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#include \"hinic_pmd_dpdev.h\"\n+\n+static void parse_dev_cap(struct hinic_hwdev *dev,\n+\t\t\t  struct hinic_dev_cap *dev_cap,\n+\t\t\t  enum func_type type);\n+\n+bool hinic_support_nic(struct hinic_hwdev *hwdev, struct nic_service_cap *cap)\n+{\n+\tif (!hwdev)\n+\t\treturn false;\n+\n+\tif (!IS_NIC_TYPE(hwdev))\n+\t\treturn false;\n+\n+\tif (cap)\n+\t\tmemcpy(cap, &hwdev->cfg_mgmt->svc_cap.nic_cap, sizeof(*cap));\n+\n+\treturn true;\n+}\n+\n+static void hinic_parse_shared_res_cap(struct service_cap *cap,\n+\t\t\t\t\tstruct hinic_dev_cap *dev_cap,\n+\t\t\t\t\t__rte_unused enum func_type type)\n+{\n+\tstruct host_shared_resource_cap *shared_cap = &cap->shared_res_cap;\n+\n+\tshared_cap->host_pctxs = dev_cap->host_pctx_num;\n+\n+\tif (dev_cap->host_sf_en)\n+\t\tcap->sf_en = true;\n+\telse\n+\t\tcap->sf_en = false;\n+\n+\tshared_cap->host_cctxs = dev_cap->host_ccxt_num;\n+\tshared_cap->host_scqs = dev_cap->host_scq_num;\n+\tshared_cap->host_srqs = dev_cap->host_srq_num;\n+\tshared_cap->host_mpts = dev_cap->host_mpt_num;\n+\n+\tPMD_DRV_LOG(INFO, \"Get share resource capability:\");\n+\tPMD_DRV_LOG(INFO, \"host_pctxs: 0x%x, host_cctxs: 0x%x, host_scqs: 0x%x, host_srqs: 0x%x, host_mpts: 0x%x\",\n+\t\t    shared_cap->host_pctxs, shared_cap->host_cctxs,\n+\t\t    shared_cap->host_scqs, shared_cap->host_srqs,\n+\t\t    shared_cap->host_mpts);\n+}\n+\n+static void hinic_parse_l2nic_res_cap(struct service_cap *cap,\n+\t\t\t\tstruct hinic_dev_cap *dev_cap,\n+\t\t\t\tenum func_type type)\n+{\n+\tstruct nic_service_cap *nic_cap = &cap->nic_cap;\n+\n+\tif (type == TYPE_PF || type == TYPE_PPF) {\n+\t\tnic_cap->max_sqs = dev_cap->nic_max_sq + 1;\n+\t\tnic_cap->max_rqs = dev_cap->nic_max_rq + 1;\n+\t\tnic_cap->vf_max_sqs = dev_cap->nic_vf_max_sq + 1;\n+\t\tnic_cap->vf_max_rqs = dev_cap->nic_vf_max_rq + 1;\n+\t} else {\n+\t\tnic_cap->max_sqs = dev_cap->nic_max_sq;\n+\t\tnic_cap->max_rqs = dev_cap->nic_max_rq;\n+\t\tnic_cap->vf_max_sqs = 0;\n+\t\tnic_cap->vf_max_rqs = 0;\n+\t}\n+\n+\tif (dev_cap->nic_lro_en)\n+\t\tnic_cap->lro_en = true;\n+\telse\n+\t\tnic_cap->lro_en = false;\n+\n+\tnic_cap->lro_sz = dev_cap->nic_lro_sz;\n+\tnic_cap->tso_sz = dev_cap->nic_tso_sz;\n+\n+\tPMD_DRV_LOG(INFO, \"Get l2nic resource capability:\");\n+\tPMD_DRV_LOG(INFO, \"max_sqs: 0x%x, max_rqs: 0x%x, vf_max_sqs: 0x%x, vf_max_rqs: 0x%x\",\n+\t\t    nic_cap->max_sqs, nic_cap->max_rqs,\n+\t\t    nic_cap->vf_max_sqs, nic_cap->vf_max_rqs);\n+}\n+\n+static int get_cap_from_fw(struct hinic_hwdev *dev, enum func_type type)\n+{\n+\tint err;\n+\tu16 in_len, out_len;\n+\tstruct hinic_dev_cap dev_cap;\n+\n+\tmemset(&dev_cap, 0, sizeof(dev_cap));\n+\tin_len = sizeof(dev_cap);\n+\tout_len = in_len;\n+\tdev_cap.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;\n+\terr = hinic_msg_to_mgmt_sync(dev, HINIC_MOD_CFGM, HINIC_CFG_NIC_CAP,\n+\t\t\t\t     &dev_cap, in_len, &dev_cap, &out_len, 0);\n+\tif (err || dev_cap.mgmt_msg_head.status || !out_len) {\n+\t\tPMD_DRV_LOG(ERR, \"Get capability from FW failed, err: %d, status: %d, out_len: %d\",\n+\t\t\terr, dev_cap.mgmt_msg_head.status, out_len);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tparse_dev_cap(dev, &dev_cap, type);\n+\treturn 0;\n+}\n+\n+static int get_dev_cap(struct hinic_hwdev *dev)\n+{\n+\tint err;\n+\tenum func_type type = HINIC_FUNC_TYPE(dev);\n+\n+\tswitch (type) {\n+\tcase TYPE_PF:\n+\tcase TYPE_PPF:\n+\t\terr = get_cap_from_fw(dev, type);\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Get PF/PPF capability failed\");\n+\t\t\treturn err;\n+\t\t}\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"Unsupported PCI function type\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+u16 hinic_func_max_qnum(void *hwdev)\n+{\n+\tstruct hinic_hwdev *dev = (struct hinic_hwdev *)hwdev;\n+\n+\treturn dev->cfg_mgmt->svc_cap.max_sqs;\n+}\n+\n+int init_cfg_mgmt(struct hinic_hwdev *dev)\n+{\n+\tstruct cfg_mgmt_info *cfg_mgmt;\n+\n+\tcfg_mgmt = kzalloc(sizeof(*cfg_mgmt), GFP_KERNEL);\n+\tif (!cfg_mgmt) {\n+\t\tPMD_DRV_LOG(ERR, \"Alloc cfg mgmt failed\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tdev->cfg_mgmt = cfg_mgmt;\n+\tcfg_mgmt->hwdev = dev;\n+\n+\treturn 0;\n+}\n+\n+void free_cfg_mgmt(struct hinic_hwdev *dev)\n+{\n+\tkfree(dev->cfg_mgmt);\n+\tdev->cfg_mgmt = NULL;\n+}\n+\n+static void hinic_parse_pub_res_cap(struct service_cap *cap,\n+\t\t\t      struct hinic_dev_cap *dev_cap,\n+\t\t\t      enum func_type type)\n+{\n+\tstruct dev_sf_svc_attr *attr = &cap->sf_svc_attr;\n+\n+\tif (dev_cap->sf_svc_attr & SF_SVC_FT_BIT)\n+\t\tattr->ft_en = true;\n+\telse\n+\t\tattr->ft_en = false;\n+\n+\tif (dev_cap->sf_svc_attr & SF_SVC_RDMA_BIT)\n+\t\tattr->rdma_en = true;\n+\telse\n+\t\tattr->rdma_en = false;\n+\n+\tif (type == TYPE_PPF) {\n+\t\t/* For PPF's SF EN flag, we assign it in get_dynamic_res_cap().\n+\t\t * we only save its VF's flag.\n+\t\t */\n+\t\tattr->sf_en_vf = dev_cap->sf_en_vf;\n+\t} else if (type == TYPE_PF) {\n+\t\tif (dev_cap->sf_en_pf)\n+\t\t\tcap->sf_en = true;\n+\t\telse\n+\t\t\tcap->sf_en = false;\n+\n+\t\tattr->sf_en_vf = dev_cap->sf_en_vf;\n+\t}\n+\n+\tcap->host_id = dev_cap->host_id;\n+\tcap->ep_id = dev_cap->ep_id;\n+\tcap->interrupt_type = dev_cap->intr_type;\n+\tcap->max_cos_id = dev_cap->max_cos_id;\n+\tcap->er_id = dev_cap->er_id;\n+\tcap->port_id = dev_cap->port_id;\n+\n+\tif (type == TYPE_PF || type == TYPE_PPF) {\n+\t\tcap->max_vf = dev_cap->max_vf;\n+\t\tcap->pf_num = dev_cap->pf_num;\n+\t\tcap->pf_id_start = dev_cap->pf_id_start;\n+\t\tcap->vf_num = dev_cap->vf_num;\n+\t\tcap->vf_id_start = dev_cap->vf_id_start;\n+\t\tcap->max_sqs = dev_cap->nic_max_sq + 1;\n+\t\tcap->max_rqs = dev_cap->nic_max_rq + 1;\n+\t}\n+\n+\tcap->chip_svc_type = CFG_SVC_NIC_BIT0;\n+\tcap->host_total_function = dev_cap->host_total_func;\n+\tcap->host_oq_id_mask_val = dev_cap->host_oq_id_mask_val;\n+\tcap->max_connect_num = dev_cap->max_conn_num;\n+\tcap->max_stick2cache_num = dev_cap->max_stick2cache_num;\n+\tcap->bfilter_start_addr = dev_cap->max_bfilter_start_addr;\n+\tcap->bfilter_len = dev_cap->bfilter_len;\n+\tcap->hash_bucket_num = dev_cap->hash_bucket_num;\n+\tcap->dev_ver_info.cfg_file_ver = dev_cap->cfg_file_ver;\n+\tcap->net_port_mode = dev_cap->net_port_mode;\n+\n+\tPMD_DRV_LOG(INFO, \"Get public resource capability:\");\n+\tPMD_DRV_LOG(INFO, \"host_id: 0x%x, ep_id: 0x%x, intr_type: 0x%x, max_cos_id: 0x%x, er_id: 0x%x, port_id: 0x%x\",\n+\t\t    cap->host_id, cap->ep_id, cap->intr_chip_en,\n+\t\t    cap->max_cos_id, cap->er_id, cap->port_id);\n+\tPMD_DRV_LOG(INFO, \"host_total_function: 0x%x, host_oq_id_mask_val: 0x%x, net_port_mode: 0x%x, max_vf: 0x%x\",\n+\t\t    cap->host_total_function, cap->host_oq_id_mask_val,\n+\t\t    cap->net_port_mode, cap->max_vf);\n+\tPMD_DRV_LOG(INFO, \"pf_num: 0x%x, pf_id_start: 0x%x, vf_num: 0x%x, vf_id_start: 0x%x\",\n+\t\t    cap->pf_num, cap->pf_id_start,\n+\t\t    cap->vf_num, cap->vf_id_start);\n+}\n+\n+static void parse_dev_cap(struct hinic_hwdev *dev,\n+\t\t\t  struct hinic_dev_cap *dev_cap,\n+\t\t\t  enum func_type type)\n+{\n+\tstruct service_cap *cap = &dev->cfg_mgmt->svc_cap;\n+\n+\t/* Public resource */\n+\thinic_parse_pub_res_cap(cap, dev_cap, type);\n+\n+\t/* PPF managed dynamic resource */\n+\tif (type == TYPE_PPF)\n+\t\thinic_parse_shared_res_cap(cap, dev_cap, type);\n+\n+\t/* L2 NIC resource */\n+\tif (IS_NIC_TYPE(dev))\n+\t\thinic_parse_l2nic_res_cap(cap, dev_cap, type);\n+}\n+\n+int hinic_init_capability(struct hinic_nic_dev *nic_dev)\n+{\n+\tint err;\n+\tstruct hinic_hwdev *dev = nic_dev->hwdev;\n+\tstruct cfg_mgmt_info *cfg_mgmt = dev->cfg_mgmt;\n+\n+\tcfg_mgmt->svc_cap.sf_svc_attr.ft_pf_en = false;\n+\tcfg_mgmt->svc_cap.sf_svc_attr.rdma_pf_en = false;\n+\n+\tcfg_mgmt->svc_cap.max_connect_num = 1024 * 1024; /* 1M */\n+\tcfg_mgmt->svc_cap.max_stick2cache_num = 12 * 1024;\n+\n+\tcfg_mgmt->svc_cap.timer_en = true;\n+\tcfg_mgmt->svc_cap.bloomfilter_en = false;\n+\n+\terr = get_dev_cap(dev);\n+\tif (err)\n+\t\treturn err;\n+\n+\t/* get nic capability */\n+\tif (!hinic_support_nic(dev, &nic_dev->nic_cap)) {\n+\t\tPMD_DRV_LOG(ERR, \"Device does not support nic feature\");\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/hinic/base/hinic_pmd_cfg.h b/drivers/net/hinic/base/hinic_pmd_cfg.h\nnew file mode 100644\nindex 000000000..45654a4e3\n--- /dev/null\n+++ b/drivers/net/hinic/base/hinic_pmd_cfg.h\n@@ -0,0 +1,264 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#ifndef _HINIC_PMD_CFG_H_\n+#define _HINIC_PMD_CFG_H_\n+\n+#define CFG_MAX_CMD_TIMEOUT     8000 /* ms */\n+\n+enum {\n+\tSF_SVC_FT_BIT = (1 << 0),\n+\tSF_SVC_RDMA_BIT = (1 << 1),\n+};\n+\n+struct host_shared_resource_cap {\n+\tu32 host_pctxs; /* Parent Context max 1M, IOE and FCoE max 8K flows */\n+\tu32 host_cctxs; /* Child Context: max 8K */\n+\tu32 host_scqs;  /* shared CQ, chip interface module uses 1 SCQ\n+\t\t\t * TOE/IOE/FCoE each uses 1 SCQ\n+\t\t\t * RoCE/IWARP uses multiple SCQs\n+\t\t\t * So 6 SCQ least\n+\t\t\t */\n+\tu32 host_srqs; /* SRQ number: 256K */\n+\tu32 host_mpts; /* MR number:1M */\n+};\n+\n+struct dev_sf_svc_attr {\n+\tbool ft_en;     /* business enable flag (not include RDMA) */\n+\tbool ft_pf_en;  /* In FPGA Test VF resource is in PF or not,\n+\t\t\t * 0 - VF, 1 - PF, VF doesn't need this bit.\n+\t\t\t */\n+\n+\tbool rdma_en;\n+\tbool rdma_pf_en; /* In FPGA Test VF RDMA resource is in PF or not,\n+\t\t\t  * 0 - VF, 1 - PF, VF doesn't need this bit.\n+\t\t\t  */\n+\tu8 sf_en_vf;    /* SF_EN for PPF/PF's VF */\n+};\n+\n+/* device capability */\n+struct service_cap {\n+\tstruct dev_sf_svc_attr sf_svc_attr;\n+\tenum cfg_svc_type_en svc_type;\t\t/* user input service type */\n+\tenum cfg_svc_type_en chip_svc_type;\t/* HW supported service type */\n+\n+\t/* Host global resources */\n+\tu16 host_total_function;\n+\tu8 host_oq_id_mask_val;\n+\tu8 host_id;\n+\tu8 ep_id;\n+\t/* Don't get interrupt_type from firmware */\n+\tenum intr_type interrupt_type;\n+\tu8 intr_chip_en;\n+\tu8 max_cos_id;\t/* PF/VF's max cos id */\n+\tu8 er_id;\t/* PF/VF's ER */\n+\tu8 port_id;\t/* PF/VF's physical port */\n+\tu8 max_vf;\t/* max VF number that PF supported */\n+\tbool sf_en;\t/* stateful business status */\n+\tu8 timer_en;\t/* 0:disable, 1:enable */\n+\tu8 bloomfilter_en; /* 0:disable, 1:enable*/\n+\tu16 max_sqs;\n+\tu16 max_rqs;\n+\n+\t/* PF BAT Bfliter CFG(16) is set when FT_EN=1 */\n+\tu32 max_connect_num;\t/* PF/VF maximum connection number(1M) */\n+\t/* The maximum connections which can be stick to cache memory, max 1K */\n+\tu16 max_stick2cache_num;\n+\t/* Starting address in cache memory for bloom filter, 64Bytes aligned */\n+\tu16 bfilter_start_addr;\n+\t/* Length for bloom filter, aligned on 64Bytes. The size is length*64B.\n+\t * Bloom filter memory size + 1 must be power of 2.\n+\t * The maximum memory size of bloom filter is 4M\n+\t */\n+\tu16 bfilter_len;\n+\t/* The size of hash bucket tables, align on 64 entries.\n+\t * Be used to AND (&) the hash value. Bucket Size +1 must be power of 2.\n+\t * The maximum number of hash bucket is 4M\n+\t */\n+\tu16 hash_bucket_num;\n+\tu8 net_port_mode; /* 0:ETH,1:FIC,2:4FC */\n+\n+\tu32 pf_num;\n+\tu32 pf_id_start;\n+\tu32 vf_num;\n+\tu32 vf_id_start;\n+\n+\tstruct host_shared_resource_cap shared_res_cap; /* shared capability */\n+\tstruct dev_version_info     dev_ver_info;       /* version */\n+\tstruct nic_service_cap      nic_cap;            /* NIC capability */\n+};\n+\n+struct cfg_eq {\n+\tenum hinic_service_type type;\n+\tint eqn;\n+\tint free; /* 1 - allocated, 0- freed */\n+};\n+\n+struct cfg_eq_info {\n+\tstruct cfg_eq *eq;\n+\n+\tu8 num_ceq;\n+\tu8 num_aeq;\n+\tu8 num_eq;\t/* num_eq = num_ceq + num_aeq */\n+\n+\tu8 num_ceq_remain;\n+};\n+\n+struct cfg_mgmt_info {\n+\tstruct hinic_hwdev *hwdev;\n+\tstruct service_cap  svc_cap;\n+\tstruct cfg_eq_info  eq_info;\n+\tu32 func_seq_num;   /* temporary */\n+};\n+\n+enum cfg_sub_cmd {\n+\t/* PPF(PF) <-> FW */\n+\tHINIC_CFG_NIC_CAP = 0,\n+\tCFG_FW_VERSION,\n+\tCFG_UCODE_VERSION,\n+\tHINIC_CFG_MBOX_CAP = 6\n+};\n+\n+struct hinic_dev_cap {\n+\tstruct hinic_mgmt_msg_head mgmt_msg_head;\n+\n+\t/* Public resource */\n+\tu8 sf_svc_attr;\n+\tu8 host_id;\n+\tu8 sf_en_pf;\n+\tu8 sf_en_vf;\n+\n+\tu8 ep_id;\n+\tu8 intr_type;\n+\tu8 max_cos_id;\n+\tu8 er_id;\n+\tu8 port_id;\n+\tu8 max_vf;\n+\tu16 svc_cap_en;\n+\tu16 host_total_func;\n+\tu8 host_oq_id_mask_val;\n+\tu8 max_vf_cos_id;\n+\n+\tu32 max_conn_num;\n+\tu16 max_stick2cache_num;\n+\tu16 max_bfilter_start_addr;\n+\tu16 bfilter_len;\n+\tu16 hash_bucket_num;\n+\tu8 cfg_file_ver;\n+\tu8 net_port_mode;\n+\tu8 valid_cos_bitmap;\t/* every bit indicate cos is valid */\n+\tu8 rsvd1;\n+\tu32 pf_num;\n+\tu32 pf_id_start;\n+\tu32 vf_num;\n+\tu32 vf_id_start;\n+\n+\t/* shared resource */\n+\tu32 host_pctx_num;\n+\tu8 host_sf_en;\n+\tu8 rsvd2[3];\n+\tu32 host_ccxt_num;\n+\tu32 host_scq_num;\n+\tu32 host_srq_num;\n+\tu32 host_mpt_num;\n+\n+\t/* l2nic */\n+\tu16 nic_max_sq;\n+\tu16 nic_max_rq;\n+\tu16 nic_vf_max_sq;\n+\tu16 nic_vf_max_rq;\n+\tu8 nic_lro_en;\n+\tu8 nic_lro_sz;\n+\tu8 nic_tso_sz;\n+\tu8 rsvd3;\n+\n+\t/* RoCE */\n+\tu32 roce_max_qp;\n+\tu32 roce_max_cq;\n+\tu32 roce_max_srq;\n+\tu32 roce_max_mpt;\n+\n+\tu32 roce_vf_max_qp;\n+\tu32 roce_vf_max_cq;\n+\tu32 roce_vf_max_srq;\n+\tu32 roce_vf_max_mpt;\n+\n+\tu32 roce_cmtt_cl_start;\n+\tu32 roce_cmtt_cl_end;\n+\tu32 roce_cmtt_cl_size;\n+\n+\tu32 roce_dmtt_cl_start;\n+\tu32 roce_dmtt_cl_end;\n+\tu32 roce_dmtt_cl_size;\n+\n+\tu32 roce_wqe_cl_start;\n+\tu32 roce_wqe_cl_end;\n+\tu32 roce_wqe_cl_size;\n+\n+\t/* IWARP */\n+\tu32 iwarp_max_qp;\n+\tu32 iwarp_max_cq;\n+\tu32 iwarp_max_mpt;\n+\n+\tu32 iwarp_vf_max_qp;\n+\tu32 iwarp_vf_max_cq;\n+\tu32 iwarp_vf_max_mpt;\n+\n+\tu32 iwarp_cmtt_cl_start;\n+\tu32 iwarp_cmtt_cl_end;\n+\tu32 iwarp_cmtt_cl_size;\n+\n+\tu32 iwarp_dmtt_cl_start;\n+\tu32 iwarp_dmtt_cl_end;\n+\tu32 iwarp_dmtt_cl_size;\n+\n+\tu32 iwarp_wqe_cl_start;\n+\tu32 iwarp_wqe_cl_end;\n+\tu32 iwarp_wqe_cl_size;\n+\n+\t/* FCoE */\n+\tu32 fcoe_max_qp;\n+\tu32 fcoe_max_cq;\n+\tu32 fcoe_max_srq;\n+\n+\tu32 fcoe_max_cctx;\n+\tu32 fcoe_cctx_id_start;\n+\n+\tu8 fcoe_vp_id_start;\n+\tu8 fcoe_vp_id_end;\n+\tu8 rsvd4[2];\n+\n+\t/* IoE */\n+\tu32 ioe_max_pctx;\n+\tu32 ioe_max_cctx;\n+\n+\t/* ToE */\n+\tu32 toe_max_pctx;\n+\tu32 toe_max_cq;\n+\tu32 toe_max_srq;\n+\tu32 toe_srq_id_start;\n+\n+\t/* FC */\n+\tu32 fc_max_pctx;\n+\tu32 fc_max_scq;\n+\tu32 fc_max_srq;\n+\n+\tu32 fc_max_cctx;\n+\tu32 fc_cctx_id_start;\n+\n+\tu8 fc_vp_id_start;\n+\tu8 fc_vp_id_end;\n+\tu8 rsvd5[2];\n+};\n+\n+int init_cfg_mgmt(struct hinic_hwdev *hwdev);\n+void free_cfg_mgmt(struct hinic_hwdev *hwdev);\n+\n+/*for clear ucode&MIB stats*/\n+void hinic_clear_vport_stats(struct hinic_hwdev *hwdev);\n+void hinic_clear_phy_port_stats(struct hinic_hwdev *hwdev);\n+\n+bool hinic_support_nic(struct hinic_hwdev *hwdev, struct nic_service_cap *cap);\n+\n+#endif /* _HINIC_PMD_CFG_H_ */\ndiff --git a/drivers/net/hinic/base/hinic_pmd_hw.h b/drivers/net/hinic/base/hinic_pmd_hw.h\nnew file mode 100644\nindex 000000000..16334fe4b\n--- /dev/null\n+++ b/drivers/net/hinic/base/hinic_pmd_hw.h\n@@ -0,0 +1,49 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#ifndef _HINIC_PMD_HW_H_\n+#define _HINIC_PMD_HW_H_\n+\n+#ifndef __BIG_ENDIAN__\n+#define __BIG_ENDIAN__    0x4321\n+#endif\n+\n+#ifndef __LITTLE_ENDIAN__\n+#define __LITTLE_ENDIAN__    0x1234\n+#endif\n+\n+#ifdef __BYTE_ORDER__\n+#undef __BYTE_ORDER__\n+#endif\n+/* X86 */\n+#define __BYTE_ORDER__    __LITTLE_ENDIAN__\n+\n+#define HINIC_RECV_NEXT_AEQE\t(HINIC_ERROR)\n+#define HINIC_RECV_DONE\t        (HINIC_OK)\n+\n+enum hinic_mod_type {\n+\tHINIC_MOD_COMM = 0,\t/* HW communication module */\n+\tHINIC_MOD_L2NIC = 1,\t/* L2NIC module */\n+\tHINIC_MOD_CFGM = 7,\t/* Configuration module */\n+\tHINIC_MOD_HILINK = 14,\n+\tHINIC_MOD_MAX\t= 15\n+};\n+\n+struct hinic_cmd_buf {\n+\tvoid\t\t*buf;\n+\tdma_addr_t\tdma_addr;\n+\tstruct rte_mbuf *mbuf;\n+\tu16\t\tsize;\n+};\n+\n+enum hinic_ack_type {\n+\tHINIC_ACK_TYPE_CMDQ,\n+\tHINIC_ACK_TYPE_SHARE_CQN,\n+\tHINIC_ACK_TYPE_APP_CQN,\n+\n+\tHINIC_MOD_ACK_MAX = 15,\n+\n+};\n+\n+#endif /* _HINIC_PMD_HW_H_ */\ndiff --git a/drivers/net/hinic/base/hinic_pmd_hwdev.c b/drivers/net/hinic/base/hinic_pmd_hwdev.c\nnew file mode 100644\nindex 000000000..db4840dd2\n--- /dev/null\n+++ b/drivers/net/hinic/base/hinic_pmd_hwdev.c\n@@ -0,0 +1,1544 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#include \"hinic_pmd_dpdev.h\"\n+\n+#define HINIC_DEAULT_EQ_MSIX_PENDING_LIMIT\t0\n+#define HINIC_DEAULT_EQ_MSIX_COALESC_TIMER_CFG\t0xFF\n+#define HINIC_DEAULT_EQ_MSIX_RESEND_TIMER_CFG\t7\n+\n+#define HINIC_FLR_TIMEOUT\t\t\t1000\n+\n+#define HINIC_MGMT_CHANNEL_STATUS_SHIFT\t\t0x0\n+#define HINIC_MGMT_CHANNEL_STATUS_MASK\t\t0x1\n+\n+#define FFM_RECORD_NUM_MAX\t\t\t32\n+\n+#define\tHINIC_MSIX_CNT_RESEND_TIMER_SHIFT\t29\n+#define\tHINIC_MSIX_CNT_RESEND_TIMER_MASK\t0x7U\n+\n+#define HINIC_MSIX_CNT_SET(val, member)\t\t\\\n+\t\t(((val) & HINIC_MSIX_CNT_##member##_MASK) << \\\n+\t\tHINIC_MSIX_CNT_##member##_SHIFT)\n+\n+#define HINIC_GET_MGMT_CHANNEL_STATUS(val, member)\t\\\n+\t(((val) >> HINIC_##member##_SHIFT) & HINIC_##member##_MASK)\n+\n+struct hinic_cons_idx_attr {\n+\tstruct hinic_mgmt_msg_head mgmt_msg_head;\n+\n+\tu16\tfunc_idx;\n+\tu8\tdma_attr_off;\n+\tu8\tpending_limit;\n+\tu8\tcoalescing_time;\n+\tu8\tintr_en;\n+\tu16\tintr_idx;\n+\tu32\tl2nic_sqn;\n+\tu32\tsq_id;\n+\tu64\tci_addr;\n+};\n+\n+struct hinic_clear_doorbell {\n+\tstruct hinic_mgmt_msg_head mgmt_msg_head;\n+\n+\tu16\tfunc_idx;\n+\tu8\tppf_idx;\n+\tu8\trsvd1;\n+};\n+\n+struct hinic_clear_resource {\n+\tstruct hinic_mgmt_msg_head mgmt_msg_head;\n+\n+\tu16\tfunc_idx;\n+\tu8\tppf_idx;\n+\tu8\trsvd1;\n+};\n+\n+struct hinic_cmd_set_res_state {\n+\tstruct hinic_mgmt_msg_head mgmt_msg_head;\n+\n+\tu16\tfunc_idx;\n+\tu8\tstate;\n+\tu8\trsvd1;\n+\tu32\trsvd2;\n+};\n+\n+const int hinic_hw_rx_buf_size[] = {\n+\tHINIC_RX_BUF_SIZE_32B,\n+\tHINIC_RX_BUF_SIZE_64B,\n+\tHINIC_RX_BUF_SIZE_96B,\n+\tHINIC_RX_BUF_SIZE_128B,\n+\tHINIC_RX_BUF_SIZE_192B,\n+\tHINIC_RX_BUF_SIZE_256B,\n+\tHINIC_RX_BUF_SIZE_384B,\n+\tHINIC_RX_BUF_SIZE_512B,\n+\tHINIC_RX_BUF_SIZE_768B,\n+\tHINIC_RX_BUF_SIZE_1K,\n+\tHINIC_RX_BUF_SIZE_1_5K,\n+\tHINIC_RX_BUF_SIZE_2K,\n+\tHINIC_RX_BUF_SIZE_3K,\n+\tHINIC_RX_BUF_SIZE_4K,\n+\tHINIC_RX_BUF_SIZE_8K,\n+\tHINIC_RX_BUF_SIZE_16K,\n+};\n+\n+struct hinic_msix_config {\n+\tstruct hinic_mgmt_msg_head mgmt_msg_head;\n+\n+\tu16\tfunc_id;\n+\tu16\tmsix_index;\n+\tu8\tpending_cnt;\n+\tu8\tcoalesct_timer_cnt;\n+\tu8\tlli_tmier_cnt;\n+\tu8\tlli_credit_cnt;\n+\tu8\tresend_timer_cnt;\n+\tu8\trsvd1[3];\n+};\n+\n+struct hinic_cmd_fault_event {\n+\tstruct hinic_mgmt_msg_head mgmt_msg_head;\n+\n+\tstruct hinic_fault_event event;\n+};\n+\n+struct hinic_mgmt_watchdog_info {\n+\tstruct hinic_mgmt_msg_head mgmt_msg_head;\n+\n+\tu32 curr_time_h;\n+\tu32 curr_time_l;\n+\tu32 task_id;\n+\tu32 rsv;\n+\n+\tu32 reg[13];\n+\tu32 pc;\n+\tu32 lr;\n+\tu32 cpsr;\n+\n+\tu32 stack_top;\n+\tu32 stack_bottom;\n+\tu32 sp;\n+\tu32 curr_used;\n+\tu32 peak_used;\n+\tu32 is_overflow;\n+\n+\tu32 stack_actlen;\n+\tu8 data[1024];\n+};\n+\n+#define MAX_PCIE_DFX_BUF_SIZE (1024)\n+\n+struct hinic_pcie_dfx_ntc {\n+\tstruct hinic_mgmt_msg_head mgmt_msg_head;\n+\n+\tint len;\n+\tu32 rsvd;\n+};\n+\n+struct hinic_pcie_dfx_info {\n+\tstruct hinic_mgmt_msg_head mgmt_msg_head;\n+\n+\tu8 host_id;\n+\tu8 last;\n+\tu8 rsvd[2];\n+\tu32 offset;\n+\n+\tu8 data[MAX_PCIE_DFX_BUF_SIZE];\n+};\n+\n+struct ffm_intr_info {\n+\tu8 node_id;\n+\t/* error level of the interrupt source */\n+\tu8 err_level;\n+\t/* Classification by interrupt source properties */\n+\tu16 err_type;\n+\tu32 err_csr_addr;\n+\tu32 err_csr_value;\n+};\n+\n+struct hinic_comm_board_info {\n+\tstruct hinic_mgmt_msg_head mgmt_msg_head;\n+\n+\tstruct hinic_board_info info;\n+\n+\tu32\trsvd1[5];\n+};\n+\n+struct hi30_ctle_data {\n+\tu8 ctlebst[3];\n+\tu8 ctlecmband[3];\n+\tu8 ctlermband[3];\n+\tu8 ctleza[3];\n+\tu8 ctlesqh[3];\n+\tu8 ctleactgn[3];\n+\tu8 ctlepassgn;\n+};\n+\n+struct hi30_ffe_data {\n+\tu8 PRE2;\n+\tu8 PRE1;\n+\tu8 POST1;\n+\tu8 POST2;\n+\tu8 MAIN;\n+};\n+\n+struct hinic_link_info {\n+\tu8\tvendor_name[16];\n+\t/* port type:\n+\t * 1 - fiber; 2 - electric; 3 - copper; 4 - AOC; 5 - backplane;\n+\t * 6 - baseT; 0xffff - unknown\n+\t *\n+\t * port subtype:\n+\t * Only when port_type is fiber:\n+\t * 1 - SR; 2 - LR\n+\t */\n+\tu32\tport_type;\n+\tu32\tport_sub_type;\n+\tu32\tcable_length;\n+\tu8\tcable_temp;\n+\tu8\tcable_max_speed;/* 1(G)/10(G)/25(G)... */\n+\tu8\tsfp_type;\t/* 0 - qsfp; 1 - sfp */\n+\tu8\trsvd0;\n+\tu32\tpower[4];\t/* uW; if is sfp, only power[2] is valid */\n+\n+\tu8\tan_state;\t/* 0 - off; 1 - on */\n+\tu8\tfec;\t\t/* 0 - RSFEC; 1 - BASEFEC; 2 - NOFEC */\n+\tu16\tspeed;\t\t/* 1(G)/10(G)/25(G)... */\n+\n+\tu8\tcable_absent;\t/* 0 - cable present; 1 - cable unpresent */\n+\tu8\talos;\t\t/* 0 - yes; 1 - no */\n+\tu8\trx_los;\t\t/* 0 - yes; 1 - no */\n+\tu8\tpma_status;\n+\tu32\tpma_dbg_info_reg;\t/* pma debug info: */\n+\tu32\tpma_signal_ok_reg;\t/* signal ok: */\n+\n+\tu32\tpcs_err_blk_cnt_reg;\t/* error block counter: */\n+\tu32\trf_lf_status_reg;\t/* RF/LF status: */\n+\tu8\tpcs_link_reg;\t\t/* pcs link: */\n+\tu8\tmac_link_reg;\t\t/* mac link: */\n+\tu8\tmac_tx_en;\n+\tu8\tmac_rx_en;\n+\tu32\tpcs_err_cnt;\n+\n+\tu8\tlane_used;\n+\tu8\thi30_ffe[5];\n+\tu8\thi30_ctle[19];\n+\tu8\thi30_dfe[14];\n+\tu8\trsvd4;\n+};\n+\n+struct hinic_hilink_link_info {\n+\tstruct hinic_mgmt_msg_head mgmt_msg_head;\n+\n+\tu16\tport_id;\n+\tu8\tinfo_type;\t/* 1: link up  2: link down  3 cable plugged */\n+\tu8\trsvd1;\n+\n+\tstruct hinic_link_info info;\n+\n+\tu8\trsvd2[780];\n+};\n+\n+enum hinic_link_port_type {\n+\tLINK_PORT_FIBRE\t= 1,\n+\tLINK_PORT_ELECTRIC,\n+\tLINK_PORT_COPPER,\n+\tLINK_PORT_AOC,\n+\tLINK_PORT_BACKPLANE,\n+\tLINK_PORT_BASET,\n+\tLINK_PORT_MAX_TYPE,\n+};\n+\n+enum hilink_fibre_subtype {\n+\tFIBRE_SUBTYPE_SR = 1,\n+\tFIBRE_SUBTYPE_LR,\n+\tFIBRE_SUBTYPE_MAX,\n+};\n+\n+enum hilink_fec_type {\n+\tHILINK_FEC_RSFEC,\n+\tHILINK_FEC_BASEFEC,\n+\tHILINK_FEC_NOFEC,\n+\tHILINK_FEC_MAX_TYPE,\n+};\n+\n+static const char *__hw_to_char_fec[HILINK_FEC_MAX_TYPE] = {\n+\t\"RS-FEC\", \"BASE-FEC\", \"NO-FEC\"};\n+\n+static const char *__hw_to_char_port_type[LINK_PORT_MAX_TYPE] = {\n+\t\"Unknown\", \"Fibre\", \"Electric\", \"Direct Attach Copper\", \"AOC\",\n+\t\"Back plane\", \"BaseT\"\n+};\n+\n+static const char *hinic_module_link_err[LINK_ERR_NUM] = {\n+\t\"Unrecognized module\",\n+};\n+\n+#define HINIC_DMA_ATTR_ENTRY_ST_SHIFT\t\t\t\t0\n+#define HINIC_DMA_ATTR_ENTRY_AT_SHIFT\t\t\t\t8\n+#define HINIC_DMA_ATTR_ENTRY_PH_SHIFT\t\t\t\t10\n+#define HINIC_DMA_ATTR_ENTRY_NO_SNOOPING_SHIFT\t\t\t12\n+#define HINIC_DMA_ATTR_ENTRY_TPH_EN_SHIFT\t\t\t13\n+\n+#define HINIC_DMA_ATTR_ENTRY_ST_MASK\t\t\t\t0xFF\n+#define HINIC_DMA_ATTR_ENTRY_AT_MASK\t\t\t\t0x3\n+#define HINIC_DMA_ATTR_ENTRY_PH_MASK\t\t\t\t0x3\n+#define HINIC_DMA_ATTR_ENTRY_NO_SNOOPING_MASK\t\t\t0x1\n+#define HINIC_DMA_ATTR_ENTRY_TPH_EN_MASK\t\t\t0x1\n+\n+#define HINIC_DMA_ATTR_ENTRY_SET(val, member)\t\t\t\\\n+\t\t(((u32)(val) & HINIC_DMA_ATTR_ENTRY_##member##_MASK) << \\\n+\t\t\tHINIC_DMA_ATTR_ENTRY_##member##_SHIFT)\n+\n+#define HINIC_DMA_ATTR_ENTRY_CLEAR(val, member)\t\t\\\n+\t\t((val) & (~(HINIC_DMA_ATTR_ENTRY_##member##_MASK\t\\\n+\t\t\t<< HINIC_DMA_ATTR_ENTRY_##member##_SHIFT)))\n+\n+#define HINIC_PCIE_ST_DISABLE\t\t\t0\n+#define HINIC_PCIE_AT_DISABLE\t\t\t0\n+#define HINIC_PCIE_PH_DISABLE\t\t\t0\n+\n+#define PCIE_MSIX_ATTR_ENTRY\t\t\t0\n+\n+#define HINIC_MSG_TO_MGMT_MAX_LEN\t\t2016\n+\n+/**\n+ * hinic_cpu_to_be32 - convert data to big endian 32 bit format\n+ * @data: the data to convert\n+ * @len: length of data to convert, must be Multiple of 4B\n+ **/\n+void hinic_cpu_to_be32(void *data, int len)\n+{\n+\tu32 i;\n+\tu32 *mem = (u32 *)data;\n+\n+\tfor (i = 0; i < ((u32)len >> 2); i++) {\n+\t\t*mem = cpu_to_be32(*mem);\n+\t\tmem++;\n+\t}\n+}\n+\n+/**\n+ * hinic_cpu_to_be32 - convert data from big endian 32 bit format\n+ * @data: the data to convert\n+ * @len: length of data to convert\n+ **/\n+void hinic_be32_to_cpu(void *data, int len)\n+{\n+\tint i, chunk_sz = sizeof(u32);\n+\tu32 *mem = (u32 *)data;\n+\n+\tlen = len / chunk_sz;\n+\n+\tfor (i = 0; i < len; i++) {\n+\t\t*mem = be32_to_cpu(*mem);\n+\t\tmem++;\n+\t}\n+}\n+\n+/**\n+ * hinic_set_sge - set dma area in scatter gather entry\n+ * @sge: scatter gather entry\n+ * @addr: dma address\n+ * @len: length of relevant data in the dma address\n+ **/\n+void hinic_set_sge(struct hinic_sge *sge, dma_addr_t addr, u32 len)\n+{\n+\tsge->hi_addr = upper_32_bits(addr);\n+\tsge->lo_addr = lower_32_bits(addr);\n+\tsge->len  = len;\n+}\n+\n+/**\n+ * hinic_set_ci_table - set ci attribute table\n+ * @hwdev: the hardware interface of a nic device\n+ * @q_id: Queue id of SQ\n+ * @attr: Point to SQ CI attribute table\n+ * @return\n+ *   0 on success and ci attribute table is filled,\n+ *   negative error value otherwise.\n+ **/\n+int hinic_set_ci_table(void *hwdev, u16 q_id, struct hinic_sq_attr *attr)\n+{\n+\tstruct hinic_cons_idx_attr cons_idx_attr;\n+\n+\tmemset(&cons_idx_attr, 0, sizeof(cons_idx_attr));\n+\tcons_idx_attr.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;\n+\tcons_idx_attr.func_idx = hinic_global_func_id(hwdev);\n+\tcons_idx_attr.dma_attr_off  = attr->dma_attr_off;\n+\tcons_idx_attr.pending_limit = attr->pending_limit;\n+\tcons_idx_attr.coalescing_time = attr->coalescing_time;\n+\tif (attr->intr_en) {\n+\t\tcons_idx_attr.intr_en = attr->intr_en;\n+\t\tcons_idx_attr.intr_idx = attr->intr_idx;\n+\t}\n+\n+\tcons_idx_attr.l2nic_sqn = attr->l2nic_sqn;\n+\tcons_idx_attr.sq_id = q_id;\n+\tcons_idx_attr.ci_addr = attr->ci_dma_base;\n+\n+\treturn hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,\n+\t\t\t\t      HINIC_MGMT_CMD_L2NIC_SQ_CI_ATTR_SET,\n+\t\t\t\t      &cons_idx_attr, sizeof(cons_idx_attr),\n+\t\t\t\t      NULL, NULL, 0);\n+}\n+\n+/**\n+ * get_hw_rx_buf_size - translate rx_buf_size into hw_rx_buf_size\n+ * @rx_buf_sz: receive buffer size\n+ * @return\n+ *   hw rx buffer size\n+ **/\n+static u16 get_hw_rx_buf_size(int rx_buf_sz)\n+{\n+\tu16 num_hw_types = sizeof(hinic_hw_rx_buf_size)\n+\t\t\t   / sizeof(hinic_hw_rx_buf_size[0]);\n+\tu16 i;\n+\n+\tfor (i = 0; i < num_hw_types; i++) {\n+\t\tif (hinic_hw_rx_buf_size[i] == rx_buf_sz)\n+\t\t\treturn i;\n+\t}\n+\n+\tPMD_DRV_LOG(ERR, \"Hw can't support rx buf size of %d\", rx_buf_sz);\n+\n+\treturn DEFAULT_RX_BUF_SIZE;\t/* default 2K */\n+}\n+\n+/**\n+ * hinic_set_pagesize - set page size to vat table\n+ * @hwdev: the hardware interface of a nic device\n+ * @page_size: vat page size\n+ * @return\n+ *   0 on success,\n+ *   negative error value otherwise.\n+ **/\n+int hinic_set_pagesize(void *hwdev, u8 page_size)\n+{\n+\tstruct hinic_page_size cmd;\n+\n+\tif (page_size > HINIC_PAGE_SIZE_MAX) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid page_size %u, bigger than %u\",\n+\t\t       page_size, HINIC_PAGE_SIZE_MAX);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;\n+\tcmd.func_idx = hinic_global_func_id(hwdev);\n+\tcmd.ppf_idx = hinic_ppf_idx(hwdev);\n+\tcmd.page_size = page_size;\n+\n+\treturn hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,\n+\t\t\t\t\tHINIC_MGMT_CMD_PAGESIZE_SET,\n+\t\t\t\t\t&cmd, sizeof(cmd),\n+\t\t\t\t\tNULL, NULL, 0);\n+}\n+\n+/**\n+ * hinic_set_root_ctxt - init root context in NIC\n+ * @hwdev: the hardware interface of a nic device\n+ * @rq_depth: the depth of receive queue\n+ * @sq_depth: the depth of transmit queue\n+ * @rx_buf_sz: receive buffer size from app\n+ * Return: 0 on success, negative error value otherwise.\n+ **/\n+int hinic_set_root_ctxt(void *hwdev, u16 rq_depth, u16 sq_depth, int rx_buf_sz)\n+{\n+\tstruct hinic_root_ctxt root_ctxt;\n+\n+\tmemset(&root_ctxt, 0, sizeof(root_ctxt));\n+\troot_ctxt.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;\n+\troot_ctxt.func_idx = hinic_global_func_id(hwdev);\n+\troot_ctxt.ppf_idx = hinic_ppf_idx(hwdev);\n+\troot_ctxt.set_cmdq_depth = 0;\n+\troot_ctxt.cmdq_depth = 0;\n+\troot_ctxt.lro_en = 1;\n+\troot_ctxt.rq_depth  = (u16)ilog2(rq_depth);\n+\troot_ctxt.rx_buf_sz = get_hw_rx_buf_size(rx_buf_sz);\n+\troot_ctxt.sq_depth  = (u16)ilog2(sq_depth);\n+\n+\treturn hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,\n+\t\t\t\t      HINIC_MGMT_CMD_VAT_SET,\n+\t\t\t\t      &root_ctxt, sizeof(root_ctxt),\n+\t\t\t\t      NULL, NULL, 0);\n+}\n+\n+/**\n+ * hinic_clean_root_ctxt - clean root context table in NIC\n+ * @hwdev: the hardware interface of a nic device\n+ * @return\n+ *   0 on success,\n+ *   negative error value otherwise.\n+ **/\n+int hinic_clean_root_ctxt(void *hwdev)\n+{\n+\tstruct hinic_root_ctxt root_ctxt;\n+\n+\tmemset(&root_ctxt, 0, sizeof(root_ctxt));\n+\troot_ctxt.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;\n+\troot_ctxt.func_idx = hinic_global_func_id(hwdev);\n+\troot_ctxt.ppf_idx = hinic_ppf_idx(hwdev);\n+\troot_ctxt.set_cmdq_depth = 0;\n+\troot_ctxt.cmdq_depth = 0;\n+\troot_ctxt.lro_en = 0;\n+\troot_ctxt.rq_depth  = 0;\n+\troot_ctxt.rx_buf_sz = 0;\n+\troot_ctxt.sq_depth  = 0;\n+\n+\treturn hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,\n+\t\t\t\t      HINIC_MGMT_CMD_VAT_SET,\n+\t\t\t\t      &root_ctxt, sizeof(root_ctxt),\n+\t\t\t\t      NULL, NULL, 0);\n+}\n+\n+static int wait_for_flr_finish(struct hinic_hwif *hwif)\n+{\n+\tunsigned long end;\n+\tenum hinic_pf_status status;\n+\n+\tend = jiffies + msecs_to_jiffies(HINIC_FLR_TIMEOUT);\n+\tdo {\n+\t\tstatus = hinic_get_pf_status(hwif);\n+\t\tif (status == HINIC_PF_STATUS_FLR_FINISH_FLAG) {\n+\t\t\thinic_set_pf_status(hwif, HINIC_PF_STATUS_ACTIVE_FLAG);\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\trte_delay_ms(10);\n+\t} while (time_before(jiffies, end));\n+\n+\treturn -EFAULT;\n+}\n+\n+#define HINIC_WAIT_CMDQ_IDLE_TIMEOUT\t\t1000\n+\n+static int wait_cmdq_stop(struct hinic_hwdev *hwdev)\n+{\n+\tenum hinic_cmdq_type cmdq_type;\n+\tstruct hinic_cmdqs *cmdqs = hwdev->cmdqs;\n+\tunsigned long end;\n+\tint err = 0;\n+\n+\tif (!(cmdqs->status & HINIC_CMDQ_ENABLE))\n+\t\treturn 0;\n+\n+\tcmdqs->status &= ~HINIC_CMDQ_ENABLE;\n+\n+\tend = jiffies + msecs_to_jiffies(HINIC_WAIT_CMDQ_IDLE_TIMEOUT);\n+\tdo {\n+\t\terr = 0;\n+\t\tcmdq_type = HINIC_CMDQ_SYNC;\n+\t\tfor (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) {\n+\t\t\tif (!hinic_cmdq_idle(&cmdqs->cmdq[cmdq_type])) {\n+\t\t\t\terr = -EBUSY;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (!err)\n+\t\t\treturn 0;\n+\n+\t\trte_delay_ms(1);\n+\t} while (time_before(jiffies, end));\n+\n+\tcmdqs->status |= HINIC_CMDQ_ENABLE;\n+\n+\treturn err;\n+}\n+\n+/**\n+ * hinic_pf_rx_tx_flush - clean up hardware resource\n+ * @hwdev: the hardware interface of a nic device\n+ * @return\n+ *   0 on success,\n+ *   negative error value otherwise.\n+ **/\n+static int hinic_pf_rx_tx_flush(struct hinic_hwdev *hwdev)\n+{\n+\tstruct hinic_hwif *hwif = hwdev->hwif;\n+\tstruct hinic_clear_doorbell clear_db;\n+\tstruct hinic_clear_resource clr_res;\n+\tint err;\n+\n+\trte_delay_ms(100);\n+\n+\terr = wait_cmdq_stop(hwdev);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Cmdq is still working\");\n+\t\treturn err;\n+\t}\n+\n+\thinic_disable_doorbell(hwif);\n+\tmemset(&clear_db, 0, sizeof(clear_db));\n+\tclear_db.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;\n+\tclear_db.func_idx = HINIC_HWIF_GLOBAL_IDX(hwif);\n+\tclear_db.ppf_idx  = HINIC_HWIF_PPF_IDX(hwif);\n+\terr = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,\n+\t\t\t\t     HINIC_MGMT_CMD_FLUSH_DOORBELL, &clear_db,\n+\t\t\t\t     sizeof(clear_db), NULL, NULL, 0);\n+\tif (err)\n+\t\tPMD_DRV_LOG(WARNING, \"Flush doorbell failed\");\n+\n+\thinic_set_pf_status(hwif, HINIC_PF_STATUS_FLR_START_FLAG);\n+\tmemset(&clr_res, 0, sizeof(clr_res));\n+\tclr_res.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;\n+\tclr_res.func_idx = HINIC_HWIF_GLOBAL_IDX(hwif);\n+\tclr_res.ppf_idx  = HINIC_HWIF_PPF_IDX(hwif);\n+\n+\terr = hinic_msg_to_mgmt_no_ack(hwdev, HINIC_MOD_COMM,\n+\t\t\t\t       HINIC_MGMT_CMD_START_FLR, &clr_res,\n+\t\t\t\t       sizeof(clr_res), NULL, NULL);\n+\tif (err)\n+\t\tPMD_DRV_LOG(WARNING, \"Notice flush message failed\");\n+\n+\terr = wait_for_flr_finish(hwif);\n+\tif (err)\n+\t\tPMD_DRV_LOG(WARNING, \"Wait firmware FLR timeout\");\n+\n+\thinic_enable_doorbell(hwif);\n+\n+\terr = hinic_reinit_cmdq_ctxts(hwdev);\n+\tif (err)\n+\t\tPMD_DRV_LOG(WARNING, \"Reinit cmdq failed\");\n+\n+\treturn 0;\n+}\n+\n+int hinic_func_rx_tx_flush(struct hinic_hwdev *hwdev)\n+{\n+\treturn hinic_pf_rx_tx_flush(hwdev);\n+}\n+\n+/**\n+ * hinic_get_interrupt_cfg - get interrupt configuration from NIC\n+ * @hwdev: the hardware interface of a nic device\n+ * @interrupt_info: Information of Interrupt aggregation\n+ * Return: 0 on success, negative error value otherwise.\n+ **/\n+static int hinic_get_interrupt_cfg(struct hinic_hwdev *hwdev,\n+\t\t\t\tstruct nic_interrupt_info *interrupt_info)\n+{\n+\tstruct hinic_msix_config msix_cfg;\n+\tu16 out_size = sizeof(msix_cfg);\n+\tint err;\n+\n+\tmemset(&msix_cfg, 0, sizeof(msix_cfg));\n+\tmsix_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;\n+\tmsix_cfg.func_id = hinic_global_func_id(hwdev);\n+\tmsix_cfg.msix_index = interrupt_info->msix_index;\n+\n+\terr = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,\n+\t\t\t\t     HINIC_MGMT_CMD_MSI_CTRL_REG_RD_BY_UP,\n+\t\t\t\t     &msix_cfg, sizeof(msix_cfg),\n+\t\t\t\t     &msix_cfg, &out_size, 0);\n+\tif (err || !out_size || msix_cfg.mgmt_msg_head.status) {\n+\t\tPMD_DRV_LOG(ERR, \"Get interrupt config failed, ret: %d\",\n+\t\t\tmsix_cfg.mgmt_msg_head.status);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tinterrupt_info->lli_credit_limit = msix_cfg.lli_credit_cnt;\n+\tinterrupt_info->lli_timer_cfg = msix_cfg.lli_tmier_cnt;\n+\tinterrupt_info->pending_limt = msix_cfg.pending_cnt;\n+\tinterrupt_info->coalesc_timer_cfg = msix_cfg.coalesct_timer_cnt;\n+\tinterrupt_info->resend_timer_cfg = msix_cfg.resend_timer_cnt;\n+\treturn 0;\n+}\n+\n+/**\n+ * hinic_set_interrupt_cfg - set interrupt configuration to NIC\n+ * @hwdev: the hardware interface of a nic device\n+ * @interrupt_info: Information of Interrupt aggregation\n+ * Return: 0 on success, negative error value otherwise.\n+ **/\n+int hinic_set_interrupt_cfg(struct hinic_hwdev *hwdev,\n+\t\t\t    struct nic_interrupt_info interrupt_info)\n+{\n+\tstruct hinic_msix_config msix_cfg;\n+\tstruct nic_interrupt_info temp_info;\n+\tu16 out_size = sizeof(msix_cfg);\n+\tint err;\n+\n+\tmemset(&msix_cfg, 0, sizeof(msix_cfg));\n+\tmsix_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;\n+\tmsix_cfg.func_id = hinic_global_func_id(hwdev);\n+\tmsix_cfg.msix_index = (u16)interrupt_info.msix_index;\n+\n+\ttemp_info.msix_index = interrupt_info.msix_index;\n+\n+\terr = hinic_get_interrupt_cfg(hwdev, &temp_info);\n+\tif (err)\n+\t\treturn -EINVAL;\n+\n+\tmsix_cfg.lli_credit_cnt = temp_info.lli_credit_limit;\n+\tmsix_cfg.lli_tmier_cnt = temp_info.lli_timer_cfg;\n+\tmsix_cfg.pending_cnt = temp_info.pending_limt;\n+\tmsix_cfg.coalesct_timer_cnt = temp_info.coalesc_timer_cfg;\n+\tmsix_cfg.resend_timer_cnt = temp_info.resend_timer_cfg;\n+\n+\tif (interrupt_info.lli_set) {\n+\t\tmsix_cfg.lli_credit_cnt = interrupt_info.lli_credit_limit;\n+\t\tmsix_cfg.lli_tmier_cnt = interrupt_info.lli_timer_cfg;\n+\t}\n+\n+\tif (interrupt_info.interrupt_coalesc_set) {\n+\t\tmsix_cfg.pending_cnt = interrupt_info.pending_limt;\n+\t\tmsix_cfg.coalesct_timer_cnt = interrupt_info.coalesc_timer_cfg;\n+\t\tmsix_cfg.resend_timer_cnt = interrupt_info.resend_timer_cfg;\n+\t}\n+\n+\terr = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,\n+\t\t\t\t     HINIC_MGMT_CMD_MSI_CTRL_REG_WR_BY_UP,\n+\t\t\t\t     &msix_cfg, sizeof(msix_cfg),\n+\t\t\t\t     &msix_cfg, &out_size, 0);\n+\tif (err || !out_size || msix_cfg.mgmt_msg_head.status) {\n+\t\tPMD_DRV_LOG(ERR, \"Set interrupt config failed, ret: %d\",\n+\t\t\tmsix_cfg.mgmt_msg_head.status);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * hinic_misx_intr_clear_resend_bit - clear interrupt resend configuration\n+ * @hwdev: the hardware interface of a nic device\n+ * @msix_idx: Index of msix interrupt\n+ * @clear_resend_en: enable flag of clear resend configuration\n+ **/\n+void hinic_misx_intr_clear_resend_bit(void *hwdev, u16 msix_idx,\n+\t\t\t\t      u8 clear_resend_en)\n+{\n+\tstruct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif;\n+\tu32 msix_ctrl = 0, addr;\n+\n+\tmsix_ctrl = HINIC_MSIX_CNT_SET(clear_resend_en, RESEND_TIMER);\n+\n+\taddr = HINIC_CSR_MSIX_CNT_ADDR(msix_idx);\n+\n+\thinic_hwif_write_reg(hwif, addr, msix_ctrl);\n+}\n+\n+/**\n+ * init_aeqs_msix_attr - Init interrupt attributes of aeq\n+ * @hwdev: the hardware interface of a nic device\n+ * @return\n+ *   0 on success,\n+ *   negative error value otherwise.\n+ **/\n+int init_aeqs_msix_attr(void *hwdev)\n+{\n+\tstruct hinic_hwdev *nic_hwdev = (struct hinic_hwdev *)hwdev;\n+\tstruct hinic_aeqs *aeqs = nic_hwdev->aeqs;\n+\tstruct nic_interrupt_info info = {0};\n+\tstruct hinic_eq *eq;\n+\tu16 q_id;\n+\tint err;\n+\n+\tinfo.lli_set = 0;\n+\tinfo.interrupt_coalesc_set = 1;\n+\tinfo.pending_limt = HINIC_DEAULT_EQ_MSIX_PENDING_LIMIT;\n+\tinfo.coalesc_timer_cfg = HINIC_DEAULT_EQ_MSIX_COALESC_TIMER_CFG;\n+\tinfo.resend_timer_cfg = HINIC_DEAULT_EQ_MSIX_RESEND_TIMER_CFG;\n+\n+\tfor (q_id = 0; q_id < aeqs->num_aeqs; q_id++) {\n+\t\teq = &aeqs->aeq[q_id];\n+\t\tinfo.msix_index = eq->eq_irq.msix_entry_idx;\n+\t\terr = hinic_set_interrupt_cfg(hwdev, info);\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Set msix attr for aeq %d failed\",\n+\t\t\t\t    q_id);\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * set_pf_dma_attr_entry - set the dma attributes for entry\n+ * @hwdev: the pointer to the private hardware device object\n+ * @entry_idx: the entry index in the dma table\n+ * @st: PCIE TLP steering tag\n+ * @at:\tPCIE TLP AT field\n+ * @ph: PCIE TLP Processing Hint field\n+ * @no_snooping: PCIE TLP No snooping\n+ * @tph_en: PCIE TLP Processing Hint Enable\n+ **/\n+static void set_pf_dma_attr_entry(struct hinic_hwdev *hwdev, u32 entry_idx,\n+\t\t\t\t  u8 st, u8 at, u8 ph,\n+\t\t\t\t  enum hinic_pcie_nosnoop no_snooping,\n+\t\t\t\t  enum hinic_pcie_tph tph_en)\n+{\n+\tu32 addr, val, dma_attr_entry;\n+\n+\t/* Read Modify Write */\n+\taddr = HINIC_CSR_DMA_ATTR_TBL_ADDR(entry_idx);\n+\n+\tval = hinic_hwif_read_reg(hwdev->hwif, addr);\n+\tval = HINIC_DMA_ATTR_ENTRY_CLEAR(val, ST)\t&\n+\t\tHINIC_DMA_ATTR_ENTRY_CLEAR(val, AT)\t&\n+\t\tHINIC_DMA_ATTR_ENTRY_CLEAR(val, PH)\t&\n+\t\tHINIC_DMA_ATTR_ENTRY_CLEAR(val, NO_SNOOPING)\t&\n+\t\tHINIC_DMA_ATTR_ENTRY_CLEAR(val, TPH_EN);\n+\n+\tdma_attr_entry = HINIC_DMA_ATTR_ENTRY_SET(st, ST)\t|\n+\t\t\t HINIC_DMA_ATTR_ENTRY_SET(at, AT)\t|\n+\t\t\t HINIC_DMA_ATTR_ENTRY_SET(ph, PH)\t|\n+\t\t\t HINIC_DMA_ATTR_ENTRY_SET(no_snooping, NO_SNOOPING) |\n+\t\t\t HINIC_DMA_ATTR_ENTRY_SET(tph_en, TPH_EN);\n+\n+\tval |= dma_attr_entry;\n+\thinic_hwif_write_reg(hwdev->hwif, addr, val);\n+}\n+\n+/**\n+ * dma_attr_table_init - initialize the the default dma attributes\n+ * @hwdev: the pointer to the private hardware device object\n+ **/\n+static void dma_attr_table_init(struct hinic_hwdev *hwdev)\n+{\n+\tif (HINIC_IS_VF(hwdev))\n+\t\treturn;\n+\n+\tset_pf_dma_attr_entry(hwdev, PCIE_MSIX_ATTR_ENTRY,\n+\t\t\t      HINIC_PCIE_ST_DISABLE,\n+\t\t\t      HINIC_PCIE_AT_DISABLE,\n+\t\t\t      HINIC_PCIE_PH_DISABLE,\n+\t\t\t      HINIC_PCIE_SNOOP,\n+\t\t\t      HINIC_PCIE_TPH_DISABLE);\n+}\n+\n+int hinic_init_attr_table(struct hinic_hwdev *hwdev)\n+{\n+\tdma_attr_table_init(hwdev);\n+\n+\treturn init_aeqs_msix_attr(hwdev);\n+}\n+\n+static int hinic_get_mgmt_channel_status(void *handle)\n+{\n+\tstruct hinic_hwdev *hwdev = (struct hinic_hwdev *)handle;\n+\tu32 val;\n+\n+\tif (!hwdev)\n+\t\treturn true;\n+\n+\tval = hinic_hwif_read_reg(hwdev->hwif, HINIC_ICPL_RESERVD_ADDR);\n+\n+\treturn HINIC_GET_MGMT_CHANNEL_STATUS(val, MGMT_CHANNEL_STATUS);\n+}\n+\n+int hinic_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd,\n+\t\t\t   void *buf_in, u16 in_size,\n+\t\t\t   void *buf_out, u16 *out_size, u32 timeout)\n+{\n+\tint rc = HINIC_ERROR;\n+\n+\tif (!hwdev || in_size > HINIC_MSG_TO_MGMT_MAX_LEN)\n+\t\treturn -EINVAL;\n+\n+\t/* If status is hot upgrading, don't send message to mgmt */\n+\tif (hinic_get_mgmt_channel_status(hwdev))\n+\t\treturn -EPERM;\n+\n+\trc = hinic_pf_to_mgmt_sync(hwdev, mod, cmd, buf_in,\n+\t\t\t\t   in_size, buf_out, out_size,\n+\t\t\t\t   timeout);\n+\n+\treturn rc;\n+}\n+\n+#define FAULT_SHOW_STR_LEN 16\n+static void fault_report_show(struct hinic_hwdev *hwdev,\n+\t\t\t      struct hinic_fault_event *event)\n+{\n+\tchar fault_type[FAULT_TYPE_MAX][FAULT_SHOW_STR_LEN + 1] = {\n+\t\t\"chip\", \"ucode\", \"mem rd timeout\", \"mem wr timeout\",\n+\t\t\"reg rd timeout\", \"reg wr timeout\"};\n+\tchar fault_level[FAULT_LEVEL_MAX][FAULT_SHOW_STR_LEN + 1] = {\n+\t\t\"fatal\", \"reset\", \"flr\", \"general\", \"suggestion\"};\n+\tchar type_str[FAULT_SHOW_STR_LEN + 1] = { 0 };\n+\tchar level_str[FAULT_SHOW_STR_LEN + 1] = { 0 };\n+\tu8 err_level;\n+\n+\tPMD_DRV_LOG(WARNING, \"Fault event report received, func_id: %d\",\n+\t\t hinic_global_func_id(hwdev));\n+\n+\tif (event->type < FAULT_TYPE_MAX)\n+\t\tstrncpy(type_str, fault_type[event->type], FAULT_SHOW_STR_LEN);\n+\telse\n+\t\tstrncpy(type_str, \"unknown\", FAULT_SHOW_STR_LEN);\n+\tPMD_DRV_LOG(WARNING, \"fault type:    %d [%s]\",\n+\t\t event->type, type_str);\n+\tPMD_DRV_LOG(WARNING, \"fault val[0]:  0x%08x\",\n+\t\t event->event.val[0]);\n+\tPMD_DRV_LOG(WARNING, \"fault val[1]:  0x%08x\",\n+\t\t event->event.val[1]);\n+\tPMD_DRV_LOG(WARNING, \"fault val[2]:  0x%08x\",\n+\t\t event->event.val[2]);\n+\tPMD_DRV_LOG(WARNING, \"fault val[3]:  0x%08x\",\n+\t\t event->event.val[3]);\n+\n+\tswitch (event->type) {\n+\tcase FAULT_TYPE_CHIP:\n+\t\terr_level = event->event.chip.err_level;\n+\t\tif (err_level < FAULT_LEVEL_MAX)\n+\t\t\tstrncpy(level_str, fault_level[err_level],\n+\t\t\t\tFAULT_SHOW_STR_LEN);\n+\t\telse\n+\t\t\tstrncpy(level_str, \"unknown\",\n+\t\t\t\tFAULT_SHOW_STR_LEN);\n+\n+\t\tPMD_DRV_LOG(WARNING, \"err_level:     %d [%s]\",\n+\t\t\t err_level, level_str);\n+\n+\t\tif (err_level == FAULT_LEVEL_SERIOUS_FLR) {\n+\t\t\tPMD_DRV_LOG(WARNING, \"flr func_id:   %d\",\n+\t\t\t\t event->event.chip.func_id);\n+\t\t} else {\n+\t\t\tPMD_DRV_LOG(WARNING, \"node_id:       %d\",\n+\t\t\t\t event->event.chip.node_id);\n+\t\t\tPMD_DRV_LOG(WARNING, \"err_type:      %d\",\n+\t\t\t\t event->event.chip.err_type);\n+\t\t\tPMD_DRV_LOG(WARNING, \"err_csr_addr:  %d\",\n+\t\t\t\t event->event.chip.err_csr_addr);\n+\t\t\tPMD_DRV_LOG(WARNING, \"err_csr_value: %d\",\n+\t\t\t\t event->event.chip.err_csr_value);\n+\t\t}\n+\t\tbreak;\n+\tcase FAULT_TYPE_UCODE:\n+\t\tPMD_DRV_LOG(WARNING, \"cause_id:      %d\",\n+\t\t\t event->event.ucode.cause_id);\n+\t\tPMD_DRV_LOG(WARNING, \"core_id:       %d\",\n+\t\t\t event->event.ucode.core_id);\n+\t\tPMD_DRV_LOG(WARNING, \"c_id:          %d\",\n+\t\t\t event->event.ucode.c_id);\n+\t\tPMD_DRV_LOG(WARNING, \"epc:           %d\",\n+\t\t\t event->event.ucode.epc);\n+\t\tbreak;\n+\tcase FAULT_TYPE_MEM_RD_TIMEOUT:\n+\tcase FAULT_TYPE_MEM_WR_TIMEOUT:\n+\t\tPMD_DRV_LOG(WARNING, \"err_csr_ctrl:  %d\",\n+\t\t\t event->event.mem_timeout.err_csr_ctrl);\n+\t\tPMD_DRV_LOG(WARNING, \"err_csr_data:  %d\",\n+\t\t\t event->event.mem_timeout.err_csr_data);\n+\t\tPMD_DRV_LOG(WARNING, \"ctrl_tab:      %d\",\n+\t\t\t event->event.mem_timeout.ctrl_tab);\n+\t\tPMD_DRV_LOG(WARNING, \"mem_index:     %d\",\n+\t\t\t event->event.mem_timeout.mem_index);\n+\t\tbreak;\n+\tcase FAULT_TYPE_REG_RD_TIMEOUT:\n+\tcase FAULT_TYPE_REG_WR_TIMEOUT:\n+\t\tPMD_DRV_LOG(WARNING, \"err_csr:       %d\",\n+\t\t\t event->event.reg_timeout.err_csr);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+}\n+\n+static int resources_state_set(struct hinic_hwdev *hwdev,\n+\t\t\t       enum hinic_res_state state)\n+{\n+\tstruct hinic_hwif *hwif = hwdev->hwif;\n+\tstruct hinic_cmd_set_res_state res_state;\n+\n+\tmemset(&res_state, 0, sizeof(res_state));\n+\tres_state.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;\n+\tres_state.func_idx = HINIC_HWIF_GLOBAL_IDX(hwif);\n+\tres_state.state = state;\n+\n+\treturn hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,\n+\t\t\t\t HINIC_MGMT_CMD_RES_STATE_SET,\n+\t\t\t\t &res_state, sizeof(res_state), NULL, NULL, 0);\n+}\n+\n+/**\n+ * hinic_activate_hwdev_state - Active host nic state and notify mgmt channel\n+ * that host nic is ready.\n+ * @hwdev: the hardware interface of a nic device\n+ * @return\n+ *   0 on success,\n+ *   negative error value otherwise.\n+ **/\n+int hinic_activate_hwdev_state(struct hinic_hwdev *hwdev)\n+{\n+\tint rc = HINIC_OK;\n+\n+\tif (!hwdev)\n+\t\treturn -EINVAL;\n+\n+\tif (!HINIC_IS_VF(hwdev))\n+\t\thinic_set_pf_status(hwdev->hwif,\n+\t\t\t\t    HINIC_PF_STATUS_ACTIVE_FLAG);\n+\n+\trc = resources_state_set(hwdev, HINIC_RES_ACTIVE);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize resources state failed\");\n+\t\treturn rc;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * hinic_deactivate_hwdev_state - Deactivate host nic state and notify mgmt\n+ * channel that host nic is not ready.\n+ * @hwdev: the pointer to the private hardware device object\n+ **/\n+void hinic_deactivate_hwdev_state(struct hinic_hwdev *hwdev)\n+{\n+\tint rc = HINIC_OK;\n+\n+\tif (!hwdev)\n+\t\treturn;\n+\n+\trc = resources_state_set(hwdev, HINIC_RES_CLEAN);\n+\tif (rc)\n+\t\tPMD_DRV_LOG(ERR, \"Deinit resources state failed\");\n+\n+\tif (!HINIC_IS_VF(hwdev))\n+\t\thinic_set_pf_status(hwdev->hwif, HINIC_PF_STATUS_INIT);\n+}\n+\n+int hinic_get_board_info(void *hwdev, struct hinic_board_info *info)\n+{\n+\tstruct hinic_comm_board_info board_info;\n+\tu16 out_size = sizeof(board_info);\n+\tint err;\n+\n+\tif (!hwdev || !info)\n+\t\treturn -EINVAL;\n+\n+\tmemset(&board_info, 0, sizeof(board_info));\n+\tboard_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;\n+\terr = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,\n+\t\t\t\t     HINIC_MGMT_CMD_GET_BOARD_INFO,\n+\t\t\t\t     &board_info, sizeof(board_info),\n+\t\t\t\t     &board_info, &out_size, 0);\n+\tif (err || board_info.mgmt_msg_head.status || !out_size) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to get board info, err: %d, status: 0x%x, out size: 0x%x\",\n+\t\t\terr, board_info.mgmt_msg_head.status, out_size);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tmemcpy(info, &board_info.info, sizeof(*info));\n+\treturn 0;\n+}\n+\n+/**\n+ * hinic_l2nic_reset - Restore the initial state of NIC\n+ * @hwdev: the hardware interface of a nic device\n+ * @return\n+ *   0 on success,\n+ *   negative error value otherwise.\n+ **/\n+int hinic_l2nic_reset(struct hinic_hwdev *hwdev)\n+{\n+\tstruct hinic_hwif *hwif = hwdev->hwif;\n+\tstruct hinic_l2nic_reset l2nic_reset;\n+\tint err = 0;\n+\n+\terr = hinic_set_vport_enable(hwdev, false);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Set vport disable failed\");\n+\t\treturn err;\n+\t}\n+\n+\trte_delay_ms(100);\n+\n+\tmemset(&l2nic_reset, 0, sizeof(l2nic_reset));\n+\tl2nic_reset.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;\n+\tl2nic_reset.func_id = HINIC_HWIF_GLOBAL_IDX(hwif);\n+\terr = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,\n+\t\t\t\t     HINIC_MGMT_CMD_L2NIC_RESET,\n+\t\t\t\t     &l2nic_reset, sizeof(l2nic_reset),\n+\t\t\t\t     NULL, NULL, 0);\n+\tif (err || l2nic_reset.mgmt_msg_head.status) {\n+\t\tPMD_DRV_LOG(ERR, \"Reset L2NIC resources failed\");\n+\t\treturn -EFAULT;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void hinic_show_sw_watchdog_timeout_info(struct hinic_hwdev *hwdev,\n+\t\t\t\t\t\tvoid *buf_in, u16 in_size,\n+\t\t\t\t\t\tvoid *buf_out, u16 *out_size)\n+{\n+\tstruct hinic_mgmt_watchdog_info *watchdog_info;\n+\tu32 *dump_addr, *reg, stack_len, i, j;\n+\n+\tif (in_size != sizeof(*watchdog_info)) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid mgmt watchdog report, length: %d, should be %zu\",\n+\t\t\tin_size, sizeof(*watchdog_info));\n+\t\treturn;\n+\t}\n+\n+\twatchdog_info = (struct hinic_mgmt_watchdog_info *)buf_in;\n+\n+\tPMD_DRV_LOG(ERR, \"Mgmt deadloop time: 0x%x 0x%x, task id: 0x%x, sp: 0x%x\",\n+\t\twatchdog_info->curr_time_h, watchdog_info->curr_time_l,\n+\t\twatchdog_info->task_id, watchdog_info->sp);\n+\tPMD_DRV_LOG(ERR, \"Stack current used: 0x%x, peak used: 0x%x, overflow flag: 0x%x, top: 0x%x, bottom: 0x%x\",\n+\t\twatchdog_info->curr_used, watchdog_info->peak_used,\n+\t\twatchdog_info->is_overflow, watchdog_info->stack_top,\n+\t\twatchdog_info->stack_bottom);\n+\n+\tPMD_DRV_LOG(ERR, \"Mgmt pc: 0x%08x, lr: 0x%08x, cpsr:0x%08x\",\n+\t\twatchdog_info->pc, watchdog_info->lr, watchdog_info->cpsr);\n+\n+\tPMD_DRV_LOG(ERR, \"Mgmt register info\");\n+\n+\tfor (i = 0; i < 3; i++) {\n+\t\treg = watchdog_info->reg + (u64)(u32)(4 * i);\n+\t\tPMD_DRV_LOG(ERR, \"0x%08x 0x%08x 0x%08x 0x%08x\",\n+\t\t\t*(reg), *(reg + 1), *(reg + 2), *(reg + 3));\n+\t}\n+\n+\tPMD_DRV_LOG(ERR, \"0x%08x\", watchdog_info->reg[12]);\n+\n+\tif (watchdog_info->stack_actlen <= 1024) {\n+\t\tstack_len = watchdog_info->stack_actlen;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Oops stack length: 0x%x is wrong\",\n+\t\t\twatchdog_info->stack_actlen);\n+\t\tstack_len = 1024;\n+\t}\n+\n+\tPMD_DRV_LOG(ERR, \"Mgmt dump stack, 16Bytes per line(start from sp)\");\n+\tfor (i = 0; i < (stack_len / 16); i++) {\n+\t\tdump_addr = (u32 *)(watchdog_info->data + ((u64)(u32)(i * 16)));\n+\t\tPMD_DRV_LOG(ERR, \"0x%08x 0x%08x 0x%08x 0x%08x\",\n+\t\t\t*dump_addr, *(dump_addr + 1), *(dump_addr + 2),\n+\t\t\t*(dump_addr + 3));\n+\t}\n+\n+\tfor (j = 0; j < ((stack_len % 16) / 4); j++) {\n+\t\tdump_addr = (u32 *)(watchdog_info->data +\n+\t\t\t    ((u64)(u32)(i * 16 + j * 4)));\n+\t\tPMD_DRV_LOG(ERR, \"0x%08x\", *dump_addr);\n+\t}\n+\n+\t*out_size = sizeof(*watchdog_info);\n+\twatchdog_info = (struct hinic_mgmt_watchdog_info *)buf_out;\n+\twatchdog_info->mgmt_msg_head.status = 0;\n+}\n+\n+static void hinic_show_pcie_dfx_info(struct hinic_hwdev *hwdev,\n+\t\t\t\t     void *buf_in, u16 in_size,\n+\t\t\t\t     void *buf_out, u16 *out_size)\n+{\n+\tstruct hinic_pcie_dfx_ntc *notice_info =\n+\t\t(struct hinic_pcie_dfx_ntc *)buf_in;\n+\tstruct hinic_pcie_dfx_info dfx_info;\n+\tu16 size = 0;\n+\tu16 cnt = 0;\n+\tu32 num = 0;\n+\tu32 i, j;\n+\tint err;\n+\tu32 *reg;\n+\n+\tif (in_size != sizeof(*notice_info)) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid pcie dfx notice info, length: %d, should be %zu.\",\n+\t\t\tin_size, sizeof(*notice_info));\n+\t\treturn;\n+\t}\n+\n+\t((struct hinic_pcie_dfx_ntc *)buf_out)->mgmt_msg_head.status = 0;\n+\t*out_size = sizeof(*notice_info);\n+\tmemset(&dfx_info, 0, sizeof(dfx_info));\n+\tnum = (u32)(notice_info->len / 1024);\n+\tPMD_DRV_LOG(INFO, \"INFO LEN: %d\", notice_info->len);\n+\tPMD_DRV_LOG(INFO, \"PCIE DFX:\");\n+\tdfx_info.host_id = 0;\n+\tdfx_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;\n+\tfor (i = 0; i < num; i++) {\n+\t\tdfx_info.offset = i * MAX_PCIE_DFX_BUF_SIZE;\n+\t\tif (i == (num - 1))\n+\t\t\tdfx_info.last = 1;\n+\t\tsize = sizeof(dfx_info);\n+\t\terr = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,\n+\t\t\t\t\t     HINIC_MGMT_CMD_PCIE_DFX_GET,\n+\t\t\t\t\t     &dfx_info, sizeof(dfx_info),\n+\t\t\t\t\t     &dfx_info, &size, 0);\n+\t\tif (err || dfx_info.mgmt_msg_head.status || !size) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Failed to get pcie dfx info, err: %d, status: 0x%x, out size: 0x%x\",\n+\t\t\t\terr, dfx_info.mgmt_msg_head.status, size);\n+\t\t\treturn;\n+\t\t}\n+\n+\t\treg = (u32 *)dfx_info.data;\n+\t\tfor (j = 0; j < 256; j = j + 8) {\n+\t\t\tPMD_DRV_LOG(ERR, \"0x%04x: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\",\n+\t\t\t\tcnt, reg[j], reg[(u32)(j + 1)],\n+\t\t\t\treg[(u32)(j + 2)], reg[(u32)(j + 3)],\n+\t\t\t\treg[(u32)(j + 4)], reg[(u32)(j + 5)],\n+\t\t\t\treg[(u32)(j + 6)], reg[(u32)(j + 7)]);\n+\t\t\tcnt = cnt + 32;\n+\t\t}\n+\t\tmemset(dfx_info.data, 0, MAX_PCIE_DFX_BUF_SIZE);\n+\t}\n+}\n+\n+static void\n+hinic_show_ffm_info(struct hinic_hwdev *hwdev, void *buf_in, u16 in_size,\n+\t\t\tvoid *buf_out, u16 *out_size)\n+{\n+\tstruct ffm_intr_info *intr;\n+\tstruct hinic_nic_dev *nic_dev = (struct hinic_nic_dev *)hwdev->dev_hdl;\n+\n+\tif (in_size != sizeof(struct ffm_intr_info)) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid input buffer len, length: %d, should be %zu.\",\n+\t\t\tin_size, sizeof(struct ffm_intr_info));\n+\t\treturn;\n+\t}\n+\n+\tif (nic_dev->ffm_num < FFM_RECORD_NUM_MAX) {\n+\t\tnic_dev->ffm_num++;\n+\t\tintr = (struct ffm_intr_info *)buf_in;\n+\t\tPMD_DRV_LOG(WARNING, \"node_id(%d),err_csr_addr(0x%x),err_csr_val(0x%x),err_level(0x%x),err_type(0x%x)\",\n+\t\t\t    intr->node_id,\n+\t\t\t    intr->err_csr_addr,\n+\t\t\t    intr->err_csr_value,\n+\t\t\t    intr->err_level,\n+\t\t\t    intr->err_type);\n+\t}\n+}\n+\n+void hinic_comm_async_event_handle(struct hinic_hwdev *hwdev, u8 cmd,\n+\t\t\t\t   void *buf_in, u16 in_size,\n+\t\t\t\t   void *buf_out, u16 *out_size)\n+{\n+\tstruct hinic_cmd_fault_event *fault_event, *ret_fault_event;\n+\n+\tif (!hwdev)\n+\t\treturn;\n+\n+\t*out_size = 0;\n+\n+\tswitch (cmd) {\n+\tcase HINIC_MGMT_CMD_FAULT_REPORT:\n+\t\tif (in_size != sizeof(*fault_event)) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Invalid fault event report, length: %d, should be %zu\",\n+\t\t\t\tin_size, sizeof(*fault_event));\n+\t\t\treturn;\n+\t\t}\n+\n+\t\tfault_event = (struct hinic_cmd_fault_event *)buf_in;\n+\t\tfault_report_show(hwdev, &fault_event->event);\n+\n+\t\tif (hinic_func_type(hwdev) != TYPE_VF) {\n+\t\t\tret_fault_event =\n+\t\t\t\t(struct hinic_cmd_fault_event *)buf_out;\n+\t\t\tret_fault_event->mgmt_msg_head.status = 0;\n+\t\t\t*out_size = sizeof(*ret_fault_event);\n+\t\t}\n+\t\tbreak;\n+\n+\tcase HINIC_MGMT_CMD_WATCHDOG_INFO:\n+\t\thinic_show_sw_watchdog_timeout_info(hwdev, buf_in, in_size,\n+\t\t\t\t\t\t    buf_out, out_size);\n+\t\tbreak;\n+\n+\tcase HINIC_MGMT_CMD_PCIE_DFX_NTC:\n+\t\thinic_show_pcie_dfx_info(hwdev, buf_in, in_size,\n+\t\t\t\t\t buf_out, out_size);\n+\t\tbreak;\n+\n+\tcase HINIC_MGMT_CMD_FFM_SET:\n+\t\thinic_show_ffm_info(hwdev, buf_in, in_size, buf_out, out_size);\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tbreak;\n+\t}\n+}\n+\n+static void hinic_cable_status_event(struct hinic_hwdev *hwdev, u8 cmd,\n+\t\t\t\t     void *buf_in, u16 in_size, void *buf_out,\n+\t\t\t\t     u16 *out_size)\n+{\n+\tstruct hinic_cable_plug_event *plug_event;\n+\tstruct hinic_link_err_event *link_err;\n+\n+\tif (cmd == HINIC_PORT_CMD_CABLE_PLUG_EVENT) {\n+\t\tplug_event = (struct hinic_cable_plug_event *)buf_in;\n+\t\tPMD_DRV_LOG(INFO, \"Port module event: Cable %s\",\n+\t\t\t plug_event->plugged ? \"plugged\" : \"unplugged\");\n+\n+\t\t*out_size = sizeof(*plug_event);\n+\t\tplug_event = (struct hinic_cable_plug_event *)buf_out;\n+\t\tplug_event->mgmt_msg_head.status = 0;\n+\t} else if (cmd == HINIC_PORT_CMD_LINK_ERR_EVENT) {\n+\t\tlink_err = (struct hinic_link_err_event *)buf_in;\n+\t\tif (link_err->err_type >= LINK_ERR_NUM) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Link failed, Unknown type: 0x%x\",\n+\t\t\t\tlink_err->err_type);\n+\t\t} else {\n+\t\t\tPMD_DRV_LOG(INFO, \"Link failed, type: 0x%x: %s\",\n+\t\t\t\t link_err->err_type,\n+\t\t\t\t hinic_module_link_err[link_err->err_type]);\n+\t\t}\n+\n+\t\t*out_size = sizeof(*link_err);\n+\t\tlink_err = (struct hinic_link_err_event *)buf_out;\n+\t\tlink_err->mgmt_msg_head.status = 0;\n+\t}\n+}\n+\n+void hinic_l2nic_async_event_handle(struct hinic_hwdev *hwdev,\n+\t\t\t\t    void *param, u8 cmd,\n+\t\t\t\t    void *buf_in, u16 in_size,\n+\t\t\t\t    void *buf_out, u16 *out_size)\n+{\n+\tstruct hinic_port_link_status *in_link;\n+\tstruct rte_eth_dev *eth_dev;\n+\n+\tif (!hwdev)\n+\t\treturn;\n+\n+\t*out_size = 0;\n+\n+\tswitch (cmd) {\n+\tcase HINIC_PORT_CMD_LINK_STATUS_REPORT:\n+\t\teth_dev = (struct rte_eth_dev *)param;\n+\t\tin_link = (struct hinic_port_link_status *)buf_in;\n+\t\tPMD_DRV_LOG(INFO, \"Link status event report, dev_name: %s, port_id: %d, link_status: %s\",\n+\t\t\t eth_dev->data->name, eth_dev->data->port_id,\n+\t\t\t in_link->link ? \"UP\" : \"DOWN\");\n+\n+\t\thinic_lsc_process(eth_dev, in_link->link);\n+\t\tbreak;\n+\n+\tcase HINIC_PORT_CMD_CABLE_PLUG_EVENT:\n+\tcase HINIC_PORT_CMD_LINK_ERR_EVENT:\n+\t\thinic_cable_status_event(hwdev, cmd, buf_in, in_size,\n+\t\t\t\t\t buf_out, out_size);\n+\t\tbreak;\n+\n+\tcase HINIC_PORT_CMD_MGMT_RESET:\n+\t\tPMD_DRV_LOG(WARNING, \"Mgmt is reset\");\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"Unsupported event %d to process\",\n+\t\t\tcmd);\n+\t\tbreak;\n+\t}\n+}\n+\n+static void print_cable_info(struct hinic_hwdev *hwdev,\n+\t\t\t     struct hinic_link_info *info)\n+{\n+\tchar tmp_str[512] = {0};\n+\tchar tmp_vendor[17] = {0};\n+\tconst char *port_type = \"Unknown port type\";\n+\tint i;\n+\n+\tif (info->cable_absent) {\n+\t\tPMD_DRV_LOG(INFO, \"Cable unpresent\");\n+\t\treturn;\n+\t}\n+\n+\tif (info->port_type < LINK_PORT_MAX_TYPE)\n+\t\tport_type = __hw_to_char_port_type[info->port_type];\n+\telse\n+\t\tPMD_DRV_LOG(INFO, \"Unknown port type: %u\",\n+\t\t\t info->port_type);\n+\tif (info->port_type == LINK_PORT_FIBRE) {\n+\t\tif (info->port_sub_type == FIBRE_SUBTYPE_SR)\n+\t\t\tport_type = \"Fibre-SR\";\n+\t\telse if (info->port_sub_type == FIBRE_SUBTYPE_LR)\n+\t\t\tport_type = \"Fibre-LR\";\n+\t}\n+\n+\tfor (i = sizeof(info->vendor_name) - 1; i >= 0; i--) {\n+\t\tif (info->vendor_name[i] == ' ')\n+\t\t\tinfo->vendor_name[i] = '\\0';\n+\t\telse\n+\t\t\tbreak;\n+\t}\n+\n+\tmemcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name));\n+\tsnprintf(tmp_str, (sizeof(tmp_str) - 1),\n+\t\t \"Vendor: %s, %s, %s, length: %um, max_speed: %uGbps\",\n+\t\t tmp_vendor, info->sfp_type ? \"SFP\" : \"QSFP\", port_type,\n+\t\t info->cable_length, info->cable_max_speed);\n+\tif (info->port_type != LINK_PORT_COPPER)\n+\t\tsnprintf(tmp_str + strlen(tmp_str), (sizeof(tmp_str) - 1),\n+\t\t\t \"%s, Temperature: %u\", tmp_str,\n+\t\t\t info->cable_temp);\n+\n+\tPMD_DRV_LOG(INFO, \"Cable information: %s\", tmp_str);\n+}\n+\n+static void print_hi30_status(struct hinic_hwdev *hwdev,\n+\t\t\t      struct hinic_link_info *info)\n+{\n+\tstruct hi30_ffe_data *ffe_data;\n+\tstruct hi30_ctle_data *ctle_data;\n+\n+\tffe_data = (struct hi30_ffe_data *)info->hi30_ffe;\n+\tctle_data = (struct hi30_ctle_data *)info->hi30_ctle;\n+\n+\tPMD_DRV_LOG(INFO, \"TX_FFE: PRE2=%s%d; PRE1=%s%d; MAIN=%d; POST1=%s%d; POST1X=%s%d\",\n+\t\t (ffe_data->PRE1 & 0x10) ? \"-\" : \"\",\n+\t\t (int)(ffe_data->PRE1 & 0xf),\n+\t\t (ffe_data->PRE2 & 0x10) ? \"-\" : \"\",\n+\t\t (int)(ffe_data->PRE2 & 0xf),\n+\t\t (int)ffe_data->MAIN,\n+\t\t (ffe_data->POST1 & 0x10) ? \"-\" : \"\",\n+\t\t (int)(ffe_data->POST1 & 0xf),\n+\t\t (ffe_data->POST2 & 0x10) ? \"-\" : \"\",\n+\t\t (int)(ffe_data->POST2 & 0xf));\n+\tPMD_DRV_LOG(INFO, \"RX_CTLE: Gain1~3=%u %u %u; Boost1~3=%u %u %u; Zero1~3=%u %u %u; Squelch1~3=%u %u %u\",\n+\t\t ctle_data->ctlebst[0], ctle_data->ctlebst[1],\n+\t\t ctle_data->ctlebst[2], ctle_data->ctlecmband[0],\n+\t\t ctle_data->ctlecmband[1], ctle_data->ctlecmband[2],\n+\t\t ctle_data->ctlermband[0], ctle_data->ctlermband[1],\n+\t\t ctle_data->ctlermband[2], ctle_data->ctleza[0],\n+\t\t ctle_data->ctleza[1], ctle_data->ctleza[2]);\n+}\n+\n+static void print_link_info(struct hinic_hwdev *hwdev,\n+\t\t\t    struct hinic_link_info *info,\n+\t\t\t    enum hilink_info_print_event type)\n+{\n+\tconst char *fec = \"None\";\n+\n+\tif (info->fec < HILINK_FEC_MAX_TYPE)\n+\t\tfec = __hw_to_char_fec[info->fec];\n+\telse\n+\t\tPMD_DRV_LOG(INFO, \"Unknown fec type: %u\",\n+\t\t\t info->fec);\n+\n+\tif (type == HILINK_EVENT_LINK_UP || !info->an_state) {\n+\t\tPMD_DRV_LOG(INFO, \"Link information: speed %dGbps, %s, autoneg %s\",\n+\t\t\t info->speed, fec, info->an_state ? \"on\" : \"off\");\n+\t} else {\n+\t\tPMD_DRV_LOG(INFO, \"Link information: antoneg: %s\",\n+\t\t\t info->an_state ? \"on\" : \"off\");\n+\t}\n+}\n+\n+static const char *hilink_info_report_type[HILINK_EVENT_MAX_TYPE] = {\n+\t\"\", \"link up\", \"link down\", \"cable plugged\"\n+};\n+\n+static void hinic_print_hilink_info(struct hinic_hwdev *hwdev, void *buf_in,\n+\t\t\t\t    u16 in_size, void *buf_out, u16 *out_size)\n+{\n+\tstruct hinic_hilink_link_info *hilink_info =\n+\t\t(struct hinic_hilink_link_info *)buf_in;\n+\tstruct hinic_link_info *info;\n+\tenum hilink_info_print_event type;\n+\n+\tif (in_size != sizeof(*hilink_info)) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid hilink info message size %d, should be %zu\",\n+\t\t\tin_size, sizeof(*hilink_info));\n+\t\treturn;\n+\t}\n+\n+\t((struct hinic_hilink_link_info *)buf_out)->mgmt_msg_head.status = 0;\n+\t*out_size = sizeof(*hilink_info);\n+\n+\tinfo = &hilink_info->info;\n+\ttype = hilink_info->info_type;\n+\n+\tif (type < HILINK_EVENT_LINK_UP || type >= HILINK_EVENT_MAX_TYPE) {\n+\t\tPMD_DRV_LOG(INFO, \"Invalid hilink info report, type: %d\",\n+\t\t\t type);\n+\t\treturn;\n+\t}\n+\n+\tPMD_DRV_LOG(INFO, \"Hilink info report after %s\",\n+\t\t hilink_info_report_type[type]);\n+\n+\tprint_cable_info(hwdev, info);\n+\n+\tprint_link_info(hwdev, info, type);\n+\n+\tprint_hi30_status(hwdev, info);\n+\n+\tif (type == HILINK_EVENT_LINK_UP)\n+\t\treturn;\n+\n+\tif (type == HILINK_EVENT_CABLE_PLUGGED) {\n+\t\tPMD_DRV_LOG(INFO, \"alos: %u, rx_los: %u\",\n+\t\t\t info->alos, info->rx_los);\n+\t\treturn;\n+\t}\n+\n+\tPMD_DRV_LOG(INFO, \"PMA ctrl: %s, MAC tx %s, MAC rx %s, PMA debug inforeg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x\",\n+\t\t info->pma_status ? \"on\" : \"off\",\n+\t\t info->mac_tx_en ? \"enable\" : \"disable\",\n+\t\t info->mac_rx_en ? \"enable\" : \"disable\", info->pma_dbg_info_reg,\n+\t\t info->pma_signal_ok_reg, info->rf_lf_status_reg);\n+\tPMD_DRV_LOG(INFO, \"alos: %u, rx_los: %u, PCS block counter reg: 0x%x,PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x\",\n+\t\t info->alos, info->rx_los, info->pcs_err_blk_cnt_reg,\n+\t\t info->pcs_link_reg, info->mac_link_reg, info->pcs_err_cnt);\n+}\n+\n+void hinic_hilink_async_event_handle(struct hinic_hwdev *hwdev, u8 cmd,\n+\t\t\t\t     void *buf_in, u16 in_size,\n+\t\t\t\t     void *buf_out, u16 *out_size)\n+{\n+\tif (!hwdev)\n+\t\treturn;\n+\n+\t*out_size = 0;\n+\n+\tswitch (cmd) {\n+\tcase HINIC_HILINK_CMD_GET_LINK_INFO:\n+\t\thinic_print_hilink_info(hwdev, buf_in, in_size, buf_out,\n+\t\t\t\t\tout_size);\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"Unsupported event %d to process\",\n+\t\t\tcmd);\n+\t\tbreak;\n+\t}\n+}\n+\n+/**\n+ * hinic_convert_rx_buf_size - convert rx buffer size to hw size\n+ * @rx_buf_sz: receive buffer size of mbuf\n+ * @match_sz: receive buffer size of hardware\n+ * @return\n+ *   0 on success,\n+ *   negative error value otherwise.\n+ **/\n+int hinic_convert_rx_buf_size(u32 rx_buf_sz, u32 *match_sz)\n+{\n+\tu32 i, num_hw_types, best_match_sz;\n+\n+\tif (unlikely(!match_sz || rx_buf_sz < HINIC_RX_BUF_SIZE_32B))\n+\t\treturn -EINVAL;\n+\n+\tif (rx_buf_sz >= HINIC_RX_BUF_SIZE_16K) {\n+\t\tbest_match_sz =  HINIC_RX_BUF_SIZE_16K;\n+\t\tgoto size_matched;\n+\t}\n+\n+\tnum_hw_types = sizeof(hinic_hw_rx_buf_size) /\n+\t\tsizeof(hinic_hw_rx_buf_size[0]);\n+\tbest_match_sz = hinic_hw_rx_buf_size[0];\n+\tfor (i = 0; i < num_hw_types; i++) {\n+\t\tif (rx_buf_sz == hinic_hw_rx_buf_size[i]) {\n+\t\t\tbest_match_sz = hinic_hw_rx_buf_size[i];\n+\t\t\tbreak;\n+\t\t} else if (rx_buf_sz < hinic_hw_rx_buf_size[i]) {\n+\t\t\tbreak;\n+\t\t}\n+\t\tbest_match_sz = hinic_hw_rx_buf_size[i];\n+\t}\n+\n+size_matched:\n+\t*match_sz = best_match_sz;\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/hinic/base/hinic_pmd_hwdev.h b/drivers/net/hinic/base/hinic_pmd_hwdev.h\nnew file mode 100644\nindex 000000000..b1c667934\n--- /dev/null\n+++ b/drivers/net/hinic/base/hinic_pmd_hwdev.h\n@@ -0,0 +1,205 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#ifndef _HINIC_PMD_HWDEV_H_\n+#define _HINIC_PMD_HWDEV_H_\n+\n+#define HINIC_PAGE_SIZE_MAX\t20\n+#define HINIC_PAGE_SIZE_DPDK\t6\n+\n+#define HINIC_PCIE_LINK_DOWN\t\t0xFFFFFFFF\n+\n+#define HINIC_DEV_ACTIVE_FW_TIMEOUT\t(35 * 1000)\n+#define HINIC_DEV_BUSY_ACTIVE_FW\t0xFE\n+\n+struct hinic_page_addr {\n+\tvoid *virt_addr;\n+\tu64 phys_addr;\n+};\n+\n+struct nic_interrupt_info {\n+\tu32 lli_set;\n+\tu32 interrupt_coalesc_set;\n+\tu16 msix_index;\n+\tu8 lli_credit_limit;\n+\tu8 lli_timer_cfg;\n+\tu8 pending_limt;\n+\tu8 coalesc_timer_cfg;\n+\tu8 resend_timer_cfg;\n+};\n+\n+struct hinic_sq_attr {\n+\tu8 dma_attr_off;\n+\tu8 pending_limit;\n+\tu8 coalescing_time;\n+\tu8 intr_en;\n+\tu16 intr_idx;\n+\tu32 l2nic_sqn;\n+\t/* bit[63:2] is addr's high 62bit, bit[0] is valid flag */\n+\tu64 ci_dma_base;\n+};\n+\n+struct hinic_board_info {\n+\tu32\tboard_type;\n+\tu32\tport_num;\n+\tu32\tport_speed;\n+\tu32\tpcie_width;\n+\tu32\thost_num;\n+\tu32\tpf_num;\n+\tu32\tvf_total_num;\n+\tu32\ttile_num;\n+\tu32\tqcm_num;\n+\tu32\tcore_num;\n+\tu32\twork_mode;\n+\tu32\tservice_mode;\n+\tu32\tpcie_mode;\n+\tu32\tcfg_addr;\n+\tu32\tboot_sel;\n+};\n+\n+/* defined by chip */\n+enum hinic_fault_type {\n+\tFAULT_TYPE_CHIP,\n+\tFAULT_TYPE_UCODE,\n+\tFAULT_TYPE_MEM_RD_TIMEOUT,\n+\tFAULT_TYPE_MEM_WR_TIMEOUT,\n+\tFAULT_TYPE_REG_RD_TIMEOUT,\n+\tFAULT_TYPE_REG_WR_TIMEOUT,\n+\tFAULT_TYPE_MAX,\n+};\n+\n+/* defined by chip */\n+enum hinic_fault_err_level {\n+\t/* default err_level=FAULT_LEVEL_FATAL if\n+\t * type==FAULT_TYPE_MEM_RD_TIMEOUT || FAULT_TYPE_MEM_WR_TIMEOUT ||\n+\t *\t FAULT_TYPE_REG_RD_TIMEOUT || FAULT_TYPE_REG_WR_TIMEOUT ||\n+\t *\t FAULT_TYPE_UCODE\n+\t * other: err_level in event.chip.err_level if type==FAULT_TYPE_CHIP\n+\t */\n+\tFAULT_LEVEL_FATAL,\n+\tFAULT_LEVEL_SERIOUS_RESET,\n+\tFAULT_LEVEL_SERIOUS_FLR,\n+\tFAULT_LEVEL_GENERAL,\n+\tFAULT_LEVEL_SUGGESTION,\n+\tFAULT_LEVEL_MAX\n+};\n+\n+/* defined by chip */\n+struct hinic_fault_event {\n+\t/* enum hinic_fault_type */\n+\tu8 type;\n+\tu8 rsvd0[3];\n+\tunion {\n+\t\tu32 val[4];\n+\t\t/* valid only type==FAULT_TYPE_CHIP */\n+\t\tstruct {\n+\t\t\tu8 node_id;\n+\t\t\t/* enum hinic_fault_err_level */\n+\t\t\tu8 err_level;\n+\t\t\tu8 err_type;\n+\t\t\tu8 rsvd1;\n+\t\t\tu32 err_csr_addr;\n+\t\t\tu32 err_csr_value;\n+\t\t/* func_id valid only err_level==FAULT_LEVEL_SERIOUS_FLR */\n+\t\t\tu16 func_id;\n+\t\t\tu16 rsvd2;\n+\t\t} chip;\n+\n+\t\t/* valid only type==FAULT_TYPE_UCODE */\n+\t\tstruct {\n+\t\t\tu8 cause_id;\n+\t\t\tu8 core_id;\n+\t\t\tu8 c_id;\n+\t\t\tu8 rsvd3;\n+\t\t\tu32 epc;\n+\t\t\tu32 rsvd4;\n+\t\t\tu32 rsvd5;\n+\t\t} ucode;\n+\n+\t\t/* valid only type==FAULT_TYPE_MEM_RD_TIMEOUT ||\n+\t\t *\t\tFAULT_TYPE_MEM_WR_TIMEOUT\n+\t\t */\n+\t\tstruct {\n+\t\t\tu32 err_csr_ctrl;\n+\t\t\tu32 err_csr_data;\n+\t\t\tu32 ctrl_tab;\n+\t\t\tu32 mem_index;\n+\t\t} mem_timeout;\n+\n+\t\t/* valid only type==FAULT_TYPE_REG_RD_TIMEOUT ||\n+\t\t *\t\t    FAULT_TYPE_REG_WR_TIMEOUT\n+\t\t */\n+\t\tstruct {\n+\t\t\tu32 err_csr;\n+\t\t\tu32 rsvd6;\n+\t\t\tu32 rsvd7;\n+\t\t\tu32 rsvd8;\n+\t\t} reg_timeout;\n+\t} event;\n+};\n+\n+struct hinic_hwdev {\n+\tstruct rte_pci_device *pcidev_hdl;\n+\tvoid *dev_hdl;\n+\n+\tstruct hinic_hwif *hwif;\n+\n+\tstruct hinic_nic_io *nic_io;\n+\tstruct cfg_mgmt_info *cfg_mgmt;\n+\n+\tstruct hinic_aeqs *aeqs;\n+\n+\tstruct hinic_mbox_func_to_func *func_to_func;\n+\n+\tstruct hinic_msg_pf_to_mgmt *pf_to_mgmt;\n+\n+\tstruct hinic_cmdqs *cmdqs;\n+\n+\tstruct hinic_page_addr page_pa0;\n+\tstruct hinic_page_addr page_pa1;\n+};\n+\n+int hinic_get_board_info(void *hwdev, struct hinic_board_info *info);\n+\n+int hinic_set_ci_table(void *hwdev, u16 q_id, struct hinic_sq_attr *attr);\n+\n+int hinic_set_root_ctxt(void *hwdev, u16 rq_depth, u16 sq_depth, int rx_buf_sz);\n+int hinic_clean_root_ctxt(void *hwdev);\n+\n+int hinic_func_rx_tx_flush(struct hinic_hwdev *hwdev);\n+\n+int hinic_set_interrupt_cfg(struct hinic_hwdev *hwdev,\n+\t\t\t    struct nic_interrupt_info interrupt_info);\n+\n+void hinic_misx_intr_clear_resend_bit(void *hwdev, u16 msix_idx,\n+\t\t\t\t      u8 clear_resend_en);\n+\n+int init_aeqs_msix_attr(void *hwdev);\n+\n+int hinic_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd,\n+\t\t\t   void *buf_in, u16 in_size,\n+\t\t\t   void *buf_out, u16 *out_size, u32 timeout);\n+\n+void hinic_comm_async_event_handle(struct hinic_hwdev *hwdev, u8 cmd,\n+\t\t\t\t   void *buf_in, u16 in_size,\n+\t\t\t\t   void *buf_out, u16 *out_size);\n+\n+void hinic_l2nic_async_event_handle(struct hinic_hwdev *hwdev, void *param,\n+\t\t\t\t    u8 cmd, void *buf_in, u16 in_size,\n+\t\t\t\t    void *buf_out, u16 *out_size);\n+\n+void hinic_hilink_async_event_handle(struct hinic_hwdev *hwdev, u8 cmd,\n+\t\t\t\t     void *buf_in, u16 in_size, void *buf_out,\n+\t\t\t\t     u16 *out_size);\n+\n+int hinic_init_attr_table(struct hinic_hwdev *hwdev);\n+\n+int hinic_activate_hwdev_state(struct hinic_hwdev *hwdev);\n+void hinic_deactivate_hwdev_state(struct hinic_hwdev *hwdev);\n+\n+int hinic_l2nic_reset(struct hinic_hwdev *hwdev);\n+\n+int hinic_convert_rx_buf_size(u32 rx_buf_sz, u32 *match_sz);\n+\n+#endif /* _HINIC_PMD_HWDEV_H_ */\ndiff --git a/drivers/net/hinic/base/hinic_pmd_hwif.c b/drivers/net/hinic/base/hinic_pmd_hwif.c\nnew file mode 100644\nindex 000000000..8404527a4\n--- /dev/null\n+++ b/drivers/net/hinic/base/hinic_pmd_hwif.c\n@@ -0,0 +1,542 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#include <stdlib.h>\n+#include <unistd.h>\n+#include <fcntl.h>\n+#include <sys/mman.h>\n+#include <sys/ioctl.h>\n+#include <rte_log.h>\n+#include <rte_cycles.h>\n+#include <rte_pci.h>\n+#include <rte_bus_pci.h>\n+#include \"hinic_pmd_dpdev.h\"\n+\n+#define HINIC_CFG_REGS_BAR\t0\n+#define HINIC_INTR_MSI_BAR\t2\n+#define HINIC_DB_MEM_BAR\t4\n+#define HINIC_ASSERT_ON\t\t1\n+\n+static inline void __iomem *\n+io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset)\n+{\n+\t/* io_mapping only for compile using hinic kernel, dwqe not support */\n+\tu32 hinic_assert = HINIC_ASSERT_ON;\n+\n+\tHINIC_BUG_ON(hinic_assert);\n+\n+\treturn ((char __force __iomem *)mapping) + offset;\n+}\n+\n+static inline void\n+io_mapping_unmap(void __iomem *vaddr)\n+{\n+\t/* io_mapping only for compile using hinic kernel, dwqe not support */\n+\tu32 hinic_assert = HINIC_ASSERT_ON;\n+\tHINIC_BUG_ON(hinic_assert);\n+\n+\t*((u32 *)vaddr) = 0;\n+}\n+\n+/**\n+ * hwif_ready - test if the HW initialization passed\n+ * @hwdev: the pointer to the private hardware device object\n+ * Return: 0 - success, negative - failure\n+ **/\n+static int hwif_ready(struct hinic_hwdev *hwdev)\n+{\n+\tu32 addr, attr1;\n+\n+\taddr   = HINIC_CSR_FUNC_ATTR1_ADDR;\n+\tattr1  = hinic_hwif_read_reg(hwdev->hwif, addr);\n+\n+\tif (!HINIC_AF1_GET(attr1, MGMT_INIT_STATUS))\n+\t\treturn -EBUSY;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * set_hwif_attr - set the attributes as members in hwif\n+ * @hwif: the hardware interface of a pci function device\n+ * @attr0: the first attribute that was read from the hw\n+ * @attr1: the second attribute that was read from the hw\n+ * @attr2: the third attribute that was read from the hw\n+ **/\n+static void set_hwif_attr(struct hinic_hwif *hwif, u32 attr0, u32 attr1,\n+\t\t\t  u32 attr2)\n+{\n+\thwif->attr.func_global_idx = HINIC_AF0_GET(attr0, FUNC_GLOBAL_IDX);\n+\thwif->attr.port_to_port_idx = HINIC_AF0_GET(attr0, P2P_IDX);\n+\thwif->attr.pci_intf_idx = HINIC_AF0_GET(attr0, PCI_INTF_IDX);\n+\thwif->attr.vf_in_pf = HINIC_AF0_GET(attr0, VF_IN_PF);\n+\thwif->attr.func_type = HINIC_AF0_GET(attr0, FUNC_TYPE);\n+\n+\thwif->attr.ppf_idx = HINIC_AF1_GET(attr1, PPF_IDX);\n+\n+\thwif->attr.num_aeqs = BIT(HINIC_AF1_GET(attr1, AEQS_PER_FUNC));\n+\thwif->attr.num_ceqs = BIT(HINIC_AF1_GET(attr1, CEQS_PER_FUNC));\n+\thwif->attr.num_irqs = BIT(HINIC_AF1_GET(attr1, IRQS_PER_FUNC));\n+\thwif->attr.num_dma_attr = BIT(HINIC_AF1_GET(attr1, DMA_ATTR_PER_FUNC));\n+\n+\thwif->attr.global_vf_id_of_pf = HINIC_AF2_GET(attr2,\n+\t\t\t\t\t\t      GLOBAL_VF_ID_OF_PF);\n+}\n+\n+/**\n+ * get_hwif_attr - read and set the attributes as members in hwif\n+ * @hwif: the hardware interface of a pci function device\n+ **/\n+static void get_hwif_attr(struct hinic_hwif *hwif)\n+{\n+\tu32 addr, attr0, attr1, attr2;\n+\n+\taddr   = HINIC_CSR_FUNC_ATTR0_ADDR;\n+\tattr0  = hinic_hwif_read_reg(hwif, addr);\n+\n+\taddr   = HINIC_CSR_FUNC_ATTR1_ADDR;\n+\tattr1  = hinic_hwif_read_reg(hwif, addr);\n+\n+\taddr   = HINIC_CSR_FUNC_ATTR2_ADDR;\n+\tattr2  = hinic_hwif_read_reg(hwif, addr);\n+\n+\tset_hwif_attr(hwif, attr0, attr1, attr2);\n+}\n+\n+void hinic_set_pf_status(struct hinic_hwif *hwif, enum hinic_pf_status status)\n+{\n+\tu32 attr5 = HINIC_AF5_SET(status, PF_STATUS);\n+\tu32 addr  = HINIC_CSR_FUNC_ATTR5_ADDR;\n+\n+\thinic_hwif_write_reg(hwif, addr, attr5);\n+}\n+\n+enum hinic_pf_status hinic_get_pf_status(struct hinic_hwif *hwif)\n+{\n+\tu32 attr5 = hinic_hwif_read_reg(hwif, HINIC_CSR_FUNC_ATTR5_ADDR);\n+\n+\treturn HINIC_AF5_GET(attr5, PF_STATUS);\n+}\n+\n+static enum hinic_doorbell_ctrl\n+hinic_get_doorbell_ctrl_status(struct hinic_hwif *hwif)\n+{\n+\tu32 attr4 = hinic_hwif_read_reg(hwif, HINIC_CSR_FUNC_ATTR4_ADDR);\n+\n+\treturn HINIC_AF4_GET(attr4, DOORBELL_CTRL);\n+}\n+\n+static enum hinic_outbound_ctrl\n+hinic_get_outbound_ctrl_status(struct hinic_hwif *hwif)\n+{\n+\tu32 attr4 = hinic_hwif_read_reg(hwif, HINIC_CSR_FUNC_ATTR4_ADDR);\n+\n+\treturn HINIC_AF4_GET(attr4, OUTBOUND_CTRL);\n+}\n+\n+void hinic_enable_doorbell(struct hinic_hwif *hwif)\n+{\n+\tu32 addr, attr4;\n+\n+\taddr = HINIC_CSR_FUNC_ATTR4_ADDR;\n+\tattr4 = hinic_hwif_read_reg(hwif, addr);\n+\n+\tattr4 = HINIC_AF4_CLEAR(attr4, DOORBELL_CTRL);\n+\tattr4 |= HINIC_AF4_SET(ENABLE_DOORBELL, DOORBELL_CTRL);\n+\n+\thinic_hwif_write_reg(hwif, addr, attr4);\n+}\n+\n+void hinic_disable_doorbell(struct hinic_hwif *hwif)\n+{\n+\tu32 addr, attr4;\n+\n+\taddr = HINIC_CSR_FUNC_ATTR4_ADDR;\n+\tattr4 = hinic_hwif_read_reg(hwif, addr);\n+\n+\tattr4 = HINIC_AF4_CLEAR(attr4, DOORBELL_CTRL);\n+\tattr4 |= HINIC_AF4_SET(DISABLE_DOORBELL, DOORBELL_CTRL);\n+\n+\thinic_hwif_write_reg(hwif, addr, attr4);\n+}\n+\n+/**\n+ * set_ppf - try to set hwif as ppf and set the type of hwif in this case\n+ * @hwif: the hardware interface of a pci function device\n+ **/\n+static void set_ppf(struct hinic_hwif *hwif)\n+{\n+\tstruct hinic_func_attr *attr = &hwif->attr;\n+\tu32 addr, val, ppf_election;\n+\n+\t/* Read Modify Write */\n+\taddr  = HINIC_CSR_PPF_ELECTION_ADDR;\n+\n+\tval = hinic_hwif_read_reg(hwif, addr);\n+\tval = HINIC_PPF_ELECTION_CLEAR(val, IDX);\n+\n+\tppf_election =  HINIC_PPF_ELECTION_SET(attr->func_global_idx, IDX);\n+\tval |= ppf_election;\n+\n+\thinic_hwif_write_reg(hwif, addr, val);\n+\n+\t/* Check PPF */\n+\tval = hinic_hwif_read_reg(hwif, addr);\n+\n+\tattr->ppf_idx = HINIC_PPF_ELECTION_GET(val, IDX);\n+\tif (attr->ppf_idx == attr->func_global_idx)\n+\t\tattr->func_type = TYPE_PPF;\n+}\n+\n+/**\n+ * get_mpf - get the mpf index into the hwif\n+ * @hwif: the hardware interface of a pci function device\n+ **/\n+static void get_mpf(struct hinic_hwif *hwif)\n+{\n+\tstruct hinic_func_attr *attr = &hwif->attr;\n+\tu32 mpf_election, addr;\n+\n+\taddr = HINIC_CSR_GLOBAL_MPF_ELECTION_ADDR;\n+\n+\tmpf_election = hinic_hwif_read_reg(hwif, addr);\n+\tattr->mpf_idx = HINIC_MPF_ELECTION_GET(mpf_election, IDX);\n+}\n+\n+/**\n+ * set_mpf - try to set hwif as mpf and set the mpf idx in hwif\n+ * @hwif: the hardware interface of a pci function device\n+ **/\n+static void set_mpf(struct hinic_hwif *hwif)\n+{\n+\tstruct hinic_func_attr *attr = &hwif->attr;\n+\tu32 addr, val, mpf_election;\n+\n+\t/* Read Modify Write */\n+\taddr  = HINIC_CSR_GLOBAL_MPF_ELECTION_ADDR;\n+\n+\tval = hinic_hwif_read_reg(hwif, addr);\n+\n+\tval = HINIC_MPF_ELECTION_CLEAR(val, IDX);\n+\tmpf_election = HINIC_MPF_ELECTION_SET(attr->func_global_idx, IDX);\n+\n+\tval |= mpf_election;\n+\thinic_hwif_write_reg(hwif, addr, val);\n+\n+\tget_mpf(hwif);\n+}\n+\n+static void init_db_area_idx(struct hinic_free_db_area *free_db_area)\n+{\n+\tu32 i;\n+\n+\tfor (i = 0; i < HINIC_DB_MAX_AREAS; i++)\n+\t\tfree_db_area->db_idx[i] = i;\n+\n+\tfree_db_area->alloc_pos = 0;\n+\tfree_db_area->return_pos = 0;\n+\n+\tfree_db_area->num_free = HINIC_DB_MAX_AREAS;\n+\n+\tspin_lock_init(&free_db_area->idx_lock);\n+}\n+\n+static int get_db_idx(struct hinic_hwif *hwif, u32 *idx)\n+{\n+\tstruct hinic_free_db_area *free_db_area = &hwif->free_db_area;\n+\tu32 pos;\n+\tu32 pg_idx;\n+\n+\tspin_lock(&free_db_area->idx_lock);\n+\n+\tif (free_db_area->num_free == 0) {\n+\t\tspin_unlock(&free_db_area->idx_lock);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfree_db_area->num_free--;\n+\n+\tpos = free_db_area->alloc_pos++;\n+\tpos &= HINIC_DB_MAX_AREAS - 1;\n+\n+\tpg_idx = free_db_area->db_idx[pos];\n+\n+\tfree_db_area->db_idx[pos] = 0xFFFFFFFF;\n+\n+\tspin_unlock(&free_db_area->idx_lock);\n+\n+\t*idx = pg_idx;\n+\n+\treturn 0;\n+}\n+\n+static void free_db_idx(struct hinic_hwif *hwif, u32 idx)\n+{\n+\tstruct hinic_free_db_area *free_db_area = &hwif->free_db_area;\n+\tu32 pos;\n+\n+\tspin_lock(&free_db_area->idx_lock);\n+\n+\tpos = free_db_area->return_pos++;\n+\tpos &= HINIC_DB_MAX_AREAS - 1;\n+\n+\tfree_db_area->db_idx[pos] = idx;\n+\n+\tfree_db_area->num_free++;\n+\n+\tspin_unlock(&free_db_area->idx_lock);\n+}\n+\n+void hinic_free_db_addr(void *hwdev, void __iomem *db_base,\n+\t\t\tvoid __iomem *dwqe_base)\n+{\n+\tstruct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif;\n+\tu32 idx = DB_IDX(db_base, hwif->db_base);\n+\n+\tif (dwqe_base)\n+\t\tio_mapping_unmap(dwqe_base);\n+\n+\tfree_db_idx(hwif, idx);\n+}\n+\n+int hinic_alloc_db_addr(void *hwdev, void __iomem **db_base,\n+\t\t\tvoid __iomem **dwqe_base)\n+{\n+\tstruct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif;\n+\tu64 offset;\n+\tu32 idx;\n+\tint err;\n+\n+\terr = get_db_idx(hwif, &idx);\n+\tif (err)\n+\t\treturn -EFAULT;\n+\n+\t*db_base = hwif->db_base + idx * HINIC_DB_PAGE_SIZE;\n+\n+\tif (!dwqe_base)\n+\t\treturn 0;\n+\n+\toffset = ((u64)idx) << HINIC_PAGE_SHIFT;\n+\t*dwqe_base = io_mapping_map_wc(hwif->dwqe_mapping, offset);\n+\tif (!(*dwqe_base)) {\n+\t\thinic_free_db_addr(hwdev, *db_base, NULL);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void hinic_set_msix_state(void *hwdev, u16 msix_idx, enum hinic_msix_state flag)\n+{\n+\tstruct hinic_hwdev *hw = (struct hinic_hwdev *)hwdev;\n+\tstruct hinic_hwif *hwif = hw->hwif;\n+\tu32 offset = msix_idx * HINIC_PCI_MSIX_ENTRY_SIZE\n+\t\t+ HINIC_PCI_MSIX_ENTRY_VECTOR_CTRL;\n+\tu32 mask_bits;\n+\n+\t/* vfio-pci does not mmap msi-x vector table to user space,\n+\t * we can not access the space when kernel driver is vfio-pci\n+\t */\n+\tif (hw->pcidev_hdl->kdrv == RTE_KDRV_VFIO)\n+\t\treturn;\n+\n+\tmask_bits = readl(hwif->intr_regs_base + offset);\n+\tmask_bits &= ~HINIC_PCI_MSIX_ENTRY_CTRL_MASKBIT;\n+\tif (flag)\n+\t\tmask_bits |= HINIC_PCI_MSIX_ENTRY_CTRL_MASKBIT;\n+\n+\twritel(mask_bits, hwif->intr_regs_base + offset);\n+}\n+\n+static void disable_all_msix(struct hinic_hwdev *hwdev)\n+{\n+\tu16 num_irqs = hwdev->hwif->attr.num_irqs;\n+\tu16 i;\n+\n+\tfor (i = 0; i < num_irqs; i++)\n+\t\thinic_set_msix_state(hwdev, i, HINIC_MSIX_DISABLE);\n+}\n+\n+static int wait_until_doorbell_and_outbound_enabled(struct hinic_hwif *hwif)\n+{\n+\tunsigned long end;\n+\tenum hinic_doorbell_ctrl db_ctrl;\n+\tenum hinic_outbound_ctrl outbound_ctrl;\n+\n+\tend = jiffies +\n+\t\tmsecs_to_jiffies(HINIC_WAIT_DOORBELL_AND_OUTBOUND_TIMEOUT);\n+\tdo {\n+\t\tdb_ctrl = hinic_get_doorbell_ctrl_status(hwif);\n+\t\toutbound_ctrl = hinic_get_outbound_ctrl_status(hwif);\n+\n+\t\tif (outbound_ctrl == ENABLE_OUTBOUND &&\n+\t\t    db_ctrl == ENABLE_DOORBELL)\n+\t\t\treturn 0;\n+\n+\t\trte_delay_ms(1);\n+\t} while (time_before(jiffies, end));\n+\n+\treturn -EFAULT;\n+}\n+\n+u16 hinic_global_func_id(void *hwdev)\n+{\n+\tstruct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif;\n+\n+\treturn hwif->attr.func_global_idx;\n+}\n+\n+enum func_type hinic_func_type(void *hwdev)\n+{\n+\tstruct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif;\n+\n+\treturn hwif->attr.func_type;\n+}\n+\n+u8 hinic_ppf_idx(void *hwdev)\n+{\n+\tstruct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif;\n+\n+\treturn hwif->attr.ppf_idx;\n+}\n+\n+/**\n+ * hinic_init_hwif - initialize the hw interface\n+ * @hwdev: the pointer to the private hardware device object\n+ * @cfg_reg_base: base physical address of configuration registers\n+ * @intr_reg_base: base physical address of msi-x vector table\n+ * @db_base_phy: base physical address of doorbell registers\n+ * @db_base: base virtual address of doorbell registers\n+ * @dwqe_mapping: direct wqe io mapping address\n+ * Return: 0 - success, negative - failure\n+ **/\n+int hinic_init_hwif(struct hinic_hwdev *hwdev, void *cfg_reg_base,\n+\t\t    void *intr_reg_base, u64 db_base_phy,\n+\t\t    void *db_base, void *dwqe_mapping)\n+{\n+\tstruct hinic_hwif *hwif;\n+\tint err;\n+\n+\thwif = hwdev->hwif;\n+\n+\thwif->cfg_regs_base = (u8 __iomem *)cfg_reg_base;\n+\thwif->intr_regs_base = (u8 __iomem *)intr_reg_base;\n+\n+\thwif->db_base_phy = db_base_phy;\n+\thwif->db_base = (u8 __iomem *)db_base;\n+\thwif->dwqe_mapping = (struct io_mapping *)dwqe_mapping;\n+\tinit_db_area_idx(&hwif->free_db_area);\n+\n+\tget_hwif_attr(hwif);\n+\n+\terr = hwif_ready(hwdev);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Hwif is not ready\");\n+\t\tgoto hwif_ready_err;\n+\t}\n+\n+\terr = wait_until_doorbell_and_outbound_enabled(hwif);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Hw doorbell/outbound is disabled\");\n+\t\tgoto hwif_ready_err;\n+\t}\n+\n+\tif (!HINIC_IS_VF(hwdev)) {\n+\t\tset_ppf(hwif);\n+\n+\t\tif (HINIC_IS_PPF(hwdev))\n+\t\t\tset_mpf(hwif);\n+\n+\t\tget_mpf(hwif);\n+\t}\n+\n+\treturn 0;\n+\n+hwif_ready_err:\n+\tspin_lock_deinit(&hwif->free_db_area.idx_lock);\n+\n+\treturn err;\n+}\n+\n+#define HINIC_HWIF_ATTR_REG_PRINT_NUM        (6)\n+#define HINIC_HWIF_APICMD_REG_PRINT_NUM      (2)\n+#define HINIC_HWIF_EQ_REG_PRINT_NUM          (2)\n+\n+static void hinic_parse_hwif_attr(struct hinic_nic_dev *nic_dev)\n+{\n+\tstruct hinic_hwif *hwif;\n+\n+\tif (!nic_dev->hwdev || !nic_dev->hwdev->hwif) {\n+\t\tPMD_DRV_LOG(ERR, \"Hwif not initialized\");\n+\t\treturn;\n+\t}\n+\n+\thwif = nic_dev->hwdev->hwif;\n+\tPMD_DRV_LOG(INFO, \"Device %s hwif attribute:\", nic_dev->proc_dev_name);\n+\tPMD_DRV_LOG(INFO, \"func_idx:%u, p2p_idx:%u, pciintf_idx:%u, \"\n+\t\t    \"vf_in_pf:%u, ppf_idx:%u, global_vf_id:%u, func_type:%u\",\n+\t\t    hwif->attr.func_global_idx,\n+\t\t    hwif->attr.port_to_port_idx, hwif->attr.pci_intf_idx,\n+\t\t    hwif->attr.vf_in_pf, hwif->attr.ppf_idx,\n+\t\t    hwif->attr.global_vf_id_of_pf, hwif->attr.func_type);\n+\tPMD_DRV_LOG(INFO, \"num_aeqs:%u, num_ceqs:%u, num_irqs:%u, dma_attr:%u\",\n+\t\t    hwif->attr.num_aeqs, hwif->attr.num_ceqs,\n+\t\t    hwif->attr.num_irqs, hwif->attr.num_dma_attr);\n+}\n+\n+static void hinic_get_mmio(struct hinic_nic_dev *nic_dev, void **cfg_regs_base,\n+\t\t\t  void **intr_base, void **db_base)\n+{\n+\tstruct rte_pci_device *pci_dev = nic_dev->hwdev->pcidev_hdl;\n+\n+\t*cfg_regs_base = pci_dev->mem_resource[HINIC_CFG_REGS_BAR].addr;\n+\t*intr_base = pci_dev->mem_resource[HINIC_INTR_MSI_BAR].addr;\n+\t*db_base = pci_dev->mem_resource[HINIC_DB_MEM_BAR].addr;\n+}\n+\n+void hinic_hwif_res_free(struct hinic_nic_dev *nic_dev)\n+{\n+\trte_free(nic_dev->hwdev->hwif);\n+\tnic_dev->hwdev->hwif = NULL;\n+}\n+\n+int hinic_hwif_res_init(struct hinic_nic_dev *nic_dev)\n+{\n+\tint err = HINIC_ERROR;\n+\tvoid *cfg_regs_base, *db_base, *intr_base = NULL;\n+\tstruct hinic_hwdev *hwdev = nic_dev->hwdev;\n+\n+\t/* hinic related init */\n+\thwdev->hwif = (struct hinic_hwif *)rte_zmalloc(\"hinic_hwif\",\n+\t\t\tsizeof(*hwdev->hwif), RTE_CACHE_LINE_SIZE);\n+\tif (!hwdev->hwif) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate hwif failed, dev_name: %s\",\n+\t\t\t    nic_dev->proc_dev_name);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\thinic_get_mmio(nic_dev, &cfg_regs_base, &intr_base, &db_base);\n+\n+\terr = hinic_init_hwif(hwdev, cfg_regs_base,\n+\t\t\t      intr_base, 0, db_base, NULL);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize hwif failed, dev_name: %s\",\n+\t\t\t    nic_dev->proc_dev_name);\n+\t\tgoto init_hwif_err;\n+\t}\n+\n+\t/* disable msix interrupt in hw device */\n+\tdisable_all_msix(hwdev);\n+\n+\t/* print hwif attributes */\n+\thinic_parse_hwif_attr(nic_dev);\n+\n+\treturn HINIC_OK;\n+\n+init_hwif_err:\n+\trte_free(nic_dev->hwdev->hwif);\n+\tnic_dev->hwdev->hwif = NULL;\n+\n+\treturn err;\n+}\ndiff --git a/drivers/net/hinic/base/hinic_pmd_hwif.h b/drivers/net/hinic/base/hinic_pmd_hwif.h\nnew file mode 100644\nindex 000000000..66295754d\n--- /dev/null\n+++ b/drivers/net/hinic/base/hinic_pmd_hwif.h\n@@ -0,0 +1,90 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#ifndef _HINIC_PMD_HWIF_H_\n+#define _HINIC_PMD_HWIF_H_\n+\n+#define HINIC_WAIT_DOORBELL_AND_OUTBOUND_TIMEOUT\t30000\n+\n+struct io_mapping;\n+struct hinic_hwdev;\n+\n+struct hinic_free_db_area {\n+\tu32\t\tdb_idx[HINIC_DB_MAX_AREAS];\n+\n+\tu32\t\tnum_free;\n+\n+\tu32\t\talloc_pos;\n+\tu32\t\treturn_pos;\n+\t/* spinlock for idx */\n+\tspinlock_t\tidx_lock;\n+};\n+\n+struct hinic_func_attr {\n+\tu16\t\t\tfunc_global_idx;\n+\tu8\t\t\tport_to_port_idx;\n+\tu8\t\t\tpci_intf_idx;\n+\tu8\t\t\tvf_in_pf;\n+\tenum func_type\t\tfunc_type;\n+\n+\tu8\t\t\tmpf_idx;\n+\n+\tu8\t\t\tppf_idx;\n+\n+\tu16\t\t\tnum_irqs;\t\t/* max: 2 ^ 15 */\n+\tu8\t\t\tnum_aeqs;\t\t/* max: 2 ^ 3 */\n+\tu8\t\t\tnum_ceqs;\t\t/* max: 2 ^ 7 */\n+\n+\tu8\t\t\tnum_dma_attr;\t\t/* max: 2 ^ 6 */\n+\n+\tu16\t\t\tglobal_vf_id_of_pf;\n+};\n+\n+struct hinic_hwif {\n+\tu8 __iomem\t\t\t*cfg_regs_base;\n+\tu8 __iomem\t\t\t*intr_regs_base;\n+\tu64\t\t\t\tdb_base_phy;\n+\tu8 __iomem\t\t\t*db_base;\n+\tstruct io_mapping\t\t*dwqe_mapping;\n+\n+\tstruct hinic_free_db_area\tfree_db_area;\n+\n+\tstruct hinic_func_attr\t\tattr;\n+};\n+\n+static inline u32 hinic_hwif_read_reg(struct hinic_hwif *hwif, u32 reg)\n+{\n+\treturn be32_to_cpu(readl(hwif->cfg_regs_base + reg));\n+}\n+\n+static inline void hinic_hwif_write_reg(struct hinic_hwif *hwif, u32 reg,\n+\t\t\t\t\tu32 val)\n+{\n+\twritel(cpu_to_be32(val), hwif->cfg_regs_base + reg);\n+}\n+\n+void hinic_set_pf_status(struct hinic_hwif *hwif, enum hinic_pf_status status);\n+\n+enum hinic_pf_status hinic_get_pf_status(struct hinic_hwif *hwif);\n+\n+void hinic_enable_doorbell(struct hinic_hwif *hwif);\n+\n+void hinic_disable_doorbell(struct hinic_hwif *hwif);\n+\n+int hinic_alloc_db_addr(void *hwdev, void __iomem **db_base,\n+\t\t\tvoid __iomem **dwqe_base);\n+\n+void hinic_free_db_addr(void *hwdev, void __iomem *db_base,\n+\t\t\tvoid __iomem *dwqe_base);\n+\n+void hinic_set_msix_state(void *hwdev, u16 msix_idx,\n+\t\t\t  enum hinic_msix_state flag);\n+\n+u8 hinic_ppf_idx(void *hwdev);\n+\n+int hinic_init_hwif(struct hinic_hwdev *hwdev, void *cfg_reg_base,\n+\t\t    void *intr_reg_base, u64 db_base_phy,\n+\t\t    void *db_base, void *dwqe_mapping);\n+\n+#endif /* _HINIC_PMD_HWIF_H_ */\n",
    "prefixes": [
        "v4",
        "04/11"
    ]
}