diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2008-04-11 11:47:46 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-16 20:06:50 -0400 |
commit | c6686fe3e4c4e8e5104bbec254a5874779eed2bc (patch) | |
tree | 92b38869244d58e459011dd5e2af6214b040a76e /drivers/net/tc35815.c | |
parent | 22adf7e536df12b1793448972c908cb21ea5a17a (diff) |
tc35815: Use generic PHY layer
Convert the tc35815 driver to use the generic PHY layer in
drivers/net/phy. Also rename 'boardtype' to 'chiptype' which hould be
more appropriate.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/tc35815.c')
-rw-r--r-- | drivers/net/tc35815.c | 1052 |
1 files changed, 301 insertions, 751 deletions
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index 60eff784d5e4..59f783eb98b9 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c | |||
@@ -23,9 +23,9 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #ifdef TC35815_NAPI | 25 | #ifdef TC35815_NAPI |
26 | #define DRV_VERSION "1.36-NAPI" | 26 | #define DRV_VERSION "1.37-NAPI" |
27 | #else | 27 | #else |
28 | #define DRV_VERSION "1.36" | 28 | #define DRV_VERSION "1.37" |
29 | #endif | 29 | #endif |
30 | static const char *version = "tc35815.c:v" DRV_VERSION "\n"; | 30 | static const char *version = "tc35815.c:v" DRV_VERSION "\n"; |
31 | #define MODNAME "tc35815" | 31 | #define MODNAME "tc35815" |
@@ -47,8 +47,8 @@ static const char *version = "tc35815.c:v" DRV_VERSION "\n"; | |||
47 | #include <linux/skbuff.h> | 47 | #include <linux/skbuff.h> |
48 | #include <linux/delay.h> | 48 | #include <linux/delay.h> |
49 | #include <linux/pci.h> | 49 | #include <linux/pci.h> |
50 | #include <linux/mii.h> | 50 | #include <linux/phy.h> |
51 | #include <linux/ethtool.h> | 51 | #include <linux/workqueue.h> |
52 | #include <linux/platform_device.h> | 52 | #include <linux/platform_device.h> |
53 | #include <asm/io.h> | 53 | #include <asm/io.h> |
54 | #include <asm/byteorder.h> | 54 | #include <asm/byteorder.h> |
@@ -60,16 +60,16 @@ static const char *version = "tc35815.c:v" DRV_VERSION "\n"; | |||
60 | #define WORKAROUND_100HALF_PROMISC | 60 | #define WORKAROUND_100HALF_PROMISC |
61 | /* #define TC35815_USE_PACKEDBUFFER */ | 61 | /* #define TC35815_USE_PACKEDBUFFER */ |
62 | 62 | ||
63 | typedef enum { | 63 | enum tc35815_chiptype { |
64 | TC35815CF = 0, | 64 | TC35815CF = 0, |
65 | TC35815_NWU, | 65 | TC35815_NWU, |
66 | TC35815_TX4939, | 66 | TC35815_TX4939, |
67 | } board_t; | 67 | }; |
68 | 68 | ||
69 | /* indexed by board_t, above */ | 69 | /* indexed by tc35815_chiptype, above */ |
70 | static const struct { | 70 | static const struct { |
71 | const char *name; | 71 | const char *name; |
72 | } board_info[] __devinitdata = { | 72 | } chip_info[] __devinitdata = { |
73 | { "TOSHIBA TC35815CF 10/100BaseTX" }, | 73 | { "TOSHIBA TC35815CF 10/100BaseTX" }, |
74 | { "TOSHIBA TC35815 with Wake on LAN" }, | 74 | { "TOSHIBA TC35815 with Wake on LAN" }, |
75 | { "TOSHIBA TC35815/TX4939" }, | 75 | { "TOSHIBA TC35815/TX4939" }, |
@@ -87,7 +87,6 @@ MODULE_DEVICE_TABLE (pci, tc35815_pci_tbl); | |||
87 | static struct tc35815_options { | 87 | static struct tc35815_options { |
88 | int speed; | 88 | int speed; |
89 | int duplex; | 89 | int duplex; |
90 | int doforce; | ||
91 | } options; | 90 | } options; |
92 | 91 | ||
93 | /* | 92 | /* |
@@ -348,7 +347,7 @@ struct BDesc { | |||
348 | Int_STargAbtEn | \ | 347 | Int_STargAbtEn | \ |
349 | Int_BLExEn | Int_FDAExEn) /* maybe 0xb7f*/ | 348 | Int_BLExEn | Int_FDAExEn) /* maybe 0xb7f*/ |
350 | #define DMA_CTL_CMD DMA_BURST_SIZE | 349 | #define DMA_CTL_CMD DMA_BURST_SIZE |
351 | #define HAVE_DMA_RXALIGN(lp) likely((lp)->boardtype != TC35815CF) | 350 | #define HAVE_DMA_RXALIGN(lp) likely((lp)->chiptype != TC35815CF) |
352 | 351 | ||
353 | /* Tuning parameters */ | 352 | /* Tuning parameters */ |
354 | #define DMA_BURST_SIZE 32 | 353 | #define DMA_BURST_SIZE 32 |
@@ -401,16 +400,7 @@ struct FrFD { | |||
401 | 400 | ||
402 | #define TC35815_TX_TIMEOUT msecs_to_jiffies(400) | 401 | #define TC35815_TX_TIMEOUT msecs_to_jiffies(400) |
403 | 402 | ||
404 | /* Timer state engine. */ | 403 | /* Information that need to be kept for each controller. */ |
405 | enum tc35815_timer_state { | ||
406 | arbwait = 0, /* Waiting for auto negotiation to complete. */ | ||
407 | lupwait = 1, /* Auto-neg complete, awaiting link-up status. */ | ||
408 | ltrywait = 2, /* Forcing try of all modes, from fastest to slowest. */ | ||
409 | asleep = 3, /* Time inactive. */ | ||
410 | lcheck = 4, /* Check link status. */ | ||
411 | }; | ||
412 | |||
413 | /* Information that need to be kept for each board. */ | ||
414 | struct tc35815_local { | 404 | struct tc35815_local { |
415 | struct pci_dev *pci_dev; | 405 | struct pci_dev *pci_dev; |
416 | 406 | ||
@@ -432,12 +422,12 @@ struct tc35815_local { | |||
432 | */ | 422 | */ |
433 | spinlock_t lock; | 423 | spinlock_t lock; |
434 | 424 | ||
435 | int phy_addr; | 425 | struct mii_bus mii_bus; |
436 | int fullduplex; | 426 | struct phy_device *phy_dev; |
437 | unsigned short saved_lpa; | 427 | int duplex; |
438 | struct timer_list timer; | 428 | int speed; |
439 | enum tc35815_timer_state timer_state; /* State of auto-neg timer. */ | 429 | int link; |
440 | unsigned int timer_ticks; /* Number of clicks at each state */ | 430 | struct work_struct restart_work; |
441 | 431 | ||
442 | /* | 432 | /* |
443 | * Transmitting: Batch Mode. | 433 | * Transmitting: Batch Mode. |
@@ -475,10 +465,8 @@ struct tc35815_local { | |||
475 | dma_addr_t skb_dma; | 465 | dma_addr_t skb_dma; |
476 | } tx_skbs[TX_FD_NUM], rx_skbs[RX_BUF_NUM]; | 466 | } tx_skbs[TX_FD_NUM], rx_skbs[RX_BUF_NUM]; |
477 | #endif | 467 | #endif |
478 | struct mii_if_info mii; | ||
479 | unsigned short mii_id[2]; | ||
480 | u32 msg_enable; | 468 | u32 msg_enable; |
481 | board_t boardtype; | 469 | enum tc35815_chiptype chiptype; |
482 | }; | 470 | }; |
483 | 471 | ||
484 | static inline dma_addr_t fd_virt_to_bus(struct tc35815_local *lp, void *virt) | 472 | static inline dma_addr_t fd_virt_to_bus(struct tc35815_local *lp, void *virt) |
@@ -586,19 +574,222 @@ static const struct ethtool_ops tc35815_ethtool_ops; | |||
586 | /* Example routines you must write ;->. */ | 574 | /* Example routines you must write ;->. */ |
587 | static void tc35815_chip_reset(struct net_device *dev); | 575 | static void tc35815_chip_reset(struct net_device *dev); |
588 | static void tc35815_chip_init(struct net_device *dev); | 576 | static void tc35815_chip_init(struct net_device *dev); |
589 | static void tc35815_find_phy(struct net_device *dev); | ||
590 | static void tc35815_phy_chip_init(struct net_device *dev); | ||
591 | 577 | ||
592 | #ifdef DEBUG | 578 | #ifdef DEBUG |
593 | static void panic_queues(struct net_device *dev); | 579 | static void panic_queues(struct net_device *dev); |
594 | #endif | 580 | #endif |
595 | 581 | ||
596 | static void tc35815_timer(unsigned long data); | 582 | static void tc35815_restart_work(struct work_struct *work); |
597 | static void tc35815_start_auto_negotiation(struct net_device *dev, | 583 | |
598 | struct ethtool_cmd *ep); | 584 | static int tc_mdio_read(struct mii_bus *bus, int mii_id, int regnum) |
599 | static int tc_mdio_read(struct net_device *dev, int phy_id, int location); | 585 | { |
600 | static void tc_mdio_write(struct net_device *dev, int phy_id, int location, | 586 | struct net_device *dev = bus->priv; |
601 | int val); | 587 | struct tc35815_regs __iomem *tr = |
588 | (struct tc35815_regs __iomem *)dev->base_addr; | ||
589 | unsigned long timeout = jiffies + 10; | ||
590 | |||
591 | tc_writel(MD_CA_Busy | (mii_id << 5) | (regnum & 0x1f), &tr->MD_CA); | ||
592 | while (tc_readl(&tr->MD_CA) & MD_CA_Busy) { | ||
593 | if (time_after(jiffies, timeout)) | ||
594 | return -EIO; | ||
595 | cpu_relax(); | ||
596 | } | ||
597 | return tc_readl(&tr->MD_Data) & 0xffff; | ||
598 | } | ||
599 | |||
600 | static int tc_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 val) | ||
601 | { | ||
602 | struct net_device *dev = bus->priv; | ||
603 | struct tc35815_regs __iomem *tr = | ||
604 | (struct tc35815_regs __iomem *)dev->base_addr; | ||
605 | unsigned long timeout = jiffies + 10; | ||
606 | |||
607 | tc_writel(val, &tr->MD_Data); | ||
608 | tc_writel(MD_CA_Busy | MD_CA_Wr | (mii_id << 5) | (regnum & 0x1f), | ||
609 | &tr->MD_CA); | ||
610 | while (tc_readl(&tr->MD_CA) & MD_CA_Busy) { | ||
611 | if (time_after(jiffies, timeout)) | ||
612 | return -EIO; | ||
613 | cpu_relax(); | ||
614 | } | ||
615 | return 0; | ||
616 | } | ||
617 | |||
618 | static void tc_handle_link_change(struct net_device *dev) | ||
619 | { | ||
620 | struct tc35815_local *lp = netdev_priv(dev); | ||
621 | struct phy_device *phydev = lp->phy_dev; | ||
622 | unsigned long flags; | ||
623 | int status_change = 0; | ||
624 | |||
625 | spin_lock_irqsave(&lp->lock, flags); | ||
626 | if (phydev->link && | ||
627 | (lp->speed != phydev->speed || lp->duplex != phydev->duplex)) { | ||
628 | struct tc35815_regs __iomem *tr = | ||
629 | (struct tc35815_regs __iomem *)dev->base_addr; | ||
630 | u32 reg; | ||
631 | |||
632 | reg = tc_readl(&tr->MAC_Ctl); | ||
633 | reg |= MAC_HaltReq; | ||
634 | tc_writel(reg, &tr->MAC_Ctl); | ||
635 | if (phydev->duplex == DUPLEX_FULL) | ||
636 | reg |= MAC_FullDup; | ||
637 | else | ||
638 | reg &= ~MAC_FullDup; | ||
639 | tc_writel(reg, &tr->MAC_Ctl); | ||
640 | reg &= ~MAC_HaltReq; | ||
641 | tc_writel(reg, &tr->MAC_Ctl); | ||
642 | |||
643 | /* | ||
644 | * TX4939 PCFG.SPEEDn bit will be changed on | ||
645 | * NETDEV_CHANGE event. | ||
646 | */ | ||
647 | |||
648 | #if !defined(NO_CHECK_CARRIER) && defined(WORKAROUND_LOSTCAR) | ||
649 | /* | ||
650 | * WORKAROUND: enable LostCrS only if half duplex | ||
651 | * operation. | ||
652 | * (TX4939 does not have EnLCarr) | ||
653 | */ | ||
654 | if (phydev->duplex == DUPLEX_HALF && | ||
655 | lp->chiptype != TC35815_TX4939) | ||
656 | tc_writel(tc_readl(&tr->Tx_Ctl) | Tx_EnLCarr, | ||
657 | &tr->Tx_Ctl); | ||
658 | #endif | ||
659 | |||
660 | lp->speed = phydev->speed; | ||
661 | lp->duplex = phydev->duplex; | ||
662 | status_change = 1; | ||
663 | } | ||
664 | |||
665 | if (phydev->link != lp->link) { | ||
666 | if (phydev->link) { | ||
667 | #ifdef WORKAROUND_100HALF_PROMISC | ||
668 | /* delayed promiscuous enabling */ | ||
669 | if (dev->flags & IFF_PROMISC) | ||
670 | tc35815_set_multicast_list(dev); | ||
671 | #endif | ||
672 | netif_schedule(dev); | ||
673 | } else { | ||
674 | lp->speed = 0; | ||
675 | lp->duplex = -1; | ||
676 | } | ||
677 | lp->link = phydev->link; | ||
678 | |||
679 | status_change = 1; | ||
680 | } | ||
681 | spin_unlock_irqrestore(&lp->lock, flags); | ||
682 | |||
683 | if (status_change && netif_msg_link(lp)) { | ||
684 | phy_print_status(phydev); | ||
685 | #ifdef DEBUG | ||
686 | printk(KERN_DEBUG | ||
687 | "%s: MII BMCR %04x BMSR %04x LPA %04x\n", | ||
688 | dev->name, | ||
689 | phy_read(phydev, MII_BMCR), | ||
690 | phy_read(phydev, MII_BMSR), | ||
691 | phy_read(phydev, MII_LPA)); | ||
692 | #endif | ||
693 | } | ||
694 | } | ||
695 | |||
696 | static int tc_mii_probe(struct net_device *dev) | ||
697 | { | ||
698 | struct tc35815_local *lp = netdev_priv(dev); | ||
699 | struct phy_device *phydev = NULL; | ||
700 | int phy_addr; | ||
701 | u32 dropmask; | ||
702 | |||
703 | /* find the first phy */ | ||
704 | for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { | ||
705 | if (lp->mii_bus.phy_map[phy_addr]) { | ||
706 | if (phydev) { | ||
707 | printk(KERN_ERR "%s: multiple PHYs found\n", | ||
708 | dev->name); | ||
709 | return -EINVAL; | ||
710 | } | ||
711 | phydev = lp->mii_bus.phy_map[phy_addr]; | ||
712 | break; | ||
713 | } | ||
714 | } | ||
715 | |||
716 | if (!phydev) { | ||
717 | printk(KERN_ERR "%s: no PHY found\n", dev->name); | ||
718 | return -ENODEV; | ||
719 | } | ||
720 | |||
721 | /* attach the mac to the phy */ | ||
722 | phydev = phy_connect(dev, phydev->dev.bus_id, | ||
723 | &tc_handle_link_change, 0, | ||
724 | lp->chiptype == TC35815_TX4939 ? | ||
725 | PHY_INTERFACE_MODE_RMII : PHY_INTERFACE_MODE_MII); | ||
726 | if (IS_ERR(phydev)) { | ||
727 | printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); | ||
728 | return PTR_ERR(phydev); | ||
729 | } | ||
730 | printk(KERN_INFO "%s: attached PHY driver [%s] " | ||
731 | "(mii_bus:phy_addr=%s, id=%x)\n", | ||
732 | dev->name, phydev->drv->name, phydev->dev.bus_id, | ||
733 | phydev->phy_id); | ||
734 | |||
735 | /* mask with MAC supported features */ | ||
736 | phydev->supported &= PHY_BASIC_FEATURES; | ||
737 | dropmask = 0; | ||
738 | if (options.speed == 10) | ||
739 | dropmask |= SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; | ||
740 | else if (options.speed == 100) | ||
741 | dropmask |= SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full; | ||
742 | if (options.duplex == 1) | ||
743 | dropmask |= SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full; | ||
744 | else if (options.duplex == 2) | ||
745 | dropmask |= SUPPORTED_10baseT_Half | SUPPORTED_100baseT_Half; | ||
746 | phydev->supported &= ~dropmask; | ||
747 | phydev->advertising = phydev->supported; | ||
748 | |||
749 | lp->link = 0; | ||
750 | lp->speed = 0; | ||
751 | lp->duplex = -1; | ||
752 | lp->phy_dev = phydev; | ||
753 | |||
754 | return 0; | ||
755 | } | ||
756 | |||
757 | static int tc_mii_init(struct net_device *dev) | ||
758 | { | ||
759 | struct tc35815_local *lp = netdev_priv(dev); | ||
760 | int err; | ||
761 | int i; | ||
762 | |||
763 | lp->mii_bus.name = "tc35815_mii_bus"; | ||
764 | lp->mii_bus.read = tc_mdio_read; | ||
765 | lp->mii_bus.write = tc_mdio_write; | ||
766 | lp->mii_bus.id = (lp->pci_dev->bus->number << 8) | lp->pci_dev->devfn; | ||
767 | lp->mii_bus.priv = dev; | ||
768 | lp->mii_bus.dev = &lp->pci_dev->dev; | ||
769 | lp->mii_bus.irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); | ||
770 | if (!lp->mii_bus.irq) { | ||
771 | err = -ENOMEM; | ||
772 | goto err_out; | ||
773 | } | ||
774 | |||
775 | for (i = 0; i < PHY_MAX_ADDR; i++) | ||
776 | lp->mii_bus.irq[i] = PHY_POLL; | ||
777 | |||
778 | err = mdiobus_register(&lp->mii_bus); | ||
779 | if (err) | ||
780 | goto err_out_free_mdio_irq; | ||
781 | err = tc_mii_probe(dev); | ||
782 | if (err) | ||
783 | goto err_out_unregister_bus; | ||
784 | return 0; | ||
785 | |||
786 | err_out_unregister_bus: | ||
787 | mdiobus_unregister(&lp->mii_bus); | ||
788 | err_out_free_mdio_irq: | ||
789 | kfree(lp->mii_bus.irq); | ||
790 | err_out: | ||
791 | return err; | ||
792 | } | ||
602 | 793 | ||
603 | #ifdef CONFIG_CPU_TX49XX | 794 | #ifdef CONFIG_CPU_TX49XX |
604 | /* | 795 | /* |
@@ -669,8 +860,8 @@ static int __devinit tc35815_init_one (struct pci_dev *pdev, | |||
669 | if (!printed_version++) { | 860 | if (!printed_version++) { |
670 | printk(version); | 861 | printk(version); |
671 | dev_printk(KERN_DEBUG, &pdev->dev, | 862 | dev_printk(KERN_DEBUG, &pdev->dev, |
672 | "speed:%d duplex:%d doforce:%d\n", | 863 | "speed:%d duplex:%d\n", |
673 | options.speed, options.duplex, options.doforce); | 864 | options.speed, options.duplex); |
674 | } | 865 | } |
675 | 866 | ||
676 | if (!pdev->irq) { | 867 | if (!pdev->irq) { |
@@ -718,9 +909,10 @@ static int __devinit tc35815_init_one (struct pci_dev *pdev, | |||
718 | dev->irq = pdev->irq; | 909 | dev->irq = pdev->irq; |
719 | dev->base_addr = (unsigned long) ioaddr; | 910 | dev->base_addr = (unsigned long) ioaddr; |
720 | 911 | ||
912 | INIT_WORK(&lp->restart_work, tc35815_restart_work); | ||
721 | spin_lock_init(&lp->lock); | 913 | spin_lock_init(&lp->lock); |
722 | lp->pci_dev = pdev; | 914 | lp->pci_dev = pdev; |
723 | lp->boardtype = ent->driver_data; | 915 | lp->chiptype = ent->driver_data; |
724 | 916 | ||
725 | lp->msg_enable = NETIF_MSG_TX_ERR | NETIF_MSG_HW | NETIF_MSG_DRV | NETIF_MSG_LINK; | 917 | lp->msg_enable = NETIF_MSG_TX_ERR | NETIF_MSG_HW | NETIF_MSG_DRV | NETIF_MSG_LINK; |
726 | pci_set_drvdata(pdev, dev); | 918 | pci_set_drvdata(pdev, dev); |
@@ -741,24 +933,19 @@ static int __devinit tc35815_init_one (struct pci_dev *pdev, | |||
741 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | 933 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); |
742 | printk(KERN_INFO "%s: %s at 0x%lx, %s, IRQ %d\n", | 934 | printk(KERN_INFO "%s: %s at 0x%lx, %s, IRQ %d\n", |
743 | dev->name, | 935 | dev->name, |
744 | board_info[ent->driver_data].name, | 936 | chip_info[ent->driver_data].name, |
745 | dev->base_addr, | 937 | dev->base_addr, |
746 | print_mac(mac, dev->dev_addr), | 938 | print_mac(mac, dev->dev_addr), |
747 | dev->irq); | 939 | dev->irq); |
748 | 940 | ||
749 | setup_timer(&lp->timer, tc35815_timer, (unsigned long) dev); | 941 | rc = tc_mii_init(dev); |
750 | lp->mii.dev = dev; | 942 | if (rc) |
751 | lp->mii.mdio_read = tc_mdio_read; | 943 | goto err_out_unregister; |
752 | lp->mii.mdio_write = tc_mdio_write; | ||
753 | lp->mii.phy_id_mask = 0x1f; | ||
754 | lp->mii.reg_num_mask = 0x1f; | ||
755 | tc35815_find_phy(dev); | ||
756 | lp->mii.phy_id = lp->phy_addr; | ||
757 | lp->mii.full_duplex = 0; | ||
758 | lp->mii.force_media = 0; | ||
759 | 944 | ||
760 | return 0; | 945 | return 0; |
761 | 946 | ||
947 | err_out_unregister: | ||
948 | unregister_netdev(dev); | ||
762 | err_out: | 949 | err_out: |
763 | free_netdev (dev); | 950 | free_netdev (dev); |
764 | return rc; | 951 | return rc; |
@@ -768,7 +955,11 @@ err_out: | |||
768 | static void __devexit tc35815_remove_one (struct pci_dev *pdev) | 955 | static void __devexit tc35815_remove_one (struct pci_dev *pdev) |
769 | { | 956 | { |
770 | struct net_device *dev = pci_get_drvdata (pdev); | 957 | struct net_device *dev = pci_get_drvdata (pdev); |
958 | struct tc35815_local *lp = netdev_priv(dev); | ||
771 | 959 | ||
960 | phy_disconnect(lp->phy_dev); | ||
961 | mdiobus_unregister(&lp->mii_bus); | ||
962 | kfree(lp->mii_bus.irq); | ||
772 | unregister_netdev (dev); | 963 | unregister_netdev (dev); |
773 | free_netdev (dev); | 964 | free_netdev (dev); |
774 | 965 | ||
@@ -1098,20 +1289,14 @@ static int tc35815_tx_full(struct net_device *dev) | |||
1098 | static void tc35815_restart(struct net_device *dev) | 1289 | static void tc35815_restart(struct net_device *dev) |
1099 | { | 1290 | { |
1100 | struct tc35815_local *lp = netdev_priv(dev); | 1291 | struct tc35815_local *lp = netdev_priv(dev); |
1101 | int pid = lp->phy_addr; | ||
1102 | int do_phy_reset = 1; | ||
1103 | del_timer(&lp->timer); /* Kill if running */ | ||
1104 | 1292 | ||
1105 | if (lp->mii_id[0] == 0x0016 && (lp->mii_id[1] & 0xfc00) == 0xf800) { | 1293 | if (lp->phy_dev) { |
1106 | /* Resetting PHY cause problem on some chip... (SEEQ 80221) */ | ||
1107 | do_phy_reset = 0; | ||
1108 | } | ||
1109 | if (do_phy_reset) { | ||
1110 | int timeout; | 1294 | int timeout; |
1111 | tc_mdio_write(dev, pid, MII_BMCR, BMCR_RESET); | 1295 | |
1296 | phy_write(lp->phy_dev, MII_BMCR, BMCR_RESET); | ||
1112 | timeout = 100; | 1297 | timeout = 100; |
1113 | while (--timeout) { | 1298 | while (--timeout) { |
1114 | if (!(tc_mdio_read(dev, pid, MII_BMCR) & BMCR_RESET)) | 1299 | if (!(phy_read(lp->phy_dev, MII_BMCR) & BMCR_RESET)) |
1115 | break; | 1300 | break; |
1116 | udelay(1); | 1301 | udelay(1); |
1117 | } | 1302 | } |
@@ -1119,45 +1304,53 @@ static void tc35815_restart(struct net_device *dev) | |||
1119 | printk(KERN_ERR "%s: BMCR reset failed.\n", dev->name); | 1304 | printk(KERN_ERR "%s: BMCR reset failed.\n", dev->name); |
1120 | } | 1305 | } |
1121 | 1306 | ||
1307 | spin_lock_irq(&lp->lock); | ||
1122 | tc35815_chip_reset(dev); | 1308 | tc35815_chip_reset(dev); |
1123 | tc35815_clear_queues(dev); | 1309 | tc35815_clear_queues(dev); |
1124 | tc35815_chip_init(dev); | 1310 | tc35815_chip_init(dev); |
1125 | /* Reconfigure CAM again since tc35815_chip_init() initialize it. */ | 1311 | /* Reconfigure CAM again since tc35815_chip_init() initialize it. */ |
1126 | tc35815_set_multicast_list(dev); | 1312 | tc35815_set_multicast_list(dev); |
1313 | spin_unlock_irq(&lp->lock); | ||
1314 | |||
1315 | netif_wake_queue(dev); | ||
1127 | } | 1316 | } |
1128 | 1317 | ||
1129 | static void tc35815_tx_timeout(struct net_device *dev) | 1318 | static void tc35815_restart_work(struct work_struct *work) |
1319 | { | ||
1320 | struct tc35815_local *lp = | ||
1321 | container_of(work, struct tc35815_local, restart_work); | ||
1322 | struct net_device *dev = lp->dev; | ||
1323 | |||
1324 | tc35815_restart(dev); | ||
1325 | } | ||
1326 | |||
1327 | static void tc35815_schedule_restart(struct net_device *dev) | ||
1130 | { | 1328 | { |
1131 | struct tc35815_local *lp = netdev_priv(dev); | 1329 | struct tc35815_local *lp = netdev_priv(dev); |
1132 | struct tc35815_regs __iomem *tr = | 1330 | struct tc35815_regs __iomem *tr = |
1133 | (struct tc35815_regs __iomem *)dev->base_addr; | 1331 | (struct tc35815_regs __iomem *)dev->base_addr; |
1134 | 1332 | ||
1333 | /* disable interrupts */ | ||
1334 | tc_writel(0, &tr->Int_En); | ||
1335 | tc_writel(tc_readl(&tr->DMA_Ctl) | DMA_IntMask, &tr->DMA_Ctl); | ||
1336 | schedule_work(&lp->restart_work); | ||
1337 | } | ||
1338 | |||
1339 | static void tc35815_tx_timeout(struct net_device *dev) | ||
1340 | { | ||
1341 | struct tc35815_regs __iomem *tr = | ||
1342 | (struct tc35815_regs __iomem *)dev->base_addr; | ||
1343 | |||
1135 | printk(KERN_WARNING "%s: transmit timed out, status %#x\n", | 1344 | printk(KERN_WARNING "%s: transmit timed out, status %#x\n", |
1136 | dev->name, tc_readl(&tr->Tx_Stat)); | 1345 | dev->name, tc_readl(&tr->Tx_Stat)); |
1137 | 1346 | ||
1138 | /* Try to restart the adaptor. */ | 1347 | /* Try to restart the adaptor. */ |
1139 | spin_lock_irq(&lp->lock); | 1348 | tc35815_schedule_restart(dev); |
1140 | tc35815_restart(dev); | ||
1141 | spin_unlock_irq(&lp->lock); | ||
1142 | |||
1143 | dev->stats.tx_errors++; | 1349 | dev->stats.tx_errors++; |
1144 | |||
1145 | /* If we have space available to accept new transmit | ||
1146 | * requests, wake up the queueing layer. This would | ||
1147 | * be the case if the chipset_init() call above just | ||
1148 | * flushes out the tx queue and empties it. | ||
1149 | * | ||
1150 | * If instead, the tx queue is retained then the | ||
1151 | * netif_wake_queue() call should be placed in the | ||
1152 | * TX completion interrupt handler of the driver instead | ||
1153 | * of here. | ||
1154 | */ | ||
1155 | if (!tc35815_tx_full(dev)) | ||
1156 | netif_wake_queue(dev); | ||
1157 | } | 1350 | } |
1158 | 1351 | ||
1159 | /* | 1352 | /* |
1160 | * Open/initialize the board. This is called (in the current kernel) | 1353 | * Open/initialize the controller. This is called (in the current kernel) |
1161 | * sometime after booting when the 'ifconfig' program is run. | 1354 | * sometime after booting when the 'ifconfig' program is run. |
1162 | * | 1355 | * |
1163 | * This routine should set everything up anew at each open, even | 1356 | * This routine should set everything up anew at each open, even |
@@ -1177,7 +1370,6 @@ tc35815_open(struct net_device *dev) | |||
1177 | return -EAGAIN; | 1370 | return -EAGAIN; |
1178 | } | 1371 | } |
1179 | 1372 | ||
1180 | del_timer(&lp->timer); /* Kill if running */ | ||
1181 | tc35815_chip_reset(dev); | 1373 | tc35815_chip_reset(dev); |
1182 | 1374 | ||
1183 | if (tc35815_init_queues(dev) != 0) { | 1375 | if (tc35815_init_queues(dev) != 0) { |
@@ -1194,6 +1386,9 @@ tc35815_open(struct net_device *dev) | |||
1194 | tc35815_chip_init(dev); | 1386 | tc35815_chip_init(dev); |
1195 | spin_unlock_irq(&lp->lock); | 1387 | spin_unlock_irq(&lp->lock); |
1196 | 1388 | ||
1389 | /* schedule a link state check */ | ||
1390 | phy_start(lp->phy_dev); | ||
1391 | |||
1197 | /* We are now ready to accept transmit requeusts from | 1392 | /* We are now ready to accept transmit requeusts from |
1198 | * the queueing layer of the networking. | 1393 | * the queueing layer of the networking. |
1199 | */ | 1394 | */ |
@@ -1314,7 +1509,7 @@ static void tc35815_fatal_error_interrupt(struct net_device *dev, u32 status) | |||
1314 | panic("%s: Too many fatal errors.", dev->name); | 1509 | panic("%s: Too many fatal errors.", dev->name); |
1315 | printk(KERN_WARNING "%s: Resetting ...\n", dev->name); | 1510 | printk(KERN_WARNING "%s: Resetting ...\n", dev->name); |
1316 | /* Try to restart the adaptor. */ | 1511 | /* Try to restart the adaptor. */ |
1317 | tc35815_restart(dev); | 1512 | tc35815_schedule_restart(dev); |
1318 | } | 1513 | } |
1319 | 1514 | ||
1320 | #ifdef TC35815_NAPI | 1515 | #ifdef TC35815_NAPI |
@@ -1735,12 +1930,11 @@ tc35815_check_tx_stat(struct net_device *dev, int status) | |||
1735 | 1930 | ||
1736 | #ifndef NO_CHECK_CARRIER | 1931 | #ifndef NO_CHECK_CARRIER |
1737 | /* TX4939 does not have NCarr */ | 1932 | /* TX4939 does not have NCarr */ |
1738 | if (lp->boardtype == TC35815_TX4939) | 1933 | if (lp->chiptype == TC35815_TX4939) |
1739 | status &= ~Tx_NCarr; | 1934 | status &= ~Tx_NCarr; |
1740 | #ifdef WORKAROUND_LOSTCAR | 1935 | #ifdef WORKAROUND_LOSTCAR |
1741 | /* WORKAROUND: ignore LostCrS in full duplex operation */ | 1936 | /* WORKAROUND: ignore LostCrS in full duplex operation */ |
1742 | if ((lp->timer_state != asleep && lp->timer_state != lcheck) | 1937 | if (!lp->link || lp->duplex == DUPLEX_FULL) |
1743 | || lp->fullduplex) | ||
1744 | status &= ~Tx_NCarr; | 1938 | status &= ~Tx_NCarr; |
1745 | #endif | 1939 | #endif |
1746 | #endif | 1940 | #endif |
@@ -1905,10 +2099,11 @@ tc35815_close(struct net_device *dev) | |||
1905 | #ifdef TC35815_NAPI | 2099 | #ifdef TC35815_NAPI |
1906 | napi_disable(&lp->napi); | 2100 | napi_disable(&lp->napi); |
1907 | #endif | 2101 | #endif |
2102 | if (lp->phy_dev) | ||
2103 | phy_stop(lp->phy_dev); | ||
2104 | cancel_work_sync(&lp->restart_work); | ||
1908 | 2105 | ||
1909 | /* Flush the Tx and disable Rx here. */ | 2106 | /* Flush the Tx and disable Rx here. */ |
1910 | |||
1911 | del_timer(&lp->timer); /* Kill if running */ | ||
1912 | tc35815_chip_reset(dev); | 2107 | tc35815_chip_reset(dev); |
1913 | free_irq(dev->irq, dev); | 2108 | free_irq(dev->irq, dev); |
1914 | 2109 | ||
@@ -1993,8 +2188,8 @@ tc35815_set_multicast_list(struct net_device *dev) | |||
1993 | /* With some (all?) 100MHalf HUB, controller will hang | 2188 | /* With some (all?) 100MHalf HUB, controller will hang |
1994 | * if we enabled promiscuous mode before linkup... */ | 2189 | * if we enabled promiscuous mode before linkup... */ |
1995 | struct tc35815_local *lp = netdev_priv(dev); | 2190 | struct tc35815_local *lp = netdev_priv(dev); |
1996 | int pid = lp->phy_addr; | 2191 | |
1997 | if (!(tc_mdio_read(dev, pid, MII_BMSR) & BMSR_LSTATUS)) | 2192 | if (!lp->link) |
1998 | return; | 2193 | return; |
1999 | #endif | 2194 | #endif |
2000 | /* Enable promiscuous mode */ | 2195 | /* Enable promiscuous mode */ |
@@ -2041,60 +2236,19 @@ static void tc35815_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo * | |||
2041 | static int tc35815_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 2236 | static int tc35815_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
2042 | { | 2237 | { |
2043 | struct tc35815_local *lp = netdev_priv(dev); | 2238 | struct tc35815_local *lp = netdev_priv(dev); |
2044 | spin_lock_irq(&lp->lock); | ||
2045 | mii_ethtool_gset(&lp->mii, cmd); | ||
2046 | spin_unlock_irq(&lp->lock); | ||
2047 | return 0; | ||
2048 | } | ||
2049 | |||
2050 | static int tc35815_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
2051 | { | ||
2052 | struct tc35815_local *lp = netdev_priv(dev); | ||
2053 | int rc; | ||
2054 | #if 1 /* use our negotiation method... */ | ||
2055 | /* Verify the settings we care about. */ | ||
2056 | if (cmd->autoneg != AUTONEG_ENABLE && | ||
2057 | cmd->autoneg != AUTONEG_DISABLE) | ||
2058 | return -EINVAL; | ||
2059 | if (cmd->autoneg == AUTONEG_DISABLE && | ||
2060 | ((cmd->speed != SPEED_100 && | ||
2061 | cmd->speed != SPEED_10) || | ||
2062 | (cmd->duplex != DUPLEX_HALF && | ||
2063 | cmd->duplex != DUPLEX_FULL))) | ||
2064 | return -EINVAL; | ||
2065 | 2239 | ||
2066 | /* Ok, do it to it. */ | 2240 | if (!lp->phy_dev) |
2067 | spin_lock_irq(&lp->lock); | 2241 | return -ENODEV; |
2068 | del_timer(&lp->timer); | 2242 | return phy_ethtool_gset(lp->phy_dev, cmd); |
2069 | tc35815_start_auto_negotiation(dev, cmd); | ||
2070 | spin_unlock_irq(&lp->lock); | ||
2071 | rc = 0; | ||
2072 | #else | ||
2073 | spin_lock_irq(&lp->lock); | ||
2074 | rc = mii_ethtool_sset(&lp->mii, cmd); | ||
2075 | spin_unlock_irq(&lp->lock); | ||
2076 | #endif | ||
2077 | return rc; | ||
2078 | } | 2243 | } |
2079 | 2244 | ||
2080 | static int tc35815_nway_reset(struct net_device *dev) | 2245 | static int tc35815_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
2081 | { | 2246 | { |
2082 | struct tc35815_local *lp = netdev_priv(dev); | 2247 | struct tc35815_local *lp = netdev_priv(dev); |
2083 | int rc; | ||
2084 | spin_lock_irq(&lp->lock); | ||
2085 | rc = mii_nway_restart(&lp->mii); | ||
2086 | spin_unlock_irq(&lp->lock); | ||
2087 | return rc; | ||
2088 | } | ||
2089 | 2248 | ||
2090 | static u32 tc35815_get_link(struct net_device *dev) | 2249 | if (!lp->phy_dev) |
2091 | { | 2250 | return -ENODEV; |
2092 | struct tc35815_local *lp = netdev_priv(dev); | 2251 | return phy_ethtool_sset(lp->phy_dev, cmd); |
2093 | int rc; | ||
2094 | spin_lock_irq(&lp->lock); | ||
2095 | rc = mii_link_ok(&lp->mii); | ||
2096 | spin_unlock_irq(&lp->lock); | ||
2097 | return rc; | ||
2098 | } | 2252 | } |
2099 | 2253 | ||
2100 | static u32 tc35815_get_msglevel(struct net_device *dev) | 2254 | static u32 tc35815_get_msglevel(struct net_device *dev) |
@@ -2148,8 +2302,7 @@ static const struct ethtool_ops tc35815_ethtool_ops = { | |||
2148 | .get_drvinfo = tc35815_get_drvinfo, | 2302 | .get_drvinfo = tc35815_get_drvinfo, |
2149 | .get_settings = tc35815_get_settings, | 2303 | .get_settings = tc35815_get_settings, |
2150 | .set_settings = tc35815_set_settings, | 2304 | .set_settings = tc35815_set_settings, |
2151 | .nway_reset = tc35815_nway_reset, | 2305 | .get_link = ethtool_op_get_link, |
2152 | .get_link = tc35815_get_link, | ||
2153 | .get_msglevel = tc35815_get_msglevel, | 2306 | .get_msglevel = tc35815_get_msglevel, |
2154 | .set_msglevel = tc35815_set_msglevel, | 2307 | .set_msglevel = tc35815_set_msglevel, |
2155 | .get_strings = tc35815_get_strings, | 2308 | .get_strings = tc35815_get_strings, |
@@ -2160,610 +2313,12 @@ static const struct ethtool_ops tc35815_ethtool_ops = { | |||
2160 | static int tc35815_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | 2313 | static int tc35815_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
2161 | { | 2314 | { |
2162 | struct tc35815_local *lp = netdev_priv(dev); | 2315 | struct tc35815_local *lp = netdev_priv(dev); |
2163 | int rc; | ||
2164 | 2316 | ||
2165 | if (!netif_running(dev)) | 2317 | if (!netif_running(dev)) |
2166 | return -EINVAL; | 2318 | return -EINVAL; |
2167 | 2319 | if (!lp->phy_dev) | |
2168 | spin_lock_irq(&lp->lock); | 2320 | return -ENODEV; |
2169 | rc = generic_mii_ioctl(&lp->mii, if_mii(rq), cmd, NULL); | 2321 | return phy_mii_ioctl(lp->phy_dev, if_mii(rq), cmd); |
2170 | spin_unlock_irq(&lp->lock); | ||
2171 | |||
2172 | return rc; | ||
2173 | } | ||
2174 | |||
2175 | static int tc_mdio_read(struct net_device *dev, int phy_id, int location) | ||
2176 | { | ||
2177 | struct tc35815_regs __iomem *tr = | ||
2178 | (struct tc35815_regs __iomem *)dev->base_addr; | ||
2179 | u32 data; | ||
2180 | tc_writel(MD_CA_Busy | (phy_id << 5) | location, &tr->MD_CA); | ||
2181 | while (tc_readl(&tr->MD_CA) & MD_CA_Busy) | ||
2182 | ; | ||
2183 | data = tc_readl(&tr->MD_Data); | ||
2184 | return data & 0xffff; | ||
2185 | } | ||
2186 | |||
2187 | static void tc_mdio_write(struct net_device *dev, int phy_id, int location, | ||
2188 | int val) | ||
2189 | { | ||
2190 | struct tc35815_regs __iomem *tr = | ||
2191 | (struct tc35815_regs __iomem *)dev->base_addr; | ||
2192 | tc_writel(val, &tr->MD_Data); | ||
2193 | tc_writel(MD_CA_Busy | MD_CA_Wr | (phy_id << 5) | location, &tr->MD_CA); | ||
2194 | while (tc_readl(&tr->MD_CA) & MD_CA_Busy) | ||
2195 | ; | ||
2196 | } | ||
2197 | |||
2198 | /* Auto negotiation. The scheme is very simple. We have a timer routine | ||
2199 | * that keeps watching the auto negotiation process as it progresses. | ||
2200 | * The DP83840 is first told to start doing it's thing, we set up the time | ||
2201 | * and place the timer state machine in it's initial state. | ||
2202 | * | ||
2203 | * Here the timer peeks at the DP83840 status registers at each click to see | ||
2204 | * if the auto negotiation has completed, we assume here that the DP83840 PHY | ||
2205 | * will time out at some point and just tell us what (didn't) happen. For | ||
2206 | * complete coverage we only allow so many of the ticks at this level to run, | ||
2207 | * when this has expired we print a warning message and try another strategy. | ||
2208 | * This "other" strategy is to force the interface into various speed/duplex | ||
2209 | * configurations and we stop when we see a link-up condition before the | ||
2210 | * maximum number of "peek" ticks have occurred. | ||
2211 | * | ||
2212 | * Once a valid link status has been detected we configure the BigMAC and | ||
2213 | * the rest of the Happy Meal to speak the most efficient protocol we could | ||
2214 | * get a clean link for. The priority for link configurations, highest first | ||
2215 | * is: | ||
2216 | * 100 Base-T Full Duplex | ||
2217 | * 100 Base-T Half Duplex | ||
2218 | * 10 Base-T Full Duplex | ||
2219 | * 10 Base-T Half Duplex | ||
2220 | * | ||
2221 | * We start a new timer now, after a successful auto negotiation status has | ||
2222 | * been detected. This timer just waits for the link-up bit to get set in | ||
2223 | * the BMCR of the DP83840. When this occurs we print a kernel log message | ||
2224 | * describing the link type in use and the fact that it is up. | ||
2225 | * | ||
2226 | * If a fatal error of some sort is signalled and detected in the interrupt | ||
2227 | * service routine, and the chip is reset, or the link is ifconfig'd down | ||
2228 | * and then back up, this entire process repeats itself all over again. | ||
2229 | */ | ||
2230 | /* Note: Above comments are come from sunhme driver. */ | ||
2231 | |||
2232 | static int tc35815_try_next_permutation(struct net_device *dev) | ||
2233 | { | ||
2234 | struct tc35815_local *lp = netdev_priv(dev); | ||
2235 | int pid = lp->phy_addr; | ||
2236 | unsigned short bmcr; | ||
2237 | |||
2238 | bmcr = tc_mdio_read(dev, pid, MII_BMCR); | ||
2239 | |||
2240 | /* Downgrade from full to half duplex. Only possible via ethtool. */ | ||
2241 | if (bmcr & BMCR_FULLDPLX) { | ||
2242 | bmcr &= ~BMCR_FULLDPLX; | ||
2243 | printk(KERN_DEBUG "%s: try next permutation (BMCR %x)\n", dev->name, bmcr); | ||
2244 | tc_mdio_write(dev, pid, MII_BMCR, bmcr); | ||
2245 | return 0; | ||
2246 | } | ||
2247 | |||
2248 | /* Downgrade from 100 to 10. */ | ||
2249 | if (bmcr & BMCR_SPEED100) { | ||
2250 | bmcr &= ~BMCR_SPEED100; | ||
2251 | printk(KERN_DEBUG "%s: try next permutation (BMCR %x)\n", dev->name, bmcr); | ||
2252 | tc_mdio_write(dev, pid, MII_BMCR, bmcr); | ||
2253 | return 0; | ||
2254 | } | ||
2255 | |||
2256 | /* We've tried everything. */ | ||
2257 | return -1; | ||
2258 | } | ||
2259 | |||
2260 | static void | ||
2261 | tc35815_display_link_mode(struct net_device *dev) | ||
2262 | { | ||
2263 | struct tc35815_local *lp = netdev_priv(dev); | ||
2264 | int pid = lp->phy_addr; | ||
2265 | unsigned short lpa, bmcr; | ||
2266 | char *speed = "", *duplex = ""; | ||
2267 | |||
2268 | lpa = tc_mdio_read(dev, pid, MII_LPA); | ||
2269 | bmcr = tc_mdio_read(dev, pid, MII_BMCR); | ||
2270 | if (options.speed ? (bmcr & BMCR_SPEED100) : (lpa & (LPA_100HALF | LPA_100FULL))) | ||
2271 | speed = "100Mb/s"; | ||
2272 | else | ||
2273 | speed = "10Mb/s"; | ||
2274 | if (options.duplex ? (bmcr & BMCR_FULLDPLX) : (lpa & (LPA_100FULL | LPA_10FULL))) | ||
2275 | duplex = "Full Duplex"; | ||
2276 | else | ||
2277 | duplex = "Half Duplex"; | ||
2278 | |||
2279 | if (netif_msg_link(lp)) | ||
2280 | printk(KERN_INFO "%s: Link is up at %s, %s.\n", | ||
2281 | dev->name, speed, duplex); | ||
2282 | printk(KERN_DEBUG "%s: MII BMCR %04x BMSR %04x LPA %04x\n", | ||
2283 | dev->name, | ||
2284 | bmcr, tc_mdio_read(dev, pid, MII_BMSR), lpa); | ||
2285 | } | ||
2286 | |||
2287 | static void tc35815_display_forced_link_mode(struct net_device *dev) | ||
2288 | { | ||
2289 | struct tc35815_local *lp = netdev_priv(dev); | ||
2290 | int pid = lp->phy_addr; | ||
2291 | unsigned short bmcr; | ||
2292 | char *speed = "", *duplex = ""; | ||
2293 | |||
2294 | bmcr = tc_mdio_read(dev, pid, MII_BMCR); | ||
2295 | if (bmcr & BMCR_SPEED100) | ||
2296 | speed = "100Mb/s"; | ||
2297 | else | ||
2298 | speed = "10Mb/s"; | ||
2299 | if (bmcr & BMCR_FULLDPLX) | ||
2300 | duplex = "Full Duplex.\n"; | ||
2301 | else | ||
2302 | duplex = "Half Duplex.\n"; | ||
2303 | |||
2304 | if (netif_msg_link(lp)) | ||
2305 | printk(KERN_INFO "%s: Link has been forced up at %s, %s", | ||
2306 | dev->name, speed, duplex); | ||
2307 | } | ||
2308 | |||
2309 | static void tc35815_set_link_modes(struct net_device *dev) | ||
2310 | { | ||
2311 | struct tc35815_local *lp = netdev_priv(dev); | ||
2312 | struct tc35815_regs __iomem *tr = | ||
2313 | (struct tc35815_regs __iomem *)dev->base_addr; | ||
2314 | int pid = lp->phy_addr; | ||
2315 | unsigned short bmcr, lpa; | ||
2316 | int speed; | ||
2317 | |||
2318 | if (lp->timer_state == arbwait) { | ||
2319 | lpa = tc_mdio_read(dev, pid, MII_LPA); | ||
2320 | bmcr = tc_mdio_read(dev, pid, MII_BMCR); | ||
2321 | printk(KERN_DEBUG "%s: MII BMCR %04x BMSR %04x LPA %04x\n", | ||
2322 | dev->name, | ||
2323 | bmcr, tc_mdio_read(dev, pid, MII_BMSR), lpa); | ||
2324 | if (!(lpa & (LPA_10HALF | LPA_10FULL | | ||
2325 | LPA_100HALF | LPA_100FULL))) { | ||
2326 | /* fall back to 10HALF */ | ||
2327 | printk(KERN_INFO "%s: bad ability %04x - falling back to 10HD.\n", | ||
2328 | dev->name, lpa); | ||
2329 | lpa = LPA_10HALF; | ||
2330 | } | ||
2331 | if (options.duplex ? (bmcr & BMCR_FULLDPLX) : (lpa & (LPA_100FULL | LPA_10FULL))) | ||
2332 | lp->fullduplex = 1; | ||
2333 | else | ||
2334 | lp->fullduplex = 0; | ||
2335 | if (options.speed ? (bmcr & BMCR_SPEED100) : (lpa & (LPA_100HALF | LPA_100FULL))) | ||
2336 | speed = 100; | ||
2337 | else | ||
2338 | speed = 10; | ||
2339 | } else { | ||
2340 | /* Forcing a link mode. */ | ||
2341 | bmcr = tc_mdio_read(dev, pid, MII_BMCR); | ||
2342 | if (bmcr & BMCR_FULLDPLX) | ||
2343 | lp->fullduplex = 1; | ||
2344 | else | ||
2345 | lp->fullduplex = 0; | ||
2346 | if (bmcr & BMCR_SPEED100) | ||
2347 | speed = 100; | ||
2348 | else | ||
2349 | speed = 10; | ||
2350 | } | ||
2351 | |||
2352 | tc_writel(tc_readl(&tr->MAC_Ctl) | MAC_HaltReq, &tr->MAC_Ctl); | ||
2353 | if (lp->fullduplex) { | ||
2354 | tc_writel(tc_readl(&tr->MAC_Ctl) | MAC_FullDup, &tr->MAC_Ctl); | ||
2355 | } else { | ||
2356 | tc_writel(tc_readl(&tr->MAC_Ctl) & ~MAC_FullDup, &tr->MAC_Ctl); | ||
2357 | } | ||
2358 | tc_writel(tc_readl(&tr->MAC_Ctl) & ~MAC_HaltReq, &tr->MAC_Ctl); | ||
2359 | |||
2360 | /* TX4939 PCFG.SPEEDn bit will be changed on NETDEV_CHANGE event. */ | ||
2361 | |||
2362 | #ifndef NO_CHECK_CARRIER | ||
2363 | /* TX4939 does not have EnLCarr */ | ||
2364 | if (lp->boardtype != TC35815_TX4939) { | ||
2365 | #ifdef WORKAROUND_LOSTCAR | ||
2366 | /* WORKAROUND: enable LostCrS only if half duplex operation */ | ||
2367 | if (!lp->fullduplex && lp->boardtype != TC35815_TX4939) | ||
2368 | tc_writel(tc_readl(&tr->Tx_Ctl) | Tx_EnLCarr, &tr->Tx_Ctl); | ||
2369 | #endif | ||
2370 | } | ||
2371 | #endif | ||
2372 | lp->mii.full_duplex = lp->fullduplex; | ||
2373 | } | ||
2374 | |||
2375 | static void tc35815_timer(unsigned long data) | ||
2376 | { | ||
2377 | struct net_device *dev = (struct net_device *)data; | ||
2378 | struct tc35815_local *lp = netdev_priv(dev); | ||
2379 | int pid = lp->phy_addr; | ||
2380 | unsigned short bmsr, bmcr, lpa; | ||
2381 | int restart_timer = 0; | ||
2382 | |||
2383 | spin_lock_irq(&lp->lock); | ||
2384 | |||
2385 | lp->timer_ticks++; | ||
2386 | switch (lp->timer_state) { | ||
2387 | case arbwait: | ||
2388 | /* | ||
2389 | * Only allow for 5 ticks, thats 10 seconds and much too | ||
2390 | * long to wait for arbitration to complete. | ||
2391 | */ | ||
2392 | /* TC35815 need more times... */ | ||
2393 | if (lp->timer_ticks >= 10) { | ||
2394 | /* Enter force mode. */ | ||
2395 | if (!options.doforce) { | ||
2396 | printk(KERN_NOTICE "%s: Auto-Negotiation unsuccessful," | ||
2397 | " cable probblem?\n", dev->name); | ||
2398 | /* Try to restart the adaptor. */ | ||
2399 | tc35815_restart(dev); | ||
2400 | goto out; | ||
2401 | } | ||
2402 | printk(KERN_NOTICE "%s: Auto-Negotiation unsuccessful," | ||
2403 | " trying force link mode\n", dev->name); | ||
2404 | printk(KERN_DEBUG "%s: BMCR %x BMSR %x\n", dev->name, | ||
2405 | tc_mdio_read(dev, pid, MII_BMCR), | ||
2406 | tc_mdio_read(dev, pid, MII_BMSR)); | ||
2407 | bmcr = BMCR_SPEED100; | ||
2408 | tc_mdio_write(dev, pid, MII_BMCR, bmcr); | ||
2409 | |||
2410 | /* | ||
2411 | * OK, seems we need do disable the transceiver | ||
2412 | * for the first tick to make sure we get an | ||
2413 | * accurate link state at the second tick. | ||
2414 | */ | ||
2415 | |||
2416 | lp->timer_state = ltrywait; | ||
2417 | lp->timer_ticks = 0; | ||
2418 | restart_timer = 1; | ||
2419 | } else { | ||
2420 | /* Anything interesting happen? */ | ||
2421 | bmsr = tc_mdio_read(dev, pid, MII_BMSR); | ||
2422 | if (bmsr & BMSR_ANEGCOMPLETE) { | ||
2423 | /* Just what we've been waiting for... */ | ||
2424 | tc35815_set_link_modes(dev); | ||
2425 | |||
2426 | /* | ||
2427 | * Success, at least so far, advance our state | ||
2428 | * engine. | ||
2429 | */ | ||
2430 | lp->timer_state = lupwait; | ||
2431 | restart_timer = 1; | ||
2432 | } else { | ||
2433 | restart_timer = 1; | ||
2434 | } | ||
2435 | } | ||
2436 | break; | ||
2437 | |||
2438 | case lupwait: | ||
2439 | /* | ||
2440 | * Auto negotiation was successful and we are awaiting a | ||
2441 | * link up status. I have decided to let this timer run | ||
2442 | * forever until some sort of error is signalled, reporting | ||
2443 | * a message to the user at 10 second intervals. | ||
2444 | */ | ||
2445 | bmsr = tc_mdio_read(dev, pid, MII_BMSR); | ||
2446 | if (bmsr & BMSR_LSTATUS) { | ||
2447 | /* | ||
2448 | * Wheee, it's up, display the link mode in use and put | ||
2449 | * the timer to sleep. | ||
2450 | */ | ||
2451 | tc35815_display_link_mode(dev); | ||
2452 | netif_carrier_on(dev); | ||
2453 | #ifdef WORKAROUND_100HALF_PROMISC | ||
2454 | /* delayed promiscuous enabling */ | ||
2455 | if (dev->flags & IFF_PROMISC) | ||
2456 | tc35815_set_multicast_list(dev); | ||
2457 | #endif | ||
2458 | #if 1 | ||
2459 | lp->saved_lpa = tc_mdio_read(dev, pid, MII_LPA); | ||
2460 | lp->timer_state = lcheck; | ||
2461 | restart_timer = 1; | ||
2462 | #else | ||
2463 | lp->timer_state = asleep; | ||
2464 | restart_timer = 0; | ||
2465 | #endif | ||
2466 | } else { | ||
2467 | if (lp->timer_ticks >= 10) { | ||
2468 | printk(KERN_NOTICE "%s: Auto negotiation successful, link still " | ||
2469 | "not completely up.\n", dev->name); | ||
2470 | lp->timer_ticks = 0; | ||
2471 | restart_timer = 1; | ||
2472 | } else { | ||
2473 | restart_timer = 1; | ||
2474 | } | ||
2475 | } | ||
2476 | break; | ||
2477 | |||
2478 | case ltrywait: | ||
2479 | /* | ||
2480 | * Making the timeout here too long can make it take | ||
2481 | * annoyingly long to attempt all of the link mode | ||
2482 | * permutations, but then again this is essentially | ||
2483 | * error recovery code for the most part. | ||
2484 | */ | ||
2485 | bmsr = tc_mdio_read(dev, pid, MII_BMSR); | ||
2486 | bmcr = tc_mdio_read(dev, pid, MII_BMCR); | ||
2487 | if (lp->timer_ticks == 1) { | ||
2488 | /* | ||
2489 | * Re-enable transceiver, we'll re-enable the | ||
2490 | * transceiver next tick, then check link state | ||
2491 | * on the following tick. | ||
2492 | */ | ||
2493 | restart_timer = 1; | ||
2494 | break; | ||
2495 | } | ||
2496 | if (lp->timer_ticks == 2) { | ||
2497 | restart_timer = 1; | ||
2498 | break; | ||
2499 | } | ||
2500 | if (bmsr & BMSR_LSTATUS) { | ||
2501 | /* Force mode selection success. */ | ||
2502 | tc35815_display_forced_link_mode(dev); | ||
2503 | netif_carrier_on(dev); | ||
2504 | tc35815_set_link_modes(dev); | ||
2505 | #ifdef WORKAROUND_100HALF_PROMISC | ||
2506 | /* delayed promiscuous enabling */ | ||
2507 | if (dev->flags & IFF_PROMISC) | ||
2508 | tc35815_set_multicast_list(dev); | ||
2509 | #endif | ||
2510 | #if 1 | ||
2511 | lp->saved_lpa = tc_mdio_read(dev, pid, MII_LPA); | ||
2512 | lp->timer_state = lcheck; | ||
2513 | restart_timer = 1; | ||
2514 | #else | ||
2515 | lp->timer_state = asleep; | ||
2516 | restart_timer = 0; | ||
2517 | #endif | ||
2518 | } else { | ||
2519 | if (lp->timer_ticks >= 4) { /* 6 seconds or so... */ | ||
2520 | int ret; | ||
2521 | |||
2522 | ret = tc35815_try_next_permutation(dev); | ||
2523 | if (ret == -1) { | ||
2524 | /* | ||
2525 | * Aieee, tried them all, reset the | ||
2526 | * chip and try all over again. | ||
2527 | */ | ||
2528 | printk(KERN_NOTICE "%s: Link down, " | ||
2529 | "cable problem?\n", | ||
2530 | dev->name); | ||
2531 | |||
2532 | /* Try to restart the adaptor. */ | ||
2533 | tc35815_restart(dev); | ||
2534 | goto out; | ||
2535 | } | ||
2536 | lp->timer_ticks = 0; | ||
2537 | restart_timer = 1; | ||
2538 | } else { | ||
2539 | restart_timer = 1; | ||
2540 | } | ||
2541 | } | ||
2542 | break; | ||
2543 | |||
2544 | case lcheck: | ||
2545 | bmcr = tc_mdio_read(dev, pid, MII_BMCR); | ||
2546 | lpa = tc_mdio_read(dev, pid, MII_LPA); | ||
2547 | if (bmcr & (BMCR_PDOWN | BMCR_ISOLATE | BMCR_RESET)) { | ||
2548 | printk(KERN_ERR "%s: PHY down? (BMCR %x)\n", dev->name, | ||
2549 | bmcr); | ||
2550 | } else if ((lp->saved_lpa ^ lpa) & | ||
2551 | (LPA_100FULL|LPA_100HALF|LPA_10FULL|LPA_10HALF)) { | ||
2552 | printk(KERN_NOTICE "%s: link status changed" | ||
2553 | " (BMCR %x LPA %x->%x)\n", dev->name, | ||
2554 | bmcr, lp->saved_lpa, lpa); | ||
2555 | } else { | ||
2556 | /* go on */ | ||
2557 | restart_timer = 1; | ||
2558 | break; | ||
2559 | } | ||
2560 | /* Try to restart the adaptor. */ | ||
2561 | tc35815_restart(dev); | ||
2562 | goto out; | ||
2563 | |||
2564 | case asleep: | ||
2565 | default: | ||
2566 | /* Can't happens.... */ | ||
2567 | printk(KERN_ERR "%s: Aieee, link timer is asleep but we got " | ||
2568 | "one anyways!\n", dev->name); | ||
2569 | restart_timer = 0; | ||
2570 | lp->timer_ticks = 0; | ||
2571 | lp->timer_state = asleep; /* foo on you */ | ||
2572 | break; | ||
2573 | } | ||
2574 | |||
2575 | if (restart_timer) { | ||
2576 | lp->timer.expires = jiffies + msecs_to_jiffies(1200); | ||
2577 | add_timer(&lp->timer); | ||
2578 | } | ||
2579 | out: | ||
2580 | spin_unlock_irq(&lp->lock); | ||
2581 | } | ||
2582 | |||
2583 | static void tc35815_start_auto_negotiation(struct net_device *dev, | ||
2584 | struct ethtool_cmd *ep) | ||
2585 | { | ||
2586 | struct tc35815_local *lp = netdev_priv(dev); | ||
2587 | int pid = lp->phy_addr; | ||
2588 | unsigned short bmsr, bmcr, advertize; | ||
2589 | int timeout; | ||
2590 | |||
2591 | netif_carrier_off(dev); | ||
2592 | bmsr = tc_mdio_read(dev, pid, MII_BMSR); | ||
2593 | bmcr = tc_mdio_read(dev, pid, MII_BMCR); | ||
2594 | advertize = tc_mdio_read(dev, pid, MII_ADVERTISE); | ||
2595 | |||
2596 | if (ep == NULL || ep->autoneg == AUTONEG_ENABLE) { | ||
2597 | if (options.speed || options.duplex) { | ||
2598 | /* Advertise only specified configuration. */ | ||
2599 | advertize &= ~(ADVERTISE_10HALF | | ||
2600 | ADVERTISE_10FULL | | ||
2601 | ADVERTISE_100HALF | | ||
2602 | ADVERTISE_100FULL); | ||
2603 | if (options.speed != 10) { | ||
2604 | if (options.duplex != 1) | ||
2605 | advertize |= ADVERTISE_100FULL; | ||
2606 | if (options.duplex != 2) | ||
2607 | advertize |= ADVERTISE_100HALF; | ||
2608 | } | ||
2609 | if (options.speed != 100) { | ||
2610 | if (options.duplex != 1) | ||
2611 | advertize |= ADVERTISE_10FULL; | ||
2612 | if (options.duplex != 2) | ||
2613 | advertize |= ADVERTISE_10HALF; | ||
2614 | } | ||
2615 | if (options.speed == 100) | ||
2616 | bmcr |= BMCR_SPEED100; | ||
2617 | else if (options.speed == 10) | ||
2618 | bmcr &= ~BMCR_SPEED100; | ||
2619 | if (options.duplex == 2) | ||
2620 | bmcr |= BMCR_FULLDPLX; | ||
2621 | else if (options.duplex == 1) | ||
2622 | bmcr &= ~BMCR_FULLDPLX; | ||
2623 | } else { | ||
2624 | /* Advertise everything we can support. */ | ||
2625 | if (bmsr & BMSR_10HALF) | ||
2626 | advertize |= ADVERTISE_10HALF; | ||
2627 | else | ||
2628 | advertize &= ~ADVERTISE_10HALF; | ||
2629 | if (bmsr & BMSR_10FULL) | ||
2630 | advertize |= ADVERTISE_10FULL; | ||
2631 | else | ||
2632 | advertize &= ~ADVERTISE_10FULL; | ||
2633 | if (bmsr & BMSR_100HALF) | ||
2634 | advertize |= ADVERTISE_100HALF; | ||
2635 | else | ||
2636 | advertize &= ~ADVERTISE_100HALF; | ||
2637 | if (bmsr & BMSR_100FULL) | ||
2638 | advertize |= ADVERTISE_100FULL; | ||
2639 | else | ||
2640 | advertize &= ~ADVERTISE_100FULL; | ||
2641 | } | ||
2642 | |||
2643 | tc_mdio_write(dev, pid, MII_ADVERTISE, advertize); | ||
2644 | |||
2645 | /* Enable Auto-Negotiation, this is usually on already... */ | ||
2646 | bmcr |= BMCR_ANENABLE; | ||
2647 | tc_mdio_write(dev, pid, MII_BMCR, bmcr); | ||
2648 | |||
2649 | /* Restart it to make sure it is going. */ | ||
2650 | bmcr |= BMCR_ANRESTART; | ||
2651 | tc_mdio_write(dev, pid, MII_BMCR, bmcr); | ||
2652 | printk(KERN_DEBUG "%s: ADVERTISE %x BMCR %x\n", dev->name, advertize, bmcr); | ||
2653 | |||
2654 | /* BMCR_ANRESTART self clears when the process has begun. */ | ||
2655 | timeout = 64; /* More than enough. */ | ||
2656 | while (--timeout) { | ||
2657 | bmcr = tc_mdio_read(dev, pid, MII_BMCR); | ||
2658 | if (!(bmcr & BMCR_ANRESTART)) | ||
2659 | break; /* got it. */ | ||
2660 | udelay(10); | ||
2661 | } | ||
2662 | if (!timeout) { | ||
2663 | printk(KERN_ERR "%s: TC35815 would not start auto " | ||
2664 | "negotiation BMCR=0x%04x\n", | ||
2665 | dev->name, bmcr); | ||
2666 | printk(KERN_NOTICE "%s: Performing force link " | ||
2667 | "detection.\n", dev->name); | ||
2668 | goto force_link; | ||
2669 | } else { | ||
2670 | printk(KERN_DEBUG "%s: auto negotiation started.\n", dev->name); | ||
2671 | lp->timer_state = arbwait; | ||
2672 | } | ||
2673 | } else { | ||
2674 | force_link: | ||
2675 | /* Force the link up, trying first a particular mode. | ||
2676 | * Either we are here at the request of ethtool or | ||
2677 | * because the Happy Meal would not start to autoneg. | ||
2678 | */ | ||
2679 | |||
2680 | /* Disable auto-negotiation in BMCR, enable the duplex and | ||
2681 | * speed setting, init the timer state machine, and fire it off. | ||
2682 | */ | ||
2683 | if (ep == NULL || ep->autoneg == AUTONEG_ENABLE) { | ||
2684 | bmcr = BMCR_SPEED100; | ||
2685 | } else { | ||
2686 | if (ep->speed == SPEED_100) | ||
2687 | bmcr = BMCR_SPEED100; | ||
2688 | else | ||
2689 | bmcr = 0; | ||
2690 | if (ep->duplex == DUPLEX_FULL) | ||
2691 | bmcr |= BMCR_FULLDPLX; | ||
2692 | } | ||
2693 | tc_mdio_write(dev, pid, MII_BMCR, bmcr); | ||
2694 | |||
2695 | /* OK, seems we need do disable the transceiver for the first | ||
2696 | * tick to make sure we get an accurate link state at the | ||
2697 | * second tick. | ||
2698 | */ | ||
2699 | lp->timer_state = ltrywait; | ||
2700 | } | ||
2701 | |||
2702 | del_timer(&lp->timer); | ||
2703 | lp->timer_ticks = 0; | ||
2704 | lp->timer.expires = jiffies + msecs_to_jiffies(1200); | ||
2705 | add_timer(&lp->timer); | ||
2706 | } | ||
2707 | |||
2708 | static void tc35815_find_phy(struct net_device *dev) | ||
2709 | { | ||
2710 | struct tc35815_local *lp = netdev_priv(dev); | ||
2711 | int pid = lp->phy_addr; | ||
2712 | unsigned short id0; | ||
2713 | |||
2714 | /* find MII phy */ | ||
2715 | for (pid = 31; pid >= 0; pid--) { | ||
2716 | id0 = tc_mdio_read(dev, pid, MII_BMSR); | ||
2717 | if (id0 != 0xffff && id0 != 0x0000 && | ||
2718 | (id0 & BMSR_RESV) != (0xffff & BMSR_RESV) /* paranoia? */ | ||
2719 | ) { | ||
2720 | lp->phy_addr = pid; | ||
2721 | break; | ||
2722 | } | ||
2723 | } | ||
2724 | if (pid < 0) { | ||
2725 | printk(KERN_ERR "%s: No MII Phy found.\n", | ||
2726 | dev->name); | ||
2727 | lp->phy_addr = pid = 0; | ||
2728 | } | ||
2729 | |||
2730 | lp->mii_id[0] = tc_mdio_read(dev, pid, MII_PHYSID1); | ||
2731 | lp->mii_id[1] = tc_mdio_read(dev, pid, MII_PHYSID2); | ||
2732 | if (netif_msg_hw(lp)) | ||
2733 | printk(KERN_INFO "%s: PHY(%02x) ID %04x %04x\n", dev->name, | ||
2734 | pid, lp->mii_id[0], lp->mii_id[1]); | ||
2735 | } | ||
2736 | |||
2737 | static void tc35815_phy_chip_init(struct net_device *dev) | ||
2738 | { | ||
2739 | struct tc35815_local *lp = netdev_priv(dev); | ||
2740 | int pid = lp->phy_addr; | ||
2741 | unsigned short bmcr; | ||
2742 | struct ethtool_cmd ecmd, *ep; | ||
2743 | |||
2744 | /* dis-isolate if needed. */ | ||
2745 | bmcr = tc_mdio_read(dev, pid, MII_BMCR); | ||
2746 | if (bmcr & BMCR_ISOLATE) { | ||
2747 | int count = 32; | ||
2748 | printk(KERN_DEBUG "%s: unisolating...", dev->name); | ||
2749 | tc_mdio_write(dev, pid, MII_BMCR, bmcr & ~BMCR_ISOLATE); | ||
2750 | while (--count) { | ||
2751 | if (!(tc_mdio_read(dev, pid, MII_BMCR) & BMCR_ISOLATE)) | ||
2752 | break; | ||
2753 | udelay(20); | ||
2754 | } | ||
2755 | printk(" %s.\n", count ? "done" : "failed"); | ||
2756 | } | ||
2757 | |||
2758 | if (options.speed && options.duplex) { | ||
2759 | ecmd.autoneg = AUTONEG_DISABLE; | ||
2760 | ecmd.speed = options.speed == 10 ? SPEED_10 : SPEED_100; | ||
2761 | ecmd.duplex = options.duplex == 1 ? DUPLEX_HALF : DUPLEX_FULL; | ||
2762 | ep = &ecmd; | ||
2763 | } else { | ||
2764 | ep = NULL; | ||
2765 | } | ||
2766 | tc35815_start_auto_negotiation(dev, ep); | ||
2767 | } | 2322 | } |
2768 | 2323 | ||
2769 | static void tc35815_chip_reset(struct net_device *dev) | 2324 | static void tc35815_chip_reset(struct net_device *dev) |
@@ -2815,8 +2370,6 @@ static void tc35815_chip_init(struct net_device *dev) | |||
2815 | (struct tc35815_regs __iomem *)dev->base_addr; | 2370 | (struct tc35815_regs __iomem *)dev->base_addr; |
2816 | unsigned long txctl = TX_CTL_CMD; | 2371 | unsigned long txctl = TX_CTL_CMD; |
2817 | 2372 | ||
2818 | tc35815_phy_chip_init(dev); | ||
2819 | |||
2820 | /* load station address to CAM */ | 2373 | /* load station address to CAM */ |
2821 | tc35815_set_cam_entry(dev, CAM_ENTRY_SOURCE, dev->dev_addr); | 2374 | tc35815_set_cam_entry(dev, CAM_ENTRY_SOURCE, dev->dev_addr); |
2822 | 2375 | ||
@@ -2853,12 +2406,11 @@ static void tc35815_chip_init(struct net_device *dev) | |||
2853 | /* start MAC transmitter */ | 2406 | /* start MAC transmitter */ |
2854 | #ifndef NO_CHECK_CARRIER | 2407 | #ifndef NO_CHECK_CARRIER |
2855 | /* TX4939 does not have EnLCarr */ | 2408 | /* TX4939 does not have EnLCarr */ |
2856 | if (lp->boardtype == TC35815_TX4939) | 2409 | if (lp->chiptype == TC35815_TX4939) |
2857 | txctl &= ~Tx_EnLCarr; | 2410 | txctl &= ~Tx_EnLCarr; |
2858 | #ifdef WORKAROUND_LOSTCAR | 2411 | #ifdef WORKAROUND_LOSTCAR |
2859 | /* WORKAROUND: ignore LostCrS in full duplex operation */ | 2412 | /* WORKAROUND: ignore LostCrS in full duplex operation */ |
2860 | if ((lp->timer_state != asleep && lp->timer_state != lcheck) || | 2413 | if (!lp->phy_dev || !lp->link || lp->duplex == DUPLEX_FULL) |
2861 | lp->fullduplex) | ||
2862 | txctl &= ~Tx_EnLCarr; | 2414 | txctl &= ~Tx_EnLCarr; |
2863 | #endif | 2415 | #endif |
2864 | #endif /* !NO_CHECK_CARRIER */ | 2416 | #endif /* !NO_CHECK_CARRIER */ |
@@ -2879,8 +2431,9 @@ static int tc35815_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2879 | if (!netif_running(dev)) | 2431 | if (!netif_running(dev)) |
2880 | return 0; | 2432 | return 0; |
2881 | netif_device_detach(dev); | 2433 | netif_device_detach(dev); |
2434 | if (lp->phy_dev) | ||
2435 | phy_stop(lp->phy_dev); | ||
2882 | spin_lock_irqsave(&lp->lock, flags); | 2436 | spin_lock_irqsave(&lp->lock, flags); |
2883 | del_timer(&lp->timer); /* Kill if running */ | ||
2884 | tc35815_chip_reset(dev); | 2437 | tc35815_chip_reset(dev); |
2885 | spin_unlock_irqrestore(&lp->lock, flags); | 2438 | spin_unlock_irqrestore(&lp->lock, flags); |
2886 | pci_set_power_state(pdev, PCI_D3hot); | 2439 | pci_set_power_state(pdev, PCI_D3hot); |
@@ -2891,15 +2444,14 @@ static int tc35815_resume(struct pci_dev *pdev) | |||
2891 | { | 2444 | { |
2892 | struct net_device *dev = pci_get_drvdata(pdev); | 2445 | struct net_device *dev = pci_get_drvdata(pdev); |
2893 | struct tc35815_local *lp = netdev_priv(dev); | 2446 | struct tc35815_local *lp = netdev_priv(dev); |
2894 | unsigned long flags; | ||
2895 | 2447 | ||
2896 | pci_restore_state(pdev); | 2448 | pci_restore_state(pdev); |
2897 | if (!netif_running(dev)) | 2449 | if (!netif_running(dev)) |
2898 | return 0; | 2450 | return 0; |
2899 | pci_set_power_state(pdev, PCI_D0); | 2451 | pci_set_power_state(pdev, PCI_D0); |
2900 | spin_lock_irqsave(&lp->lock, flags); | ||
2901 | tc35815_restart(dev); | 2452 | tc35815_restart(dev); |
2902 | spin_unlock_irqrestore(&lp->lock, flags); | 2453 | if (lp->phy_dev) |
2454 | phy_start(lp->phy_dev); | ||
2903 | netif_device_attach(dev); | 2455 | netif_device_attach(dev); |
2904 | return 0; | 2456 | return 0; |
2905 | } | 2457 | } |
@@ -2920,8 +2472,6 @@ module_param_named(speed, options.speed, int, 0); | |||
2920 | MODULE_PARM_DESC(speed, "0:auto, 10:10Mbps, 100:100Mbps"); | 2472 | MODULE_PARM_DESC(speed, "0:auto, 10:10Mbps, 100:100Mbps"); |
2921 | module_param_named(duplex, options.duplex, int, 0); | 2473 | module_param_named(duplex, options.duplex, int, 0); |
2922 | MODULE_PARM_DESC(duplex, "0:auto, 1:half, 2:full"); | 2474 | MODULE_PARM_DESC(duplex, "0:auto, 1:half, 2:full"); |
2923 | module_param_named(doforce, options.doforce, int, 0); | ||
2924 | MODULE_PARM_DESC(doforce, "try force link mode if auto-negotiation failed"); | ||
2925 | 2475 | ||
2926 | static int __init tc35815_init_module(void) | 2476 | static int __init tc35815_init_module(void) |
2927 | { | 2477 | { |