aboutsummaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/linux/lantiq/patches-5.10/0703-net-lantiq-enable-jumbo-frames-on-GSWIP.patch101
-rw-r--r--target/linux/lantiq/patches-5.10/0703-v5.16-net-lantiq_xrx200-increase-buffer-reservation.patch (renamed from target/linux/lantiq/patches-5.10/0704-v5.16-net-lantiq_xrx200-increase-buffer-reservation.patch)0
-rw-r--r--target/linux/lantiq/patches-5.10/0704-v5.17-net-lantiq_xrx200-add-ingress-SG-DMA-support.patch (renamed from target/linux/lantiq/patches-5.10/0705-v5.17-net-lantiq_xrx200-add-ingress-SG-DMA-support.patch)0
-rw-r--r--target/linux/lantiq/patches-5.10/0705-v5.13-net-dsa-lantiq-allow-to-use-all-GPHYs-on-xRX300-and-.patch275
-rw-r--r--target/linux/lantiq/patches-5.10/0706-v5.18-net-lantiq-enable-jumbo-frames-on-GSWIP.patch127
5 files changed, 402 insertions, 101 deletions
diff --git a/target/linux/lantiq/patches-5.10/0703-net-lantiq-enable-jumbo-frames-on-GSWIP.patch b/target/linux/lantiq/patches-5.10/0703-net-lantiq-enable-jumbo-frames-on-GSWIP.patch
deleted file mode 100644
index 6593e43db7..0000000000
--- a/target/linux/lantiq/patches-5.10/0703-net-lantiq-enable-jumbo-frames-on-GSWIP.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From 24a43ae2ac0ea06c474b1c80dc75651294d49321 Mon Sep 17 00:00:00 2001
-From: Thomas Nixon <tom@tomn.co.uk>
-Date: Sat, 2 Oct 2021 00:48:05 +0100
-Subject: [PATCH 2/2] net: lantiq: enable jumbo frames on GSWIP
-
-This enables non-standard MTUs on a per-port basis, with the overall
-frame size set based on the CPU port.
-
-When the MTU is not changed, this should have no effect.
-
-Long packets crash the switch with MTUs of greater than 2526, so the
-maximum is limited for now.
-
-Signed-off-by: Thomas Nixon <tom@tomn.co.uk>
----
- drivers/net/dsa/lantiq_gswip.c | 46 +++++++++++++++++++++++++++++++---
- 1 file changed, 42 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -238,6 +238,11 @@
-
- #define XRX200_GPHY_FW_ALIGN (16 * 1024)
-
-+/* maximum packet size supported by the switch; in theory this should be 9600,
-+ * but long packets currently cause lock-ups with an MTU of over 2526
-+ */
-+#define GSWIP_MAX_PACKET_LENGTH 2556
-+
- struct gswip_hw_info {
- int max_ports;
- int cpu_port;
-@@ -856,10 +861,6 @@ static int gswip_setup(struct dsa_switch
- gswip_switch_mask(priv, 0, GSWIP_PCE_PCTRL_0_INGRESS,
- GSWIP_PCE_PCTRL_0p(cpu_port));
-
-- gswip_switch_mask(priv, 0, GSWIP_MAC_CTRL_2_MLEN,
-- GSWIP_MAC_CTRL_2p(cpu_port));
-- gswip_switch_w(priv, VLAN_ETH_FRAME_LEN + 8 + ETH_FCS_LEN,
-- GSWIP_MAC_FLEN);
- gswip_switch_mask(priv, 0, GSWIP_BM_QUEUE_GCTRL_GL_MOD,
- GSWIP_BM_QUEUE_GCTRL);
-
-@@ -876,6 +877,8 @@ static int gswip_setup(struct dsa_switch
- return err;
- }
-
-+ ds->mtu_enforcement_ingress = true;
-+
- gswip_port_enable(ds, cpu_port, NULL);
- return 0;
- }
-@@ -1438,6 +1441,39 @@ static int gswip_port_fdb_dump(struct ds
- return 0;
- }
-
-+static int gswip_port_max_mtu(struct dsa_switch *ds, int port)
-+{
-+ /* includes 8 bytes for special header */
-+ return GSWIP_MAX_PACKET_LENGTH - VLAN_ETH_HLEN - ETH_FCS_LEN;
-+}
-+
-+static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
-+{
-+ struct gswip_priv *priv = ds->priv;
-+ int cpu_port = priv->hw_info->cpu_port;
-+
-+ /* cpu port always has maximum mtu of user ports, so use it to set
-+ * switch frame size, including 8 byte special header
-+ */
-+ if (port == cpu_port) {
-+ new_mtu += 8;
-+ gswip_switch_w(priv, VLAN_ETH_HLEN + new_mtu + ETH_FCS_LEN,
-+ GSWIP_MAC_FLEN);
-+ }
-+
-+ /* enable MLEN for ports with non-standard MTUs, including the special
-+ * header on the CPU port added above
-+ */
-+ if (new_mtu != ETH_DATA_LEN)
-+ gswip_switch_mask(priv, 0, GSWIP_MAC_CTRL_2_MLEN,
-+ GSWIP_MAC_CTRL_2p(port));
-+ else
-+ gswip_switch_mask(priv, GSWIP_MAC_CTRL_2_MLEN, 0,
-+ GSWIP_MAC_CTRL_2p(port));
-+
-+ return 0;
-+}
-+
- static void gswip_phylink_validate(struct dsa_switch *ds, int port,
- unsigned long *supported,
- struct phylink_link_state *state)
-@@ -1781,6 +1817,8 @@ static const struct dsa_switch_ops gswip
- .port_fdb_add = gswip_port_fdb_add,
- .port_fdb_del = gswip_port_fdb_del,
- .port_fdb_dump = gswip_port_fdb_dump,
-+ .port_change_mtu = gswip_port_change_mtu,
-+ .port_max_mtu = gswip_port_max_mtu,
- .phylink_validate = gswip_phylink_validate,
- .phylink_mac_config = gswip_phylink_mac_config,
- .phylink_mac_link_down = gswip_phylink_mac_link_down,
diff --git a/target/linux/lantiq/patches-5.10/0704-v5.16-net-lantiq_xrx200-increase-buffer-reservation.patch b/target/linux/lantiq/patches-5.10/0703-v5.16-net-lantiq_xrx200-increase-buffer-reservation.patch
index 77c0eb6354..77c0eb6354 100644
--- a/target/linux/lantiq/patches-5.10/0704-v5.16-net-lantiq_xrx200-increase-buffer-reservation.patch
+++ b/target/linux/lantiq/patches-5.10/0703-v5.16-net-lantiq_xrx200-increase-buffer-reservation.patch
diff --git a/target/linux/lantiq/patches-5.10/0705-v5.17-net-lantiq_xrx200-add-ingress-SG-DMA-support.patch b/target/linux/lantiq/patches-5.10/0704-v5.17-net-lantiq_xrx200-add-ingress-SG-DMA-support.patch
index f2c36952fc..f2c36952fc 100644
--- a/target/linux/lantiq/patches-5.10/0705-v5.17-net-lantiq_xrx200-add-ingress-SG-DMA-support.patch
+++ b/target/linux/lantiq/patches-5.10/0704-v5.17-net-lantiq_xrx200-add-ingress-SG-DMA-support.patch
diff --git a/target/linux/lantiq/patches-5.10/0705-v5.13-net-dsa-lantiq-allow-to-use-all-GPHYs-on-xRX300-and-.patch b/target/linux/lantiq/patches-5.10/0705-v5.13-net-dsa-lantiq-allow-to-use-all-GPHYs-on-xRX300-and-.patch
new file mode 100644
index 0000000000..c0911ef874
--- /dev/null
+++ b/target/linux/lantiq/patches-5.10/0705-v5.13-net-dsa-lantiq-allow-to-use-all-GPHYs-on-xRX300-and-.patch
@@ -0,0 +1,275 @@
+From a09d042b086202735c4ed64573cdd79933020001 Mon Sep 17 00:00:00 2001
+From: Aleksander Jan Bajkowski <olek2@wp.pl>
+Date: Mon, 22 Mar 2021 21:37:15 +0100
+Subject: [PATCH] net: dsa: lantiq: allow to use all GPHYs on xRX300 and xRX330
+
+This patch allows to use all PHYs on GRX300 and GRX330. The ARX300
+has 3 and the GRX330 has 4 integrated PHYs connected to different
+ports compared to VRX200. Each integrated PHY can work as single
+Gigabit Ethernet PHY (GMII) or as double Fast Ethernet PHY (MII).
+
+Allowed port configurations:
+
+xRX200:
+GMAC0: RGMII, MII, REVMII or RMII port
+GMAC1: RGMII, MII, REVMII or RMII port
+GMAC2: GPHY0 (GMII)
+GMAC3: GPHY0 (MII)
+GMAC4: GPHY1 (GMII)
+GMAC5: GPHY1 (MII) or RGMII port
+
+xRX300:
+GMAC0: RGMII port
+GMAC1: GPHY2 (GMII)
+GMAC2: GPHY0 (GMII)
+GMAC3: GPHY0 (MII)
+GMAC4: GPHY1 (GMII)
+GMAC5: GPHY1 (MII) or RGMII port
+
+xRX330:
+GMAC0: RGMII, GMII or RMII port
+GMAC1: GPHY2 (GMII)
+GMAC2: GPHY0 (GMII)
+GMAC3: GPHY0 (MII) or GPHY3 (GMII)
+GMAC4: GPHY1 (GMII)
+GMAC5: GPHY1 (MII), RGMII or RMII port
+
+Tested on D-Link DWR966 (xRX330) with OpenWRT.
+
+Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/lantiq_gswip.c | 142 ++++++++++++++++++++++++++-------
+ 1 file changed, 113 insertions(+), 29 deletions(-)
+
+--- a/drivers/net/dsa/lantiq_gswip.c
++++ b/drivers/net/dsa/lantiq_gswip.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0
+ /*
+- * Lantiq / Intel GSWIP switch driver for VRX200 SoCs
++ * Lantiq / Intel GSWIP switch driver for VRX200, xRX300 and xRX330 SoCs
+ *
+ * Copyright (C) 2010 Lantiq Deutschland
+ * Copyright (C) 2012 John Crispin <john@phrozen.org>
+@@ -104,6 +104,7 @@
+ #define GSWIP_MII_CFG_MODE_RMIIP 0x2
+ #define GSWIP_MII_CFG_MODE_RMIIM 0x3
+ #define GSWIP_MII_CFG_MODE_RGMII 0x4
++#define GSWIP_MII_CFG_MODE_GMII 0x9
+ #define GSWIP_MII_CFG_MODE_MASK 0xf
+ #define GSWIP_MII_CFG_RATE_M2P5 0x00
+ #define GSWIP_MII_CFG_RATE_M25 0x10
+@@ -241,6 +242,7 @@
+ struct gswip_hw_info {
+ int max_ports;
+ int cpu_port;
++ const struct dsa_switch_ops *ops;
+ };
+
+ struct xway_gphy_match_data {
+@@ -1438,12 +1440,42 @@ static int gswip_port_fdb_dump(struct ds
+ return 0;
+ }
+
+-static void gswip_phylink_validate(struct dsa_switch *ds, int port,
+- unsigned long *supported,
+- struct phylink_link_state *state)
++static void gswip_phylink_set_capab(unsigned long *supported,
++ struct phylink_link_state *state)
+ {
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+
++ /* Allow all the expected bits */
++ phylink_set(mask, Autoneg);
++ phylink_set_port_modes(mask);
++ phylink_set(mask, Pause);
++ phylink_set(mask, Asym_Pause);
++
++ /* With the exclusion of MII, Reverse MII and Reduced MII, we
++ * support Gigabit, including Half duplex
++ */
++ if (state->interface != PHY_INTERFACE_MODE_MII &&
++ state->interface != PHY_INTERFACE_MODE_REVMII &&
++ state->interface != PHY_INTERFACE_MODE_RMII) {
++ phylink_set(mask, 1000baseT_Full);
++ phylink_set(mask, 1000baseT_Half);
++ }
++
++ phylink_set(mask, 10baseT_Half);
++ phylink_set(mask, 10baseT_Full);
++ phylink_set(mask, 100baseT_Half);
++ phylink_set(mask, 100baseT_Full);
++
++ bitmap_and(supported, supported, mask,
++ __ETHTOOL_LINK_MODE_MASK_NBITS);
++ bitmap_and(state->advertising, state->advertising, mask,
++ __ETHTOOL_LINK_MODE_MASK_NBITS);
++}
++
++static void gswip_xrx200_phylink_validate(struct dsa_switch *ds, int port,
++ unsigned long *supported,
++ struct phylink_link_state *state)
++{
+ switch (port) {
+ case 0:
+ case 1:
+@@ -1470,38 +1502,54 @@ static void gswip_phylink_validate(struc
+ return;
+ }
+
+- /* Allow all the expected bits */
+- phylink_set(mask, Autoneg);
+- phylink_set_port_modes(mask);
+- phylink_set(mask, Pause);
+- phylink_set(mask, Asym_Pause);
++ gswip_phylink_set_capab(supported, state);
+
+- /* With the exclusion of MII, Reverse MII and Reduced MII, we
+- * support Gigabit, including Half duplex
+- */
+- if (state->interface != PHY_INTERFACE_MODE_MII &&
+- state->interface != PHY_INTERFACE_MODE_REVMII &&
+- state->interface != PHY_INTERFACE_MODE_RMII) {
+- phylink_set(mask, 1000baseT_Full);
+- phylink_set(mask, 1000baseT_Half);
++ return;
++
++unsupported:
++ bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
++ dev_err(ds->dev, "Unsupported interface '%s' for port %d\n",
++ phy_modes(state->interface), port);
++}
++
++static void gswip_xrx300_phylink_validate(struct dsa_switch *ds, int port,
++ unsigned long *supported,
++ struct phylink_link_state *state)
++{
++ switch (port) {
++ case 0:
++ if (!phy_interface_mode_is_rgmii(state->interface) &&
++ state->interface != PHY_INTERFACE_MODE_GMII &&
++ state->interface != PHY_INTERFACE_MODE_RMII)
++ goto unsupported;
++ break;
++ case 1:
++ case 2:
++ case 3:
++ case 4:
++ if (state->interface != PHY_INTERFACE_MODE_INTERNAL)
++ goto unsupported;
++ break;
++ case 5:
++ if (!phy_interface_mode_is_rgmii(state->interface) &&
++ state->interface != PHY_INTERFACE_MODE_INTERNAL &&
++ state->interface != PHY_INTERFACE_MODE_RMII)
++ goto unsupported;
++ break;
++ default:
++ bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
++ dev_err(ds->dev, "Unsupported port: %i\n", port);
++ return;
+ }
+
+- phylink_set(mask, 10baseT_Half);
+- phylink_set(mask, 10baseT_Full);
+- phylink_set(mask, 100baseT_Half);
+- phylink_set(mask, 100baseT_Full);
++ gswip_phylink_set_capab(supported, state);
+
+- bitmap_and(supported, supported, mask,
+- __ETHTOOL_LINK_MODE_MASK_NBITS);
+- bitmap_and(state->advertising, state->advertising, mask,
+- __ETHTOOL_LINK_MODE_MASK_NBITS);
+ return;
+
+ unsupported:
+ bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
+ dev_err(ds->dev, "Unsupported interface '%s' for port %d\n",
+ phy_modes(state->interface), port);
+- return;
+ }
+
+ static void gswip_port_set_link(struct gswip_priv *priv, int port, bool link)
+@@ -1639,6 +1687,9 @@ static void gswip_phylink_mac_config(str
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ miicfg |= GSWIP_MII_CFG_MODE_RGMII;
+ break;
++ case PHY_INTERFACE_MODE_GMII:
++ miicfg |= GSWIP_MII_CFG_MODE_GMII;
++ break;
+ default:
+ dev_err(ds->dev,
+ "Unsupported interface: %d\n", state->interface);
+@@ -1765,7 +1816,7 @@ static int gswip_get_sset_count(struct d
+ return ARRAY_SIZE(gswip_rmon_cnt);
+ }
+
+-static const struct dsa_switch_ops gswip_switch_ops = {
++static const struct dsa_switch_ops gswip_xrx200_switch_ops = {
+ .get_tag_protocol = gswip_get_tag_protocol,
+ .setup = gswip_setup,
+ .port_enable = gswip_port_enable,
+@@ -1781,7 +1832,31 @@ static const struct dsa_switch_ops gswip
+ .port_fdb_add = gswip_port_fdb_add,
+ .port_fdb_del = gswip_port_fdb_del,
+ .port_fdb_dump = gswip_port_fdb_dump,
+- .phylink_validate = gswip_phylink_validate,
++ .phylink_validate = gswip_xrx200_phylink_validate,
++ .phylink_mac_config = gswip_phylink_mac_config,
++ .phylink_mac_link_down = gswip_phylink_mac_link_down,
++ .phylink_mac_link_up = gswip_phylink_mac_link_up,
++ .get_strings = gswip_get_strings,
++ .get_ethtool_stats = gswip_get_ethtool_stats,
++ .get_sset_count = gswip_get_sset_count,
++};
++
++static const struct dsa_switch_ops gswip_xrx300_switch_ops = {
++ .get_tag_protocol = gswip_get_tag_protocol,
++ .setup = gswip_setup,
++ .port_enable = gswip_port_enable,
++ .port_disable = gswip_port_disable,
++ .port_bridge_join = gswip_port_bridge_join,
++ .port_bridge_leave = gswip_port_bridge_leave,
++ .port_fast_age = gswip_port_fast_age,
++ .port_vlan_filtering = gswip_port_vlan_filtering,
++ .port_vlan_add = gswip_port_vlan_add,
++ .port_vlan_del = gswip_port_vlan_del,
++ .port_stp_state_set = gswip_port_stp_state_set,
++ .port_fdb_add = gswip_port_fdb_add,
++ .port_fdb_del = gswip_port_fdb_del,
++ .port_fdb_dump = gswip_port_fdb_dump,
++ .phylink_validate = gswip_xrx300_phylink_validate,
+ .phylink_mac_config = gswip_phylink_mac_config,
+ .phylink_mac_link_down = gswip_phylink_mac_link_down,
+ .phylink_mac_link_up = gswip_phylink_mac_link_up,
+@@ -2043,7 +2118,7 @@ static int gswip_probe(struct platform_d
+ priv->ds->dev = dev;
+ priv->ds->num_ports = priv->hw_info->max_ports;
+ priv->ds->priv = priv;
+- priv->ds->ops = &gswip_switch_ops;
++ priv->ds->ops = priv->hw_info->ops;
+ priv->dev = dev;
+ version = gswip_switch_r(priv, GSWIP_VERSION);
+
+@@ -2127,10 +2202,19 @@ static int gswip_remove(struct platform_
+ static const struct gswip_hw_info gswip_xrx200 = {
+ .max_ports = 7,
+ .cpu_port = 6,
++ .ops = &gswip_xrx200_switch_ops,
++};
++
++static const struct gswip_hw_info gswip_xrx300 = {
++ .max_ports = 7,
++ .cpu_port = 6,
++ .ops = &gswip_xrx300_switch_ops,
+ };
+
+ static const struct of_device_id gswip_of_match[] = {
+ { .compatible = "lantiq,xrx200-gswip", .data = &gswip_xrx200 },
++ { .compatible = "lantiq,xrx300-gswip", .data = &gswip_xrx300 },
++ { .compatible = "lantiq,xrx330-gswip", .data = &gswip_xrx300 },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, gswip_of_match);
diff --git a/target/linux/lantiq/patches-5.10/0706-v5.18-net-lantiq-enable-jumbo-frames-on-GSWIP.patch b/target/linux/lantiq/patches-5.10/0706-v5.18-net-lantiq-enable-jumbo-frames-on-GSWIP.patch
new file mode 100644
index 0000000000..9d96883910
--- /dev/null
+++ b/target/linux/lantiq/patches-5.10/0706-v5.18-net-lantiq-enable-jumbo-frames-on-GSWIP.patch
@@ -0,0 +1,127 @@
+From c40bb4fedcd6b8b6a714da5dd466eb88ed2652d1 Mon Sep 17 00:00:00 2001
+From: Aleksander Jan Bajkowski <olek2@wp.pl>
+Date: Wed, 9 Mar 2022 00:04:57 +0100
+Subject: net: dsa: lantiq_gswip: enable jumbo frames on GSWIP
+
+This enables non-standard MTUs on a per-port basis, with the overall
+frame size set based on the CPU port.
+
+When the MTU is not changed, this should have no effect.
+
+Long packets crash the switch with MTUs of greater than 2526, so the
+maximum is limited for now. Medium packets are sometimes dropped (e.g.
+TCP over 2477, UDP over 2516-2519, ICMP over 2526), Hence an MTU value
+of 2400 seems safe.
+
+Signed-off-by: Thomas Nixon <tom@tomn.co.uk>
+Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
+Link: https://lore.kernel.org/r/20220308230457.1599237-1-olek2@wp.pl
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/lantiq_gswip.c | 53 ++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 49 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/lantiq_gswip.c
++++ b/drivers/net/dsa/lantiq_gswip.c
+@@ -213,6 +213,7 @@
+ #define GSWIP_MAC_CTRL_0_GMII_MII 0x0001
+ #define GSWIP_MAC_CTRL_0_GMII_RGMII 0x0002
+ #define GSWIP_MAC_CTRL_2p(p) (0x905 + ((p) * 0xC))
++#define GSWIP_MAC_CTRL_2_LCHKL BIT(2) /* Frame Length Check Long Enable */
+ #define GSWIP_MAC_CTRL_2_MLEN BIT(3) /* Maximum Untagged Frame Lnegth */
+
+ /* Ethernet Switch Fetch DMA Port Control Register */
+@@ -239,6 +240,15 @@
+
+ #define XRX200_GPHY_FW_ALIGN (16 * 1024)
+
++/* Maximum packet size supported by the switch. In theory this should be 10240,
++ * but long packets currently cause lock-ups with an MTU of over 2526. Medium
++ * packets are sometimes dropped (e.g. TCP over 2477, UDP over 2516-2519, ICMP
++ * over 2526), hence an MTU value of 2400 seems safe. This issue only affects
++ * packet reception. This is probably caused by the PPA engine, which is on the
++ * RX part of the device. Packet transmission works properly up to 10240.
++ */
++#define GSWIP_MAX_PACKET_LENGTH 2400
++
+ struct gswip_hw_info {
+ int max_ports;
+ int cpu_port;
+@@ -858,10 +868,6 @@ static int gswip_setup(struct dsa_switch
+ gswip_switch_mask(priv, 0, GSWIP_PCE_PCTRL_0_INGRESS,
+ GSWIP_PCE_PCTRL_0p(cpu_port));
+
+- gswip_switch_mask(priv, 0, GSWIP_MAC_CTRL_2_MLEN,
+- GSWIP_MAC_CTRL_2p(cpu_port));
+- gswip_switch_w(priv, VLAN_ETH_FRAME_LEN + 8 + ETH_FCS_LEN,
+- GSWIP_MAC_FLEN);
+ gswip_switch_mask(priv, 0, GSWIP_BM_QUEUE_GCTRL_GL_MOD,
+ GSWIP_BM_QUEUE_GCTRL);
+
+@@ -878,6 +884,8 @@ static int gswip_setup(struct dsa_switch
+ return err;
+ }
+
++ ds->mtu_enforcement_ingress = true;
++
+ gswip_port_enable(ds, cpu_port, NULL);
+ return 0;
+ }
+@@ -1472,6 +1480,39 @@ static void gswip_phylink_set_capab(unsi
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+ }
+
++static int gswip_port_max_mtu(struct dsa_switch *ds, int port)
++{
++ /* Includes 8 bytes for special header. */
++ return GSWIP_MAX_PACKET_LENGTH - VLAN_ETH_HLEN - ETH_FCS_LEN;
++}
++
++static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
++{
++ struct gswip_priv *priv = ds->priv;
++ int cpu_port = priv->hw_info->cpu_port;
++
++ /* CPU port always has maximum mtu of user ports, so use it to set
++ * switch frame size, including 8 byte special header.
++ */
++ if (port == cpu_port) {
++ new_mtu += 8;
++ gswip_switch_w(priv, VLAN_ETH_HLEN + new_mtu + ETH_FCS_LEN,
++ GSWIP_MAC_FLEN);
++ }
++
++ /* Enable MLEN for ports with non-standard MTUs, including the special
++ * header on the CPU port added above.
++ */
++ if (new_mtu != ETH_DATA_LEN)
++ gswip_switch_mask(priv, 0, GSWIP_MAC_CTRL_2_MLEN,
++ GSWIP_MAC_CTRL_2p(port));
++ else
++ gswip_switch_mask(priv, GSWIP_MAC_CTRL_2_MLEN, 0,
++ GSWIP_MAC_CTRL_2p(port));
++
++ return 0;
++}
++
+ static void gswip_xrx200_phylink_validate(struct dsa_switch *ds, int port,
+ unsigned long *supported,
+ struct phylink_link_state *state)
+@@ -1832,6 +1873,8 @@ static const struct dsa_switch_ops gswip
+ .port_fdb_add = gswip_port_fdb_add,
+ .port_fdb_del = gswip_port_fdb_del,
+ .port_fdb_dump = gswip_port_fdb_dump,
++ .port_change_mtu = gswip_port_change_mtu,
++ .port_max_mtu = gswip_port_max_mtu,
+ .phylink_validate = gswip_xrx200_phylink_validate,
+ .phylink_mac_config = gswip_phylink_mac_config,
+ .phylink_mac_link_down = gswip_phylink_mac_link_down,
+@@ -1856,6 +1899,8 @@ static const struct dsa_switch_ops gswip
+ .port_fdb_add = gswip_port_fdb_add,
+ .port_fdb_del = gswip_port_fdb_del,
+ .port_fdb_dump = gswip_port_fdb_dump,
++ .port_change_mtu = gswip_port_change_mtu,
++ .port_max_mtu = gswip_port_max_mtu,
+ .phylink_validate = gswip_xrx300_phylink_validate,
+ .phylink_mac_config = gswip_phylink_mac_config,
+ .phylink_mac_link_down = gswip_phylink_mac_link_down,