[11/12] net/ice/base: implement support for SMA controller

Message ID 20210916095304.3058210-12-qi.z.zhang@intel.com (mailing list archive)
State Accepted, archived
Delegated to: Qi Zhang
Headers
Series ice base code batch 2 for DPDK 21.11 |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Qi Zhang Sept. 16, 2021, 9:53 a.m. UTC
  Add support for controlling SMA connectors using GPIO get/set AQs.

Signed-off-by: Maciej Machnikowski <maciej.machnikowski@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
 drivers/net/ice/base/ice_ptp_hw.c | 213 ++++++++++++++++++++++++++++++
 drivers/net/ice/base/ice_ptp_hw.h |  11 ++
 drivers/net/ice/base/ice_type.h   |   1 +
 3 files changed, 225 insertions(+)
  

Comments

Ferruh Yigit Sept. 22, 2021, 12:43 p.m. UTC | #1
On 9/16/2021 10:53 AM, Qi Zhang wrote:
> Add support for controlling SMA connectors using GPIO get/set AQs.
> 
> Signed-off-by: Maciej Machnikowski <maciej.machnikowski@intel.com>
> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> ---
>  drivers/net/ice/base/ice_ptp_hw.c | 213 ++++++++++++++++++++++++++++++
>  drivers/net/ice/base/ice_ptp_hw.h |  11 ++
>  drivers/net/ice/base/ice_type.h   |   1 +
>  3 files changed, 225 insertions(+)

Hi Qi, Qiming, What 'SMA' stands for?
  
Machnikowski, Maciej Sept. 22, 2021, 12:56 p.m. UTC | #2
It's SubMiniature version A - type of external connector we use on our time-enhanced NICs.

> -----Original Message-----
> From: Yigit, Ferruh <ferruh.yigit@intel.com>
> Sent: Wednesday, September 22, 2021 2:44 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Yang, Qiming
> <qiming.yang@intel.com>
> Cc: Guo, Junfeng <junfeng.guo@intel.com>; dev@dpdk.org; Machnikowski,
> Maciej <maciej.machnikowski@intel.com>
> Subject: Re: [dpdk-dev] [PATCH 11/12] net/ice/base: implement support for
> SMA controller
> 
> On 9/16/2021 10:53 AM, Qi Zhang wrote:
> > Add support for controlling SMA connectors using GPIO get/set AQs.
> >
> > Signed-off-by: Maciej Machnikowski <maciej.machnikowski@intel.com>
> > Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> > ---
> >  drivers/net/ice/base/ice_ptp_hw.c | 213
> ++++++++++++++++++++++++++++++
> >  drivers/net/ice/base/ice_ptp_hw.h |  11 ++
> >  drivers/net/ice/base/ice_type.h   |   1 +
> >  3 files changed, 225 insertions(+)
> 
> Hi Qi, Qiming, What 'SMA' stands for?
  
Ferruh Yigit Sept. 22, 2021, 1:51 p.m. UTC | #3
On 9/22/2021 1:56 PM, Machnikowski, Maciej wrote:
> It's SubMiniature version A - type of external connector we use on our time-enhanced NICs.
> 

Thanks, will use it in the commit log as "SMA (SubMiniature version A) ..."

>> -----Original Message-----
>> From: Yigit, Ferruh <ferruh.yigit@intel.com>
>> Sent: Wednesday, September 22, 2021 2:44 PM
>> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Yang, Qiming
>> <qiming.yang@intel.com>
>> Cc: Guo, Junfeng <junfeng.guo@intel.com>; dev@dpdk.org; Machnikowski,
>> Maciej <maciej.machnikowski@intel.com>
>> Subject: Re: [dpdk-dev] [PATCH 11/12] net/ice/base: implement support for
>> SMA controller
>>
>> On 9/16/2021 10:53 AM, Qi Zhang wrote:
>>> Add support for controlling SMA connectors using GPIO get/set AQs.
>>>
>>> Signed-off-by: Maciej Machnikowski <maciej.machnikowski@intel.com>
>>> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
>>> ---
>>>  drivers/net/ice/base/ice_ptp_hw.c | 213
>> ++++++++++++++++++++++++++++++
>>>  drivers/net/ice/base/ice_ptp_hw.h |  11 ++
>>>  drivers/net/ice/base/ice_type.h   |   1 +
>>>  3 files changed, 225 insertions(+)
>>
>> Hi Qi, Qiming, What 'SMA' stands for?
  

Patch

diff --git a/drivers/net/ice/base/ice_ptp_hw.c b/drivers/net/ice/base/ice_ptp_hw.c
index 9ed335349b..7e797c9511 100644
--- a/drivers/net/ice/base/ice_ptp_hw.c
+++ b/drivers/net/ice/base/ice_ptp_hw.c
@@ -3077,6 +3077,219 @@  ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd,
 	return ICE_SUCCESS;
 }
 
