]> git.sur5r.net Git - u-boot/blob - drivers/net/ep93xx_eth.c
arm: imx6ul: Add Engicam GEAM6UL Starter Kit initial support
[u-boot] / 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(struct mii_dev *bus, int addr, int devad,
34                               int reg);
35 static int ep93xx_miiphy_write(struct mii_dev *bus, int addr, int devad,
36                                int reg, u16 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         int retval;
425         struct mii_dev *mdiodev = mdio_alloc();
426         if (!mdiodev)
427                 return -ENOMEM;
428         strncpy(mdiodev->name, "ep93xx_eth0", MDIO_NAME_LEN);
429         mdiodev->read = ep93xx_miiphy_read;
430         mdiodev->write = ep93xx_miiphy_write;
431
432         retval = mdio_register(mdiodev);
433         if (retval < 0)
434                 return retval;
435         return 0;
436 }
437 #endif
438
439 /**
440  * Initialize the EP93xx MAC.  The MAC hardware is reset.  Buffers are
441  * allocated, if necessary, for the TX and RX descriptor and status queues,
442  * as well as for received packets.  The EP93XX MAC hardware is initialized.
443  * Transmit and receive operations are enabled.
444  */
445 int ep93xx_eth_initialize(u8 dev_num, int base_addr)
446 {
447         int ret = -1;
448         struct eth_device *dev;
449         struct ep93xx_priv *priv;
450
451         debug("+ep93xx_eth_initialize");
452
453         priv = malloc(sizeof(*priv));
454         if (!priv) {
455                 error("malloc() failed");
456                 goto eth_init_failed_0;
457         }
458         memset(priv, 0, sizeof(*priv));
459
460         priv->regs = (struct mac_regs *)base_addr;
461
462         priv->tx_dq.base = calloc(NUMTXDESC,
463                                 sizeof(struct tx_descriptor));
464         if (priv->tx_dq.base == NULL) {
465                 error("calloc() failed");
466                 goto eth_init_failed_1;
467         }
468
469         priv->tx_sq.base = calloc(NUMTXDESC,
470                                 sizeof(struct tx_status));
471         if (priv->tx_sq.base == NULL) {
472                 error("calloc() failed");
473                 goto eth_init_failed_2;
474         }
475
476         priv->rx_dq.base = calloc(NUMRXDESC,
477                                 sizeof(struct rx_descriptor));
478         if (priv->rx_dq.base == NULL) {
479                 error("calloc() failed");
480                 goto eth_init_failed_3;
481         }
482
483         priv->rx_sq.base = calloc(NUMRXDESC,
484                                 sizeof(struct rx_status));
485         if (priv->rx_sq.base == NULL) {
486                 error("calloc() failed");
487                 goto eth_init_failed_4;
488         }
489
490         dev = malloc(sizeof *dev);
491         if (dev == NULL) {
492                 error("malloc() failed");
493                 goto eth_init_failed_5;
494         }
495         memset(dev, 0, sizeof *dev);
496
497         dev->iobase = base_addr;
498         dev->priv = priv;
499         dev->init = ep93xx_eth_open;
500         dev->halt = ep93xx_eth_close;
501         dev->send = ep93xx_eth_send_packet;
502         dev->recv = ep93xx_eth_rcv_packet;
503
504         sprintf(dev->name, "ep93xx_eth-%hu", dev_num);
505
506         eth_register(dev);
507
508         /* Done! */
509         ret = 1;
510         goto eth_init_done;
511
512 eth_init_failed_5:
513         free(priv->rx_sq.base);
514         /* Fall through */
515
516 eth_init_failed_4:
517         free(priv->rx_dq.base);
518         /* Fall through */
519
520 eth_init_failed_3:
521         free(priv->tx_sq.base);
522         /* Fall through */
523
524 eth_init_failed_2:
525         free(priv->tx_dq.base);
526         /* Fall through */
527
528 eth_init_failed_1:
529         free(priv);
530         /* Fall through */
531
532 eth_init_failed_0:
533         /* Fall through */
534
535 eth_init_done:
536         debug("-ep93xx_eth_initialize %d", ret);
537         return ret;
538 }
539
540 #if defined(CONFIG_MII)
541
542 /**
543  * Maximum MII address we support
544  */
545 #define MII_ADDRESS_MAX                 31
546
547 /**
548  * Maximum MII register address we support
549  */
550 #define MII_REGISTER_MAX                31
551
552 /**
553  * Read a 16-bit value from an MII register.
554  */
555 static int ep93xx_miiphy_read(struct mii_dev *bus, int addr, int devad,
556                               int reg)
557 {
558         unsigned short value = 0;
559         struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
560         int ret = -1;
561         uint32_t self_ctl;
562
563         debug("+ep93xx_miiphy_read");
564
565         /* Parameter checks */
566         BUG_ON(bus->name == NULL);
567         BUG_ON(addr > MII_ADDRESS_MAX);
568         BUG_ON(reg > MII_REGISTER_MAX);
569
570         /*
571          * Save the current SelfCTL register value.  Set MAC to suppress
572          * preamble bits.  Wait for any previous MII command to complete
573          * before issuing the new command.
574          */
575         self_ctl = readl(&mac->selfctl);
576 #if defined(CONFIG_MII_SUPPRESS_PREAMBLE)
577         writel(self_ctl & ~(1 << 8), &mac->selfctl);
578 #endif  /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */
579
580         while (readl(&mac->miists) & MIISTS_BUSY)
581                 ; /* noop */
582
583         /*
584          * Issue the MII 'read' command.  Wait for the command to complete.
585          * Read the MII data value.
586          */
587         writel(MIICMD_OPCODE_READ | ((uint32_t)addr << 5) | (uint32_t)reg,
588                 &mac->miicmd);
589         while (readl(&mac->miists) & MIISTS_BUSY)
590                 ; /* noop */
591
592         value = (unsigned short)readl(&mac->miidata);
593
594         /* Restore the saved SelfCTL value and return. */
595         writel(self_ctl, &mac->selfctl);
596
597         ret = 0;
598         /* Fall through */
599
600         debug("-ep93xx_miiphy_read");
601         if (ret < 0)
602                 return ret;
603         return value;
604 }
605
606 /**
607  * Write a 16-bit value to an MII register.
608  */
609 static int ep93xx_miiphy_write(struct mii_dev *bus, int addr, int devad,
610                                int reg, u16 value)
611 {
612         struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
613         int ret = -1;
614         uint32_t self_ctl;
615
616         debug("+ep93xx_miiphy_write");
617
618         /* Parameter checks */
619         BUG_ON(bus->name == NULL);
620         BUG_ON(addr > MII_ADDRESS_MAX);
621         BUG_ON(reg > MII_REGISTER_MAX);
622
623         /*
624          * Save the current SelfCTL register value.  Set MAC to suppress
625          * preamble bits.  Wait for any previous MII command to complete
626          * before issuing the new command.
627          */
628         self_ctl = readl(&mac->selfctl);
629 #if defined(CONFIG_MII_SUPPRESS_PREAMBLE)
630         writel(self_ctl & ~(1 << 8), &mac->selfctl);
631 #endif  /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */
632
633         while (readl(&mac->miists) & MIISTS_BUSY)
634                 ; /* noop */
635
636         /* Issue the MII 'write' command.  Wait for the command to complete. */
637         writel((uint32_t)value, &mac->miidata);
638         writel(MIICMD_OPCODE_WRITE | ((uint32_t)addr << 5) | (uint32_t)reg,
639                 &mac->miicmd);
640         while (readl(&mac->miists) & MIISTS_BUSY)
641                 ; /* noop */
642
643         /* Restore the saved SelfCTL value and return. */
644         writel(self_ctl, &mac->selfctl);
645
646         ret = 0;
647         /* Fall through */
648
649         debug("-ep93xx_miiphy_write");
650         return ret;
651 }
652 #endif  /* defined(CONFIG_MII) */