[RESEND PATCH net-next] r8169: add module param for control of ASPM disable.

2018-02-14 Thread Chunhao Lin
The patch is from Todd Broch <tbr...@chromium.org>.
ASPM has been disabled in this driver by default as its been
implicated in stability issues on at least one platform.  This CL adds
a module parameter to allow control of ASPM disable.  The default
value is to enable ASPM again as its provides signficant (200mW) power
savings on the platform I tested.

I make some modification that let this patch only for RTL8168G and later.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 73 
 1 file changed, 50 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 0bf7d17..87d3136 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -346,6 +346,7 @@ static const struct pci_device_id rtl8169_pci_tbl[] = {
 MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
 
 static int rx_buf_sz = 16383;
+static int aspm_disable = 0;
 static int use_dac = -1;
 static struct {
u32 msg_enable;
@@ -867,6 +868,8 @@ struct rtl8169_private {
 
 MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
 MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
+module_param(aspm_disable, int, 0444);
+MODULE_PARM_DESC(aspm_disable, "Disable ASPM completely.");
 module_param(use_dac, int, 0);
 MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
 module_param_named(debug, debug.msg_enable, int, 0);
@@ -5878,6 +5881,20 @@ static void rtl_pcie_state_l2l3_enable(struct 
rtl8169_private *tp, bool enable)
RTL_W8(Config3, data);
 }
 
+static void rtl_hw_internal_aspm_clkreq_enable(struct rtl8169_private *tp,
+   bool enable)
+{
+   void __iomem *ioaddr = tp->mmio_addr;
+
+   if (enable) {
+   RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn);
+   RTL_W8(Config5, RTL_R8(Config5) | ASPM_en);
+   } else {
+   RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
+   RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en);
+   }
+}
+
 #define R8168_CPCMD_QUIRK_MASK (\
EnableBist | \
Mac_dbgo_oe | \
@@ -6264,7 +6281,6 @@ static void rtl_hw_start_8168g(struct rtl8169_private *tp)
 
 static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)
 {
-   void __iomem *ioaddr = tp->mmio_addr;
static const struct ephy_info e_info_8168g_1[] = {
{ 0x00, 0x, 0x0008 },
{ 0x0c, 0x37d0, 0x0820 },
@@ -6275,14 +6291,14 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private 
*tp)
rtl_hw_start_8168g(tp);
 
/* disable aspm and clock request before access ephy */
-   RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
-   RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en);
+   rtl_hw_internal_aspm_clkreq_enable(tp, false);
rtl_ephy_init(tp, e_info_8168g_1, ARRAY_SIZE(e_info_8168g_1));
+   if (!aspm_disable)
+   rtl_hw_internal_aspm_clkreq_enable(tp, true);
 }
 
 static void rtl_hw_start_8168g_2(struct rtl8169_private *tp)
 {
-   void __iomem *ioaddr = tp->mmio_addr;
static const struct ephy_info e_info_8168g_2[] = {
{ 0x00, 0x, 0x0008 },
{ 0x0c, 0x3df0, 0x0200 },
@@ -6293,14 +6309,14 @@ static void rtl_hw_start_8168g_2(struct rtl8169_private 
*tp)
rtl_hw_start_8168g(tp);
 
/* disable aspm and clock request before access ephy */
-   RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
-   RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en);
+   rtl_hw_internal_aspm_clkreq_enable(tp, false);
rtl_ephy_init(tp, e_info_8168g_2, ARRAY_SIZE(e_info_8168g_2));
+   if (!aspm_disable)
+   rtl_hw_internal_aspm_clkreq_enable(tp, true);
 }
 
 static void rtl_hw_start_8411_2(struct rtl8169_private *tp)
 {
-   void __iomem *ioaddr = tp->mmio_addr;
static const struct ephy_info e_info_8411_2[] = {
{ 0x00, 0x, 0x0008 },
{ 0x0c, 0x3df0, 0x0200 },
@@ -6312,9 +6328,10 @@ static void rtl_hw_start_8411_2(struct rtl8169_private 
*tp)
rtl_hw_start_8168g(tp);
 
/* disable aspm and clock request before access ephy */
-   RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
-   RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en);
+   rtl_hw_internal_aspm_clkreq_enable(tp, false);
rtl_ephy_init(tp, e_info_8411_2, ARRAY_SIZE(e_info_8411_2));
+   if (!aspm_disable)
+   rtl_hw_internal_aspm_clkreq_enable(tp, true);
 }
 
 static void rtl_hw_start_8168h_1(struct rtl8169_private *tp)
@@ -6333,8 +6350,7 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private 
*tp)
};
 
