1
2
3
4
5
6
7
8
9
10
11#include <config.h>
12#include <common.h>
13#include <dm.h>
14#include <malloc.h>
15#include <net.h>
16#include <command.h>
17#include <tsec.h>
18#include <fsl_mdio.h>
19#include <linux/errno.h>
20#include <asm/processor.h>
21#include <asm/io.h>
22
23#ifndef CONFIG_DM_ETH
24
25
26static struct tsec_info_struct tsec_info[] = {
27#ifdef CONFIG_TSEC1
28 STD_TSEC_INFO(1),
29#endif
30#ifdef CONFIG_TSEC2
31 STD_TSEC_INFO(2),
32#endif
33#ifdef CONFIG_MPC85XX_FEC
34 {
35 .regs = TSEC_GET_REGS(2, 0x2000),
36 .devname = CONFIG_MPC85XX_FEC_NAME,
37 .phyaddr = FEC_PHY_ADDR,
38 .flags = FEC_FLAGS,
39 .mii_devname = DEFAULT_MII_NAME
40 },
41#endif
42#ifdef CONFIG_TSEC3
43 STD_TSEC_INFO(3),
44#endif
45#ifdef CONFIG_TSEC4
46 STD_TSEC_INFO(4),
47#endif
48};
49#endif
50
51#define TBIANA_SETTINGS ( \
52 TBIANA_ASYMMETRIC_PAUSE \
53 | TBIANA_SYMMETRIC_PAUSE \
54 | TBIANA_FULL_DUPLEX \
55 )
56
57
58#ifndef CONFIG_TSEC_TBICR_SETTINGS
59#define CONFIG_TSEC_TBICR_SETTINGS ( \
60 TBICR_PHY_RESET \
61 | TBICR_ANEG_ENABLE \
62 | TBICR_FULL_DUPLEX \
63 | TBICR_SPEED1_SET \
64 )
65#endif
66
67
68static void tsec_configure_serdes(struct tsec_private *priv)
69{
70
71
72
73
74 tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa),
75 0, TBI_ANA, TBIANA_SETTINGS);
76 tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa),
77 0, TBI_TBICON, TBICON_CLK_SELECT);
78 tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa),
79 0, TBI_CR, CONFIG_TSEC_TBICR_SETTINGS);
80}
81
82#ifdef CONFIG_MCAST_TFTP
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102#ifndef CONFIG_DM_ETH
103static int tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set)
104#else
105static int tsec_mcast_addr(struct udevice *dev, const u8 *mcast_mac, int set)
106#endif
107{
108 struct tsec_private *priv = (struct tsec_private *)dev->priv;
109 struct tsec __iomem *regs = priv->regs;
110 u32 result, value;
111 u8 whichbit, whichreg;
112
113 result = ether_crc(MAC_ADDR_LEN, mcast_mac);
114 whichbit = (result >> 24) & 0x1f;
115 whichreg = result >> 29;
116
117 value = BIT(31 - whichbit);
118
119 if (set)
120 setbits_be32(®s->hash.gaddr0 + whichreg, value);
121 else
122 clrbits_be32(®s->hash.gaddr0 + whichreg, value);
123
124 return 0;
125}
126#endif
127
128
129
130
131
132
133static void init_registers(struct tsec __iomem *regs)
134{
135
136 out_be32(®s->ievent, IEVENT_INIT_CLEAR);
137
138 out_be32(®s->imask, IMASK_INIT_CLEAR);
139
140 out_be32(®s->hash.iaddr0, 0);
141 out_be32(®s->hash.iaddr1, 0);
142 out_be32(®s->hash.iaddr2, 0);
143 out_be32(®s->hash.iaddr3, 0);
144 out_be32(®s->hash.iaddr4, 0);
145 out_be32(®s->hash.iaddr5, 0);
146 out_be32(®s->hash.iaddr6, 0);
147 out_be32(®s->hash.iaddr7, 0);
148
149 out_be32(®s->hash.gaddr0, 0);
150 out_be32(®s->hash.gaddr1, 0);
151 out_be32(®s->hash.gaddr2, 0);
152 out_be32(®s->hash.gaddr3, 0);
153 out_be32(®s->hash.gaddr4, 0);
154 out_be32(®s->hash.gaddr5, 0);
155 out_be32(®s->hash.gaddr6, 0);
156 out_be32(®s->hash.gaddr7, 0);
157
158 out_be32(®s->rctrl, 0x00000000);
159
160
161 memset((void *)®s->rmon, 0, sizeof(regs->rmon));
162
163 out_be32(®s->rmon.cam1, 0xffffffff);
164 out_be32(®s->rmon.cam2, 0xffffffff);
165
166 out_be32(®s->mrblr, MRBLR_INIT_SETTINGS);
167
168 out_be32(®s->minflr, MINFLR_INIT_SETTINGS);
169
170 out_be32(®s->attr, ATTR_INIT_SETTINGS);
171 out_be32(®s->attreli, ATTRELI_INIT_SETTINGS);
172}
173
174
175
176
177
178static void adjust_link(struct tsec_private *priv, struct phy_device *phydev)
179{
180 struct tsec __iomem *regs = priv->regs;
181 u32 ecntrl, maccfg2;
182
183 if (!phydev->link) {
184 printf("%s: No link.\n", phydev->dev->name);
185 return;
186 }
187
188
189 ecntrl = in_be32(®s->ecntrl);
190 ecntrl &= ~ECNTRL_R100;
191
192 maccfg2 = in_be32(®s->maccfg2);
193 maccfg2 &= ~(MACCFG2_IF | MACCFG2_FULL_DUPLEX);
194
195 if (phydev->duplex)
196 maccfg2 |= MACCFG2_FULL_DUPLEX;
197
198 switch (phydev->speed) {
199 case 1000:
200 maccfg2 |= MACCFG2_GMII;
201 break;
202 case 100:
203 case 10:
204 maccfg2 |= MACCFG2_MII;
205
206
207
208
209
210 if (phydev->speed == 100)
211 ecntrl |= ECNTRL_R100;
212 break;
213 default:
214 printf("%s: Speed was bad\n", phydev->dev->name);
215 break;
216 }
217
218 out_be32(®s->ecntrl, ecntrl);
219 out_be32(®s->maccfg2, maccfg2);
220
221 printf("Speed: %d, %s duplex%s\n", phydev->speed,
222 (phydev->duplex) ? "full" : "half",
223 (phydev->port == PORT_FIBRE) ? ", fiber mode" : "");
224}
225
226
227
228
229
230
231
232#ifndef CONFIG_DM_ETH
233static int tsec_send(struct eth_device *dev, void *packet, int length)
234#else
235static int tsec_send(struct udevice *dev, void *packet, int length)
236#endif
237{
238 struct tsec_private *priv = (struct tsec_private *)dev->priv;
239 struct tsec __iomem *regs = priv->regs;
240 u16 status;
241 int result = 0;
242 int i;
243
244
245 for (i = 0;
246 in_be16(&priv->txbd[priv->tx_idx].status) & TXBD_READY;
247 i++) {
248 if (i >= TOUT_LOOP) {
249 debug("%s: tsec: tx buffers full\n", dev->name);
250 return result;
251 }
252 }
253
254 out_be32(&priv->txbd[priv->tx_idx].bufptr, (u32)packet);
255 out_be16(&priv->txbd[priv->tx_idx].length, length);
256 status = in_be16(&priv->txbd[priv->tx_idx].status);
257 out_be16(&priv->txbd[priv->tx_idx].status, status |
258 (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT));
259
260
261 out_be32(®s->tstat, TSTAT_CLEAR_THALT);
262
263
264 for (i = 0;
265 in_be16(&priv->txbd[priv->tx_idx].status) & TXBD_READY;
266 i++) {
267 if (i >= TOUT_LOOP) {
268 debug("%s: tsec: tx error\n", dev->name);
269 return result;
270 }
271 }
272
273 priv->tx_idx = (priv->tx_idx + 1) % TX_BUF_CNT;
274 result = in_be16(&priv->txbd[priv->tx_idx].status) & TXBD_STATS;
275
276 return result;
277}
278
279#ifndef CONFIG_DM_ETH
280static int tsec_recv(struct eth_device *dev)
281{
282 struct tsec_private *priv = (struct tsec_private *)dev->priv;
283 struct tsec __iomem *regs = priv->regs;
284
285 while (!(in_be16(&priv->rxbd[priv->rx_idx].status) & RXBD_EMPTY)) {
286 int length = in_be16(&priv->rxbd[priv->rx_idx].length);
287 u16 status = in_be16(&priv->rxbd[priv->rx_idx].status);
288 uchar *packet = net_rx_packets[priv->rx_idx];
289
290
291 if (!(status & RXBD_STATS))
292 net_process_received_packet(packet, length - 4);
293 else
294 printf("Got error %x\n", (status & RXBD_STATS));
295
296 out_be16(&priv->rxbd[priv->rx_idx].length, 0);
297
298 status = RXBD_EMPTY;
299
300 if ((priv->rx_idx + 1) == PKTBUFSRX)
301 status |= RXBD_WRAP;
302 out_be16(&priv->rxbd[priv->rx_idx].status, status);
303
304 priv->rx_idx = (priv->rx_idx + 1) % PKTBUFSRX;
305 }
306
307 if (in_be32(®s->ievent) & IEVENT_BSY) {
308 out_be32(®s->ievent, IEVENT_BSY);
309 out_be32(®s->rstat, RSTAT_CLEAR_RHALT);
310 }
311
312 return -1;
313}
314#else
315static int tsec_recv(struct udevice *dev, int flags, uchar **packetp)
316{
317 struct tsec_private *priv = (struct tsec_private *)dev->priv;
318 struct tsec __iomem *regs = priv->regs;
319 int ret = -1;
320
321 if (!(in_be16(&priv->rxbd[priv->rx_idx].status) & RXBD_EMPTY)) {
322 int length = in_be16(&priv->rxbd[priv->rx_idx].length);
323 u16 status = in_be16(&priv->rxbd[priv->rx_idx].status);
324 u32 buf;
325
326
327 if (!(status & RXBD_STATS)) {
328 buf = in_be32(&priv->rxbd[priv->rx_idx].bufptr);
329 *packetp = (uchar *)buf;
330 ret = length - 4;
331 } else {
332 printf("Got error %x\n", (status & RXBD_STATS));
333 }
334 }
335
336 if (in_be32(®s->ievent) & IEVENT_BSY) {
337 out_be32(®s->ievent, IEVENT_BSY);
338 out_be32(®s->rstat, RSTAT_CLEAR_RHALT);
339 }
340
341 return ret;
342}
343
344static int tsec_free_pkt(struct udevice *dev, uchar *packet, int length)
345{
346 struct tsec_private *priv = (struct tsec_private *)dev->priv;
347 u16 status;
348
349 out_be16(&priv->rxbd[priv->rx_idx].length, 0);
350
351 status = RXBD_EMPTY;
352
353 if ((priv->rx_idx + 1) == PKTBUFSRX)
354 status |= RXBD_WRAP;
355 out_be16(&priv->rxbd[priv->rx_idx].status, status);
356
357 priv->rx_idx = (priv->rx_idx + 1) % PKTBUFSRX;
358
359 return 0;
360}
361#endif
362
363
364#ifndef CONFIG_DM_ETH
365static void tsec_halt(struct eth_device *dev)
366#else
367static void tsec_halt(struct udevice *dev)
368#endif
369{
370 struct tsec_private *priv = (struct tsec_private *)dev->priv;
371 struct tsec __iomem *regs = priv->regs;
372
373 clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
374 setbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
375
376 while ((in_be32(®s->ievent) & (IEVENT_GRSC | IEVENT_GTSC))
377 != (IEVENT_GRSC | IEVENT_GTSC))
378 ;
379
380 clrbits_be32(®s->maccfg1, MACCFG1_TX_EN | MACCFG1_RX_EN);
381
382
383 phy_shutdown(priv->phydev);
384}
385
386#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129
387
388
389
390
391
392void redundant_init(struct tsec_private *priv)
393{
394 struct tsec __iomem *regs = priv->regs;
395 uint t, count = 0;
396 int fail = 1;
397 static const u8 pkt[] = {
398 0x00, 0x1e, 0x4f, 0x12, 0xcb, 0x2c, 0x00, 0x25,
399 0x64, 0xbb, 0xd1, 0xab, 0x08, 0x00, 0x45, 0x00,
400 0x00, 0x5c, 0xdd, 0x22, 0x00, 0x00, 0x80, 0x01,
401 0x1f, 0x71, 0x0a, 0xc1, 0x14, 0x22, 0x0a, 0xc1,
402 0x14, 0x6a, 0x08, 0x00, 0xef, 0x7e, 0x02, 0x00,
403 0x94, 0x05, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
404 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
405 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
406 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
407 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
408 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
409 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
410 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
411 0x71, 0x72};
412
413
414 setbits_be32(®s->rctrl, 0x8);
415
416 setbits_be32(®s->maccfg1, MACCFG1_LOOPBACK);
417
418 setbits_be32(®s->maccfg1, MACCFG1_RX_EN | MACCFG1_TX_EN);
419
420
421 setbits_be32(®s->dmactrl, DMACTRL_INIT_SETTINGS);
422 out_be32(®s->tstat, TSTAT_CLEAR_THALT);
423 out_be32(®s->rstat, RSTAT_CLEAR_RHALT);
424 clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
425
426 do {
427 u16 status;
428
429 tsec_send(priv->dev, (void *)pkt, sizeof(pkt));
430
431
432 for (t = 0;
433 in_be16(&priv->rxbd[priv->rx_idx].status) & RXBD_EMPTY;
434 t++) {
435 if (t >= 10 * TOUT_LOOP) {
436 printf("%s: tsec: rx error\n", priv->dev->name);
437 break;
438 }
439 }
440
441 if (!memcmp(pkt, net_rx_packets[priv->rx_idx], sizeof(pkt)))
442 fail = 0;
443
444 out_be16(&priv->rxbd[priv->rx_idx].length, 0);
445 status = RXBD_EMPTY;
446 if ((priv->rx_idx + 1) == PKTBUFSRX)
447 status |= RXBD_WRAP;
448 out_be16(&priv->rxbd[priv->rx_idx].status, status);
449 priv->rx_idx = (priv->rx_idx + 1) % PKTBUFSRX;
450
451 if (in_be32(®s->ievent) & IEVENT_BSY) {
452 out_be32(®s->ievent, IEVENT_BSY);
453 out_be32(®s->rstat, RSTAT_CLEAR_RHALT);
454 }
455 if (fail) {
456 printf("loopback recv packet error!\n");
457 clrbits_be32(®s->maccfg1, MACCFG1_RX_EN);
458 udelay(1000);
459 setbits_be32(®s->maccfg1, MACCFG1_RX_EN);
460 }
461 } while ((count++ < 4) && (fail == 1));
462
463 if (fail)
464 panic("eTSEC init fail!\n");
465
466 clrbits_be32(®s->rctrl, 0x8);
467
468 clrbits_be32(®s->maccfg1, MACCFG1_LOOPBACK);
469}
470#endif
471
472
473
474
475
476static void startup_tsec(struct tsec_private *priv)
477{
478 struct tsec __iomem *regs = priv->regs;
479 u16 status;
480 int i;
481
482
483 priv->rx_idx = 0;
484 priv->tx_idx = 0;
485#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129
486 uint svr;
487#endif
488
489
490 out_be32(®s->tbase, (u32)&priv->txbd[0]);
491 out_be32(®s->rbase, (u32)&priv->rxbd[0]);
492
493
494 for (i = 0; i < PKTBUFSRX; i++) {
495 out_be16(&priv->rxbd[i].status, RXBD_EMPTY);
496 out_be16(&priv->rxbd[i].length, 0);
497 out_be32(&priv->rxbd[i].bufptr, (u32)net_rx_packets[i]);
498 }
499 status = in_be16(&priv->rxbd[PKTBUFSRX - 1].status);
500 out_be16(&priv->rxbd[PKTBUFSRX - 1].status, status | RXBD_WRAP);
501
502
503 for (i = 0; i < TX_BUF_CNT; i++) {
504 out_be16(&priv->txbd[i].status, 0);
505 out_be16(&priv->txbd[i].length, 0);
506 out_be32(&priv->txbd[i].bufptr, 0);
507 }
508 status = in_be16(&priv->txbd[TX_BUF_CNT - 1].status);
509 out_be16(&priv->txbd[TX_BUF_CNT - 1].status, status | TXBD_WRAP);
510
511#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129
512 svr = get_svr();
513 if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0))
514 redundant_init(priv);
515#endif
516
517 setbits_be32(®s->maccfg1, MACCFG1_RX_EN | MACCFG1_TX_EN);
518
519
520 setbits_be32(®s->dmactrl, DMACTRL_INIT_SETTINGS);
521 out_be32(®s->tstat, TSTAT_CLEAR_THALT);
522 out_be32(®s->rstat, RSTAT_CLEAR_RHALT);
523 clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
524}
525
526
527
528
529
530
531
532#ifndef CONFIG_DM_ETH
533static int tsec_init(struct eth_device *dev, bd_t *bd)
534#else
535static int tsec_init(struct udevice *dev)
536#endif
537{
538 struct tsec_private *priv = (struct tsec_private *)dev->priv;
539#ifdef CONFIG_DM_ETH
540 struct eth_pdata *pdata = dev_get_platdata(dev);
541#endif
542 struct tsec __iomem *regs = priv->regs;
543 u32 tempval;
544 int ret;
545
546
547 tsec_halt(dev);
548
549
550 out_be32(®s->maccfg2, MACCFG2_INIT_SETTINGS);
551
552
553 out_be32(®s->ecntrl, ECNTRL_INIT_SETTINGS);
554
555
556
557
558
559
560
561#ifndef CONFIG_DM_ETH
562 tempval = (dev->enetaddr[5] << 24) | (dev->enetaddr[4] << 16) |
563 (dev->enetaddr[3] << 8) | dev->enetaddr[2];
564#else
565 tempval = (pdata->enetaddr[5] << 24) | (pdata->enetaddr[4] << 16) |
566 (pdata->enetaddr[3] << 8) | pdata->enetaddr[2];
567#endif
568
569 out_be32(®s->macstnaddr1, tempval);
570
571#ifndef CONFIG_DM_ETH
572 tempval = (dev->enetaddr[1] << 24) | (dev->enetaddr[0] << 16);
573#else
574 tempval = (pdata->enetaddr[1] << 24) | (pdata->enetaddr[0] << 16);
575#endif
576
577 out_be32(®s->macstnaddr2, tempval);
578
579
580 init_registers(regs);
581
582
583 startup_tsec(priv);
584
585
586 ret = phy_startup(priv->phydev);
587 if (ret) {
588 printf("Could not initialize PHY %s\n",
589 priv->phydev->dev->name);
590 return ret;
591 }
592
593 adjust_link(priv, priv->phydev);
594
595
596 return priv->phydev->link ? 0 : -1;
597}
598
599static phy_interface_t tsec_get_interface(struct tsec_private *priv)
600{
601 struct tsec __iomem *regs = priv->regs;
602 u32 ecntrl;
603
604 ecntrl = in_be32(®s->ecntrl);
605
606 if (ecntrl & ECNTRL_SGMII_MODE)
607 return PHY_INTERFACE_MODE_SGMII;
608
609 if (ecntrl & ECNTRL_TBI_MODE) {
610 if (ecntrl & ECNTRL_REDUCED_MODE)
611 return PHY_INTERFACE_MODE_RTBI;
612 else
613 return PHY_INTERFACE_MODE_TBI;
614 }
615
616 if (ecntrl & ECNTRL_REDUCED_MODE) {
617 phy_interface_t interface;
618
619 if (ecntrl & ECNTRL_REDUCED_MII_MODE)
620 return PHY_INTERFACE_MODE_RMII;
621
622 interface = priv->interface;
623
624
625
626
627
628 if (interface == PHY_INTERFACE_MODE_RGMII_ID ||
629 interface == PHY_INTERFACE_MODE_RGMII_TXID ||
630 interface == PHY_INTERFACE_MODE_RGMII_RXID)
631 return interface;
632
633 return PHY_INTERFACE_MODE_RGMII;
634 }
635
636 if (priv->flags & TSEC_GIGABIT)
637 return PHY_INTERFACE_MODE_GMII;
638
639 return PHY_INTERFACE_MODE_MII;
640}
641
642
643
644
645
646
647static int init_phy(struct tsec_private *priv)
648{
649 struct phy_device *phydev;
650 struct tsec __iomem *regs = priv->regs;
651 u32 supported = (SUPPORTED_10baseT_Half |
652 SUPPORTED_10baseT_Full |
653 SUPPORTED_100baseT_Half |
654 SUPPORTED_100baseT_Full);
655
656 if (priv->flags & TSEC_GIGABIT)
657 supported |= SUPPORTED_1000baseT_Full;
658
659
660 out_be32(®s->tbipa, priv->tbiaddr);
661
662 priv->interface = tsec_get_interface(priv);
663
664 if (priv->interface == PHY_INTERFACE_MODE_SGMII)
665 tsec_configure_serdes(priv);
666
667 phydev = phy_connect(priv->bus, priv->phyaddr, priv->dev,
668 priv->interface);
669 if (!phydev)
670 return 0;
671
672 phydev->supported &= supported;
673 phydev->advertising = phydev->supported;
674
675 priv->phydev = phydev;
676
677 phy_config(phydev);
678
679 return 1;
680}
681
682#ifndef CONFIG_DM_ETH
683
684
685
686
687static int tsec_initialize(bd_t *bis, struct tsec_info_struct *tsec_info)
688{
689 struct eth_device *dev;
690 int i;
691 struct tsec_private *priv;
692
693 dev = (struct eth_device *)malloc(sizeof(*dev));
694
695 if (!dev)
696 return 0;
697
698 memset(dev, 0, sizeof(*dev));
699
700 priv = (struct tsec_private *)malloc(sizeof(*priv));
701
702 if (!priv) {
703 free(dev);
704 return 0;
705 }
706
707 priv->regs = tsec_info->regs;
708 priv->phyregs_sgmii = tsec_info->miiregs_sgmii;
709
710 priv->phyaddr = tsec_info->phyaddr;
711 priv->tbiaddr = CONFIG_SYS_TBIPA_VALUE;
712 priv->flags = tsec_info->flags;
713
714 strcpy(dev->name, tsec_info->devname);
715 priv->interface = tsec_info->interface;
716 priv->bus = miiphy_get_dev_by_name(tsec_info->mii_devname);
717 priv->dev = dev;
718 dev->iobase = 0;
719 dev->priv = priv;
720 dev->init = tsec_init;
721 dev->halt = tsec_halt;
722 dev->send = tsec_send;
723 dev->recv = tsec_recv;
724#ifdef CONFIG_MCAST_TFTP
725 dev->mcast = tsec_mcast_addr;
726#endif
727
728
729 for (i = 0; i < 6; i++)
730 dev->enetaddr[i] = 0;
731
732 eth_register(dev);
733
734
735 setbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
736 udelay(2);
737 clrbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
738
739
740 return init_phy(priv);
741}
742
743
744
745
746
747
748int tsec_eth_init(bd_t *bis, struct tsec_info_struct *tsecs, int num)
749{
750 int i;
751 int count = 0;
752
753 for (i = 0; i < num; i++) {
754 int ret = tsec_initialize(bis, &tsecs[i]);
755
756 if (ret > 0)
757 count += ret;
758 }
759
760 return count;
761}
762
763int tsec_standard_init(bd_t *bis)
764{
765 struct fsl_pq_mdio_info info;
766
767 info.regs = TSEC_GET_MDIO_REGS_BASE(1);
768 info.name = DEFAULT_MII_NAME;
769
770 fsl_pq_mdio_init(bis, &info);
771
772 return tsec_eth_init(bis, tsec_info, ARRAY_SIZE(tsec_info));
773}
774#else
775int tsec_probe(struct udevice *dev)
776{
777 struct tsec_private *priv = dev_get_priv(dev);
778 struct eth_pdata *pdata = dev_get_platdata(dev);
779 struct fsl_pq_mdio_info mdio_info;
780 struct ofnode_phandle_args phandle_args;
781 ofnode parent;
782 const char *phy_mode;
783 int ret;
784
785 pdata->iobase = (phys_addr_t)dev_read_addr(dev);
786 priv->regs = (struct tsec *)pdata->iobase;
787
788 if (dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
789 &phandle_args)) {
790 debug("phy-handle does not exist under tsec %s\n", dev->name);
791 return -ENOENT;
792 } else {
793 int reg = ofnode_read_u32_default(phandle_args.node, "reg", 0);
794
795 priv->phyaddr = reg;
796 }
797
798 parent = ofnode_get_parent(phandle_args.node);
799 if (ofnode_valid(parent)) {
800 int reg = ofnode_read_u32_default(parent, "reg", 0);
801 priv->phyregs_sgmii = (struct tsec_mii_mng *)(reg + 0x520);
802 } else {
803 debug("No parent node for PHY?\n");
804 return -ENOENT;
805 }
806
807 if (dev_read_phandle_with_args(dev, "tbi-handle", NULL, 0, 0,
808 &phandle_args)) {
809 priv->tbiaddr = CONFIG_SYS_TBIPA_VALUE;
810 } else {
811 int reg = ofnode_read_u32_default(phandle_args.node, "reg",
812 CONFIG_SYS_TBIPA_VALUE);
813 priv->tbiaddr = reg;
814 }
815
816 phy_mode = dev_read_prop(dev, "phy-connection-type", NULL);
817 if (phy_mode)
818 pdata->phy_interface = phy_get_interface_by_name(phy_mode);
819 if (pdata->phy_interface == -1) {
820 debug("Invalid PHY interface '%s'\n", phy_mode);
821 return -EINVAL;
822 }
823 priv->interface = pdata->phy_interface;
824
825
826 priv->flags = TSEC_GIGABIT;
827 if (priv->interface == PHY_INTERFACE_MODE_SGMII)
828 priv->flags |= TSEC_SGMII;
829
830 mdio_info.regs = priv->phyregs_sgmii;
831 mdio_info.name = (char *)dev->name;
832 ret = fsl_pq_mdio_init(NULL, &mdio_info);
833 if (ret)
834 return ret;
835
836
837 setbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
838 udelay(2);
839 clrbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
840
841 priv->dev = dev;
842 priv->bus = miiphy_get_dev_by_name(dev->name);
843
844
845 return !init_phy(priv);
846}
847
848int tsec_remove(struct udevice *dev)
849{
850 struct tsec_private *priv = dev->priv;
851
852 free(priv->phydev);
853 mdio_unregister(priv->bus);
854 mdio_free(priv->bus);
855
856 return 0;
857}
858
859static const struct eth_ops tsec_ops = {
860 .start = tsec_init,
861 .send = tsec_send,
862 .recv = tsec_recv,
863 .free_pkt = tsec_free_pkt,
864 .stop = tsec_halt,
865#ifdef CONFIG_MCAST_TFTP
866 .mcast = tsec_mcast_addr,
867#endif
868};
869
870static const struct udevice_id tsec_ids[] = {
871 { .compatible = "fsl,tsec" },
872 { }
873};
874
875U_BOOT_DRIVER(eth_tsec) = {
876 .name = "tsec",
877 .id = UCLASS_ETH,
878 .of_match = tsec_ids,
879 .probe = tsec_probe,
880 .remove = tsec_remove,
881 .ops = &tsec_ops,
882 .priv_auto_alloc_size = sizeof(struct tsec_private),
883 .platdata_auto_alloc_size = sizeof(struct eth_pdata),
884 .flags = DM_FLAG_ALLOC_PRIV_DMA,
885};
886#endif
887