diff options
author | Ondrej Zary <linux@rainbow-software.org> | 2014-06-30 12:38:28 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-07-07 20:06:51 -0400 |
commit | c0a87c22d3f098517473c60c709478db80fcc544 (patch) | |
tree | 4b1337ac823f450427cfd77fac1a8d37e66bd912 | |
parent | eb522bb4e0dc4800d3cd2eedc4288f90022293fa (diff) |
tlan: Enable link monitoring
Enable old link monitoring code and modify it:
- control LINK LED
- use separate timer so it does not interfere with ACT LED
Tested with Olicom OC-2326.
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/ti/tlan.c | 115 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/tlan.h | 3 |
2 files changed, 49 insertions, 69 deletions
diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 2199fc8e5003..ccde7482d404 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); |
@@ -194,9 +190,7 @@ static void tlan_phy_power_up(struct net_device *); | |||
194 | static void tlan_phy_reset(struct net_device *); | 190 | static void tlan_phy_reset(struct net_device *); |
195 | static void tlan_phy_start_link(struct net_device *); | 191 | static void tlan_phy_start_link(struct net_device *); |
196 | static void tlan_phy_finish_auto_neg(struct net_device *); | 192 | static void tlan_phy_finish_auto_neg(struct net_device *); |
197 | #ifdef MONITOR | 193 | static void tlan_phy_monitor(unsigned long); |
198 | static void tlan_phy_monitor(struct net_device *); | ||
199 | #endif | ||
200 | 194 | ||
201 | /* | 195 | /* |
202 | static int tlan_phy_nop(struct net_device *); | 196 | static int tlan_phy_nop(struct net_device *); |
@@ -339,6 +333,7 @@ static void tlan_stop(struct net_device *dev) | |||
339 | { | 333 | { |
340 | struct tlan_priv *priv = netdev_priv(dev); | 334 | struct tlan_priv *priv = netdev_priv(dev); |
341 | 335 | ||
336 | del_timer_sync(&priv->media_timer); | ||
342 | tlan_read_and_clear_stats(dev, TLAN_RECORD); | 337 | tlan_read_and_clear_stats(dev, TLAN_RECORD); |
343 | outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD); | 338 | outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD); |
344 | /* Reset and power down phy */ | 339 | /* Reset and power down phy */ |
@@ -888,6 +883,7 @@ static int tlan_open(struct net_device *dev) | |||
888 | } | 883 | } |
889 | 884 | ||
890 | init_timer(&priv->timer); | 885 | init_timer(&priv->timer); |
886 | init_timer(&priv->media_timer); | ||
891 | 887 | ||
892 | tlan_start(dev); | 888 | tlan_start(dev); |
893 | 889 | ||
@@ -1810,11 +1806,6 @@ static void tlan_timer(unsigned long data) | |||
1810 | priv->timer.function = NULL; | 1806 | priv->timer.function = NULL; |
1811 | 1807 | ||
1812 | switch (priv->timer_type) { | 1808 | switch (priv->timer_type) { |
1813 | #ifdef MONITOR | ||
1814 | case TLAN_TIMER_LINK_BEAT: | ||
1815 | tlan_phy_monitor(dev); | ||
1816 | break; | ||
1817 | #endif | ||
1818 | case TLAN_TIMER_PHY_PDOWN: | 1809 | case TLAN_TIMER_PHY_PDOWN: |
1819 | tlan_phy_power_down(dev); | 1810 | tlan_phy_power_down(dev); |
1820 | break; | 1811 | break; |
@@ -1858,8 +1849,6 @@ static void tlan_timer(unsigned long data) | |||
1858 | } | 1849 | } |
1859 | 1850 | ||
1860 | 1851 | ||
1861 | |||
1862 | |||
1863 | /***************************************************************************** | 1852 | /***************************************************************************** |
1864 | ****************************************************************************** | 1853 | ****************************************************************************** |
1865 | 1854 | ||
@@ -2257,42 +2246,39 @@ tlan_finish_reset(struct net_device *dev) | |||
2257 | tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status); | 2246 | tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status); |
2258 | udelay(1000); | 2247 | udelay(1000); |
2259 | tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status); | 2248 | tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status); |
2260 | if ((status & MII_GS_LINK) && | 2249 | if (status & MII_GS_LINK) { |
2261 | /* We only support link info on Nat.Sem. PHY's */ | 2250 | /* We only support link info on Nat.Sem. PHY's */ |
2262 | (tlphy_id1 == NAT_SEM_ID1) && | 2251 | if ((tlphy_id1 == NAT_SEM_ID1) && |
2263 | (tlphy_id2 == NAT_SEM_ID2)) { | 2252 | (tlphy_id2 == NAT_SEM_ID2)) { |
2264 | tlan_mii_read_reg(dev, phy, MII_AN_LPA, &partner); | 2253 | tlan_mii_read_reg(dev, phy, MII_AN_LPA, |
2265 | tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, &tlphy_par); | 2254 | &partner); |
2266 | 2255 | tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, | |
2267 | netdev_info(dev, | 2256 | &tlphy_par); |
2268 | "Link active with %s %uMbps %s-Duplex\n", | 2257 | |
2269 | !(tlphy_par & TLAN_PHY_AN_EN_STAT) | 2258 | netdev_info(dev, |
2270 | ? "forced" : "Autonegotiation enabled,", | 2259 | "Link active, %s %uMbps %s-Duplex\n", |
2271 | tlphy_par & TLAN_PHY_SPEED_100 | 2260 | !(tlphy_par & TLAN_PHY_AN_EN_STAT) |
2272 | ? 100 : 10, | 2261 | ? "forced" : "Autonegotiation enabled,", |
2273 | tlphy_par & TLAN_PHY_DUPLEX_FULL | 2262 | tlphy_par & TLAN_PHY_SPEED_100 |
2274 | ? "Full" : "Half"); | 2263 | ? 100 : 10, |
2275 | 2264 | tlphy_par & TLAN_PHY_DUPLEX_FULL | |
2276 | if (tlphy_par & TLAN_PHY_AN_EN_STAT) { | 2265 | ? "Full" : "Half"); |
2277 | netdev_info(dev, "Partner capability:"); | 2266 | |
2278 | for (i = 5; i < 10; i++) | 2267 | if (tlphy_par & TLAN_PHY_AN_EN_STAT) { |
2279 | if (partner & (1 << i)) | 2268 | netdev_info(dev, "Partner capability:"); |
2280 | pr_cont(" %s", media[i-5]); | 2269 | for (i = 5; i < 10; i++) |
2281 | pr_cont("\n"); | 2270 | if (partner & (1 << i)) |
2282 | } | 2271 | pr_cont(" %s", |
2283 | 2272 | media[i-5]); | |
2284 | tlan_dio_write8(dev->base_addr, TLAN_LED_REG, | 2273 | pr_cont("\n"); |
2285 | TLAN_LED_LINK); | 2274 | } |
2286 | #ifdef MONITOR | 2275 | } else |
2287 | /* We have link beat..for now anyway */ | 2276 | netdev_info(dev, "Link active\n"); |
2288 | priv->link = 1; | 2277 | /* Enabling link beat monitoring */ |
2289 | /*Enabling link beat monitoring */ | 2278 | priv->media_timer.function = tlan_phy_monitor; |
2290 | tlan_set_timer(dev, (10*HZ), TLAN_TIMER_LINK_BEAT); | 2279 | priv->media_timer.data = (unsigned long) dev; |
2291 | #endif | 2280 | priv->media_timer.expires = jiffies + HZ; |
2292 | } else if (status & MII_GS_LINK) { | 2281 | add_timer(&priv->media_timer); |
2293 | netdev_info(dev, "Link active\n"); | ||
2294 | tlan_dio_write8(dev->base_addr, TLAN_LED_REG, | ||
2295 | TLAN_LED_LINK); | ||
2296 | } | 2282 | } |
2297 | } | 2283 | } |
2298 | 2284 | ||
@@ -2314,6 +2300,7 @@ tlan_finish_reset(struct net_device *dev) | |||
2314 | dev->base_addr + TLAN_HOST_CMD + 1); | 2300 | dev->base_addr + TLAN_HOST_CMD + 1); |
2315 | outl(priv->rx_list_dma, dev->base_addr + TLAN_CH_PARM); | 2301 | outl(priv->rx_list_dma, dev->base_addr + TLAN_CH_PARM); |
2316 | outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD); | 2302 | outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD); |
2303 | tlan_dio_write8(dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK); | ||
2317 | netif_carrier_on(dev); | 2304 | netif_carrier_on(dev); |
2318 | } else { | 2305 | } else { |
2319 | netdev_info(dev, "Link inactive, will retry in 10 secs...\n"); | 2306 | netdev_info(dev, "Link inactive, will retry in 10 secs...\n"); |
@@ -2719,7 +2706,6 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev) | |||
2719 | 2706 | ||
2720 | } | 2707 | } |
2721 | 2708 | ||
2722 | #ifdef MONITOR | ||
2723 | 2709 | ||
2724 | /********************************************************************* | 2710 | /********************************************************************* |
2725 | * | 2711 | * |
@@ -2729,18 +2715,18 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev) | |||
2729 | * None | 2715 | * None |
2730 | * | 2716 | * |
2731 | * Params: | 2717 | * Params: |
2732 | * dev The device structure of this device. | 2718 | * data The device structure of this device. |
2733 | * | 2719 | * |
2734 | * | 2720 | * |
2735 | * This function monitors PHY condition by reading the status | 2721 | * This function monitors PHY condition by reading the status |
2736 | * register via the MII bus. This can be used to give info | 2722 | * register via the MII bus, controls LINK LED and notifies the |
2737 | * about link changes (up/down), and possible switch to alternate | 2723 | * kernel about link state. |
2738 | * media. | ||
2739 | * | 2724 | * |
2740 | *******************************************************************/ | 2725 | *******************************************************************/ |
2741 | 2726 | ||
2742 | void tlan_phy_monitor(struct net_device *dev) | 2727 | static void tlan_phy_monitor(unsigned long data) |
2743 | { | 2728 | { |
2729 | struct net_device *dev = (struct net_device *) data; | ||
2744 | struct tlan_priv *priv = netdev_priv(dev); | 2730 | struct tlan_priv *priv = netdev_priv(dev); |
2745 | u16 phy; | 2731 | u16 phy; |
2746 | u16 phy_status; | 2732 | u16 phy_status; |
@@ -2752,30 +2738,25 @@ void tlan_phy_monitor(struct net_device *dev) | |||
2752 | 2738 | ||
2753 | /* Check if link has been lost */ | 2739 | /* Check if link has been lost */ |
2754 | if (!(phy_status & MII_GS_LINK)) { | 2740 | if (!(phy_status & MII_GS_LINK)) { |
2755 | if (priv->link) { | 2741 | if (netif_carrier_ok(dev)) { |
2756 | priv->link = 0; | ||
2757 | printk(KERN_DEBUG "TLAN: %s has lost link\n", | 2742 | printk(KERN_DEBUG "TLAN: %s has lost link\n", |
2758 | dev->name); | 2743 | dev->name); |
2744 | tlan_dio_write8(dev->base_addr, TLAN_LED_REG, 0); | ||
2759 | netif_carrier_off(dev); | 2745 | netif_carrier_off(dev); |
2760 | tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT); | ||
2761 | return; | ||
2762 | } | 2746 | } |
2763 | } | 2747 | } |
2764 | 2748 | ||
2765 | /* Link restablished? */ | 2749 | /* Link restablished? */ |
2766 | if ((phy_status & MII_GS_LINK) && !priv->link) { | 2750 | if ((phy_status & MII_GS_LINK) && !netif_carrier_ok(dev)) { |
2767 | priv->link = 1; | 2751 | tlan_dio_write8(dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK); |
2768 | printk(KERN_DEBUG "TLAN: %s has reestablished link\n", | 2752 | printk(KERN_DEBUG "TLAN: %s has reestablished link\n", |
2769 | dev->name); | 2753 | dev->name); |
2770 | netif_carrier_on(dev); | 2754 | netif_carrier_on(dev); |
2771 | } | 2755 | } |
2772 | 2756 | priv->media_timer.expires = jiffies + HZ; | |
2773 | /* Setup a new monitor */ | 2757 | add_timer(&priv->media_timer); |
2774 | tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT); | ||
2775 | } | 2758 | } |
2776 | 2759 | ||
2777 | #endif /* MONITOR */ | ||
2778 | |||
2779 | 2760 | ||
2780 | /***************************************************************************** | 2761 | /***************************************************************************** |
2781 | ****************************************************************************** | 2762 | ****************************************************************************** |
diff --git a/drivers/net/ethernet/ti/tlan.h b/drivers/net/ethernet/ti/tlan.h index 2eb33a250788..4ced9053d9f4 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,7 +207,6 @@ 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; | 211 | u8 neg_be_verbose; |
212 | }; | 212 | }; |
@@ -219,7 +219,6 @@ struct tlan_priv { | |||
219 | * | 219 | * |
220 | ****************************************************************/ | 220 | ****************************************************************/ |
221 | 221 | ||
222 | #define TLAN_TIMER_LINK_BEAT 1 | ||
223 | #define TLAN_TIMER_ACTIVITY 2 | 222 | #define TLAN_TIMER_ACTIVITY 2 |
224 | #define TLAN_TIMER_PHY_PDOWN 3 | 223 | #define TLAN_TIMER_PHY_PDOWN 3 |
225 | #define TLAN_TIMER_PHY_PUP 4 | 224 | #define TLAN_TIMER_PHY_PUP 4 |