* Patch by Dan Malek, 07 Apr 2004:
[oweals/u-boot.git] / cpu / mpc85xx / tsec.c
1 /*
2  * tsec.c
3  * Motorola Three Speed Ethernet Controller driver
4  *
5  * This software may be used and distributed according to the
6  * terms of the GNU Public License, Version 2, incorporated
7  * herein by reference.
8  *
9  * (C) Copyright 2003, Motorola, Inc.
10  * maintained by Xianghua Xiao (x.xiao@motorola.com)
11  * author Andy Fleming
12  *
13  */
14
15 #include <config.h>
16 #include <mpc85xx.h>
17 #include <common.h>
18 #include <malloc.h>
19 #include <net.h>
20 #include <command.h>
21
22 #if defined(CONFIG_TSEC_ENET)
23 #include "tsec.h"
24
25 #define TX_BUF_CNT 2
26
27 #undef TSEC_DEBUG
28 #ifdef TSEC_DEBUG
29 #define DBGPRINT(x) printf(x)
30 #else
31 #define DBGPRINT(x)
32 #endif
33
34 static uint rxIdx;      /* index of the current RX buffer */
35 static uint txIdx;      /* index of the current TX buffer */
36
37 typedef volatile struct rtxbd {
38         txbd8_t txbd[TX_BUF_CNT];
39         rxbd8_t rxbd[PKTBUFSRX];
40 }  RTXBD;
41
42 #ifdef __GNUC__
43 static RTXBD rtx __attribute__ ((aligned(8)));
44 #else
45 #error "rtx must be 64-bit aligned"
46 #endif
47
48 static int tsec_send(struct eth_device* dev, volatile void *packet, int length);
49 static int tsec_recv(struct eth_device* dev);
50 static int tsec_init(struct eth_device* dev, bd_t * bd);
51 static void tsec_halt(struct eth_device* dev);
52 static void init_registers(tsec_t *regs);
53 static void startup_tsec(tsec_t *regs);
54 static void init_phy(tsec_t *regs);
55 uint read_phy_reg(tsec_t *regbase, uint phyid, uint offset);
56
57 static int      phy_id = -1;
58
59 /* Initialize device structure.  returns 0 on failure, 1 on
60  * success */
61 int tsec_initialize(bd_t *bis)
62 {
63         struct eth_device* dev;
64         int i;
65         tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
66
67         dev = (struct eth_device*) malloc(sizeof *dev);
68
69         if(dev == NULL)
70                 return 0;
71
72         memset(dev, 0, sizeof *dev);
73
74         sprintf(dev->name, "MOTO ETHERNET");
75         dev->iobase = 0;
76         dev->priv   = 0;
77         dev->init   = tsec_init;
78         dev->halt   = tsec_halt;
79         dev->send   = tsec_send;
80         dev->recv   = tsec_recv;
81
82         /* Tell u-boot to get the addr from the env */
83         for(i=0;i<6;i++)
84                 dev->enetaddr[i] = 0;
85
86         eth_register(dev);
87
88         /* Reconfigure the PHY to advertise everything here
89          * so that it works with both gigabit and 10/100 */
90 #ifdef CONFIG_PHY_M88E1011
91         /* Assign a Physical address to the TBI */
92         regs->tbipa=TBIPA_VALUE;
93
94         /* reset the management interface */
95         regs->miimcfg=MIIMCFG_RESET;
96
97         regs->miimcfg=MIIMCFG_INIT_VALUE;
98
99         /* Wait until the bus is free */
100         while(regs->miimind & MIIMIND_BUSY);
101
102         /* Locate PHYs.  Skip TBIPA, which we know is 31.
103         */
104         for (i=0; i<31; i++) {
105                 if (read_phy_reg(regs, i, 2) == 0x141) {
106                         if (phy_id == -1)
107                                 phy_id = i;
108 #ifdef TSEC_DEBUG
109                         printf("Found Marvell PHY at 0x%02x\n", i);
110 #endif
111                 }
112         }
113 #ifdef TSEC_DEBUG
114         printf("Using PHY ID 0x%02x\n", phy_id);
115 #endif
116         write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_RESET);
117
118         RESET_ERRATA(regs, phy_id);
119
120         /* Configure the PHY to advertise gbit and 10/100 */
121         write_phy_reg(regs, phy_id, MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT);
122         write_phy_reg(regs, phy_id, MIIM_ANAR, MIIM_ANAR_INIT);
123
124         /* Reset the PHY so the new settings take effect */
125         write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_RESET);
126 #endif
127         return 1;
128 }
129
130
131 /* Initializes data structures and registers for the controller,
132  * and brings the interface up */
133 int tsec_init(struct eth_device* dev, bd_t * bd)
134 {
135         tsec_t *regs;
136         uint tempval;
137         char tmpbuf[MAC_ADDR_LEN];
138         int i;
139
140         regs = (tsec_t *)(TSEC_BASE_ADDR);
141
142         /* Make sure the controller is stopped */
143         tsec_halt(dev);
144
145         /* Reset the MAC */
146         regs->maccfg1 |= MACCFG1_SOFT_RESET;
147
148         /* Clear MACCFG1[Soft_Reset] */
149         regs->maccfg1 &= ~(MACCFG1_SOFT_RESET);
150
151         /* Init MACCFG2.  Defaults to GMII/MII */
152         regs->maccfg2 = MACCFG2_INIT_SETTINGS;
153
154         /* Init ECNTRL */
155         regs->ecntrl = ECNTRL_INIT_SETTINGS;
156
157         /* Copy the station address into the address registers.
158          * Backwards, because little endian MACS are dumb */
159         for(i=0;i<MAC_ADDR_LEN;i++) {
160                 tmpbuf[MAC_ADDR_LEN - 1 - i] = bd->bi_enetaddr[i];
161         }
162         (uint)(regs->macstnaddr1) = *((uint *)(tmpbuf));
163
164         tempval = *((uint *)(tmpbuf +4));
165
166         (uint)(regs->macstnaddr2) = tempval;
167
168         /* Initialize the PHY */
169         init_phy(regs);
170
171         /* reset the indices to zero */
172         rxIdx = 0;
173         txIdx = 0;
174
175         /* Clear out (for the most part) the other registers */
176         init_registers(regs);
177
178         /* Ready the device for tx/rx */
179         startup_tsec(regs);
180
181         return 1;
182
183 }
184
185
186 /* Reads from the register at offset in the PHY at phyid, */
187 /* using the register set defined in regbase.  It waits until the */
188 /* bits in the miimstat are valid (miimind notvalid bit cleared), */
189 /* and then passes those bits on to the variable specified in */
190 /* value */
191 /* Before it does the read, it needs to clear the command field */
192 uint read_phy_reg(tsec_t *regbase, uint phyid, uint offset)
193 {
194         uint value;
195
196         /* Put the address of the phy, and the register number into
197          * MIIMADD
198          */
199         regbase->miimadd = (phyid << 8) | offset;
200
201         /* Clear the command register, and wait */
202         regbase->miimcom = 0;
203         asm("msync");
204
205         /* Initiate a read command, and wait */
206         regbase->miimcom = MIIM_READ_COMMAND;
207         asm("msync");
208
209         /* Wait for the the indication that the read is done */
210         while((regbase->miimind & (MIIMIND_NOTVALID | MIIMIND_BUSY)));
211
212         /* Grab the value read from the PHY */
213         value = regbase->miimstat;
214
215         return value;
216 }
217
218 /* Setup the PHY */
219 static void init_phy(tsec_t *regs)
220 {
221         uint testval;
222         unsigned int timeout = TSEC_TIMEOUT;
223
224         /* Assign a Physical address to the TBI */
225         regs->tbipa=TBIPA_VALUE;
226
227         /* reset the management interface */
228         regs->miimcfg=MIIMCFG_RESET;
229
230         regs->miimcfg=MIIMCFG_INIT_VALUE;
231
232         /* Wait until the bus is free */
233         while(regs->miimind & MIIMIND_BUSY);
234
235 #ifdef CONFIG_PHY_CIS8201
236         /* override PHY config settings */
237         write_phy_reg(regs, 0, MIIM_AUX_CONSTAT, MIIM_AUXCONSTAT_INIT);
238
239         /* Set up interface mode */
240         write_phy_reg(regs, 0, MIIM_EXT_CON1, MIIM_EXTCON1_INIT);
241 #endif
242
243         /* Set the PHY to gigabit, full duplex, Auto-negotiate */
244         write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_INIT);
245
246         /* Wait until STATUS indicates Auto-Negotiation is done */
247         DBGPRINT("Waiting for Auto-negotiation to complete\n");
248         testval=read_phy_reg(regs, phy_id, MIIM_STATUS);
249
250         while((!(testval & MIIM_STATUS_AN_DONE))&& timeout--) {
251                 testval=read_phy_reg(regs, phy_id, MIIM_STATUS);
252         }
253
254         if(testval & MIIM_STATUS_AN_DONE)
255                 DBGPRINT("Auto-negotiation done\n");
256         else
257                 DBGPRINT("Auto-negotiation timed-out.\n");
258
259 #ifdef CONFIG_PHY_CIS8201
260         /* Find out what duplexity (duplicity?) we have */
261         /* Read it twice to make sure */
262         testval=read_phy_reg(regs, phy_id, MIIM_AUX_CONSTAT);
263
264         if(testval & MIIM_AUXCONSTAT_DUPLEX) {
265                 DBGPRINT("Enet starting in full duplex\n");
266                 regs->maccfg2 |= MACCFG2_FULL_DUPLEX;
267         } else {
268                 DBGPRINT("Enet starting in half duplex\n");
269                 regs->maccfg2 &= ~MACCFG2_FULL_DUPLEX;
270         }
271
272         /* Also, we look to see what speed we are at
273          * if Gigabit, MACCFG2 goes in GMII, otherwise,
274          * MII mode.
275          */
276         if((testval & MIIM_AUXCONSTAT_SPEED) != MIIM_AUXCONSTAT_GBIT) {
277                 if((testval & MIIM_AUXCONSTAT_SPEED) == MIIM_AUXCONSTAT_100)
278                         DBGPRINT("Enet starting in 100BT\n");
279                 else
280                         DBGPRINT("Enet starting in 10BT\n");
281
282                 /* mark the mode in MACCFG2 */
283                 regs->maccfg2 = ((regs->maccfg2&~(MACCFG2_IF)) | MACCFG2_MII);
284         } else {
285                 DBGPRINT("Enet starting in 1000BT\n");
286         }
287
288 #endif
289
290 #ifdef CONFIG_PHY_M88E1011
291         /* Read the PHY to see what speed and duplex we are */
292         testval=read_phy_reg(regs, phy_id, MIIM_PHY_STATUS);
293
294         timeout = TSEC_TIMEOUT;
295         while((!(testval & MIIM_PHYSTAT_SPDDONE)) && timeout--) {
296                 testval = read_phy_reg(regs,phy_id,MIIM_PHY_STATUS);
297         }
298
299         if(!(testval & MIIM_PHYSTAT_SPDDONE))
300                 DBGPRINT("Enet: Speed not resolved\n");
301
302         testval=read_phy_reg(regs, phy_id, MIIM_PHY_STATUS);
303         if(testval & MIIM_PHYSTAT_DUPLEX) {
304                 DBGPRINT("Enet starting in Full Duplex\n");
305                 regs->maccfg2 |= MACCFG2_FULL_DUPLEX;
306         } else {
307                 DBGPRINT("Enet starting in Half Duplex\n");
308                 regs->maccfg2 &= ~MACCFG2_FULL_DUPLEX;
309         }
310
311         if(!((testval&MIIM_PHYSTAT_SPEED) == MIIM_PHYSTAT_GBIT)) {
312                 if((testval & MIIM_PHYSTAT_SPEED) == MIIM_PHYSTAT_100)
313                         DBGPRINT("Enet starting in 100BT\n");
314                 else
315                         DBGPRINT("Enet starting in 10BT\n");
316
317                 regs->maccfg2 = ((regs->maccfg2&~(MACCFG2_IF)) | MACCFG2_MII);
318         } else {
319                 DBGPRINT("Enet starting in 1000BT\n");
320         }
321 #endif
322
323 }
324
325
326 static void init_registers(tsec_t *regs)
327 {
328         /* Clear IEVENT */
329         regs->ievent = IEVENT_INIT_CLEAR;
330
331         regs->imask = IMASK_INIT_CLEAR;
332
333         regs->hash.iaddr0 = 0;
334         regs->hash.iaddr1 = 0;
335         regs->hash.iaddr2 = 0;
336         regs->hash.iaddr3 = 0;
337         regs->hash.iaddr4 = 0;
338         regs->hash.iaddr5 = 0;
339         regs->hash.iaddr6 = 0;
340         regs->hash.iaddr7 = 0;
341
342         regs->hash.gaddr0 = 0;
343         regs->hash.gaddr1 = 0;
344         regs->hash.gaddr2 = 0;
345         regs->hash.gaddr3 = 0;
346         regs->hash.gaddr4 = 0;
347         regs->hash.gaddr5 = 0;
348         regs->hash.gaddr6 = 0;
349         regs->hash.gaddr7 = 0;
350
351         regs->rctrl = 0x00000000;
352
353         /* Init RMON mib registers */
354         memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t));
355
356         regs->rmon.cam1 = 0xffffffff;
357         regs->rmon.cam2 = 0xffffffff;
358
359         regs->mrblr = MRBLR_INIT_SETTINGS;
360
361         regs->minflr = MINFLR_INIT_SETTINGS;
362
363         regs->attr = ATTR_INIT_SETTINGS;
364         regs->attreli = ATTRELI_INIT_SETTINGS;
365
366 }
367
368 static void startup_tsec(tsec_t *regs)
369 {
370         int i;
371
372         /* Point to the buffer descriptors */
373         regs->tbase = (unsigned int)(&rtx.txbd[txIdx]);
374         regs->rbase = (unsigned int)(&rtx.rxbd[rxIdx]);
375
376         /* Initialize the Rx Buffer descriptors */
377         for (i = 0; i < PKTBUFSRX; i++) {
378                 rtx.rxbd[i].status = RXBD_EMPTY;
379                 rtx.rxbd[i].length = 0;
380                 rtx.rxbd[i].bufPtr = (uint)NetRxPackets[i];
381         }
382         rtx.rxbd[PKTBUFSRX -1].status |= RXBD_WRAP;
383
384         /* Initialize the TX Buffer Descriptors */
385         for(i=0; i<TX_BUF_CNT; i++) {
386                 rtx.txbd[i].status = 0;
387                 rtx.txbd[i].length = 0;
388                 rtx.txbd[i].bufPtr = 0;
389         }
390         rtx.txbd[TX_BUF_CNT -1].status |= TXBD_WRAP;
391
392         /* Enable Transmit and Receive */
393         regs->maccfg1 |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
394
395         /* Tell the DMA it is clear to go */
396         regs->dmactrl |= DMACTRL_INIT_SETTINGS;
397         regs->tstat = TSTAT_CLEAR_THALT;
398         regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
399 }
400
401 /* This returns the status bits of the device.  The return value
402  * is never checked, and this is what the 8260 driver did, so we
403  * do the same.  Presumably, this would be zero if there were no
404  * errors */
405 static int tsec_send(struct eth_device* dev, volatile void *packet, int length)
406 {
407         int i;
408         int result = 0;
409         tsec_t * regs = (tsec_t *)(TSEC_BASE_ADDR);
410
411         /* Find an empty buffer descriptor */
412         for(i=0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
413                 if (i >= TOUT_LOOP) {
414                         DBGPRINT("tsec: tx buffers full\n");
415                         return result;
416                 }
417         }
418
419         rtx.txbd[txIdx].bufPtr = (uint)packet;
420         rtx.txbd[txIdx].length = length;
421         rtx.txbd[txIdx].status |= (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT);
422
423         /* Tell the DMA to go */
424         regs->tstat = TSTAT_CLEAR_THALT;
425
426         /* Wait for buffer to be transmitted */
427         for(i=0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
428                 if (i >= TOUT_LOOP) {
429                         DBGPRINT("tsec: tx error\n");
430                         return result;
431                 }
432         }
433
434         txIdx = (txIdx + 1) % TX_BUF_CNT;
435         result = rtx.txbd[txIdx].status & TXBD_STATS;
436
437         return result;
438 }
439
440 static int tsec_recv(struct eth_device* dev)
441 {
442         int length;
443         tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
444
445         while(!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) {
446
447                 length = rtx.rxbd[rxIdx].length;
448
449                 /* Send the packet up if there were no errors */
450                 if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) {
451                         NetReceive(NetRxPackets[rxIdx], length - 4);
452                 }
453
454                 rtx.rxbd[rxIdx].length = 0;
455
456                 /* Set the wrap bit if this is the last element in the list */
457                 rtx.rxbd[rxIdx].status = RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0);
458
459                 rxIdx = (rxIdx + 1) % PKTBUFSRX;
460         }
461
462         if(regs->ievent&IEVENT_BSY) {
463                 regs->ievent = IEVENT_BSY;
464                 regs->rstat = RSTAT_CLEAR_RHALT;
465         }
466
467         return -1;
468
469 }
470
471
472 static void tsec_halt(struct eth_device* dev)
473 {
474         tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
475
476         regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
477         regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS);
478
479         while(!(regs->ievent & (IEVENT_GRSC | IEVENT_GTSC)));
480
481         regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN);
482
483 }
484
485 #ifndef CONFIG_BITBANGMII
486 /*
487  * Read a MII PHY register.
488  *
489  * Returns:
490  *   0 on success
491  */
492 int miiphy_read(unsigned char  addr,
493                 unsigned char  reg,
494                 unsigned short *value)
495 {
496         tsec_t *regs;
497         unsigned short rv;
498
499         regs = (tsec_t *)(TSEC_BASE_ADDR);
500         rv = (unsigned short)read_phy_reg(regs, addr, reg);
501         *value = rv;
502
503         return 0;
504 }
505
506 /*
507  * Write a MII PHY register.
508  *
509  * Returns:
510  *   0 on success
511  */
512 int miiphy_write(unsigned char  addr,
513                  unsigned char  reg,
514                  unsigned short value)
515 {
516         tsec_t *regs;
517
518         regs = (tsec_t *)(TSEC_BASE_ADDR);
519         write_phy_reg(regs, addr, reg, value);
520
521         return 0;
522 }
523 #endif /* CONFIG_BITBANGMII */
524 #endif /* CONFIG_TSEC_ENET */