Revert "caam: Fix CAAM error on startup"
authorFabio Estevam <festevam@gmail.com>
Thu, 5 Jun 2025 10:52:44 +0000 (07:52 -0300)
committerTom Rini <trini@konsulko.com>
Mon, 9 Jun 2025 17:01:24 +0000 (11:01 -0600)
This reverts commit 159b6f0e119962ce5da645f548cefe9196c8778e.

Since commit 159b6f0e1199 ("caam: Fix CAAM error on startup") the following
regression was reported by Tim Harvey:

"I've found that this patch causes a regression on an imx8mm board
(imx8mm_venice_defconfig) where the first call to caam_rng_read fails
here in jr_dequeue but if you call it again it works. With some
debugging added:
SEC0:  RNG instantiated
...
Hit any key to stop autoboot:  0
u-boot=> rng list
RNG #0 - caam-rng
u-boot=> rng 0 10
caam_rng_read caam-rng len=16
run_descriptor_jr_idx idx=0
Error in SEC deq: -1
caam_rng_read_one run_descriptor_jr failed: -1
caam_rng_read caam-rng caam_rng_read_one failed: -5
Reading RNG failed
u-boot=> rng 0 10
caam_rng_read caam-rng len=16
run_descriptor_jr_idx idx=0
00000000: ad 2e ad c0 2a 12 27 c4 65 82 66 19 be ef f6 07  ....*.'.e.f.....

If I revert your patch caam_rng_read works initially and on subsequent
calls."

" I ran into this when I was testing
lwIP HTTPS as it causes anything that uses dm_rng to fail the first
time (such as HTTPS)."

Revert it for now to avoid the regression.

Reported-by: Tim Harvey <tharvey@gateworks.com>
Signed-off-by: Fabio Estevam <festevam@gmail.com>
Acked-by: Peng Fan <peng.fan@nxp.com>
drivers/crypto/fsl/jr.c
drivers/crypto/fsl/jr.h

index 1d95d2b..8f7a821 100644 (file)
@@ -217,6 +217,13 @@ static int jr_enqueue(uint32_t *desc_addr,
 
        jr->head = (head + 1) & (jr->size - 1);
 
+       /* Invalidate output ring */
+       start = (unsigned long)jr->output_ring &
+                                       ~(ARCH_DMA_MINALIGN - 1);
+       end = ALIGN((unsigned long)jr->output_ring + jr->op_size,
+                   ARCH_DMA_MINALIGN);
+       invalidate_dcache_range(start, end);
+
        sec_out32(&regs->irja, 1);
 
        return 0;
@@ -236,7 +243,6 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam)
 #else
        uint32_t *addr;
 #endif
-       unsigned long start, end;
 
        while (sec_in32(&regs->orsf) && CIRC_CNT(jr->head, jr->tail,
                                                 jr->size)) {
@@ -244,11 +250,6 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam)
                found = 0;
 
                caam_dma_addr_t op_desc;
-
-               /* Invalidate output ring */
-               start = (unsigned long)jr->output_ring & ~(ARCH_DMA_MINALIGN - 1);
-               end = ALIGN((unsigned long)jr->output_ring + jr->op_size, ARCH_DMA_MINALIGN);
-               invalidate_dcache_range(start, end);
        #ifdef CONFIG_CAAM_64BIT
                /* Read the 64 bit Descriptor address from Output Ring.
                 * The 32 bit hign and low part of the address will
@@ -282,13 +283,8 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam)
                }
 
                /* Error condition if match not found */
-               if (!found) {
-                       int slots_full = sec_in32(&regs->orsf);
-
-                       jr->tail = (jr->tail + slots_full) & (jr->size - 1);
-                       sec_out32(&regs->orjr, slots_full);
+               if (!found)
                        return -1;
-               }
 
                jr->info[idx].op_done = 1;
                callback = (void *)jr->info[idx].callback;
@@ -300,14 +296,14 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam)
                 */
                if (idx == tail)
                        do {
-                               jr->info[tail].op_done = 0;
                                tail = (tail + 1) & (jr->size - 1);
                        } while (jr->info[tail].op_done);
 
                jr->tail = tail;
-
+               jr->read_idx = (jr->read_idx + 1) & (jr->size - 1);
 
                sec_out32(&regs->orjr, 1);
+               jr->info[idx].op_done = 0;
 
                callback(status, arg);
        }
@@ -382,6 +378,7 @@ static int jr_sw_cleanup(uint8_t sec_idx, struct caam_regs *caam)
 
        jr->head = 0;
        jr->tail = 0;
+       jr->read_idx = 0;
        jr->write_idx = 0;
        memset(jr->info, 0, sizeof(jr->info));
        memset(jr->input_ring, 0, jr->size * sizeof(caam_dma_addr_t));
index 8d5ca03..b136cd8 100644 (file)
@@ -83,6 +83,10 @@ struct jobring {
         * in-order job completion
         */
        int tail;
+       /* Read index of the output ring. It may not match with tail in case
+        * of out of order completetion
+        */
+       int read_idx;
        /* Write index to input ring. Would be always equal to head */
        int write_idx;
        /* Size of the rings. */