diff options
Diffstat (limited to 'target/linux/lantiq/patches-5.15/0706-v5.18-net-lantiq-enable-jumbo-frames-on-GSWIP.patch')
-rw-r--r-- | target/linux/lantiq/patches-5.15/0706-v5.18-net-lantiq-enable-jumbo-frames-on-GSWIP.patch | 127 |
1 files changed, 127 insertions, 0 deletions
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 index 0000000000..49a19bebee --- /dev/null +++ b/target/linux/lantiq/patches-5.15/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) +@@ -1829,6 +1870,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, +@@ -1853,6 +1896,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, |