[20/69] net/i40e/base: read LPI status from external PHY

Message ID 20191202074935.97629-21-xiaolong.ye@intel.com (mailing list archive)
State Changes Requested, archived
Delegated to: xiaolong ye
Headers
Series update for i40e base code |

Checks

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

Commit Message

Xiaolong Ye Dec. 2, 2019, 7:48 a.m. UTC
  When external PHY is used, MAC register may not reflect actual
state of LPI. Add function reading it directly from PHY or MAC,
depending on what is supported by the device.

Signed-off-by: Krzysztof Galazka <krzysztof.galazka@intel.com>
Signed-off-by: Piotr Pietruszewski <piotr.pietruszewski@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@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_common.c    | 66 ++++++++++++++++++++++++++
 drivers/net/i40e/base/i40e_prototype.h |  2 +
 drivers/net/i40e/base/i40e_type.h      |  8 ++++
 3 files changed, 76 insertions(+)
  

Patch

diff --git a/drivers/net/i40e/base/i40e_common.c b/drivers/net/i40e/base/i40e_common.c
index da7869431..51ab0c4b8 100644
--- a/drivers/net/i40e/base/i40e_common.c
+++ b/drivers/net/i40e/base/i40e_common.c
@@ -7046,6 +7046,72 @@  enum i40e_status_code i40e_led_set_phy(struct i40e_hw *hw, bool on,
 	status = i40e_led_set_reg(hw, led_addr, led_ctl);
 	return status;
 }
+
+#ifdef CARLSVILLE_HW
+/**
+ * i40e_get_phy_lpi_status - read LPI status from external PHY or MAC
+ * @hw: pointer to the hw struct
+ * @stat: pointer to structure with status of rx and tx lpi
+ *
+ * Read LPI state directly from external PHY or MAC, depending on device ID.
+ */
+#else
+/**
+ * i40e_get_phy_lpi_status - read LPI status from MAC
+ * @hw: pointer to the hw struct
+ * @stat: pointer to structure with status of rx and tx lpi
+ *
+ * Read LPI state directly from MAC.
+ */
+#endif
+#ifndef EXTERNAL_RELEASE
+/*
+ * Implemented for Broadcom Orca PHY used in Carlsville.
+ * Refer to FVL DCR335 for details.
+ */
+#endif
+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;
+
+#ifdef CARLSVILLE_HW
+	if (hw->device_id == I40E_DEV_ID_10G_BASE_T_BC) {
+#ifndef EXTERNAL_RELEASE
+	/* For accessing LPI status in Broadcom PHY we're using AQ command only.
+	 * Broadcom PHY supports API >= 1.7, so there is no need for supporting
+	 * direct register access.
+	 */
+#endif
+		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;
+	}
+
+#endif /* CARLSVILLE_HW */
+	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;
+}
 #endif /* PF_DRIVER */
 
 /**
diff --git a/drivers/net/i40e/base/i40e_prototype.h b/drivers/net/i40e/base/i40e_prototype.h
index 406b902b3..4d1b007b8 100644
--- a/drivers/net/i40e/base/i40e_prototype.h
+++ b/drivers/net/i40e/base/i40e_prototype.h
@@ -74,6 +74,8 @@  enum i40e_status_code i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
 enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
 					      u32 time, u32 interval);
 
+enum i40e_status_code i40e_get_phy_lpi_status(struct i40e_hw *hw,
+					      struct i40e_hw_port_stats *stats);
 /* admin send queue commands */
 
 enum i40e_status_code i40e_aq_get_firmware_version(struct i40e_hw *hw,
diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index 322300fa3..23adbbccd 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -2038,4 +2038,12 @@  struct i40e_profile_info {
 	u8 reserved[7];
 	u8 name[I40E_DDP_NAME_SIZE];
 };
+
+#ifdef CARLSVILLE_HW
+#define I40E_BCM_PHY_PCS_STATUS1_PAGE	0x3
+#define I40E_BCM_PHY_PCS_STATUS1_REG	0x0001
+#define I40E_BCM_PHY_PCS_STATUS1_RX_LPI	BIT(8)
+#define I40E_BCM_PHY_PCS_STATUS1_TX_LPI	BIT(9)
+#endif
+
 #endif /* _I40E_TYPE_H_ */