All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: jensemil.schulzostergaard@microchip.com
Cc: Jakub Kicinski <kuba@kernel.org>,
	UNGLinuxDriver@microchip.com, andrew@lunn.ch, olteanv@gmail.com,
	davem@davemloft.net, edumazet@google.com, pabeni@redhat.com,
	horms@kernel.org, robh@kernel.org, krzk+dt@kernel.org,
	conor+dt@kernel.org, woojung.huh@microchip.com,
	linux@armlinux.org.uk, Steen.Hegelund@microchip.com,
	daniel.machon@microchip.com, linux-kernel@vger.kernel.org,
	netdev@vger.kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH net-next v4 4/9] net: dsa: lan9645x: add basic dsa driver for LAN9645X
Date: Tue,  5 May 2026 18:45:55 -0700	[thread overview]
Message-ID: <20260506014555.1616575-1-kuba@kernel.org> (raw)
In-Reply-To: <20260430-dsa_lan9645x_switch_driver_base-v4-4-f1b6005fa8b7@microchip.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
net: dsa: lan9645x: add basic dsa driver for LAN9645X

This patch introduces a new DSA driver for the Microchip LAN9645X switch
family, covering probe/setup/teardown, NPI CPU port wiring, per-port
initialisation, and phylink MAC integration. A few questions inline.

> diff --git a/drivers/net/dsa/microchip/lan9645x/Kconfig b/drivers/net/dsa/microchip/lan9645x/Kconfig
> new file mode 100644
> index 000000000000..4d9fdf34104e
> --- /dev/null
> +++ b/drivers/net/dsa/microchip/lan9645x/Kconfig
> @@ -0,0 +1,11 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +config NET_DSA_MICROCHIP_LAN9645X
> +	tristate "Microchip Lan9645x switch support"
> +	depends on NET_DSA
> +	select NET_DSA_TAG_LAN9645X
> +	help
> +	  This driver adds DSA support for Microchip Lan9645x switch chips.

The driver is non-functional without a parent MFD that registers the named
regmaps ("gcb", "qs", "chip_top", "rew", "sys", "hsio", "dev", "dev1" ..
"dev8", "qsys", "afi", "ana") consumed by lan9645x_request_target_regmaps().

Should this Kconfig depend on the parent provider symbol so that selecting
this option without the parent driver does not produce a module whose probe
always fails?

Is there a companion parent-driver patch this patch depends on? If so,
would it be worth naming it in the commit message and documenting the
ordering?

> diff --git a/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c b/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c
> new file mode 100644
> index 000000000000..6fd66ea67cfd
> --- /dev/null
> +++ b/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c
> @@ -0,0 +1,423 @@

[ ... ]

