omap-aes.c revision eeb2b202c5b886b76c3bfa76f47e450fa69389fb
1537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin/* 2537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin * Cryptographic API. 3537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin * 4537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin * Support for OMAP AES HW acceleration. 5537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin * 6537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin * Copyright (c) 2010 Nokia Corporation 7537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin * Author: Dmitry Kasatkin <dmitry.kasatkin@nokia.com> 8537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin * 9537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin * This program is free software; you can redistribute it and/or modify 10537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin * it under the terms of the GNU General Public License version 2 as published 11537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin * by the Free Software Foundation. 12537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin * 13537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin */ 14537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 15537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define pr_fmt(fmt) "%s: " fmt, __func__ 16537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 17537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <linux/err.h> 18537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <linux/module.h> 19537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <linux/init.h> 20537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <linux/errno.h> 21537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <linux/kernel.h> 22537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <linux/clk.h> 23537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <linux/platform_device.h> 24537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <linux/scatterlist.h> 25537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <linux/dma-mapping.h> 26537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <linux/io.h> 27537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <linux/crypto.h> 28537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <linux/interrupt.h> 29537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <crypto/scatterwalk.h> 30537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <crypto/aes.h> 31537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 32537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <plat/cpu.h> 33537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#include <plat/dma.h> 34537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 35537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin/* OMAP TRM gives bitfields as start:end, where start is the higher bit 36537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin number. For example 7:0 */ 37537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end)) 38537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) 39537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 40537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_KEY(x) (0x1C - ((x ^ 0x01) * 0x04)) 41537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_IV(x) (0x20 + ((x) * 0x04)) 42537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 43537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_CTRL 0x30 44537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_CTRL_CTR_WIDTH (1 << 7) 45537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_CTRL_CTR (1 << 6) 46537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_CTRL_CBC (1 << 5) 47537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_CTRL_KEY_SIZE (3 << 3) 48537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_CTRL_DIRECTION (1 << 2) 49537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_CTRL_INPUT_READY (1 << 1) 50537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_CTRL_OUTPUT_READY (1 << 0) 51537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 52537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_DATA 0x34 53537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_DATA_N(x) (0x34 + ((x) * 0x04)) 54537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 55537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_REV 0x44 56537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_REV_MAJOR 0xF0 57537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_REV_MINOR 0x0F 58537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 59537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_MASK 0x48 60537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_MASK_SIDLE (1 << 6) 61537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_MASK_START (1 << 5) 62537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_MASK_DMA_OUT_EN (1 << 3) 63537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_MASK_DMA_IN_EN (1 << 2) 64537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_MASK_SOFTRESET (1 << 1) 65537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_AUTOIDLE (1 << 0) 66537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 67537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_SYSSTATUS 0x4C 68537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define AES_REG_SYSSTATUS_RESETDONE (1 << 0) 69537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 70537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define DEFAULT_TIMEOUT (5*HZ) 71537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 72537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define FLAGS_MODE_MASK 0x000f 73537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define FLAGS_ENCRYPT BIT(0) 74537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define FLAGS_CBC BIT(1) 75537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define FLAGS_GIV BIT(2) 76537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 77537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define FLAGS_NEW_KEY BIT(4) 78537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define FLAGS_NEW_IV BIT(5) 79537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define FLAGS_INIT BIT(6) 80537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define FLAGS_FAST BIT(7) 81eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin#define FLAGS_BUSY BIT(8) 82537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 83537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstruct omap_aes_ctx { 84537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_dev *dd; 85537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 86537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin int keylen; 87537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin u32 key[AES_KEYSIZE_256 / sizeof(u32)]; 88537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin unsigned long flags; 89537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin}; 90537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 91537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstruct omap_aes_reqctx { 92537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin unsigned long mode; 93537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin}; 94537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 95537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define OMAP_AES_QUEUE_LENGTH 1 96537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin#define OMAP_AES_CACHE_SIZE 0 97537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 98537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstruct omap_aes_dev { 99537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct list_head list; 100537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin unsigned long phys_base; 101537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin void __iomem *io_base; 102537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct clk *iclk; 103537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_ctx *ctx; 104537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct device *dev; 105537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin unsigned long flags; 106537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 107537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin u32 *iv; 108537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin u32 ctrl; 109537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 110537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin spinlock_t lock; 111537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct crypto_queue queue; 112537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 113537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct tasklet_struct task; 114537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 115537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct ablkcipher_request *req; 116537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin size_t total; 117537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct scatterlist *in_sg; 118537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin size_t in_offset; 119537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct scatterlist *out_sg; 120537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin size_t out_offset; 121537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 122537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin size_t buflen; 123537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin void *buf_in; 124537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin size_t dma_size; 125537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin int dma_in; 126537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin int dma_lch_in; 127537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_addr_t dma_addr_in; 128537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin void *buf_out; 129537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin int dma_out; 130537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin int dma_lch_out; 131537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_addr_t dma_addr_out; 132537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin}; 133537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 134537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin/* keep registered devices data here */ 135537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic LIST_HEAD(dev_list); 136537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic DEFINE_SPINLOCK(list_lock); 137537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 138537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic inline u32 omap_aes_read(struct omap_aes_dev *dd, u32 offset) 139537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 140537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return __raw_readl(dd->io_base + offset); 141537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 142537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 143537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic inline void omap_aes_write(struct omap_aes_dev *dd, u32 offset, 144537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin u32 value) 145537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 146537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin __raw_writel(value, dd->io_base + offset); 147537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 148537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 149537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic inline void omap_aes_write_mask(struct omap_aes_dev *dd, u32 offset, 150537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin u32 value, u32 mask) 151537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 152537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin u32 val; 153537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 154537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin val = omap_aes_read(dd, offset); 155537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin val &= ~mask; 156537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin val |= value; 157537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_write(dd, offset, val); 158537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 159537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 160537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic void omap_aes_write_n(struct omap_aes_dev *dd, u32 offset, 161537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin u32 *value, int count) 162537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 163537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin for (; count--; value++, offset += 4) 164537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_write(dd, offset, *value); 165537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 166537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 167537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_wait(struct omap_aes_dev *dd, u32 offset, u32 bit) 168537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 169537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin unsigned long timeout = jiffies + DEFAULT_TIMEOUT; 170537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 171537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin while (!(omap_aes_read(dd, offset) & bit)) { 172537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (time_is_before_jiffies(timeout)) { 173537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_err(dd->dev, "omap-aes timeout\n"); 174537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return -ETIMEDOUT; 175537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 176537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 177537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return 0; 178537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 179537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 180537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_hw_init(struct omap_aes_dev *dd) 181537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 182537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin clk_enable(dd->iclk); 183eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin 184537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!(dd->flags & FLAGS_INIT)) { 185537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* is it necessary to reset before every operation? */ 186537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_SOFTRESET, 187537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin AES_REG_MASK_SOFTRESET); 188537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* 189537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin * prevent OCP bus error (SRESP) in case an access to the module 190537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin * is performed while the module is coming out of soft reset 191537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin */ 192537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin __asm__ __volatile__("nop"); 193537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin __asm__ __volatile__("nop"); 194537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 195eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin if (omap_aes_wait(dd, AES_REG_SYSSTATUS, 196eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin AES_REG_SYSSTATUS_RESETDONE)) { 197eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin clk_disable(dd->iclk); 198eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin return -ETIMEDOUT; 199eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin } 200eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin dd->flags |= FLAGS_INIT; 201537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 202537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 203eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin return 0; 204537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 205537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 206537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic void omap_aes_write_ctrl(struct omap_aes_dev *dd) 207537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 208537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin unsigned int key32; 209537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin int i; 210537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin u32 val, mask; 211537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 212537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3); 213537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (dd->flags & FLAGS_CBC) 214537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin val |= AES_REG_CTRL_CBC; 215537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (dd->flags & FLAGS_ENCRYPT) 216537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin val |= AES_REG_CTRL_DIRECTION; 217537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 218537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (dd->ctrl == val && !(dd->flags & FLAGS_NEW_IV) && 219537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin !(dd->ctx->flags & FLAGS_NEW_KEY)) 220537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin goto out; 221537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 222537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* only need to write control registers for new settings */ 223537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 224537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->ctrl = val; 225537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 226537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin val = 0; 227537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (dd->dma_lch_out >= 0) 228537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin val |= AES_REG_MASK_DMA_OUT_EN; 229537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (dd->dma_lch_in >= 0) 230537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin val |= AES_REG_MASK_DMA_IN_EN; 231537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 232537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin mask = AES_REG_MASK_DMA_IN_EN | AES_REG_MASK_DMA_OUT_EN; 233537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 234537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_write_mask(dd, AES_REG_MASK, val, mask); 235537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 236537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("Set key\n"); 237537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin key32 = dd->ctx->keylen / sizeof(u32); 238537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* set a key */ 239537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin for (i = 0; i < key32; i++) { 240537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_write(dd, AES_REG_KEY(i), 241537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin __le32_to_cpu(dd->ctx->key[i])); 242537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 243537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->ctx->flags &= ~FLAGS_NEW_KEY; 244537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 245537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (dd->flags & FLAGS_NEW_IV) { 246537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("Set IV\n"); 247537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_write_n(dd, AES_REG_IV(0), dd->iv, 4); 248537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->flags &= ~FLAGS_NEW_IV; 249537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 250537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 251537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin mask = AES_REG_CTRL_CBC | AES_REG_CTRL_DIRECTION | 252537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin AES_REG_CTRL_KEY_SIZE; 253537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 254537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_write_mask(dd, AES_REG_CTRL, dd->ctrl, mask); 255537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 256537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinout: 257537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* start DMA or disable idle mode */ 258537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START, 259537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin AES_REG_MASK_START); 260537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 261537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 262537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic struct omap_aes_dev *omap_aes_find_dev(struct omap_aes_ctx *ctx) 263537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 264537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_dev *dd = NULL, *tmp; 265537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 266537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin spin_lock_bh(&list_lock); 267537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!ctx->dd) { 268537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin list_for_each_entry(tmp, &dev_list, list) { 269537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* FIXME: take fist available aes core */ 270537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd = tmp; 271537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin break; 272537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 273537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin ctx->dd = dd; 274537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } else { 275537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* already found before */ 276537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd = ctx->dd; 277537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 278537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin spin_unlock_bh(&list_lock); 279537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 280537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return dd; 281537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 282537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 283537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic void omap_aes_dma_callback(int lch, u16 ch_status, void *data) 284537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 285537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_dev *dd = data; 286537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 287537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (lch == dd->dma_lch_out) 288537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin tasklet_schedule(&dd->task); 289537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 290537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 291537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_dma_init(struct omap_aes_dev *dd) 292537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 293537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin int err = -ENOMEM; 294537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 295537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->dma_lch_out = -1; 296537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->dma_lch_in = -1; 297537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 298537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->buf_in = (void *)__get_free_pages(GFP_KERNEL, OMAP_AES_CACHE_SIZE); 299537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->buf_out = (void *)__get_free_pages(GFP_KERNEL, OMAP_AES_CACHE_SIZE); 300537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->buflen = PAGE_SIZE << OMAP_AES_CACHE_SIZE; 301537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->buflen &= ~(AES_BLOCK_SIZE - 1); 302537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 303537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!dd->buf_in || !dd->buf_out) { 304537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_err(dd->dev, "unable to alloc pages.\n"); 305537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin goto err_alloc; 306537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 307537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 308537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* MAP here */ 309537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->dma_addr_in = dma_map_single(dd->dev, dd->buf_in, dd->buflen, 310537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin DMA_TO_DEVICE); 311537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (dma_mapping_error(dd->dev, dd->dma_addr_in)) { 312537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_err(dd->dev, "dma %d bytes error\n", dd->buflen); 313537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin err = -EINVAL; 314537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin goto err_map_in; 315537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 316537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 317537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->dma_addr_out = dma_map_single(dd->dev, dd->buf_out, dd->buflen, 318537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin DMA_FROM_DEVICE); 319537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (dma_mapping_error(dd->dev, dd->dma_addr_out)) { 320537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_err(dd->dev, "dma %d bytes error\n", dd->buflen); 321537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin err = -EINVAL; 322537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin goto err_map_out; 323537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 324537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 325537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin err = omap_request_dma(dd->dma_in, "omap-aes-rx", 326537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_dma_callback, dd, &dd->dma_lch_in); 327537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (err) { 328537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_err(dd->dev, "Unable to request DMA channel\n"); 329537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin goto err_dma_in; 330537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 331537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin err = omap_request_dma(dd->dma_out, "omap-aes-tx", 332537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_dma_callback, dd, &dd->dma_lch_out); 333537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (err) { 334537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_err(dd->dev, "Unable to request DMA channel\n"); 335537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin goto err_dma_out; 336537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 337537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 338537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return 0; 339537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 340537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinerr_dma_out: 341537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_free_dma(dd->dma_lch_in); 342537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinerr_dma_in: 343537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen, 344537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin DMA_FROM_DEVICE); 345537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinerr_map_out: 346537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen, DMA_TO_DEVICE); 347537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinerr_map_in: 348537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin free_pages((unsigned long)dd->buf_out, OMAP_AES_CACHE_SIZE); 349537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin free_pages((unsigned long)dd->buf_in, OMAP_AES_CACHE_SIZE); 350537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinerr_alloc: 351537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (err) 352537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_err("error: %d\n", err); 353537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return err; 354537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 355537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 356537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic void omap_aes_dma_cleanup(struct omap_aes_dev *dd) 357537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 358537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_free_dma(dd->dma_lch_out); 359537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_free_dma(dd->dma_lch_in); 360537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen, 361537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin DMA_FROM_DEVICE); 362537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen, DMA_TO_DEVICE); 363537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin free_pages((unsigned long)dd->buf_out, OMAP_AES_CACHE_SIZE); 364537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin free_pages((unsigned long)dd->buf_in, OMAP_AES_CACHE_SIZE); 365537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 366537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 367537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic void sg_copy_buf(void *buf, struct scatterlist *sg, 368537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin unsigned int start, unsigned int nbytes, int out) 369537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 370537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct scatter_walk walk; 371537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 372537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!nbytes) 373537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return; 374537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 375537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin scatterwalk_start(&walk, sg); 376537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin scatterwalk_advance(&walk, start); 377537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin scatterwalk_copychunks(buf, &walk, nbytes, out); 378537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin scatterwalk_done(&walk, out, 0); 379537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 380537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 381537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int sg_copy(struct scatterlist **sg, size_t *offset, void *buf, 382537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin size_t buflen, size_t total, int out) 383537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 384537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin unsigned int count, off = 0; 385537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 386537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin while (buflen && total) { 387537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin count = min((*sg)->length - *offset, total); 388537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin count = min(count, buflen); 389537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 390537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!count) 391537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return off; 392537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 393537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin sg_copy_buf(buf + off, *sg, *offset, count, out); 394537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 395537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin off += count; 396537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin buflen -= count; 397537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin *offset += count; 398537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin total -= count; 399537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 400537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (*offset == (*sg)->length) { 401537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin *sg = sg_next(*sg); 402537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (*sg) 403537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin *offset = 0; 404537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin else 405537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin total = 0; 406537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 407537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 408537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 409537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return off; 410537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 411537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 412537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, 413537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_addr_t dma_addr_out, int length) 414537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 415537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_ctx *ctx = crypto_tfm_ctx(tfm); 416537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_dev *dd = ctx->dd; 417537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin int len32; 418537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 419537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("len: %d\n", length); 420537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 421537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->dma_size = length; 422537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 423537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!(dd->flags & FLAGS_FAST)) 424537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_sync_single_for_device(dd->dev, dma_addr_in, length, 425537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin DMA_TO_DEVICE); 426537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 427537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin len32 = DIV_ROUND_UP(length, sizeof(u32)); 428537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 429537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* IN */ 4303bd2e2216bc82a83fc5048f8e61d2d22dd5d9cdaDmitry Kasatkin omap_set_dma_dest_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_CONSTANT, 4313bd2e2216bc82a83fc5048f8e61d2d22dd5d9cdaDmitry Kasatkin dd->phys_base + AES_REG_DATA, 0, 4); 4323bd2e2216bc82a83fc5048f8e61d2d22dd5d9cdaDmitry Kasatkin 4333bd2e2216bc82a83fc5048f8e61d2d22dd5d9cdaDmitry Kasatkin omap_set_dma_dest_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4); 4343bd2e2216bc82a83fc5048f8e61d2d22dd5d9cdaDmitry Kasatkin omap_set_dma_src_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4); 4353bd2e2216bc82a83fc5048f8e61d2d22dd5d9cdaDmitry Kasatkin 436537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_set_dma_transfer_params(dd->dma_lch_in, OMAP_DMA_DATA_TYPE_S32, 437537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin len32, 1, OMAP_DMA_SYNC_PACKET, dd->dma_in, 438537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin OMAP_DMA_DST_SYNC); 439537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 440537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_set_dma_src_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_POST_INC, 441537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_addr_in, 0, 0); 442537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 443537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* OUT */ 4443bd2e2216bc82a83fc5048f8e61d2d22dd5d9cdaDmitry Kasatkin omap_set_dma_src_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_CONSTANT, 4453bd2e2216bc82a83fc5048f8e61d2d22dd5d9cdaDmitry Kasatkin dd->phys_base + AES_REG_DATA, 0, 4); 4463bd2e2216bc82a83fc5048f8e61d2d22dd5d9cdaDmitry Kasatkin 4473bd2e2216bc82a83fc5048f8e61d2d22dd5d9cdaDmitry Kasatkin omap_set_dma_src_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4); 4483bd2e2216bc82a83fc5048f8e61d2d22dd5d9cdaDmitry Kasatkin omap_set_dma_dest_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4); 4493bd2e2216bc82a83fc5048f8e61d2d22dd5d9cdaDmitry Kasatkin 450537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_set_dma_transfer_params(dd->dma_lch_out, OMAP_DMA_DATA_TYPE_S32, 451537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin len32, 1, OMAP_DMA_SYNC_PACKET, 452537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->dma_out, OMAP_DMA_SRC_SYNC); 453537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 454537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_set_dma_dest_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_POST_INC, 455537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_addr_out, 0, 0); 456537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 457537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_start_dma(dd->dma_lch_in); 458537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_start_dma(dd->dma_lch_out); 459537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 460537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_write_ctrl(dd); 461537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 462537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return 0; 463537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 464537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 465537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_crypt_dma_start(struct omap_aes_dev *dd) 466537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 467537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct crypto_tfm *tfm = crypto_ablkcipher_tfm( 468537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin crypto_ablkcipher_reqtfm(dd->req)); 469537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin int err, fast = 0, in, out; 470537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin size_t count; 471537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_addr_t addr_in, addr_out; 472537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 473537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("total: %d\n", dd->total); 474537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 475537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (sg_is_last(dd->in_sg) && sg_is_last(dd->out_sg)) { 476537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* check for alignment */ 477537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin in = IS_ALIGNED((u32)dd->in_sg->offset, sizeof(u32)); 478537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin out = IS_ALIGNED((u32)dd->out_sg->offset, sizeof(u32)); 479537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 480537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin fast = in && out; 481537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 482537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 483537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (fast) { 484537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin count = min(dd->total, sg_dma_len(dd->in_sg)); 485537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin count = min(count, sg_dma_len(dd->out_sg)); 486537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 487537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (count != dd->total) 488537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return -EINVAL; 489537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 490537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("fast\n"); 491537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 492537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin err = dma_map_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); 493537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!err) { 494537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_err(dd->dev, "dma_map_sg() error\n"); 495537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return -EINVAL; 496537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 497537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 498537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin err = dma_map_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE); 499537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!err) { 500537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_err(dd->dev, "dma_map_sg() error\n"); 501537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); 502537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return -EINVAL; 503537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 504537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 505537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin addr_in = sg_dma_address(dd->in_sg); 506537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin addr_out = sg_dma_address(dd->out_sg); 507537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 508537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->flags |= FLAGS_FAST; 509537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 510537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } else { 511537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* use cache buffers */ 512537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin count = sg_copy(&dd->in_sg, &dd->in_offset, dd->buf_in, 513537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->buflen, dd->total, 0); 514537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 515537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin addr_in = dd->dma_addr_in; 516537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin addr_out = dd->dma_addr_out; 517537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 518537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->flags &= ~FLAGS_FAST; 519537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 520537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 521537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 522537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->total -= count; 523537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 524537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin err = omap_aes_hw_init(dd); 525537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 526537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin err = omap_aes_crypt_dma(tfm, addr_in, addr_out, count); 527537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 528537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return err; 529537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 530537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 531537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic void omap_aes_finish_req(struct omap_aes_dev *dd, int err) 532537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 533537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_ctx *ctx; 534537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 535537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("err: %d\n", err); 536537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 537eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin dd->flags &= ~FLAGS_BUSY; 538eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin 539537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(dd->req)); 540537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 541537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!dd->total) 542537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->req->base.complete(&dd->req->base, err); 543537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 544537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 545537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd) 546537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 547537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin int err = 0; 548537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin size_t count; 549537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 550537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("total: %d\n", dd->total); 551537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 552537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_write_mask(dd, AES_REG_MASK, 0, AES_REG_MASK_START); 553537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 554eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin clk_disable(dd->iclk); 555537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 556537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_stop_dma(dd->dma_lch_in); 557537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_stop_dma(dd->dma_lch_out); 558537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 559537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (dd->flags & FLAGS_FAST) { 560537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE); 561537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); 562537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } else { 563537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dma_sync_single_for_device(dd->dev, dd->dma_addr_out, 564537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->dma_size, DMA_FROM_DEVICE); 565537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 566537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* copy data */ 567537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin count = sg_copy(&dd->out_sg, &dd->out_offset, dd->buf_out, 568537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->buflen, dd->dma_size, 1); 569537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (count != dd->dma_size) { 570537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin err = -EINVAL; 571537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_err("not all data converted: %u\n", count); 572537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 573537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 574537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 575537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (err || !dd->total) 576537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_finish_req(dd, err); 577537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 578537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return err; 579537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 580537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 581eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkinstatic int omap_aes_handle_req(struct omap_aes_dev *dd, 582eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin struct ablkcipher_request *req) 583537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 584537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct crypto_async_request *async_req, *backlog; 585537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_ctx *ctx; 586537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_reqctx *rctx; 587537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin unsigned long flags; 588eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin int err = 0; 589537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 590537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin spin_lock_irqsave(&dd->lock, flags); 591eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin if (req) 592eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin err = ablkcipher_enqueue_request(&dd->queue, req); 593eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin if (dd->flags & FLAGS_BUSY) { 594eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin spin_unlock_irqrestore(&dd->lock, flags); 595eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin return err; 596eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin } 597537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin backlog = crypto_get_backlog(&dd->queue); 598537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin async_req = crypto_dequeue_request(&dd->queue); 599eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin if (async_req) 600eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin dd->flags |= FLAGS_BUSY; 601537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin spin_unlock_irqrestore(&dd->lock, flags); 602537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 603537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!async_req) 604537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return 0; 605537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 606537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (backlog) 607537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin backlog->complete(backlog, -EINPROGRESS); 608537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 609537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin req = ablkcipher_request_cast(async_req); 610537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 611537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("get new req\n"); 612537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 613537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* assign new request to device */ 614537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->req = req; 615537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->total = req->nbytes; 616537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->in_offset = 0; 617537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->in_sg = req->src; 618537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->out_offset = 0; 619537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->out_sg = req->dst; 620537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 621537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin rctx = ablkcipher_request_ctx(req); 622537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req)); 623537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin rctx->mode &= FLAGS_MODE_MASK; 624537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode; 625537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 626537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->iv = req->info; 627537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if ((dd->flags & FLAGS_CBC) && dd->iv) 628537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->flags |= FLAGS_NEW_IV; 629537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin else 630537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->flags &= ~FLAGS_NEW_IV; 631537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 632537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin ctx->dd = dd; 633537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (dd->ctx != ctx) { 634537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* assign new context to device */ 635537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->ctx = ctx; 636537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin ctx->flags |= FLAGS_NEW_KEY; 637537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 638537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 639537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) 640537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_err("request size is not exact amount of AES blocks\n"); 641537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 642eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin omap_aes_crypt_dma_start(dd); 643eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin 644eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin return err; 645537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 646537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 647537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic void omap_aes_task(unsigned long data) 648537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 649537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_dev *dd = (struct omap_aes_dev *)data; 650537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 651537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("enter\n"); 652537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 653eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin omap_aes_crypt_dma_stop(dd); 654537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 655eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin if (dd->total) 656eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin omap_aes_crypt_dma_start(dd); 657eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin else 658eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin omap_aes_handle_req(dd, NULL); 659537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 660537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("exit\n"); 661537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 662537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 663537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode) 664537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 665537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx( 666537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin crypto_ablkcipher_reqtfm(req)); 667537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_reqctx *rctx = ablkcipher_request_ctx(req); 668537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_dev *dd; 669537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 670537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("nbytes: %d, enc: %d, cbc: %d\n", req->nbytes, 671537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin !!(mode & FLAGS_ENCRYPT), 672537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin !!(mode & FLAGS_CBC)); 673537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 674537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd = omap_aes_find_dev(ctx); 675537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!dd) 676537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return -ENODEV; 677537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 678537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin rctx->mode = mode; 679537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 680eeb2b202c5b886b76c3bfa76f47e450fa69389fbDmitry Kasatkin return omap_aes_handle_req(dd, req); 681537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 682537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 683537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin/* ********************** ALG API ************************************ */ 684537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 685537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, 686537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin unsigned int keylen) 687537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 688537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); 689537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 690537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 && 691537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin keylen != AES_KEYSIZE_256) 692537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return -EINVAL; 693537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 694537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("enter, keylen: %d\n", keylen); 695537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 696537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin memcpy(ctx->key, key, keylen); 697537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin ctx->keylen = keylen; 698537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin ctx->flags |= FLAGS_NEW_KEY; 699537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 700537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return 0; 701537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 702537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 703537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_ecb_encrypt(struct ablkcipher_request *req) 704537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 705537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return omap_aes_crypt(req, FLAGS_ENCRYPT); 706537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 707537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 708537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_ecb_decrypt(struct ablkcipher_request *req) 709537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 710537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return omap_aes_crypt(req, 0); 711537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 712537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 713537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_cbc_encrypt(struct ablkcipher_request *req) 714537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 715537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return omap_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC); 716537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 717537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 718537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_cbc_decrypt(struct ablkcipher_request *req) 719537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 720537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return omap_aes_crypt(req, FLAGS_CBC); 721537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 722537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 723537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_cra_init(struct crypto_tfm *tfm) 724537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 725537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("enter\n"); 726537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 727537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin tfm->crt_ablkcipher.reqsize = sizeof(struct omap_aes_reqctx); 728537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 729537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return 0; 730537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 731537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 732537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic void omap_aes_cra_exit(struct crypto_tfm *tfm) 733537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 734537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("enter\n"); 735537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 736537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 737537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin/* ********************** ALGS ************************************ */ 738537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 739537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic struct crypto_alg algs[] = { 740537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 741537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_name = "ecb(aes)", 742537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_driver_name = "ecb-aes-omap", 743537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_priority = 100, 744537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 745537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_blocksize = AES_BLOCK_SIZE, 746537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_ctxsize = sizeof(struct omap_aes_ctx), 747537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_alignmask = 0, 748537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_type = &crypto_ablkcipher_type, 749537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_module = THIS_MODULE, 750537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_init = omap_aes_cra_init, 751537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_exit = omap_aes_cra_exit, 752537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_u.ablkcipher = { 753537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .min_keysize = AES_MIN_KEY_SIZE, 754537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .max_keysize = AES_MAX_KEY_SIZE, 755537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .setkey = omap_aes_setkey, 756537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .encrypt = omap_aes_ecb_encrypt, 757537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .decrypt = omap_aes_ecb_decrypt, 758537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 759537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin}, 760537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 761537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_name = "cbc(aes)", 762537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_driver_name = "cbc-aes-omap", 763537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_priority = 100, 764537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 765537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_blocksize = AES_BLOCK_SIZE, 766537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_ctxsize = sizeof(struct omap_aes_ctx), 767537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_alignmask = 0, 768537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_type = &crypto_ablkcipher_type, 769537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_module = THIS_MODULE, 770537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_init = omap_aes_cra_init, 771537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_exit = omap_aes_cra_exit, 772537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .cra_u.ablkcipher = { 773537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .min_keysize = AES_MIN_KEY_SIZE, 774537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .max_keysize = AES_MAX_KEY_SIZE, 775537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .ivsize = AES_BLOCK_SIZE, 776537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .setkey = omap_aes_setkey, 777537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .encrypt = omap_aes_cbc_encrypt, 778537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .decrypt = omap_aes_cbc_decrypt, 779537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 780537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 781537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin}; 782537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 783537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_probe(struct platform_device *pdev) 784537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 785537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct device *dev = &pdev->dev; 786537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_dev *dd; 787537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct resource *res; 788537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin int err = -ENOMEM, i, j; 789537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin u32 reg; 790537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 791537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd = kzalloc(sizeof(struct omap_aes_dev), GFP_KERNEL); 792537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (dd == NULL) { 793537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_err(dev, "unable to alloc data struct.\n"); 794537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin goto err_data; 795537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 796537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->dev = dev; 797537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin platform_set_drvdata(pdev, dd); 798537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 799537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin spin_lock_init(&dd->lock); 800537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin crypto_init_queue(&dd->queue, OMAP_AES_QUEUE_LENGTH); 801537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 802537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* Get the base address */ 803537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 804537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!res) { 805537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_err(dev, "invalid resource type\n"); 806537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin err = -ENODEV; 807537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin goto err_res; 808537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 809537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->phys_base = res->start; 810537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 811537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* Get the DMA */ 812537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 813537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!res) 814537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_info(dev, "no DMA info\n"); 815537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin else 816537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->dma_out = res->start; 817537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 818537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* Get the DMA */ 819537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 820537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!res) 821537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_info(dev, "no DMA info\n"); 822537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin else 823537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->dma_in = res->start; 824537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 825537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin /* Initializing the clock */ 826537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->iclk = clk_get(dev, "ick"); 827537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!dd->iclk) { 828537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_err(dev, "clock intialization failed.\n"); 829537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin err = -ENODEV; 830537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin goto err_res; 831537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 832537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 833537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd->io_base = ioremap(dd->phys_base, SZ_4K); 834537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!dd->io_base) { 835537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_err(dev, "can't ioremap\n"); 836537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin err = -ENOMEM; 837537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin goto err_io; 838537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 839537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 840537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin clk_enable(dd->iclk); 841537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin reg = omap_aes_read(dd, AES_REG_REV); 842537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_info(dev, "OMAP AES hw accel rev: %u.%u\n", 843537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin (reg & AES_REG_REV_MAJOR) >> 4, reg & AES_REG_REV_MINOR); 844537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin clk_disable(dd->iclk); 845537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 846537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin tasklet_init(&dd->task, omap_aes_task, (unsigned long)dd); 847537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 848537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin err = omap_aes_dma_init(dd); 849537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (err) 850537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin goto err_dma; 851537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 852537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin INIT_LIST_HEAD(&dd->list); 853537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin spin_lock(&list_lock); 854537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin list_add_tail(&dd->list, &dev_list); 855537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin spin_unlock(&list_lock); 856537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 857537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin for (i = 0; i < ARRAY_SIZE(algs); i++) { 858537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_debug("i: %d\n", i); 859537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin INIT_LIST_HEAD(&algs[i].cra_list); 860537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin err = crypto_register_alg(&algs[i]); 861537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (err) 862537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin goto err_algs; 863537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 864537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 865537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_info("probe() done\n"); 866537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 867537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return 0; 868537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinerr_algs: 869537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin for (j = 0; j < i; j++) 870537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin crypto_unregister_alg(&algs[j]); 871537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_dma_cleanup(dd); 872537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinerr_dma: 873537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin tasklet_kill(&dd->task); 874537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin iounmap(dd->io_base); 875537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinerr_io: 876537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin clk_put(dd->iclk); 877537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinerr_res: 878537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin kfree(dd); 879537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd = NULL; 880537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinerr_data: 881537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dev_err(dev, "initialization failed.\n"); 882537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return err; 883537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 884537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 885537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int omap_aes_remove(struct platform_device *pdev) 886537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 887537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin struct omap_aes_dev *dd = platform_get_drvdata(pdev); 888537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin int i; 889537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 890537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!dd) 891537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return -ENODEV; 892537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 893537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin spin_lock(&list_lock); 894537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin list_del(&dd->list); 895537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin spin_unlock(&list_lock); 896537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 897537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin for (i = 0; i < ARRAY_SIZE(algs); i++) 898537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin crypto_unregister_alg(&algs[i]); 899537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 900537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin tasklet_kill(&dd->task); 901537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin omap_aes_dma_cleanup(dd); 902537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin iounmap(dd->io_base); 903537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin clk_put(dd->iclk); 904537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin kfree(dd); 905537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin dd = NULL; 906537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 907537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return 0; 908537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 909537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 910537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic struct platform_driver omap_aes_driver = { 911537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .probe = omap_aes_probe, 912537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .remove = omap_aes_remove, 913537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .driver = { 914537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .name = "omap-aes", 915537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin .owner = THIS_MODULE, 916537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin }, 917537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin}; 918537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 919537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic int __init omap_aes_mod_init(void) 920537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 921537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_info("loading %s driver\n", "omap-aes"); 922537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 923537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin if (!cpu_class_is_omap2() || omap_type() != OMAP2_DEVICE_TYPE_SEC) { 924537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin pr_err("Unsupported cpu\n"); 925537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return -ENODEV; 926537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin } 927537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 928537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin return platform_driver_register(&omap_aes_driver); 929537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 930537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 931537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinstatic void __exit omap_aes_mod_exit(void) 932537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin{ 933537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin platform_driver_unregister(&omap_aes_driver); 934537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin} 935537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 936537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinmodule_init(omap_aes_mod_init); 937537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkinmodule_exit(omap_aes_mod_exit); 938537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 939537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry KasatkinMODULE_DESCRIPTION("OMAP AES hw acceleration support."); 940537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry KasatkinMODULE_LICENSE("GPL v2"); 941537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry KasatkinMODULE_AUTHOR("Dmitry Kasatkin"); 942537559a5b3ef854772bd89fbb43aa77d0bbfb721Dmitry Kasatkin 943