3 * Motorola Three Speed Ethernet Controller driver
5 * This software may be used and distributed according to the
6 * terms of the GNU Public License, Version 2, incorporated
9 * (C) Copyright 2003, Motorola, Inc.
10 * maintained by Xianghua Xiao (x.xiao@motorola.com)
22 #if defined(CONFIG_TSEC_ENET)
29 #define DBGPRINT(x) printf(x)
34 static uint rxIdx; /* index of the current RX buffer */
35 static uint txIdx; /* index of the current TX buffer */
37 typedef volatile struct rtxbd {
38 txbd8_t txbd[TX_BUF_CNT];
39 rxbd8_t rxbd[PKTBUFSRX];
43 static RTXBD rtx __attribute__ ((aligned(8)));
45 #error "rtx must be 64-bit aligned"
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);
57 static int phy_id = -1;
59 /* Initialize device structure. returns 0 on failure, 1 on
61 int tsec_initialize(bd_t *bis)
63 struct eth_device* dev;
65 tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
67 dev = (struct eth_device*) malloc(sizeof *dev);
72 memset(dev, 0, sizeof *dev);
74 sprintf(dev->name, "MOTO ETHERNET");
77 dev->init = tsec_init;
78 dev->halt = tsec_halt;
79 dev->send = tsec_send;
80 dev->recv = tsec_recv;
82 /* Tell u-boot to get the addr from the env */
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;
94 /* reset the management interface */
95 regs->miimcfg=MIIMCFG_RESET;
97 regs->miimcfg=MIIMCFG_INIT_VALUE;
99 /* Wait until the bus is free */
100 while(regs->miimind & MIIMIND_BUSY);
102 /* Locate PHYs. Skip TBIPA, which we know is 31.
104 for (i=0; i<31; i++) {
105 if (read_phy_reg(regs, i, 2) == 0x141) {
109 printf("Found Marvell PHY at 0x%02x\n", i);
114 printf("Using PHY ID 0x%02x\n", phy_id);
116 write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_RESET);
118 RESET_ERRATA(regs, phy_id);
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);
124 /* Reset the PHY so the new settings take effect */
125 write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_RESET);
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)
137 char tmpbuf[MAC_ADDR_LEN];
140 regs = (tsec_t *)(TSEC_BASE_ADDR);
142 /* Make sure the controller is stopped */
146 regs->maccfg1 |= MACCFG1_SOFT_RESET;
148 /* Clear MACCFG1[Soft_Reset] */
149 regs->maccfg1 &= ~(MACCFG1_SOFT_RESET);
151 /* Init MACCFG2. Defaults to GMII/MII */
152 regs->maccfg2 = MACCFG2_INIT_SETTINGS;
155 regs->ecntrl = ECNTRL_INIT_SETTINGS;
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];
162 (uint)(regs->macstnaddr1) = *((uint *)(tmpbuf));
164 tempval = *((uint *)(tmpbuf +4));
166 (uint)(regs->macstnaddr2) = tempval;
168 /* Initialize the PHY */
171 /* reset the indices to zero */
175 /* Clear out (for the most part) the other registers */
176 init_registers(regs);
178 /* Ready the device for tx/rx */
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 */
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)
196 /* Put the address of the phy, and the register number into
199 regbase->miimadd = (phyid << 8) | offset;
201 /* Clear the command register, and wait */
202 regbase->miimcom = 0;
205 /* Initiate a read command, and wait */
206 regbase->miimcom = MIIM_READ_COMMAND;
209 /* Wait for the the indication that the read is done */
210 while((regbase->miimind & (MIIMIND_NOTVALID | MIIMIND_BUSY)));
212 /* Grab the value read from the PHY */
213 value = regbase->miimstat;
219 static void init_phy(tsec_t *regs)
222 unsigned int timeout = TSEC_TIMEOUT;
224 /* Assign a Physical address to the TBI */
225 regs->tbipa=TBIPA_VALUE;
227 /* reset the management interface */
228 regs->miimcfg=MIIMCFG_RESET;
230 regs->miimcfg=MIIMCFG_INIT_VALUE;
232 /* Wait until the bus is free */
233 while(regs->miimind & MIIMIND_BUSY);
235 #ifdef CONFIG_PHY_CIS8201
236 /* override PHY config settings */
237 write_phy_reg(regs, 0, MIIM_AUX_CONSTAT, MIIM_AUXCONSTAT_INIT);
239 /* Set up interface mode */
240 write_phy_reg(regs, 0, MIIM_EXT_CON1, MIIM_EXTCON1_INIT);
243 /* Set the PHY to gigabit, full duplex, Auto-negotiate */
244 write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_INIT);
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);
250 while((!(testval & MIIM_STATUS_AN_DONE))&& timeout--) {
251 testval=read_phy_reg(regs, phy_id, MIIM_STATUS);
254 if(testval & MIIM_STATUS_AN_DONE)
255 DBGPRINT("Auto-negotiation done\n");
257 DBGPRINT("Auto-negotiation timed-out.\n");
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);
264 if(testval & MIIM_AUXCONSTAT_DUPLEX) {
265 DBGPRINT("Enet starting in full duplex\n");
266 regs->maccfg2 |= MACCFG2_FULL_DUPLEX;
268 DBGPRINT("Enet starting in half duplex\n");
269 regs->maccfg2 &= ~MACCFG2_FULL_DUPLEX;
272 /* Also, we look to see what speed we are at
273 * if Gigabit, MACCFG2 goes in GMII, otherwise,
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");
280 DBGPRINT("Enet starting in 10BT\n");
282 /* mark the mode in MACCFG2 */
283 regs->maccfg2 = ((regs->maccfg2&~(MACCFG2_IF)) | MACCFG2_MII);
285 DBGPRINT("Enet starting in 1000BT\n");
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);
294 timeout = TSEC_TIMEOUT;
295 while((!(testval & MIIM_PHYSTAT_SPDDONE)) && timeout--) {
296 testval = read_phy_reg(regs,phy_id,MIIM_PHY_STATUS);
299 if(!(testval & MIIM_PHYSTAT_SPDDONE))
300 DBGPRINT("Enet: Speed not resolved\n");
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;
307 DBGPRINT("Enet starting in Half Duplex\n");
308 regs->maccfg2 &= ~MACCFG2_FULL_DUPLEX;
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");
315 DBGPRINT("Enet starting in 10BT\n");
317 regs->maccfg2 = ((regs->maccfg2&~(MACCFG2_IF)) | MACCFG2_MII);
319 DBGPRINT("Enet starting in 1000BT\n");
326 static void init_registers(tsec_t *regs)
329 regs->ievent = IEVENT_INIT_CLEAR;
331 regs->imask = IMASK_INIT_CLEAR;
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;
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;
351 regs->rctrl = 0x00000000;
353 /* Init RMON mib registers */
354 memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t));
356 regs->rmon.cam1 = 0xffffffff;
357 regs->rmon.cam2 = 0xffffffff;
359 regs->mrblr = MRBLR_INIT_SETTINGS;
361 regs->minflr = MINFLR_INIT_SETTINGS;
363 regs->attr = ATTR_INIT_SETTINGS;
364 regs->attreli = ATTRELI_INIT_SETTINGS;
368 static void startup_tsec(tsec_t *regs)
372 /* Point to the buffer descriptors */
373 regs->tbase = (unsigned int)(&rtx.txbd[txIdx]);
374 regs->rbase = (unsigned int)(&rtx.rxbd[rxIdx]);
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];
382 rtx.rxbd[PKTBUFSRX -1].status |= RXBD_WRAP;
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;
390 rtx.txbd[TX_BUF_CNT -1].status |= TXBD_WRAP;
392 /* Enable Transmit and Receive */
393 regs->maccfg1 |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
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);
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
405 static int tsec_send(struct eth_device* dev, volatile void *packet, int length)
409 tsec_t * regs = (tsec_t *)(TSEC_BASE_ADDR);
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");
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);
423 /* Tell the DMA to go */
424 regs->tstat = TSTAT_CLEAR_THALT;
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");
434 txIdx = (txIdx + 1) % TX_BUF_CNT;
435 result = rtx.txbd[txIdx].status & TXBD_STATS;
440 static int tsec_recv(struct eth_device* dev)
443 tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
445 while(!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) {
447 length = rtx.rxbd[rxIdx].length;
449 /* Send the packet up if there were no errors */
450 if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) {
451 NetReceive(NetRxPackets[rxIdx], length - 4);
454 rtx.rxbd[rxIdx].length = 0;
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);
459 rxIdx = (rxIdx + 1) % PKTBUFSRX;
462 if(regs->ievent&IEVENT_BSY) {
463 regs->ievent = IEVENT_BSY;
464 regs->rstat = RSTAT_CLEAR_RHALT;
472 static void tsec_halt(struct eth_device* dev)
474 tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
476 regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
477 regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS);
479 while(!(regs->ievent & (IEVENT_GRSC | IEVENT_GTSC)));
481 regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN);
485 #ifndef CONFIG_BITBANGMII
487 * Read a MII PHY register.
492 int miiphy_read(unsigned char addr,
494 unsigned short *value)
499 regs = (tsec_t *)(TSEC_BASE_ADDR);
500 rv = (unsigned short)read_phy_reg(regs, addr, reg);
507 * Write a MII PHY register.
512 int miiphy_write(unsigned char addr,
514 unsigned short value)
518 regs = (tsec_t *)(TSEC_BASE_ADDR);
519 write_phy_reg(regs, addr, reg, value);
523 #endif /* CONFIG_BITBANGMII */
524 #endif /* CONFIG_TSEC_ENET */