hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/drivers/crypto/inside-secure/safexcel_ring.c
....@@ -14,7 +14,12 @@
1414 struct safexcel_desc_ring *cdr,
1515 struct safexcel_desc_ring *rdr)
1616 {
17
- cdr->offset = sizeof(u32) * priv->config.cd_offset;
17
+ int i;
18
+ struct safexcel_command_desc *cdesc;
19
+ dma_addr_t atok;
20
+
21
+ /* Actual command descriptor ring */
22
+ cdr->offset = priv->config.cd_offset;
1823 cdr->base = dmam_alloc_coherent(priv->dev,
1924 cdr->offset * EIP197_DEFAULT_RING_SIZE,
2025 &cdr->base_dma, GFP_KERNEL);
....@@ -24,7 +29,34 @@
2429 cdr->base_end = cdr->base + cdr->offset * (EIP197_DEFAULT_RING_SIZE - 1);
2530 cdr->read = cdr->base;
2631
27
- rdr->offset = sizeof(u32) * priv->config.rd_offset;
32
+ /* Command descriptor shadow ring for storing additional token data */
33
+ cdr->shoffset = priv->config.cdsh_offset;
34
+ cdr->shbase = dmam_alloc_coherent(priv->dev,
35
+ cdr->shoffset *
36
+ EIP197_DEFAULT_RING_SIZE,
37
+ &cdr->shbase_dma, GFP_KERNEL);
38
+ if (!cdr->shbase)
39
+ return -ENOMEM;
40
+ cdr->shwrite = cdr->shbase;
41
+ cdr->shbase_end = cdr->shbase + cdr->shoffset *
42
+ (EIP197_DEFAULT_RING_SIZE - 1);
43
+
44
+ /*
45
+ * Populate command descriptors with physical pointers to shadow descs.
46
+ * Note that we only need to do this once if we don't overwrite them.
47
+ */
48
+ cdesc = cdr->base;
49
+ atok = cdr->shbase_dma;
50
+ for (i = 0; i < EIP197_DEFAULT_RING_SIZE; i++) {
51
+ cdesc->atok_lo = lower_32_bits(atok);
52
+ cdesc->atok_hi = upper_32_bits(atok);
53
+ cdesc = (void *)cdesc + cdr->offset;
54
+ atok += cdr->shoffset;
55
+ }
56
+
57
+ rdr->offset = priv->config.rd_offset;
58
+ /* Use shoffset for result token offset here */
59
+ rdr->shoffset = priv->config.res_offset;
2860 rdr->base = dmam_alloc_coherent(priv->dev,
2961 rdr->offset * EIP197_DEFAULT_RING_SIZE,
3062 &rdr->base_dma, GFP_KERNEL);
....@@ -42,10 +74,39 @@
4274 return (atomic_inc_return(&priv->ring_used) % priv->config.rings);
4375 }
4476
45
-static void *safexcel_ring_next_wptr(struct safexcel_crypto_priv *priv,
46
- struct safexcel_desc_ring *ring)
77
+static void *safexcel_ring_next_cwptr(struct safexcel_crypto_priv *priv,
78
+ struct safexcel_desc_ring *ring,
79
+ bool first,
80
+ struct safexcel_token **atoken)
4781 {
4882 void *ptr = ring->write;
83
+
84
+ if (first)
85
+ *atoken = ring->shwrite;
86
+
87
+ if ((ring->write == ring->read - ring->offset) ||
88
+ (ring->read == ring->base && ring->write == ring->base_end))
89
+ return ERR_PTR(-ENOMEM);
90
+
91
+ if (ring->write == ring->base_end) {
92
+ ring->write = ring->base;
93
+ ring->shwrite = ring->shbase;
94
+ } else {
95
+ ring->write += ring->offset;
96
+ ring->shwrite += ring->shoffset;
97
+ }
98
+
99
+ return ptr;
100
+}
101
+
102
+static void *safexcel_ring_next_rwptr(struct safexcel_crypto_priv *priv,
103
+ struct safexcel_desc_ring *ring,
104
+ struct result_data_desc **rtoken)
105
+{
106
+ void *ptr = ring->write;
107
+
108
+ /* Result token at relative offset shoffset */
109
+ *rtoken = ring->write + ring->shoffset;
49110
50111 if ((ring->write == ring->read - ring->offset) ||
51112 (ring->read == ring->base && ring->write == ring->base_end))
....@@ -106,10 +167,13 @@
106167 if (ring->write == ring->read)
107168 return;
108169
109
- if (ring->write == ring->base)
170
+ if (ring->write == ring->base) {
110171 ring->write = ring->base_end;
111
- else
172
+ ring->shwrite = ring->shbase_end;
173
+ } else {
112174 ring->write -= ring->offset;
175
+ ring->shwrite -= ring->shoffset;
176
+ }
113177 }
114178
115179 struct safexcel_command_desc *safexcel_add_cdesc(struct safexcel_crypto_priv *priv,
....@@ -117,39 +181,41 @@
117181 bool first, bool last,
118182 dma_addr_t data, u32 data_len,
119183 u32 full_data_len,
120
- dma_addr_t context) {
184
+ dma_addr_t context,
185
+ struct safexcel_token **atoken)
186
+{
121187 struct safexcel_command_desc *cdesc;
122
- int i;
123188
124
- cdesc = safexcel_ring_next_wptr(priv, &priv->ring[ring_id].cdr);
189
+ cdesc = safexcel_ring_next_cwptr(priv, &priv->ring[ring_id].cdr,
190
+ first, atoken);
125191 if (IS_ERR(cdesc))
126192 return cdesc;
127193
128
- memset(cdesc, 0, sizeof(struct safexcel_command_desc));
129
-
130
- cdesc->first_seg = first;
131
- cdesc->last_seg = last;
132194 cdesc->particle_size = data_len;
195
+ cdesc->rsvd0 = 0;
196
+ cdesc->last_seg = last;
197
+ cdesc->first_seg = first;
198
+ cdesc->additional_cdata_size = 0;
199
+ cdesc->rsvd1 = 0;
133200 cdesc->data_lo = lower_32_bits(data);
134201 cdesc->data_hi = upper_32_bits(data);
135202
136
- if (first && context) {
137
- struct safexcel_token *token =
138
- (struct safexcel_token *)cdesc->control_data.token;
139
-
140
- cdesc->control_data.packet_length = full_data_len;
203
+ if (first) {
204
+ /*
205
+ * Note that the length here MUST be >0 or else the EIP(1)97
206
+ * may hang. Newer EIP197 firmware actually incorporates this
207
+ * fix already, but that doesn't help the EIP97 and we may
208
+ * also be running older firmware.
209
+ */
210
+ cdesc->control_data.packet_length = full_data_len ?: 1;
141211 cdesc->control_data.options = EIP197_OPTION_MAGIC_VALUE |
142212 EIP197_OPTION_64BIT_CTX |
143
- EIP197_OPTION_CTX_CTRL_IN_CMD;
144
- cdesc->control_data.context_lo =
145
- (lower_32_bits(context) & GENMASK(31, 2)) >> 2;
213
+ EIP197_OPTION_CTX_CTRL_IN_CMD |
214
+ EIP197_OPTION_RC_AUTO;
215
+ cdesc->control_data.type = EIP197_TYPE_BCLA;
216
+ cdesc->control_data.context_lo = lower_32_bits(context) |
217
+ EIP197_CONTEXT_SMALL;
146218 cdesc->control_data.context_hi = upper_32_bits(context);
147
-
148
- /* TODO: large xform HMAC with SHA-384/512 uses refresh = 3 */
149
- cdesc->control_data.refresh = 2;
150
-
151
- for (i = 0; i < EIP197_MAX_TOKENS; i++)
152
- eip197_noop_token(&token[i]);
153219 }
154220
155221 return cdesc;
....@@ -161,18 +227,28 @@
161227 dma_addr_t data, u32 len)
162228 {
163229 struct safexcel_result_desc *rdesc;
230
+ struct result_data_desc *rtoken;
164231
165
- rdesc = safexcel_ring_next_wptr(priv, &priv->ring[ring_id].rdr);
232
+ rdesc = safexcel_ring_next_rwptr(priv, &priv->ring[ring_id].rdr,
233
+ &rtoken);
166234 if (IS_ERR(rdesc))
167235 return rdesc;
168236
169
- memset(rdesc, 0, sizeof(struct safexcel_result_desc));
170
-
171
- rdesc->first_seg = first;
172
- rdesc->last_seg = last;
173237 rdesc->particle_size = len;
238
+ rdesc->rsvd0 = 0;
239
+ rdesc->descriptor_overflow = 1; /* assume error */
240
+ rdesc->buffer_overflow = 1; /* assume error */
241
+ rdesc->last_seg = last;
242
+ rdesc->first_seg = first;
243
+ rdesc->result_size = EIP197_RD64_RESULT_SIZE;
244
+ rdesc->rsvd1 = 0;
174245 rdesc->data_lo = lower_32_bits(data);
175246 rdesc->data_hi = upper_32_bits(data);
176247
248
+ /* Clear length in result token */
249
+ rtoken->packet_length = 0;
250
+ /* Assume errors - HW will clear if not the case */
251
+ rtoken->error_code = 0x7fff;
252
+
177253 return rdesc;
178254 }