get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 87059,
    "url": "https://patches.dpdk.org/api/patches/87059/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20210122094800.197748-4-jiawenwu@trustnetic.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20210122094800.197748-4-jiawenwu@trustnetic.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210122094800.197748-4-jiawenwu@trustnetic.com",
    "date": "2021-01-22T09:47:43",
    "name": "[v1,03/20] net/txgbe: support add and remove VF device MAC address",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "72c035befc9545d55fcf944fb6515f253529d065",
    "submitter": {
        "id": 1932,
        "url": "https://patches.dpdk.org/api/people/1932/?format=api",
        "name": "Jiawen Wu",
        "email": "jiawenwu@trustnetic.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20210122094800.197748-4-jiawenwu@trustnetic.com/mbox/",
    "series": [
        {
            "id": 14902,
            "url": "https://patches.dpdk.org/api/series/14902/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=14902",
            "date": "2021-01-22T09:47:41",
            "name": "net/txgbe: add VF driver support",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/14902/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/87059/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/87059/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 8B152A0A0A;\n\tFri, 22 Jan 2021 10:48:09 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id BDF7C140E38;\n\tFri, 22 Jan 2021 10:48:03 +0100 (CET)",
            "from smtpbgeu1.qq.com (smtpbgeu1.qq.com [52.59.177.22])\n by mails.dpdk.org (Postfix) with ESMTP id 282A8140E27\n for <dev@dpdk.org>; Fri, 22 Jan 2021 10:48:01 +0100 (CET)",
            "from wxdbg.localdomain.com (unknown [183.129.236.74])\n by esmtp6.qq.com (ESMTP) with\n id ; Fri, 22 Jan 2021 17:47:56 +0800 (CST)"
        ],
        "X-QQ-mid": "bizesmtp9t1611308877t5rx54zdf",
        "X-QQ-SSF": "01400000002000C0D000B00A0000000",
        "X-QQ-FEAT": "iV2IPzHxhZmuPOMuKmh3BDssVy4eqS3ijMkjqbrx5OYCEPZtEndqBT1uAMZ2l\n bpNFfMomKh7NFROZPhByTpeA03zteavFVmdhKs7Ft+9ACXzT8lp9a3aaD2+V6+ikmaYdBdC\n vi+dOmvxsL48LZlc14JvRNZRCKfq/BiH8gVGd55CgAujA91+xU6mRaqdy0KV5ORSetuclin\n beZD6SMnZgGTUJnfEmPd5AcrRpSiIl536tArgjdlvsPQyEEhOLUZkRSiFJ0tOL1c0dfGZt3\n 6XyWn37ayFlAR7gZLBbes0HKLRB+5YjD94XqcjlZTNk3dFcpmz66MhxykRUNQufTAl4fF5+\n Eg69C2z82HSk3mj+6T5vsN6GCvDVQ==",
        "X-QQ-GoodBg": "2",
        "From": "Jiawen Wu <jiawenwu@trustnetic.com>",
        "To": "dev@dpdk.org",
        "Cc": "Jiawen Wu <jiawenwu@trustnetic.com>",
        "Date": "Fri, 22 Jan 2021 17:47:43 +0800",
        "Message-Id": "<20210122094800.197748-4-jiawenwu@trustnetic.com>",
        "X-Mailer": "git-send-email 2.27.0",
        "In-Reply-To": "<20210122094800.197748-1-jiawenwu@trustnetic.com>",
        "References": "<20210122094800.197748-1-jiawenwu@trustnetic.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-QQ-SENDSIZE": "520",
        "Feedback-ID": "bizesmtp:trustnetic.com:qybgforeign:qybgforeign5",
        "X-QQ-Bgrelay": "1",
        "Subject": "[dpdk-dev] [PATCH v1 03/20] net/txgbe: support add and remove VF\n device MAC address",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Generate a random MAC address if none was assigned by PF during\nthe initialization of VF device. And support to add and remove\nMAC address.\n\nSigned-off-by: Jiawen Wu <jiawenwu@trustnetic.com>\n---\n drivers/net/txgbe/base/txgbe_vf.c   | 102 +++++++++++++++++\n drivers/net/txgbe/base/txgbe_vf.h   |   5 +\n drivers/net/txgbe/txgbe_ethdev_vf.c | 168 ++++++++++++++++++++++++++++\n 3 files changed, 275 insertions(+)",
    "diff": "diff --git a/drivers/net/txgbe/base/txgbe_vf.c b/drivers/net/txgbe/base/txgbe_vf.c\nindex 30bc0e40d..bcd34bfa2 100644\n--- a/drivers/net/txgbe/base/txgbe_vf.c\n+++ b/drivers/net/txgbe/base/txgbe_vf.c\n@@ -21,9 +21,16 @@ s32 txgbe_init_ops_vf(struct txgbe_hw *hw)\n \n \t/* MAC */\n \tmac->reset_hw = txgbe_reset_hw_vf;\n+\tmac->start_hw = txgbe_start_hw_vf;\n+\t/* Cannot clear stats on VF */\n+\tmac->get_mac_addr = txgbe_get_mac_addr_vf;\n \tmac->stop_hw = txgbe_stop_hw_vf;\n \tmac->negotiate_api_version = txgbevf_negotiate_api_version;\n \n+\t/* RAR, Multicast, VLAN */\n+\tmac->set_rar = txgbe_set_rar_vf;\n+\tmac->set_uc_addr = txgbevf_set_uc_addr_vf;\n+\n \tmac->max_tx_queues = 1;\n \tmac->max_rx_queues = 1;\n \n@@ -60,6 +67,23 @@ static void txgbe_virt_clr_reg(struct txgbe_hw *hw)\n \ttxgbe_flush(hw);\n }\n \n+/**\n+ *  txgbe_start_hw_vf - Prepare hardware for Tx/Rx\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Starts the hardware by filling the bus info structure and media type, clears\n+ *  all on chip counters, initializes receive address registers, multicast\n+ *  table, VLAN filter table, calls routine to set up link and flow control\n+ *  settings, and leaves transmit and receive units disabled and uninitialized\n+ **/\n+s32 txgbe_start_hw_vf(struct txgbe_hw *hw)\n+{\n+\t/* Clear adapter stopped flag */\n+\thw->adapter_stopped = false;\n+\n+\treturn 0;\n+}\n+\n /**\n  *  txgbe_reset_hw_vf - Performs hardware reset\n  *  @hw: pointer to hardware structure\n@@ -195,6 +219,84 @@ STATIC s32 txgbevf_write_msg_read_ack(struct txgbe_hw *hw, u32 *msg,\n \treturn mbx->read_posted(hw, retmsg, size, 0);\n }\n \n+/**\n+ *  txgbe_set_rar_vf - set device MAC address\n+ *  @hw: pointer to hardware structure\n+ *  @index: Receive address register to write\n+ *  @addr: Address to put into receive address register\n+ *  @vmdq: VMDq \"set\" or \"pool\" index\n+ *  @enable_addr: set flag that address is active\n+ **/\n+s32 txgbe_set_rar_vf(struct txgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,\n+\t\t     u32 enable_addr)\n+{\n+\tu32 msgbuf[3];\n+\tu8 *msg_addr = (u8 *)(&msgbuf[1]);\n+\ts32 ret_val;\n+\tUNREFERENCED_PARAMETER(vmdq, enable_addr, index);\n+\n+\tmemset(msgbuf, 0, 12);\n+\tmsgbuf[0] = TXGBE_VF_SET_MAC_ADDR;\n+\tmemcpy(msg_addr, addr, 6);\n+\tret_val = txgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 3);\n+\n+\tmsgbuf[0] &= ~TXGBE_VT_MSGTYPE_CTS;\n+\n+\t/* if nacked the address was rejected, use \"perm_addr\" */\n+\tif (!ret_val &&\n+\t    (msgbuf[0] == (TXGBE_VF_SET_MAC_ADDR | TXGBE_VT_MSGTYPE_NACK))) {\n+\t\ttxgbe_get_mac_addr_vf(hw, hw->mac.addr);\n+\t\treturn TXGBE_ERR_MBX;\n+\t}\n+\n+\treturn ret_val;\n+}\n+\n+/**\n+ * txgbe_get_mac_addr_vf - Read device MAC address\n+ * @hw: pointer to the HW structure\n+ * @mac_addr: the MAC address\n+ **/\n+s32 txgbe_get_mac_addr_vf(struct txgbe_hw *hw, u8 *mac_addr)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < ETH_ADDR_LEN; i++)\n+\t\tmac_addr[i] = hw->mac.perm_addr[i];\n+\n+\treturn 0;\n+}\n+\n+s32 txgbevf_set_uc_addr_vf(struct txgbe_hw *hw, u32 index, u8 *addr)\n+{\n+\tu32 msgbuf[3], msgbuf_chk;\n+\tu8 *msg_addr = (u8 *)(&msgbuf[1]);\n+\ts32 ret_val;\n+\n+\tmemset(msgbuf, 0, sizeof(msgbuf));\n+\t/*\n+\t * If index is one then this is the start of a new list and needs\n+\t * indication to the PF so it can do it's own list management.\n+\t * If it is zero then that tells the PF to just clear all of\n+\t * this VF's macvlans and there is no new list.\n+\t */\n+\tmsgbuf[0] |= index << TXGBE_VT_MSGINFO_SHIFT;\n+\tmsgbuf[0] |= TXGBE_VF_SET_MACVLAN;\n+\tmsgbuf_chk = msgbuf[0];\n+\tif (addr)\n+\t\tmemcpy(msg_addr, addr, 6);\n+\n+\tret_val = txgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 3);\n+\tif (!ret_val) {\n+\t\tmsgbuf[0] &= ~TXGBE_VT_MSGTYPE_CTS;\n+\n+\t\tif (msgbuf[0] == (msgbuf_chk | TXGBE_VT_MSGTYPE_NACK))\n+\t\t\treturn TXGBE_ERR_OUT_OF_MEM;\n+\t}\n+\n+\treturn ret_val;\n+}\n+\n /**\n  *  txgbevf_negotiate_api_version - Negotiate supported API version\n  *  @hw: pointer to the HW structure\ndiff --git a/drivers/net/txgbe/base/txgbe_vf.h b/drivers/net/txgbe/base/txgbe_vf.h\nindex 70f90c262..f8c6532f6 100644\n--- a/drivers/net/txgbe/base/txgbe_vf.h\n+++ b/drivers/net/txgbe/base/txgbe_vf.h\n@@ -11,8 +11,13 @@\n #define TXGBE_VF_MAX_RX_QUEUES\t8\n \n s32 txgbe_init_ops_vf(struct txgbe_hw *hw);\n+s32 txgbe_start_hw_vf(struct txgbe_hw *hw);\n s32 txgbe_reset_hw_vf(struct txgbe_hw *hw);\n s32 txgbe_stop_hw_vf(struct txgbe_hw *hw);\n+s32 txgbe_get_mac_addr_vf(struct txgbe_hw *hw, u8 *mac_addr);\n+s32 txgbe_set_rar_vf(struct txgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,\n+\t\t     u32 enable_addr);\n+s32 txgbevf_set_uc_addr_vf(struct txgbe_hw *hw, u32 index, u8 *addr);\n int txgbevf_negotiate_api_version(struct txgbe_hw *hw, int api);\n int txgbevf_get_queues(struct txgbe_hw *hw, unsigned int *num_tcs,\n \t\t       unsigned int *default_tc);\ndiff --git a/drivers/net/txgbe/txgbe_ethdev_vf.c b/drivers/net/txgbe/txgbe_ethdev_vf.c\nindex a6bead4d1..62b1568cb 100644\n--- a/drivers/net/txgbe/txgbe_ethdev_vf.c\n+++ b/drivers/net/txgbe/txgbe_ethdev_vf.c\n@@ -19,6 +19,7 @@\n static int txgbevf_dev_close(struct rte_eth_dev *dev);\n static void txgbevf_intr_disable(struct rte_eth_dev *dev);\n static void txgbevf_intr_enable(struct rte_eth_dev *dev);\n+static void txgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);\n \n /*\n  * The set of PCI devices this driver supports (for VF)\n@@ -57,6 +58,22 @@ txgbevf_negotiate_api(struct txgbe_hw *hw)\n \t}\n }\n \n+static void\n+generate_random_mac_addr(struct rte_ether_addr *mac_addr)\n+{\n+\tuint64_t random;\n+\n+\t/* Set Organizationally Unique Identifier (OUI) prefix. */\n+\tmac_addr->addr_bytes[0] = 0x00;\n+\tmac_addr->addr_bytes[1] = 0x09;\n+\tmac_addr->addr_bytes[2] = 0xC0;\n+\t/* Force indication of locally assigned MAC address. */\n+\tmac_addr->addr_bytes[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;\n+\t/* Generate the last 3 bytes of the MAC address with a random number. */\n+\trandom = rte_rand();\n+\tmemcpy(&mac_addr->addr_bytes[3], &random, 3);\n+}\n+\n /*\n  * Virtual Function device init\n  */\n@@ -67,6 +84,8 @@ eth_txgbevf_dev_init(struct rte_eth_dev *eth_dev)\n \tuint32_t tc, tcs;\n \tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);\n \tstruct txgbe_hw *hw = TXGBE_DEV_HW(eth_dev);\n+\tstruct rte_ether_addr *perm_addr =\n+\t\t\t(struct rte_ether_addr *)hw->mac.perm_addr;\n \n \tPMD_INIT_FUNC_TRACE();\n \n@@ -142,8 +161,53 @@ eth_txgbevf_dev_init(struct rte_eth_dev *eth_dev)\n \t/* Get Rx/Tx queue count via mailbox, which is ready after reset_hw */\n \ttxgbevf_get_queues(hw, &tcs, &tc);\n \n+\t/* Allocate memory for storing MAC addresses */\n+\teth_dev->data->mac_addrs = rte_zmalloc(\"txgbevf\", RTE_ETHER_ADDR_LEN *\n+\t\t\t\t\t       hw->mac.num_rar_entries, 0);\n+\tif (eth_dev->data->mac_addrs == NULL) {\n+\t\tPMD_INIT_LOG(ERR,\n+\t\t\t     \"Failed to allocate %u bytes needed to store \"\n+\t\t\t     \"MAC addresses\",\n+\t\t\t     RTE_ETHER_ADDR_LEN * hw->mac.num_rar_entries);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\t/* Generate a random MAC address, if none was assigned by PF. */\n+\tif (rte_is_zero_ether_addr(perm_addr)) {\n+\t\tgenerate_random_mac_addr(perm_addr);\n+\t\terr = txgbe_set_rar_vf(hw, 1, perm_addr->addr_bytes, 0, 1);\n+\t\tif (err) {\n+\t\t\trte_free(eth_dev->data->mac_addrs);\n+\t\t\teth_dev->data->mac_addrs = NULL;\n+\t\t\treturn err;\n+\t\t}\n+\t\tPMD_INIT_LOG(INFO, \"\\tVF MAC address not assigned by Host PF\");\n+\t\tPMD_INIT_LOG(INFO, \"\\tAssign randomly generated MAC address \"\n+\t\t\t     \"%02x:%02x:%02x:%02x:%02x:%02x\",\n+\t\t\t     perm_addr->addr_bytes[0],\n+\t\t\t     perm_addr->addr_bytes[1],\n+\t\t\t     perm_addr->addr_bytes[2],\n+\t\t\t     perm_addr->addr_bytes[3],\n+\t\t\t     perm_addr->addr_bytes[4],\n+\t\t\t     perm_addr->addr_bytes[5]);\n+\t}\n+\n+\t/* Copy the permanent MAC address */\n+\trte_ether_addr_copy(perm_addr, &eth_dev->data->mac_addrs[0]);\n+\n+\t/* reset the hardware with the new settings */\n+\terr = hw->mac.start_hw(hw);\n+\tif (err) {\n+\t\tPMD_INIT_LOG(ERR, \"VF Initialization Failure: %d\", err);\n+\t\treturn -EIO;\n+\t}\n+\n \ttxgbevf_intr_enable(eth_dev);\n \n+\tPMD_INIT_LOG(DEBUG, \"port %d vendorID=0x%x deviceID=0x%x mac.type=%s\",\n+\t\t     eth_dev->data->port_id, pci_dev->id.vendor_id,\n+\t\t     pci_dev->id.device_id, \"txgbe_mac_raptor_vf\");\n+\n \treturn 0;\n }\n \n@@ -232,11 +296,112 @@ txgbevf_dev_close(struct rte_eth_dev *dev)\n \n \ttxgbe_dev_free_queues(dev);\n \n+\t/**\n+\t * Remove the VF MAC address ro ensure\n+\t * that the VF traffic goes to the PF\n+\t * after stop, close and detach of the VF\n+\t **/\n+\ttxgbevf_remove_mac_addr(dev, 0);\n+\n \tdev->dev_ops = NULL;\n \n \t/* Disable the interrupts for VF */\n \ttxgbevf_intr_disable(dev);\n \n+\trte_free(dev->data->mac_addrs);\n+\tdev->data->mac_addrs = NULL;\n+\n+\treturn 0;\n+}\n+\n+static int\n+txgbevf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,\n+\t\t     __rte_unused uint32_t index,\n+\t\t     __rte_unused uint32_t pool)\n+{\n+\tstruct txgbe_hw *hw = TXGBE_DEV_HW(dev);\n+\tint err;\n+\n+\t/*\n+\t * On a VF, adding again the same MAC addr is not an idempotent\n+\t * operation. Trap this case to avoid exhausting the [very limited]\n+\t * set of PF resources used to store VF MAC addresses.\n+\t */\n+\tif (memcmp(hw->mac.perm_addr, mac_addr,\n+\t\t\tsizeof(struct rte_ether_addr)) == 0)\n+\t\treturn -1;\n+\terr = txgbevf_set_uc_addr_vf(hw, 2, mac_addr->addr_bytes);\n+\tif (err != 0)\n+\t\tPMD_DRV_LOG(ERR, \"Unable to add MAC address \"\n+\t\t\t    \"%02x:%02x:%02x:%02x:%02x:%02x - err=%d\",\n+\t\t\t    mac_addr->addr_bytes[0],\n+\t\t\t    mac_addr->addr_bytes[1],\n+\t\t\t    mac_addr->addr_bytes[2],\n+\t\t\t    mac_addr->addr_bytes[3],\n+\t\t\t    mac_addr->addr_bytes[4],\n+\t\t\t    mac_addr->addr_bytes[5],\n+\t\t\t    err);\n+\treturn err;\n+}\n+\n+static void\n+txgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)\n+{\n+\tstruct txgbe_hw *hw = TXGBE_DEV_HW(dev);\n+\tstruct rte_ether_addr *perm_addr =\n+\t\t\t(struct rte_ether_addr *)hw->mac.perm_addr;\n+\tstruct rte_ether_addr *mac_addr;\n+\tuint32_t i;\n+\tint err;\n+\n+\t/*\n+\t * The TXGBE_VF_SET_MACVLAN command of the txgbe-pf driver does\n+\t * not support the deletion of a given MAC address.\n+\t * Instead, it imposes to delete all MAC addresses, then to add again\n+\t * all MAC addresses with the exception of the one to be deleted.\n+\t */\n+\t(void)txgbevf_set_uc_addr_vf(hw, 0, NULL);\n+\n+\t/*\n+\t * Add again all MAC addresses, with the exception of the deleted one\n+\t * and of the permanent MAC address.\n+\t */\n+\tfor (i = 0, mac_addr = dev->data->mac_addrs;\n+\t     i < hw->mac.num_rar_entries; i++, mac_addr++) {\n+\t\t/* Skip the deleted MAC address */\n+\t\tif (i == index)\n+\t\t\tcontinue;\n+\t\t/* Skip NULL MAC addresses */\n+\t\tif (rte_is_zero_ether_addr(mac_addr))\n+\t\t\tcontinue;\n+\t\t/* Skip the permanent MAC address */\n+\t\tif (memcmp(perm_addr, mac_addr,\n+\t\t\t\tsizeof(struct rte_ether_addr)) == 0)\n+\t\t\tcontinue;\n+\t\terr = txgbevf_set_uc_addr_vf(hw, 2, mac_addr->addr_bytes);\n+\t\tif (err != 0)\n+\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t    \"Adding again MAC address \"\n+\t\t\t\t    \"%02x:%02x:%02x:%02x:%02x:%02x failed \"\n+\t\t\t\t    \"err=%d\",\n+\t\t\t\t    mac_addr->addr_bytes[0],\n+\t\t\t\t    mac_addr->addr_bytes[1],\n+\t\t\t\t    mac_addr->addr_bytes[2],\n+\t\t\t\t    mac_addr->addr_bytes[3],\n+\t\t\t\t    mac_addr->addr_bytes[4],\n+\t\t\t\t    mac_addr->addr_bytes[5],\n+\t\t\t\t    err);\n+\t}\n+}\n+\n+static int\n+txgbevf_set_default_mac_addr(struct rte_eth_dev *dev,\n+\t\tstruct rte_ether_addr *addr)\n+{\n+\tstruct txgbe_hw *hw = TXGBE_DEV_HW(dev);\n+\n+\thw->mac.set_rar(hw, 0, (void *)addr, 0, 0);\n+\n \treturn 0;\n }\n \n@@ -245,6 +410,9 @@ txgbevf_dev_close(struct rte_eth_dev *dev)\n  * operation have been implemented\n  */\n static const struct eth_dev_ops txgbevf_eth_dev_ops = {\n+\t.mac_addr_add         = txgbevf_add_mac_addr,\n+\t.mac_addr_remove      = txgbevf_remove_mac_addr,\n+\t.mac_addr_set         = txgbevf_set_default_mac_addr,\n };\n \n RTE_PMD_REGISTER_PCI(net_txgbe_vf, rte_txgbevf_pmd);\n",
    "prefixes": [
        "v1",
        "03/20"
    ]
}