Support for RTL838x based managed switches

I have the F version of DGS-1210-28, DGS-1210-28P and DGS-1210-28MP. The photos on https://svanheule.net/ and https://wikidevi.wi-cat.ru/ are from my devices.

I have bought the F2 in EU, so its not a regional thing

Yeah, it really makes no sense to me

I have now studied the 28P, 28MP and mine 24P pictures intensively.

interesting difference are visible when comparing the 28P and 28MP, some expected some not.

  • the 28P and MP have different power-supplies (this is expected)
  • the MP chassis was prepared for 4 fan-mounts, but only same 2 are equipped as the P
  • both share the same heat-spreaders around the eth-plugs
  • the 28P uses 3x12V, 3xGnd on the connector to mainboard, the 28MP only uses 2x12 and 2xGnd

In contrast i could not spot any difference between the 28P and 24P. So i would sort-of-guess that these are the same devices.

But i will add some closeups and further infos onto the wiki page

I now "hacked" a solution by entirely bypassing the lm63 dance.
With some left-over plugs from Noctura PC fans, I directly attached 12V to the fans
(see picture below)

I took +12V from one of the original 3PIn-Connector for the fans
and GND i added a cable to one of the 3 gnd wires (black colored) that came from the power supply board to the mainboard.

The generated noise is okay-ish.. (switch will end up in basement, so it doesnt matter sooo much for me)

At least now i can mount the switch and start using it...

next step is for me to extend the poe.lua script to support more than 8 ports and add some further infos into it. (like temperatures) or is there already something similar available?

The "more power" version uses a smaller total cross section than the "power" version?

If you hadn't already planned to do so, I would suggest to just create a new subsection on the existing 28(M)P page, since these devices are so similar.

Have a look at the realtek-poe thread to join forces:

1 Like

IIUC, only the clock line is floating, right? Isn't it possible to force the clock line, ignoring the spec? That's what I read from i2c-gpio.c is the meaning of "i2c-gpio,scl-output-only". So don't configure the clock gpio as open drain. Make it an output.

I really don't know what I'm talking about here, but that has never stopped me...

isnt this the config you are proposing?

this results in the i2c is "fully populated" but any read results in 0x0.. so i guess, there is slightly more to that.... possibly the truth lies in how the orig driver does the GPIO setup (before drv_smi_read etc)

Yes, I guess it is. I thought i2c-gpio,scl-open-drain had the opposite meaning, but I see now that this is the correct way to try to configured a forced clock line.

Except... The i2c-gpio driver defaults to 5 µs delay which is increased to 50 µs when i2c-gpio,scl-output-only is set. Why are you setting it as low as 2 µs? Did you try using a higher value?

Thanks for the helpful insights. Nevertheless it would be nice to flash D-Links without serial. Looking around my DGS-1210-16 appDemo.exe (A1 predecessor of ISS.exe) I found some helpful information. Maybe something like this works on later firmware too:

DGS-1210-16 login: guest
Password: guest123 (hard coded ...)
DGS-1210-16> show privilege
Current privilege level is 1
DGS-1210-16> enable 15
Password: ilovecameo (hard coded ...)
DGS-1210-16# show privilege
Current privilege level is 15
DGS-1210-16# system call "sleep 10" --> comes back after 10 seconds
DGS-1210-16# system call "/usr/sbin/telnetd -p 10023 /bin/sh" --> not working, tbd ...

@svanheule Have you seen this so far:

