OpenWrt – Rev 1

Subversion Repositories:
Rev:
From 5c727f92ea5e019fd216f73009eee2b6e0867726 Mon Sep 17 00:00:00 2001
From: Christian Lamparter <chunkeey@googlemail.com>
Date: Fri, 25 Aug 2017 15:47:22 +0200
Subject: [PATCH 09/25] crypto: crypto4xx - refactor
 crypto4xx_copy_pkt_to_dst()

This patch refactors the crypto4xx_copy_pkt_to_dst() to use
scatterwalk_map_and_copy() to copy the processed data between
the crypto engine's scatter ring buffer and the destination
specified by the ablkcipher_request.

This also makes the crypto4xx_fill_one_page() function redundant.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
 drivers/crypto/amcc/crypto4xx_core.c | 126 +++++++++--------------------------
 1 file changed, 30 insertions(+), 96 deletions(-)

--- a/drivers/crypto/amcc/crypto4xx_core.c
+++ b/drivers/crypto/amcc/crypto4xx_core.c
@@ -38,6 +38,7 @@
 #include <crypto/aes.h>
 #include <crypto/ctr.h>
 #include <crypto/sha.h>
+#include <crypto/scatterwalk.h>
 #include "crypto4xx_reg_def.h"
 #include "crypto4xx_core.h"
 #include "crypto4xx_sa.h"
@@ -483,111 +484,44 @@ static inline struct ce_sd *crypto4xx_ge
        return  (struct ce_sd *)(dev->sdr + sizeof(struct ce_sd) * idx);
 }
 
-static u32 crypto4xx_fill_one_page(struct crypto4xx_device *dev,
-                                  dma_addr_t *addr, u32 *length,
-                                  u32 *idx, u32 *offset, u32 *nbytes)
-{
-       u32 len;
-
-       if (*length > dev->scatter_buffer_size) {
-               memcpy(phys_to_virt(*addr),
-                       dev->scatter_buffer_va +
-                       *idx * dev->scatter_buffer_size + *offset,
-                       dev->scatter_buffer_size);
-               *offset = 0;
-               *length -= dev->scatter_buffer_size;
-               *nbytes -= dev->scatter_buffer_size;
-               if (*idx == PPC4XX_LAST_SD)
-                       *idx = 0;
-               else
-                       (*idx)++;
-               *addr = *addr +  dev->scatter_buffer_size;
-               return 1;
-       } else if (*length < dev->scatter_buffer_size) {
-               memcpy(phys_to_virt(*addr),
-                       dev->scatter_buffer_va +
-                       *idx * dev->scatter_buffer_size + *offset, *length);
-               if ((*offset + *length) == dev->scatter_buffer_size) {
-                       if (*idx == PPC4XX_LAST_SD)
-                               *idx = 0;
-                       else
-                               (*idx)++;
-                       *nbytes -= *length;
-                       *offset = 0;
-               } else {
-                       *nbytes -= *length;
-                       *offset += *length;
-               }
-
-               return 0;
-       } else {
-               len = (*nbytes <= dev->scatter_buffer_size) ?
-                               (*nbytes) : dev->scatter_buffer_size;
-               memcpy(phys_to_virt(*addr),
-                       dev->scatter_buffer_va +
-                       *idx * dev->scatter_buffer_size + *offset,
-                       len);
-               *offset = 0;
-               *nbytes -= len;
-
-               if (*idx == PPC4XX_LAST_SD)
-                       *idx = 0;
-               else
-                       (*idx)++;
-
-               return 0;
-    }
-}
-
 static void crypto4xx_copy_pkt_to_dst(struct crypto4xx_device *dev,
                                      struct ce_pd *pd,
                                      struct pd_uinfo *pd_uinfo,
                                      u32 nbytes,
                                      struct scatterlist *dst)
 {
-       dma_addr_t addr;
-       u32 this_sd;
-       u32 offset;
-       u32 len;
-       u32 i;
-       u32 sg_len;
-       struct scatterlist *sg;
-
-       this_sd = pd_uinfo->first_sd;
-       offset = 0;
-       i = 0;
+       unsigned int first_sd = pd_uinfo->first_sd;
+       unsigned int last_sd;
+       unsigned int overflow = 0;
+       unsigned int to_copy;
+       unsigned int dst_start = 0;
+
+       /*
+        * Because the scatter buffers are all neatly organized in one
+        * big continuous ringbuffer; scatterwalk_map_and_copy() can
+        * be instructed to copy a range of buffers in one go.
+        */
+
+       last_sd = (first_sd + pd_uinfo->num_sd);
+       if (last_sd > PPC4XX_LAST_SD) {
+               last_sd = PPC4XX_LAST_SD;
+               overflow = last_sd % PPC4XX_NUM_SD;
+       }
 
        while (nbytes) {
-               sg = &dst[i];
-               sg_len = sg->length;
-               addr = dma_map_page(dev->core_dev->device, sg_page(sg),
-                               sg->offset, sg->length, DMA_TO_DEVICE);
-
-               if (offset == 0) {
-                       len = (nbytes <= sg->length) ? nbytes : sg->length;
-                       while (crypto4xx_fill_one_page(dev, &addr, &len,
-                               &this_sd, &offset, &nbytes))
-                               ;
-                       if (!nbytes)
-                               return;
-                       i++;
-               } else {
-                       len = (nbytes <= (dev->scatter_buffer_size - offset)) ?
-                               nbytes : (dev->scatter_buffer_size - offset);
-                       len = (sg->length < len) ? sg->length : len;
-                       while (crypto4xx_fill_one_page(dev, &addr, &len,
-                                              &this_sd, &offset, &nbytes))
-                               ;
-                       if (!nbytes)
-                               return;
-                       sg_len -= len;
-                       if (sg_len) {
-                               addr += len;
-                               while (crypto4xx_fill_one_page(dev, &addr,
-                                       &sg_len, &this_sd, &offset, &nbytes))
-                                       ;
-                       }
-                       i++;
+               void *buf = dev->scatter_buffer_va +
+                       first_sd * PPC4XX_SD_BUFFER_SIZE;
+
+               to_copy = min(nbytes, PPC4XX_SD_BUFFER_SIZE *
+                                     (1 + last_sd - first_sd));
+               scatterwalk_map_and_copy(buf, dst, dst_start, to_copy, 1);
+               nbytes -= to_copy;
+
+               if (overflow) {
+                       first_sd = 0;
+                       last_sd = overflow;
+                       dst_start += to_copy;
+                       overflow = 0;
                }
        }
 }