[23/69] net/i40e/base: add reading LPI counters
diff mbox series

Message ID 20191202074935.97629-24-xiaolong.ye@intel.com
State New
Delegated to: xiaolong ye
Headers show
Series
  • update for i40e base code
Related show

Checks

Context Check Description
ci/Intel-compilation success Compilation OK
ci/checkpatch success coding style OK

Commit Message

Ye Xiaolong Dec. 2, 2019, 7:48 a.m. UTC
This change introduces new function i40e_get_lpi_counters() reading
Low Power Idle (LPI) mode counters from Energy Efficient Ethernet (EEE)
statistics. Since reading EEE statistics requires running DNL script,
function i40e_aq_run_phy_activity() able to run it, was	implemented.

i40e_lpi_stat_update() was introduced as helper function for retrieving
LPI counters' values relative to given offsets.

This change also fixes order of fields in struct
i40e_aqc_run_phy_activity and introduces union in the struct
providing more descriptive names of fields depending on usage
(command or response).

Signed-off-by: Piotr Pietruszewski <piotr.pietruszewski@intel.com>
Reviewed-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
Reviewed-by: Kirsher Jeffrey T <jeffrey.t.kirsher@intel.com>
Signed-off-by: Xiaolong Ye <xiaolong.ye@intel.com>
---
 drivers/net/i40e/base/i40e_adminq_cmd.h |  26 ++++--
 drivers/net/i40e/base/i40e_common.c     | 113 ++++++++++++++++++++++++
 drivers/net/i40e/base/i40e_prototype.h  |  12 +++
 3 files changed, 145 insertions(+), 6 deletions(-)

Patch
diff mbox series

diff --git a/drivers/net/i40e/base/i40e_adminq_cmd.h b/drivers/net/i40e/base/i40e_adminq_cmd.h
index 9179bbe8f..7b4703449 100644
--- a/drivers/net/i40e/base/i40e_adminq_cmd.h
+++ b/drivers/net/i40e/base/i40e_adminq_cmd.h
@@ -2276,15 +2276,29 @@  enum i40e_aq_phy_reg_type {
 	I40E_AQC_PHY_REG_EXERNAL_MODULE	= 0x3
 };
 
+#pragma pack(1)
 /* Run PHY Activity (0x0626) */
 struct i40e_aqc_run_phy_activity {
-	__le16  activity_id;
-	u8      flags;
-	u8      reserved1;
-	__le32  control;
-	__le32  data;
-	u8      reserved2[4];
+	u8	cmd_flags;
+	__le16	activity_id;
+#define I40E_AQ_RUN_PHY_ACTIVITY_ACTIVITY_ID_USER_DEFINED	0x10
+	u8	reserved;
+	union {
+		struct {
+			__le32  dnl_opcode;
+#define I40E_AQ_RUN_PHY_ACTIVITY_DNL_OPCODE_GET_EEE_STATISTICS	0x801b
+			__le32  data;
+			u8	reserved2[4];
+		} cmd;
+		struct {
+			__le32	cmd_status;
+#define I40E_AQ_RUN_PHY_ACTIVITY_CMD_STATUS_SUCCESS		0x4
+			__le32	data0;
+			__le32	data1;
+		} resp;
+	} params;
 };
+#pragma pack()
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_run_phy_activity);
 
diff --git a/drivers/net/i40e/base/i40e_common.c b/drivers/net/i40e/base/i40e_common.c
index 80921349a..b03a6bef2 100644
--- a/drivers/net/i40e/base/i40e_common.c
+++ b/drivers/net/i40e/base/i40e_common.c
@@ -7115,6 +7115,74 @@  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
+ *
+ * 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)
+{
+	enum i40e_status_code retval;
+	u32 cmd_status;
+
+	retval = i40e_aq_run_phy_activity(hw,
+			I40E_AQ_RUN_PHY_ACTIVITY_ACTIVITY_ID_USER_DEFINED,
+			I40E_AQ_RUN_PHY_ACTIVITY_DNL_OPCODE_GET_EEE_STATISTICS,
+			&cmd_status, tx_counter, rx_counter, NULL);
+
+	if (cmd_status != I40E_AQ_RUN_PHY_ACTIVITY_CMD_STATUS_SUCCESS)
+		retval = I40E_ERR_ADMIN_QUEUE_ERROR;
+
+	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;
+
+	retval = i40e_get_lpi_counters(hw, &tx_counter, &rx_counter);
+	if (retval)
+		goto err;
+
+	if (!offset_loaded) {
+		*tx_offset = tx_counter;
+		*rx_offset = rx_counter;
+	}
+
+	if (tx_counter >= *tx_offset)
+		*tx_stat = (u32)(tx_counter - *tx_offset);
+	else
+		*tx_stat = (u32)((tx_counter + BIT_ULL(32)) - *tx_offset);
+
+	if (rx_counter >= *rx_offset)
+		*rx_stat = (u32)(rx_counter - *rx_offset);
+	else
+		*rx_stat = (u32)((rx_counter + BIT_ULL(32)) - *rx_offset);
+err:
+	return retval;
+}
 #endif /* PF_DRIVER */
 
 /**
@@ -7378,6 +7446,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;
+}
+
 #endif /* PF_DRIVER */
 #ifdef VF_DRIVER
 
diff --git a/drivers/net/i40e/base/i40e_prototype.h b/drivers/net/i40e/base/i40e_prototype.h
index 4d1b007b8..eaaeb5eea 100644
--- a/drivers/net/i40e/base/i40e_prototype.h
+++ b/drivers/net/i40e/base/i40e_prototype.h
@@ -76,6 +76,12 @@  enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
 
 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);
+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,
@@ -563,6 +569,12 @@  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);
+#ifdef PF_DRIVER
+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);
+#endif
 
 enum i40e_status_code i40e_aq_set_arp_proxy_config(struct i40e_hw *hw,
 			struct i40e_aqc_arp_proxy_data *proxy_config,