Support for RTL838x based managed switches

Thanks for the pointer. I was using the script in package/rtl83xx-poe/files/bin/poe.lua and had not noticed those files in the target.

I took everything from the poe_zyxel.lua script and added to bin/poe.lua with a couple of minor fixups (this code was obviously not tested :wink: You can see the result here:

But still no go, unfortunately. Init, enabling port 3, and calling info:

root@OpenWrt:/# /tmp/poe.lua 
OK, port open with values 'device: /dev/ttyS1, baud: 19200, data bits: 8, parity: none, stop bits: 1, flow control: off'
Getting status
send   20 01 ff ff ff ff ff ff ff ff ff 18
recv   20 01 02 08 01 e1 21 16 00 05 04 4d
 01 e1 21 05
Getting status
send   20 02 ff ff ff ff ff ff ff ff ff 19
recv   20 02 02 08 01 e1 21 16 00 05 04 4e
 01 e1 21 05
send   07 03 02 ff ff ff ff ff ff ff ff 04
recv   07 03 00 ff ff ff ff ff ff ff ff 02
send   17 04 02 ff ff ff ff ff ff ff ff 15
recv   17 04 00 ff ff ff ff ff ff ff ff 13
send   2b 05 ff ff ff ff ff ff ff ff ff 27
recv   2b 05 aa 01 00 00 00 01 01 ff 00 dc
send   0b 06 00 00 00 ff ff ff ff ff ff 0b
recv   0b 06 00 ff ff ff ff ff ff ff ff 09
send   0a 07 aa 00 01 ff ff ff ff ff ff b6
recv   0a 07 00 ff ff ff ff ff ff ff ff 09
send   41 08 01 00 00 02 00 00 00 41 ff 8c
recv   41 08 00 ff ff ff ff ff ff ff ff 41
send   18 09 00 03 02 00 00 ff ff ff ff 22
recv   18 09 00 00 ff ff ff ff ff ff ff 1a
send   18 0a 01 03 02 00 00 ff ff ff ff 24
recv   18 0a 01 00 ff ff ff ff ff ff ff 1c
send   18 0b 02 03 02 00 00 ff ff ff ff 26
recv   18 0b 02 00 ff ff ff ff ff ff ff 1e
send   18 0c 03 03 02 00 00 ff ff ff ff 28
recv   18 0c 03 00 ff ff ff ff ff ff ff 20
send   18 0d 04 03 02 00 00 ff ff ff ff 2a
recv   18 0d 04 00 ff ff ff ff ff ff ff 22
send   18 0e 05 03 02 00 00 ff ff ff ff 2c
recv   18 0e 05 00 ff ff ff ff ff ff ff 24
send   18 0f 06 03 02 00 00 ff ff ff ff 2e
recv   18 0f 06 00 ff ff ff ff ff ff ff 26
send   18 10 07 03 02 00 00 ff ff ff ff 30
recv   18 10 07 00 ff ff ff ff ff ff ff 28
send   1d 11 03 03 00 00 01 01 02 02 ff 39
recv   1d 11 03 00 00 00 01 00 02 00 ff 33
send   1c 12 03 03 00 03 01 03 02 03 ff 3f
recv   1c 12 03 00 00 00 01 00 02 00 ff 33
send   15 13 03 01 00 01 01 01 02 01 ff 31
recv   15 13 03 00 00 00 01 00 02 00 ff 2d
send   1d 14 07 07 04 04 05 05 06 06 ff 5c
recv   1d 14 07 00 04 00 05 00 06 00 ff 46
send   1c 15 07 03 04 03 05 03 06 03 ff 52
recv   1c 15 07 00 04 00 05 00 06 00 ff 46
send   15 16 07 01 04 01 05 01 06 01 ff 44
recv   15 16 07 00 04 00 05 00 06 00 ff 40
send   02 17 01 ff ff ff ff ff ff ff ff 12
recv   02 17 00 ff ff ff ff ff ff ff ff 11
send   27 18 00 ff ff ff ff ff ff ff ff 37
recv   27 18 02 00 00 00 00 00 00 00 00 41
send   28 19 00 01 01 01 02 01 03 01 ff 4a
recv   28 19 00 00 01 00 02 00 03 00 ff 46
send   28 1a 04 01 05 01 06 01 07 01 ff 4a
send   22 1b 00 00 ff ff ff ff ff ff ff 36
recv   22 1b 00 00 00 00 00 00 ff ff ff 3a
send   22 1c 00 01 ff ff ff ff ff ff ff 38
recv   22 1c 00 00 00 00 00 00 ff ff ff 3b
send   22 1d 00 02 ff ff ff ff ff ff ff 3a
recv   22 1d 00 00 00 00 00 00 ff ff ff 3c
send   22 1e 00 03 ff ff ff ff ff ff ff 3c
recv   22 1e 00 00 00 00 00 00 ff ff ff 3d
send   22 1f 00 04 ff ff ff ff ff ff ff 3e
recv   22 1f 00 00 00 00 00 00 ff ff ff 3e
send   22 20 00 05 ff ff ff ff ff ff ff 40
recv   22 20 00 00 00 00 00 00 ff ff ff 3f
send   22 21 00 06 ff ff ff ff ff ff ff 42
recv   22 21 00 00 00 00 00 00 ff ff ff 40
send   22 22 00 07 ff ff ff ff ff ff ff 44
recv   22 22 00 00 00 00 00 00 ff ff ff 41
send   17 23 01 ff ff ff ff ff ff ff ff 33
recv   17 23 00 ff ff ff ff ff ff ff ff 32
send   0b 24 01 00 00 ff ff ff ff ff ff 2a
recv   0b 24 00 ff ff ff ff ff ff ff ff 27
send   1c 25 00 00 01 00 02 00 03 00 ff 46
recv   1c 25 00 00 01 00 02 00 03 00 ff 46
send   1c 26 04 00 05 00 06 00 07 00 ff 46
send   1a 27 00 00 01 00 02 00 03 00 ff 46
recv   1a 27 00 00 01 00 02 00 03 00 ff 46
send   1a 28 04 00 05 00 06 00 07 00 ff 46
send   15 29 00 01 01 01 02 01 03 01 ff 47
recv   15 29 00 00 01 00 02 00 03 00 ff 43
send   15 2a 04 01 05 01 06 01 07 01 ff 47
send   16 2b 00 9c 01 9c 02 9c 03 9c ff b6
recv   16 2b 00 00 01 00 02 00 03 00 ff 46
send   16 2c 04 9c 05 9c 06 9c 07 9c ff b6
send   25 2d 00 ff ff ff ff ff ff ff ff 4a
recv   25 2d 00 01 00 02 01 02 00 ff ff 56
send   00 2e 00 00 ff ff ff ff ff ff ff 27
recv   00 2e 00 00 ff ff ff ff ff ff ff 27
send   03 2f 00 01 ff ff ff ff ff ff ff 2c
recv   03 2f 00 00 ff ff ff ff ff ff ff 2b
send   25 30 00 ff ff ff ff ff ff ff ff 4d
recv   25 30 00 00 00 02 01 02 00 ff ff 58
send   00 31 01 00 ff ff ff ff ff ff ff 2b
recv   00 31 01 00 ff ff ff ff ff ff ff 2b
send   03 32 01 01 ff ff ff ff ff ff ff 30
recv   03 32 01 00 ff ff ff ff ff ff ff 2f
send   25 33 01 ff ff ff ff ff ff ff ff 51
recv   25 33 01 00 00 02 01 02 00 ff ff 5c
send   00 34 02 00 ff ff ff ff ff ff ff 2f
recv   00 34 02 00 ff ff ff ff ff ff ff 2f
send   03 35 02 01 ff ff ff ff ff ff ff 34
recv   03 35 02 00 ff ff ff ff ff ff ff 33
send   25 36 02 ff ff ff ff ff ff ff ff 55
recv   25 36 02 00 00 02 01 02 00 ff ff 60
send   00 37 03 00 ff ff ff ff ff ff ff 33
recv   00 37 03 00 ff ff ff ff ff ff ff 33
send   03 38 03 01 ff ff ff ff ff ff ff 38
recv   03 38 03 00 ff ff ff ff ff ff ff 37
send   25 39 03 ff ff ff ff ff ff ff ff 59
recv   25 39 03 00 00 02 01 02 00 ff ff 64
send   00 3a 04 00 ff ff ff ff ff ff ff 37
recv   00 3a 04 00 ff ff ff ff ff ff ff 37
send   03 3b 04 01 ff ff ff ff ff ff ff 3c
recv   03 3b 04 00 ff ff ff ff ff ff ff 3b
send   25 3c 04 ff ff ff ff ff ff ff ff 5d
recv   25 3c 04 00 00 02 01 02 00 ff ff 68
send   00 3d 05 00 ff ff ff ff ff ff ff 3b
recv   00 3d 05 00 ff ff ff ff ff ff ff 3b
send   03 3e 05 01 ff ff ff ff ff ff ff 40
recv   03 3e 05 00 ff ff ff ff ff ff ff 3f
send   25 3f 05 ff ff ff ff ff ff ff ff 61
recv   25 3f 05 00 00 02 01 02 00 ff ff 6c
send   00 40 06 00 ff ff ff ff ff ff ff 3f
recv   00 40 06 00 ff ff ff ff ff ff ff 3f
send   03 41 06 01 ff ff ff ff ff ff ff 44
recv   03 41 06 00 ff ff ff ff ff ff ff 43
send   25 42 06 ff ff ff ff ff ff ff ff 65
recv   25 42 06 00 00 02 01 02 00 ff ff 70
send   00 43 07 00 ff ff ff ff ff ff ff 43
recv   00 43 07 00 ff ff ff ff ff ff ff 43
send   03 44 07 01 ff ff ff ff ff ff ff 48
recv   03 44 07 00 ff ff ff ff ff ff ff 47
send   25 45 07 ff ff ff ff ff ff ff ff 69
recv   25 45 07 00 00 02 01 02 00 ff ff 74
send   10 46 7f 02 ff ff ff ff ff ff ff d0
recv   10 46 7f 00 ff ff ff ff ff ff ff ce
send   2b 47 ff ff ff ff ff ff ff ff ff 69
recv   2b 47 aa 01 00 00 00 01 01 ff 00 1e
send   0b 48 00 00 00 ff ff ff ff ff ff 4d
recv   0b 48 00 ff ff ff ff ff ff ff ff 4b
send   2b 49 ff ff ff ff ff ff ff ff ff 6b
recv   2b 49 aa 00 00 00 00 01 01 ff 00 1f
send   0b 4a 01 00 00 ff ff ff ff ff ff 50
recv   0b 4a 00 ff ff ff ff ff ff ff ff 4d
send   00 4b 00 01 ff ff ff ff ff ff ff 45
recv   00 4b 00 00 ff ff ff ff ff ff ff 44
send   03 4c 00 01 ff ff ff ff ff ff ff 49
recv   03 4c 00 00 ff ff ff ff ff ff ff 48
send   00 4d 01 01 ff ff ff ff ff ff ff 48
recv   00 4d 01 00 ff ff ff ff ff ff ff 47
send   03 4e 01 01 ff ff ff ff ff ff ff 4c
recv   03 4e 01 00 ff ff ff ff ff ff ff 4b
send   00 4f 02 01 ff ff ff ff ff ff ff 4b
recv   00 4f 02 00 ff ff ff ff ff ff ff 4a
send   03 50 02 01 ff ff ff ff ff ff ff 4f
recv   03 50 02 00 ff ff ff ff ff ff ff 4e
send   00 51 03 01 ff ff ff ff ff ff ff 4e
recv   00 51 03 00 ff ff ff ff ff ff ff 4d
send   03 52 03 01 ff ff ff ff ff ff ff 52
recv   03 52 03 00 ff ff ff ff ff ff ff 51
send   00 53 04 01 ff ff ff ff ff ff ff 51
recv   00 53 04 00 ff ff ff ff ff ff ff 50
send   03 54 04 01 ff ff ff ff ff ff ff 55
recv   03 54 04 00 ff ff ff ff ff ff ff 54
send   00 55 05 01 ff ff ff ff ff ff ff 54
recv   00 55 05 00 ff ff ff ff ff ff ff 53
send   03 56 05 01 ff ff ff ff ff ff ff 58
recv   03 56 05 00 ff ff ff ff ff ff ff 57
send   00 57 06 01 ff ff ff ff ff ff ff 57
recv   00 57 06 00 ff ff ff ff ff ff ff 56
send   03 58 06 01 ff ff ff ff ff ff ff 5b
recv   03 58 06 00 ff ff ff ff ff ff ff 5a
send   00 59 07 01 ff ff ff ff ff ff ff 5a
recv   00 59 07 00 ff ff ff ff ff ff ff 59
send   03 5a 07 01 ff ff ff ff ff ff ff 5e
recv   03 5a 07 00 ff ff ff ff ff ff ff 5d

root@OpenWrt:~# ubus -v call poe port '{"enable":true,"port":3}'
{

}

send   00 5b 02 01 ff ff ff ff ff ff ff 57
recv   00 5b 02 00 ff ff ff ff ff ff ff 56

root@OpenWrt:~# ubus -v call poe info
{
        "ports": [

        ],
        "power_budget": "65W",
        "power_consumption": "0W"
}

send   23 5c ff ff ff ff ff ff ff ff ff 76
recv   23 5c 00 00 03 02 07 02 ff ff 00 8b
send   2a 5d 00 ff ff ff ff ff ff ff ff 7f
recv   2a 5d 00 00 00 00 00 00 00 00 00 87

Oh, yes, and I changed the sequence number thing to increase for every command. Wondered if the reuse could confuse the firmware, and it certainly confused me.

But still no power on port 3. Which has a RPi4 with the PoE hat connected for this test. Known to be working with another PoE switch, and also working fine with the OEM firmware on the GS1900-10HP. So there is still some magic piece missing here.

I'm currently looking at the implementation in D-Link firmwares, which also has a global port enable (command 06). I'll update the wiki later, but you could try inserting this command in the PoE initialisation:

06  sq  01 ff ff  ff ff ff  ff ff ff  ck

Thanks. I've now tried the 06 sq 01 command as well as lots of random other changes. Still no success. I have concluded that there is no point to continue without some idea on exactly what goes wrong. I need to look at what the ZyXEL firmware does differently.

Unfortunately, I am not equipped (or qualified :slight_smile: ) to peek at two pins 0.5 mm apart on an QFP48 package, so I have ruled out snooping on the microcontroller. Has anyone else done this? And if so, are the raw traces available anywhere? I guess it's easy to miss a detail or two when analyzing, and I can offer an extra pair of eyes looking at it.

Another option is getting the OEM source. I have sent a request to ZyXEL, who in my experience are among the best wrt following their GPL obligations. So I do expect to get the sources in a few days. But I also expect the PoE application and similar stuff to have a closed license, and only be provided as binaries (which I consider a pity, but within their full rights). Still, this will with some luck provide the means to rebuild the OEM image with a few tweaks. If I can get an old enough toolchain running. That's usuatlly the biggest problem there.

Then there is the possibility of modifying the OEM binary image I already have. I guess it should be possible to gain a normal root shell there, and maybe even install a serial snooping tool? Of course, there is again the big question of whether this is within my capabilities, but I can give it a try.

Or maybe just lean back and wait for someone else to figure this out :slight_smile: While I do something else. So I started looking at the SFP slots. They have worked just fine for my limited testing so far. But it would be nice to have access to the "eeprom", and in particular do the DOM readings. Example from the OEM firmware with a SFP with DOM support and no connection in port 10:

GS1900# sh  fiber-transceiver interfaces 9-10
 Port   | Temperature  | Voltage     | Current      | Output power | Input power | OE-Present | LOS 
        | [C]          | [Volt]      | [mA]         | [mWatt]      | [mWatt]     |            |     
===================================================================================================
    9   |  N/S         |  N/S        |  N/S         |  N/S         |  N/S        | Remove  | Loss 
   10   | 40.41  (OK)  | 3.29  (OK)  | 4.19   (OK)  | 0.26  (OK)   | 0.00  (E)   | Insert     | Loss 

In my naïvity, I imagined that I should simply be able to dump something from the i2c buses already defined in the DTS. But that was also a nogo:

root@OpenWrt:/# i2cdetect -l
i2c-1   i2c             i2c-gpio-1                              I2C adapter
i2c-0   i2c             i2c-gpio-0                              I2C adapter
root@OpenWrt:/# i2cdetect 1
i2cdetect: WARNING! This program can confuse your I2C bus
Continue? [y/N] y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
root@OpenWrt:/# i2cdump 1 0x50
i2cdump: WARNING! This program can confuse your I2C bus
Continue? [y/N] y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
10: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
20: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
30: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
40: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
50: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
60: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
70: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
80: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
90: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
a0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
b0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
c0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
d0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
e0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
f0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX

So I am missing something here as well, and starting to wonder it this is really for me at all...

The pin definitions in the DTS seem to match the board configuration the OEM firmware nicely presents in "show tech-support" output:

====== Fiber =================
Fiber Port Number: 2

------------ Fiber Detect
LPort  Present  MediaChg  OE Status              LOS Status
------ -------- --------- ---------------------- ----------------------
8      OE       OE        Enabled  (GPIO:EXT_26) Enabled  (GPIO:EXT_27)
9      OE       OE        Enabled  (GPIO:EXT_32) Enabled  (GPIO:EXT_33)

------------ Fiber Optical
LPort  SMI DEV  SMI TYPE  ID    Delay   SCK    SDA
------ -------- --------- ----- ------- ------ ------
8      SFP1     8 BITS    0x50  4000    EXT_25 EXT_24
9      SFP2     8 BITS    0x50  4000    EXT_31 EXT_30

------------ Fiber TX Disable
LPort  GPIO
------ ------
8      EXT_23
9      EXT_29

Is this just me not understanding something basic again?

It seems that you are trying to get stuff from 0x50 which is a dedicated SFP basic page.
You can only see it when there is an SFP module inserted, if there is an advanced page with DOM you will also see 0x51.

You can see that they have 2 I2C buses as you need one per SFP or to use a switch.

Yes, there is one bus defined per SFP slot, but as you can see from the i2cdetect there is nothing showing up on any adress. Nothing on either 0x50 or 0x51.

SUCCESS with PoE!!! Finally.

I took the nice GPIO map presented by the OEM firmware and exported every one of them in OpenWrt, setting the correct direction and going through the values one by one.

------------------ Board Configuration ------------------

****************************
 GS1900-10HP
****************************
============================
 Board GPIO
============================
Device  Pin  Direction  Default  Current
------- ---- ---------- -------- --------
INT     0    OUT        0        0       
INT     1    OUT        1        1       
INT     2    OUT        0        0       
INT     3    OUT        0        0       
INT     8    OUT        1        1       
INT     9    OUT        1        1       
INT     12   IN         0        0       
INT     13   OUT        1        1       
INT     14   OUT        1        1       
INT     15   OUT        1        1       
INT     16   IN         0        0       
INT     17   OUT        1        1       
INT     18   OUT        0        0       
INT     19   IN         0        0       
INT     20   OUT        1        1       
INT     21   IN         0        0       
INT     22   IN         0        0       
INT     23   OUT        1        1       
EXT     0    IN  (IN  ) 0        1       
EXT     1    IN  (IN  ) 0        0       
EXT     2    IN  (IN  ) 0        0       
EXT     3    IN  (IN  ) 0        1       
EXT     4    IN  (IN  ) 0        1       
EXT     5    OUT (OUT ) 1        1       
EXT     6    OUT (OUT ) 1        1       
EXT     7    IN  (IN  ) 0        1       
EXT     8    OUT (OUT ) 1        1       
EXT     13   OUT (OUT ) 0        1       
EXT     14   OUT (OUT ) 0        0       
EXT     15   OUT (OUT ) 0        0       
EXT     16   OUT (OUT ) 0        0       
EXT     17   OUT (OUT ) 0        0       
EXT     18   OUT (OUT ) 0        0       
EXT     21   IN  (IN  ) 0        0       
EXT     22   IN  (IN  ) 0        1       
EXT     23   OUT (OUT ) 0        0       
EXT     24   OUT (OUT ) 0        1       
EXT     25   OUT (OUT ) 0        0       
EXT     26   IN  (IN  ) 0        1       
EXT     27   IN  (IN  ) 0        1       
EXT     28   IN  (IN  ) 0        0       
EXT     29   OUT (OUT ) 0        0       
EXT     30   OUT (OUT ) 0        1       
EXT     31   OUT (OUT ) 0        1       
EXT     32   IN  (IN  ) 0        0       
EXT     33   IN  (IN  ) 0        1       
EXT     34   OUT (OUT ) 1        1       

This was compared to (ignore the unexported pins):

root@OpenWrt:/# for x in $(seq 0 34); do i=$((160+x)); echo -ne "$x\t"; grep . /
sys/class/gpio/gpio$i/direction 2>/dev/null|tr \\n \\t; grep . /sys/class/gpio/g
pio$i/value; done
0       in      1
1       in      0
2       in      0
3       grep: /sys/class/gpio/gpio163/value: No such file or directory
4       in      1
5       out     1
6       out     1
7       in      1
8       out     1
9       grep: /sys/class/gpio/gpio169/value: No such file or directory
10      grep: /sys/class/gpio/gpio170/value: No such file or directory
11      grep: /sys/class/gpio/gpio171/value: No such file or directory
12      grep: /sys/class/gpio/gpio172/value: No such file or directory
13      out     0
14      out     0
15      out     0
16      out     0
17      out     0
18      out     0
19      in      0
20      in      1
21      in      0
22      in      1
23      out     0
24      grep: /sys/class/gpio/gpio184/value: No such file or directory
25      grep: /sys/class/gpio/gpio185/value: No such file or directory
26      in      1
27      in      1
28      in      0
29      out     0
30      grep: /sys/class/gpio/gpio190/value: No such file or directory
31      grep: /sys/class/gpio/gpio191/value: No such file or directory
32      out     0
33      out     1
34      out     1

Noting that the state of output pin 13 was different, I tested what a change there would do. With the PoE powered RPi4 still connected to port 3:

root@OpenWrt:/# echo 1 > /sys/class/gpio/gpio173/value
root@OpenWrt:/# [51625.831163] RTL8380 Link change: status: 1, ports 400

root@OpenWrt:/# [51626.042205] rtl838x_phylink_mac_config port 10, mode 0
[51626.047981] PHY autonegotiates
[51626.051458] rtl838x-switch switch@bb000000 lan3: Link is Up - 1Gbps/Full - flow control off
[51626.060889] br-lan: port 3(lan3) entered blocking state
[51626.066765] br-lan: port 3(lan3) entered forwarding state
[51626.076517] rtl838x_port_stp_state_set: port 10 state  4
[51626.082538] rtl838x_port_stp_state_set: port 10 state  3

root@OpenWrt:/# [51645.757282] RTL8380 Link change: status: 1, ports 400
[51645.763114] rtl838x-switch switch@bb000000 lan3: Link is Down
[51645.769711] br-lan: port 3(lan3) entered disabled state
[51645.778569] rtl838x_phylink_mac_config port 10, mode 0
[51645.784363] PHY autonegotiates
[51645.787790] rtl838x-switch switch@bb000000 lan3: Link is Up - 1Gbps/Full - flow control off
[51645.797176] rtl838x_port_stp_state_set: port 10 state  0
[51645.803148] FAST AGE port 10
[51645.806544] br-lan: port 3(lan3) entered blocking state
[51645.812423] br-lan: port 3(lan3) entered forwarding state
[51645.822205] rtl838x_port_stp_state_set: port 10 state  4
[51645.828235] rtl838x_port_stp_state_set: port 10 state  3
[51646.521446] rtl838x-switch switch@bb000000 lan3: Link is Down
[51646.528029] br-lan: port 3(lan3) entered disabled state
[51646.536916] rtl838x_port_stp_state_set: port 10 state  0
[51646.542902] FAST AGE port 10
[51648.683890] RTL8380 Link change: status: 1, ports 400
[51649.594467] rtl838x_phylink_mac_config port 10, mode 0
[51649.600238] PHY autonegotiates
[51649.603715] rtl838x-switch switch@bb000000 lan3: Link is Up - 1Gbps/Full - flow control rx/tx
[51649.613330] br-lan: port 3(lan3) entered blocking state
[51649.619203] br-lan: port 3(lan3) entered forwarding state
[51649.629028] rtl838x_port_stp_state_set: port 10 state  4
[51649.635051] rtl838x_port_stp_state_set: port 10 state  3

Now the lua script works just fine:

root@OpenWrt:~#  ubus -v call poe info
{
        "ports": [
                "enabled",
                "enabled",
                "3.6W",
                "enabled",
                "enabled",
                "enabled",
                "enabled",
                "enabled"
        ],
        "power_budget": "65W",
        "power_consumption": "3.6W"
}

So the script was probably fine from the beginning. the problem was than the "main switch" was off.

2 Likes

Hm, is pinctrl setup correctly?

Maybe not? There is no pinctrl driver in the target. I assume that is because it's really not necessary - all these devices map the SoC pins exactly the same. But that's probably a question for @anon13997276 or other experts to answer

Hm, from the leaked datasheet I found it appears that I2C pins are also SPI pins, so there is gotta be some kind of pin muxing going on.

Sorry, I am not familiar with the SoC, maybe I am completely wrong

Good to see that you got PoE working. I'm also surprised at the amount of detail the Zyxel firmware exposes; really helpful to port a device :slight_smile:

I've been looking at the MCU firmware, to better understand the serial commands. It appears that the 06-command is just a shorthand to enable/disable all the ports at once, and not a global override.

Yes, I was surprised by that too. Very useful indeed. But I'd imagine the CLI code originally comes from the same source. Isn't there a similar "show tech-support" command in the D-Link CLI?

1 Like

So far I have also not been able to get the I2C to the SFP cages working. Pin-muxing is however not necessary, because the pins used on the RTL838x are pins 122 and 123, LED_DAT and LED_CLK. These form an I2C bus which steers the RTL8231 GPIO expander close by the SFP cages. It is that GPIO expander that then provides the PINs for e.g. LOS, module present and the I2C bus.
But this also means that the I2C bus to the cages is actually simulated, because the pins on the 8231 are just gpios. The naming LED_DAT/CLK comes from the fact, that the purpose of the RTL8231 normally is to steer all the front-panel leds of the switches.
The status is that I can see I2C coming to the right pins on a SFP board that merely provides measuring pins, but I cant read out any real module. Maybe because I am also missing the main switch.

Could you post the command you used for the gpio configuration? Also maybe you could send a patch for the .dts that sets the power switch by default to "on"?

I didn't do anythin fancy. Just exported whatever was there, except 4 pins that didn't show up in the OEM overview:

for i in $(seq 160 194); do echo $i >/sys/class/gpio/export; done
for i in 5 6 8 13 14 15 16 17 18 23 24 25 29 30 31 34; do echo out >/sys/class/gpio/gpio$((160+i))/direction; done
for x in 9 10 11 12; do echo $((160+x)) >/sys/class/gpio/unexport; done

The exports obviously fail for the pins used for other stuff, like the SFP i2c buses. I simply ignored that.

Yes, I plan to do something like that. Just thinking that it maybe should be a system export instead, which is automatically enabled by the lua script (if it exists)?

You can use OpenWrt's gpio-export, which would allow users to disable the PoE subsystem via the GPIO if desired. The mainline alternative is gpio-hog. gpio-hog exports the gpio and sets it to the required level, but cannot be modified at runtime.

I must admit that I don't like either. gpio-hog because it doesn't allow changing the value. That's fine if we decide that this should just always be on. But I think it can be useful to be able to turn it off since the hardware has this support. And gpio-export because it is a dead end.

Why not use ucidef_add_gpio_switch and let etc/init.d/gpio_switch create the switch?

I personally like to have these things in the DTS, because it describes the hardware. The devicetree contains all information about the device, whereas etc/init.d/gpio_switch contains one specific detail about a number of devices. I prefer to have device info in one place, per device, rather than in a set of scripts that say "this is how you enable feature X on these devices". It's more of a personal preference I guess, and we're probably going too much off-topic here anyway :slight_smile:

I do agree that it's nice to document the hardware in the DTS, so i tried a gpio-hog. But I can't get that working. This is the gpio-confroller node:

	gpio1: rtl8231-gpio {
		compatible = "realtek,rtl8231-gpio";
		#gpio-cells = <2>;
		indirect-access-bus-id = <0>;
		gpio-controller;

		poe_enable {
			gpio-hog;
			gpios = <13 0>;
			output-high;
		};
	};

and I do see

[    0.466243] GPIO line 173 (poe_enable) hogged as output/high

but the power is not enabled. Maybe it's a transition thingy, and this is happening too early for the PoE controller?

Anyway, I won't spend more time trying to figure this out. Togling it from 0 to 1 works, and will enable PoE output even without the lua script (tested from full power off). It's still probably wise to explicitly configure sane settings, but it doesn't seem to be required for basic functionality. Running the current starup function later is actually harmful as it will disable all ports during setup. Is this required for other switches?

I will try to dump the default settings from power-on to see what they are.

EDIT: I was wrong. Enabling the GPIO is not sufficient from cold boot. Some of the ZyXEL specific initialization is required. I guess the controller was already confgured by a previous script run. I'll try to verify, but it's a bit hard to test if I need to physically power the switch off between test runs.

I hit something here, mostly by accident while trying to figure out the gpio-hog issue:

root@OpenWrt:/# 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 -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
root@OpenWrt:/# i2cdump -y 1 0x50
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 03 04 07 00 00 00 01 40 00 0c 00 01 0d 00 00 00    ???...?@.?.??...
10: 37 1b 00 00 46 69 62 65 72 53 74 6f 72 65 20 20    7?..FiberStore  
20: 20 20 20 20 00 00 00 00 53 46 50 31 47 2d 53 58        ....SFP1G-SX
30: 2d 38 35 20 20 20 20 20 20 20 20 20 03 52 00 b8    -85         ?R.?
40: 00 1a 00 00 44 38 37 42 32 33 31 32 34 36 35 20    .?..D87B2312465 
50: 20 20 20 20 31 37 31 32 30 32 20 20 68 f0 01 dc        171202  h???
60: 00 00 08 78 6f f5 14 69 89 9b 8d 5b 28 e7 c7 ea    ..?xo??i???[(???
70: 2e 6c 40 00 00 00 00 00 00 00 00 00 ce 8f 7d cc    .l@.........??}?
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@OpenWrt:/# i2cdump -y 1 0x51
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 64 00 ce 00 55 00 d8 00 94 3e 6d 92 87 5a 7a 76    d.?.U.?.?>m??Zzv
10: af c8 00 00 a6 04 00 00 1b a7 03 7b 13 93 04 ea    ??..??..???{????
20: 31 2d 00 3f 1f 07 00 64 00 00 00 00 00 00 00 00    1-.???.d........
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 e0    ?...?...?......?
60: 28 ba 80 9c 08 2d 0a 34 00 00 ff ff ff ff 02 00    (????-?4......?.
70: 00 40 00 ff 00 40 ff ff 00 00 ff 00 00 00 00 00    .@...@..........
80: 57 4f 54 52 42 39 56 42 41 41 31 30 2d 32 36 32    WOTRB9VBAA10-262
90: 36 2d 30 31 56 30 31 20 89 fb 55 00 00 00 00 7d    6-01V01 ??U....}
a0: 00 00 00 00 00 00 00 00 00 00 62 a4 64 00 69 9c    ..........b?d.i?
b0: 75 1b 81 f1 12 26 0b f5 0c f2 0f b6 00 00 aa aa    u????&??????..??
c0: 47 4c 43 2d 53 58 2d 4d 4d 44 20 20 20 20 20 20    GLC-SX-MMD      
d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 59                   Y
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 ff c0 ff ff ff c0 ff ff    .........?...?..

If I have got this right, then there are two parts necessary to make this work:

  1. set the gpio value as requested when changing direction
  2. configure the gpios for open drain

The latter should probably be done explictly to avoid unnecessary warnings, but since this is development by accident I wanted to make sure the changes were as few as possible. I believe this is enough to make it work:

diff --git a/target/linux/rtl838x/dts/rtl8380_zyxel_gs1900-10hp.dts b/target/linux/rtl838x/dts/rtl8380_zyxel_gs1900-10hp.dts
index 4be9ad90f7c6..cf921f2fd8eb 100644
--- a/target/linux/rtl838x/dts/rtl8380_zyxel_gs1900-10hp.dts
+++ b/target/linux/rtl838x/dts/rtl8380_zyxel_gs1900-10hp.dts
@@ -53,8 +53,6 @@
                gpios = <&gpio1 24 GPIO_ACTIVE_HIGH /* sda */
                         &gpio1 25 GPIO_ACTIVE_HIGH /* sdc */ >;
                i2c-gpio,delay-us = <2>;
-               i2c-gpio,sda-open-drain;
-               i2c-gpio,scl-open-drain;
        };
        /* addional gpios:
         * MOD-DEF0: gpio1 26
@@ -68,8 +66,6 @@
                gpios = <&gpio1 30 GPIO_ACTIVE_HIGH /* sda */
                         &gpio1 31 GPIO_ACTIVE_HIGH /* sdc */ >;
                i2c-gpio,delay-us = <2>;
-               i2c-gpio,sda-open-drain;
-               i2c-gpio,scl-open-drain;
        };
        /* addional gpios:
         * MOD-DEF0: gpio1 32
diff --git a/target/linux/rtl838x/files-5.4/drivers/gpio/gpio-rtl8231.c b/target/linux/rtl838x/files-5.4/drivers/gpio/gpio-rtl8231.c
index b1710bfb0e13..ec959add6729 100644
--- a/target/linux/rtl838x/files-5.4/drivers/gpio/gpio-rtl8231.c
+++ b/target/linux/rtl838x/files-5.4/drivers/gpio/gpio-rtl8231.c
@@ -184,6 +184,8 @@ static int rtl8231_direction_output(struct gpio_chip *gc, unsigned int offset, i
        pr_debug("%s: %d\n", __func__, offset);
        mutex_lock(&smi_lock);
        err = rtl8231_pin_dir(gpios, offset, 0);
+       if (!err)
+               err = rtl8231_pin_set(gpios, offset, value);
        mutex_unlock(&smi_lock);
        return err;
 }

1 Like

I can confirm that this works. Great work, bmok!
What a stupid mistake on my side to disregard the value in
rtl8231_pin_dir :wink:
Would you mind sending a PR to the 83xx_dev branch?

And BTW: It should now be possible to use the generic SFP support in Linux with these modules: https://www.mjmwired.net/kernel/Documentation/devicetree/bindings/net/sff,sfp.txt