Message ID | 20131124005022.GA6299@electric-eye.fr.zoreil.com |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
Francois Romieu <romieu@fr.zoreil.com> : [...] > You can try the genuinely untested hack below if you don't like current > runtime suspend / resume behavior. The patch is badly broken.
Hi Francois > Which one exactly ? Sorry - just based upon a Google search, this problem with the card not recognizing that a cable has been plugged into the interface, seems to have come up off and on for a while, many years. > blah ? "<blah>" - referring to the network interface name, in my case "enp22s0". This interface is a Netgear "Gigabit PC Card", model GA511, into a Thinkpad T60, acting as a router. > The r8169 driver is the same in v3.12 and v3.12.1. Either some userspace > application works in your back or your device experienced a runtime > suspend / resume cycle where it previously didn't. That would seem to make sense. After some more problems with the interface, I later noticed that having the card come-up at 1000Mb/s and Full duplex was not enough to indicate that the card was working. When the interface was just handling ping packets it seemed to work fine. But then, whenever there was a file transfer - downloading some email or a large file, for instance - the interface seems to "choke". Watching a repeated "ethtool enp22s0", the link speed and duplex would change constantly, dropping down to 10Mb/s and Half duplex, then up to 100Mb/s and Full duplex, than back down. If the file transfers were halted, so that nothing more than ping was going through the interface, the speed and duplex would come back up, to 1000Mb/s and Full duplex. Practically, the interface was unusable, and I swapped-out the card for an Intel Pro 100, which works fine. So the problem would then seem to have nothing to do with the PC Card hardware on the Thinkpad. > What do you want exactly ? 10 Mb/s, 100 Mb/s ? Limited / no advertising ? Well, according to "ethtool", the card advertises up to 1000Mb/s, Full duplex, and Auto-negotiation. It just seems that it should not constantly try to re-configure itself. I have not studied the code to find-out what would trigger a re-negotiation, or trigger a suspend/resume. > The patch is badly broken. Sorry - I haven't tried to re-compile the driver, since it was easier to just swap-out the card, for another with a different driver. Maybe there is a simple way to modify the driver to "lock" the configuration? Or ... ? If you have another patch, I can plug the card back in and try it out. Thanks James -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 7280d5d..701ca00 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -812,6 +812,13 @@ struct rtl8169_private { #define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN) u32 ocp_base; + + struct { + u32 adv; + u16 speed; + u8 duplex; + u8 autoneg; + } rtl_settings; }; MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); @@ -1755,6 +1762,11 @@ static int rtl8169_set_speed(struct net_device *dev, if (ret < 0) goto out; + tp->autoneg = autoneg; + tp->speed = speed; + tp->duplex = duplex; + tp->adv = advertising; + if (netif_running(dev) && (autoneg == AUTONEG_ENABLE) && (advertising & ADVERTISED_1000baseT_Full)) { mod_timer(&tp->timer, jiffies + RTL8169_PHY_TIMEOUT); @@ -3778,6 +3790,14 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) netif_info(tp, link, dev, "TBI auto-negotiating\n"); } +static void rtl_resume_phy(struct net_device *dev, struct rtl8169_private *tp) +{ + rtl8169_init_phy(dev, tp); + + if (tp->speed) + tp->set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->adv); +} + static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) { void __iomem *ioaddr = tp->mmio_addr; @@ -6661,7 +6681,7 @@ static int rtl8169_resume(struct device *device) struct net_device *dev = pci_get_drvdata(pdev); struct rtl8169_private *tp = netdev_priv(dev); - rtl8169_init_phy(dev, tp); + rtl_resume_phy(dev, tp); if (netif_running(dev)) __rtl8169_resume(dev); @@ -6702,7 +6722,7 @@ static int rtl8169_runtime_resume(struct device *device) tp->saved_wolopts = 0; rtl_unlock_work(tp); - rtl8169_init_phy(dev, tp); + rtl_resume_phy(dev, tp); __rtl8169_resume(dev);