As explained in patch 2, the driver doesn't know how to change the MTU
on MV88E6165, MV88E6191, MV88E6220, MV88E6250 and MV88E6290, and there
is a regression where it actually reports an MTU value below the
Ethernet standard (1500).
Fixing that shows another issue where DSA is unprepared to be told that
a switch supports an MTU of only 1500, and still errors out. That is
addressed by patch 1.
Testing was not done on "real" hardware, but on a different Marvell DSA
switch, with code modified such that the driver doesn't know how to
change the MTU on that, either.
A key assumption is that these switches don't need any MTU configuration
to pass full MTU-sized, DSA-tagged packets, which seems like a
reasonable assumption to make. My 6390 and 6190 switches, with
.port_set_jumbo_size commented out, certainly don't seem to have any
problem passing MTU-sized traffic, as can be seen in this iperf3 session
captured with tcpdump on the DSA master:
$MAC > $MAC, Marvell DSA mode Forward, dev 2, port 8, untagged, VID 1000,
FPri 0, ethertype IPv4 (0x0800), length 1518:
10.0.0.69.49590 > 10.0.0.1.5201: Flags [.], seq 81088:82536,
ack 1, win 502, options [nop,nop,TS val 2221498829 ecr 3012859850],
length 1448
I don't want to go all the way and say that the adjustment made by
commit b9c587fed61c ("dsa: mv88e6xxx: Include tagger overhead when
setting MTU for DSA and CPU ports") is completely unnecessary, just that
there's an equally good chance that the switches with unknown MTU
configuration procedure "just work".
Vladimir Oltean (2):
net: dsa: don't error out when drivers return ETH_DATA_LEN in
.port_max_mtu()
net: dsa: mv88e6xxx: fix max_mtu of 1492 on 6165, 6191, 6220, 6250,
6290
drivers/net/dsa/mv88e6xxx/chip.c | 16 ++++++++++++----
net/dsa/slave.c | 9 +++++----
2 files changed, 17 insertions(+), 8 deletions(-)
--
2.34.1
There are 3 classes of switch families that the driver is aware of, as
far as mv88e6xxx_change_mtu() is concerned:
- MTU configuration is available per port. Here, the
chip->info->ops->port_set_jumbo_size() method will be present.
- MTU configuration is global to the switch. Here, the
chip->info->ops->set_max_frame_size() method will be present.
- We don't know how to change the MTU. Here, none of the above methods
will be present.
Switch families MV88E6165, MV88E6191, MV88E6220, MV88E6250 and MV88E6290
fall in category 3.
The blamed commit has adjusted the MTU for all 3 categories by EDSA_HLEN
(8 bytes), resulting in a new maximum MTU of 1492 being reported by the
driver for these switches.
I don't have the hardware to test, but I do have a MV88E6390 switch on
which I can simulate this by commenting out its .port_set_jumbo_size
definition from mv88e6390_ops. The result is this set of messages at
probe time:
mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 1
mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 2
mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 3
mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 4
mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 5
mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 6
mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 7
mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 8
It is highly implausible that there exist Ethernet switches which don't
support the standard MTU of 1500 octets, and this is what the DSA
framework says as well - the error comes from dsa_slave_create() ->
dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN).
But the error messages are alarming, and it would be good to suppress
them.
As a consequence of this unlikeliness, we reimplement mv88e6xxx_get_max_mtu()
and mv88e6xxx_change_mtu() on switches from the 3rd category as follows:
the maximum supported MTU is 1500, and any request to set the MTU to a
value larger than that fails in dev_validate_mtu().
Fixes: b9c587fed61c ("dsa: mv88e6xxx: Include tagger overhead when setting MTU for DSA and CPU ports")
Signed-off-by: Vladimir Oltean <[email protected]>
---
drivers/net/dsa/mv88e6xxx/chip.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 0a5d6c7bb128..30383c4f8fd0 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3549,7 +3549,7 @@ static int mv88e6xxx_get_max_mtu(struct dsa_switch *ds, int port)
return 10240 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
else if (chip->info->ops->set_max_frame_size)
return 1632 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
- return 1522 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
+ return ETH_DATA_LEN;
}
static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
@@ -3557,6 +3557,17 @@ static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
struct mv88e6xxx_chip *chip = ds->priv;
int ret = 0;
+ /* For families where we don't know how to alter the MTU,
+ * just accept any value up to ETH_DATA_LEN
+ */
+ if (!chip->info->ops->port_set_jumbo_size &&
+ !chip->info->ops->set_max_frame_size) {
+ if (new_mtu > ETH_DATA_LEN)
+ return -EINVAL;
+
+ return 0;
+ }
+
if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
new_mtu += EDSA_HLEN;
@@ -3565,9 +3576,6 @@ static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu);
else if (chip->info->ops->set_max_frame_size)
ret = chip->info->ops->set_max_frame_size(chip, new_mtu);
- else
- if (new_mtu > 1522)
- ret = -EINVAL;
mv88e6xxx_reg_unlock(chip);
return ret;
--
2.34.1
Currently, when dsa_slave_change_mtu() is called on a user port where
dev->max_mtu is 1500 (as returned by ds->ops->port_max_mtu()), the code
will stumble upon this check:
if (new_master_mtu > mtu_limit)
return -ERANGE;
because new_master_mtu is adjusted for the tagger overhead but mtu_limit
is not.
But it would be good if the logic went through, for example if the DSA
master really depends on an MTU adjustment to accept DSA-tagged frames.
To make the code pass through the check, we need to adjust mtu_limit for
the overhead as well, if the minimum restriction was caused by the DSA
user port's MTU (dev->max_mtu). A DSA user port MTU and a DSA master MTU
are always offset by the protocol overhead.
Currently no drivers return 1500 .port_max_mtu(), but this is only
temporary and a bug in itself - mv88e6xxx should have done that, but
since commit b9c587fed61c ("dsa: mv88e6xxx: Include tagger overhead when
setting MTU for DSA and CPU ports") it no longer does. This is a
preparation for fixing that.
Fixes: bfcb813203e6 ("net: dsa: configure the MTU for switch ports")
Signed-off-by: Vladimir Oltean <[email protected]>
---
net/dsa/slave.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 6957971c2db2..cac17183589f 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1933,6 +1933,7 @@ int dsa_slave_change_mtu(struct net_device *dev, int new_mtu)
int new_master_mtu;
int old_master_mtu;
int mtu_limit;
+ int overhead;
int cpu_mtu;
int err;
@@ -1961,9 +1962,10 @@ int dsa_slave_change_mtu(struct net_device *dev, int new_mtu)
largest_mtu = slave_mtu;
}
- mtu_limit = min_t(int, master->max_mtu, dev->max_mtu);
+ overhead = dsa_tag_protocol_overhead(cpu_dp->tag_ops);
+ mtu_limit = min_t(int, master->max_mtu, dev->max_mtu + overhead);
old_master_mtu = master->mtu;
- new_master_mtu = largest_mtu + dsa_tag_protocol_overhead(cpu_dp->tag_ops);
+ new_master_mtu = largest_mtu + overhead;
if (new_master_mtu > mtu_limit)
return -ERANGE;
@@ -1998,8 +2000,7 @@ int dsa_slave_change_mtu(struct net_device *dev, int new_mtu)
out_port_failed:
if (new_master_mtu != old_master_mtu)
- dsa_port_mtu_change(cpu_dp, old_master_mtu -
- dsa_tag_protocol_overhead(cpu_dp->tag_ops));
+ dsa_port_mtu_change(cpu_dp, old_master_mtu - overhead);
out_cpu_failed:
if (new_master_mtu != old_master_mtu)
dev_set_mtu(master, old_master_mtu);
--
2.34.1
On Tue, Mar 14, 2023 at 08:24:04PM +0200, Vladimir Oltean wrote:
> Currently, when dsa_slave_change_mtu() is called on a user port where
> dev->max_mtu is 1500 (as returned by ds->ops->port_max_mtu()), the code
> will stumble upon this check:
>
> if (new_master_mtu > mtu_limit)
> return -ERANGE;
>
> because new_master_mtu is adjusted for the tagger overhead but mtu_limit
> is not.
>
> But it would be good if the logic went through, for example if the DSA
> master really depends on an MTU adjustment to accept DSA-tagged frames.
>
> To make the code pass through the check, we need to adjust mtu_limit for
> the overhead as well, if the minimum restriction was caused by the DSA
> user port's MTU (dev->max_mtu). A DSA user port MTU and a DSA master MTU
> are always offset by the protocol overhead.
>
> Currently no drivers return 1500 .port_max_mtu(), but this is only
> temporary and a bug in itself - mv88e6xxx should have done that, but
> since commit b9c587fed61c ("dsa: mv88e6xxx: Include tagger overhead when
> setting MTU for DSA and CPU ports") it no longer does. This is a
> preparation for fixing that.
>
> Fixes: bfcb813203e6 ("net: dsa: configure the MTU for switch ports")
> Signed-off-by: Vladimir Oltean <[email protected]>
Reviewed-by: Simon Horman <[email protected]>
On Tue, Mar 14, 2023 at 08:24:05PM +0200, Vladimir Oltean wrote:
> There are 3 classes of switch families that the driver is aware of, as
> far as mv88e6xxx_change_mtu() is concerned:
>
> - MTU configuration is available per port. Here, the
> chip->info->ops->port_set_jumbo_size() method will be present.
>
> - MTU configuration is global to the switch. Here, the
> chip->info->ops->set_max_frame_size() method will be present.
>
> - We don't know how to change the MTU. Here, none of the above methods
> will be present.
>
> Switch families MV88E6165, MV88E6191, MV88E6220, MV88E6250 and MV88E6290
> fall in category 3.
>
> The blamed commit has adjusted the MTU for all 3 categories by EDSA_HLEN
> (8 bytes), resulting in a new maximum MTU of 1492 being reported by the
> driver for these switches.
>
> I don't have the hardware to test, but I do have a MV88E6390 switch on
> which I can simulate this by commenting out its .port_set_jumbo_size
> definition from mv88e6390_ops. The result is this set of messages at
> probe time:
>
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 1
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 2
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 3
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 4
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 5
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 6
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 7
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 8
>
> It is highly implausible that there exist Ethernet switches which don't
> support the standard MTU of 1500 octets, and this is what the DSA
> framework says as well - the error comes from dsa_slave_create() ->
> dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN).
>
> But the error messages are alarming, and it would be good to suppress
> them.
>
> As a consequence of this unlikeliness, we reimplement mv88e6xxx_get_max_mtu()
> and mv88e6xxx_change_mtu() on switches from the 3rd category as follows:
> the maximum supported MTU is 1500, and any request to set the MTU to a
> value larger than that fails in dev_validate_mtu().
>
> Fixes: b9c587fed61c ("dsa: mv88e6xxx: Include tagger overhead when setting MTU for DSA and CPU ports")
> Signed-off-by: Vladimir Oltean <[email protected]>
Reviewed-by: Simon Horman <[email protected]>
On 3/14/23 11:24, Vladimir Oltean wrote:
> Currently, when dsa_slave_change_mtu() is called on a user port where
> dev->max_mtu is 1500 (as returned by ds->ops->port_max_mtu()), the code
> will stumble upon this check:
>
> if (new_master_mtu > mtu_limit)
> return -ERANGE;
>
> because new_master_mtu is adjusted for the tagger overhead but mtu_limit
> is not.
>
> But it would be good if the logic went through, for example if the DSA
> master really depends on an MTU adjustment to accept DSA-tagged frames.
>
> To make the code pass through the check, we need to adjust mtu_limit for
> the overhead as well, if the minimum restriction was caused by the DSA
> user port's MTU (dev->max_mtu). A DSA user port MTU and a DSA master MTU
> are always offset by the protocol overhead.
>
> Currently no drivers return 1500 .port_max_mtu(), but this is only
> temporary and a bug in itself - mv88e6xxx should have done that, but
> since commit b9c587fed61c ("dsa: mv88e6xxx: Include tagger overhead when
> setting MTU for DSA and CPU ports") it no longer does. This is a
> preparation for fixing that.
>
> Fixes: bfcb813203e6 ("net: dsa: configure the MTU for switch ports")
> Signed-off-by: Vladimir Oltean <[email protected]>
Reviewed-by: Florian Fainelli <[email protected]>
--
Florian
On 3/14/23 11:24, Vladimir Oltean wrote:
> There are 3 classes of switch families that the driver is aware of, as
> far as mv88e6xxx_change_mtu() is concerned:
>
> - MTU configuration is available per port. Here, the
> chip->info->ops->port_set_jumbo_size() method will be present.
>
> - MTU configuration is global to the switch. Here, the
> chip->info->ops->set_max_frame_size() method will be present.
>
> - We don't know how to change the MTU. Here, none of the above methods
> will be present.
>
> Switch families MV88E6165, MV88E6191, MV88E6220, MV88E6250 and MV88E6290
> fall in category 3.
>
> The blamed commit has adjusted the MTU for all 3 categories by EDSA_HLEN
> (8 bytes), resulting in a new maximum MTU of 1492 being reported by the
> driver for these switches.
>
> I don't have the hardware to test, but I do have a MV88E6390 switch on
> which I can simulate this by commenting out its .port_set_jumbo_size
> definition from mv88e6390_ops. The result is this set of messages at
> probe time:
>
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 1
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 2
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 3
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 4
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 5
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 6
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 7
> mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 8
>
> It is highly implausible that there exist Ethernet switches which don't
> support the standard MTU of 1500 octets, and this is what the DSA
> framework says as well - the error comes from dsa_slave_create() ->
> dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN).
>
> But the error messages are alarming, and it would be good to suppress
> them.
>
> As a consequence of this unlikeliness, we reimplement mv88e6xxx_get_max_mtu()
> and mv88e6xxx_change_mtu() on switches from the 3rd category as follows:
> the maximum supported MTU is 1500, and any request to set the MTU to a
> value larger than that fails in dev_validate_mtu().
>
> Fixes: b9c587fed61c ("dsa: mv88e6xxx: Include tagger overhead when setting MTU for DSA and CPU ports")
> Signed-off-by: Vladimir Oltean <[email protected]>
Reviewed-by: Florian Fainelli <[email protected]>
--
Florian
Hello:
This series was applied to netdev/net.git (main)
by David S. Miller <[email protected]>:
On Tue, 14 Mar 2023 20:24:03 +0200 you wrote:
> As explained in patch 2, the driver doesn't know how to change the MTU
> on MV88E6165, MV88E6191, MV88E6220, MV88E6250 and MV88E6290, and there
> is a regression where it actually reports an MTU value below the
> Ethernet standard (1500).
>
> Fixing that shows another issue where DSA is unprepared to be told that
> a switch supports an MTU of only 1500, and still errors out. That is
> addressed by patch 1.
>
> [...]
Here is the summary with links:
- [net,1/2] net: dsa: don't error out when drivers return ETH_DATA_LEN in .port_max_mtu()
https://git.kernel.org/netdev/net/c/636e8adf7878
- [net,2/2] net: dsa: mv88e6xxx: fix max_mtu of 1492 on 6165, 6191, 6220, 6250, 6290
https://git.kernel.org/netdev/net/c/7e9517375a14
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html