diff mbox series

[v2,01/70] net/ice/base: add netlist helper functions

Message ID 20220815073206.2917968-2-qi.z.zhang@intel.com (mailing list archive)
State Awaiting Upstream
Delegated to: Qi Zhang
Headers show
Series ice base code update | expand

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Zhang, Qi Z Aug. 15, 2022, 7:30 a.m. UTC
Add new functions to check in netlist if HW has:
- Recovered Clock device,
- Clock Generation Unit,
- Clock Multiplexer,
- GPS generic device.

Signed-off-by: Michal Michalik <michal.michalik@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
 drivers/net/ice/base/ice_adminq_cmd.h |  54 +++++++++++
 drivers/net/ice/base/ice_common.c     | 130 +++++++++++++++++++++-----
 drivers/net/ice/base/ice_common.h     |  10 ++
 drivers/net/ice/base/ice_ptp_hw.c     |  37 +++++---
 drivers/net/ice/base/ice_ptp_hw.h     |   1 +
 5 files changed, 195 insertions(+), 37 deletions(-)

Comments

Qiming Yang Aug. 15, 2022, 6:28 a.m. UTC | #1
Hi,
> -----Original Message-----
> From: Zhang, Qi Z <qi.z.zhang@intel.com>
> Sent: Monday, August 15, 2022 3:31 PM
> To: Yang, Qiming <qiming.yang@intel.com>
> Cc: dev@dpdk.org; Zhang, Qi Z <qi.z.zhang@intel.com>; Michalik, Michal
> <michal.michalik@intel.com>
> Subject: [PATCH v2 01/70] net/ice/base: add netlist helper functions
> 
> Add new functions to check in netlist if HW has:
> - Recovered Clock device,
> - Clock Generation Unit,
> - Clock Multiplexer,
> - GPS generic device.
> 
> Signed-off-by: Michal Michalik <michal.michalik@intel.com>
> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> ---
>  drivers/net/ice/base/ice_adminq_cmd.h |  54 +++++++++++
>  drivers/net/ice/base/ice_common.c     | 130 +++++++++++++++++++++-----
>  drivers/net/ice/base/ice_common.h     |  10 ++
>  drivers/net/ice/base/ice_ptp_hw.c     |  37 +++++---
>  drivers/net/ice/base/ice_ptp_hw.h     |   1 +
>  5 files changed, 195 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/net/ice/base/ice_adminq_cmd.h
> b/drivers/net/ice/base/ice_adminq_cmd.h
> index 253b971dfd..a3add411b8 100644
> --- a/drivers/net/ice/base/ice_adminq_cmd.h
> +++ b/drivers/net/ice/base/ice_adminq_cmd.h
> @@ -1635,6 +1635,7 @@ struct ice_aqc_link_topo_params {
>  #define ICE_AQC_LINK_TOPO_NODE_TYPE_CAGE	6
>  #define ICE_AQC_LINK_TOPO_NODE_TYPE_MEZZ	7
>  #define ICE_AQC_LINK_TOPO_NODE_TYPE_ID_EEPROM	8
> +#define ICE_AQC_LINK_TOPO_NODE_TYPE_GPS		11
>  #define ICE_AQC_LINK_TOPO_NODE_CTX_S		4
>  #define ICE_AQC_LINK_TOPO_NODE_CTX_M		\
>  				(0xF << ICE_AQC_LINK_TOPO_NODE_CTX_S)
> @@ -1672,9 +1673,61 @@ struct ice_aqc_get_link_topo {
>  	struct ice_aqc_link_topo_addr addr;
>  	u8 node_part_num;
>  #define ICE_ACQ_GET_LINK_TOPO_NODE_NR_PCA9575	0x21
> +#define ICE_ACQ_GET_LINK_TOPO_NODE_NR_GEN_GPS	0x48
>  	u8 rsvd[9];
>  };
> 
> +/* Get Link Topology Pin (direct, 0x06E1) */ struct
> +ice_aqc_get_link_topo_pin {
> +	struct ice_aqc_link_topo_addr addr;
> +	u8 input_io_params;
> +#define ICE_AQC_LINK_TOPO_INPUT_IO_FUNC_S	0
> +#define ICE_AQC_LINK_TOPO_INPUT_IO_FUNC_M	\
> +				(0x1F <<
> ICE_AQC_LINK_TOPO_INPUT_IO_FUNC_S)
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_GPIO		0
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_RESET_N	1
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_INT_N		2
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_PRESENT_N	3
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_TX_DIS	4
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_MODSEL_N	5
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_LPMODE	6
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_TX_FAULT	7
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_RX_LOSS	8
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_RS0		9
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_RS1		10
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_EEPROM_WP	11
> +/* 12 repeats intentionally due to two different uses depending on
> context */
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_LED		12
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_RED_LED	12
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_GREEN_LED	13
> +#define ICE_AQC_LINK_TOPO_IO_FUNC_BLUE_LED	14
> +#define ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_S	5
> +#define ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_M	\
> +			(0x7 << ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_S)
> +#define ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_GPIO	3
> +/* Use ICE_AQC_LINK_TOPO_NODE_TYPE_* for the type values */
> +	u8 output_io_params;
> +#define ICE_AQC_LINK_TOPO_OUTPUT_IO_FUNC_S	0
> +#define ICE_AQC_LINK_TOPO_OUTPUT_IO_FUNC_M	\
> +			(0x1F << \
> ICE_AQC_LINK_TOPO_INPUT_IO_FUNC_NUM_S)
> +/* Use ICE_AQC_LINK_TOPO_IO_FUNC_* for the non-numerical options */
> +#define ICE_AQC_LINK_TOPO_OUTPUT_IO_TYPE_S	5
> +#define ICE_AQC_LINK_TOPO_OUTPUT_IO_TYPE_M	\
> +			(0x7 << ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_S)
> +/* Use ICE_AQC_LINK_TOPO_NODE_TYPE_* for the type values */
> +	u8 output_io_flags;
> +#define ICE_AQC_LINK_TOPO_OUTPUT_SPEED_S	0
> +#define ICE_AQC_LINK_TOPO_OUTPUT_SPEED_M	\
> +			(0x7 << ICE_AQC_LINK_TOPO_OUTPUT_SPEED_S)
> +#define ICE_AQC_LINK_TOPO_OUTPUT_INT_S		3
> +#define ICE_AQC_LINK_TOPO_OUTPUT_INT_M		\
> +			(0x3 << ICE_AQC_LINK_TOPO_OUTPUT_INT_S)
> +#define ICE_AQC_LINK_TOPO_OUTPUT_POLARITY	BIT(5)
> +#define ICE_AQC_LINK_TOPO_OUTPUT_VALUE		BIT(6)
> +#define ICE_AQC_LINK_TOPO_OUTPUT_DRIVEN		BIT(7)
> +	u8 rsvd[7];
> +};
> +
>  /* Read/Write I2C (direct, 0x06E2/0x06E3) */  struct ice_aqc_i2c {
>  	struct ice_aqc_link_topo_addr topo_addr; @@ -2936,6 +2989,7 @@
> struct ice_aq_desc {
>  		struct ice_aqc_get_link_status get_link_status;
>  		struct ice_aqc_event_lan_overflow lan_overflow;
>  		struct ice_aqc_get_link_topo get_link_topo;
> +		struct ice_aqc_get_link_topo_pin get_link_topo_pin;
>  		struct ice_aqc_set_health_status_config
>  			set_health_status_config;
>  		struct ice_aqc_get_supported_health_status_codes
> diff --git a/drivers/net/ice/base/ice_common.c
> b/drivers/net/ice/base/ice_common.c
> index db87bacd97..edc24030ec 100644
> --- a/drivers/net/ice/base/ice_common.c
> +++ b/drivers/net/ice/base/ice_common.c
> @@ -396,37 +396,103 @@ ice_aq_get_phy_caps(struct ice_port_info *pi,
> bool qual_mods, u8 report_mode,  }
> 
>  /**
> - * ice_aq_get_link_topo_handle - get link topology node return status
> - * @pi: port information structure
> - * @node_type: requested node type
> - * @cd: pointer to command details structure or NULL
> - *
> - * Get link topology node return status for specified node type (0x06E0)
> - *
> - * Node type cage can be used to determine if cage is present. If AQC
> - * returns error (ENOENT), then no cage present. If no cage present, then
> - * connection type is backplane or BASE-T.
> + * ice_aq_get_netlist_node_pin
> + * @hw: pointer to the hw struct
> + * @cmd: get_link_topo_pin AQ structure
> + * @node_handle: output node handle parameter if node found
>   */
> -static enum ice_status
> -ice_aq_get_link_topo_handle(struct ice_port_info *pi, u8 node_type,
> -			    struct ice_sq_cd *cd)
> +enum ice_status
> +ice_aq_get_netlist_node_pin(struct ice_hw *hw,
> +			    struct ice_aqc_get_link_topo_pin *cmd,
> +			    u16 *node_handle)
>  {
> -	struct ice_aqc_get_link_topo *cmd;
>  	struct ice_aq_desc desc;
> 
> -	cmd = &desc.params.get_link_topo;
> +	ice_fill_dflt_direct_cmd_desc(&desc,
> ice_aqc_opc_get_link_topo_pin);
> +	desc.params.get_link_topo_pin = *cmd;
> +
> +	if (ice_aq_send_cmd(hw, &desc, NULL, 0, NULL))
> +		return ICE_ERR_NOT_SUPPORTED;
> +
> +	if (node_handle)
> +		*node_handle =
> +
> 	LE16_TO_CPU(desc.params.get_link_topo_pin.addr.handle);
> +
> +	return ICE_SUCCESS;
> +}
> +
> +/**
> + * ice_aq_get_netlist_node
> + * @hw: pointer to the hw struct
> + * @cmd: get_link_topo AQ structure
> + * @node_part_number: output node part number if node found
> + * @node_handle: output node handle parameter if node found  */ enum
> +ice_status ice_aq_get_netlist_node(struct ice_hw *hw, struct
> +ice_aqc_get_link_topo *cmd,
> +			u8 *node_part_number, u16 *node_handle) {
> +	struct ice_aq_desc desc;
> 
>  	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
> +	desc.params.get_link_topo = *cmd;
> 
> -	cmd->addr.topo_params.node_type_ctx =
> -		(ICE_AQC_LINK_TOPO_NODE_CTX_PORT <<
> -		 ICE_AQC_LINK_TOPO_NODE_CTX_S);
> +	if (ice_aq_send_cmd(hw, &desc, NULL, 0, NULL))
> +		return ICE_ERR_NOT_SUPPORTED;
> 
> -	/* set node type */
> -	cmd->addr.topo_params.node_type_ctx |=
> -		(ICE_AQC_LINK_TOPO_NODE_TYPE_M & node_type);
> +	if (node_handle)
> +		*node_handle =
> +
> 	LE16_TO_CPU(desc.params.get_link_topo.addr.handle);
> +	if (node_part_number)
> +		*node_part_number =
> desc.params.get_link_topo.node_part_num;
> 
> -	return ice_aq_send_cmd(pi->hw, &desc, NULL, 0, cd);
> +	return ICE_SUCCESS;
> +}
> +
> +#define MAX_NETLIST_SIZE 10
> +/**
> + * ice_find_netlist_node
> + * @hw: pointer to the hw struct
> + * @node_type_ctx: type of netlist node to look for
> + * @node_part_number: node part number to look for
> + * @node_handle: output parameter if node found - optional
> + *
> + * Find and return the node handle for a given node type and part
> +number in the
> + * netlist. When found ICE_SUCCESS is returned,
> ICE_ERR_DOES_NOT_EXIST
> + * otherwise. If node_handle provided, it would be set to found node
> handle.
> + */
> +enum ice_status
> +ice_find_netlist_node(struct ice_hw *hw, u8 node_type_ctx, u8
> node_part_number,
> +		      u16 *node_handle)
> +{
> +	struct ice_aqc_get_link_topo cmd;
> +	u8 rec_node_part_number;
> +	u16 rec_node_handle;
> +	u8 idx;
> +
> +	for (idx = 0; idx < MAX_NETLIST_SIZE; idx++) {
> +		enum ice_status status;
> +
> +		memset(&cmd, 0, sizeof(cmd));
> +
> +		cmd.addr.topo_params.node_type_ctx =
> +			(node_type_ctx <<
> ICE_AQC_LINK_TOPO_NODE_TYPE_S);
> +		cmd.addr.topo_params.index = idx;
> +
> +		status = ice_aq_get_netlist_node(hw, &cmd,
> +						 &rec_node_part_number,
> +						 &rec_node_handle);
> +		if (status)
> +			return status;
> +
> +		if (rec_node_part_number == node_part_number) {
> +			if (node_handle)
> +				*node_handle = rec_node_handle;
> +			return ICE_SUCCESS;
> +		}
> +	}
> +
> +	return ICE_ERR_DOES_NOT_EXIST;
>  }
> 
>  /**
> @@ -438,13 +504,27 @@ ice_aq_get_link_topo_handle(struct ice_port_info
> *pi, u8 node_type,
>   */
>  static bool ice_is_media_cage_present(struct ice_port_info *pi)  {
> +	struct ice_aqc_get_link_topo *cmd;
> +	struct ice_aq_desc desc;
> +
> +	cmd = &desc.params.get_link_topo;
> +
> +	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
> +
> +	cmd->addr.topo_params.node_type_ctx =
> +		(ICE_AQC_LINK_TOPO_NODE_CTX_PORT <<
> +		 ICE_AQC_LINK_TOPO_NODE_CTX_S);
> +
> +	/* set node type */
> +	cmd->addr.topo_params.node_type_ctx |=
> +		(ICE_AQC_LINK_TOPO_NODE_TYPE_M &
> +		 ICE_AQC_LINK_TOPO_NODE_TYPE_CAGE);
> +
>  	/* Node type cage can be used to determine if cage is present. If
> AQC
>  	 * returns error (ENOENT), then no cage present. If no cage present
> then
>  	 * connection type is backplane or BASE-T.
>  	 */
> -	return !ice_aq_get_link_topo_handle(pi,
> -
> ICE_AQC_LINK_TOPO_NODE_TYPE_CAGE,
> -					    NULL);
> +	return ice_aq_get_netlist_node(pi->hw, cmd, NULL, NULL);
>  }
> 
>  /**
> diff --git a/drivers/net/ice/base/ice_common.h
> b/drivers/net/ice/base/ice_common.h
> index a3cbf4fb05..1044a3088e 100644
> --- a/drivers/net/ice/base/ice_common.h
> +++ b/drivers/net/ice/base/ice_common.h
> @@ -145,6 +145,16 @@ enum ice_status
>  ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8
> report_mode,
>  		    struct ice_aqc_get_phy_caps_data *caps,
>  		    struct ice_sq_cd *cd);
> +enum ice_status
> +ice_aq_get_netlist_node_pin(struct ice_hw *hw,
> +			    struct ice_aqc_get_link_topo_pin *cmd,
> +			    u16 *node_handle);
> +enum ice_status
> +ice_aq_get_netlist_node(struct ice_hw *hw, struct ice_aqc_get_link_topo
> *cmd,
> +			u8 *node_part_number, u16 *node_handle); enum
> ice_status
> +ice_find_netlist_node(struct ice_hw *hw, u8 node_type_ctx, u8
> node_part_number,
> +		      u16 *node_handle);
>  void
>  ice_update_phy_type(u64 *phy_type_low, u64 *phy_type_high,
>  		    u16 link_speeds_bitmap);
> diff --git a/drivers/net/ice/base/ice_ptp_hw.c
> b/drivers/net/ice/base/ice_ptp_hw.c
> index 7e797c9511..5b366c95c5 100644
> --- a/drivers/net/ice/base/ice_ptp_hw.c
> +++ b/drivers/net/ice/base/ice_ptp_hw.c
> @@ -3095,10 +3095,10 @@ ice_ptp_port_cmd_e810(struct ice_hw *hw,
> enum ice_ptp_tmr_cmd cmd,  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;
> +	struct ice_aqc_get_link_topo cmd;
> +	u8 node_part_number, idx;
>  	enum ice_status status;
> -	u8 idx;
> +	u16 node_handle;
> 
>  	if (!hw || !pca9575_handle)
>  		return ICE_ERR_PARAM;
> @@ -3109,12 +3109,10 @@ ice_get_pca9575_handle(struct ice_hw *hw,
> __le16 *pca9575_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);
> +	memset(&cmd, 0, sizeof(cmd));
> 
>  	/* Set node type to GPIO controller */
> -	cmd->addr.topo_params.node_type_ctx =
> +	cmd.addr.topo_params.node_type_ctx =
>  		(ICE_AQC_LINK_TOPO_NODE_TYPE_M &
>  		 ICE_AQC_LINK_TOPO_NODE_TYPE_GPIO_CTRL);
> 
> @@ -3129,24 +3127,39 @@ ice_get_pca9575_handle(struct ice_hw *hw,
> __le16 *pca9575_handle)
>  	else
>  		return ICE_ERR_NOT_SUPPORTED;
> 
> -	cmd->addr.topo_params.index = idx;
> +	cmd.addr.topo_params.index = idx;
> 
> -	status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
> +	status = ice_aq_get_netlist_node(hw, &cmd, &node_part_number,
> +					 &node_handle);
>  	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)
> +	if (node_part_number !=
> 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;
> +	hw->io_expander_handle = node_handle;
>  	*pca9575_handle = hw->io_expander_handle;
> 
>  	return ICE_SUCCESS;
>  }
> 
> +/**
> + * ice_is_gps_present_e810t
> + * @hw: pointer to the hw struct
> + *
> + * Check if the GPS generic device is present in the netlist  */ bool
> +ice_is_gps_present_e810t(struct ice_hw *hw) {
> +	if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_GPS,
> +
> ICE_ACQ_GET_LINK_TOPO_NODE_NR_GEN_GPS, NULL))
> +		return false;
> +
> +	return true;
> +}
> +
>  /**
>   * ice_read_e810t_pca9575_reg
>   * @hw: pointer to the hw struct
> diff --git a/drivers/net/ice/base/ice_ptp_hw.h
> b/drivers/net/ice/base/ice_ptp_hw.h
> index ee3366e83c..4f349593aa 100644
> --- a/drivers/net/ice/base/ice_ptp_hw.h
> +++ b/drivers/net/ice/base/ice_ptp_hw.h
> @@ -221,6 +221,7 @@ enum ice_status ice_phy_cfg_rx_offset_e822(struct
> ice_hw *hw, u8 port);  enum ice_status ice_phy_exit_bypass_e822(struct
> ice_hw *hw, u8 port);
> 
>  /* E810 family functions */
> +bool ice_is_gps_present_e810t(struct ice_hw *hw);
>  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);
> --
> 2.31.1

