diff options
author | Florian Fainelli <florian@openwrt.org> | 2009-01-22 17:06:25 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-22 17:06:25 -0500 |
commit | 5ef3041e4a7cd817bc5ebbb0e5e956a2bdd32c38 (patch) | |
tree | 3e238cc8e639d050ef65bc31017b935b64f4acae /drivers/net/au1000_eth.c | |
parent | 4feb88e5c694bfe414cbc3ce0e383f7f7038f90b (diff) |
au1000: reorder functions
This patch reorders functions so that we do longer need
forward declarations.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/au1000_eth.c')
-rw-r--r-- | drivers/net/au1000_eth.c | 1043 |
1 files changed, 511 insertions, 532 deletions
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 9c875bb3f76c..6d76ccb8e296 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c | |||
@@ -81,24 +81,6 @@ MODULE_AUTHOR(DRV_AUTHOR); | |||
81 | MODULE_DESCRIPTION(DRV_DESC); | 81 | MODULE_DESCRIPTION(DRV_DESC); |
82 | MODULE_LICENSE("GPL"); | 82 | MODULE_LICENSE("GPL"); |
83 | 83 | ||
84 | // prototypes | ||
85 | static void hard_stop(struct net_device *); | ||
86 | static void enable_rx_tx(struct net_device *dev); | ||
87 | static struct net_device * au1000_probe(int port_num); | ||
88 | static int au1000_init(struct net_device *); | ||
89 | static int au1000_open(struct net_device *); | ||
90 | static int au1000_close(struct net_device *); | ||
91 | static int au1000_tx(struct sk_buff *, struct net_device *); | ||
92 | static int au1000_rx(struct net_device *); | ||
93 | static irqreturn_t au1000_interrupt(int, void *); | ||
94 | static void au1000_tx_timeout(struct net_device *); | ||
95 | static void set_rx_mode(struct net_device *); | ||
96 | static int au1000_ioctl(struct net_device *, struct ifreq *, int); | ||
97 | static int au1000_mdio_read(struct net_device *, int, int); | ||
98 | static void au1000_mdio_write(struct net_device *, int, int, u16); | ||
99 | static void au1000_adjust_link(struct net_device *); | ||
100 | static void enable_mac(struct net_device *, int); | ||
101 | |||
102 | /* | 84 | /* |
103 | * Theory of operation | 85 | * Theory of operation |
104 | * | 86 | * |
@@ -188,6 +170,26 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES]; | |||
188 | # error MAC0-associated PHY attached 2nd MACs MII bus not supported yet | 170 | # error MAC0-associated PHY attached 2nd MACs MII bus not supported yet |
189 | #endif | 171 | #endif |
190 | 172 | ||
173 | static void enable_mac(struct net_device *dev, int force_reset) | ||
174 | { | ||
175 | unsigned long flags; | ||
176 | struct au1000_private *aup = netdev_priv(dev); | ||
177 | |||
178 | spin_lock_irqsave(&aup->lock, flags); | ||
179 | |||
180 | if(force_reset || (!aup->mac_enabled)) { | ||
181 | *aup->enable = MAC_EN_CLOCK_ENABLE; | ||
182 | au_sync_delay(2); | ||
183 | *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 | ||
184 | | MAC_EN_CLOCK_ENABLE); | ||
185 | au_sync_delay(2); | ||
186 | |||
187 | aup->mac_enabled = 1; | ||
188 | } | ||
189 | |||
190 | spin_unlock_irqrestore(&aup->lock, flags); | ||
191 | } | ||
192 | |||
191 | /* | 193 | /* |
192 | * MII operations | 194 | * MII operations |
193 | */ | 195 | */ |
@@ -281,6 +283,107 @@ static int au1000_mdiobus_reset(struct mii_bus *bus) | |||
281 | return 0; | 283 | return 0; |
282 | } | 284 | } |
283 | 285 | ||
286 | static void hard_stop(struct net_device *dev) | ||
287 | { | ||
288 | struct au1000_private *aup = netdev_priv(dev); | ||
289 | |||
290 | if (au1000_debug > 4) | ||
291 | printk(KERN_INFO "%s: hard stop\n", dev->name); | ||
292 | |||
293 | aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE); | ||
294 | au_sync_delay(10); | ||
295 | } | ||
296 | |||
297 | static void enable_rx_tx(struct net_device *dev) | ||
298 | { | ||
299 | struct au1000_private *aup = netdev_priv(dev); | ||
300 | |||
301 | if (au1000_debug > 4) | ||
302 | printk(KERN_INFO "%s: enable_rx_tx\n", dev->name); | ||
303 | |||
304 | aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE); | ||
305 | au_sync_delay(10); | ||
306 | } | ||
307 | |||
308 | static void | ||
309 | au1000_adjust_link(struct net_device *dev) | ||
310 | { | ||
311 | struct au1000_private *aup = netdev_priv(dev); | ||
312 | struct phy_device *phydev = aup->phy_dev; | ||
313 | unsigned long flags; | ||
314 | |||
315 | int status_change = 0; | ||
316 | |||
317 | BUG_ON(!aup->phy_dev); | ||
318 | |||
319 | spin_lock_irqsave(&aup->lock, flags); | ||
320 | |||
321 | if (phydev->link && (aup->old_speed != phydev->speed)) { | ||
322 | // speed changed | ||
323 | |||
324 | switch(phydev->speed) { | ||
325 | case SPEED_10: | ||
326 | case SPEED_100: | ||
327 | break; | ||
328 | default: | ||
329 | printk(KERN_WARNING | ||
330 | "%s: Speed (%d) is not 10/100 ???\n", | ||
331 | dev->name, phydev->speed); | ||
332 | break; | ||
333 | } | ||
334 | |||
335 | aup->old_speed = phydev->speed; | ||
336 | |||
337 | status_change = 1; | ||
338 | } | ||
339 | |||
340 | if (phydev->link && (aup->old_duplex != phydev->duplex)) { | ||
341 | // duplex mode changed | ||
342 | |||
343 | /* switching duplex mode requires to disable rx and tx! */ | ||
344 | hard_stop(dev); | ||
345 | |||
346 | if (DUPLEX_FULL == phydev->duplex) | ||
347 | aup->mac->control = ((aup->mac->control | ||
348 | | MAC_FULL_DUPLEX) | ||
349 | & ~MAC_DISABLE_RX_OWN); | ||
350 | else | ||
351 | aup->mac->control = ((aup->mac->control | ||
352 | & ~MAC_FULL_DUPLEX) | ||
353 | | MAC_DISABLE_RX_OWN); | ||
354 | au_sync_delay(1); | ||
355 | |||
356 | enable_rx_tx(dev); | ||
357 | aup->old_duplex = phydev->duplex; | ||
358 | |||
359 | status_change = 1; | ||
360 | } | ||
361 | |||
362 | if(phydev->link != aup->old_link) { | ||
363 | // link state changed | ||
364 | |||
365 | if (!phydev->link) { | ||
366 | /* link went down */ | ||
367 | aup->old_speed = 0; | ||
368 | aup->old_duplex = -1; | ||
369 | } | ||
370 | |||
371 | aup->old_link = phydev->link; | ||
372 | status_change = 1; | ||
373 | } | ||
374 | |||
375 | spin_unlock_irqrestore(&aup->lock, flags); | ||
376 | |||
377 | if (status_change) { | ||
378 | if (phydev->link) | ||
379 | printk(KERN_INFO "%s: link up (%d/%s)\n", | ||
380 | dev->name, phydev->speed, | ||
381 | DUPLEX_FULL == phydev->duplex ? "Full" : "Half"); | ||
382 | else | ||
383 | printk(KERN_INFO "%s: link down\n", dev->name); | ||
384 | } | ||
385 | } | ||
386 | |||
284 | static int mii_probe (struct net_device *dev) | 387 | static int mii_probe (struct net_device *dev) |
285 | { | 388 | { |
286 | struct au1000_private *const aup = netdev_priv(dev); | 389 | struct au1000_private *const aup = netdev_priv(dev); |
@@ -412,48 +515,6 @@ void ReleaseDB(struct au1000_private *aup, db_dest_t *pDB) | |||
412 | aup->pDBfree = pDB; | 515 | aup->pDBfree = pDB; |
413 | } | 516 | } |
414 | 517 | ||
415 | static void enable_rx_tx(struct net_device *dev) | ||
416 | { | ||
417 | struct au1000_private *aup = netdev_priv(dev); | ||
418 | |||
419 | if (au1000_debug > 4) | ||
420 | printk(KERN_INFO "%s: enable_rx_tx\n", dev->name); | ||
421 | |||
422 | aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE); | ||
423 | au_sync_delay(10); | ||
424 | } | ||
425 | |||
426 | static void hard_stop(struct net_device *dev) | ||
427 | { | ||
428 | struct au1000_private *aup = netdev_priv(dev); | ||
429 | |||
430 | if (au1000_debug > 4) | ||
431 | printk(KERN_INFO "%s: hard stop\n", dev->name); | ||
432 | |||
433 | aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE); | ||
434 | au_sync_delay(10); | ||
435 | } | ||
436 | |||
437 | static void enable_mac(struct net_device *dev, int force_reset) | ||
438 | { | ||
439 | unsigned long flags; | ||
440 | struct au1000_private *aup = netdev_priv(dev); | ||
441 | |||
442 | spin_lock_irqsave(&aup->lock, flags); | ||
443 | |||
444 | if(force_reset || (!aup->mac_enabled)) { | ||
445 | *aup->enable = MAC_EN_CLOCK_ENABLE; | ||
446 | au_sync_delay(2); | ||
447 | *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 | ||
448 | | MAC_EN_CLOCK_ENABLE); | ||
449 | au_sync_delay(2); | ||
450 | |||
451 | aup->mac_enabled = 1; | ||
452 | } | ||
453 | |||
454 | spin_unlock_irqrestore(&aup->lock, flags); | ||
455 | } | ||
456 | |||
457 | static void reset_mac_unlocked(struct net_device *dev) | 518 | static void reset_mac_unlocked(struct net_device *dev) |
458 | { | 519 | { |
459 | struct au1000_private *const aup = netdev_priv(dev); | 520 | struct au1000_private *const aup = netdev_priv(dev); |
@@ -542,30 +603,6 @@ static struct { | |||
542 | static int num_ifs; | 603 | static int num_ifs; |
543 | 604 | ||
544 | /* | 605 | /* |
545 | * Setup the base address and interrupt of the Au1xxx ethernet macs | ||
546 | * based on cpu type and whether the interface is enabled in sys_pinfunc | ||
547 | * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0. | ||
548 | */ | ||
549 | static int __init au1000_init_module(void) | ||
550 | { | ||
551 | int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4); | ||
552 | struct net_device *dev; | ||
553 | int i, found_one = 0; | ||
554 | |||
555 | num_ifs = NUM_ETH_INTERFACES - ni; | ||
556 | |||
557 | for(i = 0; i < num_ifs; i++) { | ||
558 | dev = au1000_probe(i); | ||
559 | iflist[i].dev = dev; | ||
560 | if (dev) | ||
561 | found_one++; | ||
562 | } | ||
563 | if (!found_one) | ||
564 | return -ENODEV; | ||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | /* | ||
569 | * ethtool operations | 606 | * ethtool operations |
570 | */ | 607 | */ |
571 | 608 | ||
@@ -611,199 +648,6 @@ static const struct ethtool_ops au1000_ethtool_ops = { | |||
611 | .get_link = ethtool_op_get_link, | 648 | .get_link = ethtool_op_get_link, |
612 | }; | 649 | }; |
613 | 650 | ||
614 | static struct net_device * au1000_probe(int port_num) | ||
615 | { | ||
616 | static unsigned version_printed = 0; | ||
617 | struct au1000_private *aup = NULL; | ||
618 | struct net_device *dev = NULL; | ||
619 | db_dest_t *pDB, *pDBfree; | ||
620 | char ethaddr[6]; | ||
621 | int irq, i, err; | ||
622 | u32 base, macen; | ||
623 | |||
624 | if (port_num >= NUM_ETH_INTERFACES) | ||
625 | return NULL; | ||
626 | |||
627 | base = CPHYSADDR(iflist[port_num].base_addr ); | ||
628 | macen = CPHYSADDR(iflist[port_num].macen_addr); | ||
629 | irq = iflist[port_num].irq; | ||
630 | |||
631 | if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") || | ||
632 | !request_mem_region(macen, 4, "Au1x00 ENET")) | ||
633 | return NULL; | ||
634 | |||
635 | if (version_printed++ == 0) | ||
636 | printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR); | ||
637 | |||
638 | dev = alloc_etherdev(sizeof(struct au1000_private)); | ||
639 | if (!dev) { | ||
640 | printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME); | ||
641 | return NULL; | ||
642 | } | ||
643 | |||
644 | if ((err = register_netdev(dev)) != 0) { | ||
645 | printk(KERN_ERR "%s: Cannot register net device, error %d\n", | ||
646 | DRV_NAME, err); | ||
647 | free_netdev(dev); | ||
648 | return NULL; | ||
649 | } | ||
650 | |||
651 | printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n", | ||
652 | dev->name, base, irq); | ||
653 | |||
654 | aup = netdev_priv(dev); | ||
655 | |||
656 | spin_lock_init(&aup->lock); | ||
657 | |||
658 | /* Allocate the data buffers */ | ||
659 | /* Snooping works fine with eth on all au1xxx */ | ||
660 | aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE * | ||
661 | (NUM_TX_BUFFS + NUM_RX_BUFFS), | ||
662 | &aup->dma_addr, 0); | ||
663 | if (!aup->vaddr) { | ||
664 | free_netdev(dev); | ||
665 | release_mem_region( base, MAC_IOSIZE); | ||
666 | release_mem_region(macen, 4); | ||
667 | return NULL; | ||
668 | } | ||
669 | |||
670 | /* aup->mac is the base address of the MAC's registers */ | ||
671 | aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr; | ||
672 | |||
673 | /* Setup some variables for quick register address access */ | ||
674 | aup->enable = (volatile u32 *)iflist[port_num].macen_addr; | ||
675 | aup->mac_id = port_num; | ||
676 | au_macs[port_num] = aup; | ||
677 | |||
678 | if (port_num == 0) { | ||
679 | if (prom_get_ethernet_addr(ethaddr) == 0) | ||
680 | memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr)); | ||
681 | else { | ||
682 | printk(KERN_INFO "%s: No MAC address found\n", | ||
683 | dev->name); | ||
684 | /* Use the hard coded MAC addresses */ | ||
685 | } | ||
686 | |||
687 | setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); | ||
688 | } else if (port_num == 1) | ||
689 | setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR); | ||
690 | |||
691 | /* | ||
692 | * Assign to the Ethernet ports two consecutive MAC addresses | ||
693 | * to match those that are printed on their stickers | ||
694 | */ | ||
695 | memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); | ||
696 | dev->dev_addr[5] += port_num; | ||
697 | |||
698 | *aup->enable = 0; | ||
699 | aup->mac_enabled = 0; | ||
700 | |||
701 | aup->mii_bus = mdiobus_alloc(); | ||
702 | if (aup->mii_bus == NULL) | ||
703 | goto err_out; | ||
704 | |||
705 | aup->mii_bus->priv = dev; | ||
706 | aup->mii_bus->read = au1000_mdiobus_read; | ||
707 | aup->mii_bus->write = au1000_mdiobus_write; | ||
708 | aup->mii_bus->reset = au1000_mdiobus_reset; | ||
709 | aup->mii_bus->name = "au1000_eth_mii"; | ||
710 | snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%x", aup->mac_id); | ||
711 | aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); | ||
712 | for(i = 0; i < PHY_MAX_ADDR; ++i) | ||
713 | aup->mii_bus->irq[i] = PHY_POLL; | ||
714 | |||
715 | /* if known, set corresponding PHY IRQs */ | ||
716 | #if defined(AU1XXX_PHY_STATIC_CONFIG) | ||
717 | # if defined(AU1XXX_PHY0_IRQ) | ||
718 | if (AU1XXX_PHY0_BUSID == aup->mac_id) | ||
719 | aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ; | ||
720 | # endif | ||
721 | # if defined(AU1XXX_PHY1_IRQ) | ||
722 | if (AU1XXX_PHY1_BUSID == aup->mac_id) | ||
723 | aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ; | ||
724 | # endif | ||
725 | #endif | ||
726 | mdiobus_register(aup->mii_bus); | ||
727 | |||
728 | if (mii_probe(dev) != 0) { | ||
729 | goto err_out; | ||
730 | } | ||
731 | |||
732 | pDBfree = NULL; | ||
733 | /* setup the data buffer descriptors and attach a buffer to each one */ | ||
734 | pDB = aup->db; | ||
735 | for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) { | ||
736 | pDB->pnext = pDBfree; | ||
737 | pDBfree = pDB; | ||
738 | pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i); | ||
739 | pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr); | ||
740 | pDB++; | ||
741 | } | ||
742 | aup->pDBfree = pDBfree; | ||
743 | |||
744 | for (i = 0; i < NUM_RX_DMA; i++) { | ||
745 | pDB = GetFreeDB(aup); | ||
746 | if (!pDB) { | ||
747 | goto err_out; | ||
748 | } | ||
749 | aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; | ||
750 | aup->rx_db_inuse[i] = pDB; | ||
751 | } | ||
752 | for (i = 0; i < NUM_TX_DMA; i++) { | ||
753 | pDB = GetFreeDB(aup); | ||
754 | if (!pDB) { | ||
755 | goto err_out; | ||
756 | } | ||
757 | aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; | ||
758 | aup->tx_dma_ring[i]->len = 0; | ||
759 | aup->tx_db_inuse[i] = pDB; | ||
760 | } | ||
761 | |||
762 | dev->base_addr = base; | ||
763 | dev->irq = irq; | ||
764 | dev->open = au1000_open; | ||
765 | dev->hard_start_xmit = au1000_tx; | ||
766 | dev->stop = au1000_close; | ||
767 | dev->set_multicast_list = &set_rx_mode; | ||
768 | dev->do_ioctl = &au1000_ioctl; | ||
769 | SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); | ||
770 | dev->tx_timeout = au1000_tx_timeout; | ||
771 | dev->watchdog_timeo = ETH_TX_TIMEOUT; | ||
772 | |||
773 | /* | ||
774 | * The boot code uses the ethernet controller, so reset it to start | ||
775 | * fresh. au1000_init() expects that the device is in reset state. | ||
776 | */ | ||
777 | reset_mac(dev); | ||
778 | |||
779 | return dev; | ||
780 | |||
781 | err_out: | ||
782 | if (aup->mii_bus != NULL) { | ||
783 | mdiobus_unregister(aup->mii_bus); | ||
784 | mdiobus_free(aup->mii_bus); | ||
785 | } | ||
786 | |||
787 | /* here we should have a valid dev plus aup-> register addresses | ||
788 | * so we can reset the mac properly.*/ | ||
789 | reset_mac(dev); | ||
790 | |||
791 | for (i = 0; i < NUM_RX_DMA; i++) { | ||
792 | if (aup->rx_db_inuse[i]) | ||
793 | ReleaseDB(aup, aup->rx_db_inuse[i]); | ||
794 | } | ||
795 | for (i = 0; i < NUM_TX_DMA; i++) { | ||
796 | if (aup->tx_db_inuse[i]) | ||
797 | ReleaseDB(aup, aup->tx_db_inuse[i]); | ||
798 | } | ||
799 | dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS), | ||
800 | (void *)aup->vaddr, aup->dma_addr); | ||
801 | unregister_netdev(dev); | ||
802 | free_netdev(dev); | ||
803 | release_mem_region( base, MAC_IOSIZE); | ||
804 | release_mem_region(macen, 4); | ||
805 | return NULL; | ||
806 | } | ||
807 | 651 | ||
808 | /* | 652 | /* |
809 | * Initialize the interface. | 653 | * Initialize the interface. |
@@ -864,83 +708,170 @@ static int au1000_init(struct net_device *dev) | |||
864 | return 0; | 708 | return 0; |
865 | } | 709 | } |
866 | 710 | ||
867 | static void | 711 | static inline void update_rx_stats(struct net_device *dev, u32 status) |
868 | au1000_adjust_link(struct net_device *dev) | ||
869 | { | 712 | { |
870 | struct au1000_private *aup = netdev_priv(dev); | 713 | struct au1000_private *aup = netdev_priv(dev); |
871 | struct phy_device *phydev = aup->phy_dev; | 714 | struct net_device_stats *ps = &dev->stats; |
872 | unsigned long flags; | ||
873 | 715 | ||
874 | int status_change = 0; | 716 | ps->rx_packets++; |
717 | if (status & RX_MCAST_FRAME) | ||
718 | ps->multicast++; | ||
875 | 719 | ||
876 | BUG_ON(!aup->phy_dev); | 720 | if (status & RX_ERROR) { |
721 | ps->rx_errors++; | ||
722 | if (status & RX_MISSED_FRAME) | ||
723 | ps->rx_missed_errors++; | ||
724 | if (status & (RX_OVERLEN | RX_OVERLEN | RX_LEN_ERROR)) | ||
725 | ps->rx_length_errors++; | ||
726 | if (status & RX_CRC_ERROR) | ||
727 | ps->rx_crc_errors++; | ||
728 | if (status & RX_COLL) | ||
729 | ps->collisions++; | ||
730 | } | ||
731 | else | ||
732 | ps->rx_bytes += status & RX_FRAME_LEN_MASK; | ||
877 | 733 | ||
878 | spin_lock_irqsave(&aup->lock, flags); | 734 | } |
879 | 735 | ||
880 | if (phydev->link && (aup->old_speed != phydev->speed)) { | 736 | /* |
881 | // speed changed | 737 | * Au1000 receive routine. |
738 | */ | ||
739 | static int au1000_rx(struct net_device *dev) | ||
740 | { | ||
741 | struct au1000_private *aup = netdev_priv(dev); | ||
742 | struct sk_buff *skb; | ||
743 | volatile rx_dma_t *prxd; | ||
744 | u32 buff_stat, status; | ||
745 | db_dest_t *pDB; | ||
746 | u32 frmlen; | ||
882 | 747 | ||
883 | switch(phydev->speed) { | 748 | if (au1000_debug > 5) |
884 | case SPEED_10: | 749 | printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head); |
885 | case SPEED_100: | ||
886 | break; | ||
887 | default: | ||
888 | printk(KERN_WARNING | ||
889 | "%s: Speed (%d) is not 10/100 ???\n", | ||
890 | dev->name, phydev->speed); | ||
891 | break; | ||
892 | } | ||
893 | 750 | ||
894 | aup->old_speed = phydev->speed; | 751 | prxd = aup->rx_dma_ring[aup->rx_head]; |
752 | buff_stat = prxd->buff_stat; | ||
753 | while (buff_stat & RX_T_DONE) { | ||
754 | status = prxd->status; | ||
755 | pDB = aup->rx_db_inuse[aup->rx_head]; | ||
756 | update_rx_stats(dev, status); | ||
757 | if (!(status & RX_ERROR)) { | ||
895 | 758 | ||
896 | status_change = 1; | 759 | /* good frame */ |
760 | frmlen = (status & RX_FRAME_LEN_MASK); | ||
761 | frmlen -= 4; /* Remove FCS */ | ||
762 | skb = dev_alloc_skb(frmlen + 2); | ||
763 | if (skb == NULL) { | ||
764 | printk(KERN_ERR | ||
765 | "%s: Memory squeeze, dropping packet.\n", | ||
766 | dev->name); | ||
767 | dev->stats.rx_dropped++; | ||
768 | continue; | ||
769 | } | ||
770 | skb_reserve(skb, 2); /* 16 byte IP header align */ | ||
771 | skb_copy_to_linear_data(skb, | ||
772 | (unsigned char *)pDB->vaddr, frmlen); | ||
773 | skb_put(skb, frmlen); | ||
774 | skb->protocol = eth_type_trans(skb, dev); | ||
775 | netif_rx(skb); /* pass the packet to upper layers */ | ||
776 | } | ||
777 | else { | ||
778 | if (au1000_debug > 4) { | ||
779 | if (status & RX_MISSED_FRAME) | ||
780 | printk("rx miss\n"); | ||
781 | if (status & RX_WDOG_TIMER) | ||
782 | printk("rx wdog\n"); | ||
783 | if (status & RX_RUNT) | ||
784 | printk("rx runt\n"); | ||
785 | if (status & RX_OVERLEN) | ||
786 | printk("rx overlen\n"); | ||
787 | if (status & RX_COLL) | ||
788 | printk("rx coll\n"); | ||
789 | if (status & RX_MII_ERROR) | ||
790 | printk("rx mii error\n"); | ||
791 | if (status & RX_CRC_ERROR) | ||
792 | printk("rx crc error\n"); | ||
793 | if (status & RX_LEN_ERROR) | ||
794 | printk("rx len error\n"); | ||
795 | if (status & RX_U_CNTRL_FRAME) | ||
796 | printk("rx u control frame\n"); | ||
797 | if (status & RX_MISSED_FRAME) | ||
798 | printk("rx miss\n"); | ||
799 | } | ||
800 | } | ||
801 | prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE); | ||
802 | aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1); | ||
803 | au_sync(); | ||
804 | |||
805 | /* next descriptor */ | ||
806 | prxd = aup->rx_dma_ring[aup->rx_head]; | ||
807 | buff_stat = prxd->buff_stat; | ||
897 | } | 808 | } |
809 | return 0; | ||
810 | } | ||
898 | 811 | ||
899 | if (phydev->link && (aup->old_duplex != phydev->duplex)) { | 812 | static void update_tx_stats(struct net_device *dev, u32 status) |
900 | // duplex mode changed | 813 | { |
814 | struct au1000_private *aup = netdev_priv(dev); | ||
815 | struct net_device_stats *ps = &dev->stats; | ||
901 | 816 | ||
902 | /* switching duplex mode requires to disable rx and tx! */ | 817 | if (status & TX_FRAME_ABORTED) { |
903 | hard_stop(dev); | 818 | if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) { |
819 | if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) { | ||
820 | /* any other tx errors are only valid | ||
821 | * in half duplex mode */ | ||
822 | ps->tx_errors++; | ||
823 | ps->tx_aborted_errors++; | ||
824 | } | ||
825 | } | ||
826 | else { | ||
827 | ps->tx_errors++; | ||
828 | ps->tx_aborted_errors++; | ||
829 | if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER)) | ||
830 | ps->tx_carrier_errors++; | ||
831 | } | ||
832 | } | ||
833 | } | ||
904 | 834 | ||
905 | if (DUPLEX_FULL == phydev->duplex) | 835 | /* |
906 | aup->mac->control = ((aup->mac->control | 836 | * Called from the interrupt service routine to acknowledge |
907 | | MAC_FULL_DUPLEX) | 837 | * the TX DONE bits. This is a must if the irq is setup as |
908 | & ~MAC_DISABLE_RX_OWN); | 838 | * edge triggered. |
909 | else | 839 | */ |
910 | aup->mac->control = ((aup->mac->control | 840 | static void au1000_tx_ack(struct net_device *dev) |
911 | & ~MAC_FULL_DUPLEX) | 841 | { |
912 | | MAC_DISABLE_RX_OWN); | 842 | struct au1000_private *aup = netdev_priv(dev); |
913 | au_sync_delay(1); | 843 | volatile tx_dma_t *ptxd; |
914 | 844 | ||
915 | enable_rx_tx(dev); | 845 | ptxd = aup->tx_dma_ring[aup->tx_tail]; |
916 | aup->old_duplex = phydev->duplex; | ||
917 | 846 | ||
918 | status_change = 1; | 847 | while (ptxd->buff_stat & TX_T_DONE) { |
919 | } | 848 | update_tx_stats(dev, ptxd->status); |
849 | ptxd->buff_stat &= ~TX_T_DONE; | ||
850 | ptxd->len = 0; | ||
851 | au_sync(); | ||
920 | 852 | ||
921 | if(phydev->link != aup->old_link) { | 853 | aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1); |
922 | // link state changed | 854 | ptxd = aup->tx_dma_ring[aup->tx_tail]; |
923 | 855 | ||
924 | if (!phydev->link) { | 856 | if (aup->tx_full) { |
925 | /* link went down */ | 857 | aup->tx_full = 0; |
926 | aup->old_speed = 0; | 858 | netif_wake_queue(dev); |
927 | aup->old_duplex = -1; | ||
928 | } | 859 | } |
929 | |||
930 | aup->old_link = phydev->link; | ||
931 | status_change = 1; | ||
932 | } | 860 | } |
861 | } | ||
933 | 862 | ||
934 | spin_unlock_irqrestore(&aup->lock, flags); | 863 | /* |
864 | * Au1000 interrupt service routine. | ||
865 | */ | ||
866 | static irqreturn_t au1000_interrupt(int irq, void *dev_id) | ||
867 | { | ||
868 | struct net_device *dev = dev_id; | ||
935 | 869 | ||
936 | if (status_change) { | 870 | /* Handle RX interrupts first to minimize chance of overrun */ |
937 | if (phydev->link) | 871 | |
938 | printk(KERN_INFO "%s: link up (%d/%s)\n", | 872 | au1000_rx(dev); |
939 | dev->name, phydev->speed, | 873 | au1000_tx_ack(dev); |
940 | DUPLEX_FULL == phydev->duplex ? "Full" : "Half"); | 874 | return IRQ_RETVAL(1); |
941 | else | ||
942 | printk(KERN_INFO "%s: link down\n", dev->name); | ||
943 | } | ||
944 | } | 875 | } |
945 | 876 | ||
946 | static int au1000_open(struct net_device *dev) | 877 | static int au1000_open(struct net_device *dev) |
@@ -1003,88 +934,6 @@ static int au1000_close(struct net_device *dev) | |||
1003 | return 0; | 934 | return 0; |
1004 | } | 935 | } |
1005 | 936 | ||
1006 | static void __exit au1000_cleanup_module(void) | ||
1007 | { | ||
1008 | int i, j; | ||
1009 | struct net_device *dev; | ||
1010 | struct au1000_private *aup; | ||
1011 | |||
1012 | for (i = 0; i < num_ifs; i++) { | ||
1013 | dev = iflist[i].dev; | ||
1014 | if (dev) { | ||
1015 | aup = netdev_priv(dev); | ||
1016 | unregister_netdev(dev); | ||
1017 | mdiobus_unregister(aup->mii_bus); | ||
1018 | mdiobus_free(aup->mii_bus); | ||
1019 | for (j = 0; j < NUM_RX_DMA; j++) | ||
1020 | if (aup->rx_db_inuse[j]) | ||
1021 | ReleaseDB(aup, aup->rx_db_inuse[j]); | ||
1022 | for (j = 0; j < NUM_TX_DMA; j++) | ||
1023 | if (aup->tx_db_inuse[j]) | ||
1024 | ReleaseDB(aup, aup->tx_db_inuse[j]); | ||
1025 | dma_free_noncoherent(NULL, MAX_BUF_SIZE * | ||
1026 | (NUM_TX_BUFFS + NUM_RX_BUFFS), | ||
1027 | (void *)aup->vaddr, aup->dma_addr); | ||
1028 | release_mem_region(dev->base_addr, MAC_IOSIZE); | ||
1029 | release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4); | ||
1030 | free_netdev(dev); | ||
1031 | } | ||
1032 | } | ||
1033 | } | ||
1034 | |||
1035 | static void update_tx_stats(struct net_device *dev, u32 status) | ||
1036 | { | ||
1037 | struct au1000_private *aup = netdev_priv(dev); | ||
1038 | struct net_device_stats *ps = &dev->stats; | ||
1039 | |||
1040 | if (status & TX_FRAME_ABORTED) { | ||
1041 | if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) { | ||
1042 | if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) { | ||
1043 | /* any other tx errors are only valid | ||
1044 | * in half duplex mode */ | ||
1045 | ps->tx_errors++; | ||
1046 | ps->tx_aborted_errors++; | ||
1047 | } | ||
1048 | } | ||
1049 | else { | ||
1050 | ps->tx_errors++; | ||
1051 | ps->tx_aborted_errors++; | ||
1052 | if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER)) | ||
1053 | ps->tx_carrier_errors++; | ||
1054 | } | ||
1055 | } | ||
1056 | } | ||
1057 | |||
1058 | |||
1059 | /* | ||
1060 | * Called from the interrupt service routine to acknowledge | ||
1061 | * the TX DONE bits. This is a must if the irq is setup as | ||
1062 | * edge triggered. | ||
1063 | */ | ||
1064 | static void au1000_tx_ack(struct net_device *dev) | ||
1065 | { | ||
1066 | struct au1000_private *aup = netdev_priv(dev); | ||
1067 | volatile tx_dma_t *ptxd; | ||
1068 | |||
1069 | ptxd = aup->tx_dma_ring[aup->tx_tail]; | ||
1070 | |||
1071 | while (ptxd->buff_stat & TX_T_DONE) { | ||
1072 | update_tx_stats(dev, ptxd->status); | ||
1073 | ptxd->buff_stat &= ~TX_T_DONE; | ||
1074 | ptxd->len = 0; | ||
1075 | au_sync(); | ||
1076 | |||
1077 | aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1); | ||
1078 | ptxd = aup->tx_dma_ring[aup->tx_tail]; | ||
1079 | |||
1080 | if (aup->tx_full) { | ||
1081 | aup->tx_full = 0; | ||
1082 | netif_wake_queue(dev); | ||
1083 | } | ||
1084 | } | ||
1085 | } | ||
1086 | |||
1087 | |||
1088 | /* | 937 | /* |
1089 | * Au1000 transmit routine. | 938 | * Au1000 transmit routine. |
1090 | */ | 939 | */ |
@@ -1142,123 +991,6 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev) | |||
1142 | return 0; | 991 | return 0; |
1143 | } | 992 | } |
1144 | 993 | ||
1145 | static inline void update_rx_stats(struct net_device *dev, u32 status) | ||
1146 | { | ||
1147 | struct au1000_private *aup = netdev_priv(dev); | ||
1148 | struct net_device_stats *ps = &dev->stats; | ||
1149 | |||
1150 | ps->rx_packets++; | ||
1151 | if (status & RX_MCAST_FRAME) | ||
1152 | ps->multicast++; | ||
1153 | |||
1154 | if (status & RX_ERROR) { | ||
1155 | ps->rx_errors++; | ||
1156 | if (status & RX_MISSED_FRAME) | ||
1157 | ps->rx_missed_errors++; | ||
1158 | if (status & (RX_OVERLEN | RX_OVERLEN | RX_LEN_ERROR)) | ||
1159 | ps->rx_length_errors++; | ||
1160 | if (status & RX_CRC_ERROR) | ||
1161 | ps->rx_crc_errors++; | ||
1162 | if (status & RX_COLL) | ||
1163 | ps->collisions++; | ||
1164 | } | ||
1165 | else | ||
1166 | ps->rx_bytes += status & RX_FRAME_LEN_MASK; | ||
1167 | |||
1168 | } | ||
1169 | |||
1170 | /* | ||
1171 | * Au1000 receive routine. | ||
1172 | */ | ||
1173 | static int au1000_rx(struct net_device *dev) | ||
1174 | { | ||
1175 | struct au1000_private *aup = netdev_priv(dev); | ||
1176 | struct sk_buff *skb; | ||
1177 | volatile rx_dma_t *prxd; | ||
1178 | u32 buff_stat, status; | ||
1179 | db_dest_t *pDB; | ||
1180 | u32 frmlen; | ||
1181 | |||
1182 | if (au1000_debug > 5) | ||
1183 | printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head); | ||
1184 | |||
1185 | prxd = aup->rx_dma_ring[aup->rx_head]; | ||
1186 | buff_stat = prxd->buff_stat; | ||
1187 | while (buff_stat & RX_T_DONE) { | ||
1188 | status = prxd->status; | ||
1189 | pDB = aup->rx_db_inuse[aup->rx_head]; | ||
1190 | update_rx_stats(dev, status); | ||
1191 | if (!(status & RX_ERROR)) { | ||
1192 | |||
1193 | /* good frame */ | ||
1194 | frmlen = (status & RX_FRAME_LEN_MASK); | ||
1195 | frmlen -= 4; /* Remove FCS */ | ||
1196 | skb = dev_alloc_skb(frmlen + 2); | ||
1197 | if (skb == NULL) { | ||
1198 | printk(KERN_ERR | ||
1199 | "%s: Memory squeeze, dropping packet.\n", | ||
1200 | dev->name); | ||
1201 | dev->stats.rx_dropped++; | ||
1202 | continue; | ||
1203 | } | ||
1204 | skb_reserve(skb, 2); /* 16 byte IP header align */ | ||
1205 | skb_copy_to_linear_data(skb, | ||
1206 | (unsigned char *)pDB->vaddr, frmlen); | ||
1207 | skb_put(skb, frmlen); | ||
1208 | skb->protocol = eth_type_trans(skb, dev); | ||
1209 | netif_rx(skb); /* pass the packet to upper layers */ | ||
1210 | } | ||
1211 | else { | ||
1212 | if (au1000_debug > 4) { | ||
1213 | if (status & RX_MISSED_FRAME) | ||
1214 | printk("rx miss\n"); | ||
1215 | if (status & RX_WDOG_TIMER) | ||
1216 | printk("rx wdog\n"); | ||
1217 | if (status & RX_RUNT) | ||
1218 | printk("rx runt\n"); | ||
1219 | if (status & RX_OVERLEN) | ||
1220 | printk("rx overlen\n"); | ||
1221 | if (status & RX_COLL) | ||
1222 | printk("rx coll\n"); | ||
1223 | if (status & RX_MII_ERROR) | ||
1224 | printk("rx mii error\n"); | ||
1225 | if (status & RX_CRC_ERROR) | ||
1226 | printk("rx crc error\n"); | ||
1227 | if (status & RX_LEN_ERROR) | ||
1228 | printk("rx len error\n"); | ||
1229 | if (status & RX_U_CNTRL_FRAME) | ||
1230 | printk("rx u control frame\n"); | ||
1231 | if (status & RX_MISSED_FRAME) | ||
1232 | printk("rx miss\n"); | ||
1233 | } | ||
1234 | } | ||
1235 | prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE); | ||
1236 | aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1); | ||
1237 | au_sync(); | ||
1238 | |||
1239 | /* next descriptor */ | ||
1240 | prxd = aup->rx_dma_ring[aup->rx_head]; | ||
1241 | buff_stat = prxd->buff_stat; | ||
1242 | } | ||
1243 | return 0; | ||
1244 | } | ||
1245 | |||
1246 | |||
1247 | /* | ||
1248 | * Au1000 interrupt service routine. | ||
1249 | */ | ||
1250 | static irqreturn_t au1000_interrupt(int irq, void *dev_id) | ||
1251 | { | ||
1252 | struct net_device *dev = dev_id; | ||
1253 | |||
1254 | /* Handle RX interrupts first to minimize chance of overrun */ | ||
1255 | |||
1256 | au1000_rx(dev); | ||
1257 | au1000_tx_ack(dev); | ||
1258 | return IRQ_RETVAL(1); | ||
1259 | } | ||
1260 | |||
1261 | |||
1262 | /* | 994 | /* |
1263 | * The Tx ring has been full longer than the watchdog timeout | 995 | * The Tx ring has been full longer than the watchdog timeout |
1264 | * value. The transmitter must be hung? | 996 | * value. The transmitter must be hung? |
@@ -1315,5 +1047,252 @@ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
1315 | return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd); | 1047 | return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd); |
1316 | } | 1048 | } |
1317 | 1049 | ||
1050 | static struct net_device * au1000_probe(int port_num) | ||
1051 | { | ||
1052 | static unsigned version_printed = 0; | ||
1053 | struct au1000_private *aup = NULL; | ||
1054 | struct net_device *dev = NULL; | ||
1055 | db_dest_t *pDB, *pDBfree; | ||
1056 | char ethaddr[6]; | ||
1057 | int irq, i, err; | ||
1058 | u32 base, macen; | ||
1059 | |||
1060 | if (port_num >= NUM_ETH_INTERFACES) | ||
1061 | return NULL; | ||
1062 | |||
1063 | base = CPHYSADDR(iflist[port_num].base_addr ); | ||
1064 | macen = CPHYSADDR(iflist[port_num].macen_addr); | ||
1065 | irq = iflist[port_num].irq; | ||
1066 | |||
1067 | if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") || | ||
1068 | !request_mem_region(macen, 4, "Au1x00 ENET")) | ||
1069 | return NULL; | ||
1070 | |||
1071 | if (version_printed++ == 0) | ||
1072 | printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR); | ||
1073 | |||
1074 | dev = alloc_etherdev(sizeof(struct au1000_private)); | ||
1075 | if (!dev) { | ||
1076 | printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME); | ||
1077 | return NULL; | ||
1078 | } | ||
1079 | |||
1080 | if ((err = register_netdev(dev)) != 0) { | ||
1081 | printk(KERN_ERR "%s: Cannot register net device, error %d\n", | ||
1082 | DRV_NAME, err); | ||
1083 | free_netdev(dev); | ||
1084 | return NULL; | ||
1085 | } | ||
1086 | |||
1087 | printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n", | ||
1088 | dev->name, base, irq); | ||
1089 | |||
1090 | aup = netdev_priv(dev); | ||
1091 | |||
1092 | spin_lock_init(&aup->lock); | ||
1093 | |||
1094 | /* Allocate the data buffers */ | ||
1095 | /* Snooping works fine with eth on all au1xxx */ | ||
1096 | aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE * | ||
1097 | (NUM_TX_BUFFS + NUM_RX_BUFFS), | ||
1098 | &aup->dma_addr, 0); | ||
1099 | if (!aup->vaddr) { | ||
1100 | free_netdev(dev); | ||
1101 | release_mem_region( base, MAC_IOSIZE); | ||
1102 | release_mem_region(macen, 4); | ||
1103 | return NULL; | ||
1104 | } | ||
1105 | |||
1106 | /* aup->mac is the base address of the MAC's registers */ | ||
1107 | aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr; | ||
1108 | |||
1109 | /* Setup some variables for quick register address access */ | ||
1110 | aup->enable = (volatile u32 *)iflist[port_num].macen_addr; | ||
1111 | aup->mac_id = port_num; | ||
1112 | au_macs[port_num] = aup; | ||
1113 | |||
1114 | if (port_num == 0) { | ||
1115 | if (prom_get_ethernet_addr(ethaddr) == 0) | ||
1116 | memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr)); | ||
1117 | else { | ||
1118 | printk(KERN_INFO "%s: No MAC address found\n", | ||
1119 | dev->name); | ||
1120 | /* Use the hard coded MAC addresses */ | ||
1121 | } | ||
1122 | |||
1123 | setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); | ||
1124 | } else if (port_num == 1) | ||
1125 | setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR); | ||
1126 | |||
1127 | /* | ||
1128 | * Assign to the Ethernet ports two consecutive MAC addresses | ||
1129 | * to match those that are printed on their stickers | ||
1130 | */ | ||
1131 | memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); | ||
1132 | dev->dev_addr[5] += port_num; | ||
1133 | |||
1134 | *aup->enable = 0; | ||
1135 | aup->mac_enabled = 0; | ||
1136 | |||
1137 | aup->mii_bus = mdiobus_alloc(); | ||
1138 | if (aup->mii_bus == NULL) | ||
1139 | goto err_out; | ||
1140 | |||
1141 | aup->mii_bus->priv = dev; | ||
1142 | aup->mii_bus->read = au1000_mdiobus_read; | ||
1143 | aup->mii_bus->write = au1000_mdiobus_write; | ||
1144 | aup->mii_bus->reset = au1000_mdiobus_reset; | ||
1145 | aup->mii_bus->name = "au1000_eth_mii"; | ||
1146 | snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%x", aup->mac_id); | ||
1147 | aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); | ||
1148 | for(i = 0; i < PHY_MAX_ADDR; ++i) | ||
1149 | aup->mii_bus->irq[i] = PHY_POLL; | ||
1150 | |||
1151 | /* if known, set corresponding PHY IRQs */ | ||
1152 | #if defined(AU1XXX_PHY_STATIC_CONFIG) | ||
1153 | # if defined(AU1XXX_PHY0_IRQ) | ||
1154 | if (AU1XXX_PHY0_BUSID == aup->mac_id) | ||
1155 | aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ; | ||
1156 | # endif | ||
1157 | # if defined(AU1XXX_PHY1_IRQ) | ||
1158 | if (AU1XXX_PHY1_BUSID == aup->mac_id) | ||
1159 | aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ; | ||
1160 | # endif | ||
1161 | #endif | ||
1162 | mdiobus_register(aup->mii_bus); | ||
1163 | |||
1164 | if (mii_probe(dev) != 0) { | ||
1165 | goto err_out; | ||
1166 | } | ||
1167 | |||
1168 | pDBfree = NULL; | ||
1169 | /* setup the data buffer descriptors and attach a buffer to each one */ | ||
1170 | pDB = aup->db; | ||
1171 | for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) { | ||
1172 | pDB->pnext = pDBfree; | ||
1173 | pDBfree = pDB; | ||
1174 | pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i); | ||
1175 | pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr); | ||
1176 | pDB++; | ||
1177 | } | ||
1178 | aup->pDBfree = pDBfree; | ||
1179 | |||
1180 | for (i = 0; i < NUM_RX_DMA; i++) { | ||
1181 | pDB = GetFreeDB(aup); | ||
1182 | if (!pDB) { | ||
1183 | goto err_out; | ||
1184 | } | ||
1185 | aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; | ||
1186 | aup->rx_db_inuse[i] = pDB; | ||
1187 | } | ||
1188 | for (i = 0; i < NUM_TX_DMA; i++) { | ||
1189 | pDB = GetFreeDB(aup); | ||
1190 | if (!pDB) { | ||
1191 | goto err_out; | ||
1192 | } | ||
1193 | aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; | ||
1194 | aup->tx_dma_ring[i]->len = 0; | ||
1195 | aup->tx_db_inuse[i] = pDB; | ||
1196 | } | ||
1197 | |||
1198 | dev->base_addr = base; | ||
1199 | dev->irq = irq; | ||
1200 | dev->open = au1000_open; | ||
1201 | dev->hard_start_xmit = au1000_tx; | ||
1202 | dev->stop = au1000_close; | ||
1203 | dev->set_multicast_list = &set_rx_mode; | ||
1204 | dev->do_ioctl = &au1000_ioctl; | ||
1205 | SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); | ||
1206 | dev->tx_timeout = au1000_tx_timeout; | ||
1207 | dev->watchdog_timeo = ETH_TX_TIMEOUT; | ||
1208 | |||
1209 | /* | ||
1210 | * The boot code uses the ethernet controller, so reset it to start | ||
1211 | * fresh. au1000_init() expects that the device is in reset state. | ||
1212 | */ | ||
1213 | reset_mac(dev); | ||
1214 | |||
1215 | return dev; | ||
1216 | |||
1217 | err_out: | ||
1218 | if (aup->mii_bus != NULL) { | ||
1219 | mdiobus_unregister(aup->mii_bus); | ||
1220 | mdiobus_free(aup->mii_bus); | ||
1221 | } | ||
1222 | |||
1223 | /* here we should have a valid dev plus aup-> register addresses | ||
1224 | * so we can reset the mac properly.*/ | ||
1225 | reset_mac(dev); | ||
1226 | |||
1227 | for (i = 0; i < NUM_RX_DMA; i++) { | ||
1228 | if (aup->rx_db_inuse[i]) | ||
1229 | ReleaseDB(aup, aup->rx_db_inuse[i]); | ||
1230 | } | ||
1231 | for (i = 0; i < NUM_TX_DMA; i++) { | ||
1232 | if (aup->tx_db_inuse[i]) | ||
1233 | ReleaseDB(aup, aup->tx_db_inuse[i]); | ||
1234 | } | ||
1235 | dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS), | ||
1236 | (void *)aup->vaddr, aup->dma_addr); | ||
1237 | unregister_netdev(dev); | ||
1238 | free_netdev(dev); | ||
1239 | release_mem_region( base, MAC_IOSIZE); | ||
1240 | release_mem_region(macen, 4); | ||
1241 | return NULL; | ||
1242 | } | ||
1243 | |||
1244 | /* | ||
1245 | * Setup the base address and interrupt of the Au1xxx ethernet macs | ||
1246 | * based on cpu type and whether the interface is enabled in sys_pinfunc | ||
1247 | * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0. | ||
1248 | */ | ||
1249 | static int __init au1000_init_module(void) | ||
1250 | { | ||
1251 | int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4); | ||
1252 | struct net_device *dev; | ||
1253 | int i, found_one = 0; | ||
1254 | |||
1255 | num_ifs = NUM_ETH_INTERFACES - ni; | ||
1256 | |||
1257 | for(i = 0; i < num_ifs; i++) { | ||
1258 | dev = au1000_probe(i); | ||
1259 | iflist[i].dev = dev; | ||
1260 | if (dev) | ||
1261 | found_one++; | ||
1262 | } | ||
1263 | if (!found_one) | ||
1264 | return -ENODEV; | ||
1265 | return 0; | ||
1266 | } | ||
1267 | |||
1268 | static void __exit au1000_cleanup_module(void) | ||
1269 | { | ||
1270 | int i, j; | ||
1271 | struct net_device *dev; | ||
1272 | struct au1000_private *aup; | ||
1273 | |||
1274 | for (i = 0; i < num_ifs; i++) { | ||
1275 | dev = iflist[i].dev; | ||
1276 | if (dev) { | ||
1277 | aup = netdev_priv(dev); | ||
1278 | unregister_netdev(dev); | ||
1279 | mdiobus_unregister(aup->mii_bus); | ||
1280 | mdiobus_free(aup->mii_bus); | ||
1281 | for (j = 0; j < NUM_RX_DMA; j++) | ||
1282 | if (aup->rx_db_inuse[j]) | ||
1283 | ReleaseDB(aup, aup->rx_db_inuse[j]); | ||
1284 | for (j = 0; j < NUM_TX_DMA; j++) | ||
1285 | if (aup->tx_db_inuse[j]) | ||
1286 | ReleaseDB(aup, aup->tx_db_inuse[j]); | ||
1287 | dma_free_noncoherent(NULL, MAX_BUF_SIZE * | ||
1288 | (NUM_TX_BUFFS + NUM_RX_BUFFS), | ||
1289 | (void *)aup->vaddr, aup->dma_addr); | ||
1290 | release_mem_region(dev->base_addr, MAC_IOSIZE); | ||
1291 | release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4); | ||
1292 | free_netdev(dev); | ||
1293 | } | ||
1294 | } | ||
1295 | } | ||
1296 | |||
1318 | module_init(au1000_init_module); | 1297 | module_init(au1000_init_module); |
1319 | module_exit(au1000_cleanup_module); | 1298 | module_exit(au1000_cleanup_module); |