net/i40e/base: support LLDP agent
[dpdk.git] / drivers / net / i40e / base / i40e_common.c
index a0a1f84..8ebf8b8 100644 (file)
@@ -1,42 +1,12 @@
-/*******************************************************************************
-
-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-2018
+ */
 
 #include "i40e_type.h"
 #include "i40e_adminq.h"
 #include "i40e_prototype.h"
 #include "virtchnl.h"
 
-
 /**
  * i40e_set_mac_type - Sets MAC type
  * @hw: pointer to the HW structure
@@ -65,10 +35,13 @@ 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_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_A0_SUPPORT
@@ -1041,6 +1014,17 @@ enum i40e_status_code i40e_init_shared_code(struct i40e_hw *hw)
        if (hw->mac.type == I40E_MAC_X722)
                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;
 
        status = i40e_init_nvm(hw);
        return status;
@@ -1290,6 +1274,8 @@ STATIC enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
                break;
        case I40E_PHY_TYPE_100BASE_TX:
        case I40E_PHY_TYPE_1000BASE_T:
+       case I40E_PHY_TYPE_2_5GBASE_T:
+       case I40E_PHY_TYPE_5GBASE_T:
        case I40E_PHY_TYPE_10GBASE_T:
                media = I40E_MEDIA_TYPE_BASET;
                break;
@@ -1326,6 +1312,29 @@ STATIC enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
        return media;
 }
 
+/**
+ * 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       200
 /**
  * i40e_pf_reset - Reset the PF
@@ -1349,7 +1358,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);
@@ -1395,14 +1404,14 @@ enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw)
                        if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK))
                                break;
                        reg2 = rd32(hw, I40E_GLGEN_RSTAT);
-                       if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) {
-                               DEBUGOUT("Core reset upcoming. Skipping PF reset request.\n");
-                               DEBUGOUT1("I40E_GLGEN_RSTAT = 0x%x\n", reg2);
-                               return I40E_ERR_NOT_READY;
-                       }
+                       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;
                }
@@ -1883,6 +1892,10 @@ 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;
 
+#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;
@@ -2025,7 +2038,11 @@ enum i40e_status_code i40e_aq_get_link_info(struct i40e_hw *hw,
 
        if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
            hw->aq.api_min_ver >= 7) {
-               hw->phy.phy_types = LE32_TO_CPU(*(__le32 *)resp->link_type);
+               __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);
        }
 
@@ -2168,9 +2185,9 @@ aq_get_partner_advt_exit:
  *
  * Sets loopback modes.
  **/
-enum i40e_status_code
-i40e_aq_set_lb_modes(struct i40e_hw *hw, u8 lb_level, u8 lb_type, u8 speed,
-                    struct i40e_asq_cmd_details *cmd_details)
+enum i40e_status_code i40e_aq_set_lb_modes(struct i40e_hw *hw,
+                               u16 lb_modes,
+                               struct i40e_asq_cmd_details *cmd_details)
 {
        struct i40e_aq_desc desc;
        struct i40e_aqc_set_lb_mode *cmd =
@@ -2180,11 +2197,7 @@ i40e_aq_set_lb_modes(struct i40e_hw *hw, u8 lb_level, u8 lb_type, u8 speed,
        i40e_fill_default_direct_cmd_desc(&desc,
                                          i40e_aqc_opc_set_lb_modes);
 
-       cmd->lb_level = lb_level;
-       cmd->lb_type = lb_type;
-       cmd->speed = speed;
-       if (speed)
-               cmd->force_speed = 1;
+       cmd->lb_mode = CPU_TO_LE16(lb_modes);
 
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
@@ -2711,13 +2724,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;
@@ -2729,6 +2743,7 @@ 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);
@@ -3708,9 +3723,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;
 
@@ -4002,6 +4018,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) {
@@ -4131,6 +4167,43 @@ i40e_aq_update_nvm_exit:
        return status;
 }
 