/* disable aspm and clock request before access ephy */
-   RTL_W8(Config2, RTL_R8(Config2) & ~Clk

[PATCH net-next] r8169: add module param for control of ASPM disable

2018-02-01 Thread Chunhao Lin
The patch is from Todd Broch <tbr...@chromium.org>.
ASPM has been disabled in this driver by default as its been
implicated in stability issues on at least one platform.  This CL adds
a  module parameter to allow control of ASPM disable.  The default
value is to enable ASPM again as its provides signficant (200mW) power
savings on the platform I tested.

I make some modification that let this patch only for RTL8168G and later.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 73 
 1 file changed, 50 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 0bf7d17..87d3136 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -346,6 +346,7 @@ static const struct pci_device_id rtl8169_pci_tbl[] = {
 MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
 
 static int rx_buf_sz = 16383;
+static int aspm_disable = 0;
 static int use_dac = -1;
 static struct {
u32 msg_enable;
@@ -867,6 +868,8 @@ struct rtl8169_private {
 
 MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
 MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
+module_param(aspm_disable, int, 0444);
+MODULE_PARM_DESC(aspm_disable, "Disable ASPM completely.");
 module_param(use_dac, int, 0);
 MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
 module_param_named(debug, debug.msg_enable, int, 0);
@@ -5878,6 +5881,20 @@ static void rtl_pcie_state_l2l3_enable(struct 
rtl8169_private *tp, bool enable)
RTL_W8(Config3, data);
 }
 
+static void rtl_hw_internal_aspm_clkreq_enable(struct rtl8169_private *tp,
+   bool enable)
+{
+   void __iomem *ioaddr = tp->mmio_addr;
+
+   if (enable) {
+   RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn);
+   RTL_W8(Config5, RTL_R8(Config5) | ASPM_en);
+   } else {
+   RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
+   RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en);
+   }
+}
+
 #define R8168_CPCMD_QUIRK_MASK (\
EnableBist | \
Mac_dbgo_oe | \
@@ -6264,7 +6281,6 @@ static void rtl_hw_start_8168g(struct rtl8169_private *tp)
 
 static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)
 {
-   void __iomem *ioaddr = tp->mmio_addr;
static const struct ephy_info e_info_8168g_1[] = {
{ 0x00, 0x, 0x0008 },
{ 0x0c, 0x37d0, 0x0820 },
@@ -6275,14 +6291,14 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private 
*tp)
rtl_hw_start_8168g(tp);
 
/* disable aspm and clock request before access ephy */
-   RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
-   RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en);
+   rtl_hw_internal_aspm_clkreq_enable(tp, false);
rtl_ephy_init(tp, e_info_8168g_1, ARRAY_SIZE(e_info_8168g_1));
+   if (!aspm_disable)
+   rtl_hw_internal_aspm_clkreq_enable(tp, true);
 }
 
 static void rtl_hw_start_8168g_2(struct rtl8169_private *tp)
 {
-   void __iomem *ioaddr = tp->mmio_addr;
static const struct ephy_info e_info_8168g_2[] = {
{ 0x00, 0x, 0x0008 },
{ 0x0c, 0x3df0, 0x0200 },
@@ -6293,14 +6309,14 @@ static void rtl_hw_start_8168g_2(struct rtl8169_private 
*tp)
rtl_hw_start_8168g(tp);
 
/* disable aspm and clock request before access ephy */
-   RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
-   RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en);
+   rtl_hw_internal_aspm_clkreq_enable(tp, false);
rtl_ephy_init(tp, e_info_8168g_2, ARRAY_SIZE(e_info_8168g_2));
+   if (!aspm_disable)
+   rtl_hw_internal_aspm_clkreq_enable(tp, true);
 }
 
 static void rtl_hw_start_8411_2(struct rtl8169_private *tp)
 {
-   void __iomem *ioaddr = tp->mmio_addr;
static const struct ephy_info e_info_8411_2[] = {
{ 0x00, 0x, 0x0008 },
{ 0x0c, 0x3df0, 0x0200 },
@@ -6312,9 +6328,10 @@ static void rtl_hw_start_8411_2(struct rtl8169_private 
*tp)
rtl_hw_start_8168g(tp);
 
/* disable aspm and clock request before access ephy */
-   RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
-   RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en);
+   rtl_hw_internal_aspm_clkreq_enable(tp, false);
rtl_ephy_init(tp, e_info_8411_2, ARRAY_SIZE(e_info_8411_2));
+   if (!aspm_disable)
+   rtl_hw_internal_aspm_clkreq_enable(tp, true);
 }
 
 static void rtl_hw_start_8168h_1(struct rtl8169_private *tp)
@@ -6333,8 +6350,7 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private 
*tp)
};
 
/* disable aspm and clock request before access ephy */
-   RTL_W8(Config2, RTL_R8(Config2) & ~

[PATCH net] r8169: fix RTL8168EP take too long to complete driver initialization.

2018-01-30 Thread Chunhao Lin
Driver check the wrong register bit in rtl_ocp_tx_cond() that keep driver
waiting until timeout.

Fix this by waiting for the right register bit.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 734286e..dd713df 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -1395,7 +1395,7 @@ DECLARE_RTL_COND(rtl_ocp_tx_cond)
 {
void __iomem *ioaddr = tp->mmio_addr;
 
-   return RTL_R8(IBISR0) & 0x02;
+   return RTL_R8(IBISR0) & 0x20;
 }
 
 static void rtl8168ep_stop_cmac(struct rtl8169_private *tp)
@@ -1403,7 +1403,7 @@ static void rtl8168ep_stop_cmac(struct rtl8169_private 
*tp)
void __iomem *ioaddr = tp->mmio_addr;
 
RTL_W8(IBCR2, RTL_R8(IBCR2) & ~0x01);
-   rtl_msleep_loop_wait_low(tp, _ocp_tx_cond, 50, 2000);
+   rtl_msleep_loop_wait_high(tp, _ocp_tx_cond, 50, 2000);
RTL_W8(IBISR0, RTL_R8(IBISR0) | 0x20);
RTL_W8(IBCR0, RTL_R8(IBCR0) & ~0x01);
 }
-- 
2.7.4



[PATCH net v2] 8139too: fix system hang when there is a tx timeout event.

2016-07-31 Thread Chunhao Lin
If tx timeout event occur, kernel will call rtl8139_tx_timeout_task() to reset
hardware. But in this function, driver does not stop tx and rx function before
reset hardware, that will cause system hang.

In this patch, add stop tx and rx function before reset hardware.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/8139too.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/realtek/8139too.c 
b/drivers/net/ethernet/realtek/8139too.c
index ef668d3..da4c2d8 100644
--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -1667,6 +1667,10 @@ static void rtl8139_tx_timeout_task (struct work_struct 
*work)
int i;
u8 tmp8;
 
+   napi_disable(>napi);
+   netif_stop_queue(dev);
+   synchronize_sched();
+
netdev_dbg(dev, "Transmit timeout, status %02x %04x %04x media %02x\n",
   RTL_R8(ChipCmd), RTL_R16(IntrStatus),
   RTL_R16(IntrMask), RTL_R8(MediaStatus));
@@ -1696,10 +1700,10 @@ static void rtl8139_tx_timeout_task (struct work_struct 
*work)
spin_unlock_irq(>lock);
 
/* ...and finally, reset everything */
-   if (netif_running(dev)) {
-   rtl8139_hw_start (dev);
-   netif_wake_queue (dev);
-   }
+   napi_enable(>napi);
+   rtl8139_hw_start(dev);
+   netif_wake_queue(dev);
+
spin_unlock_bh(>rx_lock);
 }
 
-- 
1.9.1



[PATCH net v2 0/3] r8169:fix 3 runtime pm related issues.

2016-07-29 Thread Chunhao Lin
v2:
use "struct device *d = >pci_dev->dev" instead of "struct pci_dev *pdev = 
tp->pci_dev"

v1:
This series of patches fix 3 runtime pm related issues that are listed below.

Chunhao Lin (3):
  r8169:fix kernel log spam when set or get hardware wol setting.
  r8169:add checking driver's runtime pm status in
rtl8169_get_ethtool_stats()
  r8169:fix nic may not work after changing mac address.

 drivers/net/ethernet/realtek/r8169.c | 37 
 1 file changed, 33 insertions(+), 4 deletions(-)

-- 
1.9.1



[PATCH net v2 1/3] r8169:fix kernel log spam when set or get hardware wol setting.

2016-07-29 Thread Chunhao Lin
NIC will be put into D3 state during runtime suspend state. When set or
get hardware wol setting, driver will write or read hardware registers.
If we set or get hardware wol setting in runtime suspend state, because
NIC will in D3 state, the hardware registers read by driver will return all
0xff. That will let driver thinking register flag is not toggled and
then prints the warning message "rtl_counters_cond == 1 (loop: 1000,
delay: 10)" to kernel log.

For fixing this issue, add checking driver's pm runtime status in
rtl8169_get_wol() and rtl8169_set_wol().

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 0e62d74..00c387b 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -1749,13 +1749,21 @@ static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
 static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo 
*wol)
 {
struct rtl8169_private *tp = netdev_priv(dev);
+   struct device *d = >pci_dev->dev;
+
+   pm_runtime_get_noresume(d);
 
rtl_lock_work(tp);
 
wol->supported = WAKE_ANY;
-   wol->wolopts = __rtl8169_get_wol(tp);
+   if (pm_runtime_active(d))
+   wol->wolopts = __rtl8169_get_wol(tp);
+   else
+   wol->wolopts = tp->saved_wolopts;
 
rtl_unlock_work(tp);
+
+   pm_runtime_put_noidle(d);
 }
 
 static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
@@ -1845,6 +1853,9 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, 
u32 wolopts)
 static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
struct rtl8169_private *tp = netdev_priv(dev);
+   struct device *d = >pci_dev->dev;
+
+   pm_runtime_get_noresume(d);
 
rtl_lock_work(tp);
 
@@ -1852,12 +1863,17 @@ static int rtl8169_set_wol(struct net_device *dev, 
struct ethtool_wolinfo *wol)
tp->features |= RTL_FEATURE_WOL;
else
tp->features &= ~RTL_FEATURE_WOL;
-   __rtl8169_set_wol(tp, wol->wolopts);
+   if (pm_runtime_active(d))
+   __rtl8169_set_wol(tp, wol->wolopts);
+   else
+   tp->saved_wolopts = wol->wolopts;
 
rtl_unlock_work(tp);
 
device_set_wakeup_enable(>pci_dev->dev, wol->wolopts);
 
+   pm_runtime_put_noidle(d);
+
return 0;
 }
 
-- 
1.9.1



[PATCH net v2 2/3] r8169:add checking driver's runtime pm status in rtl8169_get_ethtool_stats()

2016-07-29 Thread Chunhao Lin
Not to call rtl8169_update_counters() to dump tally counter when driver
is in runtime suspend state.

Calling rtl8169_update_counters() in runtime suspend state will produce
warning message "rtl_counters_cond == 1 (loop: 1000, delay: 10)".

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 00c387b..d0b5cae 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -2308,11 +2308,17 @@ static void rtl8169_get_ethtool_stats(struct net_device 
*dev,
  struct ethtool_stats *stats, u64 *data)
 {
struct rtl8169_private *tp = netdev_priv(dev);
+   struct device *d = >pci_dev->dev;
struct rtl8169_counters *counters = tp->counters;
 
ASSERT_RTNL();
 
-   rtl8169_update_counters(dev);
+   pm_runtime_get_noresume(d);
+
+   if (pm_runtime_active(d))
+   rtl8169_update_counters(dev);
+
+   pm_runtime_put_noidle(d);
 
data[0] = le64_to_cpu(counters->tx_packets);
data[1] = le64_to_cpu(counters->rx_packets);
-- 
1.9.1



[PATCH net v2 3/3] r8169:fix nic may not work after changing mac address.

2016-07-29 Thread Chunhao Lin
When there is no AC power, NIC may not work after changing mac address.
Please refer to following link.
http://www.spinics.net/lists/netdev/msg356572.html

This issue is caused by runtime power management. When there is no AC
power, if we put NIC down (ifconfig down), the driver will be in runtime
suspend state and hardware will be put into D3 state. During this time,
driver cannot access hardware regisers. So if you set new mac address
during this time, it will not be set to hardware. After resume, NIC will
keep using the old mac address and the network will not work normally.

In this patch I add detecting runtime pm status when setting mac address.
If driver is in runtime suspend state, it will skip setting mac address, keep
the new mac address, and set the new mac address during runtime resume.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index d0b5cae..e55638c 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -4480,6 +4480,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 
*addr)
 static int rtl_set_mac_address(struct net_device *dev, void *p)
 {
struct rtl8169_private *tp = netdev_priv(dev);
+   struct device *d = >pci_dev->dev;
struct sockaddr *addr = p;
 
if (!is_valid_ether_addr(addr->sa_data))
@@ -4487,7 +4488,12 @@ static int rtl_set_mac_address(struct net_device *dev, 
void *p)
 
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
-   rtl_rar_set(tp, dev->dev_addr);
+   pm_runtime_get_noresume(d);
+
+   if (pm_runtime_active(d))
+   rtl_rar_set(tp, dev->dev_addr);
+
+   pm_runtime_put_noidle(d);
 
return 0;
 }
@@ -7890,6 +7896,7 @@ static int rtl8169_runtime_resume(struct device *device)
struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
+   rtl_rar_set(tp, dev->dev_addr);
 
if (!tp->TxDescArray)
return 0;
-- 
1.9.1



[PATCH net] 8139too:fix system hang when there is a tx timeout event.

2016-07-27 Thread Chunhao Lin
If tx timeout event occur, kernel will call rtl8139_tx_timeout_task() to reset
hardware. But in this function, driver does not stop tx and rx function before
reset hardware, that will cause system hang.

In this patch, add stop tx and rx function before reset hardware.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/8139too.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/realtek/8139too.c 
b/drivers/net/ethernet/realtek/8139too.c
index ef668d3..0d77f3c 100644
--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -1667,6 +1667,10 @@ static void rtl8139_tx_timeout_task (struct work_struct 
*work)
int i;
u8 tmp8;
 
+   napi_disable(>napi);
+   netif_stop_queue(dev);
+   synchronize_sched();
+
netdev_dbg(dev, "Transmit timeout, status %02x %04x %04x media %02x\n",
   RTL_R8(ChipCmd), RTL_R16(IntrStatus),
   RTL_R16(IntrMask), RTL_R8(MediaStatus));
@@ -1696,10 +1700,10 @@ static void rtl8139_tx_timeout_task (struct work_struct 
*work)
spin_unlock_irq(>lock);
 
/* ...and finally, reset everything */
-   if (netif_running(dev)) {
-   rtl8139_hw_start (dev);
-   netif_wake_queue (dev);
-   }
+   napi_enable(>napi);
+   rtl8139_hw_start (dev);
+   netif_wake_queue (dev);
+
spin_unlock_bh(>rx_lock);
 }
 
-- 
1.9.1



