blob: 60a5aff1f568c1e7688f4dfd0bc64242b70d0acc [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Qualcomm Crypto Engine driver.
2 *
3 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
4 *
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 Masavarapu72077202011-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
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070045/*
46 * CE HW device structure.
47 * Each engine has an instance of the structure.
48 * Each engine can only handle one crypto operation at one time. It is up to
49 * the sw above to ensure single threading of operation on an engine.
50 */
51struct qce_device {
52 struct device *pdev; /* Handle to platform_device structure */
Mona Hossain3b574d82011-09-01 15:02:01 -070053
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070054 unsigned char *coh_vmem; /* Allocated coherent virtual memory */
55 dma_addr_t coh_pmem; /* Allocated coherent physical memory */
Mona Hossain3b574d82011-09-01 15:02:01 -070056 int memsize; /* Memory allocated */
57
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070058 void __iomem *iobase; /* Virtual io base of CE HW */
59 unsigned int phy_iobase; /* Physical io base of CE HW */
Mona Hossain3b574d82011-09-01 15:02:01 -070060
Ramesh Masavarapu28311912011-10-27 11:04:12 -070061 struct clk *ce_core_src_clk; /* Handle to CE src clk*/
62 struct clk *ce_core_clk; /* Handle to CE clk */
63 struct clk *ce_clk; /* Handle to CE clk */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070064
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070065 qce_comp_func_ptr_t qce_cb; /* qce callback function pointer */
66
67 int assoc_nents;
68 int ivsize;
69 int authsize;
70 int src_nents;
71 int dst_nents;
72
73 void *areq;
74 enum qce_cipher_mode_enum mode;
Mona Hossain3b574d82011-09-01 15:02:01 -070075 struct ce_dm_data ce_dm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070076};
77
78/* Standard initialization vector for SHA-1, source: FIPS 180-2 */
Mona Hossain3b574d82011-09-01 15:02:01 -070079static uint8_t _std_init_vector_sha1_uint8[] = {
80 0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89,
81 0x98, 0xBA, 0xDC, 0xFE, 0x10, 0x32, 0x54, 0x76,
82 0xC3, 0xD2, 0xE1, 0xF0
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070083};
Mona Hossain3b574d82011-09-01 15:02:01 -070084
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070085/* Standard initialization vector for SHA-256, source: FIPS 180-2 */
Mona Hossain3b574d82011-09-01 15:02:01 -070086static uint8_t _std_init_vector_sha256_uint8[] = {
87 0x6A, 0x09, 0xE6, 0x67, 0xBB, 0x67, 0xAE, 0x85,
88 0x3C, 0x6E, 0xF3, 0x72, 0xA5, 0x4F, 0xF5, 0x3A,
89 0x51, 0x0E, 0x52, 0x7F, 0x9B, 0x05, 0x68, 0x8C,
90 0x1F, 0x83, 0xD9, 0xAB, 0x5B, 0xE0, 0xCD, 0x19
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070091};
92
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070093static void _byte_stream_swap_to_net_words(uint32_t *iv, unsigned char *b,
94 unsigned int len)
95{
96 unsigned i, j;
97 unsigned char swap_iv[AES_IV_LENGTH];
98
99 memset(swap_iv, 0, AES_IV_LENGTH);
100 for (i = (AES_IV_LENGTH-len), j = len-1; i < AES_IV_LENGTH; i++, j--)
101 swap_iv[i] = b[j];
Mona Hossain3b574d82011-09-01 15:02:01 -0700102 memcpy(iv, swap_iv, AES_IV_LENGTH);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700103}
104
105static int count_sg(struct scatterlist *sg, int nbytes)
106{
107 int i;
108
109 for (i = 0; nbytes > 0; i++, sg = sg_next(sg))
110 nbytes -= sg->length;
111 return i;
112}
113
114static int dma_map_pmem_sg(struct buf_info *pmem, unsigned entries,
115 struct scatterlist *sg)
116{
117 int i;
118 for (i = 0; i < entries; i++) {
119
120 sg->dma_address = (dma_addr_t)pmem->offset;
121 sg++;
122 pmem++;
123 }
124 return 0;
125}
126
127static int _probe_ce_engine(struct qce_device *pce_dev)
128{
129 unsigned int val;
130 unsigned int rev;
131
Mona Hossain3b574d82011-09-01 15:02:01 -0700132 val = (uint32_t)(*((uint32_t *)pce_dev->ce_dm.buffer.version));
Mona Hossain5f5dde12011-09-12 10:28:34 -0700133 if (((val & 0xfffffff) != 0x0000043) &&
134 ((val & 0xfffffff) != 0x0000042) &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700135 ((val & 0xfffffff) != 0x0000040)) {
136 dev_err(pce_dev->pdev,
137 "Unknown Qualcomm crypto device at 0x%x 0x%x\n",
138 pce_dev->phy_iobase, val);
139 return -EIO;
140 };
141 rev = (val & CRYPTO_CORE_REV_MASK);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700142 if (rev >= 0x42) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700143 dev_info(pce_dev->pdev,
144 "Qualcomm Crypto 4.2 device found at 0x%x\n",
145 pce_dev->phy_iobase);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700146 pce_dev->ce_dm.ce_block_size = 64;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700147 } else {
148 if (rev == 0x40) {
149 dev_info(pce_dev->pdev,
150 "Qualcomm Crypto 4.0 device found at 0x%x\n",
151 pce_dev->phy_iobase);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700152 pce_dev->ce_dm.ce_block_size = 16;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700153 }
154 }
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700155 /*
156 * This is a temporary change - until Data Mover changes its
157 * configuration from 16 byte crci to 64 byte crci.
158 */
159 if (cpu_is_msm9615())
160 pce_dev->ce_dm.ce_block_size = 16;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700161
162 dev_info(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -0700163 "IO base 0x%x\n, ce_in channel %d , "
164 "ce_out channel %d\n, "
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700165 "crci_in %d, crci_out %d\n",
166 (unsigned int) pce_dev->iobase,
Mona Hossain3b574d82011-09-01 15:02:01 -0700167 pce_dev->ce_dm.chan_ce_in, pce_dev->ce_dm.chan_ce_out,
168 pce_dev->ce_dm.crci_in, pce_dev->ce_dm.crci_out);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700169
170 return 0;
171};
172
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700173static void config_ce_engine(struct qce_device *pce_dev)
174{
175 unsigned int val = 0;
Ramesh Masavarapu72077202011-11-02 10:34:26 -0700176 unsigned int ret = 0;
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700177
Ramesh Masavarapu72077202011-11-02 10:34:26 -0700178 /* Crypto config register returns a 0 when it is XPU protected. */
179 ret = readl_relaxed(pce_dev->iobase + CRYPTO_CONFIG_REG);
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700180
Ramesh Masavarapu72077202011-11-02 10:34:26 -0700181 /* Configure the crypto register if it is not XPU protected. */
182 if (ret) {
183 val = BIT(CRYPTO_MASK_DOUT_INTR) |
184 BIT(CRYPTO_MASK_DIN_INTR) |
185 BIT(CRYPTO_MASK_OP_DONE_INTR) |
186 BIT(CRYPTO_MASK_ERR_INTR);
187
188 writel_relaxed(val, pce_dev->iobase + CRYPTO_CONFIG_REG);
189 }
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700190}
Mona Hossain3b574d82011-09-01 15:02:01 -0700191
192static void _check_probe_done_call_back(struct msm_dmov_cmd *cmd_ptr,
193 unsigned int result, struct msm_dmov_errdata *err)
194{
195 struct qce_device *pce_dev;
196 pce_dev = (struct qce_device *) cmd_ptr->user;
197
198 if (result != ADM_STATUS_OK) {
199 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
200 result);
201 pce_dev->ce_dm.chan_ce_in_status = -1;
202 } else {
203 _probe_ce_engine(pce_dev);
204 pce_dev->ce_dm.chan_ce_in_status = 0;
205 }
206 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
207};
208
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700209static int _init_ce_engine(struct qce_device *pce_dev)
210{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700211 /* Reset ce */
212 clk_reset(pce_dev->ce_core_clk, CLK_RESET_ASSERT);
213 clk_reset(pce_dev->ce_core_clk, CLK_RESET_DEASSERT);
Mona Hossain3b574d82011-09-01 15:02:01 -0700214
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700215 /*
216 * Ensure previous instruction (any writes to CLK registers)
217 * to toggle the CLK reset lines was completed before configuring
218 * ce engine. The ce engine configuration settings should not be lost
219 * becasue of clk reset.
220 */
221 mb();
222
223 /* Configure the CE Engine */
224 config_ce_engine(pce_dev);
225
226 /*
227 * Ensure ce configuration is completed.
228 */
229 mb();
230
Mona Hossain3b574d82011-09-01 15:02:01 -0700231 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
232 _check_probe_done_call_back;
233 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
234 pce_dev->ce_dm.cmdptrlist.probe_ce_hw;
235 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
236 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
237 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
238 pce_dev->ce_dm.chan_ce_in_cmd);
239
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700240 return 0;
241};
242
Mona Hossain3b574d82011-09-01 15:02:01 -0700243static int _ce_setup_hash_cmdrptrlist(struct qce_device *pce_dev,
244 struct qce_sha_req *sreq)
245{
246 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
247
248 switch (sreq->alg) {
249 case QCE_HASH_SHA1:
250 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr = cmdptrlist->auth_sha1;
251 break;
252
253 case QCE_HASH_SHA256:
254 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr = cmdptrlist->auth_sha256;
255 break;
256 case QCE_HASH_SHA1_HMAC:
257 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
258 cmdptrlist->auth_sha1_hmac;
259 break;
260
261 case QCE_HASH_SHA256_HMAC:
262 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
263 cmdptrlist->auth_sha256_hmac;
264 break;
265 case QCE_HASH_AES_CMAC:
266 if (sreq->authklen == AES128_KEY_SIZE)
267 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
268 cmdptrlist->auth_aes_128_cmac;
269 else
270 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
271 cmdptrlist->auth_aes_256_cmac;
272 break;
273
274 default:
275 break;
276 }
277
278 return 0;
279}
280
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700281static int _ce_setup_hash(struct qce_device *pce_dev, struct qce_sha_req *sreq)
282{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700283 uint32_t diglen;
284 int i;
285 uint32_t auth_cfg = 0;
286 bool sha1 = false;
287
288 if (sreq->alg == QCE_HASH_AES_CMAC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700289
Mona Hossain3b574d82011-09-01 15:02:01 -0700290 memcpy(pce_dev->ce_dm.buffer.auth_key, sreq->authkey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700291 sreq->authklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700292 auth_cfg |= (1 << CRYPTO_LAST);
293 auth_cfg |= (CRYPTO_AUTH_MODE_CMAC << CRYPTO_AUTH_MODE);
294 auth_cfg |= (CRYPTO_AUTH_SIZE_ENUM_16_BYTES <<
295 CRYPTO_AUTH_SIZE);
296 auth_cfg |= CRYPTO_AUTH_ALG_AES << CRYPTO_AUTH_ALG;
297
298 switch (sreq->authklen) {
299 case AES128_KEY_SIZE:
300 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES128 <<
301 CRYPTO_AUTH_KEY_SIZE);
302 break;
303 case AES256_KEY_SIZE:
304 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES256 <<
305 CRYPTO_AUTH_KEY_SIZE);
306 break;
307 default:
308 break;
309 }
310
311 goto go_proc;
312 }
313
314 /* if not the last, the size has to be on the block boundary */
315 if (sreq->last_blk == 0 && (sreq->size % SHA256_BLOCK_SIZE))
316 return -EIO;
317
318 switch (sreq->alg) {
319 case QCE_HASH_SHA1:
320 case QCE_HASH_SHA1_HMAC:
321 diglen = SHA1_DIGEST_SIZE;
322 sha1 = true;
323 break;
324 case QCE_HASH_SHA256:
325 case QCE_HASH_SHA256_HMAC:
326 diglen = SHA256_DIGEST_SIZE;
327 break;
328 default:
329 return -EINVAL;
330 }
331
332 if ((sreq->alg == QCE_HASH_SHA1_HMAC) ||
333 (sreq->alg == QCE_HASH_SHA256_HMAC)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700334
Mona Hossain3b574d82011-09-01 15:02:01 -0700335 memcpy(pce_dev->ce_dm.buffer.auth_key, sreq->authkey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700336 sreq->authklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700337 auth_cfg |= (CRYPTO_AUTH_MODE_HMAC << CRYPTO_AUTH_MODE);
338 } else {
339 auth_cfg |= (CRYPTO_AUTH_MODE_HASH << CRYPTO_AUTH_MODE);
340 }
341
342 /* write 20/32 bytes, 5/8 words into auth_iv for SHA1/SHA256 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700343 if (sreq->first_blk) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700344 if (sha1)
345 memcpy(pce_dev->ce_dm.buffer.auth_iv,
346 _std_init_vector_sha1_uint8, diglen);
347 else
348 memcpy(pce_dev->ce_dm.buffer.auth_iv,
349 _std_init_vector_sha256_uint8, diglen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700350 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700351 memcpy(pce_dev->ce_dm.buffer.auth_iv, sreq->digest,
352 diglen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700353 }
354
Mona Hossain3b574d82011-09-01 15:02:01 -0700355 /* write auth_bytecnt 0/1/2/3, start with 0 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700356 for (i = 0; i < 4; i++)
Mona Hossain3b574d82011-09-01 15:02:01 -0700357 *(((uint32_t *)(pce_dev->ce_dm.buffer.auth_byte_count) + i)) =
358 sreq->auth_data[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700359
360 /* write seg_cfg */
361 if (sha1)
362 auth_cfg |= (CRYPTO_AUTH_SIZE_SHA1 << CRYPTO_AUTH_SIZE);
363 else
364 auth_cfg |= (CRYPTO_AUTH_SIZE_SHA256 << CRYPTO_AUTH_SIZE);
365
366 if (sreq->last_blk)
367 auth_cfg |= 1 << CRYPTO_LAST;
368
369 auth_cfg |= CRYPTO_AUTH_ALG_SHA << CRYPTO_AUTH_ALG;
370
371go_proc:
372 auth_cfg |= (CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);
373
Mona Hossain3b574d82011-09-01 15:02:01 -0700374 /* write auth seg cfg */
375 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start)) =
376 auth_cfg;
377 /* write auth seg size */
378 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start) + 1) =
379 sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700380
Mona Hossain3b574d82011-09-01 15:02:01 -0700381 /* write auth seg size start*/
382 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start)+2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700383
Mona Hossain3b574d82011-09-01 15:02:01 -0700384 /* write seg size */
385 *((uint32_t *)(pce_dev->ce_dm.buffer.seg_size)) = sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700386
Mona Hossain3b574d82011-09-01 15:02:01 -0700387 _ce_setup_hash_cmdrptrlist(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700388
Mona Hossain3b574d82011-09-01 15:02:01 -0700389 return 0;
390}
391
392static int _ce_setup_cipher_cmdrptrlist(struct qce_device *pce_dev,
393 struct qce_req *creq)
394{
395 struct ce_cmdptrlists_ops *cmdptrlist =
396 &pce_dev->ce_dm.cmdptrlist;
397
398 if (creq->alg != CIPHER_ALG_AES) {
399 switch (creq->alg) {
400 case CIPHER_ALG_DES:
401 if (creq->mode == QCE_MODE_ECB) {
402 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
403 cmdptrlist->cipher_des_ecb;
404 } else {
405 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
406 cmdptrlist->cipher_des_cbc;
407 }
408 break;
409
410 case CIPHER_ALG_3DES:
411 if (creq->mode == QCE_MODE_ECB) {
412 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
413 cmdptrlist->cipher_3des_ecb;
414 } else {
415 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
416 cmdptrlist->cipher_3des_cbc;
417 }
418 break;
419 default:
420 break;
421 }
422 } else {
423 switch (creq->mode) {
424 case QCE_MODE_ECB:
425 if (creq->encklen == AES128_KEY_SIZE) {
426 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
427 cmdptrlist->cipher_aes_128_ecb;
428 } else {
429 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
430 cmdptrlist->cipher_aes_256_ecb;
431 }
432 break;
433
434 case QCE_MODE_CBC:
435 if (creq->encklen == AES128_KEY_SIZE) {
436 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
437 cmdptrlist->cipher_aes_128_cbc_ctr;
438 } else {
439 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
440 cmdptrlist->cipher_aes_256_cbc_ctr;
441 }
442 break;
443
444 case QCE_MODE_CTR:
445 if (creq->encklen == AES128_KEY_SIZE) {
446 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
447 cmdptrlist->cipher_aes_128_cbc_ctr;
448 } else {
449 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
450 cmdptrlist->cipher_aes_256_cbc_ctr;
451 }
452 break;
453
454 case QCE_MODE_XTS:
455 if (creq->encklen == AES128_KEY_SIZE) {
456 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
457 cmdptrlist->cipher_aes_128_xts;
458 } else {
459 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
460 cmdptrlist->cipher_aes_256_xts;
461 }
462 break;
463 case QCE_MODE_CCM:
464 if (creq->encklen == AES128_KEY_SIZE) {
465 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
466 cmdptrlist->aead_aes_128_ccm;
467 } else {
468 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
469 cmdptrlist->aead_aes_256_ccm;
470 }
471 break;
472 default:
473 break;
474 }
475 }
476
477 if (creq->mode == QCE_MODE_CCM)
478 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
479 cmdptrlist->aead_ce_out;
480 else
481 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
482 cmdptrlist->cipher_ce_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700483
484 return 0;
485}
486
487static int _ce_setup_cipher(struct qce_device *pce_dev, struct qce_req *creq,
488 uint32_t totallen_in, uint32_t coffset)
489{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700490 uint32_t enck_size_in_word = creq->encklen / sizeof(uint32_t);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700491 uint32_t encr_cfg = 0;
492 uint32_t ivsize = creq->ivsize;
Mona Hossain3b574d82011-09-01 15:02:01 -0700493 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700494
495 if (creq->mode == QCE_MODE_XTS)
Mona Hossain3b574d82011-09-01 15:02:01 -0700496 memcpy(buffer->encr_key, creq->enckey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700497 creq->encklen/2);
498 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700499 memcpy(buffer->encr_key, creq->enckey, creq->encklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700500
501 if ((creq->op == QCE_REQ_AEAD) && (creq->mode == QCE_MODE_CCM)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700502 uint32_t noncelen32 = MAX_NONCE/sizeof(uint32_t);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700503 uint32_t auth_cfg = 0;
504
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700505 /* write nonce */
Mona Hossain3b574d82011-09-01 15:02:01 -0700506 memcpy(buffer->auth_nonce_info, creq->nonce, MAX_NONCE);
507 memcpy(buffer->auth_key, creq->enckey, creq->encklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700508
509 auth_cfg |= (noncelen32 << CRYPTO_AUTH_NONCE_NUM_WORDS);
510 auth_cfg &= ~(1 << CRYPTO_USE_HW_KEY_AUTH);
511 auth_cfg |= (1 << CRYPTO_LAST);
512 if (creq->dir == QCE_ENCRYPT)
513 auth_cfg |= (CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);
514 else
515 auth_cfg |= (CRYPTO_AUTH_POS_AFTER << CRYPTO_AUTH_POS);
516 auth_cfg |= (((creq->authsize >> 1) - 2) << CRYPTO_AUTH_SIZE);
517 auth_cfg |= (CRYPTO_AUTH_MODE_CCM << CRYPTO_AUTH_MODE);
518 if (creq->authklen == AES128_KEY_SIZE)
519 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES128 <<
520 CRYPTO_AUTH_KEY_SIZE);
521 else {
522 if (creq->authklen == AES256_KEY_SIZE)
523 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES256 <<
524 CRYPTO_AUTH_KEY_SIZE);
525 }
526 auth_cfg |= (CRYPTO_AUTH_ALG_AES << CRYPTO_AUTH_ALG);
Mona Hossain3b574d82011-09-01 15:02:01 -0700527 *((uint32_t *)(buffer->auth_seg_cfg_size_start)) = auth_cfg;
528
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700529 if (creq->dir == QCE_ENCRYPT)
Mona Hossain3b574d82011-09-01 15:02:01 -0700530 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 1) =
531 totallen_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700532 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700533 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 1) =
534 (totallen_in - creq->authsize);
535 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700536 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700537
538 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700539
540 switch (creq->mode) {
541 case QCE_MODE_ECB:
542 encr_cfg |= (CRYPTO_ENCR_MODE_ECB << CRYPTO_ENCR_MODE);
543 break;
544
545 case QCE_MODE_CBC:
546 encr_cfg |= (CRYPTO_ENCR_MODE_CBC << CRYPTO_ENCR_MODE);
547 break;
548
549 case QCE_MODE_XTS:
550 encr_cfg |= (CRYPTO_ENCR_MODE_XTS << CRYPTO_ENCR_MODE);
551 break;
552
553 case QCE_MODE_CCM:
554 encr_cfg |= (CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE);
555 break;
556
557 case QCE_MODE_CTR:
558 default:
559 encr_cfg |= (CRYPTO_ENCR_MODE_CTR << CRYPTO_ENCR_MODE);
560 break;
561 }
562 pce_dev->mode = creq->mode;
563
564 switch (creq->alg) {
565 case CIPHER_ALG_DES:
Mona Hossain3b574d82011-09-01 15:02:01 -0700566 if (creq->mode != QCE_MODE_ECB)
567 memcpy(buffer->encr_cntr_iv, creq->iv, ivsize);
568
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700569 encr_cfg |= ((CRYPTO_ENCR_KEY_SZ_DES << CRYPTO_ENCR_KEY_SZ) |
570 (CRYPTO_ENCR_ALG_DES << CRYPTO_ENCR_ALG));
571 break;
572
573 case CIPHER_ALG_3DES:
Mona Hossain3b574d82011-09-01 15:02:01 -0700574 if (creq->mode != QCE_MODE_ECB)
575 memcpy(buffer->encr_cntr_iv, creq->iv, ivsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700576
577 encr_cfg |= ((CRYPTO_ENCR_KEY_SZ_3DES << CRYPTO_ENCR_KEY_SZ) |
578 (CRYPTO_ENCR_ALG_DES << CRYPTO_ENCR_ALG));
579 break;
580
581 case CIPHER_ALG_AES:
582 default:
583 if (creq->mode == QCE_MODE_XTS) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700584 memcpy(buffer->encr_xts_key, (creq->enckey +
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700585 creq->encklen/2), creq->encklen/2);
Mona Hossain3b574d82011-09-01 15:02:01 -0700586 *((uint32_t *)(buffer->encr_xts_du_size)) =
587 creq->cryptlen;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700588
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700589 }
590 if (creq->mode != QCE_MODE_ECB) {
591 if (creq->mode == QCE_MODE_XTS)
Mona Hossain3b574d82011-09-01 15:02:01 -0700592 _byte_stream_swap_to_net_words(
593 (uint32_t *)(buffer->encr_cntr_iv),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700594 creq->iv, ivsize);
595 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700596 memcpy(buffer->encr_cntr_iv, creq->iv,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700597 ivsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700598 }
599 /* set number of counter bits */
Mona Hossain3b574d82011-09-01 15:02:01 -0700600 *((uint32_t *)(buffer->encr_mask)) = (uint32_t)0xffffffff;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700601
602 if (creq->op == QCE_REQ_ABLK_CIPHER_NO_KEY) {
603 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES128 <<
604 CRYPTO_ENCR_KEY_SZ);
605 encr_cfg |= CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG;
606 } else {
607 uint32_t key_size;
608
609 if (creq->mode == QCE_MODE_XTS) {
610 key_size = creq->encklen/2;
611 enck_size_in_word = key_size/sizeof(uint32_t);
612 } else {
613 key_size = creq->encklen;
614 }
615
616 switch (key_size) {
617 case AES128_KEY_SIZE:
618 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES128 <<
619 CRYPTO_ENCR_KEY_SZ);
620 break;
621 case AES256_KEY_SIZE:
622 default:
623 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES256 <<
624 CRYPTO_ENCR_KEY_SZ);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700625 break;
626 } /* end of switch (creq->encklen) */
627
628 encr_cfg |= CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700629 } /* else of if (creq->op == QCE_REQ_ABLK_CIPHER_NO_KEY) */
630 break;
631 } /* end of switch (creq->mode) */
632
633 /* write encr seg cfg */
634 encr_cfg |= ((creq->dir == QCE_ENCRYPT) ? 1 : 0) << CRYPTO_ENCODE;
635
636 /* write encr seg cfg */
Mona Hossain3b574d82011-09-01 15:02:01 -0700637 *((uint32_t *)(buffer->encr_seg_cfg_size_start)) = encr_cfg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700638 /* write encr seg size */
639 if ((creq->mode == QCE_MODE_CCM) && (creq->dir == QCE_DECRYPT))
Mona Hossain3b574d82011-09-01 15:02:01 -0700640 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 1) =
641 (creq->cryptlen + creq->authsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700642 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700643 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 1) =
644 creq->cryptlen;
645
646
647 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 2) =
648 (coffset & 0xffff);
649
650 *((uint32_t *)(buffer->seg_size)) = totallen_in;
651
652 _ce_setup_cipher_cmdrptrlist(pce_dev, creq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700653 return 0;
654};
655
656static int _aead_complete(struct qce_device *pce_dev)
657{
658 struct aead_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700659
660 areq = (struct aead_request *) pce_dev->areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700661
662 if (areq->src != areq->dst) {
663 dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
664 DMA_FROM_DEVICE);
665 }
666 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
667 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
668 DMA_TO_DEVICE);
669
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700670 dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
671 DMA_TO_DEVICE);
672
Mona Hossain3b574d82011-09-01 15:02:01 -0700673 /* check MAC */
674 if (pce_dev->mode == QCE_MODE_CCM) {
675 uint32_t result;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700676
Mona Hossain3b574d82011-09-01 15:02:01 -0700677 result =
678 (uint32_t)(*((uint32_t *)pce_dev->ce_dm.buffer.status));
679 result &= (1 << CRYPTO_MAC_FAILED);
680 result |= (pce_dev->ce_dm.chan_ce_in_status |
681 pce_dev->ce_dm.chan_ce_out_status);
682 pce_dev->qce_cb(areq, pce_dev->ce_dm.buffer.auth_result, NULL,
683 result);
684 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700685 return 0;
686};
687
688static void _sha_complete(struct qce_device *pce_dev)
689{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700690 struct ahash_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700691
692 areq = (struct ahash_request *) pce_dev->areq;
693 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
694 DMA_TO_DEVICE);
695
Mona Hossain3b574d82011-09-01 15:02:01 -0700696 pce_dev->qce_cb(areq, pce_dev->ce_dm.buffer.auth_result,
697 pce_dev->ce_dm.buffer.auth_byte_count,
698 pce_dev->ce_dm.chan_ce_in_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700699
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700700};
701
702static int _ablk_cipher_complete(struct qce_device *pce_dev)
703{
704 struct ablkcipher_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700705
706 areq = (struct ablkcipher_request *) pce_dev->areq;
707
708 if (areq->src != areq->dst) {
709 dma_unmap_sg(pce_dev->pdev, areq->dst,
710 pce_dev->dst_nents, DMA_FROM_DEVICE);
711 }
712 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
713 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
714 DMA_TO_DEVICE);
Mona Hossain3b574d82011-09-01 15:02:01 -0700715
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700716 if (pce_dev->mode == QCE_MODE_ECB) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700717 pce_dev->qce_cb(areq, NULL, NULL,
718 pce_dev->ce_dm.chan_ce_in_status |
719 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700720 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700721
Mona Hossain3b574d82011-09-01 15:02:01 -0700722 pce_dev->qce_cb(areq, NULL, pce_dev->ce_dm.buffer.encr_cntr_iv,
723 pce_dev->ce_dm.chan_ce_in_status |
724 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700725 }
726
727 return 0;
728};
729
730static int _ablk_cipher_use_pmem_complete(struct qce_device *pce_dev)
731{
732 struct ablkcipher_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700733
734 areq = (struct ablkcipher_request *) pce_dev->areq;
735
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700736 if (pce_dev->mode == QCE_MODE_ECB) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700737 pce_dev->qce_cb(areq, NULL, NULL,
738 pce_dev->ce_dm.chan_ce_in_status |
739 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700740 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700741 pce_dev->qce_cb(areq, NULL, pce_dev->ce_dm.buffer.encr_cntr_iv,
742 pce_dev->ce_dm.chan_ce_in_status |
743 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700744 }
745
746 return 0;
747};
748
749static int qce_split_and_insert_dm_desc(struct dmov_desc *pdesc,
750 unsigned int plen, unsigned int paddr, int *index)
751{
Mona Hossain3b574d82011-09-01 15:02:01 -0700752 while (plen > QCE_FIFO_SIZE) {
753 pdesc->len = QCE_FIFO_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700754 if (paddr > 0) {
755 pdesc->addr = paddr;
Mona Hossain3b574d82011-09-01 15:02:01 -0700756 paddr += QCE_FIFO_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700757 }
758 plen -= pdesc->len;
759 if (plen > 0) {
760 *index = (*index) + 1;
761 if ((*index) >= QCE_MAX_NUM_DESC)
762 return -ENOMEM;
763 pdesc++;
764 }
765 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700766 if ((plen > 0) && (plen <= QCE_FIFO_SIZE)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700767 pdesc->len = plen;
768 if (paddr > 0)
769 pdesc->addr = paddr;
770 }
771
772 return 0;
773}
774
775static int _chain_sg_buffer_in(struct qce_device *pce_dev,
776 struct scatterlist *sg, unsigned int nbytes)
777{
778 unsigned int len;
779 unsigned int dlen;
780 struct dmov_desc *pdesc;
781
Mona Hossain3b574d82011-09-01 15:02:01 -0700782 pdesc = pce_dev->ce_dm.ce_in_src_desc +
783 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700784 /*
785 * Two consective chunks may be handled by the old
786 * buffer descriptor.
787 */
788 while (nbytes > 0) {
789 len = min(nbytes, sg_dma_len(sg));
790 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
791 nbytes -= len;
792 if (dlen == 0) {
793 pdesc->addr = sg_dma_address(sg);
794 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700795 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700796 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700797 sg_dma_address(sg),
798 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700799 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
800 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700801 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700802 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700803 pdesc->addr,
804 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700805 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700806 pce_dev->ce_dm.ce_in_src_desc_index++;
807 if (pce_dev->ce_dm.ce_in_src_desc_index >=
808 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700809 return -ENOMEM;
810 pdesc++;
811 pdesc->len = len;
812 pdesc->addr = sg_dma_address(sg);
Mona Hossain3b574d82011-09-01 15:02:01 -0700813 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700814 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700815 sg_dma_address(sg),
816 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700817 }
818 if (nbytes > 0)
819 sg = sg_next(sg);
820 }
821 return 0;
822}
823
824static int _chain_pm_buffer_in(struct qce_device *pce_dev,
825 unsigned int pmem, unsigned int nbytes)
826{
827 unsigned int dlen;
828 struct dmov_desc *pdesc;
829
Mona Hossain3b574d82011-09-01 15:02:01 -0700830 pdesc = pce_dev->ce_dm.ce_in_src_desc +
831 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700832 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
833 if (dlen == 0) {
834 pdesc->addr = pmem;
835 pdesc->len = nbytes;
836 } else if (pmem == (pdesc->addr + dlen)) {
837 pdesc->len = dlen + nbytes;
838 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700839 pce_dev->ce_dm.ce_in_src_desc_index++;
840 if (pce_dev->ce_dm.ce_in_src_desc_index >=
841 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700842 return -ENOMEM;
843 pdesc++;
844 pdesc->len = nbytes;
845 pdesc->addr = pmem;
846 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700847 return 0;
848}
849
850static void _chain_buffer_in_init(struct qce_device *pce_dev)
851{
852 struct dmov_desc *pdesc;
853
Mona Hossain3b574d82011-09-01 15:02:01 -0700854 pce_dev->ce_dm.ce_in_src_desc_index = 0;
855 pce_dev->ce_dm.ce_in_dst_desc_index = 0;
856 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700857 pdesc->len = 0;
858}
859
860static void _ce_in_final(struct qce_device *pce_dev, unsigned total)
861{
862 struct dmov_desc *pdesc;
863 dmov_sg *pcmd;
864
Mona Hossain3b574d82011-09-01 15:02:01 -0700865 pdesc = pce_dev->ce_dm.ce_in_src_desc +
866 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700867 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700868
869 pdesc = pce_dev->ce_dm.ce_in_dst_desc;
870 if (total > QCE_FIFO_SIZE) {
871 qce_split_and_insert_dm_desc(pdesc, total, 0,
872 &pce_dev->ce_dm.ce_in_dst_desc_index);
873 pdesc = pce_dev->ce_dm.ce_in_dst_desc +
874 pce_dev->ce_dm.ce_in_dst_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -0700875 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700876 } else
877 pdesc->len = ADM_DESC_LAST | total;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700878
Mona Hossain3b574d82011-09-01 15:02:01 -0700879 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700880 pcmd->cmd |= CMD_LC;
Mona Hossain3b574d82011-09-01 15:02:01 -0700881
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700882}
883
884#ifdef QCE_DEBUG
885static void _ce_in_dump(struct qce_device *pce_dev)
886{
887 int i;
888 struct dmov_desc *pdesc;
889
890 dev_info(pce_dev->pdev, "_ce_in_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700891 for (i = 0; i <= pce_dev->ce_dm.ce_in_src_desc_index; i++) {
892 pdesc = pce_dev->ce_dm.ce_in_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700893 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
894 pdesc->len);
895 }
896 dev_info(pce_dev->pdev, "_ce_in_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700897 for (i = 0; i <= pce_dev->ce_dm.ce_in_dst_desc_index; i++) {
898 pdesc = pce_dev->ce_dm.ce_in_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700899 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
900 pdesc->len);
901 }
902};
903
904static void _ce_out_dump(struct qce_device *pce_dev)
905{
906 int i;
907 struct dmov_desc *pdesc;
908
909 dev_info(pce_dev->pdev, "_ce_out_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700910 for (i = 0; i <= pce_dev->ce_dm.ce_out_src_desc_index; i++) {
911 pdesc = pce_dev->ce_dm.ce_out_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700912 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
913 pdesc->len);
914 }
915
916 dev_info(pce_dev->pdev, "_ce_out_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700917 for (i = 0; i <= pce_dev->ce_dm.ce_out_dst_desc_index; i++) {
918 pdesc = pce_dev->ce_dm.ce_out_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700919 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
920 pdesc->len);
921 }
922};
923
924#else
925
926static void _ce_in_dump(struct qce_device *pce_dev)
927{
928};
929
930static void _ce_out_dump(struct qce_device *pce_dev)
931{
932};
933
934#endif
935
936static int _chain_sg_buffer_out(struct qce_device *pce_dev,
937 struct scatterlist *sg, unsigned int nbytes)
938{
939 unsigned int len;
940 unsigned int dlen;
941 struct dmov_desc *pdesc;
942
Mona Hossain3b574d82011-09-01 15:02:01 -0700943 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
944 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700945 /*
946 * Two consective chunks may be handled by the old
947 * buffer descriptor.
948 */
949 while (nbytes > 0) {
950 len = min(nbytes, sg_dma_len(sg));
951 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
952 nbytes -= len;
953 if (dlen == 0) {
954 pdesc->addr = sg_dma_address(sg);
955 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700956 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700957 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
958 sg_dma_address(sg),
Mona Hossain3b574d82011-09-01 15:02:01 -0700959 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700960 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
961 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700962 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700963 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
964 pdesc->addr,
Mona Hossain3b574d82011-09-01 15:02:01 -0700965 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700966
967 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700968 pce_dev->ce_dm.ce_out_dst_desc_index++;
969 if (pce_dev->ce_dm.ce_out_dst_desc_index >=
970 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700971 return -EIO;
972 pdesc++;
973 pdesc->len = len;
974 pdesc->addr = sg_dma_address(sg);
Mona Hossain3b574d82011-09-01 15:02:01 -0700975 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700976 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
977 sg_dma_address(sg),
Mona Hossain3b574d82011-09-01 15:02:01 -0700978 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700979
980 }
981 if (nbytes > 0)
982 sg = sg_next(sg);
983 }
984 return 0;
985}
986
987static int _chain_pm_buffer_out(struct qce_device *pce_dev,
988 unsigned int pmem, unsigned int nbytes)
989{
990 unsigned int dlen;
991 struct dmov_desc *pdesc;
992
Mona Hossain3b574d82011-09-01 15:02:01 -0700993 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
994 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700995 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
996
997 if (dlen == 0) {
998 pdesc->addr = pmem;
999 pdesc->len = nbytes;
1000 } else if (pmem == (pdesc->addr + dlen)) {
1001 pdesc->len = dlen + nbytes;
1002 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001003 pce_dev->ce_dm.ce_out_dst_desc_index++;
1004 if (pce_dev->ce_dm.ce_out_dst_desc_index >= QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001005 return -EIO;
1006 pdesc++;
1007 pdesc->len = nbytes;
1008 pdesc->addr = pmem;
1009 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001010 return 0;
1011};
1012
1013static void _chain_buffer_out_init(struct qce_device *pce_dev)
1014{
1015 struct dmov_desc *pdesc;
1016
Mona Hossain3b574d82011-09-01 15:02:01 -07001017 pce_dev->ce_dm.ce_out_dst_desc_index = 0;
1018 pce_dev->ce_dm.ce_out_src_desc_index = 0;
1019 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001020 pdesc->len = 0;
1021};
1022
1023static void _ce_out_final(struct qce_device *pce_dev, unsigned total)
1024{
1025 struct dmov_desc *pdesc;
1026 dmov_sg *pcmd;
1027
Mona Hossain3b574d82011-09-01 15:02:01 -07001028 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
1029 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001030 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001031
Mona Hossain3b574d82011-09-01 15:02:01 -07001032 pdesc = pce_dev->ce_dm.ce_out_src_desc +
1033 pce_dev->ce_dm.ce_out_src_desc_index;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001034 if (total > QCE_FIFO_SIZE) {
1035 qce_split_and_insert_dm_desc(pdesc, total, 0,
1036 &pce_dev->ce_dm.ce_out_src_desc_index);
1037 pdesc = pce_dev->ce_dm.ce_out_src_desc +
1038 pce_dev->ce_dm.ce_out_src_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -07001039 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001040 } else
1041 pdesc->len = ADM_DESC_LAST | total;
Mona Hossain3b574d82011-09-01 15:02:01 -07001042
1043 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001044 pcmd->cmd |= CMD_LC;
1045};
1046
1047static void _aead_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1048 unsigned int result, struct msm_dmov_errdata *err)
1049{
1050 struct qce_device *pce_dev;
1051
1052 pce_dev = (struct qce_device *) cmd_ptr->user;
1053 if (result != ADM_STATUS_OK) {
1054 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1055 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001056 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001057 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001058 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001059 }
1060
Mona Hossain3b574d82011-09-01 15:02:01 -07001061 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1062 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1063 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1064 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001065
1066 /* done */
1067 _aead_complete(pce_dev);
1068 }
1069};
1070
1071static void _aead_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1072 unsigned int result, struct msm_dmov_errdata *err)
1073{
1074 struct qce_device *pce_dev;
1075
1076 pce_dev = (struct qce_device *) cmd_ptr->user;
1077 if (result != ADM_STATUS_OK) {
1078 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1079 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001080 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001081 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001082 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001083 };
1084
Mona Hossain3b574d82011-09-01 15:02:01 -07001085 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1086 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1087 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1088 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001089
1090 /* done */
1091 _aead_complete(pce_dev);
1092 }
1093
1094};
1095
1096static void _sha_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1097 unsigned int result, struct msm_dmov_errdata *err)
1098{
1099 struct qce_device *pce_dev;
1100
1101 pce_dev = (struct qce_device *) cmd_ptr->user;
1102 if (result != ADM_STATUS_OK) {
1103 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1104 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001105 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001106 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001107 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001108 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001109 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001110 _sha_complete(pce_dev);
1111};
1112
1113static void _ablk_cipher_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1114 unsigned int result, struct msm_dmov_errdata *err)
1115{
1116 struct qce_device *pce_dev;
1117
1118 pce_dev = (struct qce_device *) cmd_ptr->user;
1119 if (result != ADM_STATUS_OK) {
1120 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1121 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001122 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001123 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001124 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001125 }
1126
Mona Hossain3b574d82011-09-01 15:02:01 -07001127 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1128 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1129 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1130 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001131
1132 /* done */
1133 _ablk_cipher_complete(pce_dev);
1134 }
1135};
1136
1137static void _ablk_cipher_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1138 unsigned int result, struct msm_dmov_errdata *err)
1139{
1140 struct qce_device *pce_dev;
1141
1142 pce_dev = (struct qce_device *) cmd_ptr->user;
Mona Hossain3b574d82011-09-01 15:02:01 -07001143
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001144 if (result != ADM_STATUS_OK) {
1145 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1146 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001147 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001148 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001149 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001150 };
1151
Mona Hossain3b574d82011-09-01 15:02:01 -07001152 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1153 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1154 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1155 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001156
1157 /* done */
1158 _ablk_cipher_complete(pce_dev);
1159 }
1160};
1161
1162
1163static void _ablk_cipher_ce_in_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1164 unsigned int result, struct msm_dmov_errdata *err)
1165{
1166 struct qce_device *pce_dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001167 pce_dev = (struct qce_device *) cmd_ptr->user;
1168 if (result != ADM_STATUS_OK) {
1169 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1170 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001171 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001172 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001173 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001174 }
1175
Mona Hossain3b574d82011-09-01 15:02:01 -07001176 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1177 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1178 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1179 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001180
1181 /* done */
1182 _ablk_cipher_use_pmem_complete(pce_dev);
1183 }
1184};
1185
1186static void _ablk_cipher_ce_out_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1187 unsigned int result, struct msm_dmov_errdata *err)
1188{
1189 struct qce_device *pce_dev;
1190
1191 pce_dev = (struct qce_device *) cmd_ptr->user;
1192 if (result != ADM_STATUS_OK) {
1193 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1194 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001195 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001196 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001197 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001198 };
1199
Mona Hossain3b574d82011-09-01 15:02:01 -07001200 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1201 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1202 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1203 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001204
1205 /* done */
1206 _ablk_cipher_use_pmem_complete(pce_dev);
1207 }
1208};
1209
Mona Hossain3b574d82011-09-01 15:02:01 -07001210static int qce_setup_cmd_buffers(struct qce_device *pce_dev,
1211 unsigned char **pvaddr)
1212{
1213 struct ce_reg_buffers *addr = (struct ce_reg_buffers *)(*pvaddr);
1214 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
1215
1216 /*
1217 * Designate chunks of the allocated memory to various
1218 * buffer pointers
1219 */
1220 buffer->reset_buf_64 = addr->reset_buf_64;
1221 buffer->version = addr->version;
1222 buffer->encr_seg_cfg_size_start = addr->encr_seg_cfg_size_start;
1223 buffer->encr_key = addr->encr_key;
1224 buffer->encr_xts_key = addr->encr_xts_key;
1225 buffer->encr_xts_du_size = addr->encr_xts_du_size;
1226 buffer->encr_cntr_iv = addr->encr_cntr_iv;
1227 buffer->encr_mask = addr->encr_mask;
1228 buffer->auth_seg_cfg_size_start = addr->auth_seg_cfg_size_start;
1229 buffer->auth_key = addr->auth_key;
1230 buffer->auth_iv = addr->auth_iv;
1231 buffer->auth_result = addr->auth_result;
1232 buffer->auth_nonce_info = addr->auth_nonce_info;
1233 buffer->auth_byte_count = addr->auth_byte_count;
1234 buffer->seg_size = addr->seg_size;
1235 buffer->go_proc = addr->go_proc;
1236 buffer->status = addr->status;
1237 buffer->pad = addr->pad;
1238
1239 memset(buffer->reset_buf_64, 0, 64);
1240 *((uint32_t *)buffer->encr_mask) = (uint32_t)(0xffffffff);
1241 *((uint32_t *)buffer->go_proc) = (uint32_t)(1 << CRYPTO_GO);
1242
1243 *pvaddr += sizeof(struct ce_reg_buffers);
1244
1245 return 0;
1246
1247}
1248
1249static int _setup_cipher_cmdlists(struct qce_device *pce_dev,
1250 unsigned char **pvaddr)
1251{
1252 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1253
1254 /*
1255 * Designate chunks of the allocated memory to various
1256 * command list pointers related to cipher operation
1257 */
1258 pce_dev->ce_dm.cmdlist.set_cipher_cfg = pscmd;
1259 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1260 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG +
1261 pce_dev->phy_iobase);
1262 pscmd->len = CRYPTO_REG_SIZE * 3;
1263 pscmd->src =
1264 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_seg_cfg_size_start);
1265 pscmd++;
1266
1267 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_key = pscmd;
1268 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1269 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1270 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1271 pscmd->len = CRYPTO_REG_SIZE * 4;
1272 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1273 pscmd++;
1274
1275 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_key = pscmd;
1276 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1277 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1278 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1279 pscmd->len = CRYPTO_REG_SIZE * 8;
1280 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1281 pscmd++;
1282
1283 pce_dev->ce_dm.cmdlist.set_cipher_des_key = pscmd;
1284 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1285 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1286 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1287 pscmd->len = CRYPTO_REG_SIZE * 2;
1288 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1289 pscmd++;
1290
1291 pce_dev->ce_dm.cmdlist.set_cipher_3des_key = pscmd;
1292 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1293 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1294 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1295 pscmd->len = CRYPTO_REG_SIZE * 6;
1296 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1297 pscmd++;
1298
1299 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_xts_key = pscmd;
1300 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1301 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1302 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1303 pce_dev->phy_iobase);
1304 pscmd->len = CRYPTO_REG_SIZE * 4;
1305 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1306 pscmd++;
1307
1308 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_xts_key = pscmd;
1309 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1310 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1311 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1312 pce_dev->phy_iobase);
1313 pscmd->len = CRYPTO_REG_SIZE * 8;
1314 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1315 pscmd++;
1316
1317 pce_dev->ce_dm.cmdlist.set_cipher_xts_du_size = pscmd;
1318 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1319 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_DU_SIZE_REG +
1320 pce_dev->phy_iobase);
1321 pscmd->len = CRYPTO_REG_SIZE * 4;
1322 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_du_size);
1323 pscmd++;
1324
1325 pce_dev->ce_dm.cmdlist.set_cipher_aes_iv = pscmd;
1326 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1327 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1328 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1329 pscmd->len = CRYPTO_REG_SIZE * 4;
1330 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1331 pscmd++;
1332
1333 pce_dev->ce_dm.cmdlist.get_cipher_aes_iv = pscmd;
1334 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1335 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1336 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1337 pscmd->len = CRYPTO_REG_SIZE * 4;
1338 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1339 pscmd++;
1340
1341 pce_dev->ce_dm.cmdlist.get_cipher_aes_xts_iv = pscmd;
1342 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1343 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1344 pscmd->len = CRYPTO_REG_SIZE * 4;
1345 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1346 pscmd++;
1347
1348 pce_dev->ce_dm.cmdlist.set_cipher_des_iv = pscmd;
1349 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1350 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1351 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1352 pscmd->len = CRYPTO_REG_SIZE * 2;
1353 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1354 pscmd++;
1355
1356 pce_dev->ce_dm.cmdlist.get_cipher_des_iv = pscmd;
1357 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1358 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1359 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1360 pscmd->len = CRYPTO_REG_SIZE * 2;
1361 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1362 pscmd++;
1363
1364 pce_dev->ce_dm.cmdlist.set_cipher_mask = pscmd;
1365 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1366 pscmd->dst = (unsigned) (CRYPTO_CNTR_MASK_REG + pce_dev->phy_iobase);
1367 pscmd->len = CRYPTO_REG_SIZE;
1368 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_mask);
1369 pscmd++;
1370
1371 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1372
1373 pce_dev->ce_dm.cmdlist.reset_cipher_key = pscmd;
1374 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1375 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1376 pscmd->len = CRYPTO_REG_SIZE * 8;
1377 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1378 pscmd++;
1379
1380 pce_dev->ce_dm.cmdlist.reset_cipher_xts_key = pscmd;
1381 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1382 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1383 pce_dev->phy_iobase);
1384 pscmd->len = CRYPTO_REG_SIZE * 8;
1385 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1386 pscmd++;
1387
1388 pce_dev->ce_dm.cmdlist.reset_cipher_iv = pscmd;
1389 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1390 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1391 pscmd->len = CRYPTO_REG_SIZE * 4;
1392 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1393 pscmd++;
1394
1395 pce_dev->ce_dm.cmdlist.reset_cipher_cfg = pscmd;
1396 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1397 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG + pce_dev->phy_iobase);
1398 pscmd->len = CRYPTO_REG_SIZE;
1399 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1400 pscmd++;
1401
1402 *pvaddr = (unsigned char *) pscmd;
1403
1404 return 0;
1405}
1406
1407static int _setup_auth_cmdlists(struct qce_device *pce_dev,
1408 unsigned char **pvaddr)
1409{
1410 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1411
1412 /*
1413 * Designate chunks of the allocated memory to various
1414 * command list pointers related to authentication operation
1415 */
1416 pce_dev->ce_dm.cmdlist.set_auth_cfg = pscmd;
1417 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1418 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1419 pscmd->len = CRYPTO_REG_SIZE * 3;
1420 pscmd->src =
1421 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start);
1422 pscmd++;
1423
1424 pce_dev->ce_dm.cmdlist.set_auth_key_128 = pscmd;
1425 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1426 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1427 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1428 pscmd->len = CRYPTO_REG_SIZE * 4;
1429 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1430 pscmd++;
1431
1432 pce_dev->ce_dm.cmdlist.set_auth_key_256 = pscmd;
1433 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1434 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1435 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1436 pscmd->len = CRYPTO_REG_SIZE * 8;
1437 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1438 pscmd++;
1439
1440 pce_dev->ce_dm.cmdlist.set_auth_key_512 = pscmd;
1441 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1442 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1443 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1444 pscmd->len = CRYPTO_REG_SIZE * 16;
1445 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1446 pscmd++;
1447
1448 pce_dev->ce_dm.cmdlist.set_auth_iv_16 = pscmd;
1449 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1450 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1451 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1452 pscmd->len = CRYPTO_REG_SIZE * 4;
1453 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1454 pscmd++;
1455
1456 pce_dev->ce_dm.cmdlist.get_auth_result_16 = pscmd;
1457 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1458 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1459 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1460 pscmd->len = CRYPTO_REG_SIZE * 4;
1461 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1462 pscmd++;
1463
1464 pce_dev->ce_dm.cmdlist.set_auth_iv_20 = pscmd;
1465 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1466 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1467 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1468 pscmd->len = CRYPTO_REG_SIZE * 5;
1469 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1470 pscmd++;
1471
1472 pce_dev->ce_dm.cmdlist.get_auth_result_20 = pscmd;
1473 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1474 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1475 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1476 pscmd->len = CRYPTO_REG_SIZE * 5;
1477 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1478 pscmd++;
1479
1480 pce_dev->ce_dm.cmdlist.set_auth_iv_32 = pscmd;
1481 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1482 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1483 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1484 pscmd->len = CRYPTO_REG_SIZE * 8;
1485 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1486 pscmd++;
1487
1488
1489 pce_dev->ce_dm.cmdlist.get_auth_result_32 = pscmd;
1490 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1491 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1492 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1493 pscmd->len = CRYPTO_REG_SIZE * 8;
1494 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1495 pscmd++;
1496
1497 pce_dev->ce_dm.cmdlist.set_auth_byte_count = pscmd;
1498 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1499 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1500 pce_dev->phy_iobase);
1501 pscmd->len = CRYPTO_REG_SIZE * 4;
1502 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1503 pscmd++;
1504
1505 pce_dev->ce_dm.cmdlist.get_auth_byte_count = pscmd;
1506 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1507 pscmd->src = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1508 pce_dev->phy_iobase);
1509 pscmd->len = CRYPTO_REG_SIZE * 4;
1510 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1511 pscmd++;
1512
1513 pce_dev->ce_dm.cmdlist.set_auth_nonce_info = pscmd;
1514 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1515 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1516 pscmd->dst = (unsigned) (CRYPTO_AUTH_INFO_NONCE0_REG +
1517 pce_dev->phy_iobase);
1518 pscmd->len = CRYPTO_REG_SIZE * 4;
1519 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_nonce_info);
1520 pscmd++;
1521
1522 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1523
1524 pce_dev->ce_dm.cmdlist.reset_auth_key = pscmd;
1525 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1526 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1527 pscmd->len = CRYPTO_REG_SIZE * 16;
1528 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1529 pscmd++;
1530
1531 pce_dev->ce_dm.cmdlist.reset_auth_iv = pscmd;
1532 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1533 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1534 pscmd->len = CRYPTO_REG_SIZE * 16;
1535 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1536 pscmd++;
1537
1538 pce_dev->ce_dm.cmdlist.reset_auth_cfg = pscmd;
1539 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1540 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1541 pscmd->len = CRYPTO_REG_SIZE;
1542 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1543 pscmd++;
1544
1545
1546 pce_dev->ce_dm.cmdlist.reset_auth_byte_count = pscmd;
1547 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1548 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1549 pce_dev->phy_iobase);
1550 pscmd->len = CRYPTO_REG_SIZE * 4;
1551 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1552 pscmd++;
1553
1554 /* WAIT UNTIL MAC OP IS DONE*/
1555
1556 pce_dev->ce_dm.cmdlist.get_status_wait = pscmd;
1557 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1558 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1559 pscmd->len = CRYPTO_REG_SIZE;
1560 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1561 pscmd++;
1562
1563 *pvaddr = (unsigned char *) pscmd;
1564
1565 return 0;
1566}
1567
1568static int qce_setup_cmdlists(struct qce_device *pce_dev,
1569 unsigned char **pvaddr)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001570{
1571 dmov_sg *pcmd;
Mona Hossain3b574d82011-09-01 15:02:01 -07001572 dmov_s *pscmd;
1573 unsigned char *vaddr = *pvaddr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001574 struct dmov_desc *pdesc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001575 int i = 0;
1576
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001577 /*
Mona Hossain3b574d82011-09-01 15:02:01 -07001578 * Designate chunks of the allocated memory to various
1579 * command list pointers related to operation define
1580 * in ce_cmdlists structure.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001581 */
Mona Hossain3b574d82011-09-01 15:02:01 -07001582 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
1583 *pvaddr = (unsigned char *) vaddr;
1584
1585 _setup_cipher_cmdlists(pce_dev, pvaddr);
1586 _setup_auth_cmdlists(pce_dev, pvaddr);
1587
1588 pscmd = (dmov_s *)(*pvaddr);
1589
1590 /* GET HW VERSION COMMAND LIST */
1591 pce_dev->ce_dm.cmdlist.get_hw_version = pscmd;
1592 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1593 pscmd->src = (unsigned) (CRYPTO_VERSION_REG + pce_dev->phy_iobase);
1594 pscmd->len = CRYPTO_REG_SIZE;
1595 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.version);
1596 pscmd++;
1597
1598
1599 /* SET SEG SIZE REGISTER and OCB COMMAND LIST */
1600 pce_dev->ce_dm.cmdlist.set_seg_size_ocb = pscmd;
1601 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1602 pscmd->dst = (unsigned) (CRYPTO_SEG_SIZE_REG + pce_dev->phy_iobase);
1603 pscmd->len = CRYPTO_REG_SIZE;
1604 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.seg_size);
1605 pscmd++;
1606
1607
1608 /* OCU COMMAND LIST */
1609 pce_dev->ce_dm.cmdlist.get_status_ocu = pscmd;
1610 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCU;
1611 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1612 pscmd->len = CRYPTO_REG_SIZE;
1613 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1614 pscmd++;
1615
1616 /* SET GO_PROC REGISTERS COMMAND LIST */
1617 pce_dev->ce_dm.cmdlist.set_go_proc = pscmd;
1618 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1619 pscmd->dst = (unsigned) (CRYPTO_GOPROC_REG + pce_dev->phy_iobase);
1620 pscmd->len = CRYPTO_REG_SIZE;
1621 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.go_proc);
1622 pscmd++;
1623
1624 pcmd = (dmov_sg *)pscmd;
1625 pce_dev->ce_dm.cmdlist.ce_data_in = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001626 /* swap byte and half word , dst crci , scatter gather */
1627 pcmd->cmd = CMD_DST_SWAP_BYTES | CMD_DST_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001628 CMD_DST_CRCI(pce_dev->ce_dm.crci_in) | CMD_MODE_SG;
1629
1630 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001631 pdesc->addr = 0; /* to be filled in each operation */
1632 pdesc->len = 0; /* to be filled in each operation */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001633
Mona Hossain3b574d82011-09-01 15:02:01 -07001634 pdesc = pce_dev->ce_dm.ce_in_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001635 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1636 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1637 pdesc->len = 0; /* to be filled in each operation */
1638 pdesc++;
1639 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001640 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_src_desc);
1641 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001642 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1643 DST_INDEX_SG_CMD(0);
Mona Hossain3b574d82011-09-01 15:02:01 -07001644
1645
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001646 pcmd++;
Mona Hossain3b574d82011-09-01 15:02:01 -07001647 pce_dev->ce_dm.cmdlist.ce_data_out = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001648 /* swap byte, half word, source crci, scatter gather */
1649 pcmd->cmd = CMD_SRC_SWAP_BYTES | CMD_SRC_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001650 CMD_SRC_CRCI(pce_dev->ce_dm.crci_out) | CMD_MODE_SG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001651
Mona Hossain3b574d82011-09-01 15:02:01 -07001652 pdesc = pce_dev->ce_dm.ce_out_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001653 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1654 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1655 pdesc->len = 0; /* to be filled in each operation */
1656 pdesc++;
1657 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001658
Mona Hossain3b574d82011-09-01 15:02:01 -07001659 pdesc = pce_dev->ce_dm.ce_out_dst_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 */
Mona Hossain3b574d82011-09-01 15:02:01 -07001662
1663 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_src_desc);
1664 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001665 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1666 DST_INDEX_SG_CMD(0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001667 pcmd++;
1668
Mona Hossain3b574d82011-09-01 15:02:01 -07001669 *pvaddr = (unsigned char *) pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001670
1671 return 0;
Mona Hossain3b574d82011-09-01 15:02:01 -07001672}
1673
1674static int _setup_cipher_cmdptrlists(struct qce_device *pce_dev,
1675 unsigned char **pvaddr)
1676{
1677 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1678 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1679 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1680
1681 /*
1682 * Designate chunks of the allocated memory to various
1683 * command list pointers related to cipher operations defined
1684 * in ce_cmdptrlists_ops structure.
1685 */
1686 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1687 cmdptrlist->cipher_aes_128_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1688
1689 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1690 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1691 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1692 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1693 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1694 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1695 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1696 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1697 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_iv);
1698
1699 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1700 cmdptrlist->cipher_aes_256_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1701
1702 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1703 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1704 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1705 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1706 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1707 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1708 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1709 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1710 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_iv);
1711
1712 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1713 cmdptrlist->cipher_aes_128_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1714
1715 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1716 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1717 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1718 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1719 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1720 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1721 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1722
1723 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1724 cmdptrlist->cipher_aes_256_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1725
1726 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1727 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1728 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1729 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1730 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1731 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1732 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1733
1734 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1735 cmdptrlist->cipher_aes_128_xts = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1736
1737 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1738 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1739 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1740 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_xts_key);
1741 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1742 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1743 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
1744 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1745 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1746 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1747 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_xts_iv);
1748
1749 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1750 cmdptrlist->cipher_aes_256_xts = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1751
1752 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1753 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1754 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1755 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_xts_key);
1756 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1757 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1758 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
1759 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1760 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1761 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1762 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_xts_iv);
1763
1764 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1765 cmdptrlist->cipher_des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1766
1767 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1768 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1769 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1770 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1771 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1772 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1773 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1774 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_des_iv);
1775
1776 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1777 cmdptrlist->cipher_des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1778
1779 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1780 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1781 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1782 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1783 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1784 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1785
1786 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1787 cmdptrlist->cipher_3des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1788
1789 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1790 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1791 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1792 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1793 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1794 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1795 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1796 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_des_iv);
1797
1798 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1799 cmdptrlist->cipher_3des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1800
1801 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1802 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1803 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1804 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1805 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1806 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1807
1808 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1809 cmdptrlist->cipher_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1810
1811 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1812 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1813 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1814
1815 return 0;
1816}
1817
1818static int _setup_auth_cmdptrlists(struct qce_device *pce_dev,
1819 unsigned char **pvaddr)
1820{
1821 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1822 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1823 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1824
1825 /*
1826 * Designate chunks of the allocated memory to various
1827 * command list pointers related to authentication operations
1828 * defined in ce_cmdptrlists_ops structure.
1829 */
1830 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1831 cmdptrlist->auth_sha1 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1832
1833 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1834 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1835 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1836 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1837 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1838 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1839 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1840 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1841 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1842 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1843 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1844 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1845
1846 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1847 cmdptrlist->auth_sha256 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1848
1849 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1850 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1851 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1852 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1853 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1854 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1855 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1856 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1857 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1858 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1859 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1860 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1861
1862 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1863 cmdptrlist->auth_sha1_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1864
1865 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1866 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1867 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1868 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1869 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1870 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1871 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1872 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1873 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1874 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1875 *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_hmac = 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_key_512);
1885 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1886 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1887 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1888 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1889 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1890 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1891 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1892 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1893 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1894 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1895
1896 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1897 cmdptrlist->auth_aes_128_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1898
1899 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1900 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1901 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1902 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1903 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1904 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1905 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
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);
1910 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1911 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1912 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1913
1914 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1915 cmdptrlist->auth_aes_256_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1916
1917 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1918 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1919 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1920 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1921 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1922 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1923 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1924 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1925 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1926 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1927 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1928 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1929 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1930 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1931
1932 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1933
1934 return 0;
1935}
1936
1937static int _setup_aead_cmdptrlists(struct qce_device *pce_dev,
1938 unsigned char **pvaddr)
1939{
1940 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1941 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1942 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1943
1944 /*
1945 * Designate chunks of the allocated memory to various
1946 * command list pointers related to aead operations
1947 * defined in ce_cmdptrlists_ops structure.
1948 */
1949 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1950 cmdptrlist->aead_aes_128_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1951
1952 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1953 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1954 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1955 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1956 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1957 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1958 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1959 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1960 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1961 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1962 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1963 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1964 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1965
1966 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1967 cmdptrlist->aead_aes_256_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1968
1969 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1970 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1971 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1972 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1973 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1974 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1975 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1976 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1977 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1978 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1979 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1980 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1981 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1982
1983 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1984 cmdptrlist->aead_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1985
1986 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1987 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1988 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1989 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1990
1991 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1992
1993 return 0;
1994}
1995
1996static int qce_setup_cmdptrlists(struct qce_device *pce_dev,
1997 unsigned char **pvaddr)
1998{
1999 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
2000 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
2001 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
2002 /*
2003 * Designate chunks of the allocated memory to various
2004 * command list pointers related to operations defined
2005 * in ce_cmdptrlists_ops structure.
2006 */
2007 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
2008 cmdptrlist->probe_ce_hw = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
2009
2010 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_hw_version);
2011 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
2012
2013 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
2014
2015 _setup_cipher_cmdptrlists(pce_dev, pvaddr);
2016 _setup_auth_cmdptrlists(pce_dev, pvaddr);
2017 _setup_aead_cmdptrlists(pce_dev, pvaddr);
2018
2019 return 0;
2020}
2021
2022
2023static int qce_setup_ce_dm_data(struct qce_device *pce_dev)
2024{
2025 unsigned char *vaddr;
2026
2027 /* 1. ce_in channel data xfer command src descriptors, 128 entries */
2028 vaddr = pce_dev->coh_vmem;
2029 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2030 pce_dev->ce_dm.ce_in_src_desc = (struct dmov_desc *) vaddr;
2031 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2032
2033 /* 2. ce_in channel data xfer command dst descriptors, 128 entries */
2034 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2035 pce_dev->ce_dm.ce_in_dst_desc = (struct dmov_desc *) vaddr;
2036 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2037
2038
2039 /* 3. ce_out channel data xfer command src descriptors, 128 entries */
2040 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2041 pce_dev->ce_dm.ce_out_src_desc = (struct dmov_desc *) vaddr;
2042 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2043
2044 /* 4. ce_out channel data xfer command dst descriptors, 128 entries. */
2045 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2046 pce_dev->ce_dm.ce_out_dst_desc = (struct dmov_desc *) vaddr;
2047 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2048
2049 qce_setup_cmd_buffers(pce_dev, &vaddr);
2050 qce_setup_cmdlists(pce_dev, &vaddr);
2051 qce_setup_cmdptrlists(pce_dev, &vaddr);
2052
2053 pce_dev->ce_dm.buffer.ignore_data = vaddr;
2054
2055 pce_dev->ce_dm.phy_ce_pad = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.pad);
2056 pce_dev->ce_dm.phy_ce_out_ignore =
2057 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.ignore_data);
2058
2059 pce_dev->ce_dm.chan_ce_in_cmd->user = (void *) pce_dev;
2060 pce_dev->ce_dm.chan_ce_in_cmd->exec_func = NULL;
2061
2062 pce_dev->ce_dm.chan_ce_out_cmd->user = (void *) pce_dev;
2063 pce_dev->ce_dm.chan_ce_out_cmd->exec_func = NULL;
2064
2065 return 0;
2066}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002067
2068static int _qce_start_dma(struct qce_device *pce_dev, bool ce_in, bool ce_out)
2069{
2070
2071 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002072 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002073 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002074 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002075
2076 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002077 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002078 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002079 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002080
2081 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002082 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
2083 pce_dev->ce_dm.chan_ce_in_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002084 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002085 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_out,
2086 pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002087
2088 return 0;
2089};
2090
2091int qce_aead_req(void *handle, struct qce_req *q_req)
2092{
2093 struct qce_device *pce_dev = (struct qce_device *) handle;
2094 struct aead_request *areq = (struct aead_request *) q_req->areq;
2095 uint32_t authsize = q_req->authsize;
2096 uint32_t totallen_in, totallen_out, out_len;
2097 uint32_t pad_len_in, pad_len_out;
2098 uint32_t pad_mac_len_out, pad_ptx_len_out;
2099 int rc = 0;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002100 int ce_block_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002101
Mona Hossain5f5dde12011-09-12 10:28:34 -07002102 ce_block_size = pce_dev->ce_dm.ce_block_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002103 if (q_req->dir == QCE_ENCRYPT) {
2104 q_req->cryptlen = areq->cryptlen;
2105 totallen_in = q_req->cryptlen + areq->assoclen;
2106 totallen_out = q_req->cryptlen + authsize + areq->assoclen;
2107 out_len = areq->cryptlen + authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002108 pad_len_in = ALIGN(totallen_in, ce_block_size) - totallen_in;
2109 pad_mac_len_out = ALIGN(authsize, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002110 authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002111 pad_ptx_len_out = ALIGN(q_req->cryptlen, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002112 q_req->cryptlen;
2113 pad_len_out = pad_ptx_len_out + pad_mac_len_out;
2114 totallen_out += pad_len_out;
2115 } else {
2116 q_req->cryptlen = areq->cryptlen - authsize;
2117 totallen_in = areq->cryptlen + areq->assoclen;
2118 totallen_out = q_req->cryptlen + areq->assoclen;
2119 out_len = areq->cryptlen - authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002120 pad_len_in = ALIGN(areq->cryptlen, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002121 areq->cryptlen;
2122 pad_len_out = pad_len_in + authsize;
2123 totallen_out += pad_len_out;
2124 }
2125
2126 _chain_buffer_in_init(pce_dev);
2127 _chain_buffer_out_init(pce_dev);
2128
2129 pce_dev->assoc_nents = 0;
2130 pce_dev->src_nents = 0;
2131 pce_dev->dst_nents = 0;
2132 pce_dev->ivsize = q_req->ivsize;
2133 pce_dev->authsize = q_req->authsize;
2134
2135 /* associated data input */
2136 pce_dev->assoc_nents = count_sg(areq->assoc, areq->assoclen);
2137 dma_map_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
2138 DMA_TO_DEVICE);
2139 if (_chain_sg_buffer_in(pce_dev, areq->assoc, areq->assoclen) < 0) {
2140 rc = -ENOMEM;
2141 goto bad;
2142 }
2143 /* cipher input */
2144 pce_dev->src_nents = count_sg(areq->src, areq->cryptlen);
2145 dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2146 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2147 DMA_TO_DEVICE);
2148 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->cryptlen) < 0) {
2149 rc = -ENOMEM;
2150 goto bad;
2151 }
2152 /* pad data in */
2153 if (pad_len_in) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002154 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002155 pad_len_in) < 0) {
2156 rc = -ENOMEM;
2157 goto bad;
2158 }
2159 }
2160
2161 /* ignore associated data */
Mona Hossain3b574d82011-09-01 15:02:01 -07002162 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_out_ignore,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002163 areq->assoclen) < 0) {
2164 rc = -ENOMEM;
2165 goto bad;
2166 }
2167 /* cipher + mac output for encryption */
2168 if (areq->src != areq->dst) {
2169 pce_dev->dst_nents = count_sg(areq->dst, out_len);
2170 dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2171 DMA_FROM_DEVICE);
2172 };
2173 if (_chain_sg_buffer_out(pce_dev, areq->dst, out_len) < 0) {
2174 rc = -ENOMEM;
2175 goto bad;
2176 }
2177 /* pad data out */
2178 if (pad_len_out) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002179 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002180 pad_len_out) < 0) {
2181 rc = -ENOMEM;
2182 goto bad;
2183 }
2184 }
2185
2186 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain5f5dde12011-09-12 10:28:34 -07002187 _ce_in_final(pce_dev, ALIGN(totallen_in, ce_block_size));
2188 _ce_out_final(pce_dev, ALIGN(totallen_out, ce_block_size));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002189
2190 /* set up crypto device */
2191 rc = _ce_setup_cipher(pce_dev, q_req, totallen_in, areq->assoclen);
2192 if (rc < 0)
2193 goto bad;
2194
2195 /* setup for callback, and issue command to adm */
2196 pce_dev->areq = q_req->areq;
2197 pce_dev->qce_cb = q_req->qce_cb;
2198
Mona Hossain3b574d82011-09-01 15:02:01 -07002199 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _aead_ce_in_call_back;
2200 pce_dev->ce_dm.chan_ce_out_cmd->complete_func = _aead_ce_out_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002201
2202 _ce_in_dump(pce_dev);
2203 _ce_out_dump(pce_dev);
2204
2205 rc = _qce_start_dma(pce_dev, true, true);
2206 if (rc == 0)
2207 return 0;
2208bad:
2209 if (pce_dev->assoc_nents) {
2210 dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
2211 DMA_TO_DEVICE);
2212 }
2213
2214 if (pce_dev->src_nents) {
2215 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2216 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2217 DMA_TO_DEVICE);
2218 }
2219 if (pce_dev->dst_nents) {
2220 dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2221 DMA_FROM_DEVICE);
2222 }
2223 return rc;
2224}
2225EXPORT_SYMBOL(qce_aead_req);
2226
2227int qce_ablk_cipher_req(void *handle, struct qce_req *c_req)
2228{
2229 int rc = 0;
2230 struct qce_device *pce_dev = (struct qce_device *) handle;
2231 struct ablkcipher_request *areq = (struct ablkcipher_request *)
2232 c_req->areq;
2233
Mona Hossain5f5dde12011-09-12 10:28:34 -07002234 uint32_t pad_len = ALIGN(areq->nbytes, pce_dev->ce_dm.ce_block_size)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002235 - areq->nbytes;
2236
2237 _chain_buffer_in_init(pce_dev);
2238 _chain_buffer_out_init(pce_dev);
2239
2240 pce_dev->src_nents = 0;
2241 pce_dev->dst_nents = 0;
2242
2243 /* cipher input */
2244 pce_dev->src_nents = count_sg(areq->src, areq->nbytes);
2245
2246 if (c_req->use_pmem != 1)
2247 dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2248 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2249 DMA_TO_DEVICE);
2250 else
2251 dma_map_pmem_sg(&c_req->pmem->src[0], pce_dev->src_nents,
2252 areq->src);
2253
2254 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->nbytes) < 0) {
2255 rc = -ENOMEM;
2256 goto bad;
2257 }
2258
2259 /* cipher output */
2260 if (areq->src != areq->dst) {
2261 pce_dev->dst_nents = count_sg(areq->dst, areq->nbytes);
2262 if (c_req->use_pmem != 1)
2263 dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2264 DMA_FROM_DEVICE);
2265 else
2266 dma_map_pmem_sg(&c_req->pmem->dst[0],
2267 pce_dev->dst_nents, areq->dst);
2268 };
2269 if (_chain_sg_buffer_out(pce_dev, areq->dst, areq->nbytes) < 0) {
2270 rc = -ENOMEM;
2271 goto bad;
2272 }
2273
2274 /* pad data */
2275 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002276 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002277 pad_len) < 0) {
2278 rc = -ENOMEM;
2279 goto bad;
2280 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002281 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002282 pad_len) < 0) {
2283 rc = -ENOMEM;
2284 goto bad;
2285 }
2286 }
2287
2288 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain2563cbc2011-09-14 15:24:08 -07002289 _ce_in_final(pce_dev, areq->nbytes + pad_len);
2290 _ce_out_final(pce_dev, areq->nbytes + pad_len);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002291
2292 _ce_in_dump(pce_dev);
2293 _ce_out_dump(pce_dev);
2294
2295 /* set up crypto device */
2296 rc = _ce_setup_cipher(pce_dev, c_req, areq->nbytes, 0);
2297 if (rc < 0)
2298 goto bad;
2299
2300 /* setup for callback, and issue command to adm */
2301 pce_dev->areq = areq;
2302 pce_dev->qce_cb = c_req->qce_cb;
2303 if (c_req->use_pmem == 1) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002304 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002305 _ablk_cipher_ce_in_call_back_pmem;
Mona Hossain3b574d82011-09-01 15:02:01 -07002306 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002307 _ablk_cipher_ce_out_call_back_pmem;
2308 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07002309 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002310 _ablk_cipher_ce_in_call_back;
Mona Hossain3b574d82011-09-01 15:02:01 -07002311 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002312 _ablk_cipher_ce_out_call_back;
2313 }
2314 rc = _qce_start_dma(pce_dev, true, true);
2315
2316 if (rc == 0)
2317 return 0;
2318bad:
2319 if (c_req->use_pmem != 1) {
2320 if (pce_dev->dst_nents) {
2321 dma_unmap_sg(pce_dev->pdev, areq->dst,
2322 pce_dev->dst_nents, DMA_FROM_DEVICE);
2323 }
2324 if (pce_dev->src_nents) {
2325 dma_unmap_sg(pce_dev->pdev, areq->src,
2326 pce_dev->src_nents,
2327 (areq->src == areq->dst) ?
2328 DMA_BIDIRECTIONAL :
2329 DMA_TO_DEVICE);
2330 }
2331 }
2332 return rc;
2333}
2334EXPORT_SYMBOL(qce_ablk_cipher_req);
2335
2336int qce_process_sha_req(void *handle, struct qce_sha_req *sreq)
2337{
2338 struct qce_device *pce_dev = (struct qce_device *) handle;
2339 int rc;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002340 uint32_t pad_len = ALIGN(sreq->size, pce_dev->ce_dm.ce_block_size) -
2341 sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002342 struct ahash_request *areq = (struct ahash_request *)sreq->areq;
2343
2344 _chain_buffer_in_init(pce_dev);
2345 pce_dev->src_nents = count_sg(sreq->src, sreq->size);
2346 dma_map_sg(pce_dev->pdev, sreq->src, pce_dev->src_nents,
2347 DMA_TO_DEVICE);
2348
2349 if (_chain_sg_buffer_in(pce_dev, sreq->src, sreq->size) < 0) {
2350 rc = -ENOMEM;
2351 goto bad;
2352 }
2353
2354 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002355 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002356 pad_len) < 0) {
2357 rc = -ENOMEM;
2358 goto bad;
2359 }
2360 }
Mona Hossain2563cbc2011-09-14 15:24:08 -07002361 _ce_in_final(pce_dev, sreq->size + pad_len);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002362
2363 _ce_in_dump(pce_dev);
2364
Mona Hossain3b574d82011-09-01 15:02:01 -07002365 rc = _ce_setup_hash(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002366
2367 if (rc < 0)
2368 goto bad;
2369
2370 pce_dev->areq = areq;
2371 pce_dev->qce_cb = sreq->qce_cb;
Mona Hossain3b574d82011-09-01 15:02:01 -07002372 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _sha_ce_in_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002373
2374 rc = _qce_start_dma(pce_dev, true, false);
2375
2376 if (rc == 0)
2377 return 0;
2378bad:
2379 if (pce_dev->src_nents) {
2380 dma_unmap_sg(pce_dev->pdev, sreq->src,
2381 pce_dev->src_nents, DMA_TO_DEVICE);
2382 }
2383
2384 return rc;
2385}
2386EXPORT_SYMBOL(qce_process_sha_req);
2387
2388/* crypto engine open function. */
2389void *qce_open(struct platform_device *pdev, int *rc)
2390{
2391 struct qce_device *pce_dev;
2392 struct resource *resource;
2393 struct clk *ce_core_clk;
2394 struct clk *ce_clk;
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002395 struct clk *ce_core_src_clk;
2396 int ret = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002397
2398 pce_dev = kzalloc(sizeof(struct qce_device), GFP_KERNEL);
2399 if (!pce_dev) {
2400 *rc = -ENOMEM;
2401 dev_err(&pdev->dev, "Can not allocate memory\n");
2402 return NULL;
2403 }
2404 pce_dev->pdev = &pdev->dev;
2405
2406 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2407 if (!resource) {
2408 *rc = -ENXIO;
2409 dev_err(pce_dev->pdev, "Missing MEM resource\n");
2410 goto err_pce_dev;
2411 };
2412 pce_dev->phy_iobase = resource->start;
2413 pce_dev->iobase = ioremap_nocache(resource->start,
2414 resource->end - resource->start + 1);
2415 if (!pce_dev->iobase) {
2416 *rc = -ENOMEM;
2417 dev_err(pce_dev->pdev, "Can not map io memory\n");
2418 goto err_pce_dev;
2419 }
2420
Mona Hossain3b574d82011-09-01 15:02:01 -07002421 pce_dev->ce_dm.chan_ce_in_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002422 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002423 pce_dev->ce_dm.chan_ce_out_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002424 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002425 if (pce_dev->ce_dm.chan_ce_in_cmd == NULL ||
2426 pce_dev->ce_dm.chan_ce_out_cmd == NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002427 dev_err(pce_dev->pdev, "Can not allocate memory\n");
2428 *rc = -ENOMEM;
2429 goto err_dm_chan_cmd;
2430 }
2431
2432 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2433 "crypto_channels");
2434 if (!resource) {
2435 *rc = -ENXIO;
2436 dev_err(pce_dev->pdev, "Missing DMA channel resource\n");
2437 goto err_dm_chan_cmd;
2438 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002439 pce_dev->ce_dm.chan_ce_in = resource->start;
2440 pce_dev->ce_dm.chan_ce_out = resource->end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002441 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2442 "crypto_crci_in");
2443 if (!resource) {
2444 *rc = -ENXIO;
2445 dev_err(pce_dev->pdev, "Missing DMA crci in resource\n");
2446 goto err_dm_chan_cmd;
2447 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002448 pce_dev->ce_dm.crci_in = resource->start;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002449 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2450 "crypto_crci_out");
2451 if (!resource) {
2452 *rc = -ENXIO;
2453 dev_err(pce_dev->pdev, "Missing DMA crci out resource\n");
2454 goto err_dm_chan_cmd;
2455 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002456 pce_dev->ce_dm.crci_out = resource->start;
2457 pce_dev->memsize = 2 * PAGE_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002458 pce_dev->coh_vmem = dma_alloc_coherent(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -07002459 pce_dev->memsize, &pce_dev->coh_pmem, GFP_KERNEL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002460
2461 if (pce_dev->coh_vmem == NULL) {
2462 *rc = -ENOMEM;
2463 dev_err(pce_dev->pdev, "Can not allocate coherent memory.\n");
2464 goto err;
2465 }
2466
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002467 /* Get CE3 src core clk. */
2468 ce_core_src_clk = clk_get(pce_dev->pdev, "ce3_core_src_clk");
2469 if (!IS_ERR(ce_core_src_clk)) {
2470 pce_dev->ce_core_src_clk = ce_core_src_clk;
2471
2472 /* Set the core src clk @100Mhz */
2473 ret = clk_set_rate(pce_dev->ce_core_src_clk, 100000000);
2474 if (ret) {
2475 clk_put(pce_dev->ce_core_src_clk);
2476 goto err;
2477 }
2478 } else
2479 pce_dev->ce_core_src_clk = NULL;
2480
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002481 /* Get CE core clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002482 ce_core_clk = clk_get(pce_dev->pdev, "core_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002483 if (IS_ERR(ce_core_clk)) {
2484 *rc = PTR_ERR(ce_core_clk);
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002485 if (pce_dev->ce_core_src_clk != NULL)
2486 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002487 goto err;
2488 }
2489 pce_dev->ce_core_clk = ce_core_clk;
2490 /* Get CE clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002491 ce_clk = clk_get(pce_dev->pdev, "iface_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002492 if (IS_ERR(ce_clk)) {
2493 *rc = PTR_ERR(ce_clk);
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002494 if (pce_dev->ce_core_src_clk != NULL)
2495 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002496 clk_put(pce_dev->ce_core_clk);
2497 goto err;
2498 }
2499 pce_dev->ce_clk = ce_clk;
2500
2501 /* Enable CE core clk */
2502 *rc = clk_enable(pce_dev->ce_core_clk);
2503 if (*rc) {
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002504 if (pce_dev->ce_core_src_clk != NULL)
2505 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002506 clk_put(pce_dev->ce_core_clk);
2507 clk_put(pce_dev->ce_clk);
2508 goto err;
2509 } else {
2510 /* Enable CE clk */
2511 *rc = clk_enable(pce_dev->ce_clk);
2512 if (*rc) {
2513 clk_disable(pce_dev->ce_core_clk);
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002514 if (pce_dev->ce_core_src_clk != NULL)
2515 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002516 clk_put(pce_dev->ce_core_clk);
2517 clk_put(pce_dev->ce_clk);
2518 goto err;
2519
2520 }
2521 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002522 qce_setup_ce_dm_data(pce_dev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002523
Mona Hossain3b574d82011-09-01 15:02:01 -07002524 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
2525 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002526 if (_init_ce_engine(pce_dev)) {
2527 *rc = -ENXIO;
2528 goto err;
2529 }
2530 *rc = 0;
2531 return pce_dev;
2532
2533err:
2534 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002535 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
Mona Hossaine1b13f82011-08-30 09:35:49 -07002536 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002537err_dm_chan_cmd:
Mona Hossain3b574d82011-09-01 15:02:01 -07002538 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2539 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002540 if (pce_dev->iobase)
2541 iounmap(pce_dev->iobase);
2542
2543err_pce_dev:
2544
2545 kfree(pce_dev);
2546
2547 return NULL;
2548}
2549EXPORT_SYMBOL(qce_open);
2550
2551/* crypto engine close function. */
2552int qce_close(void *handle)
2553{
2554 struct qce_device *pce_dev = (struct qce_device *) handle;
2555
2556 if (handle == NULL)
2557 return -ENODEV;
2558 if (pce_dev->iobase)
2559 iounmap(pce_dev->iobase);
2560
2561 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002562 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
2563 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002564 clk_disable(pce_dev->ce_clk);
2565 clk_disable(pce_dev->ce_core_clk);
2566
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002567 if (pce_dev->ce_core_src_clk != NULL)
2568 clk_put(pce_dev->ce_core_src_clk);
2569
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002570 clk_put(pce_dev->ce_clk);
2571 clk_put(pce_dev->ce_core_clk);
2572
Mona Hossain3b574d82011-09-01 15:02:01 -07002573 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2574 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002575 kfree(handle);
2576
2577 return 0;
2578}
2579EXPORT_SYMBOL(qce_close);
2580
2581int qce_hw_support(void *handle, struct ce_hw_support *ce_support)
2582{
2583 if (ce_support == NULL)
2584 return -EINVAL;
2585
2586 ce_support->sha1_hmac_20 = false;
2587 ce_support->sha1_hmac = false;
2588 ce_support->sha256_hmac = false;
2589 ce_support->sha_hmac = false;
2590 ce_support->cmac = true;
2591 ce_support->aes_key_192 = false;
2592 ce_support->aes_xts = true;
2593 ce_support->aes_ccm = true;
2594 ce_support->ota = false;
2595 return 0;
2596}
2597EXPORT_SYMBOL(qce_hw_support);
2598
2599MODULE_LICENSE("GPL v2");
2600MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
2601MODULE_DESCRIPTION("Crypto Engine driver");
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002602MODULE_VERSION("2.14");