]> Git Repo - J-u-boot.git/blobdiff - drivers/net/rtl8169.c
Merge patch series "Add TI K3 PCIe Controller support for J7200"
[J-u-boot.git] / drivers / net / rtl8169.c
index 5ccdfdd68392040ce8866a2d98cbbcc45c3afb23..edcae88a3fc5be371da5e4fc91066a97685e82e4 100644 (file)
  * 26 August 2006 Mihai Georgian <[email protected]>
  * Modified to use le32_to_cpu and cpu_to_le32 properly
  */
-#include <common.h>
 #include <cpu_func.h>
 #include <dm.h>
 #include <errno.h>
+#include <log.h>
 #include <malloc.h>
 #include <memalign.h>
 #include <net.h>
-#ifndef CONFIG_DM_ETH
-#include <netdev.h>
-#endif
+#include <asm/cache.h>
 #include <asm/io.h>
 #include <pci.h>
+#include <linux/delay.h>
+#include <linux/printk.h>
 
 #undef DEBUG_RTL8169
 #undef DEBUG_RTL8169_TX
@@ -96,12 +96,12 @@ static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
 #define TX_TIMEOUT  (6*HZ)
 
 /* write/read MMIO register. Notice: {read,write}[wl] do the necessary swapping */
-#define RTL_W8(reg, val8)      writeb((val8), ioaddr + (reg))
-#define RTL_W16(reg, val16)    writew((val16), ioaddr + (reg))
-#define RTL_W32(reg, val32)    writel((val32), ioaddr + (reg))
-#define RTL_R8(reg)            readb(ioaddr + (reg))
-#define RTL_R16(reg)           readw(ioaddr + (reg))
-#define RTL_R32(reg)           readl(ioaddr + (reg))
+#define RTL_W8(reg, val8)      writeb((val8), (void *)(ioaddr + (reg)))
+#define RTL_W16(reg, val16)    writew((val16), (void *)(ioaddr + (reg)))
+#define RTL_W32(reg, val32)    writel((val32), (void *)(ioaddr + (reg)))
+#define RTL_R8(reg)            readb((void *)(ioaddr + (reg)))
+#define RTL_R16(reg)           readw((void *)(ioaddr + (reg)))
+#define RTL_R32(reg)           readl((void *)(ioaddr + (reg)))
 
 #define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)(unsigned long)dev->priv, \
        (pci_addr_t)(unsigned long)a)
@@ -118,9 +118,9 @@ enum RTL8169_registers {
        FLASH = 0x30,
        ERSR = 0x36,
        ChipCmd = 0x37,
-       TxPoll = 0x38,
-       IntrMask = 0x3C,
-       IntrStatus = 0x3E,
+       TxPoll_8169 = 0x38,
+       IntrMask_8169 = 0x3C,
+       IntrStatus_8169 = 0x3E,
        TxConfig = 0x40,
        RxConfig = 0x44,
        RxMissed = 0x4C,
@@ -148,6 +148,12 @@ enum RTL8169_registers {
        FuncForceEvent = 0xFC,
 };
 
+enum RTL8125_registers {
+       IntrMask_8125 = 0x38,
+       IntrStatus_8125 = 0x3C,
+       TxPoll_8125 = 0x90,
+};
+
 enum RTL8169_register_content {
        /*InterruptStatusBits */
        SYSErr = 0x8000,
@@ -237,6 +243,9 @@ enum RTL8169_register_content {
 
        /*_TBICSRBit*/
        TBILinkOK = 0x02000000,
+
+       /* FuncEvent/Misc */
+       RxDv_Gated_En = 0x80000,
 };
 
 static struct {
@@ -260,6 +269,7 @@ static struct {
        {"RTL-8101e",           0x34, 0xff7e1880,},
        {"RTL-8100e",           0x32, 0xff7e1880,},
        {"RTL-8168h/8111h",     0x54, 0xff7e1880,},
+       {"RTL-8125B",           0x64, 0xff7e1880,},
 };
 
 enum _DescStatusBit {
@@ -301,10 +311,12 @@ static unsigned char rxdata[RX_BUF_LEN];
  *
  * This can be fixed by defining CONFIG_SYS_NONCACHED_MEMORY which will cause
  * the driver to allocate descriptors from a pool of non-cached memory.
+ *
+ * Hardware maintain D-cache coherency in RISC-V architecture.
  */
 #if RTL8169_DESC_SIZE < ARCH_DMA_MINALIGN
 #if !defined(CONFIG_SYS_NONCACHED_MEMORY) && \
-       !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_X86)
+       !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_X86) && !defined(CONFIG_RISCV)
 #warning cache-line size is larger than descriptor size
 #endif
 #endif
@@ -341,6 +353,8 @@ static const unsigned int rtl8169_rx_config =
     (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
 
 static struct pci_device_id supported[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8125) },
+       { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8161) },
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167) },
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168) },
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169) },
@@ -508,17 +522,13 @@ static void rtl_flush_buffer(void *buf, size_t size)
 /**************************************************************************
 RECV - Receive a frame
 ***************************************************************************/
