From nobody Sat Oct 11 12:07:00 2025 Received: from out-182.mta1.migadu.com (out-182.mta1.migadu.com [95.215.58.182]) (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 6AD112D5414 for ; Tue, 10 Jun 2025 23:36:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749598601; cv=none; b=cOi0BSMUNXYB3fvSUIcSykBbZP0w9xKSYkkaSP8xe6o7dwd5+5IBjDw8Ut2KbIb822rAcUmu4ur3Lm4N5X+RERu0oxa6mLgwME+FRJV3wxb6glLJWTtj1gPCytE+HQJYz12xWaPye+93nVLKFrvq0jBJ3eoCQ1ZZalnAzW7Vs1o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749598601; c=relaxed/simple; bh=a9mHbrJOiLHj5NsYMvttJmJI0NUURDRVikwiQPz8Cus=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fQ6qonTV2ej/zrVWZB7PNB1S02CpabO8Rx1RaIo/flKLyp3ca4tUgSuRJuQEz54eg7ztv0npavAol2wCLrxmpPPfaRFw5GxLpum6rSk5iLWPEAXUPMILFERPCOW7n9uUwYb2ZNjJGA0DNJpbLM4frfzsinq+VniQKZP2rPpHQhY= 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=tfNYDMO7; arc=none smtp.client-ip=95.215.58.182 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="tfNYDMO7" 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=1749598587; 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=tfNYDMO7Au3DTDerxjE0DGvNgY2OqXdcMVgnOQRqTXw9fXo84yvLvCA+DQrgu/1mgMY49P AloQrvAIeqAJVRzRHJqN0KqMCq+q47mn4yAeP4w5nE6U6j1xHayiqE5ZE4OQEbIpGxEpth Ko22Xk0VPSTDvSugTlfI42g/jJi184c= From: Sean Anderson To: netdev@vger.kernel.org, Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King Cc: linux-kernel@vger.kernel.org, Daniel Golle , Simon Horman , Kory Maincent , Heiner Kallweit , Lei Wei , Christian Marangi , Vineeth Karumanchi , 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:35:47 -0400 Message-Id: <20250610233547.3588356-1-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