[PATCH net-next 03/12] net: pcs: pcs-xpcs: Preserve BMCR_ANENBLE during link up

Alex Elder
2026-05-01T15:54:39Z

From: Daniel Thompson <daniel@riscstar.com>

Currently the XCPS found on Toshiba TC9564 (a.k.a. Qualcomm QPS615)
is unable to operate at 1000base-X and slower with a PHY connected
using SGMII/2500base-X (in our case a Qualcomm QCA8081). The link
negotiates speed correctly but the MAC can't get any packets out.

This attracted attention to the ANENABLE bit and we observed that the
bit is currently set during config and cleared during link up.
Preserving the bit during link up allows the system to work as expected.

Perhaps I lack the imagination but I couldn't come up with any reason
why keeping the ANENABLE bit set would break things for other XPCS
implementations. Let's ensure link up sets the bit for SGMII interfaces.

Signed-off-by: Daniel Thompson <daniel@riscstar.com>
Signed-off-by: Alex Elder <elder@riscstar.com>
---
drivers/net/pcs/pcs-xpcs.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index b2c84b7e1e113..1d62d5b31c61c 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -1263,11 +1263,14 @@ static void xpcs_link_up_sgmii_1000basex(struct dw_xpcs *xpcs,
phy_interface_t interface,
int speed, int duplex)
{
+ u16 an_enable;
int ret;

if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
return;

+ an_enable = (interface == PHY_INTERFACE_MODE_SGMII ? BMCR_ANENABLE : 0);
+
if (interface == PHY_INTERFACE_MODE_1000BASEX) {
if (speed != SPEED_1000) {
dev_err(&xpcs->mdiodev->dev,
@@ -1283,7 +1286,7 @@ static void xpcs_link_up_sgmii_1000basex(struct dw_xpcs *xpcs,
}

ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MII_BMCR,
- mii_bmcr_encode_fixed(speed, duplex));
+ mii_bmcr_encode_fixed(speed, duplex) | an_enable);
if (ret)
dev_err(&xpcs->mdiodev->dev, "%s: xpcs_write returned %pe\n",
__func__, ERR_PTR(ret));
--
2.51.0