r8169: fix dmar pte write access is not set error

When close device, if wol is enabled, rx will be enabled. When open
device it will cause rx packet to be dma to the wrong memory address
after pci_set_master() and system log will show blow messages.

DMAR: DRHD: handling fault status reg 3
DMAR: [DMA Write] Request device [02:00.0] PASID ffffffff fault addr
ffdd4000 [fault reason 05] PTE Write access is not set

In this patch, driver disable tx/rx when close device. If wol is
enabled, only enable rx filter and disable rxdv_gate(if support) to
let hardware only receive packet to fifo but not to dma it.

Signed-off-by: Chunhao Lin <hau@realtek.com>
Reviewed-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Chunhao Lin 2022-12-26 20:31:53 +08:00 committed by David S. Miller
parent ad425666a1
commit bb41c13c05

View File

@ -2438,6 +2438,9 @@ static void rtl_wol_enable_rx(struct rtl8169_private *tp)
if (tp->mac_version >= RTL_GIGA_MAC_VER_25)
RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) |
AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
if (tp->mac_version >= RTL_GIGA_MAC_VER_40)
rtl_disable_rxdvgate(tp);
}
static void rtl_prepare_power_down(struct rtl8169_private *tp)
@ -3872,7 +3875,7 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp)
netdev_reset_queue(tp->dev);
}
static void rtl8169_cleanup(struct rtl8169_private *tp, bool going_down)
static void rtl8169_cleanup(struct rtl8169_private *tp)
{
napi_disable(&tp->napi);
@ -3884,9 +3887,6 @@ static void rtl8169_cleanup(struct rtl8169_private *tp, bool going_down)
rtl_rx_close(tp);
if (going_down && tp->dev->wol_enabled)
goto no_reset;
switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_28:
case RTL_GIGA_MAC_VER_31:
@ -3907,7 +3907,7 @@ static void rtl8169_cleanup(struct rtl8169_private *tp, bool going_down)
}
rtl_hw_reset(tp);
no_reset:
rtl8169_tx_clear(tp);
rtl8169_init_ring_indexes(tp);
}
@ -3918,7 +3918,7 @@ static void rtl_reset_work(struct rtl8169_private *tp)
netif_stop_queue(tp->dev);
rtl8169_cleanup(tp, false);
rtl8169_cleanup(tp);
for (i = 0; i < NUM_RX_DESC; i++)
rtl8169_mark_to_asic(tp->RxDescArray + i);
@ -4605,7 +4605,7 @@ static void rtl8169_down(struct rtl8169_private *tp)
pci_clear_master(tp->pci_dev);
rtl_pci_commit(tp);
rtl8169_cleanup(tp, true);
rtl8169_cleanup(tp);
rtl_disable_exit_l1(tp);
rtl_prepare_power_down(tp);
}