remove repeated 'the' in the code
[dpdk.git] / drivers / net / i40e / base / i40e_common.c
index 17b53ae..9eee104 100644 (file)
@@ -1,41 +1,13 @@
-/*******************************************************************************
-
-Copyright (c) 2013 - 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 <inttypes.h>
 
 #include "i40e_type.h"
 #include "i40e_adminq.h"
 #include "i40e_prototype.h"
-#include "i40e_virtchnl.h"
-
+#include "virtchnl.h"
 
 /**
  * i40e_set_mac_type - Sets MAC type
@@ -44,11 +16,7 @@ POSSIBILITY OF SUCH DAMAGE.
  * This function sets the mac type of the adapter based on the
  * vendor ID and device ID stored in the hw structure.
  **/
-#if defined(INTEGRATED_VF) || defined(VF_DRIVER)
 enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
-#else
-STATIC enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
-#endif
 {
        enum i40e_status_code status = I40E_SUCCESS;
 
@@ -65,13 +33,18 @@ STATIC enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
                case I40E_DEV_ID_QSFP_C:
                case I40E_DEV_ID_10G_BASE_T:
                case I40E_DEV_ID_10G_BASE_T4:
+               case I40E_DEV_ID_10G_BASE_T_BC:
+               case I40E_DEV_ID_10G_B:
+               case I40E_DEV_ID_10G_SFP:
+               case I40E_DEV_ID_5G_BASE_T_BC:
                case I40E_DEV_ID_20G_KR2:
                case I40E_DEV_ID_20G_KR2_A:
                case I40E_DEV_ID_25G_B:
                case I40E_DEV_ID_25G_SFP28:
+               case I40E_DEV_ID_X710_N3000:
+               case I40E_DEV_ID_XXV710_N3000:
                        hw->mac.type = I40E_MAC_XL710;
                        break;
-#ifdef X722_SUPPORT
 #ifdef X722_A0_SUPPORT
                case I40E_DEV_ID_X722_A0:
 #endif
@@ -83,8 +56,6 @@ STATIC enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
                case I40E_DEV_ID_SFP_I_X722:
                        hw->mac.type = I40E_MAC_X722;
                        break;
-#endif
-#ifdef X722_SUPPORT
 #if defined(INTEGRATED_VF) || defined(VF_DRIVER)
                case I40E_DEV_ID_X722_VF:
 #ifdef X722_A0_SUPPORT
@@ -93,10 +64,10 @@ STATIC enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
                        hw->mac.type = I40E_MAC_X722_VF;
                        break;
 #endif /* INTEGRATED_VF || VF_DRIVER */
-#endif /* X722_SUPPORT */
 #if defined(INTEGRATED_VF) || defined(VF_DRIVER)
                case I40E_DEV_ID_VF:
                case I40E_DEV_ID_VF_HV:
+               case I40E_DEV_ID_ADAPTIVE_VF:
                        hw->mac.type = I40E_MAC_VF;
                        break;
 #endif
@@ -113,7 +84,6 @@ STATIC enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
        return status;
 }
 
-#ifndef I40E_NDIS_SUPPORT
 /**
  * i40e_aq_str - convert AQ err code to a string
  * @hw: pointer to the HW structure
@@ -314,13 +284,14 @@ const char *i40e_stat_str(struct i40e_hw *hw, enum i40e_status_code stat_err)
                return "I40E_NOT_SUPPORTED";
        case I40E_ERR_FIRMWARE_API_VERSION:
                return "I40E_ERR_FIRMWARE_API_VERSION";
+       case I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR:
+               return "I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR";
        }
 
        snprintf(hw->err_str, sizeof(hw->err_str), "%d", stat_err);
        return hw->err_str;
 }
 
-#endif /* I40E_NDIS_SUPPORT */
 /**
  * i40e_debug_aq
  * @hw: debug mask related to admin queue
@@ -335,30 +306,37 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
                   void *buffer, u16 buf_len)
 {
        struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
-       u16 len = LE16_TO_CPU(aq_desc->datalen);
+       u32 effective_mask = hw->debug_mask & mask;
        u8 *buf = (u8 *)buffer;
-       u16 i = 0;
+       u16 len;
+       u16 i;
 
-       if ((!(mask & hw->debug_mask)) || (desc == NULL))
+       if (!effective_mask || !desc)
                return;
 
-       i40e_debug(hw, mask,
+       len = LE16_TO_CPU(aq_desc->datalen);
+
+       i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
                   "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n",
                   LE16_TO_CPU(aq_desc->opcode),
                   LE16_TO_CPU(aq_desc->flags),
                   LE16_TO_CPU(aq_desc->datalen),
                   LE16_TO_CPU(aq_desc->retval));
-       i40e_debug(hw, mask, "\tcookie (h,l) 0x%08X 0x%08X\n",
+       i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
+                  "\tcookie (h,l) 0x%08X 0x%08X\n",
                   LE32_TO_CPU(aq_desc->cookie_high),
                   LE32_TO_CPU(aq_desc->cookie_low));
-       i40e_debug(hw, mask, "\tparam (0,1)  0x%08X 0x%08X\n",
+       i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
+                  "\tparam (0,1)  0x%08X 0x%08X\n",
                   LE32_TO_CPU(aq_desc->params.internal.param0),
                   LE32_TO_CPU(aq_desc->params.internal.param1));
-       i40e_debug(hw, mask, "\taddr (h,l)   0x%08X 0x%08X\n",
+       i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
+                  "\taddr (h,l)   0x%08X 0x%08X\n",
                   LE32_TO_CPU(aq_desc->params.external.addr_high),
                   LE32_TO_CPU(aq_desc->params.external.addr_low));
 
-       if ((buffer != NULL) && (aq_desc->datalen != 0)) {
+       if (buffer && (buf_len != 0) && (len != 0) &&
+           (effective_mask & I40E_DEBUG_AQ_DESC_BUFFER)) {
                i40e_debug(hw, mask, "AQ CMD Buffer:\n");
                if (buf_len < len)
                        len = buf_len;
@@ -446,7 +424,6 @@ enum i40e_status_code i40e_aq_queue_shutdown(struct i40e_hw *hw,
 
        return status;
 }
-#ifdef X722_SUPPORT
 
 /**
  * i40e_aq_get_set_rss_lut
@@ -605,7 +582,6 @@ enum i40e_status_code i40e_aq_set_rss_key(struct i40e_hw *hw,
 {
        return i40e_aq_get_set_rss_key(hw, vsi_id, key, true);
 }
-#endif /* X722_SUPPORT */
 
 /* The i40e_ptype_lookup table is used to convert from the 8-bit ptype in the
  * hardware to a bit-field that can be used by SW to more easily determine the
@@ -1021,9 +997,7 @@ enum i40e_status_code i40e_init_shared_code(struct i40e_hw *hw)
 
        switch (hw->mac.type) {
        case I40E_MAC_XL710:
-#ifdef X722_SUPPORT
        case I40E_MAC_X722:
-#endif
                break;
        default:
                return I40E_ERR_DEVICE_NOT_SUPPORTED;
@@ -1043,11 +1017,21 @@ enum i40e_status_code i40e_init_shared_code(struct i40e_hw *hw)
        else
                hw->pf_id = (u8)(func_rid & 0x7);
 
-#ifdef X722_SUPPORT
        if (hw->mac.type == I40E_MAC_X722)
-               hw->flags |= I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE;
+               hw->flags |= I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE |
+                            I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK;
+       /* NVMUpdate features structure initialization */
+       hw->nvmupd_features.major = I40E_NVMUPD_FEATURES_API_VER_MAJOR;
+       hw->nvmupd_features.minor = I40E_NVMUPD_FEATURES_API_VER_MINOR;
+       hw->nvmupd_features.size = sizeof(hw->nvmupd_features);
+       i40e_memset(hw->nvmupd_features.features, 0x0,
+                   I40E_NVMUPD_FEATURES_API_FEATURES_ARRAY_LEN *
+                   sizeof(*hw->nvmupd_features.features),
+                   I40E_NONDMA_MEM);
+
+       /* No features supported at the moment */
+       hw->nvmupd_features.features[0] = 0;
 
-#endif
        status = i40e_init_nvm(hw);
        return status;
 }
@@ -1292,10 +1276,15 @@ STATIC enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
        case I40E_PHY_TYPE_40GBASE_LR4:
        case I40E_PHY_TYPE_25GBASE_LR:
        case I40E_PHY_TYPE_25GBASE_SR:
+       case I40E_PHY_TYPE_10GBASE_AOC:
+       case I40E_PHY_TYPE_25GBASE_AOC:
+       case I40E_PHY_TYPE_40GBASE_AOC:
                media = I40E_MEDIA_TYPE_FIBER;
                break;
        case I40E_PHY_TYPE_100BASE_TX:
        case I40E_PHY_TYPE_1000BASE_T:
+       case I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS:
+       case I40E_PHY_TYPE_5GBASE_T_LINK_STATUS:
        case I40E_PHY_TYPE_10GBASE_T:
                media = I40E_MEDIA_TYPE_BASET;
                break;
@@ -1304,9 +1293,8 @@ STATIC enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
        case I40E_PHY_TYPE_10GBASE_CR1:
        case I40E_PHY_TYPE_40GBASE_CR4:
        case I40E_PHY_TYPE_10GBASE_SFPP_CU:
-       case I40E_PHY_TYPE_40GBASE_AOC:
-       case I40E_PHY_TYPE_10GBASE_AOC:
        case I40E_PHY_TYPE_25GBASE_CR:
+       case I40E_PHY_TYPE_25GBASE_ACC:
                media = I40E_MEDIA_TYPE_DA;
                break;
        case I40E_PHY_TYPE_1000BASE_KX:
@@ -1330,7 +1318,30 @@ STATIC enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
        return media;
 }
 
-#define I40E_PF_RESET_WAIT_COUNT       200
+/**
+ * i40e_poll_globr - Poll for Global Reset completion
+ * @hw: pointer to the hardware structure
+ * @retry_limit: how many times to retry before failure
+ **/
+STATIC enum i40e_status_code i40e_poll_globr(struct i40e_hw *hw,
+                                            u32 retry_limit)
+{
+       u32 cnt, reg = 0;
+
+       for (cnt = 0; cnt < retry_limit; cnt++) {
+               reg = rd32(hw, I40E_GLGEN_RSTAT);
+               if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
+                       return I40E_SUCCESS;
+               i40e_msec_delay(100);
+       }
+
+       DEBUGOUT("Global reset failed.\n");
+       DEBUGOUT1("I40E_GLGEN_RSTAT = 0x%x\n", reg);
+
+       return I40E_ERR_RESET_FAILED;
+}
+
+#define I40E_PF_RESET_WAIT_COUNT       1000
 /**
  * i40e_pf_reset - Reset the PF
  * @hw: pointer to the hardware structure
@@ -1353,7 +1364,7 @@ enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw)
                        I40E_GLGEN_RSTCTL_GRSTDEL_MASK) >>
                        I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT;
 
-       grst_del = grst_del * 20;
+       grst_del = min(grst_del * 20, 160U);
 
        for (cnt = 0; cnt < grst_del; cnt++) {
                reg = rd32(hw, I40E_GLGEN_RSTAT);
@@ -1389,6 +1400,8 @@ enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw)
         * we don't need to do the PF Reset
         */
        if (!cnt) {
+               u32 reg2 = 0;
+
                reg = rd32(hw, I40E_PFGEN_CTRL);
                wr32(hw, I40E_PFGEN_CTRL,
                     (reg | I40E_PFGEN_CTRL_PFSWR_MASK));
@@ -1396,9 +1409,15 @@ enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw)
                        reg = rd32(hw, I40E_PFGEN_CTRL);
                        if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK))
                                break;
+                       reg2 = rd32(hw, I40E_GLGEN_RSTAT);
+                       if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK)
+                               break;
                        i40e_msec_delay(1);
                }
-               if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) {
+               if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) {
+                       if (i40e_poll_globr(hw, grst_del) != I40E_SUCCESS)
+                               return I40E_ERR_RESET_FAILED;
+               } else if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) {
                        DEBUGOUT("PF reset polling failed to complete.\n");
                        return I40E_ERR_RESET_FAILED;
                }
@@ -1528,9 +1547,9 @@ static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx)
        u32 gpio_val = 0;
        u32 port;
 
-       if (!hw->func_caps.led[idx])
+       if (!I40E_IS_X710TL_DEVICE(hw->device_id) &&
+           !hw->func_caps.led[idx])
                return 0;
-
        gpio_val = rd32(hw, I40E_GLGEN_GPIO_CTL(idx));
        port = (gpio_val & I40E_GLGEN_GPIO_CTL_PRT_NUM_MASK) >>
                I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT;
@@ -1549,8 +1568,15 @@ static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx)
 #define I40E_FILTER_ACTIVITY 0xE
 #define I40E_LINK_ACTIVITY 0xC
 #define I40E_MAC_ACTIVITY 0xD
+#define I40E_FW_LED BIT(4)
+#define I40E_LED_MODE_VALID (I40E_GLGEN_GPIO_CTL_LED_MODE_MASK >> \
+                            I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT)
+
 #define I40E_LED0 22
 
+#define I40E_PIN_FUNC_SDP 0x0
+#define I40E_PIN_FUNC_LED 0x1
+
 /**
  * i40e_led_get - return current on/off mode
  * @hw: pointer to the hw struct
@@ -1584,6 +1610,7 @@ u32 i40e_led_get(struct i40e_hw *hw)
                case I40E_COMBINED_ACTIVITY:
                case I40E_FILTER_ACTIVITY:
                case I40E_MAC_ACTIVITY:
+               case I40E_LINK_ACTIVITY:
                        continue;
                default:
                        break;
@@ -1611,8 +1638,10 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
        u32 current_mode = 0;
        int i;
 
-       if (mode & 0xfffffff0)
+       if (mode & ~I40E_LED_MODE_VALID) {
                DEBUGOUT1("invalid mode passed in %X\n", mode);
+               return;
+       }
 
        /* as per the documentation GPIO 22-29 are the LED
         * GPIO pins named LED0..LED7
@@ -1632,19 +1661,30 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
                case I40E_COMBINED_ACTIVITY:
                case I40E_FILTER_ACTIVITY:
                case I40E_MAC_ACTIVITY:
+               case I40E_LINK_ACTIVITY:
                        continue;
                default:
                        break;
                }
 
+               if (I40E_IS_X710TL_DEVICE(hw->device_id)) {
+                       u32 pin_func = 0;
+
+                       if (mode & I40E_FW_LED)
+                               pin_func = I40E_PIN_FUNC_SDP;
+                       else
+                               pin_func = I40E_PIN_FUNC_LED;
+
+                       gpio_val &= ~I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK;
+                       gpio_val |= ((pin_func <<
+                                    I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT) &
+                                    I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK);
+               }
                gpio_val &= ~I40E_GLGEN_GPIO_CTL_LED_MODE_MASK;
                /* this & is a bit of paranoia, but serves as a range check */
                gpio_val |= ((mode << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) &
                             I40E_GLGEN_GPIO_CTL_LED_MODE_MASK);
 
