Devicetree
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Christian Marangi" <ansuelsmth@gmail.com>, devicetree@vger.kernel.org
Cc: robh@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH net-next v20 14/15] net: pcs: airoha: add PCS driver for Airoha AN7581 SoC
Date: Sun, 15 Nov 2026 10:45:19 +0000	[thread overview]
Message-ID: <sashiko-outbox-215404@kernel.org> (raw)
In-Reply-To: <20261114104426.235620-15-ansuelsmth@gmail.com>

Thank you for your contribution! Sashiko AI review found 6 potential
issues to consider:
- [High] net: pcs: airoha: missing 1000BASE-X AN setup in
  airoha_pcs_config()
- [High] net: pcs: airoha: invalid in-band AN capability reported for
  2500BASE-X
- [High] net: pcs: airoha: broken syscon lookup and RMW race on
  airoha,scu
- [High] net: pcs: airoha: unsynchronized shared PLLs and resets in
  an7581_pcs_bringup()
- [Medium] net: pcs: airoha: missing Kconfig dependencies for PHYLINK
  and REGMAP_MMIO
- [Medium] net: pcs: airoha: uninitialized speed_reg in
  airoha_pcs_link_up()
--

commit 5496b74992ab5a11c007cdfeb5d147b3fefaeace
Author: Christian Marangi <ansuelsmth@gmail.com>

net: pcs: airoha: add PCS driver for Airoha AN7581 SoC

This commit adds a phylink PCS driver for the Ethernet, PON, PCIe and USB
SerDes on the Airoha AN7581 SoC, supporting USXGMII, 10GBASE-R, 2500BASE-X,
1000BASE-X and SGMII modes.

> diff --git a/drivers/net/pcs/airoha/Kconfig b/drivers/net/pcs/airoha/Kconfig
> new file mode 100644
> index 0000000000000..1aa4c0d33b87d
> --- /dev/null
> +++ b/drivers/net/pcs/airoha/Kconfig
> @@ -0,0 +1,13 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +config PCS_AIROHA
> +	tristate
> +	select FWNODE_PCS
> +
> +config PCS_AIROHA_AN7581
> +	tristate "Airoha AN7581 PCS driver"
> +	depends on ARCH_AIROHA || COMPILE_TEST
> +	select PCS_AIROHA

[Severity: Medium]
Does PCS_AIROHA need dependencies or selects for PHYLINK, REGMAP_MMIO,
GENERIC_PHY and MFD_SYSCON?

airoha_pcs_init_named_regmap() calls devm_regmap_init_mmio() and
__an7581_pcs_alloc_regmap_fields() calls devm_regmap_field_alloc(), which
have no stubs when CONFIG_REGMAP is disabled and fail to link without
CONFIG_REGMAP_MMIO.  The driver also calls phylink helpers such as
phylink_mii_c22_pcs_decode_state(), phylink_decode_usxgmii_word() and
phylink_mii_c22_pcs_encode_advertisement() (which require CONFIG_PHYLINK),
devm_phy_get() and phy_set_mode_ext() (which fail to link if PCS_AIROHA=y
and GENERIC_PHY=m), and syscon_regmap_lookup_by_phandle() (which returns
-ENOTSUPP without CONFIG_MFD_SYSCON).

> diff --git a/drivers/net/pcs/airoha/pcs-airoha-common.c b/drivers/net/pcs/airoha/pcs-airoha-common.c
> new file mode 100644
> index 0000000000000..9964d4df2ec97
> --- /dev/null
> +++ b/drivers/net/pcs/airoha/pcs-airoha-common.c

[ ... ]

> +	/* Setup SGMII AN and advertisement in DEV_ABILITY */
> +	if (interface == PHY_INTERFACE_MODE_SGMII) {
> +		if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
> +			int advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
> +										 advertising);
> +			if (advertise < 0)
> +				return advertise;
> +
> +			regmap_update_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_4,
> +					   AIROHA_PCS_HSGMII_AN_SGMII_DEV_ABILITY,
> +					   FIELD_PREP(AIROHA_PCS_HSGMII_AN_SGMII_DEV_ABILITY,
> +						      advertise));
> +
> +			regmap_set_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0,
> +					AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE);
> +		} else {
> +			regmap_clear_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0,
> +					  AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE);
> +		}
> +	}

