[PATCH net v3] net: phylink: treat PSGMII as an inband capable interface

From: Sandeep Sondagar

Date: Sun Aug 09 2026 - 12:02:31 EST


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().

Fixes: 83b5f0253b1e ("net: phy: Introduce PSGMII PHY interface mode")
Signed-off-by: Sandeep Sondagar <sandeepsondagar@xxxxxxxxx>
---
This series classifies PHY_INTERFACE_MODE_PSGMII (the Qualcomm 5-port
SGMII) as an in-band capable interface in phylink, and adds the mode to
the generic clause 22 PCS helpers so that the in-band SGMII word is
actually used to derive the resolved link speed and state.

Currently PSGMII is missing from phylink_get_inband_type(), so phylink
reports INBAND_NONE and the PCS falls back to PHYLINK_PCS_NEG_NONE,
being programmed in force mode with its control-register speed bits
(default 1000base). A slower copper link, e.g. 100base-T, is therefore
reported as 1Gbps and cannot pass traffic.
---
drivers/net/phy/phylink.c | 3 +++
include/linux/phylink.h | 1 +
2 files changed, 4 insertions(+)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 18d2ead97aa5..1ce9d2266774 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1040,6 +1040,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:
@@ -4183,6 +4184,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);
@@ -4263,6 +4265,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:

---
base-commit: 594d905195024b228c962627ae5ae7c17bd582a4
change-id: 20260809-phylink-psgmii-587bf427bed7

Best regards,
--
Sandeep Sondagar <sandeepsondagar@xxxxxxxxx>