From eb522bb4e0dc4800d3cd2eedc4288f90022293fa Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 30 Jun 2014 18:38:27 +0200 Subject: tlan: Enable activity LED on Olicom OC-2325 and OC-2326 Olicom OC-2325 and OC-2326 ethernet cards have an activity LED but it does not work with tlan driver as it's not enabled. Enable it. Tested with OC-2326. Signed-off-by: Ondrej Zary Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/tlan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 62b19be5183d..2199fc8e5003 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -107,8 +107,10 @@ static struct board { { "Compaq Netelligent 10/100 TX Embedded UTP", TLAN_ADAPTER_NONE, 0x83 }, { "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 }, - { "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xf8 }, - { "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xf8 }, + { "Olicom OC-2325", TLAN_ADAPTER_ACTIVITY_LED | + TLAN_ADAPTER_UNMANAGED_PHY, 0xf8 }, + { "Olicom OC-2326", TLAN_ADAPTER_ACTIVITY_LED | + TLAN_ADAPTER_USE_INTERN_10, 0xf8 }, { "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, { "Compaq Netelligent 10 T/2 PCI UTP/coax", TLAN_ADAPTER_NONE, 0x83 }, { "Compaq NetFlex-3/E", -- cgit v1.2.2 From c0a87c22d3f098517473c60c709478db80fcc544 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 30 Jun 2014 18:38:28 +0200 Subject: 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 Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/tlan.c | 115 +++++++++++++++++------------------------ 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 "); 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 */ - /***************************************************************************** ****************************************************************************** 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 { u32 timer_set_at; u32 timer_type; struct timer_list timer; + struct timer_list media_timer; struct board *adapter; u32 adapter_rev; u32 aui; @@ -206,7 +207,6 @@ struct tlan_priv { u8 tlan_rev; u8 tlan_full_duplex; spinlock_t lock; - u8 link; struct work_struct tlan_tqueue; u8 neg_be_verbose; }; @@ -219,7 +219,6 @@ struct tlan_priv { * ****************************************************************/ -#define TLAN_TIMER_LINK_BEAT 1 #define TLAN_TIMER_ACTIVITY 2 #define TLAN_TIMER_PHY_PDOWN 3 #define TLAN_TIMER_PHY_PUP 4 -- cgit v1.2.2 From e36124d464d5ba74a171385ac1ba93acf4343de4 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 30 Jun 2014 18:38:29 +0200 Subject: tlan: Add ethtool support Add basic ethtool support to tlan driver: - driver info - link detect (this allows NetworkManager to detect carrier) - EEPROM read Signed-off-by: Ondrej Zary Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/tlan.c | 37 +++++++++++++++++++++++++++++++++++++ drivers/net/ethernet/ti/tlan.h | 1 + 2 files changed, 38 insertions(+) diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index ccde7482d404..00ec926084ea 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -778,7 +778,43 @@ static const struct net_device_ops tlan_netdev_ops = { #endif }; +static void tlan_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + struct tlan_priv *priv = netdev_priv(dev); + + strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); + if (priv->pci_dev) + strlcpy(info->bus_info, pci_name(priv->pci_dev), + sizeof(info->bus_info)); + else + strlcpy(info->bus_info, "EISA", sizeof(info->bus_info)); + info->eedump_len = TLAN_EEPROM_SIZE; +} + +static int tlan_get_eeprom_len(struct net_device *dev) +{ + return TLAN_EEPROM_SIZE; +} +static int tlan_get_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *data) +{ + int i; + + for (i = 0; i < TLAN_EEPROM_SIZE; i++) + if (tlan_ee_read_byte(dev, i, &data[i])) + return -EIO; + + return 0; +} + +static const struct ethtool_ops tlan_ethtool_ops = { + .get_drvinfo = tlan_get_drvinfo, + .get_link = ethtool_op_get_link, + .get_eeprom_len = tlan_get_eeprom_len, + .get_eeprom = tlan_get_eeprom, +}; /*************************************************************** * tlan_init @@ -841,6 +877,7 @@ static int tlan_init(struct net_device *dev) /* Device methods */ dev->netdev_ops = &tlan_netdev_ops; + dev->ethtool_ops = &tlan_ethtool_ops; dev->watchdog_timeo = TX_TIMEOUT; return 0; diff --git a/drivers/net/ethernet/ti/tlan.h b/drivers/net/ethernet/ti/tlan.h index 4ced9053d9f4..b6ceebaa2185 100644 --- a/drivers/net/ethernet/ti/tlan.h +++ b/drivers/net/ethernet/ti/tlan.h @@ -240,6 +240,7 @@ struct tlan_priv { #define TLAN_EEPROM_ACK 0 #define TLAN_EEPROM_STOP 1 +#define TLAN_EEPROM_SIZE 256 -- cgit v1.2.2 From 59be4ad6bb01fa80b6ad2cf15163ccb617f7d603 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 30 Jun 2014 18:38:30 +0200 Subject: tlan: Fix MAC address byte order on OC-2325/OC-2326 Olicom OC-2325 and OC-2326 cards have the MAC address byte-swapped in EEPROM. Byte-swap the MAC address if it's located at offset 0xF8. Signed-off-by: Ondrej Zary Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/tlan.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 00ec926084ea..cacc76da91a2 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -863,7 +863,7 @@ static int tlan_init(struct net_device *dev) priv->rx_list_dma + sizeof(struct tlan_list)*TLAN_NUM_RX_LISTS; err = 0; - for (i = 0; i < 6 ; i++) + for (i = 0; i < ETH_ALEN; i++) err |= tlan_ee_read_byte(dev, (u8) priv->adapter->addr_ofs + i, (u8 *) &dev->dev_addr[i]); @@ -871,7 +871,14 @@ static int tlan_init(struct net_device *dev) pr_err("%s: Error reading MAC from eeprom: %d\n", dev->name, err); } - dev->addr_len = 6; + /* Olicom OC-2325/OC-2326 have the address byte-swapped */ + if (priv->adapter->addr_ofs == 0xf8) { + for (i = 0; i < ETH_ALEN; i += 2) { + char tmp = dev->dev_addr[i]; + dev->dev_addr[i] = dev->dev_addr[i + 1]; + dev->dev_addr[i + 1] = tmp; + } + } netif_carrier_off(dev); -- cgit v1.2.2 From 36bbe2f4b4c81a2857d9c8f0443a86f42911336b Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 30 Jun 2014 18:38:31 +0200 Subject: tlan: Restart autonegotiation on link loss When link is lost on a card which uses internal PHY for 10 Mbit speeds, restart autonegotiation to allow switching between 10 and 100 Mbps speeds. Signed-off-by: Ondrej Zary Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/tlan.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index cacc76da91a2..3b8364568a6a 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -2720,6 +2720,7 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev) else if (!(mode & 0x0080) && (mode & 0x0040)) priv->tlan_full_duplex = true; + /* switch to internal PHY for 10 Mbps */ if ((!(mode & 0x0180)) && (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) && (priv->phy_num != 0)) { @@ -2787,6 +2788,21 @@ static void tlan_phy_monitor(unsigned long data) dev->name); tlan_dio_write8(dev->base_addr, TLAN_LED_REG, 0); netif_carrier_off(dev); + if (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) { + /* power down internal PHY */ + u16 data = MII_GC_PDOWN | MII_GC_LOOPBK | + MII_GC_ISOLATE; + + tlan_mii_sync(dev->base_addr); + tlan_mii_write_reg(dev, priv->phy[0], + MII_GEN_CTL, data); + /* set to external PHY */ + priv->phy_num = 1; + /* restart autonegotiation */ + tlan_set_timer(dev, 4 * HZ / 10, + TLAN_TIMER_PHY_PDOWN); + return; + } } } -- cgit v1.2.2 From 8e62d670488282eed56bbdd0216691ababb0f6e9 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 30 Jun 2014 18:38:32 +0200 Subject: tlan: Don't scream if no link Remove excess printks when the link is down. Signed-off-by: Ondrej Zary Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/tlan.c | 9 --------- drivers/net/ethernet/ti/tlan.h | 1 - 2 files changed, 10 deletions(-) diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 3b8364568a6a..872f94c7f1cf 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -1198,9 +1198,6 @@ static irqreturn_t tlan_handle_interrupt(int irq, void *dev_id) static int tlan_close(struct net_device *dev) { - struct tlan_priv *priv = netdev_priv(dev); - - priv->neg_be_verbose = 0; tlan_stop(dev); free_irq(dev->irq, dev); @@ -2701,12 +2698,6 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev) /* Wait for 8 sec to give the process * more time. Perhaps we should fail after a while. */ - if (!priv->neg_be_verbose++) { - pr_info("Giving autonegotiation more time.\n"); - pr_info("Please check that your adapter has\n"); - pr_info("been properly connected to a HUB or Switch.\n"); - pr_info("Trying to establish link in the background...\n"); - } tlan_set_timer(dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN); return; } diff --git a/drivers/net/ethernet/ti/tlan.h b/drivers/net/ethernet/ti/tlan.h index b6ceebaa2185..e9928411827e 100644 --- a/drivers/net/ethernet/ti/tlan.h +++ b/drivers/net/ethernet/ti/tlan.h @@ -208,7 +208,6 @@ struct tlan_priv { u8 tlan_full_duplex; spinlock_t lock; struct work_struct tlan_tqueue; - u8 neg_be_verbose; }; -- cgit v1.2.2 From 278e48b0c4152e600e2ed8328ba4347bc499d3f9 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 30 Jun 2014 18:38:33 +0200 Subject: tlan: Make autonegotiation faster Reduce the autonegotiation poll interval from 8 seconds to 2. This greatly reduces the time needed to detect link presence, especially on Olicom cards at 10 Mbps (two autonegoatiations required). Signed-off-by: Ondrej Zary Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/tlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 872f94c7f1cf..c4021de7ebea 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -2698,7 +2698,7 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev) /* Wait for 8 sec to give the process * more time. Perhaps we should fail after a while. */ - tlan_set_timer(dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN); + tlan_set_timer(dev, 2 * HZ, TLAN_TIMER_PHY_FINISH_AN); return; } -- cgit v1.2.2 From 9cff441ed64a44db7cd15d187030f2f9c1bb6465 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 30 Jun 2014 18:38:34 +0200 Subject: tlan: Add PHY reset timeout Add a timeout to prevent infinite loop waiting for PHY to reset. Signed-off-by: Ondrej Zary Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/tlan.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index c4021de7ebea..8278150119d5 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -2568,6 +2568,7 @@ static void tlan_phy_reset(struct net_device *dev) struct tlan_priv *priv = netdev_priv(dev); u16 phy; u16 value; + unsigned long timeout = jiffies + HZ; phy = priv->phy[priv->phy_num]; @@ -2575,9 +2576,13 @@ static void tlan_phy_reset(struct net_device *dev) tlan_mii_sync(dev->base_addr); value = MII_GC_LOOPBK | MII_GC_RESET; tlan_mii_write_reg(dev, phy, MII_GEN_CTL, value); - tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value); - while (value & MII_GC_RESET) + do { tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value); + if (time_after(jiffies, timeout)) { + netdev_err(dev, "PHY reset timeout\n"); + return; + } + } while (value & MII_GC_RESET); /* Wait for 500 ms and initialize. * I don't remember why I wait this long. -- cgit v1.2.2 From 7a72eddc8e943a96afc86264e095f5b1d037ed4a Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 30 Jun 2014 18:38:35 +0200 Subject: tlan: Don't disable internal PHY on cards that use it in 10 Mbps mode In tlan_reset_adapter, we disable internal PHY when an external one is used. On cards which use internal PHY in 10 Mbps mode, we enable it later when setting 10 Mbps mode but it does not really work (PHY fails to reset). Leave it enabled instead. Signed-off-by: Ondrej Zary Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/tlan.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 8278150119d5..50ac9e7b927f 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -2237,7 +2237,9 @@ tlan_reset_adapter(struct net_device *dev) } } - if (priv->phy_num == 0) + /* don't power down internal PHY if we're going to use it */ + if (priv->phy_num == 0 || + (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10)) data |= TLAN_NET_CFG_PHY_EN; tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data); @@ -2688,7 +2690,6 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev) struct tlan_priv *priv = netdev_priv(dev); u16 an_adv; u16 an_lpa; - u16 data; u16 mode; u16 phy; u16 status; @@ -2721,9 +2722,6 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev) (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) && (priv->phy_num != 0)) { priv->phy_num = 0; - data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN - | TLAN_NET_CFG_PHY_EN; - tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data); tlan_set_timer(dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN); return; } -- cgit v1.2.2 From e697b16b47d1c6d63859cfd44cecb888c7dde92f Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 30 Jun 2014 18:38:36 +0200 Subject: tlan: Enable device at resume pci_disable_device() is called in _suspend but there's no corresponding pci_enable_device() in _resume. This causes "disabling already-disabled device" warning on 2nd suspend. Add pci_enable_device() call to _resume to fix this problem. Signed-off-by: Ondrej Zary Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/tlan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 50ac9e7b927f..1f21764fea53 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -365,8 +365,10 @@ static int tlan_suspend(struct pci_dev *pdev, pm_message_t state) static int tlan_resume(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); + int rc = pci_enable_device(pdev); - pci_set_power_state(pdev, PCI_D0); + if (rc) + return rc; pci_restore_state(pdev); pci_enable_wake(pdev, PCI_D0, 0); netif_device_attach(dev); -- cgit v1.2.2 From 9162e7e5197e14c7488c54980d7cbdc2071f8085 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 30 Jun 2014 18:38:37 +0200 Subject: tlan: Isolate external PHY when using internal PHY When using internal 10 Mbps PHY, isolate the external PHY from MII bus. External PHY must be kept powered up because it passes TX from tlan chip to network. This fixes weird link-loss problems under load with OC-2326 card at 10 Mbps. Signed-off-by: Ondrej Zary Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/tlan.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 1f21764fea53..6078342fe3f2 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -2528,9 +2528,10 @@ static void tlan_phy_power_down(struct net_device *dev) value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE; tlan_mii_sync(dev->base_addr); tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value); - if ((priv->phy_num == 0) && - (priv->phy[1] != TLAN_PHY_NONE) && - (!(priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10))) { + if ((priv->phy_num == 0) && (priv->phy[1] != TLAN_PHY_NONE)) { + /* if using internal PHY, the external PHY must be powered on */ + if (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) + value = MII_GC_ISOLATE; /* just isolate it from MII */ tlan_mii_sync(dev->base_addr); tlan_mii_write_reg(dev, priv->phy[1], MII_GEN_CTL, value); } -- cgit v1.2.2