root/drivers/crypto/omap-des.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. omap_des_read
  2. omap_des_write
  3. omap_des_write_mask
  4. omap_des_write_n
  5. omap_des_hw_init
  6. omap_des_write_ctrl
  7. omap_des_dma_trigger_omap4
  8. omap_des_dma_stop
  9. omap_des_find_dev
  10. omap_des_dma_out_callback
  11. omap_des_dma_init
  12. omap_des_dma_cleanup
  13. omap_des_crypt_dma
  14. omap_des_crypt_dma_start
  15. omap_des_finish_req
  16. omap_des_crypt_dma_stop
  17. omap_des_handle_queue
  18. omap_des_prepare_req
  19. omap_des_crypt_req
  20. omap_des_done_task
  21. omap_des_crypt
  22. omap_des_setkey
  23. omap_des3_setkey
  24. omap_des_ecb_encrypt
  25. omap_des_ecb_decrypt
  26. omap_des_cbc_encrypt
  27. omap_des_cbc_decrypt
  28. omap_des_cra_init
  29. omap_des_cra_exit
  30. omap_des_irq
  31. omap_des_get_of
  32. omap_des_get_of
  33. omap_des_get_pdev
  34. omap_des_probe
  35. omap_des_remove
  36. omap_des_suspend
  37. omap_des_resume

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Support for OMAP DES and Triple DES HW acceleration.
   4  *
   5  * Copyright (c) 2013 Texas Instruments Incorporated
   6  * Author: Joel Fernandes <joelf@ti.com>
   7  */
   8 
   9 #define pr_fmt(fmt) "%s: " fmt, __func__
  10 
  11 #ifdef DEBUG
  12 #define prn(num) printk(#num "=%d\n", num)
  13 #define prx(num) printk(#num "=%x\n", num)
  14 #else
  15 #define prn(num) do { } while (0)
  16 #define prx(num)  do { } while (0)
  17 #endif
  18 
  19 #include <linux/err.h>
  20 #include <linux/module.h>
  21 #include <linux/init.h>
  22 #include <linux/errno.h>
  23 #include <linux/kernel.h>
  24 #include <linux/platform_device.h>
  25 #include <linux/scatterlist.h>
  26 #include <linux/dma-mapping.h>
  27 #include <linux/dmaengine.h>
  28 #include <linux/pm_runtime.h>
  29 #include <linux/of.h>
  30 #include <linux/of_device.h>
  31 #include <linux/of_address.h>
  32 #include <linux/io.h>
  33 #include <linux/crypto.h>
  34 #include <linux/interrupt.h>
  35 #include <crypto/scatterwalk.h>
  36 #include <crypto/internal/des.h>
  37 #include <crypto/algapi.h>
  38 #include <crypto/engine.h>
  39 
  40 #include "omap-crypto.h"
  41 
  42 #define DST_MAXBURST                    2
  43 
  44 #define DES_BLOCK_WORDS         (DES_BLOCK_SIZE >> 2)
  45 
  46 #define _calc_walked(inout) (dd->inout##_walk.offset - dd->inout##_sg->offset)
  47 
  48 #define DES_REG_KEY(dd, x)              ((dd)->pdata->key_ofs - \
  49                                                 ((x ^ 0x01) * 0x04))
  50 
  51 #define DES_REG_IV(dd, x)               ((dd)->pdata->iv_ofs + ((x) * 0x04))
  52 
  53 #define DES_REG_CTRL(dd)                ((dd)->pdata->ctrl_ofs)
  54 #define DES_REG_CTRL_CBC                BIT(4)
  55 #define DES_REG_CTRL_TDES               BIT(3)
  56 #define DES_REG_CTRL_DIRECTION          BIT(2)
  57 #define DES_REG_CTRL_INPUT_READY        BIT(1)
  58 #define DES_REG_CTRL_OUTPUT_READY       BIT(0)
  59 
  60 #define DES_REG_DATA_N(dd, x)           ((dd)->pdata->data_ofs + ((x) * 0x04))
  61 
  62 #define DES_REG_REV(dd)                 ((dd)->pdata->rev_ofs)
  63 
  64 #define DES_REG_MASK(dd)                ((dd)->pdata->mask_ofs)
  65 
  66 #define DES_REG_LENGTH_N(x)             (0x24 + ((x) * 0x04))
  67 
  68 #define DES_REG_IRQ_STATUS(dd)         ((dd)->pdata->irq_status_ofs)
  69 #define DES_REG_IRQ_ENABLE(dd)         ((dd)->pdata->irq_enable_ofs)
  70 #define DES_REG_IRQ_DATA_IN            BIT(1)
  71 #define DES_REG_IRQ_DATA_OUT           BIT(2)
  72 
  73 #define FLAGS_MODE_MASK         0x000f
  74 #define FLAGS_ENCRYPT           BIT(0)
  75 #define FLAGS_CBC               BIT(1)
  76 #define FLAGS_INIT              BIT(4)
  77 #define FLAGS_BUSY              BIT(6)
  78 
  79 #define DEFAULT_AUTOSUSPEND_DELAY       1000
  80 
  81 #define FLAGS_IN_DATA_ST_SHIFT  8
  82 #define FLAGS_OUT_DATA_ST_SHIFT 10
  83 
  84 struct omap_des_ctx {
  85         struct crypto_engine_ctx enginectx;
  86         struct omap_des_dev *dd;
  87 
  88         int             keylen;
  89         u32             key[(3 * DES_KEY_SIZE) / sizeof(u32)];
  90         unsigned long   flags;
  91 };
  92 
  93 struct omap_des_reqctx {
  94         unsigned long mode;
  95 };
  96 
  97 #define OMAP_DES_QUEUE_LENGTH   1
  98 #define OMAP_DES_CACHE_SIZE     0
  99 
 100 struct omap_des_algs_info {
 101         struct crypto_alg       *algs_list;
 102         unsigned int            size;
 103         unsigned int            registered;
 104 };
 105 
 106 struct omap_des_pdata {
 107         struct omap_des_algs_info       *algs_info;
 108         unsigned int    algs_info_size;
 109 
 110         void            (*trigger)(struct omap_des_dev *dd, int length);
 111 
 112         u32             key_ofs;
 113         u32             iv_ofs;
 114         u32             ctrl_ofs;
 115         u32             data_ofs;
 116         u32             rev_ofs;
 117         u32             mask_ofs;
 118         u32             irq_enable_ofs;
 119         u32             irq_status_ofs;
 120 
 121         u32             dma_enable_in;
 122         u32             dma_enable_out;
 123         u32             dma_start;
 124 
 125         u32             major_mask;
 126         u32             major_shift;
 127         u32             minor_mask;
 128         u32             minor_shift;
 129 };
 130 
 131 struct omap_des_dev {
 132         struct list_head        list;
 133         unsigned long           phys_base;
 134         void __iomem            *io_base;
 135         struct omap_des_ctx     *ctx;
 136         struct device           *dev;
 137         unsigned long           flags;
 138         int                     err;
 139 
 140         struct tasklet_struct   done_task;
 141 
 142         struct ablkcipher_request       *req;
 143         struct crypto_engine            *engine;
 144         /*
 145          * total is used by PIO mode for book keeping so introduce
 146          * variable total_save as need it to calc page_order
 147          */
 148         size_t                          total;
 149         size_t                          total_save;
 150 
 151         struct scatterlist              *in_sg;
 152         struct scatterlist              *out_sg;
 153 
 154         /* Buffers for copying for unaligned cases */
 155         struct scatterlist              in_sgl;
 156         struct scatterlist              out_sgl;
 157         struct scatterlist              *orig_out;
 158 
 159         struct scatter_walk             in_walk;
 160         struct scatter_walk             out_walk;
 161         struct dma_chan         *dma_lch_in;
 162         struct dma_chan         *dma_lch_out;
 163         int                     in_sg_len;
 164         int                     out_sg_len;
 165         int                     pio_only;
 166         const struct omap_des_pdata     *pdata;
 167 };
 168 
 169 /* keep registered devices data here */
 170 static LIST_HEAD(dev_list);
 171 static DEFINE_SPINLOCK(list_lock);
 172 
 173 #ifdef DEBUG
 174 #define omap_des_read(dd, offset)                               \
 175         ({                                                              \
 176          int _read_ret;                                          \
 177          _read_ret = __raw_readl(dd->io_base + offset);          \
 178          pr_err("omap_des_read(" #offset "=%#x)= %#x\n",       \
 179                  offset, _read_ret);                            \
 180          _read_ret;                                              \
 181          })
 182 #else
 183 static inline u32 omap_des_read(struct omap_des_dev *dd, u32 offset)
 184 {
 185         return __raw_readl(dd->io_base + offset);
 186 }
 187 #endif
 188 
 189 #ifdef DEBUG
 190 #define omap_des_write(dd, offset, value)                               \
 191         do {                                                            \
 192                 pr_err("omap_des_write(" #offset "=%#x) value=%#x\n", \
 193                                 offset, value);                                \
 194                 __raw_writel(value, dd->io_base + offset);              \
 195         } while (0)
 196 #else
 197 static inline void omap_des_write(struct omap_des_dev *dd, u32 offset,
 198                 u32 value)
 199 {
 200         __raw_writel(value, dd->io_base + offset);
 201 }
 202 #endif
 203 
 204 static inline void omap_des_write_mask(struct omap_des_dev *dd, u32 offset,
 205                                         u32 value, u32 mask)
 206 {
 207         u32 val;
 208 
 209         val = omap_des_read(dd, offset);
 210         val &= ~mask;
 211         val |= value;
 212         omap_des_write(dd, offset, val);
 213 }
 214 
 215 static void omap_des_write_n(struct omap_des_dev *dd, u32 offset,
 216                                         u32 *value, int count)
 217 {
 218         for (; count--; value++, offset += 4)
 219                 omap_des_write(dd, offset, *value);
 220 }
 221 
 222 static int omap_des_hw_init(struct omap_des_dev *dd)
 223 {
 224         int err;
 225 
 226         /*
 227          * clocks are enabled when request starts and disabled when finished.
 228          * It may be long delays between requests.
 229          * Device might go to off mode to save power.
 230          */
 231         err = pm_runtime_get_sync(dd->dev);
 232         if (err < 0) {
 233                 pm_runtime_put_noidle(dd->dev);
 234                 dev_err(dd->dev, "%s: failed to get_sync(%d)\n", __func__, err);
 235                 return err;
 236         }
 237 
 238         if (!(dd->flags & FLAGS_INIT)) {
 239                 dd->flags |= FLAGS_INIT;
 240                 dd->err = 0;
 241         }
 242 
 243         return 0;
 244 }
 245 
 246 static int omap_des_write_ctrl(struct omap_des_dev *dd)
 247 {
 248         unsigned int key32;
 249         int i, err;
 250         u32 val = 0, mask = 0;
 251 
 252         err = omap_des_hw_init(dd);
 253         if (err)
 254                 return err;
 255 
 256         key32 = dd->ctx->keylen / sizeof(u32);
 257 
 258         /* it seems a key should always be set even if it has not changed */
 259         for (i = 0; i < key32; i++) {
 260                 omap_des_write(dd, DES_REG_KEY(dd, i),
 261                                __le32_to_cpu(dd->ctx->key[i]));
 262         }
 263 
 264         if ((dd->flags & FLAGS_CBC) && dd->req->info)
 265                 omap_des_write_n(dd, DES_REG_IV(dd, 0), dd->req->info, 2);
 266 
 267         if (dd->flags & FLAGS_CBC)
 268                 val |= DES_REG_CTRL_CBC;
 269         if (dd->flags & FLAGS_ENCRYPT)
 270                 val |= DES_REG_CTRL_DIRECTION;
 271         if (key32 == 6)
 272                 val |= DES_REG_CTRL_TDES;
 273 
 274         mask |= DES_REG_CTRL_CBC | DES_REG_CTRL_DIRECTION | DES_REG_CTRL_TDES;
 275 
 276         omap_des_write_mask(dd, DES_REG_CTRL(dd), val, mask);
 277 
 278         return 0;
 279 }
 280 
 281 static void omap_des_dma_trigger_omap4(struct omap_des_dev *dd, int length)
 282 {
 283         u32 mask, val;
 284 
 285         omap_des_write(dd, DES_REG_LENGTH_N(0), length);
 286 
 287         val = dd->pdata->dma_start;
 288 
 289         if (dd->dma_lch_out != NULL)
 290                 val |= dd->pdata->dma_enable_out;
 291         if (dd->dma_lch_in != NULL)
 292                 val |= dd->pdata->dma_enable_in;
 293 
 294         mask = dd->pdata->dma_enable_out | dd->pdata->dma_enable_in |
 295                dd->pdata->dma_start;
 296 
 297         omap_des_write_mask(dd, DES_REG_MASK(dd), val, mask);
 298 }
 299 
 300 static void omap_des_dma_stop(struct omap_des_dev *dd)
 301 {
 302         u32 mask;
 303 
 304         mask = dd->pdata->dma_enable_out | dd->pdata->dma_enable_in |
 305                dd->pdata->dma_start;
 306 
 307         omap_des_write_mask(dd, DES_REG_MASK(dd), 0, mask);
 308 }
 309 
 310 static struct omap_des_dev *omap_des_find_dev(struct omap_des_ctx *ctx)
 311 {
 312         struct omap_des_dev *dd = NULL, *tmp;
 313 
 314         spin_lock_bh(&list_lock);
 315         if (!ctx->dd) {
 316                 list_for_each_entry(tmp, &dev_list, list) {
 317                         /* FIXME: take fist available des core */
 318                         dd = tmp;
 319                         break;
 320                 }
 321                 ctx->dd = dd;
 322         } else {
 323                 /* already found before */
 324                 dd = ctx->dd;
 325         }
 326         spin_unlock_bh(&list_lock);
 327 
 328         return dd;
 329 }
 330 
 331 static void omap_des_dma_out_callback(void *data)
 332 {
 333         struct omap_des_dev *dd = data;
 334 
 335         /* dma_lch_out - completed */
 336         tasklet_schedule(&dd->done_task);
 337 }
 338 
 339 static int omap_des_dma_init(struct omap_des_dev *dd)
 340 {
 341         int err;
 342 
 343         dd->dma_lch_out = NULL;
 344         dd->dma_lch_in = NULL;
 345 
 346         dd->dma_lch_in = dma_request_chan(dd->dev, "rx");
 347         if (IS_ERR(dd->dma_lch_in)) {
 348                 dev_err(dd->dev, "Unable to request in DMA channel\n");
 349                 return PTR_ERR(dd->dma_lch_in);
 350         }
 351 
 352         dd->dma_lch_out = dma_request_chan(dd->dev, "tx");
 353         if (IS_ERR(dd->dma_lch_out)) {
 354                 dev_err(dd->dev, "Unable to request out DMA channel\n");
 355                 err = PTR_ERR(dd->dma_lch_out);
 356                 goto err_dma_out;
 357         }
 358 
 359         return 0;
 360 
 361 err_dma_out:
 362         dma_release_channel(dd->dma_lch_in);
 363 
 364         return err;
 365 }
 366 
 367 static void omap_des_dma_cleanup(struct omap_des_dev *dd)
 368 {
 369         if (dd->pio_only)
 370                 return;
 371 
 372         dma_release_channel(dd->dma_lch_out);
 373         dma_release_channel(dd->dma_lch_in);
 374 }
 375 
 376 static int omap_des_crypt_dma(struct crypto_tfm *tfm,
 377                 struct scatterlist *in_sg, struct scatterlist *out_sg,
 378                 int in_sg_len, int out_sg_len)
 379 {
 380         struct omap_des_ctx *ctx = crypto_tfm_ctx(tfm);
 381         struct omap_des_dev *dd = ctx->dd;
 382         struct dma_async_tx_descriptor *tx_in, *tx_out;
 383         struct dma_slave_config cfg;
 384         int ret;
 385 
 386         if (dd->pio_only) {
 387                 scatterwalk_start(&dd->in_walk, dd->in_sg);
 388                 scatterwalk_start(&dd->out_walk, dd->out_sg);
 389 
 390                 /* Enable DATAIN interrupt and let it take
 391                    care of the rest */
 392                 omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x2);
 393                 return 0;
 394         }
 395 
 396         dma_sync_sg_for_device(dd->dev, dd->in_sg, in_sg_len, DMA_TO_DEVICE);
 397 
 398         memset(&cfg, 0, sizeof(cfg));
 399 
 400         cfg.src_addr = dd->phys_base + DES_REG_DATA_N(dd, 0);
 401         cfg.dst_addr = dd->phys_base + DES_REG_DATA_N(dd, 0);
 402         cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 403         cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 404         cfg.src_maxburst = DST_MAXBURST;
 405         cfg.dst_maxburst = DST_MAXBURST;
 406 
 407         /* IN */
 408         ret = dmaengine_slave_config(dd->dma_lch_in, &cfg);
 409         if (ret) {
 410                 dev_err(dd->dev, "can't configure IN dmaengine slave: %d\n",
 411                         ret);
 412                 return ret;
 413         }
 414 
 415         tx_in = dmaengine_prep_slave_sg(dd->dma_lch_in, in_sg, in_sg_len,
 416                                         DMA_MEM_TO_DEV,
 417                                         DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 418         if (!tx_in) {
 419                 dev_err(dd->dev, "IN prep_slave_sg() failed\n");
 420                 return -EINVAL;
 421         }
 422 
 423         /* No callback necessary */
 424         tx_in->callback_param = dd;
 425 
 426         /* OUT */
 427         ret = dmaengine_slave_config(dd->dma_lch_out, &cfg);
 428         if (ret) {
 429                 dev_err(dd->dev, "can't configure OUT dmaengine slave: %d\n",
 430                         ret);
 431                 return ret;
 432         }
 433 
 434         tx_out = dmaengine_prep_slave_sg(dd->dma_lch_out, out_sg, out_sg_len,
 435                                         DMA_DEV_TO_MEM,
 436                                         DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 437         if (!tx_out) {
 438                 dev_err(dd->dev, "OUT prep_slave_sg() failed\n");
 439                 return -EINVAL;
 440         }
 441 
 442         tx_out->callback = omap_des_dma_out_callback;
 443         tx_out->callback_param = dd;
 444 
 445         dmaengine_submit(tx_in);
 446         dmaengine_submit(tx_out);
 447 
 448         dma_async_issue_pending(dd->dma_lch_in);
 449         dma_async_issue_pending(dd->dma_lch_out);
 450 
 451         /* start DMA */
 452         dd->pdata->trigger(dd, dd->total);
 453 
 454         return 0;
 455 }
 456 
 457 static int omap_des_crypt_dma_start(struct omap_des_dev *dd)
 458 {
 459         struct crypto_tfm *tfm = crypto_ablkcipher_tfm(
 460                                         crypto_ablkcipher_reqtfm(dd->req));
 461         int err;
 462 
 463         pr_debug("total: %d\n", dd->total);
 464 
 465         if (!dd->pio_only) {
 466                 err = dma_map_sg(dd->dev, dd->in_sg, dd->in_sg_len,
 467                                  DMA_TO_DEVICE);
 468                 if (!err) {
 469                         dev_err(dd->dev, "dma_map_sg() error\n");
 470                         return -EINVAL;
 471                 }
 472 
 473                 err = dma_map_sg(dd->dev, dd->out_sg, dd->out_sg_len,
 474                                  DMA_FROM_DEVICE);
 475                 if (!err) {
 476                         dev_err(dd->dev, "dma_map_sg() error\n");
 477                         return -EINVAL;
 478                 }
 479         }
 480 
 481         err = omap_des_crypt_dma(tfm, dd->in_sg, dd->out_sg, dd->in_sg_len,
 482                                  dd->out_sg_len);
 483         if (err && !dd->pio_only) {
 484                 dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE);
 485                 dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len,
 486                              DMA_FROM_DEVICE);
 487         }
 488 
 489         return err;
 490 }
 491 
 492 static void omap_des_finish_req(struct omap_des_dev *dd, int err)
 493 {
 494         struct ablkcipher_request *req = dd->req;
 495 
 496         pr_debug("err: %d\n", err);
 497 
 498         crypto_finalize_ablkcipher_request(dd->engine, req, err);
 499 
 500         pm_runtime_mark_last_busy(dd->dev);
 501         pm_runtime_put_autosuspend(dd->dev);
 502 }
 503 
 504 static int omap_des_crypt_dma_stop(struct omap_des_dev *dd)
 505 {
 506         pr_debug("total: %d\n", dd->total);
 507 
 508         omap_des_dma_stop(dd);
 509 
 510         dmaengine_terminate_all(dd->dma_lch_in);
 511         dmaengine_terminate_all(dd->dma_lch_out);
 512 
 513         return 0;
 514 }
 515 
 516 static int omap_des_handle_queue(struct omap_des_dev *dd,
 517                                  struct ablkcipher_request *req)
 518 {
 519         if (req)
 520                 return crypto_transfer_ablkcipher_request_to_engine(dd->engine, req);
 521 
 522         return 0;
 523 }
 524 
 525 static int omap_des_prepare_req(struct crypto_engine *engine,
 526                                 void *areq)
 527 {
 528         struct ablkcipher_request *req = container_of(areq, struct ablkcipher_request, base);
 529         struct omap_des_ctx *ctx = crypto_ablkcipher_ctx(
 530                         crypto_ablkcipher_reqtfm(req));
 531         struct omap_des_dev *dd = omap_des_find_dev(ctx);
 532         struct omap_des_reqctx *rctx;
 533         int ret;
 534         u16 flags;
 535 
 536         if (!dd)
 537                 return -ENODEV;
 538 
 539         /* assign new request to device */
 540         dd->req = req;
 541         dd->total = req->nbytes;
 542         dd->total_save = req->nbytes;
 543         dd->in_sg = req->src;
 544         dd->out_sg = req->dst;
 545         dd->orig_out = req->dst;
 546 
 547         flags = OMAP_CRYPTO_COPY_DATA;
 548         if (req->src == req->dst)
 549                 flags |= OMAP_CRYPTO_FORCE_COPY;
 550 
 551         ret = omap_crypto_align_sg(&dd->in_sg, dd->total, DES_BLOCK_SIZE,
 552                                    &dd->in_sgl, flags,
 553                                    FLAGS_IN_DATA_ST_SHIFT, &dd->flags);
 554         if (ret)
 555                 return ret;
 556 
 557         ret = omap_crypto_align_sg(&dd->out_sg, dd->total, DES_BLOCK_SIZE,
 558                                    &dd->out_sgl, 0,
 559                                    FLAGS_OUT_DATA_ST_SHIFT, &dd->flags);
 560         if (ret)
 561                 return ret;
 562 
 563         dd->in_sg_len = sg_nents_for_len(dd->in_sg, dd->total);
 564         if (dd->in_sg_len < 0)
 565                 return dd->in_sg_len;
 566 
 567         dd->out_sg_len = sg_nents_for_len(dd->out_sg, dd->total);
 568         if (dd->out_sg_len < 0)
 569                 return dd->out_sg_len;
 570 
 571         rctx = ablkcipher_request_ctx(req);
 572         ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req));
 573         rctx->mode &= FLAGS_MODE_MASK;
 574         dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode;
 575 
 576         dd->ctx = ctx;
 577         ctx->dd = dd;
 578 
 579         return omap_des_write_ctrl(dd);
 580 }
 581 
 582 static int omap_des_crypt_req(struct crypto_engine *engine,
 583                               void *areq)
 584 {
 585         struct ablkcipher_request *req = container_of(areq, struct ablkcipher_request, base);
 586         struct omap_des_ctx *ctx = crypto_ablkcipher_ctx(
 587                         crypto_ablkcipher_reqtfm(req));
 588         struct omap_des_dev *dd = omap_des_find_dev(ctx);
 589 
 590         if (!dd)
 591                 return -ENODEV;
 592 
 593         return omap_des_crypt_dma_start(dd);
 594 }
 595 
 596 static void omap_des_done_task(unsigned long data)
 597 {
 598         struct omap_des_dev *dd = (struct omap_des_dev *)data;
 599 
 600         pr_debug("enter done_task\n");
 601 
 602         if (!dd->pio_only) {
 603                 dma_sync_sg_for_device(dd->dev, dd->out_sg, dd->out_sg_len,
 604                                        DMA_FROM_DEVICE);
 605                 dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE);
 606                 dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len,
 607                              DMA_FROM_DEVICE);
 608                 omap_des_crypt_dma_stop(dd);
 609         }
 610 
 611         omap_crypto_cleanup(&dd->in_sgl, NULL, 0, dd->total_save,
 612                             FLAGS_IN_DATA_ST_SHIFT, dd->flags);
 613 
 614         omap_crypto_cleanup(&dd->out_sgl, dd->orig_out, 0, dd->total_save,
 615                             FLAGS_OUT_DATA_ST_SHIFT, dd->flags);
 616 
 617         omap_des_finish_req(dd, 0);
 618 
 619         pr_debug("exit\n");
 620 }
 621 
 622 static int omap_des_crypt(struct ablkcipher_request *req, unsigned long mode)
 623 {
 624         struct omap_des_ctx *ctx = crypto_ablkcipher_ctx(
 625                         crypto_ablkcipher_reqtfm(req));
 626         struct omap_des_reqctx *rctx = ablkcipher_request_ctx(req);
 627         struct omap_des_dev *dd;
 628 
 629         pr_debug("nbytes: %d, enc: %d, cbc: %d\n", req->nbytes,
 630                  !!(mode & FLAGS_ENCRYPT),
 631                  !!(mode & FLAGS_CBC));
 632 
 633         if (!IS_ALIGNED(req->nbytes, DES_BLOCK_SIZE)) {
 634                 pr_err("request size is not exact amount of DES blocks\n");
 635                 return -EINVAL;
 636         }
 637 
 638         dd = omap_des_find_dev(ctx);
 639         if (!dd)
 640                 return -ENODEV;
 641 
 642         rctx->mode = mode;
 643 
 644         return omap_des_handle_queue(dd, req);
 645 }
 646 
 647 /* ********************** ALG API ************************************ */
 648 
 649 static int omap_des_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
 650                            unsigned int keylen)
 651 {
 652         struct omap_des_ctx *ctx = crypto_ablkcipher_ctx(cipher);
 653         int err;
 654 
 655         pr_debug("enter, keylen: %d\n", keylen);
 656 
 657         err = verify_ablkcipher_des_key(cipher, key);
 658         if (err)
 659                 return err;
 660 
 661         memcpy(ctx->key, key, keylen);
 662         ctx->keylen = keylen;
 663 
 664         return 0;
 665 }
 666 
 667 static int omap_des3_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
 668                             unsigned int keylen)
 669 {
 670         struct omap_des_ctx *ctx = crypto_ablkcipher_ctx(cipher);
 671         int err;
 672 
 673         pr_debug("enter, keylen: %d\n", keylen);
 674 
 675         err = verify_ablkcipher_des3_key(cipher, key);
 676         if (err)
 677                 return err;
 678 
 679         memcpy(ctx->key, key, keylen);
 680         ctx->keylen = keylen;
 681 
 682         return 0;
 683 }
 684 
 685 static int omap_des_ecb_encrypt(struct ablkcipher_request *req)
 686 {
 687         return omap_des_crypt(req, FLAGS_ENCRYPT);
 688 }
 689 
 690 static int omap_des_ecb_decrypt(struct ablkcipher_request *req)
 691 {
 692         return omap_des_crypt(req, 0);
 693 }
 694 
 695 static int omap_des_cbc_encrypt(struct ablkcipher_request *req)
 696 {
 697         return omap_des_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC);
 698 }
 699 
 700 static int omap_des_cbc_decrypt(struct ablkcipher_request *req)
 701 {
 702         return omap_des_crypt(req, FLAGS_CBC);
 703 }
 704 
 705 static int omap_des_prepare_req(struct crypto_engine *engine,
 706                                 void *areq);
 707 static int omap_des_crypt_req(struct crypto_engine *engine,
 708                               void *areq);
 709 
 710 static int omap_des_cra_init(struct crypto_tfm *tfm)
 711 {
 712         struct omap_des_ctx *ctx = crypto_tfm_ctx(tfm);
 713 
 714         pr_debug("enter\n");
 715 
 716         tfm->crt_ablkcipher.reqsize = sizeof(struct omap_des_reqctx);
 717 
 718         ctx->enginectx.op.prepare_request = omap_des_prepare_req;
 719         ctx->enginectx.op.unprepare_request = NULL;
 720         ctx->enginectx.op.do_one_request = omap_des_crypt_req;
 721 
 722         return 0;
 723 }
 724 
 725 static void omap_des_cra_exit(struct crypto_tfm *tfm)
 726 {
 727         pr_debug("enter\n");
 728 }
 729 
 730 /* ********************** ALGS ************************************ */
 731 
 732 static struct crypto_alg algs_ecb_cbc[] = {
 733 {
 734         .cra_name               = "ecb(des)",
 735         .cra_driver_name        = "ecb-des-omap",
 736         .cra_priority           = 100,
 737         .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER |
 738                                   CRYPTO_ALG_KERN_DRIVER_ONLY |
 739                                   CRYPTO_ALG_ASYNC,
 740         .cra_blocksize          = DES_BLOCK_SIZE,
 741         .cra_ctxsize            = sizeof(struct omap_des_ctx),
 742         .cra_alignmask          = 0,
 743         .cra_type               = &crypto_ablkcipher_type,
 744         .cra_module             = THIS_MODULE,
 745         .cra_init               = omap_des_cra_init,
 746         .cra_exit               = omap_des_cra_exit,
 747         .cra_u.ablkcipher = {
 748                 .min_keysize    = DES_KEY_SIZE,
 749                 .max_keysize    = DES_KEY_SIZE,
 750                 .setkey         = omap_des_setkey,
 751                 .encrypt        = omap_des_ecb_encrypt,
 752                 .decrypt        = omap_des_ecb_decrypt,
 753         }
 754 },
 755 {
 756         .cra_name               = "cbc(des)",
 757         .cra_driver_name        = "cbc-des-omap",
 758         .cra_priority           = 100,
 759         .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER |
 760                                   CRYPTO_ALG_KERN_DRIVER_ONLY |
 761                                   CRYPTO_ALG_ASYNC,
 762         .cra_blocksize          = DES_BLOCK_SIZE,
 763         .cra_ctxsize            = sizeof(struct omap_des_ctx),
 764         .cra_alignmask          = 0,
 765         .cra_type               = &crypto_ablkcipher_type,
 766         .cra_module             = THIS_MODULE,
 767         .cra_init               = omap_des_cra_init,
 768         .cra_exit               = omap_des_cra_exit,
 769         .cra_u.ablkcipher = {
 770                 .min_keysize    = DES_KEY_SIZE,
 771                 .max_keysize    = DES_KEY_SIZE,
 772                 .ivsize         = DES_BLOCK_SIZE,
 773                 .setkey         = omap_des_setkey,
 774                 .encrypt        = omap_des_cbc_encrypt,
 775                 .decrypt        = omap_des_cbc_decrypt,
 776         }
 777 },
 778 {
 779         .cra_name               = "ecb(des3_ede)",
 780         .cra_driver_name        = "ecb-des3-omap",
 781         .cra_priority           = 100,
 782         .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER |
 783                                   CRYPTO_ALG_KERN_DRIVER_ONLY |
 784                                   CRYPTO_ALG_ASYNC,
 785         .cra_blocksize          = DES_BLOCK_SIZE,
 786         .cra_ctxsize            = sizeof(struct omap_des_ctx),
 787         .cra_alignmask          = 0,
 788         .cra_type               = &crypto_ablkcipher_type,
 789         .cra_module             = THIS_MODULE,
 790         .cra_init               = omap_des_cra_init,
 791         .cra_exit               = omap_des_cra_exit,
 792         .cra_u.ablkcipher = {
 793                 .min_keysize    = 3*DES_KEY_SIZE,
 794                 .max_keysize    = 3*DES_KEY_SIZE,
 795                 .setkey         = omap_des3_setkey,
 796                 .encrypt        = omap_des_ecb_encrypt,
 797                 .decrypt        = omap_des_ecb_decrypt,
 798         }
 799 },
 800 {
 801         .cra_name               = "cbc(des3_ede)",
 802         .cra_driver_name        = "cbc-des3-omap",
 803         .cra_priority           = 100,
 804         .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER |
 805                                   CRYPTO_ALG_KERN_DRIVER_ONLY |
 806                                   CRYPTO_ALG_ASYNC,
 807         .cra_blocksize          = DES_BLOCK_SIZE,
 808         .cra_ctxsize            = sizeof(struct omap_des_ctx),
 809         .cra_alignmask          = 0,
 810         .cra_type               = &crypto_ablkcipher_type,
 811         .cra_module             = THIS_MODULE,
 812         .cra_init               = omap_des_cra_init,
 813         .cra_exit               = omap_des_cra_exit,
 814         .cra_u.ablkcipher = {
 815                 .min_keysize    = 3*DES_KEY_SIZE,
 816                 .max_keysize    = 3*DES_KEY_SIZE,
 817                 .ivsize         = DES_BLOCK_SIZE,
 818                 .setkey         = omap_des3_setkey,
 819                 .encrypt        = omap_des_cbc_encrypt,
 820                 .decrypt        = omap_des_cbc_decrypt,
 821         }
 822 }
 823 };
 824 
 825 static struct omap_des_algs_info omap_des_algs_info_ecb_cbc[] = {
 826         {
 827                 .algs_list      = algs_ecb_cbc,
 828                 .size           = ARRAY_SIZE(algs_ecb_cbc),
 829         },
 830 };
 831 
 832 #ifdef CONFIG_OF
 833 static const struct omap_des_pdata omap_des_pdata_omap4 = {
 834         .algs_info      = omap_des_algs_info_ecb_cbc,
 835         .algs_info_size = ARRAY_SIZE(omap_des_algs_info_ecb_cbc),
 836         .trigger        = omap_des_dma_trigger_omap4,
 837         .key_ofs        = 0x14,
 838         .iv_ofs         = 0x18,
 839         .ctrl_ofs       = 0x20,
 840         .data_ofs       = 0x28,
 841         .rev_ofs        = 0x30,
 842         .mask_ofs       = 0x34,
 843         .irq_status_ofs = 0x3c,
 844         .irq_enable_ofs = 0x40,
 845         .dma_enable_in  = BIT(5),
 846         .dma_enable_out = BIT(6),
 847         .major_mask     = 0x0700,
 848         .major_shift    = 8,
 849         .minor_mask     = 0x003f,
 850         .minor_shift    = 0,
 851 };
 852 
 853 static irqreturn_t omap_des_irq(int irq, void *dev_id)
 854 {
 855         struct omap_des_dev *dd = dev_id;
 856         u32 status, i;
 857         u32 *src, *dst;
 858 
 859         status = omap_des_read(dd, DES_REG_IRQ_STATUS(dd));
 860         if (status & DES_REG_IRQ_DATA_IN) {
 861                 omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x0);
 862 
 863                 BUG_ON(!dd->in_sg);
 864 
 865                 BUG_ON(_calc_walked(in) > dd->in_sg->length);
 866 
 867                 src = sg_virt(dd->in_sg) + _calc_walked(in);
 868 
 869                 for (i = 0; i < DES_BLOCK_WORDS; i++) {
 870                         omap_des_write(dd, DES_REG_DATA_N(dd, i), *src);
 871 
 872                         scatterwalk_advance(&dd->in_walk, 4);
 873                         if (dd->in_sg->length == _calc_walked(in)) {
 874                                 dd->in_sg = sg_next(dd->in_sg);
 875                                 if (dd->in_sg) {
 876                                         scatterwalk_start(&dd->in_walk,
 877                                                           dd->in_sg);
 878                                         src = sg_virt(dd->in_sg) +
 879                                               _calc_walked(in);
 880                                 }
 881                         } else {
 882                                 src++;
 883                         }
 884                 }
 885 
 886                 /* Clear IRQ status */
 887                 status &= ~DES_REG_IRQ_DATA_IN;
 888                 omap_des_write(dd, DES_REG_IRQ_STATUS(dd), status);
 889 
 890                 /* Enable DATA_OUT interrupt */
 891                 omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x4);
 892 
 893         } else if (status & DES_REG_IRQ_DATA_OUT) {
 894                 omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x0);
 895 
 896                 BUG_ON(!dd->out_sg);
 897 
 898                 BUG_ON(_calc_walked(out) > dd->out_sg->length);
 899 
 900                 dst = sg_virt(dd->out_sg) + _calc_walked(out);
 901 
 902                 for (i = 0; i < DES_BLOCK_WORDS; i++) {
 903                         *dst = omap_des_read(dd, DES_REG_DATA_N(dd, i));
 904                         scatterwalk_advance(&dd->out_walk, 4);
 905                         if (dd->out_sg->length == _calc_walked(out)) {
 906                                 dd->out_sg = sg_next(dd->out_sg);
 907                                 if (dd->out_sg) {
 908                                         scatterwalk_start(&dd->out_walk,
 909                                                           dd->out_sg);
 910                                         dst = sg_virt(dd->out_sg) +
 911                                               _calc_walked(out);
 912                                 }
 913                         } else {
 914                                 dst++;
 915                         }
 916                 }
 917 
 918                 BUG_ON(dd->total < DES_BLOCK_SIZE);
 919 
 920                 dd->total -= DES_BLOCK_SIZE;
 921 
 922                 /* Clear IRQ status */
 923                 status &= ~DES_REG_IRQ_DATA_OUT;
 924                 omap_des_write(dd, DES_REG_IRQ_STATUS(dd), status);
 925 
 926                 if (!dd->total)
 927                         /* All bytes read! */
 928                         tasklet_schedule(&dd->done_task);
 929                 else
 930                         /* Enable DATA_IN interrupt for next block */
 931                         omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x2);
 932         }
 933 
 934         return IRQ_HANDLED;
 935 }
 936 
 937 static const struct of_device_id omap_des_of_match[] = {
 938         {
 939                 .compatible     = "ti,omap4-des",
 940                 .data           = &omap_des_pdata_omap4,
 941         },
 942         {},
 943 };
 944 MODULE_DEVICE_TABLE(of, omap_des_of_match);
 945 
 946 static int omap_des_get_of(struct omap_des_dev *dd,
 947                 struct platform_device *pdev)
 948 {
 949 
 950         dd->pdata = of_device_get_match_data(&pdev->dev);
 951         if (!dd->pdata) {
 952                 dev_err(&pdev->dev, "no compatible OF match\n");
 953                 return -EINVAL;
 954         }
 955 
 956         return 0;
 957 }
 958 #else
 959 static int omap_des_get_of(struct omap_des_dev *dd,
 960                 struct device *dev)
 961 {
 962         return -EINVAL;
 963 }
 964 #endif
 965 
 966 static int omap_des_get_pdev(struct omap_des_dev *dd,
 967                 struct platform_device *pdev)
 968 {
 969         /* non-DT devices get pdata from pdev */
 970         dd->pdata = pdev->dev.platform_data;
 971 
 972         return 0;
 973 }
 974 
 975 static int omap_des_probe(struct platform_device *pdev)
 976 {
 977         struct device *dev = &pdev->dev;
 978         struct omap_des_dev *dd;
 979         struct crypto_alg *algp;
 980         struct resource *res;
 981         int err = -ENOMEM, i, j, irq = -1;
 982         u32 reg;
 983 
 984         dd = devm_kzalloc(dev, sizeof(struct omap_des_dev), GFP_KERNEL);
 985         if (dd == NULL) {
 986                 dev_err(dev, "unable to alloc data struct.\n");
 987                 goto err_data;
 988         }
 989         dd->dev = dev;
 990         platform_set_drvdata(pdev, dd);
 991 
 992         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 993         if (!res) {
 994                 dev_err(dev, "no MEM resource info\n");
 995                 goto err_res;
 996         }
 997 
 998         err = (dev->of_node) ? omap_des_get_of(dd, pdev) :
 999                                omap_des_get_pdev(dd, pdev);
1000         if (err)
1001                 goto err_res;
1002 
1003         dd->io_base = devm_ioremap_resource(dev, res);
1004         if (IS_ERR(dd->io_base)) {
1005                 err = PTR_ERR(dd->io_base);
1006                 goto err_res;
1007         }
1008         dd->phys_base = res->start;
1009 
1010         pm_runtime_use_autosuspend(dev);
1011         pm_runtime_set_autosuspend_delay(dev, DEFAULT_AUTOSUSPEND_DELAY);
1012 
1013         pm_runtime_enable(dev);
1014         err = pm_runtime_get_sync(dev);
1015         if (err < 0) {
1016                 pm_runtime_put_noidle(dev);
1017                 dev_err(dd->dev, "%s: failed to get_sync(%d)\n", __func__, err);
1018                 goto err_get;
1019         }
1020 
1021         omap_des_dma_stop(dd);
1022 
1023         reg = omap_des_read(dd, DES_REG_REV(dd));
1024 
1025         pm_runtime_put_sync(dev);
1026 
1027         dev_info(dev, "OMAP DES hw accel rev: %u.%u\n",
1028                  (reg & dd->pdata->major_mask) >> dd->pdata->major_shift,
1029                  (reg & dd->pdata->minor_mask) >> dd->pdata->minor_shift);
1030 
1031         tasklet_init(&dd->done_task, omap_des_done_task, (unsigned long)dd);
1032 
1033         err = omap_des_dma_init(dd);
1034         if (err == -EPROBE_DEFER) {
1035                 goto err_irq;
1036         } else if (err && DES_REG_IRQ_STATUS(dd) && DES_REG_IRQ_ENABLE(dd)) {
1037                 dd->pio_only = 1;
1038 
1039                 irq = platform_get_irq(pdev, 0);
1040                 if (irq < 0) {
1041                         err = irq;
1042                         goto err_irq;
1043                 }
1044 
1045                 err = devm_request_irq(dev, irq, omap_des_irq, 0,
1046                                 dev_name(dev), dd);
1047                 if (err) {
1048                         dev_err(dev, "Unable to grab omap-des IRQ\n");
1049                         goto err_irq;
1050                 }
1051         }
1052 
1053 
1054         INIT_LIST_HEAD(&dd->list);
1055         spin_lock(&list_lock);
1056         list_add_tail(&dd->list, &dev_list);
1057         spin_unlock(&list_lock);
1058 
1059         /* Initialize des crypto engine */
1060         dd->engine = crypto_engine_alloc_init(dev, 1);
1061         if (!dd->engine) {
1062                 err = -ENOMEM;
1063                 goto err_engine;
1064         }
1065 
1066         err = crypto_engine_start(dd->engine);
1067         if (err)
1068                 goto err_engine;
1069 
1070         for (i = 0; i < dd->pdata->algs_info_size; i++) {
1071                 for (j = 0; j < dd->pdata->algs_info[i].size; j++) {
1072                         algp = &dd->pdata->algs_info[i].algs_list[j];
1073 
1074                         pr_debug("reg alg: %s\n", algp->cra_name);
1075 
1076                         err = crypto_register_alg(algp);
1077                         if (err)
1078                                 goto err_algs;
1079 
1080                         dd->pdata->algs_info[i].registered++;
1081                 }
1082         }
1083 
1084         return 0;
1085 
1086 err_algs:
1087         for (i = dd->pdata->algs_info_size - 1; i >= 0; i--)
1088                 for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--)
1089                         crypto_unregister_alg(
1090                                         &dd->pdata->algs_info[i].algs_list[j]);
1091 
1092 err_engine:
1093         if (dd->engine)
1094                 crypto_engine_exit(dd->engine);
1095 
1096         omap_des_dma_cleanup(dd);
1097 err_irq:
1098         tasklet_kill(&dd->done_task);
1099 err_get:
1100         pm_runtime_disable(dev);
1101 err_res:
1102         dd = NULL;
1103 err_data:
1104         dev_err(dev, "initialization failed.\n");
1105         return err;
1106 }
1107 
1108 static int omap_des_remove(struct platform_device *pdev)
1109 {
1110         struct omap_des_dev *dd = platform_get_drvdata(pdev);
1111         int i, j;
1112 
1113         if (!dd)
1114                 return -ENODEV;
1115 
1116         spin_lock(&list_lock);
1117         list_del(&dd->list);
1118         spin_unlock(&list_lock);
1119 
1120         for (i = dd->pdata->algs_info_size - 1; i >= 0; i--)
1121                 for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--)
1122                         crypto_unregister_alg(
1123                                         &dd->pdata->algs_info[i].algs_list[j]);
1124 
1125         tasklet_kill(&dd->done_task);
1126         omap_des_dma_cleanup(dd);
1127         pm_runtime_disable(dd->dev);
1128         dd = NULL;
1129 
1130         return 0;
1131 }
1132 
1133 #ifdef CONFIG_PM_SLEEP
1134 static int omap_des_suspend(struct device *dev)
1135 {
1136         pm_runtime_put_sync(dev);
1137         return 0;
1138 }
1139 
1140 static int omap_des_resume(struct device *dev)
1141 {
1142         int err;
1143 
1144         err = pm_runtime_get_sync(dev);
1145         if (err < 0) {
1146                 pm_runtime_put_noidle(dev);
1147                 dev_err(dev, "%s: failed to get_sync(%d)\n", __func__, err);
1148                 return err;
1149         }
1150         return 0;
1151 }
1152 #endif
1153 
1154 static SIMPLE_DEV_PM_OPS(omap_des_pm_ops, omap_des_suspend, omap_des_resume);
1155 
1156 static struct platform_driver omap_des_driver = {
1157         .probe  = omap_des_probe,
1158         .remove = omap_des_remove,
1159         .driver = {
1160                 .name   = "omap-des",
1161                 .pm     = &omap_des_pm_ops,
1162                 .of_match_table = of_match_ptr(omap_des_of_match),
1163         },
1164 };
1165 
1166 module_platform_driver(omap_des_driver);
1167 
1168 MODULE_DESCRIPTION("OMAP DES hw acceleration support.");
1169 MODULE_LICENSE("GPL v2");
1170 MODULE_AUTHOR("Joel Fernandes <joelf@ti.com>");

/* [<][>][^][v][top][bottom][index][help] */