Hi,
I'm trying to get a recent u-boot running properly on a QNAP
TurboStation TS-101/TS-201, and I'm having problems with the network
driver. When powered on, the device refuses to send anything to the
network on the first attempt (eg. first ping fails). The second and
subsequent attempts however, works perfectly.
With debugging switched on, the driver outputs the expected init output,
but on the first attempt appears to loop on "rtl_recv", outputting this
hundreds of times. (I don't have a debug log handy right now, but the
only difference is that instead of *one* rtl_recv, there are hundreds)
On the second attempt, there's only one rtl_recv.
Anyone got a clue as to what is going on?
I'm using the attached patch to correct endianness issues and add device
IDs.
Regards,
Øyvind Repvik
--- u-boot-1.3.1.orig/drivers/net/rtl8169.c 2007-12-06 10:21:19.000000000
+0100
+++ u-boot-1.3.1.ts/drivers/net/rtl8169.c 2008-02-24 17:48:40.000000000
+0100
@@ -48,7 +48,10 @@
*
* Indent Options: indent -kr -i8
***************************************************************************/
-
+/*
+ * 26 August 2006 Mihai Georgian <[EMAIL PROTECTED]>
+ * Modified to use le32_to_cpu and cpu_to_le32 properly
+ */
#include <common.h>
#include <malloc.h>
#include <net.h>
@@ -68,12 +71,7 @@
static u32 ioaddr;
/* Condensed operations for readability. */
-#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
-#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
-
#define currticks() get_timer(0)
-#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
-#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
/* media options */
#define MAX_UNITS 8
@@ -102,7 +100,7 @@
#define RTL_MIN_IO_SIZE 0x80
#define TX_TIMEOUT (6*HZ)
-/* write/read MMIO register */
+/* 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))
@@ -218,7 +216,7 @@
PHY_Enable_Auto_Nego = 0x1000,
/* PHY_STAT_REG = 1; */
- PHY_Auto_Neco_Comp = 0x0020,
+ PHY_Auto_Nego_Comp = 0x0020,
/* PHY_AUTO_NEGO_REG = 4; */
PHY_Cap_10_Half = 0x0020,
@@ -249,6 +247,16 @@
} rtl_chip_info[] = {
{"RTL-8169", 0x00, 0xff7e1880,},
{"RTL-8169", 0x04, 0xff7e1880,},
+ {"RTL8169", 0x00, 0xff7e1880,},
+ {"RTL8169s/8110s", 0x02, 0xff7e1880,},
+ {"RTL8169s/8110s", 0x04, 0xff7e1880,},
+ {"RTL8169sb/8110sb", 0x10, 0xff7e1880,},
+ {"RTL8169sc/8110sc", 0x18, 0xff7e1880,},
+ {"RTL8168b/8111sb", 0x30, 0xff7e1880,},
+ {"RTL8168b/8111sb", 0x38, 0xff7e1880,},
+ {"RTL8101e", 0x34, 0xff7e1880,},
+ {"RTL8100e", 0x32, 0xff7e1880,},
+
};
enum _DescStatusBit {
@@ -315,7 +323,7 @@
static struct pci_device_id supported[] = {
{PCI_VENDOR_ID_REALTEK, 0x8169},
- {}
+ {PCI_VENDOR_ID_REALTEK, 0x8167}
};
void mdio_write(int RegAddr, int value)
@@ -413,23 +421,23 @@
ioaddr = dev->iobase;
cur_rx = tpc->cur_rx;
- if ((tpc->RxDescArray[cur_rx].status & OWNbit) == 0) {
- if (!(tpc->RxDescArray[cur_rx].status & RxRES)) {
+ if ((le32_to_cpu(tpc->RxDescArray[cur_rx].status) & OWNbit) == 0) {
+ if (!(le32_to_cpu(tpc->RxDescArray[cur_rx].status) & RxRES)) {
unsigned char rxdata[RX_BUF_LEN];
- length = (int) (tpc->RxDescArray[cur_rx].
- status & 0x00001FFF) - 4;
+ length = (int) (le32_to_cpu(tpc->RxDescArray[cur_rx].
+ status) & 0x00001FFF) - 4;
memcpy(rxdata, tpc->RxBufferRing[cur_rx], length);
NetReceive(rxdata, length);
if (cur_rx == NUM_RX_DESC - 1)
tpc->RxDescArray[cur_rx].status =
- (OWNbit | EORbit) + RX_BUF_SIZE;
+ cpu_to_le32((OWNbit | EORbit) +
RX_BUF_SIZE);
else
tpc->RxDescArray[cur_rx].status =
- OWNbit + RX_BUF_SIZE;
+ cpu_to_le32(OWNbit + RX_BUF_SIZE);
tpc->RxDescArray[cur_rx].buf_addr =
- virt_to_bus(tpc->RxBufferRing[cur_rx]);
+ cpu_to_le32(tpc->RxBufferRing[cur_rx]);
} else {
puts("Error Rx");
}
@@ -454,6 +462,7 @@
u8 *ptxb;
int entry = tpc->cur_tx % NUM_TX_DESC;
u32 len = length;
+ int ret;
#ifdef DEBUG_RTL8169_TX
int stime = currticks();
@@ -470,34 +479,38 @@
while (len < ETH_ZLEN)
ptxb[len++] = '\0';
- tpc->TxDescArray[entry].buf_addr = virt_to_bus(ptxb);
+ tpc->TxDescArray[entry].buf_addr = cpu_to_le32(ptxb);
if (entry != (NUM_TX_DESC - 1)) {
tpc->TxDescArray[entry].status =
- (OWNbit | FSbit | LSbit) | ((len > ETH_ZLEN) ?
- len : ETH_ZLEN);
+ cpu_to_le32((OWNbit | FSbit | LSbit) |
+ ((len > ETH_ZLEN) ? len : ETH_ZLEN));
} else {
tpc->TxDescArray[entry].status =
- (OWNbit | EORbit | FSbit | LSbit) |
- ((len > ETH_ZLEN) ? length : ETH_ZLEN);
+ cpu_to_le32((OWNbit | EORbit | FSbit | LSbit) |
+ ((len > ETH_ZLEN) ? len : ETH_ZLEN));
}
RTL_W8(TxPoll, 0x40); /* set polling bit */
tpc->cur_tx++;
to = currticks() + TX_TIMEOUT;
- while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() <
to)); /* wait */
+ while ((le32_to_cpu(tpc->TxDescArray[entry].status) & OWNbit)
+ && (currticks() < to)); /* wait */
if (currticks() >= to) {
#ifdef DEBUG_RTL8169_TX
puts ("tx timeout/error\n");
printf ("%s elapsed time : %d\n", __FUNCTION__,
currticks()-stime);
#endif
- return 0;
+ ret = 0;
} else {
#ifdef DEBUG_RTL8169_TX
puts("tx done\n");
#endif
- return length;
+ ret = length;
}
+ /* Delay to make net console (nc) work properly */
+ udelay(20);
+ return ret;
}
static void rtl8169_set_rx_mode(struct eth_device *dev)
@@ -564,8 +577,8 @@
tpc->cur_rx = 0;
- RTL_W32(TxDescStartAddr, virt_to_le32desc(tpc->TxDescArray));
- RTL_W32(RxDescStartAddr, virt_to_le32desc(tpc->RxDescArray));
+ RTL_W32(TxDescStartAddr, tpc->TxDescArray);
+ RTL_W32(RxDescStartAddr, tpc->RxDescArray);
RTL_W8(Cfg9346, Cfg9346_Lock);
udelay(10);
@@ -603,13 +616,14 @@
for (i = 0; i < NUM_RX_DESC; i++) {
if (i == (NUM_RX_DESC - 1))
tpc->RxDescArray[i].status =
- (OWNbit | EORbit) + RX_BUF_SIZE;
+ cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE);
else
- tpc->RxDescArray[i].status = OWNbit + RX_BUF_SIZE;
+ tpc->RxDescArray[i].status =
+ cpu_to_le32(OWNbit + RX_BUF_SIZE);
tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
tpc->RxDescArray[i].buf_addr =
- virt_to_bus(tpc->RxBufferRing[i]);
+ cpu_to_le32(tpc->RxBufferRing[i]);
}
#ifdef DEBUG_RTL8169
@@ -623,8 +637,6 @@
static void rtl_reset(struct eth_device *dev, bd_t *bis)
{
int i;
- u8 diff;
- u32 TxPhyAddr, RxPhyAddr;
#ifdef DEBUG_RTL8169
int stime = currticks();
@@ -632,25 +644,14 @@
#endif
tpc->TxDescArrays = tx_ring;
- if (tpc->TxDescArrays == 0)
- puts("Allot Error");
/* Tx Desscriptor needs 256 bytes alignment; */
- TxPhyAddr = virt_to_bus(tpc->TxDescArrays);
- diff = 256 - (TxPhyAddr - ((TxPhyAddr >> 8) << 8));
- TxPhyAddr += diff;
- tpc->TxDescArray = (struct TxDesc *) (tpc->TxDescArrays + diff);
+ tpc->TxDescArray = (struct TxDesc *) ((unsigned long)(tpc->TxDescArrays
+
+ 255) & ~255);
tpc->RxDescArrays = rx_ring;
/* Rx Desscriptor needs 256 bytes alignment; */
- RxPhyAddr = virt_to_bus(tpc->RxDescArrays);
- diff = 256 - (RxPhyAddr - ((RxPhyAddr >> 8) << 8));
- RxPhyAddr += diff;
- tpc->RxDescArray = (struct RxDesc *) (tpc->RxDescArrays + diff);
-
- if (tpc->TxDescArrays == NULL || tpc->RxDescArrays == NULL) {
- puts("Allocate RxDescArray or TxDescArray failed\n");
- return;
- }
+ tpc->RxDescArray = (struct RxDesc *) ((unsigned long)(tpc->RxDescArrays
+
+ 255) & ~255);
rtl8169_init_ring(dev);
rtl8169_hw_start(dev);
@@ -733,7 +734,7 @@
/* Get MAC address. FIXME: read EEPROM */
for (i = 0; i < MAC_ADDR_LEN; i++)
- dev->enetaddr[i] = RTL_R8(MAC0 + i);
+ bis->bi_enetaddr[i] = dev->enetaddr[i] = RTL_R8(MAC0 + i);
#ifdef DEBUG_RTL8169
printf("MAC Address");
@@ -808,7 +809,7 @@
/* wait for auto-negotiation process */
for (i = 10000; i > 0; i--) {
/* check if auto-negotiation complete */
- if (mdio_read(PHY_STAT_REG) & PHY_Auto_Neco_Comp) {
+ if (mdio_read(PHY_STAT_REG) & PHY_Auto_Nego_Comp) {
udelay(100);
option = RTL_R8(PHYstatus);
if (option & _1000bpsF) {
@@ -818,13 +819,12 @@
#endif
} else {
#ifdef DEBUG_RTL8169
- printf
- ("%s: %sMbps %s-duplex
operation.\n",
- dev->name,
- (option & _100bps) ? "100" :
- "10",
- (option & FullDup) ? "Full" :
- "Half");
+ printf("%s: %sMbps %s-duplex
operation.\n",
+ dev->name,
+ (option & _100bps) ? "100" :
+ "10",
+ (option & FullDup) ? "Full" :
+ "Half");
#endif
}
break;
@@ -869,7 +869,7 @@
sprintf (dev->name, "RTL8169#%d", card_number);
dev->priv = (void *) devno;
- dev->iobase = (int)bus_to_phys(iobase);
+ dev->iobase = (int)pci_mem_to_phys(devno, iobase);
dev->init = rtl_reset;
dev->halt = rtl_halt;
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
U-Boot-Users mailing list
U-Boot-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/u-boot-users