Skip to content

Conversation

@logicog
Copy link
Owner

@logicog logicog commented Nov 4, 2025

This fixes several issues with the existing SFP code and the link status code. It now provides full support for 2 SFP ports and uses also the link status register for ports 8 and 9 correctly.
This was tested on 5+1, 4+2 and 8+1 devices.
An example output now is e.g.:

> stat

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
5       SFP OK  Down    0x00000000      0x00000000      0x00000000      0x00000000
1       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
2       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
3       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
4       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
6       SFP OK  10G     0x0000002d      0x00000000      0x00000000      0x00000000

> sfp

Slot 0 - Rate: 67  Encoding: 06
OEM             SFP-10G-SR      2   

Slot 1 - Rate: 0d  Encoding: 01
OEM             SFP-GE-SX-MM850     

For reasons of code complexity (use of additional variables), the ports are not in sequence on RTL8272 devices, only for RTL8273 this is the case.

@vDorst
Copy link
Collaborator

vDorst commented Dec 7, 2025

@logicog can you rebase this PR, so I can check it again.

@logicog
Copy link
Owner Author

logicog commented Dec 7, 2025

On it. Need to push my work on IGMP aside, first.

@logicog
Copy link
Owner Author

logicog commented Dec 7, 2025

Done.

@vDorst
Copy link
Collaborator

vDorst commented Dec 7, 2025

Website and console don't match.
Console stat is correct.
I do have a SFP, 10Gbit link and RJ45, 1gbit, connected.

Screenshot_20251207_121644

status.json

[{"portNum":5,"isSFP":1,"enabled":1,"link":4,"txG":"0x056","txB":"0x0","rxG":"0x033","rxB":"0x0"},{"portNum":1,"isSFP":0,"enabled":1,"link":0,"txG":"0x00","txB":"0x0","rxG":"0x00","rxB":"0x0"},{"portNum":2,"isSFP":0,"enabled":1,"link":2,"txG":"0x0e1","txB":"0x0","rxG":"0x0165","rxB":"0x0"},{"portNum":3,"isSFP":0,"enabled":1,"link":0,"txG":"0x00","txB":"0x0","rxG":"0x00","rxB":"0x0"},{"portNum":4,"isSFP":0,"enabled":1,"link":0,"txG":"0x00","txB":"0x0","rxG":"0x00","rxB":"0x0"},{"portNum":6,"isSFP":1,"enabled":0,"link":1,"txG":"0x00","txB":"0x0","rxG":"0x00","rxB":"0x0"}]

Console

stat

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
5       SFP OK  10G     0x00000035      0x00000000      0x0000005a      0x00000000
1       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
2       On      1000M   0x000001ce      0x00000000      0x00000134      0x00000000
3       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
4       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
6       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000

@logicog
Copy link
Owner Author

logicog commented Dec 7, 2025

Was the website correct before? The code hopefully only changes the behaviour of the console.

@vDorst
Copy link
Collaborator

vDorst commented Dec 7, 2025

Nope. Result from the current main fccafe8
Screenshot_20251207_161519

status.json:

[{"portNum":5,"isSFP":1,"enabled":1,"link":4,"txG":"0x0d","txB":"0x0","rxG":"0x017","rxB":"0x0"},{"portNum":1,"isSFP":0,"enabled":1,"link":0,"txG":"0x00","txB":"0x0","rxG":"0x00","rxB":"0x0"},{"portNum":2,"isSFP":0,"enabled":1,"link":2,"txG":"0x06b","txB":"0x0","rxG":"0x08b","rxB":"0x0"},{"portNum":3,"isSFP":0,"enabled":1,"link":0,"txG":"0x00","txB":"0x0","rxG":"0x00","rxB":"0x0"},{"portNum":4,"isSFP":0,"enabled":1,"link":0,"txG":"0x00","txB":"0x0","rxG":"0x00","rxB":"0x0"},{"portNum":6,"isSFP":1,"enabled":0,"link":1,"txG":"0x00","txB":"0x0","rxG":"0x00","rxB":"0x0"}]