[Severity: High]
Should this block also run when interface is PHY_INTERFACE_MODE_1000BASEX?

phylink_mii_c22_pcs_encode_advertisement() encodes the Clause 37
ADVERTISE_1000XFULL, ADVERTISE_1000XPAUSE and ADVERTISE_1000XPSE_ASYM bits
for 1000BASE-X (while returning constant 0x0001 for SGMII).  Guarding this
with only PHY_INTERFACE_MODE_SGMII leaves AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_4
and AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE unconfigured in 1000BASE-X mode,
breaking Clause 37 auto-negotiation and pause advertisement.

[ ... ]

> +		if (interface == PHY_INTERFACE_MODE_SGMII ||
> +		    interface == PHY_INTERFACE_MODE_2500BASEX) {
> +			u32 ck_gen_mode;
> +			u32 speed_reg;
> +			u32 if_mode;
> +
> +			switch (speed) {
> +			case SPEED_2500:
> +				speed_reg = AIROHA_PCS_LINK_MODE_P0_2_5G;
> +				break;
> +			case SPEED_1000:
> +				speed_reg = AIROHA_PCS_LINK_MODE_P0_1G;
> +				if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_1000;
> +				ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_1000;
> +				break;
> +			case SPEED_100:
> +				speed_reg = AIROHA_PCS_LINK_MODE_P0_100M;
> +				if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_100;
> +				ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_100;
> +				break;
> +			case SPEED_10:
> +				speed_reg = AIROHA_PCS_LINK_MODE_P0_10M;
> +				if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_10;
> +				ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_10;
> +				break;
> +			}
> +
> +			if (interface == PHY_INTERFACE_MODE_SGMII) {
> +				regmap_update_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13,
> +						   AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE,
> +						   if_mode);
> +
> +				regmap_update_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_AN_SGMII_MODE_FORCE,
> +						   AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE |
> +						   AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_SEL,
> +						   ck_gen_mode |
> +						   AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_SEL);
> +			}
> +
> +			regmap_update_bits(maps->multi_sgmii, AIROHA_PCS_MULTI_SGMII_SGMII_STS_CTRL_0,
> +					   AIROHA_PCS_LINK_MODE_P0 |
> +					   AIROHA_PCS_FORCE_SPD_MODE_P0,
> +					   speed_reg |
> +					   AIROHA_PCS_FORCE_SPD_MODE_P0);
> +		}

[Severity: Medium]
Can speed_reg be used uninitialized here when interface is
PHY_INTERFACE_MODE_2500BASEX?

Unlike the preceding USXGMII/10GBASER and SGMII/1000BASEX blocks, this
switch (speed) has no default: return; branch.  In 2500BASE-X mode,
execution skips the earlier blocks, so an unexpected speed leaves speed_reg
uninitialized when written to AIROHA_PCS_MULTI_SGMII_SGMII_STS_CTRL_0 (and
triggers compiler uninitialized-variable warnings, along with if_mode and
ck_gen_mode under SPEED_2500).

[ ... ]

> +static unsigned int airoha_pcs_inband_caps(struct phylink_pcs *pcs,
> +					   phy_interface_t interface)
> +{
> +	return LINK_INBAND_ENABLE | LINK_INBAND_DISABLE;
> +}

[Severity: High]
Does reporting LINK_INBAND_ENABLE for PHY_INTERFACE_MODE_2500BASEX break
2500BASE-X link configuration?

Because phylink_get_inband_type(PHY_INTERFACE_MODE_2500BASEX) is
INBAND_BASEX, returning LINK_INBAND_ENABLE causes phylink_pcs_neg_mode() to
select PHYLINK_PCS_NEG_INBAND_ENABLED when autonegotiation is advertised or
used with a PHY.  However, for 2500BASE-X, airoha_pcs_config()
unconditionally clears AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE in hardware,
and airoha_pcs_link_up() only programs AIROHA_PCS_LINK_MODE_P0_2_5G in the
neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED branch.

