]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: pcs: pcs-mtk-lynxi: deprecate "mediatek,pnswap"
authorVladimir Oltean <vladimir.oltean@nxp.com>
Mon, 19 Jan 2026 09:12:20 +0000 (11:12 +0200)
committerJakub Kicinski <kuba@kernel.org>
Thu, 22 Jan 2026 03:46:59 +0000 (19:46 -0800)
Prefer the new "rx-polarity" and "tx-polarity" properties, which in this
case have the advantage that polarity inversion can be specified per
direction (and per protocol, although this isn't useful here).

We use the vendor specific ones as fallback if the standard description
doesn't exist.

Daniel, referring to the Mediatek SDK, clarifies that the combined
SGMII_PN_SWAP_TX_RX register field should be split like this: bit 0 is
TX and bit 1 is RX:
https://lore.kernel.org/linux-phy/aSW--slbJWpXK0nv@makrotopia.org/

Suggested-by: Daniel Golle <daniel@makrotopia.org>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260119091220.1493761-6-vladimir.oltean@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/pcs/Kconfig
drivers/net/pcs/pcs-mtk-lynxi.c

index ecbc3530e780c5c77dd69fbb3acfc03e0c9ee8d4..e417fd66f660ad58601d4381e7112a592db507ed 100644 (file)
@@ -20,6 +20,7 @@ config PCS_LYNX
 
 config PCS_MTK_LYNXI
        tristate
+       select PHY_COMMON_PROPS
        select REGMAP
        help
          This module provides helpers to phylink for managing the LynxI PCS
index 7f719da5812e5e9551aef9e13bfa1f36bb34ac04..74dbce205f71370478fd3457e376560df97b0a55 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/mdio.h>
 #include <linux/of.h>
 #include <linux/pcs/pcs-mtk-lynxi.h>
+#include <linux/phy/phy-common-props.h>
 #include <linux/phylink.h>
 #include <linux/regmap.h>
 
@@ -62,8 +63,9 @@
 
 /* Register to QPHY wrapper control */
 #define SGMSYS_QPHY_WRAP_CTRL          0xec
-#define SGMII_PN_SWAP_MASK             GENMASK(1, 0)
-#define SGMII_PN_SWAP_TX_RX            (BIT(0) | BIT(1))
+#define SGMII_PN_SWAP_RX               BIT(1)
+#define SGMII_PN_SWAP_TX               BIT(0)
+
 
 /* struct mtk_pcs_lynxi -  This structure holds each sgmii regmap andassociated
  *                         data
@@ -121,6 +123,42 @@ static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
                                         FIELD_GET(SGMII_LPA, adv));
 }
 
+static int mtk_pcs_config_polarity(struct mtk_pcs_lynxi *mpcs,
+                                  phy_interface_t interface)
+{
+       struct fwnode_handle *fwnode = mpcs->fwnode, *pcs_fwnode;
+       unsigned int pol, default_pol = PHY_POL_NORMAL;
+       unsigned int val = 0;
+       int ret;
+
+       if (fwnode_property_read_bool(fwnode, "mediatek,pnswap"))
+               default_pol = PHY_POL_INVERT;
+
+       pcs_fwnode = fwnode_get_named_child_node(fwnode, "pcs");
+
+       ret = phy_get_rx_polarity(pcs_fwnode, phy_modes(interface),
+                                 BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT),
+                                 default_pol, &pol);
+       if (ret) {
+               fwnode_handle_put(pcs_fwnode);
+               return ret;
+       }
+       if (pol == PHY_POL_INVERT)
+               val |= SGMII_PN_SWAP_RX;
+
+       ret = phy_get_tx_polarity(pcs_fwnode, phy_modes(interface),
+                                 BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT),
+                                 default_pol, &pol);
+       fwnode_handle_put(pcs_fwnode);
+       if (ret)
+               return ret;
+       if (pol == PHY_POL_INVERT)
+               val |= SGMII_PN_SWAP_TX;
+
+       return regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
+                                 SGMII_PN_SWAP_RX | SGMII_PN_SWAP_TX, val);
+}
+
 static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
                                phy_interface_t interface,
                                const unsigned long *advertising,
@@ -130,6 +168,7 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
        bool mode_changed = false, changed;
        unsigned int rgc3, sgm_mode, bmcr;
        int advertise, link_timer;
+       int ret;
 
        advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
                                                             advertising);
@@ -169,10 +208,9 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
                regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0,
                                SGMII_SW_RESET);
 
-               if (fwnode_property_read_bool(mpcs->fwnode, "mediatek,pnswap"))
-                       regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
-                                          SGMII_PN_SWAP_MASK,
-                                          SGMII_PN_SWAP_TX_RX);
+               ret = mtk_pcs_config_polarity(mpcs, interface);
+               if (ret)
+                       return ret;
 
                if (interface == PHY_INTERFACE_MODE_2500BASEX)
                        rgc3 = SGMII_PHY_SPEED_3_125G;