Console stat

> stat

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
4       Off     Up      0x0000003b      0x00000000      0x00000015      0x00000000
5       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
6       On      1000M   0x000000d1      0x00000000      0x000000c2      0x00000000
7       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
8       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000
9       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000

@logicog
Copy link
Owner Author

logicog commented Dec 7, 2025

I'll add a fix for the website, too, then, now that we know that the new code in principle works. I'll try to do this by tomorrow.

This fixes handling of the SFP ports in the stat command.
The output of the command now is for physical ports, which however are
not shown in sequence.
The RTL8272/3 use 2 32 bit registers to indicate the MAC link speed, the
second register is used for ports 8 and 9, where 9 is the CPU port.
Use both registers.
This adds the speed status display of other link speeds:
100M 500M 1000M: Green 2nd LED
2.5G, 5G, 10G: Orange 2nd LED
@logicog
Copy link
Owner Author

logicog commented Dec 8, 2025

The website seems to work now, too. There had been no support for the 2nd SFP slot and then also the 10G link speed display had been forgotten. I also added the now identifiable link speeds of 5G and 500M, which the switches support in HW (but not in code due to the lack of a 5G module, however one could test 500M connections, but that is an RTL proprietary link speed and hardly found anywhere, so I am not overly enthusiastic).

@logicog
Copy link
Owner Author

logicog commented Dec 8, 2025

I also added SFP information in the send_basic_info() function, which is shown on the Switch Configuration web-page:
sfp_info

@vDorst
Copy link
Collaborator

vDorst commented Dec 8, 2025

Do you think the switch also supports the 2.5gbit-lite version?

I like the idea but I think that I like a seprat windows/tooltip better.
Example: I saw that Ubuiquiti UDM Pro Max seems to show it when you hover over the port ICON like this
mCVIFqRmVNSqBRrrQtggZl1G
Daniel has I think most of the code already #35 (comment)

@logicog
Copy link
Owner Author

logicog commented Dec 8, 2025

Yes, the switch does support 2.5GBit-lite, as it is a feature of the RTL8221B and RTL8224 which is probably at the heart of the RTL8372. At the SerDes one gets 1000MBit, the speed setting does not change. However, there is a difference in the SDS configuration. But that is an RTL proprietary format, like 500MBit so not sure about the usefulness.

What I know is that 2.5GBit modules work. One needs the right modules, though. It should also support 5GBit, but I do not have such a module to test, they are rare and expensive. It requires different SDS settings, so without some additional code, it will probably not work.

Admittedly, the tool-tip looks seriously cool, if not to say geeky. I already had though about tool-tips for the ports. I'll work on it...

@vDorst
Copy link
Collaborator

vDorst commented Dec 8, 2025

SFP ports are switched.

Screenshot_20251208_220748
> stat

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
5       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000
1       On      Down    0x00000000      0x00000000      0x00000001      0x00000000
2       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
3       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
4       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
6       SFP OK  10G     0x00000331      0x00000000      0x00000223      0x00000000

Left port is used right now.

@logicog
Copy link
Owner Author

logicog commented Dec 9, 2025

Not for me. The SFP-Module is in the left slot of keeplink KP-9000-6XHML-X2:

> stat

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
5       SFP OK  10G     0x00000099      0x00000000      0x00000415      0x00000000
1       On      1000M   0x000001e8      0x00000000      0x00000476      0x00000000
2       On      1000M   0x0000035d      0x00000000      0x00000162      0x00000000
3       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
4       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
6       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000
Screenshot_20251209_064815

Note, that on the web, for you sfp_slot_0, which is the 0th I2C connection is correct, but for me, not. So at least in both cases logical port 5 is associated with I2C- connection 1, So for now, we only have a problem with geometry, not with association of I2C-port to SDS-lane or to the GPIOs.
So what about introducing say a MACHINE_KL_9000_6XHML_X2, and MACHINE_SWGT024_V2_0 which use a different geometry? Something like

