From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.1 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E7D0C169C4 for ; Wed, 6 Feb 2019 18:40:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C384E20663 for ; Wed, 6 Feb 2019 18:40:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jyRXZBOZ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726585AbfBFSkI (ORCPT ); Wed, 6 Feb 2019 13:40:08 -0500 Received: from mail-wm1-f68.google.com ([209.85.128.68]:35120 "EHLO mail-wm1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725928AbfBFSkI (ORCPT ); Wed, 6 Feb 2019 13:40:08 -0500 Received: by mail-wm1-f68.google.com with SMTP id t200so4005512wmt.0 for ; Wed, 06 Feb 2019 10:40:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=to:cc:from:subject:message-id:date:user-agent:mime-version :content-language:content-transfer-encoding; bh=v0rE1WTyRdz9PuCSoquapbCuos5IxPW1EptJWaEh5nw=; b=jyRXZBOZ+ofRzkurFTEPCuchfvIjYNdSuNkSWo1cf/Iv3BKYZjKBdTowjkVvziA5Vr qc+OHBrYGNNUcRRAywgr8VhUsEwNYINr5R1o1aE2V6I4rUBui4Y8x1gLegJ747pUbvIp LtTdDLJOJGiC1Q7vwCYAq7SA0pPFUBxCq4UpjGlM2f0LfrraDxCOqjKUGCO2kx0yB3t1 1y90IYFdjH+DLOnFBV7nL6lqmxsu76S1TLlxaykUMIvROkT2KN16hhmlqecvzi+TENzz v/cDukFqO7dwAfjDiE7Ug9fJSisT7sV9BV/kn7BBNixZm2lifSaKdnjkUILmPGOIy00s EY7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:cc:from:subject:message-id:date:user-agent :mime-version:content-language:content-transfer-encoding; bh=v0rE1WTyRdz9PuCSoquapbCuos5IxPW1EptJWaEh5nw=; b=V4UU2vQkkNgASYWaq9AWAvBv/VQ0xzb4fvhMykeRDcDEtVgR02JYD9lt56JBoOO6TE zjhwm4FlrioDwEn2u+QFig4Wz1qttLS0DwjqgH+nqg4x2pgAZITO2NlKhbgeTD2G3Xdw TCgdRKpvbnQ+Y4HRx1TfjOLAhhYn8Nzumu4r2A53UZvS1r6IkHPgyGAbapNh5SITPIi2 TfADzcj3JPJ6wgMElBMnoUyVDeI7St0W3VlNNrw/SU30LaZIFk632kQ61soykxrcLvnO 5UQX1kfOKyDOIbwx92eaFBS8vCUyT4ApxEnCYtGuZJGOV7YJrGmryGxQKnaNGQblWNdc 8n8g== X-Gm-Message-State: AHQUAuY/ihdiYMTgxbUvoNnKF6f0NwvqGChGu9XlqpoPT+r02rvAc2Ap 9jevooJZRQCxQu2QweY7MpI= X-Google-Smtp-Source: AHgI3IY/PIZ+Y7xlKhaJA0SfRszExJERl/ubT503uGKn1UgoO10q4pZNQeY67o1J2RjeMCheC5WYRQ== X-Received: by 2002:a7b:c5cc:: with SMTP id n12mr4217165wmk.149.1549478406124; Wed, 06 Feb 2019 10:40:06 -0800 (PST) Received: from ?IPv6:2003:ea:8bf1:e200:480f:ead4:b207:c2dd? ([2003:ea:8bf1:e200:480f:ead4:b207:c2dd]) by smtp.googlemail.com with ESMTPSA id y139sm20481987wmd.22.2019.02.06.10.40.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 Feb 2019 10:40:04 -0800 (PST) To: Andrew Lunn , Florian Fainelli , David Miller Cc: "netdev@vger.kernel.org" , Russell King - ARM Linux From: Heiner Kallweit Subject: [PATCH net-next] net: phy: consider latched link-down status in polling mode Message-ID: <7180c54c-34b2-0a36-97ff-bbda302eb427@gmail.com> Date: Wed, 6 Feb 2019 19:39:52 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.5.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The link status value latches link-down events. To get the current status we read the register twice in genphy_update_link(). There's a potential risk that we miss a link-down event in polling mode. This may cause issues if the user e.g. connects his machine to a different network. On the other hand reading the latched value may cause issues in interrupt mode. Following scenario: - After boot link goes up - phy_start() is called triggering an aneg restart, hence link goes down and link-down info is latched. - After aneg has finished link goes up and triggers an interrupt. Interrupt handler reads link status, means it reads the latched "link is down" info. But there won't be another interrupt as long as link stays up, therefore phylib will never recognize that link is up. Deal with both scenarios by reading the register twice in interrupt mode only. Signed-off-by: Heiner Kallweit --- drivers/net/phy/phy-c45.c | 10 ++++++++-- drivers/net/phy/phy_device.c | 13 +++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c index c92d0fb7e..449f0f986 100644 --- a/drivers/net/phy/phy-c45.c +++ b/drivers/net/phy/phy-c45.c @@ -134,9 +134,15 @@ int genphy_c45_read_link(struct phy_device *phydev, u32 mmd_mask) mmd_mask &= ~BIT(devad); /* The link state is latched low so that momentary link - * drops can be detected. Do not double-read the status - * register if the link is down. + * drops can be detected. Do not double-read the status + * in polling mode to detect such short link drops. */ + if (!phy_polling_mode(phydev)) { + val = phy_read_mmd(phydev, devad, MDIO_STAT1); + if (val < 0) + return val; + } + val = phy_read_mmd(phydev, devad, MDIO_STAT1); if (val < 0) return val; diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 891e0178b..d490cd2a8 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1729,10 +1729,15 @@ int genphy_update_link(struct phy_device *phydev) { int status; - /* Do a fake read */ - status = phy_read(phydev, MII_BMSR); - if (status < 0) - return status; + /* The link state is latched low so that momentary link + * drops can be detected. Do not double-read the status + * in polling mode to detect such short link drops. + */ + if (!phy_polling_mode(phydev)) { + status = phy_read(phydev, MII_BMSR); + if (status < 0) + return status; + } /* Read link and autonegotiation status */ status = phy_read(phydev, MII_BMSR); -- 2.20.1