[U-Boot-Users] [PATCH 5/5] Large driver modification, including COMET support

Guennadi Liakhovetski lg at denx.de
Tue Nov 20 13:18:43 CET 2007


This patch is needed to support the network controller on
LinkStation / KuroBox classical (HD, not HG) systems.
Modifications are quite large, full details are unknown.
Appeared in the linkstation port by Mihai Georgin,
here presented without modifications.

Author: Mihai Georgin
---
This patch is not really for submission. Don't know what to do with it. 
This driver is used on many platforms, and this patch will, probably, 
break it at least on some of them. Review and test would be highly 
appreciated.

 drivers/dc2114x.c |  319 ++++++++++++++++++++++++++++++++---------------------
 1 files changed, 195 insertions(+), 124 deletions(-)

diff --git a/drivers/dc2114x.c b/drivers/dc2114x.c
index d5275dc..39ba49b 100644
--- a/drivers/dc2114x.c
+++ b/drivers/dc2114x.c
@@ -47,6 +47,7 @@
  */
 #define DE4X5_BMR	0x000		/* Bus Mode Register */
 #define DE4X5_TPD	0x008		/* Transmit Poll Demand Reg */
+#define DE4X5_RPD	0x010		/* Receive Poll Demand Reg */
 #define DE4X5_RRBA	0x018		/* RX Ring Base Address Reg */
 #define DE4X5_TRBA	0x020		/* TX Ring Base Address Reg */
 #define DE4X5_STS	0x028		/* Status Register */
@@ -64,6 +65,7 @@
 #define OMR_PS		0x00040000	/* Port Select */
 #define OMR_SDP		0x02000000	/* SD Polarity - MUST BE ASSERTED */
 #define OMR_PM		0x00000080	/* Pass All Multicast */
+#define OMR_PMS		0x00000040	/* Promiscuous */
 
 /* Descriptor bits.
  */
@@ -97,6 +99,29 @@
 
 #define POLL_DEMAND	1
 
+/* The chip types have been taken from linux-2.4.31
+ * drivers/net/tulip/tulip.h
+ * Only COMET is used for now
+ */
+enum chips {
+	DC21040 = 0,
+	DC21041 = 1,
+	DC21140 = 2,
+	DC21142 = 3, DC21143 = 3,
+	LC82C168,
+	MX98713,
+	MX98715,
+	MX98725,
+	AX88140,
+	PNIC2,
+	COMET,
+	COMPEX9881,
+	I21145,
+	DM910X,
+	CONEXANT,
+};
+static int chip_idx = DC21143;
+
 #ifdef CONFIG_TULIP_FIX_DAVICOM
 #define RESET_DM9102(dev) {\
     unsigned long i;\
@@ -108,26 +133,23 @@
 #else
 #define RESET_DE4X5(dev) {\
     int i;\
-    i=INL(dev, DE4X5_BMR);\
-    udelay(1000);\
+    i=0x01A04000;\
     OUTL(dev, i | BMR_SWR, DE4X5_BMR);\
     udelay(1000);\
     OUTL(dev, i, DE4X5_BMR);\
     udelay(1000);\
-    for (i=0;i<5;i++) {INL(dev, DE4X5_BMR); udelay(10000);}\
-    udelay(1000);\
 }
 #endif
 
 #define START_DE4X5(dev) {\
-    s32 omr; \
+    u32 omr; \
     omr = INL(dev, DE4X5_OMR);\
     omr |= OMR_ST | OMR_SR;\
     OUTL(dev, omr, DE4X5_OMR);		/* Enable the TX and/or RX */\
 }
 
 #define STOP_DE4X5(dev) {\
-    s32 omr; \
+    u32 omr; \
     omr = INL(dev, DE4X5_OMR);\
     omr &= ~(OMR_ST|OMR_SR);\
     OUTL(dev, omr, DE4X5_OMR);		/* Disable the TX and/or RX */ \
