blob: 9ffc801bc708346c7cb5492d3624c8f6276e9f80 [file] [log] [blame]
wdenk42d1f032003-10-15 23:53:47 +00001/*
wdenk97d80fc2004-06-09 00:34:46 +00002 * Freescale Three Speed Ethernet Controller driver
wdenk42d1f032003-10-15 23:53:47 +00003 *
4 * This software may be used and distributed according to the
5 * terms of the GNU Public License, Version 2, incorporated
6 * herein by reference.
7 *
Mingkai Hua32a6be2011-01-27 12:52:45 +08008 * Copyright 2004-2011 Freescale Semiconductor, Inc.
wdenk42d1f032003-10-15 23:53:47 +00009 * (C) Copyright 2003, Motorola, Inc.
wdenk42d1f032003-10-15 23:53:47 +000010 * author Andy Fleming
11 *
12 */
13
14#include <config.h>
wdenk42d1f032003-10-15 23:53:47 +000015#include <common.h>
16#include <malloc.h>
17#include <net.h>
18#include <command.h>
Andy Flemingdd3d1f52008-08-31 16:33:25 -050019#include <tsec.h>
Andy Fleming063c1262011-04-08 02:10:54 -050020#include <fsl_mdio.h>
Kim Phillips0d071cd2009-08-24 14:32:26 -050021#include <asm/errno.h>
chenhui zhaoaada81d2011-10-03 08:38:50 -050022#include <asm/processor.h>
wdenk42d1f032003-10-15 23:53:47 +000023
Wolfgang Denkd87080b2006-03-31 18:32:53 +020024DECLARE_GLOBAL_DATA_PTR;
25
Marian Balakowicz63ff0042005-10-28 22:30:33 +020026#define TX_BUF_CNT 2
wdenk42d1f032003-10-15 23:53:47 +000027
Jon Loeliger89875e92006-10-10 17:03:43 -050028static uint rxIdx; /* index of the current RX buffer */
29static uint txIdx; /* index of the current TX buffer */
wdenk42d1f032003-10-15 23:53:47 +000030
31typedef volatile struct rtxbd {
32 txbd8_t txbd[TX_BUF_CNT];
33 rxbd8_t rxbd[PKTBUFSRX];
Jon Loeliger89875e92006-10-10 17:03:43 -050034} RTXBD;
wdenk42d1f032003-10-15 23:53:47 +000035
Andy Fleming75b9d4a2008-08-31 16:33:26 -050036#define MAXCONTROLLERS (8)
wdenk97d80fc2004-06-09 00:34:46 +000037
wdenk97d80fc2004-06-09 00:34:46 +000038static struct tsec_private *privlist[MAXCONTROLLERS];
Andy Fleming75b9d4a2008-08-31 16:33:26 -050039static int num_tsecs = 0;
wdenk97d80fc2004-06-09 00:34:46 +000040
wdenk42d1f032003-10-15 23:53:47 +000041#ifdef __GNUC__
42static RTXBD rtx __attribute__ ((aligned(8)));
43#else
44#error "rtx must be 64-bit aligned"
45#endif
46
Joe Hershbergerc8a60b52012-05-21 09:46:36 +000047static int tsec_send(struct eth_device *dev, void *packet, int length);
chenhui zhaoaada81d2011-10-03 08:38:50 -050048
Andy Fleming75b9d4a2008-08-31 16:33:26 -050049/* Default initializations for TSEC controllers. */
50
51static struct tsec_info_struct tsec_info[] = {
52#ifdef CONFIG_TSEC1
53 STD_TSEC_INFO(1), /* TSEC1 */
54#endif
55#ifdef CONFIG_TSEC2
56 STD_TSEC_INFO(2), /* TSEC2 */
57#endif
58#ifdef CONFIG_MPC85XX_FEC
59 {
60 .regs = (tsec_t *)(TSEC_BASE_ADDR + 0x2000),
Andy Fleming75b9d4a2008-08-31 16:33:26 -050061 .devname = CONFIG_MPC85XX_FEC_NAME,
62 .phyaddr = FEC_PHY_ADDR,
Andy Fleming063c1262011-04-08 02:10:54 -050063 .flags = FEC_FLAGS,
64 .mii_devname = DEFAULT_MII_NAME
Andy Fleming75b9d4a2008-08-31 16:33:26 -050065 }, /* FEC */
66#endif
67#ifdef CONFIG_TSEC3
68 STD_TSEC_INFO(3), /* TSEC3 */
69#endif
70#ifdef CONFIG_TSEC4
71 STD_TSEC_INFO(4), /* TSEC4 */
72#endif
73};
74
Andy Fleming2abe3612008-08-31 16:33:27 -050075#define TBIANA_SETTINGS ( \
76 TBIANA_ASYMMETRIC_PAUSE \
77 | TBIANA_SYMMETRIC_PAUSE \
78 | TBIANA_FULL_DUPLEX \
79 )
80
Felix Radensky90b5bf22010-06-28 01:57:39 +030081/* By default force the TBI PHY into 1000Mbps full duplex when in SGMII mode */
82#ifndef CONFIG_TSEC_TBICR_SETTINGS
Kumar Gala72c96a62010-12-01 22:55:54 -060083#define CONFIG_TSEC_TBICR_SETTINGS ( \
Andy Fleming2abe3612008-08-31 16:33:27 -050084 TBICR_PHY_RESET \
Kumar Gala72c96a62010-12-01 22:55:54 -060085 | TBICR_ANEG_ENABLE \
Andy Fleming2abe3612008-08-31 16:33:27 -050086 | TBICR_FULL_DUPLEX \
87 | TBICR_SPEED1_SET \
88 )
Felix Radensky90b5bf22010-06-28 01:57:39 +030089#endif /* CONFIG_TSEC_TBICR_SETTINGS */
Peter Tyser46e91672009-11-03 17:52:07 -060090
Andy Fleming2abe3612008-08-31 16:33:27 -050091/* Configure the TBI for SGMII operation */
92static void tsec_configure_serdes(struct tsec_private *priv)
93{
Peter Tyserc6dbdfd2009-11-09 13:09:46 -060094 /* Access TBI PHY registers at given TSEC register offset as opposed
95 * to the register offset used for external PHY accesses */
Andy Fleming063c1262011-04-08 02:10:54 -050096 tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa),
97 0, TBI_ANA, TBIANA_SETTINGS);
98 tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa),
99 0, TBI_TBICON, TBICON_CLK_SELECT);
100 tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa),
101 0, TBI_CR, CONFIG_TSEC_TBICR_SETTINGS);
Andy Fleming2abe3612008-08-31 16:33:27 -0500102}
michael.firth@bt.com55fe7c52008-01-16 11:40:51 +0000103
David Updegraff53a5c422007-06-11 10:41:07 -0500104#ifdef CONFIG_MCAST_TFTP
105
106/* CREDITS: linux gianfar driver, slightly adjusted... thanx. */
107
108/* Set the appropriate hash bit for the given addr */
109
110/* The algorithm works like so:
111 * 1) Take the Destination Address (ie the multicast address), and
112 * do a CRC on it (little endian), and reverse the bits of the
113 * result.
114 * 2) Use the 8 most significant bits as a hash into a 256-entry
115 * table. The table is controlled through 8 32-bit registers:
Claudiu Manoil876d4512013-09-30 12:44:40 +0300116 * gaddr0-7. gaddr0's MSB is entry 0, and gaddr7's LSB is entry
117 * 255. This means that the 3 most significant bits in the
David Updegraff53a5c422007-06-11 10:41:07 -0500118 * hash index which gaddr register to use, and the 5 other bits
119 * indicate which bit (assuming an IBM numbering scheme, which
Claudiu Manoil876d4512013-09-30 12:44:40 +0300120 * for PowerPC (tm) is usually the case) in the register holds
David Updegraff53a5c422007-06-11 10:41:07 -0500121 * the entry. */
122static int
Claudiu Manoil9c4cffa2013-09-30 12:44:39 +0300123tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set)
David Updegraff53a5c422007-06-11 10:41:07 -0500124{
Peter Tyserc6dbdfd2009-11-09 13:09:46 -0600125 struct tsec_private *priv = privlist[1];
Claudiu Manoil876d4512013-09-30 12:44:40 +0300126 struct tsec __iomem *regs = priv->regs;
127 u32 result, value;
128 u8 whichbit, whichreg;
David Updegraff53a5c422007-06-11 10:41:07 -0500129
Claudiu Manoil876d4512013-09-30 12:44:40 +0300130 result = ether_crc(MAC_ADDR_LEN, mcast_mac);
131 whichbit = (result >> 24) & 0x1f; /* the 5 LSB = which bit to set */
132 whichreg = result >> 29; /* the 3 MSB = which reg to set it in */
David Updegraff53a5c422007-06-11 10:41:07 -0500133
Claudiu Manoil876d4512013-09-30 12:44:40 +0300134 value = 1 << (31-whichbit);
David Updegraff53a5c422007-06-11 10:41:07 -0500135
Claudiu Manoil876d4512013-09-30 12:44:40 +0300136 if (set)
137 setbits_be32(&regs->hash.gaddr0 + whichreg, value);
138 else
139 clrbits_be32(&regs->hash.gaddr0 + whichreg, value);
140
David Updegraff53a5c422007-06-11 10:41:07 -0500141 return 0;
142}
143#endif /* Multicast TFTP ? */
Mingkai Hu90751912011-01-27 12:52:46 +0800144
145/* Initialized required registers to appropriate values, zeroing
146 * those we don't care about (unless zero is bad, in which case,
147 * choose a more appropriate value)
148 */
149static void init_registers(tsec_t *regs)
150{
151 /* Clear IEVENT */
152 out_be32(&regs->ievent, IEVENT_INIT_CLEAR);
153
154 out_be32(&regs->imask, IMASK_INIT_CLEAR);
155
156 out_be32(&regs->hash.iaddr0, 0);
157 out_be32(&regs->hash.iaddr1, 0);
158 out_be32(&regs->hash.iaddr2, 0);
159 out_be32(&regs->hash.iaddr3, 0);
160 out_be32(&regs->hash.iaddr4, 0);
161 out_be32(&regs->hash.iaddr5, 0);
162 out_be32(&regs->hash.iaddr6, 0);
163 out_be32(&regs->hash.iaddr7, 0);
164
165 out_be32(&regs->hash.gaddr0, 0);
166 out_be32(&regs->hash.gaddr1, 0);
167 out_be32(&regs->hash.gaddr2, 0);
168 out_be32(&regs->hash.gaddr3, 0);
169 out_be32(&regs->hash.gaddr4, 0);
170 out_be32(&regs->hash.gaddr5, 0);
171 out_be32(&regs->hash.gaddr6, 0);
172 out_be32(&regs->hash.gaddr7, 0);
173
174 out_be32(&regs->rctrl, 0x00000000);
175
176 /* Init RMON mib registers */
177 memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t));
178
179 out_be32(&regs->rmon.cam1, 0xffffffff);
180 out_be32(&regs->rmon.cam2, 0xffffffff);
181
182 out_be32(&regs->mrblr, MRBLR_INIT_SETTINGS);
183
184 out_be32(&regs->minflr, MINFLR_INIT_SETTINGS);
185
186 out_be32(&regs->attr, ATTR_INIT_SETTINGS);
187 out_be32(&regs->attreli, ATTRELI_INIT_SETTINGS);
188
189}
190
191/* Configure maccfg2 based on negotiated speed and duplex
192 * reported by PHY handling code
193 */
Andy Fleming063c1262011-04-08 02:10:54 -0500194static void adjust_link(struct tsec_private *priv, struct phy_device *phydev)
Mingkai Hu90751912011-01-27 12:52:46 +0800195{
Mingkai Hu90751912011-01-27 12:52:46 +0800196 tsec_t *regs = priv->regs;
197 u32 ecntrl, maccfg2;
198
Andy Fleming063c1262011-04-08 02:10:54 -0500199 if (!phydev->link) {
200 printf("%s: No link.\n", phydev->dev->name);
Mingkai Hu90751912011-01-27 12:52:46 +0800201 return;
202 }
203
204 /* clear all bits relative with interface mode */
205 ecntrl = in_be32(&regs->ecntrl);
206 ecntrl &= ~ECNTRL_R100;
207
208 maccfg2 = in_be32(&regs->maccfg2);
209 maccfg2 &= ~(MACCFG2_IF | MACCFG2_FULL_DUPLEX);
210
Andy Fleming063c1262011-04-08 02:10:54 -0500211 if (phydev->duplex)
Mingkai Hu90751912011-01-27 12:52:46 +0800212 maccfg2 |= MACCFG2_FULL_DUPLEX;
213
Andy Fleming063c1262011-04-08 02:10:54 -0500214 switch (phydev->speed) {
Mingkai Hu90751912011-01-27 12:52:46 +0800215 case 1000:
216 maccfg2 |= MACCFG2_GMII;
217 break;
218 case 100:
219 case 10:
220 maccfg2 |= MACCFG2_MII;
221
222 /* Set R100 bit in all modes although
223 * it is only used in RGMII mode
224 */
Andy Fleming063c1262011-04-08 02:10:54 -0500225 if (phydev->speed == 100)
Mingkai Hu90751912011-01-27 12:52:46 +0800226 ecntrl |= ECNTRL_R100;
227 break;
228 default:
Andy Fleming063c1262011-04-08 02:10:54 -0500229 printf("%s: Speed was bad\n", phydev->dev->name);
Mingkai Hu90751912011-01-27 12:52:46 +0800230 break;
231 }
232
233 out_be32(&regs->ecntrl, ecntrl);
234 out_be32(&regs->maccfg2, maccfg2);
235
Andy Fleming063c1262011-04-08 02:10:54 -0500236 printf("Speed: %d, %s duplex%s\n", phydev->speed,
237 (phydev->duplex) ? "full" : "half",
238 (phydev->port == PORT_FIBRE) ? ", fiber mode" : "");
Mingkai Hu90751912011-01-27 12:52:46 +0800239}
240
chenhui zhaoaada81d2011-10-03 08:38:50 -0500241#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129
242/*
243 * When MACCFG1[Rx_EN] is enabled during system boot as part
244 * of the eTSEC port initialization sequence,
245 * the eTSEC Rx logic may not be properly initialized.
246 */
247void redundant_init(struct eth_device *dev)
248{
249 struct tsec_private *priv = dev->priv;
250 tsec_t *regs = priv->regs;
251 uint t, count = 0;
252 int fail = 1;
253 static const u8 pkt[] = {
254 0x00, 0x1e, 0x4f, 0x12, 0xcb, 0x2c, 0x00, 0x25,
255 0x64, 0xbb, 0xd1, 0xab, 0x08, 0x00, 0x45, 0x00,
256 0x00, 0x5c, 0xdd, 0x22, 0x00, 0x00, 0x80, 0x01,
257 0x1f, 0x71, 0x0a, 0xc1, 0x14, 0x22, 0x0a, 0xc1,
258 0x14, 0x6a, 0x08, 0x00, 0xef, 0x7e, 0x02, 0x00,
259 0x94, 0x05, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
260 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
261 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
262 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
263 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
264 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
265 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
266 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
267 0x71, 0x72};
268
269 /* Enable promiscuous mode */
270 setbits_be32(&regs->rctrl, 0x8);
271 /* Enable loopback mode */
272 setbits_be32(&regs->maccfg1, MACCFG1_LOOPBACK);
273 /* Enable transmit and receive */
274 setbits_be32(&regs->maccfg1, MACCFG1_RX_EN | MACCFG1_TX_EN);
275
276 /* Tell the DMA it is clear to go */
277 setbits_be32(&regs->dmactrl, DMACTRL_INIT_SETTINGS);
278 out_be32(&regs->tstat, TSTAT_CLEAR_THALT);
279 out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
280 clrbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
281
282 do {
283 tsec_send(dev, (void *)pkt, sizeof(pkt));
284
285 /* Wait for buffer to be received */
286 for (t = 0; rtx.rxbd[rxIdx].status & RXBD_EMPTY; t++) {
287 if (t >= 10 * TOUT_LOOP) {
288 printf("%s: tsec: rx error\n", dev->name);
289 break;
290 }
291 }
292
293 if (!memcmp(pkt, (void *)NetRxPackets[rxIdx], sizeof(pkt)))
294 fail = 0;
295
296 rtx.rxbd[rxIdx].length = 0;
297 rtx.rxbd[rxIdx].status =
298 RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0);
299 rxIdx = (rxIdx + 1) % PKTBUFSRX;
300
301 if (in_be32(&regs->ievent) & IEVENT_BSY) {
302 out_be32(&regs->ievent, IEVENT_BSY);
303 out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
304 }
305 if (fail) {
306 printf("loopback recv packet error!\n");
307 clrbits_be32(&regs->maccfg1, MACCFG1_RX_EN);
308 udelay(1000);
309 setbits_be32(&regs->maccfg1, MACCFG1_RX_EN);
310 }
311 } while ((count++ < 4) && (fail == 1));
312
313 if (fail)
314 panic("eTSEC init fail!\n");
315 /* Disable promiscuous mode */
316 clrbits_be32(&regs->rctrl, 0x8);
317 /* Disable loopback mode */
318 clrbits_be32(&regs->maccfg1, MACCFG1_LOOPBACK);
319}
320#endif
321
Mingkai Hu90751912011-01-27 12:52:46 +0800322/* Set up the buffers and their descriptors, and bring up the
323 * interface
324 */
325static void startup_tsec(struct eth_device *dev)
326{
327 int i;
328 struct tsec_private *priv = (struct tsec_private *)dev->priv;
329 tsec_t *regs = priv->regs;
330
Andy Fleming063c1262011-04-08 02:10:54 -0500331 /* reset the indices to zero */
332 rxIdx = 0;
333 txIdx = 0;
chenhui zhaoaada81d2011-10-03 08:38:50 -0500334#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129
335 uint svr;
336#endif
Andy Fleming063c1262011-04-08 02:10:54 -0500337
Mingkai Hu90751912011-01-27 12:52:46 +0800338 /* Point to the buffer descriptors */
339 out_be32(&regs->tbase, (unsigned int)(&rtx.txbd[txIdx]));
340 out_be32(&regs->rbase, (unsigned int)(&rtx.rxbd[rxIdx]));
341
342 /* Initialize the Rx Buffer descriptors */
343 for (i = 0; i < PKTBUFSRX; i++) {
344 rtx.rxbd[i].status = RXBD_EMPTY;
345 rtx.rxbd[i].length = 0;
346 rtx.rxbd[i].bufPtr = (uint) NetRxPackets[i];
347 }
348 rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP;
349
350 /* Initialize the TX Buffer Descriptors */
351 for (i = 0; i < TX_BUF_CNT; i++) {
352 rtx.txbd[i].status = 0;
353 rtx.txbd[i].length = 0;
354 rtx.txbd[i].bufPtr = 0;
355 }
356 rtx.txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP;
357
chenhui zhaoaada81d2011-10-03 08:38:50 -0500358#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129
359 svr = get_svr();
360 if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0))
361 redundant_init(dev);
362#endif
Mingkai Hu90751912011-01-27 12:52:46 +0800363 /* Enable Transmit and Receive */
364 setbits_be32(&regs->maccfg1, MACCFG1_RX_EN | MACCFG1_TX_EN);
365
366 /* Tell the DMA it is clear to go */
367 setbits_be32(&regs->dmactrl, DMACTRL_INIT_SETTINGS);
368 out_be32(&regs->tstat, TSTAT_CLEAR_THALT);
369 out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
370 clrbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
371}
372
373/* This returns the status bits of the device. The return value
374 * is never checked, and this is what the 8260 driver did, so we
375 * do the same. Presumably, this would be zero if there were no
376 * errors
377 */
Joe Hershbergerc8a60b52012-05-21 09:46:36 +0000378static int tsec_send(struct eth_device *dev, void *packet, int length)
Mingkai Hu90751912011-01-27 12:52:46 +0800379{
380 int i;
381 int result = 0;
382 struct tsec_private *priv = (struct tsec_private *)dev->priv;
383 tsec_t *regs = priv->regs;
384
385 /* Find an empty buffer descriptor */
386 for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
387 if (i >= TOUT_LOOP) {
388 debug("%s: tsec: tx buffers full\n", dev->name);
389 return result;
390 }
391 }
392
393 rtx.txbd[txIdx].bufPtr = (uint) packet;
394 rtx.txbd[txIdx].length = length;
395 rtx.txbd[txIdx].status |=
396 (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT);
397
398 /* Tell the DMA to go */
399 out_be32(&regs->tstat, TSTAT_CLEAR_THALT);
400
401 /* Wait for buffer to be transmitted */
402 for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
403 if (i >= TOUT_LOOP) {
404 debug("%s: tsec: tx error\n", dev->name);
405 return result;
406 }
407 }
408
409 txIdx = (txIdx + 1) % TX_BUF_CNT;
410 result = rtx.txbd[txIdx].status & TXBD_STATS;
411
412 return result;
413}
414
415static int tsec_recv(struct eth_device *dev)
416{
417 int length;
418 struct tsec_private *priv = (struct tsec_private *)dev->priv;
419 tsec_t *regs = priv->regs;
420
421 while (!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) {
422
423 length = rtx.rxbd[rxIdx].length;
424
425 /* Send the packet up if there were no errors */
426 if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) {
427 NetReceive(NetRxPackets[rxIdx], length - 4);
428 } else {
429 printf("Got error %x\n",
430 (rtx.rxbd[rxIdx].status & RXBD_STATS));
431 }
432
433 rtx.rxbd[rxIdx].length = 0;
434
435 /* Set the wrap bit if this is the last element in the list */
436 rtx.rxbd[rxIdx].status =
437 RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0);
438
439 rxIdx = (rxIdx + 1) % PKTBUFSRX;
440 }
441
442 if (in_be32(&regs->ievent) & IEVENT_BSY) {
443 out_be32(&regs->ievent, IEVENT_BSY);
444 out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
445 }
446
447 return -1;
448
449}
450
451/* Stop the interface */
452static void tsec_halt(struct eth_device *dev)
453{
454 struct tsec_private *priv = (struct tsec_private *)dev->priv;
455 tsec_t *regs = priv->regs;
456
457 clrbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
458 setbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
459
460 while ((in_be32(&regs->ievent) & (IEVENT_GRSC | IEVENT_GTSC))
461 != (IEVENT_GRSC | IEVENT_GTSC))
462 ;
463
464 clrbits_be32(&regs->maccfg1, MACCFG1_TX_EN | MACCFG1_RX_EN);
465
466 /* Shut down the PHY, as needed */
Andy Fleming063c1262011-04-08 02:10:54 -0500467 phy_shutdown(priv->phydev);
Mingkai Hu90751912011-01-27 12:52:46 +0800468}
469
470/* Initializes data structures and registers for the controller,
471 * and brings the interface up. Returns the link status, meaning
472 * that it returns success if the link is up, failure otherwise.
473 * This allows u-boot to find the first active controller.
474 */
475static int tsec_init(struct eth_device *dev, bd_t * bd)
476{
477 uint tempval;
478 char tmpbuf[MAC_ADDR_LEN];
479 int i;
480 struct tsec_private *priv = (struct tsec_private *)dev->priv;
481 tsec_t *regs = priv->regs;
Timur Tabi11af8d62012-07-09 08:52:43 +0000482 int ret;
Mingkai Hu90751912011-01-27 12:52:46 +0800483
484 /* Make sure the controller is stopped */
485 tsec_halt(dev);
486
487 /* Init MACCFG2. Defaults to GMII */
488 out_be32(&regs->maccfg2, MACCFG2_INIT_SETTINGS);
489
490 /* Init ECNTRL */
491 out_be32(&regs->ecntrl, ECNTRL_INIT_SETTINGS);
492
493 /* Copy the station address into the address registers.
494 * Backwards, because little endian MACS are dumb */
495 for (i = 0; i < MAC_ADDR_LEN; i++)
496 tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->enetaddr[i];
497
498 tempval = (tmpbuf[0] << 24) | (tmpbuf[1] << 16) | (tmpbuf[2] << 8) |
499 tmpbuf[3];
500
501 out_be32(&regs->macstnaddr1, tempval);
502
503 tempval = *((uint *) (tmpbuf + 4));
504
505 out_be32(&regs->macstnaddr2, tempval);
506
Mingkai Hu90751912011-01-27 12:52:46 +0800507 /* Clear out (for the most part) the other registers */
508 init_registers(regs);
509
510 /* Ready the device for tx/rx */
511 startup_tsec(dev);
512
Andy Fleming063c1262011-04-08 02:10:54 -0500513 /* Start up the PHY */
Timur Tabi11af8d62012-07-09 08:52:43 +0000514 ret = phy_startup(priv->phydev);
515 if (ret) {
516 printf("Could not initialize PHY %s\n",
517 priv->phydev->dev->name);
518 return ret;
519 }
Andy Fleming063c1262011-04-08 02:10:54 -0500520
521 adjust_link(priv, priv->phydev);
522
Mingkai Hu90751912011-01-27 12:52:46 +0800523 /* If there's no link, fail */
Andy Fleming063c1262011-04-08 02:10:54 -0500524 return priv->phydev->link ? 0 : -1;
Mingkai Hu90751912011-01-27 12:52:46 +0800525}
526
Andy Fleming063c1262011-04-08 02:10:54 -0500527static phy_interface_t tsec_get_interface(struct tsec_private *priv)
528{
529 tsec_t *regs = priv->regs;
530 u32 ecntrl;
531
532 ecntrl = in_be32(&regs->ecntrl);
533
534 if (ecntrl & ECNTRL_SGMII_MODE)
535 return PHY_INTERFACE_MODE_SGMII;
536
537 if (ecntrl & ECNTRL_TBI_MODE) {
538 if (ecntrl & ECNTRL_REDUCED_MODE)
539 return PHY_INTERFACE_MODE_RTBI;
540 else
541 return PHY_INTERFACE_MODE_TBI;
542 }
543
544 if (ecntrl & ECNTRL_REDUCED_MODE) {
545 if (ecntrl & ECNTRL_REDUCED_MII_MODE)
546 return PHY_INTERFACE_MODE_RMII;
547 else {
548 phy_interface_t interface = priv->interface;
549
550 /*
551 * This isn't autodetected, so it must
552 * be set by the platform code.
553 */
554 if ((interface == PHY_INTERFACE_MODE_RGMII_ID) ||
555 (interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
556 (interface == PHY_INTERFACE_MODE_RGMII_RXID))
557 return interface;
558
559 return PHY_INTERFACE_MODE_RGMII;
560 }
561 }
562
563 if (priv->flags & TSEC_GIGABIT)
564 return PHY_INTERFACE_MODE_GMII;
565
566 return PHY_INTERFACE_MODE_MII;
567}
568
569
Mingkai Hu90751912011-01-27 12:52:46 +0800570/* Discover which PHY is attached to the device, and configure it
571 * properly. If the PHY is not recognized, then return 0
572 * (failure). Otherwise, return 1
573 */
574static int init_phy(struct eth_device *dev)
575{
576 struct tsec_private *priv = (struct tsec_private *)dev->priv;
Andy Fleming063c1262011-04-08 02:10:54 -0500577 struct phy_device *phydev;
Mingkai Hu90751912011-01-27 12:52:46 +0800578 tsec_t *regs = priv->regs;
Andy Fleming063c1262011-04-08 02:10:54 -0500579 u32 supported = (SUPPORTED_10baseT_Half |
580 SUPPORTED_10baseT_Full |
581 SUPPORTED_100baseT_Half |
582 SUPPORTED_100baseT_Full);
583
584 if (priv->flags & TSEC_GIGABIT)
585 supported |= SUPPORTED_1000baseT_Full;
Mingkai Hu90751912011-01-27 12:52:46 +0800586
587 /* Assign a Physical address to the TBI */
588 out_be32(&regs->tbipa, CONFIG_SYS_TBIPA_VALUE);
589
Andy Fleming063c1262011-04-08 02:10:54 -0500590 priv->interface = tsec_get_interface(priv);
Mingkai Hu90751912011-01-27 12:52:46 +0800591
Andy Fleming063c1262011-04-08 02:10:54 -0500592 if (priv->interface == PHY_INTERFACE_MODE_SGMII)
Mingkai Hu90751912011-01-27 12:52:46 +0800593 tsec_configure_serdes(priv);
594
Andy Fleming063c1262011-04-08 02:10:54 -0500595 phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface);
Mingkai Hu90751912011-01-27 12:52:46 +0800596
Andy Fleming063c1262011-04-08 02:10:54 -0500597 phydev->supported &= supported;
598 phydev->advertising = phydev->supported;
599
600 priv->phydev = phydev;
601
602 phy_config(phydev);
Mingkai Hu90751912011-01-27 12:52:46 +0800603
604 return 1;
605}
606
607/* Initialize device structure. Returns success if PHY
608 * initialization succeeded (i.e. if it recognizes the PHY)
609 */
610static int tsec_initialize(bd_t *bis, struct tsec_info_struct *tsec_info)
611{
612 struct eth_device *dev;
613 int i;
614 struct tsec_private *priv;
615
616 dev = (struct eth_device *)malloc(sizeof *dev);
617
618 if (NULL == dev)
619 return 0;
620
621 memset(dev, 0, sizeof *dev);
622
623 priv = (struct tsec_private *)malloc(sizeof(*priv));
624
625 if (NULL == priv)
626 return 0;
627
628 privlist[num_tsecs++] = priv;
629 priv->regs = tsec_info->regs;
Mingkai Hu90751912011-01-27 12:52:46 +0800630 priv->phyregs_sgmii = tsec_info->miiregs_sgmii;
631
632 priv->phyaddr = tsec_info->phyaddr;
633 priv->flags = tsec_info->flags;
634
635 sprintf(dev->name, tsec_info->devname);
Andy Fleming063c1262011-04-08 02:10:54 -0500636 priv->interface = tsec_info->interface;
637 priv->bus = miiphy_get_dev_by_name(tsec_info->mii_devname);
Mingkai Hu90751912011-01-27 12:52:46 +0800638 dev->iobase = 0;
639 dev->priv = priv;
640 dev->init = tsec_init;
641 dev->halt = tsec_halt;
642 dev->send = tsec_send;
643 dev->recv = tsec_recv;
644#ifdef CONFIG_MCAST_TFTP
645 dev->mcast = tsec_mcast_addr;
646#endif
647
648 /* Tell u-boot to get the addr from the env */
649 for (i = 0; i < 6; i++)
650 dev->enetaddr[i] = 0;
651
652 eth_register(dev);
653
654 /* Reset the MAC */
655 setbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
656 udelay(2); /* Soft Reset must be asserted for 3 TX clocks */
657 clrbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
658
Mingkai Hu90751912011-01-27 12:52:46 +0800659 /* Try to initialize PHY here, and return */
660 return init_phy(dev);
661}
662
663/*
664 * Initialize all the TSEC devices
665 *
666 * Returns the number of TSEC devices that were initialized
667 */
668int tsec_eth_init(bd_t *bis, struct tsec_info_struct *tsecs, int num)
669{
670 int i;
671 int ret, count = 0;
672
673 for (i = 0; i < num; i++) {
674 ret = tsec_initialize(bis, &tsecs[i]);
675 if (ret > 0)
676 count += ret;
677 }
678
679 return count;
680}
681
682int tsec_standard_init(bd_t *bis)
683{
Andy Fleming063c1262011-04-08 02:10:54 -0500684 struct fsl_pq_mdio_info info;
685
686 info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR;
687 info.name = DEFAULT_MII_NAME;
688
689 fsl_pq_mdio_init(bis, &info);
690
Mingkai Hu90751912011-01-27 12:52:46 +0800691 return tsec_eth_init(bis, tsec_info, ARRAY_SIZE(tsec_info));
692}