]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: fec: account for VLAN header in frame length calculations
authorClemens Gruber <mail@clemensgruber.at>
Wed, 21 Jan 2026 08:37:51 +0000 (09:37 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 30 Jan 2026 09:32:26 +0000 (10:32 +0100)
commit ca1bb3fedf26a08ed31974131bc0064d4fe33649 upstream.

The MAX_FL (maximum frame length) and related calculations used ETH_HLEN,
which does not account for the 4-byte VLAN tag in tagged frames. This
caused the hardware to reject valid VLAN frames as oversized, resulting
in RX errors and dropped packets.

Use VLAN_ETH_HLEN instead of ETH_HLEN in the MAX_FL register setup,
cut-through mode threshold, buffer allocation, and max_mtu calculation.

Cc: stable@kernel.org # v6.18+
Fixes: 62b5bb7be7bc ("net: fec: update MAX_FL based on the current MTU")
Fixes: d466c16026e9 ("net: fec: enable the Jumbo frame support for i.MX8QM")
Fixes: 59e9bf037d75 ("net: fec: add change_mtu to support dynamic buffer allocation")
Fixes: ec2a1681ed4f ("net: fec: use a member variable for maximum buffer size")
Signed-off-by: Clemens Gruber <mail@clemensgruber.at>
Reviewed-by: Wei Fang <wei.fang@nxp.com>
Link: https://patch.msgid.link/20260121083751.66997-1-mail@clemensgruber.at
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/freescale/fec_main.c

index e2b75d1970ae6f146cae6c7f79fc6a94ebb5dacd..f30e8fabfaded828329c513b24dd21d757f25173 100644 (file)
@@ -1151,7 +1151,7 @@ fec_restart(struct net_device *ndev)
        u32 rcntl = FEC_RCR_MII;
 
        if (OPT_ARCH_HAS_MAX_FL)
-               rcntl |= (fep->netdev->mtu + ETH_HLEN + ETH_FCS_LEN) << 16;
+               rcntl |= (fep->netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN) << 16;
 
        if (fep->bufdesc_ex)
                fec_ptp_save_state(fep);
@@ -1286,12 +1286,13 @@ fec_restart(struct net_device *ndev)
 
                /* When Jumbo Frame is enabled, the FIFO may not be large enough
                 * to hold an entire frame. In such cases, if the MTU exceeds
-                * (PKT_MAXBUF_SIZE - ETH_HLEN - ETH_FCS_LEN), configure the interface
-                * to operate in cut-through mode, triggered by the FIFO threshold.
+                * (PKT_MAXBUF_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN), configure
+                * the interface to operate in cut-through mode, triggered by
+                * the FIFO threshold.
                 * Otherwise, enable the ENET store-and-forward mode.
                 */
                if ((fep->quirks & FEC_QUIRK_JUMBO_FRAME) &&
-                   (ndev->mtu > (PKT_MAXBUF_SIZE - ETH_HLEN - ETH_FCS_LEN)))
+                   (ndev->mtu > (PKT_MAXBUF_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN)))
                        writel(0xF, fep->hwp + FEC_X_WMRK);
                else
                        writel(FEC_TXWMRK_STRFWD, fep->hwp + FEC_X_WMRK);
@@ -4052,7 +4053,7 @@ static int fec_change_mtu(struct net_device *ndev, int new_mtu)
        if (netif_running(ndev))
                return -EBUSY;
 
-       order = get_order(new_mtu + ETH_HLEN + ETH_FCS_LEN
+       order = get_order(new_mtu + VLAN_ETH_HLEN + ETH_FCS_LEN
                          + FEC_DRV_RESERVE_SPACE);
        fep->rx_frame_size = (PAGE_SIZE << order) - FEC_DRV_RESERVE_SPACE;
        fep->pagepool_order = order;
@@ -4609,7 +4610,7 @@ fec_probe(struct platform_device *pdev)
        else
                fep->max_buf_size = PKT_MAXBUF_SIZE;
 
-       ndev->max_mtu = fep->max_buf_size - ETH_HLEN - ETH_FCS_LEN;
+       ndev->max_mtu = fep->max_buf_size - VLAN_ETH_HLEN - ETH_FCS_LEN;
 
        ret = register_netdev(ndev);
        if (ret)