+/* E810T SMA functions
+ *
+ * The following functions operate specifically on E810T hardware and are used
+ * to access the extended GPIOs available.
+ */
+
+/**
+ * ice_get_pca9575_handle
+ * @hw: pointer to the hw struct
+ * @pca9575_handle: GPIO controller's handle
+ *
+ * Find and return the GPIO controller's handle in the netlist.
+ * When found - the value will be cached in the hw structure and following calls
+ * will return cached value
+ */
+static enum ice_status
+ice_get_pca9575_handle(struct ice_hw *hw, __le16 *pca9575_handle)
+{
+	struct ice_aqc_get_link_topo *cmd;
+	struct ice_aq_desc desc;
+	enum ice_status status;
+	u8 idx;
+
+	if (!hw || !pca9575_handle)
+		return ICE_ERR_PARAM;
+
+	/* If handle was read previously return cached value */
+	if (hw->io_expander_handle) {
+		*pca9575_handle = hw->io_expander_handle;
+		return ICE_SUCCESS;
+	}
+
+	/* If handle was not detected read it from the netlist */
+	cmd = &desc.params.get_link_topo;
+	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
+
+	/* Set node type to GPIO controller */
+	cmd->addr.topo_params.node_type_ctx =
+		(ICE_AQC_LINK_TOPO_NODE_TYPE_M &
+		 ICE_AQC_LINK_TOPO_NODE_TYPE_GPIO_CTRL);
+
+#define SW_PCA9575_SFP_TOPO_IDX		2
+#define SW_PCA9575_QSFP_TOPO_IDX	1
+
+	/* Check if the SW IO expander controlling SMA exists in the netlist. */
+	if (hw->device_id == ICE_DEV_ID_E810C_SFP)
+		idx = SW_PCA9575_SFP_TOPO_IDX;
+	else if (hw->device_id == ICE_DEV_ID_E810C_QSFP)
+		idx = SW_PCA9575_QSFP_TOPO_IDX;
+	else
+		return ICE_ERR_NOT_SUPPORTED;
+
+	cmd->addr.topo_params.index = idx;
+
+	status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
+	if (status)
+		return ICE_ERR_NOT_SUPPORTED;
+
+	/* Verify if we found the right IO expander type */
+	if (desc.params.get_link_topo.node_part_num !=
+		ICE_ACQ_GET_LINK_TOPO_NODE_NR_PCA9575)
+		return ICE_ERR_NOT_SUPPORTED;
+
+	/* If present save the handle and return it */
+	hw->io_expander_handle = desc.params.get_link_topo.addr.handle;
+	*pca9575_handle = hw->io_expander_handle;
+
+	return ICE_SUCCESS;
+}
+
+/**
+ * ice_read_e810t_pca9575_reg
+ * @hw: pointer to the hw struct
+ * @offset: GPIO controller register offset
+ * @data: pointer to data to be read from the GPIO controller
+ *
+ * Read the register from the GPIO controller
+ */
+enum ice_status
+ice_read_e810t_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data)
+{
+	struct ice_aqc_link_topo_addr link_topo;
+	enum ice_status status;
+	__le16 addr;
+
+	memset(&link_topo, 0, sizeof(link_topo));
+
+	status = ice_get_pca9575_handle(hw, &link_topo.handle);
+	if (status)
+		return status;
+
+	link_topo.topo_params.node_type_ctx =
+		(ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED <<
+		 ICE_AQC_LINK_TOPO_NODE_CTX_S);
+
+	addr = CPU_TO_LE16((u16)offset);
+
+	return ice_aq_read_i2c(hw, link_topo, 0, addr, 1, data, NULL);
+}
+
+/**
+ * ice_write_e810t_pca9575_reg
+ * @hw: pointer to the hw struct
+ * @offset: GPIO controller register offset
+ * @data: data to be written to the GPIO controller
+ *
+ * Write the data to the GPIO controller register
+ */
+enum ice_status
+ice_write_e810t_pca9575_reg(struct ice_hw *hw, u8 offset, u8 data)
+{
+	struct ice_aqc_link_topo_addr link_topo;
+	enum ice_status status;
+	__le16 addr;
+
+	memset(&link_topo, 0, sizeof(link_topo));
+
+	status = ice_get_pca9575_handle(hw, &link_topo.handle);
+	if (status)
+		return status;
+
+	link_topo.topo_params.node_type_ctx =
+		(ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED <<
+		 ICE_AQC_LINK_TOPO_NODE_CTX_S);
+
+	addr = CPU_TO_LE16((u16)offset);
+
+	return ice_aq_write_i2c(hw, link_topo, 0, addr, 1, &data, NULL);
+}
+
+/**
+ * ice_read_sma_ctrl_e810t
+ * @hw: pointer to the hw struct
+ * @data: pointer to data to be read from the GPIO controller
+ *
+ * Read the SMA controller state. Only bits 3-7 in data are valid.
+ */
+enum ice_status ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data)
+{
+	enum ice_status status;
+	u16 handle;
+	u8 i;
+
+	status = ice_get_pca9575_handle(hw, &handle);
+	if (status)
+		return status;
+
+	*data = 0;
+
+	for (i = ICE_E810T_SMA_MIN_BIT; i <= ICE_E810T_SMA_MAX_BIT; i++) {
+		bool pin;
+
+		status = ice_aq_get_gpio(hw, handle, i + ICE_E810T_P1_OFFSET,
+					 &pin, NULL);
+		if (status)
+			break;
+		*data |= (u8)(!pin) << i;
+	}
+
+	return status;
+}
+
+/**
+ * ice_write_sma_ctrl_e810t
+ * @hw: pointer to the hw struct
+ * @data: data to be written to the GPIO controller
+ *
+ * Write the data to the SMA controller. Only bits 3-7 in data are valid.
+ */
+enum ice_status ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data)
+{
+	enum ice_status status;
+	u16 handle;
+	u8 i;
+
+	status = ice_get_pca9575_handle(hw, &handle);
+	if (status)
+		return status;
+
+	for (i = ICE_E810T_SMA_MIN_BIT; i <= ICE_E810T_SMA_MAX_BIT; i++) {
+		bool pin;
+
+		pin = !(data & (1 << i));
+		status = ice_aq_set_gpio(hw, handle, i + ICE_E810T_P1_OFFSET,
+					 pin, NULL);
+		if (status)
+			break;
+	}
+
+	return status;
+}
+
+/**
+ * ice_e810t_is_pca9575_present
+ * @hw: pointer to the hw struct
+ *
+ * Check if the SW IO expander is present in the netlist
+ */
+bool ice_e810t_is_pca9575_present(struct ice_hw *hw)
+{
+	enum ice_status status;
+	__le16 handle = 0;
+
+	if (!ice_is_e810t(hw))
+		return false;
+
+	status = ice_get_pca9575_handle(hw, &handle);
+	if (!status && handle)
+		return true;
+
+	return false;
+}
+
 /* Device agnostic functions
  *
  * The following functions implement shared behavior common to both E822 and
diff --git a/drivers/net/ice/base/ice_ptp_hw.h b/drivers/net/ice/base/ice_ptp_hw.h
index c804085095..ee3366e83c 100644
--- a/drivers/net/ice/base/ice_ptp_hw.h
+++ b/drivers/net/ice/base/ice_ptp_hw.h
@@ -222,6 +222,13 @@  enum ice_status ice_phy_exit_bypass_e822(struct ice_hw *hw, u8 port);
 
 /* E810 family functions */
 enum ice_status ice_ptp_init_phy_e810(struct ice_hw *hw);
