SFP OEM SFP-2.5G-T kernel PHY?

I’ve tried something like that, starting to add the phy, but run in to errors again.

I wonder if it is useful to add the phy to the system.

The module automatically sets the link speed, and applies some kind of throttling . Adding the phy may interfere with this process.

Now I get why it reports itself as being an optical SFP. On that you also cannot interfere with link speed

It may be better to only try to read the current link speed with i2c at 0x56 and report that to the system, instead of the unknown speed. Depends if it can be found at this address.

Any opinions on that?

Imho we need a phy to adjust linkspeed correctly,else it always use the link-speed of the mac (sgmii-2500baseX)

And afaik all sfp are displayed as optical.

I can connect to the sfp on the RJ45 side at any speed 10/100/1000/2500, setting the link speed of my usb rtl8156 on the other side of the copper. The speed on the MAC side of the SFP stays at 2500.

This is exactly as described on the optcore site.

This is all done inside the SFP module hardware independently. It must by accessing the PHY to do so. I believe if we access the PHY also from the kernel side, then we can get very irratic results as they will be interfering with each other.

However,

I found out, it is possible to read the link speed at i2c address 0x51 at byte 0x78. As for duplex, I see no difference in the registers.

The value of byte 0x78 is higher when I change the link speed (via the RTL8156) to a higher speed.

10   Mbps = 0x0a
100  Mbps = 0x01
1000 Mbps = 0x02
2500 Mbps = 0x04

Edit:

Anyway, I wonder if the other side is set at half duplex, what happens, as 2500baseX only has Full mode, no Half… Maybe that is why I cannot see any changes in registers between Full and Half.

So we could get the speed from the register, and duplex will always be Full. That will look better then

        Speed: Unknown!
        Duplex: Unknown! (255)

Byte should be able to read wtth:

unsigned char speedbyte;
sfp_read(sfp, 0x51 == 0x51, 0x78, &speedbyte, 1);

Imho you should make this discussion on lkml (linux mailinglist) in netdev section to get feedback from Russel and others more deep in sfp and phylink handling. Of course you can add me in CC.

seems the phylink-part got missing…do not see the changes in 6.5-rc1, so now we have the state where autoneg needs to be set manually to disabled

[root@bpir3 ~]# i2cdump -y 0 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 02 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    ................

At offset 4 it has: 0x001cc849 , which means that we have this PHY at 0x56:

		PHY_ID_MATCH_EXACT(0x001cc849),
		.name           = "RTL8221B-VB-CG 2.5Gbps PHY",
1 Like

Great find,need to test this with my modules which should be same.

And now we need to find out how we can use this phy

edit: seems your sfp is different to mine (have inserted one into sfp2 - so i2c1)

root@bpi-r3:~# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: 50 51 -- -- -- -- 56 -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
root@bpi-r3:~# i2cdump -y 1 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: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
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    ................                                   
root@bpi-r3:~#

root@bpi-r3:~# ethtool lan4
Settings for lan4:                                                                                        
  Supported ports: [ FIBRE ]                                                                              
  Supported link modes:   2500baseX/Full                                                                  
  Supported pause frame use: Symmetric Receive-only                                                       
  Supports auto-negotiation: No                                                                           
  Supported FEC modes: Not reported                                                                       
  Advertised link modes:  2500baseX/Full                                                                  
  Advertised pause frame use: Symmetric Receive-only                                                      
  Advertised auto-negotiation: No                                                                         
  Advertised FEC modes: Not reported                                                                      
  Speed: Unknown!                                                                                         
  Duplex: Unknown! (255)                                                                                  
  Auto-negotiation: off                                                                                   
  Port: FIBRE                                                                                             
  PHYAD: 0                                                                                                
  Transceiver: internal                                                                                   
  Supports Wake-on: d                                                                                     
  Wake-on: d                                                                                              
  Link detected: no                                                                                       
root@bpi-r3:~# ethtool -m lan4                                                                            
  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                                                  
  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                                 : SK2301110010                                                
  Date code                                 : 230110                                                      
  Optical diagnostics support               : Yes                                                         
  Laser bias current                        : 0.000 mA                                                    
  Laser output power                        : 0.0000 mW / -inf dBm                                        
  Receiver signal average optical power     : 0.0000 mW / -inf dBm                                        
  Module temperature                        : 29.81 degrees C / 85.66 degrees F                           
  Module voltage                            : 3.3642 V                                                    
  Alarm/warning flags implemented           : Yes                                                         
  Laser bias current high alarm             : Off                                                         
  Laser bias current low alarm              : On                                                          
  Laser bias current high warning           : Off                                                         
  Laser bias current low warning            : On                                                          
  Laser output power high alarm             : Off                                                         
  Laser output power low alarm              : On                                                          
  Laser output power high warning           : Off                                                         
  Laser output power low warning            : On                                                          
  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                  : On                                                          
  Laser rx power high warning               : Off                                                         
  Laser rx power low warning                : On                                                          
  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@bpi-r3:~#

Strange they are different, we ordered from the same vendor, almost at the same time.

Maybe in one of my hacky tries, it got unlocked? Or perhapse it is an eeprom that never is written…

Yours is SK2301110008 mine are SK2301110007 and SK2301110009

Then it may be a fake id in eeprom…

Actually, there is more info to dump…

/*
 *	Description:
 *	a) Optical transceiver EEPROM read/write transactions are just like
 *		the at24 eeproms managed by the at24.c i2c driver
 *	b) The register/memory layout is up to 256 128 byte pages defined by
 *		a "pages valid" register and switched via a "page select"
 *		register as explained in below diagram.
 *	c) 256 bytes are mapped at a time. 'Lower page 00h' is the first 128
 *	        bytes of address space, and always references the same
 *	        location, independent of the page select register.
 *	        All mapped pages are mapped into the upper 128 bytes
 *	        (offset 128-255) of the i2c address.
 *	d) Devices with one I2C address (eg QSFP, CMIS) use I2C address 0x50
 *		(A0h in the spec), and map all pages in the upper 128 bytes
 *		of that address.
 *	e) Devices with two I2C addresses (eg SFP) have 256 bytes of data
 *		at I2C address 0x50, and 256 bytes of data at I2C address
 *		0x51 (A2h in the spec).  Page selection and paged access
 *		only apply to this second I2C address (0x51).
 *	e) The address space is presented, by the driver, as a linear
 *	        address space.  For devices with one I2C client at address
 *	        0x50 (eg QSFP, CMIS), offset 0-127 are in the lower
 *	        half of address 50/A0h/optoe_client.  Offset 128-255 are in
 *	        page 0, 256-383 are page 1, etc.  More generally, offset
 *	        'n' resides in page (n/128)-1.  ('page -1' is the lower
 *	        half, offset 0-127).
 *	f) For devices with two I2C clients at address 0x50 and 0x51 (eg SFP),
 *		the address space places offset 0-127 in the lower
 *	        half of 50/A0/optoe_client, offset 128-255 in the upper
 *	        half.  Offset 256-383 is in the lower half of 51/A2/dummy.
 *	        Offset 384-511 is in page 0, in the upper half of 51/A2/...
 *	        Offset 512-639 is in page 1, in the upper half of 51/A2/...
 *	        Offset 'n' is in page (n/128)-3 (for n > 383)
 *
 *	                    One I2c addressed (eg QSFP, CMIS) Memory Map
 *
 *	                    2-Wire Serial Address: 1010000x
 *
 *	                    Lower Page 00h (128 bytes)
 *	                    =====================
 *	                   |                     |
 *	                   |                     |
 *	                   |                     |
 *	                   |                     |
 *	                   |                     |
 *	                   |                     |
 *	                   |                     |
 *	                   |                     |
 *	                   |                     |
 *	                   |                     |
 *	                   |Page Select Byte(127)|
 *	                    =====================
 *	                              |
 *	                              |
 *	                              V
 *	     ------------------------------------------------------------
 *	    |                 |                  |                       |
 *	    |                 |                  |                       |
 *	    V                 V                  V                       V
 *	 ------------   --------------      ---------------     --------------
 *	|            | |              |    |               |   |              |
 *	|   Upper    | |     Upper    |    |     Upper     |   |    Upper     |
 *	|  Page 00h  | |    Page 01h  |    |    Page 02h   |   |   Page 03h   |
 *	|            | |   (Optional) |    |   (Optional)  |   |  (Optional   |
 *	|            | |              |    |               |   |   for Cable  |
 *	|            | |              |    |               |   |  Assemblies) |
 *	|    ID      | |     AST      |    |      User     |   |              |
 *	|  Fields    | |    Table     |    |   EEPROM Data |   |              |
 *	|            | |              |    |               |   |              |
 *	|            | |              |    |               |   |              |
 *	|            | |              |    |               |   |              |
 *	 ------------   --------------      ---------------     --------------
 *
 * The SFF 8636 (QSFP) spec only defines the 4 pages described above.
 * In anticipation of future applications and devices, this driver
 * supports access to the full architected range, 256 pages.
 *
 * The CMIS (Common Management Interface Specification) defines use of
 * considerably more pages (at least to page 0xAF), which this driver
 * supports.
 *
 * NOTE: This version of the driver ONLY SUPPORTS BANK 0 PAGES on CMIS
 * devices.
 *
 **/