-               if (mode == I40E_LINK_ACTIVITY)
-                       blink = false;
-
                if (blink)
                        gpio_val |= BIT(I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
                else
@@ -1674,35 +1714,61 @@ enum i40e_status_code i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
 {
        struct i40e_aq_desc desc;
        enum i40e_status_code status;
+       u16 max_delay = I40E_MAX_PHY_TIMEOUT, total_delay = 0;
        u16 abilities_size = sizeof(struct i40e_aq_get_phy_abilities_resp);
 
        if (!abilities)
                return I40E_ERR_PARAM;
 
-       i40e_fill_default_direct_cmd_desc(&desc,
-                                         i40e_aqc_opc_get_phy_abilities);
+       do {
+               i40e_fill_default_direct_cmd_desc(&desc,
+                                              i40e_aqc_opc_get_phy_abilities);
 
-       desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
-       if (abilities_size > I40E_AQ_LARGE_BUF)
-               desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+               desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
+               if (abilities_size > I40E_AQ_LARGE_BUF)
+                       desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
 
-       if (qualified_modules)
-               desc.params.external.param0 |=
+               if (qualified_modules)
+                       desc.params.external.param0 |=
                        CPU_TO_LE32(I40E_AQ_PHY_REPORT_QUALIFIED_MODULES);
 
-       if (report_init)
-               desc.params.external.param0 |=
+               if (report_init)
+                       desc.params.external.param0 |=
                        CPU_TO_LE32(I40E_AQ_PHY_REPORT_INITIAL_VALUES);
 
-       status = i40e_asq_send_command(hw, &desc, abilities, abilities_size,
-                                   cmd_details);
+               status = i40e_asq_send_command(hw, &desc, abilities,
+                                              abilities_size, cmd_details);
 
-       if (hw->aq.asq_last_status == I40E_AQ_RC_EIO)
-               status = I40E_ERR_UNKNOWN_PHY;
+               switch (hw->aq.asq_last_status) {
+               case I40E_AQ_RC_EIO:
+                       status = I40E_ERR_UNKNOWN_PHY;
+                       break;
+               case I40E_AQ_RC_EAGAIN:
+                       i40e_msec_delay(1);
+                       total_delay++;
+                       status = I40E_ERR_TIMEOUT;
+                       break;
+               /* also covers I40E_AQ_RC_OK */
+               default:
+                       break;
+               }
+
+       } while ((hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN) &&
+               (total_delay < max_delay));
+
+       if (status != I40E_SUCCESS)
+               return status;
 
        if (report_init) {
-               hw->phy.phy_types = LE32_TO_CPU(abilities->phy_type);
-               hw->phy.phy_types |= ((u64)abilities->phy_type_ext << 32);
+               if (hw->mac.type ==  I40E_MAC_XL710 &&
+                   hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
+                   hw->aq.api_min_ver >= I40E_MINOR_VER_GET_LINK_INFO_XL710) {
+                       status = i40e_aq_get_link_info(hw, true, NULL, NULL);
+               } else {
+                       hw->phy.phy_types = LE32_TO_CPU(abilities->phy_type);
+                       hw->phy.phy_types |=
+                                       ((u64)abilities->phy_type_ext << 32);
+               }
        }
 
        return status;
@@ -1745,6 +1811,8 @@ enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw,
 /**
  * i40e_set_fc
  * @hw: pointer to the hw struct
+ * @aq_failures: buffer to return AdminQ failure information
+ * @atomic_restart: whether to enable atomic link restart
  *
  * Set the requested flow control mode using set_phy_config.
  **/
@@ -1829,6 +1897,7 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
  * @max_frame_size: Maximum Frame Size to be supported by the port
  * @crc_en: Tell HW to append a CRC to outgoing frames
  * @pacing: Pacing configurations
+ * @auto_drop_blocking_packets: Tell HW to drop packets if TC queue is blocked
  * @cmd_details: pointer to command details structure or NULL
  *
  * Configure MAC settings for frame size, jumbo frame support and the
@@ -1837,6 +1906,7 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
 enum i40e_status_code i40e_aq_set_mac_config(struct i40e_hw *hw,
                                u16 max_frame_size,
                                bool crc_en, u16 pacing,
+                               bool auto_drop_blocking_packets,
                                struct i40e_asq_cmd_details *cmd_details)
 {
        struct i40e_aq_desc desc;
@@ -1855,6 +1925,19 @@ enum i40e_status_code i40e_aq_set_mac_config(struct i40e_hw *hw,
        if (crc_en)
                cmd->params |= I40E_AQ_SET_MAC_CONFIG_CRC_EN;
 
+       if (auto_drop_blocking_packets) {
+               if (hw->flags & I40E_HW_FLAG_DROP_MODE)
+                       cmd->params |=
+                               I40E_AQ_SET_MAC_CONFIG_DROP_BLOCKING_PACKET_EN;
+               else
+                       i40e_debug(hw, I40E_DEBUG_ALL,
+                                  "This FW api version does not support drop mode.\n");
+       }
+
+#define I40E_AQ_SET_MAC_CONFIG_FC_DEFAULT_THRESHOLD    0x7FFF
+       cmd->fc_refresh_threshold =
+               CPU_TO_LE16(I40E_AQ_SET_MAC_CONFIG_FC_DEFAULT_THRESHOLD);
+
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
        return status;
@@ -1964,7 +2047,7 @@ enum i40e_status_code i40e_aq_get_link_info(struct i40e_hw *hw,
        hw_link_info->fec_info = resp->config & (I40E_AQ_CONFIG_FEC_KR_ENA |
                                                 I40E_AQ_CONFIG_FEC_RS_ENA);
        hw_link_info->ext_info = resp->ext_info;
-       hw_link_info->loopback = resp->loopback;
+       hw_link_info->loopback = resp->loopback & I40E_AQ_LOOPBACK_MASK;
        hw_link_info->max_frame_size = LE16_TO_CPU(resp->max_frame_size);
        hw_link_info->pacing = resp->config & I40E_AQ_CONFIG_PACING_MASK;
 
@@ -1995,6 +2078,19 @@ enum i40e_status_code i40e_aq_get_link_info(struct i40e_hw *hw,
             hw->aq.fw_min_ver < 40)) && hw_link_info->phy_type == 0xE)
                hw_link_info->phy_type = I40E_PHY_TYPE_10GBASE_SFPP_CU;
 
+       /* 'Get Link Status' response data structure from X722 FW has
+        * different format and does not contain this information
+        */
+       if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE &&
+           hw->mac.type != I40E_MAC_X722) {
+               __le32 tmp;
+
+               i40e_memcpy(&tmp, resp->link_type, sizeof(tmp),
+                           I40E_NONDMA_TO_NONDMA);
+               hw->phy.phy_types = LE32_TO_CPU(tmp);
+               hw->phy.phy_types |= ((u64)resp->link_type_ext << 32);
+       }
+
        /* save link status information */
        if (link)
                i40e_memcpy(link, hw_link_info, sizeof(*hw_link_info),
@@ -2179,6 +2275,22 @@ enum i40e_status_code i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
        return status;
 }
 
+/**
+ * i40e_hw_ver_ge
+ * @hw: pointer to the hw struct
+ * @maj: api major value
+ * @min: api minor value
+ *
+ * Assert whether current HW api version is greater/equal than provided.
+ **/
+static bool i40e_hw_ver_ge(struct i40e_hw *hw, u16 maj, u16 min)
+{
+       if (hw->aq.api_maj_ver > maj ||
+           (hw->aq.api_maj_ver == maj && hw->aq.api_min_ver >= min))
+               return true;
+       return false;
+}
+
 /**
  * i40e_aq_add_vsi
  * @hw: pointer to the hw struct
@@ -2304,18 +2416,16 @@ enum i40e_status_code i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw,
 
        if (set) {
                flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
-               if (rx_only_promisc &&
-                   (((hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver >= 5)) ||
-                    (hw->aq.api_maj_ver > 1)))
-                       flags |= I40E_AQC_SET_VSI_PROMISC_TX;
+               if (rx_only_promisc && i40e_hw_ver_ge(hw, 1, 5))
+                       flags |= I40E_AQC_SET_VSI_PROMISC_RX_ONLY;
        }
 
        cmd->promiscuous_flags = CPU_TO_LE16(flags);
 
        cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
-       if (((hw->aq.api_maj_ver >= 1) && (hw->aq.api_min_ver >= 5)) ||
-            (hw->aq.api_maj_ver > 1))
-               cmd->valid_flags |= CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_TX);
+       if (i40e_hw_ver_ge(hw, 1, 5))
+               cmd->valid_flags |=
+                       CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_RX_ONLY);
 
        cmd->seid = CPU_TO_LE16(seid);
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
@@ -2447,11 +2557,51 @@ enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
        i40e_fill_default_direct_cmd_desc(&desc,
                                        i40e_aqc_opc_set_vsi_promiscuous_modes);
 
-       if (enable)
+       if (enable) {
                flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
+               if (i40e_hw_ver_ge(hw, 1, 5))
+                       flags |= I40E_AQC_SET_VSI_PROMISC_RX_ONLY;
+       }
 
        cmd->promiscuous_flags = CPU_TO_LE16(flags);
        cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
+       if (i40e_hw_ver_ge(hw, 1, 5))
+               cmd->valid_flags |=
+                       CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_RX_ONLY);
+       cmd->seid = CPU_TO_LE16(seid);
+       cmd->vlan_tag = CPU_TO_LE16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
+
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+       return status;
+}
+
+/**
+ * i40e_aq_set_vsi_bc_promisc_on_vlan
+ * @hw: pointer to the hw struct
+ * @seid: vsi number
+ * @enable: set broadcast promiscuous enable/disable for a given VLAN
+ * @vid: The VLAN tag filter - capture any broadcast packet with this VLAN tag
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum i40e_status_code i40e_aq_set_vsi_bc_promisc_on_vlan(struct i40e_hw *hw,
+                               u16 seid, bool enable, u16 vid,
+                               struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+               (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
+       enum i40e_status_code status;
+       u16 flags = 0;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                       i40e_aqc_opc_set_vsi_promiscuous_modes);
+
+       if (enable)
+               flags |= I40E_AQC_SET_VSI_PROMISC_BROADCAST;
+
+       cmd->promiscuous_flags = CPU_TO_LE16(flags);
+       cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
        cmd->seid = CPU_TO_LE16(seid);
        cmd->vlan_tag = CPU_TO_LE16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
 
@@ -2527,7 +2677,7 @@ enum i40e_status_code i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
 }
 
 /**
- * i40e_get_vsi_params - get VSI configuration info
+ * i40e_aq_get_vsi_params - get VSI configuration info
  * @hw: pointer to the hw struct
  * @vsi_ctx: pointer to a vsi context struct
  * @cmd_details: pointer to command details structure or NULL
@@ -2639,13 +2789,14 @@ enum i40e_status_code i40e_aq_get_switch_config(struct i40e_hw *hw,
  * i40e_aq_set_switch_config
  * @hw: pointer to the hardware structure
  * @flags: bit flag values to set
+ * @mode: cloud filter mode
  * @valid_flags: which bit flags to set
  * @cmd_details: pointer to command details structure or NULL
  *
  * Set switch configuration bits
  **/
 enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw,
-                               u16 flags, u16 valid_flags,
+                               u16 flags, u16 valid_flags, u8 mode,
                                struct i40e_asq_cmd_details *cmd_details)
 {
        struct i40e_aq_desc desc;
@@ -2657,7 +2808,12 @@ enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw,
                                          i40e_aqc_opc_set_switch_config);
        scfg->flags = CPU_TO_LE16(flags);
        scfg->valid_flags = CPU_TO_LE16(valid_flags);
-
+       scfg->mode = mode;
+       if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) {
+               scfg->switch_tag = CPU_TO_LE16(hw->switch_tag);
+               scfg->first_tag = CPU_TO_LE16(hw->first_tag);
+               scfg->second_tag = CPU_TO_LE16(hw->second_tag);
+       }
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
        return status;
@@ -2782,7 +2938,7 @@ enum i40e_status_code i40e_get_link_status(struct i40e_hw *hw, bool *link_up)
 }
 
 /**
- * i40e_updatelink_status - update status of the HW network link
+ * i40e_update_link_info - update status of the HW network link
  * @hw: pointer to the hw struct
  **/
 enum i40e_status_code i40e_update_link_info(struct i40e_hw *hw)
@@ -2795,14 +2951,28 @@ enum i40e_status_code i40e_update_link_info(struct i40e_hw *hw)
                return status;
 
        /* extra checking needed to ensure link info to user is timely */
