net/bnxt: update identifier with remap support
[dpdk.git] / drivers / net / i40e / base / i40e_common.c
index f256651..46a0b78 100644 (file)
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2001-2018
+ * Copyright(c) 2001-2020 Intel Corporation
  */
 
 #include "i40e_type.h"
  * 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;
 
@@ -38,6 +34,7 @@ STATIC enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
                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:
@@ -1548,9 +1545,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;
@@ -1569,8 +1566,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
@@ -1632,8 +1636,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
@@ -1659,6 +1665,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) &
@@ -1718,19 +1737,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;
@@ -1873,6 +1895,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
@@ -1881,6 +1904,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;
@@ -1899,6 +1923,15 @@ 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);
@@ -2043,8 +2076,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),
@@ -2901,9 +2934,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);
@@ -4852,8 +4892,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);
 
@@ -6691,6 +6729,7 @@ enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
        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:
@@ -6727,6 +6766,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:
@@ -6836,8 +6876,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;
@@ -6865,8 +6905,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;
@@ -6999,7 +7039,8 @@ enum i40e_status_code i40e_get_phy_lpi_status(struct i40e_hw *hw,
        stat->rx_lpi_status = 0;
        stat->tx_lpi_status = 0;
 
-       if (hw->device_id == I40E_DEV_ID_10G_BASE_T_BC &&
+       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_2_5GB ||
             hw->phy.link_info.link_speed == I40E_LINK_SPEED_5GB)) {
                ret = i40e_aq_get_phy_register(hw,
@@ -7027,6 +7068,149 @@ enum i40e_status_code i40e_get_phy_lpi_status(struct i40e_hw *hw,
        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 (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
@@ -7154,23 +7338,52 @@ do_retry:
                wr32(hw, reg_addr, reg_val);
 }
 
-#ifdef PF_DRIVER
 /**
- * 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, bool page_change,
-                               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 =
@@ -7188,27 +7401,35 @@ enum i40e_status_code i40e_aq_set_phy_register(struct i40e_hw *hw,
        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, bool page_change,
-                               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 =
@@ -7225,6 +7446,8 @@ enum i40e_status_code i40e_aq_get_phy_register(struct i40e_hw *hw,
        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);
@@ -7232,7 +7455,51 @@ enum i40e_status_code i40e_aq_get_phy_register(struct i40e_hw *hw,
        return status;
 }
 
-#endif /* PF_DRIVER */
+/**
+ * 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
 
 /**