From: Jakub Kicinski <kuba@kernel.org>
To: alexander.duyck@gmail.com
Cc: Jakub Kicinski <kuba@kernel.org>,
netdev@vger.kernel.org, mike.marciniszyn@gmail.com,
alexanderduyck@fb.com, andrew+netdev@lunn.ch, andrew@lunn.ch,
davem@davemloft.net, edumazet@google.com, hkallweit1@gmail.com,
jiawenwu@trustnetic.com, kees@kernel.org, kernel-team@meta.com,
linux-kernel@vger.kernel.org, linux@armlinux.org.uk,
mengyuanlou@net-swift.com, mohsin.bashr@gmail.com,
pabeni@redhat.com
Subject: Re: [net-next PATCH v4 2/4] net: pcs: xpcs: Allow for multiple addr in creation
Date: Mon, 3 Aug 2026 18:48:30 -0700 [thread overview]
Message-ID: <20260804014830.2532522-1-kuba@kernel.org> (raw)
In-Reply-To: <178536366014.250758.7525172425951669429.stgit@ahduyck-xeon-server.home.arpa>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
--- Patch [2]: [net-next PATCH v4 2/4] net: pcs: xpcs: Allow for multiple addr in creation ---
commit 659d2ab0068099d84cd67aa41fc9d8519508054c
Author: Mike Marciniszyn (Meta) <mike.marciniszyn@gmail.com>
net: pcs: xpcs: Allow for multiple addr in creation
This extends xpcs_create_data(), xpcs_create() and xpcs_free_data() to take
an array of mdio devices, adds a new exported xpcs_create_pcs_mdiodevs()
entry point, and switches fbnic over to registering two MDIO addresses. A
new xpcs->channels field records how many mdio devices were provisioned.
A few questions below on the new multi-channel plumbing and the
kernel-doc/changelog wording.
The changelog says:
Add xpcs_create_mdiodevs() and xpcs_create_pcs_mdiodevs calls so that a
driver using the above part can tell xpcs the addr values in one call.
xpcs_create_mdiodevs() is added as static, with no EXPORT_SYMBOL_GPL and no
declaration in include/linux/pcs/pcs-xpcs.h, so a driver that needs the
struct dw_xpcs handle (the xpcs_create_mdiodev() users) still cannot pass
more than one address. Should the changelog only mention
xpcs_create_pcs_mdiodevs() as the driver-facing addition?
> diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c b/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c
> index 09c5225111be3..88fc78d55c7a5 100644
> --- a/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c
> +++ b/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c
> @@ -200,9 +200,11 @@ int fbnic_phylink_create(struct net_device *netdev)
> struct fbnic_dev *fbd = fbn->fbd;
> struct phylink_pcs *pcs;
> struct phylink *phylink;
> + /* See fbnic_mdio.c addr usage */
> + int addrs[] = { 0, 1 };
> int err;
>
> - pcs = xpcs_create_pcs_mdiodev(fbd->mdio_bus, 0);
> + pcs = xpcs_create_pcs_mdiodevs(fbd->mdio_bus, addrs, ARRAY_SIZE(addrs));
> if (IS_ERR(pcs)) {
> err = PTR_ERR(pcs);
> dev_err(fbd->dev, "Failed to create PCS device: %d\n", err);
> diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
> index 6a645df58f9b8..a6b993745f3be 100644
> --- a/drivers/net/pcs/pcs-xpcs.c
> +++ b/drivers/net/pcs/pcs-xpcs.c
> @@ -214,9 +214,18 @@ int xpcs_read(struct dw_xpcs *xpcs, int dev, u32 reg)
> return mdiodev_c45_read(xpcs->mdiodev[0], dev, reg);
> }
>
> +static int
> +xpcs_mdev_write_ch(struct dw_xpcs *xpcs, int ch, int dev, u32 reg, u16 val)
> +{
> + if (ch >= xpcs->channels)
> + return -ENXIO;
> +
> + return mdiodev_c45_write(xpcs->mdiodev[ch], dev, reg, val);
> +}
> +
> int xpcs_write(struct dw_xpcs *xpcs, int dev, u32 reg, u16 val)
> {
> - return mdiodev_c45_write(xpcs->mdiodev[0], dev, reg, val);
> + return xpcs_mdev_write_ch(xpcs, 0, dev, reg, val);
> }
>
> int xpcs_modify(struct dw_xpcs *xpcs, int dev, u32 reg, u16 mask, u16 set)
[Severity: Medium]
[Finding: main-1-1]
[Sources: opus-5]
Only the write path becomes channel aware here. xpcs_read(),
xpcs_modify(), xpcs_modify_changed() and the
phylink_mii_c45_pcs_get_state(xpcs->mdiodev[0], ...) call in
xpcs_get_state_c73() stay pinned to mdiodev[0], and no per-channel read or
read-modify-write helper appears later in the series either (checked at
7b16dc0f9f78, where xpcs_write_pcs_ch() and xpcs_mdev_write_ch() are the
only channel-aware accessors).
For fbnic, addr 1 is a distinct register page:
drivers/net/ethernet/meta/fbnic/fbnic_mdio.c maps addr 0/1 onto
FBNIC_PCS_PAGE(addr), described as allowing access to both halves of the
PCS for the 50R2 config.
So in the two-instance modes (PHY_INTERFACE_MODE_LAUI and
PHY_INTERFACE_MODE_100GBASEP, both with .channels = 2), instance 1 gets the
vendor writes from xpcs_config_rsfec_pma() later in the series, but:
xpcs_pre_config() -> xpcs_soft_reset() -> xpcs_modify() -> mdiodev[0]
xpcs_get_state_c73() -> xpcs_read(MDIO_STAT1/STAT2) -> mdiodev[0]
Does instance 1 need its own soft reset for those vendor writes to latch,
and should its fault/alignment status be folded into the state reported to
phylink? As written, a faulted or unreset second half would not be visible.
> @@ -1507,16 +1516,21 @@ static int xpcs_identify(struct dw_xpcs *xpcs)
[ ... ]
> @@ -1610,25 +1627,24 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev)
> return ERR_PTR(ret);
> }
>
> -/**
> - * xpcs_create_mdiodev() - create a DW xPCS instance with the MDIO @addr
> - * @bus: pointer to the MDIO-bus descriptor for the device to be looked at
> - * @addr: device MDIO-bus ID
> - *
> - * Return: a pointer to the DW XPCS handle if successful, otherwise -ENODEV if
> - * the PCS device couldn't be found on the bus and other negative errno related
> - * to the data allocation and MDIO-bus communications.
> - */
> -struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr)
> +static struct dw_xpcs *
> +xpcs_create_mdiodevs(struct mii_bus *bus, const int *addrs, int channels)
> {
> - struct mdio_device *mdiodev;
> + struct mdio_device *mdiodev[DW_XPCS_MAX_CHANNELS], *rval;
> struct dw_xpcs *xpcs;
> + int i;
> +
> + if (!addrs || channels <= 0 || channels > DW_XPCS_MAX_CHANNELS)
> + return ERR_PTR(-EINVAL);
[ ... ]
> +/**
> + * xpcs_create_pcs_mdiodevs() - create a DW xPCS instance with multiple @addrs
> + * @bus: pointer to the embedded phylink PCS instance
[Severity: Low]
[Finding: main-1-4]
[Sources: opus-5]
Should @bus be described as the MDIO-bus descriptor, as the existing
xpcs_create_mdiodev() kernel-doc does? It is a struct mii_bus * that gets
handed to mdio_device_create(bus, addrs[i]); the embedded phylink PCS is
what the function returns.
> + * @addrs: an array of int
> + * @channels: the number of addrs items or channels
> + *
> + * Return: a pointer to the phylink PCS if successful, otherwise -ENODEV if
> + * the PCS device couldn't be found on the bus and other negative errno related
> + * to the data allocation and MDIO-bus communications.
> + */
[Severity: Low]
[Finding: main-1-4]
[Sources: opus-5]
Could the Return: section also mention -EINVAL? The new check in
xpcs_create_mdiodevs():
if (!addrs || channels <= 0 || channels > DW_XPCS_MAX_CHANNELS)
return ERR_PTR(-EINVAL);
is reachable through this exported wrapper, but only -ENODEV and
allocation/MDIO errors are listed. Both wording issues are still present at
the end of the series (7b16dc0f9f78).
> +struct phylink_pcs *
> +xpcs_create_pcs_mdiodevs(struct mii_bus *bus, const int *addrs, int channels)
> +{
> + struct dw_xpcs *xpcs;
> +
> + xpcs = xpcs_create_mdiodevs(bus, addrs, channels);
> + if (IS_ERR(xpcs))
> + return ERR_CAST(xpcs);
> +
> + return &xpcs->pcs;
> +}
> +EXPORT_SYMBOL_GPL(xpcs_create_pcs_mdiodevs);
[ ... ]
> diff --git a/drivers/net/pcs/pcs-xpcs.h b/drivers/net/pcs/pcs-xpcs.h
> index 5c804cfd47d3c..36f4906e689a8 100644
> --- a/drivers/net/pcs/pcs-xpcs.h
> +++ b/drivers/net/pcs/pcs-xpcs.h
> @@ -114,6 +114,7 @@ struct dw_xpcs {
> struct mdio_device *mdiodev[DW_XPCS_MAX_CHANNELS];
> struct clk_bulk_data clks[DW_XPCS_NUM_CLKS];
> struct phylink_pcs pcs;
> + int channels;
[Severity: Low]
[Finding: main-1-2]
[Sources: opus-5]
This isn't a bug, but the name channels now carries two different meanings
in this driver. Here it counts the MDIO devices a driver provisioned, while
struct pma_pcs_values::channels in pcs-xpcs.c counts the PCS instances the
active link mode uses (.channels = 1 for 25GBASER/50GBASER, .channels = 2
for LAUI/100GBASEP).
fbnic_phylink_create() passes addrs[] = { 0, 1 } before any interface is
selected, so xpcs->channels is 2 even in the single-instance modes fbnic
also advertises. The bound in xpcs_mdev_write_ch():
if (ch >= xpcs->channels)
return -ENXIO;
then checks against the provisioned count rather than the active mode's
count. Would a name like n_mdiodevs or num_addrs make that invariant
clearer?
The fbnic side also repeats the fbnic_mdio.c address layout as bare numbers
tied to it only by the "/* See fbnic_mdio.c addr usage */" comment; could
those addresses come from a shared define?
> phy_interface_t interface;
> bool need_reset;
> u8 eee_mult_fact;
next prev parent reply other threads:[~2026-08-04 1:48 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-29 22:16 [net-next PATCH v4 0/4] Add support for XPCS based RSFEC configuration Alexander Duyck
2026-07-29 22:18 ` [net-next PATCH v4 1/4] net: pcs: xpcs: Expand mdiodev member as an array Alexander Duyck
2026-07-29 22:21 ` [net-next PATCH v4 2/4] net: pcs: xpcs: Allow for multiple addr in creation Alexander Duyck
2026-08-04 1:48 ` Jakub Kicinski [this message]
2026-07-29 22:23 ` [net-next PATCH v4 3/4] net: pcs: xpcs: Add hooks for xpcs configuration of rsfec Alexander Duyck
2026-08-04 1:48 ` Jakub Kicinski
2026-07-29 22:25 ` [net-next PATCH v4 4/4] net: pcs: xpcs: Add handling for 4 channel rsfec device Alexander Duyck
2026-08-04 1:48 ` Jakub Kicinski
2026-08-04 1:49 ` [net-next PATCH v4 0/4] Add support for XPCS based RSFEC configuration Jakub Kicinski
2026-08-04 15:50 ` Alexander Duyck
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=20260804014830.2532522-1-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=alexander.duyck@gmail.com \
--cc=alexanderduyck@fb.com \
--cc=andrew+netdev@lunn.ch \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hkallweit1@gmail.com \
--cc=jiawenwu@trustnetic.com \
--cc=kees@kernel.org \
--cc=kernel-team@meta.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=mengyuanlou@net-swift.com \
--cc=mike.marciniszyn@gmail.com \
--cc=mohsin.bashr@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.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