get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 88186,
    "url": "http://patches.dpdk.org/api/patches/88186/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20210225080901.3645291-3-jiawenwu@trustnetic.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": "<20210225080901.3645291-3-jiawenwu@trustnetic.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210225080901.3645291-3-jiawenwu@trustnetic.com",
    "date": "2021-02-25T08:08:46",
    "name": "[v3,02/17] net/txgbe: add base code for VF driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "5f9c218abe83d56f4139ad5e1bd2aeaafd59b9e7",
    "submitter": {
        "id": 1932,
        "url": "http://patches.dpdk.org/api/people/1932/?format=api",
        "name": "Jiawen Wu",
        "email": "jiawenwu@trustnetic.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/20210225080901.3645291-3-jiawenwu@trustnetic.com/mbox/",
    "series": [
        {
            "id": 15371,
            "url": "http://patches.dpdk.org/api/series/15371/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=15371",
            "date": "2021-02-25T08:08:45",
            "name": "net/txgbe: add VF driver support",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/15371/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/88186/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/88186/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 5529CA034F;\n\tThu, 25 Feb 2021 09:08:45 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 4EA4916076C;\n\tThu, 25 Feb 2021 09:08:38 +0100 (CET)",
            "from smtpproxy21.qq.com (smtpbg704.qq.com [203.205.195.105])\n by mails.dpdk.org (Postfix) with ESMTP id 3E12F4067B\n for <dev@dpdk.org>; Thu, 25 Feb 2021 09:08:35 +0100 (CET)",
            "from wxdbg.localdomain.com (unknown [183.129.236.74])\n by esmtp6.qq.com (ESMTP) with\n id ; Thu, 25 Feb 2021 16:08:30 +0800 (CST)"
        ],
        "X-QQ-mid": "bizesmtp20t1614240510t2q908lr",
        "X-QQ-SSF": "01400000002000C0D000000A0000000",
        "X-QQ-FEAT": "QSPOcZ5XRR8EtOZ5aZE9yARR9eQEPTFH9rb3A2gvQ9zfRj2ZdEPHubFPByV1h\n 2eRWy1pKdk0BM9LnxNgdez2JSdKsdhWFbH3w5/zRWnb07rxO800gnOx/FtBpBRxoCzc+wAD\n LdRXU98Rs+q2b5TlJeL0cn/r1P1TAFS+29W68/dOrVntDd6Fxan9LNfOsKNhTOz6gAxzvy3\n 2BcbPNWjW5RzrM5D24uWlKI5HPm6sOyEUj4xlv15GXP+qsFdi0a+ZBcV5CTMeRgmAkX+bDX\n lMJqwdne6I616DfOAuGVtw7uB/CY/rpTSq1nzkLx/8yeguvbXDtxtKLsRzTuRx0VyRrxmXG\n NZzppNWFhLgu8zHOkIF1T9QUHFJSw==",
        "X-QQ-GoodBg": "2",
        "From": "Jiawen Wu <jiawenwu@trustnetic.com>",
        "To": "dev@dpdk.org",
        "Cc": "Jiawen Wu <jiawenwu@trustnetic.com>",
        "Date": "Thu, 25 Feb 2021 16:08:46 +0800",
        "Message-Id": "<20210225080901.3645291-3-jiawenwu@trustnetic.com>",
        "X-Mailer": "git-send-email 2.27.0",
        "In-Reply-To": "<20210225080901.3645291-1-jiawenwu@trustnetic.com>",
        "References": "<20210225080901.3645291-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 v3 02/17] net/txgbe: add base code for VF driver",
        "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": "Implement VF device init and uninit function with hardware operations,\nand negotiate with PF in mailbox.\n\nSigned-off-by: Jiawen Wu <jiawenwu@trustnetic.com>\n---\n drivers/net/txgbe/base/meson.build  |   1 +\n drivers/net/txgbe/base/txgbe.h      |   1 +\n drivers/net/txgbe/base/txgbe_hw.c   |   4 +\n drivers/net/txgbe/base/txgbe_mbx.c  | 354 ++++++++++++++++++++++++++++\n drivers/net/txgbe/base/txgbe_mbx.h  |  16 ++\n drivers/net/txgbe/base/txgbe_type.h |   7 +\n drivers/net/txgbe/base/txgbe_vf.c   | 285 ++++++++++++++++++++++\n drivers/net/txgbe/base/txgbe_vf.h   |  20 ++\n drivers/net/txgbe/txgbe_ethdev_vf.c | 116 +++++++++\n 9 files changed, 804 insertions(+)\n create mode 100644 drivers/net/txgbe/base/txgbe_vf.c\n create mode 100644 drivers/net/txgbe/base/txgbe_vf.h",
    "diff": "diff --git a/drivers/net/txgbe/base/meson.build b/drivers/net/txgbe/base/meson.build\nindex 3c63bf5f4..33d0adf0d 100644\n--- a/drivers/net/txgbe/base/meson.build\n+++ b/drivers/net/txgbe/base/meson.build\n@@ -9,6 +9,7 @@ sources = [\n \t'txgbe_mbx.c',\n \t'txgbe_mng.c',\n \t'txgbe_phy.c',\n+\t'txgbe_vf.c',\n ]\n \n error_cflags = []\ndiff --git a/drivers/net/txgbe/base/txgbe.h b/drivers/net/txgbe/base/txgbe.h\nindex b054bb8d0..d7199512b 100644\n--- a/drivers/net/txgbe/base/txgbe.h\n+++ b/drivers/net/txgbe/base/txgbe.h\n@@ -11,6 +11,7 @@\n #include \"txgbe_eeprom.h\"\n #include \"txgbe_phy.h\"\n #include \"txgbe_hw.h\"\n+#include \"txgbe_vf.h\"\n #include \"txgbe_dcb.h\"\n \n #endif /* _TXGBE_H_ */\ndiff --git a/drivers/net/txgbe/base/txgbe_hw.c b/drivers/net/txgbe/base/txgbe_hw.c\nindex dc419d7d4..c357c8658 100644\n--- a/drivers/net/txgbe/base/txgbe_hw.c\n+++ b/drivers/net/txgbe/base/txgbe_hw.c\n@@ -6,6 +6,7 @@\n #include \"txgbe_mbx.h\"\n #include \"txgbe_phy.h\"\n #include \"txgbe_dcb.h\"\n+#include \"txgbe_vf.h\"\n #include \"txgbe_eeprom.h\"\n #include \"txgbe_mng.h\"\n #include \"txgbe_hw.h\"\n@@ -2491,6 +2492,9 @@ s32 txgbe_init_shared_code(struct txgbe_hw *hw)\n \tcase txgbe_mac_raptor:\n \t\tstatus = txgbe_init_ops_pf(hw);\n \t\tbreak;\n+\tcase txgbe_mac_raptor_vf:\n+\t\tstatus = txgbe_init_ops_vf(hw);\n+\t\tbreak;\n \tdefault:\n \t\tstatus = TXGBE_ERR_DEVICE_NOT_SUPPORTED;\n \t\tbreak;\ndiff --git a/drivers/net/txgbe/base/txgbe_mbx.c b/drivers/net/txgbe/base/txgbe_mbx.c\nindex bfe53478e..b308839e7 100644\n--- a/drivers/net/txgbe/base/txgbe_mbx.c\n+++ b/drivers/net/txgbe/base/txgbe_mbx.c\n@@ -118,6 +118,360 @@ s32 txgbe_check_for_rst(struct txgbe_hw *hw, u16 mbx_id)\n \treturn ret_val;\n }\n \n+/**\n+ *  txgbe_poll_for_msg - Wait for message notification\n+ *  @hw: pointer to the HW structure\n+ *  @mbx_id: id of mailbox to write\n+ *\n+ *  returns SUCCESS if it successfully received a message notification\n+ **/\n+STATIC s32 txgbe_poll_for_msg(struct txgbe_hw *hw, u16 mbx_id)\n+{\n+\tstruct txgbe_mbx_info *mbx = &hw->mbx;\n+\tint countdown = mbx->timeout;\n+\n+\tDEBUGFUNC(\"txgbe_poll_for_msg\");\n+\n+\tif (!countdown || !mbx->check_for_msg)\n+\t\tgoto out;\n+\n+\twhile (countdown && mbx->check_for_msg(hw, mbx_id)) {\n+\t\tcountdown--;\n+\t\tif (!countdown)\n+\t\t\tbreak;\n+\t\tusec_delay(mbx->usec_delay);\n+\t}\n+\n+\tif (countdown == 0)\n+\t\tDEBUGOUT(\"Polling for VF%d mailbox message timedout\", mbx_id);\n+\n+out:\n+\treturn countdown ? 0 : TXGBE_ERR_MBX;\n+}\n+\n+/**\n+ *  txgbe_poll_for_ack - Wait for message acknowledgment\n+ *  @hw: pointer to the HW structure\n+ *  @mbx_id: id of mailbox to write\n+ *\n+ *  returns SUCCESS if it successfully received a message acknowledgment\n+ **/\n+STATIC s32 txgbe_poll_for_ack(struct txgbe_hw *hw, u16 mbx_id)\n+{\n+\tstruct txgbe_mbx_info *mbx = &hw->mbx;\n+\tint countdown = mbx->timeout;\n+\n+\tDEBUGFUNC(\"txgbe_poll_for_ack\");\n+\n+\tif (!countdown || !mbx->check_for_ack)\n+\t\tgoto out;\n+\n+\twhile (countdown && mbx->check_for_ack(hw, mbx_id)) {\n+\t\tcountdown--;\n+\t\tif (!countdown)\n+\t\t\tbreak;\n+\t\tusec_delay(mbx->usec_delay);\n+\t}\n+\n+\tif (countdown == 0)\n+\t\tDEBUGOUT(\"Polling for VF%d mailbox ack timedout\", mbx_id);\n+\n+out:\n+\treturn countdown ? 0 : TXGBE_ERR_MBX;\n+}\n+\n+/**\n+ *  txgbe_read_posted_mbx - Wait for message notification and receive message\n+ *  @hw: pointer to the HW structure\n+ *  @msg: The message buffer\n+ *  @size: Length of buffer\n+ *  @mbx_id: id of mailbox to write\n+ *\n+ *  returns SUCCESS if it successfully received a message notification and\n+ *  copied it into the receive buffer.\n+ **/\n+s32 txgbe_read_posted_mbx(struct txgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)\n+{\n+\tstruct txgbe_mbx_info *mbx = &hw->mbx;\n+\ts32 ret_val = TXGBE_ERR_MBX;\n+\n+\tDEBUGFUNC(\"txgbe_read_posted_mbx\");\n+\n+\tif (!mbx->read)\n+\t\tgoto out;\n+\n+\tret_val = txgbe_poll_for_msg(hw, mbx_id);\n+\n+\t/* if ack received read message, otherwise we timed out */\n+\tif (!ret_val)\n+\t\tret_val = mbx->read(hw, msg, size, mbx_id);\n+out:\n+\treturn ret_val;\n+}\n+\n+/**\n+ *  txgbe_write_posted_mbx - Write a message to the mailbox, wait for ack\n+ *  @hw: pointer to the HW structure\n+ *  @msg: The message buffer\n+ *  @size: Length of buffer\n+ *  @mbx_id: id of mailbox to write\n+ *\n+ *  returns SUCCESS if it successfully copied message into the buffer and\n+ *  received an ack to that message within delay * timeout period\n+ **/\n+s32 txgbe_write_posted_mbx(struct txgbe_hw *hw, u32 *msg, u16 size,\n+\t\t\t   u16 mbx_id)\n+{\n+\tstruct txgbe_mbx_info *mbx = &hw->mbx;\n+\ts32 ret_val = TXGBE_ERR_MBX;\n+\n+\tDEBUGFUNC(\"txgbe_write_posted_mbx\");\n+\n+\t/* exit if either we can't write or there isn't a defined timeout */\n+\tif (!mbx->write || !mbx->timeout)\n+\t\tgoto out;\n+\n+\t/* send msg */\n+\tret_val = mbx->write(hw, msg, size, mbx_id);\n+\n+\t/* if msg sent wait until we receive an ack */\n+\tif (!ret_val)\n+\t\tret_val = txgbe_poll_for_ack(hw, mbx_id);\n+out:\n+\treturn ret_val;\n+}\n+\n+/**\n+ *  txgbe_read_v2p_mailbox - read v2p mailbox\n+ *  @hw: pointer to the HW structure\n+ *\n+ *  This function is used to read the v2p mailbox without losing the read to\n+ *  clear status bits.\n+ **/\n+STATIC u32 txgbe_read_v2p_mailbox(struct txgbe_hw *hw)\n+{\n+\tu32 v2p_mailbox = rd32(hw, TXGBE_VFMBCTL);\n+\n+\tv2p_mailbox |= hw->mbx.v2p_mailbox;\n+\thw->mbx.v2p_mailbox |= v2p_mailbox & TXGBE_VFMBCTL_R2C_BITS;\n+\n+\treturn v2p_mailbox;\n+}\n+\n+/**\n+ *  txgbe_check_for_bit_vf - Determine if a status bit was set\n+ *  @hw: pointer to the HW structure\n+ *  @mask: bitmask for bits to be tested and cleared\n+ *\n+ *  This function is used to check for the read to clear bits within\n+ *  the V2P mailbox.\n+ **/\n+STATIC s32 txgbe_check_for_bit_vf(struct txgbe_hw *hw, u32 mask)\n+{\n+\tu32 v2p_mailbox = txgbe_read_v2p_mailbox(hw);\n+\ts32 ret_val = TXGBE_ERR_MBX;\n+\n+\tif (v2p_mailbox & mask)\n+\t\tret_val = 0;\n+\n+\thw->mbx.v2p_mailbox &= ~mask;\n+\n+\treturn ret_val;\n+}\n+\n+/**\n+ *  txgbe_check_for_msg_vf - checks to see if the PF has sent mail\n+ *  @hw: pointer to the HW structure\n+ *  @mbx_id: id of mailbox to check\n+ *\n+ *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX\n+ **/\n+s32 txgbe_check_for_msg_vf(struct txgbe_hw *hw, u16 mbx_id)\n+{\n+\ts32 ret_val = TXGBE_ERR_MBX;\n+\n+\tUNREFERENCED_PARAMETER(mbx_id);\n+\tDEBUGFUNC(\"txgbe_check_for_msg_vf\");\n+\n+\tif (!txgbe_check_for_bit_vf(hw, TXGBE_VFMBCTL_PFSTS)) {\n+\t\tret_val = 0;\n+\t\thw->mbx.stats.reqs++;\n+\t}\n+\n+\treturn ret_val;\n+}\n+\n+/**\n+ *  txgbe_check_for_ack_vf - checks to see if the PF has ACK'd\n+ *  @hw: pointer to the HW structure\n+ *  @mbx_id: id of mailbox to check\n+ *\n+ *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX\n+ **/\n+s32 txgbe_check_for_ack_vf(struct txgbe_hw *hw, u16 mbx_id)\n+{\n+\ts32 ret_val = TXGBE_ERR_MBX;\n+\n+\tUNREFERENCED_PARAMETER(mbx_id);\n+\tDEBUGFUNC(\"txgbe_check_for_ack_vf\");\n+\n+\tif (!txgbe_check_for_bit_vf(hw, TXGBE_VFMBCTL_PFACK)) {\n+\t\tret_val = 0;\n+\t\thw->mbx.stats.acks++;\n+\t}\n+\n+\treturn ret_val;\n+}\n+\n+/**\n+ *  txgbe_check_for_rst_vf - checks to see if the PF has reset\n+ *  @hw: pointer to the HW structure\n+ *  @mbx_id: id of mailbox to check\n+ *\n+ *  returns true if the PF has set the reset done bit or else false\n+ **/\n+s32 txgbe_check_for_rst_vf(struct txgbe_hw *hw, u16 mbx_id)\n+{\n+\ts32 ret_val = TXGBE_ERR_MBX;\n+\n+\tUNREFERENCED_PARAMETER(mbx_id);\n+\tDEBUGFUNC(\"txgbe_check_for_rst_vf\");\n+\n+\tif (!txgbe_check_for_bit_vf(hw, (TXGBE_VFMBCTL_RSTD |\n+\t    TXGBE_VFMBCTL_RSTI))) {\n+\t\tret_val = 0;\n+\t\thw->mbx.stats.rsts++;\n+\t}\n+\n+\treturn ret_val;\n+}\n+\n+/**\n+ *  txgbe_obtain_mbx_lock_vf - obtain mailbox lock\n+ *  @hw: pointer to the HW structure\n+ *\n+ *  return SUCCESS if we obtained the mailbox lock\n+ **/\n+STATIC s32 txgbe_obtain_mbx_lock_vf(struct txgbe_hw *hw)\n+{\n+\ts32 ret_val = TXGBE_ERR_MBX;\n+\n+\tDEBUGFUNC(\"txgbe_obtain_mbx_lock_vf\");\n+\n+\t/* Take ownership of the buffer */\n+\twr32(hw, TXGBE_VFMBCTL, TXGBE_VFMBCTL_VFU);\n+\n+\t/* reserve mailbox for vf use */\n+\tif (txgbe_read_v2p_mailbox(hw) & TXGBE_VFMBCTL_VFU)\n+\t\tret_val = 0;\n+\n+\treturn ret_val;\n+}\n+\n+/**\n+ *  txgbe_write_mbx_vf - Write a message to the mailbox\n+ *  @hw: pointer to the HW structure\n+ *  @msg: The message buffer\n+ *  @size: Length of buffer\n+ *  @mbx_id: id of mailbox to write\n+ *\n+ *  returns SUCCESS if it successfully copied message into the buffer\n+ **/\n+s32 txgbe_write_mbx_vf(struct txgbe_hw *hw, u32 *msg, u16 size,\n+\t\t\t      u16 mbx_id)\n+{\n+\ts32 ret_val;\n+\tu16 i;\n+\n+\tUNREFERENCED_PARAMETER(mbx_id);\n+\n+\tDEBUGFUNC(\"txgbe_write_mbx_vf\");\n+\n+\t/* lock the mailbox to prevent pf/vf race condition */\n+\tret_val = txgbe_obtain_mbx_lock_vf(hw);\n+\tif (ret_val)\n+\t\tgoto out_no_write;\n+\n+\t/* flush msg and acks as we are overwriting the message buffer */\n+\ttxgbe_check_for_msg_vf(hw, 0);\n+\ttxgbe_check_for_ack_vf(hw, 0);\n+\n+\t/* copy the caller specified message to the mailbox memory buffer */\n+\tfor (i = 0; i < size; i++)\n+\t\twr32a(hw, TXGBE_VFMBX, i, msg[i]);\n+\n+\t/* update stats */\n+\thw->mbx.stats.msgs_tx++;\n+\n+\t/* Drop VFU and interrupt the PF to tell it a message has been sent */\n+\twr32(hw, TXGBE_VFMBCTL, TXGBE_VFMBCTL_REQ);\n+\n+out_no_write:\n+\treturn ret_val;\n+}\n+\n+/**\n+ *  txgbe_read_mbx_vf - Reads a message from the inbox intended for vf\n+ *  @hw: pointer to the HW structure\n+ *  @msg: The message buffer\n+ *  @size: Length of buffer\n+ *  @mbx_id: id of mailbox to read\n+ *\n+ *  returns SUCCESS if it successfully read message from buffer\n+ **/\n+s32 txgbe_read_mbx_vf(struct txgbe_hw *hw, u32 *msg, u16 size,\n+\t\t\t     u16 mbx_id)\n+{\n+\ts32 ret_val = 0;\n+\tu16 i;\n+\n+\tDEBUGFUNC(\"txgbe_read_mbx_vf\");\n+\tUNREFERENCED_PARAMETER(mbx_id);\n+\n+\t/* lock the mailbox to prevent pf/vf race condition */\n+\tret_val = txgbe_obtain_mbx_lock_vf(hw);\n+\tif (ret_val)\n+\t\tgoto out_no_read;\n+\n+\t/* copy the message from the mailbox memory buffer */\n+\tfor (i = 0; i < size; i++)\n+\t\tmsg[i] = rd32a(hw, TXGBE_VFMBX, i);\n+\n+\t/* Acknowledge receipt and release mailbox, then we're done */\n+\twr32(hw, TXGBE_VFMBCTL, TXGBE_VFMBCTL_ACK);\n+\n+\t/* update stats */\n+\thw->mbx.stats.msgs_rx++;\n+\n+out_no_read:\n+\treturn ret_val;\n+}\n+\n+/**\n+ *  txgbe_init_mbx_params_vf - set initial values for vf mailbox\n+ *  @hw: pointer to the HW structure\n+ *\n+ *  Initializes the hw->mbx struct to correct values for vf mailbox\n+ */\n+void txgbe_init_mbx_params_vf(struct txgbe_hw *hw)\n+{\n+\tstruct txgbe_mbx_info *mbx = &hw->mbx;\n+\n+\t/* start mailbox as timed out and let the reset_hw call set the timeout\n+\t * value to begin communications\n+\t */\n+\tmbx->timeout = 0;\n+\tmbx->usec_delay = TXGBE_VF_MBX_INIT_DELAY;\n+\n+\tmbx->size = TXGBE_P2VMBX_SIZE;\n+\n+\tmbx->stats.msgs_tx = 0;\n+\tmbx->stats.msgs_rx = 0;\n+\tmbx->stats.reqs = 0;\n+\tmbx->stats.acks = 0;\n+\tmbx->stats.rsts = 0;\n+}\n+\n STATIC s32 txgbe_check_for_bit_pf(struct txgbe_hw *hw, u32 mask, s32 index)\n {\n \tu32 mbvficr = rd32(hw, TXGBE_MBVFICR(index));\ndiff --git a/drivers/net/txgbe/base/txgbe_mbx.h b/drivers/net/txgbe/base/txgbe_mbx.h\nindex 4a058b0bb..ccf5d12f2 100644\n--- a/drivers/net/txgbe/base/txgbe_mbx.h\n+++ b/drivers/net/txgbe/base/txgbe_mbx.h\n@@ -60,6 +60,8 @@ enum txgbe_pfvf_api_rev {\n #define TXGBE_VF_GET_RSS_KEY\t0x0b    /* get RSS key */\n #define TXGBE_VF_UPDATE_XCAST_MODE\t0x0c\n \n+#define TXGBE_VF_BACKUP\t\t0x8001 /* VF requests backup */\n+\n /* mode choices for TXGBE_VF_UPDATE_XCAST_MODE */\n enum txgbevf_xcast_modes {\n \tTXGBEVF_XCAST_MODE_NONE = 0,\n@@ -76,12 +78,20 @@ enum txgbevf_xcast_modes {\n \n /* length of permanent address message returned from PF */\n #define TXGBE_VF_PERMADDR_MSG_LEN\t4\n+/* word in permanent address message with the current multicast type */\n+#define TXGBE_VF_MC_TYPE_WORD\t\t3\n+\n+#define TXGBE_VF_MBX_INIT_TIMEOUT\t2000 /* number of retries on mailbox */\n+#define TXGBE_VF_MBX_INIT_DELAY\t\t500  /* microseconds between retries */\n \n s32 txgbe_read_mbx(struct txgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);\n s32 txgbe_write_mbx(struct txgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);\n+s32 txgbe_read_posted_mbx(struct txgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);\n+s32 txgbe_write_posted_mbx(struct txgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);\n s32 txgbe_check_for_msg(struct txgbe_hw *hw, u16 mbx_id);\n s32 txgbe_check_for_ack(struct txgbe_hw *hw, u16 mbx_id);\n s32 txgbe_check_for_rst(struct txgbe_hw *hw, u16 mbx_id);\n+void txgbe_init_mbx_params_vf(struct txgbe_hw *hw);\n void txgbe_init_mbx_params_pf(struct txgbe_hw *hw);\n \n s32 txgbe_read_mbx_pf(struct txgbe_hw *hw, u32 *msg, u16 size, u16 vf_number);\n@@ -90,4 +100,10 @@ s32 txgbe_check_for_msg_pf(struct txgbe_hw *hw, u16 vf_number);\n s32 txgbe_check_for_ack_pf(struct txgbe_hw *hw, u16 vf_number);\n s32 txgbe_check_for_rst_pf(struct txgbe_hw *hw, u16 vf_number);\n \n+s32 txgbe_read_mbx_vf(struct txgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);\n+s32 txgbe_write_mbx_vf(struct txgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);\n+s32 txgbe_check_for_msg_vf(struct txgbe_hw *hw, u16 mbx_id);\n+s32 txgbe_check_for_ack_vf(struct txgbe_hw *hw, u16 mbx_id);\n+s32 txgbe_check_for_rst_vf(struct txgbe_hw *hw, u16 mbx_id);\n+\n #endif /* _TXGBE_MBX_H_ */\ndiff --git a/drivers/net/txgbe/base/txgbe_type.h b/drivers/net/txgbe/base/txgbe_type.h\nindex 22efcef78..ef8358ae3 100644\n--- a/drivers/net/txgbe/base/txgbe_type.h\n+++ b/drivers/net/txgbe/base/txgbe_type.h\n@@ -11,6 +11,9 @@\n #define TXGBE_LINK_UP_TIME\t90 /* 9.0 Seconds */\n #define TXGBE_AUTO_NEG_TIME\t45 /* 4.5 Seconds */\n \n+#define TXGBE_RX_HDR_SIZE\t256\n+#define TXGBE_RX_BUF_SIZE\t2048\n+\n #define TXGBE_FRAME_SIZE_MAX\t(9728) /* Maximum frame size, +FCS */\n #define TXGBE_FRAME_SIZE_DFT\t(1518) /* Default frame size, +FCS */\n #define TXGBE_NUM_POOL\t\t(64)\n@@ -23,6 +26,7 @@\n \n #define TXGBE_FDIR_INIT_DONE_POLL\t\t10\n #define TXGBE_FDIRCMD_CMD_POLL\t\t\t10\n+#define TXGBE_VF_INIT_TIMEOUT\t200 /* Number of retries to clear RSTI */\n \n #define TXGBE_ALIGN\t\t128 /* as intel did */\n \n@@ -703,6 +707,7 @@ struct txgbe_mbx_info {\n \tstruct txgbe_mbx_stats stats;\n \tu32 timeout;\n \tu32 usec_delay;\n+\tu32 v2p_mailbox;\n \tu16 size;\n };\n \n@@ -732,6 +737,7 @@ struct txgbe_hw {\n \tu16 subsystem_vendor_id;\n \tu8 revision_id;\n \tbool adapter_stopped;\n+\tint api_version;\n \tbool allow_unsupported_sfp;\n \tbool need_crosstalk_fix;\n \n@@ -755,6 +761,7 @@ struct txgbe_hw {\n \tu32 q_rx_regs[128 * 4];\n \tu32 q_tx_regs[128 * 4];\n \tbool offset_loaded;\n+\tbool rx_loaded;\n \tstruct {\n \t\tu64 rx_qp_packets;\n \t\tu64 tx_qp_packets;\ndiff --git a/drivers/net/txgbe/base/txgbe_vf.c b/drivers/net/txgbe/base/txgbe_vf.c\nnew file mode 100644\nindex 000000000..5d4e10158\n--- /dev/null\n+++ b/drivers/net/txgbe/base/txgbe_vf.c\n@@ -0,0 +1,285 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2015-2020\n+ */\n+\n+#include \"txgbe_mbx.h\"\n+#include \"txgbe_vf.h\"\n+\n+/**\n+ *  txgbe_init_ops_vf - Initialize the pointers for vf\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  This will assign function pointers, adapter-specific functions can\n+ *  override the assignment of generic function pointers by assigning\n+ *  their own adapter-specific function pointers.\n+ *  Does not touch the hardware.\n+ **/\n+s32 txgbe_init_ops_vf(struct txgbe_hw *hw)\n+{\n+\tstruct txgbe_mac_info *mac = &hw->mac;\n+\tstruct txgbe_mbx_info *mbx = &hw->mbx;\n+\n+\t/* MAC */\n+\tmac->reset_hw = txgbe_reset_hw_vf;\n+\tmac->stop_hw = txgbe_stop_hw_vf;\n+\tmac->negotiate_api_version = txgbevf_negotiate_api_version;\n+\n+\tmac->max_tx_queues = 1;\n+\tmac->max_rx_queues = 1;\n+\n+\tmbx->init_params = txgbe_init_mbx_params_vf;\n+\tmbx->read = txgbe_read_mbx_vf;\n+\tmbx->write = txgbe_write_mbx_vf;\n+\tmbx->read_posted = txgbe_read_posted_mbx;\n+\tmbx->write_posted = txgbe_write_posted_mbx;\n+\tmbx->check_for_msg = txgbe_check_for_msg_vf;\n+\tmbx->check_for_ack = txgbe_check_for_ack_vf;\n+\tmbx->check_for_rst = txgbe_check_for_rst_vf;\n+\n+\treturn 0;\n+}\n+\n+/* txgbe_virt_clr_reg - Set register to default (power on) state.\n+ * @hw: pointer to hardware structure\n+ */\n+static void txgbe_virt_clr_reg(struct txgbe_hw *hw)\n+{\n+\tint i;\n+\tu32 vfsrrctl;\n+\n+\t/* default values (BUF_SIZE = 2048, HDR_SIZE = 256) */\n+\tvfsrrctl = TXGBE_RXCFG_HDRLEN(TXGBE_RX_HDR_SIZE);\n+\tvfsrrctl |= TXGBE_RXCFG_PKTLEN(TXGBE_RX_BUF_SIZE);\n+\n+\tfor (i = 0; i < 8; i++) {\n+\t\twr32m(hw, TXGBE_RXCFG(i),\n+\t\t\t(TXGBE_RXCFG_HDRLEN_MASK | TXGBE_RXCFG_PKTLEN_MASK),\n+\t\t\tvfsrrctl);\n+\t}\n+\n+\ttxgbe_flush(hw);\n+}\n+\n+/**\n+ *  txgbe_reset_hw_vf - Performs hardware reset\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Resets the hardware by resetting the transmit and receive units, masks and\n+ *  clears all interrupts.\n+ **/\n+s32 txgbe_reset_hw_vf(struct txgbe_hw *hw)\n+{\n+\tstruct txgbe_mbx_info *mbx = &hw->mbx;\n+\tu32 timeout = TXGBE_VF_INIT_TIMEOUT;\n+\ts32 ret_val = TXGBE_ERR_INVALID_MAC_ADDR;\n+\tu32 msgbuf[TXGBE_VF_PERMADDR_MSG_LEN];\n+\tu8 *addr = (u8 *)(&msgbuf[1]);\n+\n+\tDEBUGFUNC(\"txgbevf_reset_hw_vf\");\n+\n+\t/* Call adapter stop to disable tx/rx and clear interrupts */\n+\thw->mac.stop_hw(hw);\n+\n+\t/* reset the api version */\n+\thw->api_version = txgbe_mbox_api_10;\n+\n+\t/* backup msix vectors */\n+\tmbx->timeout = TXGBE_VF_MBX_INIT_TIMEOUT;\n+\tmsgbuf[0] = TXGBE_VF_BACKUP;\n+\tmbx->write_posted(hw, msgbuf, 1, 0);\n+\tmsec_delay(10);\n+\n+\tDEBUGOUT(\"Issuing a function level reset to MAC\\n\");\n+\twr32(hw, TXGBE_VFRST, TXGBE_VFRST_SET);\n+\ttxgbe_flush(hw);\n+\tmsec_delay(50);\n+\n+\thw->offset_loaded = 1;\n+\n+\t/* we cannot reset while the RSTI / RSTD bits are asserted */\n+\twhile (!mbx->check_for_rst(hw, 0) && timeout) {\n+\t\ttimeout--;\n+\t\t/* if it doesn't work, try in 1 ms */\n+\t\tusec_delay(5);\n+\t}\n+\n+\tif (!timeout)\n+\t\treturn TXGBE_ERR_RESET_FAILED;\n+\n+\t/* Reset VF registers to initial values */\n+\ttxgbe_virt_clr_reg(hw);\n+\n+\t/* mailbox timeout can now become active */\n+\tmbx->timeout = TXGBE_VF_MBX_INIT_TIMEOUT;\n+\n+\tmsgbuf[0] = TXGBE_VF_RESET;\n+\tmbx->write_posted(hw, msgbuf, 1, 0);\n+\n+\tmsec_delay(10);\n+\n+\t/*\n+\t * set our \"perm_addr\" based on info provided by PF\n+\t * also set up the mc_filter_type which is piggy backed\n+\t * on the mac address in word 3\n+\t */\n+\tret_val = mbx->read_posted(hw, msgbuf,\n+\t\t\tTXGBE_VF_PERMADDR_MSG_LEN, 0);\n+\tif (ret_val)\n+\t\treturn ret_val;\n+\n+\tif (msgbuf[0] != (TXGBE_VF_RESET | TXGBE_VT_MSGTYPE_ACK) &&\n+\t    msgbuf[0] != (TXGBE_VF_RESET | TXGBE_VT_MSGTYPE_NACK))\n+\t\treturn TXGBE_ERR_INVALID_MAC_ADDR;\n+\n+\tif (msgbuf[0] == (TXGBE_VF_RESET | TXGBE_VT_MSGTYPE_ACK))\n+\t\tmemcpy(hw->mac.perm_addr, addr, ETH_ADDR_LEN);\n+\n+\thw->mac.mc_filter_type = msgbuf[TXGBE_VF_MC_TYPE_WORD];\n+\n+\treturn ret_val;\n+}\n+\n+/**\n+ *  txgbe_stop_hw_vf - Generic stop Tx/Rx units\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Sets the adapter_stopped flag within txgbe_hw struct. Clears interrupts,\n+ *  disables transmit and receive units. The adapter_stopped flag is used by\n+ *  the shared code and drivers to determine if the adapter is in a stopped\n+ *  state and should not touch the hardware.\n+ **/\n+s32 txgbe_stop_hw_vf(struct txgbe_hw *hw)\n+{\n+\tu16 i;\n+\n+\t/*\n+\t * Set the adapter_stopped flag so other driver functions stop touching\n+\t * the hardware\n+\t */\n+\thw->adapter_stopped = true;\n+\n+\t/* Clear interrupt mask to stop from interrupts being generated */\n+\twr32(hw, TXGBE_VFIMC, TXGBE_VFIMC_MASK);\n+\n+\t/* Clear any pending interrupts, flush previous writes */\n+\twr32(hw, TXGBE_VFICR, TXGBE_VFICR_MASK);\n+\n+\t/* Disable the transmit unit.  Each queue must be disabled. */\n+\tfor (i = 0; i < hw->mac.max_tx_queues; i++)\n+\t\twr32(hw, TXGBE_TXCFG(i), TXGBE_TXCFG_FLUSH);\n+\n+\t/* Disable the receive unit by stopping each queue */\n+\tfor (i = 0; i < hw->mac.max_rx_queues; i++)\n+\t\twr32m(hw, TXGBE_RXCFG(i), TXGBE_RXCFG_ENA, 0);\n+\n+\t/* Clear packet split and pool config */\n+\twr32(hw, TXGBE_VFPLCFG, 0);\n+\thw->rx_loaded = 1;\n+\n+\t/* flush all queues disables */\n+\ttxgbe_flush(hw);\n+\tmsec_delay(2);\n+\n+\treturn 0;\n+}\n+\n+STATIC s32 txgbevf_write_msg_read_ack(struct txgbe_hw *hw, u32 *msg,\n+\t\t\t\t      u32 *retmsg, u16 size)\n+{\n+\tstruct txgbe_mbx_info *mbx = &hw->mbx;\n+\ts32 retval = mbx->write_posted(hw, msg, size, 0);\n+\n+\tif (retval)\n+\t\treturn retval;\n+\n+\treturn mbx->read_posted(hw, retmsg, size, 0);\n+}\n+\n+/**\n+ *  txgbevf_negotiate_api_version - Negotiate supported API version\n+ *  @hw: pointer to the HW structure\n+ *  @api: integer containing requested API version\n+ **/\n+int txgbevf_negotiate_api_version(struct txgbe_hw *hw, int api)\n+{\n+\tint err;\n+\tu32 msg[3];\n+\n+\t/* Negotiate the mailbox API version */\n+\tmsg[0] = TXGBE_VF_API_NEGOTIATE;\n+\tmsg[1] = api;\n+\tmsg[2] = 0;\n+\n+\terr = txgbevf_write_msg_read_ack(hw, msg, msg, 3);\n+\tif (!err) {\n+\t\tmsg[0] &= ~TXGBE_VT_MSGTYPE_CTS;\n+\n+\t\t/* Store value and return 0 on success */\n+\t\tif (msg[0] == (TXGBE_VF_API_NEGOTIATE | TXGBE_VT_MSGTYPE_ACK)) {\n+\t\t\thw->api_version = api;\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\terr = TXGBE_ERR_INVALID_ARGUMENT;\n+\t}\n+\n+\treturn err;\n+}\n+\n+int txgbevf_get_queues(struct txgbe_hw *hw, unsigned int *num_tcs,\n+\t\t       unsigned int *default_tc)\n+{\n+\tint err, i;\n+\tu32 msg[5];\n+\n+\t/* do nothing if API doesn't support txgbevf_get_queues */\n+\tswitch (hw->api_version) {\n+\tcase txgbe_mbox_api_11:\n+\tcase txgbe_mbox_api_12:\n+\tcase txgbe_mbox_api_13:\n+\t\tbreak;\n+\tdefault:\n+\t\treturn 0;\n+\t}\n+\n+\t/* Fetch queue configuration from the PF */\n+\tmsg[0] = TXGBE_VF_GET_QUEUES;\n+\tfor (i = 1; i < 5; i++)\n+\t\tmsg[i] = 0;\n+\n+\terr = txgbevf_write_msg_read_ack(hw, msg, msg, 5);\n+\tif (!err) {\n+\t\tmsg[0] &= ~TXGBE_VT_MSGTYPE_CTS;\n+\n+\t\t/*\n+\t\t * if we didn't get an ACK there must have been\n+\t\t * some sort of mailbox error so we should treat it\n+\t\t * as such\n+\t\t */\n+\t\tif (msg[0] != (TXGBE_VF_GET_QUEUES | TXGBE_VT_MSGTYPE_ACK))\n+\t\t\treturn TXGBE_ERR_MBX;\n+\n+\t\t/* record and validate values from message */\n+\t\thw->mac.max_tx_queues = msg[TXGBE_VF_TX_QUEUES];\n+\t\tif (hw->mac.max_tx_queues == 0 ||\n+\t\t    hw->mac.max_tx_queues > TXGBE_VF_MAX_TX_QUEUES)\n+\t\t\thw->mac.max_tx_queues = TXGBE_VF_MAX_TX_QUEUES;\n+\n+\t\thw->mac.max_rx_queues = msg[TXGBE_VF_RX_QUEUES];\n+\t\tif (hw->mac.max_rx_queues == 0 ||\n+\t\t    hw->mac.max_rx_queues > TXGBE_VF_MAX_RX_QUEUES)\n+\t\t\thw->mac.max_rx_queues = TXGBE_VF_MAX_RX_QUEUES;\n+\n+\t\t*num_tcs = msg[TXGBE_VF_TRANS_VLAN];\n+\t\t/* in case of unknown state assume we cannot tag frames */\n+\t\tif (*num_tcs > hw->mac.max_rx_queues)\n+\t\t\t*num_tcs = 1;\n+\n+\t\t*default_tc = msg[TXGBE_VF_DEF_QUEUE];\n+\t\t/* default to queue 0 on out-of-bounds queue number */\n+\t\tif (*default_tc >= hw->mac.max_tx_queues)\n+\t\t\t*default_tc = 0;\n+\t}\n+\n+\treturn err;\n+}\ndiff --git a/drivers/net/txgbe/base/txgbe_vf.h b/drivers/net/txgbe/base/txgbe_vf.h\nnew file mode 100644\nindex 000000000..70f90c262\n--- /dev/null\n+++ b/drivers/net/txgbe/base/txgbe_vf.h\n@@ -0,0 +1,20 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2015-2020\n+ */\n+\n+#ifndef _TXGBE_VF_H_\n+#define _TXGBE_VF_H_\n+\n+#include \"txgbe_type.h\"\n+\n+#define TXGBE_VF_MAX_TX_QUEUES\t8\n+#define TXGBE_VF_MAX_RX_QUEUES\t8\n+\n+s32 txgbe_init_ops_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+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);\n+\n+#endif /* __TXGBE_VF_H__ */\ndiff --git a/drivers/net/txgbe/txgbe_ethdev_vf.c b/drivers/net/txgbe/txgbe_ethdev_vf.c\nindex 1c3765e4e..4fbb4f154 100644\n--- a/drivers/net/txgbe/txgbe_ethdev_vf.c\n+++ b/drivers/net/txgbe/txgbe_ethdev_vf.c\n@@ -10,11 +10,14 @@\n #include <rte_log.h>\n #include <ethdev_pci.h>\n \n+#include \"txgbe_logs.h\"\n #include \"base/txgbe.h\"\n #include \"txgbe_ethdev.h\"\n #include \"txgbe_rxtx.h\"\n \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 \n /*\n  * The set of PCI devices this driver supports (for VF)\n@@ -27,14 +30,43 @@ static const struct rte_pci_id pci_id_txgbevf_map[] = {\n \n static const struct eth_dev_ops txgbevf_eth_dev_ops;\n \n+/*\n+ * Negotiate mailbox API version with the PF.\n+ * After reset API version is always set to the basic one (txgbe_mbox_api_10).\n+ * Then we try to negotiate starting with the most recent one.\n+ * If all negotiation attempts fail, then we will proceed with\n+ * the default one (txgbe_mbox_api_10).\n+ */\n+static void\n+txgbevf_negotiate_api(struct txgbe_hw *hw)\n+{\n+\tint32_t i;\n+\n+\t/* start with highest supported, proceed down */\n+\tstatic const int sup_ver[] = {\n+\t\ttxgbe_mbox_api_13,\n+\t\ttxgbe_mbox_api_12,\n+\t\ttxgbe_mbox_api_11,\n+\t\ttxgbe_mbox_api_10,\n+\t};\n+\n+\tfor (i = 0; i < ARRAY_SIZE(sup_ver); i++) {\n+\t\tif (txgbevf_negotiate_api_version(hw, sup_ver[i]) == 0)\n+\t\t\tbreak;\n+\t}\n+}\n+\n /*\n  * Virtual Function device init\n  */\n static int\n eth_txgbevf_dev_init(struct rte_eth_dev *eth_dev)\n {\n+\tint err;\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+\n \tPMD_INIT_FUNC_TRACE();\n \n \teth_dev->dev_ops = &txgbevf_eth_dev_ops;\n@@ -71,6 +103,46 @@ eth_txgbevf_dev_init(struct rte_eth_dev *eth_dev)\n \thw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;\n \thw->hw_addr = (void *)pci_dev->mem_resource[0].addr;\n \n+\t/* Initialize the shared code (base driver) */\n+\terr = txgbe_init_shared_code(hw);\n+\tif (err != 0) {\n+\t\tPMD_INIT_LOG(ERR,\n+\t\t\t\"Shared code init failed for txgbevf: %d\", err);\n+\t\treturn -EIO;\n+\t}\n+\n+\t/* init_mailbox_params */\n+\thw->mbx.init_params(hw);\n+\n+\t/* Disable the interrupts for VF */\n+\ttxgbevf_intr_disable(eth_dev);\n+\n+\thw->mac.num_rar_entries = 128; /* The MAX of the underlying PF */\n+\terr = hw->mac.reset_hw(hw);\n+\n+\t/*\n+\t * The VF reset operation returns the TXGBE_ERR_INVALID_MAC_ADDR when\n+\t * the underlying PF driver has not assigned a MAC address to the VF.\n+\t * In this case, assign a random MAC address.\n+\t */\n+\tif (err != 0 && err != TXGBE_ERR_INVALID_MAC_ADDR) {\n+\t\tPMD_INIT_LOG(ERR, \"VF Initialization Failure: %d\", err);\n+\t\t/*\n+\t\t * This error code will be propagated to the app by\n+\t\t * rte_eth_dev_reset, so use a public error code rather than\n+\t\t * the internal-only TXGBE_ERR_RESET_FAILED\n+\t\t */\n+\t\treturn -EAGAIN;\n+\t}\n+\n+\t/* negotiate mailbox API version to use with the PF. */\n+\ttxgbevf_negotiate_api(hw);\n+\n+\t/* Get Rx/Tx queue count via mailbox, which is ready after reset_hw */\n+\ttxgbevf_get_queues(hw, &tcs, &tc);\n+\n+\ttxgbevf_intr_enable(eth_dev);\n+\n \treturn 0;\n }\n \n@@ -110,13 +182,57 @@ static struct rte_pci_driver rte_txgbevf_pmd = {\n \t.remove = eth_txgbevf_pci_remove,\n };\n \n+/*\n+ * Virtual Function operations\n+ */\n+static void\n+txgbevf_intr_disable(struct rte_eth_dev *dev)\n+{\n+\tstruct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);\n+\tstruct txgbe_hw *hw = TXGBE_DEV_HW(dev);\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\t/* Clear interrupt mask to stop from interrupts being generated */\n+\twr32(hw, TXGBE_VFIMS, TXGBE_VFIMS_MASK);\n+\n+\ttxgbe_flush(hw);\n+\n+\t/* Clear mask value. */\n+\tintr->mask_misc = TXGBE_VFIMS_MASK;\n+}\n+\n+static void\n+txgbevf_intr_enable(struct rte_eth_dev *dev)\n+{\n+\tstruct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);\n+\tstruct txgbe_hw *hw = TXGBE_DEV_HW(dev);\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\t/* VF enable interrupt autoclean */\n+\twr32(hw, TXGBE_VFIMC, TXGBE_VFIMC_MASK);\n+\n+\ttxgbe_flush(hw);\n+\n+\tintr->mask_misc = 0;\n+}\n+\n static int\n txgbevf_dev_close(struct rte_eth_dev *dev)\n {\n+\tstruct txgbe_hw *hw = TXGBE_DEV_HW(dev);\n \tPMD_INIT_FUNC_TRACE();\n \tif (rte_eal_process_type() != RTE_PROC_PRIMARY)\n \t\treturn 0;\n \n+\thw->mac.reset_hw(hw);\n+\n+\ttxgbe_dev_free_queues(dev);\n+\n+\t/* Disable the interrupts for VF */\n+\ttxgbevf_intr_disable(dev);\n+\n \treturn 0;\n }\n \n",
    "prefixes": [
        "v3",
        "02/17"
    ]
}