]> www.infradead.org Git - users/hch/misc.git/commitdiff
net: fec: enable the Jumbo frame support for i.MX8QM
authorShenwei Wang <shenwei.wang@nxp.com>
Wed, 10 Sep 2025 18:52:11 +0000 (13:52 -0500)
committerJakub Kicinski <kuba@kernel.org>
Sun, 14 Sep 2025 21:20:01 +0000 (14:20 -0700)
Certain i.MX SoCs, such as i.MX8QM and i.MX8QXP, feature enhanced
FEC hardware that supports Ethernet Jumbo frames with packet sizes
up to 16K bytes.

When Jumbo frames are supported, the TX FIFO may not be large enough
to hold an entire frame. To handle this, the FIFO is configured to
operate in cut-through mode when the frame size exceeds
(PKT_MAXBUF_SIZE - ETH_HLEN - ETH_FCS_LEN), which allows transmission
to begin once the FIFO reaches a certain threshold.

Reviewed-by: Wei Fang <wei.fang@nxp.com>
Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
Link: https://patch.msgid.link/20250910185211.721341-7-shenwei.wang@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/freescale/fec.h
drivers/net/ethernet/freescale/fec_main.c

index 0127cfa5529f23f3f03113189d77f36126267e47..41e0d85d15dada8c753f59c9acfd929f3fd7d4be 100644 (file)
@@ -514,6 +514,9 @@ struct bufdesc_ex {
  */
 #define FEC_QUIRK_HAS_MDIO_C45         BIT(24)
 
+/* Jumbo Frame support */
+#define FEC_QUIRK_JUMBO_FRAME          BIT(25)
+
 struct bufdesc_prop {
        int qid;
        /* Address of Rx and Tx buffers */
index 0e596681842b63d1edd944308edafc863925fec4..1edcfaee6819e02d44f6eb51baaef0d43db69de6 100644 (file)
@@ -167,7 +167,8 @@ static const struct fec_devinfo fec_imx8qm_info = {
                  FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
                  FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
                  FEC_QUIRK_CLEAR_SETUP_MII | FEC_QUIRK_HAS_MULTI_QUEUES |
-                 FEC_QUIRK_DELAYED_CLKS_SUPPORT | FEC_QUIRK_HAS_MDIO_C45,
+                 FEC_QUIRK_DELAYED_CLKS_SUPPORT | FEC_QUIRK_HAS_MDIO_C45 |
+                 FEC_QUIRK_JUMBO_FRAME,
 };
 
 static const struct fec_devinfo fec_s32v234_info = {
@@ -233,6 +234,7 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
  * 2048 byte skbufs are allocated. However, alignment requirements
  * varies between FEC variants. Worst case is 64, so round down by 64.
  */
+#define MAX_JUMBO_BUF_SIZE     (round_down(16384 - FEC_DRV_RESERVE_SPACE - 64, 64))
 #define PKT_MAXBUF_SIZE                (round_down(2048 - 64, 64))
 #define PKT_MINBUF_SIZE                64
 
@@ -1281,8 +1283,18 @@ fec_restart(struct net_device *ndev)
        if (fep->quirks & FEC_QUIRK_ENET_MAC) {
                /* enable ENET endian swap */
                ecntl |= FEC_ECR_BYTESWP;
-               /* enable ENET store and forward mode */
-               writel(FEC_TXWMRK_STRFWD, fep->hwp + FEC_X_WMRK);
+
+               /* 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.
+                * 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)))
+                       writel(0xF, fep->hwp + FEC_X_WMRK);
+               else
+                       writel(FEC_TXWMRK_STRFWD, fep->hwp + FEC_X_WMRK);
        }
 
        if (fep->bufdesc_ex)
@@ -4584,7 +4596,12 @@ fec_probe(struct platform_device *pdev)
 
        fep->pagepool_order = 0;
        fep->rx_frame_size = FEC_ENET_RX_FRSIZE;
-       fep->max_buf_size = PKT_MAXBUF_SIZE;
+
+       if (fep->quirks & FEC_QUIRK_JUMBO_FRAME)
+               fep->max_buf_size = MAX_JUMBO_BUF_SIZE;
+       else
+               fep->max_buf_size = PKT_MAXBUF_SIZE;
+
        ndev->max_mtu = fep->max_buf_size - ETH_HLEN - ETH_FCS_LEN;
 
        ret = register_netdev(ndev);