xref: /openbmc/u-boot/drivers/net/ep93xx_eth.c (revision e139cb31)
1 /*
2  * Cirrus Logic EP93xx ethernet MAC / MII driver.
3  *
4  * Copyright (C) 2010, 2009
5  * Matthias Kaehlcke <matthias@kaehlcke.net>
6  *
7  * Copyright (C) 2004, 2005
8  * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com>
9  *
10  * Based on the original eth.[ch] Cirrus Logic EP93xx Rev D. Ethernet Driver,
11  * which is
12  *
13  * (C) Copyright 2002 2003
14  * Adam Bezanson, Network Audio Technologies, Inc.
15  * <bezanson@netaudiotech.com>
16  *
17  * See file CREDITS for list of people who contributed to this project.
18  *
19  * This program is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 2 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful, but
25  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27  * for more details.
28  *
29  * You should have received a copy of the GNU General Public License along
30  * with this program; if not, write to the Free Software Foundation, Inc.,
31  * 675 Mass Ave, Cambridge, MA 02139, USA.
32  */
33 
34 #include <command.h>
35 #include <common.h>
36 #include <asm/arch/ep93xx.h>
37 #include <asm/io.h>
38 #include <malloc.h>
39 #include <miiphy.h>
40 #include <linux/types.h>
41 #include "ep93xx_eth.h"
42 
43 #define GET_PRIV(eth_dev)	((struct ep93xx_priv *)(eth_dev)->priv)
44 #define GET_REGS(eth_dev)	(GET_PRIV(eth_dev)->regs)
45 
46 /* ep93xx_miiphy ops forward declarations */
47 static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr,
48 			unsigned char const reg, unsigned short * const value);
49 static int ep93xx_miiphy_write(const char * const dev, unsigned char const addr,
50 			unsigned char const reg, unsigned short const value);
51 
52 #if defined(EP93XX_MAC_DEBUG)
53 /**
54  * Dump ep93xx_mac values to the terminal.
55  */
56 static void dump_dev(struct eth_device *dev)
57 {
58 	struct ep93xx_priv *priv = GET_PRIV(dev);
59 	int i;
60 
61 	printf("\ndump_dev()\n");
62 	printf("  rx_dq.base	     %p\n", priv->rx_dq.base);
63 	printf("  rx_dq.current	     %p\n", priv->rx_dq.current);
64 	printf("  rx_dq.end	     %p\n", priv->rx_dq.end);
65 	printf("  rx_sq.base	     %p\n", priv->rx_sq.base);
66 	printf("  rx_sq.current	     %p\n", priv->rx_sq.current);
67 	printf("  rx_sq.end	     %p\n", priv->rx_sq.end);
68 
69 	for (i = 0; i < NUMRXDESC; i++)
70 		printf("  rx_buffer[%2.d]      %p\n", i, NetRxPackets[i]);
71 
72 	printf("  tx_dq.base	     %p\n", priv->tx_dq.base);
73 	printf("  tx_dq.current	     %p\n", priv->tx_dq.current);
74 	printf("  tx_dq.end	     %p\n", priv->tx_dq.end);
75 	printf("  tx_sq.base	     %p\n", priv->tx_sq.base);
76 	printf("  tx_sq.current	     %p\n", priv->tx_sq.current);
77 	printf("  tx_sq.end	     %p\n", priv->tx_sq.end);
78 }
79 
80 /**
81  * Dump all RX status queue entries to the terminal.
82  */
83 static void dump_rx_status_queue(struct eth_device *dev)
84 {
85 	struct ep93xx_priv *priv = GET_PRIV(dev);
86 	int i;
87 
88 	printf("\ndump_rx_status_queue()\n");
89 	printf("  descriptor address	 word1		 word2\n");
90 	for (i = 0; i < NUMRXDESC; i++) {
91 		printf("  [ %p ]	     %08X	 %08X\n",
92 			priv->rx_sq.base + i,
93 			(priv->rx_sq.base + i)->word1,
94 			(priv->rx_sq.base + i)->word2);
95 	}
96 }
97 
98 /**
99  * Dump all RX descriptor queue entries to the terminal.
100  */
101 static void dump_rx_descriptor_queue(struct eth_device *dev)
102 {
103 	struct ep93xx_priv *priv = GET_PRIV(dev);
104 	int i;
105 
106 	printf("\ndump_rx_descriptor_queue()\n");
107 	printf("  descriptor address	 word1		 word2\n");
108 	for (i = 0; i < NUMRXDESC; i++) {
109 		printf("  [ %p ]	     %08X	 %08X\n",
110 			priv->rx_dq.base + i,
111 			(priv->rx_dq.base + i)->word1,
112 			(priv->rx_dq.base + i)->word2);
113 	}
114 }
115 
116 /**
117  * Dump all TX descriptor queue entries to the terminal.
118  */
119 static void dump_tx_descriptor_queue(struct eth_device *dev)
120 {
121 	struct ep93xx_priv *priv = GET_PRIV(dev);
122 	int i;
123 
124 	printf("\ndump_tx_descriptor_queue()\n");
125 	printf("  descriptor address	 word1		 word2\n");
126 	for (i = 0; i < NUMTXDESC; i++) {
127 		printf("  [ %p ]	     %08X	 %08X\n",
128 			priv->tx_dq.base + i,
129 			(priv->tx_dq.base + i)->word1,
130 			(priv->tx_dq.base + i)->word2);
131 	}
132 }
133 
134 /**
135  * Dump all TX status queue entries to the terminal.
136  */
137 static void dump_tx_status_queue(struct eth_device *dev)
138 {
139 	struct ep93xx_priv *priv = GET_PRIV(dev);
140 	int i;
141 
142 	printf("\ndump_tx_status_queue()\n");
143 	printf("  descriptor address	 word1\n");
144 	for (i = 0; i < NUMTXDESC; i++) {
145 		printf("  [ %p ]	     %08X\n",
146 			priv->rx_sq.base + i,
147 			(priv->rx_sq.base + i)->word1);
148 	}
149 }
150 #else
151 #define dump_dev(x)
152 #define dump_rx_descriptor_queue(x)
153 #define dump_rx_status_queue(x)
154 #define dump_tx_descriptor_queue(x)
155 #define dump_tx_status_queue(x)
156 #endif	/* defined(EP93XX_MAC_DEBUG) */
157 
158 /**
159  * Reset the EP93xx MAC by twiddling the soft reset bit and spinning until
160  * it's cleared.
161  */
162 static void ep93xx_mac_reset(struct eth_device *dev)
163 {
164 	struct mac_regs *mac = GET_REGS(dev);
165 	uint32_t value;
166 
167 	debug("+ep93xx_mac_reset");
168 
169 	value = readl(&mac->selfctl);
170 	value |= SELFCTL_RESET;
171 	writel(value, &mac->selfctl);
172 
173 	while (readl(&mac->selfctl) & SELFCTL_RESET)
174 		; /* noop */
175 
176 	debug("-ep93xx_mac_reset");
177 }
178 
179 /* Eth device open */
180 static int ep93xx_eth_open(struct eth_device *dev, bd_t *bd)
181 {
182 	struct ep93xx_priv *priv = GET_PRIV(dev);
183 	struct mac_regs *mac = GET_REGS(dev);
184 	uchar *mac_addr = dev->enetaddr;
185 	int i;
186 
187 	debug("+ep93xx_eth_open");
188 
189 	/* Reset the MAC */
190 	ep93xx_mac_reset(dev);
191 
192 	/* Reset the descriptor queues' current and end address values */
193 	priv->tx_dq.current = priv->tx_dq.base;
194 	priv->tx_dq.end = (priv->tx_dq.base + NUMTXDESC);
195 
196 	priv->tx_sq.current = priv->tx_sq.base;
197 	priv->tx_sq.end = (priv->tx_sq.base + NUMTXDESC);
198 
199 	priv->rx_dq.current = priv->rx_dq.base;
200 	priv->rx_dq.end = (priv->rx_dq.base + NUMRXDESC);
201 
202 	priv->rx_sq.current = priv->rx_sq.base;
203 	priv->rx_sq.end = (priv->rx_sq.base + NUMRXDESC);
204 
205 	/*
206 	 * Set the transmit descriptor and status queues' base address,
207 	 * current address, and length registers.  Set the maximum frame
208 	 * length and threshold. Enable the transmit descriptor processor.
209 	 */
210 	writel((uint32_t)priv->tx_dq.base, &mac->txdq.badd);
211 	writel((uint32_t)priv->tx_dq.base, &mac->txdq.curadd);
212 	writel(sizeof(struct tx_descriptor) * NUMTXDESC, &mac->txdq.blen);
213 
214 	writel((uint32_t)priv->tx_sq.base, &mac->txstsq.badd);
215 	writel((uint32_t)priv->tx_sq.base, &mac->txstsq.curadd);
216 	writel(sizeof(struct tx_status) * NUMTXDESC, &mac->txstsq.blen);
217 
218 	writel(0x00040000, &mac->txdthrshld);
219 	writel(0x00040000, &mac->txststhrshld);
220 
221 	writel((TXSTARTMAX << 0) | (PKTSIZE_ALIGN << 16), &mac->maxfrmlen);
222 	writel(BMCTL_TXEN, &mac->bmctl);
223 
224 	/*
225 	 * Set the receive descriptor and status queues' base address,
226 	 * current address, and length registers.  Enable the receive
227 	 * descriptor processor.
228 	 */
229 	writel((uint32_t)priv->rx_dq.base, &mac->rxdq.badd);
230 	writel((uint32_t)priv->rx_dq.base, &mac->rxdq.curadd);
231 	writel(sizeof(struct rx_descriptor) * NUMRXDESC, &mac->rxdq.blen);
232 
233 	writel((uint32_t)priv->rx_sq.base, &mac->rxstsq.badd);
234 	writel((uint32_t)priv->rx_sq.base, &mac->rxstsq.curadd);
235 	writel(sizeof(struct rx_status) * NUMRXDESC, &mac->rxstsq.blen);
236 
237 	writel(0x00040000, &mac->rxdthrshld);
238 
239 	writel(BMCTL_RXEN, &mac->bmctl);
240 
241 	writel(0x00040000, &mac->rxststhrshld);
242 
243 	/* Wait until the receive descriptor processor is active */
244 	while (!(readl(&mac->bmsts) & BMSTS_RXACT))
245 		; /* noop */
246 
247 	/*
248 	 * Initialize the RX descriptor queue. Clear the TX descriptor queue.
249 	 * Clear the RX and TX status queues. Enqueue the RX descriptor and
250 	 * status entries to the MAC.
251 	 */
252 	for (i = 0; i < NUMRXDESC; i++) {
253 		/* set buffer address */
254 		(priv->rx_dq.base + i)->word1 = (uint32_t)NetRxPackets[i];
255 
256 		/* set buffer length, clear buffer index and NSOF */
257 		(priv->rx_dq.base + i)->word2 = PKTSIZE_ALIGN;
258 	}
259 
260 	memset(priv->tx_dq.base, 0,
261 		(sizeof(struct tx_descriptor) * NUMTXDESC));
262 	memset(priv->rx_sq.base, 0,
263 		(sizeof(struct rx_status) * NUMRXDESC));
264 	memset(priv->tx_sq.base, 0,
265 		(sizeof(struct tx_status) * NUMTXDESC));
266 
267 	writel(NUMRXDESC, &mac->rxdqenq);
268 	writel(NUMRXDESC, &mac->rxstsqenq);
269 
270 	/* Set the primary MAC address */
271 	writel(AFP_IAPRIMARY, &mac->afp);
272 	writel(mac_addr[0] | (mac_addr[1] << 8) |
273 		(mac_addr[2] << 16) | (mac_addr[3] << 24),
274 		&mac->indad);
275 	writel(mac_addr[4] | (mac_addr[5] << 8), &mac->indad_upper);
276 
277 	/* Turn on RX and TX */
278 	writel(RXCTL_IA0 | RXCTL_BA | RXCTL_SRXON |
279 		RXCTL_RCRCA | RXCTL_MA, &mac->rxctl);
280 	writel(TXCTL_STXON, &mac->txctl);
281 
282 	/* Dump data structures if we're debugging */
283 	dump_dev(dev);
284 	dump_rx_descriptor_queue(dev);
285 	dump_rx_status_queue(dev);
286 	dump_tx_descriptor_queue(dev);
287 	dump_tx_status_queue(dev);
288 
289 	debug("-ep93xx_eth_open");
290 
291 	return 1;
292 }
293 
294 /**
295  * Halt EP93xx MAC transmit and receive by clearing the TxCTL and RxCTL
296  * registers.
297  */
298 static void ep93xx_eth_close(struct eth_device *dev)
299 {
300 	struct mac_regs *mac = GET_REGS(dev);
301 
302 	debug("+ep93xx_eth_close");
303 
304 	writel(0x00000000, &mac->rxctl);
305 	writel(0x00000000, &mac->txctl);
306 
307 	debug("-ep93xx_eth_close");
308 }
309 
310 /**
311  * Copy a frame of data from the MAC into the protocol layer for further
312  * processing.
313  */
314 static int ep93xx_eth_rcv_packet(struct eth_device *dev)
315 {
316 	struct mac_regs *mac = GET_REGS(dev);
317 	struct ep93xx_priv *priv = GET_PRIV(dev);
318 	int len = -1;
319 
320 	debug("+ep93xx_eth_rcv_packet");
321 
322 	if (RX_STATUS_RFP(priv->rx_sq.current)) {
323 		if (RX_STATUS_RWE(priv->rx_sq.current)) {
324 			/*
325 			 * We have a good frame. Extract the frame's length
326 			 * from the current rx_status_queue entry, and copy
327 			 * the frame's data into NetRxPackets[] of the
328 			 * protocol stack. We track the total number of
329 			 * bytes in the frame (nbytes_frame) which will be
330 			 * used when we pass the data off to the protocol
331 			 * layer via NetReceive().
332 			 */
333 			len = RX_STATUS_FRAME_LEN(priv->rx_sq.current);
334 
335 			NetReceive((uchar *)priv->rx_dq.current->word1,	len);
336 
337 			debug("reporting %d bytes...\n", len);
338 		} else {
339 			/* Do we have an erroneous packet? */
340 			error("packet rx error, status %08X %08X",
341 				priv->rx_sq.current->word1,
342 				priv->rx_sq.current->word2);
343 			dump_rx_descriptor_queue(dev);
344 			dump_rx_status_queue(dev);
345 		}
346 
347 		/*
348 		 * Clear the associated status queue entry, and
349 		 * increment our current pointers to the next RX
350 		 * descriptor and status queue entries (making sure
351 		 * we wrap properly).
352 		 */
353 		memset((void *)priv->rx_sq.current, 0,
354 			sizeof(struct rx_status));
355 
356 		priv->rx_sq.current++;
357 		if (priv->rx_sq.current >= priv->rx_sq.end)
358 			priv->rx_sq.current = priv->rx_sq.base;
359 
360 		priv->rx_dq.current++;
361 		if (priv->rx_dq.current >= priv->rx_dq.end)
362 			priv->rx_dq.current = priv->rx_dq.base;
363 
364 		/*
365 		 * Finally, return the RX descriptor and status entries
366 		 * back to the MAC engine, and loop again, checking for
367 		 * more descriptors to process.
368 		 */
369 		writel(1, &mac->rxdqenq);
370 		writel(1, &mac->rxstsqenq);
371 	} else {
372 		len = 0;
373 	}
374 
375 	debug("-ep93xx_eth_rcv_packet %d", len);
376 	return len;
377 }
378 
379 /**
380  * Send a block of data via ethernet.
381  */
382 static int ep93xx_eth_send_packet(struct eth_device *dev,
383 				void * const packet, int const length)
384 {
385 	struct mac_regs *mac = GET_REGS(dev);
386 	struct ep93xx_priv *priv = GET_PRIV(dev);
387 	int ret = -1;
388 
389 	debug("+ep93xx_eth_send_packet");
390 
391 	/* Parameter check */
392 	BUG_ON(packet == NULL);
393 
394 	/*
395 	 * Initialize the TX descriptor queue with the new packet's info.
396 	 * Clear the associated status queue entry. Enqueue the packet
397 	 * to the MAC for transmission.
398 	 */
399 
400 	/* set buffer address */
401 	priv->tx_dq.current->word1 = (uint32_t)packet;
402 
403 	/* set buffer length and EOF bit */
404 	priv->tx_dq.current->word2 = length | TX_DESC_EOF;
405 
406 	/* clear tx status */
407 	priv->tx_sq.current->word1 = 0;
408 
409 	/* enqueue the TX descriptor */
410 	writel(1, &mac->txdqenq);
411 
412 	/* wait for the frame to become processed */
413 	while (!TX_STATUS_TXFP(priv->tx_sq.current))
414 		; /* noop */
415 
416 	if (!TX_STATUS_TXWE(priv->tx_sq.current)) {
417 		error("packet tx error, status %08X",
418 			priv->tx_sq.current->word1);
419 		dump_tx_descriptor_queue(dev);
420 		dump_tx_status_queue(dev);
421 
422 		/* TODO: Add better error handling? */
423 		goto eth_send_out;
424 	}
425 
426 	ret = 0;
427 	/* Fall through */
428 
429 eth_send_out:
430 	debug("-ep93xx_eth_send_packet %d", ret);
431 	return ret;
432 }
433 
434 #if defined(CONFIG_MII)
435 int ep93xx_miiphy_initialize(bd_t * const bd)
436 {
437 	miiphy_register("ep93xx_eth0", ep93xx_miiphy_read, ep93xx_miiphy_write);
438 	return 0;
439 }
440 #endif
441 
442 /**
443  * Initialize the EP93xx MAC.  The MAC hardware is reset.  Buffers are
444  * allocated, if necessary, for the TX and RX descriptor and status queues,
445  * as well as for received packets.  The EP93XX MAC hardware is initialized.
446  * Transmit and receive operations are enabled.
447  */
448 int ep93xx_eth_initialize(u8 dev_num, int base_addr)
449 {
450 	int ret = -1;
451 	struct eth_device *dev;
452 	struct ep93xx_priv *priv;
453 
454 	debug("+ep93xx_eth_initialize");
455 
456 	priv = malloc(sizeof(*priv));
457 	if (!priv) {
458 		error("malloc() failed");
459 		goto eth_init_failed_0;
460 	}
461 	memset(priv, 0, sizeof(*priv));
462 
463 	priv->regs = (struct mac_regs *)base_addr;
464 
465 	priv->tx_dq.base = calloc(NUMTXDESC,
466 				sizeof(struct tx_descriptor));
467 	if (priv->tx_dq.base == NULL) {
468 		error("calloc() failed");
469 		goto eth_init_failed_1;
470 	}
471 
472 	priv->tx_sq.base = calloc(NUMTXDESC,
473 				sizeof(struct tx_status));
474 	if (priv->tx_sq.base == NULL) {
475 		error("calloc() failed");
476 		goto eth_init_failed_2;
477 	}
478 
479 	priv->rx_dq.base = calloc(NUMRXDESC,
480 				sizeof(struct rx_descriptor));
481 	if (priv->rx_dq.base == NULL) {
482 		error("calloc() failed");
483 		goto eth_init_failed_3;
484 	}
485 
486 	priv->rx_sq.base = calloc(NUMRXDESC,
487 				sizeof(struct rx_status));
488 	if (priv->rx_sq.base == NULL) {
489 		error("calloc() failed");
490 		goto eth_init_failed_4;
491 	}
492 
493 	dev = malloc(sizeof *dev);
494 	if (dev == NULL) {
495 		error("malloc() failed");
496 		goto eth_init_failed_5;
497 	}
498 	memset(dev, 0, sizeof *dev);
499 
500 	dev->iobase = base_addr;
501 	dev->priv = priv;
502 	dev->init = ep93xx_eth_open;
503 	dev->halt = ep93xx_eth_close;
504 	dev->send = ep93xx_eth_send_packet;
505 	dev->recv = ep93xx_eth_rcv_packet;
506 
507 	sprintf(dev->name, "ep93xx_eth-%hu", dev_num);
508 
509 	eth_register(dev);
510 
511 	/* Done! */
512 	ret = 1;
513 	goto eth_init_done;
514 
515 eth_init_failed_5:
516 	free(priv->rx_sq.base);
517 	/* Fall through */
518 
519 eth_init_failed_4:
520 	free(priv->rx_dq.base);
521 	/* Fall through */
522 
523 eth_init_failed_3:
524 	free(priv->tx_sq.base);
525 	/* Fall through */
526 
527 eth_init_failed_2:
528 	free(priv->tx_dq.base);
529 	/* Fall through */
530 
531 eth_init_failed_1:
532 	free(priv);
533 	/* Fall through */
534 
535 eth_init_failed_0:
536 	/* Fall through */
537 
538 eth_init_done:
539 	debug("-ep93xx_eth_initialize %d", ret);
540 	return ret;
541 }
542 
543 #if defined(CONFIG_MII)
544 
545 /**
546  * Maximum MII address we support
547  */
548 #define MII_ADDRESS_MAX			31
549 
550 /**
551  * Maximum MII register address we support
552  */
553 #define MII_REGISTER_MAX		31
554 
555 /**
556  * Read a 16-bit value from an MII register.
557  */
558 static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr,
559 			unsigned char const reg, unsigned short * const value)
560 {
561 	struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
562 	int ret = -1;
563 	uint32_t self_ctl;
564 
565 	debug("+ep93xx_miiphy_read");
566 
567 	/* Parameter checks */
568 	BUG_ON(dev == NULL);
569 	BUG_ON(addr > MII_ADDRESS_MAX);
570 	BUG_ON(reg > MII_REGISTER_MAX);
571 	BUG_ON(value == NULL);
572 
573 	/*
574 	 * Save the current SelfCTL register value.  Set MAC to suppress
575 	 * preamble bits.  Wait for any previous MII command to complete
576 	 * before issuing the new command.
577 	 */
578 	self_ctl = readl(&mac->selfctl);
579 #if defined(CONFIG_MII_SUPPRESS_PREAMBLE)
580 	writel(self_ctl & ~(1 << 8), &mac->selfctl);
581 #endif	/* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */
582 
583 	while (readl(&mac->miists) & MIISTS_BUSY)
584 		; /* noop */
585 
586 	/*
587 	 * Issue the MII 'read' command.  Wait for the command to complete.
588 	 * Read the MII data value.
589 	 */
590 	writel(MIICMD_OPCODE_READ | ((uint32_t)addr << 5) | (uint32_t)reg,
591 		&mac->miicmd);
592 	while (readl(&mac->miists) & MIISTS_BUSY)
593 		; /* noop */
594 
595 	*value = (unsigned short)readl(&mac->miidata);
596 
597 	/* Restore the saved SelfCTL value and return. */
598 	writel(self_ctl, &mac->selfctl);
599 
600 	ret = 0;
601 	/* Fall through */
602 
603 	debug("-ep93xx_miiphy_read");
604 	return ret;
605 }
606 
607 /**
608  * Write a 16-bit value to an MII register.
609  */
610 static int ep93xx_miiphy_write(const char * const dev, unsigned char const addr,
611 			unsigned char const reg, unsigned short const value)
612 {
613 	struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
614 	int ret = -1;
615 	uint32_t self_ctl;
616 
617 	debug("+ep93xx_miiphy_write");
618 
619 	/* Parameter checks */
620 	BUG_ON(dev == NULL);
621 	BUG_ON(addr > MII_ADDRESS_MAX);
622 	BUG_ON(reg > MII_REGISTER_MAX);
623 
624 	/*
625 	 * Save the current SelfCTL register value.  Set MAC to suppress
626 	 * preamble bits.  Wait for any previous MII command to complete
627 	 * before issuing the new command.
628 	 */
629 	self_ctl = readl(&mac->selfctl);
630 #if defined(CONFIG_MII_SUPPRESS_PREAMBLE)
631 	writel(self_ctl & ~(1 << 8), &mac->selfctl);
632 #endif	/* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */
633 
634 	while (readl(&mac->miists) & MIISTS_BUSY)
635 		; /* noop */
636 
637 	/* Issue the MII 'write' command.  Wait for the command to complete. */
638 	writel((uint32_t)value, &mac->miidata);
639 	writel(MIICMD_OPCODE_WRITE | ((uint32_t)addr << 5) | (uint32_t)reg,
640 		&mac->miicmd);
641 	while (readl(&mac->miists) & MIISTS_BUSY)
642 		; /* noop */
643 
644 	/* Restore the saved SelfCTL value and return. */
645 	writel(self_ctl, &mac->selfctl);
646 
647 	ret = 0;
648 	/* Fall through */
649 
650 	debug("-ep93xx_miiphy_write");
651 	return ret;
652 }
653 #endif	/* defined(CONFIG_MII) */
654