In rtl837x_common.h:
#define MACHINE_KL_9000_6XHML_X2
// #define MACHINE_SWGT024_V2_0
#ifdef MACHINE_KL_9000_6XHML_X2
#define GEOMETRY_PHY_3_IS_PORT_5
#endif

In rtl837x_port.c:
#ifdef GEOMETRY_PHY_3_IS_PORT_5
__code uint8_t log_to_phys_port[9] = {
	0, 0, 0, 5, 1, 2, 3, 4, 6
};
#else
__code uint8_t log_to_phys_port[9] = {
	0, 0, 0, 6, 1, 2, 3, 4, 5
};
#endif

The Problem is that the web-interface also has such definitions in port.js:

const logToPhysPort = [0, 0, 0, 5, 1, 2, 3, 4, 6];
const physToLogPort = [	4, 5, 6, 7, 3, 8];

So this is a bigger mess. And I now know why I had a terrible feeling when introducing PHY-port mappings to the web-application.
We could run the javascript through the C-Preprocessor when compiling the image...
Or we could give a geometry hint in the status.json...

@vDorst
Copy link
Collaborator

vDorst commented Dec 9, 2025

Note, that on the web, for you sfp_slot_0, which is the 0th I2C connection is correct, but for me, not. So at least in both cases logical port 5 is associated with I2C- connection 1, So for now, we only have a problem with geometry, not with association of I2C-port to SDS-lane or to the GPIOs.

I can provide the link-changes prints, so we can figureout which port is connected which sds and also document it on the wiki.

So what about introducing say a MACHINE_KL_9000_6XHML_X2, and MACHINE_SWGT024_V2_0 which use a different geometry?

Can we put characteristic in a struct instead of define so it is more unified?
I see examples in the linux kernel like this
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/net/ethernet/mediatek/mtk_eth_soc.c?h=v6.17.11#n5593 and https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/net/ethernet/mediatek/mtk_eth_soc.c?h=v6.17.11#n5570

Or we could give a geometry hint in the status.json...
This is good idea.

@logicog
Copy link
Owner Author

logicog commented Dec 9, 2025

I can provide the link-changes prints, so we can figureout which port is connected which sds and also document it on the wiki.
At this point I believe this is not the problem, unless one of both of the 2 SFP-ports does not work for you.

I like the structures. This is allows compile-time verification. It may make the code a bit larger, but since we do not have an issue with the flash-size, this is irrelevant.

I will provide a proposal using structures, later today (finally got IGMP working, need to wrap that up while it is fresh in my mind). Note that we will still need some defines, because we cannot auto-detect geometry, this has to be input to the compiler, the structures in the kernel you mention are based on auto-detection of the SoC. Device-tree btw would probably be the ideal solution, as it creates structures in the build image, which are compile-time dependent, but this comes with an enormous amount of additionally required infrastructure.

Because we go for the structure, I will also add information on geometry to the .json sent to the client which ends up in a struct there.

@vDorst
Copy link
Collaborator

vDorst commented Dec 9, 2025

The "auto-detect" can just be a config-setting.
When the device information is to much we can put it in a bank, and only copy the used settings in to XDATA memory or program it in the "CODE"-bank.
And frequently used settings we can add flags in SRAM, so that the code-size to fetch a setting don't explode or consuming to much cycles.

@vDorst
Copy link
Collaborator

vDorst commented Dec 9, 2025

Here the link status log.

Started left at the first RJ45 port.
insert and remove the cable and SFP port also sfp-module.

Detecting CPU: RTL8372
Software version: v0.1.0-g06fbf85

Starting up...
  Flash controller
NIC reset

rtl8372_init called
Configuring 2nd SFP+ port

phy_config: 8
  phy config done

phy_config: 3
  phy config done

rtl8372_init done

vlan_setup called 
vlan_setup done 

port_l2_setup called

port_l2_forget called
port_l2_forget done

port_l2_setup done
uip_arp_init called
A minimal prompt to explore the RTL8372:

