From: Sean Anderson <sean.anderson@linux.dev>
To: netdev@vger.kernel.org, Andrew Lunn <andrew+netdev@lunn.ch>,
"David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Russell King <linux@armlinux.org.uk>
Cc: Heiner Kallweit <hkallweit1@gmail.com>,
upstream@airoha.com, Kory Maincent <kory.maincent@bootlin.com>,
Christian Marangi <ansuelsmth@gmail.com>,
linux-kernel@vger.kernel.org,
Claudiu Beznea <claudiu.beznea@microchip.com>,
Nicolas Ferre <nicolas.ferre@microchip.com>,
Sean Anderson <sean.anderson@linux.dev>
Subject: [net-next PATCH v2 12/14] net: macb: Move most of mac_config to mac_prepare
Date: Mon, 7 Apr 2025 19:21:32 -0400 [thread overview]
Message-ID: <20250407232132.2317095-1-sean.anderson@linux.dev> (raw)
In-Reply-To: <20250407231746.2316518-1-sean.anderson@linux.dev>
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 <sean.anderson@linux.dev>
---
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 ++++++++++++++---------
drivers/net/pcs/Kconfig | 1 +
2 files changed, 133 insertions(+), 77 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 1fe8ec37491b..ed37b1d85212 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 speed)
netdev_err(bp->dev, "adjusting tx_clk failed.\n");
}
-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 = container_of(pcs, struct macb, phylink_usx_pcs);
- u32 config;
-
- config = gem_readl(bp, USX_CONTROL);
- config = GEM_BFINS(SERDES_RATE, MACB_SERDES_RATE_10G, config);
- config = GEM_BFINS(USX_CTRL_SPEED, HS_SPEED_10000M, config);
- config &= ~(GEM_BIT(TX_SCR_BYPASS) | GEM_BIT(RX_SCR_BYPASS));
- config |= GEM_BIT(TX_EN);
- gem_writel(bp, USX_CONTROL, config);
+static void macb_pcs_get_state(struct phylink_pcs *pcs, unsigned int neg_mode,
+ struct phylink_link_state *state)
+{
+ struct macb *bp = 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 = false;
+ int old, new;
+
+ old = gem_readl(bp, PCSANADV);
+ new = phylink_mii_c22_pcs_encode_advertisement(interface, advertising);
+ if (new != -EINVAL && old != new) {
+ changed = true;
+ gem_writel(bp, PCSANADV, new);
+ }
+
+ old = new = gem_readl(bp, PCSCNTRL);
+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
+ new |= BMCR_ANENABLE;
+ else
+ new &= ~BMCR_ANENABLE;
+ if (old != new) {
+ changed = 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 = container_of(pcs, struct macb, phylink_sgmii_pcs);
+ bool changed = false;
+ unsigned long flags;
+ u32 old, new;
+
+ spin_lock_irqsave(&bp->lock, flags);
+ old = new = gem_readl(bp, NCFGR);
+ new |= GEM_BIT(SGMIIEN);
+ if (old != new) {
+ changed = true;
+ gem_writel(bp, NCFGR, new);
+ }
+
+ if (macb_pcs_config_an(bp, mode, interface, advertising))
+ changed = true;
+
+ spin_unlock_irqrestore(&bp->lock, flags);
+ return changed;
+}
+
+static void macb_pcs_an_restart(struct phylink_pcs *pcs)
+{
+ struct macb *bp = container_of(pcs, struct macb, phylink_sgmii_pcs);
+ u32 bmcr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bp->lock, flags);
+
+ bmcr = gem_readl(bp, PCSCNTRL);
+ bmcr |= BMCR_ANENABLE;
+ gem_writel(bp, PCSCNTRL, bmcr);
+
+ spin_lock_irqsave(&bp->lock, flags);
}
static void macb_usx_pcs_get_state(struct phylink_pcs *pcs,
@@ -589,45 +661,60 @@ static int macb_usx_pcs_config(struct phylink_pcs *pcs,
bool permit_pause_to_mac)
{
struct macb *bp = container_of(pcs, struct macb, phylink_usx_pcs);
+ unsigned long flags;
+ bool changed;
+ u16 old, new;
- 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 = true;
- return 0;
-}
+ old = new = gem_readl(bp, USX_CONTROL);
+ new |= GEM_BIT(SIGNAL_OK);
+ if (old != new) {
+ changed = true;
+ gem_writel(bp, USX_CONTROL, new);
+ }
-static void macb_pcs_get_state(struct phylink_pcs *pcs, unsigned int neg_mode,
- struct phylink_link_state *state)
-{
- state->link = 0;
-}
+ old = new = gem_readl(bp, USX_CONTROL);
+ new = GEM_BFINS(SERDES_RATE, MACB_SERDES_RATE_10G, new);
+ new = GEM_BFINS(USX_CTRL_SPEED, HS_SPEED_10000M, new);
+ new &= ~(GEM_BIT(TX_SCR_BYPASS) | GEM_BIT(RX_SCR_BYPASS));
+ new |= GEM_BIT(TX_EN);
+ if (old != new) {
+ changed = true;
+ gem_writel(bp, USX_CONTROL, new);
+ }
-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;
}
static const struct phylink_pcs_ops macb_phylink_usx_pcs_ops = {
.pcs_get_state = macb_usx_pcs_get_state,
.pcs_config = macb_usx_pcs_config,
- .pcs_link_up = macb_usx_pcs_link_up,
};
static const struct phylink_pcs_ops macb_phylink_pcs_ops = {
.pcs_get_state = macb_pcs_get_state,
- .pcs_an_restart = macb_pcs_an_restart,
.pcs_config = macb_pcs_config,
+ .pcs_an_restart = macb_pcs_an_restart,
};
+static struct phylink_pcs *macb_mac_select_pcs(struct phylink_config *config,
+ phy_interface_t interface)
+{
+ struct net_device *ndev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(ndev);
+
+ if (interface == PHY_INTERFACE_MODE_10GBASER)
+ return &bp->phylink_usx_pcs;
+ else if (interface == PHY_INTERFACE_MODE_SGMII)
+ return &bp->phylink_sgmii_pcs;
+ else
+ return NULL;
+}
+
static void macb_mac_config(struct phylink_config *config, unsigned int mode,
const struct phylink_link_state *state)
{
@@ -646,18 +733,14 @@ static void macb_mac_config(struct phylink_config *config, unsigned int mode,
if (state->interface == PHY_INTERFACE_MODE_RMII)
ctrl |= MACB_BIT(RM9200_RMII);
} else if (macb_is_gem(bp)) {
- ctrl &= ~(GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL));
- ncr &= ~GEM_BIT(ENABLE_HS_MAC);
-
- if (state->interface == PHY_INTERFACE_MODE_SGMII) {
- ctrl |= GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL);
- } else if (state->interface == PHY_INTERFACE_MODE_10GBASER) {
+ if (macb_mac_select_pcs(config, state->interface))
ctrl |= GEM_BIT(PCSSEL);
- ncr |= GEM_BIT(ENABLE_HS_MAC);
- } else if (bp->caps & MACB_CAPS_MIIONRGMII &&
- bp->phy_interface == PHY_INTERFACE_MODE_MII) {
+ else
+ ctrl &= ~GEM_BIT(PCSSEL);
+
+ if (bp->caps & MACB_CAPS_MIIONRGMII &&
+ bp->phy_interface == PHY_INTERFACE_MODE_MII)
ncr |= MACB_BIT(MIIONRGMII);
- }
}
/* Apply the new configuration, if any */
@@ -667,22 +750,6 @@ static void macb_mac_config(struct phylink_config *config, unsigned int mode,
if (old_ncr ^ ncr)
macb_or_gem_writel(bp, NCR, ncr);
- /* 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 == PHY_INTERFACE_MODE_SGMII) {
- u32 pcsctrl, old_pcsctrl;
-
- old_pcsctrl = gem_readl(bp, PCSCNTRL);
- if (mode == MLO_AN_FIXED)
- pcsctrl = old_pcsctrl & ~GEM_BIT(PCSAUTONEG);
- else
- pcsctrl = old_pcsctrl | GEM_BIT(PCSAUTONEG);
- if (old_pcsctrl != pcsctrl)
- gem_writel(bp, PCSCNTRL, pcsctrl);
- }
-
spin_unlock_irqrestore(&bp->lock, flags);
}
@@ -735,10 +802,12 @@ static void macb_mac_link_up(struct phylink_config *config,
if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC)) {
ctrl &= ~MACB_BIT(PAE);
if (macb_is_gem(bp)) {
- ctrl &= ~GEM_BIT(GBE);
+ ctrl &= ~(GEM_BIT(GBE) | GEM_BIT(ENABLE_HS_MAC));
if (speed == SPEED_1000)
ctrl |= GEM_BIT(GBE);
+ else if (speed == SPEED_10000)
+ ctrl |= GEM_BIT(ENABLE_HS_MAC);
}
if (rx_pause)
@@ -776,20 +845,6 @@ static void macb_mac_link_up(struct phylink_config *config,
netif_tx_wake_all_queues(ndev);
}
-static struct phylink_pcs *macb_mac_select_pcs(struct phylink_config *config,
- phy_interface_t interface)
-{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
-
- if (interface == PHY_INTERFACE_MODE_10GBASER)
- return &bp->phylink_usx_pcs;
- else if (interface == PHY_INTERFACE_MODE_SGMII)
- return &bp->phylink_sgmii_pcs;
- else
- return NULL;
-}
-
static const struct phylink_mac_ops macb_phylink_ops = {
.mac_select_pcs = macb_mac_select_pcs,
.mac_config = macb_mac_config,
diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig
index 90ca0002600b..261d2fd29fc7 100644
--- a/drivers/net/pcs/Kconfig
+++ b/drivers/net/pcs/Kconfig
@@ -57,6 +57,7 @@ config PCS_XILINX
depends on PCS
select MDIO_DEVICE
select PHYLINK
+ default XILINX_AXI_EMAC
tristate "Xilinx PCS driver"
help
PCS driver for the Xilinx 1G/2.5G Ethernet PCS/PMA or SGMII device.
--
2.35.1.1320.gc452695387.dirty
next prev parent reply other threads:[~2025-04-07 23:21 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-07 23:17 [net-next PATCH v2 00/14] Add PCS core support Sean Anderson
2025-04-07 23:17 ` [net-next PATCH v2 01/14] dt-bindings: net: Add Xilinx PCS Sean Anderson
2025-04-11 14:46 ` Rob Herring
2025-04-07 23:17 ` [net-next PATCH v2 02/14] device property: Add optional nargs_prop for get_reference_args Sean Anderson
2025-04-09 2:21 ` kernel test robot
2025-04-09 2:32 ` kernel test robot
2025-04-07 23:17 ` [net-next PATCH v2 03/14] device property: Add fwnode_property_get_reference_optional_args Sean Anderson
2025-04-07 23:17 ` [net-next PATCH v2 04/14] scripts: kernel-doc: fix parsing function-like typedefs (again) Sean Anderson
2025-04-07 23:17 ` [net-next PATCH v2 05/14] net: phylink: Support setting PCS link change callbacks Sean Anderson
2025-04-07 23:17 ` [net-next PATCH v2 06/14] net: pcs: Add subsystem Sean Anderson
2025-04-07 23:17 ` [net-next PATCH v2 07/14] net: dsa: ocelot: suppress PHY device scanning on the internal MDIO bus Sean Anderson
2025-04-07 23:17 ` [net-next PATCH v2 08/14] net: pcs: lynx: Convert to an MDIO driver Sean Anderson
2025-04-07 23:17 ` [net-next PATCH v2 09/14] net: phy: Export some functions Sean Anderson
2025-04-07 23:17 ` [net-next PATCH v2 10/14] net: pcs: Add Xilinx PCS driver Sean Anderson
2025-04-07 23:20 ` [net-next PATCH v2 11/14] net: axienet: Convert to use PCS subsystem Sean Anderson
2025-04-08 12:19 ` Gupta, Suraj
2025-04-08 15:33 ` Sean Anderson
2025-04-09 2:32 ` kernel test robot
2025-04-07 23:21 ` Sean Anderson [this message]
2025-04-07 23:21 ` [net-next PATCH v2 13/14] net: macb: Support external PCSs Sean Anderson
2025-04-07 23:22 ` [net-next PATCH v2 14/14] of: property: Add device link support for PCS Sean Anderson
2025-04-11 14:47 ` Rob Herring (Arm)
2025-04-11 19:44 ` Saravana Kannan
2025-04-08 14:50 ` [net-next PATCH v2 00/14] Add PCS core support Jakub Kicinski
2025-04-08 15:30 ` Sean Anderson
2025-04-08 15:33 ` Jakub Kicinski
2025-04-08 17:27 ` Russell King (Oracle)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250407232132.2317095-1-sean.anderson@linux.dev \
--to=sean.anderson@linux.dev \
--cc=andrew+netdev@lunn.ch \
--cc=ansuelsmth@gmail.com \
--cc=claudiu.beznea@microchip.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hkallweit1@gmail.com \
--cc=kory.maincent@bootlin.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=netdev@vger.kernel.org \
--cc=nicolas.ferre@microchip.com \
--cc=pabeni@redhat.com \
--cc=upstream@airoha.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).