-#ifdef CONFIG_DM_ETH
 static int rtl_recv_common(struct udevice *dev, unsigned long dev_iobase,
                           uchar **packetp)
-#else
-static int rtl_recv_common(pci_dev_t dev, unsigned long dev_iobase,
-                          uchar **packetp)
-#endif
 {
        /* return true if there's an ethernet packet ready to read */
        /* nic->packet should contain data on return */
        /* nic->packetlen should contain length of data */
+       struct pci_child_plat *pplat = dev_get_parent_plat(dev);
        int cur_rx;
        int length = 0;
 
@@ -545,22 +555,12 @@ static int rtl_recv_common(pci_dev_t dev, unsigned long dev_iobase,
                        else
                                tpc->RxDescArray[cur_rx].status =
                                        cpu_to_le32(OWNbit + RX_BUF_SIZE);
-#ifdef CONFIG_DM_ETH
                        tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32(
                                dm_pci_mem_to_phys(dev,
                                        (pci_addr_t)(unsigned long)
                                        tpc->RxBufferRing[cur_rx]));
-#else
-                       tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32(
-                               pci_mem_to_phys(dev, (pci_addr_t)(unsigned long)
-                               tpc->RxBufferRing[cur_rx]));
-#endif
                        rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]);
-#ifdef CONFIG_DM_ETH
                        *packetp = rxdata;