+/**
+ * i40e_aq_rearrange_nvm
+ * @hw: pointer to the hw struct
+ * @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_nvm_progress
  * @hw: pointer to the hw struct
@@ -4238,7 +4311,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);
@@ -4274,151 +4347,39 @@ 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)
-{
-       struct i40e_aq_desc desc;
-       struct i40e_aqc_lldp_add_tlv *cmd =
-               (struct i40e_aqc_lldp_add_tlv *)&desc.params.raw;
-       enum i40e_status_code status;
-
-       if (buff_size == 0 || !buff || tlv_len == 0)
-               return I40E_ERR_PARAM;
-
-       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_add_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);
-
-       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, buff, buff_size, cmd_details);
-       if (!status) {
-               if (mib_len != NULL)
-                       *mib_len = LE16_TO_CPU(desc.datalen);
-       }
-
-       return status;
-}
-
-/**
- * i40e_aq_update_lldp_tlv
- * @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
- * @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.
- **/
-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,
-                               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_update_tlv *cmd =
-               (struct i40e_aqc_lldp_update_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 || 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);
-
-       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);
-
-       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 (!(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;
        }
 
-       return status;
-}
-
-/**
- * i40e_aq_delete_lldp_tlv
- * @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
- * @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.
- **/
-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,
-                               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;
-       enum i40e_status_code status;
+       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_restore);
 
-       if (buff_size == 0 || !buff)
-               return I40E_ERR_PARAM;
+       if (restore)
+               cmd->command |= I40E_AQ_LLDP_AGENT_RESTORE;
 
-       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_delete_tlv);
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
-       /* 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);
-
-       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;
 }
@@ -4427,11 +4388,13 @@ enum i40e_status_code i40e_aq_delete_lldp_tlv(struct i40e_hw *hw,
  * i40e_aq_stop_lldp
  * @hw: pointer to the hw struct
  * @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
  *
  * Stop or Shutdown the embedded LLDP Agent
  **/
 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;
@@ -4444,6 +4407,14 @@ enum i40e_status_code i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
        if (shutdown_agent)
                cmd->command |= I40E_AQ_LLDP_AGENT_SHUTDOWN;
 
+       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;
@@ -4452,11 +4423,13 @@ enum i40e_status_code i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
 /**
  * i40e_aq_start_lldp
  * @hw: pointer to the hw struct
+ * @persist: True if start of LLDP should be persistent across power cycles
  * @cmd_details: pointer to command details structure or NULL
  *
  * Start the embedded LLDP Agent on all ports.
  **/
 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;
@@ -4467,6 +4440,15 @@ enum i40e_status_code i40e_aq_start_lldp(struct i40e_hw *hw,
        i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_start);
 
        cmd->command = I40E_AQ_LLDP_AGENT_START;
+
+       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");
+       }
+
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
        return status;
@@ -4488,6 +4470,9 @@ i40e_aq_set_dcb_parameters(struct i40e_hw *hw, bool dcb_enable,
                (struct i40e_aqc_set_dcb_parameters *)&desc.params.raw;
        enum i40e_status_code status;
 
+       if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_STOPPABLE))
+               return I40E_ERR_DEVICE_NOT_SUPPORTED;
+
        i40e_fill_default_direct_cmd_desc(&desc,
                                          i40e_aqc_opc_set_dcb_parameters);
 
