blob: 84d41da8452003fde4f79848e27e1f4fc45deb61 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Qualcomm Crypto Engine driver.
2 *
Rohit Vaswanif061c3d2013-01-04 12:01:23 -08003 * Copyright (c) 2011 - 2013, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 and
7 * only version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#include <linux/types.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/mod_devicetable.h>
18#include <linux/device.h>
19#include <linux/clk.h>
20#include <linux/err.h>
21#include <linux/dma-mapping.h>
22#include <linux/io.h>
23#include <linux/platform_device.h>
24#include <linux/spinlock.h>
25#include <linux/delay.h>
26#include <linux/crypto.h>
Mona Hossain5c8ea1f2011-07-28 15:11:29 -070027#include <linux/qcedev.h>
Ramesh Masavarapu720772002011-11-02 10:34:26 -070028#include <linux/bitops.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070029#include <crypto/hash.h>
30#include <crypto/sha.h>
31#include <mach/dma.h>
32#include <mach/clk.h>
Ramesh Masavarapufa679d92011-10-13 23:42:59 -070033#include <mach/socinfo.h>
Mona Hossain5c8ea1f2011-07-28 15:11:29 -070034
35#include "qce.h"
Mona Hossain3b574d82011-09-01 15:02:01 -070036#include "qce40.h"
Mona Hossain5c8ea1f2011-07-28 15:11:29 -070037#include "qcryptohw_40.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070038
39/* ADM definitions */
40#define LI_SG_CMD (1 << 31) /* last index in the scatter gather cmd */
41#define SRC_INDEX_SG_CMD(index) ((index & 0x3fff) << 16)
42#define DST_INDEX_SG_CMD(index) (index & 0x3fff)
43#define ADM_DESC_LAST (1 << 31)
Mona Hossain3b574d82011-09-01 15:02:01 -070044#define QCE_FIFO_SIZE 0x8000
Ramesh Masavarapu9e1c0a02012-02-07 08:56:40 -080045
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070046/*
47 * CE HW device structure.
48 * Each engine has an instance of the structure.
49 * Each engine can only handle one crypto operation at one time. It is up to
50 * the sw above to ensure single threading of operation on an engine.
51 */
52struct qce_device {
53 struct device *pdev; /* Handle to platform_device structure */
Mona Hossain3b574d82011-09-01 15:02:01 -070054
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070055 unsigned char *coh_vmem; /* Allocated coherent virtual memory */
56 dma_addr_t coh_pmem; /* Allocated coherent physical memory */
Mona Hossain3b574d82011-09-01 15:02:01 -070057 int memsize; /* Memory allocated */
58
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070059 void __iomem *iobase; /* Virtual io base of CE HW */
60 unsigned int phy_iobase; /* Physical io base of CE HW */
Mona Hossain3b574d82011-09-01 15:02:01 -070061
Ramesh Masavarapu28311912011-10-27 11:04:12 -070062 struct clk *ce_core_src_clk; /* Handle to CE src clk*/
63 struct clk *ce_core_clk; /* Handle to CE clk */
64 struct clk *ce_clk; /* Handle to CE clk */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070065
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070066 qce_comp_func_ptr_t qce_cb; /* qce callback function pointer */
67
68 int assoc_nents;
69 int ivsize;
70 int authsize;
71 int src_nents;
72 int dst_nents;
73
74 void *areq;
75 enum qce_cipher_mode_enum mode;
Mona Hossain3b574d82011-09-01 15:02:01 -070076 struct ce_dm_data ce_dm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070077};
78
79/* Standard initialization vector for SHA-1, source: FIPS 180-2 */
Mona Hossain3b574d82011-09-01 15:02:01 -070080static uint8_t _std_init_vector_sha1_uint8[] = {
81 0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89,
82 0x98, 0xBA, 0xDC, 0xFE, 0x10, 0x32, 0x54, 0x76,
83 0xC3, 0xD2, 0xE1, 0xF0
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070084};
Mona Hossain3b574d82011-09-01 15:02:01 -070085
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070086/* Standard initialization vector for SHA-256, source: FIPS 180-2 */
Mona Hossain3b574d82011-09-01 15:02:01 -070087static uint8_t _std_init_vector_sha256_uint8[] = {
88 0x6A, 0x09, 0xE6, 0x67, 0xBB, 0x67, 0xAE, 0x85,
89 0x3C, 0x6E, 0xF3, 0x72, 0xA5, 0x4F, 0xF5, 0x3A,
90 0x51, 0x0E, 0x52, 0x7F, 0x9B, 0x05, 0x68, 0x8C,
91 0x1F, 0x83, 0xD9, 0xAB, 0x5B, 0xE0, 0xCD, 0x19
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070092};
93
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070094static void _byte_stream_swap_to_net_words(uint32_t *iv, unsigned char *b,
95 unsigned int len)
96{
97 unsigned i, j;
98 unsigned char swap_iv[AES_IV_LENGTH];
99
100 memset(swap_iv, 0, AES_IV_LENGTH);
101 for (i = (AES_IV_LENGTH-len), j = len-1; i < AES_IV_LENGTH; i++, j--)
102 swap_iv[i] = b[j];
Mona Hossain3b574d82011-09-01 15:02:01 -0700103 memcpy(iv, swap_iv, AES_IV_LENGTH);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700104}
105
106static int count_sg(struct scatterlist *sg, int nbytes)
107{
108 int i;
109
Rohit Vaswanif061c3d2013-01-04 12:01:23 -0800110 for (i = 0; nbytes > 0; i++, sg = scatterwalk_sg_next(sg))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700111 nbytes -= sg->length;
112 return i;
113}
114
Rohit Vaswanif061c3d2013-01-04 12:01:23 -0800115static int qce_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
116 enum dma_data_direction direction)
117{
118 int i;
119
120 for (i = 0; i < nents; ++i) {
121 dma_map_sg(dev, sg, 1, direction);
122 sg = scatterwalk_sg_next(sg);
123 }
124
125 return nents;
126}
127
128static int qce_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
129 int nents, enum dma_data_direction direction)
130{
131 int i;
132
133 for (i = 0; i < nents; ++i) {
134 dma_unmap_sg(dev, sg, 1, direction);
135 sg = scatterwalk_sg_next(sg);
136 }
137
138 return nents;
139}
140
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700141static int dma_map_pmem_sg(struct buf_info *pmem, unsigned entries,
142 struct scatterlist *sg)
143{
144 int i;
145 for (i = 0; i < entries; i++) {
146
147 sg->dma_address = (dma_addr_t)pmem->offset;
148 sg++;
149 pmem++;
150 }
151 return 0;
152}
153
154static int _probe_ce_engine(struct qce_device *pce_dev)
155{
156 unsigned int val;
157 unsigned int rev;
Ramesh Masavarapu9e1c0a02012-02-07 08:56:40 -0800158 unsigned int ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700159
Mona Hossain3b574d82011-09-01 15:02:01 -0700160 val = (uint32_t)(*((uint32_t *)pce_dev->ce_dm.buffer.version));
Mona Hossain5f5dde12011-09-12 10:28:34 -0700161 if (((val & 0xfffffff) != 0x0000043) &&
162 ((val & 0xfffffff) != 0x0000042) &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700163 ((val & 0xfffffff) != 0x0000040)) {
164 dev_err(pce_dev->pdev,
165 "Unknown Qualcomm crypto device at 0x%x 0x%x\n",
166 pce_dev->phy_iobase, val);
167 return -EIO;
168 };
169 rev = (val & CRYPTO_CORE_REV_MASK);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700170 if (rev >= 0x42) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700171 dev_info(pce_dev->pdev,
172 "Qualcomm Crypto 4.2 device found at 0x%x\n",
173 pce_dev->phy_iobase);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700174 pce_dev->ce_dm.ce_block_size = 64;
Ramesh Masavarapu9e1c0a02012-02-07 08:56:40 -0800175
176 /* Configure the crypto register to support 64byte CRCI if it
177 * is not XPU protected and the HW version of device is greater
178 * than 0x42.
179 * Crypto config register returns a 0 when it is XPU protected.
180 */
181
182 ret = readl_relaxed(pce_dev->iobase + CRYPTO_CONFIG_REG);
183 if (ret) {
Mona Hossaine7585292012-02-22 17:14:26 -0800184 val = BIT(CRYPTO_MASK_DOUT_INTR) |
185 BIT(CRYPTO_MASK_DIN_INTR) |
186 BIT(CRYPTO_MASK_OP_DONE_INTR) |
187 BIT(CRYPTO_MASK_ERR_INTR) |
188 (CRYPTO_REQ_SIZE_ENUM_64_BYTES <<
189 CRYPTO_REQ_SIZE) |
190 (CRYPTO_FIFO_ENUM_64_BYTES <<
191 CRYPTO_FIFO_THRESHOLD);
Ramesh Masavarapu9e1c0a02012-02-07 08:56:40 -0800192
193 writel_relaxed(val, pce_dev->iobase +
194 CRYPTO_CONFIG_REG);
195 } /* end of if (ret) */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700196 } else {
197 if (rev == 0x40) {
198 dev_info(pce_dev->pdev,
199 "Qualcomm Crypto 4.0 device found at 0x%x\n",
200 pce_dev->phy_iobase);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700201 pce_dev->ce_dm.ce_block_size = 16;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700202 }
203 }
204
205 dev_info(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -0700206 "IO base 0x%x\n, ce_in channel %d , "
207 "ce_out channel %d\n, "
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700208 "crci_in %d, crci_out %d\n",
209 (unsigned int) pce_dev->iobase,
Mona Hossain3b574d82011-09-01 15:02:01 -0700210 pce_dev->ce_dm.chan_ce_in, pce_dev->ce_dm.chan_ce_out,
211 pce_dev->ce_dm.crci_in, pce_dev->ce_dm.crci_out);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700212
213 return 0;
214};
215
Mona Hossain3b574d82011-09-01 15:02:01 -0700216
217static void _check_probe_done_call_back(struct msm_dmov_cmd *cmd_ptr,
218 unsigned int result, struct msm_dmov_errdata *err)
219{
220 struct qce_device *pce_dev;
221 pce_dev = (struct qce_device *) cmd_ptr->user;
222
223 if (result != ADM_STATUS_OK) {
224 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
225 result);
226 pce_dev->ce_dm.chan_ce_in_status = -1;
227 } else {
228 _probe_ce_engine(pce_dev);
229 pce_dev->ce_dm.chan_ce_in_status = 0;
230 }
231 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
232};
233
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700234static int _init_ce_engine(struct qce_device *pce_dev)
235{
Mona Hossainb8db7432011-11-17 12:33:24 -0800236 int status;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700237 /* Reset ce */
238 clk_reset(pce_dev->ce_core_clk, CLK_RESET_ASSERT);
239 clk_reset(pce_dev->ce_core_clk, CLK_RESET_DEASSERT);
Mona Hossain3b574d82011-09-01 15:02:01 -0700240
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700241 /*
242 * Ensure previous instruction (any writes to CLK registers)
243 * to toggle the CLK reset lines was completed before configuring
244 * ce engine. The ce engine configuration settings should not be lost
245 * becasue of clk reset.
246 */
247 mb();
248
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700249 /*
Mona Hossainb8db7432011-11-17 12:33:24 -0800250 * Clear ACCESS_VIOL bit in CRYPTO_STATUS REGISTER
251 */
252 status = readl_relaxed(pce_dev->iobase + CRYPTO_STATUS_REG);
253 *((uint32_t *)(pce_dev->ce_dm.buffer.status)) = status & (~0x40000);
254 /*
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700255 * Ensure ce configuration is completed.
256 */
257 mb();
258
Mona Hossain3b574d82011-09-01 15:02:01 -0700259 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
260 _check_probe_done_call_back;
261 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
262 pce_dev->ce_dm.cmdptrlist.probe_ce_hw;
263 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
264 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
265 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
266 pce_dev->ce_dm.chan_ce_in_cmd);
267
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700268 return 0;
269};
270
Mona Hossain3b574d82011-09-01 15:02:01 -0700271static int _ce_setup_hash_cmdrptrlist(struct qce_device *pce_dev,
272 struct qce_sha_req *sreq)
273{
274 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
275
276 switch (sreq->alg) {
277 case QCE_HASH_SHA1:
278 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr = cmdptrlist->auth_sha1;
279 break;
280
281 case QCE_HASH_SHA256:
282 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr = cmdptrlist->auth_sha256;
283 break;
284 case QCE_HASH_SHA1_HMAC:
285 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
286 cmdptrlist->auth_sha1_hmac;
287 break;
288
289 case QCE_HASH_SHA256_HMAC:
290 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
291 cmdptrlist->auth_sha256_hmac;
292 break;
293 case QCE_HASH_AES_CMAC:
294 if (sreq->authklen == AES128_KEY_SIZE)
295 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
296 cmdptrlist->auth_aes_128_cmac;
297 else
298 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
299 cmdptrlist->auth_aes_256_cmac;
300 break;
301
302 default:
303 break;
304 }
305
306 return 0;
307}
308
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700309static int _ce_setup_hash(struct qce_device *pce_dev, struct qce_sha_req *sreq)
310{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700311 uint32_t diglen;
312 int i;
313 uint32_t auth_cfg = 0;
314 bool sha1 = false;
315
316 if (sreq->alg == QCE_HASH_AES_CMAC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700317
Mona Hossain3b574d82011-09-01 15:02:01 -0700318 memcpy(pce_dev->ce_dm.buffer.auth_key, sreq->authkey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700319 sreq->authklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700320 auth_cfg |= (1 << CRYPTO_LAST);
321 auth_cfg |= (CRYPTO_AUTH_MODE_CMAC << CRYPTO_AUTH_MODE);
322 auth_cfg |= (CRYPTO_AUTH_SIZE_ENUM_16_BYTES <<
323 CRYPTO_AUTH_SIZE);
324 auth_cfg |= CRYPTO_AUTH_ALG_AES << CRYPTO_AUTH_ALG;
325
326 switch (sreq->authklen) {
327 case AES128_KEY_SIZE:
328 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES128 <<
329 CRYPTO_AUTH_KEY_SIZE);
330 break;
331 case AES256_KEY_SIZE:
332 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES256 <<
333 CRYPTO_AUTH_KEY_SIZE);
334 break;
335 default:
336 break;
337 }
338
339 goto go_proc;
340 }
341
342 /* if not the last, the size has to be on the block boundary */
343 if (sreq->last_blk == 0 && (sreq->size % SHA256_BLOCK_SIZE))
344 return -EIO;
345
346 switch (sreq->alg) {
347 case QCE_HASH_SHA1:
348 case QCE_HASH_SHA1_HMAC:
349 diglen = SHA1_DIGEST_SIZE;
350 sha1 = true;
351 break;
352 case QCE_HASH_SHA256:
353 case QCE_HASH_SHA256_HMAC:
354 diglen = SHA256_DIGEST_SIZE;
355 break;
356 default:
357 return -EINVAL;
358 }
359
360 if ((sreq->alg == QCE_HASH_SHA1_HMAC) ||
361 (sreq->alg == QCE_HASH_SHA256_HMAC)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700362
Mona Hossain3b574d82011-09-01 15:02:01 -0700363 memcpy(pce_dev->ce_dm.buffer.auth_key, sreq->authkey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700364 sreq->authklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700365 auth_cfg |= (CRYPTO_AUTH_MODE_HMAC << CRYPTO_AUTH_MODE);
366 } else {
367 auth_cfg |= (CRYPTO_AUTH_MODE_HASH << CRYPTO_AUTH_MODE);
368 }
369
370 /* write 20/32 bytes, 5/8 words into auth_iv for SHA1/SHA256 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700371 if (sreq->first_blk) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700372 if (sha1)
373 memcpy(pce_dev->ce_dm.buffer.auth_iv,
374 _std_init_vector_sha1_uint8, diglen);
375 else
376 memcpy(pce_dev->ce_dm.buffer.auth_iv,
377 _std_init_vector_sha256_uint8, diglen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700378 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700379 memcpy(pce_dev->ce_dm.buffer.auth_iv, sreq->digest,
380 diglen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700381 }
382
Mona Hossain3b574d82011-09-01 15:02:01 -0700383 /* write auth_bytecnt 0/1/2/3, start with 0 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700384 for (i = 0; i < 4; i++)
Mona Hossain3b574d82011-09-01 15:02:01 -0700385 *(((uint32_t *)(pce_dev->ce_dm.buffer.auth_byte_count) + i)) =
386 sreq->auth_data[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700387
388 /* write seg_cfg */
389 if (sha1)
390 auth_cfg |= (CRYPTO_AUTH_SIZE_SHA1 << CRYPTO_AUTH_SIZE);
391 else
392 auth_cfg |= (CRYPTO_AUTH_SIZE_SHA256 << CRYPTO_AUTH_SIZE);
393
394 if (sreq->last_blk)
395 auth_cfg |= 1 << CRYPTO_LAST;
396
397 auth_cfg |= CRYPTO_AUTH_ALG_SHA << CRYPTO_AUTH_ALG;
398
399go_proc:
400 auth_cfg |= (CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);
401
Mona Hossain3b574d82011-09-01 15:02:01 -0700402 /* write auth seg cfg */
403 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start)) =
404 auth_cfg;
405 /* write auth seg size */
406 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start) + 1) =
407 sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700408
Mona Hossain3b574d82011-09-01 15:02:01 -0700409 /* write auth seg size start*/
410 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start)+2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700411
Mona Hossain3b574d82011-09-01 15:02:01 -0700412 /* write seg size */
413 *((uint32_t *)(pce_dev->ce_dm.buffer.seg_size)) = sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700414
Mona Hossain3b574d82011-09-01 15:02:01 -0700415 _ce_setup_hash_cmdrptrlist(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700416
Mona Hossain3b574d82011-09-01 15:02:01 -0700417 return 0;
418}
419
420static int _ce_setup_cipher_cmdrptrlist(struct qce_device *pce_dev,
421 struct qce_req *creq)
422{
423 struct ce_cmdptrlists_ops *cmdptrlist =
424 &pce_dev->ce_dm.cmdptrlist;
425
426 if (creq->alg != CIPHER_ALG_AES) {
427 switch (creq->alg) {
428 case CIPHER_ALG_DES:
429 if (creq->mode == QCE_MODE_ECB) {
430 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
431 cmdptrlist->cipher_des_ecb;
432 } else {
433 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
434 cmdptrlist->cipher_des_cbc;
435 }
436 break;
437
438 case CIPHER_ALG_3DES:
439 if (creq->mode == QCE_MODE_ECB) {
440 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
441 cmdptrlist->cipher_3des_ecb;
442 } else {
443 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
444 cmdptrlist->cipher_3des_cbc;
445 }
446 break;
447 default:
448 break;
449 }
450 } else {
451 switch (creq->mode) {
452 case QCE_MODE_ECB:
453 if (creq->encklen == AES128_KEY_SIZE) {
454 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
455 cmdptrlist->cipher_aes_128_ecb;
456 } else {
457 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
458 cmdptrlist->cipher_aes_256_ecb;
459 }
460 break;
461
462 case QCE_MODE_CBC:
463 if (creq->encklen == AES128_KEY_SIZE) {
464 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
465 cmdptrlist->cipher_aes_128_cbc_ctr;
466 } else {
467 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
468 cmdptrlist->cipher_aes_256_cbc_ctr;
469 }
470 break;
471
472 case QCE_MODE_CTR:
473 if (creq->encklen == AES128_KEY_SIZE) {
474 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
475 cmdptrlist->cipher_aes_128_cbc_ctr;
476 } else {
477 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
478 cmdptrlist->cipher_aes_256_cbc_ctr;
479 }
480 break;
481
482 case QCE_MODE_XTS:
483 if (creq->encklen == AES128_KEY_SIZE) {
484 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
485 cmdptrlist->cipher_aes_128_xts;
486 } else {
487 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
488 cmdptrlist->cipher_aes_256_xts;
489 }
490 break;
491 case QCE_MODE_CCM:
492 if (creq->encklen == AES128_KEY_SIZE) {
493 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
494 cmdptrlist->aead_aes_128_ccm;
495 } else {
496 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
497 cmdptrlist->aead_aes_256_ccm;
498 }
499 break;
500 default:
501 break;
502 }
503 }
504
Mona Hossainb8db7432011-11-17 12:33:24 -0800505 switch (creq->mode) {
506 case QCE_MODE_CCM:
Mona Hossain3b574d82011-09-01 15:02:01 -0700507 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
Mona Hossainb8db7432011-11-17 12:33:24 -0800508 cmdptrlist->aead_ce_out;
509 break;
510 case QCE_MODE_ECB:
Mona Hossain3b574d82011-09-01 15:02:01 -0700511 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
Mona Hossainb8db7432011-11-17 12:33:24 -0800512 cmdptrlist->cipher_ce_out;
513 break;
514 default:
515 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
516 cmdptrlist->cipher_ce_out_get_iv;
517 break;
518 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700519
520 return 0;
521}
522
523static int _ce_setup_cipher(struct qce_device *pce_dev, struct qce_req *creq,
524 uint32_t totallen_in, uint32_t coffset)
525{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700526 uint32_t enck_size_in_word = creq->encklen / sizeof(uint32_t);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700527 uint32_t encr_cfg = 0;
528 uint32_t ivsize = creq->ivsize;
Mona Hossain3b574d82011-09-01 15:02:01 -0700529 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700530
531 if (creq->mode == QCE_MODE_XTS)
Mona Hossain3b574d82011-09-01 15:02:01 -0700532 memcpy(buffer->encr_key, creq->enckey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700533 creq->encklen/2);
534 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700535 memcpy(buffer->encr_key, creq->enckey, creq->encklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700536
537 if ((creq->op == QCE_REQ_AEAD) && (creq->mode == QCE_MODE_CCM)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700538 uint32_t noncelen32 = MAX_NONCE/sizeof(uint32_t);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700539 uint32_t auth_cfg = 0;
540
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700541 /* write nonce */
Mona Hossain3b574d82011-09-01 15:02:01 -0700542 memcpy(buffer->auth_nonce_info, creq->nonce, MAX_NONCE);
543 memcpy(buffer->auth_key, creq->enckey, creq->encklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700544
545 auth_cfg |= (noncelen32 << CRYPTO_AUTH_NONCE_NUM_WORDS);
546 auth_cfg &= ~(1 << CRYPTO_USE_HW_KEY_AUTH);
547 auth_cfg |= (1 << CRYPTO_LAST);
548 if (creq->dir == QCE_ENCRYPT)
549 auth_cfg |= (CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);
550 else
551 auth_cfg |= (CRYPTO_AUTH_POS_AFTER << CRYPTO_AUTH_POS);
552 auth_cfg |= (((creq->authsize >> 1) - 2) << CRYPTO_AUTH_SIZE);
553 auth_cfg |= (CRYPTO_AUTH_MODE_CCM << CRYPTO_AUTH_MODE);
554 if (creq->authklen == AES128_KEY_SIZE)
555 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES128 <<
556 CRYPTO_AUTH_KEY_SIZE);
557 else {
558 if (creq->authklen == AES256_KEY_SIZE)
559 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES256 <<
560 CRYPTO_AUTH_KEY_SIZE);
561 }
562 auth_cfg |= (CRYPTO_AUTH_ALG_AES << CRYPTO_AUTH_ALG);
Mona Hossain3b574d82011-09-01 15:02:01 -0700563 *((uint32_t *)(buffer->auth_seg_cfg_size_start)) = auth_cfg;
564
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700565 if (creq->dir == QCE_ENCRYPT)
Mona Hossain3b574d82011-09-01 15:02:01 -0700566 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 1) =
567 totallen_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700568 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700569 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 1) =
570 (totallen_in - creq->authsize);
571 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700572 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700573
574 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700575
576 switch (creq->mode) {
577 case QCE_MODE_ECB:
578 encr_cfg |= (CRYPTO_ENCR_MODE_ECB << CRYPTO_ENCR_MODE);
579 break;
580
581 case QCE_MODE_CBC:
582 encr_cfg |= (CRYPTO_ENCR_MODE_CBC << CRYPTO_ENCR_MODE);
583 break;
584
585 case QCE_MODE_XTS:
586 encr_cfg |= (CRYPTO_ENCR_MODE_XTS << CRYPTO_ENCR_MODE);
587 break;
588
589 case QCE_MODE_CCM:
590 encr_cfg |= (CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE);
591 break;
592
593 case QCE_MODE_CTR:
594 default:
595 encr_cfg |= (CRYPTO_ENCR_MODE_CTR << CRYPTO_ENCR_MODE);
596 break;
597 }
598 pce_dev->mode = creq->mode;
599
600 switch (creq->alg) {
601 case CIPHER_ALG_DES:
Mona Hossain3b574d82011-09-01 15:02:01 -0700602 if (creq->mode != QCE_MODE_ECB)
603 memcpy(buffer->encr_cntr_iv, creq->iv, ivsize);
604
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700605 encr_cfg |= ((CRYPTO_ENCR_KEY_SZ_DES << CRYPTO_ENCR_KEY_SZ) |
606 (CRYPTO_ENCR_ALG_DES << CRYPTO_ENCR_ALG));
607 break;
608
609 case CIPHER_ALG_3DES:
Mona Hossain3b574d82011-09-01 15:02:01 -0700610 if (creq->mode != QCE_MODE_ECB)
611 memcpy(buffer->encr_cntr_iv, creq->iv, ivsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700612
613 encr_cfg |= ((CRYPTO_ENCR_KEY_SZ_3DES << CRYPTO_ENCR_KEY_SZ) |
614 (CRYPTO_ENCR_ALG_DES << CRYPTO_ENCR_ALG));
615 break;
616
617 case CIPHER_ALG_AES:
618 default:
619 if (creq->mode == QCE_MODE_XTS) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700620 memcpy(buffer->encr_xts_key, (creq->enckey +
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700621 creq->encklen/2), creq->encklen/2);
Mona Hossain3b574d82011-09-01 15:02:01 -0700622 *((uint32_t *)(buffer->encr_xts_du_size)) =
623 creq->cryptlen;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700624
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700625 }
626 if (creq->mode != QCE_MODE_ECB) {
627 if (creq->mode == QCE_MODE_XTS)
Mona Hossain3b574d82011-09-01 15:02:01 -0700628 _byte_stream_swap_to_net_words(
629 (uint32_t *)(buffer->encr_cntr_iv),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700630 creq->iv, ivsize);
631 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700632 memcpy(buffer->encr_cntr_iv, creq->iv,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700633 ivsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700634 }
635 /* set number of counter bits */
Mona Hossain3b574d82011-09-01 15:02:01 -0700636 *((uint32_t *)(buffer->encr_mask)) = (uint32_t)0xffffffff;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700637
638 if (creq->op == QCE_REQ_ABLK_CIPHER_NO_KEY) {
639 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES128 <<
640 CRYPTO_ENCR_KEY_SZ);
641 encr_cfg |= CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG;
642 } else {
643 uint32_t key_size;
644
645 if (creq->mode == QCE_MODE_XTS) {
646 key_size = creq->encklen/2;
647 enck_size_in_word = key_size/sizeof(uint32_t);
648 } else {
649 key_size = creq->encklen;
650 }
651
652 switch (key_size) {
653 case AES128_KEY_SIZE:
654 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES128 <<
655 CRYPTO_ENCR_KEY_SZ);
656 break;
657 case AES256_KEY_SIZE:
658 default:
659 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES256 <<
660 CRYPTO_ENCR_KEY_SZ);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700661 break;
662 } /* end of switch (creq->encklen) */
663
664 encr_cfg |= CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700665 } /* else of if (creq->op == QCE_REQ_ABLK_CIPHER_NO_KEY) */
666 break;
667 } /* end of switch (creq->mode) */
668
669 /* write encr seg cfg */
670 encr_cfg |= ((creq->dir == QCE_ENCRYPT) ? 1 : 0) << CRYPTO_ENCODE;
671
672 /* write encr seg cfg */
Mona Hossain3b574d82011-09-01 15:02:01 -0700673 *((uint32_t *)(buffer->encr_seg_cfg_size_start)) = encr_cfg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700674 /* write encr seg size */
675 if ((creq->mode == QCE_MODE_CCM) && (creq->dir == QCE_DECRYPT))
Mona Hossain3b574d82011-09-01 15:02:01 -0700676 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 1) =
677 (creq->cryptlen + creq->authsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700678 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700679 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 1) =
680 creq->cryptlen;
681
682
683 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 2) =
684 (coffset & 0xffff);
685
686 *((uint32_t *)(buffer->seg_size)) = totallen_in;
687
688 _ce_setup_cipher_cmdrptrlist(pce_dev, creq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700689 return 0;
690};
691
692static int _aead_complete(struct qce_device *pce_dev)
693{
694 struct aead_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700695
696 areq = (struct aead_request *) pce_dev->areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700697
698 if (areq->src != areq->dst) {
Rohit Vaswanif061c3d2013-01-04 12:01:23 -0800699 qce_dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700700 DMA_FROM_DEVICE);
701 }
Rohit Vaswanif061c3d2013-01-04 12:01:23 -0800702 qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700703 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
704 DMA_TO_DEVICE);
705
Rohit Vaswanif061c3d2013-01-04 12:01:23 -0800706 qce_dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700707 DMA_TO_DEVICE);
708
Mona Hossain3b574d82011-09-01 15:02:01 -0700709 /* check MAC */
710 if (pce_dev->mode == QCE_MODE_CCM) {
711 uint32_t result;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700712
Mona Hossain3b574d82011-09-01 15:02:01 -0700713 result =
714 (uint32_t)(*((uint32_t *)pce_dev->ce_dm.buffer.status));
715 result &= (1 << CRYPTO_MAC_FAILED);
716 result |= (pce_dev->ce_dm.chan_ce_in_status |
717 pce_dev->ce_dm.chan_ce_out_status);
718 pce_dev->qce_cb(areq, pce_dev->ce_dm.buffer.auth_result, NULL,
719 result);
720 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700721 return 0;
722};
723
724static void _sha_complete(struct qce_device *pce_dev)
725{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700726 struct ahash_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700727
728 areq = (struct ahash_request *) pce_dev->areq;
Rohit Vaswanif061c3d2013-01-04 12:01:23 -0800729 qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700730 DMA_TO_DEVICE);
731
Mona Hossain3b574d82011-09-01 15:02:01 -0700732 pce_dev->qce_cb(areq, pce_dev->ce_dm.buffer.auth_result,
733 pce_dev->ce_dm.buffer.auth_byte_count,
734 pce_dev->ce_dm.chan_ce_in_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700735
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700736};
737
738static int _ablk_cipher_complete(struct qce_device *pce_dev)
739{
740 struct ablkcipher_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700741
742 areq = (struct ablkcipher_request *) pce_dev->areq;
743
744 if (areq->src != areq->dst) {
Rohit Vaswanif061c3d2013-01-04 12:01:23 -0800745 qce_dma_unmap_sg(pce_dev->pdev, areq->dst,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700746 pce_dev->dst_nents, DMA_FROM_DEVICE);
747 }
Rohit Vaswanif061c3d2013-01-04 12:01:23 -0800748 qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700749 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
750 DMA_TO_DEVICE);
Mona Hossain3b574d82011-09-01 15:02:01 -0700751
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700752 if (pce_dev->mode == QCE_MODE_ECB) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700753 pce_dev->qce_cb(areq, NULL, NULL,
754 pce_dev->ce_dm.chan_ce_in_status |
755 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700756 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700757
Mona Hossain3b574d82011-09-01 15:02:01 -0700758 pce_dev->qce_cb(areq, NULL, pce_dev->ce_dm.buffer.encr_cntr_iv,
759 pce_dev->ce_dm.chan_ce_in_status |
760 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700761 }
762
763 return 0;
764};
765
766static int _ablk_cipher_use_pmem_complete(struct qce_device *pce_dev)
767{
768 struct ablkcipher_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700769
770 areq = (struct ablkcipher_request *) pce_dev->areq;
771
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700772 if (pce_dev->mode == QCE_MODE_ECB) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700773 pce_dev->qce_cb(areq, NULL, NULL,
774 pce_dev->ce_dm.chan_ce_in_status |
775 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700776 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700777 pce_dev->qce_cb(areq, NULL, pce_dev->ce_dm.buffer.encr_cntr_iv,
778 pce_dev->ce_dm.chan_ce_in_status |
779 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700780 }
781
782 return 0;
783};
784
785static int qce_split_and_insert_dm_desc(struct dmov_desc *pdesc,
786 unsigned int plen, unsigned int paddr, int *index)
787{
Mona Hossain3b574d82011-09-01 15:02:01 -0700788 while (plen > QCE_FIFO_SIZE) {
789 pdesc->len = QCE_FIFO_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700790 if (paddr > 0) {
791 pdesc->addr = paddr;
Mona Hossain3b574d82011-09-01 15:02:01 -0700792 paddr += QCE_FIFO_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700793 }
794 plen -= pdesc->len;
795 if (plen > 0) {
796 *index = (*index) + 1;
797 if ((*index) >= QCE_MAX_NUM_DESC)
798 return -ENOMEM;
799 pdesc++;
800 }
801 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700802 if ((plen > 0) && (plen <= QCE_FIFO_SIZE)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700803 pdesc->len = plen;
804 if (paddr > 0)
805 pdesc->addr = paddr;
806 }
807
808 return 0;
809}
810
811static int _chain_sg_buffer_in(struct qce_device *pce_dev,
812 struct scatterlist *sg, unsigned int nbytes)
813{
814 unsigned int len;
815 unsigned int dlen;
816 struct dmov_desc *pdesc;
817
Mona Hossain3b574d82011-09-01 15:02:01 -0700818 pdesc = pce_dev->ce_dm.ce_in_src_desc +
819 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700820 /*
821 * Two consective chunks may be handled by the old
822 * buffer descriptor.
823 */
824 while (nbytes > 0) {
825 len = min(nbytes, sg_dma_len(sg));
826 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
827 nbytes -= len;
828 if (dlen == 0) {
829 pdesc->addr = sg_dma_address(sg);
830 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700831 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700832 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700833 sg_dma_address(sg),
834 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700835 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
836 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700837 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700838 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700839 pdesc->addr,
840 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700841 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700842 pce_dev->ce_dm.ce_in_src_desc_index++;
843 if (pce_dev->ce_dm.ce_in_src_desc_index >=
844 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700845 return -ENOMEM;
846 pdesc++;
847 pdesc->len = len;
848 pdesc->addr = sg_dma_address(sg);
Mona Hossain3b574d82011-09-01 15:02:01 -0700849 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700850 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700851 sg_dma_address(sg),
852 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700853 }
854 if (nbytes > 0)
Rohit Vaswanif061c3d2013-01-04 12:01:23 -0800855 sg = scatterwalk_sg_next(sg);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700856 }
857 return 0;
858}
859
860static int _chain_pm_buffer_in(struct qce_device *pce_dev,
861 unsigned int pmem, unsigned int nbytes)
862{
863 unsigned int dlen;
864 struct dmov_desc *pdesc;
865
Mona Hossain3b574d82011-09-01 15:02:01 -0700866 pdesc = pce_dev->ce_dm.ce_in_src_desc +
867 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700868 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
869 if (dlen == 0) {
870 pdesc->addr = pmem;
871 pdesc->len = nbytes;
872 } else if (pmem == (pdesc->addr + dlen)) {
873 pdesc->len = dlen + nbytes;
874 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700875 pce_dev->ce_dm.ce_in_src_desc_index++;
876 if (pce_dev->ce_dm.ce_in_src_desc_index >=
877 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700878 return -ENOMEM;
879 pdesc++;
880 pdesc->len = nbytes;
881 pdesc->addr = pmem;
882 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700883 return 0;
884}
885
886static void _chain_buffer_in_init(struct qce_device *pce_dev)
887{
888 struct dmov_desc *pdesc;
889
Mona Hossain3b574d82011-09-01 15:02:01 -0700890 pce_dev->ce_dm.ce_in_src_desc_index = 0;
891 pce_dev->ce_dm.ce_in_dst_desc_index = 0;
892 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700893 pdesc->len = 0;
894}
895
896static void _ce_in_final(struct qce_device *pce_dev, unsigned total)
897{
898 struct dmov_desc *pdesc;
899 dmov_sg *pcmd;
900
Mona Hossain3b574d82011-09-01 15:02:01 -0700901 pdesc = pce_dev->ce_dm.ce_in_src_desc +
902 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700903 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700904
905 pdesc = pce_dev->ce_dm.ce_in_dst_desc;
906 if (total > QCE_FIFO_SIZE) {
907 qce_split_and_insert_dm_desc(pdesc, total, 0,
908 &pce_dev->ce_dm.ce_in_dst_desc_index);
909 pdesc = pce_dev->ce_dm.ce_in_dst_desc +
910 pce_dev->ce_dm.ce_in_dst_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -0700911 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700912 } else
913 pdesc->len = ADM_DESC_LAST | total;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700914
Mona Hossain3b574d82011-09-01 15:02:01 -0700915 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700916 pcmd->cmd |= CMD_LC;
Mona Hossain3b574d82011-09-01 15:02:01 -0700917
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700918}
919
920#ifdef QCE_DEBUG
921static void _ce_in_dump(struct qce_device *pce_dev)
922{
923 int i;
924 struct dmov_desc *pdesc;
925
926 dev_info(pce_dev->pdev, "_ce_in_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700927 for (i = 0; i <= pce_dev->ce_dm.ce_in_src_desc_index; i++) {
928 pdesc = pce_dev->ce_dm.ce_in_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700929 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
930 pdesc->len);
931 }
932 dev_info(pce_dev->pdev, "_ce_in_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700933 for (i = 0; i <= pce_dev->ce_dm.ce_in_dst_desc_index; i++) {
934 pdesc = pce_dev->ce_dm.ce_in_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700935 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
936 pdesc->len);
937 }
938};
939
940static void _ce_out_dump(struct qce_device *pce_dev)
941{
942 int i;
943 struct dmov_desc *pdesc;
944
945 dev_info(pce_dev->pdev, "_ce_out_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700946 for (i = 0; i <= pce_dev->ce_dm.ce_out_src_desc_index; i++) {
947 pdesc = pce_dev->ce_dm.ce_out_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700948 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
949 pdesc->len);
950 }
951
952 dev_info(pce_dev->pdev, "_ce_out_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700953 for (i = 0; i <= pce_dev->ce_dm.ce_out_dst_desc_index; i++) {
954 pdesc = pce_dev->ce_dm.ce_out_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700955 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
956 pdesc->len);
957 }
958};
959
960#else
961
962static void _ce_in_dump(struct qce_device *pce_dev)
963{
964};
965
966static void _ce_out_dump(struct qce_device *pce_dev)
967{
968};
969
970#endif
971
972static int _chain_sg_buffer_out(struct qce_device *pce_dev,
973 struct scatterlist *sg, unsigned int nbytes)
974{
975 unsigned int len;
976 unsigned int dlen;
977 struct dmov_desc *pdesc;
978
Mona Hossain3b574d82011-09-01 15:02:01 -0700979 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
980 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700981 /*
982 * Two consective chunks may be handled by the old
983 * buffer descriptor.
984 */
985 while (nbytes > 0) {
986 len = min(nbytes, sg_dma_len(sg));
987 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
988 nbytes -= len;
989 if (dlen == 0) {
990 pdesc->addr = sg_dma_address(sg);
991 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700992 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700993 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
994 sg_dma_address(sg),
Mona Hossain3b574d82011-09-01 15:02:01 -0700995 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700996 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
997 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700998 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700999 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
1000 pdesc->addr,
Mona Hossain3b574d82011-09-01 15:02:01 -07001001 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001002
1003 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001004 pce_dev->ce_dm.ce_out_dst_desc_index++;
1005 if (pce_dev->ce_dm.ce_out_dst_desc_index >=
1006 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001007 return -EIO;
1008 pdesc++;
1009 pdesc->len = len;
1010 pdesc->addr = sg_dma_address(sg);
Mona Hossain3b574d82011-09-01 15:02:01 -07001011 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001012 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
1013 sg_dma_address(sg),
Mona Hossain3b574d82011-09-01 15:02:01 -07001014 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001015
1016 }
1017 if (nbytes > 0)
Rohit Vaswanif061c3d2013-01-04 12:01:23 -08001018 sg = scatterwalk_sg_next(sg);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001019 }
1020 return 0;
1021}
1022
1023static int _chain_pm_buffer_out(struct qce_device *pce_dev,
1024 unsigned int pmem, unsigned int nbytes)
1025{
1026 unsigned int dlen;
1027 struct dmov_desc *pdesc;
1028
Mona Hossain3b574d82011-09-01 15:02:01 -07001029 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
1030 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001031 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
1032
1033 if (dlen == 0) {
1034 pdesc->addr = pmem;
1035 pdesc->len = nbytes;
1036 } else if (pmem == (pdesc->addr + dlen)) {
1037 pdesc->len = dlen + nbytes;
1038 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001039 pce_dev->ce_dm.ce_out_dst_desc_index++;
1040 if (pce_dev->ce_dm.ce_out_dst_desc_index >= QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001041 return -EIO;
1042 pdesc++;
1043 pdesc->len = nbytes;
1044 pdesc->addr = pmem;
1045 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001046 return 0;
1047};
1048
1049static void _chain_buffer_out_init(struct qce_device *pce_dev)
1050{
1051 struct dmov_desc *pdesc;
1052
Mona Hossain3b574d82011-09-01 15:02:01 -07001053 pce_dev->ce_dm.ce_out_dst_desc_index = 0;
1054 pce_dev->ce_dm.ce_out_src_desc_index = 0;
1055 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001056 pdesc->len = 0;
1057};
1058
1059static void _ce_out_final(struct qce_device *pce_dev, unsigned total)
1060{
1061 struct dmov_desc *pdesc;
1062 dmov_sg *pcmd;
1063
Mona Hossain3b574d82011-09-01 15:02:01 -07001064 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
1065 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001066 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001067
Mona Hossain3b574d82011-09-01 15:02:01 -07001068 pdesc = pce_dev->ce_dm.ce_out_src_desc +
1069 pce_dev->ce_dm.ce_out_src_desc_index;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001070 if (total > QCE_FIFO_SIZE) {
1071 qce_split_and_insert_dm_desc(pdesc, total, 0,
1072 &pce_dev->ce_dm.ce_out_src_desc_index);
1073 pdesc = pce_dev->ce_dm.ce_out_src_desc +
1074 pce_dev->ce_dm.ce_out_src_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -07001075 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001076 } else
1077 pdesc->len = ADM_DESC_LAST | total;
Mona Hossain3b574d82011-09-01 15:02:01 -07001078
1079 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001080 pcmd->cmd |= CMD_LC;
1081};
1082
1083static void _aead_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1084 unsigned int result, struct msm_dmov_errdata *err)
1085{
1086 struct qce_device *pce_dev;
1087
1088 pce_dev = (struct qce_device *) cmd_ptr->user;
1089 if (result != ADM_STATUS_OK) {
1090 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1091 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001092 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001093 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001094 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001095 }
1096
Mona Hossain3b574d82011-09-01 15:02:01 -07001097 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1098 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1099 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1100 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001101
1102 /* done */
1103 _aead_complete(pce_dev);
1104 }
1105};
1106
1107static void _aead_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1108 unsigned int result, struct msm_dmov_errdata *err)
1109{
1110 struct qce_device *pce_dev;
1111
1112 pce_dev = (struct qce_device *) cmd_ptr->user;
1113 if (result != ADM_STATUS_OK) {
1114 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1115 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001116 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001117 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001118 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001119 };
1120
Mona Hossain3b574d82011-09-01 15:02:01 -07001121 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1122 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1123 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1124 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001125
1126 /* done */
1127 _aead_complete(pce_dev);
1128 }
1129
1130};
1131
1132static void _sha_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1133 unsigned int result, struct msm_dmov_errdata *err)
1134{
1135 struct qce_device *pce_dev;
1136
1137 pce_dev = (struct qce_device *) cmd_ptr->user;
1138 if (result != ADM_STATUS_OK) {
1139 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1140 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001141 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001142 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001143 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001144 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001145 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001146 _sha_complete(pce_dev);
1147};
1148
1149static void _ablk_cipher_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1150 unsigned int result, struct msm_dmov_errdata *err)
1151{
1152 struct qce_device *pce_dev;
1153
1154 pce_dev = (struct qce_device *) cmd_ptr->user;
1155 if (result != ADM_STATUS_OK) {
1156 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1157 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001158 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001159 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001160 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001161 }
1162
Mona Hossain3b574d82011-09-01 15:02:01 -07001163 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1164 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1165 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1166 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001167
1168 /* done */
1169 _ablk_cipher_complete(pce_dev);
1170 }
1171};
1172
1173static void _ablk_cipher_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1174 unsigned int result, struct msm_dmov_errdata *err)
1175{
1176 struct qce_device *pce_dev;
1177
1178 pce_dev = (struct qce_device *) cmd_ptr->user;
Mona Hossain3b574d82011-09-01 15:02:01 -07001179
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001180 if (result != ADM_STATUS_OK) {
1181 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1182 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001183 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001184 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001185 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001186 };
1187
Mona Hossain3b574d82011-09-01 15:02:01 -07001188 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1189 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1190 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1191 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001192
1193 /* done */
1194 _ablk_cipher_complete(pce_dev);
1195 }
1196};
1197
1198
1199static void _ablk_cipher_ce_in_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1200 unsigned int result, struct msm_dmov_errdata *err)
1201{
1202 struct qce_device *pce_dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001203 pce_dev = (struct qce_device *) cmd_ptr->user;
1204 if (result != ADM_STATUS_OK) {
1205 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1206 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001207 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001208 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001209 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001210 }
1211
Mona Hossain3b574d82011-09-01 15:02:01 -07001212 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1213 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1214 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1215 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001216
1217 /* done */
1218 _ablk_cipher_use_pmem_complete(pce_dev);
1219 }
1220};
1221
1222static void _ablk_cipher_ce_out_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1223 unsigned int result, struct msm_dmov_errdata *err)
1224{
1225 struct qce_device *pce_dev;
1226
1227 pce_dev = (struct qce_device *) cmd_ptr->user;
1228 if (result != ADM_STATUS_OK) {
1229 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1230 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001231 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001232 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001233 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001234 };
1235
Mona Hossain3b574d82011-09-01 15:02:01 -07001236 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1237 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1238 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1239 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001240
1241 /* done */
1242 _ablk_cipher_use_pmem_complete(pce_dev);
1243 }
1244};
1245
Mona Hossain3b574d82011-09-01 15:02:01 -07001246static int qce_setup_cmd_buffers(struct qce_device *pce_dev,
1247 unsigned char **pvaddr)
1248{
1249 struct ce_reg_buffers *addr = (struct ce_reg_buffers *)(*pvaddr);
1250 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
1251
1252 /*
1253 * Designate chunks of the allocated memory to various
1254 * buffer pointers
1255 */
1256 buffer->reset_buf_64 = addr->reset_buf_64;
1257 buffer->version = addr->version;
1258 buffer->encr_seg_cfg_size_start = addr->encr_seg_cfg_size_start;
1259 buffer->encr_key = addr->encr_key;
1260 buffer->encr_xts_key = addr->encr_xts_key;
1261 buffer->encr_xts_du_size = addr->encr_xts_du_size;
1262 buffer->encr_cntr_iv = addr->encr_cntr_iv;
1263 buffer->encr_mask = addr->encr_mask;
1264 buffer->auth_seg_cfg_size_start = addr->auth_seg_cfg_size_start;
1265 buffer->auth_key = addr->auth_key;
1266 buffer->auth_iv = addr->auth_iv;
1267 buffer->auth_result = addr->auth_result;
1268 buffer->auth_nonce_info = addr->auth_nonce_info;
1269 buffer->auth_byte_count = addr->auth_byte_count;
1270 buffer->seg_size = addr->seg_size;
1271 buffer->go_proc = addr->go_proc;
1272 buffer->status = addr->status;
1273 buffer->pad = addr->pad;
1274
1275 memset(buffer->reset_buf_64, 0, 64);
1276 *((uint32_t *)buffer->encr_mask) = (uint32_t)(0xffffffff);
1277 *((uint32_t *)buffer->go_proc) = (uint32_t)(1 << CRYPTO_GO);
1278
1279 *pvaddr += sizeof(struct ce_reg_buffers);
1280
1281 return 0;
1282
1283}
1284
1285static int _setup_cipher_cmdlists(struct qce_device *pce_dev,
1286 unsigned char **pvaddr)
1287{
1288 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1289
1290 /*
1291 * Designate chunks of the allocated memory to various
1292 * command list pointers related to cipher operation
1293 */
1294 pce_dev->ce_dm.cmdlist.set_cipher_cfg = pscmd;
1295 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1296 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG +
1297 pce_dev->phy_iobase);
1298 pscmd->len = CRYPTO_REG_SIZE * 3;
1299 pscmd->src =
1300 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_seg_cfg_size_start);
1301 pscmd++;
1302
1303 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_key = pscmd;
1304 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1305 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1306 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1307 pscmd->len = CRYPTO_REG_SIZE * 4;
1308 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1309 pscmd++;
1310
1311 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_key = pscmd;
1312 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1313 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1314 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1315 pscmd->len = CRYPTO_REG_SIZE * 8;
1316 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1317 pscmd++;
1318
1319 pce_dev->ce_dm.cmdlist.set_cipher_des_key = pscmd;
1320 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1321 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1322 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1323 pscmd->len = CRYPTO_REG_SIZE * 2;
1324 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1325 pscmd++;
1326
1327 pce_dev->ce_dm.cmdlist.set_cipher_3des_key = pscmd;
1328 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1329 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1330 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1331 pscmd->len = CRYPTO_REG_SIZE * 6;
1332 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1333 pscmd++;
1334
1335 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_xts_key = pscmd;
1336 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1337 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1338 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1339 pce_dev->phy_iobase);
1340 pscmd->len = CRYPTO_REG_SIZE * 4;
1341 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1342 pscmd++;
1343
1344 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_xts_key = pscmd;
1345 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1346 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1347 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1348 pce_dev->phy_iobase);
1349 pscmd->len = CRYPTO_REG_SIZE * 8;
1350 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1351 pscmd++;
1352
1353 pce_dev->ce_dm.cmdlist.set_cipher_xts_du_size = pscmd;
1354 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1355 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_DU_SIZE_REG +
1356 pce_dev->phy_iobase);
1357 pscmd->len = CRYPTO_REG_SIZE * 4;
1358 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_du_size);
1359 pscmd++;
1360
1361 pce_dev->ce_dm.cmdlist.set_cipher_aes_iv = pscmd;
1362 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1363 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1364 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1365 pscmd->len = CRYPTO_REG_SIZE * 4;
1366 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1367 pscmd++;
1368
Mona Hossain3b574d82011-09-01 15:02:01 -07001369 pce_dev->ce_dm.cmdlist.set_cipher_des_iv = pscmd;
1370 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1371 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1372 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1373 pscmd->len = CRYPTO_REG_SIZE * 2;
1374 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1375 pscmd++;
1376
Mona Hossainb8db7432011-11-17 12:33:24 -08001377 pce_dev->ce_dm.cmdlist.get_cipher_iv = pscmd;
Mona Hossain3b574d82011-09-01 15:02:01 -07001378 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1379 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1380 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
Mona Hossainb8db7432011-11-17 12:33:24 -08001381 pscmd->len = CRYPTO_REG_SIZE * 4;
Mona Hossain3b574d82011-09-01 15:02:01 -07001382 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1383 pscmd++;
1384
1385 pce_dev->ce_dm.cmdlist.set_cipher_mask = pscmd;
1386 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1387 pscmd->dst = (unsigned) (CRYPTO_CNTR_MASK_REG + pce_dev->phy_iobase);
1388 pscmd->len = CRYPTO_REG_SIZE;
1389 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_mask);
1390 pscmd++;
1391
1392 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1393
1394 pce_dev->ce_dm.cmdlist.reset_cipher_key = pscmd;
1395 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1396 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1397 pscmd->len = CRYPTO_REG_SIZE * 8;
1398 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1399 pscmd++;
1400
1401 pce_dev->ce_dm.cmdlist.reset_cipher_xts_key = pscmd;
1402 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1403 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1404 pce_dev->phy_iobase);
1405 pscmd->len = CRYPTO_REG_SIZE * 8;
1406 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1407 pscmd++;
1408
1409 pce_dev->ce_dm.cmdlist.reset_cipher_iv = pscmd;
1410 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1411 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1412 pscmd->len = CRYPTO_REG_SIZE * 4;
1413 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1414 pscmd++;
1415
1416 pce_dev->ce_dm.cmdlist.reset_cipher_cfg = pscmd;
1417 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1418 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG + pce_dev->phy_iobase);
1419 pscmd->len = CRYPTO_REG_SIZE;
1420 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1421 pscmd++;
1422
1423 *pvaddr = (unsigned char *) pscmd;
1424
1425 return 0;
1426}
1427
1428static int _setup_auth_cmdlists(struct qce_device *pce_dev,
1429 unsigned char **pvaddr)
1430{
1431 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1432
1433 /*
1434 * Designate chunks of the allocated memory to various
1435 * command list pointers related to authentication operation
1436 */
1437 pce_dev->ce_dm.cmdlist.set_auth_cfg = pscmd;
1438 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1439 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1440 pscmd->len = CRYPTO_REG_SIZE * 3;
1441 pscmd->src =
1442 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start);
1443 pscmd++;
1444
1445 pce_dev->ce_dm.cmdlist.set_auth_key_128 = pscmd;
1446 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1447 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1448 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1449 pscmd->len = CRYPTO_REG_SIZE * 4;
1450 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1451 pscmd++;
1452
1453 pce_dev->ce_dm.cmdlist.set_auth_key_256 = pscmd;
1454 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1455 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1456 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1457 pscmd->len = CRYPTO_REG_SIZE * 8;
1458 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1459 pscmd++;
1460
1461 pce_dev->ce_dm.cmdlist.set_auth_key_512 = pscmd;
1462 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1463 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1464 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1465 pscmd->len = CRYPTO_REG_SIZE * 16;
1466 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1467 pscmd++;
1468
1469 pce_dev->ce_dm.cmdlist.set_auth_iv_16 = pscmd;
1470 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1471 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1472 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1473 pscmd->len = CRYPTO_REG_SIZE * 4;
1474 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1475 pscmd++;
1476
1477 pce_dev->ce_dm.cmdlist.get_auth_result_16 = pscmd;
1478 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1479 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1480 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1481 pscmd->len = CRYPTO_REG_SIZE * 4;
1482 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1483 pscmd++;
1484
1485 pce_dev->ce_dm.cmdlist.set_auth_iv_20 = pscmd;
1486 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1487 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1488 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1489 pscmd->len = CRYPTO_REG_SIZE * 5;
1490 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1491 pscmd++;
1492
1493 pce_dev->ce_dm.cmdlist.get_auth_result_20 = pscmd;
1494 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1495 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1496 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1497 pscmd->len = CRYPTO_REG_SIZE * 5;
1498 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1499 pscmd++;
1500
1501 pce_dev->ce_dm.cmdlist.set_auth_iv_32 = pscmd;
1502 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1503 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1504 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1505 pscmd->len = CRYPTO_REG_SIZE * 8;
1506 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1507 pscmd++;
1508
1509
1510 pce_dev->ce_dm.cmdlist.get_auth_result_32 = pscmd;
1511 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1512 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1513 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1514 pscmd->len = CRYPTO_REG_SIZE * 8;
1515 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1516 pscmd++;
1517
1518 pce_dev->ce_dm.cmdlist.set_auth_byte_count = pscmd;
1519 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1520 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1521 pce_dev->phy_iobase);
1522 pscmd->len = CRYPTO_REG_SIZE * 4;
1523 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1524 pscmd++;
1525
1526 pce_dev->ce_dm.cmdlist.get_auth_byte_count = pscmd;
1527 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1528 pscmd->src = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1529 pce_dev->phy_iobase);
1530 pscmd->len = CRYPTO_REG_SIZE * 4;
1531 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1532 pscmd++;
1533
1534 pce_dev->ce_dm.cmdlist.set_auth_nonce_info = pscmd;
1535 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1536 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1537 pscmd->dst = (unsigned) (CRYPTO_AUTH_INFO_NONCE0_REG +
1538 pce_dev->phy_iobase);
1539 pscmd->len = CRYPTO_REG_SIZE * 4;
1540 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_nonce_info);
1541 pscmd++;
1542
1543 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1544
1545 pce_dev->ce_dm.cmdlist.reset_auth_key = pscmd;
1546 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1547 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1548 pscmd->len = CRYPTO_REG_SIZE * 16;
1549 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1550 pscmd++;
1551
1552 pce_dev->ce_dm.cmdlist.reset_auth_iv = pscmd;
1553 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1554 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1555 pscmd->len = CRYPTO_REG_SIZE * 16;
1556 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1557 pscmd++;
1558
1559 pce_dev->ce_dm.cmdlist.reset_auth_cfg = pscmd;
1560 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1561 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1562 pscmd->len = CRYPTO_REG_SIZE;
1563 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1564 pscmd++;
1565
1566
1567 pce_dev->ce_dm.cmdlist.reset_auth_byte_count = pscmd;
1568 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1569 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1570 pce_dev->phy_iobase);
1571 pscmd->len = CRYPTO_REG_SIZE * 4;
1572 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1573 pscmd++;
1574
1575 /* WAIT UNTIL MAC OP IS DONE*/
1576
1577 pce_dev->ce_dm.cmdlist.get_status_wait = pscmd;
1578 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1579 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1580 pscmd->len = CRYPTO_REG_SIZE;
1581 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1582 pscmd++;
1583
1584 *pvaddr = (unsigned char *) pscmd;
1585
1586 return 0;
1587}
1588
1589static int qce_setup_cmdlists(struct qce_device *pce_dev,
1590 unsigned char **pvaddr)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001591{
1592 dmov_sg *pcmd;
Mona Hossain3b574d82011-09-01 15:02:01 -07001593 dmov_s *pscmd;
1594 unsigned char *vaddr = *pvaddr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001595 struct dmov_desc *pdesc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001596 int i = 0;
1597
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001598 /*
Mona Hossain3b574d82011-09-01 15:02:01 -07001599 * Designate chunks of the allocated memory to various
1600 * command list pointers related to operation define
1601 * in ce_cmdlists structure.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001602 */
Mona Hossain3b574d82011-09-01 15:02:01 -07001603 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
1604 *pvaddr = (unsigned char *) vaddr;
1605
1606 _setup_cipher_cmdlists(pce_dev, pvaddr);
1607 _setup_auth_cmdlists(pce_dev, pvaddr);
1608
1609 pscmd = (dmov_s *)(*pvaddr);
1610
1611 /* GET HW VERSION COMMAND LIST */
1612 pce_dev->ce_dm.cmdlist.get_hw_version = pscmd;
1613 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1614 pscmd->src = (unsigned) (CRYPTO_VERSION_REG + pce_dev->phy_iobase);
1615 pscmd->len = CRYPTO_REG_SIZE;
1616 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.version);
1617 pscmd++;
1618
1619
1620 /* SET SEG SIZE REGISTER and OCB COMMAND LIST */
1621 pce_dev->ce_dm.cmdlist.set_seg_size_ocb = pscmd;
1622 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1623 pscmd->dst = (unsigned) (CRYPTO_SEG_SIZE_REG + pce_dev->phy_iobase);
1624 pscmd->len = CRYPTO_REG_SIZE;
1625 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.seg_size);
1626 pscmd++;
1627
1628
1629 /* OCU COMMAND LIST */
1630 pce_dev->ce_dm.cmdlist.get_status_ocu = pscmd;
1631 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCU;
1632 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1633 pscmd->len = CRYPTO_REG_SIZE;
1634 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1635 pscmd++;
1636
Mona Hossainb8db7432011-11-17 12:33:24 -08001637 /* CLEAR STATUS COMMAND LIST */
1638 pce_dev->ce_dm.cmdlist.clear_status = pscmd;
1639 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCU;
1640 pscmd->dst = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1641 pscmd->len = CRYPTO_REG_SIZE;
1642 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1643 pscmd++;
1644
Mona Hossain3b574d82011-09-01 15:02:01 -07001645 /* SET GO_PROC REGISTERS COMMAND LIST */
1646 pce_dev->ce_dm.cmdlist.set_go_proc = pscmd;
1647 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1648 pscmd->dst = (unsigned) (CRYPTO_GOPROC_REG + pce_dev->phy_iobase);
1649 pscmd->len = CRYPTO_REG_SIZE;
1650 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.go_proc);
1651 pscmd++;
1652
1653 pcmd = (dmov_sg *)pscmd;
1654 pce_dev->ce_dm.cmdlist.ce_data_in = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001655 /* swap byte and half word , dst crci , scatter gather */
1656 pcmd->cmd = CMD_DST_SWAP_BYTES | CMD_DST_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001657 CMD_DST_CRCI(pce_dev->ce_dm.crci_in) | CMD_MODE_SG;
1658
1659 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001660 pdesc->addr = 0; /* to be filled in each operation */
1661 pdesc->len = 0; /* to be filled in each operation */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001662
Mona Hossain3b574d82011-09-01 15:02:01 -07001663 pdesc = pce_dev->ce_dm.ce_in_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001664 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1665 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1666 pdesc->len = 0; /* to be filled in each operation */
1667 pdesc++;
1668 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001669 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_src_desc);
1670 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001671 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1672 DST_INDEX_SG_CMD(0);
Mona Hossain3b574d82011-09-01 15:02:01 -07001673
1674
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001675 pcmd++;
Mona Hossain3b574d82011-09-01 15:02:01 -07001676 pce_dev->ce_dm.cmdlist.ce_data_out = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001677 /* swap byte, half word, source crci, scatter gather */
1678 pcmd->cmd = CMD_SRC_SWAP_BYTES | CMD_SRC_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001679 CMD_SRC_CRCI(pce_dev->ce_dm.crci_out) | CMD_MODE_SG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001680
Mona Hossain3b574d82011-09-01 15:02:01 -07001681 pdesc = pce_dev->ce_dm.ce_out_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001682 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1683 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1684 pdesc->len = 0; /* to be filled in each operation */
1685 pdesc++;
1686 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001687
Mona Hossain3b574d82011-09-01 15:02:01 -07001688 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001689 pdesc->addr = 0; /* to be filled in each operation */
1690 pdesc->len = 0; /* to be filled in each operation */
Mona Hossain3b574d82011-09-01 15:02:01 -07001691
1692 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_src_desc);
1693 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001694 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1695 DST_INDEX_SG_CMD(0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001696 pcmd++;
1697
Mona Hossain3b574d82011-09-01 15:02:01 -07001698 *pvaddr = (unsigned char *) pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001699
1700 return 0;
Mona Hossain3b574d82011-09-01 15:02:01 -07001701}
1702
1703static int _setup_cipher_cmdptrlists(struct qce_device *pce_dev,
1704 unsigned char **pvaddr)
1705{
1706 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1707 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1708 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1709
1710 /*
1711 * Designate chunks of the allocated memory to various
1712 * command list pointers related to cipher operations defined
1713 * in ce_cmdptrlists_ops structure.
1714 */
1715 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1716 cmdptrlist->cipher_aes_128_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1717
1718 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1719 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1720 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1721 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1722 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1723 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1724 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001725 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001726
1727 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1728 cmdptrlist->cipher_aes_256_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1729
1730 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1731 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1732 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1733 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1734 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1735 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1736 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001737 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001738
1739 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1740 cmdptrlist->cipher_aes_128_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1741
1742 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1743 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1744 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1745 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1746 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1747 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1748 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1749
1750 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1751 cmdptrlist->cipher_aes_256_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1752
1753 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1754 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1755 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1756 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1757 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1758 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1759 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1760
1761 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1762 cmdptrlist->cipher_aes_128_xts = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1763
1764 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1765 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1766 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1767 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_xts_key);
1768 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1769 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1770 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
1771 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1772 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001773 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001774
1775 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1776 cmdptrlist->cipher_aes_256_xts = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1777
1778 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1779 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1780 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1781 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_xts_key);
1782 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1783 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1784 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
1785 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1786 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001787 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001788
1789 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1790 cmdptrlist->cipher_des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1791
1792 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1793 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1794 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1795 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1796 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1797 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001798 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001799
1800 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1801 cmdptrlist->cipher_des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1802
1803 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1804 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1805 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1806 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1807 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1808 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1809
1810 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1811 cmdptrlist->cipher_3des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1812
1813 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1814 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1815 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1816 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1817 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1818 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001819 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001820
1821 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1822 cmdptrlist->cipher_3des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1823
1824 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1825 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1826 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1827 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1828 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1829 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1830
1831 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1832 cmdptrlist->cipher_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1833
1834 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1835 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
Mona Hossainb8db7432011-11-17 12:33:24 -08001836
1837 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1838 cmdptrlist->cipher_ce_out_get_iv = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1839
1840 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1841 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_cipher_iv);
1842 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1843
Mona Hossain3b574d82011-09-01 15:02:01 -07001844 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1845
1846 return 0;
1847}
1848
1849static int _setup_auth_cmdptrlists(struct qce_device *pce_dev,
1850 unsigned char **pvaddr)
1851{
1852 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1853 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1854 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1855
1856 /*
1857 * Designate chunks of the allocated memory to various
1858 * command list pointers related to authentication operations
1859 * defined in ce_cmdptrlists_ops structure.
1860 */
1861 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1862 cmdptrlist->auth_sha1 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1863
1864 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1865 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1866 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1867 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1868 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1869 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1870 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1871 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1872 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
Mona Hossain28f583e2012-11-07 11:52:44 -08001873 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1874 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
Mona Hossain3b574d82011-09-01 15:02:01 -07001875 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1876 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1877 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1878
1879 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1880 cmdptrlist->auth_sha256 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1881
1882 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1883 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1884 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1885 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1886 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1887 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1888 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1889 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1890 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
Mona Hossain28f583e2012-11-07 11:52:44 -08001891 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1892 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
Mona Hossain3b574d82011-09-01 15:02:01 -07001893 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1894 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1895 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1896
1897 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1898 cmdptrlist->auth_sha1_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1899
1900 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1901 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1902 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1903 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1904 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1905 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1906 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1907 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1908 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1909 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
Mona Hossain28f583e2012-11-07 11:52:44 -08001910 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1911 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
Mona Hossain3b574d82011-09-01 15:02:01 -07001912 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1913 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1914 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1915
1916 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1917 cmdptrlist->auth_sha256_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1918
1919 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1920 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1921 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1922 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1923 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1924 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1925 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1926 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1927 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1928 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
Mona Hossain28f583e2012-11-07 11:52:44 -08001929 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1930 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
Mona Hossain3b574d82011-09-01 15:02:01 -07001931 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1932 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1933 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1934
1935 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1936 cmdptrlist->auth_aes_128_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1937
1938 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1939 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1940 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1941 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1942 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1943 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1944 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1945 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1946 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1947 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1948 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1949 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1950 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1951 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1952
1953 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1954 cmdptrlist->auth_aes_256_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1955
1956 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1957 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1958 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1959 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1960 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1961 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1962 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1963 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1964 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1965 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1966 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1967 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1968 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1969 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1970
1971 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1972
1973 return 0;
1974}
1975
1976static int _setup_aead_cmdptrlists(struct qce_device *pce_dev,
1977 unsigned char **pvaddr)
1978{
1979 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1980 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1981 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1982
1983 /*
1984 * Designate chunks of the allocated memory to various
1985 * command list pointers related to aead operations
1986 * defined in ce_cmdptrlists_ops structure.
1987 */
1988 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1989 cmdptrlist->aead_aes_128_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1990
1991 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1992 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1993 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1994 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1995 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1996 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1997 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1998 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1999 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
2000 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
2001 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
2002 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
2003 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
2004
2005 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
2006 cmdptrlist->aead_aes_256_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
2007
2008 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
2009 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
2010 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
2011 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
2012 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
2013 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
2014 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
2015 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
2016 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
2017 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
2018 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
2019 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
2020 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
2021
2022 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
2023 cmdptrlist->aead_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
2024
2025 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
2026 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
2027 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
2028 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
2029
2030 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
2031
2032 return 0;
2033}
2034
2035static int qce_setup_cmdptrlists(struct qce_device *pce_dev,
2036 unsigned char **pvaddr)
2037{
2038 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
2039 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
2040 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
2041 /*
2042 * Designate chunks of the allocated memory to various
2043 * command list pointers related to operations defined
2044 * in ce_cmdptrlists_ops structure.
2045 */
2046 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
2047 cmdptrlist->probe_ce_hw = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
2048
2049 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_hw_version);
Mona Hossainb8db7432011-11-17 12:33:24 -08002050 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->clear_status);
Mona Hossain3b574d82011-09-01 15:02:01 -07002051 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
2052
2053 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
2054
2055 _setup_cipher_cmdptrlists(pce_dev, pvaddr);
2056 _setup_auth_cmdptrlists(pce_dev, pvaddr);
2057 _setup_aead_cmdptrlists(pce_dev, pvaddr);
2058
2059 return 0;
2060}
2061
2062
2063static int qce_setup_ce_dm_data(struct qce_device *pce_dev)
2064{
2065 unsigned char *vaddr;
2066
2067 /* 1. ce_in channel data xfer command src descriptors, 128 entries */
2068 vaddr = pce_dev->coh_vmem;
2069 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2070 pce_dev->ce_dm.ce_in_src_desc = (struct dmov_desc *) vaddr;
2071 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2072
2073 /* 2. ce_in channel data xfer command dst descriptors, 128 entries */
2074 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2075 pce_dev->ce_dm.ce_in_dst_desc = (struct dmov_desc *) vaddr;
2076 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2077
2078
2079 /* 3. ce_out channel data xfer command src descriptors, 128 entries */
2080 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2081 pce_dev->ce_dm.ce_out_src_desc = (struct dmov_desc *) vaddr;
2082 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2083
2084 /* 4. ce_out channel data xfer command dst descriptors, 128 entries. */
2085 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2086 pce_dev->ce_dm.ce_out_dst_desc = (struct dmov_desc *) vaddr;
2087 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2088
2089 qce_setup_cmd_buffers(pce_dev, &vaddr);
2090 qce_setup_cmdlists(pce_dev, &vaddr);
2091 qce_setup_cmdptrlists(pce_dev, &vaddr);
2092
2093 pce_dev->ce_dm.buffer.ignore_data = vaddr;
2094
2095 pce_dev->ce_dm.phy_ce_pad = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.pad);
2096 pce_dev->ce_dm.phy_ce_out_ignore =
2097 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.ignore_data);
2098
2099 pce_dev->ce_dm.chan_ce_in_cmd->user = (void *) pce_dev;
2100 pce_dev->ce_dm.chan_ce_in_cmd->exec_func = NULL;
2101
2102 pce_dev->ce_dm.chan_ce_out_cmd->user = (void *) pce_dev;
2103 pce_dev->ce_dm.chan_ce_out_cmd->exec_func = NULL;
2104
2105 return 0;
2106}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002107
2108static int _qce_start_dma(struct qce_device *pce_dev, bool ce_in, bool ce_out)
2109{
2110
2111 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002112 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002113 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002114 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002115
2116 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002117 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002118 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002119 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002120
2121 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002122 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
2123 pce_dev->ce_dm.chan_ce_in_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002124 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002125 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_out,
2126 pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002127
2128 return 0;
2129};
2130
2131int qce_aead_req(void *handle, struct qce_req *q_req)
2132{
2133 struct qce_device *pce_dev = (struct qce_device *) handle;
2134 struct aead_request *areq = (struct aead_request *) q_req->areq;
2135 uint32_t authsize = q_req->authsize;
2136 uint32_t totallen_in, totallen_out, out_len;
2137 uint32_t pad_len_in, pad_len_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002138 int rc = 0;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002139 int ce_block_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002140
Mona Hossain5f5dde12011-09-12 10:28:34 -07002141 ce_block_size = pce_dev->ce_dm.ce_block_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002142 if (q_req->dir == QCE_ENCRYPT) {
Mona Hossain43fd26a2012-05-16 14:36:54 -07002143 uint32_t pad_mac_len_out;
2144
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002145 q_req->cryptlen = areq->cryptlen;
2146 totallen_in = q_req->cryptlen + areq->assoclen;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002147 pad_len_in = ALIGN(totallen_in, ce_block_size) - totallen_in;
Mona Hossain43fd26a2012-05-16 14:36:54 -07002148
2149 out_len = areq->cryptlen + authsize;
2150 totallen_out = q_req->cryptlen + authsize + areq->assoclen;
2151 pad_mac_len_out = ALIGN(authsize, ce_block_size) - authsize;
2152 totallen_out += pad_mac_len_out;
2153 pad_len_out = ALIGN(totallen_out, ce_block_size) -
2154 totallen_out + pad_mac_len_out;
2155
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002156 } else {
2157 q_req->cryptlen = areq->cryptlen - authsize;
2158 totallen_in = areq->cryptlen + areq->assoclen;
Mona Hossain43fd26a2012-05-16 14:36:54 -07002159 pad_len_in = ALIGN(totallen_in, ce_block_size) - totallen_in;
2160
2161 out_len = q_req->cryptlen;
2162 totallen_out = totallen_in;
2163 pad_len_out = ALIGN(totallen_out, ce_block_size) - totallen_out;
2164 pad_len_out += authsize;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002165 }
2166
2167 _chain_buffer_in_init(pce_dev);
2168 _chain_buffer_out_init(pce_dev);
2169
2170 pce_dev->assoc_nents = 0;
2171 pce_dev->src_nents = 0;
2172 pce_dev->dst_nents = 0;
2173 pce_dev->ivsize = q_req->ivsize;
2174 pce_dev->authsize = q_req->authsize;
2175
2176 /* associated data input */
2177 pce_dev->assoc_nents = count_sg(areq->assoc, areq->assoclen);
Rohit Vaswanif061c3d2013-01-04 12:01:23 -08002178 qce_dma_map_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002179 DMA_TO_DEVICE);
2180 if (_chain_sg_buffer_in(pce_dev, areq->assoc, areq->assoclen) < 0) {
2181 rc = -ENOMEM;
2182 goto bad;
2183 }
2184 /* cipher input */
2185 pce_dev->src_nents = count_sg(areq->src, areq->cryptlen);
Rohit Vaswanif061c3d2013-01-04 12:01:23 -08002186 qce_dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002187 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2188 DMA_TO_DEVICE);
2189 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->cryptlen) < 0) {
2190 rc = -ENOMEM;
2191 goto bad;
2192 }
2193 /* pad data in */
2194 if (pad_len_in) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002195 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002196 pad_len_in) < 0) {
2197 rc = -ENOMEM;
2198 goto bad;
2199 }
2200 }
2201
2202 /* ignore associated data */
Mona Hossain3b574d82011-09-01 15:02:01 -07002203 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_out_ignore,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002204 areq->assoclen) < 0) {
2205 rc = -ENOMEM;
2206 goto bad;
2207 }
2208 /* cipher + mac output for encryption */
2209 if (areq->src != areq->dst) {
2210 pce_dev->dst_nents = count_sg(areq->dst, out_len);
Rohit Vaswanif061c3d2013-01-04 12:01:23 -08002211 qce_dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002212 DMA_FROM_DEVICE);
2213 };
2214 if (_chain_sg_buffer_out(pce_dev, areq->dst, out_len) < 0) {
2215 rc = -ENOMEM;
2216 goto bad;
2217 }
2218 /* pad data out */
2219 if (pad_len_out) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002220 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002221 pad_len_out) < 0) {
2222 rc = -ENOMEM;
2223 goto bad;
2224 }
2225 }
2226
2227 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain5f5dde12011-09-12 10:28:34 -07002228 _ce_in_final(pce_dev, ALIGN(totallen_in, ce_block_size));
2229 _ce_out_final(pce_dev, ALIGN(totallen_out, ce_block_size));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002230
2231 /* set up crypto device */
2232 rc = _ce_setup_cipher(pce_dev, q_req, totallen_in, areq->assoclen);
2233 if (rc < 0)
2234 goto bad;
2235
2236 /* setup for callback, and issue command to adm */
2237 pce_dev->areq = q_req->areq;
2238 pce_dev->qce_cb = q_req->qce_cb;
2239
Mona Hossain3b574d82011-09-01 15:02:01 -07002240 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _aead_ce_in_call_back;
2241 pce_dev->ce_dm.chan_ce_out_cmd->complete_func = _aead_ce_out_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002242
2243 _ce_in_dump(pce_dev);
2244 _ce_out_dump(pce_dev);
2245
2246 rc = _qce_start_dma(pce_dev, true, true);
2247 if (rc == 0)
2248 return 0;
2249bad:
2250 if (pce_dev->assoc_nents) {
Rohit Vaswanif061c3d2013-01-04 12:01:23 -08002251 qce_dma_unmap_sg(pce_dev->pdev, areq->assoc,
2252 pce_dev->assoc_nents, DMA_TO_DEVICE);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002253 }
2254
2255 if (pce_dev->src_nents) {
Rohit Vaswanif061c3d2013-01-04 12:01:23 -08002256 qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002257 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2258 DMA_TO_DEVICE);
2259 }
2260 if (pce_dev->dst_nents) {
Rohit Vaswanif061c3d2013-01-04 12:01:23 -08002261 qce_dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002262 DMA_FROM_DEVICE);
2263 }
2264 return rc;
2265}
2266EXPORT_SYMBOL(qce_aead_req);
2267
2268int qce_ablk_cipher_req(void *handle, struct qce_req *c_req)
2269{
2270 int rc = 0;
2271 struct qce_device *pce_dev = (struct qce_device *) handle;
2272 struct ablkcipher_request *areq = (struct ablkcipher_request *)
2273 c_req->areq;
2274
Mona Hossain5f5dde12011-09-12 10:28:34 -07002275 uint32_t pad_len = ALIGN(areq->nbytes, pce_dev->ce_dm.ce_block_size)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002276 - areq->nbytes;
2277
2278 _chain_buffer_in_init(pce_dev);
2279 _chain_buffer_out_init(pce_dev);
2280
2281 pce_dev->src_nents = 0;
2282 pce_dev->dst_nents = 0;
2283
2284 /* cipher input */
2285 pce_dev->src_nents = count_sg(areq->src, areq->nbytes);
2286
2287 if (c_req->use_pmem != 1)
Rohit Vaswanif061c3d2013-01-04 12:01:23 -08002288 qce_dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002289 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2290 DMA_TO_DEVICE);
2291 else
2292 dma_map_pmem_sg(&c_req->pmem->src[0], pce_dev->src_nents,
2293 areq->src);
2294
2295 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->nbytes) < 0) {
2296 rc = -ENOMEM;
2297 goto bad;
2298 }
2299
2300 /* cipher output */
2301 if (areq->src != areq->dst) {
2302 pce_dev->dst_nents = count_sg(areq->dst, areq->nbytes);
2303 if (c_req->use_pmem != 1)
Rohit Vaswanif061c3d2013-01-04 12:01:23 -08002304 qce_dma_map_sg(pce_dev->pdev, areq->dst,
2305 pce_dev->dst_nents, DMA_FROM_DEVICE);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002306 else
2307 dma_map_pmem_sg(&c_req->pmem->dst[0],
2308 pce_dev->dst_nents, areq->dst);
2309 };
2310 if (_chain_sg_buffer_out(pce_dev, areq->dst, areq->nbytes) < 0) {
2311 rc = -ENOMEM;
2312 goto bad;
2313 }
2314
2315 /* pad data */
2316 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002317 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002318 pad_len) < 0) {
2319 rc = -ENOMEM;
2320 goto bad;
2321 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002322 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002323 pad_len) < 0) {
2324 rc = -ENOMEM;
2325 goto bad;
2326 }
2327 }
2328
2329 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain2563cbc2011-09-14 15:24:08 -07002330 _ce_in_final(pce_dev, areq->nbytes + pad_len);
2331 _ce_out_final(pce_dev, areq->nbytes + pad_len);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002332
2333 _ce_in_dump(pce_dev);
2334 _ce_out_dump(pce_dev);
2335
2336 /* set up crypto device */
2337 rc = _ce_setup_cipher(pce_dev, c_req, areq->nbytes, 0);
2338 if (rc < 0)
2339 goto bad;
2340
2341 /* setup for callback, and issue command to adm */
2342 pce_dev->areq = areq;
2343 pce_dev->qce_cb = c_req->qce_cb;
2344 if (c_req->use_pmem == 1) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002345 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002346 _ablk_cipher_ce_in_call_back_pmem;
Mona Hossain3b574d82011-09-01 15:02:01 -07002347 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002348 _ablk_cipher_ce_out_call_back_pmem;
2349 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07002350 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002351 _ablk_cipher_ce_in_call_back;
Mona Hossain3b574d82011-09-01 15:02:01 -07002352 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002353 _ablk_cipher_ce_out_call_back;
2354 }
2355 rc = _qce_start_dma(pce_dev, true, true);
2356
2357 if (rc == 0)
2358 return 0;
2359bad:
2360 if (c_req->use_pmem != 1) {
2361 if (pce_dev->dst_nents) {
Rohit Vaswanif061c3d2013-01-04 12:01:23 -08002362 qce_dma_unmap_sg(pce_dev->pdev, areq->dst,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002363 pce_dev->dst_nents, DMA_FROM_DEVICE);
2364 }
2365 if (pce_dev->src_nents) {
Rohit Vaswanif061c3d2013-01-04 12:01:23 -08002366 qce_dma_unmap_sg(pce_dev->pdev, areq->src,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002367 pce_dev->src_nents,
2368 (areq->src == areq->dst) ?
2369 DMA_BIDIRECTIONAL :
2370 DMA_TO_DEVICE);
2371 }
2372 }
2373 return rc;
2374}
2375EXPORT_SYMBOL(qce_ablk_cipher_req);
2376
2377int qce_process_sha_req(void *handle, struct qce_sha_req *sreq)
2378{
2379 struct qce_device *pce_dev = (struct qce_device *) handle;
2380 int rc;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002381 uint32_t pad_len = ALIGN(sreq->size, pce_dev->ce_dm.ce_block_size) -
2382 sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002383 struct ahash_request *areq = (struct ahash_request *)sreq->areq;
2384
2385 _chain_buffer_in_init(pce_dev);
2386 pce_dev->src_nents = count_sg(sreq->src, sreq->size);
Rohit Vaswanif061c3d2013-01-04 12:01:23 -08002387 qce_dma_map_sg(pce_dev->pdev, sreq->src, pce_dev->src_nents,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002388 DMA_TO_DEVICE);
2389
2390 if (_chain_sg_buffer_in(pce_dev, sreq->src, sreq->size) < 0) {
2391 rc = -ENOMEM;
2392 goto bad;
2393 }
2394
2395 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002396 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002397 pad_len) < 0) {
2398 rc = -ENOMEM;
2399 goto bad;
2400 }
2401 }
Mona Hossain2563cbc2011-09-14 15:24:08 -07002402 _ce_in_final(pce_dev, sreq->size + pad_len);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002403
2404 _ce_in_dump(pce_dev);
2405
Mona Hossain3b574d82011-09-01 15:02:01 -07002406 rc = _ce_setup_hash(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002407
2408 if (rc < 0)
2409 goto bad;
2410
2411 pce_dev->areq = areq;
2412 pce_dev->qce_cb = sreq->qce_cb;
Mona Hossain3b574d82011-09-01 15:02:01 -07002413 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _sha_ce_in_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002414
2415 rc = _qce_start_dma(pce_dev, true, false);
2416
2417 if (rc == 0)
2418 return 0;
2419bad:
2420 if (pce_dev->src_nents) {
Rohit Vaswanif061c3d2013-01-04 12:01:23 -08002421 qce_dma_unmap_sg(pce_dev->pdev, sreq->src,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002422 pce_dev->src_nents, DMA_TO_DEVICE);
2423 }
2424
2425 return rc;
2426}
2427EXPORT_SYMBOL(qce_process_sha_req);
2428
2429/* crypto engine open function. */
2430void *qce_open(struct platform_device *pdev, int *rc)
2431{
2432 struct qce_device *pce_dev;
2433 struct resource *resource;
2434 struct clk *ce_core_clk;
2435 struct clk *ce_clk;
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002436 struct clk *ce_core_src_clk;
2437 int ret = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002438
2439 pce_dev = kzalloc(sizeof(struct qce_device), GFP_KERNEL);
2440 if (!pce_dev) {
2441 *rc = -ENOMEM;
2442 dev_err(&pdev->dev, "Can not allocate memory\n");
2443 return NULL;
2444 }
2445 pce_dev->pdev = &pdev->dev;
2446
2447 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2448 if (!resource) {
2449 *rc = -ENXIO;
2450 dev_err(pce_dev->pdev, "Missing MEM resource\n");
2451 goto err_pce_dev;
2452 };
2453 pce_dev->phy_iobase = resource->start;
2454 pce_dev->iobase = ioremap_nocache(resource->start,
2455 resource->end - resource->start + 1);
2456 if (!pce_dev->iobase) {
2457 *rc = -ENOMEM;
2458 dev_err(pce_dev->pdev, "Can not map io memory\n");
2459 goto err_pce_dev;
2460 }
2461
Mona Hossain3b574d82011-09-01 15:02:01 -07002462 pce_dev->ce_dm.chan_ce_in_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002463 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002464 pce_dev->ce_dm.chan_ce_out_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002465 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002466 if (pce_dev->ce_dm.chan_ce_in_cmd == NULL ||
2467 pce_dev->ce_dm.chan_ce_out_cmd == NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002468 dev_err(pce_dev->pdev, "Can not allocate memory\n");
2469 *rc = -ENOMEM;
2470 goto err_dm_chan_cmd;
2471 }
2472
2473 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2474 "crypto_channels");
2475 if (!resource) {
2476 *rc = -ENXIO;
2477 dev_err(pce_dev->pdev, "Missing DMA channel resource\n");
2478 goto err_dm_chan_cmd;
2479 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002480 pce_dev->ce_dm.chan_ce_in = resource->start;
2481 pce_dev->ce_dm.chan_ce_out = resource->end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002482 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2483 "crypto_crci_in");
2484 if (!resource) {
2485 *rc = -ENXIO;
2486 dev_err(pce_dev->pdev, "Missing DMA crci in resource\n");
2487 goto err_dm_chan_cmd;
2488 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002489 pce_dev->ce_dm.crci_in = resource->start;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002490 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2491 "crypto_crci_out");
2492 if (!resource) {
2493 *rc = -ENXIO;
2494 dev_err(pce_dev->pdev, "Missing DMA crci out resource\n");
2495 goto err_dm_chan_cmd;
2496 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002497 pce_dev->ce_dm.crci_out = resource->start;
2498 pce_dev->memsize = 2 * PAGE_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002499 pce_dev->coh_vmem = dma_alloc_coherent(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -07002500 pce_dev->memsize, &pce_dev->coh_pmem, GFP_KERNEL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002501
2502 if (pce_dev->coh_vmem == NULL) {
2503 *rc = -ENOMEM;
2504 dev_err(pce_dev->pdev, "Can not allocate coherent memory.\n");
2505 goto err;
2506 }
2507
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002508 /* Get CE3 src core clk. */
2509 ce_core_src_clk = clk_get(pce_dev->pdev, "ce3_core_src_clk");
2510 if (!IS_ERR(ce_core_src_clk)) {
2511 pce_dev->ce_core_src_clk = ce_core_src_clk;
2512
2513 /* Set the core src clk @100Mhz */
2514 ret = clk_set_rate(pce_dev->ce_core_src_clk, 100000000);
2515 if (ret) {
2516 clk_put(pce_dev->ce_core_src_clk);
2517 goto err;
2518 }
2519 } else
2520 pce_dev->ce_core_src_clk = NULL;
2521
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002522 /* Get CE core clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002523 ce_core_clk = clk_get(pce_dev->pdev, "core_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002524 if (IS_ERR(ce_core_clk)) {
2525 *rc = PTR_ERR(ce_core_clk);
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002526 if (pce_dev->ce_core_src_clk != NULL)
2527 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002528 goto err;
2529 }
2530 pce_dev->ce_core_clk = ce_core_clk;
2531 /* Get CE clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002532 ce_clk = clk_get(pce_dev->pdev, "iface_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002533 if (IS_ERR(ce_clk)) {
2534 *rc = PTR_ERR(ce_clk);
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002535 if (pce_dev->ce_core_src_clk != NULL)
2536 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002537 clk_put(pce_dev->ce_core_clk);
2538 goto err;
2539 }
2540 pce_dev->ce_clk = ce_clk;
2541
2542 /* Enable CE core clk */
Ramesh Masavarapu2d082fa2012-04-24 16:38:31 -07002543 *rc = clk_prepare_enable(pce_dev->ce_core_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002544 if (*rc) {
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002545 if (pce_dev->ce_core_src_clk != NULL)
2546 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002547 clk_put(pce_dev->ce_core_clk);
2548 clk_put(pce_dev->ce_clk);
2549 goto err;
2550 } else {
2551 /* Enable CE clk */
Ramesh Masavarapu2d082fa2012-04-24 16:38:31 -07002552 *rc = clk_prepare_enable(pce_dev->ce_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002553 if (*rc) {
Ramesh Masavarapu2d082fa2012-04-24 16:38:31 -07002554 clk_disable_unprepare(pce_dev->ce_core_clk);
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002555 if (pce_dev->ce_core_src_clk != NULL)
2556 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002557 clk_put(pce_dev->ce_core_clk);
2558 clk_put(pce_dev->ce_clk);
2559 goto err;
2560
2561 }
2562 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002563 qce_setup_ce_dm_data(pce_dev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002564
Mona Hossain3b574d82011-09-01 15:02:01 -07002565 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
2566 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002567 if (_init_ce_engine(pce_dev)) {
2568 *rc = -ENXIO;
2569 goto err;
2570 }
2571 *rc = 0;
2572 return pce_dev;
2573
2574err:
2575 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002576 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
Mona Hossaine1b13f82011-08-30 09:35:49 -07002577 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002578err_dm_chan_cmd:
Mona Hossain3b574d82011-09-01 15:02:01 -07002579 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2580 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002581 if (pce_dev->iobase)
2582 iounmap(pce_dev->iobase);
2583
2584err_pce_dev:
2585
2586 kfree(pce_dev);
2587
2588 return NULL;
2589}
2590EXPORT_SYMBOL(qce_open);
2591
2592/* crypto engine close function. */
2593int qce_close(void *handle)
2594{
2595 struct qce_device *pce_dev = (struct qce_device *) handle;
2596
2597 if (handle == NULL)
2598 return -ENODEV;
2599 if (pce_dev->iobase)
2600 iounmap(pce_dev->iobase);
2601
2602 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002603 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
2604 pce_dev->coh_vmem, pce_dev->coh_pmem);
Ramesh Masavarapu2d082fa2012-04-24 16:38:31 -07002605 clk_disable_unprepare(pce_dev->ce_clk);
2606 clk_disable_unprepare(pce_dev->ce_core_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002607
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002608 if (pce_dev->ce_core_src_clk != NULL)
2609 clk_put(pce_dev->ce_core_src_clk);
2610
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002611 clk_put(pce_dev->ce_clk);
2612 clk_put(pce_dev->ce_core_clk);
2613
Mona Hossain3b574d82011-09-01 15:02:01 -07002614 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2615 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002616 kfree(handle);
2617
2618 return 0;
2619}
2620EXPORT_SYMBOL(qce_close);
2621
2622int qce_hw_support(void *handle, struct ce_hw_support *ce_support)
2623{
2624 if (ce_support == NULL)
2625 return -EINVAL;
2626
2627 ce_support->sha1_hmac_20 = false;
2628 ce_support->sha1_hmac = false;
2629 ce_support->sha256_hmac = false;
2630 ce_support->sha_hmac = false;
2631 ce_support->cmac = true;
2632 ce_support->aes_key_192 = false;
2633 ce_support->aes_xts = true;
2634 ce_support->aes_ccm = true;
2635 ce_support->ota = false;
Mona Hossainb43e94b2012-05-07 08:52:06 -07002636 ce_support->aligned_only = false;
2637 ce_support->bam = false;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002638 return 0;
2639}
2640EXPORT_SYMBOL(qce_hw_support);
2641
2642MODULE_LICENSE("GPL v2");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002643MODULE_DESCRIPTION("Crypto Engine driver");