build: disable experimental API check internally
[dpdk.git] / drivers / net / i40e / base / i40e_common.c
index 0eb369f..84e67f2 100644 (file)
  * 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;
 
@@ -35,10 +31,15 @@ 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_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
@@ -302,32 +303,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;
+       u32 effective_mask = hw->debug_mask & mask;
        u8 *buf = (u8 *)buffer;
        u16 len;
-       u16 i = 0;
+       u16 i;
 
-       if ((!(mask & hw->debug_mask)) || (desc == NULL))
+       if (!effective_mask || !desc)
                return;
 
        len = LE16_TO_CPU(aq_desc->datalen);
 
-       i40e_debug(hw, mask,
+       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;
@@ -1011,6 +1017,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;
@@ -1260,6 +1277,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;
@@ -1525,9 +1544,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;
@@ -1546,8 +1565,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
@@ -1609,8 +1635,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
@@ -1636,6 +1664,19 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
                        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) &
@@ -1695,19 +1736,22 @@ enum i40e_status_code i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
                status = i40e_asq_send_command(hw, &desc, abilities,
                                               abilities_size, cmd_details);
 
-               if (status != I40E_SUCCESS)
-                       break;
-
-               if (hw->aq.asq_last_status == I40E_AQ_RC_EIO) {
+               switch (hw->aq.asq_last_status) {
+               case I40E_AQ_RC_EIO:
                        status = I40E_ERR_UNKNOWN_PHY;
                        break;
-               } else if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN) {
+               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_OK) &&
-                (total_delay < max_delay));
+
+       } while ((hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN) &&
+               (total_delay < max_delay));
 
        if (status != I40E_SUCCESS)
                return status;
@@ -1850,6 +1894,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
@@ -1858,6 +1903,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;
@@ -1876,6 +1922,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;
@@ -2016,8 +2075,8 @@ 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;
 
-       if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
-           hw->aq.api_min_ver >= 7) {
+       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),
@@ -2874,9 +2933,16 @@ enum i40e_status_code i40e_update_link_info(struct i40e_hw *hw)
                if (status)
                        return status;
 
-               hw->phy.link_info.req_fec_info =
-                       abilities.fec_cfg_curr_mod_ext_info &
-                       (I40E_AQ_REQUEST_FEC_KR | I40E_AQ_REQUEST_FEC_RS);
+               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);
@@ -4147,6 +4213,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
@@ -4254,7 +4357,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);
@@ -4290,151 +4393,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;
-
-       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_delete_tlv);
+       if (restore)
+               cmd->command |= I40E_AQ_LLDP_AGENT_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);
-       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, 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;
 }
@@ -4443,11 +4434,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;
@@ -4460,6 +4453,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;
@@ -4468,11 +4469,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;
@@ -4483,6 +4486,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;
@@ -4504,6 +4516,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);
 
@@ -4876,8 +4891,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);
 
@@ -5939,6 +5952,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);
 
@@ -5948,6 +5969,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);
@@ -6321,6 +6343,70 @@ 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.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
@@ -6641,6 +6727,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:
@@ -6786,8 +6873,8 @@ phy_blinking_end:
  * @led_addr: LED register address
  * @reg_val: read register value
  **/
-static enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
-                                             u32 *reg_val)
+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;
@@ -6796,7 +6883,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 {
@@ -6815,8 +6902,8 @@ static enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
  * @led_addr: LED register address
  * @reg_val: register value to write
  **/
-static enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
-                                             u32 reg_val)
+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;
@@ -6824,7 +6911,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 {
@@ -6858,7 +6945,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)
@@ -6932,6 +7019,192 @@ restore_config:
        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;
+       u32 val;
+
+       stat->rx_lpi_status = 0;
+       stat->tx_lpi_status = 0;
+
+       if (hw->device_id == I40E_DEV_ID_10G_BASE_T_BC &&
+           (hw->phy.link_info.link_speed == I40E_LINK_SPEED_2_5GB ||
+            hw->phy.link_info.link_speed == I40E_LINK_SPEED_5GB)) {
+               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->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 (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)
+               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
@@ -7060,20 +7333,51 @@ do_retry:
 }
 
 /**
- * i40e_aq_set_phy_register
+ * 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(struct i40e_hw *hw,
-                               u8 phy_select, u8 dev_addr,
-                               u32 reg_addr, u32 reg_val,
-                               struct i40e_asq_cmd_details *cmd_details)
+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 =
@@ -7088,26 +7392,38 @@ 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;
+
+       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
+ * 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(struct i40e_hw *hw,
-                               u8 phy_select, u8 dev_addr,
-                               u32 reg_addr, u32 *reg_val,
-                               struct i40e_asq_cmd_details *cmd_details)
+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 =
@@ -7121,6 +7437,11 @@ 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;
+
+       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);
@@ -7128,6 +7449,51 @@ enum i40e_status_code i40e_aq_get_phy_register(struct i40e_hw *hw,
        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
 
 /**