From nobody Mon Dec 15 03:10:19 2025 Received: from out-177.mta0.migadu.com (out-177.mta0.migadu.com [91.218.175.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7178C217668; Fri, 23 May 2025 20:34:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748032491; cv=none; b=d2mIm6gJStzWMAtmK+xjBdm9uxzdAmuqXmw3C3PwlnKUWh9Q9AluFvThr5bVxOgQqKu03kdOVd8RaaGVO8F+2wzjbWq/ZF07rGtBajViHjRYMr9AkjbilTPvXZ54+ef0Q2Zhu2PupZzXMR1Erd46CKtBhRXf6fFgSt7qKJ5W2q4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748032491; c=relaxed/simple; bh=MJLjIswkz5DBHXAGeKAB9MEQvDlHhVhrUYQV+dGM0sg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=FIY6v/H7sB0JPWv4Ko06Gjs9xDkjU1a3XRnk6s16sEt47uqpzk6INQZy/+xqRl7GXcmu+3frf4vHqigR5oQNFpZUStS32EeW4StxCUyk2zbowfByATb7rj5OCSmjHA1/iwGbMaZ1yJxUtj6LTMSKTc5kLdVJutYDnKMOzPTmdJg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=BZMR9PAg; arc=none smtp.client-ip=91.218.175.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="BZMR9PAg" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1748032487; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bmMf5ff8Lbqwd66FtKObP9wZ01LxPu3TvS0fQ9LjtvU=; b=BZMR9PAgLauOAFbJqN/XfqjRtyANXQQXwYRfzIkRgonDuslTA/ZnIZAg9eWvZSj4QFn5kZ Ovw1XMKYbaaR+DyUuIzRj9Mb0Ct+XsnMbwxyrIcHTTRwi7Hb9XEJK+vZseeERjkanIewFX KzGUxe5gcmkeAUGXulAKwztjMV9is+4= From: Sean Anderson To: netdev@vger.kernel.org, Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King Cc: Lei Wei , Heiner Kallweit , Christian Marangi , Kory Maincent , Simon Horman , Daniel Golle , Vineeth Karumanchi , linux-kernel@vger.kernel.org, Sean Anderson , Claudiu Beznea , Nicolas Ferre Subject: [net-next PATCH v5 08/10] net: macb: Move most of mac_config to mac_prepare Date: Fri, 23 May 2025 16:33:37 -0400 Message-Id: <20250523203339.1993685-9-sean.anderson@linux.dev> In-Reply-To: <20250523203339.1993685-1-sean.anderson@linux.dev> References: <20250523203339.1993685-1-sean.anderson@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" mac_prepare is called every time the interface is changed, so we can do all of our configuration there, instead of in mac_config. This will be useful for the next patch where we will set the PCS bit based on whether we are using our internal PCS. No functional change intended. Signed-off-by: Sean Anderson --- (no changes since v2) Changes in v2: - Fix docs for macb_pcs_config_an - Include change to macb_pcs_get_state which was previously in the next patch drivers/net/ethernet/cadence/macb_main.c | 209 ++++++++++++++--------- 1 file changed, 132 insertions(+), 77 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/etherne= t/cadence/macb_main.c index e1e8bd2ec155..30591ce8be88 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -549,19 +549,91 @@ static void macb_set_tx_clk(struct macb *bp, int spee= d) netdev_err(bp->dev, "adjusting tx_clk failed.\n"); } =20 -static void macb_usx_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg= _mode, - phy_interface_t interface, int speed, - int duplex) -{ - struct macb *bp =3D container_of(pcs, struct macb, phylink_usx_pcs); - u32 config; - - config =3D gem_readl(bp, USX_CONTROL); - config =3D GEM_BFINS(SERDES_RATE, MACB_SERDES_RATE_10G, config); - config =3D GEM_BFINS(USX_CTRL_SPEED, HS_SPEED_10000M, config); - config &=3D ~(GEM_BIT(TX_SCR_BYPASS) | GEM_BIT(RX_SCR_BYPASS)); - config |=3D GEM_BIT(TX_EN); - gem_writel(bp, USX_CONTROL, config); +static void macb_pcs_get_state(struct phylink_pcs *pcs, unsigned int neg_m= ode, + struct phylink_link_state *state) +{ + struct macb *bp =3D container_of(pcs, struct macb, phylink_sgmii_pcs); + + phylink_mii_c22_pcs_decode_state(state, neg_mode, gem_readl(bp, PCSSTS), + gem_readl(bp, PCSANLPBASE)); +} + +/** + * macb_pcs_config_an() - Configure autonegotiation settings for PCSs + * @bp: The macb to operate on + * @neg_mode: The autonegotiation mode + * @interface: The interface to use + * @advertising: The advertisement mask + * + * This provides common configuration for PCS autonegotiation. + * + * Context: Call with @bp->lock held. + * Return: 1 if any registers were changed; 0 otherwise + */ +static int macb_pcs_config_an(struct macb *bp, unsigned int neg_mode, + phy_interface_t interface, + const unsigned long *advertising) +{ + bool changed =3D false; + int old, new; + + old =3D gem_readl(bp, PCSANADV); + new =3D phylink_mii_c22_pcs_encode_advertisement(interface, advertising); + if (new !=3D -EINVAL && old !=3D new) { + changed =3D true; + gem_writel(bp, PCSANADV, new); + } + + old =3D new =3D gem_readl(bp, PCSCNTRL); + if (neg_mode =3D=3D PHYLINK_PCS_NEG_INBAND_ENABLED) + new |=3D BMCR_ANENABLE; + else + new &=3D ~BMCR_ANENABLE; + if (old !=3D new) { + changed =3D true; + gem_writel(bp, PCSCNTRL, new); + } + return changed; +} + +static int macb_pcs_config(struct phylink_pcs *pcs, unsigned int mode, + phy_interface_t interface, + const unsigned long *advertising, + bool permit_pause_to_mac) +{ + struct macb *bp =3D container_of(pcs, struct macb, phylink_sgmii_pcs); + bool changed =3D false; + unsigned long flags; + u32 old, new; + + spin_lock_irqsave(&bp->lock, flags); + old =3D new =3D gem_readl(bp, NCFGR); + new |=3D GEM_BIT(SGMIIEN); + if (old !=3D new) { + changed =3D true; + gem_writel(bp, NCFGR, new); + } + + if (macb_pcs_config_an(bp, mode, interface, advertising)) + changed =3D true; + + spin_unlock_irqrestore(&bp->lock, flags); + return changed; +} + +static void macb_pcs_an_restart(struct phylink_pcs *pcs) +{ + struct macb *bp =3D container_of(pcs, struct macb, phylink_sgmii_pcs); + u32 bmcr; + unsigned long flags; + + spin_lock_irqsave(&bp->lock, flags); + + bmcr =3D gem_readl(bp, PCSCNTRL); + bmcr |=3D BMCR_ANENABLE; + gem_writel(bp, PCSCNTRL, bmcr); + + spin_lock_irqsave(&bp->lock, flags); } =20 static void macb_usx_pcs_get_state(struct phylink_pcs *pcs, @@ -589,45 +661,60 @@ static int macb_usx_pcs_config(struct phylink_pcs *pc= s, bool permit_pause_to_mac) { struct macb *bp =3D container_of(pcs, struct macb, phylink_usx_pcs); + unsigned long flags; + bool changed; + u16 old, new; =20 - gem_writel(bp, USX_CONTROL, gem_readl(bp, USX_CONTROL) | - GEM_BIT(SIGNAL_OK)); + spin_lock_irqsave(&bp->lock, flags); + if (macb_pcs_config_an(bp, neg_mode, interface, advertising)) + changed =3D true; =20 - return 0; -} + old =3D new =3D gem_readl(bp, USX_CONTROL); + new |=3D GEM_BIT(SIGNAL_OK); + if (old !=3D new) { + changed =3D true; + gem_writel(bp, USX_CONTROL, new); + } =20 -static void macb_pcs_get_state(struct phylink_pcs *pcs, unsigned int neg_m= ode, - struct phylink_link_state *state) -{ - state->link =3D 0; -} + old =3D new =3D gem_readl(bp, USX_CONTROL); + new =3D GEM_BFINS(SERDES_RATE, MACB_SERDES_RATE_10G, new); + new =3D GEM_BFINS(USX_CTRL_SPEED, HS_SPEED_10000M, new); + new &=3D ~(GEM_BIT(TX_SCR_BYPASS) | GEM_BIT(RX_SCR_BYPASS)); + new |=3D GEM_BIT(TX_EN); + if (old !=3D new) { + changed =3D true; + gem_writel(bp, USX_CONTROL, new); + } =20 -static void macb_pcs_an_restart(struct phylink_pcs *pcs) -{ - /* Not supported */ -} - -static int macb_pcs_config(struct phylink_pcs *pcs, - unsigned int neg_mode, - phy_interface_t interface, - const unsigned long *advertising, - bool permit_pause_to_mac) -{ - return 0; + spin_unlock_irqrestore(&bp->lock, flags); + return changed; } =20 static const struct phylink_pcs_ops macb_phylink_usx_pcs_ops =3D { .pcs_get_state =3D macb_usx_pcs_get_state, .pcs_config =3D macb_usx_pcs_config, - .pcs_link_up =3D macb_usx_pcs_link_up, }; =20 static const struct phylink_pcs_ops macb_phylink_pcs_ops =3D { .pcs_get_state =3D macb_pcs_get_state, - .pcs_an_restart =3D macb_pcs_an_restart, .pcs_config =3D macb_pcs_config, + .pcs_an_restart =3D macb_pcs_an_restart, }; =20 +static struct phylink_pcs *macb_mac_select_pcs(struct phylink_config *conf= ig, + phy_interface_t interface) +{ + struct net_device *ndev =3D to_net_dev(config->dev); + struct macb *bp =3D netdev_priv(ndev); + + if (interface =3D=3D PHY_INTERFACE_MODE_10GBASER) + return &bp->phylink_usx_pcs; + else if (interface =3D=3D PHY_INTERFACE_MODE_SGMII) + return &bp->phylink_sgmii_pcs; + else + return NULL; +} + static void macb_mac_config(struct phylink_config *config, unsigned int mo= de, const struct phylink_link_state *state) { @@ -646,18 +733,14 @@ static void macb_mac_config(struct phylink_config *co= nfig, unsigned int mode, if (state->interface =3D=3D PHY_INTERFACE_MODE_RMII) ctrl |=3D MACB_BIT(RM9200_RMII); } else if (macb_is_gem(bp)) { - ctrl &=3D ~(GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL)); - ncr &=3D ~GEM_BIT(ENABLE_HS_MAC); - - if (state->interface =3D=3D PHY_INTERFACE_MODE_SGMII) { - ctrl |=3D GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL); - } else if (state->interface =3D=3D PHY_INTERFACE_MODE_10GBASER) { + if (macb_mac_select_pcs(config, state->interface)) ctrl |=3D GEM_BIT(PCSSEL); - ncr |=3D GEM_BIT(ENABLE_HS_MAC); - } else if (bp->caps & MACB_CAPS_MIIONRGMII && - bp->phy_interface =3D=3D PHY_INTERFACE_MODE_MII) { + else + ctrl &=3D ~GEM_BIT(PCSSEL); + + if (bp->caps & MACB_CAPS_MIIONRGMII && + bp->phy_interface =3D=3D PHY_INTERFACE_MODE_MII) ncr |=3D MACB_BIT(MIIONRGMII); - } } =20 /* Apply the new configuration, if any */ @@ -667,22 +750,6 @@ static void macb_mac_config(struct phylink_config *con= fig, unsigned int mode, if (old_ncr ^ ncr) macb_or_gem_writel(bp, NCR, ncr); =20 - /* Disable AN for SGMII fixed link configuration, enable otherwise. - * Must be written after PCSSEL is set in NCFGR, - * otherwise writes will not take effect. - */ - if (macb_is_gem(bp) && state->interface =3D=3D PHY_INTERFACE_MODE_SGMII) { - u32 pcsctrl, old_pcsctrl; - - old_pcsctrl =3D gem_readl(bp, PCSCNTRL); - if (mode =3D=3D MLO_AN_FIXED) - pcsctrl =3D old_pcsctrl & ~GEM_BIT(PCSAUTONEG); - else - pcsctrl =3D old_pcsctrl | GEM_BIT(PCSAUTONEG); - if (old_pcsctrl !=3D pcsctrl) - gem_writel(bp, PCSCNTRL, pcsctrl); - } - spin_unlock_irqrestore(&bp->lock, flags); } =20 @@ -735,10 +802,12 @@ static void macb_mac_link_up(struct phylink_config *c= onfig, if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC)) { ctrl &=3D ~MACB_BIT(PAE); if (macb_is_gem(bp)) { - ctrl &=3D ~GEM_BIT(GBE); + ctrl &=3D ~(GEM_BIT(GBE) | GEM_BIT(ENABLE_HS_MAC)); =20 if (speed =3D=3D SPEED_1000) ctrl |=3D GEM_BIT(GBE); + else if (speed =3D=3D SPEED_10000) + ctrl |=3D GEM_BIT(ENABLE_HS_MAC); } =20 if (rx_pause) @@ -776,20 +845,6 @@ static void macb_mac_link_up(struct phylink_config *co= nfig, netif_tx_wake_all_queues(ndev); } =20 -static struct phylink_pcs *macb_mac_select_pcs(struct phylink_config *conf= ig, - phy_interface_t interface) -{ - struct net_device *ndev =3D to_net_dev(config->dev); - struct macb *bp =3D netdev_priv(ndev); - - if (interface =3D=3D PHY_INTERFACE_MODE_10GBASER) - return &bp->phylink_usx_pcs; - else if (interface =3D=3D PHY_INTERFACE_MODE_SGMII) - return &bp->phylink_sgmii_pcs; - else - return NULL; -} - static const struct phylink_mac_ops macb_phylink_ops =3D { .mac_select_pcs =3D macb_mac_select_pcs, .mac_config =3D macb_mac_config, --=20 2.35.1.1320.gc452695387.dirty