apm821xx: backport crypto4xx patches from 4.15
[oweals/openwrt.git] / target / linux / apm821xx / patches-4.14 / 020-0009-crypto-crypto4xx-refactor-crypto4xx_copy_pkt_to_dst.patch
1 From 5c727f92ea5e019fd216f73009eee2b6e0867726 Mon Sep 17 00:00:00 2001
2 From: Christian Lamparter <chunkeey@googlemail.com>
3 Date: Fri, 25 Aug 2017 15:47:22 +0200
4 Subject: [PATCH 09/25] crypto: crypto4xx - refactor
5  crypto4xx_copy_pkt_to_dst()
6
7 This patch refactors the crypto4xx_copy_pkt_to_dst() to use
8 scatterwalk_map_and_copy() to copy the processed data between
9 the crypto engine's scatter ring buffer and the destination
10 specified by the ablkcipher_request.
11
12 This also makes the crypto4xx_fill_one_page() function redundant.
13
14 Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
15 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
16 ---
17  drivers/crypto/amcc/crypto4xx_core.c | 126 +++++++++--------------------------
18  1 file changed, 30 insertions(+), 96 deletions(-)
19
20 --- a/drivers/crypto/amcc/crypto4xx_core.c
21 +++ b/drivers/crypto/amcc/crypto4xx_core.c
22 @@ -38,6 +38,7 @@
23  #include <crypto/aes.h>
24  #include <crypto/ctr.h>
25  #include <crypto/sha.h>
26 +#include <crypto/scatterwalk.h>
27  #include "crypto4xx_reg_def.h"
28  #include "crypto4xx_core.h"
29  #include "crypto4xx_sa.h"
30 @@ -481,111 +482,44 @@ static inline struct ce_sd *crypto4xx_ge
31         return  (struct ce_sd *)(dev->sdr + sizeof(struct ce_sd) * idx);
32  }
33  
34 -static u32 crypto4xx_fill_one_page(struct crypto4xx_device *dev,
35 -                                  dma_addr_t *addr, u32 *length,
36 -                                  u32 *idx, u32 *offset, u32 *nbytes)
37 -{
38 -       u32 len;
39 -
40 -       if (*length > dev->scatter_buffer_size) {
41 -               memcpy(phys_to_virt(*addr),
42 -                       dev->scatter_buffer_va +
43 -                       *idx * dev->scatter_buffer_size + *offset,
44 -                       dev->scatter_buffer_size);
45 -               *offset = 0;
46 -               *length -= dev->scatter_buffer_size;
47 -               *nbytes -= dev->scatter_buffer_size;
48 -               if (*idx == PPC4XX_LAST_SD)
49 -                       *idx = 0;
50 -               else
51 -                       (*idx)++;
52 -               *addr = *addr +  dev->scatter_buffer_size;
53 -               return 1;
54 -       } else if (*length < dev->scatter_buffer_size) {
55 -               memcpy(phys_to_virt(*addr),
56 -                       dev->scatter_buffer_va +
57 -                       *idx * dev->scatter_buffer_size + *offset, *length);
58 -               if ((*offset + *length) == dev->scatter_buffer_size) {
59 -                       if (*idx == PPC4XX_LAST_SD)
60 -                               *idx = 0;
61 -                       else
62 -                               (*idx)++;
63 -                       *nbytes -= *length;
64 -                       *offset = 0;
65 -               } else {
66 -                       *nbytes -= *length;
67 -                       *offset += *length;
68 -               }
69 -
70 -               return 0;
71 -       } else {
72 -               len = (*nbytes <= dev->scatter_buffer_size) ?
73 -                               (*nbytes) : dev->scatter_buffer_size;
74 -               memcpy(phys_to_virt(*addr),
75 -                       dev->scatter_buffer_va +
76 -                       *idx * dev->scatter_buffer_size + *offset,
77 -                       len);
78 -               *offset = 0;
79 -               *nbytes -= len;
80 -
81 -               if (*idx == PPC4XX_LAST_SD)
82 -                       *idx = 0;
83 -               else
84 -                       (*idx)++;
85 -
86 -               return 0;
87 -    }
88 -}
89 -
90  static void crypto4xx_copy_pkt_to_dst(struct crypto4xx_device *dev,
91                                       struct ce_pd *pd,
92                                       struct pd_uinfo *pd_uinfo,
93                                       u32 nbytes,
94                                       struct scatterlist *dst)
95  {
96 -       dma_addr_t addr;
97 -       u32 this_sd;
98 -       u32 offset;
99 -       u32 len;
100 -       u32 i;
101 -       u32 sg_len;
102 -       struct scatterlist *sg;
103 -
104 -       this_sd = pd_uinfo->first_sd;
105 -       offset = 0;
106 -       i = 0;
107 +       unsigned int first_sd = pd_uinfo->first_sd;
108 +       unsigned int last_sd;
109 +       unsigned int overflow = 0;
110 +       unsigned int to_copy;
111 +       unsigned int dst_start = 0;
112 +
113 +       /*
114 +        * Because the scatter buffers are all neatly organized in one
115 +        * big continuous ringbuffer; scatterwalk_map_and_copy() can
116 +        * be instructed to copy a range of buffers in one go.
117 +        */
118 +
119 +       last_sd = (first_sd + pd_uinfo->num_sd);
120 +       if (last_sd > PPC4XX_LAST_SD) {
121 +               last_sd = PPC4XX_LAST_SD;
122 +               overflow = last_sd % PPC4XX_NUM_SD;
123 +       }
124  
125         while (nbytes) {
126 -               sg = &dst[i];
127 -               sg_len = sg->length;
128 -               addr = dma_map_page(dev->core_dev->device, sg_page(sg),
129 -                               sg->offset, sg->length, DMA_TO_DEVICE);
130 -
131 -               if (offset == 0) {
132 -                       len = (nbytes <= sg->length) ? nbytes : sg->length;
133 -                       while (crypto4xx_fill_one_page(dev, &addr, &len,
134 -                               &this_sd, &offset, &nbytes))
135 -                               ;
136 -                       if (!nbytes)
137 -                               return;
138 -                       i++;
139 -               } else {
140 -                       len = (nbytes <= (dev->scatter_buffer_size - offset)) ?
141 -                               nbytes : (dev->scatter_buffer_size - offset);
142 -                       len = (sg->length < len) ? sg->length : len;
143 -                       while (crypto4xx_fill_one_page(dev, &addr, &len,
144 -                                              &this_sd, &offset, &nbytes))
145 -                               ;
146 -                       if (!nbytes)
147 -                               return;
148 -                       sg_len -= len;
149 -                       if (sg_len) {
150 -                               addr += len;
151 -                               while (crypto4xx_fill_one_page(dev, &addr,
152 -                                       &sg_len, &this_sd, &offset, &nbytes))
153 -                                       ;
154 -                       }
155 -                       i++;
156 +               void *buf = dev->scatter_buffer_va +
157 +                       first_sd * PPC4XX_SD_BUFFER_SIZE;
158 +
159 +               to_copy = min(nbytes, PPC4XX_SD_BUFFER_SIZE *
160 +                                     (1 + last_sd - first_sd));
161 +               scatterwalk_map_and_copy(buf, dst, dst_start, to_copy, 1);
162 +               nbytes -= to_copy;
163 +
164 +               if (overflow) {
165 +                       first_sd = 0;
166 +                       last_sd = overflow;
167 +                       dst_start += to_copy;
168 +                       overflow = 0;
169                 }
170         }
171  }