get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 57848,
    "url": "http://patches.dpdk.org/api/patches/57848/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1566568031-45991-7-git-send-email-xavier.huwei@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": "<1566568031-45991-7-git-send-email-xavier.huwei@huawei.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1566568031-45991-7-git-send-email-xavier.huwei@huawei.com",
    "date": "2019-08-23T13:46:55",
    "name": "[06/22] net/hns3: add support for MAC address related operations",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "a0eba4bf87fcf936a06a65cdb0b1d81e4abd6d08",
    "submitter": {
        "id": 1405,
        "url": "http://patches.dpdk.org/api/people/1405/?format=api",
        "name": "Wei Hu (Xavier)",
        "email": "xavier.huwei@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/1566568031-45991-7-git-send-email-xavier.huwei@huawei.com/mbox/",
    "series": [
        {
            "id": 6114,
            "url": "http://patches.dpdk.org/api/series/6114/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=6114",
            "date": "2019-08-23T13:46:49",
            "name": "add hns3 ethernet PMD driver",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/6114/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/57848/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/57848/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 E58801BFE8;\n\tFri, 23 Aug 2019 15:49:53 +0200 (CEST)",
            "from huawei.com (szxga07-in.huawei.com [45.249.212.35])\n\tby dpdk.org (Postfix) with ESMTP id 8E8E01BFB4\n\tfor <dev@dpdk.org>; Fri, 23 Aug 2019 15:49:37 +0200 (CEST)",
            "from DGGEMS406-HUB.china.huawei.com (unknown [172.30.72.59])\n\tby Forcepoint Email with ESMTP id A9AE5A455EE509DFE151;\n\tFri, 23 Aug 2019 21:49:36 +0800 (CST)",
            "from localhost.localdomain (10.67.212.132) by\n\tDGGEMS406-HUB.china.huawei.com (10.3.19.206) with Microsoft SMTP\n\tServer id 14.3.439.0; Fri, 23 Aug 2019 21:49:26 +0800"
        ],
        "From": "\"Wei Hu (Xavier)\" <xavier.huwei@huawei.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<linuxarm@huawei.com>, <xavier_huwei@163.com>, <liudongdong3@huawei.com>,\n\t<forest.zhouchang@huawei.com>",
        "Date": "Fri, 23 Aug 2019 21:46:55 +0800",
        "Message-ID": "<1566568031-45991-7-git-send-email-xavier.huwei@huawei.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1566568031-45991-1-git-send-email-xavier.huwei@huawei.com>",
        "References": "<1566568031-45991-1-git-send-email-xavier.huwei@huawei.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.67.212.132]",
        "X-CFilter-Loop": "Reflected",
        "Subject": "[dpdk-dev] [PATCH 06/22] net/hns3: add support for MAC address\n\trelated operations",
        "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": "This patch adds the following mac address related operations defined in\nstruct eth_dev_ops: mac_addr_add, mac_addr_remove, mac_addr_set\nand set_mc_addr_list.\n\nSigned-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>\nSigned-off-by: Chunsong Feng <fengchunsong@huawei.com>\nSigned-off-by: Min Hu (Connor) <humin29@huawei.com>\nSigned-off-by: Hao Chen <chenhao164@huawei.com>\nSigned-off-by: Huisong Li <lihuisong@huawei.com>\n---\n drivers/net/hns3/hns3_ethdev.c | 816 +++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 816 insertions(+)",
    "diff": "diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c\nindex 3b5deb0..44e21ac 100644\n--- a/drivers/net/hns3/hns3_ethdev.c\n+++ b/drivers/net/hns3/hns3_ethdev.c\n@@ -152,6 +152,818 @@ hns3_uninit_umv_space(struct hns3_hw *hw)\n \treturn 0;\n }\n \n+static bool\n+hns3_is_umv_space_full(struct hns3_hw *hw)\n+{\n+\tstruct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);\n+\tstruct hns3_pf *pf = &hns->pf;\n+\tbool is_full;\n+\n+\tis_full = (pf->used_umv_size >= pf->max_umv_size);\n+\n+\treturn is_full;\n+}\n+\n+static void\n+hns3_update_umv_space(struct hns3_hw *hw, bool is_free)\n+{\n+\tstruct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);\n+\tstruct hns3_pf *pf = &hns->pf;\n+\n+\tif (is_free) {\n+\t\tif (pf->used_umv_size > 0)\n+\t\t\tpf->used_umv_size--;\n+\t} else\n+\t\tpf->used_umv_size++;\n+}\n+\n+static void\n+hns3_prepare_mac_addr(struct hns3_mac_vlan_tbl_entry_cmd *new_req,\n+\t\t      const uint8_t *addr, bool is_mc)\n+{\n+\tconst unsigned char *mac_addr = addr;\n+\tuint32_t high_val = ((uint32_t)mac_addr[3] << 24) |\n+\t\t\t    ((uint32_t)mac_addr[2] << 16) |\n+\t\t\t    ((uint32_t)mac_addr[1] << 8) |\n+\t\t\t    (uint32_t)mac_addr[0];\n+\tuint32_t low_val = ((uint32_t)mac_addr[5] << 8) | (uint32_t)mac_addr[4];\n+\n+\thns3_set_bit(new_req->flags, HNS3_MAC_VLAN_BIT0_EN_B, 1);\n+\tif (is_mc) {\n+\t\thns3_set_bit(new_req->entry_type, HNS3_MAC_VLAN_BIT0_EN_B, 0);\n+\t\thns3_set_bit(new_req->entry_type, HNS3_MAC_VLAN_BIT1_EN_B, 1);\n+\t\thns3_set_bit(new_req->mc_mac_en, HNS3_MAC_VLAN_BIT0_EN_B, 1);\n+\t}\n+\n+\tnew_req->mac_addr_hi32 = rte_cpu_to_le_32(high_val);\n+\tnew_req->mac_addr_lo16 = rte_cpu_to_le_16(low_val & 0xffff);\n+}\n+\n+static int\n+hns3_get_mac_vlan_cmd_status(struct hns3_hw *hw, uint16_t cmdq_resp,\n+\t\t\t     uint8_t resp_code,\n+\t\t\t     enum hns3_mac_vlan_tbl_opcode op)\n+{\n+\tif (cmdq_resp) {\n+\t\thns3_err(hw, \"cmdq execute failed for get_mac_vlan_cmd_status,status=%u\",\n+\t\t\t cmdq_resp);\n+\t\treturn -EIO;\n+\t}\n+\n+\tif (op == HNS3_MAC_VLAN_ADD) {\n+\t\tif (resp_code == 0 || resp_code == 1) {\n+\t\t\treturn 0;\n+\t\t} else if (resp_code == HNS3_ADD_UC_OVERFLOW) {\n+\t\t\thns3_err(hw, \"add mac addr failed for uc_overflow\");\n+\t\t\treturn -ENOSPC;\n+\t\t} else if (resp_code == HNS3_ADD_MC_OVERFLOW) {\n+\t\t\thns3_err(hw, \"add mac addr failed for mc_overflow\");\n+\t\t\treturn -ENOSPC;\n+\t\t}\n+\n+\t\thns3_err(hw, \"add mac addr failed for undefined, code=%u\",\n+\t\t\t resp_code);\n+\t\treturn -EIO;\n+\t} else if (op == HNS3_MAC_VLAN_REMOVE) {\n+\t\tif (resp_code == 0) {\n+\t\t\treturn 0;\n+\t\t} else if (resp_code == 1) {\n+\t\t\thns3_dbg(hw, \"remove mac addr failed for miss\");\n+\t\t\treturn -ENOENT;\n+\t\t}\n+\n+\t\thns3_err(hw, \"remove mac addr failed for undefined, code=%u\",\n+\t\t\t resp_code);\n+\t\treturn -EIO;\n+\t} else if (op == HNS3_MAC_VLAN_LKUP) {\n+\t\tif (resp_code == 0) {\n+\t\t\treturn 0;\n+\t\t} else if (resp_code == 1) {\n+\t\t\thns3_dbg(hw, \"lookup mac addr failed for miss\");\n+\t\t\treturn -ENOENT;\n+\t\t}\n+\n+\t\thns3_err(hw, \"lookup mac addr failed for undefined, code=%u\",\n+\t\t\t resp_code);\n+\t\treturn -EIO;\n+\t}\n+\n+\thns3_err(hw, \"unknown opcode for get_mac_vlan_cmd_status, opcode=%u\",\n+\t\t op);\n+\n+\treturn -EINVAL;\n+}\n+\n+static int\n+hns3_lookup_mac_vlan_tbl(struct hns3_hw *hw,\n+\t\t\t struct hns3_mac_vlan_tbl_entry_cmd *req,\n+\t\t\t struct hns3_cmd_desc *desc, bool is_mc)\n+{\n+\tuint8_t resp_code;\n+\tuint16_t retval;\n+\tint ret;\n+\n+\thns3_cmd_setup_basic_desc(&desc[0], HNS3_OPC_MAC_VLAN_ADD, true);\n+\tif (is_mc) {\n+\t\tdesc[0].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);\n+\t\tmemcpy(desc[0].data, req,\n+\t\t\t   sizeof(struct hns3_mac_vlan_tbl_entry_cmd));\n+\t\thns3_cmd_setup_basic_desc(&desc[1], HNS3_OPC_MAC_VLAN_ADD,\n+\t\t\t\t\t  true);\n+\t\tdesc[1].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);\n+\t\thns3_cmd_setup_basic_desc(&desc[2], HNS3_OPC_MAC_VLAN_ADD,\n+\t\t\t\t\t  true);\n+\t\tret = hns3_cmd_send(hw, desc, HNS3_MC_MAC_VLAN_ADD_DESC_NUM);\n+\t} else {\n+\t\tmemcpy(desc[0].data, req,\n+\t\t       sizeof(struct hns3_mac_vlan_tbl_entry_cmd));\n+\t\tret = hns3_cmd_send(hw, desc, 1);\n+\t}\n+\tif (ret) {\n+\t\thns3_err(hw, \"lookup mac addr failed for cmd_send, ret =%d.\",\n+\t\t\t ret);\n+\t\treturn ret;\n+\t}\n+\tresp_code = (rte_le_to_cpu_32(desc[0].data[0]) >> 8) & 0xff;\n+\tretval = rte_le_to_cpu_16(desc[0].retval);\n+\n+\treturn hns3_get_mac_vlan_cmd_status(hw, retval, resp_code,\n+\t\t\t\t\t    HNS3_MAC_VLAN_LKUP);\n+}\n+\n+static int\n+hns3_add_mac_vlan_tbl(struct hns3_hw *hw,\n+\t\t      struct hns3_mac_vlan_tbl_entry_cmd *req,\n+\t\t      struct hns3_cmd_desc *mc_desc)\n+{\n+\tuint8_t resp_code;\n+\tuint16_t retval;\n+\tint cfg_status;\n+\tint ret;\n+\n+\tif (mc_desc == NULL) {\n+\t\tstruct hns3_cmd_desc desc;\n+\n+\t\thns3_cmd_setup_basic_desc(&desc, HNS3_OPC_MAC_VLAN_ADD, false);\n+\t\tmemcpy(desc.data, req,\n+\t\t       sizeof(struct hns3_mac_vlan_tbl_entry_cmd));\n+\t\tret = hns3_cmd_send(hw, &desc, 1);\n+\t\tresp_code = (rte_le_to_cpu_32(desc.data[0]) >> 8) & 0xff;\n+\t\tretval = rte_le_to_cpu_16(desc.retval);\n+\n+\t\tcfg_status = hns3_get_mac_vlan_cmd_status(hw, retval, resp_code,\n+\t\t\t\t\t\t\t  HNS3_MAC_VLAN_ADD);\n+\t} else {\n+\t\thns3_cmd_reuse_desc(&mc_desc[0], false);\n+\t\tmc_desc[0].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);\n+\t\thns3_cmd_reuse_desc(&mc_desc[1], false);\n+\t\tmc_desc[1].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);\n+\t\thns3_cmd_reuse_desc(&mc_desc[2], false);\n+\t\tmc_desc[2].flag &= rte_cpu_to_le_16(~HNS3_CMD_FLAG_NEXT);\n+\t\tmemcpy(mc_desc[0].data, req,\n+\t\t       sizeof(struct hns3_mac_vlan_tbl_entry_cmd));\n+\t\tmc_desc[0].retval = 0;\n+\t\tret = hns3_cmd_send(hw, mc_desc, HNS3_MC_MAC_VLAN_ADD_DESC_NUM);\n+\t\tresp_code = (rte_le_to_cpu_32(mc_desc[0].data[0]) >> 8) & 0xff;\n+\t\tretval = rte_le_to_cpu_16(mc_desc[0].retval);\n+\n+\t\tcfg_status = hns3_get_mac_vlan_cmd_status(hw, retval, resp_code,\n+\t\t\t\t\t\t\t  HNS3_MAC_VLAN_ADD);\n+\t}\n+\n+\tif (ret) {\n+\t\thns3_err(hw, \"add mac addr failed for cmd_send, ret =%d\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\treturn cfg_status;\n+}\n+\n+static int\n+hns3_remove_mac_vlan_tbl(struct hns3_hw *hw,\n+\t\t\t struct hns3_mac_vlan_tbl_entry_cmd *req)\n+{\n+\tstruct hns3_cmd_desc desc;\n+\tuint8_t resp_code;\n+\tuint16_t retval;\n+\tint ret;\n+\n+\thns3_cmd_setup_basic_desc(&desc, HNS3_OPC_MAC_VLAN_REMOVE, false);\n+\n+\tmemcpy(desc.data, req, sizeof(struct hns3_mac_vlan_tbl_entry_cmd));\n+\n+\tret = hns3_cmd_send(hw, &desc, 1);\n+\tif (ret) {\n+\t\thns3_err(hw, \"del mac addr failed for cmd_send, ret =%d\", ret);\n+\t\treturn ret;\n+\t}\n+\tresp_code = (rte_le_to_cpu_32(desc.data[0]) >> 8) & 0xff;\n+\tretval = rte_le_to_cpu_16(desc.retval);\n+\n+\treturn hns3_get_mac_vlan_cmd_status(hw, retval, resp_code,\n+\t\t\t\t\t    HNS3_MAC_VLAN_REMOVE);\n+}\n+\n+static int\n+hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)\n+{\n+\tstruct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);\n+\tstruct hns3_mac_vlan_tbl_entry_cmd req;\n+\tstruct hns3_pf *pf = &hns->pf;\n+\tstruct hns3_cmd_desc desc;\n+\tchar mac_str[RTE_ETHER_ADDR_FMT_SIZE];\n+\tuint16_t egress_port = 0;\n+\tuint8_t vf_id;\n+\tint ret;\n+\n+\t/* check if mac addr is valid */\n+\tif (!rte_is_valid_assigned_ether_addr(mac_addr)) {\n+\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t      mac_addr);\n+\t\thns3_err(hw, \"Add unicast mac addr err! addr(%s) invalid\",\n+\t\t\t mac_str);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemset(&req, 0, sizeof(req));\n+\n+\t/*\n+\t * In current version VF is not supported when PF is taken over by DPDK,\n+\t * the PF-related vf_id is 0, just need to configure parameters for\n+\t * vf_id 0.\n+\t */\n+\tvf_id = 0;\n+\thns3_set_field(egress_port, HNS3_MAC_EPORT_VFID_M,\n+\t\t       HNS3_MAC_EPORT_VFID_S, vf_id);\n+\n+\treq.egress_port = rte_cpu_to_le_16(egress_port);\n+\n+\thns3_prepare_mac_addr(&req, mac_addr->addr_bytes, false);\n+\n+\t/*\n+\t * Lookup the mac address in the mac_vlan table, and add\n+\t * it if the entry is inexistent. Repeated unicast entry\n+\t * is not allowed in the mac vlan table.\n+\t */\n+\tret = hns3_lookup_mac_vlan_tbl(hw, &req, &desc, false);\n+\tif (ret == -ENOENT) {\n+\t\tif (!hns3_is_umv_space_full(hw)) {\n+\t\t\tret = hns3_add_mac_vlan_tbl(hw, &req, NULL);\n+\t\t\tif (!ret)\n+\t\t\t\thns3_update_umv_space(hw, false);\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\thns3_err(hw, \"UC MAC table full(%u)\", pf->used_umv_size);\n+\n+\t\treturn -ENOSPC;\n+\t}\n+\n+\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, mac_addr);\n+\n+\t/* check if we just hit the duplicate */\n+\tif (ret == 0) {\n+\t\thns3_dbg(hw, \"mac addr(%s) has been in the MAC table\", mac_str);\n+\t\treturn 0;\n+\t}\n+\n+\thns3_err(hw, \"PF failed to add unicast entry(%s) in the MAC table\",\n+\t\t mac_str);\n+\n+\treturn ret;\n+}\n+\n+static int\n+hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,\n+\t\t  uint32_t idx, __attribute__ ((unused)) uint32_t pool)\n+{\n+\tstruct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tchar mac_str[RTE_ETHER_ADDR_FMT_SIZE];\n+\tint ret;\n+\n+\trte_spinlock_lock(&hw->lock);\n+\tret = hns3_add_uc_addr_common(hw, mac_addr);\n+\tif (ret) {\n+\t\trte_spinlock_unlock(&hw->lock);\n+\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t      mac_addr);\n+\t\thns3_err(hw, \"Failed to add mac addr(%s): %d\", mac_str, ret);\n+\t\treturn ret;\n+\t}\n+\n+\tif (idx == 0)\n+\t\thw->mac.default_addr_setted = true;\n+\trte_spinlock_unlock(&hw->lock);\n+\n+\treturn ret;\n+}\n+\n+static int\n+hns3_remove_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)\n+{\n+\tstruct hns3_mac_vlan_tbl_entry_cmd req;\n+\tchar mac_str[RTE_ETHER_ADDR_FMT_SIZE];\n+\tint ret;\n+\n+\t/* check if mac addr is valid */\n+\tif (!rte_is_valid_assigned_ether_addr(mac_addr)) {\n+\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t      mac_addr);\n+\t\thns3_err(hw, \"Remove unicast mac addr err! addr(%s) invalid\",\n+\t\t\t mac_str);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemset(&req, 0, sizeof(req));\n+\thns3_set_bit(req.entry_type, HNS3_MAC_VLAN_BIT0_EN_B, 0);\n+\thns3_prepare_mac_addr(&req, mac_addr->addr_bytes, false);\n+\tret = hns3_remove_mac_vlan_tbl(hw, &req);\n+\tif (ret == -ENOENT) /* mac addr isn't existent in the mac vlan table. */\n+\t\treturn 0;\n+\telse if (ret == 0)\n+\t\thns3_update_umv_space(hw, true);\n+\n+\treturn ret;\n+}\n+\n+static void\n+hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)\n+{\n+\tstruct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\t/* index will be checked by upper level rte interface */\n+\tstruct rte_ether_addr *mac_addr = &dev->data->mac_addrs[idx];\n+\tchar mac_str[RTE_ETHER_ADDR_FMT_SIZE];\n+\tint ret;\n+\n+\trte_spinlock_lock(&hw->lock);\n+\tret = hns3_remove_uc_addr_common(hw, mac_addr);\n+\tif (ret) {\n+\t\trte_spinlock_unlock(&hw->lock);\n+\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t      mac_addr);\n+\t\thns3_err(hw, \"Failed to remove mac addr(%s): %d\", mac_str, ret);\n+\t\treturn;\n+\t}\n+\n+\tif (idx == 0)\n+\t\thw->mac.default_addr_setted = false;\n+\trte_spinlock_unlock(&hw->lock);\n+}\n+\n+static int\n+hns3_set_default_mac_addr(struct rte_eth_dev *dev,\n+\t\t\t  struct rte_ether_addr *mac_addr)\n+{\n+\tstruct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct rte_ether_addr *oaddr;\n+\tchar mac_str[RTE_ETHER_ADDR_FMT_SIZE];\n+\tbool default_addr_setted;\n+\tbool rm_succes = false;\n+\tint ret, ret_val;\n+\n+\t/* check if mac addr is valid */\n+\tif (!rte_is_valid_assigned_ether_addr(mac_addr)) {\n+\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t      mac_addr);\n+\t\thns3_err(hw, \"Failed to set mac addr, addr(%s) invalid\",\n+\t\t\t mac_str);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\toaddr = (struct rte_ether_addr *)hw->mac.mac_addr;\n+\tdefault_addr_setted = hw->mac.default_addr_setted;\n+\tif (default_addr_setted && !!rte_is_same_ether_addr(mac_addr, oaddr))\n+\t\treturn 0;\n+\n+\trte_spinlock_lock(&hw->lock);\n+\tif (default_addr_setted) {\n+\t\tret = hns3_remove_uc_addr_common(hw, oaddr);\n+\t\tif (ret) {\n+\t\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t\t      oaddr);\n+\t\t\thns3_warn(hw, \"Remove old uc mac address(%s) fail: %d\",\n+\t\t\t\t  mac_str, ret);\n+\t\t\trm_succes = false;\n+\t\t} else\n+\t\t\trm_succes = true;\n+\t}\n+\n+\tret = hns3_add_uc_addr_common(hw, mac_addr);\n+\tif (ret) {\n+\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t      mac_addr);\n+\t\thns3_err(hw, \"Failed to set mac addr(%s): %d\", mac_str, ret);\n+\t\tgoto err_add_uc_addr;\n+\t}\n+\n+\tret = hns3_pause_addr_cfg(hw, mac_addr->addr_bytes);\n+\tif (ret) {\n+\t\thns3_err(hw, \"Failed to configure mac pause address: %d\", ret);\n+\t\tgoto err_pause_addr_cfg;\n+\t}\n+\n+\trte_ether_addr_copy(mac_addr,\n+\t\t\t    (struct rte_ether_addr *)hw->mac.mac_addr);\n+\thw->mac.default_addr_setted = true;\n+\trte_spinlock_unlock(&hw->lock);\n+\n+\treturn 0;\n+\n+err_pause_addr_cfg:\n+\tret_val = hns3_remove_uc_addr_common(hw, mac_addr);\n+\tif (ret_val) {\n+\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t      mac_addr);\n+\t\thns3_warn(hw,\n+\t\t\t  \"Failed to roll back to del setted mac addr(%s): %d\",\n+\t\t\t  mac_str, ret_val);\n+\t}\n+\n+err_add_uc_addr:\n+\tif (rm_succes) {\n+\t\tret_val = hns3_add_uc_addr_common(hw, oaddr);\n+\t\tif (ret_val) {\n+\t\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t\t      oaddr);\n+\t\t\thns3_warn(hw,\n+\t\t\t\t  \"Failed to restore old uc mac addr(%s): %d\",\n+\t\t\t\t  mac_str, ret_val);\n+\t\t\thw->mac.default_addr_setted = false;\n+\t\t}\n+\t}\n+\trte_spinlock_unlock(&hw->lock);\n+\n+\treturn ret;\n+}\n+\n+static int\n+hns3_configure_all_mac_addr(struct hns3_adapter *hns, bool del)\n+{\n+\tchar mac_str[RTE_ETHER_ADDR_FMT_SIZE];\n+\tstruct hns3_hw *hw = &hns->hw;\n+\tstruct rte_ether_addr *addr;\n+\tint err = 0;\n+\tint ret;\n+\tint i;\n+\n+\tfor (i = 0; i < HNS3_UC_MACADDR_NUM; i++) {\n+\t\taddr = &hw->data->mac_addrs[i];\n+\t\tif (!rte_is_valid_assigned_ether_addr(addr))\n+\t\t\tcontinue;\n+\t\tif (del)\n+\t\t\tret = hns3_remove_uc_addr_common(hw, addr);\n+\t\telse\n+\t\t\tret = hns3_add_uc_addr_common(hw, addr);\n+\t\tif (ret) {\n+\t\t\terr = ret;\n+\t\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t\t      addr);\n+\t\t\thns3_dbg(hw,\n+\t\t\t\t \"Failed to %s mac addr(%s). ret:%d i:%d\",\n+\t\t\t\t del ? \"remove\" : \"restore\", mac_str, ret, i);\n+\t\t}\n+\t}\n+\treturn err;\n+}\n+\n+static void\n+hns3_update_desc_vfid(struct hns3_cmd_desc *desc, uint8_t vfid, bool clr)\n+{\n+#define HNS3_VF_NUM_IN_FIRST_DESC 192\n+\tuint8_t word_num;\n+\tuint8_t bit_num;\n+\n+\tif (vfid < HNS3_VF_NUM_IN_FIRST_DESC) {\n+\t\tword_num = vfid / 32;\n+\t\tbit_num = vfid % 32;\n+\t\tif (clr)\n+\t\t\tdesc[1].data[word_num] &=\n+\t\t\t    rte_cpu_to_le_32(~(1UL << bit_num));\n+\t\telse\n+\t\t\tdesc[1].data[word_num] |=\n+\t\t\t    rte_cpu_to_le_32(1UL << bit_num);\n+\t} else {\n+\t\tword_num = (vfid - HNS3_VF_NUM_IN_FIRST_DESC) / 32;\n+\t\tbit_num = vfid % 32;\n+\t\tif (clr)\n+\t\t\tdesc[2].data[word_num] &=\n+\t\t\t    rte_cpu_to_le_32(~(1UL << bit_num));\n+\t\telse\n+\t\t\tdesc[2].data[word_num] |=\n+\t\t\t    rte_cpu_to_le_32(1UL << bit_num);\n+\t}\n+}\n+\n+static int\n+hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)\n+{\n+\tstruct hns3_mac_vlan_tbl_entry_cmd req;\n+\tstruct hns3_cmd_desc desc[3];\n+\tchar mac_str[RTE_ETHER_ADDR_FMT_SIZE];\n+\tuint8_t vf_id;\n+\tint ret;\n+\n+\t/* Check if mac addr is valid */\n+\tif (!rte_is_multicast_ether_addr(mac_addr)) {\n+\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t      mac_addr);\n+\t\thns3_err(hw, \"Failed to add mc mac addr, addr(%s) invalid\",\n+\t\t\t mac_str);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemset(&req, 0, sizeof(req));\n+\thns3_set_bit(req.entry_type, HNS3_MAC_VLAN_BIT0_EN_B, 0);\n+\thns3_prepare_mac_addr(&req, mac_addr->addr_bytes, true);\n+\tret = hns3_lookup_mac_vlan_tbl(hw, &req, desc, true);\n+\tif (ret) {\n+\t\t/* This mac addr do not exist, add new entry for it */\n+\t\tmemset(desc[0].data, 0, sizeof(desc[0].data));\n+\t\tmemset(desc[1].data, 0, sizeof(desc[0].data));\n+\t\tmemset(desc[2].data, 0, sizeof(desc[0].data));\n+\t}\n+\n+\t/*\n+\t * In current version VF is not supported when PF is taken over by DPDK,\n+\t * the PF-related vf_id is 0, just need to configure parameters for\n+\t * vf_id 0.\n+\t */\n+\tvf_id = 0;\n+\thns3_update_desc_vfid(desc, vf_id, false);\n+\tret = hns3_add_mac_vlan_tbl(hw, &req, desc);\n+\tif (ret) {\n+\t\tif (ret == -ENOSPC)\n+\t\t\thns3_err(hw, \"mc mac vlan table is full\");\n+\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t      mac_addr);\n+\t\thns3_err(hw, \"Failed to add mc mac addr(%s): %d\", mac_str, ret);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static int\n+hns3_remove_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)\n+{\n+\tstruct hns3_mac_vlan_tbl_entry_cmd req;\n+\tstruct hns3_cmd_desc desc[3];\n+\tchar mac_str[RTE_ETHER_ADDR_FMT_SIZE];\n+\tuint8_t vf_id;\n+\tint ret;\n+\n+\t/* Check if mac addr is valid */\n+\tif (!rte_is_multicast_ether_addr(mac_addr)) {\n+\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t      mac_addr);\n+\t\thns3_err(hw, \"Failed to rm mc mac addr, addr(%s) invalid\",\n+\t\t\t mac_str);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemset(&req, 0, sizeof(req));\n+\thns3_set_bit(req.entry_type, HNS3_MAC_VLAN_BIT0_EN_B, 0);\n+\thns3_prepare_mac_addr(&req, mac_addr->addr_bytes, true);\n+\tret = hns3_lookup_mac_vlan_tbl(hw, &req, desc, true);\n+\tif (ret == 0) {\n+\t\t/*\n+\t\t * This mac addr exist, remove this handle's VFID for it.\n+\t\t * In current version VF is not supported when PF is taken over\n+\t\t * by DPDK, the PF-related vf_id is 0, just need to configure\n+\t\t * parameters for vf_id 0.\n+\t\t */\n+\t\tvf_id = 0;\n+\t\thns3_update_desc_vfid(desc, vf_id, true);\n+\n+\t\t/* All the vfid is zero, so need to delete this entry */\n+\t\tret = hns3_remove_mac_vlan_tbl(hw, &req);\n+\t} else if (ret == -ENOENT) {\n+\t\t/* This mac addr doesn't exist. */\n+\t\treturn 0;\n+\t}\n+\n+\tif (ret) {\n+\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t      mac_addr);\n+\t\thns3_err(hw, \"Failed to rm mc mac addr(%s): %d\", mac_str, ret);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static int\n+hns3_set_mc_addr_chk_param(struct hns3_hw *hw,\n+\t\t\t   struct rte_ether_addr *mc_addr_set,\n+\t\t\t   uint32_t nb_mc_addr)\n+{\n+\tchar mac_str[RTE_ETHER_ADDR_FMT_SIZE];\n+\tstruct rte_ether_addr *addr;\n+\tuint32_t i;\n+\tuint32_t j;\n+\n+\tif (nb_mc_addr > HNS3_MC_MACADDR_NUM) {\n+\t\thns3_err(hw, \"Failed to set mc mac addr, nb_mc_addr(%d) \"\n+\t\t\t \"invalid. valid range: 0~%d\",\n+\t\t\t nb_mc_addr, HNS3_MC_MACADDR_NUM);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Check if input mac addresses are valid */\n+\tfor (i = 0; i < nb_mc_addr; i++) {\n+\t\taddr = &mc_addr_set[i];\n+\t\tif (!rte_is_multicast_ether_addr(addr)) {\n+\t\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t\t      addr);\n+\t\t\thns3_err(hw,\n+\t\t\t\t \"Failed to set mc mac addr, addr(%s) invalid.\",\n+\t\t\t\t mac_str);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\t/* Check if there are duplicate addresses */\n+\t\tfor (j = i + 1; j < nb_mc_addr; j++) {\n+\t\t\tif (rte_is_same_ether_addr(addr, &mc_addr_set[j])) {\n+\t\t\t\trte_ether_format_addr(mac_str,\n+\t\t\t\t\t\t      RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t\t\t      addr);\n+\t\t\t\thns3_err(hw, \"Failed to set mc mac addr, \"\n+\t\t\t\t\t \"addrs invalid. two same addrs(%s).\",\n+\t\t\t\t\t mac_str);\n+\t\t\t\treturn -EINVAL;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void\n+hns3_set_mc_addr_calc_addr(struct hns3_hw *hw,\n+\t\t\t   struct rte_ether_addr *mc_addr_set,\n+\t\t\t   int mc_addr_num,\n+\t\t\t   struct rte_ether_addr *reserved_addr_list,\n+\t\t\t   int *reserved_addr_num,\n+\t\t\t   struct rte_ether_addr *add_addr_list,\n+\t\t\t   int *add_addr_num,\n+\t\t\t   struct rte_ether_addr *rm_addr_list,\n+\t\t\t   int *rm_addr_num)\n+{\n+\tstruct rte_ether_addr *addr;\n+\tint current_addr_num;\n+\tint reserved_num = 0;\n+\tint add_num = 0;\n+\tint rm_num = 0;\n+\tint num;\n+\tint i;\n+\tint j;\n+\tbool same_addr;\n+\n+\t/* Calculate the mc mac address list that should be removed */\n+\tcurrent_addr_num = hw->mc_addrs_num;\n+\tfor (i = 0; i < current_addr_num; i++) {\n+\t\taddr = &hw->mc_addrs[i];\n+\t\tsame_addr = false;\n+\t\tfor (j = 0; j < mc_addr_num; j++) {\n+\t\t\tif (rte_is_same_ether_addr(addr, &mc_addr_set[j])) {\n+\t\t\t\tsame_addr = true;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (!same_addr) {\n+\t\t\trte_ether_addr_copy(addr, &rm_addr_list[rm_num]);\n+\t\t\trm_num++;\n+\t\t} else {\n+\t\t\trte_ether_addr_copy(addr,\n+\t\t\t\t\t    &reserved_addr_list[reserved_num]);\n+\t\t\treserved_num++;\n+\t\t}\n+\t}\n+\n+\t/* Calculate the mc mac address list that should be added */\n+\tfor (i = 0; i < mc_addr_num; i++) {\n+\t\taddr = &mc_addr_set[i];\n+\t\tsame_addr = false;\n+\t\tfor (j = 0; j < current_addr_num; j++) {\n+\t\t\tif (rte_is_same_ether_addr(addr, &hw->mc_addrs[j])) {\n+\t\t\t\tsame_addr = true;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (!same_addr) {\n+\t\t\trte_ether_addr_copy(addr, &add_addr_list[add_num]);\n+\t\t\tadd_num++;\n+\t\t}\n+\t}\n+\n+\t/* Reorder the mc mac address list maintained by driver */\n+\tfor (i = 0; i < reserved_num; i++)\n+\t\trte_ether_addr_copy(&reserved_addr_list[i], &hw->mc_addrs[i]);\n+\n+\tfor (i = 0; i < rm_num; i++) {\n+\t\tnum = reserved_num + i;\n+\t\trte_ether_addr_copy(&rm_addr_list[i], &hw->mc_addrs[num]);\n+\t}\n+\n+\t*reserved_addr_num = reserved_num;\n+\t*add_addr_num = add_num;\n+\t*rm_addr_num = rm_num;\n+}\n+\n+static int\n+hns3_set_mc_mac_addr_list(struct rte_eth_dev *dev,\n+\t\t\t  struct rte_ether_addr *mc_addr_set,\n+\t\t\t  uint32_t nb_mc_addr)\n+{\n+\tstruct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct rte_ether_addr reserved_addr_list[HNS3_MC_MACADDR_NUM];\n+\tstruct rte_ether_addr add_addr_list[HNS3_MC_MACADDR_NUM];\n+\tstruct rte_ether_addr rm_addr_list[HNS3_MC_MACADDR_NUM];\n+\tstruct rte_ether_addr *addr;\n+\tint reserved_addr_num;\n+\tint add_addr_num;\n+\tint rm_addr_num;\n+\tint mc_addr_num;\n+\tint num;\n+\tint ret;\n+\tint i;\n+\n+\t/* Check if input parameters are valid */\n+\tret = hns3_set_mc_addr_chk_param(hw, mc_addr_set, nb_mc_addr);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\trte_spinlock_lock(&hw->lock);\n+\n+\t/*\n+\t * Calculate the mc mac address lists those should be removed and be\n+\t * added, Reorder the mc mac address list maintained by driver.\n+\t */\n+\tmc_addr_num = (int)nb_mc_addr;\n+\thns3_set_mc_addr_calc_addr(hw, mc_addr_set, mc_addr_num,\n+\t\t\t\t   reserved_addr_list, &reserved_addr_num,\n+\t\t\t\t   add_addr_list, &add_addr_num,\n+\t\t\t\t   rm_addr_list, &rm_addr_num);\n+\n+\t/* Remove mc mac addresses */\n+\tfor (i = 0; i < rm_addr_num; i++) {\n+\t\tnum = rm_addr_num - i - 1;\n+\t\taddr = &rm_addr_list[num];\n+\t\tret = hns3_remove_mc_addr(hw, addr);\n+\t\tif (ret) {\n+\t\t\trte_spinlock_unlock(&hw->lock);\n+\t\t\treturn ret;\n+\t\t}\n+\t\thw->mc_addrs_num--;\n+\t}\n+\n+\t/* Add mc mac addresses */\n+\tfor (i = 0; i < add_addr_num; i++) {\n+\t\taddr = &add_addr_list[i];\n+\t\tret = hns3_add_mc_addr(hw, addr);\n+\t\tif (ret) {\n+\t\t\trte_spinlock_unlock(&hw->lock);\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tnum = reserved_addr_num + i;\n+\t\trte_ether_addr_copy(addr, &hw->mc_addrs[num]);\n+\t\thw->mc_addrs_num++;\n+\t}\n+\trte_spinlock_unlock(&hw->lock);\n+\n+\treturn 0;\n+}\n+\n+static int\n+hns3_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del)\n+{\n+\tchar mac_str[RTE_ETHER_ADDR_FMT_SIZE];\n+\tstruct hns3_hw *hw = &hns->hw;\n+\tstruct rte_ether_addr *addr;\n+\tint err = 0;\n+\tint ret;\n+\tint i;\n+\n+\tfor (i = 0; i < hw->mc_addrs_num; i++) {\n+\t\taddr = &hw->mc_addrs[i];\n+\t\tif (!rte_is_multicast_ether_addr(addr))\n+\t\t\tcontinue;\n+\t\tif (del)\n+\t\t\tret = hns3_remove_mc_addr(hw, addr);\n+\t\telse\n+\t\t\tret = hns3_add_mc_addr(hw, addr);\n+\t\tif (ret) {\n+\t\t\terr = ret;\n+\t\t\trte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,\n+\t\t\t\t\t      addr);\n+\t\t\thns3_dbg(hw, \"%s mc mac addr: %s failed\",\n+\t\t\t\t del ? \"Remove\" : \"Restore\", mac_str);\n+\t\t}\n+\t}\n+\treturn err;\n+}\n+\n static int\n hns3_set_mac_mtu(struct hns3_hw *hw, uint16_t new_mps)\n {\n@@ -1582,6 +2394,10 @@ hns3_dev_close(struct rte_eth_dev *eth_dev)\n \n static const struct eth_dev_ops hns3_eth_dev_ops = {\n \t.dev_close          = hns3_dev_close,\n+\t.mac_addr_add           = hns3_add_mac_addr,\n+\t.mac_addr_remove        = hns3_remove_mac_addr,\n+\t.mac_addr_set           = hns3_set_default_mac_addr,\n+\t.set_mc_addr_list       = hns3_set_mc_mac_addr_list,\n };\n \n static int\n",
    "prefixes": [
        "06/22"
    ]
}