[PATCH phy-next 06/13] phy: lynx-28g: provide default lynx_lane_supports_mode() implementation

From: Vladimir Oltean

Date: Thu May 28 2026 - 13:24:48 EST


For the 28G Lynx, there are situations where a protocol is not supported
on a lane despite there being a PCCR register and protocol converter
available:
- LX2160A SerDes 1: reference manual documents PCCD fields E25GC_CFG and
E25GD_CFG and protocol converter registers E25GCCR1..E25GCCR3 /
E25GDCR1..E25GDCR3, but nonetheless, Table 289. SerDes 1 protocol
mapping shows no RCW[SRDS_PRTCL_S1] value for which lanes C and D
support 25G
- when using the "fsl,lynx-28g" fallback compatible string, we don't
want to offer 25GbE because we don't know if the lane supports it,
even though we know how to reach the PCCR and protocol converter
registers for it.

But for the upcoming 10G Lynx SerDes, the above situations don't exist.
There, if we know how to reach the PCCR and protocol converter
registers on a lane, we implicitly know that the protocol is supported
there, so implementing priv->info->lane_supports_mode() would be
redundant.

Implement lynx_lane_supports_mode_default() which decides whether a lane
mode is supported just based on priv->info->get_pccr() and
priv->info->get_pcvt_offset().

Signed-off-by: Vladimir Oltean <vladimir.oltean@xxxxxxx>
---
drivers/phy/freescale/phy-fsl-lynx-core.c | 27 ++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/freescale/phy-fsl-lynx-core.c b/drivers/phy/freescale/phy-fsl-lynx-core.c
index f49d594622cb..802e32dc6dca 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-core.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-core.c
@@ -40,6 +40,27 @@ enum lynx_lane_mode phy_interface_to_lane_mode(phy_interface_t intf)
}
EXPORT_SYMBOL_NS_GPL(phy_interface_to_lane_mode, "PHY_FSL_LYNX");

+/* By default, assume that if we know how to get the PCCR register and
+ * protocol converter for a lane, that protocol is supported.
+ */
+static bool lynx_lane_supports_mode_default(struct lynx_lane *lane,
+ enum lynx_lane_mode mode)
+{
+ struct lynx_priv *priv = lane->priv;
+ struct lynx_pccr pccr;
+
+ if (!priv->info->get_pccr || !priv->info->get_pcvt_offset)
+ return false;
+
+ if (priv->info->get_pccr(mode, lane->id, &pccr) < 0)
+ return false;
+
+ if (priv->info->get_pcvt_offset(lane->id, mode) < 0)
+ return false;
+
+ return true;
+}
+
/* A lane mode is supported if we have a PLL that can provide its required
* clock net, and if there is a protocol converter for that mode on that lane.
*/
@@ -48,8 +69,12 @@ bool lynx_lane_supports_mode(struct lynx_lane *lane, enum lynx_lane_mode mode)
struct lynx_priv *priv = lane->priv;
int i;

- if (!priv->info->lane_supports_mode(lane->id, mode))
+ if (priv->info->lane_supports_mode) {
+ if (!priv->info->lane_supports_mode(lane->id, mode))
+ return false;
+ } else if (!lynx_lane_supports_mode_default(lane, mode)) {
return false;
+ }

for (i = 0; i < LYNX_NUM_PLL; i++) {
if (!priv->pll[i].enabled)
--
2.34.1