Clock register: 0x00001101
Register 0x7b20/RTL837X_REG_SDS_MODES: 0x00000bff
Verifying PHY settings:

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
5       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000
1       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
2       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
3       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
4       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
6       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000
Got ip command: c0a80af7
Got gw command: c0a80a01
Got netmask command: ffffff00

> 
<new link: 2000000000, was 0000000000>


> 
<new link: 2000020000, was 2000000000>
ip: invalid version or header length.ip: invalid version or header length.

> stat

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
5       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000
1       On      1000M   0x0000000e      0x00000000      0x00000000      0x00000000
2       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
3       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
4       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
6       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000

> 
<new link: 2000000000, was 2000020000>

<new link: 2000200000, was 2000000000>


> stat

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
5       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000
1       On      Down    0x0000000e      0x00000000      0x00000000      0x00000000
2       On      1000M   0x00000000      0x00000000      0x00000000      0x00000000
3       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
4       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
6       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000

> 
<new link: 2000000000, was 2000200000>

<new link: 2002000000, was 2000000000>
stat

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
5       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000
1       On      Down    0x0000000e      0x00000000      0x00000000      0x00000000
2       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
3       On      1000M   0x00000000      0x00000000      0x00000000      0x00000000
4       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
6       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000

> 
<new link: 2000000000, was 2002000000>

<new link: 2020000000, was 2000000000>
stat

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
5       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000
1       On      Down    0x0000000e      0x00000000      0x00000000      0x00000000
2       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
3       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
4       On      1000M   0x00000000      0x00000000      0x00000000      0x00000000
6       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000

> 
<new link: 2000000000, was 2020000000>

<MODULE INSERTED>  Rate: 67  Encoding: 06

DELL            WTRD1           A0  
sds_config sds: 01, mode: 1a

RTL837X_REG_SDS_MODES: 0x0000035f

Trying to set SDS mode to 0x1a

<new link: 2400000000, was 2000000000>
ip: invalid version or header length.ip: invalid version or header length.

> stat

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
5       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000
1       On      Down    0x0000000e      0x00000000      0x00000000      0x00000000
2       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
3       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
4       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
6       SFP OK  10G     0x00000012      0x00000000      0x00000000      0x00000000

> 
<new link: 2000000000, was 2400000000>

<MODULE REMOVED>


> 
<MODULE 2 INSERTED>  Rate: 67  Encoding: 06
DELL            WTRD1           A0  
sds_config sds: 00, mode: 1a

RTL837X_REG_SDS_MODES: 0x0000035a

Trying to set SDS mode to 0x1a

<new link: 2000004000, was 2000000000>
ip: invalid version or header length.ip: invalid version or header length.

> stat

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
5       SFP OK  10G     0x00000011      0x00000000      0x00000000      0x00000000
1       On      Down    0x0000000e      0x00000000      0x00000000      0x00000000
2       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
3       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
4       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
6       NO SFP  Down    0x00000012      0x00000000      0x00000000      0x00000000

@logicog
Copy link
Owner Author

logicog commented Dec 10, 2025

I pushed an initial implementation. It is more for feedback and not very well tested, so far only on the 4+2 device. But it is a bit of work and easy to get wrong, so better get feedback early.
There are lots of things that still can be done, such as using SFP-pins, there is nothing yet about the I2C pins. and looking at #40 there may be the need to have SDS configuration in.

@vDorst
Copy link
Collaborator

vDorst commented Dec 10, 2025

@logicog Thanks, you did not added machine.h and machine.c to the commit.

@logicog
Copy link
Owner Author

logicog commented Dec 13, 2025

There were a couple of issues in c5995a4 and 001c52e which somehow cancelled each other out to only break the the RTL8221B-port plus the speed settings for the links, so this was not immediately obvious when testing. The RTL8221B works again with above fix. Now checking the speed settings.

@vDorst
Copy link
Collaborator

vDorst commented Dec 14, 2025

