* [PATCH next v1] net: rtl8169: add support for RTL8126A and RTL8127A @ 2026-07-22 7:50 javen via U-Boot 2026-07-29 7:27 ` Javen 2026-08-04 8:54 ` Jerome Forissier 0 siblings, 2 replies; 5+ messages in thread From: javen via U-Boot @ 2026-07-22 7:50 UTC (permalink / raw) To: trini, joe.hershberger, rfried.dev; +Cc: u-boot, nd, Javen Xu From: Javen Xu <javen_xu@realsil.com.cn> RTL8126A and RTL8127A share most of the register layouts and quirks with RTL8125 series, but require explicit desc type and CRC-drop setup during init. This patch adds PCI IDs and MAC versions. RTL8126A is 0x66 and RTL8127A is 0x6e. And RTL8127A requires Tx Desc V3 format and an additional RADM FIFO protection configuration according to vendor driver. Signed-off-by: Javen Xu <javen_xu@realsil.com.cn> --- drivers/net/rtl8169.c | 103 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 94 insertions(+), 9 deletions(-) diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index 5b093623619..a24cff97801 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -49,6 +49,7 @@ #include <asm/cache.h> #include <asm/io.h> #include <pci.h> +#include <linux/bitops.h> #include <linux/delay.h> #include <linux/printk.h> @@ -152,8 +153,24 @@ enum RTL8125_registers { IntrMask_8125 = 0x38, IntrStatus_8125 = 0x3C, TxPoll_8125 = 0x90, + RX_DESC_MODE = 0xd8, + MACOCP = 0xb0, + RADMFIFO_PROTECT = 0x0402, + TX_DESC_MODE = 0xeb58, }; +/* MAC OCP indirect access via the MACOCP register */ +#define RTL8125_OCP_WRITE 0x80000000 +#define RTL8125_OCP_ADDR_SHIFT 16 +#define RX_DESC_CRC_DROP BIT(0) +#define RX_DESC_TYPE BIT(1) + +/* TX_DESC_MODE (MAC OCP 0xeb58): TX descriptor format select, bits [1:0] */ +#define TX_DESC_FMT_MASK GENMASK(1, 0) +#define TX_DESC_FMT_STD BIT(0) +#define TX_DESC_FMT_V3 BIT(1) +#define RX_PAUSE_SLOT_ON BIT(11) + enum RTL8169_register_content { /*InterruptStatusBits */ SYSErr = 0x8000, @@ -271,6 +288,8 @@ static struct { {"RTL-8168h/8111h", 0x54, 0xff7e1880,}, {"RTL-8125B", 0x64, 0xff7e1880,}, {"RTL-8125d", 0x6a, 0xff7e5880,}, + {"RTL-8126A", 0x66, 0xff7e5880,}, + {"RTL-8127A", 0x6e, 0xff7e5880,}, }; enum _DescStatusBit { @@ -355,6 +374,8 @@ static const unsigned int rtl8169_rx_config = static struct pci_device_id supported[] = { { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8125) }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8126) }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8127) }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8161) }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167) }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168) }, @@ -398,6 +419,33 @@ int mdio_read(int RegAddr) return value; } +/* RTL8125/8126/8127 share the same register layout and quirks */ +static bool rtl_is_8125(struct pci_child_plat *pplat) +{ + return pplat->device == 0x8125 || pplat->device == 0x8126 || + pplat->device == 0x8127; +} + +static void rtl_mac_ocp_write(u16 reg_addr, u16 value) +{ + u32 data32; + + data32 = (u32)(reg_addr / 2) << RTL8125_OCP_ADDR_SHIFT; + data32 += value; + data32 |= RTL8125_OCP_WRITE; + RTL_W32(MACOCP, data32); +} + +static u16 rtl_mac_ocp_read(u16 reg_addr) +{ + u32 data32; + + data32 = (u32)(reg_addr / 2) << RTL8125_OCP_ADDR_SHIFT; + RTL_W32(MACOCP, data32); + + return (u16)RTL_R32(MACOCP); +} + static int rtl8169_init_board(unsigned long dev_iobase, const char *name) { int i; @@ -571,12 +619,15 @@ static int rtl_recv_common(struct udevice *dev, unsigned long dev_iobase, return length; } else { - u32 IntrStatus = IntrStatus_8169; + u32 sts; - if (pplat->device == 0x8125) - IntrStatus = IntrStatus_8125; - ushort sts = RTL_R8(IntrStatus); - RTL_W8(IntrStatus, sts & ~(TxErr | RxErr | SYSErr)); + if (rtl_is_8125(pplat)) { + sts = RTL_R32(IntrStatus_8125); + RTL_W32(IntrStatus_8125, sts & ~(TxErr | RxErr | SYSErr)); + } else { + sts = RTL_R16(IntrStatus_8169); + RTL_W16(IntrStatus_8169, sts & ~(TxErr | RxErr | SYSErr)); + } udelay(100); /* wait */ } tpc->cur_rx = cur_rx; @@ -636,8 +687,8 @@ static int rtl_send_common(struct udevice *dev, unsigned long dev_iobase, ((len > ETH_ZLEN) ? len : ETH_ZLEN)); } rtl_flush_tx_desc(&tpc->TxDescArray[entry]); - if (pplat->device == 0x8125) - RTL_W8(TxPoll_8125, 0x1); /* set polling bit */ + if (rtl_is_8125(pplat)) + RTL_W32(TxPoll_8125, 0x1); /* set polling bit */ else RTL_W8(TxPoll_8169, 0x40); /* set polling bit */ @@ -697,6 +748,8 @@ static void rtl8169_set_rx_mode(void) static void rtl8169_hw_start(struct udevice *dev) { + u8 version = rtl_chip_info[tpc->chipset].version; + u16 tx_desc_mode; u32 i; #ifdef DEBUG_RTL8169 @@ -719,6 +772,36 @@ static void rtl8169_hw_start(struct udevice *dev) RTL_W8(Cfg9346, Cfg9346_Unlock); + /* + * RTL8125D/8126A/8127A require explicit descriptor-type and CRC-drop setup. + * RTL8125B (0x64) is intentionally excluded to avoid regressing working hardware. + */ + switch (version) { + case 0x6a: + case 0x66: + case 0x6e: + /* Reg 0xD8: Disable CRC drop and force legacy 16-byte RX desc */ + RTL_W8(RX_DESC_MODE, RTL_R8(RX_DESC_MODE) & ~(RX_DESC_CRC_DROP | RX_DESC_TYPE)); + + /* RxConfig 0x44: enable RX pause slot (RTL8125B and later) */ + RTL_W32(RxConfig, RTL_R32(RxConfig) | RX_PAUSE_SLOT_ON); + + /* MAC OCP 0xEB58: TX descriptor format setup */ + tx_desc_mode = rtl_mac_ocp_read(TX_DESC_MODE) & ~TX_DESC_FMT_MASK; + + if (version == 0x6e) { + /* RTL8127A specific: Tx desc V3 and RADM FIFO protection */ + rtl_mac_ocp_write(TX_DESC_MODE, tx_desc_mode | TX_DESC_FMT_V3); + RTL_W16(RADMFIFO_PROTECT, 0x2001); + } else { + /* RTL8125D / RTL8126A specific: standard Tx desc */ + rtl_mac_ocp_write(TX_DESC_MODE, tx_desc_mode | TX_DESC_FMT_STD); + } + break; + default: + break; + } + /* RTL-8169sb/8110sb or previous version */ if (tpc->chipset <= 5) RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); @@ -860,8 +943,8 @@ static void rtl_halt_common(struct udevice *dev) RTL_W8(ChipCmd, 0x00); /* Disable interrupts by clearing the interrupt mask. */ - if (pplat->device == 0x8125) - RTL_W16(IntrMask_8125, 0x0000); + if (rtl_is_8125(pplat)) + RTL_W32(IntrMask_8125, 0x00000000); else RTL_W16(IntrMask_8169, 0x0000); @@ -1052,6 +1135,8 @@ static int rtl8169_eth_probe(struct udevice *dev) switch (pplat->device) { case 0x8125: + case 0x8126: + case 0x8127: case 0x8161: case 0x8168: region = 2; -- 2.43.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* RE: [PATCH next v1] net: rtl8169: add support for RTL8126A and RTL8127A 2026-07-22 7:50 [PATCH next v1] net: rtl8169: add support for RTL8126A and RTL8127A javen via U-Boot @ 2026-07-29 7:27 ` Javen 2026-08-03 12:45 ` Jerome Forissier 2026-08-04 8:54 ` Jerome Forissier 1 sibling, 1 reply; 5+ messages in thread From: Javen @ 2026-07-29 7:27 UTC (permalink / raw) To: Javen, trini@konsulko.com, joe.hershberger@ni.com, rfried.dev@gmail.com Cc: u-boot@lists.u-boot-project.org, nd@arm.com >RTL8126A and RTL8127A share most of the register layouts and quirks with >RTL8125 series, but require explicit desc type and CRC-drop setup during init. > >This patch adds PCI IDs and MAC versions. RTL8126A is 0x66 and RTL8127A is >0x6e. And RTL8127A requires Tx Desc V3 format and an additional RADM FIFO >protection configuration according to vendor driver. > >Signed-off-by: Javen Xu <javen_xu@realsil.com.cn> >--- > drivers/net/rtl8169.c | 103 ++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 94 insertions(+), 9 deletions(-) > >diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index >5b093623619..a24cff97801 100644 >--- a/drivers/net/rtl8169.c >+++ b/drivers/net/rtl8169.c >@@ -49,6 +49,7 @@ > #include <asm/cache.h> > #include <asm/io.h> > #include <pci.h> >+#include <linux/bitops.h> > #include <linux/delay.h> > #include <linux/printk.h> > >@@ -152,8 +153,24 @@ enum RTL8125_registers { > IntrMask_8125 = 0x38, > IntrStatus_8125 = 0x3C, > TxPoll_8125 = 0x90, >+ RX_DESC_MODE = 0xd8, >+ MACOCP = 0xb0, >+ RADMFIFO_PROTECT = 0x0402, >+ TX_DESC_MODE = 0xeb58, > }; > >+/* MAC OCP indirect access via the MACOCP register */ >+#define RTL8125_OCP_WRITE 0x80000000 >+#define RTL8125_OCP_ADDR_SHIFT 16 >+#define RX_DESC_CRC_DROP BIT(0) >+#define RX_DESC_TYPE BIT(1) >+ >+/* TX_DESC_MODE (MAC OCP 0xeb58): TX descriptor format select, bits [1:0] >*/ >+#define TX_DESC_FMT_MASK GENMASK(1, 0) >+#define TX_DESC_FMT_STD BIT(0) >+#define TX_DESC_FMT_V3 BIT(1) >+#define RX_PAUSE_SLOT_ON BIT(11) >+ > enum RTL8169_register_content { > /*InterruptStatusBits */ > SYSErr = 0x8000, >@@ -271,6 +288,8 @@ static struct { > {"RTL-8168h/8111h", 0x54, 0xff7e1880,}, > {"RTL-8125B", 0x64, 0xff7e1880,}, > {"RTL-8125d", 0x6a, 0xff7e5880,}, >+ {"RTL-8126A", 0x66, 0xff7e5880,}, >+ {"RTL-8127A", 0x6e, 0xff7e5880,}, > }; > > enum _DescStatusBit { >@@ -355,6 +374,8 @@ static const unsigned int rtl8169_rx_config = > > static struct pci_device_id supported[] = { > { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8125) }, >+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8126) }, >+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8127) }, > { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8161) }, > { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167) }, > { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168) }, @@ -398,6 +419,33 >@@ int mdio_read(int RegAddr) > return value; > } > >+/* RTL8125/8126/8127 share the same register layout and quirks */ >+static bool rtl_is_8125(struct pci_child_plat *pplat) { >+ return pplat->device == 0x8125 || pplat->device == 0x8126 || >+ pplat->device == 0x8127; >+} >+ >+static void rtl_mac_ocp_write(u16 reg_addr, u16 value) { >+ u32 data32; >+ >+ data32 = (u32)(reg_addr / 2) << RTL8125_OCP_ADDR_SHIFT; >+ data32 += value; >+ data32 |= RTL8125_OCP_WRITE; >+ RTL_W32(MACOCP, data32); >+} >+ >+static u16 rtl_mac_ocp_read(u16 reg_addr) { >+ u32 data32; >+ >+ data32 = (u32)(reg_addr / 2) << RTL8125_OCP_ADDR_SHIFT; >+ RTL_W32(MACOCP, data32); >+ >+ return (u16)RTL_R32(MACOCP); >+} >+ > static int rtl8169_init_board(unsigned long dev_iobase, const char *name) { > int i; >@@ -571,12 +619,15 @@ static int rtl_recv_common(struct udevice *dev, >unsigned long dev_iobase, > return length; > > } else { >- u32 IntrStatus = IntrStatus_8169; >+ u32 sts; > >- if (pplat->device == 0x8125) >- IntrStatus = IntrStatus_8125; >- ushort sts = RTL_R8(IntrStatus); >- RTL_W8(IntrStatus, sts & ~(TxErr | RxErr | SYSErr)); >+ if (rtl_is_8125(pplat)) { >+ sts = RTL_R32(IntrStatus_8125); >+ RTL_W32(IntrStatus_8125, sts & ~(TxErr | RxErr | >SYSErr)); >+ } else { >+ sts = RTL_R16(IntrStatus_8169); >+ RTL_W16(IntrStatus_8169, sts & ~(TxErr | RxErr | >SYSErr)); >+ } > udelay(100); /* wait */ > } > tpc->cur_rx = cur_rx; >@@ -636,8 +687,8 @@ static int rtl_send_common(struct udevice *dev, >unsigned long dev_iobase, > ((len > ETH_ZLEN) ? len : ETH_ZLEN)); > } > rtl_flush_tx_desc(&tpc->TxDescArray[entry]); >- if (pplat->device == 0x8125) >- RTL_W8(TxPoll_8125, 0x1); /* set polling bit */ >+ if (rtl_is_8125(pplat)) >+ RTL_W32(TxPoll_8125, 0x1); /* set polling bit */ > else > RTL_W8(TxPoll_8169, 0x40); /* set polling bit */ > >@@ -697,6 +748,8 @@ static void rtl8169_set_rx_mode(void) > > static void rtl8169_hw_start(struct udevice *dev) { >+ u8 version = rtl_chip_info[tpc->chipset].version; >+ u16 tx_desc_mode; > u32 i; > > #ifdef DEBUG_RTL8169 >@@ -719,6 +772,36 @@ static void rtl8169_hw_start(struct udevice *dev) > > RTL_W8(Cfg9346, Cfg9346_Unlock); > >+ /* >+ * RTL8125D/8126A/8127A require explicit descriptor-type and CRC- >drop setup. >+ * RTL8125B (0x64) is intentionally excluded to avoid regressing >working hardware. >+ */ >+ switch (version) { >+ case 0x6a: >+ case 0x66: >+ case 0x6e: >+ /* Reg 0xD8: Disable CRC drop and force legacy 16-byte RX >desc */ >+ RTL_W8(RX_DESC_MODE, RTL_R8(RX_DESC_MODE) & >~(RX_DESC_CRC_DROP | >+RX_DESC_TYPE)); >+ >+ /* RxConfig 0x44: enable RX pause slot (RTL8125B and later) */ >+ RTL_W32(RxConfig, RTL_R32(RxConfig) | RX_PAUSE_SLOT_ON); >+ >+ /* MAC OCP 0xEB58: TX descriptor format setup */ >+ tx_desc_mode = rtl_mac_ocp_read(TX_DESC_MODE) & >~TX_DESC_FMT_MASK; >+ >+ if (version == 0x6e) { >+ /* RTL8127A specific: Tx desc V3 and RADM FIFO >protection */ >+ rtl_mac_ocp_write(TX_DESC_MODE, tx_desc_mode | >TX_DESC_FMT_V3); >+ RTL_W16(RADMFIFO_PROTECT, 0x2001); >+ } else { >+ /* RTL8125D / RTL8126A specific: standard Tx desc */ >+ rtl_mac_ocp_write(TX_DESC_MODE, tx_desc_mode | >TX_DESC_FMT_STD); >+ } >+ break; >+ default: >+ break; >+ } >+ > /* RTL-8169sb/8110sb or previous version */ > if (tpc->chipset <= 5) > RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); @@ -860,8 >+943,8 @@ static void rtl_halt_common(struct udevice *dev) > RTL_W8(ChipCmd, 0x00); > > /* Disable interrupts by clearing the interrupt mask. */ >- if (pplat->device == 0x8125) >- RTL_W16(IntrMask_8125, 0x0000); >+ if (rtl_is_8125(pplat)) >+ RTL_W32(IntrMask_8125, 0x00000000); > else > RTL_W16(IntrMask_8169, 0x0000); > >@@ -1052,6 +1135,8 @@ static int rtl8169_eth_probe(struct udevice *dev) > > switch (pplat->device) { > case 0x8125: >+ case 0x8126: >+ case 0x8127: > case 0x8161: > case 0x8168: > region = 2; >-- >2.43.0 Hi, all Just a gentle ping for this patch. I am reaching out to see if any had a chance to review this patch. I wonder if there is anything I need to modify, clarify, or if I missed any submission guidelines. Thanks. BRs, Javen Xu ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH next v1] net: rtl8169: add support for RTL8126A and RTL8127A 2026-07-29 7:27 ` Javen @ 2026-08-03 12:45 ` Jerome Forissier 2026-08-04 2:26 ` Javen 0 siblings, 1 reply; 5+ messages in thread From: Jerome Forissier @ 2026-08-03 12:45 UTC (permalink / raw) To: Javen, trini@konsulko.com, joe.hershberger@ni.com, rfried.dev@gmail.com Cc: u-boot@lists.u-boot-project.org, nd@arm.com Hi Javen, On 29/07/2026 09:27, Javen wrote: >> RTL8126A and RTL8127A share most of the register layouts and quirks with >> RTL8125 series, but require explicit desc type and CRC-drop setup during init. >> >> This patch adds PCI IDs and MAC versions. RTL8126A is 0x66 and RTL8127A is >> 0x6e. And RTL8127A requires Tx Desc V3 format and an additional RADM FIFO >> protection configuration according to vendor driver. >> >> Signed-off-by: Javen Xu <javen_xu@realsil.com.cn> >> --- >> drivers/net/rtl8169.c | 103 ++++++++++++++++++++++++++++++++++++++---- >> 1 file changed, 94 insertions(+), 9 deletions(-) >> >> diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index >> 5b093623619..a24cff97801 100644 >> --- a/drivers/net/rtl8169.c >> +++ b/drivers/net/rtl8169.c >> @@ -49,6 +49,7 @@ >> #include <asm/cache.h> >> #include <asm/io.h> >> #include <pci.h> >> +#include <linux/bitops.h> >> #include <linux/delay.h> >> #include <linux/printk.h> >> >> @@ -152,8 +153,24 @@ enum RTL8125_registers { >> IntrMask_8125 = 0x38, >> IntrStatus_8125 = 0x3C, >> TxPoll_8125 = 0x90, >> + RX_DESC_MODE = 0xd8, >> + MACOCP = 0xb0, >> + RADMFIFO_PROTECT = 0x0402, >> + TX_DESC_MODE = 0xeb58, >> }; >> >> +/* MAC OCP indirect access via the MACOCP register */ >> +#define RTL8125_OCP_WRITE 0x80000000 >> +#define RTL8125_OCP_ADDR_SHIFT 16 >> +#define RX_DESC_CRC_DROP BIT(0) >> +#define RX_DESC_TYPE BIT(1) >> + >> +/* TX_DESC_MODE (MAC OCP 0xeb58): TX descriptor format select, bits [1:0] >> */ >> +#define TX_DESC_FMT_MASK GENMASK(1, 0) >> +#define TX_DESC_FMT_STD BIT(0) >> +#define TX_DESC_FMT_V3 BIT(1) >> +#define RX_PAUSE_SLOT_ON BIT(11) >> + >> enum RTL8169_register_content { >> /*InterruptStatusBits */ >> SYSErr = 0x8000, >> @@ -271,6 +288,8 @@ static struct { >> {"RTL-8168h/8111h", 0x54, 0xff7e1880,}, >> {"RTL-8125B", 0x64, 0xff7e1880,}, >> {"RTL-8125d", 0x6a, 0xff7e5880,}, >> + {"RTL-8126A", 0x66, 0xff7e5880,}, >> + {"RTL-8127A", 0x6e, 0xff7e5880,}, >> }; >> >> enum _DescStatusBit { >> @@ -355,6 +374,8 @@ static const unsigned int rtl8169_rx_config = >> >> static struct pci_device_id supported[] = { >> { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8125) }, >> + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8126) }, >> + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8127) }, >> { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8161) }, >> { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167) }, >> { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168) }, @@ -398,6 +419,33 >> @@ int mdio_read(int RegAddr) >> return value; >> } >> >> +/* RTL8125/8126/8127 share the same register layout and quirks */ >> +static bool rtl_is_8125(struct pci_child_plat *pplat) { >> + return pplat->device == 0x8125 || pplat->device == 0x8126 || >> + pplat->device == 0x8127; >> +} >> + >> +static void rtl_mac_ocp_write(u16 reg_addr, u16 value) { >> + u32 data32; >> + >> + data32 = (u32)(reg_addr / 2) << RTL8125_OCP_ADDR_SHIFT; >> + data32 += value; >> + data32 |= RTL8125_OCP_WRITE; >> + RTL_W32(MACOCP, data32); >> +} >> + >> +static u16 rtl_mac_ocp_read(u16 reg_addr) { >> + u32 data32; >> + >> + data32 = (u32)(reg_addr / 2) << RTL8125_OCP_ADDR_SHIFT; >> + RTL_W32(MACOCP, data32); >> + >> + return (u16)RTL_R32(MACOCP); >> +} >> + >> static int rtl8169_init_board(unsigned long dev_iobase, const char *name) { >> int i; >> @@ -571,12 +619,15 @@ static int rtl_recv_common(struct udevice *dev, >> unsigned long dev_iobase, >> return length; >> >> } else { >> - u32 IntrStatus = IntrStatus_8169; >> + u32 sts; >> >> - if (pplat->device == 0x8125) >> - IntrStatus = IntrStatus_8125; >> - ushort sts = RTL_R8(IntrStatus); >> - RTL_W8(IntrStatus, sts & ~(TxErr | RxErr | SYSErr)); >> + if (rtl_is_8125(pplat)) { >> + sts = RTL_R32(IntrStatus_8125); >> + RTL_W32(IntrStatus_8125, sts & ~(TxErr | RxErr | >> SYSErr)); >> + } else { >> + sts = RTL_R16(IntrStatus_8169); >> + RTL_W16(IntrStatus_8169, sts & ~(TxErr | RxErr | >> SYSErr)); >> + } >> udelay(100); /* wait */ >> } >> tpc->cur_rx = cur_rx; >> @@ -636,8 +687,8 @@ static int rtl_send_common(struct udevice *dev, >> unsigned long dev_iobase, >> ((len > ETH_ZLEN) ? len : ETH_ZLEN)); >> } >> rtl_flush_tx_desc(&tpc->TxDescArray[entry]); >> - if (pplat->device == 0x8125) >> - RTL_W8(TxPoll_8125, 0x1); /* set polling bit */ >> + if (rtl_is_8125(pplat)) >> + RTL_W32(TxPoll_8125, 0x1); /* set polling bit */ >> else >> RTL_W8(TxPoll_8169, 0x40); /* set polling bit */ >> >> @@ -697,6 +748,8 @@ static void rtl8169_set_rx_mode(void) >> >> static void rtl8169_hw_start(struct udevice *dev) { >> + u8 version = rtl_chip_info[tpc->chipset].version; >> + u16 tx_desc_mode; >> u32 i; >> >> #ifdef DEBUG_RTL8169 >> @@ -719,6 +772,36 @@ static void rtl8169_hw_start(struct udevice *dev) >> >> RTL_W8(Cfg9346, Cfg9346_Unlock); >> >> + /* >> + * RTL8125D/8126A/8127A require explicit descriptor-type and CRC- >> drop setup. >> + * RTL8125B (0x64) is intentionally excluded to avoid regressing >> working hardware. >> + */ >> + switch (version) { >> + case 0x6a: >> + case 0x66: >> + case 0x6e: >> + /* Reg 0xD8: Disable CRC drop and force legacy 16-byte RX >> desc */ >> + RTL_W8(RX_DESC_MODE, RTL_R8(RX_DESC_MODE) & >> ~(RX_DESC_CRC_DROP | >> +RX_DESC_TYPE)); >> + >> + /* RxConfig 0x44: enable RX pause slot (RTL8125B and later) */ >> + RTL_W32(RxConfig, RTL_R32(RxConfig) | RX_PAUSE_SLOT_ON); >> + >> + /* MAC OCP 0xEB58: TX descriptor format setup */ >> + tx_desc_mode = rtl_mac_ocp_read(TX_DESC_MODE) & >> ~TX_DESC_FMT_MASK; >> + >> + if (version == 0x6e) { >> + /* RTL8127A specific: Tx desc V3 and RADM FIFO >> protection */ >> + rtl_mac_ocp_write(TX_DESC_MODE, tx_desc_mode | >> TX_DESC_FMT_V3); >> + RTL_W16(RADMFIFO_PROTECT, 0x2001); >> + } else { >> + /* RTL8125D / RTL8126A specific: standard Tx desc */ >> + rtl_mac_ocp_write(TX_DESC_MODE, tx_desc_mode | >> TX_DESC_FMT_STD); >> + } >> + break; >> + default: >> + break; >> + } >> + >> /* RTL-8169sb/8110sb or previous version */ >> if (tpc->chipset <= 5) >> RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); @@ -860,8 >> +943,8 @@ static void rtl_halt_common(struct udevice *dev) >> RTL_W8(ChipCmd, 0x00); >> >> /* Disable interrupts by clearing the interrupt mask. */ >> - if (pplat->device == 0x8125) >> - RTL_W16(IntrMask_8125, 0x0000); >> + if (rtl_is_8125(pplat)) >> + RTL_W32(IntrMask_8125, 0x00000000); >> else >> RTL_W16(IntrMask_8169, 0x0000); >> >> @@ -1052,6 +1135,8 @@ static int rtl8169_eth_probe(struct udevice *dev) >> >> switch (pplat->device) { >> case 0x8125: >> + case 0x8126: >> + case 0x8127: >> case 0x8161: >> case 0x8168: >> region = 2; >> -- >> 2.43.0 > > > Hi, all > > Just a gentle ping for this patch. > I am reaching out to see if any had a chance to review this patch. I wonder if there is anything I need to modify, clarify, or if I missed any submission guidelines. Thanks. I don't know this driver nor the chips so I'm afraid I can't give useful feedback. Can you please explain how you tested the change? Thanks, -- Jerome ^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [PATCH next v1] net: rtl8169: add support for RTL8126A and RTL8127A 2026-08-03 12:45 ` Jerome Forissier @ 2026-08-04 2:26 ` Javen 0 siblings, 0 replies; 5+ messages in thread From: Javen @ 2026-08-04 2:26 UTC (permalink / raw) To: Jerome Forissier, trini@konsulko.com, joe.hershberger@ni.com, rfried.dev@gmail.com Cc: u-boot@lists.u-boot-project.org, nd@arm.com Hi Jerome, > >Hi Javen, > >On 29/07/2026 09:27, Javen wrote: >>> RTL8126A and RTL8127A share most of the register layouts and quirks >>> with >>> RTL8125 series, but require explicit desc type and CRC-drop setup during >init. >>> >>> This patch adds PCI IDs and MAC versions. RTL8126A is 0x66 and >>> RTL8127A is 0x6e. And RTL8127A requires Tx Desc V3 format and an >>> additional RADM FIFO protection configuration according to vendor driver. >>> >>> Signed-off-by: Javen Xu <javen_xu@realsil.com.cn> >>> --- >>> drivers/net/rtl8169.c | 103 >>> ++++++++++++++++++++++++++++++++++++++---- >>> 1 file changed, 94 insertions(+), 9 deletions(-) >>> >>> diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index >>> 5b093623619..a24cff97801 100644 >>> --- a/drivers/net/rtl8169.c >>> +++ b/drivers/net/rtl8169.c >>> @@ -49,6 +49,7 @@ >>> #include <asm/cache.h> >>> #include <asm/io.h> >>> #include <pci.h> >>> +#include <linux/bitops.h> >>> #include <linux/delay.h> >>> #include <linux/printk.h> >>> >>> @@ -152,8 +153,24 @@ enum RTL8125_registers { >>> IntrMask_8125 = 0x38, >>> IntrStatus_8125 = 0x3C, >>> TxPoll_8125 = 0x90, >>> + RX_DESC_MODE = 0xd8, >>> + MACOCP = 0xb0, >>> + RADMFIFO_PROTECT = 0x0402, >>> + TX_DESC_MODE = 0xeb58, >>> }; These are the specific registers required for the RTL8126A/8127. MACOCP (0xb0) is used for indirect access to extended MAC registers, such as TX_DESC_MODE (0xeb58). >>> >>> +/* MAC OCP indirect access via the MACOCP register */ >>> +#define RTL8125_OCP_WRITE 0x80000000 >>> +#define RTL8125_OCP_ADDR_SHIFT 16 >>> +#define RX_DESC_CRC_DROP BIT(0) >>> +#define RX_DESC_TYPE BIT(1) >>> + >>> +/* TX_DESC_MODE (MAC OCP 0xeb58): TX descriptor format select, bits >>> +[1:0] >>> */ >>> +#define TX_DESC_FMT_MASK GENMASK(1, 0) >>> +#define TX_DESC_FMT_STD BIT(0) >>> +#define TX_DESC_FMT_V3 BIT(1) >>> +#define RX_PAUSE_SLOT_ON BIT(11) >>> + >>> enum RTL8169_register_content { >>> /*InterruptStatusBits */ >>> SYSErr = 0x8000, >>> @@ -271,6 +288,8 @@ static struct { >>> {"RTL-8168h/8111h", 0x54, 0xff7e1880,}, >>> {"RTL-8125B", 0x64, 0xff7e1880,}, >>> {"RTL-8125d", 0x6a, 0xff7e5880,}, >>> + {"RTL-8126A", 0x66, 0xff7e5880,}, >>> + {"RTL-8127A", 0x6e, 0xff7e5880,}, >>> }; >>> >>> enum _DescStatusBit { >>> @@ -355,6 +374,8 @@ static const unsigned int rtl8169_rx_config = >>> >>> static struct pci_device_id supported[] = { >>> { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8125) }, >>> + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8126) }, >>> + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8127) }, >>> { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8161) }, >>> { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167) }, >>> { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168) }, @@ -398,6 +419,33 >>> @@ int mdio_read(int RegAddr) >>> return value; >>> } >>> >>> +/* RTL8125/8126/8127 share the same register layout and quirks */ >>> +static bool rtl_is_8125(struct pci_child_plat *pplat) { >>> + return pplat->device == 0x8125 || pplat->device == 0x8126 || >>> + pplat->device == 0x8127; >>> +} >>> + >>> +static void rtl_mac_ocp_write(u16 reg_addr, u16 value) { >>> + u32 data32; >>> + >>> + data32 = (u32)(reg_addr / 2) << RTL8125_OCP_ADDR_SHIFT; >>> + data32 += value; >>> + data32 |= RTL8125_OCP_WRITE; >>> + RTL_W32(MACOCP, data32); >>> +} >>> + >>> +static u16 rtl_mac_ocp_read(u16 reg_addr) { >>> + u32 data32; >>> + >>> + data32 = (u32)(reg_addr / 2) << RTL8125_OCP_ADDR_SHIFT; >>> + RTL_W32(MACOCP, data32); >>> + >>> + return (u16)RTL_R32(MACOCP); >>> +} Newer Realtek chips require these helper functions to read/write extended registers indirectly via the MACOCP register. This is standard practice in our vendor driver. >>> + >>> static int rtl8169_init_board(unsigned long dev_iobase, const char *name) { >>> int i; >>> @@ -571,12 +619,15 @@ static int rtl_recv_common(struct udevice *dev, >>> unsigned long dev_iobase, >>> return length; >>> >>> } else { >>> - u32 IntrStatus = IntrStatus_8169; >>> + u32 sts; >>> >>> - if (pplat->device == 0x8125) >>> - IntrStatus = IntrStatus_8125; >>> - ushort sts = RTL_R8(IntrStatus); >>> - RTL_W8(IntrStatus, sts & ~(TxErr | RxErr | SYSErr)); >>> + if (rtl_is_8125(pplat)) { >>> + sts = RTL_R32(IntrStatus_8125); >>> + RTL_W32(IntrStatus_8125, sts & ~(TxErr | RxErr | >>> SYSErr)); >>> + } else { >>> + sts = RTL_R16(IntrStatus_8169); >>> + RTL_W16(IntrStatus_8169, sts & ~(TxErr | RxErr | >>> SYSErr)); >>> + } >>> udelay(100); /* wait */ >>> } RTL8125, 8126, and 8127 share the same base architecture. Unlike older 8169 chips that use 16-bit access, these newer chips require 32-bit I/O access for IntrStatus, IntrMask, and TxPoll. I grouped them using rtl_is_8125() to handle this difference properly. >>> tpc->cur_rx = cur_rx; >>> @@ -636,8 +687,8 @@ static int rtl_send_common(struct udevice *dev, >>> unsigned long dev_iobase, >>> ((len > ETH_ZLEN) ? len : ETH_ZLEN)); >>> } >>> rtl_flush_tx_desc(&tpc->TxDescArray[entry]); >>> - if (pplat->device == 0x8125) >>> - RTL_W8(TxPoll_8125, 0x1); /* set polling bit */ >>> + if (rtl_is_8125(pplat)) >>> + RTL_W32(TxPoll_8125, 0x1); /* set polling bit */ >>> else >>> RTL_W8(TxPoll_8169, 0x40); /* set polling bit */ >>> >>> @@ -697,6 +748,8 @@ static void rtl8169_set_rx_mode(void) >>> >>> static void rtl8169_hw_start(struct udevice *dev) { >>> + u8 version = rtl_chip_info[tpc->chipset].version; >>> + u16 tx_desc_mode; >>> u32 i; >>> >>> #ifdef DEBUG_RTL8169 >>> @@ -719,6 +772,36 @@ static void rtl8169_hw_start(struct udevice >>> *dev) >>> >>> RTL_W8(Cfg9346, Cfg9346_Unlock); >>> >>> + /* >>> + * RTL8125D/8126A/8127A require explicit descriptor-type and >>> + CRC- >>> drop setup. >>> + * RTL8125B (0x64) is intentionally excluded to avoid regressing >>> working hardware. >>> + */ >>> + switch (version) { >>> + case 0x6a: >>> + case 0x66: >>> + case 0x6e: >>> + /* Reg 0xD8: Disable CRC drop and force legacy 16-byte >>> + RX >>> desc */ >>> + RTL_W8(RX_DESC_MODE, RTL_R8(RX_DESC_MODE) & >>> ~(RX_DESC_CRC_DROP | >>> +RX_DESC_TYPE)); >>> + >>> + /* RxConfig 0x44: enable RX pause slot (RTL8125B and later) */ >>> + RTL_W32(RxConfig, RTL_R32(RxConfig) | RX_PAUSE_SLOT_ON); >>> + >>> + /* MAC OCP 0xEB58: TX descriptor format setup */ >>> + tx_desc_mode = rtl_mac_ocp_read(TX_DESC_MODE) & >>> ~TX_DESC_FMT_MASK; >>> + >>> + if (version == 0x6e) { >>> + /* RTL8127A specific: Tx desc V3 and RADM FIFO >>> protection */ >>> + rtl_mac_ocp_write(TX_DESC_MODE, tx_desc_mode | >>> TX_DESC_FMT_V3); >>> + RTL_W16(RADMFIFO_PROTECT, 0x2001); >>> + } else { >>> + /* RTL8125D / RTL8126A specific: standard Tx desc */ >>> + rtl_mac_ocp_write(TX_DESC_MODE, tx_desc_mode | >>> TX_DESC_FMT_STD); >>> + } >>> + break; >>> + default: >>> + break; >>> + } MAC version 0x6e is RTL8127A. According to the vendor driver, RTL8127A explicitly requires the newer V3 TX descriptor format. Also, writing 0x2001 to RADMFIFO_PROTECT (0x0402) is a hardware requirement to prevent FIFO overflow/underflow issues. RTL8126A (0x66) and RTL8125D (0x6a) just fall into the else branch to use the standard TX descriptor. >>> + >>> /* RTL-8169sb/8110sb or previous version */ >>> if (tpc->chipset <= 5) >>> RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); @@ -860,8 >>> +943,8 @@ static void rtl_halt_common(struct udevice *dev) >>> RTL_W8(ChipCmd, 0x00); >>> >>> /* Disable interrupts by clearing the interrupt mask. */ >>> - if (pplat->device == 0x8125) >>> - RTL_W16(IntrMask_8125, 0x0000); >>> + if (rtl_is_8125(pplat)) >>> + RTL_W32(IntrMask_8125, 0x00000000); >>> else >>> RTL_W16(IntrMask_8169, 0x0000); >>> >>> @@ -1052,6 +1135,8 @@ static int rtl8169_eth_probe(struct udevice >>> *dev) >>> >>> switch (pplat->device) { >>> case 0x8125: >>> + case 0x8126: >>> + case 0x8127: >>> case 0x8161: >>> case 0x8168: >>> region = 2; >>> -- >>> 2.43.0 >> >> >> Hi, all >> >> Just a gentle ping for this patch. >> I am reaching out to see if any had a chance to review this patch. I wonder if >there is anything I need to modify, clarify, or if I missed any submission >guidelines. Thanks. > >I don't know this driver nor the chips so I'm afraid I can't give useful feedback. >Can you please explain how you tested the change? I tested this patch directly on a Realtek development board (rtd1619bes) equipped with RTL8126A and RTL8127A PCIe network cards. Here are the specific testing steps I performed in the U-Boot environment: 1. PCI Enumeration & Initialization: Run the U-Boot `pci` command to dump the PCI list. This verified that the PCIe devices are correctly enumerated, and the driver successfully probes them by accurately matching the new PCI IDs (0x8126, 0x8127) and MAC versions. 2. Network Connectivity (Tx/Rx Path): Executed `ping 8.8.8.8` and verified consistent ICMP replies. This basic connectivity test confirms that the packet transmission and reception paths are working correctly. All the register can be found in Realtek vendor driver. Links: https://www.realtek.com/Download/List?cate_id=584 I hope this provides the context you need. Please let me know if there's anything else I should clarify. Thanks, Javen > >Thanks, >-- >Jerome ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH next v1] net: rtl8169: add support for RTL8126A and RTL8127A 2026-07-22 7:50 [PATCH next v1] net: rtl8169: add support for RTL8126A and RTL8127A javen via U-Boot 2026-07-29 7:27 ` Javen @ 2026-08-04 8:54 ` Jerome Forissier 1 sibling, 0 replies; 5+ messages in thread From: Jerome Forissier @ 2026-08-04 8:54 UTC (permalink / raw) To: trini, joe.hershberger, rfried.dev, Javen; +Cc: u-boot, nd On Wed, 22 Jul 2026 15:50:57 +0800, Javen wrote: > RTL8126A and RTL8127A share most of the register layouts and quirks with > RTL8125 series, but require explicit desc type and CRC-drop setup during > init. > > This patch adds PCI IDs and MAC versions. RTL8126A is 0x66 and RTL8127A > is 0x6e. And RTL8127A requires Tx Desc V3 format and an additional RADM > FIFO protection configuration according to vendor driver. > > [...] Applied to u-boot-net branch for-main, thanks! [1/1] net: rtl8169: add support for RTL8126A and RTL8127A commit: a1aaacc968ae995b7557a316907c2e2f073b1a17 Best regards, -- Jerome Forissier <jerome.forissier@arm.com> ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-08-04 8:54 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-22 7:50 [PATCH next v1] net: rtl8169: add support for RTL8126A and RTL8127A javen via U-Boot 2026-07-29 7:27 ` Javen 2026-08-03 12:45 ` Jerome Forissier 2026-08-04 2:26 ` Javen 2026-08-04 8:54 ` Jerome Forissier
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.