]> www.infradead.org Git - users/dwmw2/linux.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)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 23 Jan 2025 09:14:34 +0000 (10:14 +0100)
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>
drivers/net/ethernet/freescale/fec_main.c

index 68725506a095db945973fcff8c7d774eb520a961..f7c4ce8e9a265597f7e50a0431296c51d76c3abf 100644 (file)
@@ -840,6 +840,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;
@@ -913,7 +915,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;
 }