All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.