I can’t check now, but we can use ethtool -m eth1 page N hex on to examine more on 0x51

If 0x56 is indeed a rtl8221, then the registers at 0x56 should be (counted in 16 bit words, from rtl8211 datasheet, I cannot find any datasheet of rtl8221)

realtek

Since the id is at 2 and at 14 this could actually make sense, as the sfp was trying to access the phy_id (from MMD). Guess this was the last succesfull communication…

The last 4 bytes of the 64 byte space are to do with page selection. This could explain why @frank-w 's module reads totally different. writing 0x0000 to word 31 (byte offset 62) should set the page to page 0.

So maybe @dangowrt has a datasheet of the RTL8221B-VB-CG that he could maybe share or maybe could not. Maybe see if MAADR register is 4 bytes on RTL8221, which would make sense of the data I see?

I guess my eeprom cannot be read at this adress…maybe it needs to be enabled first? Empty should be 0x00,or i have got one without such phy

I think I flipped the page to page zero in one of my attempts to get things going. Now it is a bit stuck there when I read the address 0x56 Yours is probably on an invalid page.

Anyway, so far:

diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index d855a1830..43c760cfe 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -396,6 +396,16 @@ static void sfp_fixup_rollball_cc(struct sfp *sfp)
        sfp->id.base.extended_cc = SFF8024_ECC_10GBASE_T_SFI;
 }
 
+// For 2.5GBASE-T short-reach modules
+static void sfp_fixup_oem_2_5g(struct sfp *sfp)
+{
+       sfp->mdio_protocol = MDIO_I2C_ROLLBALL;
+       sfp->module_t_wait = msecs_to_jiffies(25 * 1000);
+       sfp->id.base.connector = SFF8024_CONNECTOR_RJ45;
+       sfp->id.base.extended_cc = SFF8024_ECC_2_5GBASE_T;
+
+}
+
 static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
                                unsigned long *modes,
                                unsigned long *interfaces)
