From: Alex Elder <elder@riscstar.com>
To: andrew@lunn.ch, hkallweit1@gmail.com, linux@armlinux.org.uk,
davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org,
pabeni@redhat.com
Cc: Daniel Thompson <daniel@riscstar.com>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH net-next 2/2] net: pcs: xpcs: select operating mode for 10G-baseR capable PCS
Date: Wed, 14 Oct 2026 17:30:59 -0500 [thread overview]
Message-ID: <20261014223100.304486-3-elder@riscstar.com> (raw)
In-Reply-To: <20261014223100.304486-1-elder@riscstar.com>
From: Daniel Thompson <daniel@riscstar.com>
Currently the XPCS found on Toshiba TC9564 is unable to operate at
2500base-X and slower with a PHY connected using SGMII/2500base-X
(in our case a Qualcomm QCA8081).
The problem arises because this XPCS supports 10Gbase-R. That means
that the reset value of SR_XS_PCS_CTRL2:PCS_TYPE_SEL (0) is valid and
this suppresses the modal switching based on bit 13 of SR_PMA_CTRL1
or SR_XS_PCS_CTRL1.
A fix for this behaviour is implemented by txgbe_xpcs_switch_mode()
as part of the quirks for WangXun devices.
Rather than introduce another quirk for TC9564 let's attempt so solve
this generically by setting SR_XS_PCS_CTRL2:PCS_TYPE_SEL to a reserved
value when we detect the right combination of phy interface and XPCS
feature support.
The generic strategy adopted requires the default value of PCS_TYPE_SEL
to be 0 on devices that support 10Gbase-R. Based on TC9564 documentation
and the logic already implemented for WangXun I believe this is likely
to be the case for currently supported XPCS devices. Sadly I don't have
access to generic XPCS docs to confirm. However I think the benefits
of avoiding a cargo culted quirk outweighs the risk of regression.
Signed-off-by: Daniel Thompson <daniel@riscstar.com>
Co-developed-by: Alex Elder <elder@riscstar.com>
Signed-off-by: Alex Elder <elder@riscstar.com>
---
drivers/net/pcs/pcs-xpcs.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index 49abf5ea6f5cc..5316cf9c31f19 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -705,10 +705,47 @@ static void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces)
static int xpcs_switch_interface_mode(struct dw_xpcs *xpcs,
phy_interface_t interface)
{
+ int mdio_stat2, ret;
+
/* Wangxun provides a full alternative implementation to handle quirks */
if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID)
return txgbe_xpcs_switch_mode(xpcs, interface);
+ mdio_stat2 = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT2);
+ if (mdio_stat2 < 0)
+ return mdio_stat2;
+
+ /*
+ * If this XPCS supports 10Gbase-R then that will be the default
+ * operating mode. There are several interface modes where this default
+ * is unhelpful. Change the operating mode for interfaces were we know
+ * the default is wrong, and restore the default otherwise.
+ */
+ if (mdio_stat2 & MDIO_PCS_STAT2_10GBR) {
+ switch (interface) {
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_1000BASEX:
+ case PHY_INTERFACE_MODE_2500BASEX:
+ /*
+ * Why are we writing MDIO_PCS_CTRL2_TYPE + 1? We want
+ * the modal behaviour that comes when we pick a
+ * reserved value. XPCS allocates extra bits to this
+ * field and allocates values from 15 down so
+ * MDIO_PCS_CTRL2_TYPE + 1 is the value likely to be
+ * allocated last (and hopefully never).
+ */
+ ret = xpcs_write(xpcs, MDIO_MMD_PCS, MDIO_CTRL2,
+ MDIO_PCS_CTRL2_TYPE + 1);
+ break;
+ default:
+ ret = xpcs_write(xpcs, MDIO_MMD_PCS, MDIO_CTRL2,
+ MDIO_PCS_CTRL2_10GBR);
+ break;
+ }
+ if (ret < 0)
+ return ret;
+ }
+
xpcs->interface = interface;
return 0;
--
2.53.0
prev parent reply other threads:[~2026-10-14 22:31 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-14 22:30 [PATCH net-next 0/2] net: pcs: xpcs: fix operating mode selection Alex Elder
2026-10-14 22:30 ` [PATCH net-next 1/2] net: pcs: xpcs: re-order xpcs_pre_config() to update after the reset Alex Elder
2026-10-14 22:30 ` Alex Elder [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261014223100.304486-3-elder@riscstar.com \
--to=elder@riscstar.com \
--cc=andrew@lunn.ch \
--cc=daniel@riscstar.com \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=hkallweit1@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.