1
1
openwrt/target/linux/generic/pending-6.12/760-14-net-dsa-mxl862xx-implement-port-MTU-configuration.patch
Daniel Golle 5b69e6a4a6 generic: 6.12: update MxL862xx DSA switch driver
Update driver to be ready for the upcoming firmware release.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-05-27 19:01:52 +01:00

110 lines
3.4 KiB
Diff

From d27d60f42f5188d6cfcb771d2188633f1031646f Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Wed, 1 Apr 2026 13:43:08 +0100
Subject: [PATCH 14/19] net: dsa: mxl862xx: implement port MTU configuration
The firmware exposes a global max_packet_len register via
MXL862XX_COMMON_CFGSET. Since this is switch-wide rather than
per-port, cache each port's requested MTU and program the register
with the maximum across all ports. The firmware call is skipped when
the effective maximum does not change.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/net/dsa/mxl862xx/mxl862xx.c | 50 +++++++++++++++++++++++++++++
drivers/net/dsa/mxl862xx/mxl862xx.h | 3 ++
2 files changed, 53 insertions(+)
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
@@ -12,6 +12,7 @@
#include <linux/etherdevice.h>
#include <linux/icmpv6.h>
#include <linux/if_bridge.h>
+#include <linux/if_vlan.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_mdio.h>
@@ -3743,6 +3744,53 @@ static int mxl862xx_set_ageing_time(stru
return ret;
}
+static int mxl862xx_port_change_mtu(struct dsa_switch *ds, int port,
+ int new_mtu)
+{
+ struct mxl862xx_priv *priv = ds->priv;
+ struct mxl862xx_cfg param = {};
+ int i, old_max = 0, new_max = 0;
+ int ret;
+
+ for (i = 0; i < ds->num_ports; i++) {
+ if (priv->ports[i].mtu > old_max)
+ old_max = priv->ports[i].mtu;
+ }
+
+ priv->ports[port].mtu = new_mtu;
+
+ for (i = 0; i < ds->num_ports; i++) {
+ if (priv->ports[i].mtu > new_max)
+ new_max = priv->ports[i].mtu;
+ }
+
+ if (new_max != old_max) {
+ ret = MXL862XX_API_READ(priv, MXL862XX_COMMON_CFGGET,
+ param);
+ if (ret)
+ return ret;
+
+ param.max_packet_len = cpu_to_le16(new_max +
+ VLAN_ETH_HLEN +
+ ETH_FCS_LEN);
+ ret = MXL862XX_API_WRITE(priv, MXL862XX_COMMON_CFGSET,
+ param);
+ if (ret) {
+ dev_err(ds->dev,
+ "failed to set MTU to %d: %pe\n",
+ new_mtu, ERR_PTR(ret));
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int mxl862xx_port_max_mtu(struct dsa_switch *ds, int port)
+{
+ return U16_MAX - VLAN_ETH_HLEN - ETH_FCS_LEN;
+}
+
static void mxl862xx_port_stp_state_set(struct dsa_switch *ds, int port,
u8 state)
{
@@ -4218,6 +4266,8 @@ static const struct dsa_switch_ops mxl86
.port_disable = mxl862xx_port_disable,
.port_fast_age = mxl862xx_port_fast_age,
.set_ageing_time = mxl862xx_set_ageing_time,
+ .port_change_mtu = mxl862xx_port_change_mtu,
+ .port_max_mtu = mxl862xx_port_max_mtu,
.port_bridge_join = mxl862xx_port_bridge_join,
.port_bridge_leave = mxl862xx_port_bridge_leave,
.port_pre_bridge_flags = mxl862xx_port_pre_bridge_flags,
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
@@ -251,6 +251,8 @@ struct mxl862xx_port_stats {
* @lag_hash_bits: hash field bitmask (MXL862XX_TRUNK_HASH_*) requested
* when this port joined its LAG; used to recompute the
* global trunk_hash when a LAG is destroyed
+ * @mtu: per-port requested MTU; the global switch register
+ * is set to the maximum across all ports
*/
struct mxl862xx_port {
struct mxl862xx_priv *priv;
@@ -275,6 +277,7 @@ struct mxl862xx_port {
struct dsa_lag *lag;
bool lag_tx_enabled;
u8 lag_hash_bits;
+ int mtu;
struct mxl862xx_port_stats stats;
spinlock_t stats_lock; /* protects stats accumulators */
};