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_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
}
#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
/**
enum i40e_status_code i40e_get_phy_lpi_status(struct i40e_hw *hw,
struct i40e_hw_port_stats *stats);
+enum i40e_status_code i40e_get_lpi_counters(struct i40e_hw *hw, u32 *tx_counter,
+ u32 *rx_counter, bool *is_clear);
+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);
/* admin send queue commands */
enum i40e_status_code i40e_aq_get_firmware_version(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_run_phy_activity(struct i40e_hw *hw, u16 activity_id, u32 opcode,
+ u32 *cmd_status, u32 *data0, u32 *data1,
+ struct i40e_asq_cmd_details *cmd_details);
enum i40e_status_code i40e_aq_set_arp_proxy_config(struct i40e_hw *hw,
struct i40e_aqc_arp_proxy_data *proxy_config,