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