@@ -135,31 +157,39 @@
 
 #define NUM_RX_DESC PKTBUFSRX
 #ifndef CONFIG_TULIP_FIX_DAVICOM
-	#define NUM_TX_DESC 1			/* Number of TX descriptors   */
+	#define NUM_TX_DESC 2		/* Number of TX descriptors   */
 #else
 	#define NUM_TX_DESC 4
 #endif
-#define RX_BUFF_SZ  PKTSIZE_ALIGN
+#define BUFLEN  1536
 
 #define TOUT_LOOP   1000000
 
 #define SETUP_FRAME_LEN 192
 #define ETH_ALEN	6
+#define ETH_ZLEN	60
 
 struct de4x5_desc {
-	volatile s32 status;
+	volatile u32 status;
 	u32 des1;
 	u32 buf;
 	u32 next;
 };
 
-static struct de4x5_desc rx_ring[NUM_RX_DESC] __attribute__ ((aligned(32))); /* RX descriptor ring         */
-static struct de4x5_desc tx_ring[NUM_TX_DESC] __attribute__ ((aligned(32))); /* TX descriptor ring         */
-static int rx_new;                             /* RX descriptor ring pointer */
-static int tx_new;                             /* TX descriptor ring pointer */
+/* Note: transmit and receive buffers must be longword aligned and
+   longword divisable */
+
+/* TX descriptor ring */
+static struct de4x5_desc tx_ring[NUM_TX_DESC] __attribute__ ((aligned(4)));
+/* TX buffer */
+static unsigned char txb[BUFLEN] __attribute__ ((aligned(32)));
+
+/* RX descriptor ring */
+static struct de4x5_desc rx_ring[NUM_RX_DESC] __attribute__ ((aligned(4)));
+/* RX buffers */
+static unsigned char rxb[NUM_RX_DESC * BUFLEN] __attribute__ ((aligned(32)));
 
-static char rxRingSize;
-static char txRingSize;
+static int rx_new;		/* RX descriptor ring pointer */
 
 #if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM)
 static void  sendto_srom(struct eth_device* dev, u_int command, u_long addr);
@@ -204,6 +234,7 @@ static void OUTL(struct eth_device* dev, int command, u_long addr)
 static struct pci_device_id supported[] = {
 	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST },
 	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142 },
+	{ PCI_VENDOR_ID_ADMTEK, PCI_DEVICE_ID_ADMTEK_AN983B },
 #ifdef CONFIG_TULIP_FIX_DAVICOM
 	{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DAVICOM_DM9102A },
 #endif
@@ -214,29 +245,41 @@ int dc21x4x_initialize(bd_t *bis)
 {
 	int             	idx=0;
 	int             	card_number = 0;
-	unsigned int           	cfrv;
+	unsigned int		cfrv;
 	unsigned char   	timer;
 	pci_dev_t		devbusfn;
 	unsigned int		iobase;
 	unsigned short		status;
 	struct eth_device* 	dev;
+	u16			vendor;
+	u16			device;
 
 	while(1) {
 		devbusfn =  pci_find_devices(supported, idx++);
 		if (devbusfn == -1) {
 			break;
 		}
+		pci_read_config_word(devbusfn, PCI_VENDOR_ID, &vendor);
+		pci_read_config_word(devbusfn, PCI_DEVICE_ID, &device);
 
-		/* Get the chip configuration revision register. */
-		pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv);
+		debug("dc21x4x: devbusfn: %08lX, VID: %08lX, DID: %08lX\n",
+			devbusfn, vendor, device);
+
+		if (vendor == PCI_VENDOR_ID_ADMTEK && \
+		    device == PCI_DEVICE_ID_ADMTEK_AN983B) {
+			chip_idx = COMET;
+		} else {
+			/* Get the chip configuration revision register. */
+			pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv);
 
 #ifndef CONFIG_TULIP_FIX_DAVICOM
-		if ((cfrv & CFRV_RN) < DC2114x_BRK ) {
-			printf("Error: The chip is not DC21143.\n");
-			continue;
-		}
+			if ((cfrv & CFRV_RN) < DC2114x_BRK ) {
+				printf("Error: The chip is not DC21143.\n");
+				idx++;
+				continue;
+			}
 #endif
-
+		}
 		pci_read_config_word(devbusfn, PCI_COMMAND, &status);
 		status |=
 #ifdef CONFIG_TULIP_USE_IO
