FAILED: patch "[PATCH] net: pcs: xpcs: fix SGMII state reading" failed to apply to 6.12-stable tree
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x def9a4745e105145133e442dd8a1c126caf0f553
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026072904-shallow-icing-2a9f@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From def9a4745e105145133e442dd8a1c126caf0f553 Mon Sep 17 00:00:00 2001
From: Coia Prant <[email protected]>
Date: Fri, 17 Jul 2026 15:43:25 +0800
Subject: [PATCH] net: pcs: xpcs: fix SGMII state reading
Commit 2a22b7ae2fa3 ("net: pcs: xpcs: adapt Wangxun NICs for SGMII mode") added a path in xpcs_get_state_c37_sgmii() that reads speed/duplex from BMCR after AN completes. However, BMCR does not reflect the negotiated result on the hardware where this has been tested:
- On RK3568 (MAC side SGMII), BMCR returns a fixed hardware reset value
- Wangxun engineer Jiawen Wu confirmed that on their side, "BMCR looks like it only wants to be return as 0" [0]
The correct information is available in CL37_ANSGM_STS, which contains the actual link status and negotiated speed/duplex.
This bug was previously masked by phylink core, which overrides the PCS link state with the PHY state when a PHY is present:
/* If we have a phy, the "up" state is the union of both the
* PHY and the MAC
*/
if (phy)
link_state.link &= pl->phy_state.link;Thus, when the link is down, the PHY's link_down state is applied on top of whatever the PCS reports, hiding the broken PCS state reading path.
Modify xpcs_get_state_c37_sgmii() to:
1. Read link state from CL37_ANSGM_STS
2. If link is up, report speed/duplex from CL37_ANSGM_STS
3. Remove the broken BMCR reading path entirely
Also properly set state->an_complete to reflect the AN completion status, and clear CL37_ANCMPLT_INTR when link is down to avoid stale state.
[0] https://lore.kernel.org/all/[email protected]/
drivers/net/pcs/pcs-xpcs.c +8 -26
@@ -1058,6 +1058,7 @@ static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs,/* Reset link_state */ state->link = false; + state->an_complete = false; state->speed =SPEED_UNKNOWN ; state->duplex =DUPLEX_UNKNOWN ; state->pause =0 ;
@@ -1069,6 +1070,8 @@ static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs,if (ret <0 )return ret; + state->an_complete = ret &DW_VR_MII_AN_STS_C37_ANCMPLT_INTR ; +if (ret &DW_VR_MII_C37_ANSGM_SP_LNKSTS ) {int speed_value;
@@ -1086,35 +1089,14 @@ static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs, state->duplex =DUPLEX_FULL ; else state->duplex = DUPLEX_HALF; - }else if (ret ==DW_VR_MII_AN_STS_C37_ANCMPLT_INTR ) { -int speed, duplex; - state->link = true; - - speed =xpcs_read (xpcs,MDIO_MMD_VEND2 ,MII_BMCR ); -if (speed <0 ) -return speed; - - speed &=BMCR_SPEED100 |BMCR_SPEED1000 ; -if (speed ==BMCR_SPEED1000 ) - state->speed =SPEED_1000 ; -else if (speed ==BMCR_SPEED100 ) - state->speed =SPEED_100 ; -else if (speed ==0 ) - state->speed =SPEED_10 ; - - duplex =xpcs_read (xpcs,MDIO_MMD_VEND2 ,MII_ADVERTISE ); -if (duplex <0 ) -return duplex; - -if (duplex &ADVERTISE_1000XFULL ) - state->duplex =DUPLEX_FULL ; -else if (duplex &ADVERTISE_1000XHALF ) - state->duplex =DUPLEX_HALF ; - -xpcs_write (xpcs,MDIO_MMD_VEND2 ,DW_VR_MII_AN_INTR_STS ,0 ); +return 0 ; } +/* Clear AN complete status or interrupt */ +if (state->an_complete) +xpcs_write (xpcs,MDIO_MMD_VEND2 ,DW_VR_MII_AN_INTR_STS ,0 ); +return 0 ; }
PATCH 1/1 net: pcs: xpcs: fix SGMII state reading
Commit 2a22b7ae2fa3 ("net: pcs: xpcs: adapt Wangxun NICs for SGMII mode") added a path in xpcs_get_state_c37_sgmii() that reads speed/duplex from BMCR after AN completes. However, BMCR does not reflect the negotiated result on the hardware where this has been tested:
- On RK3568 (MAC side SGMII), BMCR returns a fixed hardware reset value
- Wangxun engineer Jiawen Wu confirmed that on their side, "BMCR looks like it only wants to be return as 0" [0]
The correct information is available in CL37_ANSGM_STS, which contains the actual link status and negotiated speed/duplex.
This bug was previously masked by phylink core, which overrides the PCS link state with the PHY state when a PHY is present:
/* If we have a phy, the "up" state is the union of both the
* PHY and the MAC
*/
if (phy)
link_state.link &= pl->phy_state.link;Thus, when the link is down, the PHY's link_down state is applied on top of whatever the PCS reports, hiding the broken PCS state reading path.
Modify xpcs_get_state_c37_sgmii() to:
1. Read link state from CL37_ANSGM_STS
2. If link is up, report speed/duplex from CL37_ANSGM_STS
3. Remove the broken BMCR reading path entirely
Also properly set state->an_complete to reflect the AN completion status, and clear CL37_ANCMPLT_INTR when link is down to avoid stale state.
[0] https://lore.kernel.org/all/[email protected]/
--- drivers/net/pcs/pcs-xpcs.c | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-)
drivers/net/pcs/pcs-xpcs.c +7 -25
@@ -973,6 +973,7 @@ static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs,/* Reset link_state */ state->link = false; + state->an_complete = false; state->speed =SPEED_UNKNOWN ; state->duplex =DUPLEX_UNKNOWN ; state->pause =0 ;
@@ -984,6 +985,8 @@ static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs,if (ret <0 )return ret; + state->an_complete = ret &DW_VR_MII_AN_STS_C37_ANCMPLT_INTR ; +if (ret &DW_VR_MII_C37_ANSGM_SP_LNKSTS ) {int speed_value;
@@ -1002,34 +1005,13 @@ static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs, state->duplex =DUPLEX_FULL ; else state->duplex = DUPLEX_HALF; - }else if (ret ==DW_VR_MII_AN_STS_C37_ANCMPLT_INTR ) { -int speed, duplex; - - state->link = true; - - speed =xpcs_read (xpcs,MDIO_MMD_VEND2 ,MDIO_CTRL1 ); -if (speed <0 ) -return speed; - - speed &=SGMII_SPEED_SS13 |SGMII_SPEED_SS6 ; -if (speed ==SGMII_SPEED_SS6 ) - state->speed =SPEED_1000 ; -else if (speed ==SGMII_SPEED_SS13 ) - state->speed =SPEED_100 ; -else if (speed ==0 ) - state->speed =SPEED_10 ; - - duplex =xpcs_read (xpcs,MDIO_MMD_VEND2 ,MII_ADVERTISE ); -if (duplex <0 ) -return duplex; -if (duplex &DW_FULL_DUPLEX ) - state->duplex =DUPLEX_FULL ; -else if (duplex &DW_HALF_DUPLEX ) - state->duplex =DUPLEX_HALF ; +return 0 ; + } +/* Clear AN complete status or interrupt */ +if (state->an_complete)xpcs_write (xpcs,MDIO_MMD_VEND2 ,DW_VR_MII_AN_INTR_STS ,0 ); - }return 0 ; }
Signature · 1 line
2.47.3
Re: [PATCH 6.12.y] net: pcs: xpcs: fix SGMII state reading
Quoted 1 line
[PATCH 6.12.y] net: pcs: xpcs: fix SGMII state reading
Queued for 6.12 and 6.6, thanks.
Signature · 2 lines
Thanks, Sasha