]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: fec: implement TSO descriptor cleanup
authorDheeraj Reddy Jonnalagadda <dheeraj.linuxdev@gmail.com>
Mon, 20 Jan 2025 08:54:30 +0000 (14:24 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Mar 2025 11:46:57 +0000 (12:46 +0100)
[ Upstream commit 61dc1fd9205bc9d9918aa933a847b08e80b4dc20 ]

Implement cleanup of descriptors in the TSO error path of
fec_enet_txq_submit_tso(). The cleanup

- Unmaps DMA buffers for data descriptors skipping TSO header
- Clears all buffer descriptors
- Handles extended descriptors by clearing cbd_esc when enabled

Fixes: 79f339125ea3 ("net: fec: Add software TSO support")
Signed-off-by: Dheeraj Reddy Jonnalagadda <dheeraj.linuxdev@gmail.com>
Reviewed-by: Wei Fang <wei.fang@nxp.com>
Link: https://patch.msgid.link/20250120085430.99318-1-dheeraj.linuxdev@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/freescale/fec_main.c

index a591ca0b37787f0f4e12328dd6d133e3e33062c5..8e30e999456d4040353bd27ec4de03609066c5b8 100644 (file)
@@ -728,6 +728,8 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
        struct fec_enet_private *fep = netdev_priv(ndev);
        int hdr_len, total_len, data_left;
        struct bufdesc *bdp = txq->bd.cur;
+       struct bufdesc *tmp_bdp;
+       struct bufdesc_ex *ebdp;
        struct tso_t tso;
        unsigned int index = 0;
        int ret;
@@ -801,7 +803,34 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
        return 0;
 
 err_release:
-       /* TODO: Release all used data descriptors for TSO */
+       /* Release all used data descriptors for TSO */
+       tmp_bdp = txq->bd.cur;
+
+       while (tmp_bdp != bdp) {
+               /* Unmap data buffers */
+               if (tmp_bdp->cbd_bufaddr &&
+                   !IS_TSO_HEADER(txq, fec32_to_cpu(tmp_bdp->cbd_bufaddr)))
+                       dma_unmap_single(&fep->pdev->dev,
+                                        fec32_to_cpu(tmp_bdp->cbd_bufaddr),
+                                        fec16_to_cpu(tmp_bdp->cbd_datlen),
+                                        DMA_TO_DEVICE);
+
+               /* Clear standard buffer descriptor fields */
+               tmp_bdp->cbd_sc = 0;
+               tmp_bdp->cbd_datlen = 0;
+               tmp_bdp->cbd_bufaddr = 0;
+
+               /* Handle extended descriptor if enabled */
+               if (fep->bufdesc_ex) {
+                       ebdp = (struct bufdesc_ex *)tmp_bdp;
+                       ebdp->cbd_esc = 0;
+               }
+
+               tmp_bdp = fec_enet_get_nextdesc(tmp_bdp, &txq->bd);
+       }
+
+       dev_kfree_skb_any(skb);
+
        return ret;
 }