c6ccade8c1d4b4ce504bf056ba17976916edd8e3
[openwrt/staging/lynxis.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 }