>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 <[email protected]>
>---
> 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

Reply via email to