dmaengine: ti: k3-udma: Report short packet errors
authorJai Luthra <j-luthra@ti.com>
Wed, 3 Jan 2024 09:07:55 +0000 (14:37 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 16 Feb 2024 18:10:42 +0000 (19:10 +0100)
[ Upstream commit bc9847c9ba134cfe3398011e343dcf6588c1c902 ]

Propagate the TR response status to the device using BCDMA
split-channels. For example CSI-RX driver should be able to check if a
frame was not transferred completely (short packet) and needs to be
discarded.

Fixes: 25dcb5dd7b7c ("dmaengine: ti: New driver for K3 UDMA")
Signed-off-by: Jai Luthra <j-luthra@ti.com>
Acked-by: Peter Ujfalusi <peter.ujfalusi@gmail.com>
Link: https://lore.kernel.org/r/20240103-tr_resp_err-v1-1-2fdf6d48ab92@ti.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/dma/ti/k3-udma.c

index 30fd2f3..037f140 100644 (file)
@@ -3968,6 +3968,7 @@ static void udma_desc_pre_callback(struct virt_dma_chan *vc,
 {
        struct udma_chan *uc = to_udma_chan(&vc->chan);
        struct udma_desc *d;
+       u8 status;
 
        if (!vd)
                return;
@@ -3977,12 +3978,12 @@ static void udma_desc_pre_callback(struct virt_dma_chan *vc,
        if (d->metadata_size)
                udma_fetch_epib(uc, d);
 
-       /* Provide residue information for the client */
        if (result) {
                void *desc_vaddr = udma_curr_cppi5_desc_vaddr(d, d->desc_idx);
 
                if (cppi5_desc_get_type(desc_vaddr) ==
                    CPPI5_INFO0_DESC_TYPE_VAL_HOST) {
+                       /* Provide residue information for the client */
                        result->residue = d->residue -
                                          cppi5_hdesc_get_pktlen(desc_vaddr);
                        if (result->residue)
@@ -3991,7 +3992,12 @@ static void udma_desc_pre_callback(struct virt_dma_chan *vc,
                                result->result = DMA_TRANS_NOERROR;
                } else {
                        result->residue = 0;
-                       result->result = DMA_TRANS_NOERROR;
+                       /* Propagate TR Response errors to the client */
+                       status = d->hwdesc[0].tr_resp_base->status;
+                       if (status)
+                               result->result = DMA_TRANS_ABORTED;
+                       else
+                               result->result = DMA_TRANS_NOERROR;
                }
        }
 }