From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Extend the RZN1 A5PSW driver to support SoC-specific adjustments to the
management (CPU) port frame length. Some SoCs, such as the RZ/T2H and
RZ/N2H, require additional headroom on the management port to account
for a special management tag added to frames. Without this adjustment,
frames may be incorrectly detected as oversized and subsequently
discarded.
Introduce a new field, `management_port_frame_len_adj`, in
`struct a5psw_of_data` to represent this adjustment, and apply it in
`a5psw_port_change_mtu()` when configuring the frame length for the
CPU port.
This change prepares the driver for use on RZ/T2H and RZ/N2H SoCs.
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
drivers/net/dsa/rzn1_a5psw.c | 4 ++++
drivers/net/dsa/rzn1_a5psw.h | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/drivers/net/dsa/rzn1_a5psw.c b/drivers/net/dsa/rzn1_a5psw.c
index dc42a409eaef..82f4236a726e 100644
--- a/drivers/net/dsa/rzn1_a5psw.c
+++ b/drivers/net/dsa/rzn1_a5psw.c
@@ -211,6 +211,10 @@ static int a5psw_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
struct a5psw *a5psw = ds->priv;
new_mtu += ETH_HLEN + A5PSW_EXTRA_MTU_LEN + ETH_FCS_LEN;
+
+ if (dsa_is_cpu_port(ds, port))
+ new_mtu += a5psw->of_data->management_port_frame_len_adj;
+
a5psw_reg_writel(a5psw, A5PSW_FRM_LENGTH(port), new_mtu);
return 0;
diff --git a/drivers/net/dsa/rzn1_a5psw.h b/drivers/net/dsa/rzn1_a5psw.h
index 0fef32451e4f..41c910d534cf 100644
--- a/drivers/net/dsa/rzn1_a5psw.h
+++ b/drivers/net/dsa/rzn1_a5psw.h
@@ -235,11 +235,15 @@ union lk_data {
* @nports: Number of ports in the switch
* @cpu_port: CPU port number
* @tag_proto: DSA tag protocol used by the switch
+ * @management_port_frame_len_adj: Adjustment to apply to management
+ * port frame length to account for accepting a frame with special
+ * management tag.
*/
struct a5psw_of_data {
unsigned int nports;
unsigned int cpu_port;
enum dsa_tag_protocol tag_proto;
+ unsigned int management_port_frame_len_adj;
};
/**
--
2.52.0
On Fri, Nov 21, 2025 at 11:35:35AM +0000, Prabhakar wrote: > From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> > > Extend the RZN1 A5PSW driver to support SoC-specific adjustments to the > management (CPU) port frame length. Some SoCs, such as the RZ/T2H and > RZ/N2H, require additional headroom on the management port to account > for a special management tag added to frames. Without this adjustment, > frames may be incorrectly detected as oversized and subsequently > discarded. > > Introduce a new field, `management_port_frame_len_adj`, in > `struct a5psw_of_data` to represent this adjustment, and apply it in > `a5psw_port_change_mtu()` when configuring the frame length for the > CPU port. > > This change prepares the driver for use on RZ/T2H and RZ/N2H SoCs. In the next change you set this to 40. What's the reason behind such a high value (need to set the management port A5PSW_FRM_LENGTH value to 1574 bytes to pass L2 payload of 1500 bytes)? It sounds like this needs to be called out more clearly for what it is - a hardware bug.
Hi Vladimir, Thank you for the review. Sorry for the late reply. On Fri, Nov 21, 2025 at 9:05 PM Vladimir Oltean <olteanv@gmail.com> wrote: > > On Fri, Nov 21, 2025 at 11:35:35AM +0000, Prabhakar wrote: > > From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> > > > > Extend the RZN1 A5PSW driver to support SoC-specific adjustments to the > > management (CPU) port frame length. Some SoCs, such as the RZ/T2H and > > RZ/N2H, require additional headroom on the management port to account > > for a special management tag added to frames. Without this adjustment, > > frames may be incorrectly detected as oversized and subsequently > > discarded. > > > > Introduce a new field, `management_port_frame_len_adj`, in > > `struct a5psw_of_data` to represent this adjustment, and apply it in > > `a5psw_port_change_mtu()` when configuring the frame length for the > > CPU port. > > > > This change prepares the driver for use on RZ/T2H and RZ/N2H SoCs. > > In the next change you set this to 40. What's the reason behind such a > high value (need to set the management port A5PSW_FRM_LENGTH value to > 1574 bytes to pass L2 payload of 1500 bytes)? It sounds like this needs > to be called out more clearly for what it is - a hardware bug. > Regarding the question about the relatively large adjustment value: according to the hardware manual, “Set the FRM_LENGTH register in port 3 (CPU port) to more than or equal to the initial value. When you want to limit the frame length of the received frame, use FRM_LENGTH registers in port 0 to port 2.” In practice, with the default MTU (i.e. without applying the +40-byte adjustment), RX traffic operates correctly. For example, running iperf3 in reverse mode shows no issues, and frames are received without errors. However, in the forward direction (TX from the CPU port), throughput drops to zero and iperf3 fails. When the MTU of the CPU-facing interface is increased (e.g. ip link set lan0 mtu 1540), TX traffic immediately starts working correctly. Likewise, increasing the FRM_LENGTH on the switch side for the CPU port resolves the problem, which indicates that the frame length configuration on this port is directly involved. Given this behaviour, it appears that the management (CPU) port requires additional headroom to successfully transmit frames, even though RX succeeds without it. The STMMAC driver is used as the controller driver for the management port, we are trying to determine whether there is any known interaction, alignment constraint, or undocumented overhead that would explain the need for this extra margin. Could you please advise on how to handle this issue? Cheers, Prabhakar
On Tue, Dec 09, 2025 at 04:02:19PM +0000, Lad, Prabhakar wrote: > > In the next change you set this to 40. What's the reason behind such a > > high value (need to set the management port A5PSW_FRM_LENGTH value to > > 1574 bytes to pass L2 payload of 1500 bytes)? It sounds like this needs > > to be called out more clearly for what it is - a hardware bug. > > > Regarding the question about the relatively large adjustment value: > according to the hardware manual, > “Set the FRM_LENGTH register in port 3 (CPU port) to more than or > equal to the initial value. When you want to limit the frame length of > the received frame, use FRM_LENGTH registers in port 0 to port 2.” > > In practice, with the default MTU (i.e. without applying the +40-byte > adjustment), RX traffic operates correctly. For example, running > iperf3 in reverse mode shows no issues, and frames are received > without errors. However, in the forward direction (TX from the CPU > port), throughput drops to zero and iperf3 fails. > > When the MTU of the CPU-facing interface is increased (e.g. ip link > set lan0 mtu 1540), "lan0" isn't a typical name for a CPU-facing interface. Do you mean that the primary action is that you increase the MTU of a user port, and the FRM_LENGTH of the CPU port is implicitly readjusted by the driver as well (to 1540 + ETH_HLEN + A5PSW_EXTRA_MTU_LEN + ETH_FCS_LEN)? This isn't actually bringing new data, because unless you also increase the MTU of the other iperf3 device to 1540, the TCP MSS will still be calculated as if the MTU were 1500, and you won't be making use of larger packet sizes on the wire. On the contrary, you are introducing one extra variable into the equation: with this test you are also increasing the stmmac MTU, which you later clarify that by itself it doesn't change the outcome. > TX traffic immediately starts working correctly. > Likewise, increasing the FRM_LENGTH on the switch side for the CPU > port resolves the problem, which indicates that the frame length > configuration on this port is directly involved. So increasing FRM_LENGTH is the only factor that alters the outcome. > Given this behaviour, it appears that the management (CPU) port > requires additional headroom to successfully transmit frames, even > though RX succeeds without it. The STMMAC driver is used as the > controller driver for the management port, we are trying to determine > whether there is any known interaction, alignment constraint, or > undocumented overhead that would explain the need for this extra > margin. > > Could you please advise on how to handle this issue? Have you verified that the value you need to add to FRM_LENGTH is linear for MTU values above 1500? I.e. that at MTU values of 1510, 1520, 1540, 2000, ..., you always need to add 40 additional octets to FRM_LENGTH on top of the ETH_HLEN + A5PSW_EXTRA_MTU_LEN + ETH_FCS_LEN extra that the driver is already adding, and no less? One other thing to look at is to send known-size Ethernet frames using mausezahn or ping over lan0, run ethtool -S on the eth0 stmmac interface (this will also capture the switch's CPU port statistics counters) and see by how many octets does the aOctetsReceivedOK counter increment for a known size packet. Then, if you go oversize, look at the statistics counters and see which counter marks the drop. Maybe this will provide any clue. I don't have advice, but what you're saying seems highly unusual, doesn't have an explanation, and is not fully characterised.
Hi Vladimir,
On Tue, Dec 9, 2025 at 9:28 PM Vladimir Oltean <olteanv@gmail.com> wrote:
>
> On Tue, Dec 09, 2025 at 04:02:19PM +0000, Lad, Prabhakar wrote:
> > > In the next change you set this to 40. What's the reason behind such a
> > > high value (need to set the management port A5PSW_FRM_LENGTH value to
> > > 1574 bytes to pass L2 payload of 1500 bytes)? It sounds like this needs
> > > to be called out more clearly for what it is - a hardware bug.
> > >
> > Regarding the question about the relatively large adjustment value:
> > according to the hardware manual,
> > “Set the FRM_LENGTH register in port 3 (CPU port) to more than or
> > equal to the initial value. When you want to limit the frame length of
> > the received frame, use FRM_LENGTH registers in port 0 to port 2.”
> >
> > In practice, with the default MTU (i.e. without applying the +40-byte
> > adjustment), RX traffic operates correctly. For example, running
> > iperf3 in reverse mode shows no issues, and frames are received
> > without errors. However, in the forward direction (TX from the CPU
> > port), throughput drops to zero and iperf3 fails.
> >
> > When the MTU of the CPU-facing interface is increased (e.g. ip link
> > set lan0 mtu 1540),
>
> "lan0" isn't a typical name for a CPU-facing interface. Do you mean that
> the primary action is that you increase the MTU of a user port, and the
> FRM_LENGTH of the CPU port is implicitly readjusted by the driver as
> well (to 1540 + ETH_HLEN + A5PSW_EXTRA_MTU_LEN + ETH_FCS_LEN)?
>
> This isn't actually bringing new data, because unless you also increase
> the MTU of the other iperf3 device to 1540, the TCP MSS will still be
> calculated as if the MTU were 1500, and you won't be making use of
> larger packet sizes on the wire. On the contrary, you are introducing
> one extra variable into the equation: with this test you are also
> increasing the stmmac MTU, which you later clarify that by itself it
> doesn't change the outcome.
>
> > TX traffic immediately starts working correctly.
> > Likewise, increasing the FRM_LENGTH on the switch side for the CPU
> > port resolves the problem, which indicates that the frame length
> > configuration on this port is directly involved.
>
> So increasing FRM_LENGTH is the only factor that alters the outcome.
>
> > Given this behaviour, it appears that the management (CPU) port
> > requires additional headroom to successfully transmit frames, even
> > though RX succeeds without it. The STMMAC driver is used as the
> > controller driver for the management port, we are trying to determine
> > whether there is any known interaction, alignment constraint, or
> > undocumented overhead that would explain the need for this extra
> > margin.
> >
> > Could you please advise on how to handle this issue?
>
> Have you verified that the value you need to add to FRM_LENGTH is linear
> for MTU values above 1500? I.e. that at MTU values of 1510, 1520, 1540,
> 2000, ..., you always need to add 40 additional octets to FRM_LENGTH on
> top of the ETH_HLEN + A5PSW_EXTRA_MTU_LEN + ETH_FCS_LEN extra that the
> driver is already adding, and no less?
>
> One other thing to look at is to send known-size Ethernet frames using
> mausezahn or ping over lan0, run ethtool -S on the eth0 stmmac interface
> (this will also capture the switch's CPU port statistics counters) and
> see by how many octets does the aOctetsReceivedOK counter increment for
> a known size packet. Then, if you go oversize, look at the statistics
> counters and see which counter marks the drop. Maybe this will provide
> any clue.
>
So I started off with ping and that worked i.e. without +40 to
FRM_LENGTH. So when I increased the size upto <=1440 ping worked OK.
Anything after 1441 ping failed I could see
p03_etherStatsOversizePkts/p03_ifInErrors incrementing.
MTU Ifconfig
-----------------------------
ETH0 - 1508
LAN0 - 1500
LAN1 - 1500
After increasing the MTU size to 1501 of lan0 propagtes change to eth0
as seen below:
root@rzn2h-evk:~# ip link set lan0 mtu 1501
MTU Ifconfig
-----------------------------
ETH0 - 1509
LAN0 - 1501
LAN1 - 1500
$ ping -I lan0 192.168.10.30 -c5 -s 1441 # Works
$ ping -I lan0 192.168.10.30 -c5 -s 1442 # Fails and
p03_etherStatsOversizePkts/p03_ifInErrors increments.
So +40 to FRM_LENGTH just made the iperf worked earlier as the length
of iperf packets is 1514.
I'm still looking into the switch on why it could be dropping the frames.
Cheers,
Prabhakar
© 2016 - 2026 Red Hat, Inc.