net/i40e: remove duplicate tunnel type check
[dpdk.git] / drivers / net / ixgbe / base / ixgbe_vf.c
index 20a739c..91a5775 100644 (file)
@@ -1,56 +1,23 @@
-/*******************************************************************************
-
-Copyright (c) 2001-2015, Intel Corporation
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
-    this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
-    contributors may be used to endorse or promote products derived from
-    this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-***************************************************************************/
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2001-2020 Intel Corporation
+ */
 
 
 #include "ixgbe_api.h"
 #include "ixgbe_type.h"
 #include "ixgbe_vf.h"
 
-#ifndef IXGBE_VFWRITE_REG
 #define IXGBE_VFWRITE_REG IXGBE_WRITE_REG
-#endif
-#ifndef IXGBE_VFREAD_REG
 #define IXGBE_VFREAD_REG IXGBE_READ_REG
-#endif
 
 /**
- *  ixgbe_init_ops_vf - Initialize the pointers for vf
- *  @hw: pointer to hardware structure
+ * ixgbe_init_ops_vf - Initialize the pointers for vf
+ * @hw: pointer to hardware structure
  *
- *  This will assign function pointers, adapter-specific functions can
- *  override the assignment of generic function pointers by assigning
- *  their own adapter-specific function pointers.
- *  Does not touch the hardware.
+ * This will assign function pointers, adapter-specific functions can
+ * override the assignment of generic function pointers by assigning
+ * their own adapter-specific function pointers.
+ * Does not touch the hardware.
  **/
 s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw)
 {
@@ -64,6 +31,7 @@ s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw)
        hw->mac.ops.get_mac_addr = ixgbe_get_mac_addr_vf;
        hw->mac.ops.stop_adapter = ixgbe_stop_adapter_vf;
        hw->mac.ops.get_bus_info = NULL;
+       hw->mac.ops.negotiate_api_version = ixgbevf_negotiate_api_version;
 
        /* Link */
        hw->mac.ops.setup_link = ixgbe_setup_mac_link_vf;
@@ -80,6 +48,7 @@ s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw)
        hw->mac.ops.disable_mc = NULL;
        hw->mac.ops.clear_vfta = NULL;
        hw->mac.ops.set_vfta = ixgbe_set_vfta_vf;
+       hw->mac.ops.set_rlpml = ixgbevf_rlpml_set_vf;
 
        hw->mac.max_tx_queues = 1;
        hw->mac.max_rx_queues = 1;