Patch 01~12
Acked-by: Qiming Yang <qiming.yang@intel.com>
diff mbox series

Patch

diff --git a/drivers/net/ice/base/ice_adminq_cmd.h b/drivers/net/ice/base/ice_adminq_cmd.h
index 253b971dfd..a3add411b8 100644
--- a/drivers/net/ice/base/ice_adminq_cmd.h
+++ b/drivers/net/ice/base/ice_adminq_cmd.h
@@ -1635,6 +1635,7 @@  struct ice_aqc_link_topo_params {
 #define ICE_AQC_LINK_TOPO_NODE_TYPE_CAGE	6
 #define ICE_AQC_LINK_TOPO_NODE_TYPE_MEZZ	7
 #define ICE_AQC_LINK_TOPO_NODE_TYPE_ID_EEPROM	8
+#define ICE_AQC_LINK_TOPO_NODE_TYPE_GPS		11
 #define ICE_AQC_LINK_TOPO_NODE_CTX_S		4
 #define ICE_AQC_LINK_TOPO_NODE_CTX_M		\
 				(0xF << ICE_AQC_LINK_TOPO_NODE_CTX_S)
@@ -1672,9 +1673,61 @@  struct ice_aqc_get_link_topo {
 	struct ice_aqc_link_topo_addr addr;
 	u8 node_part_num;
 #define ICE_ACQ_GET_LINK_TOPO_NODE_NR_PCA9575	0x21
+#define ICE_ACQ_GET_LINK_TOPO_NODE_NR_GEN_GPS	0x48
 	u8 rsvd[9];
 };
 
+/* Get Link Topology Pin (direct, 0x06E1) */
+struct ice_aqc_get_link_topo_pin {
+	struct ice_aqc_link_topo_addr addr;
+	u8 input_io_params;
+#define ICE_AQC_LINK_TOPO_INPUT_IO_FUNC_S	0
+#define ICE_AQC_LINK_TOPO_INPUT_IO_FUNC_M	\
+				(0x1F << ICE_AQC_LINK_TOPO_INPUT_IO_FUNC_S)
+#define ICE_AQC_LINK_TOPO_IO_FUNC_GPIO		0
+#define ICE_AQC_LINK_TOPO_IO_FUNC_RESET_N	1
+#define ICE_AQC_LINK_TOPO_IO_FUNC_INT_N		2
+#define ICE_AQC_LINK_TOPO_IO_FUNC_PRESENT_N	3
+#define ICE_AQC_LINK_TOPO_IO_FUNC_TX_DIS	4
+#define ICE_AQC_LINK_TOPO_IO_FUNC_MODSEL_N	5
+#define ICE_AQC_LINK_TOPO_IO_FUNC_LPMODE	6
+#define ICE_AQC_LINK_TOPO_IO_FUNC_TX_FAULT	7
+#define ICE_AQC_LINK_TOPO_IO_FUNC_RX_LOSS	8
+#define ICE_AQC_LINK_TOPO_IO_FUNC_RS0		9
+#define ICE_AQC_LINK_TOPO_IO_FUNC_RS1		10
+#define ICE_AQC_LINK_TOPO_IO_FUNC_EEPROM_WP	11
+/* 12 repeats intentionally due to two different uses depending on context */
+#define ICE_AQC_LINK_TOPO_IO_FUNC_LED		12
+#define ICE_AQC_LINK_TOPO_IO_FUNC_RED_LED	12
+#define ICE_AQC_LINK_TOPO_IO_FUNC_GREEN_LED	13
+#define ICE_AQC_LINK_TOPO_IO_FUNC_BLUE_LED	14
+#define ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_S	5
+#define ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_M	\
+			(0x7 << ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_S)
+#define ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_GPIO	3
+/* Use ICE_AQC_LINK_TOPO_NODE_TYPE_* for the type values */
+	u8 output_io_params;
+#define ICE_AQC_LINK_TOPO_OUTPUT_IO_FUNC_S	0
+#define ICE_AQC_LINK_TOPO_OUTPUT_IO_FUNC_M	\
+			(0x1F << \ ICE_AQC_LINK_TOPO_INPUT_IO_FUNC_NUM_S)
+/* Use ICE_AQC_LINK_TOPO_IO_FUNC_* for the non-numerical options */
+#define ICE_AQC_LINK_TOPO_OUTPUT_IO_TYPE_S	5
+#define ICE_AQC_LINK_TOPO_OUTPUT_IO_TYPE_M	\
+			(0x7 << ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_S)
+/* Use ICE_AQC_LINK_TOPO_NODE_TYPE_* for the type values */
+	u8 output_io_flags;
+#define ICE_AQC_LINK_TOPO_OUTPUT_SPEED_S	0
+#define ICE_AQC_LINK_TOPO_OUTPUT_SPEED_M	\
+			(0x7 << ICE_AQC_LINK_TOPO_OUTPUT_SPEED_S)
+#define ICE_AQC_LINK_TOPO_OUTPUT_INT_S		3
+#define ICE_AQC_LINK_TOPO_OUTPUT_INT_M		\
+			(0x3 << ICE_AQC_LINK_TOPO_OUTPUT_INT_S)
+#define ICE_AQC_LINK_TOPO_OUTPUT_POLARITY	BIT(5)
+#define ICE_AQC_LINK_TOPO_OUTPUT_VALUE		BIT(6)
+#define ICE_AQC_LINK_TOPO_OUTPUT_DRIVEN		BIT(7)
+	u8 rsvd[7];
+};
+
 /* Read/Write I2C (direct, 0x06E2/0x06E3) */
 struct ice_aqc_i2c {
 	struct ice_aqc_link_topo_addr topo_addr;
@@ -2936,6 +2989,7 @@  struct ice_aq_desc {
 		struct ice_aqc_get_link_status get_link_status;
 		struct ice_aqc_event_lan_overflow lan_overflow;
 		struct ice_aqc_get_link_topo get_link_topo;
+		struct ice_aqc_get_link_topo_pin get_link_topo_pin;
 		struct ice_aqc_set_health_status_config
 			set_health_status_config;
 		struct ice_aqc_get_supported_health_status_codes
diff --git a/drivers/net/ice/base/ice_common.c b/drivers/net/ice/base/ice_common.c
index db87bacd97..edc24030ec 100644
--- a/drivers/net/ice/base/ice_common.c
+++ b/drivers/net/ice/base/ice_common.c
@@ -396,37 +396,103 @@  ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
 }
 
 /**
- * ice_aq_get_link_topo_handle - get link topology node return status
- * @pi: port information structure
- * @node_type: requested node type
- * @cd: pointer to command details structure or NULL
- *
- * Get link topology node return status for specified node type (0x06E0)
- *
- * Node type cage can be used to determine if cage is present. If AQC
- * returns error (ENOENT), then no cage present. If no cage present, then
- * connection type is backplane or BASE-T.
+ * ice_aq_get_netlist_node_pin
+ * @hw: pointer to the hw struct
+ * @cmd: get_link_topo_pin AQ structure
+ * @node_handle: output node handle parameter if node found
  */
-static enum ice_status
-ice_aq_get_link_topo_handle(struct ice_port_info *pi, u8 node_type,
-			    struct ice_sq_cd *cd)
+enum ice_status
+ice_aq_get_netlist_node_pin(struct ice_hw *hw,
+			    struct ice_aqc_get_link_topo_pin *cmd,
+			    u16 *node_handle)
 {
-	struct ice_aqc_get_link_topo *cmd;
 	struct ice_aq_desc desc;
 
-	cmd = &desc.params.get_link_topo;
+	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo_pin);
+	desc.params.get_link_topo_pin = *cmd;
+
+	if (ice_aq_send_cmd(hw, &desc, NULL, 0, NULL))
+		return ICE_ERR_NOT_SUPPORTED;
+
+	if (node_handle)
+		*node_handle =
+			LE16_TO_CPU(desc.params.get_link_topo_pin.addr.handle);
+
+	return ICE_SUCCESS;
+}
+
+/**
+ * ice_aq_get_netlist_node
+ * @hw: pointer to the hw struct
+ * @cmd: get_link_topo AQ structure
+ * @node_part_number: output node part number if node found
+ * @node_handle: output node handle parameter if node found
+ */
+enum ice_status
+ice_aq_get_netlist_node(struct ice_hw *hw, struct ice_aqc_get_link_topo *cmd,
+			u8 *node_part_number, u16 *node_handle)
+{
+	struct ice_aq_desc desc;
 
 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
+	desc.params.get_link_topo = *cmd;
 
-	cmd->addr.topo_params.node_type_ctx =
-		(ICE_AQC_LINK_TOPO_NODE_CTX_PORT <<
-		 ICE_AQC_LINK_TOPO_NODE_CTX_S);
+	if (ice_aq_send_cmd(hw, &desc, NULL, 0, NULL))
+		return ICE_ERR_NOT_SUPPORTED;
 
-	/* set node type */
-	cmd->addr.topo_params.node_type_ctx |=
-		(ICE_AQC_LINK_TOPO_NODE_TYPE_M & node_type);
+	if (node_handle)
+		*node_handle =
+			LE16_TO_CPU(desc.params.get_link_topo.addr.handle);
+	if (node_part_number)
+		*node_part_number = desc.params.get_link_topo.node_part_num;
 
-	return ice_aq_send_cmd(pi->hw, &desc, NULL, 0, cd);
+	return ICE_SUCCESS;
+}
+
+#define MAX_NETLIST_SIZE 10
+/**
+ * ice_find_netlist_node
+ * @hw: pointer to the hw struct
+ * @node_type_ctx: type of netlist node to look for
+ * @node_part_number: node part number to look for
+ * @node_handle: output parameter if node found - optional
+ *
+ * Find and return the node handle for a given node type and part number in the
+ * netlist. When found ICE_SUCCESS is returned, ICE_ERR_DOES_NOT_EXIST
+ * otherwise. If node_handle provided, it would be set to found node handle.
+ */
+enum ice_status
+ice_find_netlist_node(struct ice_hw *hw, u8 node_type_ctx, u8 node_part_number,
+		      u16 *node_handle)
+{
+	struct ice_aqc_get_link_topo cmd;
+	u8 rec_node_part_number;
+	u16 rec_node_handle;
+	u8 idx;
+
+	for (idx = 0; idx < MAX_NETLIST_SIZE; idx++) {
+		enum ice_status status;
+
+		memset(&cmd, 0, sizeof(cmd));
+
+		cmd.addr.topo_params.node_type_ctx =
+			(node_type_ctx << ICE_AQC_LINK_TOPO_NODE_TYPE_S);
+		cmd.addr.topo_params.index = idx;
+
+		status = ice_aq_get_netlist_node(hw, &cmd,
+						 &rec_node_part_number,
+						 &rec_node_handle);
+		if (status)
+			return status;
+
+		if (rec_node_part_number == node_part_number) {
+			if (node_handle)
+				*node_handle = rec_node_handle;
+			return ICE_SUCCESS;
+		}
+	}
+
+	return ICE_ERR_DOES_NOT_EXIST;
 }
 
 /**
@@ -438,13 +504,27 @@  ice_aq_get_link_topo_handle(struct ice_port_info *pi, u8 node_type,
  */
 static bool ice_is_media_cage_present(struct ice_port_info *pi)
 {
+	struct ice_aqc_get_link_topo *cmd;
+	struct ice_aq_desc desc;
+
+	cmd = &desc.params.get_link_topo;
+
+	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
+
+	cmd->addr.topo_params.node_type_ctx =
+		(ICE_AQC_LINK_TOPO_NODE_CTX_PORT <<
+		 ICE_AQC_LINK_TOPO_NODE_CTX_S);
+
+	/* set node type */
+	cmd->addr.topo_params.node_type_ctx |=
+		(ICE_AQC_LINK_TOPO_NODE_TYPE_M &
+		 ICE_AQC_LINK_TOPO_NODE_TYPE_CAGE);
+
 	/* Node type cage can be used to determine if cage is present. If AQC
 	 * returns error (ENOENT), then no cage present. If no cage present then
 	 * connection type is backplane or BASE-T.
 	 */
-	return !ice_aq_get_link_topo_handle(pi,
-					    ICE_AQC_LINK_TOPO_NODE_TYPE_CAGE,
-					    NULL);
+	return ice_aq_get_netlist_node(pi->hw, cmd, NULL, NULL);
 }
 
 /**
diff --git a/drivers/net/ice/base/ice_common.h b/drivers/net/ice/base/ice_common.h
index a3cbf4fb05..1044a3088e 100644
--- a/drivers/net/ice/base/ice_common.h
+++ b/drivers/net/ice/base/ice_common.h
@@ -145,6 +145,16 @@  enum ice_status
 ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
 		    struct ice_aqc_get_phy_caps_data *caps,
 		    struct ice_sq_cd *cd);
+enum ice_status
+ice_aq_get_netlist_node_pin(struct ice_hw *hw,
+			    struct ice_aqc_get_link_topo_pin *cmd,
+			    u16 *node_handle);
+enum ice_status
+ice_aq_get_netlist_node(struct ice_hw *hw, struct ice_aqc_get_link_topo *cmd,
+			u8 *node_part_number, u16 *node_handle);
+enum ice_status
+ice_find_netlist_node(struct ice_hw *hw, u8 node_type_ctx, u8 node_part_number,
+		      u16 *node_handle);
 void
 ice_update_phy_type(u64 *phy_type_low, u64 *phy_type_high,
 		    u16 link_speeds_bitmap);
diff --git a/drivers/net/ice/base/ice_ptp_hw.c b/drivers/net/ice/base/ice_ptp_hw.c
index 7e797c9511..5b366c95c5 100644
--- a/drivers/net/ice/base/ice_ptp_hw.c
+++ b/drivers/net/ice/base/ice_ptp_hw.c
@@ -3095,10 +3095,10 @@  ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd,
 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;
+	struct ice_aqc_get_link_topo cmd;
+	u8 node_part_number, idx;
 	enum ice_status status;
-	u8 idx;
+	u16 node_handle;
 
 	if (!hw || !pca9575_handle)
 		return ICE_ERR_PARAM;
@@ -3109,12 +3109,10 @@  ice_get_pca9575_handle(struct ice_hw *hw, __le16 *pca9575_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);
+	memset(&cmd, 0, sizeof(cmd));
 
 	/* Set node type to GPIO controller */
-	cmd->addr.topo_params.node_type_ctx =
+	cmd.addr.topo_params.node_type_ctx =
 		(ICE_AQC_LINK_TOPO_NODE_TYPE_M &
 		 ICE_AQC_LINK_TOPO_NODE_TYPE_GPIO_CTRL);
 
@@ -3129,24 +3127,39 @@  ice_get_pca9575_handle(struct ice_hw *hw, __le16 *pca9575_handle)
 	else
 		return ICE_ERR_NOT_SUPPORTED;
 
-	cmd->addr.topo_params.index = idx;
+	cmd.addr.topo_params.index = idx;
 
-	status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
+	status = ice_aq_get_netlist_node(hw, &cmd, &node_part_number,
+					 &node_handle);
 	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)