-#else
-                       net_process_received_packet(rxdata, length);
-#endif
                } else {
                        puts("Error Rx");
                        length = -EIO;
@@ -570,6 +570,10 @@ static int rtl_recv_common(pci_dev_t dev, unsigned long dev_iobase,
                return length;
 
        } else {
+               u32 IntrStatus = IntrStatus_8169;
+
+               if (pplat->device == 0x8125)
+                       IntrStatus = IntrStatus_8125;
                ushort sts = RTL_R8(IntrStatus);
                RTL_W8(IntrStatus, sts & ~(TxErr | RxErr | SYSErr));
                udelay(100);    /* wait */
@@ -578,35 +582,23 @@ static int rtl_recv_common(pci_dev_t dev, unsigned long dev_iobase,
        return (0);             /* initially as this is called to flush the input */
 }
 
-#ifdef CONFIG_DM_ETH
 int rtl8169_eth_recv(struct udevice *dev, int flags, uchar **packetp)
 {
        struct rtl8169_private *priv = dev_get_priv(dev);
 
        return rtl_recv_common(dev, priv->iobase, packetp);
 }
-#else
-static int rtl_recv(struct eth_device *dev)
-{
-       return rtl_recv_common((pci_dev_t)(unsigned long)dev->priv,
-                              dev->iobase, NULL);
-}
-#endif /* nCONFIG_DM_ETH */
 
 #define HZ 1000
 /**************************************************************************
 SEND - Transmit a frame
 ***************************************************************************/
-#ifdef CONFIG_DM_ETH
 static int rtl_send_common(struct udevice *dev, unsigned long dev_iobase,
                           void *packet, int length)
-#else
-static int rtl_send_common(pci_dev_t dev, unsigned long dev_iobase,
-                          void *packet, int length)
-#endif
 {
        /* send the packet to destination */
 
+       struct pci_child_plat *pplat = dev_get_parent_plat(dev);
        u32 to;
        u8 *ptxb;
        int entry = tpc->cur_tx % NUM_TX_DESC;
@@ -631,13 +623,8 @@ static int rtl_send_common(pci_dev_t dev, unsigned long dev_iobase,
        rtl_flush_buffer(ptxb, ALIGN(len, RTL8169_ALIGN));
 
        tpc->TxDescArray[entry].buf_Haddr = 0;
-#ifdef CONFIG_DM_ETH
        tpc->TxDescArray[entry].buf_addr = cpu_to_le32(
                dm_pci_mem_to_phys(dev, (pci_addr_t)(unsigned long)ptxb));
-#else
-       tpc->TxDescArray[entry].buf_addr = cpu_to_le32(
-               pci_mem_to_phys(dev, (pci_addr_t)(unsigned long)ptxb));
-#endif
        if (entry != (NUM_TX_DESC - 1)) {
                tpc->TxDescArray[entry].status =
                        cpu_to_le32((OWNbit | FSbit | LSbit) |
@@ -648,7 +635,10 @@ static int rtl_send_common(pci_dev_t dev, unsigned long dev_iobase,
                                    ((len > ETH_ZLEN) ? len : ETH_ZLEN));
        }
        rtl_flush_tx_desc(&tpc->TxDescArray[entry]);
-       RTL_W8(TxPoll, 0x40);   /* set polling bit */
+       if (pplat->device == 0x8125)
+               RTL_W8(TxPoll_8125, 0x1);       /* set polling bit */
+       else
+               RTL_W8(TxPoll_8169, 0x40);      /* set polling bit */
 
        tpc->cur_tx++;
        to = currticks() + TX_TIMEOUT;
@@ -674,7 +664,6 @@ static int rtl_send_common(pci_dev_t dev, unsigned long dev_iobase,
        return ret;
 }
 
-#ifdef CONFIG_DM_ETH
 int rtl8169_eth_send(struct udevice *dev, void *packet, int length)
 {
        struct rtl8169_private *priv = dev_get_priv(dev);
@@ -682,14 +671,6 @@ int rtl8169_eth_send(struct udevice *dev, void *packet, int length)
        return rtl_send_common(dev, priv->iobase, packet, length);
 }
 
-#else
-static int rtl_send(struct eth_device *dev, void *packet, int length)
-{
-       return rtl_send_common((pci_dev_t)(unsigned long)dev->priv,
-                              dev->iobase, packet, length);
-}
-#endif
-
 static void rtl8169_set_rx_mode(void)
 {
        u32 mc_filter[2];       /* Multicast hash filter */
@@ -713,11 +694,7 @@ static void rtl8169_set_rx_mode(void)
        RTL_W32(MAR0 + 4, mc_filter[1]);
 }
 
-#ifdef CONFIG_DM_ETH
 static void rtl8169_hw_start(struct udevice *dev)
-#else
-static void rtl8169_hw_start(pci_dev_t dev)
-#endif
 {
        u32 i;
 
@@ -759,24 +736,13 @@ static void rtl8169_hw_start(pci_dev_t dev)
        RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
                                (InterFrameGap << TxInterFrameGapShift));
 
-
        tpc->cur_rx = 0;
 
-#ifdef CONFIG_DM_ETH
        RTL_W32(TxDescStartAddrLow, dm_pci_mem_to_phys(dev,
                        (pci_addr_t)(unsigned long)tpc->TxDescArray));
-#else
-       RTL_W32(TxDescStartAddrLow, pci_mem_to_phys(dev,
-                       (pci_addr_t)(unsigned long)tpc->TxDescArray));
-#endif
        RTL_W32(TxDescStartAddrHigh, (unsigned long)0);
-#ifdef CONFIG_DM_ETH
        RTL_W32(RxDescStartAddrLow, dm_pci_mem_to_phys(
                        dev, (pci_addr_t)(unsigned long)tpc->RxDescArray));
-#else
-       RTL_W32(RxDescStartAddrLow, pci_mem_to_phys(
-                       dev, (pci_addr_t)(unsigned long)tpc->RxDescArray));
-#endif
        RTL_W32(RxDescStartAddrHigh, (unsigned long)0);
 
        /* RTL-8169sc/8110sc or later version */
@@ -798,11 +764,7 @@ static void rtl8169_hw_start(pci_dev_t dev)
 #endif
 }
 
-#ifdef CONFIG_DM_ETH
 static void rtl8169_init_ring(struct udevice *dev)
-#else
-static void rtl8169_init_ring(pci_dev_t dev)
-#endif
 {
        int i;
 
@@ -830,13 +792,8 @@ static void rtl8169_init_ring(pci_dev_t dev)
                                cpu_to_le32(OWNbit + RX_BUF_SIZE);
 
                tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
-#ifdef CONFIG_DM_ETH
                tpc->RxDescArray[i].buf_addr = cpu_to_le32(dm_pci_mem_to_phys(
                        dev, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i]));
-#else
-               tpc->RxDescArray[i].buf_addr = cpu_to_le32(pci_mem_to_phys(
-                       dev, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i]));
-#endif
                rtl_flush_rx_desc(&tpc->RxDescArray[i]);
        }
 
@@ -845,13 +802,8 @@ static void rtl8169_init_ring(pci_dev_t dev)
 #endif
 }
 
-#ifdef CONFIG_DM_ETH
 static void rtl8169_common_start(struct udevice *dev, unsigned char *enetaddr,
                                 unsigned long dev_iobase)
-#else
-static void rtl8169_common_start(pci_dev_t dev, unsigned char *enetaddr,
-                                unsigned long dev_iobase)
-#endif
 {
        int i;
 
@@ -881,44 +833,36 @@ static void rtl8169_common_start(pci_dev_t dev, unsigned char *enetaddr,
 #endif
 }
 
-#ifdef CONFIG_DM_ETH
 static int rtl8169_eth_start(struct udevice *dev)
 {
-       struct eth_pdata *plat = dev_get_platdata(dev);
+       struct eth_pdata *plat = dev_get_plat(dev);
        struct rtl8169_private *priv = dev_get_priv(dev);
 
        rtl8169_common_start(dev, plat->enetaddr, priv->iobase);
 
        return 0;
 }
-#else
-/**************************************************************************
-RESET - Finish setting up the ethernet interface
-***************************************************************************/
-static int rtl_reset(struct eth_device *dev, bd_t *bis)
-{
-       rtl8169_common_start((pci_dev_t)(unsigned long)dev->priv,
-                            dev->enetaddr, dev->iobase);
-
-       return 0;
-}
-#endif /* nCONFIG_DM_ETH */
 
-static void rtl_halt_common(unsigned long dev_iobase)
+static void rtl_halt_common(struct udevice *dev)
 {
+       struct rtl8169_private *priv = dev_get_priv(dev);
+       struct pci_child_plat *pplat = dev_get_parent_plat(dev);
        int i;
 
 #ifdef DEBUG_RTL8169
        printf ("%s\n", __FUNCTION__);
 #endif
 
-       ioaddr = dev_iobase;
+       ioaddr = priv->iobase;
 
        /* Stop the chip's Tx and Rx DMA processes. */
        RTL_W8(ChipCmd, 0x00);
 
        /* Disable interrupts by clearing the interrupt mask. */
-       RTL_W16(IntrMask, 0x0000);
+       if (pplat->device == 0x8125)
+               RTL_W16(IntrMask_8125, 0x0000);
+       else
+               RTL_W16(IntrMask_8169, 0x0000);
 
        RTL_W32(RxMissed, 0);
 
@@ -927,27 +871,14 @@ static void rtl_halt_common(unsigned long dev_iobase)
        }
 }
 
-#ifdef CONFIG_DM_ETH
 void rtl8169_eth_stop(struct udevice *dev)
 {
-       struct rtl8169_private *priv = dev_get_priv(dev);
-
-       rtl_halt_common(priv->iobase);
+       rtl_halt_common(dev);
 }
-#else
-/**************************************************************************
-HALT - Turn off ethernet interface
-***************************************************************************/
-static void rtl_halt(struct eth_device *dev)
-{
-       rtl_halt_common(dev->iobase);
-}
-#endif
 
-#ifdef CONFIG_DM_ETH
 static int rtl8169_write_hwaddr(struct udevice *dev)
 {
-       struct eth_pdata *plat = dev_get_platdata(dev);
+       struct eth_pdata *plat = dev_get_plat(dev);
        unsigned int i;
 
        RTL_W8(Cfg9346, Cfg9346_Unlock);
@@ -959,7 +890,6 @@ static int rtl8169_write_hwaddr(struct udevice *dev)
 
        return 0;
 }
-#endif
 
 /**************************************************************************
 INIT - Look for an adapter, this routine's visible to the outside
@@ -1100,7 +1030,6 @@ static int rtl_init(unsigned long dev_ioaddr, const char *name,
 #endif
        }
 
-
        tpc->RxDescArray = rtl_alloc_descs(NUM_RX_DESC);
        if (!tpc->RxDescArray)
                return -ENOMEM;
@@ -1112,84 +1041,17 @@ static int rtl_init(unsigned long dev_ioaddr, const char *name,
        return 0;
 }
 
-#ifndef CONFIG_DM_ETH
-int rtl8169_initialize(bd_t *bis)
-{
-       pci_dev_t devno;
-       int card_number = 0;
-       struct eth_device *dev;
-       u32 iobase;
-       int idx=0;
-
-       while(1){
-               unsigned int region;
-               u16 device;
-               int err;
-
-               /* Find RTL8169 */
-               if ((devno = pci_find_devices(supported, idx++)) < 0)
-                       break;
-
-               pci_read_config_word(devno, PCI_DEVICE_ID, &device);
-               switch (device) {
-               case 0x8168:
-                       region = 2;
-                       break;
-
-               default:
-                       region = 1;
-                       break;
-               }
-
-               pci_read_config_dword(devno, PCI_BASE_ADDRESS_0 + (region * 4), &iobase);
-               iobase &= ~0xf;
-
-               debug ("rtl8169: REALTEK RTL8169 @0x%x\n", iobase);
-
-               dev = (struct eth_device *)malloc(sizeof *dev);
-               if (!dev) {
-                       printf("Can not allocate memory of rtl8169\n");
-                       break;
-               }
-
-               memset(dev, 0, sizeof(*dev));
-               sprintf (dev->name, "RTL8169#%d", card_number);
-
-               dev->priv = (void *)(unsigned long)devno;
-               dev->iobase = (int)pci_mem_to_phys(devno, iobase);
-
-               dev->init = rtl_reset;
-               dev->halt = rtl_halt;
-               dev->send = rtl_send;
-               dev->recv = rtl_recv;
-
-               err = rtl_init(dev->iobase, dev->name, dev->enetaddr);
-               if (err < 0) {
-                       printf(pr_fmt("failed to initialize card: %d\n"), err);
-                       free(dev);
-                       continue;
-               }
-
-               eth_register (dev);
-
-               card_number++;
-       }
-       return card_number;
-}
-#endif
-
-#ifdef CONFIG_DM_ETH
 static int rtl8169_eth_probe(struct udevice *dev)
 {
-       struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
+       struct pci_child_plat *pplat = dev_get_parent_plat(dev);
        struct rtl8169_private *priv = dev_get_priv(dev);
-       struct eth_pdata *plat = dev_get_platdata(dev);
-       u32 iobase;
+       struct eth_pdata *plat = dev_get_plat(dev);
        int region;
        int ret;
 
-       debug("rtl8169: REALTEK RTL8169 @0x%x\n", iobase);
        switch (pplat->device) {
+       case 0x8125:
+       case 0x8161:
        case 0x8168:
                region = 2;
                break;
@@ -1197,16 +1059,32 @@ static int rtl8169_eth_probe(struct udevice *dev)
                region = 1;
                break;
        }
-       dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0 + region * 4, &iobase);
-       iobase &= ~0xf;
-       priv->iobase = (int)dm_pci_mem_to_phys(dev, iobase);
 
