get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 139651,
    "url": "http://patchwork.dpdk.org/api/patches/139651/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/f154698c3c39eca373f588bb283e885b9b97300d.1713964708.git.anatoly.burakov@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<f154698c3c39eca373f588bb283e885b9b97300d.1713964708.git.anatoly.burakov@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/f154698c3c39eca373f588bb283e885b9b97300d.1713964708.git.anatoly.burakov@intel.com",
    "date": "2024-04-24T13:21:40",
    "name": "[v1,06/22] net/ixgbe/base: introduce new mailbox API",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "f6aec543960f7eed7678135669f4246490bbbd32",
    "submitter": {
        "id": 4,
        "url": "http://patchwork.dpdk.org/api/people/4/?format=api",
        "name": "Anatoly Burakov",
        "email": "anatoly.burakov@intel.com"
    },
    "delegate": {
        "id": 10,
        "url": "http://patchwork.dpdk.org/api/users/10/?format=api",
        "username": "bruce",
        "first_name": "Bruce",
        "last_name": "Richardson",
        "email": "bruce.richardson@intel.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/f154698c3c39eca373f588bb283e885b9b97300d.1713964708.git.anatoly.burakov@intel.com/mbox/",
    "series": [
        {
            "id": 31814,
            "url": "http://patchwork.dpdk.org/api/series/31814/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=31814",
            "date": "2024-04-24T13:21:34",
            "name": "Update IXGBE base driver",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/31814/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/139651/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/139651/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 4E45443EAD;\n\tWed, 24 Apr 2024 15:23:00 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 577C0434A1;\n\tWed, 24 Apr 2024 15:22:30 +0200 (CEST)",
            "from mgamail.intel.com (mgamail.intel.com [192.198.163.9])\n by mails.dpdk.org (Postfix) with ESMTP id 8555E43498\n for <dev@dpdk.org>; Wed, 24 Apr 2024 15:22:28 +0200 (CEST)",
            "from fmviesa006.fm.intel.com ([10.60.135.146])\n by fmvoesa103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 24 Apr 2024 06:22:28 -0700",
            "from silpixa00401119.ir.intel.com ([10.55.129.167])\n by fmviesa006.fm.intel.com with ESMTP; 24 Apr 2024 06:22:25 -0700"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1713964949; x=1745500949;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=bRJeAngSfQ7RpA3Zdte91PMUb79otTy2iLecU4nwdYI=;\n b=W8twoE5ZsyCS4YOSIaEegsh2r35UGQnwmNaxWDgHxNiQd0/6Pzg8T0JM\n 58+lpbc//2LyTU6B4Brtfzr919xO6zUy6LAO82LqEA5Y/ccN/nW2QVquC\n 9qluxRVPo0/mjlK9cgE7m4hzD/5XEe/wHVLCnrej04hLp53VM77ngpA1o\n TmQCt64pBoK2vPsyL52pM6WZx9lbMjBdJm568w1M/7KsUzZG4+JRGsweL\n 25rp0G536Kj5Twfo7kLHTE0CNbb4XoKk/GcRVbUp3JMWxWvuZYfVuzeHT\n saQDSGuILkLwNEfTe2UB4xnre0Rm1tNvAdbrtnJ8P4unr19EoR44tkVLJ g==;",
        "X-CSE-ConnectionGUID": [
            "RCHDl3NVQI+TUkWypjZGJg==",
            "tY5txZ3MTyuXdr0xKEPOig=="
        ],
        "X-CSE-MsgGUID": [
            "aRSjLPCVQSSQ3HrL9gjbkA==",
            "vryan7+gQ+aqp/L4GTjB2g=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6600,9927,11054\"; a=\"20289259\"",
            "E=Sophos;i=\"6.07,226,1708416000\"; d=\"scan'208\";a=\"20289259\"",
            "E=Sophos;i=\"6.07,226,1708416000\"; d=\"scan'208\";a=\"24749350\""
        ],
        "X-ExtLoop1": "1",
        "From": "Anatoly Burakov <anatoly.burakov@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Jakub Chylkowski <jakubx.chylkowski@intel.com>,\n\tvladimir.medvedkin@intel.com, bruce.richardson@intel.com,\n\tMichael@dpdk.org, Alice <alice.michael@intel.com>,\n\tPietruszewski@dpdk.org, Piotr <piotr.pietruszewski@intel.com>,\n\tSkajewski@dpdk.org, PiotrX <piotrx.skajewski@intel.com>",
        "Subject": "[PATCH v1 06/22] net/ixgbe/base: introduce new mailbox API",
        "Date": "Wed, 24 Apr 2024 14:21:40 +0100",
        "Message-ID": "\n <f154698c3c39eca373f588bb283e885b9b97300d.1713964708.git.anatoly.burakov@intel.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<cover.1713964707.git.anatoly.burakov@intel.com>",
        "References": "<cover.1713964707.git.anatoly.burakov@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "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"
    },
    "content": "From: Jakub Chylkowski <jakubx.chylkowski@intel.com>\n\nCurrent mailbox API does not work as described in documentation and\nis prone to errors (for example, it is doing locks on read). Introduce\nnew mailbox API and provide compatibility functions with old API.\n\nNew error codes have been introduced:\n- IXGBE_ERR_CONFIG - ixgbe_mbx_operations is not correctly set\n- IXGBE_ERR_TIMEOUT - mailbox operation, e.g. poll for message, timedout\n- IXGBE_ERR_MBX_NOMSG - no message available on read\n\nIn addition, some refactoring has been done: mailbox structures were\ndefined twice: in ixgbe_type.h and ixgbe_vf.h. Move them into\nixgbe_mbx.h as this header is dedicated for mailbox.\n\nSigned-off-by: Jakub Chylkowski <jakubx.chylkowski@intel.com>\nReviewed-by: Michael, Alice <alice.michael@intel.com>\nReviewed-by: Pietruszewski, Piotr <piotr.pietruszewski@intel.com>\nTested-by: Michael, Alice <alice.michael@intel.com>\nTested-by: Skajewski, PiotrX <piotrx.skajewski@intel.com>\n---\n drivers/net/ixgbe/base/ixgbe_82599.c |   4 +-\n drivers/net/ixgbe/base/ixgbe_hv_vf.c |   2 +-\n drivers/net/ixgbe/base/ixgbe_mbx.c   | 843 +++++++++++++++++++--------\n drivers/net/ixgbe/base/ixgbe_mbx.h   |  59 +-\n drivers/net/ixgbe/base/ixgbe_type.h  |  32 +-\n drivers/net/ixgbe/base/ixgbe_vf.c    |  42 +-\n drivers/net/ixgbe/base/ixgbe_x540.c  |   4 +-\n drivers/net/ixgbe/ixgbe_ethdev.c     |   6 +-\n drivers/net/ixgbe/ixgbe_pf.c         |   4 +-\n 9 files changed, 702 insertions(+), 294 deletions(-)",
    "diff": "diff --git a/drivers/net/ixgbe/base/ixgbe_82599.c b/drivers/net/ixgbe/base/ixgbe_82599.c\nindex c6e8b7e976..7d2938b253 100644\n--- a/drivers/net/ixgbe/base/ixgbe_82599.c\n+++ b/drivers/net/ixgbe/base/ixgbe_82599.c\n@@ -291,6 +291,7 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)\n \tstruct ixgbe_phy_info *phy = &hw->phy;\n \tstruct ixgbe_eeprom_info *eeprom = &hw->eeprom;\n \ts32 ret_val;\n+\tu16 i;\n \n \tDEBUGFUNC(\"ixgbe_init_ops_82599\");\n \n@@ -352,7 +353,8 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)\n \tmac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw))\n \t\t\t\t      & IXGBE_FWSM_MODE_MASK);\n \n-\thw->mbx.ops.init_params = ixgbe_init_mbx_params_pf;\n+\tfor (i = 0; i < 64; i++)\n+\t\thw->mbx.ops[i].init_params = ixgbe_init_mbx_params_pf;\n \n \t/* EEPROM */\n \teeprom->ops.read = ixgbe_read_eeprom_82599;\ndiff --git a/drivers/net/ixgbe/base/ixgbe_hv_vf.c b/drivers/net/ixgbe/base/ixgbe_hv_vf.c\nindex 4572411d39..34add03e8b 100644\n--- a/drivers/net/ixgbe/base/ixgbe_hv_vf.c\n+++ b/drivers/net/ixgbe/base/ixgbe_hv_vf.c\n@@ -97,7 +97,7 @@ static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw,\n \tUNREFERENCED_1PARAMETER(autoneg_wait_to_complete);\n \n \t/* If we were hit with a reset drop the link */\n-\tif (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout)\n+\tif (!mbx->ops[0].check_for_rst(hw, 0) || !mbx->timeout)\n \t\tmac->get_link_status = true;\n \n \tif (!mac->get_link_status)\ndiff --git a/drivers/net/ixgbe/base/ixgbe_mbx.c b/drivers/net/ixgbe/base/ixgbe_mbx.c\nindex d645dcf827..2dab347396 100644\n--- a/drivers/net/ixgbe/base/ixgbe_mbx.c\n+++ b/drivers/net/ixgbe/base/ixgbe_mbx.c\n@@ -5,6 +5,9 @@\n #include \"ixgbe_type.h\"\n #include \"ixgbe_mbx.h\"\n \n+STATIC s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id);\n+STATIC s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id);\n+\n /**\n  * ixgbe_read_mbx - Reads a message from the mailbox\n  * @hw: pointer to the HW structure\n@@ -17,42 +20,91 @@\n s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)\n {\n \tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n-\ts32 ret_val = IXGBE_ERR_MBX;\n \n \tDEBUGFUNC(\"ixgbe_read_mbx\");\n \n \t/* limit read to size of mailbox */\n-\tif (size > mbx->size)\n+\tif (size > mbx->size) {\n+\t\tERROR_REPORT3(IXGBE_ERROR_ARGUMENT,\n+\t\t\t      \"Invalid mailbox message size %u, changing to %u\",\n+\t\t\t      size, mbx->size);\n \t\tsize = mbx->size;\n+\t}\n \n-\tif (mbx->ops.read)\n-\t\tret_val = mbx->ops.read(hw, msg, size, mbx_id);\n+\tif (mbx->ops[mbx_id].read)\n+\t\treturn mbx->ops[mbx_id].read(hw, msg, size, mbx_id);\n+\n+\treturn IXGBE_ERR_CONFIG;\n+}\n+\n+/**\n+ * ixgbe_poll_mbx - Wait for message and read it from 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 read\n+ *\n+ * returns SUCCESS if it successfully read message from buffer\n+ **/\n+s32 ixgbe_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)\n+{\n+\tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n+\ts32 ret_val;\n+\n+\tDEBUGFUNC(\"ixgbe_poll_mbx\");\n+\n+\tif (!mbx->ops[mbx_id].read || !mbx->ops[mbx_id].check_for_msg ||\n+\t    !mbx->timeout)\n+\t\treturn IXGBE_ERR_CONFIG;\n+\n+\t/* limit read to size of mailbox */\n+\tif (size > mbx->size) {\n+\t\tERROR_REPORT3(IXGBE_ERROR_ARGUMENT,\n+\t\t\t      \"Invalid mailbox message size %u, changing to %u\",\n+\t\t\t      size, mbx->size);\n+\t\tsize = mbx->size;\n+\t}\n+\n+\tret_val = ixgbe_poll_for_msg(hw, mbx_id);\n+\t/* if ack received read message, otherwise we timed out */\n+\tif (!ret_val)\n+\t\treturn mbx->ops[mbx_id].read(hw, msg, size, mbx_id);\n \n \treturn ret_val;\n }\n \n /**\n- * ixgbe_write_mbx - Write a message to the mailbox\n+ * ixgbe_write_mbx - Write a message to the mailbox and 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\n+ * returns SUCCESS if it successfully copied message into the buffer and\n+ * received an ACK to that message within specified period\n  **/\n s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)\n {\n \tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n-\ts32 ret_val = IXGBE_SUCCESS;\n+\ts32 ret_val = IXGBE_ERR_MBX;\n \n \tDEBUGFUNC(\"ixgbe_write_mbx\");\n \n+\t/*\n+\t * exit if either we can't write, release\n+\t * or there is no timeout defined\n+\t */\n+\tif (!mbx->ops[mbx_id].write || !mbx->ops[mbx_id].check_for_ack ||\n+\t    !mbx->ops[mbx_id].release || !mbx->timeout)\n+\t\treturn IXGBE_ERR_CONFIG;\n+\n \tif (size > mbx->size) {\n-\t\tret_val = IXGBE_ERR_MBX;\n+\t\tret_val = IXGBE_ERR_PARAM;\n \t\tERROR_REPORT2(IXGBE_ERROR_ARGUMENT,\n-\t\t\t     \"Invalid mailbox message size %d\", size);\n-\t} else if (mbx->ops.write)\n-\t\tret_val = mbx->ops.write(hw, msg, size, mbx_id);\n+\t\t\t     \"Invalid mailbox message size %u\", size);\n+\t} else {\n+\t\tret_val = mbx->ops[mbx_id].write(hw, msg, size, mbx_id);\n+\t}\n \n \treturn ret_val;\n }\n@@ -67,12 +119,12 @@ s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)\n s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)\n {\n \tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n-\ts32 ret_val = IXGBE_ERR_MBX;\n+\ts32 ret_val = IXGBE_ERR_CONFIG;\n \n \tDEBUGFUNC(\"ixgbe_check_for_msg\");\n \n-\tif (mbx->ops.check_for_msg)\n-\t\tret_val = mbx->ops.check_for_msg(hw, mbx_id);\n+\tif (mbx->ops[mbx_id].check_for_msg)\n+\t\tret_val = mbx->ops[mbx_id].check_for_msg(hw, mbx_id);\n \n \treturn ret_val;\n }\n@@ -87,12 +139,12 @@ s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)\n s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)\n {\n \tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n-\ts32 ret_val = IXGBE_ERR_MBX;\n+\ts32 ret_val = IXGBE_ERR_CONFIG;\n \n \tDEBUGFUNC(\"ixgbe_check_for_ack\");\n \n-\tif (mbx->ops.check_for_ack)\n-\t\tret_val = mbx->ops.check_for_ack(hw, mbx_id);\n+\tif (mbx->ops[mbx_id].check_for_ack)\n+\t\tret_val = mbx->ops[mbx_id].check_for_ack(hw, mbx_id);\n \n \treturn ret_val;\n }\n@@ -107,12 +159,12 @@ s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)\n s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)\n {\n \tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n-\ts32 ret_val = IXGBE_ERR_MBX;\n+\ts32 ret_val = IXGBE_ERR_CONFIG;\n \n \tDEBUGFUNC(\"ixgbe_check_for_rst\");\n \n-\tif (mbx->ops.check_for_rst)\n-\t\tret_val = mbx->ops.check_for_rst(hw, mbx_id);\n+\tif (mbx->ops[mbx_id].check_for_rst)\n+\t\tret_val = mbx->ops[mbx_id].check_for_rst(hw, mbx_id);\n \n \treturn ret_val;\n }\n@@ -131,22 +183,23 @@ STATIC s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)\n \n \tDEBUGFUNC(\"ixgbe_poll_for_msg\");\n \n-\tif (!countdown || !mbx->ops.check_for_msg)\n-\t\tgoto out;\n+\tif (!countdown || !mbx->ops[mbx_id].check_for_msg)\n+\t\treturn IXGBE_ERR_CONFIG;\n \n-\twhile (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {\n+\twhile (countdown && mbx->ops[mbx_id].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+\tif (countdown == 0) {\n \t\tERROR_REPORT2(IXGBE_ERROR_POLLING,\n-\t\t\t   \"Polling for VF%d mailbox message timedout\", mbx_id);\n+\t\t\t   \"Polling for VF%u mailbox message timedout\", mbx_id);\n+\t\treturn IXGBE_ERR_TIMEOUT;\n+\t}\n \n-out:\n-\treturn countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;\n+\treturn IXGBE_SUCCESS;\n }\n \n /**\n@@ -163,114 +216,71 @@ STATIC s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)\n \n \tDEBUGFUNC(\"ixgbe_poll_for_ack\");\n \n-\tif (!countdown || !mbx->ops.check_for_ack)\n-\t\tgoto out;\n+\tif (!countdown || !mbx->ops[mbx_id].check_for_ack)\n+\t\treturn IXGBE_ERR_CONFIG;\n \n-\twhile (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {\n+\twhile (countdown && mbx->ops[mbx_id].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+\tif (countdown == 0) {\n \t\tERROR_REPORT2(IXGBE_ERROR_POLLING,\n-\t\t\t     \"Polling for VF%d mailbox ack timedout\", mbx_id);\n+\t\t\t     \"Polling for VF%u mailbox ack timedout\", mbx_id);\n+\t\treturn IXGBE_ERR_TIMEOUT;\n+\t}\n \n-out:\n-\treturn countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;\n+\treturn IXGBE_SUCCESS;\n }\n \n /**\n- * ixgbe_read_posted_mbx - Wait for message notification and receive message\n+ * ixgbe_read_mailbox_vf - read VF's mailbox register\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+ * This function is used to read the mailbox register dedicated for VF without\n+ * losing the read to clear status bits.\n  **/\n-s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)\n+STATIC u32 ixgbe_read_mailbox_vf(struct ixgbe_hw *hw)\n {\n-\tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n-\ts32 ret_val = IXGBE_ERR_MBX;\n+\tu32 vf_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);\n \n-\tDEBUGFUNC(\"ixgbe_read_posted_mbx\");\n+\tvf_mailbox |= hw->mbx.vf_mailbox;\n+\thw->mbx.vf_mailbox |= vf_mailbox & IXGBE_VFMAILBOX_R2C_BITS;\n \n-\tif (!mbx->ops.read)\n-\t\tgoto out;\n-\n-\tret_val = ixgbe_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->ops.read(hw, msg, size, mbx_id);\n-out:\n-\treturn ret_val;\n+\treturn vf_mailbox;\n }\n \n-/**\n- * ixgbe_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 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,\n-\t\t\t   u16 mbx_id)\n+STATIC void ixgbe_clear_msg_vf(struct ixgbe_hw *hw)\n {\n-\tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n-\ts32 ret_val = IXGBE_ERR_MBX;\n-\n-\tDEBUGFUNC(\"ixgbe_write_posted_mbx\");\n-\n-\t/* exit if either we can't write or there isn't a defined timeout */\n-\tif (!mbx->ops.write || !mbx->timeout)\n-\t\tgoto out;\n-\n-\t/* send msg */\n-\tret_val = mbx->ops.write(hw, msg, size, mbx_id);\n+\tu32 vf_mailbox = ixgbe_read_mailbox_vf(hw);\n \n-\t/* if msg sent wait until we receive an ack */\n-\tif (!ret_val)\n-\t\tret_val = ixgbe_poll_for_ack(hw, mbx_id);\n-out:\n-\treturn ret_val;\n+\tif (vf_mailbox & IXGBE_VFMAILBOX_PFSTS) {\n+\t\thw->mbx.stats.reqs++;\n+\t\thw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFSTS;\n+\t}\n }\n \n-/**\n- * ixgbe_init_mbx_ops_generic - Initialize MB function pointers\n- * @hw: pointer to the HW structure\n- *\n- * Setups up the mailbox read and write message function pointers\n- **/\n-void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw)\n+STATIC void ixgbe_clear_ack_vf(struct ixgbe_hw *hw)\n {\n-\tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n+\tu32 vf_mailbox = ixgbe_read_mailbox_vf(hw);\n \n-\tmbx->ops.read_posted = ixgbe_read_posted_mbx;\n-\tmbx->ops.write_posted = ixgbe_write_posted_mbx;\n+\tif (vf_mailbox & IXGBE_VFMAILBOX_PFACK) {\n+\t\thw->mbx.stats.acks++;\n+\t\thw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFACK;\n+\t}\n }\n \n-/**\n- * ixgbe_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 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw)\n+STATIC void ixgbe_clear_rst_vf(struct ixgbe_hw *hw)\n {\n-\tu32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);\n-\n-\tv2p_mailbox |= hw->mbx.v2p_mailbox;\n-\thw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;\n+\tu32 vf_mailbox = ixgbe_read_mailbox_vf(hw);\n \n-\treturn v2p_mailbox;\n+\tif (vf_mailbox & (IXGBE_VFMAILBOX_RSTI | IXGBE_VFMAILBOX_RSTD)) {\n+\t\thw->mbx.stats.rsts++;\n+\t\thw->mbx.vf_mailbox &= ~(IXGBE_VFMAILBOX_RSTI |\n+\t\t\t\t\tIXGBE_VFMAILBOX_RSTD);\n+\t}\n }\n \n /**\n@@ -283,15 +293,12 @@ STATIC u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw)\n  **/\n STATIC s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)\n {\n-\tu32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw);\n-\ts32 ret_val = IXGBE_ERR_MBX;\n+\tu32 vf_mailbox = ixgbe_read_mailbox_vf(hw);\n \n-\tif (v2p_mailbox & mask)\n-\t\tret_val = IXGBE_SUCCESS;\n+\tif (vf_mailbox & mask)\n+\t\treturn IXGBE_SUCCESS;\n \n-\thw->mbx.v2p_mailbox &= ~mask;\n-\n-\treturn ret_val;\n+\treturn IXGBE_ERR_MBX;\n }\n \n /**\n@@ -303,17 +310,13 @@ STATIC s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)\n  **/\n STATIC s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)\n {\n-\ts32 ret_val = IXGBE_ERR_MBX;\n-\n \tUNREFERENCED_1PARAMETER(mbx_id);\n \tDEBUGFUNC(\"ixgbe_check_for_msg_vf\");\n \n-\tif (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {\n-\t\tret_val = IXGBE_SUCCESS;\n-\t\thw->mbx.stats.reqs++;\n-\t}\n+\tif (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS))\n+\t\treturn IXGBE_SUCCESS;\n \n-\treturn ret_val;\n+\treturn IXGBE_ERR_MBX;\n }\n \n /**\n@@ -325,17 +328,16 @@ STATIC s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)\n  **/\n STATIC s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)\n {\n-\ts32 ret_val = IXGBE_ERR_MBX;\n-\n \tUNREFERENCED_1PARAMETER(mbx_id);\n \tDEBUGFUNC(\"ixgbe_check_for_ack_vf\");\n \n \tif (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {\n-\t\tret_val = IXGBE_SUCCESS;\n-\t\thw->mbx.stats.acks++;\n+\t\t/* TODO: should this be autocleared? */\n+\t\tixgbe_clear_ack_vf(hw);\n+\t\treturn IXGBE_SUCCESS;\n \t}\n \n-\treturn ret_val;\n+\treturn IXGBE_ERR_MBX;\n }\n \n /**\n@@ -347,18 +349,17 @@ STATIC s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)\n  **/\n STATIC s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)\n {\n-\ts32 ret_val = IXGBE_ERR_MBX;\n-\n \tUNREFERENCED_1PARAMETER(mbx_id);\n \tDEBUGFUNC(\"ixgbe_check_for_rst_vf\");\n \n-\tif (!ixgbe_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |\n-\t    IXGBE_VFMAILBOX_RSTI))) {\n-\t\tret_val = IXGBE_SUCCESS;\n-\t\thw->mbx.stats.rsts++;\n+\tif (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_RSTI |\n+\t\t\t\t\t  IXGBE_VFMAILBOX_RSTD)) {\n+\t\t/* TODO: should this be autocleared? */\n+\t\tixgbe_clear_rst_vf(hw);\n+\t\treturn IXGBE_SUCCESS;\n \t}\n \n-\treturn ret_val;\n+\treturn IXGBE_ERR_MBX;\n }\n \n /**\n@@ -369,20 +370,114 @@ STATIC s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)\n  **/\n STATIC s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)\n {\n+\tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n+\tint countdown = mbx->timeout;\n \ts32 ret_val = IXGBE_ERR_MBX;\n+\tu32 vf_mailbox;\n \n \tDEBUGFUNC(\"ixgbe_obtain_mbx_lock_vf\");\n \n-\t/* Take ownership of the buffer */\n-\tIXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);\n+\tif (!mbx->timeout)\n+\t\treturn IXGBE_ERR_CONFIG;\n \n-\t/* reserve mailbox for vf use */\n-\tif (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)\n-\t\tret_val = IXGBE_SUCCESS;\n+\twhile (countdown--) {\n+\t\t/* Reserve mailbox for VF use */\n+\t\tvf_mailbox = ixgbe_read_mailbox_vf(hw);\n+\t\tvf_mailbox |= IXGBE_VFMAILBOX_VFU;\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);\n+\n+\t\t/* Verify that VF is the owner of the lock */\n+\t\tif (ixgbe_read_mailbox_vf(hw) & IXGBE_VFMAILBOX_VFU) {\n+\t\t\tret_val = IXGBE_SUCCESS;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\t/* Wait a bit before trying again */\n+\t\tusec_delay(mbx->usec_delay);\n+\t}\n+\n+\tif (ret_val != IXGBE_SUCCESS) {\n+\t\tERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,\n+\t\t\t\t\"Failed to obtain mailbox lock\");\n+\t\tret_val = IXGBE_ERR_TIMEOUT;\n+\t}\n \n \treturn ret_val;\n }\n \n+/**\n+ * ixgbe_release_mbx_lock_dummy - release mailbox lock\n+ * @hw: pointer to the HW structure\n+ * @mbx_id: id of mailbox to read\n+ **/\n+STATIC void ixgbe_release_mbx_lock_dummy(struct ixgbe_hw *hw, u16 mbx_id)\n+{\n+\tUNREFERENCED_2PARAMETER(hw, mbx_id);\n+\n+\tDEBUGFUNC(\"ixgbe_release_mbx_lock_dummy\");\n+}\n+\n+/**\n+ * ixgbe_release_mbx_lock_vf - release mailbox lock\n+ * @hw: pointer to the HW structure\n+ * @mbx_id: id of mailbox to read\n+ **/\n+STATIC void ixgbe_release_mbx_lock_vf(struct ixgbe_hw *hw, u16 mbx_id)\n+{\n+\tu32 vf_mailbox;\n+\n+\tUNREFERENCED_1PARAMETER(mbx_id);\n+\n+\tDEBUGFUNC(\"ixgbe_release_mbx_lock_vf\");\n+\n+\t/* Return ownership of the buffer */\n+\tvf_mailbox = ixgbe_read_mailbox_vf(hw);\n+\tvf_mailbox &= ~IXGBE_VFMAILBOX_VFU;\n+\tIXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);\n+}\n+\n+/**\n+ * ixgbe_write_mbx_vf_legacy - 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+STATIC s32 ixgbe_write_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,\n+\t\t\t\t     u16 mbx_id)\n+{\n+\ts32 ret_val;\n+\tu16 i;\n+\n+\tUNREFERENCED_1PARAMETER(mbx_id);\n+\tDEBUGFUNC(\"ixgbe_write_mbx_vf_legacy\");\n+\n+\t/* lock the mailbox to prevent pf/vf race condition */\n+\tret_val = ixgbe_obtain_mbx_lock_vf(hw);\n+\tif (ret_val)\n+\t\treturn ret_val;\n+\n+\t/* flush msg and acks as we are overwriting the message buffer */\n+\tixgbe_check_for_msg_vf(hw, 0);\n+\tixgbe_clear_msg_vf(hw);\n+\tixgbe_check_for_ack_vf(hw, 0);\n+\tixgbe_clear_ack_vf(hw);\n+\n+\t/* copy the caller specified message to the mailbox memory buffer */\n+\tfor (i = 0; i < size; i++)\n+\t\tIXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);\n+\n+\t/* update stats */\n+\thw->mbx.stats.msgs_tx++;\n+\n+\t/* interrupt the PF to tell it a message has been sent */\n+\tIXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);\n+\n+\treturn IXGBE_SUCCESS;\n+}\n+\n /**\n  * ixgbe_write_mbx_vf - Write a message to the mailbox\n  * @hw: pointer to the HW structure\n@@ -395,6 +490,7 @@ STATIC s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)\n STATIC s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,\n \t\t\t      u16 mbx_id)\n {\n+\tu32 vf_mailbox;\n \ts32 ret_val;\n \tu16 i;\n \n@@ -405,11 +501,11 @@ STATIC s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,\n \t/* lock the mailbox to prevent pf/vf race condition */\n \tret_val = ixgbe_obtain_mbx_lock_vf(hw);\n \tif (ret_val)\n-\t\tgoto out_no_write;\n+\t\tgoto out;\n \n \t/* flush msg and acks as we are overwriting the message buffer */\n-\tixgbe_check_for_msg_vf(hw, 0);\n-\tixgbe_check_for_ack_vf(hw, 0);\n+\tixgbe_clear_msg_vf(hw);\n+\tixgbe_clear_ack_vf(hw);\n \n \t/* copy the caller specified message to the mailbox memory buffer */\n \tfor (i = 0; i < size; i++)\n@@ -418,13 +514,56 @@ STATIC s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,\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-\tIXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);\n+\t/* interrupt the PF to tell it a message has been sent */\n+\tvf_mailbox = ixgbe_read_mailbox_vf(hw);\n+\tvf_mailbox |= IXGBE_VFMAILBOX_REQ;\n+\tIXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);\n+\n+\t/* if msg sent wait until we receive an ack */\n+\tixgbe_poll_for_ack(hw, mbx_id);\n+\n+out:\n+\thw->mbx.ops[mbx_id].release(hw, mbx_id);\n \n-out_no_write:\n \treturn ret_val;\n }\n \n+/**\n+ * ixgbe_read_mbx_vf_legacy - 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+STATIC s32 ixgbe_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,\n+\t\t\t\t    u16 mbx_id)\n+{\n+\ts32 ret_val;\n+\tu16 i;\n+\n+\tDEBUGFUNC(\"ixgbe_read_mbx_vf_legacy\");\n+\tUNREFERENCED_1PARAMETER(mbx_id);\n+\n+\t/* lock the mailbox to prevent pf/vf race condition */\n+\tret_val = ixgbe_obtain_mbx_lock_vf(hw);\n+\tif (ret_val)\n+\t\treturn ret_val;\n+\n+\t/* copy the message from the mailbox memory buffer */\n+\tfor (i = 0; i < size; i++)\n+\t\tmsg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);\n+\n+\t/* Acknowledge receipt and release mailbox, then we're done */\n+\tIXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);\n+\n+\t/* update stats */\n+\thw->mbx.stats.msgs_rx++;\n+\n+\treturn IXGBE_SUCCESS;\n+}\n+\n /**\n  * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf\n  * @hw: pointer to the HW structure\n@@ -437,55 +576,58 @@ STATIC s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,\n STATIC s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,\n \t\t\t     u16 mbx_id)\n {\n-\ts32 ret_val = IXGBE_SUCCESS;\n+\tu32 vf_mailbox;\n+\ts32 ret_val;\n \tu16 i;\n \n \tDEBUGFUNC(\"ixgbe_read_mbx_vf\");\n \tUNREFERENCED_1PARAMETER(mbx_id);\n \n-\t/* lock the mailbox to prevent pf/vf race condition */\n-\tret_val = ixgbe_obtain_mbx_lock_vf(hw);\n-\tif (ret_val)\n-\t\tgoto out_no_read;\n+\t/* check if there is a message from PF */\n+\tret_val = ixgbe_check_for_msg_vf(hw, 0);\n+\tif (ret_val != IXGBE_SUCCESS)\n+\t\treturn IXGBE_ERR_MBX_NOMSG;\n+\n+\tixgbe_clear_msg_vf(hw);\n \n \t/* copy the message from the mailbox memory buffer */\n \tfor (i = 0; i < size; i++)\n \t\tmsg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);\n \n-\t/* Acknowledge receipt and release mailbox, then we're done */\n-\tIXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);\n+\t/* Acknowledge receipt */\n+\tvf_mailbox = ixgbe_read_mailbox_vf(hw);\n+\tvf_mailbox |= IXGBE_VFMAILBOX_ACK;\n+\tIXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);\n \n \t/* update stats */\n \thw->mbx.stats.msgs_rx++;\n \n-out_no_read:\n-\treturn ret_val;\n+\treturn IXGBE_SUCCESS;\n }\n \n /**\n  * ixgbe_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+ * Initializes single set the hw->mbx struct to correct values for vf mailbox\n+ * Set of legacy functions is being used here\n  */\n void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)\n {\n \tstruct ixgbe_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-\tmbx->timeout = 0;\n+\tmbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;\n \tmbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;\n \n \tmbx->size = IXGBE_VFMAILBOX_SIZE;\n \n-\tmbx->ops.read = ixgbe_read_mbx_vf;\n-\tmbx->ops.write = ixgbe_write_mbx_vf;\n-\tmbx->ops.read_posted = ixgbe_read_posted_mbx;\n-\tmbx->ops.write_posted = ixgbe_write_posted_mbx;\n-\tmbx->ops.check_for_msg = ixgbe_check_for_msg_vf;\n-\tmbx->ops.check_for_ack = ixgbe_check_for_ack_vf;\n-\tmbx->ops.check_for_rst = ixgbe_check_for_rst_vf;\n+\t/* VF has only one mailbox connection, no need for more IDs */\n+\tmbx->ops[0].release = ixgbe_release_mbx_lock_dummy;\n+\tmbx->ops[0].read = ixgbe_read_mbx_vf_legacy;\n+\tmbx->ops[0].write = ixgbe_write_mbx_vf_legacy;\n+\tmbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;\n+\tmbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;\n+\tmbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;\n \n \tmbx->stats.msgs_tx = 0;\n \tmbx->stats.msgs_rx = 0;\n@@ -494,54 +636,109 @@ void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)\n \tmbx->stats.rsts = 0;\n }\n \n+/**\n+ * ixgbe_upgrade_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 ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw *hw)\n+{\n+\tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n+\n+\tmbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;\n+\tmbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;\n+\n+\tmbx->size = IXGBE_VFMAILBOX_SIZE;\n+\n+\t/* VF has only one mailbox connection, no need for more IDs */\n+\tmbx->ops[0].release = ixgbe_release_mbx_lock_vf;\n+\tmbx->ops[0].read = ixgbe_read_mbx_vf;\n+\tmbx->ops[0].write = ixgbe_write_mbx_vf;\n+\tmbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;\n+\tmbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;\n+\tmbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;\n+\tmbx->ops[0].clear = NULL;\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 void ixgbe_clear_msg_pf(struct ixgbe_hw *hw, u16 vf_id)\n+{\n+\tu32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);\n+\ts32 index = IXGBE_PFMBICR_INDEX(vf_id);\n+\tu32 pfmbicr;\n+\n+\tpfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));\n+\n+\tif (pfmbicr & (IXGBE_PFMBICR_VFREQ_VF1 << vf_shift))\n+\t\thw->mbx.stats.reqs++;\n+\n+\tIXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),\n+\t\t\tIXGBE_PFMBICR_VFREQ_VF1 << vf_shift);\n+}\n+\n+STATIC void ixgbe_clear_ack_pf(struct ixgbe_hw *hw, u16 vf_id)\n+{\n+\tu32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);\n+\ts32 index = IXGBE_PFMBICR_INDEX(vf_id);\n+\tu32 pfmbicr;\n+\n+\tpfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));\n+\n+\tif (pfmbicr & (IXGBE_PFMBICR_VFACK_VF1 << vf_shift))\n+\t\thw->mbx.stats.acks++;\n+\n+\tIXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),\n+\t\t\tIXGBE_PFMBICR_VFACK_VF1 << vf_shift);\n+}\n+\n STATIC s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)\n {\n \tu32 pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));\n-\ts32 ret_val = IXGBE_ERR_MBX;\n \n-\tif (pfmbicr & mask) {\n-\t\tret_val = IXGBE_SUCCESS;\n-\t\tIXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index), mask);\n-\t}\n+\tif (pfmbicr & mask)\n+\t\treturn IXGBE_SUCCESS;\n \n-\treturn ret_val;\n+\treturn IXGBE_ERR_MBX;\n }\n \n /**\n  * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail\n  * @hw: pointer to the HW structure\n- * @vf_number: the VF index\n+ * @vf_id: the VF index\n  *\n  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX\n  **/\n-STATIC s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)\n+STATIC s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_id)\n {\n-\tu32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_number);\n-\ts32 index = IXGBE_PFMBICR_INDEX(vf_number);\n-\ts32 ret_val = IXGBE_ERR_MBX;\n+\tu32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);\n+\ts32 index = IXGBE_PFMBICR_INDEX(vf_id);\n \n \tDEBUGFUNC(\"ixgbe_check_for_msg_pf\");\n \n \tif (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFREQ_VF1 << vf_shift,\n-\t\t\t\t    index)) {\n-\t\tret_val = IXGBE_SUCCESS;\n-\t\thw->mbx.stats.reqs++;\n-\t}\n+\t\t\t\t    index))\n+\t\treturn IXGBE_SUCCESS;\n \n-\treturn ret_val;\n+\treturn IXGBE_ERR_MBX;\n }\n \n /**\n  * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed\n  * @hw: pointer to the HW structure\n- * @vf_number: the VF index\n+ * @vf_id: the VF index\n  *\n  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX\n  **/\n-STATIC s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)\n+STATIC s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_id)\n {\n-\tu32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_number);\n-\ts32 index = IXGBE_PFMBICR_INDEX(vf_number);\n+\tu32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);\n+\ts32 index = IXGBE_PFMBICR_INDEX(vf_id);\n \ts32 ret_val = IXGBE_ERR_MBX;\n \n \tDEBUGFUNC(\"ixgbe_check_for_ack_pf\");\n@@ -549,7 +746,8 @@ STATIC s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)\n \tif (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFACK_VF1 << vf_shift,\n \t\t\t\t    index)) {\n \t\tret_val = IXGBE_SUCCESS;\n-\t\thw->mbx.stats.acks++;\n+\t\t/* TODO: should this be autocleared? */\n+\t\tixgbe_clear_ack_pf(hw, vf_id);\n \t}\n \n \treturn ret_val;\n@@ -558,14 +756,14 @@ STATIC s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)\n /**\n  * ixgbe_check_for_rst_pf - checks to see if the VF has reset\n  * @hw: pointer to the HW structure\n- * @vf_number: the VF index\n+ * @vf_id: the VF index\n  *\n  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX\n  **/\n-STATIC s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)\n+STATIC s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_id)\n {\n-\tu32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_number);\n-\tu32 index = IXGBE_PFVFLRE_INDEX(vf_number);\n+\tu32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_id);\n+\tu32 index = IXGBE_PFVFLRE_INDEX(vf_id);\n \ts32 ret_val = IXGBE_ERR_MBX;\n \tu32 vflre = 0;\n \n@@ -597,121 +795,268 @@ STATIC s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)\n /**\n  * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock\n  * @hw: pointer to the HW structure\n- * @vf_number: the VF index\n+ * @vf_id: the VF index\n  *\n  * return SUCCESS if we obtained the mailbox lock\n  **/\n-STATIC s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)\n+STATIC s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)\n {\n+\tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n+\tint countdown = mbx->timeout;\n \ts32 ret_val = IXGBE_ERR_MBX;\n-\tu32 p2v_mailbox;\n+\tu32 pf_mailbox;\n \n \tDEBUGFUNC(\"ixgbe_obtain_mbx_lock_pf\");\n \n-\t/* Take ownership of the buffer */\n-\tIXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);\n+\tif (!mbx->timeout)\n+\t\treturn IXGBE_ERR_CONFIG;\n \n-\t/* reserve mailbox for vf use */\n-\tp2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));\n-\tif (p2v_mailbox & IXGBE_PFMAILBOX_PFU)\n-\t\tret_val = IXGBE_SUCCESS;\n-\telse\n-\t\tERROR_REPORT2(IXGBE_ERROR_POLLING,\n-\t\t\t   \"Failed to obtain mailbox lock for VF%d\", vf_number);\n+\twhile (countdown--) {\n+\t\t/* Reserve mailbox for PF use */\n+\t\tpf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));\n+\t\tpf_mailbox |= IXGBE_PFMAILBOX_PFU;\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);\n \n+\t\t/* Verify that PF is the owner of the lock */\n+\t\tpf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));\n+\t\tif (pf_mailbox & IXGBE_PFMAILBOX_PFU) {\n+\t\t\tret_val = IXGBE_SUCCESS;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\t/* Wait a bit before trying again */\n+\t\tusec_delay(mbx->usec_delay);\n+\t}\n+\n+\tif (ret_val != IXGBE_SUCCESS) {\n+\t\tERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,\n+\t\t\t      \"Failed to obtain mailbox lock\");\n+\t\tret_val = IXGBE_ERR_TIMEOUT;\n+\t}\n \n \treturn ret_val;\n }\n \n+/**\n+ * ixgbe_release_mbx_lock_pf - release mailbox lock\n+ * @hw: pointer to the HW structure\n+ * @vf_id: the VF index\n+ **/\n+STATIC void ixgbe_release_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)\n+{\n+\tu32 pf_mailbox;\n+\n+\tDEBUGFUNC(\"ixgbe_release_mbx_lock_pf\");\n+\n+\t/* Return ownership of the buffer */\n+\tpf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));\n+\tpf_mailbox &= ~IXGBE_PFMAILBOX_PFU;\n+\tIXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);\n+}\n+\n+/**\n+ * ixgbe_write_mbx_pf_legacy - Places a message in the mailbox\n+ * @hw: pointer to the HW structure\n+ * @msg: The message buffer\n+ * @size: Length of buffer\n+ * @vf_id: the VF index\n+ *\n+ * returns SUCCESS if it successfully copied message into the buffer\n+ **/\n+STATIC s32 ixgbe_write_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,\n+\t\t\t\t     u16 vf_id)\n+{\n+\ts32 ret_val;\n+\tu16 i;\n+\n+\tDEBUGFUNC(\"ixgbe_write_mbx_pf_legacy\");\n+\n+\t/* lock the mailbox to prevent pf/vf race condition */\n+\tret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);\n+\tif (ret_val)\n+\t\treturn ret_val;\n+\n+\t/* flush msg and acks as we are overwriting the message buffer */\n+\tixgbe_check_for_msg_pf(hw, vf_id);\n+\tixgbe_clear_msg_pf(hw, vf_id);\n+\tixgbe_check_for_ack_pf(hw, vf_id);\n+\tixgbe_clear_ack_pf(hw, vf_id);\n+\n+\t/* copy the caller specified message to the mailbox memory buffer */\n+\tfor (i = 0; i < size; i++)\n+\t\tIXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);\n+\n+\t/* Interrupt VF to tell it a message has been sent and release buffer*/\n+\tIXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_STS);\n+\n+\t/* update stats */\n+\thw->mbx.stats.msgs_tx++;\n+\n+\treturn IXGBE_SUCCESS;\n+}\n+\n /**\n  * ixgbe_write_mbx_pf - Places a message in the mailbox\n  * @hw: pointer to the HW structure\n  * @msg: The message buffer\n  * @size: Length of buffer\n- * @vf_number: the VF index\n+ * @vf_id: the VF index\n  *\n  * returns SUCCESS if it successfully copied message into the buffer\n  **/\n STATIC s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,\n-\t\t\t      u16 vf_number)\n+\t\t\t      u16 vf_id)\n {\n+\tu32 pf_mailbox;\n \ts32 ret_val;\n \tu16 i;\n \n \tDEBUGFUNC(\"ixgbe_write_mbx_pf\");\n \n \t/* lock the mailbox to prevent pf/vf race condition */\n-\tret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);\n+\tret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);\n \tif (ret_val)\n-\t\tgoto out_no_write;\n+\t\tgoto out;\n \n \t/* flush msg and acks as we are overwriting the message buffer */\n-\tixgbe_check_for_msg_pf(hw, vf_number);\n-\tixgbe_check_for_ack_pf(hw, vf_number);\n+\tixgbe_clear_msg_pf(hw, vf_id);\n+\tixgbe_clear_ack_pf(hw, vf_id);\n \n \t/* copy the caller specified message to the mailbox memory buffer */\n \tfor (i = 0; i < size; i++)\n-\t\tIXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);\n+\t\tIXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);\n \n-\t/* Interrupt VF to tell it a message has been sent and release buffer*/\n-\tIXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);\n+\t/* Interrupt VF to tell it a message has been sent */\n+\tpf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));\n+\tpf_mailbox |= IXGBE_PFMAILBOX_STS;\n+\tIXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);\n+\n+\t/* if msg sent wait until we receive an ack */\n+\tixgbe_poll_for_ack(hw, vf_id);\n \n \t/* update stats */\n \thw->mbx.stats.msgs_tx++;\n \n-out_no_write:\n+out:\n+\thw->mbx.ops[vf_id].release(hw, vf_id);\n+\n \treturn ret_val;\n \n }\n \n+/**\n+ * ixgbe_read_mbx_pf_legacy - Read a message from the mailbox\n+ * @hw: pointer to the HW structure\n+ * @msg: The message buffer\n+ * @size: Length of buffer\n+ * @vf_id: the VF index\n+ *\n+ * This function copies a message from the mailbox buffer to the caller's\n+ * memory buffer.  The presumption is that the caller knows that there was\n+ * a message due to a VF request so no polling for message is needed.\n+ **/\n+STATIC s32 ixgbe_read_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,\n+\t\t\t\t    u16 vf_id)\n+{\n+\ts32 ret_val;\n+\tu16 i;\n+\n+\tDEBUGFUNC(\"ixgbe_read_mbx_pf_legacy\");\n+\n+\t/* lock the mailbox to prevent pf/vf race condition */\n+\tret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);\n+\tif (ret_val != IXGBE_SUCCESS)\n+\t\treturn ret_val;\n+\n+\t/* copy the message to the mailbox memory buffer */\n+\tfor (i = 0; i < size; i++)\n+\t\tmsg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);\n+\n+\t/* Acknowledge the message and release buffer */\n+\tIXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_ACK);\n+\n+\t/* update stats */\n+\thw->mbx.stats.msgs_rx++;\n+\n+\treturn IXGBE_SUCCESS;\n+}\n+\n /**\n  * ixgbe_read_mbx_pf - Read a message from the mailbox\n  * @hw: pointer to the HW structure\n  * @msg: The message buffer\n  * @size: Length of buffer\n- * @vf_number: the VF index\n+ * @vf_id: the VF index\n  *\n  * This function copies a message from the mailbox buffer to the caller's\n  * memory buffer.  The presumption is that the caller knows that there was\n  * a message due to a VF request so no polling for message is needed.\n  **/\n STATIC s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,\n-\t\t\t     u16 vf_number)\n+\t\t\t     u16 vf_id)\n {\n+\tu32 pf_mailbox;\n \ts32 ret_val;\n \tu16 i;\n \n \tDEBUGFUNC(\"ixgbe_read_mbx_pf\");\n \n-\t/* lock the mailbox to prevent pf/vf race condition */\n-\tret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);\n-\tif (ret_val)\n-\t\tgoto out_no_read;\n+\t/* check if there is a message from VF */\n+\tret_val = ixgbe_check_for_msg_pf(hw, vf_id);\n+\tif (ret_val != IXGBE_SUCCESS)\n+\t\treturn IXGBE_ERR_MBX_NOMSG;\n+\n+\tixgbe_clear_msg_pf(hw, vf_id);\n \n \t/* copy the message to the mailbox memory buffer */\n \tfor (i = 0; i < size; i++)\n-\t\tmsg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);\n+\t\tmsg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);\n \n \t/* Acknowledge the message and release buffer */\n-\tIXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);\n+\tpf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));\n+\tpf_mailbox |= IXGBE_PFMAILBOX_ACK;\n+\tIXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);\n \n \t/* update stats */\n \thw->mbx.stats.msgs_rx++;\n \n-out_no_read:\n-\treturn ret_val;\n+\treturn IXGBE_SUCCESS;\n+}\n+\n+/**\n+ * ixgbe_init_mbx_params_pf_id - set initial values for pf mailbox\n+ * @hw: pointer to the HW structure\n+ * @vf_id: the VF index\n+ *\n+ * Initializes single set of the hw->mbx struct to correct values for pf mailbox\n+ * Set of legacy functions is being used here\n+ */\n+void ixgbe_init_mbx_params_pf_id(struct ixgbe_hw *hw, u16 vf_id)\n+{\n+\tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n+\n+\tmbx->ops[vf_id].release = ixgbe_release_mbx_lock_dummy;\n+\tmbx->ops[vf_id].read = ixgbe_read_mbx_pf_legacy;\n+\tmbx->ops[vf_id].write = ixgbe_write_mbx_pf_legacy;\n+\tmbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;\n+\tmbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;\n+\tmbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;\n }\n \n /**\n  * ixgbe_init_mbx_params_pf - set initial values for pf mailbox\n  * @hw: pointer to the HW structure\n  *\n- * Initializes the hw->mbx struct to correct values for pf mailbox\n+ * Initializes all sets of the hw->mbx struct to correct values for pf\n+ * mailbox. One set corresponds to single VF. It also initializes counters\n+ * and general variables. A set of legacy functions is used by default.\n  */\n void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)\n {\n+\tu16 i;\n \tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n \n+\t/* Ensure we are not calling this function from VF */\n \tif (hw->mac.type != ixgbe_mac_82599EB &&\n \t    hw->mac.type != ixgbe_mac_X550 &&\n \t    hw->mac.type != ixgbe_mac_X550EM_x &&\n@@ -719,18 +1064,58 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)\n \t    hw->mac.type != ixgbe_mac_X540)\n \t\treturn;\n \n-\tmbx->timeout = 0;\n-\tmbx->usec_delay = 0;\n+\t/* Initialize common mailbox settings */\n+\tmbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;\n+\tmbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;\n+\tmbx->size = IXGBE_VFMAILBOX_SIZE;\n+\n+\t/* Initialize counters with zeroes */\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+\t/* No matter of VF number, we initialize params for all 64 VFs. */\n+\t/* TODO: 1. Add a define for max VF and refactor SHARED to get rid\n+\t * of magic number for that (63 or 64 depending on use case.)\n+\t * 2. rewrite the code to dynamically allocate mbx->ops[vf_id] for\n+\t * certain number of VFs instead of default maximum value of 64 (0..63)\n+\t */\n+\tfor (i = 0; i < 64; i++)\n+\t\tixgbe_init_mbx_params_pf_id(hw, i);\n+}\n+\n+/**\n+ * ixgbe_upgrade_mbx_params_pf - Upgrade initial values for pf mailbox\n+ * @hw: pointer to the HW structure\n+ * @vf_id: the VF index\n+ *\n+ * Initializes the hw->mbx struct to new function set for improved\n+ * stability and handling of messages.\n+ */\n+void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id)\n+{\n+\tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n+\n+\t/* Ensure we are not calling this function from VF */\n+\tif (hw->mac.type != ixgbe_mac_82599EB &&\n+\t    hw->mac.type != ixgbe_mac_X550 &&\n+\t    hw->mac.type != ixgbe_mac_X550EM_x &&\n+\t    hw->mac.type != ixgbe_mac_X550EM_a &&\n+\t    hw->mac.type != ixgbe_mac_X540)\n+\t\treturn;\n \n+\tmbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;\n+\tmbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;\n \tmbx->size = IXGBE_VFMAILBOX_SIZE;\n \n-\tmbx->ops.read = ixgbe_read_mbx_pf;\n-\tmbx->ops.write = ixgbe_write_mbx_pf;\n-\tmbx->ops.read_posted = ixgbe_read_posted_mbx;\n-\tmbx->ops.write_posted = ixgbe_write_posted_mbx;\n-\tmbx->ops.check_for_msg = ixgbe_check_for_msg_pf;\n-\tmbx->ops.check_for_ack = ixgbe_check_for_ack_pf;\n-\tmbx->ops.check_for_rst = ixgbe_check_for_rst_pf;\n+\tmbx->ops[vf_id].release = ixgbe_release_mbx_lock_pf;\n+\tmbx->ops[vf_id].read = ixgbe_read_mbx_pf;\n+\tmbx->ops[vf_id].write = ixgbe_write_mbx_pf;\n+\tmbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;\n+\tmbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;\n+\tmbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;\n \n \tmbx->stats.msgs_tx = 0;\n \tmbx->stats.msgs_rx = 0;\ndiff --git a/drivers/net/ixgbe/base/ixgbe_mbx.h b/drivers/net/ixgbe/base/ixgbe_mbx.h\nindex f7861e6bde..fadfccaabb 100644\n--- a/drivers/net/ixgbe/base/ixgbe_mbx.h\n+++ b/drivers/net/ixgbe/base/ixgbe_mbx.h\n@@ -7,8 +7,41 @@\n \n #include \"ixgbe_type.h\"\n \n+struct ixgbe_mbx_operations {\n+\tvoid (*init_params)(struct ixgbe_hw *hw);\n+\tvoid (*release)(struct ixgbe_hw *hw, u16 mbx_id);\n+\ts32  (*read)(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);\n+\ts32  (*write)(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);\n+\ts32  (*check_for_msg)(struct ixgbe_hw *hw, u16 vf_number);\n+\ts32  (*check_for_ack)(struct ixgbe_hw *hw, u16 vf_number);\n+\ts32  (*check_for_rst)(struct ixgbe_hw *hw, u16 vf_number);\n+\ts32  (*clear)(struct ixgbe_hw *hw, u16 vf_number);\n+};\n+\n+struct ixgbe_mbx_stats {\n+\tu32 msgs_tx;\n+\tu32 msgs_rx;\n+\n+\tu32 acks;\n+\tu32 reqs;\n+\tu32 rsts;\n+};\n+\n+struct ixgbe_mbx_info {\n+\t/*\n+\t * PF: One set of operations for each VF to handle various API versions\n+\t *     at the same time\n+\t * VF: Only the very first (0) set should be used\n+\t */\n+\tstruct ixgbe_mbx_operations ops[64];\n+\tstruct ixgbe_mbx_stats stats;\n+\tu32 timeout;\n+\tu32 usec_delay;\n+\tu32 vf_mailbox;\n+\tu16 size;\n+};\n+\n #define IXGBE_VFMAILBOX_SIZE\t16 /* 16 32 bit words - 64 bytes */\n-#define IXGBE_ERR_MBX\t\t-100\n \n #define IXGBE_VFMAILBOX\t\t0x002FC\n #define IXGBE_VFMBMEM\t\t0x00200\n@@ -65,6 +98,9 @@ enum ixgbe_pfvf_api_rev {\n \tixgbe_mbox_api_11,\t/* API version 1.1, linux/freebsd VF driver */\n \tixgbe_mbox_api_12,\t/* API version 1.2, linux/freebsd VF driver */\n \tixgbe_mbox_api_13,\t/* API version 1.3, linux/freebsd VF driver */\n+\t/* API 1.4 is being used in the upstream for IPsec */\n+\tixgbe_mbox_api_14,\t/* API version 1.4, linux/freebsd VF driver */\n+\tixgbe_mbox_api_15,\t/* API version 1.5, linux/freebsd VF driver */\n \t/* This value should always be last */\n \tixgbe_mbox_api_unknown,\t/* indicates that API version is not known */\n };\n@@ -125,15 +161,16 @@ enum ixgbevf_xcast_modes {\n #define IXGBE_VF_MBX_INIT_TIMEOUT\t2000 /* number of retries on mailbox */\n #define IXGBE_VF_MBX_INIT_DELAY\t\t500  /* microseconds between retries */\n \n-s32 ixgbe_read_mbx(struct ixgbe_hw *, u32 *, u16, u16);\n-s32 ixgbe_write_mbx(struct ixgbe_hw *, u32 *, u16, u16);\n-s32 ixgbe_read_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16);\n-s32 ixgbe_write_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16);\n-s32 ixgbe_check_for_msg(struct ixgbe_hw *, u16);\n-s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16);\n-s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16);\n-void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw);\n-void ixgbe_init_mbx_params_vf(struct ixgbe_hw *);\n-void ixgbe_init_mbx_params_pf(struct ixgbe_hw *);\n+s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);\n+s32 ixgbe_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);\n+s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);\n+s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id);\n+s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id);\n+s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id);\n+void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw);\n+void ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw *hw);\n+void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw);\n+void ixgbe_init_mbx_params_pf_id(struct ixgbe_hw *hw, u16 vf_id);\n+void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id);\n \n #endif /* _IXGBE_MBX_H_ */\ndiff --git a/drivers/net/ixgbe/base/ixgbe_type.h b/drivers/net/ixgbe/base/ixgbe_type.h\nindex 5036b2a907..10164e274c 100644\n--- a/drivers/net/ixgbe/base/ixgbe_type.h\n+++ b/drivers/net/ixgbe/base/ixgbe_type.h\n@@ -4141,35 +4141,6 @@ struct ixgbe_phy_info {\n \n #include \"ixgbe_mbx.h\"\n \n-struct ixgbe_mbx_operations {\n-\tvoid (*init_params)(struct ixgbe_hw *hw);\n-\ts32  (*read)(struct ixgbe_hw *, u32 *, u16,  u16);\n-\ts32  (*write)(struct ixgbe_hw *, u32 *, u16, u16);\n-\ts32  (*read_posted)(struct ixgbe_hw *, u32 *, u16,  u16);\n-\ts32  (*write_posted)(struct ixgbe_hw *, u32 *, u16, u16);\n-\ts32  (*check_for_msg)(struct ixgbe_hw *, u16);\n-\ts32  (*check_for_ack)(struct ixgbe_hw *, u16);\n-\ts32  (*check_for_rst)(struct ixgbe_hw *, u16);\n-};\n-\n-struct ixgbe_mbx_stats {\n-\tu32 msgs_tx;\n-\tu32 msgs_rx;\n-\n-\tu32 acks;\n-\tu32 reqs;\n-\tu32 rsts;\n-};\n-\n-struct ixgbe_mbx_info {\n-\tstruct ixgbe_mbx_operations ops;\n-\tstruct ixgbe_mbx_stats stats;\n-\tu32 timeout;\n-\tu32 usec_delay;\n-\tu32 v2p_mailbox;\n-\tu16 size;\n-};\n-\n struct ixgbe_hw {\n \tu8 IOMEM *hw_addr;\n \tvoid *back;\n@@ -4239,6 +4210,9 @@ struct ixgbe_hw {\n #define IXGBE_ERR_FDIR_CMD_INCOMPLETE\t\t-38\n #define IXGBE_ERR_FW_RESP_INVALID\t\t-39\n #define IXGBE_ERR_TOKEN_RETRY\t\t\t-40\n+#define IXGBE_ERR_MBX\t\t\t\t-41\n+#define IXGBE_ERR_MBX_NOMSG\t\t\t-42\n+#define IXGBE_ERR_TIMEOUT\t\t\t-43\n \n #define IXGBE_NOT_IMPLEMENTED\t\t\t0x7FFFFFFF\n \ndiff --git a/drivers/net/ixgbe/base/ixgbe_vf.c b/drivers/net/ixgbe/base/ixgbe_vf.c\nindex d390b0d5e0..603c24b653 100644\n--- a/drivers/net/ixgbe/base/ixgbe_vf.c\n+++ b/drivers/net/ixgbe/base/ixgbe_vf.c\n@@ -21,6 +21,8 @@\n  **/\n s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw)\n {\n+\tu16 i;\n+\n \t/* MAC */\n \thw->mac.ops.init_hw = ixgbe_init_hw_vf;\n \thw->mac.ops.reset_hw = ixgbe_reset_hw_vf;\n@@ -53,7 +55,8 @@ s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw)\n \thw->mac.max_tx_queues = 1;\n \thw->mac.max_rx_queues = 1;\n \n-\thw->mbx.ops.init_params = ixgbe_init_mbx_params_vf;\n+\tfor (i = 0; i < 64; i++)\n+\t\thw->mbx.ops[i].init_params = ixgbe_init_mbx_params_vf;\n \n \treturn IXGBE_SUCCESS;\n }\n@@ -156,6 +159,7 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)\n \n \t/* reset the api version */\n \thw->api_version = ixgbe_mbox_api_10;\n+\tixgbe_init_mbx_params_vf(hw);\n \n \tDEBUGOUT(\"Issuing a function level reset to MAC\\n\");\n \n@@ -165,7 +169,7 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)\n \tmsec_delay(50);\n \n \t/* we cannot reset while the RSTI / RSTD bits are asserted */\n-\twhile (!mbx->ops.check_for_rst(hw, 0) && timeout) {\n+\twhile (!mbx->ops[0].check_for_rst(hw, 0) && timeout) {\n \t\ttimeout--;\n \t\tusec_delay(5);\n \t}\n@@ -180,7 +184,7 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)\n \tmbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;\n \n \tmsgbuf[0] = IXGBE_VF_RESET;\n-\tmbx->ops.write_posted(hw, msgbuf, 1, 0);\n+\tixgbe_write_mbx(hw, msgbuf, 1, 0);\n \n \tmsec_delay(10);\n \n@@ -189,8 +193,8 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)\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->ops.read_posted(hw, msgbuf,\n-\t\t\tIXGBE_VF_PERMADDR_MSG_LEN, 0);\n+\tret_val = ixgbe_poll_mbx(hw, msgbuf,\n+\t\t\t\t IXGBE_VF_PERMADDR_MSG_LEN, 0);\n \tif (ret_val)\n \t\treturn ret_val;\n \n@@ -295,13 +299,12 @@ STATIC s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)\n STATIC s32 ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, u32 *msg,\n \t\t\t\t      u32 *retmsg, u16 size)\n {\n-\tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n-\ts32 retval = mbx->ops.write_posted(hw, msg, size, 0);\n+\ts32 retval = ixgbe_write_mbx(hw, msg, size, 0);\n \n \tif (retval)\n \t\treturn retval;\n \n-\treturn mbx->ops.read_posted(hw, retmsg, size, 0);\n+\treturn ixgbe_poll_mbx(hw, retmsg, size, 0);\n }\n \n /**\n@@ -351,7 +354,6 @@ s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list,\n \t\t\t\t u32 mc_addr_count, ixgbe_mc_addr_itr next,\n \t\t\t\t bool clear)\n {\n-\tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n \tu32 msgbuf[IXGBE_VFMAILBOX_SIZE];\n \tu16 *vector_list = (u16 *)&msgbuf[1];\n \tu32 vector;\n@@ -383,7 +385,7 @@ s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list,\n \t\tvector_list[i] = (u16)vector;\n \t}\n \n-\treturn mbx->ops.write_posted(hw, msgbuf, IXGBE_VFMAILBOX_SIZE, 0);\n+\treturn ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, IXGBE_VFMAILBOX_SIZE);\n }\n \n /**\n@@ -405,6 +407,7 @@ s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)\n \t\t\treturn IXGBE_ERR_FEATURE_NOT_SUPPORTED;\n \t\t/* Fall through */\n \tcase ixgbe_mbox_api_13:\n+\tcase ixgbe_mbox_api_15:\n \t\tbreak;\n \tdefault:\n \t\treturn IXGBE_ERR_FEATURE_NOT_SUPPORTED;\n@@ -551,12 +554,13 @@ s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,\n \tstruct ixgbe_mbx_info *mbx = &hw->mbx;\n \tstruct ixgbe_mac_info *mac = &hw->mac;\n \ts32 ret_val = IXGBE_SUCCESS;\n-\tu32 links_reg;\n \tu32 in_msg = 0;\n+\tu32 links_reg;\n+\n \tUNREFERENCED_1PARAMETER(autoneg_wait_to_complete);\n \n \t/* If we were hit with a reset drop the link */\n-\tif (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout)\n+\tif (!mbx->ops[0].check_for_rst(hw, 0) || !mbx->timeout)\n \t\tmac->get_link_status = true;\n \n \tif (!mac->get_link_status)\n@@ -613,21 +617,22 @@ s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,\n \t/* if the read failed it could just be a mailbox collision, best wait\n \t * until we are called again and don't report an error\n \t */\n-\tif (mbx->ops.read(hw, &in_msg, 1, 0))\n+\tif (ixgbe_read_mbx(hw, &in_msg, 1, 0)) {\n+\t\tif (hw->api_version >= ixgbe_mbox_api_15)\n+\t\t\tmac->get_link_status = false;\n \t\tgoto out;\n+\t}\n \n \tif (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) {\n-\t\t/* msg is not CTS and is FAILURE,\n-\t\t * we must have lost CTS status.\n-\t\t */\n+\t\t/* msg is not CTS and is FAILURE we must have lost CTS status */\n \t\tif (in_msg & IXGBE_VT_MSGTYPE_FAILURE)\n-\t\t\tret_val = -1;\n+\t\t\tret_val = IXGBE_ERR_MBX;\n \t\tgoto out;\n \t}\n \n \t/* the pf is talking, if we timed out in the past we reinit */\n \tif (!mbx->timeout) {\n-\t\tret_val = -1;\n+\t\tret_val = IXGBE_ERR_TIMEOUT;\n \t\tgoto out;\n \t}\n \n@@ -706,6 +711,7 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,\n \tcase ixgbe_mbox_api_11:\n \tcase ixgbe_mbox_api_12:\n \tcase ixgbe_mbox_api_13:\n+\tcase ixgbe_mbox_api_15:\n \t\tbreak;\n \tdefault:\n \t\treturn 0;\ndiff --git a/drivers/net/ixgbe/base/ixgbe_x540.c b/drivers/net/ixgbe/base/ixgbe_x540.c\nindex 8efde4645a..60649f1de8 100644\n--- a/drivers/net/ixgbe/base/ixgbe_x540.c\n+++ b/drivers/net/ixgbe/base/ixgbe_x540.c\n@@ -32,6 +32,7 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw)\n \tstruct ixgbe_phy_info *phy = &hw->phy;\n \tstruct ixgbe_eeprom_info *eeprom = &hw->eeprom;\n \ts32 ret_val;\n+\tu16 i;\n \n \tDEBUGFUNC(\"ixgbe_init_ops_X540\");\n \n@@ -111,7 +112,8 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw)\n \tmac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw))\n \t\t\t\t     & IXGBE_FWSM_MODE_MASK);\n \n-\thw->mbx.ops.init_params = ixgbe_init_mbx_params_pf;\n+\tfor (i = 0; i < 64; i++)\n+\t\thw->mbx.ops[i].init_params = ixgbe_init_mbx_params_pf;\n \n \t/* LEDs */\n \tmac->ops.blink_led_start = ixgbe_blink_led_start_X540;\ndiff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c\nindex 8c60351636..f2a397a451 100644\n--- a/drivers/net/ixgbe/ixgbe_ethdev.c\n+++ b/drivers/net/ixgbe/ixgbe_ethdev.c\n@@ -1663,7 +1663,7 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)\n \t}\n \n \t/* init_mailbox_params */\n-\thw->mbx.ops.init_params(hw);\n+\thw->mbx.ops[0].init_params(hw);\n \n \t/* Reset the hw statistics */\n \tixgbevf_dev_stats_reset(eth_dev);\n@@ -4099,7 +4099,7 @@ ixgbevf_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,\n \tint ret_val = 0;\n \n \t/* If we were hit with a reset drop the link */\n-\tif (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout)\n+\tif (!mbx->ops[0].check_for_rst(hw, 0) || !mbx->timeout)\n \t\tmac->get_link_status = true;\n \n \tif (!mac->get_link_status)\n@@ -4165,7 +4165,7 @@ ixgbevf_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,\n \t/* if the read failed it could just be a mailbox collision, best wait\n \t * until we are called again and don't report an error\n \t */\n-\tif (mbx->ops.read(hw, &in_msg, 1, 0))\n+\tif (mbx->ops[0].read(hw, &in_msg, 1, 0))\n \t\tgoto out;\n \n \tif (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) {\ndiff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c\nindex 71104247da..91ba395ac3 100644\n--- a/drivers/net/ixgbe/ixgbe_pf.c\n+++ b/drivers/net/ixgbe/ixgbe_pf.c\n@@ -77,6 +77,7 @@ int ixgbe_pf_host_init(struct rte_eth_dev *eth_dev)\n \tuint16_t vf_num;\n \tuint8_t nb_queue;\n \tint ret = 0;\n+\tsize_t i;\n \n \tPMD_INIT_FUNC_TRACE();\n \n@@ -122,7 +123,8 @@ int ixgbe_pf_host_init(struct rte_eth_dev *eth_dev)\n \tixgbe_vf_perm_addr_gen(eth_dev, vf_num);\n \n \t/* init_mailbox_params */\n-\thw->mbx.ops.init_params(hw);\n+\tfor (i = 0; i < vf_num; i++)\n+\t\thw->mbx.ops[i].init_params(hw);\n \n \t/* set mb interrupt mask */\n \tixgbe_mb_intr_setup(eth_dev);\n",
    "prefixes": [
        "v1",
        "06/22"
    ]
}