]> git.dujemihanovic.xyz Git - linux.git/commitdiff
net: wan: fsl_qmc_hdlc: Discard received CRC
authorHerve Codina <herve.codina@bootlin.com>
Tue, 30 Jul 2024 06:31:33 +0000 (08:31 +0200)
committerJakub Kicinski <kuba@kernel.org>
Thu, 1 Aug 2024 01:09:08 +0000 (18:09 -0700)
Received frame from QMC contains the CRC.
Upper layers don't need this CRC and tcpdump mentioned trailing junk
data due to this CRC presence.

As some other HDLC driver, simply discard this CRC.

Fixes: d0f2258e79fd ("net: wan: Add support for QMC HDLC")
Cc: stable@vger.kernel.org
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20240730063133.179598-1-herve.codina@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/wan/fsl_qmc_hdlc.c

index 64b4bfa6fea75b7f4f21cf2c19e9701771c6da50..8fcfbde31a1c66db1e036cee5151a9b8e58f3c91 100644 (file)
@@ -250,6 +250,7 @@ static void qmc_hcld_recv_complete(void *context, size_t length, unsigned int fl
        struct qmc_hdlc_desc *desc = context;
        struct net_device *netdev;
        struct qmc_hdlc *qmc_hdlc;
+       size_t crc_size;
        int ret;
 
        netdev = desc->netdev;
@@ -268,15 +269,26 @@ static void qmc_hcld_recv_complete(void *context, size_t length, unsigned int fl
                if (flags & QMC_RX_FLAG_HDLC_CRC) /* CRC error */
                        netdev->stats.rx_crc_errors++;
                kfree_skb(desc->skb);
-       } else {
-               netdev->stats.rx_packets++;
-               netdev->stats.rx_bytes += length;
+               goto re_queue;
+       }
 
-               skb_put(desc->skb, length);
-               desc->skb->protocol = hdlc_type_trans(desc->skb, netdev);
-               netif_rx(desc->skb);
+       /* Discard the CRC */
+       crc_size = qmc_hdlc->is_crc32 ? 4 : 2;
+       if (length < crc_size) {
+               netdev->stats.rx_length_errors++;
+               kfree_skb(desc->skb);
+               goto re_queue;
        }
+       length -= crc_size;
+
+       netdev->stats.rx_packets++;
+       netdev->stats.rx_bytes += length;
+
+       skb_put(desc->skb, length);
+       desc->skb->protocol = hdlc_type_trans(desc->skb, netdev);
+       netif_rx(desc->skb);
 
+re_queue:
        /* Re-queue a transfer using the same descriptor */
        ret = qmc_hdlc_recv_queue(qmc_hdlc, desc, desc->dma_size);
        if (ret) {