@@ -90,7 +59,7 @@ s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw)
 }
 
 /* ixgbe_virt_clr_reg - Set register to default (power on) state.
- *  @hw: pointer to hardware structure
+ * @hw: pointer to hardware structure
  */
 static void ixgbe_virt_clr_reg(struct ixgbe_hw *hw)
 {
@@ -133,13 +102,13 @@ static void ixgbe_virt_clr_reg(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_start_hw_vf - Prepare hardware for Tx/Rx
- *  @hw: pointer to hardware structure
+ * ixgbe_start_hw_vf - Prepare hardware for Tx/Rx
+ * @hw: pointer to hardware structure
  *
- *  Starts the hardware by filling the bus info structure and media type, clears
- *  all on chip counters, initializes receive address registers, multicast
- *  table, VLAN filter table, calls routine to set up link and flow control
- *  settings, and leaves transmit and receive units disabled and uninitialized
+ * Starts the hardware by filling the bus info structure and media type, clears
+ * all on chip counters, initializes receive address registers, multicast
+ * table, VLAN filter table, calls routine to set up link and flow control
+ * settings, and leaves transmit and receive units disabled and uninitialized
  **/
 s32 ixgbe_start_hw_vf(struct ixgbe_hw *hw)
 {
@@ -150,11 +119,11 @@ s32 ixgbe_start_hw_vf(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_init_hw_vf - virtual function hardware initialization
- *  @hw: pointer to hardware structure
+ * ixgbe_init_hw_vf - virtual function hardware initialization
+ * @hw: pointer to hardware structure
  *
- *  Initialize the hardware by resetting the hardware and then starting
- *  the hardware
+ * Initialize the hardware by resetting the hardware and then starting
+ * the hardware
  **/
 s32 ixgbe_init_hw_vf(struct ixgbe_hw *hw)
 {
@@ -166,11 +135,11 @@ s32 ixgbe_init_hw_vf(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_reset_hw_vf - Performs hardware reset
- *  @hw: pointer to hardware structure
+ * ixgbe_reset_hw_vf - Performs hardware reset
+ * @hw: pointer to hardware structure
  *
- *  Resets the hardware by reseting the transmit and receive units, masks and
- *  clears all interrupts.
+ * Resets the hardware by resetting the transmit and receive units, masks and
+ * clears all interrupts.
  **/
 s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)
 {
@@ -238,13 +207,13 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_stop_adapter_vf - Generic stop Tx/Rx units
- *  @hw: pointer to hardware structure
+ * ixgbe_stop_adapter_vf - Generic stop Tx/Rx units
+ * @hw: pointer to hardware structure
  *
- *  Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
- *  disables transmit and receive units. The adapter_stopped flag is used by
- *  the shared code and drivers to determine if the adapter is in a stopped
- *  state and should not touch the hardware.
+ * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
+ * disables transmit and receive units. The adapter_stopped flag is used by
+ * the shared code and drivers to determine if the adapter is in a stopped
+ * state and should not touch the hardware.
  **/
 s32 ixgbe_stop_adapter_vf(struct ixgbe_hw *hw)
 {
@@ -284,16 +253,16 @@ s32 ixgbe_stop_adapter_vf(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_mta_vector - Determines bit-vector in multicast table to set
- *  @hw: pointer to hardware structure
- *  @mc_addr: the multicast address
+ * ixgbe_mta_vector - Determines bit-vector in multicast table to set
+ * @hw: pointer to hardware structure
+ * @mc_addr: the multicast address
  *
- *  Extracts the 12 bits, from a multicast address, to determine which
- *  bit-vector to set in the multicast table. The hardware uses 12 bits, from
- *  incoming rx multicast addresses, to determine the bit-vector to check in
- *  the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
- *  by the MO field of the MCSTCTRL. The MO field is set during initialization
- *  to mc_filter_type.
+ * Extracts the 12 bits, from a multicast address, to determine which
+ * bit-vector to set in the multicast table. The hardware uses 12 bits, from
+ * incoming rx multicast addresses, to determine the bit-vector to check in
+ * the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
+ * by the MO field of the MCSTCTRL. The MO field is set during initialization
+ * to mc_filter_type.
  **/
 STATIC s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
 {
@@ -323,29 +292,29 @@ STATIC s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
        return vector;
 }
 
-STATIC void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw,
-                                       u32 *msg, u16 size)
+STATIC s32 ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, u32 *msg,
+                                     u32 *retmsg, u16 size)
 {
        struct ixgbe_mbx_info *mbx = &hw->mbx;
-       u32 retmsg[IXGBE_VFMAILBOX_SIZE];
        s32 retval = mbx->ops.write_posted(hw, msg, size, 0);
 
-       if (!retval)
-               mbx->ops.read_posted(hw, retmsg, size, 0);
+       if (retval)
+               return retval;
+
+       return mbx->ops.read_posted(hw, retmsg, size, 0);
 }
 
 /**
- *  ixgbe_set_rar_vf - set device MAC address
- *  @hw: pointer to hardware structure
- *  @index: Receive address register to write
- *  @addr: Address to put into receive address register
- *  @vmdq: VMDq "set" or "pool" index
- *  @enable_addr: set flag that address is active
+ * ixgbe_set_rar_vf - set device MAC address
+ * @hw: pointer to hardware structure
+ * @index: Receive address register to write
+ * @addr: Address to put into receive address register
+ * @vmdq: VMDq "set" or "pool" index
+ * @enable_addr: set flag that address is active
  **/
 s32 ixgbe_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
                     u32 enable_addr)
 {
-       struct ixgbe_mbx_info *mbx = &hw->mbx;
        u32 msgbuf[3];
        u8 *msg_addr = (u8 *)(&msgbuf[1]);
        s32 ret_val;
@@ -354,10 +323,7 @@ s32 ixgbe_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
        memset(msgbuf, 0, 12);
        msgbuf[0] = IXGBE_VF_SET_MAC_ADDR;
        memcpy(msg_addr, addr, 6);
-       ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0);
-
-       if (!ret_val)
-               ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0);
+       ret_val = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 3);
 
        msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
 
@@ -372,13 +338,14 @@ s32 ixgbe_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
 }
 
 /**
- *  ixgbe_update_mc_addr_list_vf - Update Multicast addresses
- *  @hw: pointer to the HW structure
- *  @mc_addr_list: array of multicast addresses to program
- *  @mc_addr_count: number of multicast addresses to program
- *  @next: caller supplied function to return next address in list
+ * ixgbe_update_mc_addr_list_vf - Update Multicast addresses
+ * @hw: pointer to the HW structure
+ * @mc_addr_list: array of multicast addresses to program
+ * @mc_addr_count: number of multicast addresses to program
+ * @next: caller supplied function to return next address in list
+ * @clear: unused
  *
- *  Updates the Multicast Table Array.
+ * Updates the Multicast Table Array.
  **/
 s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list,
                                 u32 mc_addr_count, ixgbe_mc_addr_itr next,
@@ -420,20 +387,24 @@ s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list,
 }
 
 /**
- *  ixgbevf_update_xcast_mode - Update Multicast mode
- *  @hw: pointer to the HW structure
- *  @xcast_mode: new multicast mode
+ * ixgbevf_update_xcast_mode - Update Multicast mode
+ * @hw: pointer to the HW structure
+ * @xcast_mode: new multicast mode
  *
- *  Updates the Multicast Mode of VF.
+ * Updates the Multicast Mode of VF.
  **/
 s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)
 {
-       struct ixgbe_mbx_info *mbx = &hw->mbx;
        u32 msgbuf[2];
        s32 err;
 
        switch (hw->api_version) {
        case ixgbe_mbox_api_12:
+               /* New modes were introduced in 1.3 version */
+               if (xcast_mode > IXGBEVF_XCAST_MODE_ALLMULTI)
+                       return IXGBE_ERR_FEATURE_NOT_SUPPORTED;
+               /* Fall through */
+       case ixgbe_mbox_api_13:
                break;
        default:
                return IXGBE_ERR_FEATURE_NOT_SUPPORTED;
@@ -442,11 +413,7 @@ s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)
        msgbuf[0] = IXGBE_VF_UPDATE_XCAST_MODE;
        msgbuf[1] = xcast_mode;
 
-       err = mbx->ops.write_posted(hw, msgbuf, 2, 0);
-       if (err)
-               return err;
-
-       err = mbx->ops.read_posted(hw, msgbuf, 2, 0);
+       err = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
        if (err)
                return err;
 
@@ -457,17 +424,18 @@ s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)
 }
 
 /**
- *  ixgbe_set_vfta_vf - Set/Unset vlan filter table address
- *  @hw: pointer to the HW structure
- *  @vlan: 12 bit VLAN ID
- *  @vind: unused by VF drivers
- *  @vlan_on: if true then set bit, else clear bit
- *  @vlvf_bypass: boolean flag indicating updating default pool is okay
+ * ixgbe_set_vfta_vf - Set/Unset vlan filter table address
+ * @hw: pointer to the HW structure
+ * @vlan: 12 bit VLAN ID
+ * @vind: unused by VF drivers
+ * @vlan_on: if true then set bit, else clear bit
+ * @vlvf_bypass: boolean flag indicating updating default pool is okay
+ *
+ * Turn on/off specified VLAN in the VLAN filter table.
  **/
 s32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind,
                      bool vlan_on, bool vlvf_bypass)
 {
-       struct ixgbe_mbx_info *mbx = &hw->mbx;
        u32 msgbuf[2];
        s32 ret_val;
        UNREFERENCED_2PARAMETER(vind, vlvf_bypass);
@@ -477,10 +445,7 @@ s32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind,
        /* Setting the 8 bit field MSG INFO to TRUE indicates "add" */
        msgbuf[0] |= vlan_on << IXGBE_VT_MSGINFO_SHIFT;
 
-       ret_val = mbx->ops.write_posted(hw, msgbuf, 2, 0);
-       if (!ret_val)
-               ret_val = mbx->ops.read_posted(hw, msgbuf, 1, 0);
-
+       ret_val = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
        if (!ret_val && (msgbuf[0] & IXGBE_VT_MSGTYPE_ACK))
                return IXGBE_SUCCESS;
 
@@ -488,10 +453,10 @@ s32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 }
 
 /**
- *  ixgbe_get_num_of_tx_queues_vf - Get number of TX queues
- *  @hw: pointer to hardware structure
+ * ixgbe_get_num_of_tx_queues_vf - Get number of TX queues
+ * @hw: pointer to hardware structure
  *
- *  Returns the number of transmit queues for the given adapter.
+ * Returns the number of transmit queues for the given adapter.
  **/
 u32 ixgbe_get_num_of_tx_queues_vf(struct ixgbe_hw *hw)
 {
@@ -500,10 +465,10 @@ u32 ixgbe_get_num_of_tx_queues_vf(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_get_num_of_rx_queues_vf - Get number of RX queues
- *  @hw: pointer to hardware structure
+ * ixgbe_get_num_of_rx_queues_vf - Get number of RX queues
+ * @hw: pointer to hardware structure
  *
- *  Returns the number of receive queues for the given adapter.
+ * Returns the number of receive queues for the given adapter.
  **/
 u32 ixgbe_get_num_of_rx_queues_vf(struct ixgbe_hw *hw)
 {
@@ -512,8 +477,9 @@ u32 ixgbe_get_num_of_rx_queues_vf(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_get_mac_addr_vf - Read device MAC address
- *  @hw: pointer to the HW structure
+ * ixgbe_get_mac_addr_vf - Read device MAC address
+ * @hw: pointer to the HW structure
+ * @mac_addr: the MAC address
  **/
 s32 ixgbe_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr)
 {
@@ -527,8 +493,7 @@ s32 ixgbe_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr)
 
 s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
 {
-       struct ixgbe_mbx_info *mbx = &hw->mbx;
-       u32 msgbuf[3];
+       u32 msgbuf[3], msgbuf_chk;
        u8 *msg_addr = (u8 *)(&msgbuf[1]);
        s32 ret_val;
 
@@ -541,30 +506,28 @@ s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
         */
        msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT;
        msgbuf[0] |= IXGBE_VF_SET_MACVLAN;
+       msgbuf_chk = msgbuf[0];
        if (addr)
                memcpy(msg_addr, addr, 6);
-       ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0);
 
-       if (!ret_val)
-               ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0);
+       ret_val = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 3);
+       if (!ret_val) {
+               msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
 
-       msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
-
-       if (!ret_val)
-               if (msgbuf[0] == (IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK))
-                       ret_val = IXGBE_ERR_OUT_OF_MEM;
+               if (msgbuf[0] == (msgbuf_chk | IXGBE_VT_MSGTYPE_NACK))
+                       return IXGBE_ERR_OUT_OF_MEM;
+       }
 
        return ret_val;
 }
 
 /**
- *  ixgbe_setup_mac_link_vf - Setup MAC link settings
- *  @hw: pointer to hardware structure
- *  @speed: new link speed
- *  @autoneg: true if autonegotiation enabled
- *  @autoneg_wait_to_complete: true when waiting for completion is needed
+ * ixgbe_setup_mac_link_vf - Setup MAC link settings
+ * @hw: pointer to hardware structure
+ * @speed: new link speed
+ * @autoneg_wait_to_complete: true when waiting for completion is needed
  *
- *  Set the link speed in the AUTOC register and restarts link.
+ * Set the link speed in the AUTOC register and restarts link.
  **/
 s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed speed,
                            bool autoneg_wait_to_complete)
