]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
r8169: fix data corruption issue on RTL8402
authorHeiner Kallweit <hkallweit1@gmail.com>
Thu, 1 Oct 2020 07:23:02 +0000 (09:23 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Oct 2020 08:54:56 +0000 (09:54 +0100)
[ Upstream commit ef9da46ddef071e1bbb943afbbe9b38771855554 ]

Petr reported that after resume from suspend RTL8402 partially
truncates incoming packets, and re-initializing register RxConfig
before the actual chip re-initialization sequence is needed to avoid
the issue.

Reported-by: Petr Tesarik <ptesarik@suse.cz>
Proposed-by: Petr Tesarik <ptesarik@suse.cz>
Tested-by: Petr Tesarik <ptesarik@suse.cz>
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/realtek/r8169.c

index 6df404e3dd271889fa5a7053fd3ed885bb836f29..136aef392714a6f5f482b1a4b16ff38af112a4b1 100644 (file)
@@ -4111,6 +4111,27 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
        rtl_unlock_work(tp);
 }
 
+static void rtl_init_rxcfg(struct rtl8169_private *tp)
+{
+       switch (tp->mac_version) {
+       case RTL_GIGA_MAC_VER_01 ... RTL_GIGA_MAC_VER_06:
+       case RTL_GIGA_MAC_VER_10 ... RTL_GIGA_MAC_VER_17:
+               RTL_W32(tp, RxConfig, RX_FIFO_THRESH | RX_DMA_BURST);
+               break;
+       case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24:
+       case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_36:
+       case RTL_GIGA_MAC_VER_38:
+               RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
+               break;
+       case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51:
+               RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
+               break;
+       default:
+               RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST);
+               break;
+       }
+}
+
 static int rtl_set_mac_address(struct net_device *dev, void *p)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
@@ -4128,6 +4149,10 @@ static int rtl_set_mac_address(struct net_device *dev, void *p)
 
        pm_runtime_put_noidle(d);
 
+       /* Reportedly at least Asus X453MA truncates packets otherwise */
+       if (tp->mac_version == RTL_GIGA_MAC_VER_37)
+               rtl_init_rxcfg(tp);
+
        return 0;
 }
 
@@ -4289,27 +4314,6 @@ static void rtl_pll_power_up(struct rtl8169_private *tp)
        }
 }
 
-static void rtl_init_rxcfg(struct rtl8169_private *tp)
-{
-       switch (tp->mac_version) {
-       case RTL_GIGA_MAC_VER_01 ... RTL_GIGA_MAC_VER_06:
-       case RTL_GIGA_MAC_VER_10 ... RTL_GIGA_MAC_VER_17:
-               RTL_W32(tp, RxConfig, RX_FIFO_THRESH | RX_DMA_BURST);
-               break;
-       case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24:
-       case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_36:
-       case RTL_GIGA_MAC_VER_38:
-               RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
-               break;
-       case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51:
-               RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
-               break;
-       default:
-               RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST);
-               break;
-       }
-}
-
 static void rtl8169_init_ring_indexes(struct rtl8169_private *tp)
 {
        tp->dirty_tx = tp->cur_tx = tp->cur_rx = 0;