-       if ((hw->phy.link_info.link_info & I40E_AQ_MEDIA_AVAILABLE) &&
-           ((hw->phy.link_info.link_info & I40E_AQ_LINK_UP) ||
-            !(hw->phy.link_info_old.link_info & I40E_AQ_LINK_UP))) {
-               status = i40e_aq_get_phy_capabilities(hw, false, false,
+       if (((hw->phy.link_info.link_info & I40E_AQ_MEDIA_AVAILABLE) &&
+            ((hw->phy.link_info.link_info & I40E_AQ_LINK_UP) ||
+             !(hw->phy.link_info_old.link_info & I40E_AQ_LINK_UP))) ||
+               hw->mac.type == I40E_MAC_X722) {
+               status = i40e_aq_get_phy_capabilities(hw, false,
+                                                     hw->mac.type ==
+                                                     I40E_MAC_X722,
                                                      &abilities, NULL);
                if (status)
                        return status;
 
+               if (abilities.fec_cfg_curr_mod_ext_info &
+                   I40E_AQ_ENABLE_FEC_AUTO)
+                       hw->phy.link_info.req_fec_info =
+                               (I40E_AQ_REQUEST_FEC_KR |
+                                I40E_AQ_REQUEST_FEC_RS);
+               else
+                       hw->phy.link_info.req_fec_info =
+                               abilities.fec_cfg_curr_mod_ext_info &
+                               (I40E_AQ_REQUEST_FEC_KR |
+                                I40E_AQ_REQUEST_FEC_RS);
+
                i40e_memcpy(hw->phy.link_info.module_type, &abilities.module_type,
                        sizeof(hw->phy.link_info.module_type), I40E_NONDMA_TO_NONDMA);
        }
@@ -2950,6 +3120,46 @@ get_veb_exit:
        return status;
 }
 
+/**
+ * i40e_prepare_add_macvlan
+ * @mv_list: list of macvlans to be added
+ * @desc: pointer to AQ descriptor structure
+ * @count: length of the list
+ * @seid: VSI for the mac address
+ *
+ * Internal helper function that prepares the add macvlan request
+ * and returns the buffer size.
+ **/
+static u16
+i40e_prepare_add_macvlan(struct i40e_aqc_add_macvlan_element_data *mv_list,
+                        struct i40e_aq_desc *desc, u16 count, u16 seid)
+{
+       struct i40e_aqc_macvlan *cmd =
+               (struct i40e_aqc_macvlan *)&desc->params.raw;
+       u16 buf_size;
+       int i;
+
+       buf_size = count * sizeof(*mv_list);
+
+       /* prep the rest of the request */
+       i40e_fill_default_direct_cmd_desc(desc, i40e_aqc_opc_add_macvlan);
+       cmd->num_addresses = CPU_TO_LE16(count);
+       cmd->seid[0] = CPU_TO_LE16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid);
+       cmd->seid[1] = 0;
+       cmd->seid[2] = 0;
+
+       for (i = 0; i < count; i++)
+               if (I40E_IS_MULTICAST(mv_list[i].mac_addr))
+                       mv_list[i].flags |=
+                           CPU_TO_LE16(I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC);
+
+       desc->flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
+       if (buf_size > I40E_AQ_LARGE_BUF)
+               desc->flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+
+       return buf_size;
+}
+
 /**
  * i40e_aq_add_macvlan
  * @hw: pointer to the hw struct
@@ -2960,8 +3170,74 @@ get_veb_exit:
  *
  * Add MAC/VLAN addresses to the HW filtering
  **/
-enum i40e_status_code i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
-                       struct i40e_aqc_add_macvlan_element_data *mv_list,
+enum i40e_status_code
+i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
+                   struct i40e_aqc_add_macvlan_element_data *mv_list,
+                   u16 count, struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       enum i40e_status_code status;
+       u16 buf_size;
+
+       if (count == 0 || !mv_list || !hw)
+               return I40E_ERR_PARAM;
+
+       buf_size = i40e_prepare_add_macvlan(mv_list, &desc, count, seid);
+
+       status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
+                                      cmd_details);
+
+       return status;
+}
+
+/**
+ * i40e_aq_add_macvlan_v2
+ * @hw: pointer to the hw struct
+ * @seid: VSI for the mac address
+ * @mv_list: list of macvlans to be added
+ * @count: length of the list
+ * @cmd_details: pointer to command details structure or NULL
+ * @aq_status: pointer to Admin Queue status return value
+ *
+ * Add MAC/VLAN addresses to the HW filtering.
+ * The _v2 version returns the last Admin Queue status in aq_status
+ * to avoid race conditions in access to hw->aq.asq_last_status.
+ * It also calls _v2 versions of asq_send_command functions to
+ * get the aq_status on the stack.
+ **/
+enum i40e_status_code
+i40e_aq_add_macvlan_v2(struct i40e_hw *hw, u16 seid,
+                      struct i40e_aqc_add_macvlan_element_data *mv_list,
+                      u16 count, struct i40e_asq_cmd_details *cmd_details,
+                      enum i40e_admin_queue_err *aq_status)
+{
+       struct i40e_aq_desc desc;
+       enum i40e_status_code status;
+       u16 buf_size;
+
+       if (count == 0 || !mv_list || !hw)
+               return I40E_ERR_PARAM;
+
+       buf_size = i40e_prepare_add_macvlan(mv_list, &desc, count, seid);
+
+       status = i40e_asq_send_command_v2(hw, &desc, mv_list, buf_size,
+                                         cmd_details, aq_status);
+
+       return status;
+}
+
+/**
+ * i40e_aq_remove_macvlan
+ * @hw: pointer to the hw struct
+ * @seid: VSI for the mac address
+ * @mv_list: list of macvlans to be removed
+ * @count: length of the list
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Remove MAC/VLAN addresses from the HW filtering
+ **/
+enum i40e_status_code i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
+                       struct i40e_aqc_remove_macvlan_element_data *mv_list,
                        u16 count, struct i40e_asq_cmd_details *cmd_details)
 {
        struct i40e_aq_desc desc;
@@ -2969,7 +3245,6 @@ enum i40e_status_code i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
                (struct i40e_aqc_macvlan *)&desc.params.raw;
        enum i40e_status_code status;
        u16 buf_size;
-       int i;
 
        if (count == 0 || !mv_list || !hw)
                return I40E_ERR_PARAM;
@@ -2977,17 +3252,12 @@ enum i40e_status_code i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
        buf_size = count * sizeof(*mv_list);
 
        /* prep the rest of the request */
-       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_macvlan);
+       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_macvlan);
        cmd->num_addresses = CPU_TO_LE16(count);
        cmd->seid[0] = CPU_TO_LE16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid);
        cmd->seid[1] = 0;
        cmd->seid[2] = 0;
 
-       for (i = 0; i < count; i++)
-               if (I40E_IS_MULTICAST(mv_list[i].mac_addr))
-                       mv_list[i].flags |=
-                           CPU_TO_LE16(I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC);
-
        desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
        if (buf_size > I40E_AQ_LARGE_BUF)
                desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
@@ -2999,18 +3269,25 @@ enum i40e_status_code i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
 }
 
 /**
- * i40e_aq_remove_macvlan
+ * i40e_aq_remove_macvlan_v2
  * @hw: pointer to the hw struct
  * @seid: VSI for the mac address
  * @mv_list: list of macvlans to be removed
  * @count: length of the list
  * @cmd_details: pointer to command details structure or NULL
+ * @aq_status: pointer to Admin Queue status return value
  *
- * Remove MAC/VLAN addresses from the HW filtering
+ * Remove MAC/VLAN addresses from the HW filtering.
+ * The _v2 version returns the last Admin Queue status in aq_status
+ * to avoid race conditions in access to hw->aq.asq_last_status.
+ * It also calls _v2 versions of asq_send_command functions to
+ * get the aq_status on the stack.
  **/
-enum i40e_status_code i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
-                       struct i40e_aqc_remove_macvlan_element_data *mv_list,
-                       u16 count, struct i40e_asq_cmd_details *cmd_details)
+enum i40e_status_code
+i40e_aq_remove_macvlan_v2(struct i40e_hw *hw, u16 seid,
+                         struct i40e_aqc_remove_macvlan_element_data *mv_list,
+                         u16 count, struct i40e_asq_cmd_details *cmd_details,
+                         enum i40e_admin_queue_err *aq_status)
 {
        struct i40e_aq_desc desc;
        struct i40e_aqc_macvlan *cmd =
@@ -3034,8 +3311,8 @@ enum i40e_status_code i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
        if (buf_size > I40E_AQ_LARGE_BUF)
                desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
 
-       status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
-                                      cmd_details);
+       status = i40e_asq_send_command_v2(hw, &desc, mv_list, buf_size,
+                                         cmd_details, aq_status);
 
        return status;
 }
@@ -3051,8 +3328,8 @@ enum i40e_status_code i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
  * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
  * @cmd_details: pointer to command details structure or NULL
  * @rule_id: Rule ID returned from FW
- * @rule_used: Number of rules used in internal switch
- * @rule_free: Number of rules free in internal switch
+ * @rules_used: Number of rules used in internal switch
+ * @rules_free: Number of rules free in internal switch
  *
  * Add/Delete a mirror rule to a specific switch. Mirror rules are supported for
  * VEBs/VEPA elements only
@@ -3112,8 +3389,8 @@ static enum i40e_status_code i40e_mirrorrule_op(struct i40e_hw *hw,
  * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
  * @cmd_details: pointer to command details structure or NULL
  * @rule_id: Rule ID returned from FW
- * @rule_used: Number of rules used in internal switch
- * @rule_free: Number of rules free in internal switch
+ * @rules_used: Number of rules used in internal switch
+ * @rules_free: Number of rules free in internal switch
  *
  * Add mirror rule. Mirror rules are supported for VEBs or VEPA elements only
  **/
@@ -3143,8 +3420,8 @@ enum i40e_status_code i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
  *             add_mirrorrule.
  * @mr_list: list of mirrored VLAN IDs to be removed
  * @cmd_details: pointer to command details structure or NULL
- * @rule_used: Number of rules used in internal switch
- * @rule_free: Number of rules free in internal switch
+ * @rules_used: Number of rules used in internal switch
+ * @rules_free: Number of rules free in internal switch
  *
  * Delete a mirror rule. Mirror rules are supported for VEBs/VEPA elements only
  **/
@@ -3544,9 +3821,71 @@ enum i40e_status_code i40e_aq_write_nvm_config(struct i40e_hw *hw,
        return status;
 }
 
+/**
+ * i40e_aq_nvm_update_in_process
+ * @hw: pointer to the hw struct
+ * @update_flow_state: True indicates that update flow starts, false that ends
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Indicate NVM update in process.
+ **/
+enum i40e_status_code
+i40e_aq_nvm_update_in_process(struct i40e_hw *hw,
+                             bool update_flow_state,
+                             struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_nvm_update_in_process *cmd =
+               (struct i40e_aqc_nvm_update_in_process *)&desc.params.raw;
+       enum i40e_status_code status;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                         i40e_aqc_opc_nvm_update_in_process);
+
+       cmd->command = I40E_AQ_UPDATE_FLOW_END;
+
+       if (update_flow_state)
+               cmd->command |= I40E_AQ_UPDATE_FLOW_START;
+
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+       return status;
+}
+
+/**
+ * i40e_aq_min_rollback_rev_update - triggers an ow after update
+ * @hw: pointer to the hw struct
+ * @mode: opt-in mode, 1b for single module update, 0b for bulk update
+ * @module: module to be updated. Ignored if mode is 0b
+ * @min_rrev: value of the new minimal version. Ignored if mode is 0b
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum i40e_status_code
+i40e_aq_min_rollback_rev_update(struct i40e_hw *hw, u8 mode, u8 module,
+                               u32 min_rrev,
+                               struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_rollback_revision_update *cmd =
+               (struct i40e_aqc_rollback_revision_update *)&desc.params.raw;
+       enum i40e_status_code status;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+               i40e_aqc_opc_rollback_revision_update);
+       cmd->optin_mode = mode;
+       cmd->module_selected = module;
+       cmd->min_rrev = min_rrev;
+
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+       return status;
+}
+
 /**
  * i40e_aq_oem_post_update - triggers an OEM specific flow after update
  * @hw: pointer to the hw struct
+ * @buff: buffer for result
+ * @buff_size: buffer size
  * @cmd_details: pointer to command details structure or NULL
  **/
 enum i40e_status_code i40e_aq_oem_post_update(struct i40e_hw *hw,
@@ -3626,9 +3965,10 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
        u32 valid_functions, num_functions;
        u32 number, logical_id, phys_id;
        struct i40e_hw_capabilities *p;
+       enum i40e_status_code status;
+       u16 id, ocp_cfg_word0;
        u8 major_rev;
        u32 i = 0;
-       u16 id;
 
        cap = (struct i40e_aqc_list_capabilities_element_resp *) buff;
 
@@ -3873,16 +4213,21 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
                        p->wr_csr_prot = (u64)number;
                        p->wr_csr_prot |= (u64)logical_id << 32;
                        i40e_debug(hw, I40E_DEBUG_INIT,
-                                  "HW Capability: wr_csr_prot = 0x%llX\n\n",
+                                  "HW Capability: wr_csr_prot = 0x%" PRIX64 "\n\n",
                                   (p->wr_csr_prot & 0xffff));
                        break;
+               case I40E_AQ_CAP_ID_DIS_UNUSED_PORTS:
+                       p->dis_unused_ports = (bool)number;
+                       i40e_debug(hw, I40E_DEBUG_INIT,
+                                  "HW Capability: dis_unused_ports = %d\n\n",
+                                  p->dis_unused_ports);
+                       break;
                case I40E_AQ_CAP_ID_NVM_MGMT:
                        if (number & I40E_NVM_MGMT_SEC_REV_DISABLED)
                                p->sec_rev_disabled = true;
                        if (number & I40E_NVM_MGMT_UPDATE_DISABLED)
                                p->update_disabled = true;
                        break;
-#ifdef X722_SUPPORT
                case I40E_AQ_CAP_ID_WOL_AND_PROXY:
                        hw->num_wol_proxy_filters = (u16)number;
                        hw->wol_proxy_vsi_seid = (u16)logical_id;
@@ -3896,7 +4241,6 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
                                   "HW Capability: WOL proxy filters = %d\n",
                                   hw->num_wol_proxy_filters);
                        break;
-#endif
                default:
                        break;
                }
@@ -3922,6 +4266,26 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
                        hw->num_ports++;
        }
 
+       /* OCP cards case: if a mezz is removed the ethernet port is at
+        * disabled state in PRTGEN_CNF register. Additional NVM read is
+        * needed in order to check if we are dealing with OCP card.
+        * Those cards have 4 PFs at minimum, so using PRTGEN_CNF for counting
+        * physical ports results in wrong partition id calculation and thus
+        * not supporting WoL.
+        */
+       if (hw->mac.type == I40E_MAC_X722) {
+               if (i40e_acquire_nvm(hw, I40E_RESOURCE_READ) == I40E_SUCCESS) {
+                       status = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR,
+                                                 2 * I40E_SR_OCP_CFG_WORD0,
+                                                 sizeof(ocp_cfg_word0),
+                                                 &ocp_cfg_word0, true, NULL);
+                       if (status == I40E_SUCCESS &&
+                           (ocp_cfg_word0 & I40E_SR_OCP_ENABLED))
+                               hw->num_ports = 4;
+                       i40e_release_nvm(hw);
+               }
+       }
+
        valid_functions = p->valid_functions;
        num_functions = 0;
        while (valid_functions) {
@@ -3933,8 +4297,10 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
        /* partition id is 1-based, and functions are evenly spread
         * across the ports as partitions
         */
-       hw->partition_id = (hw->pf_id / hw->num_ports) + 1;
-       hw->num_partitions = num_functions / hw->num_ports;
+       if (hw->num_ports != 0) {
+               hw->partition_id = (hw->pf_id / hw->num_ports) + 1;
+               hw->num_partitions = num_functions / hw->num_ports;
+       }
 
        /* additional HW specific goodies that might
         * someday be HW version specific
@@ -3997,13 +4363,14 @@ exit:
  * @length: length of the section to be written (in bytes from the offset)
  * @data: command buffer (size [bytes] = length)
  * @last_command: tells if this is the last command in a series
+ * @preservation_flags: Preservation mode flags
  * @cmd_details: pointer to command details structure or NULL
  *
  * Update the NVM using the admin queue commands
  **/
 enum i40e_status_code i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
                                u32 offset, u16 length, void *data,
-                               bool last_command,
+                               bool last_command, u8 preservation_flags,
                                struct i40e_asq_cmd_details *cmd_details)
 {
        struct i40e_aq_desc desc;
@@ -4024,6 +4391,16 @@ enum i40e_status_code i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
        /* If this is the last command in a series, set the proper flag. */
        if (last_command)
                cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
+       if (hw->mac.type == I40E_MAC_X722) {
+               if (preservation_flags == I40E_NVM_PRESERVATION_FLAGS_SELECTED)
+                       cmd->command_flags |=
+                               (I40E_AQ_NVM_PRESERVATION_FLAGS_SELECTED <<
+                                I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT);
+               else if (preservation_flags == I40E_NVM_PRESERVATION_FLAGS_ALL)
+                       cmd->command_flags |=
+                               (I40E_AQ_NVM_PRESERVATION_FLAGS_ALL <<
+                                I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT);
+       }
        cmd->module_pointer = module_pointer;
        cmd->offset = CPU_TO_LE32(offset);
        cmd->length = CPU_TO_LE16(length);
@@ -4039,11 +4416,48 @@ i40e_aq_update_nvm_exit:
 }
 
 /**
- * i40e_aq_get_lldp_mib
+ * i40e_aq_rearrange_nvm
  * @hw: pointer to the hw struct
- * @bridge_type: type of bridge requested
- * @mib_type: Local, Remote or both Local and Remote MIBs
- * @buff: pointer to a user supplied buffer to store the MIB block
+ * @rearrange_nvm: defines direction of rearrangement
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Rearrange NVM structure, available only for transition FW
+ **/
+enum i40e_status_code i40e_aq_rearrange_nvm(struct i40e_hw *hw,
+                               u8 rearrange_nvm,
+                               struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aqc_nvm_update *cmd;
+       enum i40e_status_code status;
+       struct i40e_aq_desc desc;
+
+       DEBUGFUNC("i40e_aq_rearrange_nvm");
+
+       cmd = (struct i40e_aqc_nvm_update *)&desc.params.raw;
+
+       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_update);
+
+       rearrange_nvm &= (I40E_AQ_NVM_REARRANGE_TO_FLAT |
+                        I40E_AQ_NVM_REARRANGE_TO_STRUCT);
+
+       if (!rearrange_nvm) {
+               status = I40E_ERR_PARAM;
+               goto i40e_aq_rearrange_nvm_exit;
+       }
+
+       cmd->command_flags |= rearrange_nvm;
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+i40e_aq_rearrange_nvm_exit:
+       return status;
+}
+
+/**
+ * i40e_aq_get_lldp_mib
+ * @hw: pointer to the hw struct
+ * @bridge_type: type of bridge requested
+ * @mib_type: Local, Remote or both Local and Remote MIBs
+ * @buff: pointer to a user supplied buffer to store the MIB block
  * @buff_size: size of the buffer (in bytes)
  * @local_len : length of the returned Local LLDP MIB
  * @remote_len: length of the returned Remote LLDP MIB
@@ -4123,7 +4537,7 @@ enum i40e_status_code i40e_aq_set_lldp_mib(struct i40e_hw *hw,
 
        cmd->type = mib_type;
        cmd->length = CPU_TO_LE16(buff_size);
-       cmd->address_high = CPU_TO_LE32(I40E_HI_WORD((u64)buff));
+       cmd->address_high = CPU_TO_LE32(I40E_HI_DWORD((u64)buff));
        cmd->address_low =  CPU_TO_LE32(I40E_LO_DWORD((u64)buff));
 
        status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
@@ -4159,200 +4573,139 @@ enum i40e_status_code i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
 }
 
 /**
- * i40e_aq_add_lldp_tlv
+ * i40e_aq_restore_lldp
  * @hw: pointer to the hw struct
- * @bridge_type: type of bridge
- * @buff: buffer with TLV to add
- * @buff_size: length of the buffer
- * @tlv_len: length of the TLV to be added
- * @mib_len: length of the LLDP MIB returned in response
+ * @setting: pointer to factory setting variable or NULL
+ * @restore: True if factory settings should be restored
  * @cmd_details: pointer to command details structure or NULL
  *
- * Add the specified TLV to LLDP Local MIB for the given bridge type,
- * it is responsibility of the caller to make sure that the TLV is not
- * already present in the LLDPDU.
- * In return firmware will write the complete LLDP MIB with the newly
- * added TLV in the response buffer.
+ * Restore LLDP Agent factory settings if @restore set to True. In other case
+ * only returns factory setting in AQ response.
  **/
-enum i40e_status_code i40e_aq_add_lldp_tlv(struct i40e_hw *hw, u8 bridge_type,
-                               void *buff, u16 buff_size, u16 tlv_len,
-                               u16 *mib_len,
-                               struct i40e_asq_cmd_details *cmd_details)
+enum i40e_status_code
+i40e_aq_restore_lldp(struct i40e_hw *hw, u8 *setting, bool restore,
+                    struct i40e_asq_cmd_details *cmd_details)
 {
        struct i40e_aq_desc desc;
-       struct i40e_aqc_lldp_add_tlv *cmd =
-               (struct i40e_aqc_lldp_add_tlv *)&desc.params.raw;
+       struct i40e_aqc_lldp_restore *cmd =
+               (struct i40e_aqc_lldp_restore *)&desc.params.raw;
        enum i40e_status_code status;
 
-       if (buff_size == 0 || !buff || tlv_len == 0)
-               return I40E_ERR_PARAM;
+       if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)) {
+               i40e_debug(hw, I40E_DEBUG_ALL,
+                          "Restore LLDP not supported by current FW version.\n");
+               return I40E_ERR_DEVICE_NOT_SUPPORTED;
+       }
 
-       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_add_tlv);
+       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_restore);
 
-       /* Indirect Command */
-       desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
-       if (buff_size > I40E_AQ_LARGE_BUF)
-               desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
-       desc.datalen = CPU_TO_LE16(buff_size);
+       if (restore)
+               cmd->command |= I40E_AQ_LLDP_AGENT_RESTORE;
 
-       cmd->type = ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) &
-                     I40E_AQ_LLDP_BRIDGE_TYPE_MASK);
-       cmd->len = CPU_TO_LE16(tlv_len);
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
-       status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
-       if (!status) {
-               if (mib_len != NULL)
-                       *mib_len = LE16_TO_CPU(desc.datalen);
-       }
+       if (setting)
+               *setting = cmd->command & 1;
 
        return status;
 }
 
 /**
- * i40e_aq_update_lldp_tlv
+ * i40e_aq_stop_lldp
  * @hw: pointer to the hw struct
- * @bridge_type: type of bridge
- * @buff: buffer with TLV to update
- * @buff_size: size of the buffer holding original and updated TLVs
- * @old_len: Length of the Original TLV
- * @new_len: Length of the Updated TLV
- * @offset: offset of the updated TLV in the buff
- * @mib_len: length of the returned LLDP MIB
+ * @shutdown_agent: True if LLDP Agent needs to be Shutdown
+ * @persist: True if stop of LLDP should be persistent across power cycles
  * @cmd_details: pointer to command details structure or NULL
  *
- * Update the specified TLV to the LLDP Local MIB for the given bridge type.
- * Firmware will place the complete LLDP MIB in response buffer with the
- * updated TLV.
+ * Stop or Shutdown the embedded LLDP Agent
  **/
-enum i40e_status_code i40e_aq_update_lldp_tlv(struct i40e_hw *hw,
-                               u8 bridge_type, void *buff, u16 buff_size,
-                               u16 old_len, u16 new_len, u16 offset,
-                               u16 *mib_len,
+enum i40e_status_code i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
+                               bool persist,
                                struct i40e_asq_cmd_details *cmd_details)
 {
        struct i40e_aq_desc desc;
-       struct i40e_aqc_lldp_update_tlv *cmd =
-               (struct i40e_aqc_lldp_update_tlv *)&desc.params.raw;
+       struct i40e_aqc_lldp_stop *cmd =
+               (struct i40e_aqc_lldp_stop *)&desc.params.raw;
        enum i40e_status_code status;
 
-       if (buff_size == 0 || !buff || offset == 0 ||
-           old_len == 0 || new_len == 0)
-               return I40E_ERR_PARAM;
-
-       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_update_tlv);
-
-       /* Indirect Command */
-       desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
-       if (buff_size > I40E_AQ_LARGE_BUF)
-               desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
-       desc.datalen = CPU_TO_LE16(buff_size);
+       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_stop);
 
-       cmd->type = ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) &
-                     I40E_AQ_LLDP_BRIDGE_TYPE_MASK);
-       cmd->old_len = CPU_TO_LE16(old_len);
-       cmd->new_offset = CPU_TO_LE16(offset);
-       cmd->new_len = CPU_TO_LE16(new_len);
+       if (shutdown_agent)
+               cmd->command |= I40E_AQ_LLDP_AGENT_SHUTDOWN;
 
-       status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
-       if (!status) {
-               if (mib_len != NULL)
-                       *mib_len = LE16_TO_CPU(desc.datalen);
+       if (persist) {
+               if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)
+                       cmd->command |= I40E_AQ_LLDP_AGENT_STOP_PERSIST;
+               else
+                       i40e_debug(hw, I40E_DEBUG_ALL,
+                                  "Persistent Stop LLDP not supported by current FW version.\n");
        }
 
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
        return status;
 }
 
 /**
- * i40e_aq_delete_lldp_tlv
+ * i40e_aq_start_lldp
  * @hw: pointer to the hw struct
- * @bridge_type: type of bridge
- * @buff: pointer to a user supplied buffer that has the TLV
- * @buff_size: length of the buffer
- * @tlv_len: length of the TLV to be deleted
- * @mib_len: length of the returned LLDP MIB
+ * @persist: True if start of LLDP should be persistent across power cycles
  * @cmd_details: pointer to command details structure or NULL
  *
- * Delete the specified TLV from LLDP Local MIB for the given bridge type.
- * The firmware places the entire LLDP MIB in the response buffer.
+ * Start the embedded LLDP Agent on all ports.
  **/
-enum i40e_status_code i40e_aq_delete_lldp_tlv(struct i40e_hw *hw,
-                               u8 bridge_type, void *buff, u16 buff_size,
-                               u16 tlv_len, u16 *mib_len,
+enum i40e_status_code i40e_aq_start_lldp(struct i40e_hw *hw,
+                               bool persist,
                                struct i40e_asq_cmd_details *cmd_details)
 {
        struct i40e_aq_desc desc;
-       struct i40e_aqc_lldp_add_tlv *cmd =
-               (struct i40e_aqc_lldp_add_tlv *)&desc.params.raw;
+       struct i40e_aqc_lldp_start *cmd =
+               (struct i40e_aqc_lldp_start *)&desc.params.raw;
        enum i40e_status_code status;
 
-       if (buff_size == 0 || !buff)
-               return I40E_ERR_PARAM;
-
-       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_delete_tlv);
+       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_start);
 
-       /* Indirect Command */
-       desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
-       if (buff_size > I40E_AQ_LARGE_BUF)
-               desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
-       desc.datalen = CPU_TO_LE16(buff_size);
-       cmd->len = CPU_TO_LE16(tlv_len);
-       cmd->type = ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) &
-                     I40E_AQ_LLDP_BRIDGE_TYPE_MASK);
+       cmd->command = I40E_AQ_LLDP_AGENT_START;
 
-       status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
-       if (!status) {
-               if (mib_len != NULL)
-                       *mib_len = LE16_TO_CPU(desc.datalen);
+       if (persist) {
+               if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)
+                       cmd->command |= I40E_AQ_LLDP_AGENT_START_PERSIST;
+               else
+                       i40e_debug(hw, I40E_DEBUG_ALL,
+                                  "Persistent Start LLDP not supported by current FW version.\n");
        }
 
-       return status;
-}
-
-/**
- * i40e_aq_stop_lldp
- * @hw: pointer to the hw struct
- * @shutdown_agent: True if LLDP Agent needs to be Shutdown
- * @cmd_details: pointer to command details structure or NULL
- *
- * Stop or Shutdown the embedded LLDP Agent
- **/
-enum i40e_status_code i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
-                               struct i40e_asq_cmd_details *cmd_details)
-{
-       struct i40e_aq_desc desc;
-       struct i40e_aqc_lldp_stop *cmd =
-               (struct i40e_aqc_lldp_stop *)&desc.params.raw;
-       enum i40e_status_code status;
-
-       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_stop);
-
-       if (shutdown_agent)
-               cmd->command |= I40E_AQ_LLDP_AGENT_SHUTDOWN;
-
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
        return status;
 }
 
 /**
- * i40e_aq_start_lldp
+ * i40e_aq_set_dcb_parameters
  * @hw: pointer to the hw struct
  * @cmd_details: pointer to command details structure or NULL
+ * @dcb_enable: True if DCB configuration needs to be applied
  *
- * Start the embedded LLDP Agent on all ports.
  **/
-enum i40e_status_code i40e_aq_start_lldp(struct i40e_hw *hw,
-                               struct i40e_asq_cmd_details *cmd_details)
+enum i40e_status_code
+i40e_aq_set_dcb_parameters(struct i40e_hw *hw, bool dcb_enable,
+                          struct i40e_asq_cmd_details *cmd_details)
 {
        struct i40e_aq_desc desc;
-       struct i40e_aqc_lldp_start *cmd =
-               (struct i40e_aqc_lldp_start *)&desc.params.raw;
+       struct i40e_aqc_set_dcb_parameters *cmd =
+               (struct i40e_aqc_set_dcb_parameters *)&desc.params.raw;
        enum i40e_status_code status;
 
-       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_start);
+       if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_STOPPABLE))
+               return I40E_ERR_DEVICE_NOT_SUPPORTED;
 
-       cmd->command = I40E_AQ_LLDP_AGENT_START;
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                         i40e_aqc_opc_set_dcb_parameters);
 
+       if (dcb_enable) {
+               cmd->valid_flags = I40E_DCB_VALID;
+               cmd->command = I40E_AQ_DCB_SET_AGENT;
+       }
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
        return status;