@@ -574,13 +537,13 @@ s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed speed,
 }
 
 /**
- *  ixgbe_check_mac_link_vf - Get link/speed status
- *  @hw: pointer to hardware structure
- *  @speed: pointer to link speed
- *  @link_up: true is link is up, false otherwise
- *  @autoneg_wait_to_complete: true when waiting for completion is needed
+ * ixgbe_check_mac_link_vf - Get link/speed status
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @link_up: true is link is up, false otherwise
+ * @autoneg_wait_to_complete: true when waiting for completion is needed
  *
- *  Reads the links register to determine if link is up and the current speed
+ * Reads the links register to determine if link is up and the current speed
  **/
 s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
                            bool *link_up, bool autoneg_wait_to_complete)
@@ -622,13 +585,29 @@ s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
        switch (links_reg & IXGBE_LINKS_SPEED_82599) {
        case IXGBE_LINKS_SPEED_10G_82599:
                *speed = IXGBE_LINK_SPEED_10GB_FULL;
+               if (hw->mac.type >= ixgbe_mac_X550) {
+                       if (links_reg & IXGBE_LINKS_SPEED_NON_STD)
+                               *speed = IXGBE_LINK_SPEED_2_5GB_FULL;
+               }
                break;
        case IXGBE_LINKS_SPEED_1G_82599:
                *speed = IXGBE_LINK_SPEED_1GB_FULL;
                break;
        case IXGBE_LINKS_SPEED_100_82599:
                *speed = IXGBE_LINK_SPEED_100_FULL;
+               if (hw->mac.type == ixgbe_mac_X550) {
+                       if (links_reg & IXGBE_LINKS_SPEED_NON_STD)
+                               *speed = IXGBE_LINK_SPEED_5GB_FULL;
+               }
+               break;
+       case IXGBE_LINKS_SPEED_10_X550EM_A:
+               *speed = IXGBE_LINK_SPEED_UNKNOWN;
+               /* Since Reserved in older MAC's */
+               if (hw->mac.type >= ixgbe_mac_X550)
+                       *speed = IXGBE_LINK_SPEED_10_FULL;
                break;
+       default:
+               *speed = IXGBE_LINK_SPEED_UNKNOWN;
        }
 
        /* if the read failed it could just be a mailbox collision, best wait
@@ -661,23 +640,32 @@ out:
 }
 
 /**
- *  ixgbevf_rlpml_set_vf - Set the maximum receive packet length
- *  @hw: pointer to the HW structure
- *  @max_size: value to assign to max frame size
+ * ixgbevf_rlpml_set_vf - Set the maximum receive packet length
+ * @hw: pointer to the HW structure
+ * @max_size: value to assign to max frame size
  **/
