@@ -157,6 +157,8 @@
#define GLGEN_RTRIG_CORER_M BIT(0)
#define GLGEN_RTRIG_GLOBR_M BIT(1)
#define GLGEN_STAT 0x000B612C
+#define GLGEN_SWITCH_MODE_CONFIG 0x000B81E0
+#define GLGEN_SWITCH_MODE_CONFIG_SELECT_25X4_ON_SINGLE_QUAD_M BIT(2)
#define GLGEN_VFLRSTAT(_i) (0x00093A04 + ((_i) * 4))
#define PFGEN_CTRL 0x00091000
#define PFGEN_CTRL_PFSWR_M BIT(0)
@@ -177,6 +179,8 @@
#define GLINT_CTL_ITR_GRAN_50_M ICE_M(0xF, 24)
#define GLINT_CTL_ITR_GRAN_25_S 28
#define GLINT_CTL_ITR_GRAN_25_M ICE_M(0xF, 28)
+#define GLGEN_MAC_LINK_TOPO 0x000B81DC
+#define GLGEN_MAC_LINK_TOPO_LINK_TOPO_M GENMASK(1, 0)
#define GLINT_DYN_CTL(_INT) (0x00160000 + ((_INT) * 4))
#define GLINT_DYN_CTL_INTENA_M BIT(0)
#define GLINT_DYN_CTL_CLEARPBA_M BIT(1)
@@ -1472,6 +1472,8 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
return;
ptp_port = &pf->ptp.port;
+ if (ice_is_e825c(hw) && hw->ptp.is_2x50g_muxed_topo)
+ port *= 2;
if (WARN_ON_ONCE(ptp_port->port_num != port))
return;
@@ -3329,6 +3331,9 @@ void ice_ptp_init(struct ice_pf *pf)
}
ptp->port.port_num = hw->pf_id;
+ if (ice_is_e825c(hw) && hw->ptp.is_2x50g_muxed_topo)
+ ptp->port.port_num = hw->pf_id * 2;
+
err = ice_ptp_init_port(pf, &ptp->port);
if (err)
goto err;
@@ -2469,6 +2469,27 @@ static int ice_get_phy_tx_tstamp_ready_eth56g(struct ice_hw *hw, u8 port,
return 0;
}
+/**
+ * ice_is_muxed_topo - detect breakout 2x50G topology for E825C
+ * @hw: pointer to the HW struct
+ *
+ * Returns: true if it's 2x50 breakout topology, false otherwise
+ */
+static bool ice_is_muxed_topo(struct ice_hw *hw)
+{
+ u8 link_topo;
+ bool mux;
+ u32 val;
+
+ val = rd32(hw, GLGEN_SWITCH_MODE_CONFIG);
+ mux = FIELD_GET(GLGEN_SWITCH_MODE_CONFIG_SELECT_25X4_ON_SINGLE_QUAD_M,
+ val);
+ val = rd32(hw, GLGEN_MAC_LINK_TOPO);
+ link_topo = FIELD_GET(GLGEN_MAC_LINK_TOPO_LINK_TOPO_M, val);
+
+ return (mux && link_topo == ICE_LINK_TOPO_UP_TO_2_LINKS);
+}
+
/**
* ice_ptp_init_phy_e825c - initialize PHY parameters
* @hw: pointer to the HW struct
@@ -2501,6 +2522,8 @@ static void ice_ptp_init_phy_e825c(struct ice_hw *hw)
return;
}
}
+
+ ptp->is_2x50g_muxed_topo = ice_is_muxed_topo(hw);
}
/* E822 family functions
@@ -851,6 +851,14 @@ enum ice_phy_model {
ICE_PHY_ETH56G,
};
+/* Global Link Topology */
+enum ice_global_link_topo {
+ ICE_LINK_TOPO_UP_TO_2_LINKS,
+ ICE_LINK_TOPO_UP_TO_4_LINKS,
+ ICE_LINK_TOPO_UP_TO_8_LINKS,
+ ICE_LINK_TOPO_RESERVED,
+};
+
struct ice_ptp_hw {
enum ice_phy_model phy_model;
union ice_phy_params phy;
@@ -858,6 +866,7 @@ struct ice_ptp_hw {
u8 ports_per_phy;
bool primary_nac;
struct ice_hw *primary_hw;
+ bool is_2x50g_muxed_topo;
};
/* Port hardware description */