summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/ti/tlan.c
diff options
context:
space:
mode:
authorOndrej Zary <linux@rainbow-software.org>2014-06-30 20:38:28 +0400
committerDavid S. Miller <davem@davemloft.net>2014-07-08 04:06:51 +0400
commitc0a87c22d3f098517473c60c709478db80fcc544 (patch)
tree4b1337ac823f450427cfd77fac1a8d37e66bd912 /drivers/net/ethernet/ti/tlan.c
parenteb522bb4e0dc4800d3cd2eedc4288f90022293fa (diff)
downloadlinux-c0a87c22d3f098517473c60c709478db80fcc544.tar.xz
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>
Diffstat (limited to 'drivers/net/ethernet/ti/tlan.c')
-rw-r--r--drivers/net/ethernet/ti/tlan.c115
1 files changed, 48 insertions, 67 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>");
MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
MODULE_LICENSE("GPL");
-
-/* Define this to enable Link beat monitoring */
-#undef MONITOR
-
/* Turn on debugging. See Documentation/networking/tlan.txt for details */
static int debug;
module_param(debug, int, 0);
@@ -194,9 +190,7 @@ static void tlan_phy_power_up(struct net_device *);
static void tlan_phy_reset(struct net_device *);
static void tlan_phy_start_link(struct net_device *);
static void tlan_phy_finish_auto_neg(struct net_device *);
-#ifdef MONITOR
-static void tlan_phy_monitor(struct net_device *);
-#endif
+static void tlan_phy_monitor(unsigned long);
/*
static int tlan_phy_nop(struct net_device *);
@@ -339,6 +333,7 @@ static void tlan_stop(struct net_device *dev)
{
struct tlan_priv *priv = netdev_priv(dev);
+ del_timer_sync(&priv->media_timer);
tlan_read_and_clear_stats(dev, TLAN_RECORD);
outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
/* Reset and power down phy */
@@ -888,6 +883,7 @@ static int tlan_open(struct net_device *dev)
}
init_timer(&priv->timer);
+ init_timer(&priv->media_timer);
tlan_start(dev);
@@ -1810,11 +1806,6 @@ static void tlan_timer(unsigned long data)
priv->timer.function = NULL;
switch (priv->timer_type) {
-#ifdef MONITOR
- case TLAN_TIMER_LINK_BEAT:
- tlan_phy_monitor(dev);
- break;
-#endif
case TLAN_TIMER_PHY_PDOWN:
tlan_phy_power_down(dev);
break;
@@ -1858,8 +1849,6 @@ static void tlan_timer(unsigned long data)
}
-
-
/*****************************************************************************
******************************************************************************
@@ -2257,42 +2246,39 @@ tlan_finish_reset(struct net_device *dev)
tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
udelay(1000);
tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
- if ((status & MII_GS_LINK) &&
- /* We only support link info on Nat.Sem. PHY's */
- (tlphy_id1 == NAT_SEM_ID1) &&
- (tlphy_id2 == NAT_SEM_ID2)) {
- tlan_mii_read_reg(dev, phy, MII_AN_LPA, &partner);
- tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, &tlphy_par);
-
- netdev_info(dev,
- "Link active with %s %uMbps %s-Duplex\n",
- !(tlphy_par & TLAN_PHY_AN_EN_STAT)
- ? "forced" : "Autonegotiation enabled,",
- tlphy_par & TLAN_PHY_SPEED_100
- ? 100 : 10,
- tlphy_par & TLAN_PHY_DUPLEX_FULL
- ? "Full" : "Half");
-
- if (tlphy_par & TLAN_PHY_AN_EN_STAT) {
- netdev_info(dev, "Partner capability:");
- for (i = 5; i < 10; i++)
- if (partner & (1 << i))
- pr_cont(" %s", media[i-5]);
- pr_cont("\n");
- }
-
- tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
- TLAN_LED_LINK);
-#ifdef MONITOR
- /* We have link beat..for now anyway */
- priv->link = 1;
- /*Enabling link beat monitoring */
- tlan_set_timer(dev, (10*HZ), TLAN_TIMER_LINK_BEAT);
-#endif
- } else if (status & MII_GS_LINK) {
- netdev_info(dev, "Link active\n");
- tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
- TLAN_LED_LINK);
+ if (status & MII_GS_LINK) {
+ /* We only support link info on Nat.Sem. PHY's */
+ if ((tlphy_id1 == NAT_SEM_ID1) &&
+ (tlphy_id2 == NAT_SEM_ID2)) {
+ tlan_mii_read_reg(dev, phy, MII_AN_LPA,
+ &partner);
+ tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR,
+ &tlphy_par);
+
+ netdev_info(dev,
+ "Link active, %s %uMbps %s-Duplex\n",
+ !(tlphy_par & TLAN_PHY_AN_EN_STAT)
+ ? "forced" : "Autonegotiation enabled,",
+ tlphy_par & TLAN_PHY_SPEED_100
+ ? 100 : 10,
+ tlphy_par & TLAN_PHY_DUPLEX_FULL
+ ? "Full" : "Half");
+
+ if (tlphy_par & TLAN_PHY_AN_EN_STAT) {
+ netdev_info(dev, "Partner capability:");
+ for (i = 5; i < 10; i++)
+ if (partner & (1 << i))
+ pr_cont(" %s",
+ media[i-5]);
+ pr_cont("\n");
+ }
+ } else
+ netdev_info(dev, "Link active\n");
+ /* Enabling link beat monitoring */
+ priv->media_timer.function = tlan_phy_monitor;
+ priv->media_timer.data = (unsigned long) dev;
+ priv->media_timer.expires = jiffies + HZ;
+ add_timer(&priv->media_timer);
}
}
@@ -2314,6 +2300,7 @@ tlan_finish_reset(struct net_device *dev)
dev->base_addr + TLAN_HOST_CMD + 1);
outl(priv->rx_list_dma, dev->base_addr + TLAN_CH_PARM);
outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD);
+ tlan_dio_write8(dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK);
netif_carrier_on(dev);
} else {
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)
}
-#ifdef MONITOR
/*********************************************************************
*
@@ -2729,18 +2715,18 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev)
* None
*
* Params:
- * dev The device structure of this device.
+ * data The device structure of this device.
*
*
* This function monitors PHY condition by reading the status
- * register via the MII bus. This can be used to give info
- * about link changes (up/down), and possible switch to alternate
- * media.
+ * register via the MII bus, controls LINK LED and notifies the
+ * kernel about link state.
*
*******************************************************************/
-void tlan_phy_monitor(struct net_device *dev)
+static void tlan_phy_monitor(unsigned long data)
{
+ struct net_device *dev = (struct net_device *) data;
struct tlan_priv *priv = netdev_priv(dev);
u16 phy;
u16 phy_status;
@@ -2752,30 +2738,25 @@ void tlan_phy_monitor(struct net_device *dev)
/* Check if link has been lost */
if (!(phy_status & MII_GS_LINK)) {
- if (priv->link) {
- priv->link = 0;
+ if (netif_carrier_ok(dev)) {
printk(KERN_DEBUG "TLAN: %s has lost link\n",
dev->name);
+ tlan_dio_write8(dev->base_addr, TLAN_LED_REG, 0);
netif_carrier_off(dev);
- tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
- return;
}
}
/* Link restablished? */
- if ((phy_status & MII_GS_LINK) && !priv->link) {
- priv->link = 1;
+ if ((phy_status & MII_GS_LINK) && !netif_carrier_ok(dev)) {
+ tlan_dio_write8(dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK);
printk(KERN_DEBUG "TLAN: %s has reestablished link\n",
dev->name);
netif_carrier_on(dev);
}
-
- /* Setup a new monitor */
- tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
+ priv->media_timer.expires = jiffies + HZ;
+ add_timer(&priv->media_timer);
}
-#endif /* MONITOR */
-
/*****************************************************************************
******************************************************************************