-void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size)
+s32 ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size)
 {
        u32 msgbuf[2];
+       s32 retval;
 
        msgbuf[0] = IXGBE_VF_SET_LPE;
        msgbuf[1] = max_size;
-       ixgbevf_write_msg_read_ack(hw, msgbuf, 2);
+
+       retval = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
+       if (retval)
+               return retval;
+       if ((msgbuf[0] & IXGBE_VF_SET_LPE) &&
+           (msgbuf[0] & IXGBE_VT_MSGTYPE_NACK))
+               return IXGBE_ERR_MBX;
+
+       return 0;
 }
 
 /**
- *  ixgbevf_negotiate_api_version - Negotiate supported API version
- *  @hw: pointer to the HW structure
- *  @api: integer containing requested API version
+ * ixgbevf_negotiate_api_version - Negotiate supported API version
+ * @hw: pointer to the HW structure
+ * @api: integer containing requested API version
  **/
 int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api)
 {
@@ -688,11 +676,8 @@ int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api)
        msg[0] = IXGBE_VF_API_NEGOTIATE;
        msg[1] = api;
        msg[2] = 0;
-       err = hw->mbx.ops.write_posted(hw, msg, 3, 0);
-
-       if (!err)
-               err = hw->mbx.ops.read_posted(hw, msg, 3, 0);
 
+       err = ixgbevf_write_msg_read_ack(hw, msg, msg, 3);
        if (!err) {
                msg[0] &= ~IXGBE_VT_MSGTYPE_CTS;
 
@@ -718,6 +703,7 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
        switch (hw->api_version) {
        case ixgbe_mbox_api_11:
        case ixgbe_mbox_api_12:
+       case ixgbe_mbox_api_13:
                break;
        default:
                return 0;
@@ -726,11 +712,8 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
        /* Fetch queue configuration from the PF */
        msg[0] = IXGBE_VF_GET_QUEUES;
        msg[1] = msg[2] = msg[3] = msg[4] = 0;
-       err = hw->mbx.ops.write_posted(hw, msg, 5, 0);
-
-       if (!err)
-               err = hw->mbx.ops.read_posted(hw, msg, 5, 0);
 
+       err = ixgbevf_write_msg_read_ack(hw, msg, msg, 5);
        if (!err) {
                msg[0] &= ~IXGBE_VT_MSGTYPE_CTS;