From patchwork Thu Jun 3 02:27:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koba Ko X-Patchwork-Id: 1486938 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FwVCq30jSz9sX2; Thu, 3 Jun 2021 12:27:19 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1lod4m-00038a-R3; Thu, 03 Jun 2021 02:27:16 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1lod4k-00037z-BY for kernel-team@lists.ubuntu.com; Thu, 03 Jun 2021 02:27:14 +0000 Received: from mail-pj1-f69.google.com ([209.85.216.69]) by youngberry.canonical.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1lod4k-0000xm-40 for kernel-team@lists.ubuntu.com; Thu, 03 Jun 2021 02:27:14 +0000 Received: by mail-pj1-f69.google.com with SMTP id o1-20020a17090a4201b029015c8f11f550so4474579pjg.5 for ; Wed, 02 Jun 2021 19:27:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=GXDvFPjhRv1emTvvKVtlQ4QGz4VEmeXSYZhLIUznynU=; b=musTMw/T3MgtsuY3munkbw2NenLISp+cXUFImarjDI07ov3L5FU0/8vfnqhm9qaF3w 0KwsdZ/0pM+P8dZQdRjan+mThYZzqF4HQzfwdxCiR50XXSkpcToa7thzh533XH3Lal0b 8Vu4ZiX5nP6winVExm/83N8FOdP8IhV8vnYs8lIPdJ+pGObsgDHB8XAhdHkKK9VB7XHw xQukliaMzv0Cz3xGq8VtRkcA8SqIzH41JgpcxE0NlAQPQPjjqNwl+N4MY5sFO3ost5hg zc6X662ePpXJYdJ8JFMMXB9fW6PMLtHDZBix4mB33MPMzrjrbxxSiOG3ZVKw3fthIN+F zo+w== X-Gm-Message-State: AOAM533msoDomQOKC6ptP6CVlz80rlh22Yns9Y8XQMAeS1eZZv/O5oy4 YWYvH+hHg1funamDGbodl9NFjed2QxkDkC6k+AqbX9JRgFJxkZMK4Yob8yqpkSpFjiOq8WEMw67 3NJ3PUyZ2Vo5LKYHlZOweidS3abg4tOuEcXzDZoIsIQ== X-Received: by 2002:a17:902:7b8a:b029:109:7bdb:ed9 with SMTP id w10-20020a1709027b8ab02901097bdb0ed9mr8590569pll.73.1622687232502; Wed, 02 Jun 2021 19:27:12 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwVaYG1qcznp2SHonS1Vzu9SudwkDjTg/QCJTwiICXMpulHhyu0q7XueUazApSWWvNfIQvcWA== X-Received: by 2002:a17:902:7b8a:b029:109:7bdb:ed9 with SMTP id w10-20020a1709027b8ab02901097bdb0ed9mr8590552pll.73.1622687232132; Wed, 02 Jun 2021 19:27:12 -0700 (PDT) Received: from canonical.com (61-220-137-34.HINET-IP.hinet.net. [61.220.137.34]) by smtp.gmail.com with ESMTPSA id f5sm592903pjp.37.2021.06.02.19.27.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jun 2021 19:27:11 -0700 (PDT) From: Koba Ko To: kernel-team@lists.ubuntu.com Subject: [PATCH 1/1][SRU][OEM-5.10] UBUNTU: SAUCE: r8169: introduce polling method for link change Date: Thu, 3 Jun 2021 10:27:08 +0800 Message-Id: <20210603022708.225525-2-koba.ko@canonical.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603022708.225525-1-koba.ko@canonical.com> References: <20210603022708.225525-1-koba.ko@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/1930645 For RTL8106E, it's a Fast-ethernet chip. If ASPM is enabled, the link chang interrupt wouldn't be triggerd immediately and must wait a very long time to get link change interrupt. Even the link change interrupt isn't triggered, the phy link is already established. Introduce a polling method to watch the status of phy link and disable the link change interrupt. Also add a quirk for those realtek devices have the same issue. Signed-off-by: Koba Ko --- drivers/net/ethernet/realtek/r8169.h | 2 + drivers/net/ethernet/realtek/r8169_main.c | 116 +++++++++++++++++++--- 2 files changed, 102 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.h b/drivers/net/ethernet/realtek/r8169.h index 2728df46ec410..a8c71adb1b571 100644 --- a/drivers/net/ethernet/realtek/r8169.h +++ b/drivers/net/ethernet/realtek/r8169.h @@ -11,6 +11,8 @@ #include #include +#define RTL8169_LINK_TIMEOUT (1 * HZ) + enum mac_version { /* support for ancient RTL_GIGA_MAC_VER_01 has been removed */ RTL_GIGA_MAC_VER_02, diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 6d58427739d93..e5272835c01db 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -177,6 +177,11 @@ static const struct pci_device_id rtl8169_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); +static const struct pci_device_id rtl8169_linkChg_polling_enabled[] = { + { PCI_VDEVICE(REALTEK, 0x8136), RTL_CFG_NO_GBIT }, + { 0 } +}; + enum rtl_registers { MAC0 = 0, /* Ethernet hardware address. */ MAC4 = 4, @@ -612,6 +617,7 @@ struct rtl8169_private { u16 cp_cmd; u32 irq_mask; struct clk *clk; + struct timer_list link_timer; struct { DECLARE_BITMAP(flags, RTL_FLAG_MAX); @@ -1175,6 +1181,16 @@ static void rtl8168ep_stop_cmac(struct rtl8169_private *tp) RTL_W8(tp, IBCR0, RTL_R8(tp, IBCR0) & ~0x01); } +static int rtl_link_chng_polling_quirk (struct rtl8169_private *tp) +{ + struct pci_dev *pdev = tp->pci_dev; + + if (pdev->vendor == 0x10ec && pdev->device == 0x8136 && !tp->supports_gmii) + return 1; + + return 0; +} + static void rtl8168dp_driver_start(struct rtl8169_private *tp) { r8168dp_oob_notify(tp, OOB_CMD_DRIVER_START); @@ -4675,6 +4691,76 @@ static void rtl_task(struct work_struct *work) rtnl_unlock(); } +static void r8169_phylink_handler(struct net_device *ndev) +{ + struct rtl8169_private *tp = netdev_priv(ndev); + + if (netif_carrier_ok(ndev)) { + rtl_link_chg_patch(tp); + pm_request_resume(&tp->pci_dev->dev); + } else { + pm_runtime_idle(&tp->pci_dev->dev); + } + + if (net_ratelimit()) + phy_print_status(tp->phydev); +} + +static unsigned int +rtl8169_xmii_link_ok(struct net_device *dev) +{ + struct rtl8169_private *tp = netdev_priv(dev); + unsigned int retval; + + retval = (RTL_R8(tp, PHYstatus) & LinkStatus) ? 1 : 0; + + return retval; +} + +static void +rtl8169_check_link_status(struct net_device *dev) +{ + struct rtl8169_private *tp = netdev_priv(dev); + int link_status_on; + + link_status_on = rtl8169_xmii_link_ok(dev); + + if (netif_carrier_ok(dev) == link_status_on) { + return; + } + + phy_mac_interrupt(tp->phydev); + + r8169_phylink_handler (dev); +} + +static void rtl8169_link_timer(struct timer_list *t) +{ + struct rtl8169_private *tp = from_timer(tp, t, link_timer); + struct net_device *dev = tp->dev; + struct timer_list *timer = t; + unsigned long flags; + + rtl8169_check_link_status(dev); + + if (timer_pending(&tp->link_timer)) + return; + + mod_timer(timer, jiffies + RTL8169_LINK_TIMEOUT); +} + +static inline void rtl8169_delete_link_timer(struct net_device *dev, struct timer_list *timer) +{ + del_timer_sync(timer); +} + +static inline void rtl8169_request_link_timer(struct net_device *dev) +{ + struct rtl8169_private *tp = netdev_priv(dev); + + timer_setup(&tp->link_timer, rtl8169_link_timer, TIMER_INIT_FLAGS); +} + static int rtl8169_poll(struct napi_struct *napi, int budget) { struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi); @@ -4691,21 +4777,6 @@ static int rtl8169_poll(struct napi_struct *napi, int budget) return work_done; } -static void r8169_phylink_handler(struct net_device *ndev) -{ - struct rtl8169_private *tp = netdev_priv(ndev); - - if (netif_carrier_ok(ndev)) { - rtl_link_chg_patch(tp); - pm_request_resume(&tp->pci_dev->dev); - } else { - pm_runtime_idle(&tp->pci_dev->dev); - } - - if (net_ratelimit()) - phy_print_status(tp->phydev); -} - static int r8169_phy_connect(struct rtl8169_private *tp) { struct phy_device *phydev = tp->phydev; @@ -4833,6 +4904,11 @@ static int rtl_open(struct net_device *dev) goto err_free_irq; rtl8169_up(tp); + + if (rtl_link_chng_polling_quirk(tp)) { + mod_timer(&tp->link_timer, jiffies + RTL8169_LINK_TIMEOUT); + } + rtl8169_init_counter_offsets(tp); netif_start_queue(dev); @@ -4897,6 +4973,7 @@ rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) static void rtl8169_net_suspend(struct rtl8169_private *tp) { + netif_device_detach(tp->dev); if (netif_running(tp->dev)) @@ -5067,7 +5144,10 @@ static const struct net_device_ops rtl_netdev_ops = { static void rtl_set_irq_mask(struct rtl8169_private *tp) { - tp->irq_mask = RxOK | RxErr | TxOK | TxErr | LinkChg; + tp->irq_mask = RxOK | RxErr | TxOK | TxErr; + + if (!rtl_link_chng_polling_quirk(tp)) + tp->irq_mask |= LinkChg; if (tp->mac_version <= RTL_GIGA_MAC_VER_06) tp->irq_mask |= SYSErr | RxOverflow | RxFIFOOver; @@ -5507,6 +5587,10 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (pci_dev_run_wake(pdev)) pm_runtime_put_sync(&pdev->dev); + if (rtl_link_chng_polling_quirk(tp)) { + rtl8169_request_link_timer(dev); + } + return 0; }