[PATCH net 0/3] r8169:fix 3 runtime pm related issues.

2016-07-27 Thread Chunhao Lin
This series of patches fix 3 runtime pm related issues that are listed below.

Chunhao Lin (3):
  r8169:fix kernel log spam when set or get hardware wol setting.
  r8169:add checking driver's runtime pm status in rtl8169_get_ethtool_stats()
  r8169:fix nic may not work after changing the mac address.

 drivers/net/ethernet/realtek/r8169.c | 37 
 1 file changed, 33 insertions(+), 4 deletions(-)

-- 
1.9.1



[PATCH net 3/3] r8169:fix nic may not work after changing the mac address.

2016-07-27 Thread Chunhao Lin
When there is no AC power, NIC may not work after changing the mac address.
Please refer to following link.
http://www.spinics.net/lists/netdev/msg356572.html

This issue is caused by runtime power management. When there is no AC power,
if we put NIC down (ifconfig down), the driver will in runtime suspend state
and hardware will be put into D3 state. During this time, driver cannot access
hardware regisers. So if you set new mac address during this time, it will not
work. And then, after resume, the NIC will keep using the old mac address and
the network will not work normally.

In this patch I add detecting runtime pm status when setting mac address.
If driver is in runtime suspend state, it will skip setting mac address and
set the new mac address during runtime resume.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 4a17342..ff1611e 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -4480,6 +4480,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 
*addr)
 static int rtl_set_mac_address(struct net_device *dev, void *p)
 {
struct rtl8169_private *tp = netdev_priv(dev);
+   struct pci_dev *pdev = tp->pci_dev;
struct sockaddr *addr = p;
 
if (!is_valid_ether_addr(addr->sa_data))
@@ -4487,7 +4488,12 @@ static int rtl_set_mac_address(struct net_device *dev, 
void *p)
 
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
-   rtl_rar_set(tp, dev->dev_addr);
+   pm_runtime_get_noresume(>dev);
+
+   if (pm_runtime_active(>dev))
+   rtl_rar_set(tp, dev->dev_addr);
+
+   pm_runtime_put_noidle(>dev);
 
return 0;
 }
@@ -7890,6 +7896,7 @@ static int rtl8169_runtime_resume(struct device *device)
struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
+   rtl_rar_set(tp, dev->dev_addr);
 
if (!tp->TxDescArray)
return 0;
-- 
1.9.1



[PATCH net 2/3] r8169:add checking driver's runtime pm status in rtl8169_get_ethtool_stats()

2016-07-27 Thread Chunhao Lin
Not to call rtl8169_update_counters() to dump tally counter when driver is in
runtime suspend state.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index f07604f..4a17342 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -2308,11 +2308,17 @@ static void rtl8169_get_ethtool_stats(struct net_device 
*dev,
  struct ethtool_stats *stats, u64 *data)
 {
struct rtl8169_private *tp = netdev_priv(dev);
+   struct pci_dev *pdev = tp->pci_dev;
struct rtl8169_counters *counters = tp->counters;
 
ASSERT_RTNL();
 
-   rtl8169_update_counters(dev);
+   pm_runtime_get_noresume(>dev);
+
+   if (pm_runtime_active(>dev))
+   rtl8169_update_counters(dev);
+
+   pm_runtime_put_noidle(>dev);
 
data[0] = le64_to_cpu(counters->tx_packets);
data[1] = le64_to_cpu(counters->rx_packets);
-- 
1.9.1



[PATCH net 1/3] r8169:fix kernel log spam when set or get hardware wol setting.

2016-07-27 Thread Chunhao Lin
NIC will be put into D3 state during runtime suspend state.
When set or get hardware wol setting, driver will write or read hardware
register. If we set or get hardware wol setting in runtime suspend state,
because NIC will in D3 state, the register value read by driver will return all
0xff. That will let driver thinking register flag is not toggled and then prints
the warning message "rtl_counters_cond == 1 (loop: 1000, delay: 10)" to kernel
log.

For fixing this issue, add checking driver's pm runtime status in
rtl8169_get_wol() and rtl8169_set_wol().

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 0e62d74..f07604f 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -1749,13 +1749,21 @@ static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
 static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo 
*wol)
 {
struct rtl8169_private *tp = netdev_priv(dev);
+   struct pci_dev *pdev = tp->pci_dev;
+
+   pm_runtime_get_noresume(>dev);
 
rtl_lock_work(tp);
 
wol->supported = WAKE_ANY;
-   wol->wolopts = __rtl8169_get_wol(tp);
+   if (pm_runtime_active(>dev))
+   wol->wolopts = __rtl8169_get_wol(tp);
+   else
+   wol->wolopts = tp->saved_wolopts;
 
rtl_unlock_work(tp);
+
+   pm_runtime_put_noidle(>dev);
 }
 
 static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
@@ -1845,6 +1853,9 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, 
u32 wolopts)
 static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
struct rtl8169_private *tp = netdev_priv(dev);
+   struct pci_dev *pdev = tp->pci_dev;
+
+   pm_runtime_get_noresume(>dev);
 
rtl_lock_work(tp);
 
@@ -1852,12 +1863,17 @@ static int rtl8169_set_wol(struct net_device *dev, 
struct ethtool_wolinfo *wol)
tp->features |= RTL_FEATURE_WOL;
else
tp->features &= ~RTL_FEATURE_WOL;
-   __rtl8169_set_wol(tp, wol->wolopts);
+   if (pm_runtime_active(>dev))
+   __rtl8169_set_wol(tp, wol->wolopts);
+   else
+   tp->saved_wolopts = wol->wolopts;
 
rtl_unlock_work(tp);
 
device_set_wakeup_enable(>pci_dev->dev, wol->wolopts);
 
+   pm_runtime_put_noidle(>dev);
+
return 0;
 }
 
-- 
1.9.1



[PATCH net v2] r8169:Remove unnecessary phy reset for pcie nic when setting link spped.

2016-03-10 Thread Chunhao Lin
For pcie nic, after setting link speed and there is no link driver does not need
to do phy reset until link up.

For some pcie nics, to do this will also reset phy speed down counter and 
prevent
phy from auto speed down.

