blob: 0f5857af114d5d5509992946d2b22d7011727237 [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>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070028#include <crypto/hash.h>
29#include <crypto/sha.h>
30#include <mach/dma.h>
31#include <mach/clk.h>
Mona Hossain5c8ea1f2011-07-28 15:11:29 -070032
33#include "qce.h"
Mona Hossain3b574d82011-09-01 15:02:01 -070034#include "qce40.h"
Mona Hossain5c8ea1f2011-07-28 15:11:29 -070035#include "qcryptohw_40.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070036
37/* ADM definitions */
38#define LI_SG_CMD (1 << 31) /* last index in the scatter gather cmd */
39#define SRC_INDEX_SG_CMD(index) ((index & 0x3fff) << 16)
40#define DST_INDEX_SG_CMD(index) (index & 0x3fff)
41#define ADM_DESC_LAST (1 << 31)
Mona Hossain3b574d82011-09-01 15:02:01 -070042#define QCE_FIFO_SIZE 0x8000
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070043/*
44 * CE HW device structure.
45 * Each engine has an instance of the structure.
46 * Each engine can only handle one crypto operation at one time. It is up to
47 * the sw above to ensure single threading of operation on an engine.
48 */
49struct qce_device {
50 struct device *pdev; /* Handle to platform_device structure */
Mona Hossain3b574d82011-09-01 15:02:01 -070051
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070052 unsigned char *coh_vmem; /* Allocated coherent virtual memory */
53 dma_addr_t coh_pmem; /* Allocated coherent physical memory */
Mona Hossain3b574d82011-09-01 15:02:01 -070054 int memsize; /* Memory allocated */
55
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070056 void __iomem *iobase; /* Virtual io base of CE HW */
57 unsigned int phy_iobase; /* Physical io base of CE HW */
Mona Hossain3b574d82011-09-01 15:02:01 -070058
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070059 struct clk *ce_core_clk; /* Handle to CE clk */
60 struct clk *ce_clk; /* Handle to CE clk */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070061
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070062 qce_comp_func_ptr_t qce_cb; /* qce callback function pointer */
63
64 int assoc_nents;
65 int ivsize;
66 int authsize;
67 int src_nents;
68 int dst_nents;
69
70 void *areq;
71 enum qce_cipher_mode_enum mode;
Mona Hossain3b574d82011-09-01 15:02:01 -070072 struct ce_dm_data ce_dm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070073};
74
75/* Standard initialization vector for SHA-1, source: FIPS 180-2 */
Mona Hossain3b574d82011-09-01 15:02:01 -070076static uint8_t _std_init_vector_sha1_uint8[] = {
77 0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89,
78 0x98, 0xBA, 0xDC, 0xFE, 0x10, 0x32, 0x54, 0x76,
79 0xC3, 0xD2, 0xE1, 0xF0
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070080};
Mona Hossain3b574d82011-09-01 15:02:01 -070081
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070082/* Standard initialization vector for SHA-256, source: FIPS 180-2 */
Mona Hossain3b574d82011-09-01 15:02:01 -070083static uint8_t _std_init_vector_sha256_uint8[] = {
84 0x6A, 0x09, 0xE6, 0x67, 0xBB, 0x67, 0xAE, 0x85,
85 0x3C, 0x6E, 0xF3, 0x72, 0xA5, 0x4F, 0xF5, 0x3A,
86 0x51, 0x0E, 0x52, 0x7F, 0x9B, 0x05, 0x68, 0x8C,
87 0x1F, 0x83, 0xD9, 0xAB, 0x5B, 0xE0, 0xCD, 0x19
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070088};
89
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070090static void _byte_stream_swap_to_net_words(uint32_t *iv, unsigned char *b,
91 unsigned int len)
92{
93 unsigned i, j;
94 unsigned char swap_iv[AES_IV_LENGTH];
95
96 memset(swap_iv, 0, AES_IV_LENGTH);
97 for (i = (AES_IV_LENGTH-len), j = len-1; i < AES_IV_LENGTH; i++, j--)
98 swap_iv[i] = b[j];
Mona Hossain3b574d82011-09-01 15:02:01 -070099 memcpy(iv, swap_iv, AES_IV_LENGTH);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700100}
101
102static int count_sg(struct scatterlist *sg, int nbytes)
103{
104 int i;
105
106 for (i = 0; nbytes > 0; i++, sg = sg_next(sg))
107 nbytes -= sg->length;
108 return i;
109}
110
111static int dma_map_pmem_sg(struct buf_info *pmem, unsigned entries,
112 struct scatterlist *sg)
113{
114 int i;
115 for (i = 0; i < entries; i++) {
116
117 sg->dma_address = (dma_addr_t)pmem->offset;
118 sg++;
119 pmem++;
120 }
121 return 0;
122}
123
124static int _probe_ce_engine(struct qce_device *pce_dev)
125{
126 unsigned int val;
127 unsigned int rev;
128
Mona Hossain3b574d82011-09-01 15:02:01 -0700129 val = (uint32_t)(*((uint32_t *)pce_dev->ce_dm.buffer.version));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700130 if (((val & 0xfffffff) != 0x0000042) &&
131 ((val & 0xfffffff) != 0x0000040)) {
132 dev_err(pce_dev->pdev,
133 "Unknown Qualcomm crypto device at 0x%x 0x%x\n",
134 pce_dev->phy_iobase, val);
135 return -EIO;
136 };
137 rev = (val & CRYPTO_CORE_REV_MASK);
138 if (rev == 0x42) {
139 dev_info(pce_dev->pdev,
140 "Qualcomm Crypto 4.2 device found at 0x%x\n",
141 pce_dev->phy_iobase);
142 } else {
143 if (rev == 0x40) {
144 dev_info(pce_dev->pdev,
145 "Qualcomm Crypto 4.0 device found at 0x%x\n",
146 pce_dev->phy_iobase);
147 }
148 }
149
150 dev_info(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -0700151 "IO base 0x%x\n, ce_in channel %d , "
152 "ce_out channel %d\n, "
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700153 "crci_in %d, crci_out %d\n",
154 (unsigned int) pce_dev->iobase,
Mona Hossain3b574d82011-09-01 15:02:01 -0700155 pce_dev->ce_dm.chan_ce_in, pce_dev->ce_dm.chan_ce_out,
156 pce_dev->ce_dm.crci_in, pce_dev->ce_dm.crci_out);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700157
158 return 0;
159};
160
Mona Hossain3b574d82011-09-01 15:02:01 -0700161
162static void _check_probe_done_call_back(struct msm_dmov_cmd *cmd_ptr,
163 unsigned int result, struct msm_dmov_errdata *err)
164{
165 struct qce_device *pce_dev;
166 pce_dev = (struct qce_device *) cmd_ptr->user;
167
168 if (result != ADM_STATUS_OK) {
169 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
170 result);
171 pce_dev->ce_dm.chan_ce_in_status = -1;
172 } else {
173 _probe_ce_engine(pce_dev);
174 pce_dev->ce_dm.chan_ce_in_status = 0;
175 }
176 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
177};
178
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700179static int _init_ce_engine(struct qce_device *pce_dev)
180{
181 unsigned int val;
182
183 /* Reset ce */
184 clk_reset(pce_dev->ce_core_clk, CLK_RESET_ASSERT);
185 clk_reset(pce_dev->ce_core_clk, CLK_RESET_DEASSERT);
186 /*
187 * Ensure previous instruction (any writes to CLK registers)
188 * to toggle the CLK reset lines was completed.
189 */
190 dsb();
191 /* configure ce */
192 val = (1 << CRYPTO_MASK_DOUT_INTR) | (1 << CRYPTO_MASK_DIN_INTR) |
193 (1 << CRYPTO_MASK_OP_DONE_INTR) |
194 (1 << CRYPTO_MASK_ERR_INTR);
195 writel_relaxed(val, pce_dev->iobase + CRYPTO_CONFIG_REG);
196 /*
197 * Ensure previous instruction (writel_relaxed to config register bit)
198 * was completed.
199 */
200 dsb();
Mona Hossain3b574d82011-09-01 15:02:01 -0700201
202 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
203 _check_probe_done_call_back;
204 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
205 pce_dev->ce_dm.cmdptrlist.probe_ce_hw;
206 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
207 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
208 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
209 pce_dev->ce_dm.chan_ce_in_cmd);
210
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700211 return 0;
212};
213
Mona Hossain3b574d82011-09-01 15:02:01 -0700214static int _ce_setup_hash_cmdrptrlist(struct qce_device *pce_dev,
215 struct qce_sha_req *sreq)
216{
217 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
218
219 switch (sreq->alg) {
220 case QCE_HASH_SHA1:
221 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr = cmdptrlist->auth_sha1;
222 break;
223
224 case QCE_HASH_SHA256:
225 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr = cmdptrlist->auth_sha256;
226 break;
227 case QCE_HASH_SHA1_HMAC:
228 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
229 cmdptrlist->auth_sha1_hmac;
230 break;
231
232 case QCE_HASH_SHA256_HMAC:
233 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
234 cmdptrlist->auth_sha256_hmac;
235 break;
236 case QCE_HASH_AES_CMAC:
237 if (sreq->authklen == AES128_KEY_SIZE)
238 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
239 cmdptrlist->auth_aes_128_cmac;
240 else
241 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
242 cmdptrlist->auth_aes_256_cmac;
243 break;
244
245 default:
246 break;
247 }
248
249 return 0;
250}
251
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700252static int _ce_setup_hash(struct qce_device *pce_dev, struct qce_sha_req *sreq)
253{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700254 uint32_t diglen;
255 int i;
256 uint32_t auth_cfg = 0;
257 bool sha1 = false;
258
259 if (sreq->alg == QCE_HASH_AES_CMAC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700260
Mona Hossain3b574d82011-09-01 15:02:01 -0700261 memcpy(pce_dev->ce_dm.buffer.auth_key, sreq->authkey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700262 sreq->authklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700263 auth_cfg |= (1 << CRYPTO_LAST);
264 auth_cfg |= (CRYPTO_AUTH_MODE_CMAC << CRYPTO_AUTH_MODE);
265 auth_cfg |= (CRYPTO_AUTH_SIZE_ENUM_16_BYTES <<
266 CRYPTO_AUTH_SIZE);
267 auth_cfg |= CRYPTO_AUTH_ALG_AES << CRYPTO_AUTH_ALG;
268
269 switch (sreq->authklen) {
270 case AES128_KEY_SIZE:
271 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES128 <<
272 CRYPTO_AUTH_KEY_SIZE);
273 break;
274 case AES256_KEY_SIZE:
275 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES256 <<
276 CRYPTO_AUTH_KEY_SIZE);
277 break;
278 default:
279 break;
280 }
281
282 goto go_proc;
283 }
284
285 /* if not the last, the size has to be on the block boundary */
286 if (sreq->last_blk == 0 && (sreq->size % SHA256_BLOCK_SIZE))
287 return -EIO;
288
289 switch (sreq->alg) {
290 case QCE_HASH_SHA1:
291 case QCE_HASH_SHA1_HMAC:
292 diglen = SHA1_DIGEST_SIZE;
293 sha1 = true;
294 break;
295 case QCE_HASH_SHA256:
296 case QCE_HASH_SHA256_HMAC:
297 diglen = SHA256_DIGEST_SIZE;
298 break;
299 default:
300 return -EINVAL;
301 }
302
303 if ((sreq->alg == QCE_HASH_SHA1_HMAC) ||
304 (sreq->alg == QCE_HASH_SHA256_HMAC)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700305
Mona Hossain3b574d82011-09-01 15:02:01 -0700306 memcpy(pce_dev->ce_dm.buffer.auth_key, sreq->authkey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700307 sreq->authklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700308 auth_cfg |= (CRYPTO_AUTH_MODE_HMAC << CRYPTO_AUTH_MODE);
309 } else {
310 auth_cfg |= (CRYPTO_AUTH_MODE_HASH << CRYPTO_AUTH_MODE);
311 }
312
313 /* write 20/32 bytes, 5/8 words into auth_iv for SHA1/SHA256 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700314 if (sreq->first_blk) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700315 if (sha1)
316 memcpy(pce_dev->ce_dm.buffer.auth_iv,
317 _std_init_vector_sha1_uint8, diglen);
318 else
319 memcpy(pce_dev->ce_dm.buffer.auth_iv,
320 _std_init_vector_sha256_uint8, diglen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700321 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700322 memcpy(pce_dev->ce_dm.buffer.auth_iv, sreq->digest,
323 diglen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700324 }
325
Mona Hossain3b574d82011-09-01 15:02:01 -0700326 /* write auth_bytecnt 0/1/2/3, start with 0 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700327 for (i = 0; i < 4; i++)
Mona Hossain3b574d82011-09-01 15:02:01 -0700328 *(((uint32_t *)(pce_dev->ce_dm.buffer.auth_byte_count) + i)) =
329 sreq->auth_data[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700330
331 /* write seg_cfg */
332 if (sha1)
333 auth_cfg |= (CRYPTO_AUTH_SIZE_SHA1 << CRYPTO_AUTH_SIZE);
334 else
335 auth_cfg |= (CRYPTO_AUTH_SIZE_SHA256 << CRYPTO_AUTH_SIZE);
336
337 if (sreq->last_blk)
338 auth_cfg |= 1 << CRYPTO_LAST;
339
340 auth_cfg |= CRYPTO_AUTH_ALG_SHA << CRYPTO_AUTH_ALG;
341
342go_proc:
343 auth_cfg |= (CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);
344
Mona Hossain3b574d82011-09-01 15:02:01 -0700345 /* write auth seg cfg */
346 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start)) =
347 auth_cfg;
348 /* write auth seg size */
349 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start) + 1) =
350 sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700351
Mona Hossain3b574d82011-09-01 15:02:01 -0700352 /* write auth seg size start*/
353 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start)+2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700354
Mona Hossain3b574d82011-09-01 15:02:01 -0700355 /* write seg size */
356 *((uint32_t *)(pce_dev->ce_dm.buffer.seg_size)) = sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700357
Mona Hossain3b574d82011-09-01 15:02:01 -0700358 _ce_setup_hash_cmdrptrlist(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700359
Mona Hossain3b574d82011-09-01 15:02:01 -0700360 return 0;
361}
362
363static int _ce_setup_cipher_cmdrptrlist(struct qce_device *pce_dev,
364 struct qce_req *creq)
365{
366 struct ce_cmdptrlists_ops *cmdptrlist =
367 &pce_dev->ce_dm.cmdptrlist;
368
369 if (creq->alg != CIPHER_ALG_AES) {
370 switch (creq->alg) {
371 case CIPHER_ALG_DES:
372 if (creq->mode == QCE_MODE_ECB) {
373 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
374 cmdptrlist->cipher_des_ecb;
375 } else {
376 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
377 cmdptrlist->cipher_des_cbc;
378 }
379 break;
380
381 case CIPHER_ALG_3DES:
382 if (creq->mode == QCE_MODE_ECB) {
383 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
384 cmdptrlist->cipher_3des_ecb;
385 } else {
386 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
387 cmdptrlist->cipher_3des_cbc;
388 }
389 break;
390 default:
391 break;
392 }
393 } else {
394 switch (creq->mode) {
395 case QCE_MODE_ECB:
396 if (creq->encklen == AES128_KEY_SIZE) {
397 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
398 cmdptrlist->cipher_aes_128_ecb;
399 } else {
400 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
401 cmdptrlist->cipher_aes_256_ecb;
402 }
403 break;
404
405 case QCE_MODE_CBC:
406 if (creq->encklen == AES128_KEY_SIZE) {
407 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
408 cmdptrlist->cipher_aes_128_cbc_ctr;
409 } else {
410 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
411 cmdptrlist->cipher_aes_256_cbc_ctr;
412 }
413 break;
414
415 case QCE_MODE_CTR:
416 if (creq->encklen == AES128_KEY_SIZE) {
417 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
418 cmdptrlist->cipher_aes_128_cbc_ctr;
419 } else {
420 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
421 cmdptrlist->cipher_aes_256_cbc_ctr;
422 }
423 break;
424
425 case QCE_MODE_XTS:
426 if (creq->encklen == AES128_KEY_SIZE) {
427 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
428 cmdptrlist->cipher_aes_128_xts;
429 } else {
430 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
431 cmdptrlist->cipher_aes_256_xts;
432 }
433 break;
434 case QCE_MODE_CCM:
435 if (creq->encklen == AES128_KEY_SIZE) {
436 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
437 cmdptrlist->aead_aes_128_ccm;
438 } else {
439 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
440 cmdptrlist->aead_aes_256_ccm;
441 }
442 break;
443 default:
444 break;
445 }
446 }
447
448 if (creq->mode == QCE_MODE_CCM)
449 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
450 cmdptrlist->aead_ce_out;
451 else
452 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
453 cmdptrlist->cipher_ce_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700454
455 return 0;
456}
457
458static int _ce_setup_cipher(struct qce_device *pce_dev, struct qce_req *creq,
459 uint32_t totallen_in, uint32_t coffset)
460{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700461 uint32_t enck_size_in_word = creq->encklen / sizeof(uint32_t);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700462 uint32_t encr_cfg = 0;
463 uint32_t ivsize = creq->ivsize;
Mona Hossain3b574d82011-09-01 15:02:01 -0700464 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700465
466 if (creq->mode == QCE_MODE_XTS)
Mona Hossain3b574d82011-09-01 15:02:01 -0700467 memcpy(buffer->encr_key, creq->enckey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700468 creq->encklen/2);
469 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700470 memcpy(buffer->encr_key, creq->enckey, creq->encklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700471
472 if ((creq->op == QCE_REQ_AEAD) && (creq->mode == QCE_MODE_CCM)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700473 uint32_t noncelen32 = MAX_NONCE/sizeof(uint32_t);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700474 uint32_t auth_cfg = 0;
475
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700476 /* write nonce */
Mona Hossain3b574d82011-09-01 15:02:01 -0700477 memcpy(buffer->auth_nonce_info, creq->nonce, MAX_NONCE);
478 memcpy(buffer->auth_key, creq->enckey, creq->encklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700479
480 auth_cfg |= (noncelen32 << CRYPTO_AUTH_NONCE_NUM_WORDS);
481 auth_cfg &= ~(1 << CRYPTO_USE_HW_KEY_AUTH);
482 auth_cfg |= (1 << CRYPTO_LAST);
483 if (creq->dir == QCE_ENCRYPT)
484 auth_cfg |= (CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);
485 else
486 auth_cfg |= (CRYPTO_AUTH_POS_AFTER << CRYPTO_AUTH_POS);
487 auth_cfg |= (((creq->authsize >> 1) - 2) << CRYPTO_AUTH_SIZE);
488 auth_cfg |= (CRYPTO_AUTH_MODE_CCM << CRYPTO_AUTH_MODE);
489 if (creq->authklen == AES128_KEY_SIZE)
490 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES128 <<
491 CRYPTO_AUTH_KEY_SIZE);
492 else {
493 if (creq->authklen == AES256_KEY_SIZE)
494 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES256 <<
495 CRYPTO_AUTH_KEY_SIZE);
496 }
497 auth_cfg |= (CRYPTO_AUTH_ALG_AES << CRYPTO_AUTH_ALG);
Mona Hossain3b574d82011-09-01 15:02:01 -0700498 *((uint32_t *)(buffer->auth_seg_cfg_size_start)) = auth_cfg;
499
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700500 if (creq->dir == QCE_ENCRYPT)
Mona Hossain3b574d82011-09-01 15:02:01 -0700501 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 1) =
502 totallen_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700503 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700504 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 1) =
505 (totallen_in - creq->authsize);
506 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700507 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700508
509 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700510
511 switch (creq->mode) {
512 case QCE_MODE_ECB:
513 encr_cfg |= (CRYPTO_ENCR_MODE_ECB << CRYPTO_ENCR_MODE);
514 break;
515
516 case QCE_MODE_CBC:
517 encr_cfg |= (CRYPTO_ENCR_MODE_CBC << CRYPTO_ENCR_MODE);
518 break;
519
520 case QCE_MODE_XTS:
521 encr_cfg |= (CRYPTO_ENCR_MODE_XTS << CRYPTO_ENCR_MODE);
522 break;
523
524 case QCE_MODE_CCM:
525 encr_cfg |= (CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE);
526 break;
527
528 case QCE_MODE_CTR:
529 default:
530 encr_cfg |= (CRYPTO_ENCR_MODE_CTR << CRYPTO_ENCR_MODE);
531 break;
532 }
533 pce_dev->mode = creq->mode;
534
535 switch (creq->alg) {
536 case CIPHER_ALG_DES:
Mona Hossain3b574d82011-09-01 15:02:01 -0700537 if (creq->mode != QCE_MODE_ECB)
538 memcpy(buffer->encr_cntr_iv, creq->iv, ivsize);
539
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700540 encr_cfg |= ((CRYPTO_ENCR_KEY_SZ_DES << CRYPTO_ENCR_KEY_SZ) |
541 (CRYPTO_ENCR_ALG_DES << CRYPTO_ENCR_ALG));
542 break;
543
544 case CIPHER_ALG_3DES:
Mona Hossain3b574d82011-09-01 15:02:01 -0700545 if (creq->mode != QCE_MODE_ECB)
546 memcpy(buffer->encr_cntr_iv, creq->iv, ivsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700547
548 encr_cfg |= ((CRYPTO_ENCR_KEY_SZ_3DES << CRYPTO_ENCR_KEY_SZ) |
549 (CRYPTO_ENCR_ALG_DES << CRYPTO_ENCR_ALG));
550 break;
551
552 case CIPHER_ALG_AES:
553 default:
554 if (creq->mode == QCE_MODE_XTS) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700555 memcpy(buffer->encr_xts_key, (creq->enckey +
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700556 creq->encklen/2), creq->encklen/2);
Mona Hossain3b574d82011-09-01 15:02:01 -0700557 *((uint32_t *)(buffer->encr_xts_du_size)) =
558 creq->cryptlen;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700559
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700560 }
561 if (creq->mode != QCE_MODE_ECB) {
562 if (creq->mode == QCE_MODE_XTS)
Mona Hossain3b574d82011-09-01 15:02:01 -0700563 _byte_stream_swap_to_net_words(
564 (uint32_t *)(buffer->encr_cntr_iv),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700565 creq->iv, ivsize);
566 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700567 memcpy(buffer->encr_cntr_iv, creq->iv,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700568 ivsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700569 }
570 /* set number of counter bits */
Mona Hossain3b574d82011-09-01 15:02:01 -0700571 *((uint32_t *)(buffer->encr_mask)) = (uint32_t)0xffffffff;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700572
573 if (creq->op == QCE_REQ_ABLK_CIPHER_NO_KEY) {
574 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES128 <<
575 CRYPTO_ENCR_KEY_SZ);
576 encr_cfg |= CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG;
577 } else {
578 uint32_t key_size;
579
580 if (creq->mode == QCE_MODE_XTS) {
581 key_size = creq->encklen/2;
582 enck_size_in_word = key_size/sizeof(uint32_t);
583 } else {
584 key_size = creq->encklen;
585 }
586
587 switch (key_size) {
588 case AES128_KEY_SIZE:
589 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES128 <<
590 CRYPTO_ENCR_KEY_SZ);
591 break;
592 case AES256_KEY_SIZE:
593 default:
594 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES256 <<
595 CRYPTO_ENCR_KEY_SZ);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700596 break;
597 } /* end of switch (creq->encklen) */
598
599 encr_cfg |= CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700600 } /* else of if (creq->op == QCE_REQ_ABLK_CIPHER_NO_KEY) */
601 break;
602 } /* end of switch (creq->mode) */
603
604 /* write encr seg cfg */
605 encr_cfg |= ((creq->dir == QCE_ENCRYPT) ? 1 : 0) << CRYPTO_ENCODE;
606
607 /* write encr seg cfg */
Mona Hossain3b574d82011-09-01 15:02:01 -0700608 *((uint32_t *)(buffer->encr_seg_cfg_size_start)) = encr_cfg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700609 /* write encr seg size */
610 if ((creq->mode == QCE_MODE_CCM) && (creq->dir == QCE_DECRYPT))
Mona Hossain3b574d82011-09-01 15:02:01 -0700611 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 1) =
612 (creq->cryptlen + creq->authsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700613 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700614 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 1) =
615 creq->cryptlen;
616
617
618 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 2) =
619 (coffset & 0xffff);
620
621 *((uint32_t *)(buffer->seg_size)) = totallen_in;
622
623 _ce_setup_cipher_cmdrptrlist(pce_dev, creq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700624 return 0;
625};
626
627static int _aead_complete(struct qce_device *pce_dev)
628{
629 struct aead_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700630
631 areq = (struct aead_request *) pce_dev->areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700632
633 if (areq->src != areq->dst) {
634 dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
635 DMA_FROM_DEVICE);
636 }
637 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
638 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
639 DMA_TO_DEVICE);
640
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700641 dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
642 DMA_TO_DEVICE);
643
Mona Hossain3b574d82011-09-01 15:02:01 -0700644 /* check MAC */
645 if (pce_dev->mode == QCE_MODE_CCM) {
646 uint32_t result;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700647
Mona Hossain3b574d82011-09-01 15:02:01 -0700648 result =
649 (uint32_t)(*((uint32_t *)pce_dev->ce_dm.buffer.status));
650 result &= (1 << CRYPTO_MAC_FAILED);
651 result |= (pce_dev->ce_dm.chan_ce_in_status |
652 pce_dev->ce_dm.chan_ce_out_status);
653 pce_dev->qce_cb(areq, pce_dev->ce_dm.buffer.auth_result, NULL,
654 result);
655 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700656 return 0;
657};
658
659static void _sha_complete(struct qce_device *pce_dev)
660{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700661 struct ahash_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700662
663 areq = (struct ahash_request *) pce_dev->areq;
664 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
665 DMA_TO_DEVICE);
666
Mona Hossain3b574d82011-09-01 15:02:01 -0700667 pce_dev->qce_cb(areq, pce_dev->ce_dm.buffer.auth_result,
668 pce_dev->ce_dm.buffer.auth_byte_count,
669 pce_dev->ce_dm.chan_ce_in_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700670
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700671};
672
673static int _ablk_cipher_complete(struct qce_device *pce_dev)
674{
675 struct ablkcipher_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700676
677 areq = (struct ablkcipher_request *) pce_dev->areq;
678
679 if (areq->src != areq->dst) {
680 dma_unmap_sg(pce_dev->pdev, areq->dst,
681 pce_dev->dst_nents, DMA_FROM_DEVICE);
682 }
683 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
684 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
685 DMA_TO_DEVICE);
Mona Hossain3b574d82011-09-01 15:02:01 -0700686
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700687 if (pce_dev->mode == QCE_MODE_ECB) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700688 pce_dev->qce_cb(areq, NULL, NULL,
689 pce_dev->ce_dm.chan_ce_in_status |
690 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700691 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700692
Mona Hossain3b574d82011-09-01 15:02:01 -0700693 pce_dev->qce_cb(areq, NULL, pce_dev->ce_dm.buffer.encr_cntr_iv,
694 pce_dev->ce_dm.chan_ce_in_status |
695 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700696 }
697
698 return 0;
699};
700
701static int _ablk_cipher_use_pmem_complete(struct qce_device *pce_dev)
702{
703 struct ablkcipher_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700704
705 areq = (struct ablkcipher_request *) pce_dev->areq;
706
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700707 if (pce_dev->mode == QCE_MODE_ECB) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700708 pce_dev->qce_cb(areq, NULL, NULL,
709 pce_dev->ce_dm.chan_ce_in_status |
710 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700711 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700712 pce_dev->qce_cb(areq, NULL, pce_dev->ce_dm.buffer.encr_cntr_iv,
713 pce_dev->ce_dm.chan_ce_in_status |
714 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700715 }
716
717 return 0;
718};
719
720static int qce_split_and_insert_dm_desc(struct dmov_desc *pdesc,
721 unsigned int plen, unsigned int paddr, int *index)
722{
Mona Hossain3b574d82011-09-01 15:02:01 -0700723 while (plen > QCE_FIFO_SIZE) {
724 pdesc->len = QCE_FIFO_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700725 if (paddr > 0) {
726 pdesc->addr = paddr;
Mona Hossain3b574d82011-09-01 15:02:01 -0700727 paddr += QCE_FIFO_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700728 }
729 plen -= pdesc->len;
730 if (plen > 0) {
731 *index = (*index) + 1;
732 if ((*index) >= QCE_MAX_NUM_DESC)
733 return -ENOMEM;
734 pdesc++;
735 }
736 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700737 if ((plen > 0) && (plen <= QCE_FIFO_SIZE)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700738 pdesc->len = plen;
739 if (paddr > 0)
740 pdesc->addr = paddr;
741 }
742
743 return 0;
744}
745
746static int _chain_sg_buffer_in(struct qce_device *pce_dev,
747 struct scatterlist *sg, unsigned int nbytes)
748{
749 unsigned int len;
750 unsigned int dlen;
751 struct dmov_desc *pdesc;
752
Mona Hossain3b574d82011-09-01 15:02:01 -0700753 pdesc = pce_dev->ce_dm.ce_in_dst_desc +
754 pce_dev->ce_dm.ce_in_dst_desc_index;
755 if (nbytes > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700756 qce_split_and_insert_dm_desc(pdesc, nbytes, 0,
Mona Hossain3b574d82011-09-01 15:02:01 -0700757 &pce_dev->ce_dm.ce_in_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700758 else
759 pdesc->len = nbytes;
760
Mona Hossain3b574d82011-09-01 15:02:01 -0700761 pdesc = pce_dev->ce_dm.ce_in_src_desc +
762 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700763 /*
764 * Two consective chunks may be handled by the old
765 * buffer descriptor.
766 */
767 while (nbytes > 0) {
768 len = min(nbytes, sg_dma_len(sg));
769 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
770 nbytes -= len;
771 if (dlen == 0) {
772 pdesc->addr = sg_dma_address(sg);
773 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700774 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700775 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700776 sg_dma_address(sg),
777 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700778 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
779 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700780 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700781 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700782 pdesc->addr,
783 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700784 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700785 pce_dev->ce_dm.ce_in_src_desc_index++;
786 if (pce_dev->ce_dm.ce_in_src_desc_index >=
787 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700788 return -ENOMEM;
789 pdesc++;
790 pdesc->len = len;
791 pdesc->addr = sg_dma_address(sg);
Mona Hossain3b574d82011-09-01 15:02:01 -0700792 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700793 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700794 sg_dma_address(sg),
795 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700796 }
797 if (nbytes > 0)
798 sg = sg_next(sg);
799 }
800 return 0;
801}
802
803static int _chain_pm_buffer_in(struct qce_device *pce_dev,
804 unsigned int pmem, unsigned int nbytes)
805{
806 unsigned int dlen;
807 struct dmov_desc *pdesc;
808
Mona Hossain3b574d82011-09-01 15:02:01 -0700809 pdesc = pce_dev->ce_dm.ce_in_src_desc +
810 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700811 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
812 if (dlen == 0) {
813 pdesc->addr = pmem;
814 pdesc->len = nbytes;
815 } else if (pmem == (pdesc->addr + dlen)) {
816 pdesc->len = dlen + nbytes;
817 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700818 pce_dev->ce_dm.ce_in_src_desc_index++;
819 if (pce_dev->ce_dm.ce_in_src_desc_index >=
820 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700821 return -ENOMEM;
822 pdesc++;
823 pdesc->len = nbytes;
824 pdesc->addr = pmem;
825 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700826 pdesc = pce_dev->ce_dm.ce_in_dst_desc +
827 pce_dev->ce_dm.ce_in_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700828 pdesc->len += nbytes;
829
830 return 0;
831}
832
833static void _chain_buffer_in_init(struct qce_device *pce_dev)
834{
835 struct dmov_desc *pdesc;
836
Mona Hossain3b574d82011-09-01 15:02:01 -0700837 pce_dev->ce_dm.ce_in_src_desc_index = 0;
838 pce_dev->ce_dm.ce_in_dst_desc_index = 0;
839 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700840 pdesc->len = 0;
841}
842
843static void _ce_in_final(struct qce_device *pce_dev, unsigned total)
844{
845 struct dmov_desc *pdesc;
846 dmov_sg *pcmd;
847
Mona Hossain3b574d82011-09-01 15:02:01 -0700848 pdesc = pce_dev->ce_dm.ce_in_src_desc +
849 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700850 pdesc->len |= ADM_DESC_LAST;
Mona Hossain3b574d82011-09-01 15:02:01 -0700851 pdesc = pce_dev->ce_dm.ce_in_dst_desc +
852 pce_dev->ce_dm.ce_in_dst_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -0700853 if (total)
854 pdesc->len = ADM_DESC_LAST | total;
855 else
856 pdesc->len |= ADM_DESC_LAST;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700857
Mona Hossain3b574d82011-09-01 15:02:01 -0700858 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700859 pcmd->cmd |= CMD_LC;
Mona Hossain3b574d82011-09-01 15:02:01 -0700860
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700861}
862
863#ifdef QCE_DEBUG
864static void _ce_in_dump(struct qce_device *pce_dev)
865{
866 int i;
867 struct dmov_desc *pdesc;
868
869 dev_info(pce_dev->pdev, "_ce_in_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700870 for (i = 0; i <= pce_dev->ce_dm.ce_in_src_desc_index; i++) {
871 pdesc = pce_dev->ce_dm.ce_in_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700872 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
873 pdesc->len);
874 }
875 dev_info(pce_dev->pdev, "_ce_in_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700876 for (i = 0; i <= pce_dev->ce_dm.ce_in_dst_desc_index; i++) {
877 pdesc = pce_dev->ce_dm.ce_in_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700878 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
879 pdesc->len);
880 }
881};
882
883static void _ce_out_dump(struct qce_device *pce_dev)
884{
885 int i;
886 struct dmov_desc *pdesc;
887
888 dev_info(pce_dev->pdev, "_ce_out_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700889 for (i = 0; i <= pce_dev->ce_dm.ce_out_src_desc_index; i++) {
890 pdesc = pce_dev->ce_dm.ce_out_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700891 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
892 pdesc->len);
893 }
894
895 dev_info(pce_dev->pdev, "_ce_out_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700896 for (i = 0; i <= pce_dev->ce_dm.ce_out_dst_desc_index; i++) {
897 pdesc = pce_dev->ce_dm.ce_out_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700898 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
899 pdesc->len);
900 }
901};
902
903#else
904
905static void _ce_in_dump(struct qce_device *pce_dev)
906{
907};
908
909static void _ce_out_dump(struct qce_device *pce_dev)
910{
911};
912
913#endif
914
915static int _chain_sg_buffer_out(struct qce_device *pce_dev,
916 struct scatterlist *sg, unsigned int nbytes)
917{
918 unsigned int len;
919 unsigned int dlen;
920 struct dmov_desc *pdesc;
921
Mona Hossain3b574d82011-09-01 15:02:01 -0700922 pdesc = pce_dev->ce_dm.ce_out_src_desc +
923 pce_dev->ce_dm.ce_out_src_desc_index;
924 if (nbytes > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700925 qce_split_and_insert_dm_desc(pdesc, nbytes, 0,
Mona Hossain3b574d82011-09-01 15:02:01 -0700926 &pce_dev->ce_dm.ce_out_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700927 else
928 pdesc->len = nbytes;
929
Mona Hossain3b574d82011-09-01 15:02:01 -0700930 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
931 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700932 /*
933 * Two consective chunks may be handled by the old
934 * buffer descriptor.
935 */
936 while (nbytes > 0) {
937 len = min(nbytes, sg_dma_len(sg));
938 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
939 nbytes -= len;
940 if (dlen == 0) {
941 pdesc->addr = sg_dma_address(sg);
942 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700943 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700944 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
945 sg_dma_address(sg),
Mona Hossain3b574d82011-09-01 15:02:01 -0700946 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700947 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
948 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700949 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700950 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
951 pdesc->addr,
Mona Hossain3b574d82011-09-01 15:02:01 -0700952 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700953
954 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700955 pce_dev->ce_dm.ce_out_dst_desc_index++;
956 if (pce_dev->ce_dm.ce_out_dst_desc_index >=
957 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700958 return -EIO;
959 pdesc++;
960 pdesc->len = len;
961 pdesc->addr = sg_dma_address(sg);
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 sg_dma_address(sg),
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 }
968 if (nbytes > 0)
969 sg = sg_next(sg);
970 }
971 return 0;
972}
973
974static int _chain_pm_buffer_out(struct qce_device *pce_dev,
975 unsigned int pmem, unsigned int nbytes)
976{
977 unsigned int dlen;
978 struct dmov_desc *pdesc;
979
Mona Hossain3b574d82011-09-01 15:02:01 -0700980 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
981 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700982 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
983
984 if (dlen == 0) {
985 pdesc->addr = pmem;
986 pdesc->len = nbytes;
987 } else if (pmem == (pdesc->addr + dlen)) {
988 pdesc->len = dlen + nbytes;
989 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700990 pce_dev->ce_dm.ce_out_dst_desc_index++;
991 if (pce_dev->ce_dm.ce_out_dst_desc_index >= QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700992 return -EIO;
993 pdesc++;
994 pdesc->len = nbytes;
995 pdesc->addr = pmem;
996 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700997 pdesc = pce_dev->ce_dm.ce_out_src_desc +
998 pce_dev->ce_dm.ce_out_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700999 pdesc->len += nbytes;
1000
1001 return 0;
1002};
1003
1004static void _chain_buffer_out_init(struct qce_device *pce_dev)
1005{
1006 struct dmov_desc *pdesc;
1007
Mona Hossain3b574d82011-09-01 15:02:01 -07001008 pce_dev->ce_dm.ce_out_dst_desc_index = 0;
1009 pce_dev->ce_dm.ce_out_src_desc_index = 0;
1010 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001011 pdesc->len = 0;
1012};
1013
1014static void _ce_out_final(struct qce_device *pce_dev, unsigned total)
1015{
1016 struct dmov_desc *pdesc;
1017 dmov_sg *pcmd;
1018
Mona Hossain3b574d82011-09-01 15:02:01 -07001019 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
1020 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001021 pdesc->len |= ADM_DESC_LAST;
Mona Hossain3b574d82011-09-01 15:02:01 -07001022 pdesc = pce_dev->ce_dm.ce_out_src_desc +
1023 pce_dev->ce_dm.ce_out_src_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -07001024 if (total)
1025 pdesc->len = ADM_DESC_LAST | total;
1026 else
1027 pdesc->len |= ADM_DESC_LAST;
Mona Hossain3b574d82011-09-01 15:02:01 -07001028
1029 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001030 pcmd->cmd |= CMD_LC;
1031};
1032
1033static void _aead_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1034 unsigned int result, struct msm_dmov_errdata *err)
1035{
1036 struct qce_device *pce_dev;
1037
1038 pce_dev = (struct qce_device *) cmd_ptr->user;
1039 if (result != ADM_STATUS_OK) {
1040 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1041 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001042 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001043 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001044 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001045 }
1046
Mona Hossain3b574d82011-09-01 15:02:01 -07001047 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1048 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1049 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1050 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001051
1052 /* done */
1053 _aead_complete(pce_dev);
1054 }
1055};
1056
1057static void _aead_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1058 unsigned int result, struct msm_dmov_errdata *err)
1059{
1060 struct qce_device *pce_dev;
1061
1062 pce_dev = (struct qce_device *) cmd_ptr->user;
1063 if (result != ADM_STATUS_OK) {
1064 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1065 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001066 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001067 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001068 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001069 };
1070
Mona Hossain3b574d82011-09-01 15:02:01 -07001071 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1072 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1073 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1074 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001075
1076 /* done */
1077 _aead_complete(pce_dev);
1078 }
1079
1080};
1081
1082static void _sha_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1083 unsigned int result, struct msm_dmov_errdata *err)
1084{
1085 struct qce_device *pce_dev;
1086
1087 pce_dev = (struct qce_device *) cmd_ptr->user;
1088 if (result != ADM_STATUS_OK) {
1089 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1090 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001091 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001092 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001093 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001094 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001095 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001096 _sha_complete(pce_dev);
1097};
1098
1099static void _ablk_cipher_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1100 unsigned int result, struct msm_dmov_errdata *err)
1101{
1102 struct qce_device *pce_dev;
1103
1104 pce_dev = (struct qce_device *) cmd_ptr->user;
1105 if (result != ADM_STATUS_OK) {
1106 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1107 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001108 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001109 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001110 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001111 }
1112
Mona Hossain3b574d82011-09-01 15:02:01 -07001113 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1114 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1115 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1116 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001117
1118 /* done */
1119 _ablk_cipher_complete(pce_dev);
1120 }
1121};
1122
1123static void _ablk_cipher_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1124 unsigned int result, struct msm_dmov_errdata *err)
1125{
1126 struct qce_device *pce_dev;
1127
1128 pce_dev = (struct qce_device *) cmd_ptr->user;
Mona Hossain3b574d82011-09-01 15:02:01 -07001129
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001130 if (result != ADM_STATUS_OK) {
1131 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1132 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001133 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001134 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001135 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001136 };
1137
Mona Hossain3b574d82011-09-01 15:02:01 -07001138 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1139 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1140 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1141 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001142
1143 /* done */
1144 _ablk_cipher_complete(pce_dev);
1145 }
1146};
1147
1148
1149static void _ablk_cipher_ce_in_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1150 unsigned int result, struct msm_dmov_errdata *err)
1151{
1152 struct qce_device *pce_dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001153 pce_dev = (struct qce_device *) cmd_ptr->user;
1154 if (result != ADM_STATUS_OK) {
1155 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1156 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001157 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001158 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001159 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001160 }
1161
Mona Hossain3b574d82011-09-01 15:02:01 -07001162 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1163 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1164 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1165 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001166
1167 /* done */
1168 _ablk_cipher_use_pmem_complete(pce_dev);
1169 }
1170};
1171
1172static void _ablk_cipher_ce_out_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1173 unsigned int result, struct msm_dmov_errdata *err)
1174{
1175 struct qce_device *pce_dev;
1176
1177 pce_dev = (struct qce_device *) cmd_ptr->user;
1178 if (result != ADM_STATUS_OK) {
1179 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1180 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001181 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001182 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001183 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001184 };
1185
Mona Hossain3b574d82011-09-01 15:02:01 -07001186 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1187 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1188 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1189 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001190
1191 /* done */
1192 _ablk_cipher_use_pmem_complete(pce_dev);
1193 }
1194};
1195
Mona Hossain3b574d82011-09-01 15:02:01 -07001196static int qce_setup_cmd_buffers(struct qce_device *pce_dev,
1197 unsigned char **pvaddr)
1198{
1199 struct ce_reg_buffers *addr = (struct ce_reg_buffers *)(*pvaddr);
1200 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
1201
1202 /*
1203 * Designate chunks of the allocated memory to various
1204 * buffer pointers
1205 */
1206 buffer->reset_buf_64 = addr->reset_buf_64;
1207 buffer->version = addr->version;
1208 buffer->encr_seg_cfg_size_start = addr->encr_seg_cfg_size_start;
1209 buffer->encr_key = addr->encr_key;
1210 buffer->encr_xts_key = addr->encr_xts_key;
1211 buffer->encr_xts_du_size = addr->encr_xts_du_size;
1212 buffer->encr_cntr_iv = addr->encr_cntr_iv;
1213 buffer->encr_mask = addr->encr_mask;
1214 buffer->auth_seg_cfg_size_start = addr->auth_seg_cfg_size_start;
1215 buffer->auth_key = addr->auth_key;
1216 buffer->auth_iv = addr->auth_iv;
1217 buffer->auth_result = addr->auth_result;
1218 buffer->auth_nonce_info = addr->auth_nonce_info;
1219 buffer->auth_byte_count = addr->auth_byte_count;
1220 buffer->seg_size = addr->seg_size;
1221 buffer->go_proc = addr->go_proc;
1222 buffer->status = addr->status;
1223 buffer->pad = addr->pad;
1224
1225 memset(buffer->reset_buf_64, 0, 64);
1226 *((uint32_t *)buffer->encr_mask) = (uint32_t)(0xffffffff);
1227 *((uint32_t *)buffer->go_proc) = (uint32_t)(1 << CRYPTO_GO);
1228
1229 *pvaddr += sizeof(struct ce_reg_buffers);
1230
1231 return 0;
1232
1233}
1234
1235static int _setup_cipher_cmdlists(struct qce_device *pce_dev,
1236 unsigned char **pvaddr)
1237{
1238 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1239
1240 /*
1241 * Designate chunks of the allocated memory to various
1242 * command list pointers related to cipher operation
1243 */
1244 pce_dev->ce_dm.cmdlist.set_cipher_cfg = pscmd;
1245 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1246 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG +
1247 pce_dev->phy_iobase);
1248 pscmd->len = CRYPTO_REG_SIZE * 3;
1249 pscmd->src =
1250 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_seg_cfg_size_start);
1251 pscmd++;
1252
1253 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_key = pscmd;
1254 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1255 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1256 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1257 pscmd->len = CRYPTO_REG_SIZE * 4;
1258 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1259 pscmd++;
1260
1261 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_key = pscmd;
1262 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1263 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1264 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1265 pscmd->len = CRYPTO_REG_SIZE * 8;
1266 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1267 pscmd++;
1268
1269 pce_dev->ce_dm.cmdlist.set_cipher_des_key = pscmd;
1270 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1271 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1272 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1273 pscmd->len = CRYPTO_REG_SIZE * 2;
1274 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1275 pscmd++;
1276
1277 pce_dev->ce_dm.cmdlist.set_cipher_3des_key = pscmd;
1278 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1279 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1280 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1281 pscmd->len = CRYPTO_REG_SIZE * 6;
1282 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1283 pscmd++;
1284
1285 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_xts_key = pscmd;
1286 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1287 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1288 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1289 pce_dev->phy_iobase);
1290 pscmd->len = CRYPTO_REG_SIZE * 4;
1291 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1292 pscmd++;
1293
1294 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_xts_key = pscmd;
1295 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1296 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1297 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1298 pce_dev->phy_iobase);
1299 pscmd->len = CRYPTO_REG_SIZE * 8;
1300 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1301 pscmd++;
1302
1303 pce_dev->ce_dm.cmdlist.set_cipher_xts_du_size = pscmd;
1304 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1305 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_DU_SIZE_REG +
1306 pce_dev->phy_iobase);
1307 pscmd->len = CRYPTO_REG_SIZE * 4;
1308 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_du_size);
1309 pscmd++;
1310
1311 pce_dev->ce_dm.cmdlist.set_cipher_aes_iv = pscmd;
1312 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1313 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1314 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1315 pscmd->len = CRYPTO_REG_SIZE * 4;
1316 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1317 pscmd++;
1318
1319 pce_dev->ce_dm.cmdlist.get_cipher_aes_iv = pscmd;
1320 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1321 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1322 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1323 pscmd->len = CRYPTO_REG_SIZE * 4;
1324 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1325 pscmd++;
1326
1327 pce_dev->ce_dm.cmdlist.get_cipher_aes_xts_iv = pscmd;
1328 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1329 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1330 pscmd->len = CRYPTO_REG_SIZE * 4;
1331 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1332 pscmd++;
1333
1334 pce_dev->ce_dm.cmdlist.set_cipher_des_iv = pscmd;
1335 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1336 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1337 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1338 pscmd->len = CRYPTO_REG_SIZE * 2;
1339 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1340 pscmd++;
1341
1342 pce_dev->ce_dm.cmdlist.get_cipher_des_iv = pscmd;
1343 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1344 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1345 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1346 pscmd->len = CRYPTO_REG_SIZE * 2;
1347 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1348 pscmd++;
1349
1350 pce_dev->ce_dm.cmdlist.set_cipher_mask = pscmd;
1351 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1352 pscmd->dst = (unsigned) (CRYPTO_CNTR_MASK_REG + pce_dev->phy_iobase);
1353 pscmd->len = CRYPTO_REG_SIZE;
1354 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_mask);
1355 pscmd++;
1356
1357 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1358
1359 pce_dev->ce_dm.cmdlist.reset_cipher_key = pscmd;
1360 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1361 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1362 pscmd->len = CRYPTO_REG_SIZE * 8;
1363 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1364 pscmd++;
1365
1366 pce_dev->ce_dm.cmdlist.reset_cipher_xts_key = pscmd;
1367 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1368 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1369 pce_dev->phy_iobase);
1370 pscmd->len = CRYPTO_REG_SIZE * 8;
1371 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1372 pscmd++;
1373
1374 pce_dev->ce_dm.cmdlist.reset_cipher_iv = pscmd;
1375 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1376 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1377 pscmd->len = CRYPTO_REG_SIZE * 4;
1378 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1379 pscmd++;
1380
1381 pce_dev->ce_dm.cmdlist.reset_cipher_cfg = pscmd;
1382 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1383 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG + pce_dev->phy_iobase);
1384 pscmd->len = CRYPTO_REG_SIZE;
1385 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1386 pscmd++;
1387
1388 *pvaddr = (unsigned char *) pscmd;
1389
1390 return 0;
1391}
1392
1393static int _setup_auth_cmdlists(struct qce_device *pce_dev,
1394 unsigned char **pvaddr)
1395{
1396 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1397
1398 /*
1399 * Designate chunks of the allocated memory to various
1400 * command list pointers related to authentication operation
1401 */
1402 pce_dev->ce_dm.cmdlist.set_auth_cfg = pscmd;
1403 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1404 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1405 pscmd->len = CRYPTO_REG_SIZE * 3;
1406 pscmd->src =
1407 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start);
1408 pscmd++;
1409
1410 pce_dev->ce_dm.cmdlist.set_auth_key_128 = pscmd;
1411 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1412 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1413 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1414 pscmd->len = CRYPTO_REG_SIZE * 4;
1415 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1416 pscmd++;
1417
1418 pce_dev->ce_dm.cmdlist.set_auth_key_256 = pscmd;
1419 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1420 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1421 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1422 pscmd->len = CRYPTO_REG_SIZE * 8;
1423 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1424 pscmd++;
1425
1426 pce_dev->ce_dm.cmdlist.set_auth_key_512 = pscmd;
1427 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1428 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1429 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1430 pscmd->len = CRYPTO_REG_SIZE * 16;
1431 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1432 pscmd++;
1433
1434 pce_dev->ce_dm.cmdlist.set_auth_iv_16 = pscmd;
1435 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1436 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1437 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1438 pscmd->len = CRYPTO_REG_SIZE * 4;
1439 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1440 pscmd++;
1441
1442 pce_dev->ce_dm.cmdlist.get_auth_result_16 = pscmd;
1443 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1444 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1445 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1446 pscmd->len = CRYPTO_REG_SIZE * 4;
1447 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1448 pscmd++;
1449
1450 pce_dev->ce_dm.cmdlist.set_auth_iv_20 = pscmd;
1451 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1452 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1453 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1454 pscmd->len = CRYPTO_REG_SIZE * 5;
1455 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1456 pscmd++;
1457
1458 pce_dev->ce_dm.cmdlist.get_auth_result_20 = pscmd;
1459 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1460 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1461 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1462 pscmd->len = CRYPTO_REG_SIZE * 5;
1463 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1464 pscmd++;
1465
1466 pce_dev->ce_dm.cmdlist.set_auth_iv_32 = pscmd;
1467 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1468 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1469 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1470 pscmd->len = CRYPTO_REG_SIZE * 8;
1471 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1472 pscmd++;
1473
1474
1475 pce_dev->ce_dm.cmdlist.get_auth_result_32 = pscmd;
1476 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1477 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1478 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1479 pscmd->len = CRYPTO_REG_SIZE * 8;
1480 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1481 pscmd++;
1482
1483 pce_dev->ce_dm.cmdlist.set_auth_byte_count = pscmd;
1484 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1485 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1486 pce_dev->phy_iobase);
1487 pscmd->len = CRYPTO_REG_SIZE * 4;
1488 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1489 pscmd++;
1490
1491 pce_dev->ce_dm.cmdlist.get_auth_byte_count = pscmd;
1492 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1493 pscmd->src = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1494 pce_dev->phy_iobase);
1495 pscmd->len = CRYPTO_REG_SIZE * 4;
1496 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1497 pscmd++;
1498
1499 pce_dev->ce_dm.cmdlist.set_auth_nonce_info = pscmd;
1500 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1501 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1502 pscmd->dst = (unsigned) (CRYPTO_AUTH_INFO_NONCE0_REG +
1503 pce_dev->phy_iobase);
1504 pscmd->len = CRYPTO_REG_SIZE * 4;
1505 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_nonce_info);
1506 pscmd++;
1507
1508 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1509
1510 pce_dev->ce_dm.cmdlist.reset_auth_key = pscmd;
1511 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1512 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1513 pscmd->len = CRYPTO_REG_SIZE * 16;
1514 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1515 pscmd++;
1516
1517 pce_dev->ce_dm.cmdlist.reset_auth_iv = pscmd;
1518 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1519 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1520 pscmd->len = CRYPTO_REG_SIZE * 16;
1521 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1522 pscmd++;
1523
1524 pce_dev->ce_dm.cmdlist.reset_auth_cfg = pscmd;
1525 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1526 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1527 pscmd->len = CRYPTO_REG_SIZE;
1528 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1529 pscmd++;
1530
1531
1532 pce_dev->ce_dm.cmdlist.reset_auth_byte_count = pscmd;
1533 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1534 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1535 pce_dev->phy_iobase);
1536 pscmd->len = CRYPTO_REG_SIZE * 4;
1537 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1538 pscmd++;
1539
1540 /* WAIT UNTIL MAC OP IS DONE*/
1541
1542 pce_dev->ce_dm.cmdlist.get_status_wait = pscmd;
1543 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1544 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1545 pscmd->len = CRYPTO_REG_SIZE;
1546 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1547 pscmd++;
1548
1549 *pvaddr = (unsigned char *) pscmd;
1550
1551 return 0;
1552}
1553
1554static int qce_setup_cmdlists(struct qce_device *pce_dev,
1555 unsigned char **pvaddr)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001556{
1557 dmov_sg *pcmd;
Mona Hossain3b574d82011-09-01 15:02:01 -07001558 dmov_s *pscmd;
1559 unsigned char *vaddr = *pvaddr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001560 struct dmov_desc *pdesc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001561 int i = 0;
1562
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001563 /*
Mona Hossain3b574d82011-09-01 15:02:01 -07001564 * Designate chunks of the allocated memory to various
1565 * command list pointers related to operation define
1566 * in ce_cmdlists structure.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001567 */
Mona Hossain3b574d82011-09-01 15:02:01 -07001568 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
1569 *pvaddr = (unsigned char *) vaddr;
1570
1571 _setup_cipher_cmdlists(pce_dev, pvaddr);
1572 _setup_auth_cmdlists(pce_dev, pvaddr);
1573
1574 pscmd = (dmov_s *)(*pvaddr);
1575
1576 /* GET HW VERSION COMMAND LIST */
1577 pce_dev->ce_dm.cmdlist.get_hw_version = pscmd;
1578 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1579 pscmd->src = (unsigned) (CRYPTO_VERSION_REG + pce_dev->phy_iobase);
1580 pscmd->len = CRYPTO_REG_SIZE;
1581 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.version);
1582 pscmd++;
1583
1584
1585 /* SET SEG SIZE REGISTER and OCB COMMAND LIST */
1586 pce_dev->ce_dm.cmdlist.set_seg_size_ocb = pscmd;
1587 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1588 pscmd->dst = (unsigned) (CRYPTO_SEG_SIZE_REG + pce_dev->phy_iobase);
1589 pscmd->len = CRYPTO_REG_SIZE;
1590 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.seg_size);
1591 pscmd++;
1592
1593
1594 /* OCU COMMAND LIST */
1595 pce_dev->ce_dm.cmdlist.get_status_ocu = pscmd;
1596 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCU;
1597 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1598 pscmd->len = CRYPTO_REG_SIZE;
1599 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1600 pscmd++;
1601
1602 /* SET GO_PROC REGISTERS COMMAND LIST */
1603 pce_dev->ce_dm.cmdlist.set_go_proc = pscmd;
1604 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1605 pscmd->dst = (unsigned) (CRYPTO_GOPROC_REG + pce_dev->phy_iobase);
1606 pscmd->len = CRYPTO_REG_SIZE;
1607 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.go_proc);
1608 pscmd++;
1609
1610 pcmd = (dmov_sg *)pscmd;
1611 pce_dev->ce_dm.cmdlist.ce_data_in = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001612 /* swap byte and half word , dst crci , scatter gather */
1613 pcmd->cmd = CMD_DST_SWAP_BYTES | CMD_DST_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001614 CMD_DST_CRCI(pce_dev->ce_dm.crci_in) | CMD_MODE_SG;
1615
1616 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001617 pdesc->addr = 0; /* to be filled in each operation */
1618 pdesc->len = 0; /* to be filled in each operation */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001619
Mona Hossain3b574d82011-09-01 15:02:01 -07001620 pdesc = pce_dev->ce_dm.ce_in_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001621 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1622 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1623 pdesc->len = 0; /* to be filled in each operation */
1624 pdesc++;
1625 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001626 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_src_desc);
1627 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001628 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1629 DST_INDEX_SG_CMD(0);
Mona Hossain3b574d82011-09-01 15:02:01 -07001630
1631
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001632 pcmd++;
Mona Hossain3b574d82011-09-01 15:02:01 -07001633 pce_dev->ce_dm.cmdlist.ce_data_out = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001634 /* swap byte, half word, source crci, scatter gather */
1635 pcmd->cmd = CMD_SRC_SWAP_BYTES | CMD_SRC_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001636 CMD_SRC_CRCI(pce_dev->ce_dm.crci_out) | CMD_MODE_SG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001637
Mona Hossain3b574d82011-09-01 15:02:01 -07001638 pdesc = pce_dev->ce_dm.ce_out_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001639 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1640 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1641 pdesc->len = 0; /* to be filled in each operation */
1642 pdesc++;
1643 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001644
Mona Hossain3b574d82011-09-01 15:02:01 -07001645 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001646 pdesc->addr = 0; /* to be filled in each operation */
1647 pdesc->len = 0; /* to be filled in each operation */
Mona Hossain3b574d82011-09-01 15:02:01 -07001648
1649 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_src_desc);
1650 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001651 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1652 DST_INDEX_SG_CMD(0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001653 pcmd++;
1654
Mona Hossain3b574d82011-09-01 15:02:01 -07001655 *pvaddr = (unsigned char *) pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001656
1657 return 0;
Mona Hossain3b574d82011-09-01 15:02:01 -07001658}
1659
1660static int _setup_cipher_cmdptrlists(struct qce_device *pce_dev,
1661 unsigned char **pvaddr)
1662{
1663 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1664 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1665 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1666
1667 /*
1668 * Designate chunks of the allocated memory to various
1669 * command list pointers related to cipher operations defined
1670 * in ce_cmdptrlists_ops structure.
1671 */
1672 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1673 cmdptrlist->cipher_aes_128_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1674
1675 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1676 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1677 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1678 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1679 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1680 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1681 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1682 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1683 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_iv);
1684
1685 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1686 cmdptrlist->cipher_aes_256_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1687
1688 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1689 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1690 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1691 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1692 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1693 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1694 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1695 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1696 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_iv);
1697
1698 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1699 cmdptrlist->cipher_aes_128_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1700
1701 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1702 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1703 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1704 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1705 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1706 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1707 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1708
1709 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1710 cmdptrlist->cipher_aes_256_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1711
1712 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1713 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1714 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1715 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1716 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1717 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1718 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1719
1720 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1721 cmdptrlist->cipher_aes_128_xts = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1722
1723 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1724 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1725 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1726 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_xts_key);
1727 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1728 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1729 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
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_CMD_PTR(cmdlist->ce_data_in);
1733 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_xts_iv);
1734
1735 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1736 cmdptrlist->cipher_aes_256_xts = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1737
1738 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1739 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1740 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1741 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_xts_key);
1742 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1743 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1744 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
1745 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1746 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1747 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1748 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_xts_iv);
1749
1750 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1751 cmdptrlist->cipher_des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1752
1753 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1754 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1755 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1756 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1757 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1758 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1759 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1760 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_des_iv);
1761
1762 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1763 cmdptrlist->cipher_des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1764
1765 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1766 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1767 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1768 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1769 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1770 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1771
1772 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1773 cmdptrlist->cipher_3des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1774
1775 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1776 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1777 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1778 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1779 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1780 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1781 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1782 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_des_iv);
1783
1784 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1785 cmdptrlist->cipher_3des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1786
1787 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1788 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1789 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1790 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1791 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1792 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1793
1794 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1795 cmdptrlist->cipher_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1796
1797 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1798 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1799 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1800
1801 return 0;
1802}
1803
1804static int _setup_auth_cmdptrlists(struct qce_device *pce_dev,
1805 unsigned char **pvaddr)
1806{
1807 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1808 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1809 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1810
1811 /*
1812 * Designate chunks of the allocated memory to various
1813 * command list pointers related to authentication operations
1814 * defined in ce_cmdptrlists_ops structure.
1815 */
1816 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1817 cmdptrlist->auth_sha1 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1818
1819 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1820 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1821 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1822 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1823 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1824 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1825 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1826 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1827 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1828 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1829 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1830 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1831
1832 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1833 cmdptrlist->auth_sha256 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1834
1835 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1836 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1837 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1838 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1839 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1840 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1841 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1842 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1843 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1844 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1845 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1846 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1847
1848 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1849 cmdptrlist->auth_sha1_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1850
1851 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1852 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1853 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1854 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1855 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1856 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1857 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1858 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1859 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1860 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1861 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1862 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1863 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1864
1865 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1866 cmdptrlist->auth_sha256_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1867
1868 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1869 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1870 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1871 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1872 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1873 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1874 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1875 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1876 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1877 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1878 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1879 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1880 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1881
1882 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1883 cmdptrlist->auth_aes_128_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1884
1885 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1886 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1887 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1888 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1889 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1890 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1891 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1892 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1893 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1894 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1895 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1896 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1897 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1898 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1899
1900 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1901 cmdptrlist->auth_aes_256_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1902
1903 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1904 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1905 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1906 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1907 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1908 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1909 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1910 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1911 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1912 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1913 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1914 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1915 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1916 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1917
1918 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1919
1920 return 0;
1921}
1922
1923static int _setup_aead_cmdptrlists(struct qce_device *pce_dev,
1924 unsigned char **pvaddr)
1925{
1926 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1927 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1928 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1929
1930 /*
1931 * Designate chunks of the allocated memory to various
1932 * command list pointers related to aead operations
1933 * defined in ce_cmdptrlists_ops structure.
1934 */
1935 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1936 cmdptrlist->aead_aes_128_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1937
1938 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1939 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1940 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1941 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1942 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1943 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1944 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1945 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1946 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1947 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1948 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1949 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1950 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1951
1952 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1953 cmdptrlist->aead_aes_256_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1954
1955 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1956 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1957 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1958 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1959 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1960 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1961 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1962 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1963 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1964 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1965 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1966 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1967 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1968
1969 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1970 cmdptrlist->aead_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1971
1972 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1973 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1974 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1975 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1976
1977 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1978
1979 return 0;
1980}
1981
1982static int qce_setup_cmdptrlists(struct qce_device *pce_dev,
1983 unsigned char **pvaddr)
1984{
1985 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1986 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1987 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1988 /*
1989 * Designate chunks of the allocated memory to various
1990 * command list pointers related to operations defined
1991 * in ce_cmdptrlists_ops structure.
1992 */
1993 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1994 cmdptrlist->probe_ce_hw = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1995
1996 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_hw_version);
1997 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1998
1999 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
2000
2001 _setup_cipher_cmdptrlists(pce_dev, pvaddr);
2002 _setup_auth_cmdptrlists(pce_dev, pvaddr);
2003 _setup_aead_cmdptrlists(pce_dev, pvaddr);
2004
2005 return 0;
2006}
2007
2008
2009static int qce_setup_ce_dm_data(struct qce_device *pce_dev)
2010{
2011 unsigned char *vaddr;
2012
2013 /* 1. ce_in channel data xfer command src descriptors, 128 entries */
2014 vaddr = pce_dev->coh_vmem;
2015 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2016 pce_dev->ce_dm.ce_in_src_desc = (struct dmov_desc *) vaddr;
2017 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2018
2019 /* 2. ce_in channel data xfer command dst descriptors, 128 entries */
2020 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2021 pce_dev->ce_dm.ce_in_dst_desc = (struct dmov_desc *) vaddr;
2022 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2023
2024
2025 /* 3. ce_out channel data xfer command src descriptors, 128 entries */
2026 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2027 pce_dev->ce_dm.ce_out_src_desc = (struct dmov_desc *) vaddr;
2028 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2029
2030 /* 4. ce_out channel data xfer command dst descriptors, 128 entries. */
2031 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2032 pce_dev->ce_dm.ce_out_dst_desc = (struct dmov_desc *) vaddr;
2033 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2034
2035 qce_setup_cmd_buffers(pce_dev, &vaddr);
2036 qce_setup_cmdlists(pce_dev, &vaddr);
2037 qce_setup_cmdptrlists(pce_dev, &vaddr);
2038
2039 pce_dev->ce_dm.buffer.ignore_data = vaddr;
2040
2041 pce_dev->ce_dm.phy_ce_pad = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.pad);
2042 pce_dev->ce_dm.phy_ce_out_ignore =
2043 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.ignore_data);
2044
2045 pce_dev->ce_dm.chan_ce_in_cmd->user = (void *) pce_dev;
2046 pce_dev->ce_dm.chan_ce_in_cmd->exec_func = NULL;
2047
2048 pce_dev->ce_dm.chan_ce_out_cmd->user = (void *) pce_dev;
2049 pce_dev->ce_dm.chan_ce_out_cmd->exec_func = NULL;
2050
2051 return 0;
2052}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002053
2054static int _qce_start_dma(struct qce_device *pce_dev, bool ce_in, bool ce_out)
2055{
2056
2057 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002058 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002059 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002060 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002061
2062 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002063 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002064 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002065 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002066
2067 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002068 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
2069 pce_dev->ce_dm.chan_ce_in_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002070 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002071 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_out,
2072 pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002073
2074 return 0;
2075};
2076
2077int qce_aead_req(void *handle, struct qce_req *q_req)
2078{
2079 struct qce_device *pce_dev = (struct qce_device *) handle;
2080 struct aead_request *areq = (struct aead_request *) q_req->areq;
2081 uint32_t authsize = q_req->authsize;
2082 uint32_t totallen_in, totallen_out, out_len;
2083 uint32_t pad_len_in, pad_len_out;
2084 uint32_t pad_mac_len_out, pad_ptx_len_out;
2085 int rc = 0;
2086
2087 if (q_req->dir == QCE_ENCRYPT) {
2088 q_req->cryptlen = areq->cryptlen;
2089 totallen_in = q_req->cryptlen + areq->assoclen;
2090 totallen_out = q_req->cryptlen + authsize + areq->assoclen;
2091 out_len = areq->cryptlen + authsize;
2092 pad_len_in = ALIGN(totallen_in, ADM_CE_BLOCK_SIZE) -
2093 totallen_in;
2094 pad_mac_len_out = ALIGN(authsize, ADM_CE_BLOCK_SIZE) -
2095 authsize;
2096 pad_ptx_len_out = ALIGN(q_req->cryptlen, ADM_CE_BLOCK_SIZE) -
2097 q_req->cryptlen;
2098 pad_len_out = pad_ptx_len_out + pad_mac_len_out;
2099 totallen_out += pad_len_out;
2100 } else {
2101 q_req->cryptlen = areq->cryptlen - authsize;
2102 totallen_in = areq->cryptlen + areq->assoclen;
2103 totallen_out = q_req->cryptlen + areq->assoclen;
2104 out_len = areq->cryptlen - authsize;
2105 pad_len_in = ALIGN(areq->cryptlen, ADM_CE_BLOCK_SIZE) -
2106 areq->cryptlen;
2107 pad_len_out = pad_len_in + authsize;
2108 totallen_out += pad_len_out;
2109 }
2110
2111 _chain_buffer_in_init(pce_dev);
2112 _chain_buffer_out_init(pce_dev);
2113
2114 pce_dev->assoc_nents = 0;
2115 pce_dev->src_nents = 0;
2116 pce_dev->dst_nents = 0;
2117 pce_dev->ivsize = q_req->ivsize;
2118 pce_dev->authsize = q_req->authsize;
2119
2120 /* associated data input */
2121 pce_dev->assoc_nents = count_sg(areq->assoc, areq->assoclen);
2122 dma_map_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
2123 DMA_TO_DEVICE);
2124 if (_chain_sg_buffer_in(pce_dev, areq->assoc, areq->assoclen) < 0) {
2125 rc = -ENOMEM;
2126 goto bad;
2127 }
2128 /* cipher input */
2129 pce_dev->src_nents = count_sg(areq->src, areq->cryptlen);
2130 dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2131 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2132 DMA_TO_DEVICE);
2133 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->cryptlen) < 0) {
2134 rc = -ENOMEM;
2135 goto bad;
2136 }
2137 /* pad data in */
2138 if (pad_len_in) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002139 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002140 pad_len_in) < 0) {
2141 rc = -ENOMEM;
2142 goto bad;
2143 }
2144 }
2145
2146 /* ignore associated data */
Mona Hossain3b574d82011-09-01 15:02:01 -07002147 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_out_ignore,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002148 areq->assoclen) < 0) {
2149 rc = -ENOMEM;
2150 goto bad;
2151 }
2152 /* cipher + mac output for encryption */
2153 if (areq->src != areq->dst) {
2154 pce_dev->dst_nents = count_sg(areq->dst, out_len);
2155 dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2156 DMA_FROM_DEVICE);
2157 };
2158 if (_chain_sg_buffer_out(pce_dev, areq->dst, out_len) < 0) {
2159 rc = -ENOMEM;
2160 goto bad;
2161 }
2162 /* pad data out */
2163 if (pad_len_out) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002164 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002165 pad_len_out) < 0) {
2166 rc = -ENOMEM;
2167 goto bad;
2168 }
2169 }
2170
2171 /* finalize the ce_in and ce_out channels command lists */
2172 _ce_in_final(pce_dev, ALIGN(totallen_in, ADM_CE_BLOCK_SIZE));
2173 _ce_out_final(pce_dev, ALIGN(totallen_out, ADM_CE_BLOCK_SIZE));
2174
2175 /* set up crypto device */
2176 rc = _ce_setup_cipher(pce_dev, q_req, totallen_in, areq->assoclen);
2177 if (rc < 0)
2178 goto bad;
2179
2180 /* setup for callback, and issue command to adm */
2181 pce_dev->areq = q_req->areq;
2182 pce_dev->qce_cb = q_req->qce_cb;
2183
Mona Hossain3b574d82011-09-01 15:02:01 -07002184 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _aead_ce_in_call_back;
2185 pce_dev->ce_dm.chan_ce_out_cmd->complete_func = _aead_ce_out_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002186
2187 _ce_in_dump(pce_dev);
2188 _ce_out_dump(pce_dev);
2189
2190 rc = _qce_start_dma(pce_dev, true, true);
2191 if (rc == 0)
2192 return 0;
2193bad:
2194 if (pce_dev->assoc_nents) {
2195 dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
2196 DMA_TO_DEVICE);
2197 }
2198
2199 if (pce_dev->src_nents) {
2200 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2201 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2202 DMA_TO_DEVICE);
2203 }
2204 if (pce_dev->dst_nents) {
2205 dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2206 DMA_FROM_DEVICE);
2207 }
2208 return rc;
2209}
2210EXPORT_SYMBOL(qce_aead_req);
2211
2212int qce_ablk_cipher_req(void *handle, struct qce_req *c_req)
2213{
2214 int rc = 0;
2215 struct qce_device *pce_dev = (struct qce_device *) handle;
2216 struct ablkcipher_request *areq = (struct ablkcipher_request *)
2217 c_req->areq;
2218
2219 uint32_t pad_len = ALIGN(areq->nbytes, ADM_CE_BLOCK_SIZE)
2220 - areq->nbytes;
2221
2222 _chain_buffer_in_init(pce_dev);
2223 _chain_buffer_out_init(pce_dev);
2224
2225 pce_dev->src_nents = 0;
2226 pce_dev->dst_nents = 0;
2227
2228 /* cipher input */
2229 pce_dev->src_nents = count_sg(areq->src, areq->nbytes);
2230
2231 if (c_req->use_pmem != 1)
2232 dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2233 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2234 DMA_TO_DEVICE);
2235 else
2236 dma_map_pmem_sg(&c_req->pmem->src[0], pce_dev->src_nents,
2237 areq->src);
2238
2239 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->nbytes) < 0) {
2240 rc = -ENOMEM;
2241 goto bad;
2242 }
2243
2244 /* cipher output */
2245 if (areq->src != areq->dst) {
2246 pce_dev->dst_nents = count_sg(areq->dst, areq->nbytes);
2247 if (c_req->use_pmem != 1)
2248 dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2249 DMA_FROM_DEVICE);
2250 else
2251 dma_map_pmem_sg(&c_req->pmem->dst[0],
2252 pce_dev->dst_nents, areq->dst);
2253 };
2254 if (_chain_sg_buffer_out(pce_dev, areq->dst, areq->nbytes) < 0) {
2255 rc = -ENOMEM;
2256 goto bad;
2257 }
2258
2259 /* pad data */
2260 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002261 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002262 pad_len) < 0) {
2263 rc = -ENOMEM;
2264 goto bad;
2265 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002266 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002267 pad_len) < 0) {
2268 rc = -ENOMEM;
2269 goto bad;
2270 }
2271 }
2272
2273 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain390d92e2011-09-02 14:15:47 -07002274 _ce_in_final(pce_dev, 0);
2275 _ce_out_final(pce_dev, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002276
2277 _ce_in_dump(pce_dev);
2278 _ce_out_dump(pce_dev);
2279
2280 /* set up crypto device */
2281 rc = _ce_setup_cipher(pce_dev, c_req, areq->nbytes, 0);
2282 if (rc < 0)
2283 goto bad;
2284
2285 /* setup for callback, and issue command to adm */
2286 pce_dev->areq = areq;
2287 pce_dev->qce_cb = c_req->qce_cb;
2288 if (c_req->use_pmem == 1) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002289 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002290 _ablk_cipher_ce_in_call_back_pmem;
Mona Hossain3b574d82011-09-01 15:02:01 -07002291 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002292 _ablk_cipher_ce_out_call_back_pmem;
2293 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07002294 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002295 _ablk_cipher_ce_in_call_back;
Mona Hossain3b574d82011-09-01 15:02:01 -07002296 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002297 _ablk_cipher_ce_out_call_back;
2298 }
2299 rc = _qce_start_dma(pce_dev, true, true);
2300
2301 if (rc == 0)
2302 return 0;
2303bad:
2304 if (c_req->use_pmem != 1) {
2305 if (pce_dev->dst_nents) {
2306 dma_unmap_sg(pce_dev->pdev, areq->dst,
2307 pce_dev->dst_nents, DMA_FROM_DEVICE);
2308 }
2309 if (pce_dev->src_nents) {
2310 dma_unmap_sg(pce_dev->pdev, areq->src,
2311 pce_dev->src_nents,
2312 (areq->src == areq->dst) ?
2313 DMA_BIDIRECTIONAL :
2314 DMA_TO_DEVICE);
2315 }
2316 }
2317 return rc;
2318}
2319EXPORT_SYMBOL(qce_ablk_cipher_req);
2320
2321int qce_process_sha_req(void *handle, struct qce_sha_req *sreq)
2322{
2323 struct qce_device *pce_dev = (struct qce_device *) handle;
2324 int rc;
2325 uint32_t pad_len = ALIGN(sreq->size, ADM_CE_BLOCK_SIZE) - sreq->size;
2326 struct ahash_request *areq = (struct ahash_request *)sreq->areq;
2327
2328 _chain_buffer_in_init(pce_dev);
2329 pce_dev->src_nents = count_sg(sreq->src, sreq->size);
2330 dma_map_sg(pce_dev->pdev, sreq->src, pce_dev->src_nents,
2331 DMA_TO_DEVICE);
2332
2333 if (_chain_sg_buffer_in(pce_dev, sreq->src, sreq->size) < 0) {
2334 rc = -ENOMEM;
2335 goto bad;
2336 }
2337
2338 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002339 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002340 pad_len) < 0) {
2341 rc = -ENOMEM;
2342 goto bad;
2343 }
2344 }
Mona Hossain390d92e2011-09-02 14:15:47 -07002345 _ce_in_final(pce_dev, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002346
2347 _ce_in_dump(pce_dev);
2348
Mona Hossain3b574d82011-09-01 15:02:01 -07002349 rc = _ce_setup_hash(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002350
2351 if (rc < 0)
2352 goto bad;
2353
2354 pce_dev->areq = areq;
2355 pce_dev->qce_cb = sreq->qce_cb;
Mona Hossain3b574d82011-09-01 15:02:01 -07002356 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _sha_ce_in_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002357
2358 rc = _qce_start_dma(pce_dev, true, false);
2359
2360 if (rc == 0)
2361 return 0;
2362bad:
2363 if (pce_dev->src_nents) {
2364 dma_unmap_sg(pce_dev->pdev, sreq->src,
2365 pce_dev->src_nents, DMA_TO_DEVICE);
2366 }
2367
2368 return rc;
2369}
2370EXPORT_SYMBOL(qce_process_sha_req);
2371
2372/* crypto engine open function. */
2373void *qce_open(struct platform_device *pdev, int *rc)
2374{
2375 struct qce_device *pce_dev;
2376 struct resource *resource;
2377 struct clk *ce_core_clk;
2378 struct clk *ce_clk;
2379
2380 pce_dev = kzalloc(sizeof(struct qce_device), GFP_KERNEL);
2381 if (!pce_dev) {
2382 *rc = -ENOMEM;
2383 dev_err(&pdev->dev, "Can not allocate memory\n");
2384 return NULL;
2385 }
2386 pce_dev->pdev = &pdev->dev;
2387
2388 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2389 if (!resource) {
2390 *rc = -ENXIO;
2391 dev_err(pce_dev->pdev, "Missing MEM resource\n");
2392 goto err_pce_dev;
2393 };
2394 pce_dev->phy_iobase = resource->start;
2395 pce_dev->iobase = ioremap_nocache(resource->start,
2396 resource->end - resource->start + 1);
2397 if (!pce_dev->iobase) {
2398 *rc = -ENOMEM;
2399 dev_err(pce_dev->pdev, "Can not map io memory\n");
2400 goto err_pce_dev;
2401 }
2402
Mona Hossain3b574d82011-09-01 15:02:01 -07002403 pce_dev->ce_dm.chan_ce_in_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002404 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002405 pce_dev->ce_dm.chan_ce_out_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002406 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002407 if (pce_dev->ce_dm.chan_ce_in_cmd == NULL ||
2408 pce_dev->ce_dm.chan_ce_out_cmd == NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002409 dev_err(pce_dev->pdev, "Can not allocate memory\n");
2410 *rc = -ENOMEM;
2411 goto err_dm_chan_cmd;
2412 }
2413
2414 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2415 "crypto_channels");
2416 if (!resource) {
2417 *rc = -ENXIO;
2418 dev_err(pce_dev->pdev, "Missing DMA channel resource\n");
2419 goto err_dm_chan_cmd;
2420 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002421 pce_dev->ce_dm.chan_ce_in = resource->start;
2422 pce_dev->ce_dm.chan_ce_out = resource->end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002423 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2424 "crypto_crci_in");
2425 if (!resource) {
2426 *rc = -ENXIO;
2427 dev_err(pce_dev->pdev, "Missing DMA crci in resource\n");
2428 goto err_dm_chan_cmd;
2429 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002430 pce_dev->ce_dm.crci_in = resource->start;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002431 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2432 "crypto_crci_out");
2433 if (!resource) {
2434 *rc = -ENXIO;
2435 dev_err(pce_dev->pdev, "Missing DMA crci out resource\n");
2436 goto err_dm_chan_cmd;
2437 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002438 pce_dev->ce_dm.crci_out = resource->start;
2439 pce_dev->memsize = 2 * PAGE_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002440 pce_dev->coh_vmem = dma_alloc_coherent(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -07002441 pce_dev->memsize, &pce_dev->coh_pmem, GFP_KERNEL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002442
2443 if (pce_dev->coh_vmem == NULL) {
2444 *rc = -ENOMEM;
2445 dev_err(pce_dev->pdev, "Can not allocate coherent memory.\n");
2446 goto err;
2447 }
2448
2449 /* Get CE core clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002450 ce_core_clk = clk_get(pce_dev->pdev, "core_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002451 if (IS_ERR(ce_core_clk)) {
2452 *rc = PTR_ERR(ce_core_clk);
2453 goto err;
2454 }
2455 pce_dev->ce_core_clk = ce_core_clk;
2456 /* Get CE clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002457 ce_clk = clk_get(pce_dev->pdev, "iface_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002458 if (IS_ERR(ce_clk)) {
2459 *rc = PTR_ERR(ce_clk);
2460 clk_put(pce_dev->ce_core_clk);
2461 goto err;
2462 }
2463 pce_dev->ce_clk = ce_clk;
2464
2465 /* Enable CE core clk */
2466 *rc = clk_enable(pce_dev->ce_core_clk);
2467 if (*rc) {
2468 clk_put(pce_dev->ce_core_clk);
2469 clk_put(pce_dev->ce_clk);
2470 goto err;
2471 } else {
2472 /* Enable CE clk */
2473 *rc = clk_enable(pce_dev->ce_clk);
2474 if (*rc) {
2475 clk_disable(pce_dev->ce_core_clk);
2476 clk_put(pce_dev->ce_core_clk);
2477 clk_put(pce_dev->ce_clk);
2478 goto err;
2479
2480 }
2481 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002482 qce_setup_ce_dm_data(pce_dev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002483
Mona Hossain3b574d82011-09-01 15:02:01 -07002484 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
2485 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002486 if (_init_ce_engine(pce_dev)) {
2487 *rc = -ENXIO;
2488 goto err;
2489 }
2490 *rc = 0;
2491 return pce_dev;
2492
2493err:
2494 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002495 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
Mona Hossaine1b13f82011-08-30 09:35:49 -07002496 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002497err_dm_chan_cmd:
Mona Hossain3b574d82011-09-01 15:02:01 -07002498 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2499 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002500 if (pce_dev->iobase)
2501 iounmap(pce_dev->iobase);
2502
2503err_pce_dev:
2504
2505 kfree(pce_dev);
2506
2507 return NULL;
2508}
2509EXPORT_SYMBOL(qce_open);
2510
2511/* crypto engine close function. */
2512int qce_close(void *handle)
2513{
2514 struct qce_device *pce_dev = (struct qce_device *) handle;
2515
2516 if (handle == NULL)
2517 return -ENODEV;
2518 if (pce_dev->iobase)
2519 iounmap(pce_dev->iobase);
2520
2521 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002522 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
2523 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002524 clk_disable(pce_dev->ce_clk);
2525 clk_disable(pce_dev->ce_core_clk);
2526
2527 clk_put(pce_dev->ce_clk);
2528 clk_put(pce_dev->ce_core_clk);
2529
Mona Hossain3b574d82011-09-01 15:02:01 -07002530 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2531 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002532 kfree(handle);
2533
2534 return 0;
2535}
2536EXPORT_SYMBOL(qce_close);
2537
2538int qce_hw_support(void *handle, struct ce_hw_support *ce_support)
2539{
2540 if (ce_support == NULL)
2541 return -EINVAL;
2542
2543 ce_support->sha1_hmac_20 = false;
2544 ce_support->sha1_hmac = false;
2545 ce_support->sha256_hmac = false;
2546 ce_support->sha_hmac = false;
2547 ce_support->cmac = true;
2548 ce_support->aes_key_192 = false;
2549 ce_support->aes_xts = true;
2550 ce_support->aes_ccm = true;
2551 ce_support->ota = false;
2552 return 0;
2553}
2554EXPORT_SYMBOL(qce_hw_support);
2555
2556MODULE_LICENSE("GPL v2");
2557MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
2558MODULE_DESCRIPTION("Crypto Engine driver");
Mona Hossain3b574d82011-09-01 15:02:01 -07002559MODULE_VERSION("2.08");