]> git.ipfire.org Git - thirdparty/u-boot.git/blame - drivers/net/mpc8xx_fec.c
Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
[thirdparty/u-boot.git] / drivers / net / mpc8xx_fec.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
907208c4
CL
2/*
3 * (C) Copyright 2000
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
907208c4
CL
5 */
6
d678a59d 7#include <common.h>
907208c4 8#include <command.h>
db41d65a 9#include <hang.h>
907208c4
CL
10#include <malloc.h>
11#include <net.h>
08dd988b 12#include <netdev.h>
18f8d4c6 13#include <asm/cpm_8xx.h>
401d1c4f 14#include <asm/global_data.h>
ba3da734 15#include <asm/io.h>
c05ed00a 16#include <linux/delay.h>
907208c4
CL
17
18#include <phy.h>
68a6aa85 19#include <linux/mii.h>
907208c4
CL
20
21DECLARE_GLOBAL_DATA_PTR;
22
907208c4
CL
23/* define WANT_MII when MII support is required */
24#if defined(CONFIG_SYS_DISCOVER_PHY) || defined(CONFIG_FEC1_PHY) || defined(CONFIG_FEC2_PHY)
25#define WANT_MII
26#else
27#undef WANT_MII
28#endif
29
30#if defined(WANT_MII)
31#include <miiphy.h>
32
33#if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
34#error "CONFIG_MII has to be defined!"
35#endif
36
37#endif
38
39#if defined(CONFIG_RMII) && !defined(WANT_MII)
40#error RMII support is unusable without a working PHY.
41#endif
42
43#ifdef CONFIG_SYS_DISCOVER_PHY
81844ace 44static int mii_discover_phy(struct udevice *dev);
907208c4
CL
45#endif
46
47int fec8xx_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg);
48int fec8xx_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
49 u16 value);
50
51static struct ether_fcc_info_s
52{
53 int ether_index;
54 int fecp_offset;
55 int phy_addr;
56 int actual_phy_addr;
57 int initialized;
58}
59 ether_fcc_info[] = {
60#if defined(CONFIG_ETHER_ON_FEC1)
61 {
62 0,
63 offsetof(immap_t, im_cpm.cp_fec1),
907208c4 64 CONFIG_FEC1_PHY,
907208c4
CL
65 -1,
66 0,
67
68 },
69#endif
70#if defined(CONFIG_ETHER_ON_FEC2)
71 {
72 1,
73 offsetof(immap_t, im_cpm.cp_fec2),
907208c4 74 CONFIG_FEC2_PHY,
907208c4
CL
75 -1,
76 0,
77 },
78#endif
79};
80
81/* Ethernet Transmit and Receive Buffers */
82#define DBUF_LENGTH 1520
83
84#define TX_BUF_CNT 2
85
86#define TOUT_LOOP 100
87
88#define PKT_MAXBUF_SIZE 1518
89#define PKT_MINBUF_SIZE 64
90#define PKT_MAXBLR_SIZE 1520
91
92#ifdef __GNUC__
70fd0710 93static char txbuf[DBUF_LENGTH] __aligned(8);
907208c4
CL
94#else
95#error txbuf must be aligned.
96#endif
97
98static uint rxIdx; /* index of the current RX buffer */
99static uint txIdx; /* index of the current TX buffer */
100
101/*
102 * FEC Ethernet Tx and Rx buffer descriptors allocated at the
103 * immr->udata_bd address on Dual-Port RAM
104 * Provide for Double Buffering
105 */
106
ba3da734 107struct common_buf_desc {
70fd0710
CL
108 cbd_t rxbd[PKTBUFSRX]; /* Rx BD */
109 cbd_t txbd[TX_BUF_CNT]; /* Tx BD */
ba3da734 110};
907208c4 111
ba3da734 112static struct common_buf_desc __iomem *rtx;
907208c4 113
907208c4
CL
114#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
115static void __mii_init(void);
116#endif
117
81844ace 118static int fec_probe(struct udevice *dev)
907208c4 119{
81844ace
CL
120 struct ether_fcc_info_s *efis = dev_get_priv(dev);
121 int index = dev_get_driver_data(dev);
907208c4
CL
122 int i;
123
124 for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++) {
81844ace
CL
125 if (ether_fcc_info[i].ether_index != index)
126 continue;
907208c4 127
81844ace 128 memcpy(efis, &ether_fcc_info[i], sizeof(*efis));
907208c4 129
907208c4
CL
130 efis->actual_phy_addr = -1;
131
907208c4
CL
132#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
133 int retval;
134 struct mii_dev *mdiodev = mdio_alloc();
135 if (!mdiodev)
136 return -ENOMEM;
56b9caed 137 strlcpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
907208c4
CL
138 mdiodev->read = fec8xx_miiphy_read;
139 mdiodev->write = fec8xx_miiphy_write;
140
141 retval = mdio_register(mdiodev);
142 if (retval < 0)
143 return retval;
144#endif
145 }
81844ace 146 return 0;
907208c4
CL
147}
148
81844ace 149static int fec_send(struct udevice *dev, void *packet, int length)
907208c4
CL
150{
151 int j, rc;
81844ace 152 struct ether_fcc_info_s *efis = dev_get_priv(dev);
ba3da734
CL
153 fec_t __iomem *fecp =
154 (fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset);
907208c4
CL
155
156 /* section 16.9.23.3
157 * Wait for ready
158 */
159 j = 0;
ba3da734
CL
160 while ((in_be16(&rtx->txbd[txIdx].cbd_sc) & BD_ENET_TX_READY) &&
161 (j < TOUT_LOOP)) {
907208c4
CL
162 udelay(1);
163 j++;
164 }
70fd0710 165 if (j >= TOUT_LOOP)
907208c4 166 printf("TX not ready\n");
907208c4 167
ba3da734
CL
168 out_be32(&rtx->txbd[txIdx].cbd_bufaddr, (uint)packet);
169 out_be16(&rtx->txbd[txIdx].cbd_datlen, length);
170 setbits_be16(&rtx->txbd[txIdx].cbd_sc,
171 BD_ENET_TX_READY | BD_ENET_TX_LAST);
907208c4
CL
172
173 /* Activate transmit Buffer Descriptor polling */
ba3da734
CL
174 /* Descriptor polling active */
175 out_be32(&fecp->fec_x_des_active, 0x01000000);
907208c4
CL
176
177 j = 0;
ba3da734
CL
178 while ((in_be16(&rtx->txbd[txIdx].cbd_sc) & BD_ENET_TX_READY) &&
179 (j < TOUT_LOOP)) {
907208c4
CL
180 udelay(1);
181 j++;
182 }
70fd0710 183 if (j >= TOUT_LOOP)
907208c4 184 printf("TX timeout\n");
70fd0710 185
907208c4 186 /* return only status bits */;
ba3da734 187 rc = in_be16(&rtx->txbd[txIdx].cbd_sc) & BD_ENET_TX_STATS;
907208c4
CL
188
189 txIdx = (txIdx + 1) % TX_BUF_CNT;
190
191 return rc;
192}
193
81844ace 194static int fec_recv(struct udevice *dev, int flags, uchar **packetp)
907208c4 195{
907208c4
CL
196 int length;
197
81844ace
CL
198 /* section 16.9.23.2 */
199 if (in_be16(&rtx->rxbd[rxIdx].cbd_sc) & BD_ENET_RX_EMPTY)
200 return -EAGAIN;
907208c4 201
81844ace 202 length = in_be16(&rtx->rxbd[rxIdx].cbd_datlen);
907208c4 203
81844ace
CL
204 if (!(in_be16(&rtx->rxbd[rxIdx].cbd_sc) & 0x003f)) {
205 uchar *rx = net_rx_packets[rxIdx];
907208c4
CL
206
207#if defined(CONFIG_CMD_CDP)
81844ace
CL
208 if ((rx[0] & 1) != 0 &&
209 memcmp((uchar *)rx, net_bcast_ethaddr, 6) != 0 &&
210 !is_cdp_packet((uchar *)rx))
211 return 0;
907208c4 212#endif
81844ace 213 *packetp = rx;
907208c4 214
81844ace
CL
215 return length - 4;
216 } else {
217 return 0;
218 }
219}
907208c4 220
81844ace
CL
221static int fec_free_pkt(struct udevice *dev, uchar *packet, int length)
222{
223 struct ether_fcc_info_s *efis = dev_get_priv(dev);
224 fec_t __iomem *fecp =
225 (fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset);
226
227 /* Give the buffer back to the FEC. */
228 out_be16(&rtx->rxbd[rxIdx].cbd_datlen, 0);
229
230 /* wrap around buffer index when necessary */
231 if ((rxIdx + 1) >= PKTBUFSRX) {
232 out_be16(&rtx->rxbd[PKTBUFSRX - 1].cbd_sc,
233 BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
234 rxIdx = 0;
235 } else {
236 out_be16(&rtx->rxbd[rxIdx].cbd_sc, BD_ENET_RX_EMPTY);
237 rxIdx++;
907208c4
CL
238 }
239
81844ace
CL
240 /* Try to fill Buffer Descriptors */
241 /* Descriptor polling active */
242 out_be32(&fecp->fec_r_des_active, 0x01000000);
243
244 return 0;
907208c4
CL
245}
246
247/**************************************************************
248 *
249 * FEC Ethernet Initialization Routine
250 *
251 *************************************************************/
252
253#define FEC_ECNTRL_PINMUX 0x00000004
254#define FEC_ECNTRL_ETHER_EN 0x00000002
255#define FEC_ECNTRL_RESET 0x00000001
256
257#define FEC_RCNTRL_BC_REJ 0x00000010
258#define FEC_RCNTRL_PROM 0x00000008
259#define FEC_RCNTRL_MII_MODE 0x00000004
260#define FEC_RCNTRL_DRT 0x00000002
261#define FEC_RCNTRL_LOOP 0x00000001
262
263#define FEC_TCNTRL_FDEN 0x00000004
264#define FEC_TCNTRL_HBC 0x00000002
265#define FEC_TCNTRL_GTS 0x00000001
266
267#define FEC_RESET_DELAY 50
268
269#if defined(CONFIG_RMII)
270
81844ace 271static inline void fec_10Mbps(struct udevice *dev)
907208c4 272{
81844ace 273 struct ether_fcc_info_s *efis = dev_get_priv(dev);
907208c4
CL
274 int fecidx = efis->ether_index;
275 uint mask = (fecidx == 0) ? 0x0000010 : 0x0000008;
ba3da734 276 immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
907208c4
CL
277
278 if ((unsigned int)fecidx >= 2)
279 hang();
280
ba3da734 281 setbits_be32(&immr->im_cpm.cp_cptr, mask);
907208c4
CL
282}
283
81844ace 284static inline void fec_100Mbps(struct udevice *dev)
907208c4 285{
81844ace 286 struct ether_fcc_info_s *efis = dev_get_priv(dev);
907208c4
CL
287 int fecidx = efis->ether_index;
288 uint mask = (fecidx == 0) ? 0x0000010 : 0x0000008;
ba3da734 289 immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
907208c4
CL
290
291 if ((unsigned int)fecidx >= 2)
292 hang();
293
ba3da734 294 clrbits_be32(&immr->im_cpm.cp_cptr, mask);
907208c4
CL
295}
296
297#endif
298
81844ace 299static inline void fec_full_duplex(struct udevice *dev)
907208c4 300{
81844ace 301 struct ether_fcc_info_s *efis = dev_get_priv(dev);
ba3da734
CL
302 fec_t __iomem *fecp =
303 (fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset);
907208c4 304
ba3da734
CL
305 clrbits_be32(&fecp->fec_r_cntrl, FEC_RCNTRL_DRT);
306 setbits_be32(&fecp->fec_x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */
907208c4
CL
307}
308
81844ace 309static inline void fec_half_duplex(struct udevice *dev)
907208c4 310{
81844ace 311 struct ether_fcc_info_s *efis = dev_get_priv(dev);
ba3da734
CL
312 fec_t __iomem *fecp =
313 (fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset);
907208c4 314
ba3da734
CL
315 setbits_be32(&fecp->fec_r_cntrl, FEC_RCNTRL_DRT);
316 clrbits_be32(&fecp->fec_x_cntrl, FEC_TCNTRL_FDEN); /* FD disable */
907208c4
CL
317}
318
319static void fec_pin_init(int fecidx)
320{
b75d8dc5 321 struct bd_info *bd = gd->bd;
ba3da734 322 immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
907208c4
CL
323
324 /*
325 * Set MII speed to 2.5 MHz or slightly below.
326 *
327 * According to the MPC860T (Rev. D) Fast ethernet controller user
328 * manual (6.2.14),
329 * the MII management interface clock must be less than or equal
330 * to 2.5 MHz.
331 * This MDC frequency is equal to system clock / (2 * MII_SPEED).
332 * Then MII_SPEED = system_clock / 2 * 2,5 MHz.
333 *
334 * All MII configuration is done via FEC1 registers:
335 */
ba3da734
CL
336 out_be32(&immr->im_cpm.cp_fec1.fec_mii_speed,
337 ((bd->bi_intfreq + 4999999) / 5000000) << 1);
907208c4 338
b1e41d1c 339#if defined(CONFIG_MPC885) && defined(WANT_MII)
907208c4 340 /* use MDC for MII */
ba3da734
CL
341 setbits_be16(&immr->im_ioport.iop_pdpar, 0x0080);
342 clrbits_be16(&immr->im_ioport.iop_pddir, 0x0080);
907208c4
CL
343#endif
344
345 if (fecidx == 0) {
346#if defined(CONFIG_ETHER_ON_FEC1)
347
b1e41d1c 348#if defined(CONFIG_MPC885) /* MPC87x/88x have got 2 FECs and different pinout */
907208c4
CL
349
350#if !defined(CONFIG_RMII)
351
ba3da734
CL
352 setbits_be16(&immr->im_ioport.iop_papar, 0xf830);
353 setbits_be16(&immr->im_ioport.iop_padir, 0x0830);
354 clrbits_be16(&immr->im_ioport.iop_padir, 0xf000);
907208c4 355
ba3da734
CL
356 setbits_be32(&immr->im_cpm.cp_pbpar, 0x00001001);
357 clrbits_be32(&immr->im_cpm.cp_pbdir, 0x00001001);
907208c4 358
ba3da734
CL
359 setbits_be16(&immr->im_ioport.iop_pcpar, 0x000c);
360 clrbits_be16(&immr->im_ioport.iop_pcdir, 0x000c);
907208c4 361
ba3da734
CL
362 setbits_be32(&immr->im_cpm.cp_pepar, 0x00000003);
363 setbits_be32(&immr->im_cpm.cp_pedir, 0x00000003);
364 clrbits_be32(&immr->im_cpm.cp_peso, 0x00000003);
907208c4 365
ba3da734 366 clrbits_be32(&immr->im_cpm.cp_cptr, 0x00000100);
907208c4
CL
367
368#else
369
370#if !defined(CONFIG_FEC1_PHY_NORXERR)
ba3da734
CL
371 setbits_be16(&immr->im_ioport.iop_papar, 0x1000);
372 clrbits_be16(&immr->im_ioport.iop_padir, 0x1000);
907208c4 373#endif
ba3da734
CL
374 setbits_be16(&immr->im_ioport.iop_papar, 0xe810);
375 setbits_be16(&immr->im_ioport.iop_padir, 0x0810);
376 clrbits_be16(&immr->im_ioport.iop_padir, 0xe000);
907208c4 377
ba3da734
CL
378 setbits_be32(&immr->im_cpm.cp_pbpar, 0x00000001);
379 clrbits_be32(&immr->im_cpm.cp_pbdir, 0x00000001);
907208c4 380
ba3da734
CL
381 setbits_be32(&immr->im_cpm.cp_cptr, 0x00000100);
382 clrbits_be32(&immr->im_cpm.cp_cptr, 0x00000050);
907208c4
CL
383
384#endif /* !CONFIG_RMII */
385
386#else
387 /*
388 * Configure all of port D for MII.
389 */
ba3da734
CL
390 out_be16(&immr->im_ioport.iop_pdpar, 0x1fff);
391 out_be16(&immr->im_ioport.iop_pddir, 0x1fff);
53193a4f
CL
392
393#if defined(CONFIG_TARGET_MCR3000)
394 out_be16(&immr->im_ioport.iop_papar, 0xBBFF);
395 out_be16(&immr->im_ioport.iop_padir, 0x04F0);
396 out_be16(&immr->im_ioport.iop_paodr, 0x0000);
397
398 out_be32(&immr->im_cpm.cp_pbpar, 0x000133FF);
399 out_be32(&immr->im_cpm.cp_pbdir, 0x0003BF0F);
400 out_be16(&immr->im_cpm.cp_pbodr, 0x0000);
401
402 out_be16(&immr->im_ioport.iop_pcpar, 0x0400);
403 out_be16(&immr->im_ioport.iop_pcdir, 0x0080);
404 out_be16(&immr->im_ioport.iop_pcso , 0x0D53);
405 out_be16(&immr->im_ioport.iop_pcint, 0x0000);
406
407 out_be16(&immr->im_ioport.iop_pdpar, 0x03FE);
408 out_be16(&immr->im_ioport.iop_pddir, 0x1C09);
409
410 setbits_be32(&immr->im_ioport.utmode, 0x80);
411#endif
907208c4
CL
412#endif
413
414#endif /* CONFIG_ETHER_ON_FEC1 */
415 } else if (fecidx == 1) {
907208c4
CL
416#if defined(CONFIG_ETHER_ON_FEC2)
417
b1e41d1c 418#if defined(CONFIG_MPC885) /* MPC87x/88x have got 2 FECs and different pinout */
907208c4
CL
419
420#if !defined(CONFIG_RMII)
ba3da734
CL
421 setbits_be32(&immr->im_cpm.cp_pepar, 0x0003fffc);
422 setbits_be32(&immr->im_cpm.cp_pedir, 0x0003fffc);
423 clrbits_be32(&immr->im_cpm.cp_peso, 0x000087fc);
424 setbits_be32(&immr->im_cpm.cp_peso, 0x00037800);
907208c4 425
ba3da734 426 clrbits_be32(&immr->im_cpm.cp_cptr, 0x00000080);
907208c4
CL
427#else
428
429#if !defined(CONFIG_FEC2_PHY_NORXERR)
ba3da734
CL
430 setbits_be32(&immr->im_cpm.cp_pepar, 0x00000010);
431 setbits_be32(&immr->im_cpm.cp_pedir, 0x00000010);
432 clrbits_be32(&immr->im_cpm.cp_peso, 0x00000010);
907208c4 433#endif
ba3da734
CL
434 setbits_be32(&immr->im_cpm.cp_pepar, 0x00039620);
435 setbits_be32(&immr->im_cpm.cp_pedir, 0x00039620);
436 setbits_be32(&immr->im_cpm.cp_peso, 0x00031000);
437 clrbits_be32(&immr->im_cpm.cp_peso, 0x00008620);
907208c4 438
ba3da734
CL
439 setbits_be32(&immr->im_cpm.cp_cptr, 0x00000080);
440 clrbits_be32(&immr->im_cpm.cp_cptr, 0x00000028);
907208c4
CL
441#endif /* CONFIG_RMII */
442
b1e41d1c 443#endif /* CONFIG_MPC885 */
907208c4
CL
444
445#endif /* CONFIG_ETHER_ON_FEC2 */
907208c4
CL
446 }
447}
448
ba3da734 449static int fec_reset(fec_t __iomem *fecp)
907208c4
CL
450{
451 int i;
452
453 /* Whack a reset.
454 * A delay is required between a reset of the FEC block and
455 * initialization of other FEC registers because the reset takes
456 * some time to complete. If you don't delay, subsequent writes
457 * to FEC registers might get killed by the reset routine which is
458 * still in progress.
459 */
460
ba3da734
CL
461 out_be32(&fecp->fec_ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET);
462 for (i = 0; (in_be32(&fecp->fec_ecntrl) & FEC_ECNTRL_RESET) &&
463 (i < FEC_RESET_DELAY); ++i)
70fd0710 464 udelay(1);
ba3da734 465
907208c4
CL
466 if (i == FEC_RESET_DELAY)
467 return -1;
468
469 return 0;
470}
471
81844ace 472static int fec_start(struct udevice *dev)
907208c4 473{
81844ace
CL
474 struct eth_pdata *plat = dev_get_plat(dev);
475 struct ether_fcc_info_s *efis = dev_get_priv(dev);
ba3da734
CL
476 immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
477 fec_t __iomem *fecp =
478 (fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset);
907208c4
CL
479 int i;
480
481#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
482 /* the MII interface is connected to FEC1
483 * so for the miiphy_xxx function to work we must
484 * call mii_init since fec_halt messes the thing up
485 */
486 if (efis->ether_index != 0)
487 __mii_init();
488#endif
489
490 if (fec_reset(fecp) < 0)
70fd0710 491 printf("FEC_RESET_DELAY timeout\n");
907208c4
CL
492
493 /* We use strictly polling mode only
494 */
ba3da734 495 out_be32(&fecp->fec_imask, 0);
907208c4
CL
496
497 /* Clear any pending interrupt
498 */
ba3da734 499 out_be32(&fecp->fec_ievent, 0xffc0);
907208c4
CL
500
501 /* No need to set the IVEC register */
502
503 /* Set station address
504 */
81844ace 505#define ea plat->enetaddr
ba3da734
CL
506 out_be32(&fecp->fec_addr_low, (ea[0] << 24) | (ea[1] << 16) |
507 (ea[2] << 8) | ea[3]);
508 out_be16(&fecp->fec_addr_high, (ea[4] << 8) | ea[5]);
907208c4
CL
509#undef ea
510
511#if defined(CONFIG_CMD_CDP)
512 /*
513 * Turn on multicast address hash table
514 */
ba3da734
CL
515 out_be32(&fecp->fec_hash_table_high, 0xffffffff);
516 out_be32(&fecp->fec_hash_table_low, 0xffffffff);
907208c4
CL
517#else
518 /* Clear multicast address hash table
519 */
ba3da734
CL
520 out_be32(&fecp->fec_hash_table_high, 0);
521 out_be32(&fecp->fec_hash_table_low, 0);
907208c4
CL
522#endif
523
524 /* Set maximum receive buffer size.
525 */
ba3da734 526 out_be32(&fecp->fec_r_buff_size, PKT_MAXBLR_SIZE);
907208c4
CL
527
528 /* Set maximum frame length
529 */
ba3da734 530 out_be32(&fecp->fec_r_hash, PKT_MAXBUF_SIZE);
907208c4
CL
531
532 /*
70fd0710 533 * Setup Buffers and Buffer Descriptors
907208c4
CL
534 */
535 rxIdx = 0;
536 txIdx = 0;
537
538 if (!rtx)
ba3da734
CL
539 rtx = (struct common_buf_desc __iomem *)
540 (immr->im_cpm.cp_dpmem + CPM_FEC_BASE);
907208c4
CL
541 /*
542 * Setup Receiver Buffer Descriptors (13.14.24.18)
543 * Settings:
544 * Empty, Wrap
545 */
546 for (i = 0; i < PKTBUFSRX; i++) {
ba3da734
CL
547 out_be16(&rtx->rxbd[i].cbd_sc, BD_ENET_RX_EMPTY);
548 out_be16(&rtx->rxbd[i].cbd_datlen, 0); /* Reset */
549 out_be32(&rtx->rxbd[i].cbd_bufaddr, (uint)net_rx_packets[i]);
907208c4 550 }
ba3da734 551 setbits_be16(&rtx->rxbd[PKTBUFSRX - 1].cbd_sc, BD_ENET_RX_WRAP);
907208c4
CL
552
553 /*
554 * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
555 * Settings:
556 * Last, Tx CRC
557 */
558 for (i = 0; i < TX_BUF_CNT; i++) {
ba3da734
CL
559 out_be16(&rtx->txbd[i].cbd_sc, BD_ENET_TX_LAST | BD_ENET_TX_TC);
560 out_be16(&rtx->txbd[i].cbd_datlen, 0); /* Reset */
561 out_be32(&rtx->txbd[i].cbd_bufaddr, (uint)txbuf);
907208c4 562 }
ba3da734 563 setbits_be16(&rtx->txbd[TX_BUF_CNT - 1].cbd_sc, BD_ENET_TX_WRAP);
907208c4
CL
564
565 /* Set receive and transmit descriptor base
566 */
ba3da734
CL
567 out_be32(&fecp->fec_r_des_start, (__force unsigned int)rtx->rxbd);
568 out_be32(&fecp->fec_x_des_start, (__force unsigned int)rtx->txbd);
907208c4
CL
569
570 /* Enable MII mode
571 */
572 /* Half duplex mode */
ba3da734
CL
573 out_be32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE | FEC_RCNTRL_DRT);
574 out_be32(&fecp->fec_x_cntrl, 0);
907208c4
CL
575
576 /* Enable big endian and don't care about SDMA FC.
577 */
ba3da734 578 out_be32(&fecp->fec_fun_code, 0x78000000);
907208c4
CL
579
580 /*
581 * Setup the pin configuration of the FEC
582 */
70fd0710 583 fec_pin_init(efis->ether_index);
907208c4
CL
584
585 rxIdx = 0;
586 txIdx = 0;
587
588 /*
589 * Now enable the transmit and receive processing
590 */
ba3da734 591 out_be32(&fecp->fec_ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
907208c4
CL
592
593 if (efis->phy_addr == -1) {
594#ifdef CONFIG_SYS_DISCOVER_PHY
595 /*
596 * wait for the PHY to wake up after reset
597 */
70fd0710 598 efis->actual_phy_addr = mii_discover_phy(dev);
907208c4
CL
599
600 if (efis->actual_phy_addr == -1) {
70fd0710 601 printf("Unable to discover phy!\n");
907208c4
CL
602 return -1;
603 }
604#else
605 efis->actual_phy_addr = -1;
606#endif
607 } else {
608 efis->actual_phy_addr = efis->phy_addr;
609 }
610
611#if defined(CONFIG_MII) && defined(CONFIG_RMII)
612 /*
613 * adapt the RMII speed to the speed of the phy
614 */
70fd0710
CL
615 if (miiphy_speed(dev->name, efis->actual_phy_addr) == _100BASET)
616 fec_100Mbps(dev);
617 else
618 fec_10Mbps(dev);
907208c4
CL
619#endif
620
621#if defined(CONFIG_MII)
622 /*
623 * adapt to the half/full speed settings
624 */
70fd0710
CL
625 if (miiphy_duplex(dev->name, efis->actual_phy_addr) == FULL)
626 fec_full_duplex(dev);
627 else
628 fec_half_duplex(dev);
907208c4
CL
629#endif
630
631 /* And last, try to fill Rx Buffer Descriptors */
ba3da734
CL
632 /* Descriptor polling active */
633 out_be32(&fecp->fec_r_des_active, 0x01000000);
907208c4
CL
634
635 efis->initialized = 1;
636
637 return 0;
638}
639
640
81844ace 641static void fec_stop(struct udevice *dev)
907208c4 642{
81844ace 643 struct ether_fcc_info_s *efis = dev_get_priv(dev);
ba3da734
CL
644 fec_t __iomem *fecp =
645 (fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset);
907208c4
CL
646 int i;
647
648 /* avoid halt if initialized; mii gets stuck otherwise */
649 if (!efis->initialized)
650 return;
651
652 /* Whack a reset.
653 * A delay is required between a reset of the FEC block and
654 * initialization of other FEC registers because the reset takes
655 * some time to complete. If you don't delay, subsequent writes
656 * to FEC registers might get killed by the reset routine which is
657 * still in progress.
658 */
659
ba3da734
CL
660 out_be32(&fecp->fec_ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET);
661 for (i = 0; (in_be32(&fecp->fec_ecntrl) & FEC_ECNTRL_RESET) &&
662 (i < FEC_RESET_DELAY); ++i)
70fd0710 663 udelay(1);
ba3da734 664
907208c4 665 if (i == FEC_RESET_DELAY) {
70fd0710 666 printf("FEC_RESET_DELAY timeout\n");
907208c4
CL
667 return;
668 }
669
670 efis->initialized = 0;
671}
672
673#if defined(CONFIG_SYS_DISCOVER_PHY) || defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
674
675/* Make MII read/write commands for the FEC.
676*/
677
678#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | \
679 (REG & 0x1f) << 18))
680
681#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | \
682 (REG & 0x1f) << 18) | \
683 (VAL & 0xffff))
684
685/* Interrupt events/masks.
686*/
687#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
688#define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
689#define FEC_ENET_BABT ((uint)0x20000000) /* Babbling transmitter */
690#define FEC_ENET_GRA ((uint)0x10000000) /* Graceful stop complete */
691#define FEC_ENET_TXF ((uint)0x08000000) /* Full frame transmitted */
692#define FEC_ENET_TXB ((uint)0x04000000) /* A buffer was transmitted */
693#define FEC_ENET_RXF ((uint)0x02000000) /* Full frame received */
694#define FEC_ENET_RXB ((uint)0x01000000) /* A buffer was received */
695#define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */
696#define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */
697
698/* send command to phy using mii, wait for result */
699static uint
700mii_send(uint mii_cmd)
701{
702 uint mii_reply;
ba3da734 703 fec_t __iomem *ep;
907208c4 704 int cnt;
ba3da734 705 immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
907208c4 706
ba3da734 707 ep = &immr->im_cpm.cp_fec;
907208c4 708
ba3da734 709 out_be32(&ep->fec_mii_data, mii_cmd); /* command to phy */
907208c4
CL
710
711 /* wait for mii complete */
712 cnt = 0;
ba3da734 713 while (!(in_be32(&ep->fec_ievent) & FEC_ENET_MII)) {
907208c4
CL
714 if (++cnt > 1000) {
715 printf("mii_send STUCK!\n");
716 break;
717 }
718 }
ba3da734
CL
719 mii_reply = in_be32(&ep->fec_mii_data); /* result from phy */
720 out_be32(&ep->fec_ievent, FEC_ENET_MII); /* clear MII complete */
70fd0710 721 return mii_reply & 0xffff; /* data read from phy */
907208c4
CL
722}
723#endif
724
725#if defined(CONFIG_SYS_DISCOVER_PHY)
81844ace 726static int mii_discover_phy(struct udevice *dev)
907208c4
CL
727{
728#define MAX_PHY_PASSES 11
729 uint phyno;
730 int pass;
731 uint phytype;
732 int phyaddr;
733
734 phyaddr = -1; /* didn't find a PHY yet */
735 for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) {
736 if (pass > 1) {
737 /* PHY may need more time to recover from reset.
738 * The LXT970 needs 50ms typical, no maximum is
739 * specified, so wait 10ms before try again.
740 * With 11 passes this gives it 100ms to wake up.
741 */
742 udelay(10000); /* wait 10ms */
743 }
744 for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) {
745 phytype = mii_send(mk_mii_read(phyno, MII_PHYSID2));
746 if (phytype != 0xffff) {
747 phyaddr = phyno;
748 phytype |= mii_send(mk_mii_read(phyno,
749 MII_PHYSID1)) << 16;
750 }
751 }
752 }
70fd0710 753 if (phyaddr < 0)
907208c4 754 printf("No PHY device found.\n");
70fd0710 755
907208c4
CL
756 return phyaddr;
757}
758#endif /* CONFIG_SYS_DISCOVER_PHY */
759
760#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && !defined(CONFIG_BITBANGMII)
761
762/****************************************************************************
763 * mii_init -- Initialize the MII via FEC 1 for MII command without ethernet
764 * This function is a subset of eth_init
765 ****************************************************************************
766 */
767static void __mii_init(void)
768{
ba3da734
CL
769 immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
770 fec_t __iomem *fecp = &immr->im_cpm.cp_fec;
907208c4
CL
771
772 if (fec_reset(fecp) < 0)
70fd0710 773 printf("FEC_RESET_DELAY timeout\n");
907208c4
CL
774
775 /* We use strictly polling mode only
776 */
ba3da734 777 out_be32(&fecp->fec_imask, 0);
907208c4
CL
778
779 /* Clear any pending interrupt
780 */
ba3da734 781 out_be32(&fecp->fec_ievent, 0xffc0);
907208c4
CL
782
783 /* Now enable the transmit and receive processing
784 */
ba3da734 785 out_be32(&fecp->fec_ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
907208c4
CL
786}
787
70fd0710 788void mii_init(void)
907208c4
CL
789{
790 int i;
791
792 __mii_init();
793
794 /* Setup the pin configuration of the FEC(s)
795 */
796 for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++)
797 fec_pin_init(ether_fcc_info[i].ether_index);
798}
799
800/*****************************************************************************
801 * Read and write a MII PHY register, routines used by MII Utilities
802 *
803 * FIXME: These routines are expected to return 0 on success, but mii_send
804 * does _not_ return an error code. Maybe 0xFFFF means error, i.e.
805 * no PHY connected...
806 * For now always return 0.
807 * FIXME: These routines only work after calling eth_init() at least once!
808 * Otherwise they hang in mii_send() !!! Sorry!
809 *****************************************************************************/
810
811int fec8xx_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
812{
813 unsigned short value = 0;
814 short rdreg; /* register working value */
815
816 rdreg = mii_send(mk_mii_read(addr, reg));
817
818 value = rdreg;
819 return value;
820}
821
822int fec8xx_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
823 u16 value)
824{
825 (void)mii_send(mk_mii_write(addr, reg, value));
826
827 return 0;
828}
829#endif
81844ace
CL
830
831static const struct eth_ops fec_ops = {
832 .start = fec_start,
833 .send = fec_send,
834 .recv = fec_recv,
835 .stop = fec_stop,
836 .free_pkt = fec_free_pkt,
837};
838
839static const struct udevice_id fec_ids[] = {
840#ifdef CONFIG_ETHER_ON_FEC1
841 {
842 .compatible = "fsl,pq1-fec1",
843 .data = 0,
844 },
845#endif
846#ifdef CONFIG_ETHER_ON_FEC2
847 {
848 .compatible = "fsl,pq1-fec2",
849 .data = 1,
850 },
851#endif
852 { }
853};
854
855U_BOOT_DRIVER(fec) = {
856 .name = "fec",
857 .id = UCLASS_ETH,
858 .of_match = fec_ids,
859 .probe = fec_probe,
860 .ops = &fec_ops,
861 .priv_auto = sizeof(struct ether_fcc_info_s),
862 .plat_auto = sizeof(struct eth_pdata),
863};