[PATCH] net: pcs: pcs-mtk-lynxi: preserve lane polarities when not described in fwnode

From: Vladimir Oltean

Date: Thu Mar 26 2026 - 17:46:46 EST


Frank Wunderlich reports that the BPI-R3 board has a default
SGMSYS_QPHY_WRAP_CTRL = 0x501, aka TX inverted and RX not inverted.
At the same time, neither rx-polarity/tx-polarity nor mediatek,pnswap
are present in the device tree.

The original driver logic was to enable both TX inversion and RX
inversion when finding mediatek,pnswap in the device tree, and leave
SGMSYS_QPHY_WRAP_CTRL to its default value otherwise.

The blamed commit has broken that by assuming that a missing
mediatek,pnswap would mean non-inverting polarity.

Restore the original behaviour by reading the SGMSYS_QPHY_WRAP_CTRL
value and using it as a default polarity if mediatek,pnswap and the new
rx-polarity/tx-polarity are all unset.

Fixes: 8871389da151 ("net: pcs: pcs-mtk-lynxi: deprecate "mediatek,pnswap"")
Reported-by: Frank Wunderlich <frank.wunderlich@xxxxxxxxx>
Closes: https://lore.kernel.org/netdev/e0ad52862d34cf4e0169c9850a7f164f127d0093@xxxxxxxxx/
Signed-off-by: Vladimir Oltean <vladimir.oltean@xxxxxxx>
---
drivers/net/pcs/pcs-mtk-lynxi.c | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
index c12f8087af9b..7518c98fa98a 100644
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -126,11 +126,24 @@ static int mtk_pcs_config_polarity(struct mtk_pcs_lynxi *mpcs,
{
struct fwnode_handle *fwnode = mpcs->fwnode, *pcs_fwnode;
unsigned int pol, default_pol = PHY_POL_NORMAL;
- unsigned int val = 0;
+ unsigned int val = 0, orig;
+ bool has_legacy_prop;
int ret;

- if (fwnode_property_read_bool(fwnode, "mediatek,pnswap"))
+ ret = regmap_read(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL, &orig);
+ if (ret)
+ return ret;
+
+ /* RX polarity:
+ * - if standard 'rx-polarity' exists in 'pcs' subnode, follow that
+ * - if 'mediatek,pnswap' is set, invert RX polarity
+ * - otherwise, leave unchanged
+ */
+ has_legacy_prop = fwnode_property_read_bool(fwnode, "mediatek,pnswap");
+ if (has_legacy_prop || FIELD_GET(SGMII_PN_SWAP_RX, orig))
default_pol = PHY_POL_INVERT;
+ else
+ default_pol = PHY_POL_NORMAL;

pcs_fwnode = fwnode_get_named_child_node(fwnode, "pcs");

@@ -144,6 +157,16 @@ static int mtk_pcs_config_polarity(struct mtk_pcs_lynxi *mpcs,
if (pol == PHY_POL_INVERT)
val |= SGMII_PN_SWAP_RX;

+ /* And TX polarity:
+ * - if standard 'tx-polarity' exists in 'pcs' subnode, follow that
+ * - if 'mediatek,pnswap' is set, invert TX polarity
+ * - otherwise, leave unchanged
+ */
+ if (has_legacy_prop || FIELD_GET(SGMII_PN_SWAP_TX, orig))
+ default_pol = PHY_POL_INVERT;
+ else
+ default_pol = PHY_POL_NORMAL;
+
ret = phy_get_tx_polarity(pcs_fwnode, phy_modes(interface),
BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT),
default_pol, &pol);
--
2.43.0


--gg3xcc6lsi5dh453--