123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- From c40bb4fedcd6b8b6a714da5dd466eb88ed2652d1 Mon Sep 17 00:00:00 2001
- From: Aleksander Jan Bajkowski <[email protected]>
- 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 <[email protected]>
- Signed-off-by: Aleksander Jan Bajkowski <[email protected]>
- Link: https://lore.kernel.org/r/[email protected]
- Signed-off-by: Jakub Kicinski <[email protected]>
- ---
- 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,
|