]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/net/rtl8139.c
Merge branch 'master' of git://git.denx.de/u-boot-samsung
[karo-tx-uboot.git] / drivers / net / rtl8139.c
index 4c248054c3eb7f76b1d9917ead2497617f193bf3..c2779db0a5c20cadd55265e163feb671ce8445c6 100644 (file)
 #include <common.h>
 #include <malloc.h>
 #include <net.h>
+#include <netdev.h>
 #include <asm/io.h>
 #include <pci.h>
 
-#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
-       defined(CONFIG_RTL8139)
-
-#define TICKS_PER_SEC  CFG_HZ
-#define TICKS_PER_MS   (TICKS_PER_SEC/1000)
-
-#define RTL_TIMEOUT    (1*TICKS_PER_SEC)
+#define RTL_TIMEOUT    100000
 
 #define ETH_FRAME_LEN          1514
 #define ETH_ALEN               6
@@ -225,6 +220,11 @@ int rtl8139_initialize(bd_t *bis)
                debug ("rtl8139: REALTEK RTL8139 @0x%x\n", iobase);
 
                dev = (struct eth_device *)malloc(sizeof *dev);
+               if (!dev) {
+                       printf("Can not allocate memory of rtl8139\n");
+                       break;
+               }
+               memset(dev, 0, sizeof(*dev));
 
                sprintf (dev->name, "RTL8139#%d", card_number);
 
@@ -292,7 +292,7 @@ static int rtl8139_probe(struct eth_device *dev, bd_t *bis)
 
 /*
        Delay between EEPROM clock transitions.
-       No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
+       No extra delay is needed with 33MHz PCI, but 66MHz may change this.
 */
 
 #define eeprom_delay() inl(ee_addr)
@@ -392,6 +392,7 @@ static void rtl_reset(struct eth_device *dev)
 #ifdef DEBUG_RX
        printf("rx ring address is %X\n",(unsigned long)rx_ring);
 #endif
+       flush_cache((unsigned long)rx_ring, RX_BUF_LEN);
        outl(phys_to_bus((int)rx_ring), ioaddr + RxBuf);
 
        /* If we add multicast support, the MAR0 register would have to be
@@ -414,9 +415,10 @@ static void rtl_reset(struct eth_device *dev)
 
 static int rtl_transmit(struct eth_device *dev, volatile void *packet, int length)
 {
-       unsigned int status, to;
+       unsigned int status;
        unsigned long txstatus;
        unsigned int len = length;
+       int i = 0;
 
        ioaddr = dev->iobase;
 
@@ -432,12 +434,11 @@ static int rtl_transmit(struct eth_device *dev, volatile void *packet, int lengt
                tx_buffer[len++] = '\0';
        }
 
+       flush_cache((unsigned long)tx_buffer, length);
        outl(phys_to_bus((int)tx_buffer), ioaddr + TxAddr0 + cur_tx*4);
        outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len,
                ioaddr + TxStatus0 + cur_tx*4);
 
-       to = currticks() + RTL_TIMEOUT;
-
        do {
                status = inw(ioaddr + IntrStatus);
                /* Only acknlowledge interrupt sources we can properly handle
@@ -445,7 +446,8 @@ static int rtl_transmit(struct eth_device *dev, volatile void *packet, int lengt
                 * rtl_poll() function.  */
                outw(status & (TxOK | TxErr | PCIErr), ioaddr + IntrStatus);
                if ((status & (TxOK | TxErr | PCIErr)) != 0) break;
-       } while (currticks() < to);
+               udelay(10);
+       } while (i++ < RTL_TIMEOUT);
 
        txstatus = inl(ioaddr + TxStatus0 + cur_tx*4);
 
@@ -458,8 +460,8 @@ static int rtl_transmit(struct eth_device *dev, volatile void *packet, int lengt
                return length;
        } else {
 #ifdef DEBUG_TX
-               printf("tx timeout/error (%d ticks), status %hX txstatus %X\n",
-                       currticks()-to, status, txstatus);
+               printf("tx timeout/error (%d usecs), status %hX txstatus %X\n",
+                      10*i, status, txstatus);
 #endif
                rtl_reset(dev);
 
@@ -489,7 +491,8 @@ static int rtl_poll(struct eth_device *dev)
 #endif
 
        ring_offs = cur_rx % RX_BUF_LEN;
-       rx_status = *(unsigned int*)KSEG1ADDR((rx_ring + ring_offs));
+       /* ring_offs is guaranteed being 4-byte aligned */
+       rx_status = le32_to_cpu(*(unsigned int *)(rx_ring + ring_offs));
        rx_size = rx_status >> 16;
        rx_status &= 0xffff;
 
@@ -519,6 +522,7 @@ static int rtl_poll(struct eth_device *dev)
                printf("rx packet %d bytes", rx_size-4);
 #endif
        }
+       flush_cache((unsigned long)rx_ring, RX_BUF_LEN);
 
        cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
        outw(cur_rx - 16, ioaddr + RxBufPtr);
@@ -544,4 +548,3 @@ static void rtl_disable(struct eth_device *dev)
                udelay (100); /* wait 100us */
        }
 }
-#endif