This patch fix the issue reported in following link.
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1547151

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index dd2cf37..94f08f1 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -1999,7 +1999,8 @@ static int rtl8169_set_speed(struct net_device *dev,
goto out;
 
if (netif_running(dev) && (autoneg == AUTONEG_ENABLE) &&
-   (advertising & ADVERTISED_1000baseT_Full)) {
+   (advertising & ADVERTISED_1000baseT_Full) &&
+   !pci_is_pcie(tp->pci_dev)) {
mod_timer(>timer, jiffies + RTL8169_PHY_TIMEOUT);
}
 out:
-- 
1.9.1



[PATCH net] r8169:Remove unnecessary phy reset for pcie nic when setting link spped.

2016-03-08 Thread Chunhao Lin
For pcie nic, after setting link speed and thers is no link  driver does not 
need
to do phy reset untill link up.

For some pcie nics, to do this will also reset phy speed down counter and 
prevent
phy from auto speed down.

This patch fix the issue reported in following link.
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1547151

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index dd2cf37..94f08f1 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -1999,7 +1999,8 @@ static int rtl8169_set_speed(struct net_device *dev,
goto out;
 
if (netif_running(dev) && (autoneg == AUTONEG_ENABLE) &&
-   (advertising & ADVERTISED_1000baseT_Full)) {
+   (advertising & ADVERTISED_1000baseT_Full) &&
+   !pci_is_pcie(tp->pci_dev)) {
mod_timer(>timer, jiffies + RTL8169_PHY_TIMEOUT);
}
 out:
-- 
1.9.1



[PATCH net v2] r8169: Enable RX_MULTI_EN for RTL_GIGA_MAC_VER_41~48

2016-03-02 Thread Chunhao Lin
For RTL8168G/RTL8168H/RTL8411B/RTL8107E, enable this flag to eliminate
message "AMD-Vi: Event logged [IO_PAGE_FAULT device=01:00.0 domain=0x0002
address=0x3000 flags=0x0050] in dmesg.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 4caeacb..dd2cf37 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -4933,8 +4933,6 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
break;
case RTL_GIGA_MAC_VER_40:
-   RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | 
RX_EARLY_OFF);
-   break;
case RTL_GIGA_MAC_VER_41:
case RTL_GIGA_MAC_VER_42:
case RTL_GIGA_MAC_VER_43:
@@ -4943,8 +4941,6 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
-   RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF);
-   break;
case RTL_GIGA_MAC_VER_49:
case RTL_GIGA_MAC_VER_50:
case RTL_GIGA_MAC_VER_51:
-- 
1.9.1



[PATCH net 0/3] r8169:issues fix.

2016-02-26 Thread Chunhao Lin
This series of patches fix 3 issues that are listed below.

Chunhao Lin (3):
  r8169:fix nic sometimes doesn't work after changing the mac address.
  r8169:eliminate error message in using ethtool -S when nic is down.
  r8169: Enable RX_MULTI_EN for RTL_GIGA_MAC_VER_41~48

 drivers/net/ethernet/realtek/r8169.c | 22 --
 1 file changed, 16 insertions(+), 6 deletions(-)

-- 
1.9.1



[PATCH net 3/3] r8169: Enable RX_MULTI_EN for RTL_GIGA_MAC_VER_41~48

2016-02-26 Thread Chunhao Lin
For RTL8168G/RTL8168H/RTL8411B/RTL8107E, enable this flag to eliminate message
"AMD-Vi: Event logged [IO_PAGE_FAULT device=01:00.0 domain=0x0002
address=0x3000 flags=0x0050] in dmesg.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 3e9eb64..c8f0077 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -4945,8 +4945,6 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
break;
case RTL_GIGA_MAC_VER_40:
-   RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | 
RX_EARLY_OFF);
-   break;
case RTL_GIGA_MAC_VER_41:
case RTL_GIGA_MAC_VER_42:
case RTL_GIGA_MAC_VER_43:
@@ -4955,8 +4953,6 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
-   RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF);
-   break;
case RTL_GIGA_MAC_VER_49:
case RTL_GIGA_MAC_VER_50:
case RTL_GIGA_MAC_VER_51:
-- 
1.9.1



[PATCH net 1/3] r8169:fix nic sometimes doesn't work after changing the mac address.

2016-02-26 Thread Chunhao Lin
When there is no AC power, NIC doesn't work after changing mac address.
Please refer to following link.
http://www.spinics.net/lists/netdev/msg356572.html

This issue is caused by runtime power management. When there is no AC power, if 
we
put NIC down (ifconfig down), the driver will be put in runtime suspend state 
and
device will in D3 state. In this time, driver cannot access hardware regisers. 
So
if you set new mac address during this time, it will not work. And then, after
resume, the NIC will keep using the old mac address and so the network will not
work normally.

In this patch I add detecting runtime pm state when setting mac address. If
driver is in runtime suspend, I will skip setting mac address and  set the new
mac address during runtime resume.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 4caeacb..432b278 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -4457,6 +4457,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 
*addr)
 static int rtl_set_mac_address(struct net_device *dev, void *p)
 {
struct rtl8169_private *tp = netdev_priv(dev);
+   struct pci_dev *pdev = tp->pci_dev;
struct sockaddr *addr = p;
 
if (!is_valid_ether_addr(addr->sa_data))
@@ -4464,7 +4465,12 @@ static int rtl_set_mac_address(struct net_device *dev, 
void *p)
 
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
-   rtl_rar_set(tp, dev->dev_addr);
+   pm_runtime_get_noresume(>dev);
+
+   if (pm_runtime_active(>dev))
+   rtl_rar_set(tp, dev->dev_addr);
+
+   pm_runtime_put_noidle(>dev);
 
return 0;
 }
@@ -7872,6 +7878,8 @@ static int rtl8169_runtime_resume(struct device *device)
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
 
+   rtl_rar_set(tp, dev->dev_addr);
+
if (!tp->TxDescArray)
return 0;
 
-- 
1.9.1



[PATCH net 2/3] r8169:eliminate error message in using ethtool -S when nic is down.

2016-02-26 Thread Chunhao Lin
This issue is caused by runtime power management. When NIC is down (ifconfig 
down)
the NIC may be put into runtime suspend state, that cause driver cannot dump
tally counter successfully and incur error message "rtl_counters_cond == 1
(loop: 1000, delay: 10)"

