Skip to content

Conversation

@vDorst
Copy link
Collaborator

@vDorst vDorst commented Jan 25, 2026

Fix the N-chips serdes swap issues.
Detect and init the chip based on detected type instead of machine profile.

Added helper functions to read/write to/from rtl8224.
rtl8224_write_reg_u16() and rtl8224_read_reg_u16 copy of phy_read()/phy_write().
Without the copy, the compiler error-out because we are out-of-ram.
Now I don't use any additional ram.

Detect the SOC type and variant. RTL8372 vs RTL8373 and also is it as
non-N/N variant of the SOC.
Even if the machine profile is wrong the hardware will be initilised on
the detected type.
Without this fix N-type SOC devices like RTL8372N, RTL8383N and also the
4-port PHY RTL8224N, don't have a functional Serdes. Although the SOC
sees a link, there is no packet flow on both SFP-port nor RTL8224 ports.

Added helper functions to read/write to the RTL8224.
RTL8224 has the same register layout so we can use the same register
defines as for the main SOC.
@vDorst vDorst requested a review from logicog January 25, 2026 16:39
@vDorst vDorst mentioned this pull request Jan 25, 2026
@logicog logicog self-assigned this Jan 25, 2026
@logicog
Copy link
Owner

logicog commented Jan 25, 2026

@feelfree69 , @TylerDurden-23 could you test this? I do not have one of those -N devices.

@TylerDurden-23
Copy link

TylerDurden-23 commented Jan 25, 2026

@logicog Works as before - the issue with the 1000 Base-T module in slot 1 persists.

Copy link
Owner

@logicog logicog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is truly impressive. The indirections to write the SDS registers of the RTL8224 give me a headache, but they looks all correct! I will test also with my non-n device and an RTL8371B.

rtl837x_phy.c Outdated

// Phy ID of the external RTL8224 PHY.
#define RTL8224_PHY_ID 0x00
#define RTL8224_DEV_ID 0x1e
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In phy.h is already a definition:

#define PHY_SDS_CTRL	30

This is also the name of that page in the RTL8221 datasheet, the RTL8224 is the Quad version of that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to rename it, because it is Vendor specific register.
In the linux kernel they call it https://elixir.bootlin.com/linux/v6.18.6/source/include/uapi/linux/mdio.h#L28

#define MDIO_MMD_VEND1		30	/* Vendor specific 1 */
#define MDIO_MMD_VEND2		31	/* Vendor specific 2 */

We can use the same naming convention.

What do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that we are already using a simulair name

phy.h
14:#define PHY_MMD_PMAPMD       1
15:#define PHY_MMD_AN   7
17:#define PHY_MMD_CTRL 31

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The kernel calls it MDIO_MMD_VEND1 because it supports a dozen different PHY vendors who support MMD, so it is not clear what this page does for an arbitrary vendor. But the ones we will encounter will always be Realtek, they use always their own ecosystem, because they have their own variant of MDIO that supports up to 63 PHYs. The PHY_MMD_CTRL is based on what they call that page in their datasheets. What about PHY_MMD_SDS ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a vendor specific register so the vendor can do that he want, and also use a different layout for every chip.
PHY_MMD_SDS is valid for rtl8221 but not for rtl8224.
Looking into rtl8221-datasheet and it doesn't have the same layout as rtl8224.

So I am think some other options

  • PHY_MMD31 How they also call these registers MMD 31
  • PHY_MMD31_VEND2 Make it more distinctive.
  • PHY_MMD_1E, PHY_MMD1E In hex

write_char('N');
}
write_char('\n');
if (machine.isRTL8373 != machine_detected.isRTL8373) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need machine.isRTL8373 if we anyway detect it? What about an RTL8371B?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This provides an extra check to see if you have at least the right profile select that can fit on the SOC.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But still how does the 8371 relates to the other chips?
Do we need add support for it of can it just use the RTL8373-settings?
Maybe we need at some extra documentation about this chip.

@feelfree69
Copy link
Contributor

@feelfree69 , @TylerDurden-23 could you test this? I do not have one of those -N devices.

Sorry, my 8173 is also not an -N device.

@vDorst
Copy link
Collaborator Author

vDorst commented Jan 25, 2026

@feelfree69 , @TylerDurden-23 could you test this? I do not have one of those -N devices.

Sorry, my 8173 is also not an -N device.

But still how does the 8173 relates to the other chips?
Do we need add support for it of can it just use the RTL8373-settings?
Maybe we need at some extra documentation about this chip.

Can you still test it to see if it still works?

@feelfree69
Copy link
Contributor

Sorry, typo. My switch is an ordinary 8+1 type with RTL8373.

Remove the unused array `rtl8224_cb`.
Rename `rtl8224_ca` to `rtl8224_sds0_setttings`.
@vDorst
Copy link
Collaborator Author

vDorst commented Jan 25, 2026

Some new patches on the linux kernel malinglist about this issue.

@logicog
Copy link
Owner

logicog commented Jan 25, 2026