@@ -4419,11 +4772,14 @@ enum i40e_status_code i40e_aq_start_stop_dcbx(struct i40e_hw *hw,
 /**
  * i40e_aq_add_udp_tunnel
  * @hw: pointer to the hw struct
- * @udp_port: the UDP port to add
- * @header_len: length of the tunneling header length in DWords
+ * @udp_port: the UDP port to add in Host byte order
  * @protocol_index: protocol index type
  * @filter_index: pointer to filter index
  * @cmd_details: pointer to command details structure or NULL
+ *
+ * Note: Firmware expects the udp_port value to be in Little Endian format,
+ * and this function will call CPU_TO_LE16 to convert from Host byte order to
+ * Little Endian order.
  **/
 enum i40e_status_code i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
                                u16 udp_port, u8 protocol_index,
@@ -4474,7 +4830,7 @@ enum i40e_status_code i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index,
 }
 
 /**
- * i40e_aq_get_switch_resource_alloc (0x0204)
+ * i40e_aq_get_switch_resource_alloc - command (0x0204) to get allocations
  * @hw: pointer to the hw struct
  * @num_entries: pointer to u8 to store the number of resource entries returned
  * @buf: pointer to a user supplied buffer.  This buffer must be large enough
@@ -4715,8 +5071,6 @@ enum i40e_status_code i40e_aq_add_mcast_etag(struct i40e_hw *hw, u16 pv_seid,
        cmd->num_unicast_etags = num_tags_in_buf;
 
        desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
-       if (length > I40E_AQ_LARGE_BUF)
-               desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
 
        status = i40e_asq_send_command(hw, &desc, buf, length, cmd_details);
 
@@ -5159,6 +5513,7 @@ enum i40e_status_code i40e_aq_config_vsi_tc_bw(struct i40e_hw *hw,
  * @hw: pointer to the hw struct
  * @seid: seid of the switching component connected to Physical Port
  * @ets_data: Buffer holding ETS parameters
+ * @opcode: Tx scheduler AQ command opcode
  * @cmd_details: pointer to command details structure or NULL
  **/
 enum i40e_status_code i40e_aq_config_switch_comp_ets(struct i40e_hw *hw,
@@ -5497,7 +5852,7 @@ enum i40e_status_code i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
        }
 
        if (mac_addr)
-               i40e_memcpy(cmd->mac, mac_addr, I40E_ETH_LENGTH_OF_ADDRESS,
+               i40e_memcpy(cmd->mac, mac_addr, ETH_ALEN,
                            I40E_NONDMA_TO_NONDMA);
 
        cmd->etype = CPU_TO_LE16(ethtype);
@@ -5521,10 +5876,10 @@ enum i40e_status_code i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
  * @hw: pointer to the hw struct
  * @seid: VSI seid to add ethertype filter from
  **/
-#define I40E_FLOW_CONTROL_ETHTYPE 0x8808
 void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
                                                    u16 seid)
 {
+#define I40E_FLOW_CONTROL_ETHTYPE 0x8808
        u16 flag = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC |
                   I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
                   I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
@@ -5547,10 +5902,10 @@ void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
  * to be shifted 1 byte over from the VxLAN VNI
  **/
 STATIC void i40e_fix_up_geneve_vni(
-       struct i40e_aqc_add_remove_cloud_filters_element_data *filters,
+       struct i40e_aqc_cloud_filters_element_data *filters,
        u8 filter_count)
 {
-       struct i40e_aqc_add_remove_cloud_filters_element_data *f = filters;
+       struct i40e_aqc_cloud_filters_element_data *f = filters;
        int i;
 
        for (i = 0; i < filter_count; i++) {
@@ -5575,13 +5930,13 @@ STATIC void i40e_fix_up_geneve_vni(
  * @filter_count: number of filters contained in the buffer
  *
  * Set the cloud filters for a given VSI.  The contents of the
- * i40e_aqc_add_remove_cloud_filters_element_data are filled
+ * i40e_aqc_cloud_filters_element_data are filled
  * in by the caller of the function.
  *
  **/
 enum i40e_status_code i40e_aq_add_cloud_filters(struct i40e_hw *hw,
        u16 seid,
-       struct i40e_aqc_add_remove_cloud_filters_element_data *filters,
+       struct i40e_aqc_cloud_filters_element_data *filters,
        u8 filter_count)
 {
        struct i40e_aq_desc desc;
@@ -5607,21 +5962,78 @@ enum i40e_status_code i40e_aq_add_cloud_filters(struct i40e_hw *hw,
 }
 
 /**
- * i40e_aq_remove_cloud_filters
+ * i40e_aq_add_cloud_filters_bb
+ * @hw: pointer to the hardware structure
+ * @seid: VSI seid to add cloud filters from
+ * @filters: Buffer which contains the filters in big buffer to be added
+ * @filter_count: number of filters contained in the buffer
+ *
+ * Set the cloud filters for a given VSI.  The contents of the
+ * i40e_aqc_cloud_filters_element_bb are filled in by the caller of
+ * the function.
+ *
+ **/
+enum i40e_status_code
+i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
+                            struct i40e_aqc_cloud_filters_element_bb *filters,
+                            u8 filter_count)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_add_remove_cloud_filters *cmd =
+       (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
+       enum i40e_status_code status;
+       u16 buff_len;
+       int i;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                         i40e_aqc_opc_add_cloud_filters);
+
+       buff_len = filter_count * sizeof(*filters);
+       desc.datalen = CPU_TO_LE16(buff_len);
+       desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
+       cmd->num_filters = filter_count;
+       cmd->seid = CPU_TO_LE16(seid);
+       cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
+
+       for (i = 0; i < filter_count; i++) {
+               u16 tnl_type;
+               u32 ti;
+
+               tnl_type = (LE16_TO_CPU(filters[i].element.flags) &
+                          I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
+                          I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
+
+               /* Due to hardware eccentricities, the VNI for Geneve is shifted
+                * one more byte further than normally used for Tenant ID in
+                * other tunnel types.
+                */
+               if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
+                       ti = LE32_TO_CPU(filters[i].element.tenant_id);
+                       filters[i].element.tenant_id = CPU_TO_LE32(ti << 8);
+               }
+       }
+
+       status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
+
+       return status;
+}
+
+/**
+ * i40e_aq_rem_cloud_filters
  * @hw: pointer to the hardware structure
  * @seid: VSI seid to remove cloud filters from
  * @filters: Buffer which contains the filters to be removed
  * @filter_count: number of filters contained in the buffer
  *
  * Remove the cloud filters for a given VSI.  The contents of the
- * i40e_aqc_add_remove_cloud_filters_element_data are filled
- * in by the caller of the function.
+ * i40e_aqc_cloud_filters_element_data are filled in by the caller
+ * of the function.
  *
  **/
-enum i40e_status_code i40e_aq_remove_cloud_filters(struct i40e_hw *hw,
-               u16 seid,
-               struct i40e_aqc_add_remove_cloud_filters_element_data *filters,
-               u8 filter_count)
+enum i40e_status_code
+i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid,
+                         struct i40e_aqc_cloud_filters_element_data *filters,
+                         u8 filter_count)
 {
        struct i40e_aq_desc desc;
        struct i40e_aqc_add_remove_cloud_filters *cmd =
@@ -5645,6 +6057,115 @@ enum i40e_status_code i40e_aq_remove_cloud_filters(struct i40e_hw *hw,
        return status;
 }
 
+/**
+ * i40e_aq_rem_cloud_filters_bb
+ * @hw: pointer to the hardware structure
+ * @seid: VSI seid to remove cloud filters from
+ * @filters: Buffer which contains the filters in big buffer to be removed
+ * @filter_count: number of filters contained in the buffer
+ *
+ * Remove the big buffer cloud filters for a given VSI.  The contents of the
+ * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the
+ * function.
+ *
+ **/
+enum i40e_status_code
+i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
+                            struct i40e_aqc_cloud_filters_element_bb *filters,
+                            u8 filter_count)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_add_remove_cloud_filters *cmd =
+       (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
+       enum i40e_status_code status;
+       u16 buff_len;
+       int i;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                         i40e_aqc_opc_remove_cloud_filters);
+
+       buff_len = filter_count * sizeof(*filters);
+       desc.datalen = CPU_TO_LE16(buff_len);
+       desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
+       cmd->num_filters = filter_count;
+       cmd->seid = CPU_TO_LE16(seid);
+       cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
+
+       for (i = 0; i < filter_count; i++) {
+               u16 tnl_type;
+               u32 ti;
+
+               tnl_type = (LE16_TO_CPU(filters[i].element.flags) &
+                          I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
+                          I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
+
+               /* Due to hardware eccentricities, the VNI for Geneve is shifted
+                * one more byte further than normally used for Tenant ID in
+                * other tunnel types.
+                */
+               if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
+                       ti = LE32_TO_CPU(filters[i].element.tenant_id);
+                       filters[i].element.tenant_id = CPU_TO_LE32(ti << 8);
+               }
+       }
+
+       status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
+
+       return status;
+}
+
+/**
+ * i40e_aq_replace_cloud_filters - Replace cloud filter command
+ * @hw: pointer to the hw struct
+ * @filters: pointer to the i40e_aqc_replace_cloud_filter_cmd struct
+ * @cmd_buf: pointer to the i40e_aqc_replace_cloud_filter_cmd_buf struct
+ *
+ **/
+enum
+i40e_status_code i40e_aq_replace_cloud_filters(struct i40e_hw *hw,
+       struct i40e_aqc_replace_cloud_filters_cmd *filters,
+       struct i40e_aqc_replace_cloud_filters_cmd_buf *cmd_buf)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_replace_cloud_filters_cmd *cmd =
+               (struct i40e_aqc_replace_cloud_filters_cmd *)&desc.params.raw;
+       enum i40e_status_code status = I40E_SUCCESS;
+       int i = 0;
+
+       /* X722 doesn't support this command */
+       if (hw->mac.type == I40E_MAC_X722)
+               return I40E_ERR_DEVICE_NOT_SUPPORTED;
+
+       /* need FW version greater than 6.00 */
+       if (hw->aq.fw_maj_ver < 6)
+               return I40E_NOT_SUPPORTED;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                         i40e_aqc_opc_replace_cloud_filters);
+
+       desc.datalen = CPU_TO_LE16(32);
+       desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
+       cmd->old_filter_type = filters->old_filter_type;
+       cmd->new_filter_type = filters->new_filter_type;
+       cmd->valid_flags = filters->valid_flags;
+       cmd->tr_bit = filters->tr_bit;
+       cmd->tr_bit2 = filters->tr_bit2;
+
+       status = i40e_asq_send_command(hw, &desc, cmd_buf,
+               sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf),  NULL);
+
+       /* for get cloud filters command */
+       for (i = 0; i < 32; i += 4) {
+               cmd_buf->filters[i / 4].filter_type = cmd_buf->data[i];
+               cmd_buf->filters[i / 4].input[0] = cmd_buf->data[i + 1];
+               cmd_buf->filters[i / 4].input[1] = cmd_buf->data[i + 2];
+               cmd_buf->filters[i / 4].input[2] = cmd_buf->data[i + 3];
+       }
+
+       return status;
+}
+
+
 /**
  * i40e_aq_alternate_write
  * @hw: pointer to the hardware structure
@@ -5955,6 +6476,7 @@ void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)
  * @ret_buff_size: actual buffer size returned
  * @ret_next_table: next block to read
  * @ret_next_index: next index to read
+ * @cmd_details: pointer to command details structure or NULL
  *
  * Dump internal FW/HW data for debug purposes.
  *
@@ -6001,6 +6523,71 @@ enum i40e_status_code i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
        return status;
 }
 
+
+/**
+ * i40e_enable_eee
+ * @hw: pointer to the hardware structure
+ * @enable: state of Energy Efficient Ethernet mode to be set
+ *
+ * Enables or disables Energy Efficient Ethernet (EEE) mode
+ * accordingly to @enable parameter.
+ **/
+enum i40e_status_code i40e_enable_eee(struct i40e_hw *hw, bool enable)
+{
+       struct i40e_aq_get_phy_abilities_resp abilities;
+       struct i40e_aq_set_phy_config config;
+       enum i40e_status_code status;
+       __le16 eee_capability;
+
+       /* Get initial PHY capabilities */
+       status = i40e_aq_get_phy_capabilities(hw, false, true, &abilities,
+                                             NULL);
+       if (status)
+               goto err;
+
+       /* Check whether NIC configuration is compatible with Energy Efficient
+        * Ethernet (EEE) mode.
+        */
+       if (abilities.eee_capability == 0) {
+               status = I40E_ERR_CONFIG;
+               goto err;
+       }
+
+       /* Cache initial EEE capability */
+       eee_capability = abilities.eee_capability;
+
+       /* Get current configuration */
+       status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
+                                             NULL);
+       if (status)
+               goto err;
+
+       /* Cache current configuration */
+       config.phy_type = abilities.phy_type;
+       config.phy_type_ext = abilities.phy_type_ext;
+       config.link_speed = abilities.link_speed;
+       config.abilities = abilities.abilities |
+                          I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
+       config.eeer = abilities.eeer_val;
+       config.low_power_ctrl = abilities.d3_lpan;
+       config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
+                           I40E_AQ_PHY_FEC_CONFIG_MASK;
+
+       /* Set desired EEE state */
+       if (enable) {
+               config.eee_capability = eee_capability;
+               config.eeer |= I40E_PRTPM_EEER_TX_LPI_EN_MASK;
+       } else {
+               config.eee_capability = 0;
+               config.eeer &= ~I40E_PRTPM_EEER_TX_LPI_EN_MASK;
+       }
+
+       /* Save modified config */
+       status = i40e_aq_set_phy_config(hw, &config, NULL);
+err:
+       return status;
+}
+
 /**
  * i40e_read_bw_from_alt_ram
  * @hw: pointer to the hardware structure
@@ -6077,7 +6664,7 @@ enum i40e_status_code i40e_aq_configure_partition_bw(struct i40e_hw *hw,
  * i40e_read_phy_register_clause22
  * @hw: pointer to the HW structure
  * @reg: register address in the page
- * @phy_adr: PHY address on MDIO interface
+ * @phy_addr: PHY address on MDIO interface
  * @value: PHY register value
  *
  * Reads specified PHY register value
@@ -6122,7 +6709,7 @@ enum i40e_status_code i40e_read_phy_register_clause22(struct i40e_hw *hw,
  * i40e_write_phy_register_clause22
  * @hw: pointer to the HW structure
  * @reg: register address in the page
- * @phy_adr: PHY address on MDIO interface
+ * @phy_addr: PHY address on MDIO interface
  * @value: PHY register value
  *
  * Writes specified PHY register value
@@ -6163,7 +6750,7 @@ enum i40e_status_code i40e_write_phy_register_clause22(struct i40e_hw *hw,
  * @hw: pointer to the HW structure
  * @page: registers page number
  * @reg: register address in the page
- * @phy_adr: PHY address on MDIO interface
+ * @phy_addr: PHY address on MDIO interface
  * @value: PHY register value
  *
  * Reads specified PHY register value
@@ -6237,7 +6824,7 @@ phy_read_end:
  * @hw: pointer to the HW structure
  * @page: registers page number
  * @reg: register address in the page
- * @phy_adr: PHY address on MDIO interface
+ * @phy_addr: PHY address on MDIO interface
  * @value: PHY register value
  *
  * Writes value to specified PHY register
@@ -6304,7 +6891,7 @@ phy_write_end:
  * @hw: pointer to the HW structure
  * @page: registers page number
  * @reg: register address in the page
- * @phy_adr: PHY address on MDIO interface
+ * @phy_addr: PHY address on MDIO interface
  * @value: PHY register value
  *
  * Writes value to specified PHY register
@@ -6321,6 +6908,8 @@ enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
                break;
        case I40E_DEV_ID_10G_BASE_T:
        case I40E_DEV_ID_10G_BASE_T4:
+       case I40E_DEV_ID_10G_BASE_T_BC:
+       case I40E_DEV_ID_5G_BASE_T_BC:
        case I40E_DEV_ID_10G_BASE_T_X722:
        case I40E_DEV_ID_25G_B:
        case I40E_DEV_ID_25G_SFP28:
@@ -6340,7 +6929,7 @@ enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
  * @hw: pointer to the HW structure
  * @page: registers page number
  * @reg: register address in the page
- * @phy_adr: PHY address on MDIO interface
+ * @phy_addr: PHY address on MDIO interface
  * @value: PHY register value
  *
  * Reads specified PHY register value
@@ -6357,6 +6946,7 @@ enum i40e_status_code i40e_read_phy_register(struct i40e_hw *hw,
                break;
        case I40E_DEV_ID_10G_BASE_T:
        case I40E_DEV_ID_10G_BASE_T4:
+       case I40E_DEV_ID_5G_BASE_T_BC:
        case I40E_DEV_ID_10G_BASE_T_X722:
        case I40E_DEV_ID_25G_B:
        case I40E_DEV_ID_25G_SFP28:
@@ -6375,7 +6965,6 @@ enum i40e_status_code i40e_read_phy_register(struct i40e_hw *hw,
  * i40e_get_phy_address
  * @hw: pointer to the HW structure
  * @dev_num: PHY port num that address we want
- * @phy_addr: Returned PHY address
  *
  * Gets PHY address for current port
  **/
@@ -6388,7 +6977,7 @@ u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num)
 }
 
 /**
- * i40e_blink_phy_led
+ * i40e_blink_phy_link_led
  * @hw: pointer to the HW structure
  * @time: time how long led will blinks in secs
  * @interval: gap between LED on and off in msecs
@@ -6462,8 +7051,66 @@ phy_blinking_end:
 }
 
 /**
- * i40e_led_get_phy - return current on/off mode
- * @hw: pointer to the hw struct
+ * i40e_led_get_reg - read LED register
+ * @hw: pointer to the HW structure
+ * @led_addr: LED register address
+ * @reg_val: read register value
+ **/
+enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
+                                      u32 *reg_val)
+{
+       enum i40e_status_code status;
+       u8 phy_addr = 0;
+
+       *reg_val = 0;
+       if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
+               status = i40e_aq_get_phy_register(hw,
+                                               I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
+                                               I40E_PHY_COM_REG_PAGE, true,
+                                               I40E_PHY_LED_PROV_REG_1,
+                                               reg_val, NULL);
+       } else {
+               phy_addr = i40e_get_phy_address(hw, hw->port);
+               status = i40e_read_phy_register_clause45(hw,
+                                                        I40E_PHY_COM_REG_PAGE,
+                                                        led_addr, phy_addr,
+                                                        (u16 *)reg_val);
+       }
+       return status;
+}
+
+/**
+ * i40e_led_set_reg - write LED register
+ * @hw: pointer to the HW structure
+ * @led_addr: LED register address
+ * @reg_val: register value to write
+ **/
+enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
+                                      u32 reg_val)
+{
+       enum i40e_status_code status;
+       u8 phy_addr = 0;
+
+       if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
+               status = i40e_aq_set_phy_register(hw,
+                                               I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
+                                               I40E_PHY_COM_REG_PAGE, true,
+                                               I40E_PHY_LED_PROV_REG_1,
+                                               reg_val, NULL);
+       } else {
+               phy_addr = i40e_get_phy_address(hw, hw->port);
+               status = i40e_write_phy_register_clause45(hw,
+                                                         I40E_PHY_COM_REG_PAGE,
+                                                         led_addr, phy_addr,
+                                                         (u16)reg_val);
+       }
+
+       return status;
+}
+
+/**
+ * i40e_led_get_phy - return current on/off mode
+ * @hw: pointer to the hw struct
  * @led_addr: address of led register to use
  * @val: original value of register to use
  *
@@ -6473,17 +7120,23 @@ enum i40e_status_code i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
 {
        enum i40e_status_code status = I40E_SUCCESS;
        u16 gpio_led_port;
+       u32 reg_val_aq;
+       u16 temp_addr;
        u8 phy_addr = 0;
        u16 reg_val;
-       u16 temp_addr;
-       u8 port_num;
-       u32 i;
 
+       if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
+               status = i40e_aq_get_phy_register(hw,
+                                               I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
+                                               I40E_PHY_COM_REG_PAGE, true,
+                                               I40E_PHY_LED_PROV_REG_1,
+                                               &reg_val_aq, NULL);
+               if (status == I40E_SUCCESS)
+                       *val = (u16)reg_val_aq;
+               return status;
+       }
        temp_addr = I40E_PHY_LED_PROV_REG_1;
-       i = rd32(hw, I40E_PFGEN_PORTNUM);
-       port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
-       phy_addr = i40e_get_phy_address(hw, port_num);
-
+       phy_addr = i40e_get_phy_address(hw, hw->port);
        for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
             temp_addr++) {
                status = i40e_read_phy_register_clause45(hw,
@@ -6505,7 +7158,9 @@ enum i40e_status_code i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
  * i40e_led_set_phy
  * @hw: pointer to the HW structure
  * @on: true or false
+ * @led_addr: address of led register to use
  * @mode: original val plus bit for set or ignore
+ *
  * Set led's on or off when controlled by the PHY
  *
  **/
@@ -6513,54 +7168,237 @@ enum i40e_status_code i40e_led_set_phy(struct i40e_hw *hw, bool on,
                                       u16 led_addr, u32 mode)
 {
        enum i40e_status_code status = I40E_SUCCESS;
-       u16 led_ctl = 0;
-       u16 led_reg = 0;
-       u8 phy_addr = 0;
-       u8 port_num;
-       u32 i;
+       u32 led_ctl = 0;
+       u32 led_reg = 0;
 
-       i = rd32(hw, I40E_PFGEN_PORTNUM);
-       port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
-       phy_addr = i40e_get_phy_address(hw, port_num);
-       status = i40e_read_phy_register_clause45(hw, I40E_PHY_COM_REG_PAGE,
-                                                led_addr, phy_addr, &led_reg);
+       status = i40e_led_get_reg(hw, led_addr, &led_reg);
        if (status)
                return status;
        led_ctl = led_reg;
        if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
                led_reg = 0;
-               status = i40e_write_phy_register_clause45(hw,
-                                                         I40E_PHY_COM_REG_PAGE,
-                                                         led_addr, phy_addr,
-                                                         led_reg);
+               status = i40e_led_set_reg(hw, led_addr, led_reg);
                if (status)
                        return status;
        }
-       status = i40e_read_phy_register_clause45(hw, I40E_PHY_COM_REG_PAGE,
-                                                led_addr, phy_addr, &led_reg);
+       status = i40e_led_get_reg(hw, led_addr, &led_reg);
        if (status)
                goto restore_config;
        if (on)
                led_reg = I40E_PHY_LED_MANUAL_ON;
        else
                led_reg = 0;
-       status = i40e_write_phy_register_clause45(hw, I40E_PHY_COM_REG_PAGE,
-                                                 led_addr, phy_addr, led_reg);
+       status = i40e_led_set_reg(hw, led_addr, led_reg);
        if (status)
                goto restore_config;
        if (mode & I40E_PHY_LED_MODE_ORIG) {
                led_ctl = (mode & I40E_PHY_LED_MODE_MASK);
-               status = i40e_write_phy_register_clause45(hw,
-                                                I40E_PHY_COM_REG_PAGE,
-                                                led_addr, phy_addr, led_ctl);
+               status = i40e_led_set_reg(hw, led_addr, led_ctl);
        }
        return status;
+
 restore_config:
-       status = i40e_write_phy_register_clause45(hw, I40E_PHY_COM_REG_PAGE,
-                                                 led_addr, phy_addr, led_ctl);
+       status = i40e_led_set_reg(hw, led_addr, led_ctl);
        return status;
 }
 #endif /* PF_DRIVER */
+/**
+ * i40e_get_phy_lpi_status - read LPI status from PHY or MAC register
+ * @hw: pointer to the hw struct
+ * @stat: pointer to structure with status of rx and tx lpi
+ *
+ * Read LPI state directly from external PHY register or from MAC
+ * register, depending on device ID and current link speed.
+ */
+enum i40e_status_code i40e_get_phy_lpi_status(struct i40e_hw *hw,
+                                             struct i40e_hw_port_stats *stat)
+{
+       enum i40e_status_code ret = I40E_SUCCESS;
+       bool eee_mrvl_phy;
+       bool eee_bcm_phy;
+       u32 val;
+
+       stat->rx_lpi_status = 0;
+       stat->tx_lpi_status = 0;
+
+       eee_bcm_phy =
+               (hw->device_id == I40E_DEV_ID_10G_BASE_T_BC ||
+                hw->device_id == I40E_DEV_ID_5G_BASE_T_BC) &&
+               (hw->phy.link_info.link_speed == I40E_LINK_SPEED_2_5GB ||
+                hw->phy.link_info.link_speed == I40E_LINK_SPEED_5GB);
+       eee_mrvl_phy =
+               hw->device_id == I40E_DEV_ID_1G_BASE_T_X722;
+
+       if (eee_bcm_phy || eee_mrvl_phy) {
+               /* read Clause 45 PCS Status 1 register */
+               ret = i40e_aq_get_phy_register(hw,
+                                              I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
+                                              I40E_BCM_PHY_PCS_STATUS1_PAGE,
+                                              true,
+                                              I40E_BCM_PHY_PCS_STATUS1_REG,
+                                              &val, NULL);
+
+               if (ret != I40E_SUCCESS)
+                       return ret;
+
+               stat->rx_lpi_status = !!(val & I40E_BCM_PHY_PCS_STATUS1_RX_LPI);
+               stat->tx_lpi_status = !!(val & I40E_BCM_PHY_PCS_STATUS1_TX_LPI);
+
+               return ret;
+       }
+
+       val = rd32(hw, I40E_PRTPM_EEE_STAT);
+       stat->rx_lpi_status = (val & I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_MASK) >>
+                              I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT;
+       stat->tx_lpi_status = (val & I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK) >>
+                              I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT;
+
+       return ret;
+}
+
+/**
+ * i40e_get_lpi_counters - read LPI counters from EEE statistics
+ * @hw: pointer to the hw struct
+ * @tx_counter: pointer to memory for TX LPI counter
+ * @rx_counter: pointer to memory for RX LPI counter
+ * @is_clear:   returns true if counters are clear after read
+ *
+ * Read Low Power Idle (LPI) mode counters from Energy Efficient
+ * Ethernet (EEE) statistics.
+ **/
+enum i40e_status_code i40e_get_lpi_counters(struct i40e_hw *hw,
+                                           u32 *tx_counter, u32 *rx_counter,
+                                           bool *is_clear)
+{
+       /* only X710-T*L requires special handling of counters
+        * for other devices we just read the MAC registers
+        */
+       if ((hw->device_id == I40E_DEV_ID_10G_BASE_T_BC ||
+            hw->device_id == I40E_DEV_ID_5G_BASE_T_BC) &&
+           hw->phy.link_info.link_speed != I40E_LINK_SPEED_1GB) {
+               enum i40e_status_code retval;
+               u32 cmd_status = 0;
+
+               *is_clear = false;
+               retval = i40e_aq_run_phy_activity(hw,
+                               I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
+                               I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT,
+                               &cmd_status, tx_counter, rx_counter, NULL);
+
+               if (!retval && cmd_status != I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
+                       retval = I40E_ERR_ADMIN_QUEUE_ERROR;
+
+               return retval;
+       }
+
+       *is_clear = true;
+       *tx_counter = rd32(hw, I40E_PRTPM_TLPIC);
+       *rx_counter = rd32(hw, I40E_PRTPM_RLPIC);
+
+       return I40E_SUCCESS;
+}
+
+/**
+ * i40e_get_lpi_duration - read LPI time duration from EEE statistics
+ * @hw: pointer to the hw struct
+ * @stat: pointer to structure with status of rx and tx lpi
+ * @tx_duration: pointer to memory for TX LPI time duration
+ * @rx_duration: pointer to memory for RX LPI time duration
+ *
+ * Read Low Power Idle (LPI) mode time duration from Energy Efficient
+ * Ethernet (EEE) statistics.
+ */
+enum i40e_status_code i40e_get_lpi_duration(struct i40e_hw *hw,
+                                           struct i40e_hw_port_stats *stat,
+                                           u64 *tx_duration, u64 *rx_duration)
+{
+       u32 tx_time_dur, rx_time_dur;
+       enum i40e_status_code retval;
+       u32 cmd_status;
+
+       if (hw->device_id != I40E_DEV_ID_10G_BASE_T_BC &&
+           hw->device_id != I40E_DEV_ID_5G_BASE_T_BC)
+               return I40E_ERR_NOT_IMPLEMENTED;
+
+       retval = i40e_aq_run_phy_activity
+               (hw, I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
+               I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_DUR,
+               &cmd_status, &tx_time_dur, &rx_time_dur, NULL);
+
+       if (retval)
+               return retval;
+       if ((cmd_status & I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK) !=
+           I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
+               return I40E_ERR_ADMIN_QUEUE_ERROR;
+
+       if (hw->phy.link_info.link_speed == I40E_LINK_SPEED_1GB &&
+           !tx_time_dur && !rx_time_dur &&
+           stat->tx_lpi_status && stat->rx_lpi_status) {
+               retval = i40e_aq_run_phy_activity
+                       (hw, I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
+                       I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT_DUR,
+                       &cmd_status,
+                       &tx_time_dur, &rx_time_dur, NULL);
+
+               if (retval)
+                       return retval;
+               if ((cmd_status & I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK) !=
+                   I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
+                       return I40E_ERR_ADMIN_QUEUE_ERROR;
+               tx_time_dur = 0;
+               rx_time_dur = 0;
+       }
+
+       *tx_duration = tx_time_dur;
+       *rx_duration = rx_time_dur;
+
+       return retval;
+}
+
+/**
+ * i40e_lpi_stat_update - update LPI counters with values relative to offset
+ * @hw: pointer to the hw struct
+ * @offset_loaded: flag indicating need of writing current value to offset
+ * @tx_offset: pointer to offset of TX LPI counter
+ * @tx_stat: pointer to value of TX LPI counter
+ * @rx_offset: pointer to offset of RX LPI counter
+ * @rx_stat: pointer to value of RX LPI counter
+ *
+ * Update Low Power Idle (LPI) mode counters while having regard to passed
+ * offsets.
+ **/
+enum i40e_status_code i40e_lpi_stat_update(struct i40e_hw *hw,
+                                          bool offset_loaded, u64 *tx_offset,
+                                          u64 *tx_stat, u64 *rx_offset,
+                                          u64 *rx_stat)
+{
+       enum i40e_status_code retval;
+       u32 tx_counter, rx_counter;
+       bool is_clear;
+
+       retval = i40e_get_lpi_counters(hw, &tx_counter, &rx_counter, &is_clear);
+       if (retval)
+               goto err;
+
+       if (is_clear) {
+               *tx_stat += tx_counter;
+               *rx_stat += rx_counter;
+       } else {
+               if (!offset_loaded) {
+                       *tx_offset = tx_counter;
+                       *rx_offset = rx_counter;
+               }
+
+               *tx_stat = (tx_counter >= *tx_offset) ?
+                       (u32)(tx_counter - *tx_offset) :
+                       (u32)((tx_counter + BIT_ULL(32)) - *tx_offset);
+               *rx_stat = (rx_counter >= *rx_offset) ?
+                       (u32)(rx_counter - *rx_offset) :
+                       (u32)((rx_counter + BIT_ULL(32)) - *rx_offset);
+       }
+err:
+       return retval;
+}
 
 /**
  * i40e_aq_rx_ctl_read_register - use FW to read from an Rx control register
@@ -6608,7 +7446,9 @@ u32 i40e_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr)
        int retry = 5;
        u32 val = 0;
 
-       use_register = (hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver < 5);
+       use_register = (((hw->aq.api_maj_ver == 1) &&
+                       (hw->aq.api_min_ver < 5)) ||
+                       (hw->mac.type == I40E_MAC_X722));
        if (!use_register) {
 do_retry:
                status = i40e_aq_rx_ctl_read_register(hw, reg_addr, &val, NULL);
@@ -6667,7 +7507,9 @@ void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
        bool use_register;
        int retry = 5;
 
-       use_register = (hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver < 5);
+       use_register = (((hw->aq.api_maj_ver == 1) &&
+                       (hw->aq.api_min_ver < 5)) ||
+                       (hw->mac.type == I40E_MAC_X722));
        if (!use_register) {
 do_retry:
                status = i40e_aq_rx_ctl_write_register(hw, reg_addr,
@@ -6683,6 +7525,169 @@ do_retry:
        if (status || use_register)
                wr32(hw, reg_addr, reg_val);
 }
+
+/**
+ * i40e_mdio_if_number_selection - MDIO I/F number selection
+ * @hw: pointer to the hw struct
+ * @set_mdio: use MDIO I/F number specified by mdio_num
+ * @mdio_num: MDIO I/F number
+ * @cmd: pointer to PHY Register command structure
+ **/
+static void
+i40e_mdio_if_number_selection(struct i40e_hw *hw, bool set_mdio, u8 mdio_num,
+                             struct i40e_aqc_phy_register_access *cmd)
+{
+       if (set_mdio && cmd->phy_interface == I40E_AQ_PHY_REG_ACCESS_EXTERNAL) {
+               if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_EXTENDED)
+                       cmd->cmd_flags |=
+                               I40E_AQ_PHY_REG_ACCESS_SET_MDIO_IF_NUMBER |
+                               ((mdio_num <<
+                               I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_SHIFT) &
+                               I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_MASK);
+               else
+                       i40e_debug(hw, I40E_DEBUG_PHY,
+                                  "MDIO I/F number selection not supported by current FW version.\n");
+       }
+}
+
+/**
+ * i40e_aq_set_phy_register_ext
+ * @hw: pointer to the hw struct
+ * @phy_select: select which phy should be accessed
+ * @dev_addr: PHY device address
+ * @page_change: enable auto page change
+ * @set_mdio: use MDIO I/F number specified by mdio_num
+ * @mdio_num: MDIO I/F number
+ * @reg_addr: PHY register address
+ * @reg_val: new register value
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Write the external PHY register.
+ * NOTE: In common cases MDIO I/F number should not be changed, thats why you
+ * may use simple wrapper i40e_aq_set_phy_register.
+ **/
+enum i40e_status_code
+i40e_aq_set_phy_register_ext(struct i40e_hw *hw,
+                            u8 phy_select, u8 dev_addr, bool page_change,
+                            bool set_mdio, u8 mdio_num,
+                            u32 reg_addr, u32 reg_val,
+                            struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_phy_register_access *cmd =
+               (struct i40e_aqc_phy_register_access *)&desc.params.raw;
+       enum i40e_status_code status;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                         i40e_aqc_opc_set_phy_register);
+
+       cmd->phy_interface = phy_select;
+       cmd->dev_addres = dev_addr;
+       cmd->reg_address = CPU_TO_LE32(reg_addr);
+       cmd->reg_value = CPU_TO_LE32(reg_val);
+
+       if (!page_change)
+               cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE;
+
+       i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd);
+
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+       return status;
+}
+
+/**
+ * i40e_aq_get_phy_register_ext
+ * @hw: pointer to the hw struct
+ * @phy_select: select which phy should be accessed
+ * @dev_addr: PHY device address
+ * @page_change: enable auto page change
+ * @set_mdio: use MDIO I/F number specified by mdio_num
+ * @mdio_num: MDIO I/F number
+ * @reg_addr: PHY register address
+ * @reg_val: read register value
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Read the external PHY register.
+ * NOTE: In common cases MDIO I/F number should not be changed, thats why you
+ * may use simple wrapper i40e_aq_get_phy_register.
+ **/
+enum i40e_status_code
+i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
+                            u8 phy_select, u8 dev_addr, bool page_change,
+                            bool set_mdio, u8 mdio_num,
+                            u32 reg_addr, u32 *reg_val,
+                            struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_phy_register_access *cmd =
+               (struct i40e_aqc_phy_register_access *)&desc.params.raw;
+       enum i40e_status_code status;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                         i40e_aqc_opc_get_phy_register);
+
+       cmd->phy_interface = phy_select;
+       cmd->dev_addres = dev_addr;
+       cmd->reg_address = CPU_TO_LE32(reg_addr);
+
+       if (!page_change)
+               cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE;
+
+       i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd);
+
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+       if (!status)
+               *reg_val = LE32_TO_CPU(cmd->reg_value);
+
+       return status;
+}
+
+/**
+ * i40e_aq_run_phy_activity
+ * @hw: pointer to the hw struct
+ * @activity_id: ID of DNL activity to run
+ * @dnl_opcode: opcode passed to DNL script
+ * @cmd_status: pointer to memory to write return value of DNL script
+ * @data0: pointer to memory for first 4 bytes of data returned by DNL script
+ * @data1: pointer to memory for last 4 bytes of data returned by DNL script
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Run DNL admin command.
+ **/
+enum i40e_status_code
+i40e_aq_run_phy_activity(struct i40e_hw *hw, u16 activity_id, u32 dnl_opcode,
+                        u32 *cmd_status, u32 *data0, u32 *data1,
+                        struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aqc_run_phy_activity *cmd;
+       enum i40e_status_code retval;
+       struct i40e_aq_desc desc;
+
+       cmd = (struct i40e_aqc_run_phy_activity *)&desc.params.raw;
+
+       if (!cmd_status || !data0 || !data1) {
+               retval = I40E_ERR_PARAM;
+               goto err;
+       }
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                         i40e_aqc_opc_run_phy_activity);
+
+       cmd->activity_id = CPU_TO_LE16(activity_id);
+       cmd->params.cmd.dnl_opcode = CPU_TO_LE32(dnl_opcode);
+
+       retval = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+       if (retval)
+               goto err;
+
+       *cmd_status = LE32_TO_CPU(cmd->params.resp.cmd_status);
+       *data0 = LE32_TO_CPU(cmd->params.resp.data0);
+       *data1 = LE32_TO_CPU(cmd->params.resp.data1);
+err:
+       return retval;
+}
+
 #ifdef VF_DRIVER
 
 /**
@@ -6699,7 +7704,7 @@ do_retry:
  * completion before returning.
  **/
 enum i40e_status_code i40e_aq_send_msg_to_pf(struct i40e_hw *hw,
-                               enum i40e_virtchnl_ops v_opcode,
+                               enum virtchnl_ops v_opcode,
                                enum i40e_status_code v_retval,
                                u8 *msg, u16 msglen,
                                struct i40e_asq_cmd_details *cmd_details)
@@ -6738,9 +7743,9 @@ enum i40e_status_code i40e_aq_send_msg_to_pf(struct i40e_hw *hw,
  * with appropriate information.
  **/
 void i40e_vf_parse_hw_config(struct i40e_hw *hw,
-                            struct i40e_virtchnl_vf_resource *msg)
+                            struct virtchnl_vf_resource *msg)
 {
-       struct i40e_virtchnl_vsi_resource *vsi_res;
+       struct virtchnl_vsi_resource *vsi_res;
        int i;
 
        vsi_res = &msg->vsi_res[0];
@@ -6749,20 +7754,18 @@ void i40e_vf_parse_hw_config(struct i40e_hw *hw,
        hw->dev_caps.num_rx_qp = msg->num_queue_pairs;
        hw->dev_caps.num_tx_qp = msg->num_queue_pairs;
        hw->dev_caps.num_msix_vectors_vf = msg->max_vectors;
-       hw->dev_caps.dcb = msg->vf_offload_flags &
-                          I40E_VIRTCHNL_VF_OFFLOAD_L2;
-       hw->dev_caps.fcoe = (msg->vf_offload_flags &
-                            I40E_VIRTCHNL_VF_OFFLOAD_FCOE) ? 1 : 0;
-       hw->dev_caps.iwarp = (msg->vf_offload_flags &
-                             I40E_VIRTCHNL_VF_OFFLOAD_IWARP) ? 1 : 0;
+       hw->dev_caps.dcb = msg->vf_cap_flags &
+                          VIRTCHNL_VF_OFFLOAD_L2;
+       hw->dev_caps.iwarp = (msg->vf_cap_flags &
+                             VIRTCHNL_VF_OFFLOAD_IWARP) ? 1 : 0;
        for (i = 0; i < msg->num_vsis; i++) {
-               if (vsi_res->vsi_type == I40E_VSI_SRIOV) {
+               if (vsi_res->vsi_type == VIRTCHNL_VSI_SRIOV) {
                        i40e_memcpy(hw->mac.perm_addr,
                                    vsi_res->default_mac_addr,
-                                   I40E_ETH_LENGTH_OF_ADDRESS,
+                                   ETH_ALEN,
                                    I40E_NONDMA_TO_NONDMA);
                        i40e_memcpy(hw->mac.addr, vsi_res->default_mac_addr,
-                                   I40E_ETH_LENGTH_OF_ADDRESS,
+                                   ETH_ALEN,
                                    I40E_NONDMA_TO_NONDMA);
                }
                vsi_res++;
@@ -6779,16 +7782,15 @@ void i40e_vf_parse_hw_config(struct i40e_hw *hw,
  **/
 enum i40e_status_code i40e_vf_reset(struct i40e_hw *hw)
 {
-       return i40e_aq_send_msg_to_pf(hw, I40E_VIRTCHNL_OP_RESET_VF,
+       return i40e_aq_send_msg_to_pf(hw, VIRTCHNL_OP_RESET_VF,
                                      I40E_SUCCESS, NULL, 0, NULL);
 }
 #endif /* VF_DRIVER */
-#ifdef X722_SUPPORT
 
 /**
  * i40e_aq_set_arp_proxy_config
  * @hw: pointer to the HW structure
- * @proxy_config - pointer to proxy config command table struct
+ * @proxy_config: pointer to proxy config command table struct
  * @cmd_details: pointer to command details
  *
  * Set ARP offload parameters from pre-populated
@@ -6812,7 +7814,7 @@ enum i40e_status_code i40e_aq_set_arp_proxy_config(struct i40e_hw *hw,
                                  CPU_TO_LE32(I40E_HI_DWORD((u64)proxy_config));
        desc.params.external.addr_low =
                                  CPU_TO_LE32(I40E_LO_DWORD((u64)proxy_config));
-       desc.datalen = sizeof(struct i40e_aqc_arp_proxy_data);
+       desc.datalen = CPU_TO_LE16(sizeof(struct i40e_aqc_arp_proxy_data));
 
        status = i40e_asq_send_command(hw, &desc, proxy_config,
                                       sizeof(struct i40e_aqc_arp_proxy_data),
@@ -6822,7 +7824,7 @@ enum i40e_status_code i40e_aq_set_arp_proxy_config(struct i40e_hw *hw,
 }
 
 /**
- * i40e_aq_opc_set_ns_proxy_table_entry
+ * i40e_aq_set_ns_proxy_table_entry
  * @hw: pointer to the HW structure
  * @ns_proxy_table_entry: pointer to NS table entry command struct
  * @cmd_details: pointer to command details
@@ -6849,7 +7851,7 @@ enum i40e_status_code i40e_aq_set_ns_proxy_table_entry(struct i40e_hw *hw,
                CPU_TO_LE32(I40E_HI_DWORD((u64)ns_proxy_table_entry));
        desc.params.external.addr_low =
                CPU_TO_LE32(I40E_LO_DWORD((u64)ns_proxy_table_entry));
-       desc.datalen = sizeof(struct i40e_aqc_ns_proxy_data);
+       desc.datalen = CPU_TO_LE16(sizeof(struct i40e_aqc_ns_proxy_data));
 
        status = i40e_asq_send_command(hw, &desc, ns_proxy_table_entry,
                                       sizeof(struct i40e_aqc_ns_proxy_data),
@@ -6912,7 +7914,7 @@ enum i40e_status_code i40e_aq_set_clear_wol_filter(struct i40e_hw *hw,
        cmd->valid_flags = CPU_TO_LE16(valid_flags);
 
        buff_len = sizeof(*filter);
-       desc.datalen = buff_len;
+       desc.datalen = CPU_TO_LE16(buff_len);
 
        desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
        desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
@@ -6973,4 +7975,423 @@ enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
 
        return status;
 }
-#endif /* X722_SUPPORT */
+
+/**
+ * i40e_aq_write_ddp - Write dynamic device personalization (ddp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @track_id: package tracking id
+ * @error_offset: returns error offset
+ * @error_info: returns error information
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+i40e_status_code i40e_aq_write_ddp(struct i40e_hw *hw, void *buff,
+                                  u16 buff_size, u32 track_id,
+                                  u32 *error_offset, u32 *error_info,
+                                  struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_write_personalization_profile *cmd =
+               (struct i40e_aqc_write_personalization_profile *)
+               &desc.params.raw;
+       struct i40e_aqc_write_ddp_resp *resp;
+       enum i40e_status_code status;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                 i40e_aqc_opc_write_personalization_profile);
+
+       desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
+       if (buff_size > I40E_AQ_LARGE_BUF)
+               desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+
+       desc.datalen = CPU_TO_LE16(buff_size);
+
+       cmd->profile_track_id = CPU_TO_LE32(track_id);
+
+       status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+       if (!status) {
+               resp = (struct i40e_aqc_write_ddp_resp *)&desc.params.raw;
+               if (error_offset)
+                       *error_offset = LE32_TO_CPU(resp->error_offset);
+               if (error_info)
+                       *error_info = LE32_TO_CPU(resp->error_info);
+       }
+
+       return status;
+}
+
+/**
+ * i40e_aq_get_ddp_list - Read dynamic device personalization (ddp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @flags: AdminQ command flags
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+i40e_status_code i40e_aq_get_ddp_list(struct i40e_hw *hw, void *buff,
+                                     u16 buff_size, u8 flags,
+                                     struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_get_applied_profiles *cmd =
+               (struct i40e_aqc_get_applied_profiles *)&desc.params.raw;
+       enum i40e_status_code status;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                         i40e_aqc_opc_get_personalization_profile_list);
+
+       desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
+       if (buff_size > I40E_AQ_LARGE_BUF)
+               desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+       desc.datalen = CPU_TO_LE16(buff_size);
+
+       cmd->flags = flags;
+
+       status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+
+       return status;
+}
+
+/**
+ * i40e_find_segment_in_package
+ * @segment_type: the segment type to search for (i.e., SEGMENT_TYPE_I40E)
+ * @pkg_hdr: pointer to the package header to be searched
+ *
+ * This function searches a package file for a particular segment type. On
+ * success it returns a pointer to the segment header, otherwise it will
+ * return NULL.
+ **/
+struct i40e_generic_seg_header *
+i40e_find_segment_in_package(u32 segment_type,
+                            struct i40e_package_header *pkg_hdr)
+{
+       struct i40e_generic_seg_header *segment;
+       u32 i;
+
+       /* Search all package segments for the requested segment type */
+       for (i = 0; i < pkg_hdr->segment_count; i++) {
+               segment =
+                       (struct i40e_generic_seg_header *)((u8 *)pkg_hdr +
+                        pkg_hdr->segment_offset[i]);
+
+               if (segment->type == segment_type)
+                       return segment;
+       }
+
+       return NULL;
+}
+
+/* Get section table in profile */
+#define I40E_SECTION_TABLE(profile, sec_tbl)                           \
+       do {                                                            \
+               struct i40e_profile_segment *p = (profile);             \
+               u32 count;                                              \
+               u32 *nvm;                                               \
+               count = p->device_table_count;                          \
+               nvm = (u32 *)&p->device_table[count];                   \
+               sec_tbl = (struct i40e_section_table *)&nvm[nvm[0] + 1]; \
+       } while (0)
+
+/* Get section header in profile */
+#define I40E_SECTION_HEADER(profile, offset)                           \
+       (struct i40e_profile_section_header *)((u8 *)(profile) + (offset))
+
+/**
+ * i40e_find_section_in_profile
+ * @section_type: the section type to search for (i.e., SECTION_TYPE_NOTE)
+ * @profile: pointer to the i40e segment header to be searched
+ *
+ * This function searches i40e segment for a particular section type. On
+ * success it returns a pointer to the section header, otherwise it will
+ * return NULL.
+ **/
+struct i40e_profile_section_header *
+i40e_find_section_in_profile(u32 section_type,
+                            struct i40e_profile_segment *profile)
+{
+       struct i40e_profile_section_header *sec;
+       struct i40e_section_table *sec_tbl;
+       u32 sec_off;
+       u32 i;
+
+       if (profile->header.type != SEGMENT_TYPE_I40E)
+               return NULL;
+
+       I40E_SECTION_TABLE(profile, sec_tbl);
+
+       for (i = 0; i < sec_tbl->section_count; i++) {
+               sec_off = sec_tbl->section_offset[i];
+               sec = I40E_SECTION_HEADER(profile, sec_off);
+               if (sec->section.type == section_type)
+                       return sec;
+       }
+
+       return NULL;
+}
+
+/**
+ * i40e_ddp_exec_aq_section - Execute generic AQ for DDP
+ * @hw: pointer to the hw struct
+ * @aq: command buffer containing all data to execute AQ
+ **/
+STATIC enum
+i40e_status_code i40e_ddp_exec_aq_section(struct i40e_hw *hw,
+                                         struct i40e_profile_aq_section *aq)
+{
+       enum i40e_status_code status;
+       struct i40e_aq_desc desc;
+       u8 *msg = NULL;
+       u16 msglen;
+
+       i40e_fill_default_direct_cmd_desc(&desc, aq->opcode);
+       desc.flags |= CPU_TO_LE16(aq->flags);
+       i40e_memcpy(desc.params.raw, aq->param, sizeof(desc.params.raw),
+                   I40E_NONDMA_TO_NONDMA);
+
+       msglen = aq->datalen;
+       if (msglen) {
+               desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF |
+                                               I40E_AQ_FLAG_RD));
+               if (msglen > I40E_AQ_LARGE_BUF)
+                       desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+               desc.datalen = CPU_TO_LE16(msglen);
+               msg = &aq->data[0];
+       }
+
+       status = i40e_asq_send_command(hw, &desc, msg, msglen, NULL);
+
+       if (status != I40E_SUCCESS) {
+               i40e_debug(hw, I40E_DEBUG_PACKAGE,
+                          "unable to exec DDP AQ opcode %u, error %d\n",
+                          aq->opcode, status);
+               return status;
+       }
+
+       /* copy returned desc to aq_buf */
+       i40e_memcpy(aq->param, desc.params.raw, sizeof(desc.params.raw),
+                   I40E_NONDMA_TO_NONDMA);
+
+       return I40E_SUCCESS;
+}
+
+/**
+ * i40e_validate_profile
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package to be validated
+ * @track_id: package tracking id
+ * @rollback: flag if the profile is for rollback.
+ *
+ * Validates supported devices and profile's sections.
+ */
+STATIC enum i40e_status_code
+i40e_validate_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+                     u32 track_id, bool rollback)
+{
+       struct i40e_profile_section_header *sec = NULL;
+       enum i40e_status_code status = I40E_SUCCESS;
+       struct i40e_section_table *sec_tbl;
+       u32 vendor_dev_id;
+       u32 dev_cnt;
+       u32 sec_off;
+       u32 i;
+
+       if (track_id == I40E_DDP_TRACKID_INVALID) {
+               i40e_debug(hw, I40E_DEBUG_PACKAGE, "Invalid track_id\n");
+               return I40E_NOT_SUPPORTED;
+       }
+
+       dev_cnt = profile->device_table_count;
+       for (i = 0; i < dev_cnt; i++) {
+               vendor_dev_id = profile->device_table[i].vendor_dev_id;
+               if ((vendor_dev_id >> 16) == I40E_INTEL_VENDOR_ID &&
+                   hw->device_id == (vendor_dev_id & 0xFFFF))
+                       break;
+       }
+       if (dev_cnt && (i == dev_cnt)) {
+               i40e_debug(hw, I40E_DEBUG_PACKAGE,
+                          "Device doesn't support DDP\n");
+               return I40E_ERR_DEVICE_NOT_SUPPORTED;
+       }
+
+       I40E_SECTION_TABLE(profile, sec_tbl);
+
+       /* Validate sections types */
+       for (i = 0; i < sec_tbl->section_count; i++) {
+               sec_off = sec_tbl->section_offset[i];
+               sec = I40E_SECTION_HEADER(profile, sec_off);
+               if (rollback) {
+                       if (sec->section.type == SECTION_TYPE_MMIO ||
+                           sec->section.type == SECTION_TYPE_AQ ||
+                           sec->section.type == SECTION_TYPE_RB_AQ) {
+                               i40e_debug(hw, I40E_DEBUG_PACKAGE,
+                                          "Not a roll-back package\n");
+                               return I40E_NOT_SUPPORTED;
+                       }
+               } else {
+                       if (sec->section.type == SECTION_TYPE_RB_AQ ||
+                           sec->section.type == SECTION_TYPE_RB_MMIO) {
+                               i40e_debug(hw, I40E_DEBUG_PACKAGE,
+                                          "Not an original package\n");
+                               return I40E_NOT_SUPPORTED;
+                       }
+               }
+       }
+
+       return status;
+}
+
+/**
+ * i40e_write_profile
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package to be downloaded
+ * @track_id: package tracking id
+ *
+ * Handles the download of a complete package.
+ */
+enum i40e_status_code
+i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+                  u32 track_id)
+{
+       enum i40e_status_code status = I40E_SUCCESS;
+       struct i40e_section_table *sec_tbl;
+       struct i40e_profile_section_header *sec = NULL;
+       struct i40e_profile_aq_section *ddp_aq;
+       u32 section_size = 0;
+       u32 offset = 0, info = 0;
+       u32 sec_off;
+       u32 i;
+
+       status = i40e_validate_profile(hw, profile, track_id, false);
+       if (status)
+               return status;
+
+       I40E_SECTION_TABLE(profile, sec_tbl);
+
+       for (i = 0; i < sec_tbl->section_count; i++) {
+               sec_off = sec_tbl->section_offset[i];
+               sec = I40E_SECTION_HEADER(profile, sec_off);
+               /* Process generic admin command */
+               if (sec->section.type == SECTION_TYPE_AQ) {
+                       ddp_aq = (struct i40e_profile_aq_section *)&sec[1];
+                       status = i40e_ddp_exec_aq_section(hw, ddp_aq);
+                       if (status) {
+                               i40e_debug(hw, I40E_DEBUG_PACKAGE,
+                                          "Failed to execute aq: section %d, opcode %u\n",
+                                          i, ddp_aq->opcode);
+                               break;
+                       }
+                       sec->section.type = SECTION_TYPE_RB_AQ;
+               }
+
+               /* Skip any non-mmio sections */
+               if (sec->section.type != SECTION_TYPE_MMIO)
+                       continue;
+
+               section_size = sec->section.size +
+                       sizeof(struct i40e_profile_section_header);
+
+               /* Write MMIO section */
+               status = i40e_aq_write_ddp(hw, (void *)sec, (u16)section_size,
+                                          track_id, &offset, &info, NULL);
+               if (status) {
+                       i40e_debug(hw, I40E_DEBUG_PACKAGE,
+                                  "Failed to write profile: section %d, offset %d, info %d\n",
+                                  i, offset, info);
+                       break;
+               }
+       }
+       return status;
+}
+
+/**
+ * i40e_rollback_profile
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package to be removed
+ * @track_id: package tracking id
+ *
+ * Rolls back previously loaded package.
+ */
+enum i40e_status_code
+i40e_rollback_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+                     u32 track_id)
+{
+       struct i40e_profile_section_header *sec = NULL;
+       enum i40e_status_code status = I40E_SUCCESS;
+       struct i40e_section_table *sec_tbl;
+       u32 offset = 0, info = 0;
+       u32 section_size = 0;
+       u32 sec_off;
+       int i;
+
+       status = i40e_validate_profile(hw, profile, track_id, true);
+       if (status)
+               return status;
+
+       I40E_SECTION_TABLE(profile, sec_tbl);
+
+       /* For rollback write sections in reverse */
+       for (i = sec_tbl->section_count - 1; i >= 0; i--) {
+               sec_off = sec_tbl->section_offset[i];
+               sec = I40E_SECTION_HEADER(profile, sec_off);
+
+               /* Skip any non-rollback sections */
+               if (sec->section.type != SECTION_TYPE_RB_MMIO)
+                       continue;
+
+               section_size = sec->section.size +
+                       sizeof(struct i40e_profile_section_header);
+
+               /* Write roll-back MMIO section */
+               status = i40e_aq_write_ddp(hw, (void *)sec, (u16)section_size,
+                                          track_id, &offset, &info, NULL);
+               if (status) {
+                       i40e_debug(hw, I40E_DEBUG_PACKAGE,
+                                  "Failed to write profile: section %d, offset %d, info %d\n",
+                                  i, offset, info);
+                       break;
+               }
+       }
+       return status;
+}
+
+/**
+ * i40e_add_pinfo_to_list
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package
+ * @profile_info_sec: buffer for information section
+ * @track_id: package tracking id
+ *
+ * Register a profile to the list of loaded profiles.
+ */
+enum i40e_status_code
+i40e_add_pinfo_to_list(struct i40e_hw *hw,
+                      struct i40e_profile_segment *profile,
+                      u8 *profile_info_sec, u32 track_id)
+{
+       enum i40e_status_code status = I40E_SUCCESS;
+       struct i40e_profile_section_header *sec = NULL;
+       struct i40e_profile_info *pinfo;
+       u32 offset = 0, info = 0;
+
+       sec = (struct i40e_profile_section_header *)profile_info_sec;
+       sec->tbl_size = 1;
+       sec->data_end = sizeof(struct i40e_profile_section_header) +
+                       sizeof(struct i40e_profile_info);
+       sec->section.type = SECTION_TYPE_INFO;
+       sec->section.offset = sizeof(struct i40e_profile_section_header);
+       sec->section.size = sizeof(struct i40e_profile_info);
+       pinfo = (struct i40e_profile_info *)(profile_info_sec +
+                                            sec->section.offset);
+       pinfo->track_id = track_id;
+       pinfo->version = profile->version;
+       pinfo->op = I40E_DDP_ADD_TRACKID;
+       i40e_memcpy(pinfo->name, profile->name, I40E_DDP_NAME_SIZE,
+                   I40E_NONDMA_TO_NONDMA);
+
+       status = i40e_aq_write_ddp(hw, (void *)sec, sec->data_end,
+                                  track_id, &offset, &info, NULL);
+       return status;
+}