diff options
-rw-r--r-- | drivers/net/ethernet/ti/tlan.c | 224 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/tlan.h | 5 |
2 files changed, 134 insertions, 95 deletions
diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 62b19be5183d..6078342fe3f2 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c | |||
@@ -69,10 +69,6 @@ MODULE_AUTHOR("Maintainer: Samuel Chessman <chessman@tux.org>"); | |||
69 | MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters"); | 69 | MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters"); |
70 | MODULE_LICENSE("GPL"); | 70 | MODULE_LICENSE("GPL"); |
71 | 71 | ||
72 | |||
73 | /* Define this to enable Link beat monitoring */ | ||
74 | #undef MONITOR | ||
75 | |||
76 | /* Turn on debugging. See Documentation/networking/tlan.txt for details */ | 72 | /* Turn on debugging. See Documentation/networking/tlan.txt for details */ |
77 | static int debug; | 73 | static int debug; |
78 | module_param(debug, int, 0); | 74 | module_param(debug, int, 0); |
@@ -107,8 +103,10 @@ static struct board { | |||
107 | { "Compaq Netelligent 10/100 TX Embedded UTP", | 103 | { "Compaq Netelligent 10/100 TX Embedded UTP", |
108 | TLAN_ADAPTER_NONE, 0x83 }, | 104 | TLAN_ADAPTER_NONE, 0x83 }, |
109 | { "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 }, | 105 | { "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 }, |
110 | { "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xf8 }, | 106 | { "Olicom OC-2325", TLAN_ADAPTER_ACTIVITY_LED | |
111 | { "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xf8 }, | 107 | TLAN_ADAPTER_UNMANAGED_PHY, 0xf8 }, |
108 | { "Olicom OC-2326", TLAN_ADAPTER_ACTIVITY_LED | | ||
109 | TLAN_ADAPTER_USE_INTERN_10, 0xf8 }, | ||
112 | { "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, | 110 | { "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, |
113 | { "Compaq Netelligent 10 T/2 PCI UTP/coax", TLAN_ADAPTER_NONE, 0x83 }, | 111 | { "Compaq Netelligent 10 T/2 PCI UTP/coax", TLAN_ADAPTER_NONE, 0x83 }, |
114 | { "Compaq NetFlex-3/E", | 112 | { "Compaq NetFlex-3/E", |
@@ -192,9 +190,7 @@ static void tlan_phy_power_up(struct net_device *); | |||
192 | static void tlan_phy_reset(struct net_device *); | 190 | static void tlan_phy_reset(struct net_device *); |
193 | static void tlan_phy_start_link(struct net_device *); | 191 | static void tlan_phy_start_link(struct net_device *); |
194 | static void tlan_phy_finish_auto_neg(struct net_device *); | 192 | static void tlan_phy_finish_auto_neg(struct net_device *); |
195 | #ifdef MONITOR | 193 | static void tlan_phy_monitor(unsigned long); |
196 | static void tlan_phy_monitor(struct net_device *); | ||
197 | #endif | ||
198 | 194 | ||
199 | /* | 195 | /* |
200 | static int tlan_phy_nop(struct net_device *); | 196 | static int tlan_phy_nop(struct net_device *); |
@@ -337,6 +333,7 @@ static void tlan_stop(struct net_device *dev) | |||
337 | { | 333 | { |
338 | struct tlan_priv *priv = netdev_priv(dev); | 334 | struct tlan_priv *priv = netdev_priv(dev); |
339 | 335 | ||
336 | del_timer_sync(&priv->media_timer); | ||
340 | tlan_read_and_clear_stats(dev, TLAN_RECORD); | 337 | tlan_read_and_clear_stats(dev, TLAN_RECORD); |
341 | outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD); | 338 | outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD); |
342 | /* Reset and power down phy */ | 339 | /* Reset and power down phy */ |
@@ -368,8 +365,10 @@ static int tlan_suspend(struct pci_dev *pdev, pm_message_t state) | |||
368 | static int tlan_resume(struct pci_dev *pdev) | 365 | static int tlan_resume(struct pci_dev *pdev) |
369 | { | 366 | { |
370 | struct net_device *dev = pci_get_drvdata(pdev); | 367 | struct net_device *dev = pci_get_drvdata(pdev); |
368 | int rc = pci_enable_device(pdev); | ||
371 | 369 | ||
372 | pci_set_power_state(pdev, PCI_D0); | 370 | if (rc) |
371 | return rc; | ||
373 | pci_restore_state(pdev); | 372 | pci_restore_state(pdev); |
374 | pci_enable_wake(pdev, PCI_D0, 0); | 373 | pci_enable_wake(pdev, PCI_D0, 0); |
375 | netif_device_attach(dev); | 374 | netif_device_attach(dev); |
@@ -781,7 +780,43 @@ static const struct net_device_ops tlan_netdev_ops = { | |||
781 | #endif | 780 | #endif |
782 | }; | 781 | }; |
783 | 782 | ||
783 | static void tlan_get_drvinfo(struct net_device *dev, | ||
784 | struct ethtool_drvinfo *info) | ||
785 | { | ||
786 | struct tlan_priv *priv = netdev_priv(dev); | ||
787 | |||
788 | strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); | ||
789 | if (priv->pci_dev) | ||
790 | strlcpy(info->bus_info, pci_name(priv->pci_dev), | ||
791 | sizeof(info->bus_info)); | ||
792 | else | ||
793 | strlcpy(info->bus_info, "EISA", sizeof(info->bus_info)); | ||
794 | info->eedump_len = TLAN_EEPROM_SIZE; | ||
795 | } | ||
796 | |||
797 | static int tlan_get_eeprom_len(struct net_device *dev) | ||
798 | { | ||
799 | return TLAN_EEPROM_SIZE; | ||
800 | } | ||
801 | |||
802 | static int tlan_get_eeprom(struct net_device *dev, | ||
803 | struct ethtool_eeprom *eeprom, u8 *data) | ||
804 | { | ||
805 | int i; | ||
806 | |||
807 | for (i = 0; i < TLAN_EEPROM_SIZE; i++) | ||
808 | if (tlan_ee_read_byte(dev, i, &data[i])) | ||
809 | return -EIO; | ||
784 | 810 | ||
811 | return 0; | ||
812 | } | ||
813 | |||
814 | static const struct ethtool_ops tlan_ethtool_ops = { | ||
815 | .get_drvinfo = tlan_get_drvinfo, | ||
816 | .get_link = ethtool_op_get_link, | ||
817 | .get_eeprom_len = tlan_get_eeprom_len, | ||
818 | .get_eeprom = tlan_get_eeprom, | ||
819 | }; | ||
785 | 820 | ||
786 | /*************************************************************** | 821 | /*************************************************************** |
787 | * tlan_init | 822 | * tlan_init |
@@ -830,7 +865,7 @@ static int tlan_init(struct net_device *dev) | |||
830 | priv->rx_list_dma + sizeof(struct tlan_list)*TLAN_NUM_RX_LISTS; | 865 | priv->rx_list_dma + sizeof(struct tlan_list)*TLAN_NUM_RX_LISTS; |
831 | 866 | ||
832 | err = 0; | 867 | err = 0; |
833 | for (i = 0; i < 6 ; i++) | 868 | for (i = 0; i < ETH_ALEN; i++) |
834 | err |= tlan_ee_read_byte(dev, | 869 | err |= tlan_ee_read_byte(dev, |
835 | (u8) priv->adapter->addr_ofs + i, | 870 | (u8) priv->adapter->addr_ofs + i, |
836 | (u8 *) &dev->dev_addr[i]); | 871 | (u8 *) &dev->dev_addr[i]); |
@@ -838,12 +873,20 @@ static int tlan_init(struct net_device *dev) | |||
838 | pr_err("%s: Error reading MAC from eeprom: %d\n", | 873 | pr_err("%s: Error reading MAC from eeprom: %d\n", |
839 | dev->name, err); | 874 | dev->name, err); |
840 | } | 875 | } |
841 | dev->addr_len = 6; | 876 | /* Olicom OC-2325/OC-2326 have the address byte-swapped */ |
877 | if (priv->adapter->addr_ofs == 0xf8) { | ||
878 | for (i = 0; i < ETH_ALEN; i += 2) { | ||
879 | char tmp = dev->dev_addr[i]; | ||
880 | dev->dev_addr[i] = dev->dev_addr[i + 1]; | ||
881 | dev->dev_addr[i + 1] = tmp; | ||
882 | } | ||
883 | } | ||
842 | 884 | ||
843 | netif_carrier_off(dev); | 885 | netif_carrier_off(dev); |
844 | 886 | ||
845 | /* Device methods */ | 887 | /* Device methods */ |
846 | dev->netdev_ops = &tlan_netdev_ops; | 888 | dev->netdev_ops = &tlan_netdev_ops; |
889 | dev->ethtool_ops = &tlan_ethtool_ops; | ||
847 | dev->watchdog_timeo = TX_TIMEOUT; | 890 | dev->watchdog_timeo = TX_TIMEOUT; |
848 | 891 | ||
849 | return 0; | 892 | return 0; |
@@ -886,6 +929,7 @@ static int tlan_open(struct net_device *dev) | |||
886 | } | 929 | } |
887 | 930 | ||
888 | init_timer(&priv->timer); | 931 | init_timer(&priv->timer); |
932 | init_timer(&priv->media_timer); | ||
889 | 933 | ||
890 | tlan_start(dev); | 934 | tlan_start(dev); |
891 | 935 | ||
@@ -1156,9 +1200,6 @@ static irqreturn_t tlan_handle_interrupt(int irq, void *dev_id) | |||
1156 | 1200 | ||
1157 | static int tlan_close(struct net_device *dev) | 1201 | static int tlan_close(struct net_device *dev) |
1158 | { | 1202 | { |
1159 | struct tlan_priv *priv = netdev_priv(dev); | ||
1160 | |||
1161 | priv->neg_be_verbose = 0; | ||
1162 | tlan_stop(dev); | 1203 | tlan_stop(dev); |
1163 | 1204 | ||
1164 | free_irq(dev->irq, dev); | 1205 | free_irq(dev->irq, dev); |
@@ -1808,11 +1849,6 @@ static void tlan_timer(unsigned long data) | |||
1808 | priv->timer.function = NULL; | 1849 | priv->timer.function = NULL; |
1809 | 1850 | ||
1810 | switch (priv->timer_type) { | 1851 | switch (priv->timer_type) { |
1811 | #ifdef MONITOR | ||
1812 | case TLAN_TIMER_LINK_BEAT: | ||
1813 | tlan_phy_monitor(dev); | ||
1814 | break; | ||
1815 | #endif | ||
1816 | case TLAN_TIMER_PHY_PDOWN: | 1852 | case TLAN_TIMER_PHY_PDOWN: |
1817 | tlan_phy_power_down(dev); | 1853 | tlan_phy_power_down(dev); |
1818 | break; | 1854 | break; |
@@ -1856,8 +1892,6 @@ static void tlan_timer(unsigned long data) | |||
1856 | } | 1892 | } |
1857 | 1893 | ||
1858 | 1894 | ||
1859 | |||
1860 | |||
1861 | /***************************************************************************** | 1895 | /***************************************************************************** |
1862 | ****************************************************************************** | 1896 | ****************************************************************************** |
1863 | 1897 | ||
@@ -2205,7 +2239,9 @@ tlan_reset_adapter(struct net_device *dev) | |||
2205 | } | 2239 | } |
2206 | } | 2240 | } |
2207 | 2241 | ||
2208 | if (priv->phy_num == 0) | 2242 | /* don't power down internal PHY if we're going to use it */ |
2243 | if (priv->phy_num == 0 || | ||
2244 | (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10)) | ||
2209 | data |= TLAN_NET_CFG_PHY_EN; | 2245 | data |= TLAN_NET_CFG_PHY_EN; |
2210 | tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data); | 2246 | tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data); |
2211 | 2247 | ||
@@ -2255,42 +2291,39 @@ tlan_finish_reset(struct net_device *dev) | |||
2255 | tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status); | 2291 | tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status); |
2256 | udelay(1000); | 2292 | udelay(1000); |
2257 | tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status); | 2293 | tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status); |
2258 | if ((status & MII_GS_LINK) && | 2294 | if (status & MII_GS_LINK) { |
2259 | /* We only support link info on Nat.Sem. PHY's */ | 2295 | /* We only support link info on Nat.Sem. PHY's */ |
2260 | (tlphy_id1 == NAT_SEM_ID1) && | 2296 | if ((tlphy_id1 == NAT_SEM_ID1) && |
2261 | (tlphy_id2 == NAT_SEM_ID2)) { | 2297 | (tlphy_id2 == NAT_SEM_ID2)) { |
2262 | tlan_mii_read_reg(dev, phy, MII_AN_LPA, &partner); | 2298 | tlan_mii_read_reg(dev, phy, MII_AN_LPA, |
2263 | tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, &tlphy_par); | 2299 | &partner); |
2264 | 2300 | tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, | |
2265 | netdev_info(dev, | 2301 | &tlphy_par); |
2266 | "Link active with %s %uMbps %s-Duplex\n", | 2302 | |
2267 | !(tlphy_par & TLAN_PHY_AN_EN_STAT) | 2303 | netdev_info(dev, |
2268 | ? "forced" : "Autonegotiation enabled,", | 2304 | "Link active, %s %uMbps %s-Duplex\n", |
2269 | tlphy_par & TLAN_PHY_SPEED_100 | 2305 | !(tlphy_par & TLAN_PHY_AN_EN_STAT) |
2270 | ? 100 : 10, | 2306 | ? "forced" : "Autonegotiation enabled,", |
2271 | tlphy_par & TLAN_PHY_DUPLEX_FULL | 2307 | tlphy_par & TLAN_PHY_SPEED_100 |
2272 | ? "Full" : "Half"); | 2308 | ? 100 : 10, |
2273 | 2309 | tlphy_par & TLAN_PHY_DUPLEX_FULL | |
2274 | if (tlphy_par & TLAN_PHY_AN_EN_STAT) { | 2310 | ? "Full" : "Half"); |
2275 | netdev_info(dev, "Partner capability:"); | 2311 | |
2276 | for (i = 5; i < 10; i++) | 2312 | if (tlphy_par & TLAN_PHY_AN_EN_STAT) { |
2277 | if (partner & (1 << i)) | 2313 | netdev_info(dev, "Partner capability:"); |
2278 | pr_cont(" %s", media[i-5]); | 2314 | for (i = 5; i < 10; i++) |
2279 | pr_cont("\n"); | 2315 | if (partner & (1 << i)) |
2280 | } | 2316 | pr_cont(" %s", |
2281 | 2317 | media[i-5]); | |
2282 | tlan_dio_write8(dev->base_addr, TLAN_LED_REG, | 2318 | pr_cont("\n"); |
2283 | TLAN_LED_LINK); | 2319 | } |
2284 | #ifdef MONITOR | 2320 | } else |
2285 | /* We have link beat..for now anyway */ | 2321 | netdev_info(dev, "Link active\n"); |
2286 | priv->link = 1; | 2322 | /* Enabling link beat monitoring */ |
2287 | /*Enabling link beat monitoring */ | 2323 | priv->media_timer.function = tlan_phy_monitor; |
2288 | tlan_set_timer(dev, (10*HZ), TLAN_TIMER_LINK_BEAT); | 2324 | priv->media_timer.data = (unsigned long) dev; |
2289 | #endif | 2325 | priv->media_timer.expires = jiffies + HZ; |
2290 | } else if (status & MII_GS_LINK) { | 2326 | add_timer(&priv->media_timer); |
2291 | netdev_info(dev, "Link active\n"); | ||
2292 | tlan_dio_write8(dev->base_addr, TLAN_LED_REG, | ||
2293 | TLAN_LED_LINK); | ||
2294 | } | 2327 | } |
2295 | } | 2328 | } |
2296 | 2329 | ||
@@ -2312,6 +2345,7 @@ tlan_finish_reset(struct net_device *dev) | |||
2312 | dev->base_addr + TLAN_HOST_CMD + 1); | 2345 | dev->base_addr + TLAN_HOST_CMD + 1); |
2313 | outl(priv->rx_list_dma, dev->base_addr + TLAN_CH_PARM); | 2346 | outl(priv->rx_list_dma, dev->base_addr + TLAN_CH_PARM); |
2314 | outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD); | 2347 | outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD); |
2348 | tlan_dio_write8(dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK); | ||
2315 | netif_carrier_on(dev); | 2349 | netif_carrier_on(dev); |
2316 | } else { | 2350 | } else { |
2317 | netdev_info(dev, "Link inactive, will retry in 10 secs...\n"); | 2351 | netdev_info(dev, "Link inactive, will retry in 10 secs...\n"); |
@@ -2494,9 +2528,10 @@ static void tlan_phy_power_down(struct net_device *dev) | |||
2494 | value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE; | 2528 | value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE; |
2495 | tlan_mii_sync(dev->base_addr); | 2529 | tlan_mii_sync(dev->base_addr); |
2496 | tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value); | 2530 | tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value); |
2497 | if ((priv->phy_num == 0) && | 2531 | if ((priv->phy_num == 0) && (priv->phy[1] != TLAN_PHY_NONE)) { |
2498 | (priv->phy[1] != TLAN_PHY_NONE) && | 2532 | /* if using internal PHY, the external PHY must be powered on */ |
2499 | (!(priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10))) { | 2533 | if (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) |
2534 | value = MII_GC_ISOLATE; /* just isolate it from MII */ | ||
2500 | tlan_mii_sync(dev->base_addr); | 2535 | tlan_mii_sync(dev->base_addr); |
2501 | tlan_mii_write_reg(dev, priv->phy[1], MII_GEN_CTL, value); | 2536 | tlan_mii_write_reg(dev, priv->phy[1], MII_GEN_CTL, value); |
2502 | } | 2537 | } |
@@ -2538,6 +2573,7 @@ static void tlan_phy_reset(struct net_device *dev) | |||
2538 | struct tlan_priv *priv = netdev_priv(dev); | 2573 | struct tlan_priv *priv = netdev_priv(dev); |
2539 | u16 phy; | 2574 | u16 phy; |
2540 | u16 value; | 2575 | u16 value; |
2576 | unsigned long timeout = jiffies + HZ; | ||
2541 | 2577 | ||
2542 | phy = priv->phy[priv->phy_num]; | 2578 | phy = priv->phy[priv->phy_num]; |
2543 | 2579 | ||
@@ -2545,9 +2581,13 @@ static void tlan_phy_reset(struct net_device *dev) | |||
2545 | tlan_mii_sync(dev->base_addr); | 2581 | tlan_mii_sync(dev->base_addr); |
2546 | value = MII_GC_LOOPBK | MII_GC_RESET; | 2582 | value = MII_GC_LOOPBK | MII_GC_RESET; |
2547 | tlan_mii_write_reg(dev, phy, MII_GEN_CTL, value); | 2583 | tlan_mii_write_reg(dev, phy, MII_GEN_CTL, value); |
2548 | tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value); | 2584 | do { |
2549 | while (value & MII_GC_RESET) | ||
2550 | tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value); | 2585 | tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value); |
2586 | if (time_after(jiffies, timeout)) { | ||
2587 | netdev_err(dev, "PHY reset timeout\n"); | ||
2588 | return; | ||
2589 | } | ||
2590 | } while (value & MII_GC_RESET); | ||
2551 | 2591 | ||
2552 | /* Wait for 500 ms and initialize. | 2592 | /* Wait for 500 ms and initialize. |
2553 | * I don't remember why I wait this long. | 2593 | * I don't remember why I wait this long. |
@@ -2653,7 +2693,6 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev) | |||
2653 | struct tlan_priv *priv = netdev_priv(dev); | 2693 | struct tlan_priv *priv = netdev_priv(dev); |
2654 | u16 an_adv; | 2694 | u16 an_adv; |
2655 | u16 an_lpa; | 2695 | u16 an_lpa; |
2656 | u16 data; | ||
2657 | u16 mode; | 2696 | u16 mode; |
2658 | u16 phy; | 2697 | u16 phy; |
2659 | u16 status; | 2698 | u16 status; |
@@ -2668,13 +2707,7 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev) | |||
2668 | /* Wait for 8 sec to give the process | 2707 | /* Wait for 8 sec to give the process |
2669 | * more time. Perhaps we should fail after a while. | 2708 | * more time. Perhaps we should fail after a while. |
2670 | */ | 2709 | */ |
2671 | if (!priv->neg_be_verbose++) { | 2710 | tlan_set_timer(dev, 2 * HZ, TLAN_TIMER_PHY_FINISH_AN); |
2672 | pr_info("Giving autonegotiation more time.\n"); | ||
2673 | pr_info("Please check that your adapter has\n"); | ||
2674 | pr_info("been properly connected to a HUB or Switch.\n"); | ||
2675 | pr_info("Trying to establish link in the background...\n"); | ||
2676 | } | ||
2677 | tlan_set_timer(dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN); | ||
2678 | return; | 2711 | return; |
2679 | } | 2712 | } |
2680 | 2713 | ||
@@ -2687,13 +2720,11 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev) | |||
2687 | else if (!(mode & 0x0080) && (mode & 0x0040)) | 2720 | else if (!(mode & 0x0080) && (mode & 0x0040)) |
2688 | priv->tlan_full_duplex = true; | 2721 | priv->tlan_full_duplex = true; |
2689 | 2722 | ||
2723 | /* switch to internal PHY for 10 Mbps */ | ||
2690 | if ((!(mode & 0x0180)) && | 2724 | if ((!(mode & 0x0180)) && |
2691 | (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) && | 2725 | (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) && |
2692 | (priv->phy_num != 0)) { | 2726 | (priv->phy_num != 0)) { |
2693 | priv->phy_num = 0; | 2727 | priv->phy_num = 0; |
2694 | data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | ||
2695 | | TLAN_NET_CFG_PHY_EN; | ||
2696 | tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data); | ||
2697 | tlan_set_timer(dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN); | 2728 | tlan_set_timer(dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN); |
2698 | return; | 2729 | return; |
2699 | } | 2730 | } |
@@ -2717,7 +2748,6 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev) | |||
2717 | 2748 | ||
2718 | } | 2749 | } |
2719 | 2750 | ||
2720 | #ifdef MONITOR | ||
2721 | 2751 | ||
2722 | /********************************************************************* | 2752 | /********************************************************************* |
2723 | * | 2753 | * |
@@ -2727,18 +2757,18 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev) | |||
2727 | * None | 2757 | * None |
2728 | * | 2758 | * |
2729 | * Params: | 2759 | * Params: |
2730 | * dev The device structure of this device. | 2760 | * data The device structure of this device. |
2731 | * | 2761 | * |
2732 | * | 2762 | * |
2733 | * This function monitors PHY condition by reading the status | 2763 | * This function monitors PHY condition by reading the status |
2734 | * register via the MII bus. This can be used to give info | 2764 | * register via the MII bus, controls LINK LED and notifies the |
2735 | * about link changes (up/down), and possible switch to alternate | 2765 | * kernel about link state. |
2736 | * media. | ||
2737 | * | 2766 | * |
2738 | *******************************************************************/ | 2767 | *******************************************************************/ |
2739 | 2768 | ||
2740 | void tlan_phy_monitor(struct net_device *dev) | 2769 | static void tlan_phy_monitor(unsigned long data) |
2741 | { | 2770 | { |
2771 | struct net_device *dev = (struct net_device *) data; | ||
2742 | struct tlan_priv *priv = netdev_priv(dev); | 2772 | struct tlan_priv *priv = netdev_priv(dev); |
2743 | u16 phy; | 2773 | u16 phy; |
2744 | u16 phy_status; | 2774 | u16 phy_status; |
@@ -2750,30 +2780,40 @@ void tlan_phy_monitor(struct net_device *dev) | |||
2750 | 2780 | ||
2751 | /* Check if link has been lost */ | 2781 | /* Check if link has been lost */ |
2752 | if (!(phy_status & MII_GS_LINK)) { | 2782 | if (!(phy_status & MII_GS_LINK)) { |
2753 | if (priv->link) { | 2783 | if (netif_carrier_ok(dev)) { |
2754 | priv->link = 0; | ||
2755 | printk(KERN_DEBUG "TLAN: %s has lost link\n", | 2784 | printk(KERN_DEBUG "TLAN: %s has lost link\n", |
2756 | dev->name); | 2785 | dev->name); |
2786 | tlan_dio_write8(dev->base_addr, TLAN_LED_REG, 0); | ||
2757 | netif_carrier_off(dev); | 2787 | netif_carrier_off(dev); |
2758 | tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT); | 2788 | if (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) { |
2759 | return; | 2789 | /* power down internal PHY */ |
2790 | u16 data = MII_GC_PDOWN | MII_GC_LOOPBK | | ||
2791 | MII_GC_ISOLATE; | ||
2792 | |||
2793 | tlan_mii_sync(dev->base_addr); | ||
2794 | tlan_mii_write_reg(dev, priv->phy[0], | ||
2795 | MII_GEN_CTL, data); | ||
2796 | /* set to external PHY */ | ||
2797 | priv->phy_num = 1; | ||
2798 | /* restart autonegotiation */ | ||
2799 | tlan_set_timer(dev, 4 * HZ / 10, | ||
2800 | TLAN_TIMER_PHY_PDOWN); | ||
2801 | return; | ||
2802 | } | ||
2760 | } | 2803 | } |
2761 | } | 2804 | } |
2762 | 2805 | ||
2763 | /* Link restablished? */ | 2806 | /* Link restablished? */ |
2764 | if ((phy_status & MII_GS_LINK) && !priv->link) { | 2807 | if ((phy_status & MII_GS_LINK) && !netif_carrier_ok(dev)) { |
2765 | priv->link = 1; | 2808 | tlan_dio_write8(dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK); |
2766 | printk(KERN_DEBUG "TLAN: %s has reestablished link\n", | 2809 | printk(KERN_DEBUG "TLAN: %s has reestablished link\n", |
2767 | dev->name); | 2810 | dev->name); |
2768 | netif_carrier_on(dev); | 2811 | netif_carrier_on(dev); |
2769 | } | 2812 | } |
2770 | 2813 | priv->media_timer.expires = jiffies + HZ; | |
2771 | /* Setup a new monitor */ | 2814 | add_timer(&priv->media_timer); |
2772 | tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT); | ||
2773 | } | 2815 | } |
2774 | 2816 | ||
2775 | #endif /* MONITOR */ | ||
2776 | |||
2777 | 2817 | ||
2778 | /***************************************************************************** | 2818 | /***************************************************************************** |
2779 | ****************************************************************************** | 2819 | ****************************************************************************** |
diff --git a/drivers/net/ethernet/ti/tlan.h b/drivers/net/ethernet/ti/tlan.h index 2eb33a250788..e9928411827e 100644 --- a/drivers/net/ethernet/ti/tlan.h +++ b/drivers/net/ethernet/ti/tlan.h | |||
@@ -195,6 +195,7 @@ struct tlan_priv { | |||
195 | u32 timer_set_at; | 195 | u32 timer_set_at; |
196 | u32 timer_type; | 196 | u32 timer_type; |
197 | struct timer_list timer; | 197 | struct timer_list timer; |
198 | struct timer_list media_timer; | ||
198 | struct board *adapter; | 199 | struct board *adapter; |
199 | u32 adapter_rev; | 200 | u32 adapter_rev; |
200 | u32 aui; | 201 | u32 aui; |
@@ -206,9 +207,7 @@ struct tlan_priv { | |||
206 | u8 tlan_rev; | 207 | u8 tlan_rev; |
207 | u8 tlan_full_duplex; | 208 | u8 tlan_full_duplex; |
208 | spinlock_t lock; | 209 | spinlock_t lock; |
209 | u8 link; | ||
210 | struct work_struct tlan_tqueue; | 210 | struct work_struct tlan_tqueue; |
211 | u8 neg_be_verbose; | ||
212 | }; | 211 | }; |
213 | 212 | ||
214 | 213 | ||
@@ -219,7 +218,6 @@ struct tlan_priv { | |||
219 | * | 218 | * |
220 | ****************************************************************/ | 219 | ****************************************************************/ |
221 | 220 | ||
222 | #define TLAN_TIMER_LINK_BEAT 1 | ||
223 | #define TLAN_TIMER_ACTIVITY 2 | 221 | #define TLAN_TIMER_ACTIVITY 2 |
224 | #define TLAN_TIMER_PHY_PDOWN 3 | 222 | #define TLAN_TIMER_PHY_PDOWN 3 |
225 | #define TLAN_TIMER_PHY_PUP 4 | 223 | #define TLAN_TIMER_PHY_PUP 4 |
@@ -241,6 +239,7 @@ struct tlan_priv { | |||
241 | #define TLAN_EEPROM_ACK 0 | 239 | #define TLAN_EEPROM_ACK 0 |
242 | #define TLAN_EEPROM_STOP 1 | 240 | #define TLAN_EEPROM_STOP 1 |
243 | 241 | ||
242 | #define TLAN_EEPROM_SIZE 256 | ||
244 | 243 | ||
245 | 244 | ||
246 | 245 | ||