Merge remote branch 'alsa/devel' into topic/misc
[pandora-kernel.git] / drivers / crypto / omap-sham.c
1 /*
2  * Cryptographic API.
3  *
4  * Support for OMAP SHA1/MD5 HW acceleration.
5  *
6  * Copyright (c) 2010 Nokia Corporation
7  * Author: Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
8  *
9  * 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  * by the Free Software Foundation.
12  *
13  * Some ideas are from old omap-sha1-md5.c driver.
14  */
15
16 #define pr_fmt(fmt) "%s: " fmt, __func__
17
18 #include <linux/err.h>
19 #include <linux/device.h>
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/errno.h>
23 #include <linux/interrupt.h>
24 #include <linux/kernel.h>
25 #include <linux/clk.h>
26 #include <linux/irq.h>
27 #include <linux/io.h>
28 #include <linux/platform_device.h>
29 #include <linux/scatterlist.h>
30 #include <linux/dma-mapping.h>
31 #include <linux/delay.h>
32 #include <linux/crypto.h>
33 #include <linux/cryptohash.h>
34 #include <crypto/scatterwalk.h>
35 #include <crypto/algapi.h>
36 #include <crypto/sha.h>
37 #include <crypto/hash.h>
38 #include <crypto/internal/hash.h>
39
40 #include <plat/cpu.h>
41 #include <plat/dma.h>
42 #include <mach/irqs.h>
43
44 #define SHA_REG_DIGEST(x)               (0x00 + ((x) * 0x04))
45 #define SHA_REG_DIN(x)                  (0x1C + ((x) * 0x04))
46
47 #define SHA1_MD5_BLOCK_SIZE             SHA1_BLOCK_SIZE
48 #define MD5_DIGEST_SIZE                 16
49
50 #define SHA_REG_DIGCNT                  0x14
51
52 #define SHA_REG_CTRL                    0x18
53 #define SHA_REG_CTRL_LENGTH             (0xFFFFFFFF << 5)
54 #define SHA_REG_CTRL_CLOSE_HASH         (1 << 4)
55 #define SHA_REG_CTRL_ALGO_CONST         (1 << 3)
56 #define SHA_REG_CTRL_ALGO               (1 << 2)
57 #define SHA_REG_CTRL_INPUT_READY        (1 << 1)
58 #define SHA_REG_CTRL_OUTPUT_READY       (1 << 0)
59
60 #define SHA_REG_REV                     0x5C
61 #define SHA_REG_REV_MAJOR               0xF0
62 #define SHA_REG_REV_MINOR               0x0F
63
64 #define SHA_REG_MASK                    0x60
65 #define SHA_REG_MASK_DMA_EN             (1 << 3)
66 #define SHA_REG_MASK_IT_EN              (1 << 2)
67 #define SHA_REG_MASK_SOFTRESET          (1 << 1)
68 #define SHA_REG_AUTOIDLE                (1 << 0)
69
70 #define SHA_REG_SYSSTATUS               0x64
71 #define SHA_REG_SYSSTATUS_RESETDONE     (1 << 0)
72
73 #define DEFAULT_TIMEOUT_INTERVAL        HZ
74
75 #define FLAGS_FIRST             0x0001
76 #define FLAGS_FINUP             0x0002
77 #define FLAGS_FINAL             0x0004
78 #define FLAGS_FAST              0x0008
79 #define FLAGS_SHA1              0x0010
80 #define FLAGS_DMA_ACTIVE        0x0020
81 #define FLAGS_OUTPUT_READY      0x0040
82 #define FLAGS_CLEAN             0x0080
83 #define FLAGS_INIT              0x0100
84 #define FLAGS_CPU               0x0200
85 #define FLAGS_HMAC              0x0400
86
87 /* 3rd byte */
88 #define FLAGS_BUSY              16
89
90 #define OP_UPDATE       1
91 #define OP_FINAL        2
92
93 struct omap_sham_dev;
94
95 struct omap_sham_reqctx {
96         struct omap_sham_dev    *dd;
97         unsigned long           flags;
98         unsigned long           op;
99
100         size_t                  digcnt;
101         u8                      *buffer;
102         size_t                  bufcnt;
103         size_t                  buflen;
104         dma_addr_t              dma_addr;
105
106         /* walk state */
107         struct scatterlist      *sg;
108         unsigned int            offset; /* offset in current sg */
109         unsigned int            total;  /* total request */
110 };
111
112 struct omap_sham_hmac_ctx {
113         struct crypto_shash     *shash;
114         u8                      ipad[SHA1_MD5_BLOCK_SIZE];
115         u8                      opad[SHA1_MD5_BLOCK_SIZE];
116 };
117
118 struct omap_sham_ctx {
119         struct omap_sham_dev    *dd;
120
121         unsigned long           flags;
122
123         /* fallback stuff */
124         struct crypto_shash     *fallback;
125
126         struct omap_sham_hmac_ctx base[0];
127 };
128
129 #define OMAP_SHAM_QUEUE_LENGTH  1
130
131 struct omap_sham_dev {
132         struct list_head        list;
133         unsigned long           phys_base;
134         struct device           *dev;
135         void __iomem            *io_base;
136         int                     irq;
137         struct clk              *iclk;
138         spinlock_t              lock;
139         int                     dma;
140         int                     dma_lch;
141         struct tasklet_struct   done_task;
142         struct tasklet_struct   queue_task;
143
144         unsigned long           flags;
145         struct crypto_queue     queue;
146         struct ahash_request    *req;
147 };
148
149 struct omap_sham_drv {
150         struct list_head        dev_list;
151         spinlock_t              lock;
152         unsigned long           flags;
153 };
154
155 static struct omap_sham_drv sham = {
156         .dev_list = LIST_HEAD_INIT(sham.dev_list),
157         .lock = __SPIN_LOCK_UNLOCKED(sham.lock),
158 };
159
160 static inline u32 omap_sham_read(struct omap_sham_dev *dd, u32 offset)
161 {
162         return __raw_readl(dd->io_base + offset);
163 }
164
165 static inline void omap_sham_write(struct omap_sham_dev *dd,
166                                         u32 offset, u32 value)
167 {
168         __raw_writel(value, dd->io_base + offset);
169 }
170
171 static inline void omap_sham_write_mask(struct omap_sham_dev *dd, u32 address,
172                                         u32 value, u32 mask)
173 {
174         u32 val;
175
176         val = omap_sham_read(dd, address);
177         val &= ~mask;
178         val |= value;
179         omap_sham_write(dd, address, val);
180 }
181
182 static inline int omap_sham_wait(struct omap_sham_dev *dd, u32 offset, u32 bit)
183 {
184         unsigned long timeout = jiffies + DEFAULT_TIMEOUT_INTERVAL;
185
186         while (!(omap_sham_read(dd, offset) & bit)) {
187                 if (time_is_before_jiffies(timeout))
188                         return -ETIMEDOUT;
189         }
190
191         return 0;
192 }
193
194 static void omap_sham_copy_hash(struct ahash_request *req, int out)
195 {
196         struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
197         u32 *hash = (u32 *)req->result;
198         int i;
199
200         if (likely(ctx->flags & FLAGS_SHA1)) {
201                 /* SHA1 results are in big endian */
202                 for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++)
203                         if (out)
204                                 hash[i] = be32_to_cpu(omap_sham_read(ctx->dd,
205                                                         SHA_REG_DIGEST(i)));
206                         else
207                                 omap_sham_write(ctx->dd, SHA_REG_DIGEST(i),
208                                                         cpu_to_be32(hash[i]));
209         } else {
210                 /* MD5 results are in little endian */
211                 for (i = 0; i < MD5_DIGEST_SIZE / sizeof(u32); i++)
212                         if (out)
213                                 hash[i] = le32_to_cpu(omap_sham_read(ctx->dd,
214                                                         SHA_REG_DIGEST(i)));
215                         else
216                                 omap_sham_write(ctx->dd, SHA_REG_DIGEST(i),
217                                                         cpu_to_le32(hash[i]));
218         }
219 }
220
221 static int omap_sham_write_ctrl(struct omap_sham_dev *dd, size_t length,
222                                  int final, int dma)
223 {
224         struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
225         u32 val = length << 5, mask;
226
227         if (unlikely(!ctx->digcnt)) {
228
229                 clk_enable(dd->iclk);
230
231                 if (!(dd->flags & FLAGS_INIT)) {
232                         omap_sham_write_mask(dd, SHA_REG_MASK,
233                                 SHA_REG_MASK_SOFTRESET, SHA_REG_MASK_SOFTRESET);
234
235                         if (omap_sham_wait(dd, SHA_REG_SYSSTATUS,
236                                                 SHA_REG_SYSSTATUS_RESETDONE))
237                                 return -ETIMEDOUT;
238
239                         dd->flags |= FLAGS_INIT;
240                 }
241         } else {
242                 omap_sham_write(dd, SHA_REG_DIGCNT, ctx->digcnt);
243         }
244
245         omap_sham_write_mask(dd, SHA_REG_MASK,
246                 SHA_REG_MASK_IT_EN | (dma ? SHA_REG_MASK_DMA_EN : 0),
247                 SHA_REG_MASK_IT_EN | SHA_REG_MASK_DMA_EN);
248         /*
249          * Setting ALGO_CONST only for the first iteration
250          * and CLOSE_HASH only for the last one.
251          */
252         if (ctx->flags & FLAGS_SHA1)
253                 val |= SHA_REG_CTRL_ALGO;
254         if (!ctx->digcnt)
255                 val |= SHA_REG_CTRL_ALGO_CONST;
256         if (final)
257                 val |= SHA_REG_CTRL_CLOSE_HASH;
258
259         mask = SHA_REG_CTRL_ALGO_CONST | SHA_REG_CTRL_CLOSE_HASH |
260                         SHA_REG_CTRL_ALGO | SHA_REG_CTRL_LENGTH;
261
262         omap_sham_write_mask(dd, SHA_REG_CTRL, val, mask);
263
264         return 0;
265 }
266
267 static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf,
268                               size_t length, int final)
269 {
270         struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
271         int err, count, len32;
272         const u32 *buffer = (const u32 *)buf;
273
274         dev_dbg(dd->dev, "xmit_cpu: digcnt: %d, length: %d, final: %d\n",
275                                                 ctx->digcnt, length, final);
276
277         err = omap_sham_write_ctrl(dd, length, final, 0);
278         if (err)
279                 return err;
280
281         if (omap_sham_wait(dd, SHA_REG_CTRL, SHA_REG_CTRL_INPUT_READY))
282                 return -ETIMEDOUT;
283
284         ctx->digcnt += length;
285
286         if (final)
287                 ctx->flags |= FLAGS_FINAL; /* catch last interrupt */
288
289         len32 = DIV_ROUND_UP(length, sizeof(u32));
290
291         for (count = 0; count < len32; count++)
292                 omap_sham_write(dd, SHA_REG_DIN(count), buffer[count]);
293
294         return -EINPROGRESS;
295 }
296
297 static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
298                               size_t length, int final)
299 {
300         struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
301         int err, len32;
302
303         dev_dbg(dd->dev, "xmit_dma: digcnt: %d, length: %d, final: %d\n",
304                                                 ctx->digcnt, length, final);
305
306         /* flush cache entries related to our page */
307         if (dma_addr == ctx->dma_addr)
308                 dma_sync_single_for_device(dd->dev, dma_addr, length,
309                                            DMA_TO_DEVICE);
310
311         len32 = DIV_ROUND_UP(length, sizeof(u32));
312
313         omap_set_dma_transfer_params(dd->dma_lch, OMAP_DMA_DATA_TYPE_S32, len32,
314                         1, OMAP_DMA_SYNC_PACKET, dd->dma, OMAP_DMA_DST_SYNC);
315
316         omap_set_dma_src_params(dd->dma_lch, 0, OMAP_DMA_AMODE_POST_INC,
317                                 dma_addr, 0, 0);
318
319         err = omap_sham_write_ctrl(dd, length, final, 1);
320         if (err)
321                 return err;
322
323         ctx->digcnt += length;
324
325         if (final)
326                 ctx->flags |= FLAGS_FINAL; /* catch last interrupt */
327
328         dd->flags |= FLAGS_DMA_ACTIVE;
329
330         omap_start_dma(dd->dma_lch);
331
332         return -EINPROGRESS;
333 }
334
335 static size_t omap_sham_append_buffer(struct omap_sham_reqctx *ctx,
336                                 const u8 *data, size_t length)
337 {
338         size_t count = min(length, ctx->buflen - ctx->bufcnt);
339
340         count = min(count, ctx->total);
341         if (count <= 0)
342                 return 0;
343         memcpy(ctx->buffer + ctx->bufcnt, data, count);
344         ctx->bufcnt += count;
345
346         return count;
347 }
348
349 static size_t omap_sham_append_sg(struct omap_sham_reqctx *ctx)
350 {
351         size_t count;
352
353         while (ctx->sg) {
354                 count = omap_sham_append_buffer(ctx,
355                                 sg_virt(ctx->sg) + ctx->offset,
356                                 ctx->sg->length - ctx->offset);
357                 if (!count)
358                         break;
359                 ctx->offset += count;
360                 ctx->total -= count;
361                 if (ctx->offset == ctx->sg->length) {
362                         ctx->sg = sg_next(ctx->sg);
363                         if (ctx->sg)
364                                 ctx->offset = 0;
365                         else
366                                 ctx->total = 0;
367                 }
368         }
369
370         return 0;
371 }
372
373 static int omap_sham_update_dma_slow(struct omap_sham_dev *dd)
374 {
375         struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
376         unsigned int final;
377         size_t count;
378
379         if (!ctx->total)
380                 return 0;
381
382         omap_sham_append_sg(ctx);
383
384         final = (ctx->flags & FLAGS_FINUP) && !ctx->total;
385
386         dev_dbg(dd->dev, "slow: bufcnt: %u, digcnt: %d, final: %d\n",
387                                          ctx->bufcnt, ctx->digcnt, final);
388
389         if (final || (ctx->bufcnt == ctx->buflen && ctx->total)) {
390                 count = ctx->bufcnt;
391                 ctx->bufcnt = 0;
392                 return omap_sham_xmit_dma(dd, ctx->dma_addr, count, final);
393         }
394
395         return 0;
396 }
397
398 static int omap_sham_update_dma_fast(struct omap_sham_dev *dd)
399 {
400         struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
401         unsigned int length;
402
403         ctx->flags |= FLAGS_FAST;
404
405         length = min(ctx->total, sg_dma_len(ctx->sg));
406         ctx->total = length;
407
408         if (!dma_map_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE)) {
409                 dev_err(dd->dev, "dma_map_sg  error\n");
410                 return -EINVAL;
411         }
412
413         ctx->total -= length;
414
415         return omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, 1);
416 }
417
418 static int omap_sham_update_cpu(struct omap_sham_dev *dd)
419 {
420         struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
421         int bufcnt;
422
423         omap_sham_append_sg(ctx);
424         bufcnt = ctx->bufcnt;
425         ctx->bufcnt = 0;
426
427         return omap_sham_xmit_cpu(dd, ctx->buffer, bufcnt, 1);
428 }
429
430 static int omap_sham_update_dma_stop(struct omap_sham_dev *dd)
431 {
432         struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
433
434         omap_stop_dma(dd->dma_lch);
435         if (ctx->flags & FLAGS_FAST)
436                 dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE);
437
438         return 0;
439 }
440
441 static void omap_sham_cleanup(struct ahash_request *req)
442 {
443         struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
444         struct omap_sham_dev *dd = ctx->dd;
445         unsigned long flags;
446
447         spin_lock_irqsave(&dd->lock, flags);
448         if (ctx->flags & FLAGS_CLEAN) {
449                 spin_unlock_irqrestore(&dd->lock, flags);
450                 return;
451         }
452         ctx->flags |= FLAGS_CLEAN;
453         spin_unlock_irqrestore(&dd->lock, flags);
454
455         if (ctx->digcnt)
456                 clk_disable(dd->iclk);
457
458         if (ctx->dma_addr)
459                 dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen,
460                                  DMA_TO_DEVICE);
461
462         if (ctx->buffer)
463                 free_page((unsigned long)ctx->buffer);
464
465         dev_dbg(dd->dev, "digcnt: %d, bufcnt: %d\n", ctx->digcnt, ctx->bufcnt);
466 }
467
468 static int omap_sham_init(struct ahash_request *req)
469 {
470         struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
471         struct omap_sham_ctx *tctx = crypto_ahash_ctx(tfm);
472         struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
473         struct omap_sham_dev *dd = NULL, *tmp;
474
475         spin_lock_bh(&sham.lock);
476         if (!tctx->dd) {
477                 list_for_each_entry(tmp, &sham.dev_list, list) {
478                         dd = tmp;
479                         break;
480                 }
481                 tctx->dd = dd;
482         } else {
483                 dd = tctx->dd;
484         }
485         spin_unlock_bh(&sham.lock);
486
487         ctx->dd = dd;
488
489         ctx->flags = 0;
490
491         ctx->flags |= FLAGS_FIRST;
492
493         dev_dbg(dd->dev, "init: digest size: %d\n",
494                 crypto_ahash_digestsize(tfm));
495
496         if (crypto_ahash_digestsize(tfm) == SHA1_DIGEST_SIZE)
497                 ctx->flags |= FLAGS_SHA1;
498
499         ctx->bufcnt = 0;
500         ctx->digcnt = 0;
501
502         ctx->buflen = PAGE_SIZE;
503         ctx->buffer = (void *)__get_free_page(
504                                 (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
505                                 GFP_KERNEL : GFP_ATOMIC);
506         if (!ctx->buffer)
507                 return -ENOMEM;
508
509         ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer, ctx->buflen,
510                                         DMA_TO_DEVICE);
511         if (dma_mapping_error(dd->dev, ctx->dma_addr)) {
512                 dev_err(dd->dev, "dma %u bytes error\n", ctx->buflen);
513                 free_page((unsigned long)ctx->buffer);
514                 return -EINVAL;
515         }
516
517         if (tctx->flags & FLAGS_HMAC) {
518                 struct omap_sham_hmac_ctx *bctx = tctx->base;
519
520                 memcpy(ctx->buffer, bctx->ipad, SHA1_MD5_BLOCK_SIZE);
521                 ctx->bufcnt = SHA1_MD5_BLOCK_SIZE;
522                 ctx->flags |= FLAGS_HMAC;
523         }
524
525         return 0;
526
527 }
528
529 static int omap_sham_update_req(struct omap_sham_dev *dd)
530 {
531         struct ahash_request *req = dd->req;
532         struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
533         int err;
534
535         dev_dbg(dd->dev, "update_req: total: %u, digcnt: %d, finup: %d\n",
536                  ctx->total, ctx->digcnt, (ctx->flags & FLAGS_FINUP) != 0);
537
538         if (ctx->flags & FLAGS_CPU)
539                 err = omap_sham_update_cpu(dd);
540         else if (ctx->flags & FLAGS_FAST)
541                 err = omap_sham_update_dma_fast(dd);
542         else
543                 err = omap_sham_update_dma_slow(dd);
544
545         /* wait for dma completion before can take more data */
546         dev_dbg(dd->dev, "update: err: %d, digcnt: %d\n", err, ctx->digcnt);
547
548         return err;
549 }
550
551 static int omap_sham_final_req(struct omap_sham_dev *dd)
552 {
553         struct ahash_request *req = dd->req;
554         struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
555         int err = 0, use_dma = 1;
556
557         if (ctx->bufcnt <= 64)
558                 /* faster to handle last block with cpu */
559                 use_dma = 0;
560
561         if (use_dma)
562                 err = omap_sham_xmit_dma(dd, ctx->dma_addr, ctx->bufcnt, 1);
563         else
564                 err = omap_sham_xmit_cpu(dd, ctx->buffer, ctx->bufcnt, 1);
565
566         ctx->bufcnt = 0;
567
568         if (err != -EINPROGRESS)
569                 omap_sham_cleanup(req);
570
571         dev_dbg(dd->dev, "final_req: err: %d\n", err);
572
573         return err;
574 }
575
576 static int omap_sham_finish_req_hmac(struct ahash_request *req)
577 {
578         struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
579         struct omap_sham_hmac_ctx *bctx = tctx->base;
580         int bs = crypto_shash_blocksize(bctx->shash);
581         int ds = crypto_shash_digestsize(bctx->shash);
582         struct {
583                 struct shash_desc shash;
584                 char ctx[crypto_shash_descsize(bctx->shash)];
585         } desc;
586
587         desc.shash.tfm = bctx->shash;
588         desc.shash.flags = 0; /* not CRYPTO_TFM_REQ_MAY_SLEEP */
589
590         return crypto_shash_init(&desc.shash) ?:
591                crypto_shash_update(&desc.shash, bctx->opad, bs) ?:
592                crypto_shash_finup(&desc.shash, req->result, ds, req->result);
593 }
594
595 static void omap_sham_finish_req(struct ahash_request *req, int err)
596 {
597         struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
598
599         if (!err) {
600                 omap_sham_copy_hash(ctx->dd->req, 1);
601                 if (ctx->flags & FLAGS_HMAC)
602                         err = omap_sham_finish_req_hmac(req);
603         }
604
605         if (ctx->flags & FLAGS_FINAL)
606                 omap_sham_cleanup(req);
607
608         clear_bit(FLAGS_BUSY, &ctx->dd->flags);
609
610         if (req->base.complete)
611                 req->base.complete(&req->base, err);
612 }
613
614 static int omap_sham_handle_queue(struct omap_sham_dev *dd)
615 {
616         struct crypto_async_request *async_req, *backlog;
617         struct omap_sham_reqctx *ctx;
618         struct ahash_request *req, *prev_req;
619         unsigned long flags;
620         int err = 0;
621
622         if (test_and_set_bit(FLAGS_BUSY, &dd->flags))
623                 return 0;
624
625         spin_lock_irqsave(&dd->lock, flags);
626         backlog = crypto_get_backlog(&dd->queue);
627         async_req = crypto_dequeue_request(&dd->queue);
628         if (!async_req)
629                 clear_bit(FLAGS_BUSY, &dd->flags);
630         spin_unlock_irqrestore(&dd->lock, flags);
631
632         if (!async_req)
633                 return 0;
634
635         if (backlog)
636                 backlog->complete(backlog, -EINPROGRESS);
637
638         req = ahash_request_cast(async_req);
639
640         prev_req = dd->req;
641         dd->req = req;
642
643         ctx = ahash_request_ctx(req);
644
645         dev_dbg(dd->dev, "handling new req, op: %lu, nbytes: %d\n",
646                                                 ctx->op, req->nbytes);
647
648         if (req != prev_req && ctx->digcnt)
649                 /* request has changed - restore hash */
650                 omap_sham_copy_hash(req, 0);
651
652         if (ctx->op == OP_UPDATE) {
653                 err = omap_sham_update_req(dd);
654                 if (err != -EINPROGRESS && (ctx->flags & FLAGS_FINUP))
655                         /* no final() after finup() */
656                         err = omap_sham_final_req(dd);
657         } else if (ctx->op == OP_FINAL) {
658                 err = omap_sham_final_req(dd);
659         }
660
661         if (err != -EINPROGRESS) {
662                 /* done_task will not finish it, so do it here */
663                 omap_sham_finish_req(req, err);
664                 tasklet_schedule(&dd->queue_task);
665         }
666
667         dev_dbg(dd->dev, "exit, err: %d\n", err);
668
669         return err;
670 }
671
672 static int omap_sham_enqueue(struct ahash_request *req, unsigned int op)
673 {
674         struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
675         struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
676         struct omap_sham_dev *dd = tctx->dd;
677         unsigned long flags;
678         int err;
679
680         ctx->op = op;
681
682         spin_lock_irqsave(&dd->lock, flags);
683         err = ahash_enqueue_request(&dd->queue, req);
684         spin_unlock_irqrestore(&dd->lock, flags);
685
686         omap_sham_handle_queue(dd);
687
688         return err;
689 }
690
691 static int omap_sham_update(struct ahash_request *req)
692 {
693         struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
694
695         if (!req->nbytes)
696                 return 0;
697
698         ctx->total = req->nbytes;
699         ctx->sg = req->src;
700         ctx->offset = 0;
701
702         if (ctx->flags & FLAGS_FINUP) {
703                 if ((ctx->digcnt + ctx->bufcnt + ctx->total) < 9) {
704                         /*
705                         * OMAP HW accel works only with buffers >= 9
706                         * will switch to bypass in final()
707                         * final has the same request and data
708                         */
709                         omap_sham_append_sg(ctx);
710                         return 0;
711                 } else if (ctx->bufcnt + ctx->total <= 64) {
712                         ctx->flags |= FLAGS_CPU;
713                 } else if (!ctx->bufcnt && sg_is_last(ctx->sg)) {
714                         /* may be can use faster functions */
715                         int aligned = IS_ALIGNED((u32)ctx->sg->offset,
716                                                                 sizeof(u32));
717
718                         if (aligned && (ctx->flags & FLAGS_FIRST))
719                                 /* digest: first and final */
720                                 ctx->flags |= FLAGS_FAST;
721
722                         ctx->flags &= ~FLAGS_FIRST;
723                 }
724         } else if (ctx->bufcnt + ctx->total <= ctx->buflen) {
725                 /* if not finaup -> not fast */
726                 omap_sham_append_sg(ctx);
727                 return 0;
728         }
729
730         return omap_sham_enqueue(req, OP_UPDATE);
731 }
732
733 static int omap_sham_shash_digest(struct crypto_shash *shash, u32 flags,
734                                   const u8 *data, unsigned int len, u8 *out)
735 {
736         struct {
737                 struct shash_desc shash;
738                 char ctx[crypto_shash_descsize(shash)];
739         } desc;
740
741         desc.shash.tfm = shash;
742         desc.shash.flags = flags & CRYPTO_TFM_REQ_MAY_SLEEP;
743
744         return crypto_shash_digest(&desc.shash, data, len, out);
745 }
746
747 static int omap_sham_final_shash(struct ahash_request *req)
748 {
749         struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
750         struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
751
752         return omap_sham_shash_digest(tctx->fallback, req->base.flags,
753                                       ctx->buffer, ctx->bufcnt, req->result);
754 }
755
756 static int omap_sham_final(struct ahash_request *req)
757 {
758         struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
759         int err = 0;
760
761         ctx->flags |= FLAGS_FINUP;
762
763         /* OMAP HW accel works only with buffers >= 9 */
764         /* HMAC is always >= 9 because of ipad */
765         if ((ctx->digcnt + ctx->bufcnt) < 9)
766                 err = omap_sham_final_shash(req);
767         else if (ctx->bufcnt)
768                 return omap_sham_enqueue(req, OP_FINAL);
769
770         omap_sham_cleanup(req);
771
772         return err;
773 }
774
775 static int omap_sham_finup(struct ahash_request *req)
776 {
777         struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
778         int err1, err2;
779
780         ctx->flags |= FLAGS_FINUP;
781
782         err1 = omap_sham_update(req);
783         if (err1 == -EINPROGRESS)
784                 return err1;
785         /*
786          * final() has to be always called to cleanup resources
787          * even if udpate() failed, except EINPROGRESS
788          */
789         err2 = omap_sham_final(req);
790
791         return err1 ?: err2;
792 }
793
794 static int omap_sham_digest(struct ahash_request *req)
795 {
796         return omap_sham_init(req) ?: omap_sham_finup(req);
797 }
798
799 static int omap_sham_setkey(struct crypto_ahash *tfm, const u8 *key,
800                       unsigned int keylen)
801 {
802         struct omap_sham_ctx *tctx = crypto_ahash_ctx(tfm);
803         struct omap_sham_hmac_ctx *bctx = tctx->base;
804         int bs = crypto_shash_blocksize(bctx->shash);
805         int ds = crypto_shash_digestsize(bctx->shash);
806         int err, i;
807         err = crypto_shash_setkey(tctx->fallback, key, keylen);
808         if (err)
809                 return err;
810
811         if (keylen > bs) {
812                 err = omap_sham_shash_digest(bctx->shash,
813                                 crypto_shash_get_flags(bctx->shash),
814                                 key, keylen, bctx->ipad);
815                 if (err)
816                         return err;
817                 keylen = ds;
818         } else {
819                 memcpy(bctx->ipad, key, keylen);
820         }
821
822         memset(bctx->ipad + keylen, 0, bs - keylen);
823         memcpy(bctx->opad, bctx->ipad, bs);
824
825         for (i = 0; i < bs; i++) {
826                 bctx->ipad[i] ^= 0x36;
827                 bctx->opad[i] ^= 0x5c;
828         }
829
830         return err;
831 }
832
833 static int omap_sham_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base)
834 {
835         struct omap_sham_ctx *tctx = crypto_tfm_ctx(tfm);
836         const char *alg_name = crypto_tfm_alg_name(tfm);
837
838         /* Allocate a fallback and abort if it failed. */
839         tctx->fallback = crypto_alloc_shash(alg_name, 0,
840                                             CRYPTO_ALG_NEED_FALLBACK);
841         if (IS_ERR(tctx->fallback)) {
842                 pr_err("omap-sham: fallback driver '%s' "
843                                 "could not be loaded.\n", alg_name);
844                 return PTR_ERR(tctx->fallback);
845         }
846
847         crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
848                                  sizeof(struct omap_sham_reqctx));
849
850         if (alg_base) {
851                 struct omap_sham_hmac_ctx *bctx = tctx->base;
852                 tctx->flags |= FLAGS_HMAC;
853                 bctx->shash = crypto_alloc_shash(alg_base, 0,
854                                                 CRYPTO_ALG_NEED_FALLBACK);
855                 if (IS_ERR(bctx->shash)) {
856                         pr_err("omap-sham: base driver '%s' "
857                                         "could not be loaded.\n", alg_base);
858                         crypto_free_shash(tctx->fallback);
859                         return PTR_ERR(bctx->shash);
860                 }
861
862         }
863
864         return 0;
865 }
866
867 static int omap_sham_cra_init(struct crypto_tfm *tfm)
868 {
869         return omap_sham_cra_init_alg(tfm, NULL);
870 }
871
872 static int omap_sham_cra_sha1_init(struct crypto_tfm *tfm)
873 {
874         return omap_sham_cra_init_alg(tfm, "sha1");
875 }
876
877 static int omap_sham_cra_md5_init(struct crypto_tfm *tfm)
878 {
879         return omap_sham_cra_init_alg(tfm, "md5");
880 }
881
882 static void omap_sham_cra_exit(struct crypto_tfm *tfm)
883 {
884         struct omap_sham_ctx *tctx = crypto_tfm_ctx(tfm);
885
886         crypto_free_shash(tctx->fallback);
887         tctx->fallback = NULL;
888
889         if (tctx->flags & FLAGS_HMAC) {
890                 struct omap_sham_hmac_ctx *bctx = tctx->base;
891                 crypto_free_shash(bctx->shash);
892         }
893 }
894
895 static struct ahash_alg algs[] = {
896 {
897         .init           = omap_sham_init,
898         .update         = omap_sham_update,
899         .final          = omap_sham_final,
900         .finup          = omap_sham_finup,
901         .digest         = omap_sham_digest,
902         .halg.digestsize        = SHA1_DIGEST_SIZE,
903         .halg.base      = {
904                 .cra_name               = "sha1",
905                 .cra_driver_name        = "omap-sha1",
906                 .cra_priority           = 100,
907                 .cra_flags              = CRYPTO_ALG_TYPE_AHASH |
908                                                 CRYPTO_ALG_ASYNC |
909                                                 CRYPTO_ALG_NEED_FALLBACK,
910                 .cra_blocksize          = SHA1_BLOCK_SIZE,
911                 .cra_ctxsize            = sizeof(struct omap_sham_ctx),
912                 .cra_alignmask          = 0,
913                 .cra_module             = THIS_MODULE,
914                 .cra_init               = omap_sham_cra_init,
915                 .cra_exit               = omap_sham_cra_exit,
916         }
917 },
918 {
919         .init           = omap_sham_init,
920         .update         = omap_sham_update,
921         .final          = omap_sham_final,
922         .finup          = omap_sham_finup,
923         .digest         = omap_sham_digest,
924         .halg.digestsize        = MD5_DIGEST_SIZE,
925         .halg.base      = {
926                 .cra_name               = "md5",
927                 .cra_driver_name        = "omap-md5",
928                 .cra_priority           = 100,
929                 .cra_flags              = CRYPTO_ALG_TYPE_AHASH |
930                                                 CRYPTO_ALG_ASYNC |
931                                                 CRYPTO_ALG_NEED_FALLBACK,
932                 .cra_blocksize          = SHA1_BLOCK_SIZE,
933                 .cra_ctxsize            = sizeof(struct omap_sham_ctx),
934                 .cra_alignmask          = 0,
935                 .cra_module             = THIS_MODULE,
936                 .cra_init               = omap_sham_cra_init,
937                 .cra_exit               = omap_sham_cra_exit,
938         }
939 },
940 {
941         .init           = omap_sham_init,
942         .update         = omap_sham_update,
943         .final          = omap_sham_final,
944         .finup          = omap_sham_finup,
945         .digest         = omap_sham_digest,
946         .setkey         = omap_sham_setkey,
947         .halg.digestsize        = SHA1_DIGEST_SIZE,
948         .halg.base      = {
949                 .cra_name               = "hmac(sha1)",
950                 .cra_driver_name        = "omap-hmac-sha1",
951                 .cra_priority           = 100,
952                 .cra_flags              = CRYPTO_ALG_TYPE_AHASH |
953                                                 CRYPTO_ALG_ASYNC |
954                                                 CRYPTO_ALG_NEED_FALLBACK,
955                 .cra_blocksize          = SHA1_BLOCK_SIZE,
956                 .cra_ctxsize            = sizeof(struct omap_sham_ctx) +
957                                         sizeof(struct omap_sham_hmac_ctx),
958                 .cra_alignmask          = 0,
959                 .cra_module             = THIS_MODULE,
960                 .cra_init               = omap_sham_cra_sha1_init,
961                 .cra_exit               = omap_sham_cra_exit,
962         }
963 },
964 {
965         .init           = omap_sham_init,
966         .update         = omap_sham_update,
967         .final          = omap_sham_final,
968         .finup          = omap_sham_finup,
969         .digest         = omap_sham_digest,
970         .setkey         = omap_sham_setkey,
971         .halg.digestsize        = MD5_DIGEST_SIZE,
972         .halg.base      = {
973                 .cra_name               = "hmac(md5)",
974                 .cra_driver_name        = "omap-hmac-md5",
975                 .cra_priority           = 100,
976                 .cra_flags              = CRYPTO_ALG_TYPE_AHASH |
977                                                 CRYPTO_ALG_ASYNC |
978                                                 CRYPTO_ALG_NEED_FALLBACK,
979                 .cra_blocksize          = SHA1_BLOCK_SIZE,
980                 .cra_ctxsize            = sizeof(struct omap_sham_ctx) +
981                                         sizeof(struct omap_sham_hmac_ctx),
982                 .cra_alignmask          = 0,
983                 .cra_module             = THIS_MODULE,
984                 .cra_init               = omap_sham_cra_md5_init,
985                 .cra_exit               = omap_sham_cra_exit,
986         }
987 }
988 };
989
990 static void omap_sham_done_task(unsigned long data)
991 {
992         struct omap_sham_dev *dd = (struct omap_sham_dev *)data;
993         struct ahash_request *req = dd->req;
994         struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
995         int ready = 1;
996
997         if (ctx->flags & FLAGS_OUTPUT_READY) {
998                 ctx->flags &= ~FLAGS_OUTPUT_READY;
999                 ready = 1;
1000         }
1001
1002         if (dd->flags & FLAGS_DMA_ACTIVE) {
1003                 dd->flags &= ~FLAGS_DMA_ACTIVE;
1004                 omap_sham_update_dma_stop(dd);
1005                 omap_sham_update_dma_slow(dd);
1006         }
1007
1008         if (ready && !(dd->flags & FLAGS_DMA_ACTIVE)) {
1009                 dev_dbg(dd->dev, "update done\n");
1010                 /* finish curent request */
1011                 omap_sham_finish_req(req, 0);
1012                 /* start new request */
1013                 omap_sham_handle_queue(dd);
1014         }
1015 }
1016
1017 static void omap_sham_queue_task(unsigned long data)
1018 {
1019         struct omap_sham_dev *dd = (struct omap_sham_dev *)data;
1020
1021         omap_sham_handle_queue(dd);
1022 }
1023
1024 static irqreturn_t omap_sham_irq(int irq, void *dev_id)
1025 {
1026         struct omap_sham_dev *dd = dev_id;
1027         struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
1028
1029         if (!ctx) {
1030                 dev_err(dd->dev, "unknown interrupt.\n");
1031                 return IRQ_HANDLED;
1032         }
1033
1034         if (unlikely(ctx->flags & FLAGS_FINAL))
1035                 /* final -> allow device to go to power-saving mode */
1036                 omap_sham_write_mask(dd, SHA_REG_CTRL, 0, SHA_REG_CTRL_LENGTH);
1037
1038         omap_sham_write_mask(dd, SHA_REG_CTRL, SHA_REG_CTRL_OUTPUT_READY,
1039                                  SHA_REG_CTRL_OUTPUT_READY);
1040         omap_sham_read(dd, SHA_REG_CTRL);
1041
1042         ctx->flags |= FLAGS_OUTPUT_READY;
1043         tasklet_schedule(&dd->done_task);
1044
1045         return IRQ_HANDLED;
1046 }
1047
1048 static void omap_sham_dma_callback(int lch, u16 ch_status, void *data)
1049 {
1050         struct omap_sham_dev *dd = data;
1051
1052         if (likely(lch == dd->dma_lch))
1053                 tasklet_schedule(&dd->done_task);
1054 }
1055
1056 static int omap_sham_dma_init(struct omap_sham_dev *dd)
1057 {
1058         int err;
1059
1060         dd->dma_lch = -1;
1061
1062         err = omap_request_dma(dd->dma, dev_name(dd->dev),
1063                         omap_sham_dma_callback, dd, &dd->dma_lch);
1064         if (err) {
1065                 dev_err(dd->dev, "Unable to request DMA channel\n");
1066                 return err;
1067         }
1068         omap_set_dma_dest_params(dd->dma_lch, 0,
1069                         OMAP_DMA_AMODE_CONSTANT,
1070                         dd->phys_base + SHA_REG_DIN(0), 0, 16);
1071
1072         omap_set_dma_dest_burst_mode(dd->dma_lch,
1073                         OMAP_DMA_DATA_BURST_16);
1074
1075         return 0;
1076 }
1077
1078 static void omap_sham_dma_cleanup(struct omap_sham_dev *dd)
1079 {
1080         if (dd->dma_lch >= 0) {
1081                 omap_free_dma(dd->dma_lch);
1082                 dd->dma_lch = -1;
1083         }
1084 }
1085
1086 static int __devinit omap_sham_probe(struct platform_device *pdev)
1087 {
1088         struct omap_sham_dev *dd;
1089         struct device *dev = &pdev->dev;
1090         struct resource *res;
1091         int err, i, j;
1092
1093         dd = kzalloc(sizeof(struct omap_sham_dev), GFP_KERNEL);
1094         if (dd == NULL) {
1095                 dev_err(dev, "unable to alloc data struct.\n");
1096                 err = -ENOMEM;
1097                 goto data_err;
1098         }
1099         dd->dev = dev;
1100         platform_set_drvdata(pdev, dd);
1101
1102         INIT_LIST_HEAD(&dd->list);
1103         spin_lock_init(&dd->lock);
1104         tasklet_init(&dd->done_task, omap_sham_done_task, (unsigned long)dd);
1105         tasklet_init(&dd->queue_task, omap_sham_queue_task, (unsigned long)dd);
1106         crypto_init_queue(&dd->queue, OMAP_SHAM_QUEUE_LENGTH);
1107
1108         dd->irq = -1;
1109
1110         /* Get the base address */
1111         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1112         if (!res) {
1113                 dev_err(dev, "no MEM resource info\n");
1114                 err = -ENODEV;
1115                 goto res_err;
1116         }
1117         dd->phys_base = res->start;
1118
1119         /* Get the DMA */
1120         res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1121         if (!res) {
1122                 dev_err(dev, "no DMA resource info\n");
1123                 err = -ENODEV;
1124                 goto res_err;
1125         }
1126         dd->dma = res->start;
1127
1128         /* Get the IRQ */
1129         dd->irq = platform_get_irq(pdev,  0);
1130         if (dd->irq < 0) {
1131                 dev_err(dev, "no IRQ resource info\n");
1132                 err = dd->irq;
1133                 goto res_err;
1134         }
1135
1136         err = request_irq(dd->irq, omap_sham_irq,
1137                         IRQF_TRIGGER_LOW, dev_name(dev), dd);
1138         if (err) {
1139                 dev_err(dev, "unable to request irq.\n");
1140                 goto res_err;
1141         }
1142
1143         err = omap_sham_dma_init(dd);
1144         if (err)
1145                 goto dma_err;
1146
1147         /* Initializing the clock */
1148         dd->iclk = clk_get(dev, "ick");
1149         if (!dd->iclk) {
1150                 dev_err(dev, "clock intialization failed.\n");
1151                 err = -ENODEV;
1152                 goto clk_err;
1153         }
1154
1155         dd->io_base = ioremap(dd->phys_base, SZ_4K);
1156         if (!dd->io_base) {
1157                 dev_err(dev, "can't ioremap\n");
1158                 err = -ENOMEM;
1159                 goto io_err;
1160         }
1161
1162         clk_enable(dd->iclk);
1163         dev_info(dev, "hw accel on OMAP rev %u.%u\n",
1164                 (omap_sham_read(dd, SHA_REG_REV) & SHA_REG_REV_MAJOR) >> 4,
1165                 omap_sham_read(dd, SHA_REG_REV) & SHA_REG_REV_MINOR);
1166         clk_disable(dd->iclk);
1167
1168         spin_lock(&sham.lock);
1169         list_add_tail(&dd->list, &sham.dev_list);
1170         spin_unlock(&sham.lock);
1171
1172         for (i = 0; i < ARRAY_SIZE(algs); i++) {
1173                 err = crypto_register_ahash(&algs[i]);
1174                 if (err)
1175                         goto err_algs;
1176         }
1177
1178         return 0;
1179
1180 err_algs:
1181         for (j = 0; j < i; j++)
1182                 crypto_unregister_ahash(&algs[j]);
1183         iounmap(dd->io_base);
1184 io_err:
1185         clk_put(dd->iclk);
1186 clk_err:
1187         omap_sham_dma_cleanup(dd);
1188 dma_err:
1189         if (dd->irq >= 0)
1190                 free_irq(dd->irq, dd);
1191 res_err:
1192         kfree(dd);
1193         dd = NULL;
1194 data_err:
1195         dev_err(dev, "initialization failed.\n");
1196
1197         return err;
1198 }
1199
1200 static int __devexit omap_sham_remove(struct platform_device *pdev)
1201 {
1202         static struct omap_sham_dev *dd;
1203         int i;
1204
1205         dd = platform_get_drvdata(pdev);
1206         if (!dd)
1207                 return -ENODEV;
1208         spin_lock(&sham.lock);
1209         list_del(&dd->list);
1210         spin_unlock(&sham.lock);
1211         for (i = 0; i < ARRAY_SIZE(algs); i++)
1212                 crypto_unregister_ahash(&algs[i]);
1213         tasklet_kill(&dd->done_task);
1214         tasklet_kill(&dd->queue_task);
1215         iounmap(dd->io_base);
1216         clk_put(dd->iclk);
1217         omap_sham_dma_cleanup(dd);
1218         if (dd->irq >= 0)
1219                 free_irq(dd->irq, dd);
1220         kfree(dd);
1221         dd = NULL;
1222
1223         return 0;
1224 }
1225
1226 static struct platform_driver omap_sham_driver = {
1227         .probe  = omap_sham_probe,
1228         .remove = omap_sham_remove,
1229         .driver = {
1230                 .name   = "omap-sham",
1231                 .owner  = THIS_MODULE,
1232         },
1233 };
1234
1235 static int __init omap_sham_mod_init(void)
1236 {
1237         pr_info("loading %s driver\n", "omap-sham");
1238
1239         if (!cpu_class_is_omap2() ||
1240                 omap_type() != OMAP2_DEVICE_TYPE_SEC) {
1241                 pr_err("Unsupported cpu\n");
1242                 return -ENODEV;
1243         }
1244
1245         return platform_driver_register(&omap_sham_driver);
1246 }
1247
1248 static void __exit omap_sham_mod_exit(void)
1249 {
1250         platform_driver_unregister(&omap_sham_driver);
1251 }
1252
1253 module_init(omap_sham_mod_init);
1254 module_exit(omap_sham_mod_exit);
1255
1256 MODULE_DESCRIPTION("OMAP SHA1/MD5 hw acceleration support.");
1257 MODULE_LICENSE("GPL v2");
1258 MODULE_AUTHOR("Dmitry Kasatkin");