r8169: add handling DASH when DASH is disabled

commit 0ab0c45d8a upstream.

For devices that support DASH, even DASH is disabled, there may still
exist a default firmware that will influence device behavior.
So driver needs to handle DASH for devices that support DASH, no
matter the DASH status is.

This patch also prepares for "fix network lost after resume on DASH
systems".

Fixes: ee7a1beb97 ("r8169:call "rtl8168_driver_start" "rtl8168_driver_stop" only when hardware dash function is enabled")
Cc: stable@vger.kernel.org
Signed-off-by: ChunHao Lin <hau@realtek.com>
Reviewed-by: Heiner Kallweit <hkallweit1@gmail.com>
Link: https://lore.kernel.org/r/20231109173400.4573-2-hau@realtek.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
ChunHao Lin 2023-11-10 01:33:59 +08:00 committed by Greg Kroah-Hartman
parent 89a0fc5004
commit ddb96a13b2

View File

@ -624,6 +624,7 @@ struct rtl8169_private {
unsigned supports_gmii:1; unsigned supports_gmii:1;
unsigned aspm_manageable:1; unsigned aspm_manageable:1;
unsigned dash_enabled:1;
dma_addr_t counters_phys_addr; dma_addr_t counters_phys_addr;
struct rtl8169_counters *counters; struct rtl8169_counters *counters;
struct rtl8169_tc_offsets tc_offset; struct rtl8169_tc_offsets tc_offset;
@ -1253,14 +1254,26 @@ static bool r8168ep_check_dash(struct rtl8169_private *tp)
return r8168ep_ocp_read(tp, 0x128) & BIT(0); return r8168ep_ocp_read(tp, 0x128) & BIT(0);
} }
static enum rtl_dash_type rtl_check_dash(struct rtl8169_private *tp) static bool rtl_dash_is_enabled(struct rtl8169_private *tp)
{
switch (tp->dash_type) {
case RTL_DASH_DP:
return r8168dp_check_dash(tp);
case RTL_DASH_EP:
return r8168ep_check_dash(tp);
default:
return false;
}
}
static enum rtl_dash_type rtl_get_dash_type(struct rtl8169_private *tp)
{ {
switch (tp->mac_version) { switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_28: case RTL_GIGA_MAC_VER_28:
case RTL_GIGA_MAC_VER_31: case RTL_GIGA_MAC_VER_31:
return r8168dp_check_dash(tp) ? RTL_DASH_DP : RTL_DASH_NONE; return RTL_DASH_DP;
case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53: case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53:
return r8168ep_check_dash(tp) ? RTL_DASH_EP : RTL_DASH_NONE; return RTL_DASH_EP;
default: default:
return RTL_DASH_NONE; return RTL_DASH_NONE;
} }
@ -1453,7 +1466,7 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
device_set_wakeup_enable(tp_to_dev(tp), wolopts); device_set_wakeup_enable(tp_to_dev(tp), wolopts);
if (tp->dash_type == RTL_DASH_NONE) { if (!tp->dash_enabled) {
rtl_set_d3_pll_down(tp, !wolopts); rtl_set_d3_pll_down(tp, !wolopts);
tp->dev->wol_enabled = wolopts ? 1 : 0; tp->dev->wol_enabled = wolopts ? 1 : 0;
} }
@ -2512,7 +2525,7 @@ static void rtl_wol_enable_rx(struct rtl8169_private *tp)
static void rtl_prepare_power_down(struct rtl8169_private *tp) static void rtl_prepare_power_down(struct rtl8169_private *tp)
{ {
if (tp->dash_type != RTL_DASH_NONE) if (tp->dash_enabled)
return; return;
if (tp->mac_version == RTL_GIGA_MAC_VER_32 || if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
@ -4875,7 +4888,7 @@ static int rtl8169_runtime_idle(struct device *device)
{ {
struct rtl8169_private *tp = dev_get_drvdata(device); struct rtl8169_private *tp = dev_get_drvdata(device);
if (tp->dash_type != RTL_DASH_NONE) if (tp->dash_enabled)
return -EBUSY; return -EBUSY;
if (!netif_running(tp->dev) || !netif_carrier_ok(tp->dev)) if (!netif_running(tp->dev) || !netif_carrier_ok(tp->dev))
@ -4901,8 +4914,7 @@ static void rtl_shutdown(struct pci_dev *pdev)
/* Restore original MAC address */ /* Restore original MAC address */
rtl_rar_set(tp, tp->dev->perm_addr); rtl_rar_set(tp, tp->dev->perm_addr);
if (system_state == SYSTEM_POWER_OFF && if (system_state == SYSTEM_POWER_OFF && !tp->dash_enabled) {
tp->dash_type == RTL_DASH_NONE) {
pci_wake_from_d3(pdev, tp->saved_wolopts); pci_wake_from_d3(pdev, tp->saved_wolopts);
pci_set_power_state(pdev, PCI_D3hot); pci_set_power_state(pdev, PCI_D3hot);
} }
@ -5260,7 +5272,8 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1); rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1);
tp->aspm_manageable = !rc; tp->aspm_manageable = !rc;
tp->dash_type = rtl_check_dash(tp); tp->dash_type = rtl_get_dash_type(tp);
tp->dash_enabled = rtl_dash_is_enabled(tp);
tp->cp_cmd = RTL_R16(tp, CPlusCmd) & CPCMD_MASK; tp->cp_cmd = RTL_R16(tp, CPlusCmd) & CPCMD_MASK;
@ -5331,7 +5344,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* configure chip for default features */ /* configure chip for default features */
rtl8169_set_features(dev, dev->features); rtl8169_set_features(dev, dev->features);
if (tp->dash_type == RTL_DASH_NONE) { if (!tp->dash_enabled) {
rtl_set_d3_pll_down(tp, true); rtl_set_d3_pll_down(tp, true);
} else { } else {
rtl_set_d3_pll_down(tp, false); rtl_set_d3_pll_down(tp, false);
@ -5371,7 +5384,8 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
"ok" : "ko"); "ok" : "ko");
if (tp->dash_type != RTL_DASH_NONE) { if (tp->dash_type != RTL_DASH_NONE) {
netdev_info(dev, "DASH enabled\n"); netdev_info(dev, "DASH %s\n",
tp->dash_enabled ? "enabled" : "disabled");
rtl8168_driver_start(tp); rtl8168_driver_start(tp);
} }