Motorcomm YT8821 on SFP module

So I have received also a SFP module with the YT8821. However it is recognized with a different Vendor PN string:

Vendor name                               : OEM
Vendor PN                                 : 2.5G-T-Y-RM

So the vendor is messing with the Vendor PN strings, using different values.

It would seem that it is only sometimes the same as other vendor and other hardware.

The one from @jcdutton has the same identification as the rtl8221b via rollball sfp.

Back to the YT8821 module:

The rollball protocol does not work on this module.

The phy is accessible at 0x56, and indeed uses a different register numbering then Marvell C22. Needs << 1.

But it seems that the phy is not write accessible.

It may need a password or another unlocking mechanism, similar to rollball protocol password.

@ericwoud Regarding the write accessibility.

If you do “ifconfig sfp1 up” ← where sfp1 is the sfp interface.

The 0x56 is then accessible.

I posted some source code for the yt8821 to another thread if you are interested.

The accessibility of the 0x56 is not dependent on the yt8821 source code.

Something that “ifconfig sfp1 up” does makes the 0x56 accessible.

Yes it is accessible, but not for writing.

Even register 4 (at byte 8 and 9), which controls the advertisements, no bit can be changed.

@ericwoud Regarding accessible for writing. I see what you mean.

This might also explain why I was finding it hard to do C45 over C22 (reg 0xd, 0xe, byte offset 0x1a, 0x1c).

I will look into how to make it writable.

Unfortunately, there is no register level documentation for the YT8821 that I could find.

The YT8821 uses (reg 0x1e, 0x1f, byte offset 0x3c, 0x3e) to access its internal registers. Some 65535 of them!

Hi. Thinking about this. The YT8821 datasheet says it supports C22 and C45, but if 0x56 is read only, it makes no sense at all. Making C22 read only, makes C45 over C22 fail to work also. I have also tested C45 over I2C with the YT8821 and the YT8821 does not detect the requests as C45, and interprets them as C22. ROLLBALL also does not work with the YT8821 as far as my testing has shown (my testing could be flawed). I don’t have a PHY that is know to work with ROLLBALL to compare against.

It is the i2c to mdio bridge that blocks the write.

On the BPI-R3 we are bit banging the I2C. What if we changed the DTS to say it was an MDIO GPIO instead, and tried to bit bang MDIO instead of I2C ? Has anyone tried that?

The module has an accompanying ic that does i2c to mdio translation towards the phy. Probably this same ic also implements the function of the i2c eeprom.

Is the rollball protocol documented?

 * address  size  contents  description
 * -------  ----  --------  -----------
 * 0x80     1     CMD       0x01/0x02/0x04 for write/read/done
 * 0x81     1     DEV       Clause 45 device
 * 0x82     2     REG       Clause 45 register
 * 0x84     2     VAL       Register value
For a read transaction, do you:
write devad to 0x81
write reg to 0x82/0x83
write ROLLBALL_CMD_READ(2) to 0x80.
poll read 0x80  until you read ROLLBALL_CMD_DONE(4) 
read value from 0x84/0x85

