From patchwork Wed Sep 21 00:23:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 12982851 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4F0E5C6FA82 for ; Wed, 21 Sep 2022 00:23:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:MIME-Version: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=Pz9qaHH10kuy9BDx0ka7o7cPZ5B8jSGi7fnibrb+zaQ=; b=egTkMN5Nbc2+uKaZ0LUJaAk5RK caGJ5MK8WJ0TdrZ740M4tz9HPsUEhDC94XPZNOoLTaouJGOEmQZUiQ71F4oV81OXRslvyerFLoBhO zGTfqMeDocXYdFefcxs2XYhLhHujWxGGsahcVEvCJhHfc8wTE47qCP+B5hqJHd0o4fO9/QPFzrlYd ELMmpQEflXlikynFTvmLKuV9pwEN/V8oxgHmg9pZheLOiEhxvYJwAGx7UWjpPIZp/YKzS5X1PEmkG 7cLsONd+szYCl/ypih9Vp0r5BLq+/nMwV+JnRvRTuOURuwgG8lXmkvur/MR/C0GtS97tUEi3u75LQ r0oA2R9g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oanWa-007g3j-W7; Wed, 21 Sep 2022 00:23:37 +0000 Received: from fudo.makrotopia.org ([2a07:2ec0:3002::71]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oanWX-007g2X-H1 for linux-mediatek@lists.infradead.org; Wed, 21 Sep 2022 00:23:35 +0000 Received: from local by fudo.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.96) (envelope-from ) id 1oanWL-00085X-2q; Wed, 21 Sep 2022 02:23:22 +0200 Date: Wed, 21 Sep 2022 01:23:14 +0100 From: Daniel Golle To: Russell King , linux-mediatek@lists.infradead.org, netdev@vger.kernel.org Cc: Sean Wang , Landen Chao , DENG Qingfang , Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Matthias Brugger , Philipp Zabel , Alexander 'lynxis' Couzens Subject: [PATCH v4] net: dsa: mt7530: add support for in-band link status Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220920_172333_588239_CE5B1399 X-CRM114-Status: GOOD ( 18.47 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Read link status from SGMII PCS for in-band managed 2500Base-X and 1000Base-X connection on a MAC port of the MT7531. This is needed to get the SFP cage working which is connected to SGMII interface of port 5 of the MT7531 switch IC on the Bananapi BPi-R3 board. While at it also handle an_complete for both the autoneg and the non-autoneg codepath. Signed-off-by: Daniel Golle --- v2: Use MLO_PAUSE_NONE and read an_complete from SGMII status register. v3: Remove unused variable, read an_complete register only in autoneg codepath, set an_complete to link status bit in case of fixed speed link. v4: fix wrong parameter variable name drivers/net/dsa/mt7530.c | 50 +++++++++++++++++++++++++++++----------- drivers/net/dsa/mt7530.h | 1 + 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c index 835807911be019..5f00a3f6f279d4 100644 --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c @@ -2699,9 +2699,6 @@ mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, case PHY_INTERFACE_MODE_NA: case PHY_INTERFACE_MODE_1000BASEX: case PHY_INTERFACE_MODE_2500BASEX: - if (phylink_autoneg_inband(mode)) - return -EINVAL; - return mt7531_sgmii_setup_mode_force(priv, port, interface); default: return -EINVAL; @@ -2777,13 +2774,6 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, return; } - if (phylink_autoneg_inband(mode) && - state->interface != PHY_INTERFACE_MODE_SGMII) { - dev_err(ds->dev, "%s: in-band negotiation unsupported\n", - __func__); - return; - } - mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port)); mcr_new = mcr_cur; mcr_new &= ~PMCR_LINK_SETTINGS_MASK; @@ -2922,6 +2912,9 @@ static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port, config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD; + if ((priv->id == ID_MT7531) && mt753x_is_mac_port(port)) + config->mac_capabilities |= MAC_2500FD; + /* This driver does not make use of the speed, duplex, pause or the * advertisement in its mac_config, so it is safe to mark this driver * as non-legacy. @@ -2987,6 +2980,7 @@ mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port, status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); state->link = !!(status & MT7531_SGMII_LINK_STATUS); + state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE); if (state->interface == PHY_INTERFACE_MODE_SGMII && (status & MT7531_SGMII_AN_ENABLE)) { val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port)); @@ -3017,16 +3011,44 @@ mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port, return 0; } +static void +mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port, + struct phylink_link_state *state) +{ + unsigned int val; + + val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); + state->link = !!(val & MT7531_SGMII_LINK_STATUS); + if (!state->link) + return; + + state->an_complete = state->link; + + if (state->interface == PHY_INTERFACE_MODE_2500BASEX) + state->speed = SPEED_2500; + else + state->speed = SPEED_1000; + + state->duplex = DUPLEX_FULL; + state->pause = MLO_PAUSE_NONE; +} + static void mt7531_pcs_get_state(struct phylink_pcs *pcs, struct phylink_link_state *state) { struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; int port = pcs_to_mt753x_pcs(pcs)->port; - if (state->interface == PHY_INTERFACE_MODE_SGMII) + if (state->interface == PHY_INTERFACE_MODE_SGMII) { mt7531_sgmii_pcs_get_state_an(priv, port, state); - else - state->link = false; + return; + } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) || + (state->interface == PHY_INTERFACE_MODE_2500BASEX)) { + mt7531_sgmii_pcs_get_state_inband(priv, port, state); + return; + } + + state->link = false; } static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode, @@ -3067,6 +3089,8 @@ mt753x_setup(struct dsa_switch *ds) priv->pcs[i].pcs.ops = priv->info->pcs_ops; priv->pcs[i].priv = priv; priv->pcs[i].port = i; + if (mt753x_is_mac_port(i)) + priv->pcs[i].pcs.poll = 1; } ret = priv->info->sw_setup(ds); diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h index e509af95c35414..e8d9664353504f 100644 --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h @@ -373,6 +373,7 @@ enum mt7530_vlan_port_acc_frm { #define MT7531_SGMII_LINK_STATUS BIT(18) #define MT7531_SGMII_AN_ENABLE BIT(12) #define MT7531_SGMII_AN_RESTART BIT(9) +#define MT7531_SGMII_AN_COMPLETE BIT(21) /* Register for SGMII PCS_SPPED_ABILITY */ #define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08)