summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandeep Sondagar <sandeepsondagar@gmail.com>2026-08-09 21:31:41 +0530
committerJakub Kicinski <kuba@kernel.org>2026-08-13 18:21:31 -0700
commit5ba017f9efef3cf65cc60005aae4cbbf70b9b2b8 (patch)
tree4a6cbb1b5a21931701c1a1aa228c4fcc90437d6d
parent77e80af7d2d4dc223716c90e9fc043bc66a8335f (diff)
net: phylink: treat PSGMII as an inband capable interface
PSGMII (the Qualcomm 5-port SGMII) conveys the link negotiation result from the PHY back to the MAC through per-channel in-band SGMII words, exactly like SGMII and QSGMII. However, PHY_INTERFACE_MODE_PSGMII is missing from phylink_get_inband_type(), so phylink reports INBAND_NONE for it and phylink_pcs_neg_mode() falls back to PHYLINK_PCS_NEG_NONE. The PCS is then programmed in force mode and its control-register speed bits (which default to 1000base) are used, so a slower copper link - e.g. 100base-T - is reported as 1Gbps and cannot pass traffic. Classify PSGMII alongside SGMII and QSGMII as INBAND_CISCO_SGMII so the PCS negotiates in-band and the resolved link speed comes from the PHY in-band word. Also add PSGMII to the generic clause 22 PCS helper functions which handle the SGMII in-band word. Without this, a PCS using these helpers would still fall through to the default handling and force the link state to false in phylink_mii_c22_pcs_decode_state(), fail to encode the SGMII advertisement, and get rejected by phylink_get_link_timer_ns(). Signed-off-by: Sandeep Sondagar <sandeepsondagar@gmail.com> Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de> Link: https://patch.msgid.link/20260809-phylink-psgmii-v3-1-908dcd3a9e3d@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/phy/phylink.c3
-rw-r--r--include/linux/phylink.h1
2 files changed, 4 insertions, 0 deletions
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index b241768edbcb..5b8e956902fb 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1039,6 +1039,7 @@ static enum inband_type phylink_get_inband_type(phy_interface_t interface)
{
switch (interface) {
case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_PSGMII:
case PHY_INTERFACE_MODE_QSGMII:
case PHY_INTERFACE_MODE_QUSGMII:
case PHY_INTERFACE_MODE_USXGMII:
@@ -4178,6 +4179,7 @@ void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
break;
case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_PSGMII:
case PHY_INTERFACE_MODE_QSGMII:
if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
phylink_decode_sgmii_word(state, lpa);
@@ -4258,6 +4260,7 @@ int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
adv |= ADVERTISE_1000XPSE_ASYM;
return adv;
case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_PSGMII:
case PHY_INTERFACE_MODE_QSGMII:
return 0x0001;
default:
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 2bc0db3d52ac..1dda5c7ed5f1 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -791,6 +791,7 @@ static inline int phylink_get_link_timer_ns(phy_interface_t interface)
{
switch (interface) {
case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_PSGMII:
case PHY_INTERFACE_MODE_QSGMII:
case PHY_INTERFACE_MODE_USXGMII:
case PHY_INTERFACE_MODE_10G_QXGMII: