diff options
Diffstat (limited to 'drivers/net/fec.c')
-rw-r--r-- | drivers/net/fec.c | 389 |
1 files changed, 283 insertions, 106 deletions
diff --git a/drivers/net/fec.c b/drivers/net/fec.c index bd6983d1afb..55d86bc4c10 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c | |||
@@ -22,10 +22,9 @@ | |||
22 | * Copyright (c) 2001-2005 Greg Ungerer (gerg@snapgear.com) | 22 | * Copyright (c) 2001-2005 Greg Ungerer (gerg@snapgear.com) |
23 | * | 23 | * |
24 | * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) | 24 | * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) |
25 | * Copyright (c) 2004-2005 Macq Electronique SA. | 25 | * Copyright (c) 2004-2006 Macq Electronique SA. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/config.h> | ||
29 | #include <linux/module.h> | 28 | #include <linux/module.h> |
30 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
31 | #include <linux/string.h> | 30 | #include <linux/string.h> |
@@ -51,7 +50,7 @@ | |||
51 | 50 | ||
52 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ | 51 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ |
53 | defined(CONFIG_M5272) || defined(CONFIG_M528x) || \ | 52 | defined(CONFIG_M5272) || defined(CONFIG_M528x) || \ |
54 | defined(CONFIG_M520x) | 53 | defined(CONFIG_M520x) || defined(CONFIG_M532x) |
55 | #include <asm/coldfire.h> | 54 | #include <asm/coldfire.h> |
56 | #include <asm/mcfsim.h> | 55 | #include <asm/mcfsim.h> |
57 | #include "fec.h" | 56 | #include "fec.h" |
@@ -80,6 +79,8 @@ static unsigned int fec_hw[] = { | |||
80 | (MCF_MBAR + 0x1000), | 79 | (MCF_MBAR + 0x1000), |
81 | #elif defined(CONFIG_M520x) | 80 | #elif defined(CONFIG_M520x) |
82 | (MCF_MBAR+0x30000), | 81 | (MCF_MBAR+0x30000), |
82 | #elif defined(CONFIG_M532x) | ||
83 | (MCF_MBAR+0xfc030000), | ||
83 | #else | 84 | #else |
84 | &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), | 85 | &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), |
85 | #endif | 86 | #endif |
@@ -143,7 +144,7 @@ typedef struct { | |||
143 | #define TX_RING_MOD_MASK 15 /* for this to work */ | 144 | #define TX_RING_MOD_MASK 15 /* for this to work */ |
144 | 145 | ||
145 | #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE) | 146 | #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE) |
146 | #error "FEC: descriptor ring size contants too large" | 147 | #error "FEC: descriptor ring size constants too large" |
147 | #endif | 148 | #endif |
148 | 149 | ||
149 | /* Interrupt events/masks. | 150 | /* Interrupt events/masks. |
@@ -167,12 +168,12 @@ typedef struct { | |||
167 | 168 | ||
168 | 169 | ||
169 | /* | 170 | /* |
170 | * The 5270/5271/5280/5282 RX control register also contains maximum frame | 171 | * The 5270/5271/5280/5282/532x RX control register also contains maximum frame |
171 | * size bits. Other FEC hardware does not, so we need to take that into | 172 | * size bits. Other FEC hardware does not, so we need to take that into |
172 | * account when setting it. | 173 | * account when setting it. |
173 | */ | 174 | */ |
174 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ | 175 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ |
175 | defined(CONFIG_M520x) | 176 | defined(CONFIG_M520x) || defined(CONFIG_M532x) |
176 | #define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) | 177 | #define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) |
177 | #else | 178 | #else |
178 | #define OPT_FRAME_SIZE 0 | 179 | #define OPT_FRAME_SIZE 0 |
@@ -255,7 +256,7 @@ static mii_list_t *mii_free; | |||
255 | static mii_list_t *mii_head; | 256 | static mii_list_t *mii_head; |
256 | static mii_list_t *mii_tail; | 257 | static mii_list_t *mii_tail; |
257 | 258 | ||
258 | static int mii_queue(struct net_device *dev, int request, | 259 | static int mii_queue(struct net_device *dev, int request, |
259 | void (*func)(uint, struct net_device *)); | 260 | void (*func)(uint, struct net_device *)); |
260 | 261 | ||
261 | /* Make MII read/write commands for the FEC. | 262 | /* Make MII read/write commands for the FEC. |
@@ -276,7 +277,7 @@ static int mii_queue(struct net_device *dev, int request, | |||
276 | #define MII_REG_SR 1 /* Status Register */ | 277 | #define MII_REG_SR 1 /* Status Register */ |
277 | #define MII_REG_PHYIR1 2 /* PHY Identification Register 1 */ | 278 | #define MII_REG_PHYIR1 2 /* PHY Identification Register 1 */ |
278 | #define MII_REG_PHYIR2 3 /* PHY Identification Register 2 */ | 279 | #define MII_REG_PHYIR2 3 /* PHY Identification Register 2 */ |
279 | #define MII_REG_ANAR 4 /* A-N Advertisement Register */ | 280 | #define MII_REG_ANAR 4 /* A-N Advertisement Register */ |
280 | #define MII_REG_ANLPAR 5 /* A-N Link Partner Ability Register */ | 281 | #define MII_REG_ANLPAR 5 /* A-N Link Partner Ability Register */ |
281 | #define MII_REG_ANER 6 /* A-N Expansion Register */ | 282 | #define MII_REG_ANER 6 /* A-N Expansion Register */ |
282 | #define MII_REG_ANNPTR 7 /* A-N Next Page Transmit Register */ | 283 | #define MII_REG_ANNPTR 7 /* A-N Next Page Transmit Register */ |
@@ -288,18 +289,18 @@ static int mii_queue(struct net_device *dev, int request, | |||
288 | #define PHY_CONF_LOOP 0x0002 /* 1 loopback mode enabled */ | 289 | #define PHY_CONF_LOOP 0x0002 /* 1 loopback mode enabled */ |
289 | #define PHY_CONF_SPMASK 0x00f0 /* mask for speed */ | 290 | #define PHY_CONF_SPMASK 0x00f0 /* mask for speed */ |
290 | #define PHY_CONF_10HDX 0x0010 /* 10 Mbit half duplex supported */ | 291 | #define PHY_CONF_10HDX 0x0010 /* 10 Mbit half duplex supported */ |
291 | #define PHY_CONF_10FDX 0x0020 /* 10 Mbit full duplex supported */ | 292 | #define PHY_CONF_10FDX 0x0020 /* 10 Mbit full duplex supported */ |
292 | #define PHY_CONF_100HDX 0x0040 /* 100 Mbit half duplex supported */ | 293 | #define PHY_CONF_100HDX 0x0040 /* 100 Mbit half duplex supported */ |
293 | #define PHY_CONF_100FDX 0x0080 /* 100 Mbit full duplex supported */ | 294 | #define PHY_CONF_100FDX 0x0080 /* 100 Mbit full duplex supported */ |
294 | 295 | ||
295 | #define PHY_STAT_LINK 0x0100 /* 1 up - 0 down */ | 296 | #define PHY_STAT_LINK 0x0100 /* 1 up - 0 down */ |
296 | #define PHY_STAT_FAULT 0x0200 /* 1 remote fault */ | 297 | #define PHY_STAT_FAULT 0x0200 /* 1 remote fault */ |
297 | #define PHY_STAT_ANC 0x0400 /* 1 auto-negotiation complete */ | 298 | #define PHY_STAT_ANC 0x0400 /* 1 auto-negotiation complete */ |
298 | #define PHY_STAT_SPMASK 0xf000 /* mask for speed */ | 299 | #define PHY_STAT_SPMASK 0xf000 /* mask for speed */ |
299 | #define PHY_STAT_10HDX 0x1000 /* 10 Mbit half duplex selected */ | 300 | #define PHY_STAT_10HDX 0x1000 /* 10 Mbit half duplex selected */ |
300 | #define PHY_STAT_10FDX 0x2000 /* 10 Mbit full duplex selected */ | 301 | #define PHY_STAT_10FDX 0x2000 /* 10 Mbit full duplex selected */ |
301 | #define PHY_STAT_100HDX 0x4000 /* 100 Mbit half duplex selected */ | 302 | #define PHY_STAT_100HDX 0x4000 /* 100 Mbit half duplex selected */ |
302 | #define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */ | 303 | #define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */ |
303 | 304 | ||
304 | 305 | ||
305 | static int | 306 | static int |
@@ -308,6 +309,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
308 | struct fec_enet_private *fep; | 309 | struct fec_enet_private *fep; |
309 | volatile fec_t *fecp; | 310 | volatile fec_t *fecp; |
310 | volatile cbd_t *bdp; | 311 | volatile cbd_t *bdp; |
312 | unsigned short status; | ||
311 | 313 | ||
312 | fep = netdev_priv(dev); | 314 | fep = netdev_priv(dev); |
313 | fecp = (volatile fec_t*)dev->base_addr; | 315 | fecp = (volatile fec_t*)dev->base_addr; |
@@ -320,8 +322,9 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
320 | /* Fill in a Tx ring entry */ | 322 | /* Fill in a Tx ring entry */ |
321 | bdp = fep->cur_tx; | 323 | bdp = fep->cur_tx; |
322 | 324 | ||
325 | status = bdp->cbd_sc; | ||
323 | #ifndef final_version | 326 | #ifndef final_version |
324 | if (bdp->cbd_sc & BD_ENET_TX_READY) { | 327 | if (status & BD_ENET_TX_READY) { |
325 | /* Ooops. All transmit buffers are full. Bail out. | 328 | /* Ooops. All transmit buffers are full. Bail out. |
326 | * This should not happen, since dev->tbusy should be set. | 329 | * This should not happen, since dev->tbusy should be set. |
327 | */ | 330 | */ |
@@ -332,7 +335,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
332 | 335 | ||
333 | /* Clear all of the status flags. | 336 | /* Clear all of the status flags. |
334 | */ | 337 | */ |
335 | bdp->cbd_sc &= ~BD_ENET_TX_STATS; | 338 | status &= ~BD_ENET_TX_STATS; |
336 | 339 | ||
337 | /* Set buffer length and buffer pointer. | 340 | /* Set buffer length and buffer pointer. |
338 | */ | 341 | */ |
@@ -357,7 +360,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
357 | 360 | ||
358 | fep->stats.tx_bytes += skb->len; | 361 | fep->stats.tx_bytes += skb->len; |
359 | fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK; | 362 | fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK; |
360 | 363 | ||
361 | /* Push the data cache so the CPM does not get stale memory | 364 | /* Push the data cache so the CPM does not get stale memory |
362 | * data. | 365 | * data. |
363 | */ | 366 | */ |
@@ -366,21 +369,22 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
366 | 369 | ||
367 | spin_lock_irq(&fep->lock); | 370 | spin_lock_irq(&fep->lock); |
368 | 371 | ||
369 | /* Send it on its way. Tell FEC its ready, interrupt when done, | 372 | /* Send it on its way. Tell FEC it's ready, interrupt when done, |
370 | * its the last BD of the frame, and to put the CRC on the end. | 373 | * it's the last BD of the frame, and to put the CRC on the end. |
371 | */ | 374 | */ |
372 | 375 | ||
373 | bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | 376 | status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR |
374 | | BD_ENET_TX_LAST | BD_ENET_TX_TC); | 377 | | BD_ENET_TX_LAST | BD_ENET_TX_TC); |
378 | bdp->cbd_sc = status; | ||
375 | 379 | ||
376 | dev->trans_start = jiffies; | 380 | dev->trans_start = jiffies; |
377 | 381 | ||
378 | /* Trigger transmission start */ | 382 | /* Trigger transmission start */ |
379 | fecp->fec_x_des_active = 0x01000000; | 383 | fecp->fec_x_des_active = 0; |
380 | 384 | ||
381 | /* If this was the last BD in the ring, start at the beginning again. | 385 | /* If this was the last BD in the ring, start at the beginning again. |
382 | */ | 386 | */ |
383 | if (bdp->cbd_sc & BD_ENET_TX_WRAP) { | 387 | if (status & BD_ENET_TX_WRAP) { |
384 | bdp = fep->tx_bd_base; | 388 | bdp = fep->tx_bd_base; |
385 | } else { | 389 | } else { |
386 | bdp++; | 390 | bdp++; |
@@ -418,7 +422,7 @@ fec_timeout(struct net_device *dev) | |||
418 | bdp = fep->tx_bd_base; | 422 | bdp = fep->tx_bd_base; |
419 | printk(" tx: %u buffers\n", TX_RING_SIZE); | 423 | printk(" tx: %u buffers\n", TX_RING_SIZE); |
420 | for (i = 0 ; i < TX_RING_SIZE; i++) { | 424 | for (i = 0 ; i < TX_RING_SIZE; i++) { |
421 | printk(" %08x: %04x %04x %08x\n", | 425 | printk(" %08x: %04x %04x %08x\n", |
422 | (uint) bdp, | 426 | (uint) bdp, |
423 | bdp->cbd_sc, | 427 | bdp->cbd_sc, |
424 | bdp->cbd_datlen, | 428 | bdp->cbd_datlen, |
@@ -480,7 +484,7 @@ fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) | |||
480 | handled = 1; | 484 | handled = 1; |
481 | fec_enet_mii(dev); | 485 | fec_enet_mii(dev); |
482 | } | 486 | } |
483 | 487 | ||
484 | } | 488 | } |
485 | return IRQ_RETVAL(handled); | 489 | return IRQ_RETVAL(handled); |
486 | } | 490 | } |
@@ -491,58 +495,59 @@ fec_enet_tx(struct net_device *dev) | |||
491 | { | 495 | { |
492 | struct fec_enet_private *fep; | 496 | struct fec_enet_private *fep; |
493 | volatile cbd_t *bdp; | 497 | volatile cbd_t *bdp; |
498 | unsigned short status; | ||
494 | struct sk_buff *skb; | 499 | struct sk_buff *skb; |
495 | 500 | ||
496 | fep = netdev_priv(dev); | 501 | fep = netdev_priv(dev); |
497 | spin_lock(&fep->lock); | 502 | spin_lock(&fep->lock); |
498 | bdp = fep->dirty_tx; | 503 | bdp = fep->dirty_tx; |
499 | 504 | ||
500 | while ((bdp->cbd_sc&BD_ENET_TX_READY) == 0) { | 505 | while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { |
501 | if (bdp == fep->cur_tx && fep->tx_full == 0) break; | 506 | if (bdp == fep->cur_tx && fep->tx_full == 0) break; |
502 | 507 | ||
503 | skb = fep->tx_skbuff[fep->skb_dirty]; | 508 | skb = fep->tx_skbuff[fep->skb_dirty]; |
504 | /* Check for errors. */ | 509 | /* Check for errors. */ |
505 | if (bdp->cbd_sc & (BD_ENET_TX_HB | BD_ENET_TX_LC | | 510 | if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | |
506 | BD_ENET_TX_RL | BD_ENET_TX_UN | | 511 | BD_ENET_TX_RL | BD_ENET_TX_UN | |
507 | BD_ENET_TX_CSL)) { | 512 | BD_ENET_TX_CSL)) { |
508 | fep->stats.tx_errors++; | 513 | fep->stats.tx_errors++; |
509 | if (bdp->cbd_sc & BD_ENET_TX_HB) /* No heartbeat */ | 514 | if (status & BD_ENET_TX_HB) /* No heartbeat */ |
510 | fep->stats.tx_heartbeat_errors++; | 515 | fep->stats.tx_heartbeat_errors++; |
511 | if (bdp->cbd_sc & BD_ENET_TX_LC) /* Late collision */ | 516 | if (status & BD_ENET_TX_LC) /* Late collision */ |
512 | fep->stats.tx_window_errors++; | 517 | fep->stats.tx_window_errors++; |
513 | if (bdp->cbd_sc & BD_ENET_TX_RL) /* Retrans limit */ | 518 | if (status & BD_ENET_TX_RL) /* Retrans limit */ |
514 | fep->stats.tx_aborted_errors++; | 519 | fep->stats.tx_aborted_errors++; |
515 | if (bdp->cbd_sc & BD_ENET_TX_UN) /* Underrun */ | 520 | if (status & BD_ENET_TX_UN) /* Underrun */ |
516 | fep->stats.tx_fifo_errors++; | 521 | fep->stats.tx_fifo_errors++; |
517 | if (bdp->cbd_sc & BD_ENET_TX_CSL) /* Carrier lost */ | 522 | if (status & BD_ENET_TX_CSL) /* Carrier lost */ |
518 | fep->stats.tx_carrier_errors++; | 523 | fep->stats.tx_carrier_errors++; |
519 | } else { | 524 | } else { |
520 | fep->stats.tx_packets++; | 525 | fep->stats.tx_packets++; |
521 | } | 526 | } |
522 | 527 | ||
523 | #ifndef final_version | 528 | #ifndef final_version |
524 | if (bdp->cbd_sc & BD_ENET_TX_READY) | 529 | if (status & BD_ENET_TX_READY) |
525 | printk("HEY! Enet xmit interrupt and TX_READY.\n"); | 530 | printk("HEY! Enet xmit interrupt and TX_READY.\n"); |
526 | #endif | 531 | #endif |
527 | /* Deferred means some collisions occurred during transmit, | 532 | /* Deferred means some collisions occurred during transmit, |
528 | * but we eventually sent the packet OK. | 533 | * but we eventually sent the packet OK. |
529 | */ | 534 | */ |
530 | if (bdp->cbd_sc & BD_ENET_TX_DEF) | 535 | if (status & BD_ENET_TX_DEF) |
531 | fep->stats.collisions++; | 536 | fep->stats.collisions++; |
532 | 537 | ||
533 | /* Free the sk buffer associated with this last transmit. | 538 | /* Free the sk buffer associated with this last transmit. |
534 | */ | 539 | */ |
535 | dev_kfree_skb_any(skb); | 540 | dev_kfree_skb_any(skb); |
536 | fep->tx_skbuff[fep->skb_dirty] = NULL; | 541 | fep->tx_skbuff[fep->skb_dirty] = NULL; |
537 | fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK; | 542 | fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK; |
538 | 543 | ||
539 | /* Update pointer to next buffer descriptor to be transmitted. | 544 | /* Update pointer to next buffer descriptor to be transmitted. |
540 | */ | 545 | */ |
541 | if (bdp->cbd_sc & BD_ENET_TX_WRAP) | 546 | if (status & BD_ENET_TX_WRAP) |
542 | bdp = fep->tx_bd_base; | 547 | bdp = fep->tx_bd_base; |
543 | else | 548 | else |
544 | bdp++; | 549 | bdp++; |
545 | 550 | ||
546 | /* Since we have freed up a buffer, the ring is no longer | 551 | /* Since we have freed up a buffer, the ring is no longer |
547 | * full. | 552 | * full. |
548 | */ | 553 | */ |
@@ -568,10 +573,15 @@ fec_enet_rx(struct net_device *dev) | |||
568 | struct fec_enet_private *fep; | 573 | struct fec_enet_private *fep; |
569 | volatile fec_t *fecp; | 574 | volatile fec_t *fecp; |
570 | volatile cbd_t *bdp; | 575 | volatile cbd_t *bdp; |
576 | unsigned short status; | ||
571 | struct sk_buff *skb; | 577 | struct sk_buff *skb; |
572 | ushort pkt_len; | 578 | ushort pkt_len; |
573 | __u8 *data; | 579 | __u8 *data; |
574 | 580 | ||
581 | #ifdef CONFIG_M532x | ||
582 | flush_cache_all(); | ||
583 | #endif | ||
584 | |||
575 | fep = netdev_priv(dev); | 585 | fep = netdev_priv(dev); |
576 | fecp = (volatile fec_t*)dev->base_addr; | 586 | fecp = (volatile fec_t*)dev->base_addr; |
577 | 587 | ||
@@ -580,13 +590,13 @@ fec_enet_rx(struct net_device *dev) | |||
580 | */ | 590 | */ |
581 | bdp = fep->cur_rx; | 591 | bdp = fep->cur_rx; |
582 | 592 | ||
583 | while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { | 593 | while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { |
584 | 594 | ||
585 | #ifndef final_version | 595 | #ifndef final_version |
586 | /* Since we have allocated space to hold a complete frame, | 596 | /* Since we have allocated space to hold a complete frame, |
587 | * the last indicator should be set. | 597 | * the last indicator should be set. |
588 | */ | 598 | */ |
589 | if ((bdp->cbd_sc & BD_ENET_RX_LAST) == 0) | 599 | if ((status & BD_ENET_RX_LAST) == 0) |
590 | printk("FEC ENET: rcv is not +last\n"); | 600 | printk("FEC ENET: rcv is not +last\n"); |
591 | #endif | 601 | #endif |
592 | 602 | ||
@@ -594,26 +604,26 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { | |||
594 | goto rx_processing_done; | 604 | goto rx_processing_done; |
595 | 605 | ||
596 | /* Check for errors. */ | 606 | /* Check for errors. */ |
597 | if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | | 607 | if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | |
598 | BD_ENET_RX_CR | BD_ENET_RX_OV)) { | 608 | BD_ENET_RX_CR | BD_ENET_RX_OV)) { |
599 | fep->stats.rx_errors++; | 609 | fep->stats.rx_errors++; |
600 | if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { | 610 | if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { |
601 | /* Frame too long or too short. */ | 611 | /* Frame too long or too short. */ |
602 | fep->stats.rx_length_errors++; | 612 | fep->stats.rx_length_errors++; |
603 | } | 613 | } |
604 | if (bdp->cbd_sc & BD_ENET_RX_NO) /* Frame alignment */ | 614 | if (status & BD_ENET_RX_NO) /* Frame alignment */ |
605 | fep->stats.rx_frame_errors++; | 615 | fep->stats.rx_frame_errors++; |
606 | if (bdp->cbd_sc & BD_ENET_RX_CR) /* CRC Error */ | 616 | if (status & BD_ENET_RX_CR) /* CRC Error */ |
607 | fep->stats.rx_crc_errors++; | ||
608 | if (bdp->cbd_sc & BD_ENET_RX_OV) /* FIFO overrun */ | ||
609 | fep->stats.rx_crc_errors++; | 617 | fep->stats.rx_crc_errors++; |
618 | if (status & BD_ENET_RX_OV) /* FIFO overrun */ | ||
619 | fep->stats.rx_fifo_errors++; | ||
610 | } | 620 | } |
611 | 621 | ||
612 | /* Report late collisions as a frame error. | 622 | /* Report late collisions as a frame error. |
613 | * On this error, the BD is closed, but we don't know what we | 623 | * On this error, the BD is closed, but we don't know what we |
614 | * have in the buffer. So, just drop this frame on the floor. | 624 | * have in the buffer. So, just drop this frame on the floor. |
615 | */ | 625 | */ |
616 | if (bdp->cbd_sc & BD_ENET_RX_CL) { | 626 | if (status & BD_ENET_RX_CL) { |
617 | fep->stats.rx_errors++; | 627 | fep->stats.rx_errors++; |
618 | fep->stats.rx_frame_errors++; | 628 | fep->stats.rx_frame_errors++; |
619 | goto rx_processing_done; | 629 | goto rx_processing_done; |
@@ -639,9 +649,7 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { | |||
639 | } else { | 649 | } else { |
640 | skb->dev = dev; | 650 | skb->dev = dev; |
641 | skb_put(skb,pkt_len-4); /* Make room */ | 651 | skb_put(skb,pkt_len-4); /* Make room */ |
642 | eth_copy_and_sum(skb, | 652 | eth_copy_and_sum(skb, data, pkt_len-4, 0); |
643 | (unsigned char *)__va(bdp->cbd_bufaddr), | ||
644 | pkt_len-4, 0); | ||
645 | skb->protocol=eth_type_trans(skb,dev); | 653 | skb->protocol=eth_type_trans(skb,dev); |
646 | netif_rx(skb); | 654 | netif_rx(skb); |
647 | } | 655 | } |
@@ -649,27 +657,28 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { | |||
649 | 657 | ||
650 | /* Clear the status flags for this buffer. | 658 | /* Clear the status flags for this buffer. |
651 | */ | 659 | */ |
652 | bdp->cbd_sc &= ~BD_ENET_RX_STATS; | 660 | status &= ~BD_ENET_RX_STATS; |
653 | 661 | ||
654 | /* Mark the buffer empty. | 662 | /* Mark the buffer empty. |
655 | */ | 663 | */ |
656 | bdp->cbd_sc |= BD_ENET_RX_EMPTY; | 664 | status |= BD_ENET_RX_EMPTY; |
665 | bdp->cbd_sc = status; | ||
657 | 666 | ||
658 | /* Update BD pointer to next entry. | 667 | /* Update BD pointer to next entry. |
659 | */ | 668 | */ |
660 | if (bdp->cbd_sc & BD_ENET_RX_WRAP) | 669 | if (status & BD_ENET_RX_WRAP) |
661 | bdp = fep->rx_bd_base; | 670 | bdp = fep->rx_bd_base; |
662 | else | 671 | else |
663 | bdp++; | 672 | bdp++; |
664 | 673 | ||
665 | #if 1 | 674 | #if 1 |
666 | /* Doing this here will keep the FEC running while we process | 675 | /* Doing this here will keep the FEC running while we process |
667 | * incoming frames. On a heavily loaded network, we should be | 676 | * incoming frames. On a heavily loaded network, we should be |
668 | * able to keep up at the expense of system resources. | 677 | * able to keep up at the expense of system resources. |
669 | */ | 678 | */ |
670 | fecp->fec_r_des_active = 0x01000000; | 679 | fecp->fec_r_des_active = 0; |
671 | #endif | 680 | #endif |
672 | } /* while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) */ | 681 | } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */ |
673 | fep->cur_rx = (cbd_t *)bdp; | 682 | fep->cur_rx = (cbd_t *)bdp; |
674 | 683 | ||
675 | #if 0 | 684 | #if 0 |
@@ -680,11 +689,12 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { | |||
680 | * our way back to the interrupt return only to come right back | 689 | * our way back to the interrupt return only to come right back |
681 | * here. | 690 | * here. |
682 | */ | 691 | */ |
683 | fecp->fec_r_des_active = 0x01000000; | 692 | fecp->fec_r_des_active = 0; |
684 | #endif | 693 | #endif |
685 | } | 694 | } |
686 | 695 | ||
687 | 696 | ||
697 | /* called from interrupt context */ | ||
688 | static void | 698 | static void |
689 | fec_enet_mii(struct net_device *dev) | 699 | fec_enet_mii(struct net_device *dev) |
690 | { | 700 | { |
@@ -696,10 +706,12 @@ fec_enet_mii(struct net_device *dev) | |||
696 | fep = netdev_priv(dev); | 706 | fep = netdev_priv(dev); |
697 | ep = fep->hwp; | 707 | ep = fep->hwp; |
698 | mii_reg = ep->fec_mii_data; | 708 | mii_reg = ep->fec_mii_data; |
699 | 709 | ||
710 | spin_lock(&fep->lock); | ||
711 | |||
700 | if ((mip = mii_head) == NULL) { | 712 | if ((mip = mii_head) == NULL) { |
701 | printk("MII and no head!\n"); | 713 | printk("MII and no head!\n"); |
702 | return; | 714 | goto unlock; |
703 | } | 715 | } |
704 | 716 | ||
705 | if (mip->mii_func != NULL) | 717 | if (mip->mii_func != NULL) |
@@ -711,6 +723,9 @@ fec_enet_mii(struct net_device *dev) | |||
711 | 723 | ||
712 | if ((mip = mii_head) != NULL) | 724 | if ((mip = mii_head) != NULL) |
713 | ep->fec_mii_data = mip->mii_regval; | 725 | ep->fec_mii_data = mip->mii_regval; |
726 | |||
727 | unlock: | ||
728 | spin_unlock(&fep->lock); | ||
714 | } | 729 | } |
715 | 730 | ||
716 | static int | 731 | static int |
@@ -728,8 +743,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi | |||
728 | 743 | ||
729 | retval = 0; | 744 | retval = 0; |
730 | 745 | ||
731 | save_flags(flags); | 746 | spin_lock_irqsave(&fep->lock,flags); |
732 | cli(); | ||
733 | 747 | ||
734 | if ((mip = mii_free) != NULL) { | 748 | if ((mip = mii_free) != NULL) { |
735 | mii_free = mip->mii_next; | 749 | mii_free = mip->mii_next; |
@@ -749,7 +763,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi | |||
749 | retval = 1; | 763 | retval = 1; |
750 | } | 764 | } |
751 | 765 | ||
752 | restore_flags(flags); | 766 | spin_unlock_irqrestore(&fep->lock,flags); |
753 | 767 | ||
754 | return(retval); | 768 | return(retval); |
755 | } | 769 | } |
@@ -872,14 +886,14 @@ static phy_cmd_t const phy_cmd_lxt970_shutdown[] = { /* disable interrupts */ | |||
872 | { mk_mii_end, } | 886 | { mk_mii_end, } |
873 | }; | 887 | }; |
874 | static phy_info_t const phy_info_lxt970 = { | 888 | static phy_info_t const phy_info_lxt970 = { |
875 | .id = 0x07810000, | 889 | .id = 0x07810000, |
876 | .name = "LXT970", | 890 | .name = "LXT970", |
877 | .config = phy_cmd_lxt970_config, | 891 | .config = phy_cmd_lxt970_config, |
878 | .startup = phy_cmd_lxt970_startup, | 892 | .startup = phy_cmd_lxt970_startup, |
879 | .ack_int = phy_cmd_lxt970_ack_int, | 893 | .ack_int = phy_cmd_lxt970_ack_int, |
880 | .shutdown = phy_cmd_lxt970_shutdown | 894 | .shutdown = phy_cmd_lxt970_shutdown |
881 | }; | 895 | }; |
882 | 896 | ||
883 | /* ------------------------------------------------------------------------- */ | 897 | /* ------------------------------------------------------------------------- */ |
884 | /* The Level one LXT971 is used on some of my custom boards */ | 898 | /* The Level one LXT971 is used on some of my custom boards */ |
885 | 899 | ||
@@ -892,7 +906,7 @@ static phy_info_t const phy_info_lxt970 = { | |||
892 | #define MII_LXT971_LCR 20 /* LED Control Register */ | 906 | #define MII_LXT971_LCR 20 /* LED Control Register */ |
893 | #define MII_LXT971_TCR 30 /* Transmit Control Register */ | 907 | #define MII_LXT971_TCR 30 /* Transmit Control Register */ |
894 | 908 | ||
895 | /* | 909 | /* |
896 | * I had some nice ideas of running the MDIO faster... | 910 | * I had some nice ideas of running the MDIO faster... |
897 | * The 971 should support 8MHz and I tried it, but things acted really | 911 | * The 971 should support 8MHz and I tried it, but things acted really |
898 | * weird, so 2.5 MHz ought to be enough for anyone... | 912 | * weird, so 2.5 MHz ought to be enough for anyone... |
@@ -930,9 +944,9 @@ static void mii_parse_lxt971_sr2(uint mii_reg, struct net_device *dev) | |||
930 | 944 | ||
931 | *s = status; | 945 | *s = status; |
932 | } | 946 | } |
933 | 947 | ||
934 | static phy_cmd_t const phy_cmd_lxt971_config[] = { | 948 | static phy_cmd_t const phy_cmd_lxt971_config[] = { |
935 | /* limit to 10MBit because my prototype board | 949 | /* limit to 10MBit because my prototype board |
936 | * doesn't work with 100. */ | 950 | * doesn't work with 100. */ |
937 | { mk_mii_read(MII_REG_CR), mii_parse_cr }, | 951 | { mk_mii_read(MII_REG_CR), mii_parse_cr }, |
938 | { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, | 952 | { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, |
@@ -946,7 +960,7 @@ static phy_cmd_t const phy_cmd_lxt971_startup[] = { /* enable interrupts */ | |||
946 | /* Somehow does the 971 tell me that the link is down | 960 | /* Somehow does the 971 tell me that the link is down |
947 | * the first read after power-up. | 961 | * the first read after power-up. |
948 | * read here to get a valid value in ack_int */ | 962 | * read here to get a valid value in ack_int */ |
949 | { mk_mii_read(MII_REG_SR), mii_parse_sr }, | 963 | { mk_mii_read(MII_REG_SR), mii_parse_sr }, |
950 | { mk_mii_end, } | 964 | { mk_mii_end, } |
951 | }; | 965 | }; |
952 | static phy_cmd_t const phy_cmd_lxt971_ack_int[] = { | 966 | static phy_cmd_t const phy_cmd_lxt971_ack_int[] = { |
@@ -962,7 +976,7 @@ static phy_cmd_t const phy_cmd_lxt971_shutdown[] = { /* disable interrupts */ | |||
962 | { mk_mii_end, } | 976 | { mk_mii_end, } |
963 | }; | 977 | }; |
964 | static phy_info_t const phy_info_lxt971 = { | 978 | static phy_info_t const phy_info_lxt971 = { |
965 | .id = 0x0001378e, | 979 | .id = 0x0001378e, |
966 | .name = "LXT971", | 980 | .name = "LXT971", |
967 | .config = phy_cmd_lxt971_config, | 981 | .config = phy_cmd_lxt971_config, |
968 | .startup = phy_cmd_lxt971_startup, | 982 | .startup = phy_cmd_lxt971_startup, |
@@ -1001,7 +1015,7 @@ static void mii_parse_qs6612_pcr(uint mii_reg, struct net_device *dev) | |||
1001 | } | 1015 | } |
1002 | 1016 | ||
1003 | static phy_cmd_t const phy_cmd_qs6612_config[] = { | 1017 | static phy_cmd_t const phy_cmd_qs6612_config[] = { |
1004 | /* The PHY powers up isolated on the RPX, | 1018 | /* The PHY powers up isolated on the RPX, |
1005 | * so send a command to allow operation. | 1019 | * so send a command to allow operation. |
1006 | */ | 1020 | */ |
1007 | { mk_mii_write(MII_QS6612_PCR, 0x0dc0), NULL }, | 1021 | { mk_mii_write(MII_QS6612_PCR, 0x0dc0), NULL }, |
@@ -1031,7 +1045,7 @@ static phy_cmd_t const phy_cmd_qs6612_shutdown[] = { /* disable interrupts */ | |||
1031 | { mk_mii_end, } | 1045 | { mk_mii_end, } |
1032 | }; | 1046 | }; |
1033 | static phy_info_t const phy_info_qs6612 = { | 1047 | static phy_info_t const phy_info_qs6612 = { |
1034 | .id = 0x00181440, | 1048 | .id = 0x00181440, |
1035 | .name = "QS6612", | 1049 | .name = "QS6612", |
1036 | .config = phy_cmd_qs6612_config, | 1050 | .config = phy_cmd_qs6612_config, |
1037 | .startup = phy_cmd_qs6612_startup, | 1051 | .startup = phy_cmd_qs6612_startup, |
@@ -1079,7 +1093,7 @@ static phy_cmd_t const phy_cmd_am79c874_config[] = { | |||
1079 | static phy_cmd_t const phy_cmd_am79c874_startup[] = { /* enable interrupts */ | 1093 | static phy_cmd_t const phy_cmd_am79c874_startup[] = { /* enable interrupts */ |
1080 | { mk_mii_write(MII_AM79C874_ICSR, 0xff00), NULL }, | 1094 | { mk_mii_write(MII_AM79C874_ICSR, 0xff00), NULL }, |
1081 | { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ | 1095 | { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ |
1082 | { mk_mii_read(MII_REG_SR), mii_parse_sr }, | 1096 | { mk_mii_read(MII_REG_SR), mii_parse_sr }, |
1083 | { mk_mii_end, } | 1097 | { mk_mii_end, } |
1084 | }; | 1098 | }; |
1085 | static phy_cmd_t const phy_cmd_am79c874_ack_int[] = { | 1099 | static phy_cmd_t const phy_cmd_am79c874_ack_int[] = { |
@@ -1121,7 +1135,7 @@ static phy_cmd_t const phy_cmd_ks8721bl_config[] = { | |||
1121 | static phy_cmd_t const phy_cmd_ks8721bl_startup[] = { /* enable interrupts */ | 1135 | static phy_cmd_t const phy_cmd_ks8721bl_startup[] = { /* enable interrupts */ |
1122 | { mk_mii_write(MII_KS8721BL_ICSR, 0xff00), NULL }, | 1136 | { mk_mii_write(MII_KS8721BL_ICSR, 0xff00), NULL }, |
1123 | { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ | 1137 | { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ |
1124 | { mk_mii_read(MII_REG_SR), mii_parse_sr }, | 1138 | { mk_mii_read(MII_REG_SR), mii_parse_sr }, |
1125 | { mk_mii_end, } | 1139 | { mk_mii_end, } |
1126 | }; | 1140 | }; |
1127 | static phy_cmd_t const phy_cmd_ks8721bl_ack_int[] = { | 1141 | static phy_cmd_t const phy_cmd_ks8721bl_ack_int[] = { |
@@ -1136,7 +1150,7 @@ static phy_cmd_t const phy_cmd_ks8721bl_shutdown[] = { /* disable interrupts */ | |||
1136 | { mk_mii_end, } | 1150 | { mk_mii_end, } |
1137 | }; | 1151 | }; |
1138 | static phy_info_t const phy_info_ks8721bl = { | 1152 | static phy_info_t const phy_info_ks8721bl = { |
1139 | .id = 0x00022161, | 1153 | .id = 0x00022161, |
1140 | .name = "KS8721BL", | 1154 | .name = "KS8721BL", |
1141 | .config = phy_cmd_ks8721bl_config, | 1155 | .config = phy_cmd_ks8721bl_config, |
1142 | .startup = phy_cmd_ks8721bl_startup, | 1156 | .startup = phy_cmd_ks8721bl_startup, |
@@ -1216,7 +1230,7 @@ static phy_info_t const * const phy_info[] = { | |||
1216 | }; | 1230 | }; |
1217 | 1231 | ||
1218 | /* ------------------------------------------------------------------------- */ | 1232 | /* ------------------------------------------------------------------------- */ |
1219 | 1233 | #if !defined(CONFIG_M532x) | |
1220 | #ifdef CONFIG_RPXCLASSIC | 1234 | #ifdef CONFIG_RPXCLASSIC |
1221 | static void | 1235 | static void |
1222 | mii_link_interrupt(void *dev_id); | 1236 | mii_link_interrupt(void *dev_id); |
@@ -1224,6 +1238,7 @@ mii_link_interrupt(void *dev_id); | |||
1224 | static irqreturn_t | 1238 | static irqreturn_t |
1225 | mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs); | 1239 | mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs); |
1226 | #endif | 1240 | #endif |
1241 | #endif | ||
1227 | 1242 | ||
1228 | #if defined(CONFIG_M5272) | 1243 | #if defined(CONFIG_M5272) |
1229 | 1244 | ||
@@ -1384,13 +1399,13 @@ static void __inline__ fec_request_intrs(struct net_device *dev) | |||
1384 | { | 1399 | { |
1385 | volatile unsigned char *icrp; | 1400 | volatile unsigned char *icrp; |
1386 | volatile unsigned long *imrp; | 1401 | volatile unsigned long *imrp; |
1387 | int i; | 1402 | int i, ilip; |
1388 | 1403 | ||
1389 | b = (fep->index) ? MCFICM_INTC1 : MCFICM_INTC0; | 1404 | b = (fep->index) ? MCFICM_INTC1 : MCFICM_INTC0; |
1390 | icrp = (volatile unsigned char *) (MCF_IPSBAR + b + | 1405 | icrp = (volatile unsigned char *) (MCF_IPSBAR + b + |
1391 | MCFINTC_ICR0); | 1406 | MCFINTC_ICR0); |
1392 | for (i = 23; (i < 36); i++) | 1407 | for (i = 23, ilip = 0x28; (i < 36); i++) |
1393 | icrp[i] = 0x23; | 1408 | icrp[i] = ilip--; |
1394 | 1409 | ||
1395 | imrp = (volatile unsigned long *) (MCF_IPSBAR + b + | 1410 | imrp = (volatile unsigned long *) (MCF_IPSBAR + b + |
1396 | MCFINTC_IMRH); | 1411 | MCFINTC_IMRH); |
@@ -1405,7 +1420,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev) | |||
1405 | { | 1420 | { |
1406 | volatile u16 *gpio_paspar; | 1421 | volatile u16 *gpio_paspar; |
1407 | volatile u8 *gpio_pehlpar; | 1422 | volatile u8 *gpio_pehlpar; |
1408 | 1423 | ||
1409 | gpio_paspar = (volatile u16 *) (MCF_IPSBAR + 0x100056); | 1424 | gpio_paspar = (volatile u16 *) (MCF_IPSBAR + 0x100056); |
1410 | gpio_pehlpar = (volatile u16 *) (MCF_IPSBAR + 0x100058); | 1425 | gpio_pehlpar = (volatile u16 *) (MCF_IPSBAR + 0x100058); |
1411 | *gpio_paspar |= 0x0f00; | 1426 | *gpio_paspar |= 0x0f00; |
@@ -1618,6 +1633,159 @@ static void __inline__ fec_uncache(unsigned long addr) | |||
1618 | 1633 | ||
1619 | /* ------------------------------------------------------------------------- */ | 1634 | /* ------------------------------------------------------------------------- */ |
1620 | 1635 | ||
1636 | #elif defined(CONFIG_M532x) | ||
1637 | /* | ||
1638 | * Code specific for M532x | ||
1639 | */ | ||
1640 | static void __inline__ fec_request_intrs(struct net_device *dev) | ||
1641 | { | ||
1642 | struct fec_enet_private *fep; | ||
1643 | int b; | ||
1644 | static const struct idesc { | ||
1645 | char *name; | ||
1646 | unsigned short irq; | ||
1647 | } *idp, id[] = { | ||
1648 | { "fec(TXF)", 36 }, | ||
1649 | { "fec(TXB)", 37 }, | ||
1650 | { "fec(TXFIFO)", 38 }, | ||
1651 | { "fec(TXCR)", 39 }, | ||
1652 | { "fec(RXF)", 40 }, | ||
1653 | { "fec(RXB)", 41 }, | ||
1654 | { "fec(MII)", 42 }, | ||
1655 | { "fec(LC)", 43 }, | ||
1656 | { "fec(HBERR)", 44 }, | ||
1657 | { "fec(GRA)", 45 }, | ||
1658 | { "fec(EBERR)", 46 }, | ||
1659 | { "fec(BABT)", 47 }, | ||
1660 | { "fec(BABR)", 48 }, | ||
1661 | { NULL }, | ||
1662 | }; | ||
1663 | |||
1664 | fep = netdev_priv(dev); | ||
1665 | b = (fep->index) ? 128 : 64; | ||
1666 | |||
1667 | /* Setup interrupt handlers. */ | ||
1668 | for (idp = id; idp->name; idp++) { | ||
1669 | if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0) | ||
1670 | printk("FEC: Could not allocate %s IRQ(%d)!\n", | ||
1671 | idp->name, b+idp->irq); | ||
1672 | } | ||
1673 | |||
1674 | /* Unmask interrupts */ | ||
1675 | MCF_INTC0_ICR36 = 0x2; | ||
1676 | MCF_INTC0_ICR37 = 0x2; | ||
1677 | MCF_INTC0_ICR38 = 0x2; | ||
1678 | MCF_INTC0_ICR39 = 0x2; | ||
1679 | MCF_INTC0_ICR40 = 0x2; | ||
1680 | MCF_INTC0_ICR41 = 0x2; | ||
1681 | MCF_INTC0_ICR42 = 0x2; | ||
1682 | MCF_INTC0_ICR43 = 0x2; | ||
1683 | MCF_INTC0_ICR44 = 0x2; | ||
1684 | MCF_INTC0_ICR45 = 0x2; | ||
1685 | MCF_INTC0_ICR46 = 0x2; | ||
1686 | MCF_INTC0_ICR47 = 0x2; | ||
1687 | MCF_INTC0_ICR48 = 0x2; | ||
1688 | |||
1689 | MCF_INTC0_IMRH &= ~( | ||
1690 | MCF_INTC_IMRH_INT_MASK36 | | ||
1691 | MCF_INTC_IMRH_INT_MASK37 | | ||
1692 | MCF_INTC_IMRH_INT_MASK38 | | ||
1693 | MCF_INTC_IMRH_INT_MASK39 | | ||
1694 | MCF_INTC_IMRH_INT_MASK40 | | ||
1695 | MCF_INTC_IMRH_INT_MASK41 | | ||
1696 | MCF_INTC_IMRH_INT_MASK42 | | ||
1697 | MCF_INTC_IMRH_INT_MASK43 | | ||
1698 | MCF_INTC_IMRH_INT_MASK44 | | ||
1699 | MCF_INTC_IMRH_INT_MASK45 | | ||
1700 | MCF_INTC_IMRH_INT_MASK46 | | ||
1701 | MCF_INTC_IMRH_INT_MASK47 | | ||
1702 | MCF_INTC_IMRH_INT_MASK48 ); | ||
1703 | |||
1704 | /* Set up gpio outputs for MII lines */ | ||
1705 | MCF_GPIO_PAR_FECI2C |= (0 | | ||
1706 | MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC | | ||
1707 | MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO); | ||
1708 | MCF_GPIO_PAR_FEC = (0 | | ||
1709 | MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | | ||
1710 | MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC); | ||
1711 | } | ||
1712 | |||
1713 | static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) | ||
1714 | { | ||
1715 | volatile fec_t *fecp; | ||
1716 | |||
1717 | fecp = fep->hwp; | ||
1718 | fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04; | ||
1719 | fecp->fec_x_cntrl = 0x00; | ||
1720 | |||
1721 | /* | ||
1722 | * Set MII speed to 2.5 MHz | ||
1723 | */ | ||
1724 | fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2; | ||
1725 | fecp->fec_mii_speed = fep->phy_speed; | ||
1726 | |||
1727 | fec_restart(dev, 0); | ||
1728 | } | ||
1729 | |||
1730 | static void __inline__ fec_get_mac(struct net_device *dev) | ||
1731 | { | ||
1732 | struct fec_enet_private *fep = netdev_priv(dev); | ||
1733 | volatile fec_t *fecp; | ||
1734 | unsigned char *iap, tmpaddr[ETH_ALEN]; | ||
1735 | |||
1736 | fecp = fep->hwp; | ||
1737 | |||
1738 | if (FEC_FLASHMAC) { | ||
1739 | /* | ||
1740 | * Get MAC address from FLASH. | ||
1741 | * If it is all 1's or 0's, use the default. | ||
1742 | */ | ||
1743 | iap = FEC_FLASHMAC; | ||
1744 | if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) && | ||
1745 | (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0)) | ||
1746 | iap = fec_mac_default; | ||
1747 | if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) && | ||
1748 | (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) | ||
1749 | iap = fec_mac_default; | ||
1750 | } else { | ||
1751 | *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; | ||
1752 | *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); | ||
1753 | iap = &tmpaddr[0]; | ||
1754 | } | ||
1755 | |||
1756 | memcpy(dev->dev_addr, iap, ETH_ALEN); | ||
1757 | |||
1758 | /* Adjust MAC if using default MAC address */ | ||
1759 | if (iap == fec_mac_default) | ||
1760 | dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index; | ||
1761 | } | ||
1762 | |||
1763 | static void __inline__ fec_enable_phy_intr(void) | ||
1764 | { | ||
1765 | } | ||
1766 | |||
1767 | static void __inline__ fec_disable_phy_intr(void) | ||
1768 | { | ||
1769 | } | ||
1770 | |||
1771 | static void __inline__ fec_phy_ack_intr(void) | ||
1772 | { | ||
1773 | } | ||
1774 | |||
1775 | static void __inline__ fec_localhw_setup(void) | ||
1776 | { | ||
1777 | } | ||
1778 | |||
1779 | /* | ||
1780 | * Do not need to make region uncached on 532x. | ||
1781 | */ | ||
1782 | static void __inline__ fec_uncache(unsigned long addr) | ||
1783 | { | ||
1784 | } | ||
1785 | |||
1786 | /* ------------------------------------------------------------------------- */ | ||
1787 | |||
1788 | |||
1621 | #else | 1789 | #else |
1622 | 1790 | ||
1623 | /* | 1791 | /* |
@@ -1688,10 +1856,10 @@ static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_priva | |||
1688 | immap->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */ | 1856 | immap->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */ |
1689 | else | 1857 | else |
1690 | immap->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */ | 1858 | immap->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */ |
1691 | 1859 | ||
1692 | /* Set MII speed to 2.5 MHz | 1860 | /* Set MII speed to 2.5 MHz |
1693 | */ | 1861 | */ |
1694 | fecp->fec_mii_speed = fep->phy_speed = | 1862 | fecp->fec_mii_speed = fep->phy_speed = |
1695 | ((bd->bi_busfreq * 1000000) / 2500000) & 0x7e; | 1863 | ((bd->bi_busfreq * 1000000) / 2500000) & 0x7e; |
1696 | } | 1864 | } |
1697 | 1865 | ||
@@ -1701,7 +1869,7 @@ static void __inline__ fec_enable_phy_intr(void) | |||
1701 | 1869 | ||
1702 | fecp = fep->hwp; | 1870 | fecp = fep->hwp; |
1703 | 1871 | ||
1704 | /* Enable MII command finished interrupt | 1872 | /* Enable MII command finished interrupt |
1705 | */ | 1873 | */ |
1706 | fecp->fec_ivec = (FEC_INTERRUPT/2) << 29; | 1874 | fecp->fec_ivec = (FEC_INTERRUPT/2) << 29; |
1707 | } | 1875 | } |
@@ -1803,7 +1971,7 @@ static void mii_display_config(struct net_device *dev) | |||
1803 | 1971 | ||
1804 | if (status & PHY_CONF_LOOP) | 1972 | if (status & PHY_CONF_LOOP) |
1805 | printk(", loopback enabled"); | 1973 | printk(", loopback enabled"); |
1806 | 1974 | ||
1807 | printk(".\n"); | 1975 | printk(".\n"); |
1808 | 1976 | ||
1809 | fep->sequence_done = 1; | 1977 | fep->sequence_done = 1; |
@@ -1825,7 +1993,7 @@ static void mii_relink(struct net_device *dev) | |||
1825 | 1993 | ||
1826 | if (fep->link) { | 1994 | if (fep->link) { |
1827 | duplex = 0; | 1995 | duplex = 0; |
1828 | if (fep->phy_status | 1996 | if (fep->phy_status |
1829 | & (PHY_STAT_100FDX | PHY_STAT_10FDX)) | 1997 | & (PHY_STAT_100FDX | PHY_STAT_10FDX)) |
1830 | duplex = 1; | 1998 | duplex = 1; |
1831 | fec_restart(dev, duplex); | 1999 | fec_restart(dev, duplex); |
@@ -1902,7 +2070,7 @@ mii_discover_phy3(uint mii_reg, struct net_device *dev) | |||
1902 | printk(" -- %s\n", phy_info[i]->name); | 2070 | printk(" -- %s\n", phy_info[i]->name); |
1903 | else | 2071 | else |
1904 | printk(" -- unknown PHY!\n"); | 2072 | printk(" -- unknown PHY!\n"); |
1905 | 2073 | ||
1906 | fep->phy = phy_info[i]; | 2074 | fep->phy = phy_info[i]; |
1907 | fep->phy_id_done = 1; | 2075 | fep->phy_id_done = 1; |
1908 | } | 2076 | } |
@@ -1922,7 +2090,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev) | |||
1922 | 2090 | ||
1923 | if (fep->phy_addr < 32) { | 2091 | if (fep->phy_addr < 32) { |
1924 | if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) { | 2092 | if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) { |
1925 | 2093 | ||
1926 | /* Got first part of ID, now get remainder. | 2094 | /* Got first part of ID, now get remainder. |
1927 | */ | 2095 | */ |
1928 | fep->phy_id = phytype << 16; | 2096 | fep->phy_id = phytype << 16; |
@@ -1985,9 +2153,12 @@ fec_enet_open(struct net_device *dev) | |||
1985 | mii_do_cmd(dev, fep->phy->config); | 2153 | mii_do_cmd(dev, fep->phy->config); |
1986 | mii_do_cmd(dev, phy_cmd_config); /* display configuration */ | 2154 | mii_do_cmd(dev, phy_cmd_config); /* display configuration */ |
1987 | 2155 | ||
1988 | /* FIXME: use netif_carrier_{on,off} ; this polls | 2156 | /* Poll until the PHY tells us its configuration |
1989 | * until link is up which is wrong... could be | 2157 | * (not link state). |
1990 | * 30 seconds or more we are trapped in here. -jgarzik | 2158 | * Request is initiated by mii_do_cmd above, but answer |
2159 | * comes by interrupt. | ||
2160 | * This should take about 25 usec per register at 2.5 MHz, | ||
2161 | * and we read approximately 5 registers. | ||
1991 | */ | 2162 | */ |
1992 | while(!fep->sequence_done) | 2163 | while(!fep->sequence_done) |
1993 | schedule(); | 2164 | schedule(); |
@@ -2056,8 +2227,6 @@ static void set_multicast_list(struct net_device *dev) | |||
2056 | ep = fep->hwp; | 2227 | ep = fep->hwp; |
2057 | 2228 | ||
2058 | if (dev->flags&IFF_PROMISC) { | 2229 | if (dev->flags&IFF_PROMISC) { |
2059 | /* Log any net taps. */ | ||
2060 | printk("%s: Promiscuous mode enabled.\n", dev->name); | ||
2061 | ep->fec_r_cntrl |= 0x0008; | 2230 | ep->fec_r_cntrl |= 0x0008; |
2062 | } else { | 2231 | } else { |
2063 | 2232 | ||
@@ -2074,7 +2243,7 @@ static void set_multicast_list(struct net_device *dev) | |||
2074 | */ | 2243 | */ |
2075 | ep->fec_hash_table_high = 0; | 2244 | ep->fec_hash_table_high = 0; |
2076 | ep->fec_hash_table_low = 0; | 2245 | ep->fec_hash_table_low = 0; |
2077 | 2246 | ||
2078 | dmi = dev->mc_list; | 2247 | dmi = dev->mc_list; |
2079 | 2248 | ||
2080 | for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) | 2249 | for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) |
@@ -2083,7 +2252,7 @@ static void set_multicast_list(struct net_device *dev) | |||
2083 | */ | 2252 | */ |
2084 | if (!(dmi->dmi_addr[0] & 1)) | 2253 | if (!(dmi->dmi_addr[0] & 1)) |
2085 | continue; | 2254 | continue; |
2086 | 2255 | ||
2087 | /* calculate crc32 value of mac address | 2256 | /* calculate crc32 value of mac address |
2088 | */ | 2257 | */ |
2089 | crc = 0xffffffff; | 2258 | crc = 0xffffffff; |
@@ -2102,7 +2271,7 @@ static void set_multicast_list(struct net_device *dev) | |||
2102 | which point to specific bit in he hash registers | 2271 | which point to specific bit in he hash registers |
2103 | */ | 2272 | */ |
2104 | hash = (crc >> (32 - HASH_BITS)) & 0x3f; | 2273 | hash = (crc >> (32 - HASH_BITS)) & 0x3f; |
2105 | 2274 | ||
2106 | if (hash > 31) | 2275 | if (hash > 31) |
2107 | ep->fec_hash_table_high |= 1 << (hash - 32); | 2276 | ep->fec_hash_table_high |= 1 << (hash - 32); |
2108 | else | 2277 | else |
@@ -2253,15 +2422,11 @@ int __init fec_enet_init(struct net_device *dev) | |||
2253 | */ | 2422 | */ |
2254 | fec_request_intrs(dev); | 2423 | fec_request_intrs(dev); |
2255 | 2424 | ||
2256 | /* Clear and enable interrupts */ | ||
2257 | fecp->fec_ievent = 0xffc00000; | ||
2258 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | | ||
2259 | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); | ||
2260 | fecp->fec_hash_table_high = 0; | 2425 | fecp->fec_hash_table_high = 0; |
2261 | fecp->fec_hash_table_low = 0; | 2426 | fecp->fec_hash_table_low = 0; |
2262 | fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; | 2427 | fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; |
2263 | fecp->fec_ecntrl = 2; | 2428 | fecp->fec_ecntrl = 2; |
2264 | fecp->fec_r_des_active = 0x01000000; | 2429 | fecp->fec_r_des_active = 0; |
2265 | 2430 | ||
2266 | dev->base_addr = (unsigned long)fecp; | 2431 | dev->base_addr = (unsigned long)fecp; |
2267 | 2432 | ||
@@ -2281,6 +2446,11 @@ int __init fec_enet_init(struct net_device *dev) | |||
2281 | /* setup MII interface */ | 2446 | /* setup MII interface */ |
2282 | fec_set_mii(dev, fep); | 2447 | fec_set_mii(dev, fep); |
2283 | 2448 | ||
2449 | /* Clear and enable interrupts */ | ||
2450 | fecp->fec_ievent = 0xffc00000; | ||
2451 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | | ||
2452 | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); | ||
2453 | |||
2284 | /* Queue up command to detect the PHY and initialize the | 2454 | /* Queue up command to detect the PHY and initialize the |
2285 | * remainder of the interface. | 2455 | * remainder of the interface. |
2286 | */ | 2456 | */ |
@@ -2312,11 +2482,6 @@ fec_restart(struct net_device *dev, int duplex) | |||
2312 | fecp->fec_ecntrl = 1; | 2482 | fecp->fec_ecntrl = 1; |
2313 | udelay(10); | 2483 | udelay(10); |
2314 | 2484 | ||
2315 | /* Enable interrupts we wish to service. | ||
2316 | */ | ||
2317 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | | ||
2318 | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); | ||
2319 | |||
2320 | /* Clear any outstanding interrupt. | 2485 | /* Clear any outstanding interrupt. |
2321 | */ | 2486 | */ |
2322 | fecp->fec_ievent = 0xffc00000; | 2487 | fecp->fec_ievent = 0xffc00000; |
@@ -2408,7 +2573,12 @@ fec_restart(struct net_device *dev, int duplex) | |||
2408 | /* And last, enable the transmit and receive processing. | 2573 | /* And last, enable the transmit and receive processing. |
2409 | */ | 2574 | */ |
2410 | fecp->fec_ecntrl = 2; | 2575 | fecp->fec_ecntrl = 2; |
2411 | fecp->fec_r_des_active = 0x01000000; | 2576 | fecp->fec_r_des_active = 0; |
2577 | |||
2578 | /* Enable interrupts we wish to service. | ||
2579 | */ | ||
2580 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | | ||
2581 | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); | ||
2412 | } | 2582 | } |
2413 | 2583 | ||
2414 | static void | 2584 | static void |
@@ -2420,9 +2590,16 @@ fec_stop(struct net_device *dev) | |||
2420 | fep = netdev_priv(dev); | 2590 | fep = netdev_priv(dev); |
2421 | fecp = fep->hwp; | 2591 | fecp = fep->hwp; |
2422 | 2592 | ||
2423 | fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ | 2593 | /* |
2424 | 2594 | ** We cannot expect a graceful transmit stop without link !!! | |
2425 | while(!(fecp->fec_ievent & FEC_ENET_GRA)); | 2595 | */ |
2596 | if (fep->link) | ||
2597 | { | ||
2598 | fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ | ||
2599 | udelay(10); | ||
2600 | if (!(fecp->fec_ievent & FEC_ENET_GRA)) | ||
2601 | printk("fec_stop : Graceful transmit stop did not complete !\n"); | ||
2602 | } | ||
2426 | 2603 | ||
2427 | /* Whack a reset. We should wait for this. | 2604 | /* Whack a reset. We should wait for this. |
2428 | */ | 2605 | */ |