diff options
author | David S. Miller <davem@davemloft.net> | 2014-07-07 20:07:05 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-07-07 20:07:05 -0400 |
commit | 0b88e7042a221a0318d726017b0f97aa42066826 (patch) | |
tree | d7bde139634d8d90cddaa730abe37a8bf17e2aeb | |
parent | b98fe24ca7d0effdd4c47a9f681d9e4f10442827 (diff) | |
parent | 9162e7e5197e14c7488c54980d7cbdc2071f8085 (diff) |
Merge branch 'tlan-next'
Ondrej Zary says:
====================
tlan: Link handling improvements and Olicom fixes
This patch series improves link handling in tlan driver, allowing the
cable to be (un)plugged anytime and NetworkManager to work properly.
Also there are some bugfixes related to Olicom OC-2326 card.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-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 | ||