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.micha...@intel.com>
Signed-off-by: Qi Zhang <qi.z.zh...@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

Reply via email to