In this patch I add deceting driver runtime pm state. If driver is in runtime
suspend state, I will skip dump tall counter.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 432b278..3e9eb64 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -2291,11 +2291,17 @@ static void rtl8169_get_ethtool_stats(struct net_device 
*dev,
  struct ethtool_stats *stats, u64 *data)
 {
struct rtl8169_private *tp = netdev_priv(dev);
+   struct pci_dev *pdev = tp->pci_dev;
struct rtl8169_counters *counters = tp->counters;
 
ASSERT_RTNL();
 
-   rtl8169_update_counters(dev);
+   pm_runtime_get_noresume(>dev);
+
+   if (pm_runtime_active(>dev))
+   rtl8169_update_counters(dev);
+
+   pm_runtime_put_noidle(>dev);
 
data[0] = le64_to_cpu(counters->tx_packets);
data[1] = le64_to_cpu(counters->rx_packets);
-- 
1.9.1



[PATCH net v4] r8169:fix "rtl_counters_cond == 1 (loop: 1000, delay: 10)" log spam.

2016-02-23 Thread Chunhao Lin
There will be a log spam when there is no cable plugged. Please refer to
following links. https://bugzilla.kernel.org/show_bug.cgi?id=104351
https://bugzilla.kernel.org/show_bug.cgi?id=107421

This issue is caused by runtime power management. When there is no cable
plugged, the driver will be suspend (runtime suspend) by OS and NIC will be
put into the D3 state. During this time, if OS call rtl8169_get_stats64()
to dump tally counter, because NIC is in D3 state, the register value read
by driver will return all 0xff. This will let driver think tally counter
flag is not toggled and then sends the warning message "rtl_counters_cond
== 1 (loop: 1000, delay: 10)" to kernel log.

For fixing this issue, 1.add checking driver's pm runtime status in
rtl8169_get_stats64(). 2.dump tally counter before going runtime suspend
for counter accuracy in runtime suspend.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 537974c..4caeacb 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -7730,10 +7730,13 @@ rtl8169_get_stats64(struct net_device *dev, struct 
rtnl_link_stats64 *stats)
 {
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
+   struct pci_dev *pdev = tp->pci_dev;
struct rtl8169_counters *counters = tp->counters;
unsigned int start;
 
-   if (netif_running(dev))
+   pm_runtime_get_noresume(>dev);
+
+   if (netif_running(dev) && pm_runtime_active(>dev))
rtl8169_rx_missed(dev, ioaddr);
 
do {
@@ -7761,7 +7764,8 @@ rtl8169_get_stats64(struct net_device *dev, struct 
rtnl_link_stats64 *stats)
 * Fetch additonal counter values missing in stats collected by driver
 * from tally counters.
 */
-   rtl8169_update_counters(dev);
+   if (pm_runtime_active(>dev))
+   rtl8169_update_counters(dev);
 
/*
 * Subtract values fetched during initalization.
@@ -7774,6 +7778,8 @@ rtl8169_get_stats64(struct net_device *dev, struct 
rtnl_link_stats64 *stats)
stats->tx_aborted_errors = le16_to_cpu(counters->tx_aborted) -
le16_to_cpu(tp->tc_offset.tx_aborted);
 
+   pm_runtime_put_noidle(>dev);
+
return stats;
 }
 
@@ -7853,6 +7859,10 @@ static int rtl8169_runtime_suspend(struct device *device)
 
rtl8169_net_suspend(dev);
 
+   /* Update counters before going runtime suspend */
+   rtl8169_rx_missed(dev, tp->mmio_addr);
+   rtl8169_update_counters(dev);
+
return 0;
 }
 
-- 
1.9.1



[PATCH net v3] r8169:fix "rtl_counters_cond == 1 (loop: 1000, delay: 10)" log spam.

2016-02-23 Thread Chunhao Lin
There will be a log spam when there is no cable plugged.
Please refer to following links.
https://bugzilla.kernel.org/show_bug.cgi?id=104351
https://bugzilla.kernel.org/show_bug.cgi?id=107421

This issue is caused by runtime power management. When there is no cable 
plugged, the driver will be suspend (runtime suspend) by OS and NIC will be put 
into the D3 state. During this time, if OS call rtl8169_get_stats64() to dump 
tally counter, because NIC is in D3 state, the register value read by driver 
will return all 0xff. This will let driver think tally counter flag is not 
toggled and then sends the warning  message "rtl_counters_cond == 1 (loop: 1000,
delay: 10)" to kernel log.

For fixing this issue,
1.add checking driver's pm runtime status in rtl8169_get_stats64().
2.dump tally counter before going runtime suspend for counter accuracy in
  runtime suspend.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 537974c..404be51 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -7730,10 +7730,13 @@ rtl8169_get_stats64(struct net_device *dev, struct 
rtnl_link_stats64 *stats)
 {
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
+   struct pci_dev *pdev = tp->pci_dev;
struct rtl8169_counters *counters = tp->counters;
unsigned int start;
 
-   if (netif_running(dev))
+   pm_runtime_get_noresume(>dev);
+
+   if (netif_running(dev) && pm_runtime_active(>dev))
rtl8169_rx_missed(dev, ioaddr);
 
do {
@@ -7761,7 +7764,8 @@ rtl8169_get_stats64(struct net_device *dev, struct 
rtnl_link_stats64 *stats)
 * Fetch additonal counter values missing in stats collected by driver
 * from tally counters.
 */
-   rtl8169_update_counters(dev);
+   if (pm_runtime_active(>dev))
+   rtl8169_update_counters(dev);
 
/*
 * Subtract values fetched during initalization.
@@ -7774,6 +7778,8 @@ rtl8169_get_stats64(struct net_device *dev, struct 
rtnl_link_stats64 *stats)
stats->tx_aborted_errors = le16_to_cpu(counters->tx_aborted) -
le16_to_cpu(tp->tc_offset.tx_aborted);
 
+   pm_runtime_put_noidle(>dev);
+
return stats;
 }
 
@@ -7853,6 +7859,11 @@ static int rtl8169_runtime_suspend(struct device *device)
 
rtl8169_net_suspend(dev);
 
+   /* Update counters before going runtime suspend */
+   if (netif_running(dev))
+   rtl8169_rx_missed(dev, tp->mmio_addr);
+   rtl8169_update_counters(dev);
+
return 0;
 }
 
-- 
1.9.1



[PATCH net v2] r8169:fix "rtl_counters_cond == 1 (loop: 1000, delay: 10)" log spam.

2016-02-22 Thread Chunhao Lin
There will be a log spam when there is no cable plugged.
Please refer to following links.
https://bugzilla.kernel.org/show_bug.cgi?id=104351
https://bugzilla.kernel.org/show_bug.cgi?id=107421

This issue is caused by runtime power management. When there is no cable
plugged, the driver will be suspend (runtime suspend) by OS and NIC will
be put into the D3 state. During this time, if OS call rtl8169_get_stats64()
to dump tally counter, because NIC is in D3 state, the register value read by
driver will return all 0xff. This will let driver think tally counter flag is 
not
toggled and then sends the warning  message "rtl_counters_cond == 1 (loop: 1000,
delay: 10)" to kernel log.

For fixing this issue,
1.add checking driver's pm runtime status in rtl8169_get_stats64().
2.dump tally counter before going runtime suspend for counter accuracy in
  runtime suspend.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 537974c..a645f8d 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -7730,10 +7730,13 @@ rtl8169_get_stats64(struct net_device *dev, struct 
rtnl_link_stats64 *stats)
 {
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
+   struct pci_dev *pdev = tp->pci_dev;
struct rtl8169_counters *counters = tp->counters;
unsigned int start;
 
-   if (netif_running(dev))
+   pm_runtime_get_noresume(>dev);
+
+   if (netif_running(dev) && pm_runtime_active(>dev))
rtl8169_rx_missed(dev, ioaddr);
 
do {
@@ -7761,7 +7764,8 @@ rtl8169_get_stats64(struct net_device *dev, struct 
rtnl_link_stats64 *stats)
 * Fetch additonal counter values missing in stats collected by driver
 * from tally counters.
 */
-   rtl8169_update_counters(dev);
+   if (pm_runtime_active(>dev))
+   rtl8169_update_counters(dev);
 
/*
 * Subtract values fetched during initalization.
@@ -7774,6 +7778,8 @@ rtl8169_get_stats64(struct net_device *dev, struct 
rtnl_link_stats64 *stats)
stats->tx_aborted_errors = le16_to_cpu(counters->tx_aborted) -
le16_to_cpu(tp->tc_offset.tx_aborted);
 
+   pm_runtime_put_noidle(>dev);
+
return stats;
 }
 
@@ -7842,6 +7848,12 @@ static int rtl8169_runtime_suspend(struct device *device)
struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
+   void __iomem *ioaddr = tp->mmio_addr;
+
+   /* Update counters before going runtime suspend */
+   if (netif_running(dev))
+   rtl8169_rx_missed(dev, ioaddr);
+   rtl8169_update_counters(dev);
 
if (!tp->TxDescArray)
return 0;
-- 
1.9.1



[PATCH net] r8169:fix "rtl_counters_cond == 1 (loop: 1000, delay: 10)" log spam.

2016-02-18 Thread Chunhao Lin
There will be a log spam when there is no cable plugged.
Please refer to following links.
https://bugzilla.kernel.org/show_bug.cgi?id=104351
https://bugzilla.kernel.org/show_bug.cgi?id=107421

This issue is caused by runtime power management. When there is no cable
plugged, the driver will be suspend (runtime suspend) by OS and NIC will
be put into the D3 state. During this time, if OS call rtl8169_get_stats64()
to dump tally counter, because NIC is in D3 state, the register value read by
driver will return all 0xff. This will let driver think tally counter flag is 
not
toggled and then sends the warning  message "rtl_counters_cond == 1 (loop: 1000,
delay: 10)" to kernel log.

I add checking driver's pm runtime status in rtl8169_get_stats64() to fix
this issue.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 537974c..798b30c 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -7730,10 +7730,13 @@ rtl8169_get_stats64(struct net_device *dev, struct 
rtnl_link_stats64 *stats)
 {
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
+   struct pci_dev *pdev = tp->pci_dev;
struct rtl8169_counters *counters = tp->counters;
unsigned int start;
 
-   if (netif_running(dev))
+   pm_runtime_get_noresume(>dev);
+
+   if (netif_running(dev) && pm_runtime_active(>dev))
rtl8169_rx_missed(dev, ioaddr);
 
do {
@@ -7761,7 +7764,8 @@ rtl8169_get_stats64(struct net_device *dev, struct 
rtnl_link_stats64 *stats)
 * Fetch additonal counter values missing in stats collected by driver
 * from tally counters.
 */
-   rtl8169_update_counters(dev);
+   if (pm_runtime_active(>dev))
+   rtl8169_update_counters(dev);
 
/*
 * Subtract values fetched during initalization.
@@ -7774,6 +7778,8 @@ rtl8169_get_stats64(struct net_device *dev, struct 
rtnl_link_stats64 *stats)
stats->tx_aborted_errors = le16_to_cpu(counters->tx_aborted) -
le16_to_cpu(tp->tc_offset.tx_aborted);
 
+   pm_runtime_put_noidle(>dev);
+
return stats;
 }
 
-- 
1.9.1



[PATCH net-next] r8169:fix system hange problem.

2016-02-04 Thread Chunhao Lin
There are typos in setting RTL8168H hardware parameters. If system install
another version driver that may cuase system hang.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 17d5571..537974c 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -6137,28 +6137,28 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private 
*tp)
sw_cnt_1ms_ini = 1600/rg_saw_cnt;
sw_cnt_1ms_ini &= 0x0fff;
data = r8168_mac_ocp_read(tp, 0xd412);
-   data &= 0x0fff;
+   data &= ~0x0fff;
data |= sw_cnt_1ms_ini;
r8168_mac_ocp_write(tp, 0xd412, data);
}
 
data = r8168_mac_ocp_read(tp, 0xe056);
-   data &= 0xf0;
-   data |= 0x07;
+   data &= ~0xf0;
+   data |= 0x70;
r8168_mac_ocp_write(tp, 0xe056, data);
 
data = r8168_mac_ocp_read(tp, 0xe052);
-   data &= 0x8008;
-   data |= 0x6000;
+   data &= ~0x6000;
+   data |= 0x8008;
r8168_mac_ocp_write(tp, 0xe052, data);
 
data = r8168_mac_ocp_read(tp, 0xe0d6);
-   data &= 0x01ff;
+   data &= ~0x01ff;
data |= 0x017f;
r8168_mac_ocp_write(tp, 0xe0d6, data);
 
data = r8168_mac_ocp_read(tp, 0xd420);
-   data &= 0x0fff;
+   data &= ~0x0fff;
data |= 0x047f;
r8168_mac_ocp_write(tp, 0xd420, data);
 
-- 
1.9.1



[PATCH net-next 2/3] r8169:Fix typo in setting RTL8168H PHY PFM mode.

2015-12-29 Thread Chunhao Lin
The PHY PFM register is in PHY page 0x0a44 register 0x11, not 0x14.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 0decc1b..629f5e5 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -3894,7 +3894,7 @@ static void rtl8168h_1_hw_phy_config(struct 
rtl8169_private *tp)
 
/* disable phy pfm mode */
rtl_writephy(tp, 0x1f, 0x0a44);
-   rtl_w0w1_phy(tp, 0x14, 0x, 0x0080);
+   rtl_w0w1_phy(tp, 0x11, 0x, 0x0080);
rtl_writephy(tp, 0x1f, 0x);
 
/* Check ALDPS bit, disable it if enabled */
@@ -3967,7 +3967,7 @@ static void rtl8168h_2_hw_phy_config(struct 
rtl8169_private *tp)
 
/* disable phy pfm mode */
rtl_writephy(tp, 0x1f, 0x0a44);
-   rtl_w0w1_phy(tp, 0x14, 0x, 0x0080);
+   rtl_w0w1_phy(tp, 0x11, 0x, 0x0080);
rtl_writephy(tp, 0x1f, 0x);
 
/* Check ALDPS bit, disable it if enabled */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 3/3] r8169:Correct the way of setting RTL8168DP ephy

2015-12-29 Thread Chunhao Lin
The original way is wrong, it always writes ephy reg 0x03.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 17 +
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 629f5e5..aa24ba9 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -5818,11 +5818,10 @@ static void rtl_hw_start_8168d_4(struct rtl8169_private 
*tp)
void __iomem *ioaddr = tp->mmio_addr;
struct pci_dev *pdev = tp->pci_dev;
static const struct ephy_info e_info_8168d_4[] = {
-   { 0x0b, ~0, 0x48 },
-   { 0x19, 0x20,   0x50 },
-   { 0x0c, ~0, 0x20 }
-   };
-   int i;
+   { 0x0b, 0x, 0x0048 },
+   { 0x19, 0x0020, 0x0050 },
+   { 0x0c, 0x0100, 0x0020 }
+   };
 
rtl_csi_access_enable_1(tp);
 
@@ -5830,13 +5829,7 @@ static void rtl_hw_start_8168d_4(struct rtl8169_private 
*tp)
 
RTL_W8(MaxTxPacketSize, TxPacketMax);
 
-   for (i = 0; i < ARRAY_SIZE(e_info_8168d_4); i++) {
-   const struct ephy_info *e = e_info_8168d_4 + i;
-   u16 w;
-
-   w = rtl_ephy_read(tp, e->offset);
-   rtl_ephy_write(tp, 0x03, (w & e->mask) | e->bits);
-   }
+   rtl_ephy_init(tp, e_info_8168d_4, ARRAY_SIZE(e_info_8168d_4));
 
rtl_enable_clock_request(pdev);
 }
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 0/3] Fix some typos in setting hardware parameter