+       priv->iobase = (ulong)dm_pci_map_bar(dev,
+                                            PCI_BASE_ADDRESS_0 + region * 4,
+                                            0, 0,
+                                            PCI_REGION_TYPE, PCI_REGION_MEM);
+
+       debug("rtl8169: REALTEK RTL8169 @0x%lx\n", priv->iobase);
        ret = rtl_init(priv->iobase, dev->name, plat->enetaddr);
        if (ret < 0) {
                printf(pr_fmt("failed to initialize card: %d\n"), ret);
                return ret;
        }
 
+       /*
+        * WAR for DHCP failure after rebooting from kernel.
+        * Clear RxDv_Gated_En bit which was set by kernel driver.
+        * Without this, U-Boot can't get an IP via DHCP.
+        * Register (FuncEvent, aka MISC) and RXDV_GATED_EN bit are from
+        * the r8169.c kernel driver.
+        */
+
+       u32 val = RTL_R32(FuncEvent);
+       debug("%s: FuncEvent/Misc (0xF0) = 0x%08X\n", __func__, val);
+       val &= ~RxDv_Gated_En;
+       RTL_W32(FuncEvent, val);
+
        return 0;
 }
 
@@ -1229,9 +1107,8 @@ U_BOOT_DRIVER(eth_rtl8169) = {
        .of_match = rtl8169_eth_ids,
        .probe  = rtl8169_eth_probe,
        .ops    = &rtl8169_eth_ops,
-       .priv_auto_alloc_size = sizeof(struct rtl8169_private),
-       .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+       .priv_auto      = sizeof(struct rtl8169_private),
+       .plat_auto      = sizeof(struct eth_pdata),
 };
 
 U_BOOT_PCI_DEVICE(eth_rtl8169, supported);
-#endif
This page took 0.037684 seconds and 4 git commands to generate.