]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/ep93xx_eth.c
Add EP93xx ethernet driver
[karo-tx-uboot.git] / drivers / net / ep93xx_eth.c
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(char * const dev, unsigned char const addr,
48                         unsigned char const reg, unsigned short * const value);
49 static int ep93xx_miiphy_write(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                                 volatile 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(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(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) */