> +static const char *lan9645x_resource_names[NUM_TARGETS + 1] = {
> +	[TARGET_GCB]          = "gcb",
> +	[TARGET_QS]           = "qs",
> +	[TARGET_CHIP_TOP]     = "chip_top",
> +	[TARGET_REW]          = "rew",
> +	[TARGET_SYS]          = "sys",
> +	[TARGET_HSIO]         = "hsio",
> +	[TARGET_DEV]          = "dev",
> +	[TARGET_DEV + 1]      = "dev1",
> +	[TARGET_DEV + 2]      = "dev2",
> +	[TARGET_DEV + 3]      = "dev3",
> +	[TARGET_DEV + 4]      = "dev4",
> +	[TARGET_DEV + 5]      = "dev5",
> +	[TARGET_DEV + 6]      = "dev6",
> +	[TARGET_DEV + 7]      = "dev7",
> +	[TARGET_DEV + 8]      = "dev8",

The first DEV instance is named "dev", while the rest are "dev1" through
"dev8". Is this asymmetry intentional, or should the first be "dev0" to
match the natural per-port numbering? Without the parent driver available
in this series, it is hard to tell which naming scheme the parent actually
registers.

If the parent registers "dev0".."dev8" then dev_get_regmap(parent, "dev")
returns NULL and probe fails with -ENODEV.

[ ... ]

> +static void lan9645x_set_feat_dis(struct lan9645x *lan9645x)
> +{
> +	u32 feat_dis;
> +
> +	/* The features which can be physically disabled on some SKUs are:
> +	 * 1) Number of ports can be 5, 7 or 9. Any ports can be used, the chip
> +	 *    tracks how many are active.
> +	 * 2) HSR/PRP. The duplicate discard table can be disabled.
> +	 * 3) TAS, frame preemption and PSFP can be disabled.
> +	 */
> +	feat_dis = lan_rd(lan9645x, GCB_FEAT_DISABLE);
> +
> +	lan9645x->num_port_dis =
> +		GCB_FEAT_DISABLE_FEAT_NUM_PORTS_DIS_GET(feat_dis);
> +	lan9645x->dd_dis = GCB_FEAT_DISABLE_FEAT_DD_DIS_GET(feat_dis);
> +	lan9645x->tsn_dis = GCB_FEAT_DISABLE_FEAT_TSN_DIS_GET(feat_dis);
> +}

Where are num_port_dis, dd_dis and tsn_dis consulted after this read?

ds->num_ports is hardcoded to NUM_PHYS_PORTS (9) in lan9645x_probe(), and
there does not appear to be any rejection of TSN or HSR/PRP configuration
on SKUs where tsn_dis=1 or dd_dis=1 in this patch. On a 5-port SKU
(num_port_dis=4), would the driver still register 9 DSA ports and allow
DT to bring up a fused-off port?

> +static int lan9645x_setup(struct dsa_switch *ds)
> +{

[ ... ]

> +	dev_info(lan9645x->dev,
> +		 "SKU features: tsn_dis=%d hsr_dis=%d max_ports=%d\n",
> +		 lan9645x->tsn_dis, lan9645x->dd_dis,
> +		 lan9645x->num_phys_ports - lan9645x->num_port_dis);

The log prints the field called dd_dis in struct lan9645x under the name
hsr_dis. Should the label in the format string match the struct field
name, or should the field be renamed?

[ ... ]

> diff --git a/drivers/net/dsa/microchip/lan9645x/lan9645x_phylink.c b/drivers/net/dsa/microchip/lan9645x/lan9645x_phylink.c
> new file mode 100644
> index 000000000000..9eac32ca342c
> --- /dev/null
> +++ b/drivers/net/dsa/microchip/lan9645x/lan9645x_phylink.c
> @@ -0,0 +1,383 @@

[ ... ]

> +/* Port 4 or 7 is RGMII_0 and port 8 is RGMII_1 */
> +#define RGMII_IDX(port) ((port) == 8 ? 1 : 0)
> +
> +void lan9645x_phylink_get_caps(struct lan9645x *lan9645x, int port,
> +			       struct phylink_config *c)
> +{
> +	c->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 |
> +			      MAC_100 | MAC_1000FD | MAC_2500FD;
> +
> +	switch (port) {
> +	case 0 ... 3:
> +		__set_bit(PHY_INTERFACE_MODE_GMII, c->supported_interfaces);
> +		break;
> +	case 4:
> +		__set_bit(PHY_INTERFACE_MODE_GMII, c->supported_interfaces);
> +		phy_interface_set_rgmii(c->supported_interfaces);
> +		break;
> +	case 5 ... 6:
> +		/* SerDes ports: QSGMII/SGMII/1000BASEX/2500BASEX modes
> +		 * require PCS support which is not yet implemented.
> +		 */
> +		break;
> +	case 7 ... 8:
> +		/* QSGMII mode on ports 7-8 requires SerDes PCS support,
> +		 * which is not yet implemented.
> +		 */
> +		phy_interface_set_rgmii(c->supported_interfaces);
> +		break;
> +	default:
> +		break;
> +	}
> +}

mac_capabilities advertises MAC_2500FD for every port, but none of the
supported_interfaces entries allow negotiating 2.5 Gb/s. GMII and RGMII
do not carry 2.5 Gb/s, and ports 5-6 have an empty supported_interfaces
bitmap. Should MAC_2500FD be dropped until a PCS-capable interface is
added, or should it be set only on ports that will actually support it?

For ports 5 and 6, supported_interfaces is left empty. Will phylink_create()
succeed for those ports given no interface mode is permitted, or will they
be silently unusable?

The commit message states:

    The lan9645x switch is a multi-port Gigabit AVB/TSN Ethernet Switch
    with five integrated 10/100/1000Base-T PHYs. In addition to the
    integrated PHYs, it supports up to 2 RGMII/RMII, up to 2
    BASE-X/SERDES/2.5GBASE-X and one Quad-SGMII/Quad-USGMII interfaces.

Given ports 5-6 have no supported_interfaces and ports 7-8 expose only
RGMII in this patch, would it help to note in the commit message that
SerDes, QSGMII/USGMII and 2.5GBASE-X are not wired up yet?

[ ... ]

> +static int lan9645x_phylink_mac_prepare(struct phylink_config *config,
> +					unsigned int mode,
> +					phy_interface_t iface)
> +{
> +	struct lan9645x_port *p = lan9645x_phylink_config_to_port(config);
> +	struct lan9645x *lan9645x = p->lan9645x;
> +	int port = p->chip_port;
> +	bool is_rgmii;
> +	u32 mask;
> +
> +	if (port == 5 || port == 6 || port > 8)
> +		return -EINVAL;
> +
> +	mask = HSIO_HW_CFG_GMII_ENA_SET(BIT(port));
> +	lan_rmw(mask, mask, lan9645x, HSIO_HW_CFG);
> +
> +	is_rgmii = phy_interface_mode_is_rgmii(iface);
> +	if (port == 4)
> +		lan_rmw(HSIO_HW_CFG_RGMII_0_CFG_SET(is_rgmii),
> +			HSIO_HW_CFG_RGMII_0_CFG,
> +			lan9645x, HSIO_HW_CFG);
> +
> +	return 0;
> +}

The HSIO_HW_CFG_RGMII_0_CFG bit is only written when port == 4, but the
comment above RGMII_IDX() states:

    /* Port 4 or 7 is RGMII_0 and port 8 is RGMII_1 */
    #define RGMII_IDX(port) ((port) == 8 ? 1 : 0)

Port 7 also maps to RGMII_0. If port 7 is configured for RGMII, does the
RGMII_0 mux ever get routed to port 7? And if port 4 is later configured
in GMII mode, the write HSIO_HW_CFG_RGMII_0_CFG_SET(0) would run and
appear to reroute RGMII_0 away from port 7.

Is there meant to be mutual-exclusion between port 4 and port 7 in RGMII
mode, and a write path for port 7 as well?

> +static void lan9645x_rgmii_dll_config(struct lan9645x_port *p)
> +{
> +	u32 rx_idx, tx_idx;
> +
> +	/* DLL register layout:
> +	 * (N*2):   RGMII_N_RX
> +	 * (N*2)+1: RGMII_N_TX
> +	 */
> +	rx_idx = RGMII_IDX(p->chip_port) * 2;
> +	tx_idx = RGMII_IDX(p->chip_port) * 2 + 1;
> +
> +	/* Enable DLL in RGMII clock paths, deassert DLL reset, and start the
> +	 * delay tune FSM.
> +	 */
> +	lan_rmw(HSIO_DLL_CFG_DLL_CLK_ENA_SET(1) |
> +		HSIO_DLL_CFG_DLL_RST_SET(0) |
> +		HSIO_DLL_CFG_DLL_ENA_SET(p->rx_internal_delay) |
> +		HSIO_DLL_CFG_DELAY_ENA_SET(p->rx_internal_delay),
> +		HSIO_DLL_CFG_DLL_CLK_ENA |
> +		HSIO_DLL_CFG_DLL_RST |
> +		HSIO_DLL_CFG_DLL_ENA |
> +		HSIO_DLL_CFG_DELAY_ENA,
> +		p->lan9645x, HSIO_DLL_CFG(rx_idx));
> +
> +	lan_rmw(HSIO_DLL_CFG_DLL_CLK_ENA_SET(1) |
> +		HSIO_DLL_CFG_DLL_RST_SET(0) |
> +		HSIO_DLL_CFG_DLL_ENA_SET(p->tx_internal_delay) |
> +		HSIO_DLL_CFG_DELAY_ENA_SET(p->tx_internal_delay),
> +		HSIO_DLL_CFG_DLL_CLK_ENA |
> +		HSIO_DLL_CFG_DLL_RST |
> +		HSIO_DLL_CFG_DLL_ENA |
> +		HSIO_DLL_CFG_DELAY_ENA,
> +		p->lan9645x, HSIO_DLL_CFG(tx_idx));
> +}

This function consults only p->rx_internal_delay and p->tx_internal_delay
and never looks at the phy_interface_t. Phylink expects the MAC to apply
internal delay only when the interface is RGMII_ID, RGMII_TXID or
RGMII_RXID, and not when the interface is plain PHY_INTERFACE_MODE_RGMII
(where the PHY provides delay).

With a DT that specifies phy-mode = "rgmii" and nonzero
rx-internal-delay-ps, will both the PHY and the MAC add delay?

And with phy-mode = "rgmii-id" but no {rx,tx}-internal-delay-ps property
in DT, will the MAC fail to add delay on either side?

> diff --git a/drivers/net/dsa/microchip/lan9645x/lan9645x_port.c b/drivers/net/dsa/microchip/lan9645x/lan9645x_port.c
> new file mode 100644
> index 000000000000..394a20ee678f
> --- /dev/null
> +++ b/drivers/net/dsa/microchip/lan9645x/lan9645x_port.c

[ ... ]

> +int lan9645x_port_setup(struct dsa_switch *ds, int port)
> +{
> +	struct dsa_port *dp = dsa_to_port(ds, port);
> +	struct lan9645x *lan9645x = ds->priv;
> +	struct lan9645x_port *p;
> +
> +	p = lan9645x_to_port(lan9645x, port);
> +
> +	if (dp->dn) {
> +		u32 val;
> +
> +		if (!of_property_read_u32(dp->dn, "rx-internal-delay-ps", &val))
> +			p->rx_internal_delay = val > 0;
> +
> +		if (!of_property_read_u32(dp->dn, "tx-internal-delay-ps", &val))
> +			p->tx_internal_delay = val > 0;
> +	}

The u32 picosecond value from DT is collapsed to a boolean via "val > 0",
discarding the tap selection. Is the discarded precision intentional, and
if so, why read the value as u32 in the first place rather than using
of_property_read_bool() on a differently-named property?

  reply	other threads:[~2026-05-06  1:45 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-30  9:34 [PATCH net-next v4 0/9] net: dsa: add DSA support for the LAN9645x switch chip family Jens Emil Schulz Østergaard
2026-04-30  9:34 ` [PATCH net-next v4 1/9] net: dsa: add tag driver for LAN9645X Jens Emil Schulz Østergaard
2026-05-06  1:45   ` Jakub Kicinski
2026-05-12  6:28     ` Jens Emil Schulz Ostergaard
2026-04-30  9:34 ` [PATCH net-next v4 2/9] dt-bindings: net: lan9645x: add LAN9645X switch bindings Jens Emil Schulz Østergaard
2026-04-30  9:34 ` [PATCH net-next v4 3/9] net: dsa: lan9645x: add autogenerated register macros Jens Emil Schulz Østergaard
2026-04-30  9:34 ` [PATCH net-next v4 4/9] net: dsa: lan9645x: add basic dsa driver for LAN9645X Jens Emil Schulz Østergaard
2026-05-06  1:45   ` Jakub Kicinski [this message]
2026-05-12  7:15     ` Jens Emil Schulz Ostergaard
2026-04-30  9:34 ` [PATCH net-next v4 5/9] net: dsa: lan9645x: add bridge support Jens Emil Schulz Østergaard
2026-05-06  1:46   ` Jakub Kicinski
2026-05-12  7:24     ` Jens Emil Schulz Ostergaard
2026-04-30  9:34 ` [PATCH net-next v4 6/9] net: dsa: lan9645x: add vlan support Jens Emil Schulz Østergaard
2026-05-06  1:46   ` Jakub Kicinski
2026-05-12  7:29     ` Jens Emil Schulz Ostergaard
2026-04-30  9:34 ` [PATCH net-next v4 7/9] net: dsa: lan9645x: add mac table integration Jens Emil Schulz Østergaard
2026-05-06  1:46   ` Jakub Kicinski
2026-05-12  7:42     ` Jens Emil Schulz Ostergaard
2026-04-30  9:34 ` [PATCH net-next v4 8/9] net: dsa: lan9645x: add mdb management Jens Emil Schulz Østergaard
2026-05-06  1:46   ` Jakub Kicinski
2026-05-12  7:45     ` Jens Emil Schulz Ostergaard
2026-04-30  9:34 ` [PATCH net-next v4 9/9] net: dsa: lan9645x: add port statistics Jens Emil Schulz Østergaard
2026-05-06  1:46   ` Jakub Kicinski
2026-05-06  1:48     ` Jakub Kicinski
2026-05-12  8:47     ` Jens Emil Schulz Ostergaard
2026-05-12 23:39       ` Jakub Kicinski

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=20260506014555.1616575-1-kuba@kernel.org \
    --to=kuba@kernel.org \
    --cc=Steen.Hegelund@microchip.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=andrew@lunn.ch \
    --cc=conor+dt@kernel.org \
    --cc=daniel.machon@microchip.com \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=jensemil.schulzostergaard@microchip.com \
    --cc=krzk+dt@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=pabeni@redhat.com \
    --cc=robh@kernel.org \
    --cc=woojung.huh@microchip.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.