+	if (node_part_number != 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;
+	hw->io_expander_handle = node_handle;
 	*pca9575_handle = hw->io_expander_handle;
 
 	return ICE_SUCCESS;
 }
 
+/**
+ * ice_is_gps_present_e810t
+ * @hw: pointer to the hw struct
+ *
+ * Check if the GPS generic device is present in the netlist
+ */
+bool ice_is_gps_present_e810t(struct ice_hw *hw)
+{
+	if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_GPS,
+				  ICE_ACQ_GET_LINK_TOPO_NODE_NR_GEN_GPS, NULL))
+		return false;
+
+	return true;
+}
+
 /**
  * ice_read_e810t_pca9575_reg
  * @hw: pointer to the hw struct
diff --git a/drivers/net/ice/base/ice_ptp_hw.h b/drivers/net/ice/base/ice_ptp_hw.h
index ee3366e83c..4f349593aa 100644
--- a/drivers/net/ice/base/ice_ptp_hw.h
+++ b/drivers/net/ice/base/ice_ptp_hw.h
@@ -221,6 +221,7 @@  enum ice_status ice_phy_cfg_rx_offset_e822(struct ice_hw *hw, u8 port);
 enum ice_status ice_phy_exit_bypass_e822(struct ice_hw *hw, u8 port);
 
 /* E810 family functions */
+bool ice_is_gps_present_e810t(struct ice_hw *hw);
 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);