kernel/lantiq: Restore kernel files for v5.15
[openwrt/staging/pepe2k.git] / target / linux / lantiq / patches-5.15 / 0706-v5.18-net-lantiq-enable-jumbo-frames-on-GSWIP.patch
diff --git a/target/linux/lantiq/patches-5.15/0706-v5.18-net-lantiq-enable-jumbo-frames-on-GSWIP.patch b/target/linux/lantiq/patches-5.15/0706-v5.18-net-lantiq-enable-jumbo-frames-on-GSWIP.patch
new file mode 100644 (file)
index 0000000..22aa2ee
--- /dev/null
@@ -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;
+@@ -846,10 +856,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);
+@@ -866,6 +872,8 @@ static int gswip_setup(struct dsa_switch
+               return err;
+       }
++      ds->mtu_enforcement_ingress = true;
++
+       gswip_port_enable(ds, cpu_port, NULL);
+       ds->configure_vlan_while_not_filtering = false;
+@@ -1456,6 +1464,39 @@ static void gswip_phylink_set_capab(unsi
+       linkmode_and(state->advertising, state->advertising, mask);
+ }
++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)
+@@ -1812,6 +1853,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,
+@@ -1836,6 +1879,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,