Skip to content

Commit

Permalink
r8169: add handling DASH when DASH is disabled
Browse files Browse the repository at this point in the history
commit 0ab0c45 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: ee7a1be ("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>
  • Loading branch information
ChunHao Lin authored and gregkh committed Nov 28, 2023
1 parent 89a0fc5 commit ddb96a1
Showing 1 changed file with 25 additions and 11 deletions.
36 changes: 25 additions & 11 deletions drivers/net/ethernet/realtek/r8169_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,7 @@ struct rtl8169_private {

unsigned supports_gmii:1;
unsigned aspm_manageable:1;
unsigned dash_enabled:1;
dma_addr_t counters_phys_addr;
struct rtl8169_counters *counters;
struct rtl8169_tc_offsets tc_offset;
Expand Down Expand Up @@ -1253,14 +1254,26 @@ static bool r8168ep_check_dash(struct rtl8169_private *tp)
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) {
case RTL_GIGA_MAC_VER_28:
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:
return r8168ep_check_dash(tp) ? RTL_DASH_EP : RTL_DASH_NONE;
return RTL_DASH_EP;
default:
return RTL_DASH_NONE;
}
Expand Down Expand Up @@ -1453,7 +1466,7 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 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);
tp->dev->wol_enabled = wolopts ? 1 : 0;
}
Expand Down Expand Up @@ -2512,7 +2525,7 @@ static void rtl_wol_enable_rx(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;

if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
Expand Down Expand Up @@ -4875,7 +4888,7 @@ static int rtl8169_runtime_idle(struct device *device)
{
struct rtl8169_private *tp = dev_get_drvdata(device);

if (tp->dash_type != RTL_DASH_NONE)
if (tp->dash_enabled)
return -EBUSY;

if (!netif_running(tp->dev) || !netif_carrier_ok(tp->dev))
Expand All @@ -4901,8 +4914,7 @@ static void rtl_shutdown(struct pci_dev *pdev)
/* Restore original MAC address */
rtl_rar_set(tp, tp->dev->perm_addr);

if (system_state == SYSTEM_POWER_OFF &&
tp->dash_type == RTL_DASH_NONE) {
if (system_state == SYSTEM_POWER_OFF && !tp->dash_enabled) {
pci_wake_from_d3(pdev, tp->saved_wolopts);
pci_set_power_state(pdev, PCI_D3hot);
}
Expand Down Expand Up @@ -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);
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;

Expand Down Expand Up @@ -5331,7 +5344,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* configure chip for default 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);
} else {
rtl_set_d3_pll_down(tp, false);
Expand Down Expand Up @@ -5371,7 +5384,8 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
"ok" : "ko");

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);
}

Expand Down

0 comments on commit ddb96a1

Please sign in to comment.