[ ... ]

> +	/* SCU is used to toggle XFI or HSGMII in global SoC registers */
> +	if (!priv->phy) {
> +		priv->scu = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,scu");
> +		if (IS_ERR(priv->scu))
> +			return PTR_ERR(priv->scu);
> +	}

[Severity: High]
Will syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,scu") permanently
return -EPROBE_DEFER on AN7581?

In arch/arm64/boot/dts/airoha/en7581.dtsi and
Documentation/devicetree/bindings/net/pcs/airoha,pcs.yaml, airoha,scu points
to the clock controller node with compatible = "airoha,en7581-scu", which
does not have "syscon" in its compatible list.  In drivers/clk/clk-en7523.c,
en7581_clk_hw_init() maps those registers with
devm_platform_ioremap_resource() and never registers a syscon regmap, so
syscon_node_to_regmap() always fails with -EPROBE_DEFER and prevents the
ETH, PON and PCIE PCS devices from probing.

In addition, en7581_serdes_phy_set_mode() in drivers/clk/clk-en7523.c
modifies REG_NP_SCU_SSR3 (0x94) and REG_NP_SCU_SSTR (0x9c) with raw
readl()/writel() under en_clk_priv::lock, which would race with
airoha_pcs_setup_scu() updating the same registers via regmap_update_bits().

> diff --git a/drivers/net/pcs/airoha/pcs-an7581.c b/drivers/net/pcs/airoha/pcs-an7581.c
> new file mode 100644
> index 0000000000000..95e155a7fa621
> --- /dev/null
> +++ b/drivers/net/pcs/airoha/pcs-an7581.c

[ ... ]

> +	/* This comment only apply to Serdes PCIe that expose
> +	 * 2 PCS.
> +	 *
> +	 * The Serdes PCIe expose 2 PCS but always require
> +	 * the PMA for the first PCS to be configured
> +	 * for correct functionality for JCPLL.
> +	 */
> +	pcs_pma = priv->pcs_pma[0];
> +
> +	/* Setup LDO */
> +	usleep_range(200, 300);
> +
> +	regmap_field_set_bits(pcs_ana_fields[AN7581_PCS_JCPLL_SPARE_L],
> +			      AIROHA_PCS_ANA_JCPLL_SPARE_L_LDO);
> +
> +	/* Setup RSTB */
> +	regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_RST_DLY],
> +			   AIROHA_PCS_ANA_JCPLL_RST_DLY_150_200);
> +	regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_PLL_RSTB], 0x1);
> +
> +	/* Enable PLL force selection and Force Disable */
> +	regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN,
> +			   AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN |
> +			   AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN,
> +			   AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN);

[ ... ]

> +	/* This comment only apply to Serdes PCIe that expose
> +	 * 2 PCS.
> +	 *
> +	 * The Serdes PCIe expose 2 PCS but always require
> +	 * the PMA for the first PCS to be configured
> +	 * for correct functionality for TXPLL.
> +	 */
> +	pcs_pma = priv->pcs_pma[0];
> +
> +	/* Setup VCO LDO Output */
> +	regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LDO_VCO_OUT], 0x1);
> +	regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LDO_OUT], 0x1);
> +
> +	/* Setup RSTB */
> +	regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_PLL_RSTB], 0x1);
> +	regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_RST_DLY], 0x4);
> +	regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_REFIN_DIV],
> +			   AIROHA_PCS_ANA_TXPLL_REFIN_DIV_1);
> +	regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_REFIN_INTERNAL], 0x1);
> +
> +	/* Enable PLL force selection and Force Disable */
> +	regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN,
> +			   AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN |
> +			   AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN,
> +			   AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN);

[Severity: High]
On the 2-port PCIe SerDes PCS (airoha,an7581-pcs-pcie), can bringing up or
reconfiguring one port disrupt the other port?

The two ports are exposed as independent phylink_pcs instances driven by
separate phylink state machines without cross-port locking:

