From patchwork Wed Apr 14 22:28:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Bauer X-Patchwork-Id: 12203869 X-Patchwork-Delegate: kuba@kernel.org 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=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT 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 66795C433ED for ; Wed, 14 Apr 2021 22:35:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 450F761019 for ; Wed, 14 Apr 2021 22:35:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233729AbhDNWf6 (ORCPT ); Wed, 14 Apr 2021 18:35:58 -0400 Received: from perseus.uberspace.de ([95.143.172.134]:40368 "EHLO perseus.uberspace.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232099AbhDNWf5 (ORCPT ); Wed, 14 Apr 2021 18:35:57 -0400 X-Greylist: delayed 400 seconds by postgrey-1.27 at vger.kernel.org; Wed, 14 Apr 2021 18:35:57 EDT Received: (qmail 19010 invoked from network); 14 Apr 2021 22:28:52 -0000 Received: from localhost (HELO localhost) (127.0.0.1) by perseus.uberspace.de with SMTP; 14 Apr 2021 22:28:52 -0000 From: David Bauer To: netdev@vger.kernel.org Cc: andrew@lunn.ch Subject: [PATCH net-next 1/2] net: phy: at803x: use paged reads Date: Thu, 15 Apr 2021 00:28:40 +0200 Message-Id: <20210414222841.82548-1-mail@david-bauer.net> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Refactor the page-switching in at803x_aneg_done to use paged reads as suggested by Andrew Lunn. This way, potential race conditions are avoided, as the MDIO lock was previously not taken. Suggested-by: Andrew Lunn Signed-off-by: David Bauer --- drivers/net/phy/at803x.c | 42 +++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c index c2aa4c92edde..b3243ad570c7 100644 --- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c @@ -144,6 +144,9 @@ #define ATH8035_PHY_ID 0x004dd072 #define AT8030_PHY_ID_MASK 0xffffffef +#define AT803X_PAGE_FIBER 0 +#define AT803X_PAGE_COPPER 1 + MODULE_DESCRIPTION("Qualcomm Atheros AR803x PHY driver"); MODULE_AUTHOR("Matus Ujhelyi"); MODULE_LICENSE("GPL"); @@ -198,6 +201,35 @@ static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg, return phy_write(phydev, AT803X_DEBUG_DATA, val); } +static int at803x_write_page(struct phy_device *phydev, int page) +{ + int mask; + int set; + + if (page == AT803X_PAGE_COPPER) { + set = AT803X_BT_BX_REG_SEL; + mask = 0; + } else { + set = 0; + mask = AT803X_BT_BX_REG_SEL; + } + + return __phy_modify(phydev, AT803X_REG_CHIP_CONFIG, mask, set); +} + +static int at803x_read_page(struct phy_device *phydev) +{ + int ccr = __phy_read(phydev, AT803X_REG_CHIP_CONFIG); + + if (ccr < 0) + return ccr; + + if (ccr & AT803X_BT_BX_REG_SEL) + return AT803X_PAGE_COPPER; + + return AT803X_PAGE_FIBER; +} + static int at803x_enable_rx_delay(struct phy_device *phydev) { return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0, @@ -753,6 +785,7 @@ static void at803x_link_change_notify(struct phy_device *phydev) static int at803x_aneg_done(struct phy_device *phydev) { + int pssr; int ccr; int aneg_done = genphy_aneg_done(phydev); @@ -767,16 +800,13 @@ static int at803x_aneg_done(struct phy_device *phydev) if ((ccr & AT803X_MODE_CFG_MASK) != AT803X_MODE_CFG_SGMII) return aneg_done; - /* switch to SGMII/fiber page */ - phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr & ~AT803X_BT_BX_REG_SEL); + pssr = phy_read_paged(phydev, AT803X_PAGE_FIBER, AT803X_PSSR); /* check if the SGMII link is OK. */ - if (!(phy_read(phydev, AT803X_PSSR) & AT803X_PSSR_MR_AN_COMPLETE)) { + if (!(pssr & AT803X_PSSR_MR_AN_COMPLETE)) { phydev_warn(phydev, "803x_aneg_done: SGMII link is not ok\n"); aneg_done = 0; } - /* switch back to copper page */ - phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL); return aneg_done; } @@ -1196,6 +1226,8 @@ static struct phy_driver at803x_driver[] = { .get_wol = at803x_get_wol, .suspend = at803x_suspend, .resume = at803x_resume, + .read_page = at803x_read_page, + .write_page = at803x_write_page, /* PHY_GBIT_FEATURES */ .read_status = at803x_read_status, .aneg_done = at803x_aneg_done,