@@ -5693,10 +5678,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++) {
@@ -5721,13 +5706,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;
@@ -5753,21 +5738,21 @@ enum i40e_status_code i40e_aq_add_cloud_filters(struct i40e_hw *hw,
 }
 
 /**
- * i40e_aq_add_cloud_filters_big_buffer
+ * 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_add_rm_cloud_filt_elem_ext are filled in by the caller of
+ * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the
  * the function.
  *
  **/
-enum i40e_status_code i40e_aq_add_cloud_filters_big_buffer(struct i40e_hw *hw,
-       u16 seid,
-       struct i40e_aqc_add_rm_cloud_filt_elem_ext *filters,
-       u8 filter_count)
+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 =
@@ -5784,9 +5769,8 @@ enum i40e_status_code i40e_aq_add_cloud_filters_big_buffer(struct i40e_hw *hw,
        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_REM_CLOUD_CMD_BIG_BUFFER;
+       cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
 
-       /* adjust Geneve VNI for HW issue */
        for (i = 0; i < filter_count; i++) {
                u16 tnl_type;
                u32 ti;
@@ -5794,6 +5778,11 @@ enum i40e_status_code i40e_aq_add_cloud_filters_big_buffer(struct i40e_hw *hw,
                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);
@@ -5806,21 +5795,21 @@ enum i40e_status_code i40e_aq_add_cloud_filters_big_buffer(struct i40e_hw *hw,
 }
 
 /**
- * i40e_aq_remove_cloud_filters
+ * 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 =
@@ -5845,22 +5834,21 @@ enum i40e_status_code i40e_aq_remove_cloud_filters(struct i40e_hw *hw,
 }
 
 /**
- * i40e_aq_remove_cloud_filters_big_buffer
+ * 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 cloud filters for a given VSI.  The contents of the
- * i40e_aqc_add_rm_cloud_filt_elem_ext are filled in by the caller of
- * the function.
+ * 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_remove_cloud_filters_big_buffer(
-       struct i40e_hw *hw,
-       u16 seid,
-       struct i40e_aqc_add_rm_cloud_filt_elem_ext *filters,
-       u8 filter_count)
+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 =
@@ -5877,9 +5865,8 @@ enum i40e_status_code i40e_aq_remove_cloud_filters_big_buffer(
        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_REM_CLOUD_CMD_BIG_BUFFER;
+       cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
 
-       /* adjust Geneve VNI for HW issue */
        for (i = 0; i < filter_count; i++) {
                u16 tnl_type;
                u32 ti;
@@ -5887,6 +5874,11 @@ enum i40e_status_code i40e_aq_remove_cloud_filters_big_buffer(
                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);
@@ -5916,6 +5908,14 @@ i40e_status_code i40e_aq_replace_cloud_filters(struct i40e_hw *hw,
        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);
 
@@ -5925,6 +5925,7 @@ i40e_status_code i40e_aq_replace_cloud_filters(struct i40e_hw *hw,
        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);
@@ -6618,6 +6619,7 @@ 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_10G_BASE_T_X722:
        case I40E_DEV_ID_25G_B:
        case I40E_DEV_ID_25G_SFP28:
@@ -6773,7 +6775,7 @@ static enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
        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,
+                                               I40E_PHY_COM_REG_PAGE, true,
                                                I40E_PHY_LED_PROV_REG_1,
                                                reg_val, NULL);
        } else {
@@ -6801,7 +6803,7 @@ static enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
        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,
+                                               I40E_PHY_COM_REG_PAGE, true,
                                                I40E_PHY_LED_PROV_REG_1,
                                                reg_val, NULL);
        } else {
@@ -6835,7 +6837,7 @@ enum i40e_status_code i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
        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,
+                                               I40E_PHY_COM_REG_PAGE, true,
                                                I40E_PHY_LED_PROV_REG_1,
                                                &reg_val_aq, NULL);
                if (status == I40E_SUCCESS)
@@ -7036,11 +7038,13 @@ do_retry:
                wr32(hw, reg_addr, reg_val);
 }
 
+#ifdef PF_DRIVER
 /**
  * i40e_aq_set_phy_register
  * @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
  * @reg_addr: PHY register address
  * @reg_val: new register value
  * @cmd_details: pointer to command details structure or NULL
@@ -7048,7 +7052,7 @@ do_retry:
  * Write the external PHY register.
  **/
 enum i40e_status_code i40e_aq_set_phy_register(struct i40e_hw *hw,
-                               u8 phy_select, u8 dev_addr,
+                               u8 phy_select, u8 dev_addr, bool page_change,
                                u32 reg_addr, u32 reg_val,
                                struct i40e_asq_cmd_details *cmd_details)
 {
@@ -7065,6 +7069,9 @@ enum i40e_status_code i40e_aq_set_phy_register(struct i40e_hw *hw,
        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;
+
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
        return status;
@@ -7075,6 +7082,7 @@ enum i40e_status_code i40e_aq_set_phy_register(struct i40e_hw *hw,
  * @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
  * @reg_addr: PHY register address
  * @reg_val: read register value
  * @cmd_details: pointer to command details structure or NULL
@@ -7082,7 +7090,7 @@ enum i40e_status_code i40e_aq_set_phy_register(struct i40e_hw *hw,
  * Read the external PHY register.
  **/
 enum i40e_status_code i40e_aq_get_phy_register(struct i40e_hw *hw,
-                               u8 phy_select, u8 dev_addr,
+                               u8 phy_select, u8 dev_addr, bool page_change,
                                u32 reg_addr, u32 *reg_val,
                                struct i40e_asq_cmd_details *cmd_details)
 {
@@ -7098,6 +7106,9 @@ enum i40e_status_code i40e_aq_get_phy_register(struct i40e_hw *hw,
        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;
+
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
        if (!status)
                *reg_val = LE32_TO_CPU(cmd->reg_value);
@@ -7105,6 +7116,7 @@ enum i40e_status_code i40e_aq_get_phy_register(struct i40e_hw *hw,
        return status;
 }
 
+#endif /* PF_DRIVER */
 #ifdef VF_DRIVER
 
 /**
@@ -7171,9 +7183,9 @@ 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 &
+       hw->dev_caps.dcb = msg->vf_cap_flags &
                           VIRTCHNL_VF_OFFLOAD_L2;
-       hw->dev_caps.iwarp = (msg->vf_offload_flags &
+       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 == VIRTCHNL_VSI_SRIOV) {