@@ -286,7 +329,10 @@ int dc21x4x_initialize(bd_t *bis)
 #ifdef CONFIG_TULIP_FIX_DAVICOM
 		sprintf(dev->name, "Davicom#%d", card_number);
 #else
-		sprintf(dev->name, "dc21x4x#%d", card_number);
+		if (chip_idx == COMET)
+			sprintf(dev->name, "COMET#%d", card_number);
+		else
+			sprintf(dev->name, "dc21x4x#%d", card_number);
 #endif
 
 #ifdef CONFIG_TULIP_USE_IO
@@ -303,8 +349,6 @@ int dc21x4x_initialize(bd_t *bis)
 		/* Ensure we're not sleeping. */
 		pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);
 
-		udelay(10 * 1000);
-
 #ifndef CONFIG_TULIP_FIX_DAVICOM
 		read_hw_addr(dev, bis);
 #endif
@@ -321,8 +365,9 @@ static int dc21x4x_init(struct eth_device* dev, bd_t* bis)
 	int		i;
 	int		devbusfn = (int) dev->priv;
 
-	/* Ensure we're not sleeping. */
-	pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);
+#if defined(DEBUG_TULIP) || defined(DEBUG_TRACE)
+	serial_printf("%0lu %s\n", get_timer(0), __FUNCTION__);
+#endif
 
 #ifdef CONFIG_TULIP_FIX_DAVICOM
 	RESET_DM9102(dev);
@@ -330,57 +375,71 @@ static int dc21x4x_init(struct eth_device* dev, bd_t* bis)
 	RESET_DE4X5(dev);
 #endif
 
-	if ((INL(dev, DE4X5_STS) & (STS_TS | STS_RS)) != 0) {
-		printf("Error: Cannot reset ethernet controller.\n");
-		return 0;
-	}
-
 #ifdef CONFIG_TULIP_SELECT_MEDIA
 	dc21x4x_select_media(dev);
 #else
-	OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR);
+	if (chip_idx == COMET) {
+		/* No multicast */
+		OUTL(dev, 0, 0xAC);
+		OUTL(dev, 0, 0xB0);
+	} else {
+		OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR);
+	}
 #endif
 
 	for (i = 0; i < NUM_RX_DESC; i++) {
 		rx_ring[i].status = cpu_to_le32(R_OWN);
-		rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);
-		rx_ring[i].buf = cpu_to_le32(phys_to_bus((u32) NetRxPackets[i]));
-#ifdef CONFIG_TULIP_FIX_DAVICOM
-		rx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &rx_ring[(i+1) % NUM_RX_DESC]));
-#else
-		rx_ring[i].next = 0;
-#endif
+		rx_ring[i].des1 = cpu_to_le32(BUFLEN);
+		rx_ring[i].buf = cpu_to_le32(phys_to_bus((u32)&rxb[i * BUFLEN]));
+		rx_ring[i].next = cpu_to_le32(phys_to_bus((u32)&rx_ring[i+1]));
 	}
+	/* Write the end of list marker to the descriptor lists. */
+	rx_ring[NUM_RX_DESC - 1].des1 |= cpu_to_le32(RD_RER);
+	rx_ring[NUM_RX_DESC - 1].next = cpu_to_le32(phys_to_bus((u32)&rx_ring[0]));
 
-	for (i=0; i < NUM_TX_DESC; i++) {
-		tx_ring[i].status = 0;
-		tx_ring[i].des1 = 0;
-		tx_ring[i].buf = 0;
+	/* Point to the first descriptor */
+	rx_new = 0;
 
-#ifdef CONFIG_TULIP_FIX_DAVICOM
-	tx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &tx_ring[(i+1) % NUM_TX_DESC]));
-#else
-		tx_ring[i].next = 0;
-#endif
-	}
+	/* We only use 1 transmit buffer, but we use 2 descriptors so
+	   transmit engines have somewhere to point to if they feel the need */
+
+	tx_ring[0].status = 0;
+	tx_ring[0].des1 = 0;
+	tx_ring[0].buf = cpu_to_le32(phys_to_bus((u32)&txb[0]));
+	tx_ring[0].next = cpu_to_le32(phys_to_bus((u32)&tx_ring[1]));
+
+	/* this descriptor should never get used, since it will never be owned
+	   by the machine (status will always == 0) */
 
-	rxRingSize = NUM_RX_DESC;
-	txRingSize = NUM_TX_DESC;
+	tx_ring[1].status = 0;
+	tx_ring[1].des1 = 0;
+	tx_ring[1].buf = cpu_to_le32(phys_to_bus((u32)&txb[0]));
+	tx_ring[1].next = cpu_to_le32(phys_to_bus((u32)&tx_ring[0]));
 
 	/* Write the end of list marker to the descriptor lists. */
-	rx_ring[rxRingSize - 1].des1 |= cpu_to_le32(RD_RER);
-	tx_ring[txRingSize - 1].des1 |= cpu_to_le32(TD_TER);
+	tx_ring[1].des1 |= cpu_to_le32(TD_TER);
 
 	/* Tell the adapter where the TX/RX rings are located. */
-	OUTL(dev, phys_to_bus((u32) &rx_ring), DE4X5_RRBA);
-	OUTL(dev, phys_to_bus((u32) &tx_ring), DE4X5_TRBA);
+	OUTL(dev, phys_to_bus((u32) &rx_ring[0]), DE4X5_RRBA);
+	OUTL(dev, phys_to_bus((u32) &tx_ring[0]), DE4X5_TRBA);
+
+	if (chip_idx == COMET) {
+		/* Bit 18 (0x00040000) is reserved in the AN983B */
+		/* datasheet, but it is used by the tulip driver */
+		OUTL(dev, (INL(dev, (DE4X5_OMR)) & ~(OMR_PMS | OMR_PM)) | OMR_PS, DE4X5_OMR);
+		/* Enable automatic Tx underrun recovery */
+		OUTL(dev, INL(dev, 0x88) | 1, 0x88);
+//		OUTL(dev, INL(dev, 0x88) | 0x19, 0x88);
+	}
 
 	START_DE4X5(dev);
 
-	tx_new = 0;
-	rx_new = 0;
+	/* Start receiving */
+	OUTL(dev, POLL_DEMAND, DE4X5_RPD);
 
-	send_setup_frame(dev, bis);
+	if (chip_idx != COMET) {	/* No setup frame needed by COMET */
+		send_setup_frame(dev, bis);
+	}
 
 	return 1;
 }
@@ -389,90 +448,96 @@ static int dc21x4x_send(struct eth_device* dev, volatile void *packet, int lengt
 {
 	int		status = -1;
 	int		i;
+	u32		len = length;
 
 	if (length <= 0) {
 		printf("%s: bad packet size: %d\n", dev->name, length);
 		goto Done;
 	}
 
-	for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+	for(i = 0; tx_ring[0].status & cpu_to_le32(T_OWN); i++) {
 		if (i >= TOUT_LOOP) {
-			printf("%s: tx error buffer not ready\n", dev->name);
+			printf(".%s: Tx not ready\n", dev->name);
 			goto Done;
 		}
 	}
 
-	tx_ring[tx_new].buf    = cpu_to_le32(phys_to_bus((u32) packet));
-	tx_ring[tx_new].des1   = cpu_to_le32(TD_TER | TD_LS | TD_FS | length);
-	tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+	/* Disable the TX */
+	OUTL(dev, INL(dev, DE4X5_OMR) & ~OMR_ST, DE4X5_OMR);
+
+	memcpy(txb, (char*)packet, length);
+
+	/* setup the transmit descriptor */
+	tx_ring[0].des1 = cpu_to_le32(TD_LS | TD_FS | length);
+	tx_ring[0].status = cpu_to_le32(T_OWN);
 
+	/* Point to transmit descriptor */
+	OUTL(dev, phys_to_bus((u32) &tx_ring[0]), DE4X5_TRBA);
+
+	/* Enable the TX */
+	OUTL(dev, INL(dev, DE4X5_OMR) | OMR_ST, DE4X5_OMR);
+
+	/* Immediate transmit demand */
 	OUTL(dev, POLL_DEMAND, DE4X5_TPD);
 
-	for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+	for(i = 0; tx_ring[0].status & cpu_to_le32(T_OWN); i++) {
 		if (i >= TOUT_LOOP) {
-			printf(".%s: tx buffer not ready\n", dev->name);
+			printf(".%s: Tx Timeout\n", dev->name);
 			goto Done;
 		}
 	}
 
-	if (le32_to_cpu(tx_ring[tx_new].status) & TD_ES) {
+	if (le32_to_cpu(tx_ring[0].status) & TD_ES) {
 #if 0 /* test-only */
 		printf("TX error status = 0x%08X\n",
-			le32_to_cpu(tx_ring[tx_new].status));
+			le32_to_cpu(tx_ring[0].status));
 #endif
-		tx_ring[tx_new].status = 0x0;
+		tx_ring[0].status = 0x0;
 		goto Done;
 	}
 
 	status = length;
 
  Done:
-    tx_new = (tx_new+1) % NUM_TX_DESC;
 	return status;
 }
 
 static int dc21x4x_recv(struct eth_device* dev)
 {
-	s32		status;
+	u32		status;
+	int		rx_prv;
 	int		length    = 0;
 
-	for ( ; ; ) {
-		status = (s32)le32_to_cpu(rx_ring[rx_new].status);
+	status = (u32)le32_to_cpu(rx_ring[rx_new].status);
+	if (status & R_OWN)
+		return 0;
 
-		if (status & R_OWN) {
-			break;
-		}
+	if (status & RD_LS) {
+		/* Valid frame status */
+		if (status & RD_ES) {
+			/* There was an error */
+			printf("RX error status = 0x%08X\n", status);
+			rx_ring[rx_new].status = cpu_to_le32(R_OWN);
+		} else {
+			/* Received valid frame */
+			length = (int)(le32_to_cpu(rx_ring[rx_new].status) >> 16);
 
-		if (status & RD_LS) {
-			/* Valid frame status.
-			 */
-			if (status & RD_ES) {
-
-				/* There was an error.
-				 */
-				printf("RX error status = 0x%08X\n", status);
-			} else {
-				/* A valid frame received.
-				 */
-				length = (le32_to_cpu(rx_ring[rx_new].status) >> 16);
-
-				/* Pass the packet up to the protocol
-				 * layers.
-				 */
-				NetReceive(NetRxPackets[rx_new], length - 4);
-			}
+			/* Pass the packet up to the protocol layers. */
+			unsigned char rxdata[BUFLEN];
+			memcpy(rxdata, rxb + rx_new * BUFLEN, length - 4);
 
-			/* Change buffer ownership for this frame, back
-			 * to the adapter.
-			 */
+			/* Give buffer ownership for this
+			 * frame back to the adapter */
 			rx_ring[rx_new].status = cpu_to_le32(R_OWN);
-		}
 
-		/* Update entry information.
-		 */
-		rx_new = (rx_new + 1) % rxRingSize;
+			/* Pass the received packet to the upper layer */
+			NetReceive(rxdata, length - 4);
+		}
 	}
 
+	/* Update current descriptor index */
+	rx_new = (rx_new + 1) % NUM_RX_DESC;
+
 	return length;
 }
 
@@ -483,7 +548,6 @@ static void dc21x4x_halt(struct eth_device* dev)
 	STOP_DE4X5(dev);
 	OUTL(dev, 0, DE4X5_SICR);
 
-	pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP);
 }
 
 static void send_setup_frame(struct eth_device* dev, bd_t *bis)
