From nobody Sat Oct 11 12:07:00 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 22C6E29AAEE for ; Tue, 10 Jun 2025 23:32:04 +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=1749598327; cv=none; b=C4ypmwFK5jDiCHjKjmmGT3mD1ZKYqe8++jjJTPtkb27Z2puhk7JjX1vOTxtJGDeNkJ3zd/AG5CWgrL35e67088ugs3SmmarMU2/Qrm2ewdL2FIrO0DE6PLADO2vsdeI8oGfTu0Vh7McsdjFHAmn9WV6gY/nkJKsVuH9T3TsvypA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749598327; c=relaxed/simple; bh=a9mHbrJOiLHj5NsYMvttJmJI0NUURDRVikwiQPz8Cus=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZHceAHGKHewrs/rbu19o7YuMUwg2FNgu3pfR6fdCmgfE/sw8HlBIjxXcZ1SGtHYvYYYjaWYD4qJM3DrhOgu29QeGjB9IbM8nXqHTokO44VeGbMIh63aHqyWTS86HPrx28qSXt8+VSl6j7EP/TxKzYP3P7zMAiPhTAmN/+Ve3jOw= 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=wArqi2lZ; 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="wArqi2lZ" 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=1749598323; 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=r8RdlCinf2+TlX4dL62XH9+5xu9xSdaTA7tP0qW17CU=; b=wArqi2lZqUqF+oXUylRPZ+1QettdjP++OmHMV2lTAYMlHeUFcuYaEaKumXQ0J5XN+75Wcw 11c5pgEE1/0AjNiv5JECh9C0zixmNyZNBffDE63H5PcEK2OB2jWf+aHxYrnRS8WbhpSv2Q glvmFyPc3rWoehjBwh+0lmQnhSAnoSU= From: Sean Anderson To: netdev@vger.kernel.org, Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King Cc: Vineeth Karumanchi , Heiner Kallweit , linux-kernel@vger.kernel.org, Kory Maincent , Daniel Golle , Simon Horman , Christian Marangi , Lei Wei , Sean Anderson , Claudiu Beznea , Nicolas Ferre Subject: [net-next PATCH v6 08/10] net: macb: Move most of mac_config to mac_prepare Date: Tue, 10 Jun 2025 19:31:32 -0400 Message-Id: <20250610233134.3588011-9-sean.anderson@linux.dev> In-Reply-To: <20250610233134.3588011-1-sean.anderson@linux.dev> References: <20250610233134.3588011-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 --- Changes in v6: - Fix use of spin_lock instead of spin_unlock 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 d1f1ae5ea161..78433d8f3746 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_unlock_irqrestore(&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