PHY_MMD31 is fine.
But that the RTL8224 is the Quad version of the 8221 is for sure, that is Realtek's naming scheme since decades and is also quite established across phy vendors, the last digit gives the numbers of PHYs in the package. Realteks PHYs all have the numbering scheme RTL82x1/2/4/8 plus a letter for versioning. For example, the 1000MBit PHYs are all the RTL8211A-G and RTL8218/A-G are the corresponding Octal versions The RTL8201x are 100MBit Single PHYs, the RTL8202/4/8 are the multi PHY packages of those chips.

Looking at the SDK, the RTL8371B is just an older version of the RTL8372, probably a different PHY. The PHYs have a tendency to continuously evolve with time while keeping their basic performance characteristics. That is also why they have so many PHY patches in the SDK. This seems to solve interoperability issues with other PHYs.

So demagic the `phy_(, 0x1f, )` to `phy_(, PHY_MMD31, )`.
So demagic the `phy_(, 0x1e, )` to `phy_(, PHY_MMD30, )`.
Use `rg -tc phy | rg -i 0x1e` to find to most locations.
@logicog
Copy link
Owner

logicog commented Jan 26, 2026

I tested this on the 2 Non-N devices MACHINE_KP_9000_6XHML_X2 and MACHINE_KP_9000_9XH_X_EU and everything seems to work, in particular the 10GBit SFP+ ports:

RESET

Initializing Flash controller
Detecting CPU: RTL8372
Software version: v0.1.0-gc11099b
Build: Jan 26 2026 10:32:34
Hardware: keepLink KP-9000-6XHML-X2
NIC reset

init_switch called
CPU revision: 6868

rtl8372_init called

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
igmp_setup called
03:
04:
05:
06:
07:
08:
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       SFP OK  Down    0x00000000      0x00000000      0x00000000      0x00000000
1       On      1000M   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  Down    0x00000000      0x00000000      0x00000000      0x00000000
Setting ip: 192.168.10.247
Setting gw: 192.168.10.1
Setting netmask: 255.255.255.0

> stat

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
5       SFP OK  10G     0x0000001b      0x00000000      0x00000029      0x00000000
1       On      1000M   0x00000052      0x00000000      0x00000006      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     0x0000002a      0x00000000      0x00000023      0x00000000

> sfp

Slot 1 - Rate: 67  Encoding: 01
Lightron Inc.   WSPXG-ES3LC-IHA 0000
Options: 68
Temp: 159c
Vcc: 7f14
TX Bias: 3004
TX Power: 1856
RX Power: 2314
Laser: 0000
State: 30

Slot 2 - Rate: 67  Encoding: 06
OEM             SFP-10G-SR      2   
Options: 68
Temp: 156e
Vcc: 8006
TX Bias: 0ce6
TX Power: 16fb
RX Power: 187d
Laser: 0000
State: 30

=========== 
Initializing Flash controller
Detecting CPU: RTL8373
Software version: v0.1.0-gcc741b0
Build: Jan 24 2026 18:30:52
Hardware: keepLink KP-9000-6XH-X-EU
NIC reset

init_switch called
CPU revision: 6868

rtl8373_init called

phy_config_8224 called
R02f8-00000bff R02f4-00000bed 
phy_config_8224 done

RTL837X_REG_SDS_MODES: 0x00000bff

RTL837X_REG_SDS_MODES: 0x00000bff
sds_config sds: 00, mode: 0d

RTL837X_REG_SDS_MODES: 0x00000bed

rtl8224_phy_enable called
R02f8-000000f3 R02f4-000000fc 
rtl8224_phy_enable done

rtl8373_init done

vlan_setup called 
vlan_setup done 

port_l2_setup called

port_l2_forget called
port_l2_forget done

port_l2_setup done
igmp_setup called
00:
01:
02:
03:
04:
05:
06:
07:
08:
uip_arp_init called
A minimal prompt to explore the RTL8372:

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

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
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
5       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
6       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
7       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
8       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
9       NO SFP  Down    0x00000000      0x00000000      0x00000000      0x00000000
Setting ip: 192.168.10.247
Setting gw: 192.168.10.1
Setting netmask: 255.255.255.0

> 
<new link: 2000000000, was 0000000000>

<new link: 2000000002, was 2000000000>

<MODULE INSERTED>  Slot: 1  Rate: 67  Encoding: 06  Module: OEM             SFP-10G-SR      2   

sds_config sds: 01, mode: 1a

RTL837X_REG_SDS_MODES: 0x00000b4d

<SFP-RX OK>  Slot: 1

<new link: 2400000002, was 2000000002>

<new link: 2000000002, was 2400000002>

<new link: 2400000002, was 2000000002>


> stat

 Port   State   Link    TxGood          TxBad           RxGood          RxBad
1       On      1000M   0x0000001b      0x00000000      0x00000017      0x00000000
2       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
3       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
4       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
5       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
6       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
7       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
8       On      Down    0x00000000      0x00000000      0x00000000      0x00000000
9       SFP OK  10G     0x00000002      0x00000000      0x0000001b      0x00000000

> 

However, My HG0402G V1.1 with an RTL8371B does not show any serial output, although the device seems to boot, and even brings up the SFP port. Probably this is unrelated...

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.

4 participants