]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - drivers/net/fec_mxc.c
- check for CONDIF_SYS_DCACHE_OFF or CONFIG_SYS_ARM_CACHE_WRITETHROUGH
[karo-tx-uboot.git] / drivers / net / fec_mxc.c
1 /*
2  * (C) Copyright 2009 Ilya Yanok, Emcraft Systems Ltd <yanok@emcraft.com>
3  * (C) Copyright 2008,2009 Eric Jarrige <eric.jarrige@armadeus.org>
4  * (C) Copyright 2008 Armadeus Systems nc
5  * (C) Copyright 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
6  * (C) Copyright 2007 Pengutronix, Juergen Beisert <j.beisert@pengutronix.de>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <malloc.h>
26 #include <net.h>
27 #include <miiphy.h>
28 #include "fec_mxc.h"
29
30 #include <asm/arch/clock.h>
31 #include <asm/arch/imx-regs.h>
32 #include <asm/io.h>
33 #include <asm/errno.h>
34
35 DECLARE_GLOBAL_DATA_PTR;
36
37 #ifndef CONFIG_MII
38 #error "CONFIG_MII has to be defined!"
39 #endif
40
41 #ifndef CONFIG_FEC_XCV_TYPE
42 #define CONFIG_FEC_XCV_TYPE     MII100
43 #endif
44
45 #if !defined(CONDIF_SYS_DCACHE_OFF) && !defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
46 /* Due to multiple RX and TX buffer descriptors sharing a cache line
47  * the driver can only work with DMA coherent memory.
48  * Since U-Boot does not provide this, cache must be disabled or
49  * write-through.
50  */
51 #error This driver cannot be used with Writeback DCACHE
52 #endif
53 /*
54  * The i.MX28 operates with packets in big endian. We need to swap them before
55  * sending and after receiving.
56  */
57 #ifdef  CONFIG_MX28
58 #define CONFIG_FEC_MXC_SWAP_PACKET
59 #endif
60
61 #undef DEBUG
62
63 struct nbuf {
64         uint8_t data[1500];     /**< actual data */
65         int length;             /**< actual length */
66         int used;               /**< buffer in use or not */
67         uint8_t head[16];       /**< MAC header(6 + 6 + 2) + 2(aligned) */
68 };
69
70 #ifdef  CONFIG_FEC_MXC_SWAP_PACKET
71 static void swap_packet(uint32_t *packet, int length)
72 {
73         int i;
74
75         for (i = 0; i < DIV_ROUND_UP(length, 4); i++)
76                 packet[i] = __swab32(packet[i]);
77 }
78 #endif
79
80 /*
81  * The i.MX28 has two ethernet interfaces, but they are not equal.
82  * Only the first one can access the MDIO bus.
83  */
84 #ifdef  CONFIG_MX28
85 static inline struct ethernet_regs *fec_miiphy_fec_to_eth(struct fec_priv *fec)
86 {
87         return (struct ethernet_regs *)MXS_ENET0_BASE;
88 }
89 #else
90 static inline struct ethernet_regs *fec_miiphy_fec_to_eth(struct fec_priv *fec)
91 {
92         return fec->eth;
93 }
94 #endif
95
96 /*
97  * MII-interface related functions
98  */
99 static int fec_miiphy_read(const char *dev, uint8_t phyAddr, uint8_t regAddr,
100                 uint16_t *retVal)
101 {
102         struct eth_device *edev = eth_get_dev_by_name(dev);
103         struct fec_priv *fec = (struct fec_priv *)edev->priv;
104         struct ethernet_regs *eth = fec_miiphy_fec_to_eth(fec);
105
106         uint32_t reg;           /* convenient holder for the PHY register */
107         uint32_t phy;           /* convenient holder for the PHY */
108         uint32_t start;
109
110         /*
111          * reading from any PHY's register is done by properly
112          * programming the FEC's MII data register.
113          */
114         writel(FEC_IEVENT_MII, &eth->ievent);
115         reg = regAddr << FEC_MII_DATA_RA_SHIFT;
116         phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
117
118         writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA |
119                         phy | reg, &eth->mii_data);
120
121         /*
122          * wait for the related interrupt
123          */
124         start = get_timer(0);
125         while (!(readl(&eth->ievent) & FEC_IEVENT_MII)) {
126                 if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
127                         printf("Read MDIO failed...\n");
128                         return -1;
129                 }
130         }
131
132         /*
133          * clear mii interrupt bit
134          */
135         writel(FEC_IEVENT_MII, &eth->ievent);
136
137         /*
138          * it's now safe to read the PHY's register
139          */
140         *retVal = readl(&eth->mii_data);
141         debug("fec_miiphy_read: phy: %02x reg:%02x val:%#x\n", phyAddr,
142                         regAddr, *retVal);
143         return 0;
144 }
145
146 static void fec_mii_setspeed(struct fec_priv *fec)
147 {
148         /*
149          * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
150          * and do not drop the Preamble.
151          */
152         writel((((imx_get_fecclk() / 1000000) + 2) / 5) << 1,
153                         &fec->eth->mii_speed);
154         debug("fec_init: mii_speed %08x\n",
155                         readl(&fec->eth->mii_speed));
156 }
157 static int fec_miiphy_write(const char *dev, uint8_t phyAddr, uint8_t regAddr,
158                 uint16_t data)
159 {
160         struct eth_device *edev = eth_get_dev_by_name(dev);
161         struct fec_priv *fec = (struct fec_priv *)edev->priv;
162         struct ethernet_regs *eth = fec_miiphy_fec_to_eth(fec);
163
164         uint32_t reg;           /* convenient holder for the PHY register */
165         uint32_t phy;           /* convenient holder for the PHY */
166         uint32_t start;
167
168         reg = regAddr << FEC_MII_DATA_RA_SHIFT;
169         phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
170
171         writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR |
172                 FEC_MII_DATA_TA | phy | reg | data, &eth->mii_data);
173
174         /*
175          * wait for the MII interrupt
176          */
177         start = get_timer(0);
178         while (!(readl(&eth->ievent) & FEC_IEVENT_MII)) {
179                 if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
180                         printf("Write MDIO failed...\n");
181                         return -1;
182                 }
183         }
184
185         /*
186          * clear MII interrupt bit
187          */
188         writel(FEC_IEVENT_MII, &eth->ievent);
189         debug("fec_miiphy_write: phy: %02x reg:%02x val:%#x\n", phyAddr,
190                         regAddr, data);
191
192         return 0;
193 }
194
195 static int miiphy_restart_aneg(struct eth_device *dev)
196 {
197         struct fec_priv *fec = (struct fec_priv *)dev->priv;
198         int ret = 0;
199
200         /*
201          * Wake up from sleep if necessary
202          * Reset PHY, then delay 300ns
203          */
204 #ifdef CONFIG_MX27
205         miiphy_write(dev->name, fec->phy_id, MII_DCOUNTER, 0x00FF);
206 #endif
207         miiphy_write(dev->name, fec->phy_id, MII_BMCR,
208                         BMCR_RESET);
209         udelay(1000);
210
211         /*
212          * Set the auto-negotiation advertisement register bits
213          */
214         miiphy_write(dev->name, fec->phy_id, MII_ADVERTISE,
215                         LPA_100FULL | LPA_100HALF | LPA_10FULL |
216                         LPA_10HALF | PHY_ANLPAR_PSB_802_3);
217         miiphy_write(dev->name, fec->phy_id, MII_BMCR,
218                         BMCR_ANENABLE | BMCR_ANRESTART);
219
220         if (fec->mii_postcall)
221                 ret = fec->mii_postcall(fec->phy_id);
222
223         return ret;
224 }
225
226 static int miiphy_wait_aneg(struct eth_device *dev)
227 {
228         uint32_t start;
229         uint16_t status;
230         struct fec_priv *fec = (struct fec_priv *)dev->priv;
231
232         /*
233          * Wait for AN completion
234          */
235         start = get_timer(0);
236         do {
237                 if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
238                         printf("%s: Autonegotiation timeout\n", dev->name);
239                         return -1;
240                 }
241
242                 if (miiphy_read(dev->name, fec->phy_id,
243                                         MII_BMSR, &status)) {
244                         printf("%s: Autonegotiation failed. status: 0x%04x\n",
245                                         dev->name, status);
246                         return -1;
247                 }
248         } while (!(status & BMSR_LSTATUS));
249
250         return 0;
251 }
252
253 static inline void fec_rx_task_enable(struct fec_priv *fec)
254 {
255         writel(1 << 24, &fec->eth->r_des_active);
256 }
257
258 static inline void fec_rx_task_disable(struct fec_priv *fec)
259 {
260 }
261
262 static inline void fec_tx_task_enable(struct fec_priv *fec)
263 {
264         writel(1 << 24, &fec->eth->x_des_active);
265 }
266
267 static inline void fec_tx_task_disable(struct fec_priv *fec)
268 {
269 }
270
271 static inline void fec_invalidate_bd(struct fec_bd *bd)
272 {
273         invalidate_dcache_range((unsigned long)bd,
274                                 (unsigned long)bd + sizeof(*bd));
275 }
276
277 static inline void fec_flush_bd(struct fec_bd *bd)
278 {
279         flush_dcache_range((unsigned long)bd,
280                         (unsigned long)bd + sizeof(*bd));
281 }
282
283 /**
284  * Initialize receive task's buffer descriptors
285  * @param[in] fec all we know about the device yet
286  * @param[in] count receive buffer count to be allocated
287  * @param[in] size size of each receive buffer
288  * @return 0 on success
289  *
290  * For this task we need additional memory for the data buffers. And each
291  * data buffer requires some alignment. Thy must be aligned to a specific
292  * boundary each (DB_DATA_ALIGNMENT).
293  */
294 static int fec_rbd_init(struct fec_priv *fec, int count, int size)
295 {
296         int ix;
297         uint32_t p;
298
299         /* reserve data memory and consider alignment */
300         if (fec->rdb_ptr == NULL)
301                 fec->rdb_ptr = calloc(size * count + DB_DATA_ALIGNMENT, 1);
302         p = (uint32_t)fec->rdb_ptr;
303         if (!p) {
304                 puts("fec_mxc: not enough malloc memory\n");
305                 return -ENOMEM;
306         }
307         p = ALIGN(p, DB_DATA_ALIGNMENT);
308
309         for (ix = 0; ix < count; ix++) {
310                 writel(p, &fec->rbd_base[ix].data_pointer);
311                 invalidate_dcache_range(p, p + size);
312                 p += size;
313                 writew(FEC_RBD_EMPTY, &fec->rbd_base[ix].status);
314                 writew(0, &fec->rbd_base[ix].data_length);
315                 if (ix < count - 1)
316                         fec_flush_bd(&fec->rbd_base[ix]);
317         }
318         /*
319          * mark the last RBD to close the ring
320          */
321         writew(FEC_RBD_WRAP | FEC_RBD_EMPTY, &fec->rbd_base[ix - 1].status);
322         fec_flush_bd(&fec->rbd_base[ix - 1]);
323         fec->rbd_index = 0;
324
325         return 0;
326 }
327
328 /**
329  * Initialize transmit task's buffer descriptors
330  * @param[in] fec all we know about the device yet
331  *
332  * Transmit buffers are created externally. We only have to init the BDs here.\n
333  * Note: There is a race condition in the hardware. When only one BD is in
334  * use it must be marked with the WRAP bit to use it for every transmitt.
335  * This bit in combination with the READY bit results into double transmit
336  * of each data buffer. It seems the state machine checks READY earlier then
337  * resetting it after the first transfer.
338  * Using two BDs solves this issue.
339  */
340 static void fec_tbd_init(struct fec_priv *fec)
341 {
342         writew(0x0000, &fec->tbd_base[0].status);
343         fec_flush_bd(&fec->tbd_base[0]);
344         writew(FEC_TBD_WRAP, &fec->tbd_base[1].status);
345         fec_flush_bd(&fec->tbd_base[1]);
346         fec->tbd_index = 0;
347 }
348
349 /**
350  * Mark the given read buffer descriptor as free
351  * @param[in] last 1 if this is the last buffer descriptor in the chain, else 0
352  * @param[in] pRbd buffer descriptor to mark free again
353  */
354 static void fec_rbd_clean(int last, struct fec_bd *pRbd)
355 {
356         /*
357          * Reset buffer descriptor as empty
358          */
359         if (last)
360                 writew(FEC_RBD_WRAP | FEC_RBD_EMPTY, &pRbd->status);
361         else
362                 writew(FEC_RBD_EMPTY, &pRbd->status);
363         /*
364          * no data in it
365          */
366         writew(0, &pRbd->data_length);
367 }
368
369 static int fec_get_hwaddr(struct eth_device *dev, int dev_id,
370                                                 unsigned char *mac)
371 {
372         imx_get_mac_from_fuse(dev_id, mac);
373         return !is_valid_ether_addr(mac);
374 }
375
376 static int fec_set_hwaddr(struct eth_device *dev)
377 {
378         uchar *mac = dev->enetaddr;
379         struct fec_priv *fec = (struct fec_priv *)dev->priv;
380
381         writel(0, &fec->eth->iaddr1);
382         writel(0, &fec->eth->iaddr2);
383         writel(0, &fec->eth->gaddr1);
384         writel(0, &fec->eth->gaddr2);
385
386         /*
387          * Set physical address
388          */
389         writel((mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3],
390                         &fec->eth->paddr1);
391         writel((mac[4] << 24) + (mac[5] << 16) + 0x8808, &fec->eth->paddr2);
392
393         return 0;
394 }
395
396 /**
397  * Start the FEC engine
398  * @param[in] dev Our device to handle
399  */
400 static int fec_open(struct eth_device *edev)
401 {
402         struct fec_priv *fec = edev->priv;
403
404         debug("fec_open: fec_open(dev)\n");
405         /* full-duplex, heartbeat disabled */
406         writel(1 << 2, &fec->eth->x_cntrl);
407         fec->rbd_index = 0;
408
409 #if defined(CONFIG_MX6Q)
410         /* Enable ENET HW endian SWAP */
411         writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_DBSWAP,
412                 &fec->eth->ecntrl);
413         /* Enable ENET store and forward mode */
414         writel(readl(&fec->eth->x_wmrk) | FEC_X_WMRK_STRFWD,
415                 &fec->eth->x_wmrk);
416 #endif
417         /*
418          * Enable FEC-Lite controller
419          */
420         writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_ETHER_EN,
421                 &fec->eth->ecntrl);
422 #if defined(CONFIG_MX25) || defined(CONFIG_MX53)
423         udelay(100);
424         /*
425          * setup the MII gasket for RMII mode
426          */
427
428         /* disable the gasket */
429         writew(0, &fec->eth->miigsk_enr);
430
431         /* wait for the gasket to be disabled */
432         while (readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY)
433                 udelay(2);
434
435         /* configure gasket for RMII, 50 MHz, no loopback, and no echo */
436         writew(MIIGSK_CFGR_IF_MODE_RMII, &fec->eth->miigsk_cfgr);
437
438         /* re-enable the gasket */
439         writew(MIIGSK_ENR_EN, &fec->eth->miigsk_enr);
440
441         /* wait until MII gasket is ready */
442         int max_loops = 10;
443         while ((readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) == 0) {
444                 if (--max_loops <= 0) {
445                         printf("WAIT for MII Gasket ready timed out\n");
446                         break;
447                 }
448         }
449 #endif
450
451         miiphy_wait_aneg(edev);
452         miiphy_speed(edev->name, fec->phy_id);
453         miiphy_duplex(edev->name, fec->phy_id);
454
455         /*
456          * Enable SmartDMA receive task
457          */
458         fec_rx_task_enable(fec);
459
460         udelay(100000);
461         return 0;
462 }
463
464 static int fec_init(struct eth_device *dev, bd_t* bd)
465 {
466         void *base;
467         struct fec_priv *fec = (struct fec_priv *)dev->priv;
468         uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop;
469         uint32_t rcntrl;
470         int i;
471
472         /* Initialize MAC address */
473         fec_set_hwaddr(dev);
474
475         /*
476          * reserve memory for both buffer descriptor chains at once
477          * Datasheet forces the startaddress of each chain is 16 byte
478          * aligned
479          */
480         if (fec->base_ptr == NULL)
481                 fec->base_ptr = calloc((2 + FEC_RBD_NUM) *
482                                 sizeof(struct fec_bd) + DB_ALIGNMENT, 1);
483         base = fec->base_ptr;
484         if (!base) {
485                 puts("fec_mxc: not enough malloc memory\n");
486                 return -ENOMEM;
487         }
488         base = (void *)ALIGN((unsigned long)base, DB_ALIGNMENT);
489
490         fec->rbd_base = base;
491
492         base += FEC_RBD_NUM * sizeof(struct fec_bd);
493
494         fec->tbd_base = base;
495
496         /*
497          * Set interrupt mask register
498          */
499         writel(0x00000000, &fec->eth->imask);
500
501         /*
502          * Clear FEC-Lite interrupt event register(IEVENT)
503          */
504         writel(0xffffffff, &fec->eth->ievent);
505
506
507         /*
508          * Set FEC-Lite receive control register(R_CNTRL):
509          */
510
511         /* Start with frame length = 1518, common for all modes. */
512         rcntrl = PKTSIZE << FEC_RCNTRL_MAX_FL_SHIFT;
513         if (fec->xcv_type == SEVENWIRE)
514                 rcntrl |= FEC_RCNTRL_FCE;
515         else if (fec->xcv_type == RGMII)
516                 rcntrl |= FEC_RCNTRL_RGMII;
517         else if (fec->xcv_type == RMII)
518                 rcntrl |= FEC_RCNTRL_RMII;
519         else    /* MII mode */
520                 rcntrl |= FEC_RCNTRL_FCE | FEC_RCNTRL_MII_MODE;
521
522         writel(rcntrl, &fec->eth->r_cntrl);
523
524         if (fec->xcv_type == MII10 || fec->xcv_type == MII100)
525                 fec_mii_setspeed(fec);
526
527         /*
528          * Set Opcode/Pause Duration Register
529          */
530         writel(0x00010020, &fec->eth->op_pause);        /* FIXME 0xffff0020; */
531         writel(0x2, &fec->eth->x_wmrk);
532         /*
533          * Set multicast address filter
534          */
535         writel(0x00000000, &fec->eth->gaddr1);
536         writel(0x00000000, &fec->eth->gaddr2);
537
538
539         /* clear MIB RAM */
540         for (i = mib_ptr; i <= mib_ptr + 0xfc; i += 4)
541                 writel(0, i);
542
543         /* FIFO receive start register */
544         writel(0x520, &fec->eth->r_fstart);
545
546         /* size and address of each buffer */
547         writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr);
548         writel((uint32_t)fec->tbd_base, &fec->eth->etdsr);
549         writel((uint32_t)fec->rbd_base, &fec->eth->erdsr);
550
551         /*
552          * Initialize RxBD/TxBD rings
553          */
554         if (fec_rbd_init(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE) < 0) {
555                 free(fec->base_ptr);
556                 fec->base_ptr = NULL;
557                 return -ENOMEM;
558         }
559         fec_tbd_init(fec);
560
561         if (fec->xcv_type != SEVENWIRE)
562                 miiphy_restart_aneg(dev);
563
564         fec_open(dev);
565         return 0;
566 }
567
568 /**
569  * Halt the FEC engine
570  * @param[in] dev Our device to handle
571  */
572 static void fec_halt(struct eth_device *dev)
573 {
574         struct fec_priv *fec = (struct fec_priv *)dev->priv;
575         int counter = 0xffff;
576
577         /*
578          * issue graceful stop command to the FEC transmitter if necessary
579          */
580         writel(FEC_TCNTRL_GTS | readl(&fec->eth->x_cntrl),
581                         &fec->eth->x_cntrl);
582
583         debug("eth_halt: wait for stop regs\n");
584         /*
585          * wait for graceful stop to register
586          */
587         while ((counter--) && (!(readl(&fec->eth->ievent) & FEC_IEVENT_GRA)))
588                 udelay(1);
589
590         /*
591          * Disable SmartDMA tasks
592          */
593         fec_tx_task_disable(fec);
594         fec_rx_task_disable(fec);
595
596         /*
597          * Disable the Ethernet Controller
598          * Note: this will also reset the BD index counter!
599          */
600         writel(readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_ETHER_EN,
601                         &fec->eth->ecntrl);
602         fec->rbd_index = 0;
603         fec->tbd_index = 0;
604         debug("eth_halt: done\n");
605 }
606
607 /**
608  * Transmit one frame
609  * @param[in] dev Our ethernet device to handle
610  * @param[in] packet Pointer to the data to be transmitted
611  * @param[in] length Data count in bytes
612  * @return 0 on success
613  */
614 static int fec_send(struct eth_device *dev, volatile void *packet, int length)
615 {
616         unsigned int status;
617         int timeout = 1000;
618
619         /*
620          * This routine transmits one frame.  This routine only accepts
621          * 6-byte Ethernet addresses.
622          */
623         struct fec_priv *fec = dev->priv;
624
625         /*
626          * Check for valid length of data.
627          */
628         if ((length > 1500) || (length <= 0)) {
629                 printf("Payload (%d) too large\n", length);
630                 return -1;
631         }
632
633         /*
634          * Setup the transmit buffer
635          * Note: We are always using the first buffer for transmission,
636          * the second will be empty and only used to stop the DMA engine
637          */
638 #ifdef  CONFIG_FEC_MXC_SWAP_PACKET
639         swap_packet((uint32_t *)packet, length);
640 #endif
641         flush_dcache_range((unsigned long)packet,
642                         (unsigned long)packet + length);
643         fec_invalidate_bd(&fec->tbd_base[fec->tbd_index]);
644         writew(length, &fec->tbd_base[fec->tbd_index].data_length);
645         writel((uint32_t)packet, &fec->tbd_base[fec->tbd_index].data_pointer);
646
647         /*
648          * update BD's status now
649          * This block:
650          * - is always the last in a chain (means no chain)
651          * - should transmit the CRC
652          * - might be the last BD in the list, so the address counter should
653          *   wrap (-> keep the WRAP flag)
654          */
655         status = readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_WRAP;
656         status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
657         writew(status, &fec->tbd_base[fec->tbd_index].status);
658         fec_flush_bd(&fec->tbd_base[fec->tbd_index]);
659
660         /*
661          * Enable SmartDMA transmit task
662          */
663         fec_tx_task_enable(fec);
664
665         /*
666          * wait until frame is sent .
667          */
668         while (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) {
669                 if (--timeout < 0)
670                         return -ETIMEDOUT;
671                 udelay(1);
672                 fec_invalidate_bd(&fec->tbd_base[fec->tbd_index]);
673         }
674         debug("fec_send: status 0x%x index %d\n",
675                         readw(&fec->tbd_base[fec->tbd_index].status),
676                         fec->tbd_index);
677         /* for next transmission use the other buffer */
678         if (fec->tbd_index)
679                 fec->tbd_index = 0;
680         else
681                 fec->tbd_index = 1;
682
683         return 0;
684 }
685
686 /**
687  * Pull one frame from the card
688  * @param[in] dev Our ethernet device to handle
689  * @return Length of packet read
690  */
691 static int fec_recv(struct eth_device *dev)
692 {
693         struct fec_priv *fec = (struct fec_priv *)dev->priv;
694         struct fec_bd *rbd = &fec->rbd_base[fec->rbd_index];
695         unsigned long ievent;
696         int frame_length, len = 0;
697         struct nbuf *frame;
698         uint16_t bd_status;
699         uchar buff[FEC_MAX_PKT_SIZE];
700
701         /*
702          * Check if any critical events have happened
703          */
704         ievent = readl(&fec->eth->ievent);
705         writel(ievent, &fec->eth->ievent);
706         debug("fec_recv: ievent 0x%lx\n", ievent);
707         if (ievent & FEC_IEVENT_BABR) {
708                 fec_halt(dev);
709                 fec_init(dev, fec->bd);
710                 printf("some error: 0x%08lx\n", ievent);
711                 return 0;
712         }
713         if (ievent & FEC_IEVENT_HBERR) {
714                 /* Heartbeat error */
715                 writel(0x00000001 | readl(&fec->eth->x_cntrl),
716                                 &fec->eth->x_cntrl);
717         }
718         if (ievent & FEC_IEVENT_GRA) {
719                 /* Graceful stop complete */
720                 if (readl(&fec->eth->x_cntrl) & 0x00000001) {
721                         fec_halt(dev);
722                         writel(~0x00000001 & readl(&fec->eth->x_cntrl),
723                                         &fec->eth->x_cntrl);
724                         fec_init(dev, fec->bd);
725                 }
726         }
727
728         /*
729          * ensure reading the right buffer status
730          */
731         fec_invalidate_bd(rbd);
732         bd_status = readw(&rbd->status);
733         debug("fec_recv: status 0x%x\n", bd_status);
734
735         if (!(bd_status & FEC_RBD_EMPTY)) {
736                 if ((bd_status & FEC_RBD_LAST) && !(bd_status & FEC_RBD_ERR) &&
737                         ((readw(&rbd->data_length) - 4) > 14)) {
738                         /*
739                          * Get buffer address and size
740                          */
741                         frame = (struct nbuf *)readl(&rbd->data_pointer);
742                         frame_length = readw(&rbd->data_length) - 4;
743
744                         invalidate_dcache_range((unsigned long)frame,
745                                                 (unsigned long)frame +
746                                                 sizeof(*frame));
747
748                         /*
749                          *  Fill the buffer and pass it to upper layers
750                          */
751 #ifdef  CONFIG_FEC_MXC_SWAP_PACKET
752                         swap_packet((uint32_t *)frame->data, frame_length);
753 #endif
754                         memcpy(buff, frame->data, frame_length);
755                         NetReceive(buff, frame_length);
756                         len = frame_length;
757                 } else {
758                         if (bd_status & FEC_RBD_ERR)
759                                 printf("error frame: 0x%08lx 0x%08x\n",
760                                                 (ulong)rbd->data_pointer,
761                                                 bd_status);
762                 }
763                 /*
764                  * free the current buffer, restart the engine
765                  * and move forward to the next buffer
766                  */
767                 fec_rbd_clean(fec->rbd_index == (FEC_RBD_NUM - 1) ? 1 : 0, rbd);
768                 fec_flush_bd(rbd);
769                 fec_rx_task_enable(fec);
770                 fec->rbd_index = (fec->rbd_index + 1) % FEC_RBD_NUM;
771         }
772         debug("fec_recv: stop\n");
773
774         return len;
775 }
776
777 static int fec_probe(bd_t *bd, int dev_id, int phy_id, uint32_t base_addr)
778 {
779         struct eth_device *edev;
780         struct fec_priv *fec;
781         unsigned char ethaddr[6];
782         uint32_t start;
783         int ret = 0;
784
785         /* create and fill edev struct */
786         edev = calloc(sizeof(struct eth_device), 1);
787         if (!edev) {
788                 puts("fec_mxc: not enough malloc memory for eth_device\n");
789                 ret = -ENOMEM;
790                 goto err1;
791         }
792
793         fec = calloc(sizeof(struct fec_priv), 1);
794         if (!fec) {
795                 puts("fec_mxc: not enough malloc memory for fec_priv\n");
796                 ret = -ENOMEM;
797                 goto err2;
798         }
799
800         edev->priv = fec;
801         edev->init = fec_init;
802         edev->send = fec_send;
803         edev->recv = fec_recv;
804         edev->halt = fec_halt;
805         edev->write_hwaddr = fec_set_hwaddr;
806
807         fec->eth = (struct ethernet_regs *)base_addr;
808         fec->bd = bd;
809
810         fec->xcv_type = CONFIG_FEC_XCV_TYPE;
811
812         /* Reset chip. */
813         writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_RESET, &fec->eth->ecntrl);
814         start = get_timer(0);
815         while (readl(&fec->eth->ecntrl) & FEC_ECNTRL_RESET) {
816                 if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
817                         printf("FEC MXC: Timeout reseting chip\n");
818                         goto err3;
819                 }
820                 udelay(10);
821         }
822
823         /*
824          * Set interrupt mask register
825          */
826         writel(0x00000000, &fec->eth->imask);
827
828         /*
829          * Clear FEC-Lite interrupt event register(IEVENT)
830          */
831         writel(0xffffffff, &fec->eth->ievent);
832
833         /*
834          * Set FEC-Lite receive control register(R_CNTRL):
835          */
836         /*
837          * Frame length=1518; MII mode;
838          */
839         writel((PKTSIZE << FEC_RCNTRL_MAX_FL_SHIFT) | FEC_RCNTRL_FCE |
840                 FEC_RCNTRL_MII_MODE, &fec->eth->r_cntrl);
841         fec_mii_setspeed(fec);
842
843         if (dev_id == -1) {
844                 sprintf(edev->name, "FEC");
845                 fec->dev_id = 0;
846         } else {
847                 sprintf(edev->name, "FEC%i", dev_id);
848                 fec->dev_id = dev_id;
849         }
850         fec->phy_id = phy_id;
851
852         miiphy_register(edev->name, fec_miiphy_read, fec_miiphy_write);
853
854         eth_register(edev);
855
856         if (fec_get_hwaddr(edev, dev_id, ethaddr) == 0) {
857                 debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr);
858                 memcpy(edev->enetaddr, ethaddr, 6);
859         }
860
861         return ret;
862
863 err3:
864         free(fec);
865 err2:
866         free(edev);
867 err1:
868         return ret;
869 }
870
871 #ifndef CONFIG_FEC_MXC_MULTI
872 int fecmxc_initialize(bd_t *bd)
873 {
874         int lout = 1;
875
876         debug("eth_init: fec_probe(bd)\n");
877         lout = fec_probe(bd, -1, CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
878
879         return lout;
880 }
881 #endif
882
883 int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr)
884 {
885         int lout = 1;
886
887         debug("eth_init: fec_probe(bd, %i, %i) @ %08x\n", dev_id, phy_id, addr);
888         lout = fec_probe(bd, dev_id, phy_id, addr);
889
890         return lout;
891 }
892
893 int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int))
894 {
895         struct fec_priv *fec = (struct fec_priv *)dev->priv;
896         fec->mii_postcall = cb;
897         return 0;
898 }