The question then becomes how many of the above can be combined into a single i2c_transfer?
If you have multple msg in a transfer, the I2C has a choice to do S at the start, and Sr between msg,  or R/S between msg.
My guess is that you write devad and reg in one transfer.
write ROLLBALL_CMD_READ in another transfer. (if you combine devad, reg and ROLLBALL_CMD_READ in a single transfer, can it be in a single msg, or need to be two msg in the transfer?
the poll read in another transfer.

Just playing with page 3 a bit. Password of ffffffff changes the behaviour of page 3.

  1. with pass, page 3 is writable like eeprom
  2. any write to 0x80 or 0x81 gets echoed back in 0x81
  3. most of 0x82 onwards just acts like an eeprom. (except that a power cycle forgets it)
  4. reading from 0x80 onwards reveals different output than reading 256 from 0x0
  5. if you change the pass regs to anything other than ffffffff, the next read starting at 0x80 onwards, reads from 0x02 onwards.

So there is something there that behaves differently with ffffffff, just Don’t know what.

I noticed the same, only happens when rollball password filled in.

0x56 registers do change, as the cable link negotiates to different speeds, the appropriate MII registers change. But, 0x56 is fixed at being read only from the CPU I2C side, and thus prevent C45 over C22 MMD access and also prevents YT8821 vendor specific access over MII 0x1E,0x1F regs.

Hi,

I have found something new.

set page to 3.

i2cdump -y 2 0x51 i
     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: 0d 87 82 41 0b b8 13 88 0f a0 ff ff ff ff 80 ff    ???A??????....?.
70: 00 00 ff ff 00 00 ff ff 01 ff ff 63 73 77 77 03    ........?..csww?
80: 00 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
90: ff ff 00 00 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 06 00 63 73 77 77    ..........?.csww

Do you see the 63 73 77 77 csww ?

That is the manufacturer key. I lets you change anything on 0x50 and 0x51, names etc.

But even that does not seem to have made 0x56 writable. :frowning:

Great find! That will help limiting the number of quirks/fixups needed for all the diffferent OEM Vendor PN strings of the RollBall modules The password is the same on the other ‘known.to be rollball’ modules.

What is the difference between a working r/w sfp 0x56 and a readonly sfp? Can you post while on page 3

i2cdump -y 2 0x51 i

I wish to see if there are any differences on page 3 between say a yt8821 and the realtek one.

Is there any way to find the make/model of the bridge chip? I cannot open my sfp for fear of damaging it.

Is 0x56 read only on the realtek sfps? Thus requiring rollball?

I can post it here later.

Yes.

It may be exactly the same mcu, but only a few different settings (on page 3?)

The driver of the YT8821 however uses only C22 commands. So my guess here is that the sfp-module-mcu does the same. This is probably why rollball does not work (as expected), as it is C45 only.

The mcu itself, probably is a general md32 or similar mcu, but we barely know what it’s programmed to do.

So we can use this to permanently modify module’s connector type info?

I am working on a tool to use on sfp modules via i2c. You can tryout all different protocols directly from commandline. I will add extracting the password and setting the vendor info to this tool. This will make it easier to change only that and minimize the chances of making an error.

It is compiled statically, so you can run it from anywhere.

I expect to have it online within a week or so.

@ericwoud

I have written similar tools but not quite ready for upload. I try out C22, C45, C45overC22, ROLLBALL from a userland app, as its easier to discover stuff that way, rather than rebuilding linux kernels. I have not looked into how to do i2c bus lock from userland yet. Is there a IOCTL for that, that automatically unlocks on device close? I also have written a SFP password scanning tool and was doing that in the hope it might help with 0x56 write access. Fortunately, I found the “csww” password just looking at me from the bottom of 0x51 page 3, so that saved me a few days scanning.

Me too, brute force attack is in the tool. But I was running 0x0 to 0xff, where I should have limited to readable characters, then I would have found it already.

The tool is practically finished, but I just try it out first thoroughly, before setting the repo public.

The functions so far are:

Usage: i2csfp I2CBUS command ...
   I2CBUS is i2c bus device name (/dev/i2c-x)
 Command one of:
   eeprom
   byte
   c22m       Clause 22 MARVELL
   c22r       Clause 22 ROLLBALL at 0x56 (read-only?)
   c45        Clause 45
   rollball   Rollball protocol (Clause 45)
   rollball22 Rollball protocol (Clause 22) NOT FUNCTIONAL!!!
   rbpassword Extract Rollball eeprom password
   bruteforce
 i2csfp I2CBUS eeprom [-p PASSWORD] [-e EXTCC] [-v VDNAME] [-n VDPN]
   -p PASSWORD specify password, without this option uses rbpassword
   -V VDNAME specify vendor name
   -N VDPN specify vendor pn
   -E EXTCC specify extended cc
 i2csfp I2CBUS byte read|write [-v] BUS-ADDRESS REGISTER [VALUE]
   -v verify write
   BUS-ADDRESS is an integer 0x00 - 0x7f
   REGISTER is an integer 0x00 - 0x7f
   VALUE is an integer 0x00 - 0xff
 i2csfp I2CBUS c22m read|write BUS-ADDRESS REGISTER [VALUE]
   BUS-ADDRESS is an integer 0x00 - 0x7f
   REGISTER is an integer 0x00 - 0x1f
   VALUE is an integer 0x00 - 0xffff
 i2csfp I2CBUS c22r read|write BUS-ADDRESS REGISTER [VALUE]
   BUS-ADDRESS is an integer 0x00 - 0x7f
   REGISTER is an integer 0x00 - 0x1f
   VALUE is an integer 0x00 - 0xffff
 i2csfp I2CBUS c45 read|write BUS-ADDRESS DEVAD REGISTER [VALUE]
   BUS-ADDRESS is an integer 0x00 - 0x7f
   DEVAD is an integer 0x00 - 0x1f
   REGISTER is an integer 0x00 - 0xffff
   VALUE is an integer 0x00 - 0xffff
 i2csfp I2CBUS rollball read|write DEVAD REGISTER [VALUE]
   DEVAD is an integer 0x00 - 0x1f
   REGISTER is an integer 0x00 - 0xffff
   VALUE is an integer 0x00 - 0xffff
 i2csfp I2CBUS rbpassword
 i2csfp I2CBUS bruteforce [-p]	[MIN] [MAX]
   Runs brute force attack on sfp module
   -p specify password to start with (last 2 bytes zeroed)
   -E specify which attack: 1 (09x50) or 2 (0x56), default 1
   MIN is the first byte to try 0x00 - 0xff, default 0x00
   MAX is the last  byte to try 0x00 - 0xff, default 0xff