aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/crypto/omap-sham.c416
1 files changed, 332 insertions, 84 deletions
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index 8074bd9947d1..fab0af488b83 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -5,6 +5,7 @@
5 * 5 *
6 * Copyright (c) 2010 Nokia Corporation 6 * Copyright (c) 2010 Nokia Corporation
7 * Author: Dmitry Kasatkin <dmitry.kasatkin@nokia.com> 7 * Author: Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
8 * Copyright (c) 2011 Texas Instruments Incorporated
8 * 9 *
9 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as published 11 * it under the terms of the GNU General Public License version 2 as published
@@ -43,16 +44,17 @@
43#include <crypto/hash.h> 44#include <crypto/hash.h>
44#include <crypto/internal/hash.h> 45#include <crypto/internal/hash.h>
45 46
46#define SHA_REG_DIGEST(x) (0x00 + ((x) * 0x04))
47#define SHA_REG_DIN(x) (0x1C + ((x) * 0x04))
48
49#define SHA1_MD5_BLOCK_SIZE SHA1_BLOCK_SIZE 47#define SHA1_MD5_BLOCK_SIZE SHA1_BLOCK_SIZE
50#define MD5_DIGEST_SIZE 16 48#define MD5_DIGEST_SIZE 16
51 49
52#define DST_MAXBURST 16 50#define DST_MAXBURST 16
53#define DMA_MIN (DST_MAXBURST * sizeof(u32)) 51#define DMA_MIN (DST_MAXBURST * sizeof(u32))
54 52
55#define SHA_REG_DIGCNT 0x14 53#define SHA_REG_IDIGEST(dd, x) ((dd)->pdata->idigest_ofs + ((x)*0x04))
54#define SHA_REG_DIN(dd, x) ((dd)->pdata->din_ofs + ((x) * 0x04))
55#define SHA_REG_DIGCNT(dd) ((dd)->pdata->digcnt_ofs)
56
57#define SHA_REG_ODIGEST(x) (0x00 + ((x) * 0x04))
56 58
57#define SHA_REG_CTRL 0x18 59#define SHA_REG_CTRL 0x18
58#define SHA_REG_CTRL_LENGTH (0xFFFFFFFF << 5) 60#define SHA_REG_CTRL_LENGTH (0xFFFFFFFF << 5)
@@ -62,19 +64,40 @@
62#define SHA_REG_CTRL_INPUT_READY (1 << 1) 64#define SHA_REG_CTRL_INPUT_READY (1 << 1)
63#define SHA_REG_CTRL_OUTPUT_READY (1 << 0) 65#define SHA_REG_CTRL_OUTPUT_READY (1 << 0)
64 66
65#define SHA_REG_REV 0x5C 67#define SHA_REG_REV(dd) ((dd)->pdata->rev_ofs)
66#define SHA_REG_REV_MAJOR 0xF0
67#define SHA_REG_REV_MINOR 0x0F
68 68
69#define SHA_REG_MASK 0x60 69#define SHA_REG_MASK(dd) ((dd)->pdata->mask_ofs)
70#define SHA_REG_MASK_DMA_EN (1 << 3) 70#define SHA_REG_MASK_DMA_EN (1 << 3)
71#define SHA_REG_MASK_IT_EN (1 << 2) 71#define SHA_REG_MASK_IT_EN (1 << 2)
72#define SHA_REG_MASK_SOFTRESET (1 << 1) 72#define SHA_REG_MASK_SOFTRESET (1 << 1)
73#define SHA_REG_AUTOIDLE (1 << 0) 73#define SHA_REG_AUTOIDLE (1 << 0)
74 74
75#define SHA_REG_SYSSTATUS 0x64 75#define SHA_REG_SYSSTATUS(dd) ((dd)->pdata->sysstatus_ofs)
76#define SHA_REG_SYSSTATUS_RESETDONE (1 << 0) 76#define SHA_REG_SYSSTATUS_RESETDONE (1 << 0)
77 77
78#define SHA_REG_MODE 0x44
79#define SHA_REG_MODE_HMAC_OUTER_HASH (1 << 7)
80#define SHA_REG_MODE_HMAC_KEY_PROC (1 << 5)
81#define SHA_REG_MODE_CLOSE_HASH (1 << 4)
82#define SHA_REG_MODE_ALGO_CONSTANT (1 << 3)
83#define SHA_REG_MODE_ALGO_MASK (3 << 1)
84#define SHA_REG_MODE_ALGO_MD5_128 (0 << 1)
85#define SHA_REG_MODE_ALGO_SHA1_160 (1 << 1)
86
87#define SHA_REG_LENGTH 0x48
88
89#define SHA_REG_IRQSTATUS 0x118
90#define SHA_REG_IRQSTATUS_CTX_RDY (1 << 3)
91#define SHA_REG_IRQSTATUS_PARTHASH_RDY (1 << 2)
92#define SHA_REG_IRQSTATUS_INPUT_RDY (1 << 1)
93#define SHA_REG_IRQSTATUS_OUTPUT_RDY (1 << 0)
94
95#define SHA_REG_IRQENA 0x11C
96#define SHA_REG_IRQENA_CTX_RDY (1 << 3)
97#define SHA_REG_IRQENA_PARTHASH_RDY (1 << 2)
98#define SHA_REG_IRQENA_INPUT_RDY (1 << 1)
99#define SHA_REG_IRQENA_OUTPUT_RDY (1 << 0)
100
78#define DEFAULT_TIMEOUT_INTERVAL HZ 101#define DEFAULT_TIMEOUT_INTERVAL HZ
79 102
80/* mostly device flags */ 103/* mostly device flags */
@@ -85,20 +108,29 @@
85#define FLAGS_INIT 4 108#define FLAGS_INIT 4
86#define FLAGS_CPU 5 109#define FLAGS_CPU 5
87#define FLAGS_DMA_READY 6 110#define FLAGS_DMA_READY 6
111#define FLAGS_AUTO_XOR 7
112#define FLAGS_BE32_SHA1 8
88/* context flags */ 113/* context flags */
89#define FLAGS_FINUP 16 114#define FLAGS_FINUP 16
90#define FLAGS_SG 17 115#define FLAGS_SG 17
91#define FLAGS_SHA1 18
92#define FLAGS_HMAC 19
93#define FLAGS_ERROR 20
94 116
95#define OP_UPDATE 1 117#define FLAGS_MODE_SHIFT 18
96#define OP_FINAL 2 118#define FLAGS_MODE_MASK (SHA_REG_MODE_ALGO_MASK \
119 << (FLAGS_MODE_SHIFT - 1))
120#define FLAGS_MODE_MD5 (SHA_REG_MODE_ALGO_MD5_128 \
121 << (FLAGS_MODE_SHIFT - 1))
122#define FLAGS_MODE_SHA1 (SHA_REG_MODE_ALGO_SHA1_160 \
123 << (FLAGS_MODE_SHIFT - 1))
124#define FLAGS_HMAC 20
125#define FLAGS_ERROR 21
126
127#define OP_UPDATE 1
128#define OP_FINAL 2
97 129
98#define OMAP_ALIGN_MASK (sizeof(u32)-1) 130#define OMAP_ALIGN_MASK (sizeof(u32)-1)
99#define OMAP_ALIGNED __attribute__((aligned(sizeof(u32)))) 131#define OMAP_ALIGNED __attribute__((aligned(sizeof(u32))))
100 132
101#define BUFLEN PAGE_SIZE 133#define BUFLEN PAGE_SIZE
102 134
103struct omap_sham_dev; 135struct omap_sham_dev;
104 136
@@ -107,7 +139,7 @@ struct omap_sham_reqctx {
107 unsigned long flags; 139 unsigned long flags;
108 unsigned long op; 140 unsigned long op;
109 141
110 u8 digest[SHA1_DIGEST_SIZE] OMAP_ALIGNED; 142 u8 digest[SHA256_DIGEST_SIZE] OMAP_ALIGNED;
111 size_t digcnt; 143 size_t digcnt;
112 size_t bufcnt; 144 size_t bufcnt;
113 size_t buflen; 145 size_t buflen;
@@ -124,8 +156,8 @@ struct omap_sham_reqctx {
124 156
125struct omap_sham_hmac_ctx { 157struct omap_sham_hmac_ctx {
126 struct crypto_shash *shash; 158 struct crypto_shash *shash;
127 u8 ipad[SHA1_MD5_BLOCK_SIZE]; 159 u8 ipad[SHA1_MD5_BLOCK_SIZE] OMAP_ALIGNED;
128 u8 opad[SHA1_MD5_BLOCK_SIZE]; 160 u8 opad[SHA1_MD5_BLOCK_SIZE] OMAP_ALIGNED;
129}; 161};
130 162
131struct omap_sham_ctx { 163struct omap_sham_ctx {
@@ -141,6 +173,31 @@ struct omap_sham_ctx {
141 173
142#define OMAP_SHAM_QUEUE_LENGTH 1 174#define OMAP_SHAM_QUEUE_LENGTH 1
143 175
176struct omap_sham_pdata {
177 unsigned long flags;
178 int digest_size;
179
180 void (*copy_hash)(struct ahash_request *req, int out);
181 void (*write_ctrl)(struct omap_sham_dev *dd, size_t length,
182 int final, int dma);
183 void (*trigger)(struct omap_sham_dev *dd, size_t length);
184 int (*poll_irq)(struct omap_sham_dev *dd);
185 irqreturn_t (*intr_hdlr)(int irq, void *dev_id);
186
187 u32 odigest_ofs;
188 u32 idigest_ofs;
189 u32 din_ofs;
190 u32 digcnt_ofs;
191 u32 rev_ofs;
192 u32 mask_ofs;
193 u32 sysstatus_ofs;
194
195 u32 major_mask;
196 u32 major_shift;
197 u32 minor_mask;
198 u32 minor_shift;
199};
200
144struct omap_sham_dev { 201struct omap_sham_dev {
145 struct list_head list; 202 struct list_head list;
146 unsigned long phys_base; 203 unsigned long phys_base;
@@ -156,6 +213,8 @@ struct omap_sham_dev {
156 unsigned long flags; 213 unsigned long flags;
157 struct crypto_queue queue; 214 struct crypto_queue queue;
158 struct ahash_request *req; 215 struct ahash_request *req;
216
217 const struct omap_sham_pdata *pdata;
159}; 218};
160 219
161struct omap_sham_drv { 220struct omap_sham_drv {
@@ -203,21 +262,44 @@ static inline int omap_sham_wait(struct omap_sham_dev *dd, u32 offset, u32 bit)
203 return 0; 262 return 0;
204} 263}
205 264
206static void omap_sham_copy_hash(struct ahash_request *req, int out) 265static void omap_sham_copy_hash_omap2(struct ahash_request *req, int out)
207{ 266{
208 struct omap_sham_reqctx *ctx = ahash_request_ctx(req); 267 struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
268 struct omap_sham_dev *dd = ctx->dd;
209 u32 *hash = (u32 *)ctx->digest; 269 u32 *hash = (u32 *)ctx->digest;
210 int i; 270 int i;
211 271
212 /* MD5 is almost unused. So copy sha1 size to reduce code */ 272 for (i = 0; i < dd->pdata->digest_size / sizeof(u32); i++) {
213 for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) {
214 if (out) 273 if (out)
215 hash[i] = omap_sham_read(ctx->dd, 274 hash[i] = omap_sham_read(dd, SHA_REG_IDIGEST(dd, i));
216 SHA_REG_DIGEST(i));
217 else 275 else
218 omap_sham_write(ctx->dd, 276 omap_sham_write(dd, SHA_REG_IDIGEST(dd, i), hash[i]);
219 SHA_REG_DIGEST(i), hash[i]); 277 }
278}
279
280static void omap_sham_copy_hash_omap4(struct ahash_request *req, int out)
281{
282 struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
283 struct omap_sham_dev *dd = ctx->dd;
284 int i;
285
286 if (ctx->flags & BIT(FLAGS_HMAC)) {
287 struct crypto_ahash *tfm = crypto_ahash_reqtfm(dd->req);
288 struct omap_sham_ctx *tctx = crypto_ahash_ctx(tfm);
289 struct omap_sham_hmac_ctx *bctx = tctx->base;
290 u32 *opad = (u32 *)bctx->opad;
291
292 for (i = 0; i < dd->pdata->digest_size / sizeof(u32); i++) {
293 if (out)
294 opad[i] = omap_sham_read(dd,
295 SHA_REG_ODIGEST(i));
296 else
297 omap_sham_write(dd, SHA_REG_ODIGEST(i),
298 opad[i]);
299 }
220 } 300 }
301
302 omap_sham_copy_hash_omap2(req, out);
221} 303}
222 304
223static void omap_sham_copy_ready_hash(struct ahash_request *req) 305static void omap_sham_copy_ready_hash(struct ahash_request *req)
@@ -225,20 +307,31 @@ static void omap_sham_copy_ready_hash(struct ahash_request *req)
225 struct omap_sham_reqctx *ctx = ahash_request_ctx(req); 307 struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
226 u32 *in = (u32 *)ctx->digest; 308 u32 *in = (u32 *)ctx->digest;
227 u32 *hash = (u32 *)req->result; 309 u32 *hash = (u32 *)req->result;
228 int i; 310 int i, d, big_endian = 0;
229 311
230 if (!hash) 312 if (!hash)
231 return; 313 return;
232 314
233 if (likely(ctx->flags & BIT(FLAGS_SHA1))) { 315 switch (ctx->flags & FLAGS_MODE_MASK) {
234 /* SHA1 results are in big endian */ 316 case FLAGS_MODE_MD5:
235 for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) 317 d = MD5_DIGEST_SIZE / sizeof(u32);
318 break;
319 case FLAGS_MODE_SHA1:
320 /* OMAP2 SHA1 is big endian */
321 if (test_bit(FLAGS_BE32_SHA1, &ctx->dd->flags))
322 big_endian = 1;
323 d = SHA1_DIGEST_SIZE / sizeof(u32);
324 break;
325 default:
326 d = 0;
327 }
328
329 if (big_endian)
330 for (i = 0; i < d; i++)
236 hash[i] = be32_to_cpu(in[i]); 331 hash[i] = be32_to_cpu(in[i]);
237 } else { 332 else
238 /* MD5 results are in little endian */ 333 for (i = 0; i < d; i++)
239 for (i = 0; i < MD5_DIGEST_SIZE / sizeof(u32); i++)
240 hash[i] = le32_to_cpu(in[i]); 334 hash[i] = le32_to_cpu(in[i]);
241 }
242} 335}
243 336
244static int omap_sham_hw_init(struct omap_sham_dev *dd) 337static int omap_sham_hw_init(struct omap_sham_dev *dd)
@@ -246,13 +339,6 @@ static int omap_sham_hw_init(struct omap_sham_dev *dd)
246 pm_runtime_get_sync(dd->dev); 339 pm_runtime_get_sync(dd->dev);
247 340
248 if (!test_bit(FLAGS_INIT, &dd->flags)) { 341 if (!test_bit(FLAGS_INIT, &dd->flags)) {
249 omap_sham_write_mask(dd, SHA_REG_MASK,
250 SHA_REG_MASK_SOFTRESET, SHA_REG_MASK_SOFTRESET);
251
252 if (omap_sham_wait(dd, SHA_REG_SYSSTATUS,
253 SHA_REG_SYSSTATUS_RESETDONE))
254 return -ETIMEDOUT;
255
256 set_bit(FLAGS_INIT, &dd->flags); 342 set_bit(FLAGS_INIT, &dd->flags);
257 dd->err = 0; 343 dd->err = 0;
258 } 344 }
@@ -260,23 +346,23 @@ static int omap_sham_hw_init(struct omap_sham_dev *dd)
260 return 0; 346 return 0;
261} 347}
262 348
263static void omap_sham_write_ctrl(struct omap_sham_dev *dd, size_t length, 349static void omap_sham_write_ctrl_omap2(struct omap_sham_dev *dd, size_t length,
264 int final, int dma) 350 int final, int dma)
265{ 351{
266 struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); 352 struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
267 u32 val = length << 5, mask; 353 u32 val = length << 5, mask;
268 354
269 if (likely(ctx->digcnt)) 355 if (likely(ctx->digcnt))
270 omap_sham_write(dd, SHA_REG_DIGCNT, ctx->digcnt); 356 omap_sham_write(dd, SHA_REG_DIGCNT(dd), ctx->digcnt);
271 357
272 omap_sham_write_mask(dd, SHA_REG_MASK, 358 omap_sham_write_mask(dd, SHA_REG_MASK(dd),
273 SHA_REG_MASK_IT_EN | (dma ? SHA_REG_MASK_DMA_EN : 0), 359 SHA_REG_MASK_IT_EN | (dma ? SHA_REG_MASK_DMA_EN : 0),
274 SHA_REG_MASK_IT_EN | SHA_REG_MASK_DMA_EN); 360 SHA_REG_MASK_IT_EN | SHA_REG_MASK_DMA_EN);
275 /* 361 /*
276 * Setting ALGO_CONST only for the first iteration 362 * Setting ALGO_CONST only for the first iteration
277 * and CLOSE_HASH only for the last one. 363 * and CLOSE_HASH only for the last one.
278 */ 364 */
279 if (ctx->flags & BIT(FLAGS_SHA1)) 365 if ((ctx->flags & FLAGS_MODE_MASK) == FLAGS_MODE_SHA1)
280 val |= SHA_REG_CTRL_ALGO; 366 val |= SHA_REG_CTRL_ALGO;
281 if (!ctx->digcnt) 367 if (!ctx->digcnt)
282 val |= SHA_REG_CTRL_ALGO_CONST; 368 val |= SHA_REG_CTRL_ALGO_CONST;
@@ -289,6 +375,81 @@ static void omap_sham_write_ctrl(struct omap_sham_dev *dd, size_t length,
289 omap_sham_write_mask(dd, SHA_REG_CTRL, val, mask); 375 omap_sham_write_mask(dd, SHA_REG_CTRL, val, mask);
290} 376}
291 377
378static void omap_sham_trigger_omap2(struct omap_sham_dev *dd, size_t length)
379{
380}
381
382static int omap_sham_poll_irq_omap2(struct omap_sham_dev *dd)
383{
384 return omap_sham_wait(dd, SHA_REG_CTRL, SHA_REG_CTRL_INPUT_READY);
385}
386
387static void omap_sham_write_n(struct omap_sham_dev *dd, u32 offset,
388 u32 *value, int count)
389{
390 for (; count--; value++, offset += 4)
391 omap_sham_write(dd, offset, *value);
392}
393
394static void omap_sham_write_ctrl_omap4(struct omap_sham_dev *dd, size_t length,
395 int final, int dma)
396{
397 struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
398 u32 val, mask;
399
400 /*
401 * Setting ALGO_CONST only for the first iteration and
402 * CLOSE_HASH only for the last one. Note that flags mode bits
403 * correspond to algorithm encoding in mode register.
404 */
405 val = (ctx->flags & FLAGS_MODE_MASK) >> (FLAGS_MODE_SHIFT - 1);
406 if (!ctx->digcnt) {
407 struct crypto_ahash *tfm = crypto_ahash_reqtfm(dd->req);
408 struct omap_sham_ctx *tctx = crypto_ahash_ctx(tfm);
409 struct omap_sham_hmac_ctx *bctx = tctx->base;
410
411 val |= SHA_REG_MODE_ALGO_CONSTANT;
412
413 if (ctx->flags & BIT(FLAGS_HMAC)) {
414 val |= SHA_REG_MODE_HMAC_KEY_PROC;
415 omap_sham_write_n(dd, SHA_REG_ODIGEST(0),
416 (u32 *)bctx->ipad,
417 SHA1_BLOCK_SIZE / sizeof(u32));
418 ctx->digcnt += SHA1_BLOCK_SIZE;
419 }
420 }
421
422 if (final) {
423 val |= SHA_REG_MODE_CLOSE_HASH;
424
425 if (ctx->flags & BIT(FLAGS_HMAC))
426 val |= SHA_REG_MODE_HMAC_OUTER_HASH;
427 }
428
429 mask = SHA_REG_MODE_ALGO_CONSTANT | SHA_REG_MODE_CLOSE_HASH |
430 SHA_REG_MODE_ALGO_MASK | SHA_REG_MODE_HMAC_OUTER_HASH |
431 SHA_REG_MODE_HMAC_KEY_PROC;
432
433 dev_dbg(dd->dev, "ctrl: %08x, flags: %08lx\n", val, ctx->flags);
434 omap_sham_write_mask(dd, SHA_REG_MODE, val, mask);
435 omap_sham_write(dd, SHA_REG_IRQENA, SHA_REG_IRQENA_OUTPUT_RDY);
436 omap_sham_write_mask(dd, SHA_REG_MASK(dd),
437 SHA_REG_MASK_IT_EN |
438 (dma ? SHA_REG_MASK_DMA_EN : 0),
439 SHA_REG_MASK_IT_EN | SHA_REG_MASK_DMA_EN);
440}
441
442static void omap_sham_trigger_omap4(struct omap_sham_dev *dd, size_t length)
443{
444 omap_sham_write(dd, SHA_REG_LENGTH, length);
445}
446
447static int omap_sham_poll_irq_omap4(struct omap_sham_dev *dd)
448{
449 return omap_sham_wait(dd, SHA_REG_IRQSTATUS,
450 SHA_REG_IRQSTATUS_INPUT_RDY);
451}
452
292static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf, 453static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf,
293 size_t length, int final) 454 size_t length, int final)
294{ 455{
@@ -299,12 +460,13 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf,
299 dev_dbg(dd->dev, "xmit_cpu: digcnt: %d, length: %d, final: %d\n", 460 dev_dbg(dd->dev, "xmit_cpu: digcnt: %d, length: %d, final: %d\n",
300 ctx->digcnt, length, final); 461 ctx->digcnt, length, final);
301 462
302 omap_sham_write_ctrl(dd, length, final, 0); 463 dd->pdata->write_ctrl(dd, length, final, 0);
464 dd->pdata->trigger(dd, length);
303 465
304 /* should be non-zero before next lines to disable clocks later */ 466 /* should be non-zero before next lines to disable clocks later */
305 ctx->digcnt += length; 467 ctx->digcnt += length;
306 468
307 if (omap_sham_wait(dd, SHA_REG_CTRL, SHA_REG_CTRL_INPUT_READY)) 469 if (dd->pdata->poll_irq(dd))
308 return -ETIMEDOUT; 470 return -ETIMEDOUT;
309 471
310 if (final) 472 if (final)
@@ -315,7 +477,7 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf,
315 len32 = DIV_ROUND_UP(length, sizeof(u32)); 477 len32 = DIV_ROUND_UP(length, sizeof(u32));
316 478
317 for (count = 0; count < len32; count++) 479 for (count = 0; count < len32; count++)
318 omap_sham_write(dd, SHA_REG_DIN(count), buffer[count]); 480 omap_sham_write(dd, SHA_REG_DIN(dd, count), buffer[count]);
319 481
320 return -EINPROGRESS; 482 return -EINPROGRESS;
321} 483}
@@ -341,7 +503,7 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
341 503
342 memset(&cfg, 0, sizeof(cfg)); 504 memset(&cfg, 0, sizeof(cfg));
343 505
344 cfg.dst_addr = dd->phys_base + SHA_REG_DIN(0); 506 cfg.dst_addr = dd->phys_base + SHA_REG_DIN(dd, 0);
345 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 507 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
346 cfg.dst_maxburst = DST_MAXBURST; 508 cfg.dst_maxburst = DST_MAXBURST;
347 509
@@ -381,7 +543,7 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
381 tx->callback = omap_sham_dma_callback; 543 tx->callback = omap_sham_dma_callback;
382 tx->callback_param = dd; 544 tx->callback_param = dd;
383 545
384 omap_sham_write_ctrl(dd, length, final, 1); 546 dd->pdata->write_ctrl(dd, length, final, 1);
385 547
386 ctx->digcnt += length; 548 ctx->digcnt += length;
387 549
@@ -393,6 +555,8 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
393 dmaengine_submit(tx); 555 dmaengine_submit(tx);
394 dma_async_issue_pending(dd->dma_lch); 556 dma_async_issue_pending(dd->dma_lch);
395 557
558 dd->pdata->trigger(dd, length);
559
396 return -EINPROGRESS; 560 return -EINPROGRESS;
397} 561}
398 562
@@ -450,7 +614,7 @@ static int omap_sham_xmit_dma_map(struct omap_sham_dev *dd,
450 ctx->flags &= ~BIT(FLAGS_SG); 614 ctx->flags &= ~BIT(FLAGS_SG);
451 615
452 ret = omap_sham_xmit_dma(dd, ctx->dma_addr, length, final, 0); 616 ret = omap_sham_xmit_dma(dd, ctx->dma_addr, length, final, 0);
453 if (ret) 617 if (ret != -EINPROGRESS)
454 dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen, 618 dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen,
455 DMA_TO_DEVICE); 619 DMA_TO_DEVICE);
456 620
@@ -544,7 +708,7 @@ static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
544 final = (ctx->flags & BIT(FLAGS_FINUP)) && !ctx->total; 708 final = (ctx->flags & BIT(FLAGS_FINUP)) && !ctx->total;
545 709
546 ret = omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, final, 1); 710 ret = omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, final, 1);
547 if (ret) 711 if (ret != -EINPROGRESS)
548 dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE); 712 dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE);
549 713
550 return ret; 714 return ret;
@@ -609,18 +773,27 @@ static int omap_sham_init(struct ahash_request *req)
609 dev_dbg(dd->dev, "init: digest size: %d\n", 773 dev_dbg(dd->dev, "init: digest size: %d\n",
610 crypto_ahash_digestsize(tfm)); 774 crypto_ahash_digestsize(tfm));
611 775
612 if (crypto_ahash_digestsize(tfm) == SHA1_DIGEST_SIZE) 776 switch (crypto_ahash_digestsize(tfm)) {
613 ctx->flags |= BIT(FLAGS_SHA1); 777 case MD5_DIGEST_SIZE:
778 ctx->flags |= FLAGS_MODE_MD5;
779 break;
780 case SHA1_DIGEST_SIZE:
781 ctx->flags |= FLAGS_MODE_SHA1;
782 break;
783 }
614 784
615 ctx->bufcnt = 0; 785 ctx->bufcnt = 0;
616 ctx->digcnt = 0; 786 ctx->digcnt = 0;
617 ctx->buflen = BUFLEN; 787 ctx->buflen = BUFLEN;
618 788
619 if (tctx->flags & BIT(FLAGS_HMAC)) { 789 if (tctx->flags & BIT(FLAGS_HMAC)) {
620 struct omap_sham_hmac_ctx *bctx = tctx->base; 790 if (!test_bit(FLAGS_AUTO_XOR, &dd->flags)) {
791 struct omap_sham_hmac_ctx *bctx = tctx->base;
792
793 memcpy(ctx->buffer, bctx->ipad, SHA1_MD5_BLOCK_SIZE);
794 ctx->bufcnt = SHA1_MD5_BLOCK_SIZE;
795 }
621 796
622 memcpy(ctx->buffer, bctx->ipad, SHA1_MD5_BLOCK_SIZE);
623 ctx->bufcnt = SHA1_MD5_BLOCK_SIZE;
624 ctx->flags |= BIT(FLAGS_HMAC); 797 ctx->flags |= BIT(FLAGS_HMAC);
625 } 798 }
626 799
@@ -697,7 +870,8 @@ static int omap_sham_finish(struct ahash_request *req)
697 870
698 if (ctx->digcnt) { 871 if (ctx->digcnt) {
699 omap_sham_copy_ready_hash(req); 872 omap_sham_copy_ready_hash(req);
700 if (ctx->flags & BIT(FLAGS_HMAC)) 873 if ((ctx->flags & BIT(FLAGS_HMAC)) &&
874 !test_bit(FLAGS_AUTO_XOR, &dd->flags))
701 err = omap_sham_finish_hmac(req); 875 err = omap_sham_finish_hmac(req);
702 } 876 }
703 877
@@ -712,7 +886,7 @@ static void omap_sham_finish_req(struct ahash_request *req, int err)
712 struct omap_sham_dev *dd = ctx->dd; 886 struct omap_sham_dev *dd = ctx->dd;
713 887
714 if (!err) { 888 if (!err) {
715 omap_sham_copy_hash(req, 1); 889 dd->pdata->copy_hash(req, 1);
716 if (test_bit(FLAGS_FINAL, &dd->flags)) 890 if (test_bit(FLAGS_FINAL, &dd->flags))
717 err = omap_sham_finish(req); 891 err = omap_sham_finish(req);
718 } else { 892 } else {
@@ -772,7 +946,7 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd,
772 946
773 if (ctx->digcnt) 947 if (ctx->digcnt)
774 /* request has changed - restore hash */ 948 /* request has changed - restore hash */
775 omap_sham_copy_hash(req, 0); 949 dd->pdata->copy_hash(req, 0);
776 950
777 if (ctx->op == OP_UPDATE) { 951 if (ctx->op == OP_UPDATE) {
778 err = omap_sham_update_req(dd); 952 err = omap_sham_update_req(dd);
@@ -911,7 +1085,21 @@ static int omap_sham_setkey(struct crypto_ahash *tfm, const u8 *key,
911 struct omap_sham_hmac_ctx *bctx = tctx->base; 1085 struct omap_sham_hmac_ctx *bctx = tctx->base;
912 int bs = crypto_shash_blocksize(bctx->shash); 1086 int bs = crypto_shash_blocksize(bctx->shash);
913 int ds = crypto_shash_digestsize(bctx->shash); 1087 int ds = crypto_shash_digestsize(bctx->shash);
1088 struct omap_sham_dev *dd = NULL, *tmp;
914 int err, i; 1089 int err, i;
1090
1091 spin_lock_bh(&sham.lock);
1092 if (!tctx->dd) {
1093 list_for_each_entry(tmp, &sham.dev_list, list) {
1094 dd = tmp;
1095 break;
1096 }
1097 tctx->dd = dd;
1098 } else {
1099 dd = tctx->dd;
1100 }
1101 spin_unlock_bh(&sham.lock);
1102
915 err = crypto_shash_setkey(tctx->fallback, key, keylen); 1103 err = crypto_shash_setkey(tctx->fallback, key, keylen);
916 if (err) 1104 if (err)
917 return err; 1105 return err;
@@ -928,11 +1116,14 @@ static int omap_sham_setkey(struct crypto_ahash *tfm, const u8 *key,
928 } 1116 }
929 1117
930 memset(bctx->ipad + keylen, 0, bs - keylen); 1118 memset(bctx->ipad + keylen, 0, bs - keylen);
931 memcpy(bctx->opad, bctx->ipad, bs);
932 1119
933 for (i = 0; i < bs; i++) { 1120 if (!test_bit(FLAGS_AUTO_XOR, &dd->flags)) {
934 bctx->ipad[i] ^= 0x36; 1121 memcpy(bctx->opad, bctx->ipad, bs);
935 bctx->opad[i] ^= 0x5c; 1122
1123 for (i = 0; i < bs; i++) {
1124 bctx->ipad[i] ^= 0x36;
1125 bctx->opad[i] ^= 0x5c;
1126 }
936 } 1127 }
937 1128
938 return err; 1129 return err;
@@ -1137,7 +1328,19 @@ finish:
1137 omap_sham_finish_req(dd->req, err); 1328 omap_sham_finish_req(dd->req, err);
1138} 1329}
1139 1330
1140static irqreturn_t omap_sham_irq(int irq, void *dev_id) 1331static irqreturn_t omap_sham_irq_common(struct omap_sham_dev *dd)
1332{
1333 if (!test_bit(FLAGS_BUSY, &dd->flags)) {
1334 dev_warn(dd->dev, "Interrupt when no active requests.\n");
1335 } else {
1336 set_bit(FLAGS_OUTPUT_READY, &dd->flags);
1337 tasklet_schedule(&dd->done_task);
1338 }
1339
1340 return IRQ_HANDLED;
1341}
1342
1343static irqreturn_t omap_sham_irq_omap2(int irq, void *dev_id)
1141{ 1344{
1142 struct omap_sham_dev *dd = dev_id; 1345 struct omap_sham_dev *dd = dev_id;
1143 1346
@@ -1149,21 +1352,67 @@ static irqreturn_t omap_sham_irq(int irq, void *dev_id)
1149 SHA_REG_CTRL_OUTPUT_READY); 1352 SHA_REG_CTRL_OUTPUT_READY);
1150 omap_sham_read(dd, SHA_REG_CTRL); 1353 omap_sham_read(dd, SHA_REG_CTRL);
1151 1354
1152 if (!test_bit(FLAGS_BUSY, &dd->flags)) { 1355 return omap_sham_irq_common(dd);
1153 dev_warn(dd->dev, "Interrupt when no active requests.\n"); 1356}
1154 return IRQ_HANDLED;
1155 }
1156 1357
1157 set_bit(FLAGS_OUTPUT_READY, &dd->flags); 1358static irqreturn_t omap_sham_irq_omap4(int irq, void *dev_id)
1158 tasklet_schedule(&dd->done_task); 1359{
1360 struct omap_sham_dev *dd = dev_id;
1159 1361
1160 return IRQ_HANDLED; 1362 omap_sham_write_mask(dd, SHA_REG_MASK(dd), 0, SHA_REG_MASK_IT_EN);
1363
1364 return omap_sham_irq_common(dd);
1161} 1365}
1162 1366
1367static const struct omap_sham_pdata omap_sham_pdata_omap2 = {
1368 .flags = BIT(FLAGS_BE32_SHA1),
1369 .digest_size = SHA1_DIGEST_SIZE,
1370 .copy_hash = omap_sham_copy_hash_omap2,
1371 .write_ctrl = omap_sham_write_ctrl_omap2,
1372 .trigger = omap_sham_trigger_omap2,
1373 .poll_irq = omap_sham_poll_irq_omap2,
1374 .intr_hdlr = omap_sham_irq_omap2,
1375 .idigest_ofs = 0x00,
1376 .din_ofs = 0x1c,
1377 .digcnt_ofs = 0x14,
1378 .rev_ofs = 0x5c,
1379 .mask_ofs = 0x60,
1380 .sysstatus_ofs = 0x64,
1381 .major_mask = 0xf0,
1382 .major_shift = 4,
1383 .minor_mask = 0x0f,
1384 .minor_shift = 0,
1385};
1386
1163#ifdef CONFIG_OF 1387#ifdef CONFIG_OF
1388static const struct omap_sham_pdata omap_sham_pdata_omap4 = {
1389 .flags = BIT(FLAGS_AUTO_XOR),
1390 .digest_size = SHA256_DIGEST_SIZE,
1391 .copy_hash = omap_sham_copy_hash_omap4,
1392 .write_ctrl = omap_sham_write_ctrl_omap4,
1393 .trigger = omap_sham_trigger_omap4,
1394 .poll_irq = omap_sham_poll_irq_omap4,
1395 .intr_hdlr = omap_sham_irq_omap4,
1396 .idigest_ofs = 0x020,
1397 .din_ofs = 0x080,
1398 .digcnt_ofs = 0x040,
1399 .rev_ofs = 0x100,
1400 .mask_ofs = 0x110,
1401 .sysstatus_ofs = 0x114,
1402 .major_mask = 0x0700,
1403 .major_shift = 8,
1404 .minor_mask = 0x003f,
1405 .minor_shift = 0,
1406};
1407
1164static const struct of_device_id omap_sham_of_match[] = { 1408static const struct of_device_id omap_sham_of_match[] = {
1165 { 1409 {
1166 .compatible = "ti,omap2-sham", 1410 .compatible = "ti,omap2-sham",
1411 .data = &omap_sham_pdata_omap2,
1412 },
1413 {
1414 .compatible = "ti,omap4-sham",
1415 .data = &omap_sham_pdata_omap4,
1167 }, 1416 },
1168 {}, 1417 {},
1169}; 1418};
@@ -1198,6 +1447,7 @@ static int omap_sham_get_res_of(struct omap_sham_dev *dd,
1198 } 1447 }
1199 1448
1200 dd->dma = -1; /* Dummy value that's unused */ 1449 dd->dma = -1; /* Dummy value that's unused */
1450 dd->pdata = match->data;
1201 1451
1202err: 1452err:
1203 return err; 1453 return err;
@@ -1243,6 +1493,9 @@ static int omap_sham_get_res_pdev(struct omap_sham_dev *dd,
1243 } 1493 }
1244 dd->dma = r->start; 1494 dd->dma = r->start;
1245 1495
1496 /* Only OMAP2/3 can be non-DT */
1497 dd->pdata = &omap_sham_pdata_omap2;
1498
1246err: 1499err:
1247 return err; 1500 return err;
1248} 1501}
@@ -1254,6 +1507,7 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
1254 struct resource res; 1507 struct resource res;
1255 dma_cap_mask_t mask; 1508 dma_cap_mask_t mask;
1256 int err, i, j; 1509 int err, i, j;
1510 u32 rev;
1257 1511
1258 dd = kzalloc(sizeof(struct omap_sham_dev), GFP_KERNEL); 1512 dd = kzalloc(sizeof(struct omap_sham_dev), GFP_KERNEL);
1259 if (dd == NULL) { 1513 if (dd == NULL) {
@@ -1282,8 +1536,8 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
1282 } 1536 }
1283 dd->phys_base = res.start; 1537 dd->phys_base = res.start;
1284 1538
1285 err = request_irq(dd->irq, omap_sham_irq, 1539 err = request_irq(dd->irq, dd->pdata->intr_hdlr, IRQF_TRIGGER_LOW,
1286 IRQF_TRIGGER_LOW, dev_name(dev), dd); 1540 dev_name(dev), dd);
1287 if (err) { 1541 if (err) {
1288 dev_err(dev, "unable to request irq.\n"); 1542 dev_err(dev, "unable to request irq.\n");
1289 goto res_err; 1543 goto res_err;
@@ -1301,21 +1555,16 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
1301 goto dma_err; 1555 goto dma_err;
1302 } 1556 }
1303 1557
1304 dd->io_base = ioremap(dd->phys_base, SZ_4K); 1558 dd->flags |= dd->pdata->flags;
1305 if (!dd->io_base) {
1306 dev_err(dev, "can't ioremap\n");
1307 err = -ENOMEM;
1308 goto io_err;
1309 }
1310 1559
1311 pm_runtime_enable(dev); 1560 pm_runtime_enable(dev);
1312 pm_runtime_get_sync(dev); 1561 pm_runtime_get_sync(dev);
1562 rev = omap_sham_read(dd, SHA_REG_REV(dd));
1563 pm_runtime_put_sync(&pdev->dev);
1313 1564
1314 dev_info(dev, "hw accel on OMAP rev %u.%u\n", 1565 dev_info(dev, "hw accel on OMAP rev %u.%u\n",
1315 (omap_sham_read(dd, SHA_REG_REV) & SHA_REG_REV_MAJOR) >> 4, 1566 (rev & dd->pdata->major_mask) >> dd->pdata->major_shift,
1316 omap_sham_read(dd, SHA_REG_REV) & SHA_REG_REV_MINOR); 1567 (rev & dd->pdata->minor_mask) >> dd->pdata->minor_shift);
1317
1318 pm_runtime_put_sync(&pdev->dev);
1319 1568
1320 spin_lock(&sham.lock); 1569 spin_lock(&sham.lock);
1321 list_add_tail(&dd->list, &sham.dev_list); 1570 list_add_tail(&dd->list, &sham.dev_list);
@@ -1333,7 +1582,6 @@ err_algs:
1333 for (j = 0; j < i; j++) 1582 for (j = 0; j < i; j++)
1334 crypto_unregister_ahash(&algs[j]); 1583 crypto_unregister_ahash(&algs[j]);
1335 pm_runtime_disable(dev); 1584 pm_runtime_disable(dev);
1336io_err:
1337 dma_release_channel(dd->dma_lch); 1585 dma_release_channel(dd->dma_lch);
1338dma_err: 1586dma_err:
1339 free_irq(dd->irq, dd); 1587 free_irq(dd->irq, dd);