@@ -475,7 +485,9 @@ static const struct sfp_quirk sfp_quirks[] = {
        SFP_QUIRK_F("Walsun", "HXSX-ATRI-1", sfp_fixup_fs_10gt),
 
        SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
-       SFP_QUIRK_M("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
+
+       SFP_QUIRK("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g, sfp_fixup_oem_2_5g),
+
        SFP_QUIRK_F("OEM", "RTSFP-10", sfp_fixup_rollball_cc),
        SFP_QUIRK_F("OEM", "RTSFP-10G", sfp_fixup_rollball_cc),
        SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball),

The phy is at 0x51, protocol needs to be rollball, and the rtl8221 at 0x56 is accessed as mmd through the phy device at 0x51.

Now I need to check kernel log and move on to the next problem…

Inserted in SFP1 slot at boot:

[root@bpir3 ~]# dmesg | grep sfp
[    0.663101] sfp sfp-1: Host maximum power 1.0W
[    0.668432] sfp sfp-2: Host maximum power 1.0W
[    1.013634] sfp sfp-1: module OEM              SFP-2.5G-T       rev 1.0  sn SK2301110007     dc 230110  
[root@bpir3 ~]# ip link set eth1 up
[  110.910137] mtk_soc_eth 15100000.ethernet eth1: configuring for inband/2500base-x link mode

[  136.867078] RTL8221B-VB-CG 2.5Gbps PHY: probe of i2c:sfp-1:11 failed with error -95
[  136.874799] mtk_soc_eth 15100000.ethernet eth1: 11111 validation with support 00,00000000,00000000,00000000 failed: -EINVAL
[  136.886040] sfp sfp-1: sfp_add_phy failed: -EINVAL

[  407.112709] sfp sfp-1: module removed

Moved to SFP2 slot:

[  423.803562] sfp sfp-2: module OEM              SFP-2.5G-T       rev 1.0  sn SK2301110007     dc 230110  
[  423.859855] hwmon hwmon0: temp1_input not attached to any thermal zone

[  449.827118] RTL8221B-VB-CG 2.5Gbps PHY: probe of i2c:sfp-2:11 failed with error -95
[  449.834836] mt7530-mdio mdio-bus:1f lan4: 11111 validation with support 00,00000000,00000000,00000000 failed: -EINVAL
[  449.845560] sfp sfp-2: sfp_add_phy failed: -EINVAL

lan4 is managed by systemd-networkd and it sets it link up.

I’ve added 11111 to the validation with support message, to find out which one. It is the one from phylink_sfp_config_phy()

I figure the probe of the device is failing because .probe is not defined for this device.

	}, {
		PHY_ID_MATCH_EXACT(0x001cc849),
		.name           = "RTL8221B-VB-CG 2.5Gbps PHY",
		.get_features   = rtl822x_get_features,
		.config_aneg    = rtl822x_config_aneg,
		.read_status    = rtl822x_read_status,
		.suspend        = genphy_suspend,
		.resume         = rtlgen_resume,
		.read_page      = rtl821x_read_page,
		.write_page     = rtl821x_write_page,
	}, {

I could add:

		.probe		= rtl822x_probe,

and

static int rtl822x_probe(struct phy_device *phydev)
{
	return 0;
}

As I have no clue about the registers.

Then see if this changes anything…

tried to set the page but seems not working (confirms my error-value 0xff)

root@bpi-r3:~# i2cset -y 1 0x56 0x3e 0x0000 w
root@bpi-r3:~# i2cget -y 1 0x56 0x3e
0xff

if interested these are the other 2 i2c-device dumps:

root@bpi-r3:~# i2cdump -y 1 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 07 00 01 00 00 00 00 02 00 05 19 00 00 00    ???.?....?.??...         
10: 1e 14 00 00 4f 45 4d 20 20 20 20 20 20 20 20 20    ??..OEM                  
20: 20 20 20 20 00 00 00 00 53 46 50 2d 32 2e 35 47        ....SFP-2.5G         
30: 2d 54 20 20 20 20 20 20 31 2e 30 20 03 52 00 19    -T      1.0 ?R.?         
40: 00 1a 00 00 53 4b 32 33 30 31 31 31 30 30 31 30    .?..SK2301110010         
50: 20 20 20 20 32 33 30 31 31 30 20 20 68 f0 01 e1        230110  h???         
60: 00 00 11 fd 9b 82 05 cf 1d 67 70 da 2b 1a 48 b0    ..???????gp?+?H?         
70: d8 89 05 00 00 00 00 00 00 00 00 00 ed 86 84 a9    ???.........????         
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    ................
root@bpi-r3:~# i2cdump -y 1 0x51                                                
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: 5f 00 ce 00 5a 00 d3 00 8c a0 75 30 88 b8 79 18    _.?.Z.?.??u0??y?         
10: 1d 4c 01 f4 19 64 03 e8 4d f0 06 30 3d e8 06 f2    ?L???d??M??0=???         
20: 2b d4 00 c7 27 10 00 df 00 00 00 00 00 00 00 00    +?.?'?.?........         
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................         
40: 00 00 00 00 3f 80 00 00 00 00 00 00 01 00 00 00    ....??......?...         
50: 01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 f1    ?...?...?......?         
60: 1b b0 83 98 00 00 00 00 00 00 ff ff ff ff 82 ff    ????..........?.         
70: 05 40 ff ff 05 40 ff ff 00 ff ff ff ff ff ff 00    ?@..?@..........         
80: 43 4e 53 38 54 55 54 41 41 43 33 30 2d 31 34 31    CNS8TUTAAC30-141         
90: 30 2d 30 34 56 30 34 20 49 fb 46 00 00 00 00 29    0-04V04 I?F....)         
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 aa aa    ..............??         
c0: 47 4c 43 2d 54 20 20 20 20 20 20 20 20 20 20 20    GLC-T                    
d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 97                   ?         
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 40 00 40 00 00 00 00    .........@.@....

I do not know exactly why mine is at page 0 and yours is not.

Anyway, the PHY in the module is a small microprocessor addressed at 0x50 and 0x51. It uses the rollbal protocol. It talks to whatever MMC hardware is on the bus and does all the magic.

You need to set protocol to rollball anyway, regardless of which chip is at 0x56.Setting protocol to rollball makes the mdio-i2c talk to address 0x51.Findng the phy_id number will go through this address. It will identify what is at 0x56.

/* SFP modules appear to always have their PHY configured for bus address
 * 0x56 (which with mdio-i2c, translates to a PHY address of 22).
 * RollBall SFPs access phy via SFP Enhanced Digital Diagnostic Interface
 * via address 0x51 (mdio-i2c will use RollBall protocol on this address).
 */
#define SFP_PHY_ADDR		22
#define SFP_PHY_ADDR_ROLLBALL	17
	switch (sfp->mdio_protocol) {
	case MDIO_I2C_NONE:
		break;

	case MDIO_I2C_MARVELL_C22:
		err = sfp_sm_probe_phy(sfp, SFP_PHY_ADDR, false);
		break;

	case MDIO_I2C_C45:
		err = sfp_sm_probe_phy(sfp, SFP_PHY_ADDR, true);
		break;

	case MDIO_I2C_ROLLBALL:
		err = sfp_sm_probe_phy(sfp, SFP_PHY_ADDR_ROLLBALL, true);
		break;

So apply the patch from post #18 on netdev/net-next.

You will then see:

[  449.827118] RTL8221B-VB-CG 2.5Gbps PHY: probe of i2c:sfp-2:11 failed with error -95

The chip is identified. Or see some information about another chip if yours is different. It takes 25 seconds after eth1/lan4 link is brought up.

PS: I still have not found any datasheet, but I have found realtek code of rtl8226, it was later renamed to rtl8221.:

xdr608x-rtl8221-fix/drivers/net/ethernet/mediatek/rtl822x/nic_rtl8226b.c at xdr608x-rtl8221-fix · ericwoud/xdr608x-rtl8221-fix · GitHub

Edit:

OpenWrt has interesting code here:

git.openwrt.org Git - openwrt/openwrt.git/blob - target/linux/realtek/files-5.4/drivers/net/phy/rtl83xx-phy.c

And here:

openwrt/target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.c at main · openwrt/openwrt · GitHub

Maybe can use rtl8226_get_eee() and rtl8226_set_eee() from this code…

Edit 2:

Here are the most recent rtl822x patches, starting from 721

openwrt/target/linux/generic/pending-6.1 at main · openwrt/openwrt · GitHub

On non SFP system it looks like this:

image

And the SOC is the STA.

But on our SFP module only MAC1, the STA is at 0x51 (17). We are also on the same mdio-bus with an i2c adapter and talk to the STA with rollball protocol. (but we can snoop around the entire bus)

In our case, we have only 1 MMD at 0x56 (22).

With this construction, the SFP module can function on many systems as the hardware is set up independantly.

Before the patch at post #18, sfp->mdio_protocol = MDIO_I2C_NONE and there is no further communication done over mdio-i2c bridge. The MMD is setup by the STA at 0x51 and the MAC is setup with fixed values.

Also reading the phy_id of the MMD goes through the STA at 0x51, this got me confused at first. In fact, all communication to the MMD should go this way. The protocol of the mdio-i2c bridge is set to rollball and the only device that speaks it is the STA at 0x51.

Adding:

		.probe		= rtl822x_probe,

Did not help, but comparing:

	}, {
		PHY_ID_MATCH_EXACT(0x001cc840),
		.name		= "RTL8226B_RTL8221B 2.5Gbps PHY",
		.get_features	= rtl822x_get_features,
		.config_aneg	= rtl822x_config_aneg,
		.read_status	= rtl822x_read_status,
		.suspend	= genphy_suspend,
		.resume		= rtlgen_resume,
		.read_page	= rtl821x_read_page,
		.write_page	= rtl821x_write_page,
		.read_mmd	= rtl822x_read_mmd,
		.write_mmd	= rtl822x_write_mmd,
	}, {

With:

	}, {
		PHY_ID_MATCH_EXACT(0x001cc849),
		.name           = "RTL8221B-VB-CG 2.5Gbps PHY",
		.get_features   = rtl822x_get_features,
		.config_aneg    = rtl822x_config_aneg,
		.read_status    = rtl822x_read_status,
		.suspend        = genphy_suspend,
		.resume         = rtlgen_resume,
		.read_page      = rtl821x_read_page,
		.write_page     = rtl821x_write_page,
	}, {

And considering:

int __phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
{
	int val;

	if (regnum > (u16)~0 || devad > 32)
		return -EINVAL;

	if (phydev->drv && phydev->drv->read_mmd) {
		val = phydev->drv->read_mmd(phydev, devad, regnum);
	} else if (phydev->is_c45) {
		val = __mdiobus_c45_read(phydev->mdio.bus, phydev->mdio.addr,
					 devad, regnum);
	} else {
		struct mii_bus *bus = phydev->mdio.bus;
		int phy_addr = phydev->mdio.addr;

		mmd_phy_indirect(bus, phy_addr, devad, regnum);

		/* Read the content of the MMD's selected register */
		val = __mdiobus_read(bus, phy_addr, MII_MMD_DATA);
	}
	return val;
}
EXPORT_SYMBOL(__phy_read_mmd);

The else if and else paths both have -EOPNOTSUPP (-95) as error value.

So it would seem that we are missing:

		.read_mmd	= rtl822x_read_mmd,
		.write_mmd	= rtl822x_write_mmd,

So I’ll try that next time…

Edit:

Nope, that did not fix it either… But I did find it: The realtek driver uses __phy_read().

__phy_read() points to __mdiobus_read(), which checks bus->read. If bus->read == NULL it returns -EOPNOTSUPP.

But on a bus with rollball protocol, only bus->read_c45 is a valid pointer and bus->read = NULL.

Guess this is the first time the realtek phy driver is used together with rollball protocol.

I have asked Russell how this should be fixed… See what he says.

Edit 2:

If I look at the code… I think the realtek.c phy driver needs to use phy_read_mmd() at least for the rtl822x family. This is the same as the aquantia and marvell driver.

So I’ve set up the realtek driver as a generic C45 device like so:

}, {
	PHY_ID_MATCH_EXACT(0x001cc849),
	.name           = "RTL8221B-VB-CG 2.5Gbps PHY",
	.get_features   = genphy_c45_pma_read_abilities,
	.config_aneg    = genphy_c45_config_aneg,
	.read_status    = genphy_c45_read_status,
	.suspend        = genphy_c45_pma_suspend,
	.resume         = genphy_c45_pma_resume,
}, {

I get everything set up nicely, no errors in the kernel log. Almost everything seems to work also at first glance. The usb rtl8156 on the other side of the copper even says that it has link up. I can read speed advertisements, also of link partner. I can connect at 2500 and at 100, and even see this speed also on the SFP. But somehow it does not report link up… That still needs some work.

1 Like

Do you see the phy-id on i2c address 0x51 too? As my 0x56 is inaccessable and rollball uses 0x51 it maybe works with my sfp too

Can really forget what you see in i2c, except for i2cdetect -y 0

Yours is for sure also a rtl8221 and yes it will work the same on yours too.

For now, need to find out why it does not report link up, for the rest it looks ok for now.

I have temporarily:

static int rtl822x_config_aneg(struct phy_device *phydev)
{
	return 0;
 // Could later add a condition on the presence of SFP and/or autoneg.
}
.......
}, {
	PHY_ID_MATCH_EXACT(0x001cc849),
	.name           = "RTL8221B-VB-CG 2.5Gbps PHY",
	.get_features   = genphy_c45_pma_read_abilities,
	.config_aneg    = rtl822x_config_aneg,
	.read_status    = genphy_c45_read_status,
	.suspend        = genphy_c45_pma_suspend,
	.resume         = genphy_c45_pma_resume,
}, {

So in fact, we are using the rtl driver only for reading

  • get_features()
  • read_status()

(If not looking at the suspend and resume.)

First find out about the link detection…