I updated to latest commit and added the fix GPIO settings,readout and document to it.
See https://github.com/vDorst/RTLPlayground/commits/sfp_work5/.
I had to swap the sds ports other I did not get a link on right sfp port.

Both modules do detect properly and get a link.
Also 1G-RJ45-SFP module works a 1Gbit.

Screenshot_20251214_113146

There were a couple of issues in....

Great that you found it!

@logicog
Copy link
Owner Author

logicog commented Dec 14, 2025

This looks great! We are going for fully flexible device support!

I just pushed support for link speed settings, try:

> port 1 1g
> port 1 duplex off
> port 1 duplex on
> port 1 show

I want to read out the SFP module parameters such as temperature, next and send the link state info and the SFP info to the web.,

@logicog
Copy link
Owner Author

logicog commented Dec 14, 2025

I'll also pull in your fixes for the SWGT024.

@logicog
Copy link
Owner Author

logicog commented Dec 14, 2025

I think I got the latest changes from you into the current commits.

@vDorst
Copy link
Collaborator

vDorst commented Dec 14, 2025

I just pushed support for link speed settings, try:

Maybe put this in a separate PR?

So we can merge the current work.

@logicog
Copy link
Owner Author

logicog commented Dec 14, 2025

Can we get the link speed in? This was already in the code, it was just broken, because of incorrect translation of physical port number to logical port number. OK, I added link partner display. But leaving it without the last commit would keep the code broken. I will start a new PR for the Web display and SFP properties, ok?

@vDorst
Copy link
Collaborator

vDorst commented Dec 14, 2025

Ok, that is fine.

@logicog
Copy link
Owner Author

logicog commented Dec 14, 2025

Cool!

@vDorst
Copy link
Collaborator

vDorst commented Dec 14, 2025

Correct that the SFP module don't show this information yet?

> port 6 show

PORT 08
Forced speed: 0x0000
s1, s2: 00 00
10M
Duplex: 0x0000 enabled: no

Link Partner advertises:

> stat

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
6       SFP OK  10G     0x00000019      0x00000000      0x00000042      0x00000000
1       On      100M    0x00000114      0x00000000      0x000000a7      0x00000000
2       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
3       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
4       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
5       NO SFP  Down    0x0000000e      0x00000000      0x0000000c      0x00000000

@logicog
Copy link
Owner Author

logicog commented Dec 14, 2025

Yes. This is entirely PHY information. But I need to make sure it is not called for an SFP module. We shall think about Ethernet-SFP modules later ;-)

@vDorst
Copy link
Collaborator

vDorst commented Dec 14, 2025

This means I can't force the SFP port to let say 1gbit or 2.5bit if I want/need to?

@logicog
Copy link
Owner Author

logicog commented Dec 14, 2025

No, you cannot. If you put a 1Gbit module on one side and the other side has a 2.5Gbit module which is able to support 1Gbit (which is not necessarily the case), you can make the 2.5Gbit module work at 1Gbit.

@logicog
Copy link
Owner Author

logicog commented Dec 14, 2025

https://superuser.com/questions/1731301/why-does-auto-port-speed-negotiation-not-work-on-sfp-fiber-uplinks
However, you can force an SFP port sometimes to use a different speed. This works by changing the SerDes frequency. The module needs to support this, even if the frequency is lower than its maximum frequency because of things like PLLs that are involved.

@vDorst
Copy link
Collaborator

vDorst commented Dec 14, 2025

I am fine to make that in a separate PR.
It is up to you, when you want this in this this PR.
Because I am ready to merge.

@logicog
Copy link
Owner Author

logicog commented Dec 14, 2025

Then let's merge.

@vDorst vDorst merged commit 677e01f into main Dec 14, 2025
@vDorst
Copy link
Collaborator

vDorst commented Dec 14, 2025

Done, great job!

@logicog
Copy link
Owner Author

logicog commented Dec 14, 2025

Thanks the great collaboration on this!

@vDorst vDorst deleted the sfp_work branch December 23, 2025 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants