xref: /rk3399_rockchip-uboot/drivers/net/xilinx_emaclite.c (revision d722e8641b664d129238bef361c847a8b5504b5c)
1 /*
2  * (C) Copyright 2007-2009 Michal Simek
3  * (C) Copyright 2003 Xilinx Inc.
4  *
5  * Michal SIMEK <monstr@monstr.eu>
6  *
7  * SPDX-License-Identifier:	GPL-2.0+
8  */
9 
10 #include <common.h>
11 #include <net.h>
12 #include <config.h>
13 #include <console.h>
14 #include <malloc.h>
15 #include <asm/io.h>
16 #include <phy.h>
17 #include <miiphy.h>
18 #include <fdtdec.h>
19 #include <asm-generic/errno.h>
20 
21 #undef DEBUG
22 
23 #define ENET_ADDR_LENGTH	6
24 
25 /* EmacLite constants */
26 #define XEL_BUFFER_OFFSET	0x0800	/* Next buffer's offset */
27 #define XEL_TPLR_OFFSET		0x07F4	/* Tx packet length */
28 #define XEL_TSR_OFFSET		0x07FC	/* Tx status */
29 #define XEL_RSR_OFFSET		0x17FC	/* Rx status */
30 #define XEL_RXBUFF_OFFSET	0x1000	/* Receive Buffer */
31 
32 /* Xmit complete */
33 #define XEL_TSR_XMIT_BUSY_MASK		0x00000001UL
34 /* Xmit interrupt enable bit */
35 #define XEL_TSR_XMIT_IE_MASK		0x00000008UL
36 /* Buffer is active, SW bit only */
37 #define XEL_TSR_XMIT_ACTIVE_MASK	0x80000000UL
38 /* Program the MAC address */
39 #define XEL_TSR_PROGRAM_MASK		0x00000002UL
40 /* define for programming the MAC address into the EMAC Lite */
41 #define XEL_TSR_PROG_MAC_ADDR	(XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK)
42 
43 /* Transmit packet length upper byte */
44 #define XEL_TPLR_LENGTH_MASK_HI		0x0000FF00UL
45 /* Transmit packet length lower byte */
46 #define XEL_TPLR_LENGTH_MASK_LO		0x000000FFUL
47 
48 /* Recv complete */
49 #define XEL_RSR_RECV_DONE_MASK		0x00000001UL
50 /* Recv interrupt enable bit */
51 #define XEL_RSR_RECV_IE_MASK		0x00000008UL
52 
53 /* MDIO */
54 #define XEL_MDIOADDR_OFFSET	0x07E4		/* MDIO Address Register */
55 #define XEL_MDIOWR_OFFSET	0x07E8		/* MDIO Write Data Register */
56 #define XEL_MDIORD_OFFSET	0x07EC		/* MDIO Read Data Register */
57 #define XEL_MDIOCTRL_OFFSET	0x07F0		/* MDIO Control Register */
58 
59 /* MDIO Address Register Bit Masks */
60 #define XEL_MDIOADDR_REGADR_MASK  0x0000001F	/* Register Address */
61 #define XEL_MDIOADDR_PHYADR_MASK  0x000003E0	/* PHY Address */
62 #define XEL_MDIOADDR_PHYADR_SHIFT 5
63 #define XEL_MDIOADDR_OP_MASK	  0x00000400	/* RD/WR Operation */
64 
65 /* MDIO Write Data Register Bit Masks */
66 #define XEL_MDIOWR_WRDATA_MASK	  0x0000FFFF	/* Data to be Written */
67 
68 /* MDIO Read Data Register Bit Masks */
69 #define XEL_MDIORD_RDDATA_MASK	  0x0000FFFF	/* Data to be Read */
70 
71 /* MDIO Control Register Bit Masks */
72 #define XEL_MDIOCTRL_MDIOSTS_MASK 0x00000001	/* MDIO Status Mask */
73 #define XEL_MDIOCTRL_MDIOEN_MASK  0x00000008	/* MDIO Enable */
74 
75 struct xemaclite {
76 	u32 nexttxbuffertouse;	/* Next TX buffer to write to */
77 	u32 nextrxbuffertouse;	/* Next RX buffer to read from */
78 	u32 txpp;		/* TX ping pong buffer */
79 	u32 rxpp;		/* RX ping pong buffer */
80 	int phyaddr;
81 	struct phy_device *phydev;
82 	struct mii_dev *bus;
83 };
84 
85 static u32 etherrxbuff[PKTSIZE_ALIGN/4]; /* Receive buffer */
86 
87 static void xemaclite_alignedread(u32 *srcptr, void *destptr, u32 bytecount)
88 {
89 	u32 i;
90 	u32 alignbuffer;
91 	u32 *to32ptr;
92 	u32 *from32ptr;
93 	u8 *to8ptr;
94 	u8 *from8ptr;
95 
96 	from32ptr = (u32 *) srcptr;
97 
98 	/* Word aligned buffer, no correction needed. */
99 	to32ptr = (u32 *) destptr;
100 	while (bytecount > 3) {
101 		*to32ptr++ = *from32ptr++;
102 		bytecount -= 4;
103 	}
104 	to8ptr = (u8 *) to32ptr;
105 
106 	alignbuffer = *from32ptr++;
107 	from8ptr = (u8 *) &alignbuffer;
108 
109 	for (i = 0; i < bytecount; i++)
110 		*to8ptr++ = *from8ptr++;
111 }
112 
113 static void xemaclite_alignedwrite(void *srcptr, u32 destptr, u32 bytecount)
114 {
115 	u32 i;
116 	u32 alignbuffer;
117 	u32 *to32ptr = (u32 *) destptr;
118 	u32 *from32ptr;
119 	u8 *to8ptr;
120 	u8 *from8ptr;
121 
122 	from32ptr = (u32 *) srcptr;
123 	while (bytecount > 3) {
124 
125 		*to32ptr++ = *from32ptr++;
126 		bytecount -= 4;
127 	}
128 
129 	alignbuffer = 0;
130 	to8ptr = (u8 *) &alignbuffer;
131 	from8ptr = (u8 *) from32ptr;
132 
133 	for (i = 0; i < bytecount; i++)
134 		*to8ptr++ = *from8ptr++;
135 
136 	*to32ptr++ = alignbuffer;
137 }
138 
139 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
140 static int wait_for_bit(const char *func, u32 *reg, const u32 mask,
141 			bool set, unsigned int timeout)
142 {
143 	u32 val;
144 	unsigned long start = get_timer(0);
145 
146 	while (1) {
147 		val = readl(reg);
148 
149 		if (!set)
150 			val = ~val;
151 
152 		if ((val & mask) == mask)
153 			return 0;
154 
155 		if (get_timer(start) > timeout)
156 			break;
157 
158 		if (ctrlc()) {
159 			puts("Abort\n");
160 			return -EINTR;
161 		}
162 
163 		udelay(1);
164 	}
165 
166 	debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n",
167 	      func, reg, mask, set);
168 
169 	return -ETIMEDOUT;
170 }
171 
172 static int mdio_wait(struct eth_device *dev)
173 {
174 	return wait_for_bit(__func__,
175 			    (u32 *)(dev->iobase + XEL_MDIOCTRL_OFFSET),
176 			    XEL_MDIOCTRL_MDIOSTS_MASK, false, 2000);
177 }
178 
179 static u32 phyread(struct eth_device *dev, u32 phyaddress, u32 registernum,
180 		   u16 *data)
181 {
182 	if (mdio_wait(dev))
183 		return 1;
184 
185 	u32 ctrl_reg = in_be32(dev->iobase + XEL_MDIOCTRL_OFFSET);
186 	out_be32(dev->iobase + XEL_MDIOADDR_OFFSET,
187 		 XEL_MDIOADDR_OP_MASK |
188 		 ((phyaddress << XEL_MDIOADDR_PHYADR_SHIFT) | registernum));
189 	out_be32(dev->iobase + XEL_MDIOCTRL_OFFSET,
190 		 ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK);
191 
192 	if (mdio_wait(dev))
193 		return 1;
194 
195 	/* Read data */
196 	*data = in_be32(dev->iobase + XEL_MDIORD_OFFSET);
197 	return 0;
198 }
199 
200 static u32 phywrite(struct eth_device *dev, u32 phyaddress, u32 registernum,
201 		    u16 data)
202 {
203 	if (mdio_wait(dev))
204 		return 1;
205 
206 	/*
207 	 * Write the PHY address, register number and clear the OP bit in the
208 	 * MDIO Address register and then write the value into the MDIO Write
209 	 * Data register. Finally, set the Status bit in the MDIO Control
210 	 * register to start a MDIO write transaction.
211 	 */
212 	u32 ctrl_reg = in_be32(dev->iobase + XEL_MDIOCTRL_OFFSET);
213 	out_be32(dev->iobase + XEL_MDIOADDR_OFFSET,
214 		 ~XEL_MDIOADDR_OP_MASK &
215 		 ((phyaddress << XEL_MDIOADDR_PHYADR_SHIFT) | registernum));
216 	out_be32(dev->iobase + XEL_MDIOWR_OFFSET, data);
217 	out_be32(dev->iobase + XEL_MDIOCTRL_OFFSET,
218 		 ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK);
219 
220 	if (mdio_wait(dev))
221 		return 1;
222 
223 	return 0;
224 }
225 #endif
226 
227 static void emaclite_halt(struct eth_device *dev)
228 {
229 	debug("eth_halt\n");
230 }
231 
232 /* Use MII register 1 (MII status register) to detect PHY */
233 #define PHY_DETECT_REG  1
234 
235 /* Mask used to verify certain PHY features (or register contents)
236  * in the register above:
237  *  0x1000: 10Mbps full duplex support
238  *  0x0800: 10Mbps half duplex support
239  *  0x0008: Auto-negotiation support
240  */
241 #define PHY_DETECT_MASK 0x1808
242 
243 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
244 static int setup_phy(struct eth_device *dev)
245 {
246 	int i;
247 	u16 phyreg;
248 	struct xemaclite *emaclite = dev->priv;
249 	struct phy_device *phydev;
250 
251 	u32 supported = SUPPORTED_10baseT_Half |
252 			SUPPORTED_10baseT_Full |
253 			SUPPORTED_100baseT_Half |
254 			SUPPORTED_100baseT_Full;
255 
256 	if (emaclite->phyaddr != -1) {
257 		phyread(dev, emaclite->phyaddr, PHY_DETECT_REG, &phyreg);
258 		if ((phyreg != 0xFFFF) &&
259 		    ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
260 			/* Found a valid PHY address */
261 			debug("Default phy address %d is valid\n",
262 			      emaclite->phyaddr);
263 		} else {
264 			debug("PHY address is not setup correctly %d\n",
265 			      emaclite->phyaddr);
266 			emaclite->phyaddr = -1;
267 		}
268 	}
269 
270 	if (emaclite->phyaddr == -1) {
271 		/* detect the PHY address */
272 		for (i = 31; i >= 0; i--) {
273 			phyread(dev, i, PHY_DETECT_REG, &phyreg);
274 			if ((phyreg != 0xFFFF) &&
275 			    ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
276 				/* Found a valid PHY address */
277 				emaclite->phyaddr = i;
278 				debug("emaclite: Found valid phy address, %d\n",
279 				      i);
280 				break;
281 			}
282 		}
283 	}
284 
285 	/* interface - look at tsec */
286 	phydev = phy_connect(emaclite->bus, emaclite->phyaddr, dev,
287 			     PHY_INTERFACE_MODE_MII);
288 	/*
289 	 * Phy can support 1000baseT but device NOT that's why phydev->supported
290 	 * must be setup for 1000baseT. phydev->advertising setups what speeds
291 	 * will be used for autonegotiation where 1000baseT must be disabled.
292 	 */
293 	phydev->supported = supported | SUPPORTED_1000baseT_Half |
294 						SUPPORTED_1000baseT_Full;
295 	phydev->advertising = supported;
296 	emaclite->phydev = phydev;
297 	phy_config(phydev);
298 	phy_startup(phydev);
299 
300 	if (!phydev->link) {
301 		printf("%s: No link.\n", phydev->dev->name);
302 		return 0;
303 	}
304 
305 	/* Do not setup anything */
306 	return 1;
307 }
308 #endif
309 
310 static int emaclite_init(struct eth_device *dev, bd_t *bis)
311 {
312 	struct xemaclite *emaclite = dev->priv;
313 	debug("EmacLite Initialization Started\n");
314 
315 /*
316  * TX - TX_PING & TX_PONG initialization
317  */
318 	/* Restart PING TX */
319 	out_be32 (dev->iobase + XEL_TSR_OFFSET, 0);
320 	/* Copy MAC address */
321 	xemaclite_alignedwrite(dev->enetaddr, dev->iobase, ENET_ADDR_LENGTH);
322 	/* Set the length */
323 	out_be32 (dev->iobase + XEL_TPLR_OFFSET, ENET_ADDR_LENGTH);
324 	/* Update the MAC address in the EMAC Lite */
325 	out_be32 (dev->iobase + XEL_TSR_OFFSET, XEL_TSR_PROG_MAC_ADDR);
326 	/* Wait for EMAC Lite to finish with the MAC address update */
327 	while ((in_be32 (dev->iobase + XEL_TSR_OFFSET) &
328 		XEL_TSR_PROG_MAC_ADDR) != 0)
329 		;
330 
331 	if (emaclite->txpp) {
332 		/* The same operation with PONG TX */
333 		out_be32 (dev->iobase + XEL_TSR_OFFSET + XEL_BUFFER_OFFSET, 0);
334 		xemaclite_alignedwrite(dev->enetaddr, dev->iobase +
335 			XEL_BUFFER_OFFSET, ENET_ADDR_LENGTH);
336 		out_be32 (dev->iobase + XEL_TPLR_OFFSET, ENET_ADDR_LENGTH);
337 		out_be32 (dev->iobase + XEL_TSR_OFFSET + XEL_BUFFER_OFFSET,
338 			XEL_TSR_PROG_MAC_ADDR);
339 		while ((in_be32 (dev->iobase + XEL_TSR_OFFSET +
340 			XEL_BUFFER_OFFSET) & XEL_TSR_PROG_MAC_ADDR) != 0)
341 			;
342 	}
343 
344 /*
345  * RX - RX_PING & RX_PONG initialization
346  */
347 	/* Write out the value to flush the RX buffer */
348 	out_be32 (dev->iobase + XEL_RSR_OFFSET, XEL_RSR_RECV_IE_MASK);
349 
350 	if (emaclite->rxpp)
351 		out_be32 (dev->iobase + XEL_RSR_OFFSET + XEL_BUFFER_OFFSET,
352 			XEL_RSR_RECV_IE_MASK);
353 
354 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
355 	out_be32(dev->iobase + XEL_MDIOCTRL_OFFSET, XEL_MDIOCTRL_MDIOEN_MASK);
356 	if (in_be32(dev->iobase + XEL_MDIOCTRL_OFFSET) &
357 		    XEL_MDIOCTRL_MDIOEN_MASK)
358 		if (!setup_phy(dev))
359 			return -1;
360 #endif
361 	debug("EmacLite Initialization complete\n");
362 	return 0;
363 }
364 
365 static int xemaclite_txbufferavailable(struct eth_device *dev)
366 {
367 	u32 reg;
368 	u32 txpingbusy;
369 	u32 txpongbusy;
370 	struct xemaclite *emaclite = dev->priv;
371 
372 	/*
373 	 * Read the other buffer register
374 	 * and determine if the other buffer is available
375 	 */
376 	reg = in_be32 (dev->iobase +
377 			emaclite->nexttxbuffertouse + 0);
378 	txpingbusy = ((reg & XEL_TSR_XMIT_BUSY_MASK) ==
379 			XEL_TSR_XMIT_BUSY_MASK);
380 
381 	reg = in_be32 (dev->iobase +
382 			(emaclite->nexttxbuffertouse ^ XEL_TSR_OFFSET) + 0);
383 	txpongbusy = ((reg & XEL_TSR_XMIT_BUSY_MASK) ==
384 			XEL_TSR_XMIT_BUSY_MASK);
385 
386 	return !(txpingbusy && txpongbusy);
387 }
388 
389 static int emaclite_send(struct eth_device *dev, void *ptr, int len)
390 {
391 	u32 reg;
392 	u32 baseaddress;
393 	struct xemaclite *emaclite = dev->priv;
394 
395 	u32 maxtry = 1000;
396 
397 	if (len > PKTSIZE)
398 		len = PKTSIZE;
399 
400 	while (!xemaclite_txbufferavailable(dev) && maxtry) {
401 		udelay(10);
402 		maxtry--;
403 	}
404 
405 	if (!maxtry) {
406 		printf("Error: Timeout waiting for ethernet TX buffer\n");
407 		/* Restart PING TX */
408 		out_be32 (dev->iobase + XEL_TSR_OFFSET, 0);
409 		if (emaclite->txpp) {
410 			out_be32 (dev->iobase + XEL_TSR_OFFSET +
411 				XEL_BUFFER_OFFSET, 0);
412 		}
413 		return -1;
414 	}
415 
416 	/* Determine the expected TX buffer address */
417 	baseaddress = (dev->iobase + emaclite->nexttxbuffertouse);
418 
419 	/* Determine if the expected buffer address is empty */
420 	reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
421 	if (((reg & XEL_TSR_XMIT_BUSY_MASK) == 0)
422 		&& ((in_be32 ((baseaddress) + XEL_TSR_OFFSET)
423 			& XEL_TSR_XMIT_ACTIVE_MASK) == 0)) {
424 
425 		if (emaclite->txpp)
426 			emaclite->nexttxbuffertouse ^= XEL_BUFFER_OFFSET;
427 
428 		debug("Send packet from 0x%x\n", baseaddress);
429 		/* Write the frame to the buffer */
430 		xemaclite_alignedwrite(ptr, baseaddress, len);
431 		out_be32 (baseaddress + XEL_TPLR_OFFSET,(len &
432 			(XEL_TPLR_LENGTH_MASK_HI | XEL_TPLR_LENGTH_MASK_LO)));
433 		reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
434 		reg |= XEL_TSR_XMIT_BUSY_MASK;
435 		if ((reg & XEL_TSR_XMIT_IE_MASK) != 0)
436 			reg |= XEL_TSR_XMIT_ACTIVE_MASK;
437 		out_be32 (baseaddress + XEL_TSR_OFFSET, reg);
438 		return 0;
439 	}
440 
441 	if (emaclite->txpp) {
442 		/* Switch to second buffer */
443 		baseaddress ^= XEL_BUFFER_OFFSET;
444 		/* Determine if the expected buffer address is empty */
445 		reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
446 		if (((reg & XEL_TSR_XMIT_BUSY_MASK) == 0)
447 			&& ((in_be32 ((baseaddress) + XEL_TSR_OFFSET)
448 				& XEL_TSR_XMIT_ACTIVE_MASK) == 0)) {
449 			debug("Send packet from 0x%x\n", baseaddress);
450 			/* Write the frame to the buffer */
451 			xemaclite_alignedwrite(ptr, baseaddress, len);
452 			out_be32 (baseaddress + XEL_TPLR_OFFSET, (len &
453 				(XEL_TPLR_LENGTH_MASK_HI |
454 					XEL_TPLR_LENGTH_MASK_LO)));
455 			reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
456 			reg |= XEL_TSR_XMIT_BUSY_MASK;
457 			if ((reg & XEL_TSR_XMIT_IE_MASK) != 0)
458 				reg |= XEL_TSR_XMIT_ACTIVE_MASK;
459 			out_be32 (baseaddress + XEL_TSR_OFFSET, reg);
460 			return 0;
461 		}
462 	}
463 
464 	puts("Error while sending frame\n");
465 	return -1;
466 }
467 
468 static int emaclite_recv(struct eth_device *dev)
469 {
470 	u32 length;
471 	u32 reg;
472 	u32 baseaddress;
473 	struct xemaclite *emaclite = dev->priv;
474 
475 	baseaddress = dev->iobase + emaclite->nextrxbuffertouse;
476 	reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
477 	debug("Testing data at address 0x%x\n", baseaddress);
478 	if ((reg & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
479 		if (emaclite->rxpp)
480 			emaclite->nextrxbuffertouse ^= XEL_BUFFER_OFFSET;
481 	} else {
482 
483 		if (!emaclite->rxpp) {
484 			debug("No data was available - address 0x%x\n",
485 								baseaddress);
486 			return 0;
487 		} else {
488 			baseaddress ^= XEL_BUFFER_OFFSET;
489 			reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
490 			if ((reg & XEL_RSR_RECV_DONE_MASK) !=
491 						XEL_RSR_RECV_DONE_MASK) {
492 				debug("No data was available - address 0x%x\n",
493 						baseaddress);
494 				return 0;
495 			}
496 		}
497 	}
498 	/* Get the length of the frame that arrived */
499 	switch(((ntohl(in_be32 (baseaddress + XEL_RXBUFF_OFFSET + 0xC))) &
500 			0xFFFF0000 ) >> 16) {
501 		case 0x806:
502 			length = 42 + 20; /* FIXME size of ARP */
503 			debug("ARP Packet\n");
504 			break;
505 		case 0x800:
506 			length = 14 + 14 +
507 			(((ntohl(in_be32 (baseaddress + XEL_RXBUFF_OFFSET +
508 						0x10))) & 0xFFFF0000) >> 16);
509 			/* FIXME size of IP packet */
510 			debug ("IP Packet\n");
511 			break;
512 		default:
513 			debug("Other Packet\n");
514 			length = PKTSIZE;
515 			break;
516 	}
517 
518 	xemaclite_alignedread((u32 *) (baseaddress + XEL_RXBUFF_OFFSET),
519 			etherrxbuff, length);
520 
521 	/* Acknowledge the frame */
522 	reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
523 	reg &= ~XEL_RSR_RECV_DONE_MASK;
524 	out_be32 (baseaddress + XEL_RSR_OFFSET, reg);
525 
526 	debug("Packet receive from 0x%x, length %dB\n", baseaddress, length);
527 	net_process_received_packet((uchar *)etherrxbuff, length);
528 	return length;
529 
530 }
531 
532 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
533 static int emaclite_miiphy_read(const char *devname, uchar addr,
534 				uchar reg, ushort *val)
535 {
536 	u32 ret;
537 	struct eth_device *dev = eth_get_dev();
538 
539 	ret = phyread(dev, addr, reg, val);
540 	debug("emaclite: Read MII 0x%x, 0x%x, 0x%x\n", addr, reg, *val);
541 	return ret;
542 }
543 
544 static int emaclite_miiphy_write(const char *devname, uchar addr,
545 				 uchar reg, ushort val)
546 {
547 	struct eth_device *dev = eth_get_dev();
548 
549 	debug("emaclite: Write MII 0x%x, 0x%x, 0x%x\n", addr, reg, val);
550 	return phywrite(dev, addr, reg, val);
551 }
552 #endif
553 
554 int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr,
555 							int txpp, int rxpp)
556 {
557 	struct eth_device *dev;
558 	struct xemaclite *emaclite;
559 
560 	dev = calloc(1, sizeof(*dev));
561 	if (dev == NULL)
562 		return -1;
563 
564 	emaclite = calloc(1, sizeof(struct xemaclite));
565 	if (emaclite == NULL) {
566 		free(dev);
567 		return -1;
568 	}
569 
570 	dev->priv = emaclite;
571 
572 	emaclite->txpp = txpp;
573 	emaclite->rxpp = rxpp;
574 
575 	sprintf(dev->name, "Xelite.%lx", base_addr);
576 
577 	dev->iobase = base_addr;
578 	dev->init = emaclite_init;
579 	dev->halt = emaclite_halt;
580 	dev->send = emaclite_send;
581 	dev->recv = emaclite_recv;
582 
583 #ifdef CONFIG_PHY_ADDR
584 	emaclite->phyaddr = CONFIG_PHY_ADDR;
585 #else
586 	emaclite->phyaddr = -1;
587 #endif
588 
589 	eth_register(dev);
590 
591 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
592 	miiphy_register(dev->name, emaclite_miiphy_read, emaclite_miiphy_write);
593 	emaclite->bus = miiphy_get_dev_by_name(dev->name);
594 
595 	out_be32(dev->iobase + XEL_MDIOCTRL_OFFSET,
596 		 XEL_MDIOCTRL_MDIOEN_MASK);
597 #endif
598 
599 	return 1;
600 }
601