summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHayes Wang <hayeswang@realtek.com>2013-04-13 12:26:55 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-16 21:02:31 -0700
commitf0776cdd7c35a4b4ca7b80e6afc4ecd0d26831d7 (patch)
tree2862d1d0a68867faf86c13a9a78a66623e207f63
parentfcea984b4ded553023858d55afcf5e782462af1c (diff)
r8169: fix auto speed down issue
commit e2409d83434d77874b461b78af6a19cd6e6a1280 upstream. It would cause no link after suspending or shutdowning when the nic changes the speed to 10M and connects to a link partner which forces the speed to 100M. Check the link partner ability to determine which speed to set. The link speed down code path is not factored in this kernel version. Signed-off-by: Hayes Wang <hayeswang@realtek.com> Acked-by: Francois Romieu <romieu@fr.zoreil.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/net/r8169.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 80b230e6f207..8350f8d21f09 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -3105,11 +3105,34 @@ static void r810x_phy_power_up(struct rtl8169_private *tp)
rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE);
}
+static void rtl_speed_down(struct rtl8169_private *tp)
+{
+ u32 adv;
+ int lpa;
+
+ rtl_writephy(tp, 0x1f, 0x0000);
+ lpa = rtl_readphy(tp, MII_LPA);
+
+ if (lpa & (LPA_10HALF | LPA_10FULL))
+ adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full;
+ else if (lpa & (LPA_100HALF | LPA_100FULL))
+ adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
+ else
+ adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
+ (tp->mii.supports_gmii ?
+ ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full : 0);
+
+ rtl8169_set_speed(tp->dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL,
+ adv);
+}
+
static void r810x_pll_power_down(struct rtl8169_private *tp)
{
if (__rtl8169_get_wol(tp) & WAKE_ANY) {
- rtl_writephy(tp, 0x1f, 0x0000);
- rtl_writephy(tp, MII_BMCR, 0x0000);
+ rtl_speed_down(tp);
return;
}
@@ -3201,8 +3224,7 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)
rtl_ephy_write(ioaddr, 0x19, 0xff64);
if (__rtl8169_get_wol(tp) & WAKE_ANY) {
- rtl_writephy(tp, 0x1f, 0x0000);
- rtl_writephy(tp, MII_BMCR, 0x0000);
+ rtl_speed_down(tp);
if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
tp->mac_version == RTL_GIGA_MAC_VER_33)