Received: by 2002:a05:6358:4e97:b0:b3:742d:4702 with SMTP id ce23csp3029935rwb; Mon, 15 Aug 2022 16:28:53 -0700 (PDT) X-Google-Smtp-Source: AA6agR5TUxRtaaBV/xzwAhDOTLTwtj0Tv5Wdu6hKVR5pb04mSvRJUg/JBQwUl9QcdCk/qFNP+St2 X-Received: by 2002:aa7:dd4f:0:b0:439:c144:24cd with SMTP id o15-20020aa7dd4f000000b00439c14424cdmr16202022edw.209.1660606133130; Mon, 15 Aug 2022 16:28:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660606133; cv=none; d=google.com; s=arc-20160816; b=gLEekxk3LqO0HlEOuQ08bZ/xP28TxX/0y6aDwHQeowYUNf2el2gvFBqJDpwlo7OqVS XF9PMXqkq3G7+pt74Nxpo8HT4m6zfySfwZO0FQnTTrwFLBR3zcAAj+CI9eRqbhknKKHn PZCoEnTh/ScPnvckQyVGGBOL62K4/qmVs2wUXTQdJsPe80tOuXGr0KF6AZDK4L90WgdM Rs9/xn/5gSgS3MLijB/3xTqpaaj8y/tZcLKjSYSlZUe+DOmZ1g6AkdTT/DSQisJxlxZm cp/DqcL4N0oU0vi/iUVDST5QVQ2899g9BWBLhbh0ygirn+0BjNOxjOjXGu6h69HKkxIT cPbw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=4Ch1jdB+vB2fZ/7wJkTWR2Qjkxh1fl1v4oLIYk4EZ2U=; b=nn6sCcYpD9g0ces4Sum9gHxTs6j//2lGSqRdfcpvifu6hY6DxWqXUZNWYWTARS3BEj sMR2DO1O+mdvhaPWKwNjsUAwOumQsUTaHoGwADAWe20hC+L+XxB2/tNcVnuBRG/L6xFi xcRLi2E5FTZUd1V8EqOJGQM3SXIFkHb/fJ+xrYf6EOO7AgGi97riny6j/aZfgFLDEhFo S3+5aio9WMPgJVviQy1DdgGt3b0tTjbm3nKUtcDm6dFmv2QBVrhIo1kpAEoiAybJz7PI wwjTyPch24FMXiBvla0iNx73x23uXyCM8dnX0PjUW9+VU/I2Wfp3lleodXvlxBCZE4gZ rgEw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=vs2wa4vD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id lr2-20020a170906fb8200b00707ad2d64edsi8356875ejb.98.2022.08.15.16.28.23; Mon, 15 Aug 2022 16:28:53 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=vs2wa4vD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242220AbiHOXRK (ORCPT + 99 others); Mon, 15 Aug 2022 19:17:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51222 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345283AbiHOXOZ (ORCPT ); Mon, 15 Aug 2022 19:14:25 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1BD1F7AC1D; Mon, 15 Aug 2022 13:01:24 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id C2B3EB80EAD; Mon, 15 Aug 2022 20:01:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 11A33C433C1; Mon, 15 Aug 2022 20:01:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1660593681; bh=DaELCTiURVygaN7KydWbsGgnuiXU/kiGrSZdk8PGV4E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vs2wa4vDtmNlsUE74amOP4HfGOSX73+dRy3GR2gYPPdwndgKKfkEq/u1ASvoQy+DN ZBmQU1ag5jVGQzIWQnlLzpXOclpfI6G8qSllkJBESCnabtivNlanSNOPRkX5bpNEIT 2GwsSyGTwYZi22GTDN9SwJHVhVFOuZ8JN/spvaCg= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Lukas Wunner , Andrew Lunn , "David S. Miller" , Sasha Levin , Oleksij Rempel , Ferry Toth Subject: [PATCH 5.18 0986/1095] usbnet: smsc95xx: Avoid link settings race on interrupt reception Date: Mon, 15 Aug 2022 20:06:25 +0200 Message-Id: <20220815180509.913191496@linuxfoundation.org> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220815180429.240518113@linuxfoundation.org> References: <20220815180429.240518113@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Lukas Wunner [ Upstream commit 8960f878e39fadc03d74292a6731f1e914cf2019 ] 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 Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- 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 2cb44d65bbc3..f5a208948d22 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); @@ -1088,6 +1090,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); } @@ -1993,7 +1996,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, -- 2.35.1