From: Jakub Kicinski <kuba@kernel.org>
To: nagadheeraj.rottela@amd.com
Cc: Jakub Kicinski <kuba@kernel.org>,
srinivas.neeli@amd.com, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@google.com, pabeni@redhat.com,
robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
richardcochran@gmail.com, michal.simek@amd.com, andrew@lunn.ch,
olteanv@gmail.com, horms@kernel.org, linux@armlinux.org.uk,
netdev@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, git-dev@amd.com
Subject: Re: [PATCH 17/20] net: dsa: xilinx: opt into TX forwarding offload on bridge join
Date: Sat, 8 Aug 2026 12:48:35 -0700 [thread overview]
Message-ID: <20260808194835.133470-1-kuba@kernel.org> (raw)
In-Reply-To: <20260807104431.157230-18-nagadheeraj.rottela@amd.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: xilinx: opt into TX forwarding offload on bridge join
The patch adds xlnx_tsn_port_bridge_join() which unconditionally sets
*tx_fwd_offload = true, so the bridge sends a single copy and relies on the
switch fabric for per-port replication. It also sets ds->max_num_bridges
to 1 in xlnx_tsn_probe().
A few questions below.
> diff --git a/drivers/net/dsa/xilinx/xilinx_tsn.c b/drivers/net/dsa/xilinx/xilinx_tsn.c
> index e48c81f18d6e..9a4d4a2fb892 100644
> --- a/drivers/net/dsa/xilinx/xilinx_tsn.c
> +++ b/drivers/net/dsa/xilinx/xilinx_tsn.c
> @@ -495,6 +495,19 @@ static int xlnx_tsn_port_set_mac_address(struct dsa_switch *ds, int port,
> return 0;
> }
>
> +static int xlnx_tsn_port_bridge_join(struct dsa_switch *ds, int port,
> + struct dsa_bridge bridge,
> + bool *tx_fwd_offload,
> + struct netlink_ext_ack *extack)
> +{
> + /* The switch fabric replicates flooded frames per egress port
> + * on its own, so the bridge does not need to clone-and-send.
> + */
> + *tx_fwd_offload = true;
[Severity: High]
Does this drop PTP frames on all user ports but one?
The comment's premise does not seem to hold for the frame class the tagger
diverts. In net/dsa/tag_xlnx_tsn.c, xlnx_tsn_xmit() takes untagged
ETH_P_1588 frames out of the fabric path entirely:
if (eth_hdr(skb)->h_proto != htons(ETH_P_1588) ||
skb_vlan_tag_present(skb))
return skb;
tagger_data->ptp_tx(dp, skb);
return NULL;
That handler, xlnx_tsn_ptp_tx() in
drivers/net/dsa/xilinx/xilinx_tsn_ptp.c, writes into the TX buffer of one
specific MAC:
m = &sw->mac[dp->index];
so the frame goes into the per-port PTP TX FIFO of the single egress MAC
and never reaches the fabric that would replicate it.
Before this patch the bridge cloned a flooded frame once per member port,
so each clone landed in its own MAC's PTP FIFO. With
BR_TX_FWD_OFFLOAD requested, net/bridge/br_switchdev.c suppresses the
remaining copies for the same hwdom:
if (nbp_switchdev_can_offload_tx_fwd(p, skb))
set_bit(p->hwdom, &BR_INPUT_SKB_CB(skb)->fwd_hwdoms);
...
return !test_bit(p->hwdom, &cb->fwd_hwdoms) &&
(!skb->offload_fwd_mark || cb->src_hwdom != p->hwdom);
With br0 containing both swp1 and swp2, an untagged PTP frame flooded from
another bridge port then loads only one MAC's PTP FIFO and the other user
port transmits nothing, with no counter or log for the loss. Should PTP
traffic be excluded from the offload, or should the tagger encode a flood
so the second copy is regenerated?
> +
> + return 0;
> +}
> +
[ ... ]
> @@ -786,6 +800,9 @@ static int xlnx_tsn_probe(struct platform_device *pdev)
> ds->phylink_mac_ops = &xlnx_tsn_phylink_mac_ops;
> ds->priv = sw;
>
> + /* The fabric offloads a single bridge across the user ports. */
> + ds->max_num_bridges = 1;
[Severity: Medium]
The commit message says:
"Set ds->max_num_bridges to 1 so the DSA core rejects a second bridge
instead of silently merging the ports."
Does the core actually reject it? In net/dsa/port.c,
dsa_port_bridge_create() only returns -EOPNOTSUPP when the bridge number
allocation comes back empty:
bridge->num = dsa_bridge_num_get(br, ds->max_num_bridges);
if (ds->max_num_bridges && !bridge->num) {
NL_SET_ERR_MSG_MOD(extack,
"Range of offloadable bridges exceeded");
kfree(bridge);
return -EOPNOTSUPP;
}
and dsa_user_changeupper() in net/dsa/user.c turns that into success:
if (err == -EOPNOTSUPP) {
NL_SET_ERR_MSG_WEAK_MOD(extack,
"Offloading not supported");
err = 0;
}
So "ip link set swp2 master br1" succeeds and the port joins br1
unoffloaded with dp->bridge rolled back to NULL. Since the driver
programs no hardware forwarding domain (the new
xlnx_tsn_port_bridge_join() touches no register and ignores its bridge
argument), and dsa_port_enable_rt() puts a non-bridged port into hardware
forwarding:
if (!dp->bridge)
dsa_port_set_state_now(dp, BR_STATE_FORWARDING, false);
both MACs stay forwarding and the fabric keeps bridging them. Does this
mean the two L2 domains are merged in hardware anyway, which is the case
the commit message claims is prevented? If rejection is the intent,
would the driver need to track the offloaded bridge in port_bridge_join
and return something other than -EOPNOTSUPP (for example -EBUSY) with an
extack?
[Severity: Medium]
Is max_num_bridges = 1 workable given the bridge number allocator is
system-global rather than per-switch? In net/dsa/dsa.c,
dsa_bridge_num_get() picks the lowest free bit of the file-scope
dsa_fwd_offloading_bridges bitmap and compares that global index against
this driver's max:
bridge_num = find_next_zero_bit(&dsa_fwd_offloading_bridges,
DSA_MAX_NUM_OFFLOADING_BRIDGES,
1);
if (bridge_num > max)
return 0;
With max == 1 the only acceptable global index is 1. If any other DSA
switch, or a second instance of this platform driver, already holds global
bridge number 1, then the very first bridge on this switch gets index 2,
2 > 1, and dsa_port_bridge_create() returns -EOPNOTSUPP, so
xlnx_tsn_port_bridge_join() is never called and *tx_fwd_offload is never
set. dsa_user_changeupper() rewrites the error to 0, so the join looks
successful while the bridge silently resumes clone-and-send and the wire
sees duplicated frames again.
Other drivers size max_num_bridges from a hardware resource count (for
example DSA_TAG_8021Q_MAX_NUM_BRIDGES or ds->num_ports). Would that be
more appropriate here?
next prev parent reply other threads:[~2026-08-08 19:48 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-07 10:44 [PATCH 00/20] xilinx: tsn: Add TSN Endpoint Ethernet MAC driver support Nagadheeraj Rottela
2026-08-07 10:44 ` [PATCH 01/20] dt-bindings: net: add Xilinx TSN Endpoint Ethernet MAC Nagadheeraj Rottela
2026-08-08 10:46 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 02/20] net: xilinx: tsn: add TSN endpoint wrapper driver Nagadheeraj Rottela
2026-08-07 20:58 ` Uwe Kleine-König
2026-08-08 12:27 ` Neeli, Srinivas
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 03/20] net: xilinx: tsn: add endpoint MAC driver skeleton Nagadheeraj Rottela
2026-08-07 21:00 ` Uwe Kleine-König
2026-08-08 12:28 ` Neeli, Srinivas
2026-08-08 10:46 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 04/20] net: xilinx: tsn: parse endpoint DMA channel configuration Nagadheeraj Rottela
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 05/20] net: xilinx: tsn: bring up the endpoint MCDMA channels Nagadheeraj Rottela
2026-08-08 10:46 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 06/20] net: xilinx: tsn: add the endpoint RX data path Nagadheeraj Rottela
2026-08-08 10:46 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 07/20] net: xilinx: tsn: add the endpoint TX " Nagadheeraj Rottela
2026-08-08 10:46 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 08/20] net: xilinx: tsn: deliver endpoint RX frames to DSA user ports Nagadheeraj Rottela
2026-08-08 10:46 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 09/20] net: dsa: tag_xlnx_tsn: add skeleton tag protocol Nagadheeraj Rottela
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 10/20] net: dsa: xilinx: add skeleton driver for TSN switch Nagadheeraj Rottela
2026-08-07 10:44 ` [PATCH 11/20] net: dsa: xilinx: implement port_stp_state_set Nagadheeraj Rottela
2026-08-08 10:46 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 12/20] net: dsa: xilinx: register per-MAC MDIO buses Nagadheeraj Rottela
2026-08-08 10:46 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 13/20] net: dsa: xilinx: wire up phylink for the switch ports Nagadheeraj Rottela
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 14/20] net: dsa: xilinx: program MAC frame filter and per-port nibbles Nagadheeraj Rottela
2026-08-08 10:46 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 15/20] net: dsa: xilinx: register PHC backed by the RTC timer block Nagadheeraj Rottela
2026-08-08 10:46 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 16/20] net: dsa: xilinx: drive per-MAC PTP TX/RX hardware paths Nagadheeraj Rottela
2026-08-08 10:46 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 17/20] net: dsa: xilinx: opt into TX forwarding offload on bridge join Nagadheeraj Rottela
2026-08-08 10:46 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski [this message]
2026-08-07 10:44 ` [PATCH 18/20] net: dsa: xilinx: offload the bridge FDB to the switch CAM Nagadheeraj Rottela
2026-08-08 10:46 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 19/20] net: dsa: xilinx: offload bridge VLAN filtering to the switch Nagadheeraj Rottela
2026-08-08 10:46 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 10:44 ` [PATCH 20/20] net: dsa: xilinx: trap link-local control frames to the CPU port Nagadheeraj Rottela
2026-08-08 10:47 ` sashiko-bot
2026-08-08 19:48 ` Jakub Kicinski
2026-08-07 22:28 ` [PATCH 00/20] xilinx: tsn: Add TSN Endpoint Ethernet MAC driver support 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=20260808194835.133470-1-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=andrew@lunn.ch \
--cc=conor+dt@kernel.org \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=edumazet@google.com \
--cc=git-dev@amd.com \
--cc=horms@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=michal.simek@amd.com \
--cc=nagadheeraj.rottela@amd.com \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=pabeni@redhat.com \
--cc=richardcochran@gmail.com \
--cc=robh@kernel.org \
--cc=srinivas.neeli@amd.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