[    0.000000] Linux version 5.10.115 (robimarko@fedora) (mips-openwrt-linux-musl-gcc (OpenWrt GCC 11.2.0 r19709-4bed263af7) 11.2.0, GNU ld (GNU Binutils) 2.37) #0 Sat May 28 22:00:52 2022
[    0.000000] RTL838X model is 83826800
[    0.000000] SoC Type: RTL8382
[    0.000000] Kernel command line: 
[    0.000000] printk: bootconsole [early0] enabled
[    0.000000] CPU0 revision is: 00019070 (MIPS 4KEc)
[    0.000000] MIPS: machine is D-Link DGS-1210-28
[    0.000000] Initrd not found or empty - disabling initrd
[    0.000000] Using appended Device Tree.
[    0.000000] Primary instruction cache 16kB, VIPT, 4-way, linesize 16 bytes.
[    0.000000] Primary data cache 16kB, 2-way, VIPT, cache aliases, linesize 16 bytes
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000000000000-0x0000000007ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000000000-0x0000000007ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000007ffffff]
[    0.000000] On node 0 totalpages: 32768
[    0.000000]   Normal zone: 288 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 32768 pages, LIFO batch:7
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 32480
[    0.000000] Kernel command line: console=ttyS0,115200
[    0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes, linear)
[    0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 113600K/131072K available (5682K kernel code, 616K rwdata, 1232K rodata, 8396K init, 203K bss, 17472K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS: 256
[    0.000000] random: get_random_bytes called from start_kernel+0x31c/0x50c with crng_init=0
[    0.000000] CPU frequency from device tree: 500MHz
[    0.000000] clocksource: MIPS: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041786 ns
[    0.000019] sched_clock: 32 bits at 250MHz, resolution 4ns, wraps every 8589934590ns
[    0.008690] Calibrating delay loop... 498.89 BogoMIPS (lpj=2494464)
[    0.075561] pid_max: default: 32768 minimum: 301
[    0.081068] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.089112] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.103312] dyndbg: Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build
[    0.122881] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.133804] futex hash table entries: 256 (order: -1, 3072 bytes, linear)
[    0.141468] pinctrl core: initialized pinctrl subsystem
[    0.148611] NET: Registered protocol family 16
[    0.302769] clocksource: Switched to clocksource MIPS
[    0.311431] NET: Registered protocol family 2
[    0.316750] IP idents hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    0.326123] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes, linear)
[    0.335563] TCP established hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.344133] TCP bind hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.351893] TCP: Hash tables configured (established 1024 bind 1024)
[    0.359533] UDP hash table entries: 256 (order: 0, 4096 bytes, linear)
[    0.366899] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes, linear)
[    0.375141] NET: Registered protocol family 1
[    0.800793] workingset: timestamp_bits=14 max_order=15 bucket_order=1
[    0.823383] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.829764] jffs2: version 2.2 (NAND) (SUMMARY) (ZLIB) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[    0.845516] pinctrl-single 1b001000.pinmux: 32 pins, size 4
[    0.852345] pinctrl-single 1b00a000.pinmux: 32 pins, size 4
[    0.859665] CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == 802967bc, ra == 802e2f4c
[    0.871460] Oops[#1]:
[    0.873900] CPU: 0 PID: 1 Comm: swapper Not tainted 5.10.115 #0
[    0.880410] $ 0   : 00000000 00000001 00000000 00000018
[    0.886163] $ 4   : 000000ff 00000000 00000000 00000000
[    0.891918] $ 8   : 00000024 802cbb58 00000018 6f2d636f
[    0.897674] $12   : 00000000 00006382 00000000 fffffffc
[    0.903428] $16   : 82272c80 00000000 82272c80 00000000
[    0.909184] $20   : 82272e08 00000000 80750000 00000000
[    0.914939] $24   : 00000008 00000020                  
[    0.920694] $28   : 8201a000 8201bc28 80750000 802e2f4c
[    0.926450] Hi    : 000044fc
[    0.929615] Lo    : 0000227e
[    0.932823] epc   : 802967bc iowrite8+0x4/0x10
[    0.937690] ra    : 802e2f4c realtek_gpio_irq_init+0xac/0xe0
[    0.943907] Status: 1010fc03 KERNEL EXL IE 
[    0.948514] Cause : 1080000c (ExcCode 03)
[    0.952924] BadVA : 00000000
[    0.956092] PrId  : 00019070 (MIPS 4KEc)
[    0.960405] Modules linked in:
[    0.963771] Process swapper (pid: 1, threadinfo=(ptrval), task=(ptrval), tls=00000000)
[    0.972493] Stack : 82272c80 82272e00 80fc6e7c 802dee90 82272c80 82272c80 82272e00 8074d7d8
[    0.981700]         8074d7d8 802dce50 8201bc5c 806d0000 00000000 00000cc0 80f90000 82272c80
[    0.990908]         802ddb74 80650000 82084410 82272e08 82275b80 82272c80 82272c80 82084410
[    1.000117]         00000000 82272d78 00000000 8075d094 80f90000 802ddb00 80fc0000 80320364
[    1.009325]         00000000 803ac928 82272c80 00000017 00000000 82084410 82084400 802e2d88
[    1.018533]         ...
[    1.021222] Call Trace:
[    1.023926] [<802967bc>] iowrite8+0x4/0x10
[    1.028462] [<802dce50>] gpiochip_add_data_with_key+0x508/0xb14
[    1.034957] [<802ddb00>] devm_gpiochip_add_data_with_key+0x60/0xd4
[    1.041767] [<802e2d88>] realtek_gpio_probe+0x1e0/0x2f8
[    1.047546] [<8031e214>] platform_drv_probe+0x40/0x94
[    1.053081] [<8031bf1c>] really_probe+0x108/0x4d8
[    1.058262] [<8031c99c>] device_driver_attach+0x120/0x130
[    1.064208] [<8031ca28>] __driver_attach+0x7c/0x13c
[    1.069579] [<80319a70>] bus_for_each_dev+0x68/0xa4
[    1.074951] [<8031b16c>] bus_add_driver+0x1c8/0x210
[    1.080322] [<8031d1f0>] driver_register+0x98/0x154
[    1.085693] [<80000638>] do_one_initcall+0x50/0x1ac
[    1.091069] [<8075de8c>] do_initcalls+0x100/0x14c
[    1.096244] [<8075e044>] kernel_init_freeable+0xfc/0x138
[    1.102112] [<80586ed0>] kernel_init+0x10/0xf8
[    1.106989] [<80001a18>] ret_from_kernel_thread+0x14/0x1c
[    1.112932] 
[    1.114550] Code: 03e00008  00000000  0000000f <a0a40000> 03e00008  00000000  0000000f  a4a40000  03e00008 
[    1.125290] 
[    1.127114] ---[ end trace 438028f3ae26080b ]---
[    1.132140] Kernel panic - not syncing: Fatal exception
[    1.137897] Rebooting in 1 seconds..
[    3.137510] Reboot failed -- System halted

As soon as the internal GPIO controller is enabled this happens, RTL8231 does not seem to be hit.
This is on DGS-1210-28P.

After bisecting, it works if the following is reverted:

I dont think that removing GPIO_OPEN_DRAIN from the GPIO properties works as:

[    8.442319] gpio-482 (scl): enforced open drain please flag it properly in DT/ACPI DSDT/board file
[    8.452529] i2c-gpio i2c-gpio: Slow GPIO pins might wreak havoc into I2C/SMBus bus timing
[    8.462349] i2c i2c-0: Not I2C compliant: can't read SCL
[    8.468435] i2c i2c-0: Bus may be unreliable
[    8.473234] i2c-gpio i2c-gpio: using lines 483 (SDA) and 482 (SCL, no clock stretching)

I checked with a logic analyzer and SCL is always digital 0 while SDA is fine.

And got it:

i2c-gpio {
		compatible = "i2c-gpio";
		sda-gpios = <&rtl8231 32 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN )>;
		scl-gpios = <&rtl8231 31 GPIO_ACTIVE_HIGH>;
		i2c-gpio,scl-output-only;
		i2c-gpio,scl-open-drain;
	};

