[BPI-R4] Zyxel PMG3000-D20B SFP module not detected

I bought a PMG3000-D20B SFP module, since I need that for my GPON Fiber uplink. However, the module is not detected whatsoever.

In dmesg, with debugging turned on, sometimes this appears while inserting it:

[Wed Jul  3 19:23:08 2024] sfp sfp1: mod-def0 0 -> 1
[Wed Jul  3 19:23:08 2024] sfp sfp1: SM: enter empty:up:down event insert
[Wed Jul  3 19:23:08 2024] sfp sfp1: SM: exit probe:up:down
[Wed Jul  3 19:23:08 2024] sfp sfp1: mod-def0 1 -> 0
[Wed Jul  3 19:23:08 2024] sfp sfp1: SM: enter probe:up:down event remove
[Wed Jul  3 19:23:08 2024] sfp sfp1: module removed
[Wed Jul  3 19:23:08 2024] sfp sfp1: SM: exit empty:up:down

The status LED of the mainboard briefly flashes bright green while pushing in the module, and then settles for a very dim green glow while the module is in. When pulling it out, it very briefly flashes bright green as well. I can also fiddle with the module to hold it at the point where it’s bright green. It stays bright then the whole time, but nothing else changes. Notably, above debug messages also scrolls through when I only push it in up to that point.

I can however successfully talk to the module via i2cdump:

# i2cdump -y 3 0x50
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 03 04 01 00 00 00 02 00 00 00 00 03 0c 00 14 c8    ???...?....??.??
10: 00 00 00 00 5a 59 58 45 4c 00 00 00 00 00 00 00    ....ZYXEL.......
20: 00 00 00 00 00 00 00 00 50 4d 47 33 30 30 30 2d    ........PMG3000-
30: 44 32 30 42 00 00 00 00 56 31 2e 30 05 1e 00 55    D20B....V1.0??.U
40: 00 1a 00 00 53 32 33 34 31 30 37 35 30 32 35 39    .?..S23410750259
50: 36 00 00 00 31 35 30 35 32 35 20 20 68 f0 01 a4    6...150525  h???
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................

When manually trying to bring the link up, this is logged:

[  448.515127] sfp sfp1: SM: enter empty:up:down event dev_down
[  448.520845] sfp sfp1: SM: exit empty:down:down
[  450.753154] mtk_soc_eth 15100000.ethernet eth2: configuring for inband/sgmii link mode
[  450.761141] mtk_soc_eth 15100000.ethernet eth2: major config sgmii
[  450.767314] mtk_soc_eth 15100000.ethernet eth2: phylink_mac_config: mode=inband/sgmii/none adv=00,00000010,00000200,00026260 pause=00
[  450.782875] sfp sfp1: SM: enter empty:down:down event dev_up
[  450.788550] sfp sfp1: SM: exit empty:up:down

ethtool reports:

