From patchwork Thu May 12 08:42:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 12847345 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69098C433FE for ; Thu, 12 May 2022 08:44:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345559AbiELIot (ORCPT ); Thu, 12 May 2022 04:44:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50518 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230160AbiELIoj (ORCPT ); Thu, 12 May 2022 04:44:39 -0400 Received: from mailout2.hostsharing.net (mailout2.hostsharing.net [IPv6:2a01:37:3000::53df:4ee9:0]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 47CD222442A; Thu, 12 May 2022 01:44:36 -0700 (PDT) Received: from h08.hostsharing.net (h08.hostsharing.net [83.223.95.28]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "*.hostsharing.net", Issuer "RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1" (verified OK)) by mailout2.hostsharing.net (Postfix) with ESMTPS id 326C710171323; Thu, 12 May 2022 10:44:34 +0200 (CEST) Received: from localhost (unknown [89.246.108.87]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id 112AD61C2B10; Thu, 12 May 2022 10:44:34 +0200 (CEST) X-Mailbox-Line: From 563c39a8b270a5e1d09d3f7b93020e8becf7d5e3 Mon Sep 17 00:00:00 2001 Message-Id: <563c39a8b270a5e1d09d3f7b93020e8becf7d5e3.1652343655.git.lukas@wunner.de> In-Reply-To: References: From: Lukas Wunner Date: Thu, 12 May 2022 10:42:01 +0200 Subject: [PATCH net-next v3 1/7] usbnet: Run unregister_netdev() before unbind() again To: "David S. Miller" , Jakub Kicinski , Paolo Abeni , Eric Dumazet Cc: netdev@vger.kernel.org, linux-usb@vger.kernel.org, Steve Glendinning , UNGLinuxDriver@microchip.com, Oliver Neukum , Andre Edich , Oleksij Rempel , Martyn Welch , Gabriel Hojda , Christoph Fritz , Lino Sanfilippo , Philipp Rosenberger , Heiner Kallweit , Andrew Lunn , Russell King , Ferry Toth Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Commit 2c9d6c2b871d ("usbnet: run unbind() before unregister_netdev()") sought to fix a use-after-free on disconnect of USB Ethernet adapters. It turns out that a different fix is necessary to address the issue: https://lore.kernel.org/netdev/18b3541e5372bc9b9fc733d422f4e698c089077c.1650177997.git.lukas@wunner.de/ So the commit was not necessary. The commit made binding and unbinding of USB Ethernet asymmetrical: Before, usbnet_probe() first invoked the ->bind() callback and then register_netdev(). usbnet_disconnect() mirrored that by first invoking unregister_netdev() and then ->unbind(). Since the commit, the order in usbnet_disconnect() is reversed and no longer mirrors usbnet_probe(). One consequence is that a PHY disconnected (and stopped) in ->unbind() is afterwards stopped once more by unregister_netdev() as it closes the netdev before unregistering. That necessitates a contortion in ->stop() because the PHY may only be stopped if it hasn't already been disconnected. Reverting the commit allows making the call to phy_stop() unconditional in ->stop(). Tested-by: Oleksij Rempel # LAN9514/9512/9500 Tested-by: Ferry Toth # LAN9514 Signed-off-by: Lukas Wunner Acked-by: Oliver Neukum Cc: Martyn Welch Cc: Andrew Lunn --- drivers/net/usb/asix_devices.c | 6 +----- drivers/net/usb/smsc95xx.c | 3 +-- drivers/net/usb/usbnet.c | 6 +++--- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 38e47a93fb83..5b5eb630c4b7 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c @@ -795,11 +795,7 @@ static int ax88772_stop(struct usbnet *dev) { struct asix_common_private *priv = dev->driver_priv; - /* On unplugged USB, we will get MDIO communication errors and the - * PHY will be set in to PHY_HALTED state. - */ - if (priv->phydev->state != PHY_HALTED) - phy_stop(priv->phydev); + phy_stop(priv->phydev); return 0; } diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 4ef61f6b85df..edf0492ad489 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -1243,8 +1243,7 @@ static int smsc95xx_start_phy(struct usbnet *dev) static int smsc95xx_stop(struct usbnet *dev) { - if (dev->net->phydev) - phy_stop(dev->net->phydev); + phy_stop(dev->net->phydev); return 0; } diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 9a6450f796dc..36b24ec11650 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1616,9 +1616,6 @@ void usbnet_disconnect (struct usb_interface *intf) xdev->bus->bus_name, xdev->devpath, dev->driver_info->description); - if (dev->driver_info->unbind) - dev->driver_info->unbind(dev, intf); - net = dev->net; unregister_netdev (net); @@ -1626,6 +1623,9 @@ void usbnet_disconnect (struct usb_interface *intf) usb_scuttle_anchored_urbs(&dev->deferred); + if (dev->driver_info->unbind) + dev->driver_info->unbind(dev, intf); + usb_kill_urb(dev->interrupt); usb_free_urb(dev->interrupt); kfree(dev->padding_pkt); From patchwork Thu May 12 08:42:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 12847358 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD27EC433FE for ; Thu, 12 May 2022 08:46:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351721AbiELIqZ (ORCPT ); Thu, 12 May 2022 04:46:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54826 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351701AbiELIqT (ORCPT ); Thu, 12 May 2022 04:46:19 -0400 Received: from mailout2.hostsharing.net (mailout2.hostsharing.net [IPv6:2a01:37:3000::53df:4ee9:0]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BE85B3D1CD for ; Thu, 12 May 2022 01:46:18 -0700 (PDT) Received: from h08.hostsharing.net (h08.hostsharing.net [IPv6:2a01:37:1000::53df:5f1c:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "*.hostsharing.net", Issuer "RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1" (verified OK)) by mailout2.hostsharing.net (Postfix) with ESMTPS id 001CF1017672D; Thu, 12 May 2022 10:46:14 +0200 (CEST) Received: from localhost (unknown [89.246.108.87]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id D0C3660E98D9; Thu, 12 May 2022 10:46:13 +0200 (CEST) X-Mailbox-Line: From 97d9528bb7fbee7313c5c6fb3a80346faaa32c13 Mon Sep 17 00:00:00 2001 Message-Id: <97d9528bb7fbee7313c5c6fb3a80346faaa32c13.1652343655.git.lukas@wunner.de> In-Reply-To: References: From: Lukas Wunner Date: Thu, 12 May 2022 10:42:02 +0200 Subject: [PATCH net-next v3 2/7] usbnet: smsc95xx: Don't clear read-only PHY interrupt To: "David S. Miller" , Jakub Kicinski , Paolo Abeni , Eric Dumazet Cc: netdev@vger.kernel.org, linux-usb@vger.kernel.org, Steve Glendinning , UNGLinuxDriver@microchip.com, Oliver Neukum , Andre Edich , Oleksij Rempel , Martyn Welch , Gabriel Hojda , Christoph Fritz , Lino Sanfilippo , Philipp Rosenberger , Heiner Kallweit , Andrew Lunn , Russell King , Ferry Toth Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Upon receiving data from the Interrupt Endpoint, the SMSC LAN95xx driver attempts to clear the signaled interrupts by writing "all ones" to the Interrupt Status Register. However the driver only ever enables a single type of interrupt, namely the PHY Interrupt. And according to page 119 of the LAN950x datasheet, its bit in the Interrupt Status Register is read-only. There's no other way to clear it than in a separate PHY register: https://www.microchip.com/content/dam/mchp/documents/UNG/ProductDocuments/DataSheets/LAN950x-Data-Sheet-DS00001875D.pdf Consequently, writing "all ones" to the Interrupt Status Register is pointless and can be dropped. Tested-by: Oleksij Rempel # LAN9514/9512/9500 Tested-by: Ferry Toth # LAN9514 Signed-off-by: Lukas Wunner --- drivers/net/usb/smsc95xx.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index edf0492ad489..2cb44d65bbc3 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -572,10 +572,6 @@ static int smsc95xx_link_reset(struct usbnet *dev) unsigned long flags; int ret; - ret = smsc95xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_); - if (ret < 0) - return ret; - spin_lock_irqsave(&pdata->mac_cr_lock, flags); if (pdata->phydev->duplex != DUPLEX_FULL) { pdata->mac_cr &= ~MAC_CR_FDPX_; From patchwork Thu May 12 08:42:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 12847359 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 87545C433EF for ; Thu, 12 May 2022 08:48:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351679AbiELIsU (ORCPT ); Thu, 12 May 2022 04:48:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33748 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351676AbiELIsT (ORCPT ); Thu, 12 May 2022 04:48:19 -0400 Received: from mailout2.hostsharing.net (mailout2.hostsharing.net [IPv6:2a01:37:3000::53df:4ee9:0]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7FFAF106A44; Thu, 12 May 2022 01:48:18 -0700 (PDT) Received: from h08.hostsharing.net (h08.hostsharing.net [83.223.95.28]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "*.hostsharing.net", Issuer "RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1" (verified OK)) by mailout2.hostsharing.net (Postfix) with ESMTPS id F39E710171219; Thu, 12 May 2022 10:48:16 +0200 (CEST) Received: from localhost (unknown [89.246.108.87]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id CCE7C60E98D9; Thu, 12 May 2022 10:48:16 +0200 (CEST) X-Mailbox-Line: From 53ea51cabb288a0eba475ffaf1b2afd15b505b62 Mon Sep 17 00:00:00 2001 Message-Id: <53ea51cabb288a0eba475ffaf1b2afd15b505b62.1652343655.git.lukas@wunner.de> In-Reply-To: References: From: Lukas Wunner Date: Thu, 12 May 2022 10:42:03 +0200 Subject: [PATCH net-next v3 3/7] usbnet: smsc95xx: Don't reset PHY behind PHY driver's back To: "David S. Miller" , Jakub Kicinski , Paolo Abeni , Eric Dumazet Cc: netdev@vger.kernel.org, linux-usb@vger.kernel.org, Steve Glendinning , UNGLinuxDriver@microchip.com, Oliver Neukum , Andre Edich , Oleksij Rempel , Martyn Welch , Gabriel Hojda , Christoph Fritz , Lino Sanfilippo , Philipp Rosenberger , Heiner Kallweit , Andrew Lunn , Russell King , Ferry Toth Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org smsc95xx_reset() resets the PHY behind the PHY driver's back, which seems like a bad idea generally. Remove that portion of the function. We're about to use PHY interrupts instead of polling to detect link changes on SMSC LAN95xx chips. Because smsc95xx_reset() is called from usbnet_open(), PHY interrupt settings are lost whenever the net_device is brought up. There are two other callers of smsc95xx_reset(), namely smsc95xx_bind() and smsc95xx_reset_resume(), and both may indeed benefit from a PHY reset. However they already perform one through their calls to phy_connect_direct() and phy_init_hw(). Tested-by: Oleksij Rempel # LAN9514/9512/9500 Tested-by: Ferry Toth # LAN9514 Signed-off-by: Lukas Wunner Cc: Martyn Welch Cc: Gabriel Hojda --- drivers/net/usb/smsc95xx.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 2cb44d65bbc3..6c37c7adde1b 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -887,24 +887,6 @@ static int smsc95xx_reset(struct usbnet *dev) return ret; } - ret = smsc95xx_write_reg(dev, PM_CTRL, PM_CTL_PHY_RST_); - if (ret < 0) - return ret; - - timeout = 0; - do { - msleep(10); - ret = smsc95xx_read_reg(dev, PM_CTRL, &read_buf); - if (ret < 0) - return ret; - timeout++; - } while ((read_buf & PM_CTL_PHY_RST_) && (timeout < 100)); - - if (timeout >= 100) { - netdev_warn(dev->net, "timeout waiting for PHY Reset\n"); - return ret; - } - ret = smsc95xx_set_mac_address(dev); if (ret < 0) return ret; From patchwork Thu May 12 08:42:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 12847360 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7CAACC433FE for ; Thu, 12 May 2022 08:50:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351691AbiELIuA (ORCPT ); Thu, 12 May 2022 04:50:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39806 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237718AbiELIt7 (ORCPT ); Thu, 12 May 2022 04:49:59 -0400 Received: from mailout2.hostsharing.net (mailout2.hostsharing.net [IPv6:2a01:37:3000::53df:4ee9:0]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 86E8F22442A; Thu, 12 May 2022 01:49:58 -0700 (PDT) Received: from h08.hostsharing.net (h08.hostsharing.net [83.223.95.28]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "*.hostsharing.net", Issuer "RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1" (verified OK)) by mailout2.hostsharing.net (Postfix) with ESMTPS id 2061D1017672D; Thu, 12 May 2022 10:49:57 +0200 (CEST) Received: from localhost (unknown [89.246.108.87]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id F158660E98D9; Thu, 12 May 2022 10:49:56 +0200 (CEST) X-Mailbox-Line: From 9891d6dab3ad4a77add7b4833e9cf202da71d059 Mon Sep 17 00:00:00 2001 Message-Id: <9891d6dab3ad4a77add7b4833e9cf202da71d059.1652343655.git.lukas@wunner.de> In-Reply-To: References: From: Lukas Wunner Date: Thu, 12 May 2022 10:42:04 +0200 Subject: [PATCH net-next v3 4/7] usbnet: smsc95xx: Avoid link settings race on interrupt reception To: "David S. Miller" , Jakub Kicinski , Paolo Abeni , Eric Dumazet Cc: netdev@vger.kernel.org, linux-usb@vger.kernel.org, Steve Glendinning , UNGLinuxDriver@microchip.com, Oliver Neukum , Andre Edich , Oleksij Rempel , Martyn Welch , Gabriel Hojda , Christoph Fritz , Lino Sanfilippo , Philipp Rosenberger , Heiner Kallweit , Andrew Lunn , Russell King , Ferry Toth Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org When a PHY interrupt is signaled, the SMSC LAN95xx driver updates the MAC full duplex mode and PHY flow control registers based on cached data in struct phy_device: smsc95xx_status() # raises EVENT_LINK_RESET usbnet_deferred_kevent() smsc95xx_link_reset() # uses cached data in phydev Simultaneously, phylib polls link status once per second and updates that cached data: phy_state_machine() phy_check_link_status() phy_read_status() lan87xx_read_status() genphy_read_status() # updates cached data in phydev If smsc95xx_link_reset() wins the race against genphy_read_status(), the registers may be updated based on stale data. E.g. if the link was previously down, phydev->duplex is set to DUPLEX_UNKNOWN and that's what smsc95xx_link_reset() will use, even though genphy_read_status() may update it to DUPLEX_FULL afterwards. PHY interrupts are currently only enabled on suspend to trigger wakeup, so the impact of the race is limited, but we're about to enable them perpetually. Avoid the race by delaying execution of smsc95xx_link_reset() until phy_state_machine() has done its job and calls back via smsc95xx_handle_link_change(). Signaling EVENT_LINK_RESET on wakeup is not necessary because phylib picks up link status changes through polling. So drop the declaration of a ->link_reset() callback. Note that the semicolon on a line by itself added in smsc95xx_status() is a placeholder for a function call which will be added in a subsequent commit. That function call will actually handle the INT_ENP_PHY_INT_ interrupt. Tested-by: Oleksij Rempel # LAN9514/9512/9500 Tested-by: Ferry Toth # LAN9514 Signed-off-by: Lukas Wunner --- drivers/net/usb/smsc95xx.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 6c37c7adde1b..6309ff8e75de 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -566,7 +566,7 @@ static int smsc95xx_phy_update_flowcontrol(struct usbnet *dev) return smsc95xx_write_reg(dev, AFC_CFG, afc_cfg); } -static int smsc95xx_link_reset(struct usbnet *dev) +static void smsc95xx_mac_update_fullduplex(struct usbnet *dev) { struct smsc95xx_priv *pdata = dev->driver_priv; unsigned long flags; @@ -583,14 +583,16 @@ static int smsc95xx_link_reset(struct usbnet *dev) spin_unlock_irqrestore(&pdata->mac_cr_lock, flags); ret = smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr); - if (ret < 0) - return ret; + if (ret < 0) { + if (ret != -ENODEV) + netdev_warn(dev->net, + "Error updating MAC full duplex mode\n"); + return; + } ret = smsc95xx_phy_update_flowcontrol(dev); if (ret < 0) netdev_warn(dev->net, "Error updating PHY flow control\n"); - - return ret; } static void smsc95xx_status(struct usbnet *dev, struct urb *urb) @@ -607,7 +609,7 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb) netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata); if (intdata & INT_ENP_PHY_INT_) - usbnet_defer_kevent(dev, EVENT_LINK_RESET); + ; else netdev_warn(dev->net, "unexpected interrupt, intdata=0x%08X\n", intdata); @@ -1070,6 +1072,7 @@ static void smsc95xx_handle_link_change(struct net_device *net) struct usbnet *dev = netdev_priv(net); phy_print_status(net->phydev); + smsc95xx_mac_update_fullduplex(dev); usbnet_defer_kevent(dev, EVENT_LINK_CHANGE); } @@ -1975,7 +1978,6 @@ static const struct driver_info smsc95xx_info = { .description = "smsc95xx USB 2.0 Ethernet", .bind = smsc95xx_bind, .unbind = smsc95xx_unbind, - .link_reset = smsc95xx_link_reset, .reset = smsc95xx_reset, .check_connect = smsc95xx_start_phy, .stop = smsc95xx_stop, From patchwork Thu May 12 08:42:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 12847368 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2DA51C433F5 for ; Thu, 12 May 2022 08:51:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351711AbiELIve (ORCPT ); Thu, 12 May 2022 04:51:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40880 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351700AbiELIu6 (ORCPT ); Thu, 12 May 2022 04:50:58 -0400 Received: from mailout1.hostsharing.net (mailout1.hostsharing.net [IPv6:2a01:37:1000::53df:5fcc:0]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E941427B3A; Thu, 12 May 2022 01:50:55 -0700 (PDT) Received: from h08.hostsharing.net (h08.hostsharing.net [IPv6:2a01:37:1000::53df:5f1c:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "*.hostsharing.net", Issuer "RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1" (verified OK)) by mailout1.hostsharing.net (Postfix) with ESMTPS id BB30A101920D9; Thu, 12 May 2022 10:50:53 +0200 (CEST) Received: from localhost (unknown [89.246.108.87]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id 9812260E98D9; Thu, 12 May 2022 10:50:53 +0200 (CEST) X-Mailbox-Line: From 748ac44eeb97b209f66182f3788d2a49d7bc28fe Mon Sep 17 00:00:00 2001 Message-Id: <748ac44eeb97b209f66182f3788d2a49d7bc28fe.1652343655.git.lukas@wunner.de> In-Reply-To: References: From: Lukas Wunner Date: Thu, 12 May 2022 10:42:05 +0200 Subject: [PATCH net-next v3 5/7] usbnet: smsc95xx: Forward PHY interrupts to PHY driver to avoid polling To: "David S. Miller" , Jakub Kicinski , Paolo Abeni , Eric Dumazet Cc: netdev@vger.kernel.org, linux-usb@vger.kernel.org, Steve Glendinning , UNGLinuxDriver@microchip.com, Oliver Neukum , Andre Edich , Oleksij Rempel , Martyn Welch , Gabriel Hojda , Christoph Fritz , Lino Sanfilippo , Philipp Rosenberger , Heiner Kallweit , Andrew Lunn , Russell King , Ferry Toth Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Link status of SMSC LAN95xx chips is polled once per second, even though they're capable of signaling PHY interrupts through the MAC layer. Forward those interrupts to the PHY driver to avoid polling. Benefits are reduced bus traffic, reduced CPU overhead and quicker interface bringup. Polling was introduced in 2016 by commit d69d16949346 ("usbnet: smsc95xx: fix link detection for disabled autonegotiation"). Back then, the LAN95xx driver neglected to enable the ENERGYON interrupt, hence couldn't detect link-up events when auto-negotiation was disabled. The proper solution would have been to enable the ENERGYON interrupt instead of polling. Since then, PHY handling was moved from the LAN95xx driver to the SMSC PHY driver with commit 05b35e7eb9a1 ("smsc95xx: add phylib support"). That PHY driver is capable of link detection with auto-negotiation disabled because it enables the ENERGYON interrupt. Note that signaling interrupts through the MAC layer not only works with the integrated PHY, but also with an external PHY, provided its interrupt pin is attached to LAN95xx's nPHY_INT pin. In the unlikely event that the interrupt pin of an external PHY is attached to a GPIO of the SoC (or not connected at all), the driver can be amended to retrieve the irq from the PHY's of_node. To forward PHY interrupts to phylib, it is not sufficient to call phy_mac_interrupt(). Instead, the PHY's interrupt handler needs to run so that PHY interrupts are cleared. That's because according to page 119 of the LAN950x datasheet, "The source of this interrupt is a level. The interrupt persists until it is cleared in the PHY." https://www.microchip.com/content/dam/mchp/documents/UNG/ProductDocuments/DataSheets/LAN950x-Data-Sheet-DS00001875D.pdf Therefore, create an IRQ domain with a single IRQ for the PHY. In the future, the IRQ domain may be extended to support the 11 GPIOs on the LAN95xx. Normally the PHY interrupt should be masked until the PHY driver has cleared it. However masking requires a (sleeping) USB transaction and interrupts are received in (non-sleepable) softirq context. I decided not to mask the interrupt at all (by using the dummy_irq_chip's noop ->irq_mask() callback): The USB interrupt endpoint is polled in 1 msec intervals and normally that's sufficient to wake the PHY driver's IRQ thread and have it clear the interrupt. If it does take longer, worst thing that can happen is the IRQ thread is woken again. No big deal. Because PHY interrupts are now perpetually enabled, there's no need to selectively enable them on suspend. So remove all invocations of smsc95xx_enable_phy_wakeup_interrupts(). In smsc95xx_resume(), move the call of phy_init_hw() before usbnet_resume() (which restarts the status URB) to ensure that the PHY is fully initialized when an interrupt is handled. Tested-by: Oleksij Rempel # LAN9514/9512/9500 Tested-by: Ferry Toth # LAN9514 Signed-off-by: Lukas Wunner Reviewed-by: Andrew Lunn # from a PHY perspective Cc: Andre Edich Reported-by: Marek Szyprowski Tested-by: Marek Szyprowski Tested-by: Marek Szyprowski --- Only change since v2: * Drop call to __irq_enter_raw() which worked around a warning in generic_handle_domain_irq(). That warning is gone since 792ea6a074ae (queued on tip.git/irq/urgent). (Marc Zyngier, Thomas Gleixner) drivers/net/usb/smsc95xx.c | 113 ++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 52 deletions(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 6309ff8e75de..bd03e16f98a1 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -53,6 +55,9 @@ #define SUSPEND_ALLMODES (SUSPEND_SUSPEND0 | SUSPEND_SUSPEND1 | \ SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3) +#define SMSC95XX_NR_IRQS (1) /* raise to 12 for GPIOs */ +#define PHY_HWIRQ (SMSC95XX_NR_IRQS - 1) + struct smsc95xx_priv { u32 mac_cr; u32 hash_hi; @@ -61,6 +66,9 @@ struct smsc95xx_priv { spinlock_t mac_cr_lock; u8 features; u8 suspend_flags; + struct irq_chip irqchip; + struct irq_domain *irqdomain; + struct fwnode_handle *irqfwnode; struct mii_bus *mdiobus; struct phy_device *phydev; }; @@ -597,6 +605,8 @@ static void smsc95xx_mac_update_fullduplex(struct usbnet *dev) static void smsc95xx_status(struct usbnet *dev, struct urb *urb) { + struct smsc95xx_priv *pdata = dev->driver_priv; + unsigned long flags; u32 intdata; if (urb->actual_length != 4) { @@ -608,11 +618,15 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb) intdata = get_unaligned_le32(urb->transfer_buffer); netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata); + local_irq_save(flags); + if (intdata & INT_ENP_PHY_INT_) - ; + generic_handle_domain_irq(pdata->irqdomain, PHY_HWIRQ); else netdev_warn(dev->net, "unexpected interrupt, intdata=0x%08X\n", intdata); + + local_irq_restore(flags); } /* Enable or disable Tx & Rx checksum offload engines */ @@ -1080,8 +1094,9 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) { struct smsc95xx_priv *pdata; bool is_internal_phy; + char usb_path[64]; + int ret, phy_irq; u32 val; - int ret; printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n"); @@ -1121,10 +1136,38 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) if (ret) goto free_pdata; + /* create irq domain for use by PHY driver and GPIO consumers */ + usb_make_path(dev->udev, usb_path, sizeof(usb_path)); + pdata->irqfwnode = irq_domain_alloc_named_fwnode(usb_path); + if (!pdata->irqfwnode) { + ret = -ENOMEM; + goto free_pdata; + } + + pdata->irqdomain = irq_domain_create_linear(pdata->irqfwnode, + SMSC95XX_NR_IRQS, + &irq_domain_simple_ops, + pdata); + if (!pdata->irqdomain) { + ret = -ENOMEM; + goto free_irqfwnode; + } + + phy_irq = irq_create_mapping(pdata->irqdomain, PHY_HWIRQ); + if (!phy_irq) { + ret = -ENOENT; + goto remove_irqdomain; + } + + pdata->irqchip = dummy_irq_chip; + pdata->irqchip.name = SMSC_CHIPNAME; + irq_set_chip_and_handler_name(phy_irq, &pdata->irqchip, + handle_simple_irq, "phy"); + pdata->mdiobus = mdiobus_alloc(); if (!pdata->mdiobus) { ret = -ENOMEM; - goto free_pdata; + goto dispose_irq; } ret = smsc95xx_read_reg(dev, HW_CFG, &val); @@ -1157,6 +1200,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) goto unregister_mdio; } + pdata->phydev->irq = phy_irq; pdata->phydev->is_internal = is_internal_phy; /* detect device revision as different features may be available */ @@ -1199,6 +1243,15 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) free_mdio: mdiobus_free(pdata->mdiobus); +dispose_irq: + irq_dispose_mapping(phy_irq); + +remove_irqdomain: + irq_domain_remove(pdata->irqdomain); + +free_irqfwnode: + irq_domain_free_fwnode(pdata->irqfwnode); + free_pdata: kfree(pdata); return ret; @@ -1211,6 +1264,9 @@ static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf) phy_disconnect(dev->net->phydev); mdiobus_unregister(pdata->mdiobus); mdiobus_free(pdata->mdiobus); + irq_dispose_mapping(irq_find_mapping(pdata->irqdomain, PHY_HWIRQ)); + irq_domain_remove(pdata->irqdomain); + irq_domain_free_fwnode(pdata->irqfwnode); netif_dbg(dev, ifdown, dev->net, "free pdata\n"); kfree(pdata); } @@ -1235,29 +1291,6 @@ static u32 smsc_crc(const u8 *buffer, size_t len, int filter) return crc << ((filter % 2) * 16); } -static int smsc95xx_enable_phy_wakeup_interrupts(struct usbnet *dev, u16 mask) -{ - int ret; - - netdev_dbg(dev->net, "enabling PHY wakeup interrupts\n"); - - /* read to clear */ - ret = smsc95xx_mdio_read_nopm(dev, PHY_INT_SRC); - if (ret < 0) - return ret; - - /* enable interrupt source */ - ret = smsc95xx_mdio_read_nopm(dev, PHY_INT_MASK); - if (ret < 0) - return ret; - - ret |= mask; - - smsc95xx_mdio_write_nopm(dev, PHY_INT_MASK, ret); - - return 0; -} - static int smsc95xx_link_ok_nopm(struct usbnet *dev) { int ret; @@ -1424,7 +1457,6 @@ static int smsc95xx_enter_suspend3(struct usbnet *dev) static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up) { struct smsc95xx_priv *pdata = dev->driver_priv; - int ret; if (!netif_running(dev->net)) { /* interface is ifconfig down so fully power down hw */ @@ -1443,27 +1475,10 @@ static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up) } netdev_dbg(dev->net, "autosuspend entering SUSPEND1\n"); - - /* enable PHY wakeup events for if cable is attached */ - ret = smsc95xx_enable_phy_wakeup_interrupts(dev, - PHY_INT_MASK_ANEG_COMP_); - if (ret < 0) { - netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); - return ret; - } - netdev_info(dev->net, "entering SUSPEND1 mode\n"); return smsc95xx_enter_suspend1(dev); } - /* enable PHY wakeup events so we remote wakeup if cable is pulled */ - ret = smsc95xx_enable_phy_wakeup_interrupts(dev, - PHY_INT_MASK_LINK_DOWN_); - if (ret < 0) { - netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); - return ret; - } - netdev_dbg(dev->net, "autosuspend entering SUSPEND3\n"); return smsc95xx_enter_suspend3(dev); } @@ -1529,13 +1544,6 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message) } if (pdata->wolopts & WAKE_PHY) { - ret = smsc95xx_enable_phy_wakeup_interrupts(dev, - (PHY_INT_MASK_ANEG_COMP_ | PHY_INT_MASK_LINK_DOWN_)); - if (ret < 0) { - netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); - goto done; - } - /* if link is down then configure EDPD and enter SUSPEND1, * otherwise enter SUSPEND0 below */ @@ -1769,11 +1777,12 @@ static int smsc95xx_resume(struct usb_interface *intf) return ret; } + phy_init_hw(pdata->phydev); + ret = usbnet_resume(intf); if (ret < 0) netdev_warn(dev->net, "usbnet_resume error\n"); - phy_init_hw(pdata->phydev); return ret; } From patchwork Thu May 12 08:42:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 12847369 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8A82EC433F5 for ; Thu, 12 May 2022 08:53:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351755AbiELIxs (ORCPT ); Thu, 12 May 2022 04:53:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45408 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350936AbiELIxj (ORCPT ); Thu, 12 May 2022 04:53:39 -0400 X-Greylist: delayed 409 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Thu, 12 May 2022 01:53:04 PDT Received: from mailout2.hostsharing.net (mailout2.hostsharing.net [83.223.78.233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB6F914040B; Thu, 12 May 2022 01:53:03 -0700 (PDT) Received: from h08.hostsharing.net (h08.hostsharing.net [83.223.95.28]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "*.hostsharing.net", Issuer "RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1" (verified OK)) by mailout2.hostsharing.net (Postfix) with ESMTPS id 2B6F410189E11; Thu, 12 May 2022 10:53:02 +0200 (CEST) Received: from localhost (unknown [89.246.108.87]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id 0746660E98D9; Thu, 12 May 2022 10:53:02 +0200 (CEST) X-Mailbox-Line: From cf9f1b5d1b07e0fa5f78bc8557216ef04f401af5 Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: Lukas Wunner Date: Thu, 12 May 2022 10:42:06 +0200 Subject: [PATCH net-next v3 6/7] net: phy: smsc: Cache interrupt mask To: "David S. Miller" , Jakub Kicinski , Paolo Abeni , Eric Dumazet Cc: netdev@vger.kernel.org, linux-usb@vger.kernel.org, Steve Glendinning , UNGLinuxDriver@microchip.com, Oliver Neukum , Andre Edich , Oleksij Rempel , Martyn Welch , Gabriel Hojda , Christoph Fritz , Lino Sanfilippo , Philipp Rosenberger , Heiner Kallweit , Andrew Lunn , Russell King , Ferry Toth Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Cache the interrupt mask to avoid re-reading it from the PHY upon every interrupt. This will simplify a subsequent commit which detects hot-removal in the interrupt handler and bails out. Analyzing and debugging PHY transactions also becomes simpler if such redundant reads are avoided. Last not least, interrupt overhead and latency is slightly improved. Tested-by: Oleksij Rempel # LAN9514/9512/9500 Tested-by: Ferry Toth # LAN9514 Signed-off-by: Lukas Wunner --- drivers/net/phy/smsc.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index 92225d0fc246..e0eadea4b4b5 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -44,6 +44,7 @@ static struct smsc_hw_stat smsc_hw_stats[] = { }; struct smsc_phy_priv { + u16 intmask; bool energy_enable; struct clk *refclk; }; @@ -58,7 +59,6 @@ static int smsc_phy_ack_interrupt(struct phy_device *phydev) static int smsc_phy_config_intr(struct phy_device *phydev) { struct smsc_phy_priv *priv = phydev->priv; - u16 intmask = 0; int rc; if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { @@ -66,12 +66,15 @@ static int smsc_phy_config_intr(struct phy_device *phydev) if (rc) return rc; - intmask = MII_LAN83C185_ISF_INT4 | MII_LAN83C185_ISF_INT6; + priv->intmask = MII_LAN83C185_ISF_INT4 | MII_LAN83C185_ISF_INT6; if (priv->energy_enable) - intmask |= MII_LAN83C185_ISF_INT7; - rc = phy_write(phydev, MII_LAN83C185_IM, intmask); + priv->intmask |= MII_LAN83C185_ISF_INT7; + + rc = phy_write(phydev, MII_LAN83C185_IM, priv->intmask); } else { - rc = phy_write(phydev, MII_LAN83C185_IM, intmask); + priv->intmask = 0; + + rc = phy_write(phydev, MII_LAN83C185_IM, 0); if (rc) return rc; @@ -83,13 +86,8 @@ static int smsc_phy_config_intr(struct phy_device *phydev) static irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev) { - int irq_status, irq_enabled; - - irq_enabled = phy_read(phydev, MII_LAN83C185_IM); - if (irq_enabled < 0) { - phy_error(phydev); - return IRQ_NONE; - } + struct smsc_phy_priv *priv = phydev->priv; + int irq_status; irq_status = phy_read(phydev, MII_LAN83C185_ISF); if (irq_status < 0) { @@ -97,7 +95,7 @@ static irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev) return IRQ_NONE; } - if (!(irq_status & irq_enabled)) + if (!(irq_status & priv->intmask)) return IRQ_NONE; phy_trigger_machine(phydev); From patchwork Thu May 12 08:42:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 12847370 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80EF6C433FE for ; Thu, 12 May 2022 08:55:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350824AbiELIz0 (ORCPT ); Thu, 12 May 2022 04:55:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57560 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350313AbiELIzW (ORCPT ); Thu, 12 May 2022 04:55:22 -0400 Received: from mailout2.hostsharing.net (mailout2.hostsharing.net [IPv6:2a01:37:3000::53df:4ee9:0]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5A1A8227824; Thu, 12 May 2022 01:55:18 -0700 (PDT) Received: from h08.hostsharing.net (h08.hostsharing.net [IPv6:2a01:37:1000::53df:5f1c:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "*.hostsharing.net", Issuer "RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1" (verified OK)) by mailout2.hostsharing.net (Postfix) with ESMTPS id 9A96A103A8B64; Thu, 12 May 2022 10:55:16 +0200 (CEST) Received: from localhost (unknown [89.246.108.87]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id 7305061638A3; Thu, 12 May 2022 10:55:16 +0200 (CEST) X-Mailbox-Line: From 4a90661372af73e056f7b243df9c039945715a3b Mon Sep 17 00:00:00 2001 Message-Id: <4a90661372af73e056f7b243df9c039945715a3b.1652343655.git.lukas@wunner.de> In-Reply-To: References: From: Lukas Wunner Date: Thu, 12 May 2022 10:42:07 +0200 Subject: [PATCH net-next v3 7/7] net: phy: smsc: Cope with hot-removal in interrupt handler To: "David S. Miller" , Jakub Kicinski , Paolo Abeni , Eric Dumazet Cc: netdev@vger.kernel.org, linux-usb@vger.kernel.org, Steve Glendinning , UNGLinuxDriver@microchip.com, Oliver Neukum , Andre Edich , Oleksij Rempel , Martyn Welch , Gabriel Hojda , Christoph Fritz , Lino Sanfilippo , Philipp Rosenberger , Heiner Kallweit , Andrew Lunn , Russell King , Ferry Toth Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org If reading the Interrupt Source Flag register fails with -ENODEV, then the PHY has been hot-removed and the correct response is to bail out instead of throwing a WARN splat and attempting to suspend the PHY. The PHY should be stopped in due course anyway as the kernel asynchronously tears down the device. Tested-by: Oleksij Rempel # LAN9514/9512/9500 Tested-by: Ferry Toth # LAN9514 Signed-off-by: Lukas Wunner --- drivers/net/phy/smsc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index e0eadea4b4b5..1b54684b68a0 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -91,7 +91,9 @@ static irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev) irq_status = phy_read(phydev, MII_LAN83C185_ISF); if (irq_status < 0) { - phy_error(phydev); + if (irq_status != -ENODEV) + phy_error(phydev); + return IRQ_NONE; }