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