]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/ep93xx_eth.c
arm: mx6: add support for i.MX6ULL
[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  * 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, net_rx_packets[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)net_rx_packets[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 net_rx_packets[] 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 net_process_received_packet().
318                          */
319                         len = RX_STATUS_FRAME_LEN(priv->rx_sq.current);
320
321                         net_process_received_packet(
322                                 (uchar *)priv->rx_dq.current->word1, len);
323
324                         debug("reporting %d bytes...\n", len);
325                 } else {
326                         /* Do we have an erroneous packet? */
327                         error("packet rx error, status %08X %08X",
328                                 priv->rx_sq.current->word1,
329                                 priv->rx_sq.current->word2);
330                         dump_rx_descriptor_queue(dev);
331                         dump_rx_status_queue(dev);
332                 }
333
334                 /*
335                  * Clear the associated status queue entry, and
336                  * increment our current pointers to the next RX
337                  * descriptor and status queue entries (making sure
338                  * we wrap properly).
339                  */
340                 memset((void *)priv->rx_sq.current, 0,
341                         sizeof(struct rx_status));
342
343                 priv->rx_sq.current++;
344                 if (priv->rx_sq.current >= priv->rx_sq.end)
345                         priv->rx_sq.current = priv->rx_sq.base;
346
347                 priv->rx_dq.current++;
348                 if (priv->rx_dq.current >= priv->rx_dq.end)
349                         priv->rx_dq.current = priv->rx_dq.base;
350
351                 /*
352                  * Finally, return the RX descriptor and status entries
353                  * back to the MAC engine, and loop again, checking for
354                  * more descriptors to process.
355                  */
356                 writel(1, &mac->rxdqenq);
357                 writel(1, &mac->rxstsqenq);
358         } else {
359                 len = 0;
360         }
361
362         debug("-ep93xx_eth_rcv_packet %d", len);
363         return len;
364 }
365
366 /**
367  * Send a block of data via ethernet.
368  */
369 static int ep93xx_eth_send_packet(struct eth_device *dev,
370                                 void * const packet, int const length)
371 {
372         struct mac_regs *mac = GET_REGS(dev);
373         struct ep93xx_priv *priv = GET_PRIV(dev);
374         int ret = -1;
375
376         debug("+ep93xx_eth_send_packet");
377
378         /* Parameter check */
379         BUG_ON(packet == NULL);
380
381         /*
382          * Initialize the TX descriptor queue with the new packet's info.
383          * Clear the associated status queue entry. Enqueue the packet
384          * to the MAC for transmission.
385          */
386
387         /* set buffer address */
388         priv->tx_dq.current->word1 = (uint32_t)packet;
389
390         /* set buffer length and EOF bit */
391         priv->tx_dq.current->word2 = length | TX_DESC_EOF;
392
393         /* clear tx status */
394         priv->tx_sq.current->word1 = 0;
395
396         /* enqueue the TX descriptor */
397         writel(1, &mac->txdqenq);
398
399         /* wait for the frame to become processed */
400         while (!TX_STATUS_TXFP(priv->tx_sq.current))
401                 ; /* noop */
402
403         if (!TX_STATUS_TXWE(priv->tx_sq.current)) {
404                 error("packet tx error, status %08X",
405                         priv->tx_sq.current->word1);
406                 dump_tx_descriptor_queue(dev);
407                 dump_tx_status_queue(dev);
408
409                 /* TODO: Add better error handling? */
410                 goto eth_send_out;
411         }
412
413         ret = 0;
414         /* Fall through */
415
416 eth_send_out:
417         debug("-ep93xx_eth_send_packet %d", ret);
418         return ret;
419 }
420
421 #if defined(CONFIG_MII)
422 int ep93xx_miiphy_initialize(bd_t * const bd)
423 {
424         miiphy_register("ep93xx_eth0", ep93xx_miiphy_read, ep93xx_miiphy_write);
425         return 0;
426 }
427 #endif
428
429 /**
430  * Initialize the EP93xx MAC.  The MAC hardware is reset.  Buffers are
431  * allocated, if necessary, for the TX and RX descriptor and status queues,
432  * as well as for received packets.  The EP93XX MAC hardware is initialized.
433  * Transmit and receive operations are enabled.
434  */
435 int ep93xx_eth_initialize(u8 dev_num, int base_addr)
436 {
437         int ret = -1;
438         struct eth_device *dev;
439         struct ep93xx_priv *priv;
440
441         debug("+ep93xx_eth_initialize");
442
443         priv = malloc(sizeof(*priv));
444         if (!priv) {
445                 error("malloc() failed");
446                 goto eth_init_failed_0;
447         }
448         memset(priv, 0, sizeof(*priv));
449
450         priv->regs = (struct mac_regs *)base_addr;
451
452         priv->tx_dq.base = calloc(NUMTXDESC,
453                                 sizeof(struct tx_descriptor));
454         if (priv->tx_dq.base == NULL) {
455                 error("calloc() failed");
456                 goto eth_init_failed_1;
457         }
458
459         priv->tx_sq.base = calloc(NUMTXDESC,
460                                 sizeof(struct tx_status));
461         if (priv->tx_sq.base == NULL) {
462                 error("calloc() failed");
463                 goto eth_init_failed_2;
464         }
465
466         priv->rx_dq.base = calloc(NUMRXDESC,
467                                 sizeof(struct rx_descriptor));
468         if (priv->rx_dq.base == NULL) {
469                 error("calloc() failed");
470                 goto eth_init_failed_3;
471         }
472
473         priv->rx_sq.base = calloc(NUMRXDESC,
474                                 sizeof(struct rx_status));
475         if (priv->rx_sq.base == NULL) {
476                 error("calloc() failed");
477                 goto eth_init_failed_4;
478         }
479
480         dev = malloc(sizeof *dev);
481         if (dev == NULL) {
482                 error("malloc() failed");
483                 goto eth_init_failed_5;
484         }
485         memset(dev, 0, sizeof *dev);
486
487         dev->iobase = base_addr;
488         dev->priv = priv;
489         dev->init = ep93xx_eth_open;
490         dev->halt = ep93xx_eth_close;
491         dev->send = ep93xx_eth_send_packet;
492         dev->recv = ep93xx_eth_rcv_packet;
493
494         sprintf(dev->name, "ep93xx_eth-%hu", dev_num);
495
496         eth_register(dev);
497
498         /* Done! */
499         ret = 1;
500         goto eth_init_done;
501
502 eth_init_failed_5:
503         free(priv->rx_sq.base);
504         /* Fall through */
505
506 eth_init_failed_4:
507         free(priv->rx_dq.base);
508         /* Fall through */
509
510 eth_init_failed_3:
511         free(priv->tx_sq.base);
512         /* Fall through */
513
514 eth_init_failed_2:
515         free(priv->tx_dq.base);
516         /* Fall through */
517
518 eth_init_failed_1:
519         free(priv);
520         /* Fall through */
521
522 eth_init_failed_0:
523         /* Fall through */
524
525 eth_init_done:
526         debug("-ep93xx_eth_initialize %d", ret);
527         return ret;
528 }
529
530 #if defined(CONFIG_MII)
531
532 /**
533  * Maximum MII address we support
534  */
535 #define MII_ADDRESS_MAX                 31
536
537 /**
538  * Maximum MII register address we support
539  */
540 #define MII_REGISTER_MAX                31
541
542 /**
543  * Read a 16-bit value from an MII register.
544  */
545 static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr,
546                         unsigned char const reg, unsigned short * const value)
547 {
548         struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
549         int ret = -1;
550         uint32_t self_ctl;
551
552         debug("+ep93xx_miiphy_read");
553
554         /* Parameter checks */
555         BUG_ON(dev == NULL);
556         BUG_ON(addr > MII_ADDRESS_MAX);
557         BUG_ON(reg > MII_REGISTER_MAX);
558         BUG_ON(value == NULL);
559
560         /*
561          * Save the current SelfCTL register value.  Set MAC to suppress
562          * preamble bits.  Wait for any previous MII command to complete
563          * before issuing the new command.
564          */
565         self_ctl = readl(&mac->selfctl);
566 #if defined(CONFIG_MII_SUPPRESS_PREAMBLE)
567         writel(self_ctl & ~(1 << 8), &mac->selfctl);
568 #endif  /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */
569
570         while (readl(&mac->miists) & MIISTS_BUSY)
571                 ; /* noop */
572
573         /*
574          * Issue the MII 'read' command.  Wait for the command to complete.
575          * Read the MII data value.
576          */
577         writel(MIICMD_OPCODE_READ | ((uint32_t)addr << 5) | (uint32_t)reg,
578                 &mac->miicmd);
579         while (readl(&mac->miists) & MIISTS_BUSY)
580                 ; /* noop */
581
582         *value = (unsigned short)readl(&mac->miidata);
583
584         /* Restore the saved SelfCTL value and return. */
585         writel(self_ctl, &mac->selfctl);
586
587         ret = 0;
588         /* Fall through */
589
590         debug("-ep93xx_miiphy_read");
591         return ret;
592 }
593
594 /**
595  * Write a 16-bit value to an MII register.
596  */
597 static int ep93xx_miiphy_write(const char * const dev, unsigned char const addr,
598                         unsigned char const reg, unsigned short const value)
599 {
600         struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
601         int ret = -1;
602         uint32_t self_ctl;
603
604         debug("+ep93xx_miiphy_write");
605
606         /* Parameter checks */
607         BUG_ON(dev == NULL);
608         BUG_ON(addr > MII_ADDRESS_MAX);
609         BUG_ON(reg > MII_REGISTER_MAX);
610
611         /*
612          * Save the current SelfCTL register value.  Set MAC to suppress
613          * preamble bits.  Wait for any previous MII command to complete
614          * before issuing the new command.
615          */
616         self_ctl = readl(&mac->selfctl);
617 #if defined(CONFIG_MII_SUPPRESS_PREAMBLE)
618         writel(self_ctl & ~(1 << 8), &mac->selfctl);
619 #endif  /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */
620
621         while (readl(&mac->miists) & MIISTS_BUSY)
622                 ; /* noop */
623
624         /* Issue the MII 'write' command.  Wait for the command to complete. */
625         writel((uint32_t)value, &mac->miidata);
626         writel(MIICMD_OPCODE_WRITE | ((uint32_t)addr << 5) | (uint32_t)reg,
627                 &mac->miicmd);
628         while (readl(&mac->miists) & MIISTS_BUSY)
629                 ; /* noop */
630
631         /* Restore the saved SelfCTL value and return. */
632         writel(self_ctl, &mac->selfctl);
633
634         ret = 0;
635         /* Fall through */
636
637         debug("-ep93xx_miiphy_write");
638         return ret;
639 }
640 #endif  /* defined(CONFIG_MII) */