This works and 0x4c returns data that matches the LM63 datasheet.
And the LM63 driver is able to control it, great.

1 Like

Great! Then the agressive timing was really the problem earlier (with the forced clock line)?

I guess you just missed that i2c-gpio,scl-open-drain property when you got the warning from gpiolib?

Yeah, there is no way such aggressive timing was achievable with bit-banging here.
I was missing the property as its description is really stupid, and with it being marked deprecated as well it makes it look like setting GPIO_OPEN_DRAIN replaced it

Yes, it's hard to understand what it does without reading the driver. Which you shouldn't have to do to create a device tree, since that's really supposed to be a hardware description and not a driver configuration description.

Anyway, good to see that OEM firmware isn't magic :slight_smile:

DT bindings are getting better, but the older ones are really hit and miss.
This time googling the open-drain enforcement message led me to the part of the driver which had the check for i2c-gpio,scl-open-drain in which case it sets the SCL GPIO as output or otherwise it enforces open-drain regardless.
Which is contradictory to me, but I am also glad that there isnt some black magic being done in the stock FW (But WTF they decided not to add the pull-up only for this I have no idea)

I went on and traced the pinout for the right top SFP:
RTL8231 PIN:
22: SDA
23: SCL
24: MOD_ABS
25: LOS
5: TX_DISABLE

Now, how would one attach the SFP node as the last 4 RJ45 and SFP ports are combo ports.

You put the reference to the sfp node under the phy controlling those ports.

@musashino also gave me a heads up on IRC today.

Apparently this is due to the behaviour of for_each_cpu(cpu, mask) on uniprocessor systems (like RTL838x). Somewhat counterintuitively, the provided mask is ignored entirely. So while cpumask_empty() returns true, for_each_cpu will still loop over exactly one CPU :person_facepalming:

1 Like

Obviously that, but the thing is that it reconfigures into 1000Base-X mode (Which is correct) but then neither copper nor fiber actually work.