SFP OEM SFP-2.5G-T kernel PHY?

Anyway, it seems to only work after live re-inserting. So after booting, pull out and insert. Need to see why…

Can already see from the adapter on the other side, that link partner advertisement is not set up correctly. (It is after re-inserting) Can eventually connect at low speed, but no response from ping. All setup is done by the SFP, so it seems that it is somehow disturbed by the new code…

Maybe the 4 seconds wait needs to be increased…

So increase the value here to 25, see if that works …

sfp_fixup_rollball_proto(sfp, 4);


Increasing this time does not help. But I have found that re-inserting is not needed. It is somehow in a toggling state: down/up - OK - down/up - Not OK - down/up - OK - down/up Not OK - etc.

Can already see the SFP it setup correctly, even before the 4/25 waiting time is finished. After bringing it up (not waiting), on the other side of the copper the link is going up really fast at 2500, or I already see it is not going to work.

The first debugging message I added to try and find this toggling problem, actually already fixed it! Lucky shot :wink:

diff --git a/drivers/net/mdio/mdio-i2c.c b/drivers/net/mdio/mdio-i2c.c
index da2001ea1..ff3f5aab3 100644
--- a/drivers/net/mdio/mdio-i2c.c
+++ b/drivers/net/mdio/mdio-i2c.c
@@ -397,6 +397,7 @@ struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
        switch (protocol) {
        case MDIO_I2C_ROLLBALL:
+               dev_info(parent, "INIT ROLLBALL!!!\n");
                ret = i2c_mii_init_rollball(i2c);
                if (ret < 0) {

I was trying to check when this init is called. But apparently the extra delay already fixes it.

So I’ll see about adding a delay function call here for a small delay and then it should be almost finished…

Also need to try out the optimum setting of the 4 second delay, see if it can be shorter for this SFP.

1 Like

New version of patch set on the gists page. It will give a better idea of how it will look like.

Turns out that it was not replugging or a delay, but certain registers are not supposed to be read. Depending on the timing, it could severally upset the PHY.

Fixed in:


This means the patch-set should be stable and ready to test… Apply it to the latest netdev/net-next, as it relies on a very recent patch from Russell.

I also need to test it, only just fixed this last issue…

1 Like

so now in your current tests the phy is recognized every time without re-plug? and recognizes the link without any autoneg tricks? have added the new patches now, but i guess i’m able to test only next days

It should all work, but because I was bug hunting, I have not really tested it thoroughly.

Also needs this patch, if not build on netdev/net-next.


May need some other I am not aware of, only used netdev/net-next


This one is also quite new, may need to add it if phy_id_compare() is not there:

https://patchwork.kernel.org/project/netdevbpf/patch/[email protected]/

Edit 2:

The matching functions are updated

So the rough version is finished, basically it all works as I wanted. So maybe some minor changes, but basically this is it.

Repo/Branch here SFP-2.5G-T net-next

Some help with testing and some improvement suggestion would be appreciated.

So, the kernel now has the phydev->possible_interfaces which is something we asked for, but now it is there…

Anyway, most of the above is obsolete with:


But then remains the issue that MediaTek LynxI PCS, 2500Base-X will only work without inband status due to hardware limitation.

Previous attempts to tackle this were not approved here

So I have thought of this:


It works with the rtl8221b on the BPI-R3, but still need to test with an optical module at 2500, which I do not have…


I guess I could test the in-band-status quirk with the rtl8221b, without the sfp-quirk, so it would be handled as if it is optical…

Well, 2500base-x is broken for the BPI-R3 on net-next… Even with unaltered code, and the sfp module with the autoneg-off quirk (without phy). I found we still need a part of the previously submitted “net: pcs: pcs-mtk-lynxi: use 2500Base-X without AN”:

So only in the mtk_pcs_lynxi_get_state() function.

So net-next really needs this fix:

Edited the commit message.

1 Like

As pointed out, the fix for handling 2500base-x without autoneg should be done in phylink.c, not in any device driver.

So now I have a simple patch (which won’t be upstreamable, but it works on R3). Now the 2.5G sfp works in optical mode, even without disabling autoneg from the sfp-quirk. It also works when the module’s phy is recognised and used.

See: new patch

One can see that phylink_pcs_neg_mode() has moved already to phylink.c in net-next, to provide for a solution something similar to this.

So this patch-set was rejected because of:

In order not to break handling of the RTL8125-internal PHY’s, we have to keep the access to the vendor-specific registers. What could be done: Split the PHY driver for e.g. RTL8226B into one for the RTL8125-internal version and one for the standalone version (using match_phy_device and maybe using the MMD read result as differentiating criteria). Then the one for the standalone version could use core c45 functions.

So this means that we could use the extra driver instance, as I had in my patchset.

I contacted Marek, but he did not find the time to continue on that patchset. I asked him if I could and that is ok. So I have prepared a new version here:


Mind you that the last commit is not part of the patchset. It is called net: phylink: add support for disabling in-band-status for base-x It will not be accepted upstream. It is needed to handle the fact that the R3 does not support inband negotiation at 2500base-x. It has to be switched off. So either use this patch, or the one from @dangowrt that modifies the pcs driver.

So if anyone would like to test this, give some feedback from the community here, that would be great.

To make the RTL8221B work on systems where the PHY is on-board rather than inside an SFP module (like GL-iNet MT-6000 or TP-LINK XDR608x) I still have to either patch phylink to enable in-band-status on the MAC/PCS side anyway (rather than relying only on out-of-band status which seems to be what Linux usually does) or configure the PHY to not use in-band-status as in this patch:

(it may need some love to conditionally enable/disable SGMII in-band-status)

Yep, solving the inband status/an issue is something that I would like to have also. But because the standard for it came very late, now all hardware handles it in different ways, and it now cannot be solved easily.

To get this patch-set to be accepted, I’ll leave the entire inband issue out of this patch-set, same as Marek’s patch-set.

If you still need 8221B’s datasheet…

Also, how did they make it to access phy registers using i2c….? 8221B doesn’t support i2c at all.

They used a mcu with RollBall protocol.

1 Like

@ericwoud Can you also add SFP-2.5G-T-R-RM to your fixup patch series? It seems completely same with SFP-2.5G-T.

root@OpenWrt:~# ethtool -m sfp2
        Identifier                                : 0x03 (SFP)
        Extended identifier                       : 0x04 (GBIC/SFP defined by 2-wire interface ID)
        Connector                                 : 0x07 (LC)
        Transceiver codes                         : 0x00 0x01 0x00 0x00 0x00 0x00 0x02 0x00 0x00
        Transceiver type                          : SONET: OC-48, short reach
        Encoding                                  : 0x05 (SONET Scrambled)
        BR, Nominal                               : 2500MBd
        Rate identifier                           : 0x00 (unspecified)
        Length (SMF,km)                           : 0km
        Length (SMF)                              : 0m
        Length (50um)                             : 300m
        Length (62.5um)                           : 200m
        Length (Copper)                           : 0m
        Length (OM3)                              : 0m
        Laser wavelength                          : 850nm
        Vendor name                               : OEM
        Vendor OUI                                : 00:00:00
        Vendor PN                                 : SFP-2.5G-T-R-RM
        Vendor rev                                : 1.0
        Option values                             : 0x00 0x1a
        Option                                    : RX_LOS implemented
        Option                                    : TX_FAULT implemented
        Option                                    : TX_DISABLE implemented
        BR margin, max                            : 0%
        BR margin, min                            : 0%
        Vendor SN                                 : 2401050130
        Date code                                 : 240105
        Optical diagnostics support               : Yes
        Laser bias current                        : 6.000 mA
        Laser output power                        : 0.5000 mW / -3.01 dBm
        Receiver signal average optical power     : 0.4000 mW / -3.98 dBm
        Module temperature                        : 42.25 degrees C / 108.05 degrees F
        Module voltage                            : 3.3505 V
        Alarm/warning flags implemented           : Yes
        Laser bias current high alarm             : Off
        Laser bias current low alarm              : Off
        Laser bias current high warning           : Off
        Laser bias current low warning            : Off
        Laser output power high alarm             : Off
        Laser output power low alarm              : Off
        Laser output power high warning           : Off
        Laser output power low warning            : Off
        Module temperature high alarm             : Off
        Module temperature low alarm              : Off
        Module temperature high warning           : Off
        Module temperature low warning            : Off
        Module voltage high alarm                 : Off
        Module voltage low alarm                  : Off
        Module voltage high warning               : Off
        Module voltage low warning                : Off
        Laser rx power high alarm                 : Off
        Laser rx power low alarm                  : Off
        Laser rx power high warning               : Off
        Laser rx power low warning                : Off
        Laser bias current high alarm threshold   : 15.000 mA
        Laser bias current low alarm threshold    : 1.000 mA
        Laser bias current high warning threshold : 13.000 mA
        Laser bias current low warning threshold  : 2.000 mA
        Laser output power high alarm threshold   : 1.9952 mW / 3.00 dBm
        Laser output power low alarm threshold    : 0.1584 mW / -8.00 dBm
        Laser output power high warning threshold : 1.5848 mW / 2.00 dBm
        Laser output power low warning threshold  : 0.1778 mW / -7.50 dBm
        Module temperature high alarm threshold   : 95.00 degrees C / 203.00 degrees F
        Module temperature low alarm threshold    : -50.00 degrees C / -58.00 degrees F
        Module temperature high warning threshold : 90.00 degrees C / 194.00 degrees F
        Module temperature low warning threshold  : -45.00 degrees C / -49.00 degrees F
        Module voltage high alarm threshold       : 3.6000 V
        Module voltage low alarm threshold        : 3.0000 V
        Module voltage high warning threshold     : 3.5000 V
        Module voltage low warning threshold      : 3.1000 V
        Laser rx power high alarm threshold       : 1.1220 mW / 0.50 dBm
        Laser rx power low alarm threshold        : 0.0199 mW / -17.01 dBm
        Laser rx power high warning threshold     : 1.0000 mW / 0.00 dBm
        Laser rx power low warning threshold      : 0.0223 mW / -16.52 dBm
root@OpenWrt:~# i2cdump -y 2 0x56
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: 20 58 00 06 00 1c c8 49 20 70 00 8a 80 00 00 30     X.?.??I p.??..0
10: 82 00 00 00 00 00 41 a0 00 00 00 00 00 1c c8 49    ?.....A?.....??I
20: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00    ...........?....
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................

Thanks, but could you first try it first? You could just replace the string in sfp.c

Does it have any brand name on the label? Or does it come from a particular store or have any other marking that this module can be recognized?

Edit: Anyway net-next is closed until 25 march, so we still have some time for it…

No brand name, and same label design as SFP-2.5G-T. I bought that from BPI’s official taobao store. And photos in the store page are also using SFP-2.5G-T rather than SFP-2.5G-T-R-RM.

Besides, how do you test your patches? I have no clue about how to backport your patches to openwrt’s 5.15…

Isn’t this patch already in openwrt for the BPI-R3 / R4?