@@ -2292,7 +2292,9 @@ struct i40e_aqc_run_phy_activity {
union {
struct {
__le32 dnl_opcode;
+#define I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT_DUR 0x801a
#define I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT 0x801b
+#define I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_DUR 0x1801b
__le32 data;
u8 reserved2[4];
} cmd;
@@ -7209,6 +7209,67 @@ enum i40e_status_code i40e_get_lpi_counters(struct i40e_hw *hw,
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)
+{
+#ifdef CARLSVILLE_HW
+ 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_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_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;
+#else /* CARLSVILLE_HW */
+ *tx_duration = 0;
+ *rx_duration = 0;
+
+ return I40E_SUCCESS;
+#endif /* CARLSVILLE_HW */
+}
+
/**
* i40e_lpi_stat_update - update LPI counters with values relative to offset
* @hw: pointer to the hw struct
@@ -82,6 +82,9 @@ 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 i40e_get_lpi_duration(struct i40e_hw *hw,
+ struct i40e_hw_port_stats *stat,
+ u64 *tx_duration, u64 *rx_duration);
/* admin send queue commands */
enum i40e_status_code i40e_aq_get_firmware_version(struct i40e_hw *hw,
@@ -1498,6 +1498,8 @@ struct i40e_hw_port_stats {
u32 rx_lpi_status;
u64 tx_lpi_count; /* etlpic */
u64 rx_lpi_count; /* erlpic */
+ u64 tx_lpi_duration;
+ u64 rx_lpi_duration;
};
/* Checksum and Shadow RAM pointers */