Re: [PATCH v4 net-next 5/5] net: pcs: pcs-mtk-lynxi: deprecate "mediatek,pnswap"
From: Frank Wunderlich
Date: Fri Apr 03 2026 - 04:23:51 EST
Am 2. April 2026 11:53:00 MESZ schrieb Vladimir Oltean <vladimir.oltean@xxxxxxx>:
>On Thu, Apr 02, 2026 at 05:50:33AM +0000, Frank Wunderlich wrote:
>> Hi,
>
>Hi,
>
>Please don't top-post :(
Sorry about that. Try to do better future :)
I keep context for now (not removing my findings from early mail),i hope it is ok.
Maybe daniel or mtk can respond if my understanding is wrong.
>> i tried using these properties in sgmiisys0 node (which should be mapped to mac0 and the mt7530 switch) without success [1].
>>
>> it looks like these properties are not read somewhere.
>
>Can you please clarify whether your problem is with the SerDes connected
>to a switch port or to a GMAC?
From my tests it looks like the issue is on switch side.
>Because if to a switch port, mt7531_create_sgmii() doesn't have any
>phandle to the SGMIISYS. That was from existing code.
>
> pcs = mtk_pcs_lynxi_create(priv->dev, NULL, regmap,
> MT7531_PHYA_CTRL_SIGNAL3);
>
>The LynxI PCS will be instantiated without a fwnode and only the
>defaults will apply.
This was a good hint, i had only seen the pcs call for mac.
>> the flow is
>>
>> mtk_probe (eth driver)
>>
>> if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
>> err = mtk_sgmii_init(eth);
>>
>> and there calling mtk_pcs_lynxi_create with the sgmiisys-node (for each mac, so imho mac0=sgmiisys0)
>> but handling the sgmiisys only as syscon, not a "real" pcs node [2].
>>
>> but your new code calls phy_get_tx_polarity and should read out this properties, but from subnode "pcs", so next try was
>>
>> &sgmiisys0 {
>> pcs {
>> rx-polarity = <PHY_POL_NORMAL>;
>> tx-polarity = <PHY_POL_INVERT>;
>> };
>> };
>>
>> which results in completely strange behaviour (looks like sgmiisys1 is mapped to mac0, but based on code in mtk_sgmii_init 0=0 should be right):
>>
>> [ 2.765218] SGMSYS_QPHY_WRAP_CTRL = 0x501, will write 0x500
>> [ 9.143849] SGMSYS_QPHY_WRAP_CTRL = 0x500, will write 0x501
>>
>> but nevertheless i tried changing sgmiisys0 to sgmiisys1 and got the dame result as before
>>
>> [ 2.713644] SGMSYS_QPHY_WRAP_CTRL = 0x501, will write 0x500
>> [ 9.061509] SGMSYS_QPHY_WRAP_CTRL = 0x500, will write 0x500
>>
>> i can only change the second serdes with sgmiisys0, but not the first.
>
>I assume the second SerDes is mapped to a GMAC port which does
>instantiate the LynxI PCS with a fwnode, right? If so, the behaviour is
>consistent with the code. Only mtk-soc-eth uses mediatek,sgmiisys AFAICS.
>
>> mapping between mac and sgmiisys in dts in mt7986a.dtsi [3] are like this:
>>
>> eth: ethernet@15100000 {
>> compatible = "mediatek,mt7986-eth";
>> mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
>> ...
>> };
>>
>> ð {
>> status = "okay";
>>
>> gmac0: mac@0 {
>> compatible = "mediatek,eth-mac";
>> ...
>> };
>>
>> gmac1: mac@1 {
>> compatible = "mediatek,eth-mac";
>> ...
>> };
>> };
>>
>> maybe it is time to revive the PCS framework discussion ([4]-[6])?
>>
>> [1] https://github.com/frank-w/BPI-Router-Linux/commit/4846a7bb352fe5911136cba33813f099bac035fd
>> [2] https://elixir.bootlin.com/linux/v7.0-rc4/source/drivers/net/ethernet/mediatek/mtk_eth_soc.c#L5001
>> [3] https://elixir.bootlin.com/linux/v7.0-rc4/source/arch/arm64/boot/dts/mediatek/mt7986a.dtsi#L528
>>
>> [4] * https://patchwork.kernel.org/project/netdevbpf/patch/20250610233134.3588011-4-sean.anderson@xxxxxxxxx/ (v6)
>> > pcs-framework itself had not yet got a response from netdev maintainer (only other parts)
>> [5] * https://patchwork.kernel.org/project/netdevbpf/patch/20250511201250.3789083-4-ansuelsmth@xxxxxxxxx/ (v4)
>> > discussion: https://lore.kernel.org/netdev/20250511201250.3789083-1-ansuelsmth@xxxxxxxxx/
>> [6] * https://patchwork.kernel.org/project/netdevbpf/patch/ba4e359584a6b3bc4b3470822c42186d5b0856f9.1721910728.git.daniel@xxxxxxxxxxxxxx/
>> > discussion: https://patchwork.kernel.org/project/netdevbpf/patch/8aa905080bdb6760875d62cb3b2b41258837f80e.1702352117.git.daniel@xxxxxxxxxxxxxx/
>
>I'm not exactly sure how device+driver for the PCS devices would help in
>this case though? Because the LynxI PCS driver would just retrieve the
>fwnode on its own, rather than it being passed by the mtk_pcs_lynxi_create()
>caller?
Imho it could be more general and cleaner than calling "external" function in code. If pcs acts
as own device i would see which dtnode is assigned to it...here i guessed both calls were
from mac,but one was from mac and one from switch.
I tried adding prints before the lynxi call,but this does not make it clean from where it comes (i guess because of threading)...but this could be understanding issue on my side.
It looked like this:
root@bpi-r3:~# dmesg | grep 'SGMSYS_QPHY_WRAP_CTRL\|pcs'
[ 2.155221] mtk_soc_eth 15100000.ethernet: create sgmii pcs for mac #0
[ 2.168308] mtk_soc_eth 15100000.ethernet: create sgmii pcs for mac #1
[ 2.699744] mt7530-mdio mdio-bus:1f: add lynxi pcs for switch (port5)
[ 2.706773] mt7530-mdio mdio-bus:1f: add lynxi pcs for switch (port6)
[ 2.707881] SGMSYS_QPHY_WRAP_CTRL = 0x501, will write 0x501
[ 9.081259] SGMSYS_QPHY_WRAP_CTRL = 0x500, will write 0x500
>We need to have a very good model of what happens when the PCS provider
>goes away, especially in multi-port scenarios. It is a similar issue as
>to what happens when a phy_device goes away.
>https://lore.kernel.org/netdev/20260311153421.u454m3e4blkstymt@skbuf/
>
>I'm not saying "let's not do that", but we'd effectively introducing an
>issue that currently does not exist, with the PCS lifetime being managed
>by the consumer.
>
>Do you have any better idea by now why SGMSYS_QPHY_WRAP_CTRL is 0x501
>for SGMIISYS #0? Is that its out-of-reset value?
We guess that switch takes this value somehow from an efuse or similar.
I have 2 ways to fix this broken state:
1) to keep dts backward compatibility and due to undocumented behaviour i prefer this patch:
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -129,6 +129,9 @@ static int mtk_pcs_config_polarity(struct mtk_pcs_lynxi *mpcs,
unsigned int val = 0, tmp;
int ret;
+ if (!fwnode)
+ return 0;
+
if (fwnode_property_read_bool(fwnode, "mediatek,pnswap"))
default_pol = PHY_POL_INVERT;
2) document pcs polarity (i'm still unsure if this is really correct as i cannot measure in hardware,just from software debugging...but not sure if the SGMSYS_QPHY_WRAP_CTRL offset is valid on switch regmap too) - it looks for me that by default is different between mac and switch side:
<https://github.com/frank-w/BPI-Router-Linux/commit/f693e2ed24287ce1e125d7f6202e14e263cc564d>
And add dts nodes like this:
<https://github.com/frank-w/BPI-Router-Linux/commit/4f7bce943dda614d24431d63adad65f1117a7f6d>
If i set same polarity to mac it is broken (thats why sgmiisys0 is disabled). I guess the pnswap property means "invert the default behaviour" and not "use inverted polarity compared to standard" and mac and switch use the same polarity with different values of the corresponding registers.
Based on my register documentation of mt7531 ("MT7531_Reference_Manual_for_Development_Board.pdf" page 729) i see
000050EC = QPHY_WRAP_CTRL
Bit 0
1'b1 : inversed TX_BIT_POLARITY TX bit polarity control (TX default inversed in MT7531)
Where bit 1 is only defined as "RX bit polarity control"
So my guess is that tx is inverted in hardware,but tx-bit is set in efuse to get the POL_NORMAL.
I did not find the register in my mt7986 register documentation...seems complete networking part is missing.
I do not expect that board changes polarity in hardware...
Regards Frank