@@ -501,30 +565,29 @@ static void send_setup_frame(struct eth_device* dev, bd_t *bis)
 		}
 	}
 
-	for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+	for(i = 0; tx_ring[0].status & cpu_to_le32(T_OWN); i++) {
 		if (i >= TOUT_LOOP) {
 			printf("%s: tx error buffer not ready\n", dev->name);
 			goto Done;
 		}
 	}
 
-	tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32) &setup_frame[0]));
-	tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN);
-	tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+	tx_ring[0].buf = cpu_to_le32(phys_to_bus((u32) &setup_frame[0]));
+	tx_ring[0].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN);
+	tx_ring[0].status = cpu_to_le32(T_OWN);
 
 	OUTL(dev, POLL_DEMAND, DE4X5_TPD);
 
-	for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+	for(i = 0; tx_ring[0].status & cpu_to_le32(T_OWN); i++) {
 		if (i >= TOUT_LOOP) {
 			printf("%s: tx buffer not ready\n", dev->name);
 			goto Done;
 		}
 	}
 
-	if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) {
-		printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[tx_new].status));
+	if (le32_to_cpu(tx_ring[0].status) != 0x7FFFFFFF) {
+		printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[0].status));
 	}
-	tx_new = (tx_new+1) % NUM_TX_DESC;
 
 Done:
 	return;
@@ -543,7 +606,7 @@ sendto_srom(struct eth_device* dev, u_int command, u_long addr)
 static int
 getfrom_srom(struct eth_device* dev, u_long addr)
 {
-	s32 tmp;
+	u32 tmp;
 
 	tmp = INL(dev, addr);
 	udelay(1);
@@ -708,19 +771,27 @@ static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_
 #ifndef CONFIG_TULIP_FIX_DAVICOM
 static void read_hw_addr(struct eth_device *dev, bd_t *bis)
 {
-	u_short tmp, *p = (u_short *)(&dev->enetaddr[0]);
-	int i, j = 0;
-
-	for (i = 0; i < (ETH_ALEN >> 1); i++) {
-		tmp = read_srom(dev, DE4X5_APROM, ((SROM_HWADD >> 1) + i));
-		*p = le16_to_cpu(tmp);
-		j += *p++;
-	}
+	if (chip_idx == COMET) {
+		/* COMET reads the ehernet address directly from the EEPROM */
+		*(u32 *)dev->enetaddr = cpu_to_le32(INL(dev, 0xA4));
+		*(u16 *)(dev->enetaddr+4) = cpu_to_le16(INL(dev, 0xA8));
+		*(u32 *)bis->bi_enetaddr = *(u32 *)dev->enetaddr;
+		*(u16 *)(bis->bi_enetaddr+4) = *(u16 *)(dev->enetaddr+4);
+	} else {
+		u_short tmp, *p = (u_short *)(&dev->enetaddr[0]);
+		int i, j = 0;
+
+		for (i = 0; i < (ETH_ALEN >> 1); i++) {
+			tmp=read_srom(dev, DE4X5_APROM, ((SROM_HWADD >> 1)+i));
+			*p = le16_to_cpu(tmp);
+			j += *p++;
+		}
 
-	if ((j == 0) || (j == 0x2fffd)) {
-		memset (dev->enetaddr, 0, ETH_ALEN);
-		debug ("Warning: can't read HW address from SROM.\n");
-		goto Done;
+		if ((j == 0) || (j == 0x2fffd)) {
+			memset (dev->enetaddr, 0, ETH_ALEN);
+			debug ("Warning: can't read HW address from SROM.\n");
+			goto Done;
+		}
 	}
 
 	return;
-- 
1.5.3.4





More information about the U-Boot mailing list