CPU0 (port 0 phylink)             CPU1 (port 1 phylink)
airoha_pcs_config(port 0)
  an7581_pcs_bringup()
    an7581_pcs_pll_bringup()
    msleep(100)
                                  airoha_pcs_pre_config(port 1)
                                    airoha_pcs_setup_scu()
                                      reset_control_bulk_assert(priv->rsts)
                                  airoha_pcs_config(port 1)
                                    an7581_pcs_jcpll_bringup()
                                      /* clears FORCE_DA_JCPLL_EN on pma[0] */
                                    an7581_pcs_txpll_bringup()
                                      /* clears FORCE_DA_TXPLL_EN on pma[0] */
    an7581_pcs_phya_bringup()  <-- calibrates while shared PLLs are disabled

Even when not racing concurrently, reconfiguring one port asserts the
shared device-wide MAC/PHY reset lines in airoha_pcs_setup_scu() and
force-disables and reprograms the shared JCPLL and TXPLL in
priv->pcs_pma[0] and priv->pcs_ana (including interface-dependent TXPLL
parameters), dropping an active link on the sibling port.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261114104426.235620-1-ansuelsmth@gmail.com?part=14

  reply	other threads:[~2026-11-15 10:45 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-14 10:43 [PATCH net-next v20 00/15] net: pcs: Introduce support for fwnode PCS Christian Marangi
2026-11-14 10:43 ` [PATCH net-next v20 01/15] net: phylink: keep and use MAC supported_interfaces in phylink struct Christian Marangi
2026-11-15 10:45   ` sashiko-bot
2026-11-14 10:43 ` [PATCH net-next v20 02/15] net: phylink: make PCS phylink instance access RCU protected Christian Marangi
2026-11-15 10:45   ` sashiko-bot
2026-11-14 10:43 ` [PATCH net-next v20 03/15] net: phylink: introduce internal phylink PCS handling Christian Marangi
2026-11-15 10:45   ` sashiko-bot
2026-11-14 10:43 ` [PATCH net-next v20 04/15] net: pcs: implement Firmware node support for PCS driver Christian Marangi
2026-11-15 10:45   ` sashiko-bot
2026-11-14 10:43 ` [PATCH net-next v20 05/15] net: phylink: save phylink instance fwnode on phylink_create Christian Marangi
2026-11-14 10:43 ` [PATCH net-next v20 06/15] net: phylink: make phylink_validate state locked Christian Marangi
2026-11-15 10:45   ` sashiko-bot
2026-11-14 10:43 ` [PATCH net-next v20 07/15] net: phylink: add capabilities helper and track modified advertising Christian Marangi
2026-11-15 10:45   ` sashiko-bot
2026-11-14 10:43 ` [PATCH net-next v20 08/15] net: phylink: support PCS provider release Christian Marangi
2026-11-15 10:45   ` sashiko-bot
2026-11-14 10:43 ` [PATCH net-next v20 09/15] net: phylink: support late PCS provider attach Christian Marangi
2026-11-15 10:45   ` sashiko-bot
2026-11-14 10:43 ` [PATCH net-next v20 10/15] net: Document PCS subsystem Christian Marangi
2026-11-14 10:43 ` [PATCH net-next v20 11/15] MAINTAINERS: add myself as PCS subsystem maintainer Christian Marangi
2026-11-14 10:43 ` [PATCH net-next v20 12/15] net: phylink: add .pcs_link_down PCS OP Christian Marangi
2026-11-14 10:43 ` [PATCH net-next v20 13/15] dt-bindings: net: pcs: Document support for Airoha Ethernet PCS Christian Marangi
2026-11-15 10:45   ` sashiko-bot
2026-11-14 10:43 ` [PATCH net-next v20 14/15] net: pcs: airoha: add PCS driver for Airoha AN7581 SoC Christian Marangi
2026-11-15 10:45   ` sashiko-bot [this message]
2026-11-14 10:43 ` [PATCH net-next v20 15/15] net: airoha: add phylink support Christian Marangi
2026-11-15 10:45   ` sashiko-bot
2026-11-14 13:27 ` [PATCH net-next v20 00/15] net: pcs: Introduce support for fwnode PCS Frank Wunderlich

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=sashiko-outbox-215404@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=ansuelsmth@gmail.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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