aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOndrej Zary <linux@rainbow-software.org>2014-06-30 12:38:28 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-07 20:06:51 -0400
commitc0a87c22d3f098517473c60c709478db80fcc544 (patch)
tree4b1337ac823f450427cfd77fac1a8d37e66bd912
parenteb522bb4e0dc4800d3cd2eedc4288f90022293fa (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.c115
-rw-r--r--drivers/net/ethernet/ti/tlan.h3
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>");
69MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters"); 69MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
70MODULE_LICENSE("GPL"); 70MODULE_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 */
77static int debug; 73static int debug;
78module_param(debug, int, 0); 74module_param(debug, int, 0);
@@ -194,9 +190,7 @@ static void tlan_phy_power_up(struct net_device *);
194static void tlan_phy_reset(struct net_device *); 190static void tlan_phy_reset(struct net_device *);
195static void tlan_phy_start_link(struct net_device *); 191static void tlan_phy_start_link(struct net_device *);
196static void tlan_phy_finish_auto_neg(struct net_device *); 192static void tlan_phy_finish_auto_neg(struct net_device *);
197#ifdef MONITOR 193static void tlan_phy_monitor(unsigned long);
198static 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
2742void tlan_phy_monitor(struct net_device *dev) 2727static 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