2015-12-29 Thread Chunhao Lin
The typos are in setting RTL8168DP, RTL8168EP and RTL8168H hardware parameters.
This series of patch fix these typos.

Chunhao Lin (3):
  r8169:Fix typo in setting RTL8168EP and RTL8168H D3cold PFM mode
  r8169:Fix typo in setting RTL8168H PHY PFM mode.
  r8169:Correct the way of setting RTL8168DP ephy

 drivers/net/ethernet/realtek/r8169.c | 27 ++-
 1 file changed, 10 insertions(+), 17 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 1/3] r8169:Fix typo in setting RTL8168EP and RTL8168H D3cold PFM mode

2015-12-29 Thread Chunhao Lin
The register for setting D3code PFM mode is  MISC_1, not DLLPR.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 58365bc..0decc1b 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -6127,7 +6127,7 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private 
*tp)
RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07);
 
RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN);
-   RTL_W8(DLLPR, RTL_R8(MISC_1) & ~PFM_D3COLD_EN);
+   RTL_W8(MISC_1, RTL_R8(MISC_1) & ~PFM_D3COLD_EN);
 
RTL_W8(DLLPR, RTL_R8(DLLPR) & ~TX_10M_PS_EN);
 
@@ -6252,7 +6252,7 @@ static void rtl_hw_start_8168ep_2(struct rtl8169_private 
*tp)
rtl_hw_start_8168ep(tp);
 
RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN);
-   RTL_W8(DLLPR, RTL_R8(MISC_1) & ~PFM_D3COLD_EN);
+   RTL_W8(MISC_1, RTL_R8(MISC_1) & ~PFM_D3COLD_EN);
 }
 
 static void rtl_hw_start_8168ep_3(struct rtl8169_private *tp)
@@ -6274,7 +6274,7 @@ static void rtl_hw_start_8168ep_3(struct rtl8169_private 
*tp)
rtl_hw_start_8168ep(tp);
 
RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN);
-   RTL_W8(DLLPR, RTL_R8(MISC_1) & ~PFM_D3COLD_EN);
+   RTL_W8(MISC_1, RTL_R8(MISC_1) & ~PFM_D3COLD_EN);
 
data = r8168_mac_ocp_read(tp, 0xd3e2);
data &= 0xf000;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 2/2] r8169:Update the way of reading RTL8168H PHY register "rg_saw_cnt"

2015-12-24 Thread Chunhao Lin
The vlaue of RTL8168H PHY register "rg_saw_cnt" only valid from bit0 to bit13.
When read this register, add bitwise-anding its value with 0x3fff.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 11cc32b..58365bc 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -6136,7 +6136,7 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private 
*tp)
rtl_pcie_state_l2l3_enable(tp, false);
 
rtl_writephy(tp, 0x1f, 0x0c42);
-   rg_saw_cnt = rtl_readphy(tp, 0x13);
+   rg_saw_cnt = (rtl_readphy(tp, 0x13) & 0x3fff);
rtl_writephy(tp, 0x1f, 0x);
if (rg_saw_cnt > 0) {
u16 sw_cnt_1ms_ini;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 0/2] r8169:Update RTL8168H PHY parameters

2015-12-24 Thread Chunhao Lin
Fix typo in setting PHY parameter and update the way of reading PHY register
"rg_saw_cnt".

Chunhao Lin (2):
  r8169:Fix typo in setting RTL8168H PHY parameter
  r8169:Update the way of reading RTL8168H PHY register "rg_saw_cnt"

 drivers/net/ethernet/realtek/r8169.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 1/2] r8169:Fix typo in setting RTL8168H PHY parameter

2015-12-24 Thread Chunhao Lin
In function "rtl8168h_2_hw_phy_config", there is a typo in setting
RTL8168H PHY parameter.

Signed-off-by: Chunhao Lin <h...@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 79ef799..11cc32b 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -3947,7 +3947,7 @@ static void rtl8168h_2_hw_phy_config(struct 
rtl8169_private *tp)
data = (ioffset_p3<<12)|(ioffset_p2<<8)|(ioffset_p1<<4)|(ioffset_p0);
 
if ((ioffset_p3 != 0x0f) || (ioffset_p2 != 0x0f) ||
-   (ioffset_p1 != 0x0f) || (ioffset_p0 == 0x0f)) {
+   (ioffset_p1 != 0x0f) || (ioffset_p0 != 0x0f)) {
rtl_writephy(tp, 0x1f, 0x0bcf);
rtl_writephy(tp, 0x16, data);
rtl_writephy(tp, 0x1f, 0x);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html