# ethtool eth2
Settings for eth2:
        Supported ports: [ MII ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Half 1000baseT/Full
                                10000baseT/Full
                                2500baseX/Full
                                1000baseKX/Full
                                10000baseKX4/Full
                                10000baseKR/Full
                                10000baseR_FEC
                                1000baseX/Full
                                10000baseCR/Full
                                10000baseSR/Full
                                10000baseLR/Full
                                10000baseLRM/Full
                                10000baseER/Full
                                2500baseT/Full
                                5000baseT/Full
                                100baseT1/Full
                                1000baseT1/Full
                                100baseFX/Half 100baseFX/Full
                                10baseT1L/Full
                                10baseT1S/Full
                                10baseT1S/Half 10baseT1S_P2MP/Half
        Supported pause frame use: Symmetric Receive-only
        Supports auto-negotiation: Yes
        Supported FEC modes: Not reported
        Advertised link modes:  1000baseT/Full
                                1000baseKX/Full
                                1000baseX/Full
                                1000baseT1/Full
        Advertised pause frame use: Symmetric Receive-only
        Advertised auto-negotiation: Yes
        Advertised FEC modes: Not reported
        Speed: Unknown!
        Duplex: Unknown! (255)
        Auto-negotiation: on
        Port: MII
        PHYAD: 0
        Transceiver: internal
        Current message level: 0x000000ff (255)
                               drv probe link timer ifdown ifup rx_err tx_err
        Link detected: no
# ethtool -m eth2
netlink error: No such device

I tried manually setting the speed of the module to 1Gbit full duplex, but to no avail. Is this module just electrically incompatible? Or is this just a missing driver quirk?

The kernel in use is 6.9-main from GitHub - frank-w/BPI-Router-Linux at 6.9-main with latest stable linux 6.9.7 merged into it. Also tried with 6.9.0 as it is in that repo, but that changed nothing either.

Ok, I have managed to make this module at least work. The issue from my observation: It has a really long boot-up sequence, and only AFTER that sequence, it pulls the MOD_DEF0 pin low.

The problem: While that pin is not pulled low, the circuit of the BPI-R4 board itself does not turn on the power supply for the SFP module. There’s a mosfet that prevents it.

See the circuit diagram:

I’ve marked the critical spot. The mosfet there will stay off until the module signalizes that it’s present/ready. But this particular module won’t do that until it had power for about a minute.

I verified this by manually poking wires at the board, bridging over the mosfet, manually energizing the module. After holding this for a while, I could let go of the bridge, and it held itself on and is working as expected now.

So this seems like quite a fundamental design flaw of the BPI-R4? Or is this module violating some kind of spec by behaving like that? In any case, judging by the circuit diagram, there is a spot there for just a 0-Ohm bridge instead of the mosfet, so I guess I’ll have to look into some fine soldering, or just soldering in a small bridge over the existing mosfet.

Edit: There is this ominous 3.3V_SFP1 thing directly to the right of the mosfet. It does not seem to go anywhere. It does not appear anywhere else in the entire circuit diagram. If this could be somehow switched on in software, it’d save me an arduous soldering job. But there is no documentation on it.

Ok, so I actually got out the soldering iron, and replaced the SFP1 mosfet with just a direct bridge from S to O:

Result: LED is always lit, even without module. But when inserting the module:

[ 5068.554425] sfp sfp1: mod-def0 0 -> 1
[ 5068.558101] sfp sfp1: SM: enter empty:up:down event insert
[ 5068.563580] sfp sfp1: SM: exit probe:up:down
[ 5068.567925] sfp sfp1: mod-def0 1 -> 0
[ 5068.571589] sfp sfp1: SM: enter probe:up:down event remove
[ 5068.577078] sfp sfp1: module removed
[ 5068.580645] sfp sfp1: SM: exit empty:up:down
[ 5126.541457] sfp sfp1: mod-def0 0 -> 1
[ 5126.545155] sfp sfp1: SM: enter empty:up:down event insert
[ 5126.550636] sfp sfp1: SM: exit probe:up:down
[ 5126.854093] sfp sfp1: SM: enter probe:up:down event timeout
[ 5126.871010] sfp sfp1: module ZYXEL PMG3000-D20B rev V1.0 sn S234107502596 dc 150525
[ 5126.878869] mtk_soc_eth 15100000.ethernet eth2: optical SFP: interfaces=[mac=2-4,22-24,27,29, sfp=22]
[ 5126.888106] mtk_soc_eth 15100000.ethernet eth2:  interface 22 (1000base-x) rate match none supports 6,10,13-14,41
[ 5126.898389] mtk_soc_eth 15100000.ethernet eth2: optical SFP: chosen 1000base-x interface
[ 5126.906480] mtk_soc_eth 15100000.ethernet eth2: requesting link mode inband/1000base-x with support 00,00000000,00000200,00006440
[ 5126.918133] mtk_soc_eth 15100000.ethernet eth2: switched to inband/1000base-x link mode
[ 5126.926147] mtk_soc_eth 15100000.ethernet eth2: major config 1000base-x
[ 5126.933304] mtk_soc_eth 15100000.ethernet eth2: phylink_mac_config: mode=inband/1000base-x/none adv=00,00000000,00000200,00006440 pause=04
[ 5126.945759] mtk_soc_eth 15100000.ethernet: mux mux_gdm1_to_gmac1_esw isn't present on the SoC
[ 5126.954291] mtk_soc_eth 15100000.ethernet: mux mux_gmac2_gmac0_to_gephy isn't present on the SoC
[ 5126.963065] mtk_soc_eth 15100000.ethernet: mux mux_u3_gmac2_to_qphy isn't present on the SoC
[ 5126.971502] mtk_soc_eth 15100000.ethernet: mux mux_gmac1_gmac2_to_sgmii_rgmii isn't present on the SoC
[ 5126.980805] mtk_soc_eth 15100000.ethernet: mux mux_gmac12_to_gephy_sgmii isn't present on the SoC
[ 5126.989683] mtk_soc_eth 15100000.ethernet: path gmac3_sgmii in set_mux_gmac123_to_gephy_sgmii updated = 1
[ 5126.999250] mtk_soc_eth 15100000.ethernet: path gmac3_sgmii in set_mux_gmac123_to_usxgmii updated = 0
[ 5127.012020] sfp sfp1: tx disable 1 -> 0
[ 5127.015892] sfp sfp1: SM: exit present:up:wait
[ 5127.020395] sfp sfp1: los 0 -> 1
[ 5127.023625] sfp sfp1: SM: enter present:up:wait event los_high
[ 5127.029465] sfp sfp1: SM: exit present:up:wait
[ 5127.037459] hwmon hwmon3: temp1_input not attached to any thermal zone
[ 5127.084076] sfp sfp1: SM: enter present:up:wait event timeout
[ 5127.089840] sfp sfp1: SM: exit present:up:wait_los

So it actually works now without having to poke around with wires on the board!

I’m still curious why the decision to put this mosfet-circuit there was made? The BPI-R3 did not have it, any any reference design I can find has nothing like it. If at all, it could be used for the status led, so it’d follow the module status.

1 Like