+enum ice_status
+ice_read_e810t_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data);
+enum ice_status
+ice_write_e810t_pca9575_reg(struct ice_hw *hw, u8 offset, u8 data);
+enum ice_status ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data);
+enum ice_status ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data);
+bool ice_e810t_is_pca9575_present(struct ice_hw *hw);
 
 #define PFTSYN_SEM_BYTES	4
 
@@ -470,4 +477,8 @@  enum ice_status ice_ptp_init_phy_e810(struct ice_hw *hw);
 #define ICE_E810T_P1_SMA2_DIR_EN	BIT(6)
 #define ICE_E810T_P1_SMA2_TX_EN		BIT(7)
 
+#define ICE_E810T_SMA_MIN_BIT	3
+#define ICE_E810T_SMA_MAX_BIT	7
+#define ICE_E810T_P1_OFFSET	8
+
 #endif /* _ICE_PTP_HW_H_ */
diff --git a/drivers/net/ice/base/ice_type.h b/drivers/net/ice/base/ice_type.h
index b2b3291fb7..72cda11a4f 100644
--- a/drivers/net/ice/base/ice_type.h
+++ b/drivers/net/ice/base/ice_type.h
@@ -1261,6 +1261,7 @@  struct ice_hw {
 	struct LIST_HEAD_TYPE rss_list_head;
 	ice_declare_bitmap(hw_ptype, ICE_FLOW_PTYPE_MAX);
 	u8 dvm_ena;
+	__le16 io_expander_handle;
 };
 
 /* Statistics collected by each port, VSI, VEB, and S-channel */