blob: 24bf89504c2b35a7a408f71e77c7a9cbb21c0d60 [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));
Mona Hossain5f5dde12011-09-12 10:28:34 -0700130 if (((val & 0xfffffff) != 0x0000043) &&
131 ((val & 0xfffffff) != 0x0000042) &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700132 ((val & 0xfffffff) != 0x0000040)) {
133 dev_err(pce_dev->pdev,
134 "Unknown Qualcomm crypto device at 0x%x 0x%x\n",
135 pce_dev->phy_iobase, val);
136 return -EIO;
137 };
138 rev = (val & CRYPTO_CORE_REV_MASK);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700139 if (rev >= 0x42) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700140 dev_info(pce_dev->pdev,
141 "Qualcomm Crypto 4.2 device found at 0x%x\n",
142 pce_dev->phy_iobase);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700143 pce_dev->ce_dm.ce_block_size = 64;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700144 } else {
145 if (rev == 0x40) {
146 dev_info(pce_dev->pdev,
147 "Qualcomm Crypto 4.0 device found at 0x%x\n",
148 pce_dev->phy_iobase);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700149 pce_dev->ce_dm.ce_block_size = 16;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700150 }
151 }
152
153 dev_info(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -0700154 "IO base 0x%x\n, ce_in channel %d , "
155 "ce_out channel %d\n, "
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700156 "crci_in %d, crci_out %d\n",
157 (unsigned int) pce_dev->iobase,
Mona Hossain3b574d82011-09-01 15:02:01 -0700158 pce_dev->ce_dm.chan_ce_in, pce_dev->ce_dm.chan_ce_out,
159 pce_dev->ce_dm.crci_in, pce_dev->ce_dm.crci_out);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700160
161 return 0;
162};
163
Mona Hossain3b574d82011-09-01 15:02:01 -0700164
165static void _check_probe_done_call_back(struct msm_dmov_cmd *cmd_ptr,
166 unsigned int result, struct msm_dmov_errdata *err)
167{
168 struct qce_device *pce_dev;
169 pce_dev = (struct qce_device *) cmd_ptr->user;
170
171 if (result != ADM_STATUS_OK) {
172 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
173 result);
174 pce_dev->ce_dm.chan_ce_in_status = -1;
175 } else {
176 _probe_ce_engine(pce_dev);
177 pce_dev->ce_dm.chan_ce_in_status = 0;
178 }
179 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
180};
181
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700182static int _init_ce_engine(struct qce_device *pce_dev)
183{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700184 /* Reset ce */
185 clk_reset(pce_dev->ce_core_clk, CLK_RESET_ASSERT);
186 clk_reset(pce_dev->ce_core_clk, CLK_RESET_DEASSERT);
Mona Hossain3b574d82011-09-01 15:02:01 -0700187
188 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
189 _check_probe_done_call_back;
190 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
191 pce_dev->ce_dm.cmdptrlist.probe_ce_hw;
192 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
193 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
194 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
195 pce_dev->ce_dm.chan_ce_in_cmd);
196
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700197 return 0;
198};
199
Mona Hossain3b574d82011-09-01 15:02:01 -0700200static int _ce_setup_hash_cmdrptrlist(struct qce_device *pce_dev,
201 struct qce_sha_req *sreq)
202{
203 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
204
205 switch (sreq->alg) {
206 case QCE_HASH_SHA1:
207 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr = cmdptrlist->auth_sha1;
208 break;
209
210 case QCE_HASH_SHA256:
211 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr = cmdptrlist->auth_sha256;
212 break;
213 case QCE_HASH_SHA1_HMAC:
214 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
215 cmdptrlist->auth_sha1_hmac;
216 break;
217
218 case QCE_HASH_SHA256_HMAC:
219 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
220 cmdptrlist->auth_sha256_hmac;
221 break;
222 case QCE_HASH_AES_CMAC:
223 if (sreq->authklen == AES128_KEY_SIZE)
224 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
225 cmdptrlist->auth_aes_128_cmac;
226 else
227 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
228 cmdptrlist->auth_aes_256_cmac;
229 break;
230
231 default:
232 break;
233 }
234
235 return 0;
236}
237
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700238static int _ce_setup_hash(struct qce_device *pce_dev, struct qce_sha_req *sreq)
239{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700240 uint32_t diglen;
241 int i;
242 uint32_t auth_cfg = 0;
243 bool sha1 = false;
244
245 if (sreq->alg == QCE_HASH_AES_CMAC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700246
Mona Hossain3b574d82011-09-01 15:02:01 -0700247 memcpy(pce_dev->ce_dm.buffer.auth_key, sreq->authkey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700248 sreq->authklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700249 auth_cfg |= (1 << CRYPTO_LAST);
250 auth_cfg |= (CRYPTO_AUTH_MODE_CMAC << CRYPTO_AUTH_MODE);
251 auth_cfg |= (CRYPTO_AUTH_SIZE_ENUM_16_BYTES <<
252 CRYPTO_AUTH_SIZE);
253 auth_cfg |= CRYPTO_AUTH_ALG_AES << CRYPTO_AUTH_ALG;
254
255 switch (sreq->authklen) {
256 case AES128_KEY_SIZE:
257 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES128 <<
258 CRYPTO_AUTH_KEY_SIZE);
259 break;
260 case AES256_KEY_SIZE:
261 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES256 <<
262 CRYPTO_AUTH_KEY_SIZE);
263 break;
264 default:
265 break;
266 }
267
268 goto go_proc;
269 }
270
271 /* if not the last, the size has to be on the block boundary */
272 if (sreq->last_blk == 0 && (sreq->size % SHA256_BLOCK_SIZE))
273 return -EIO;
274
275 switch (sreq->alg) {
276 case QCE_HASH_SHA1:
277 case QCE_HASH_SHA1_HMAC:
278 diglen = SHA1_DIGEST_SIZE;
279 sha1 = true;
280 break;
281 case QCE_HASH_SHA256:
282 case QCE_HASH_SHA256_HMAC:
283 diglen = SHA256_DIGEST_SIZE;
284 break;
285 default:
286 return -EINVAL;
287 }
288
289 if ((sreq->alg == QCE_HASH_SHA1_HMAC) ||
290 (sreq->alg == QCE_HASH_SHA256_HMAC)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700291
Mona Hossain3b574d82011-09-01 15:02:01 -0700292 memcpy(pce_dev->ce_dm.buffer.auth_key, sreq->authkey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700293 sreq->authklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700294 auth_cfg |= (CRYPTO_AUTH_MODE_HMAC << CRYPTO_AUTH_MODE);
295 } else {
296 auth_cfg |= (CRYPTO_AUTH_MODE_HASH << CRYPTO_AUTH_MODE);
297 }
298
299 /* write 20/32 bytes, 5/8 words into auth_iv for SHA1/SHA256 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700300 if (sreq->first_blk) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700301 if (sha1)
302 memcpy(pce_dev->ce_dm.buffer.auth_iv,
303 _std_init_vector_sha1_uint8, diglen);
304 else
305 memcpy(pce_dev->ce_dm.buffer.auth_iv,
306 _std_init_vector_sha256_uint8, diglen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700307 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700308 memcpy(pce_dev->ce_dm.buffer.auth_iv, sreq->digest,
309 diglen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700310 }
311
Mona Hossain3b574d82011-09-01 15:02:01 -0700312 /* write auth_bytecnt 0/1/2/3, start with 0 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700313 for (i = 0; i < 4; i++)
Mona Hossain3b574d82011-09-01 15:02:01 -0700314 *(((uint32_t *)(pce_dev->ce_dm.buffer.auth_byte_count) + i)) =
315 sreq->auth_data[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700316
317 /* write seg_cfg */
318 if (sha1)
319 auth_cfg |= (CRYPTO_AUTH_SIZE_SHA1 << CRYPTO_AUTH_SIZE);
320 else
321 auth_cfg |= (CRYPTO_AUTH_SIZE_SHA256 << CRYPTO_AUTH_SIZE);
322
323 if (sreq->last_blk)
324 auth_cfg |= 1 << CRYPTO_LAST;
325
326 auth_cfg |= CRYPTO_AUTH_ALG_SHA << CRYPTO_AUTH_ALG;
327
328go_proc:
329 auth_cfg |= (CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);
330
Mona Hossain3b574d82011-09-01 15:02:01 -0700331 /* write auth seg cfg */
332 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start)) =
333 auth_cfg;
334 /* write auth seg size */
335 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start) + 1) =
336 sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700337
Mona Hossain3b574d82011-09-01 15:02:01 -0700338 /* write auth seg size start*/
339 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start)+2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700340
Mona Hossain3b574d82011-09-01 15:02:01 -0700341 /* write seg size */
342 *((uint32_t *)(pce_dev->ce_dm.buffer.seg_size)) = sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700343
Mona Hossain3b574d82011-09-01 15:02:01 -0700344 _ce_setup_hash_cmdrptrlist(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700345
Mona Hossain3b574d82011-09-01 15:02:01 -0700346 return 0;
347}
348
349static int _ce_setup_cipher_cmdrptrlist(struct qce_device *pce_dev,
350 struct qce_req *creq)
351{
352 struct ce_cmdptrlists_ops *cmdptrlist =
353 &pce_dev->ce_dm.cmdptrlist;
354
355 if (creq->alg != CIPHER_ALG_AES) {
356 switch (creq->alg) {
357 case CIPHER_ALG_DES:
358 if (creq->mode == QCE_MODE_ECB) {
359 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
360 cmdptrlist->cipher_des_ecb;
361 } else {
362 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
363 cmdptrlist->cipher_des_cbc;
364 }
365 break;
366
367 case CIPHER_ALG_3DES:
368 if (creq->mode == QCE_MODE_ECB) {
369 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
370 cmdptrlist->cipher_3des_ecb;
371 } else {
372 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
373 cmdptrlist->cipher_3des_cbc;
374 }
375 break;
376 default:
377 break;
378 }
379 } else {
380 switch (creq->mode) {
381 case QCE_MODE_ECB:
382 if (creq->encklen == AES128_KEY_SIZE) {
383 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
384 cmdptrlist->cipher_aes_128_ecb;
385 } else {
386 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
387 cmdptrlist->cipher_aes_256_ecb;
388 }
389 break;
390
391 case QCE_MODE_CBC:
392 if (creq->encklen == AES128_KEY_SIZE) {
393 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
394 cmdptrlist->cipher_aes_128_cbc_ctr;
395 } else {
396 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
397 cmdptrlist->cipher_aes_256_cbc_ctr;
398 }
399 break;
400
401 case QCE_MODE_CTR:
402 if (creq->encklen == AES128_KEY_SIZE) {
403 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
404 cmdptrlist->cipher_aes_128_cbc_ctr;
405 } else {
406 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
407 cmdptrlist->cipher_aes_256_cbc_ctr;
408 }
409 break;
410
411 case QCE_MODE_XTS:
412 if (creq->encklen == AES128_KEY_SIZE) {
413 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
414 cmdptrlist->cipher_aes_128_xts;
415 } else {
416 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
417 cmdptrlist->cipher_aes_256_xts;
418 }
419 break;
420 case QCE_MODE_CCM:
421 if (creq->encklen == AES128_KEY_SIZE) {
422 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
423 cmdptrlist->aead_aes_128_ccm;
424 } else {
425 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
426 cmdptrlist->aead_aes_256_ccm;
427 }
428 break;
429 default:
430 break;
431 }
432 }
433
434 if (creq->mode == QCE_MODE_CCM)
435 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
436 cmdptrlist->aead_ce_out;
437 else
438 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
439 cmdptrlist->cipher_ce_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700440
441 return 0;
442}
443
444static int _ce_setup_cipher(struct qce_device *pce_dev, struct qce_req *creq,
445 uint32_t totallen_in, uint32_t coffset)
446{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700447 uint32_t enck_size_in_word = creq->encklen / sizeof(uint32_t);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700448 uint32_t encr_cfg = 0;
449 uint32_t ivsize = creq->ivsize;
Mona Hossain3b574d82011-09-01 15:02:01 -0700450 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700451
452 if (creq->mode == QCE_MODE_XTS)
Mona Hossain3b574d82011-09-01 15:02:01 -0700453 memcpy(buffer->encr_key, creq->enckey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700454 creq->encklen/2);
455 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700456 memcpy(buffer->encr_key, creq->enckey, creq->encklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700457
458 if ((creq->op == QCE_REQ_AEAD) && (creq->mode == QCE_MODE_CCM)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700459 uint32_t noncelen32 = MAX_NONCE/sizeof(uint32_t);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700460 uint32_t auth_cfg = 0;
461
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700462 /* write nonce */
Mona Hossain3b574d82011-09-01 15:02:01 -0700463 memcpy(buffer->auth_nonce_info, creq->nonce, MAX_NONCE);
464 memcpy(buffer->auth_key, creq->enckey, creq->encklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700465
466 auth_cfg |= (noncelen32 << CRYPTO_AUTH_NONCE_NUM_WORDS);
467 auth_cfg &= ~(1 << CRYPTO_USE_HW_KEY_AUTH);
468 auth_cfg |= (1 << CRYPTO_LAST);
469 if (creq->dir == QCE_ENCRYPT)
470 auth_cfg |= (CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);
471 else
472 auth_cfg |= (CRYPTO_AUTH_POS_AFTER << CRYPTO_AUTH_POS);
473 auth_cfg |= (((creq->authsize >> 1) - 2) << CRYPTO_AUTH_SIZE);
474 auth_cfg |= (CRYPTO_AUTH_MODE_CCM << CRYPTO_AUTH_MODE);
475 if (creq->authklen == AES128_KEY_SIZE)
476 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES128 <<
477 CRYPTO_AUTH_KEY_SIZE);
478 else {
479 if (creq->authklen == AES256_KEY_SIZE)
480 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES256 <<
481 CRYPTO_AUTH_KEY_SIZE);
482 }
483 auth_cfg |= (CRYPTO_AUTH_ALG_AES << CRYPTO_AUTH_ALG);
Mona Hossain3b574d82011-09-01 15:02:01 -0700484 *((uint32_t *)(buffer->auth_seg_cfg_size_start)) = auth_cfg;
485
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700486 if (creq->dir == QCE_ENCRYPT)
Mona Hossain3b574d82011-09-01 15:02:01 -0700487 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 1) =
488 totallen_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700489 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700490 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 1) =
491 (totallen_in - creq->authsize);
492 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700493 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700494
495 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700496
497 switch (creq->mode) {
498 case QCE_MODE_ECB:
499 encr_cfg |= (CRYPTO_ENCR_MODE_ECB << CRYPTO_ENCR_MODE);
500 break;
501
502 case QCE_MODE_CBC:
503 encr_cfg |= (CRYPTO_ENCR_MODE_CBC << CRYPTO_ENCR_MODE);
504 break;
505
506 case QCE_MODE_XTS:
507 encr_cfg |= (CRYPTO_ENCR_MODE_XTS << CRYPTO_ENCR_MODE);
508 break;
509
510 case QCE_MODE_CCM:
511 encr_cfg |= (CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE);
512 break;
513
514 case QCE_MODE_CTR:
515 default:
516 encr_cfg |= (CRYPTO_ENCR_MODE_CTR << CRYPTO_ENCR_MODE);
517 break;
518 }
519 pce_dev->mode = creq->mode;
520
521 switch (creq->alg) {
522 case CIPHER_ALG_DES:
Mona Hossain3b574d82011-09-01 15:02:01 -0700523 if (creq->mode != QCE_MODE_ECB)
524 memcpy(buffer->encr_cntr_iv, creq->iv, ivsize);
525
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700526 encr_cfg |= ((CRYPTO_ENCR_KEY_SZ_DES << CRYPTO_ENCR_KEY_SZ) |
527 (CRYPTO_ENCR_ALG_DES << CRYPTO_ENCR_ALG));
528 break;
529
530 case CIPHER_ALG_3DES:
Mona Hossain3b574d82011-09-01 15:02:01 -0700531 if (creq->mode != QCE_MODE_ECB)
532 memcpy(buffer->encr_cntr_iv, creq->iv, ivsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700533
534 encr_cfg |= ((CRYPTO_ENCR_KEY_SZ_3DES << CRYPTO_ENCR_KEY_SZ) |
535 (CRYPTO_ENCR_ALG_DES << CRYPTO_ENCR_ALG));
536 break;
537
538 case CIPHER_ALG_AES:
539 default:
540 if (creq->mode == QCE_MODE_XTS) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700541 memcpy(buffer->encr_xts_key, (creq->enckey +
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700542 creq->encklen/2), creq->encklen/2);
Mona Hossain3b574d82011-09-01 15:02:01 -0700543 *((uint32_t *)(buffer->encr_xts_du_size)) =
544 creq->cryptlen;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700545
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700546 }
547 if (creq->mode != QCE_MODE_ECB) {
548 if (creq->mode == QCE_MODE_XTS)
Mona Hossain3b574d82011-09-01 15:02:01 -0700549 _byte_stream_swap_to_net_words(
550 (uint32_t *)(buffer->encr_cntr_iv),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700551 creq->iv, ivsize);
552 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700553 memcpy(buffer->encr_cntr_iv, creq->iv,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700554 ivsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700555 }
556 /* set number of counter bits */
Mona Hossain3b574d82011-09-01 15:02:01 -0700557 *((uint32_t *)(buffer->encr_mask)) = (uint32_t)0xffffffff;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700558
559 if (creq->op == QCE_REQ_ABLK_CIPHER_NO_KEY) {
560 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES128 <<
561 CRYPTO_ENCR_KEY_SZ);
562 encr_cfg |= CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG;
563 } else {
564 uint32_t key_size;
565
566 if (creq->mode == QCE_MODE_XTS) {
567 key_size = creq->encklen/2;
568 enck_size_in_word = key_size/sizeof(uint32_t);
569 } else {
570 key_size = creq->encklen;
571 }
572
573 switch (key_size) {
574 case AES128_KEY_SIZE:
575 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES128 <<
576 CRYPTO_ENCR_KEY_SZ);
577 break;
578 case AES256_KEY_SIZE:
579 default:
580 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES256 <<
581 CRYPTO_ENCR_KEY_SZ);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700582 break;
583 } /* end of switch (creq->encklen) */
584
585 encr_cfg |= CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700586 } /* else of if (creq->op == QCE_REQ_ABLK_CIPHER_NO_KEY) */
587 break;
588 } /* end of switch (creq->mode) */
589
590 /* write encr seg cfg */
591 encr_cfg |= ((creq->dir == QCE_ENCRYPT) ? 1 : 0) << CRYPTO_ENCODE;
592
593 /* write encr seg cfg */
Mona Hossain3b574d82011-09-01 15:02:01 -0700594 *((uint32_t *)(buffer->encr_seg_cfg_size_start)) = encr_cfg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700595 /* write encr seg size */
596 if ((creq->mode == QCE_MODE_CCM) && (creq->dir == QCE_DECRYPT))
Mona Hossain3b574d82011-09-01 15:02:01 -0700597 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 1) =
598 (creq->cryptlen + creq->authsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700599 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700600 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 1) =
601 creq->cryptlen;
602
603
604 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 2) =
605 (coffset & 0xffff);
606
607 *((uint32_t *)(buffer->seg_size)) = totallen_in;
608
609 _ce_setup_cipher_cmdrptrlist(pce_dev, creq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700610 return 0;
611};
612
613static int _aead_complete(struct qce_device *pce_dev)
614{
615 struct aead_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700616
617 areq = (struct aead_request *) pce_dev->areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700618
619 if (areq->src != areq->dst) {
620 dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
621 DMA_FROM_DEVICE);
622 }
623 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
624 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
625 DMA_TO_DEVICE);
626
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700627 dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
628 DMA_TO_DEVICE);
629
Mona Hossain3b574d82011-09-01 15:02:01 -0700630 /* check MAC */
631 if (pce_dev->mode == QCE_MODE_CCM) {
632 uint32_t result;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700633
Mona Hossain3b574d82011-09-01 15:02:01 -0700634 result =
635 (uint32_t)(*((uint32_t *)pce_dev->ce_dm.buffer.status));
636 result &= (1 << CRYPTO_MAC_FAILED);
637 result |= (pce_dev->ce_dm.chan_ce_in_status |
638 pce_dev->ce_dm.chan_ce_out_status);
639 pce_dev->qce_cb(areq, pce_dev->ce_dm.buffer.auth_result, NULL,
640 result);
641 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700642 return 0;
643};
644
645static void _sha_complete(struct qce_device *pce_dev)
646{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700647 struct ahash_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700648
649 areq = (struct ahash_request *) pce_dev->areq;
650 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
651 DMA_TO_DEVICE);
652
Mona Hossain3b574d82011-09-01 15:02:01 -0700653 pce_dev->qce_cb(areq, pce_dev->ce_dm.buffer.auth_result,
654 pce_dev->ce_dm.buffer.auth_byte_count,
655 pce_dev->ce_dm.chan_ce_in_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700656
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700657};
658
659static int _ablk_cipher_complete(struct qce_device *pce_dev)
660{
661 struct ablkcipher_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700662
663 areq = (struct ablkcipher_request *) pce_dev->areq;
664
665 if (areq->src != areq->dst) {
666 dma_unmap_sg(pce_dev->pdev, areq->dst,
667 pce_dev->dst_nents, DMA_FROM_DEVICE);
668 }
669 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
670 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
671 DMA_TO_DEVICE);
Mona Hossain3b574d82011-09-01 15:02:01 -0700672
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700673 if (pce_dev->mode == QCE_MODE_ECB) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700674 pce_dev->qce_cb(areq, NULL, NULL,
675 pce_dev->ce_dm.chan_ce_in_status |
676 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700677 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700678
Mona Hossain3b574d82011-09-01 15:02:01 -0700679 pce_dev->qce_cb(areq, NULL, pce_dev->ce_dm.buffer.encr_cntr_iv,
680 pce_dev->ce_dm.chan_ce_in_status |
681 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700682 }
683
684 return 0;
685};
686
687static int _ablk_cipher_use_pmem_complete(struct qce_device *pce_dev)
688{
689 struct ablkcipher_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700690
691 areq = (struct ablkcipher_request *) pce_dev->areq;
692
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700693 if (pce_dev->mode == QCE_MODE_ECB) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700694 pce_dev->qce_cb(areq, NULL, NULL,
695 pce_dev->ce_dm.chan_ce_in_status |
696 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700697 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700698 pce_dev->qce_cb(areq, NULL, pce_dev->ce_dm.buffer.encr_cntr_iv,
699 pce_dev->ce_dm.chan_ce_in_status |
700 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700701 }
702
703 return 0;
704};
705
706static int qce_split_and_insert_dm_desc(struct dmov_desc *pdesc,
707 unsigned int plen, unsigned int paddr, int *index)
708{
Mona Hossain3b574d82011-09-01 15:02:01 -0700709 while (plen > QCE_FIFO_SIZE) {
710 pdesc->len = QCE_FIFO_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700711 if (paddr > 0) {
712 pdesc->addr = paddr;
Mona Hossain3b574d82011-09-01 15:02:01 -0700713 paddr += QCE_FIFO_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700714 }
715 plen -= pdesc->len;
716 if (plen > 0) {
717 *index = (*index) + 1;
718 if ((*index) >= QCE_MAX_NUM_DESC)
719 return -ENOMEM;
720 pdesc++;
721 }
722 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700723 if ((plen > 0) && (plen <= QCE_FIFO_SIZE)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700724 pdesc->len = plen;
725 if (paddr > 0)
726 pdesc->addr = paddr;
727 }
728
729 return 0;
730}
731
732static int _chain_sg_buffer_in(struct qce_device *pce_dev,
733 struct scatterlist *sg, unsigned int nbytes)
734{
735 unsigned int len;
736 unsigned int dlen;
737 struct dmov_desc *pdesc;
738
Mona Hossain3b574d82011-09-01 15:02:01 -0700739 pdesc = pce_dev->ce_dm.ce_in_dst_desc +
740 pce_dev->ce_dm.ce_in_dst_desc_index;
741 if (nbytes > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700742 qce_split_and_insert_dm_desc(pdesc, nbytes, 0,
Mona Hossain3b574d82011-09-01 15:02:01 -0700743 &pce_dev->ce_dm.ce_in_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700744 else
745 pdesc->len = nbytes;
746
Mona Hossain3b574d82011-09-01 15:02:01 -0700747 pdesc = pce_dev->ce_dm.ce_in_src_desc +
748 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700749 /*
750 * Two consective chunks may be handled by the old
751 * buffer descriptor.
752 */
753 while (nbytes > 0) {
754 len = min(nbytes, sg_dma_len(sg));
755 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
756 nbytes -= len;
757 if (dlen == 0) {
758 pdesc->addr = sg_dma_address(sg);
759 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700760 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700761 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700762 sg_dma_address(sg),
763 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700764 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
765 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700766 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700767 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700768 pdesc->addr,
769 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700770 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700771 pce_dev->ce_dm.ce_in_src_desc_index++;
772 if (pce_dev->ce_dm.ce_in_src_desc_index >=
773 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700774 return -ENOMEM;
775 pdesc++;
776 pdesc->len = len;
777 pdesc->addr = sg_dma_address(sg);
Mona Hossain3b574d82011-09-01 15:02:01 -0700778 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700779 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700780 sg_dma_address(sg),
781 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700782 }
783 if (nbytes > 0)
784 sg = sg_next(sg);
785 }
786 return 0;
787}
788
789static int _chain_pm_buffer_in(struct qce_device *pce_dev,
790 unsigned int pmem, unsigned int nbytes)
791{
792 unsigned int dlen;
793 struct dmov_desc *pdesc;
794
Mona Hossain3b574d82011-09-01 15:02:01 -0700795 pdesc = pce_dev->ce_dm.ce_in_src_desc +
796 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700797 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
798 if (dlen == 0) {
799 pdesc->addr = pmem;
800 pdesc->len = nbytes;
801 } else if (pmem == (pdesc->addr + dlen)) {
802 pdesc->len = dlen + nbytes;
803 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700804 pce_dev->ce_dm.ce_in_src_desc_index++;
805 if (pce_dev->ce_dm.ce_in_src_desc_index >=
806 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700807 return -ENOMEM;
808 pdesc++;
809 pdesc->len = nbytes;
810 pdesc->addr = pmem;
811 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700812 pdesc = pce_dev->ce_dm.ce_in_dst_desc +
813 pce_dev->ce_dm.ce_in_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700814 pdesc->len += nbytes;
815
816 return 0;
817}
818
819static void _chain_buffer_in_init(struct qce_device *pce_dev)
820{
821 struct dmov_desc *pdesc;
822
Mona Hossain3b574d82011-09-01 15:02:01 -0700823 pce_dev->ce_dm.ce_in_src_desc_index = 0;
824 pce_dev->ce_dm.ce_in_dst_desc_index = 0;
825 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700826 pdesc->len = 0;
827}
828
829static void _ce_in_final(struct qce_device *pce_dev, unsigned total)
830{
831 struct dmov_desc *pdesc;
832 dmov_sg *pcmd;
833
Mona Hossain3b574d82011-09-01 15:02:01 -0700834 pdesc = pce_dev->ce_dm.ce_in_src_desc +
835 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700836 pdesc->len |= ADM_DESC_LAST;
Mona Hossain3b574d82011-09-01 15:02:01 -0700837 pdesc = pce_dev->ce_dm.ce_in_dst_desc +
838 pce_dev->ce_dm.ce_in_dst_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -0700839 if (total)
840 pdesc->len = ADM_DESC_LAST | total;
841 else
842 pdesc->len |= ADM_DESC_LAST;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700843
Mona Hossain3b574d82011-09-01 15:02:01 -0700844 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700845 pcmd->cmd |= CMD_LC;
Mona Hossain3b574d82011-09-01 15:02:01 -0700846
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700847}
848
849#ifdef QCE_DEBUG
850static void _ce_in_dump(struct qce_device *pce_dev)
851{
852 int i;
853 struct dmov_desc *pdesc;
854
855 dev_info(pce_dev->pdev, "_ce_in_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700856 for (i = 0; i <= pce_dev->ce_dm.ce_in_src_desc_index; i++) {
857 pdesc = pce_dev->ce_dm.ce_in_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700858 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
859 pdesc->len);
860 }
861 dev_info(pce_dev->pdev, "_ce_in_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700862 for (i = 0; i <= pce_dev->ce_dm.ce_in_dst_desc_index; i++) {
863 pdesc = pce_dev->ce_dm.ce_in_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700864 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
865 pdesc->len);
866 }
867};
868
869static void _ce_out_dump(struct qce_device *pce_dev)
870{
871 int i;
872 struct dmov_desc *pdesc;
873
874 dev_info(pce_dev->pdev, "_ce_out_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700875 for (i = 0; i <= pce_dev->ce_dm.ce_out_src_desc_index; i++) {
876 pdesc = pce_dev->ce_dm.ce_out_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700877 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
878 pdesc->len);
879 }
880
881 dev_info(pce_dev->pdev, "_ce_out_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700882 for (i = 0; i <= pce_dev->ce_dm.ce_out_dst_desc_index; i++) {
883 pdesc = pce_dev->ce_dm.ce_out_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700884 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
885 pdesc->len);
886 }
887};
888
889#else
890
891static void _ce_in_dump(struct qce_device *pce_dev)
892{
893};
894
895static void _ce_out_dump(struct qce_device *pce_dev)
896{
897};
898
899#endif
900
901static int _chain_sg_buffer_out(struct qce_device *pce_dev,
902 struct scatterlist *sg, unsigned int nbytes)
903{
904 unsigned int len;
905 unsigned int dlen;
906 struct dmov_desc *pdesc;
907
Mona Hossain3b574d82011-09-01 15:02:01 -0700908 pdesc = pce_dev->ce_dm.ce_out_src_desc +
909 pce_dev->ce_dm.ce_out_src_desc_index;
910 if (nbytes > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700911 qce_split_and_insert_dm_desc(pdesc, nbytes, 0,
Mona Hossain3b574d82011-09-01 15:02:01 -0700912 &pce_dev->ce_dm.ce_out_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700913 else
914 pdesc->len = nbytes;
915
Mona Hossain3b574d82011-09-01 15:02:01 -0700916 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
917 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700918 /*
919 * Two consective chunks may be handled by the old
920 * buffer descriptor.
921 */
922 while (nbytes > 0) {
923 len = min(nbytes, sg_dma_len(sg));
924 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
925 nbytes -= len;
926 if (dlen == 0) {
927 pdesc->addr = sg_dma_address(sg);
928 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700929 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700930 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
931 sg_dma_address(sg),
Mona Hossain3b574d82011-09-01 15:02:01 -0700932 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700933 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
934 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700935 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700936 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
937 pdesc->addr,
Mona Hossain3b574d82011-09-01 15:02:01 -0700938 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700939
940 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700941 pce_dev->ce_dm.ce_out_dst_desc_index++;
942 if (pce_dev->ce_dm.ce_out_dst_desc_index >=
943 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700944 return -EIO;
945 pdesc++;
946 pdesc->len = len;
947 pdesc->addr = sg_dma_address(sg);
Mona Hossain3b574d82011-09-01 15:02:01 -0700948 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700949 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
950 sg_dma_address(sg),
Mona Hossain3b574d82011-09-01 15:02:01 -0700951 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700952
953 }
954 if (nbytes > 0)
955 sg = sg_next(sg);
956 }
957 return 0;
958}
959
960static int _chain_pm_buffer_out(struct qce_device *pce_dev,
961 unsigned int pmem, unsigned int nbytes)
962{
963 unsigned int dlen;
964 struct dmov_desc *pdesc;
965
Mona Hossain3b574d82011-09-01 15:02:01 -0700966 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
967 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700968 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
969
970 if (dlen == 0) {
971 pdesc->addr = pmem;
972 pdesc->len = nbytes;
973 } else if (pmem == (pdesc->addr + dlen)) {
974 pdesc->len = dlen + nbytes;
975 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700976 pce_dev->ce_dm.ce_out_dst_desc_index++;
977 if (pce_dev->ce_dm.ce_out_dst_desc_index >= QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700978 return -EIO;
979 pdesc++;
980 pdesc->len = nbytes;
981 pdesc->addr = pmem;
982 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700983 pdesc = pce_dev->ce_dm.ce_out_src_desc +
984 pce_dev->ce_dm.ce_out_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700985 pdesc->len += nbytes;
986
987 return 0;
988};
989
990static void _chain_buffer_out_init(struct qce_device *pce_dev)
991{
992 struct dmov_desc *pdesc;
993
Mona Hossain3b574d82011-09-01 15:02:01 -0700994 pce_dev->ce_dm.ce_out_dst_desc_index = 0;
995 pce_dev->ce_dm.ce_out_src_desc_index = 0;
996 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700997 pdesc->len = 0;
998};
999
1000static void _ce_out_final(struct qce_device *pce_dev, unsigned total)
1001{
1002 struct dmov_desc *pdesc;
1003 dmov_sg *pcmd;
1004
Mona Hossain3b574d82011-09-01 15:02:01 -07001005 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
1006 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001007 pdesc->len |= ADM_DESC_LAST;
Mona Hossain3b574d82011-09-01 15:02:01 -07001008 pdesc = pce_dev->ce_dm.ce_out_src_desc +
1009 pce_dev->ce_dm.ce_out_src_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -07001010 if (total)
1011 pdesc->len = ADM_DESC_LAST | total;
1012 else
1013 pdesc->len |= ADM_DESC_LAST;
Mona Hossain3b574d82011-09-01 15:02:01 -07001014
1015 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001016 pcmd->cmd |= CMD_LC;
1017};
1018
1019static void _aead_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1020 unsigned int result, struct msm_dmov_errdata *err)
1021{
1022 struct qce_device *pce_dev;
1023
1024 pce_dev = (struct qce_device *) cmd_ptr->user;
1025 if (result != ADM_STATUS_OK) {
1026 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1027 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001028 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001029 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001030 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001031 }
1032
Mona Hossain3b574d82011-09-01 15:02:01 -07001033 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1034 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1035 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1036 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001037
1038 /* done */
1039 _aead_complete(pce_dev);
1040 }
1041};
1042
1043static void _aead_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1044 unsigned int result, struct msm_dmov_errdata *err)
1045{
1046 struct qce_device *pce_dev;
1047
1048 pce_dev = (struct qce_device *) cmd_ptr->user;
1049 if (result != ADM_STATUS_OK) {
1050 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1051 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001052 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001053 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001054 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001055 };
1056
Mona Hossain3b574d82011-09-01 15:02:01 -07001057 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1058 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1059 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1060 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001061
1062 /* done */
1063 _aead_complete(pce_dev);
1064 }
1065
1066};
1067
1068static void _sha_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1069 unsigned int result, struct msm_dmov_errdata *err)
1070{
1071 struct qce_device *pce_dev;
1072
1073 pce_dev = (struct qce_device *) cmd_ptr->user;
1074 if (result != ADM_STATUS_OK) {
1075 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1076 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001077 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001078 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001079 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001080 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001081 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001082 _sha_complete(pce_dev);
1083};
1084
1085static void _ablk_cipher_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1086 unsigned int result, struct msm_dmov_errdata *err)
1087{
1088 struct qce_device *pce_dev;
1089
1090 pce_dev = (struct qce_device *) cmd_ptr->user;
1091 if (result != ADM_STATUS_OK) {
1092 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1093 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001094 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001095 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001096 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001097 }
1098
Mona Hossain3b574d82011-09-01 15:02:01 -07001099 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1100 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1101 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1102 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001103
1104 /* done */
1105 _ablk_cipher_complete(pce_dev);
1106 }
1107};
1108
1109static void _ablk_cipher_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1110 unsigned int result, struct msm_dmov_errdata *err)
1111{
1112 struct qce_device *pce_dev;
1113
1114 pce_dev = (struct qce_device *) cmd_ptr->user;
Mona Hossain3b574d82011-09-01 15:02:01 -07001115
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001116 if (result != ADM_STATUS_OK) {
1117 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1118 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001119 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001120 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001121 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001122 };
1123
Mona Hossain3b574d82011-09-01 15:02:01 -07001124 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1125 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1126 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1127 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001128
1129 /* done */
1130 _ablk_cipher_complete(pce_dev);
1131 }
1132};
1133
1134
1135static void _ablk_cipher_ce_in_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1136 unsigned int result, struct msm_dmov_errdata *err)
1137{
1138 struct qce_device *pce_dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001139 pce_dev = (struct qce_device *) cmd_ptr->user;
1140 if (result != ADM_STATUS_OK) {
1141 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1142 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001143 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001144 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001145 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001146 }
1147
Mona Hossain3b574d82011-09-01 15:02:01 -07001148 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1149 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1150 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1151 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001152
1153 /* done */
1154 _ablk_cipher_use_pmem_complete(pce_dev);
1155 }
1156};
1157
1158static void _ablk_cipher_ce_out_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1159 unsigned int result, struct msm_dmov_errdata *err)
1160{
1161 struct qce_device *pce_dev;
1162
1163 pce_dev = (struct qce_device *) cmd_ptr->user;
1164 if (result != ADM_STATUS_OK) {
1165 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1166 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001167 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001168 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001169 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001170 };
1171
Mona Hossain3b574d82011-09-01 15:02:01 -07001172 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1173 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1174 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1175 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001176
1177 /* done */
1178 _ablk_cipher_use_pmem_complete(pce_dev);
1179 }
1180};
1181
Mona Hossain3b574d82011-09-01 15:02:01 -07001182static int qce_setup_cmd_buffers(struct qce_device *pce_dev,
1183 unsigned char **pvaddr)
1184{
1185 struct ce_reg_buffers *addr = (struct ce_reg_buffers *)(*pvaddr);
1186 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
1187
1188 /*
1189 * Designate chunks of the allocated memory to various
1190 * buffer pointers
1191 */
1192 buffer->reset_buf_64 = addr->reset_buf_64;
1193 buffer->version = addr->version;
1194 buffer->encr_seg_cfg_size_start = addr->encr_seg_cfg_size_start;
1195 buffer->encr_key = addr->encr_key;
1196 buffer->encr_xts_key = addr->encr_xts_key;
1197 buffer->encr_xts_du_size = addr->encr_xts_du_size;
1198 buffer->encr_cntr_iv = addr->encr_cntr_iv;
1199 buffer->encr_mask = addr->encr_mask;
1200 buffer->auth_seg_cfg_size_start = addr->auth_seg_cfg_size_start;
1201 buffer->auth_key = addr->auth_key;
1202 buffer->auth_iv = addr->auth_iv;
1203 buffer->auth_result = addr->auth_result;
1204 buffer->auth_nonce_info = addr->auth_nonce_info;
1205 buffer->auth_byte_count = addr->auth_byte_count;
1206 buffer->seg_size = addr->seg_size;
1207 buffer->go_proc = addr->go_proc;
1208 buffer->status = addr->status;
1209 buffer->pad = addr->pad;
1210
1211 memset(buffer->reset_buf_64, 0, 64);
1212 *((uint32_t *)buffer->encr_mask) = (uint32_t)(0xffffffff);
1213 *((uint32_t *)buffer->go_proc) = (uint32_t)(1 << CRYPTO_GO);
1214
1215 *pvaddr += sizeof(struct ce_reg_buffers);
1216
1217 return 0;
1218
1219}
1220
1221static int _setup_cipher_cmdlists(struct qce_device *pce_dev,
1222 unsigned char **pvaddr)
1223{
1224 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1225
1226 /*
1227 * Designate chunks of the allocated memory to various
1228 * command list pointers related to cipher operation
1229 */
1230 pce_dev->ce_dm.cmdlist.set_cipher_cfg = pscmd;
1231 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1232 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG +
1233 pce_dev->phy_iobase);
1234 pscmd->len = CRYPTO_REG_SIZE * 3;
1235 pscmd->src =
1236 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_seg_cfg_size_start);
1237 pscmd++;
1238
1239 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_key = pscmd;
1240 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1241 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1242 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1243 pscmd->len = CRYPTO_REG_SIZE * 4;
1244 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1245 pscmd++;
1246
1247 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_key = pscmd;
1248 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1249 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1250 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1251 pscmd->len = CRYPTO_REG_SIZE * 8;
1252 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1253 pscmd++;
1254
1255 pce_dev->ce_dm.cmdlist.set_cipher_des_key = pscmd;
1256 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1257 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1258 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1259 pscmd->len = CRYPTO_REG_SIZE * 2;
1260 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1261 pscmd++;
1262
1263 pce_dev->ce_dm.cmdlist.set_cipher_3des_key = pscmd;
1264 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1265 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1266 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1267 pscmd->len = CRYPTO_REG_SIZE * 6;
1268 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1269 pscmd++;
1270
1271 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_xts_key = pscmd;
1272 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1273 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1274 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1275 pce_dev->phy_iobase);
1276 pscmd->len = CRYPTO_REG_SIZE * 4;
1277 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1278 pscmd++;
1279
1280 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_xts_key = pscmd;
1281 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1282 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1283 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1284 pce_dev->phy_iobase);
1285 pscmd->len = CRYPTO_REG_SIZE * 8;
1286 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1287 pscmd++;
1288
1289 pce_dev->ce_dm.cmdlist.set_cipher_xts_du_size = pscmd;
1290 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1291 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_DU_SIZE_REG +
1292 pce_dev->phy_iobase);
1293 pscmd->len = CRYPTO_REG_SIZE * 4;
1294 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_du_size);
1295 pscmd++;
1296
1297 pce_dev->ce_dm.cmdlist.set_cipher_aes_iv = pscmd;
1298 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1299 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1300 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1301 pscmd->len = CRYPTO_REG_SIZE * 4;
1302 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1303 pscmd++;
1304
1305 pce_dev->ce_dm.cmdlist.get_cipher_aes_iv = pscmd;
1306 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1307 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1308 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1309 pscmd->len = CRYPTO_REG_SIZE * 4;
1310 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1311 pscmd++;
1312
1313 pce_dev->ce_dm.cmdlist.get_cipher_aes_xts_iv = pscmd;
1314 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1315 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1316 pscmd->len = CRYPTO_REG_SIZE * 4;
1317 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1318 pscmd++;
1319
1320 pce_dev->ce_dm.cmdlist.set_cipher_des_iv = pscmd;
1321 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1322 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1323 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1324 pscmd->len = CRYPTO_REG_SIZE * 2;
1325 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1326 pscmd++;
1327
1328 pce_dev->ce_dm.cmdlist.get_cipher_des_iv = pscmd;
1329 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1330 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1331 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1332 pscmd->len = CRYPTO_REG_SIZE * 2;
1333 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1334 pscmd++;
1335
1336 pce_dev->ce_dm.cmdlist.set_cipher_mask = pscmd;
1337 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1338 pscmd->dst = (unsigned) (CRYPTO_CNTR_MASK_REG + pce_dev->phy_iobase);
1339 pscmd->len = CRYPTO_REG_SIZE;
1340 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_mask);
1341 pscmd++;
1342
1343 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1344
1345 pce_dev->ce_dm.cmdlist.reset_cipher_key = pscmd;
1346 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1347 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1348 pscmd->len = CRYPTO_REG_SIZE * 8;
1349 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1350 pscmd++;
1351
1352 pce_dev->ce_dm.cmdlist.reset_cipher_xts_key = pscmd;
1353 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1354 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1355 pce_dev->phy_iobase);
1356 pscmd->len = CRYPTO_REG_SIZE * 8;
1357 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1358 pscmd++;
1359
1360 pce_dev->ce_dm.cmdlist.reset_cipher_iv = pscmd;
1361 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1362 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1363 pscmd->len = CRYPTO_REG_SIZE * 4;
1364 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1365 pscmd++;
1366
1367 pce_dev->ce_dm.cmdlist.reset_cipher_cfg = pscmd;
1368 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1369 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG + pce_dev->phy_iobase);
1370 pscmd->len = CRYPTO_REG_SIZE;
1371 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1372 pscmd++;
1373
1374 *pvaddr = (unsigned char *) pscmd;
1375
1376 return 0;
1377}
1378
1379static int _setup_auth_cmdlists(struct qce_device *pce_dev,
1380 unsigned char **pvaddr)
1381{
1382 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1383
1384 /*
1385 * Designate chunks of the allocated memory to various
1386 * command list pointers related to authentication operation
1387 */
1388 pce_dev->ce_dm.cmdlist.set_auth_cfg = pscmd;
1389 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1390 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1391 pscmd->len = CRYPTO_REG_SIZE * 3;
1392 pscmd->src =
1393 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start);
1394 pscmd++;
1395
1396 pce_dev->ce_dm.cmdlist.set_auth_key_128 = pscmd;
1397 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1398 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1399 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1400 pscmd->len = CRYPTO_REG_SIZE * 4;
1401 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1402 pscmd++;
1403
1404 pce_dev->ce_dm.cmdlist.set_auth_key_256 = pscmd;
1405 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1406 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1407 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1408 pscmd->len = CRYPTO_REG_SIZE * 8;
1409 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1410 pscmd++;
1411
1412 pce_dev->ce_dm.cmdlist.set_auth_key_512 = pscmd;
1413 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1414 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1415 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1416 pscmd->len = CRYPTO_REG_SIZE * 16;
1417 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1418 pscmd++;
1419
1420 pce_dev->ce_dm.cmdlist.set_auth_iv_16 = pscmd;
1421 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1422 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1423 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1424 pscmd->len = CRYPTO_REG_SIZE * 4;
1425 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1426 pscmd++;
1427
1428 pce_dev->ce_dm.cmdlist.get_auth_result_16 = pscmd;
1429 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1430 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1431 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1432 pscmd->len = CRYPTO_REG_SIZE * 4;
1433 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1434 pscmd++;
1435
1436 pce_dev->ce_dm.cmdlist.set_auth_iv_20 = pscmd;
1437 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1438 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1439 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1440 pscmd->len = CRYPTO_REG_SIZE * 5;
1441 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1442 pscmd++;
1443
1444 pce_dev->ce_dm.cmdlist.get_auth_result_20 = pscmd;
1445 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1446 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1447 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1448 pscmd->len = CRYPTO_REG_SIZE * 5;
1449 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1450 pscmd++;
1451
1452 pce_dev->ce_dm.cmdlist.set_auth_iv_32 = pscmd;
1453 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1454 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1455 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1456 pscmd->len = CRYPTO_REG_SIZE * 8;
1457 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1458 pscmd++;
1459
1460
1461 pce_dev->ce_dm.cmdlist.get_auth_result_32 = pscmd;
1462 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1463 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1464 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1465 pscmd->len = CRYPTO_REG_SIZE * 8;
1466 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1467 pscmd++;
1468
1469 pce_dev->ce_dm.cmdlist.set_auth_byte_count = pscmd;
1470 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1471 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1472 pce_dev->phy_iobase);
1473 pscmd->len = CRYPTO_REG_SIZE * 4;
1474 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1475 pscmd++;
1476
1477 pce_dev->ce_dm.cmdlist.get_auth_byte_count = pscmd;
1478 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1479 pscmd->src = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1480 pce_dev->phy_iobase);
1481 pscmd->len = CRYPTO_REG_SIZE * 4;
1482 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1483 pscmd++;
1484
1485 pce_dev->ce_dm.cmdlist.set_auth_nonce_info = pscmd;
1486 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1487 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1488 pscmd->dst = (unsigned) (CRYPTO_AUTH_INFO_NONCE0_REG +
1489 pce_dev->phy_iobase);
1490 pscmd->len = CRYPTO_REG_SIZE * 4;
1491 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_nonce_info);
1492 pscmd++;
1493
1494 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1495
1496 pce_dev->ce_dm.cmdlist.reset_auth_key = pscmd;
1497 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1498 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1499 pscmd->len = CRYPTO_REG_SIZE * 16;
1500 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1501 pscmd++;
1502
1503 pce_dev->ce_dm.cmdlist.reset_auth_iv = pscmd;
1504 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1505 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1506 pscmd->len = CRYPTO_REG_SIZE * 16;
1507 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1508 pscmd++;
1509
1510 pce_dev->ce_dm.cmdlist.reset_auth_cfg = pscmd;
1511 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1512 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1513 pscmd->len = CRYPTO_REG_SIZE;
1514 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1515 pscmd++;
1516
1517
1518 pce_dev->ce_dm.cmdlist.reset_auth_byte_count = pscmd;
1519 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1520 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1521 pce_dev->phy_iobase);
1522 pscmd->len = CRYPTO_REG_SIZE * 4;
1523 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1524 pscmd++;
1525
1526 /* WAIT UNTIL MAC OP IS DONE*/
1527
1528 pce_dev->ce_dm.cmdlist.get_status_wait = pscmd;
1529 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1530 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1531 pscmd->len = CRYPTO_REG_SIZE;
1532 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1533 pscmd++;
1534
1535 *pvaddr = (unsigned char *) pscmd;
1536
1537 return 0;
1538}
1539
1540static int qce_setup_cmdlists(struct qce_device *pce_dev,
1541 unsigned char **pvaddr)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001542{
1543 dmov_sg *pcmd;
Mona Hossain3b574d82011-09-01 15:02:01 -07001544 dmov_s *pscmd;
1545 unsigned char *vaddr = *pvaddr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001546 struct dmov_desc *pdesc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001547 int i = 0;
1548
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001549 /*
Mona Hossain3b574d82011-09-01 15:02:01 -07001550 * Designate chunks of the allocated memory to various
1551 * command list pointers related to operation define
1552 * in ce_cmdlists structure.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001553 */
Mona Hossain3b574d82011-09-01 15:02:01 -07001554 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
1555 *pvaddr = (unsigned char *) vaddr;
1556
1557 _setup_cipher_cmdlists(pce_dev, pvaddr);
1558 _setup_auth_cmdlists(pce_dev, pvaddr);
1559
1560 pscmd = (dmov_s *)(*pvaddr);
1561
1562 /* GET HW VERSION COMMAND LIST */
1563 pce_dev->ce_dm.cmdlist.get_hw_version = pscmd;
1564 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1565 pscmd->src = (unsigned) (CRYPTO_VERSION_REG + pce_dev->phy_iobase);
1566 pscmd->len = CRYPTO_REG_SIZE;
1567 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.version);
1568 pscmd++;
1569
1570
1571 /* SET SEG SIZE REGISTER and OCB COMMAND LIST */
1572 pce_dev->ce_dm.cmdlist.set_seg_size_ocb = pscmd;
1573 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1574 pscmd->dst = (unsigned) (CRYPTO_SEG_SIZE_REG + pce_dev->phy_iobase);
1575 pscmd->len = CRYPTO_REG_SIZE;
1576 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.seg_size);
1577 pscmd++;
1578
1579
1580 /* OCU COMMAND LIST */
1581 pce_dev->ce_dm.cmdlist.get_status_ocu = pscmd;
1582 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCU;
1583 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1584 pscmd->len = CRYPTO_REG_SIZE;
1585 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1586 pscmd++;
1587
1588 /* SET GO_PROC REGISTERS COMMAND LIST */
1589 pce_dev->ce_dm.cmdlist.set_go_proc = pscmd;
1590 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1591 pscmd->dst = (unsigned) (CRYPTO_GOPROC_REG + pce_dev->phy_iobase);
1592 pscmd->len = CRYPTO_REG_SIZE;
1593 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.go_proc);
1594 pscmd++;
1595
1596 pcmd = (dmov_sg *)pscmd;
1597 pce_dev->ce_dm.cmdlist.ce_data_in = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001598 /* swap byte and half word , dst crci , scatter gather */
1599 pcmd->cmd = CMD_DST_SWAP_BYTES | CMD_DST_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001600 CMD_DST_CRCI(pce_dev->ce_dm.crci_in) | CMD_MODE_SG;
1601
1602 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001603 pdesc->addr = 0; /* to be filled in each operation */
1604 pdesc->len = 0; /* to be filled in each operation */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001605
Mona Hossain3b574d82011-09-01 15:02:01 -07001606 pdesc = pce_dev->ce_dm.ce_in_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001607 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1608 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1609 pdesc->len = 0; /* to be filled in each operation */
1610 pdesc++;
1611 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001612 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_src_desc);
1613 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001614 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1615 DST_INDEX_SG_CMD(0);
Mona Hossain3b574d82011-09-01 15:02:01 -07001616
1617
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001618 pcmd++;
Mona Hossain3b574d82011-09-01 15:02:01 -07001619 pce_dev->ce_dm.cmdlist.ce_data_out = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001620 /* swap byte, half word, source crci, scatter gather */
1621 pcmd->cmd = CMD_SRC_SWAP_BYTES | CMD_SRC_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001622 CMD_SRC_CRCI(pce_dev->ce_dm.crci_out) | CMD_MODE_SG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001623
Mona Hossain3b574d82011-09-01 15:02:01 -07001624 pdesc = pce_dev->ce_dm.ce_out_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001625 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1626 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1627 pdesc->len = 0; /* to be filled in each operation */
1628 pdesc++;
1629 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001630
Mona Hossain3b574d82011-09-01 15:02:01 -07001631 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001632 pdesc->addr = 0; /* to be filled in each operation */
1633 pdesc->len = 0; /* to be filled in each operation */
Mona Hossain3b574d82011-09-01 15:02:01 -07001634
1635 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_src_desc);
1636 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001637 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1638 DST_INDEX_SG_CMD(0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001639 pcmd++;
1640
Mona Hossain3b574d82011-09-01 15:02:01 -07001641 *pvaddr = (unsigned char *) pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001642
1643 return 0;
Mona Hossain3b574d82011-09-01 15:02:01 -07001644}
1645
1646static int _setup_cipher_cmdptrlists(struct qce_device *pce_dev,
1647 unsigned char **pvaddr)
1648{
1649 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1650 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1651 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1652
1653 /*
1654 * Designate chunks of the allocated memory to various
1655 * command list pointers related to cipher operations defined
1656 * in ce_cmdptrlists_ops structure.
1657 */
1658 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1659 cmdptrlist->cipher_aes_128_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1660
1661 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1662 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1663 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1664 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1665 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1666 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1667 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1668 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1669 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_iv);
1670
1671 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1672 cmdptrlist->cipher_aes_256_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1673
1674 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1675 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1676 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1677 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1678 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1679 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1680 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1681 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1682 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_iv);
1683
1684 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1685 cmdptrlist->cipher_aes_128_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1686
1687 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1688 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1689 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1690 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1691 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1692 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1693 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1694
1695 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1696 cmdptrlist->cipher_aes_256_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1697
1698 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1699 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1700 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1701 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1702 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1703 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1704 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1705
1706 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1707 cmdptrlist->cipher_aes_128_xts = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1708
1709 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1710 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1711 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1712 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_xts_key);
1713 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1714 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1715 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
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_CMD_PTR(cmdlist->ce_data_in);
1719 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_xts_iv);
1720
1721 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1722 cmdptrlist->cipher_aes_256_xts = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1723
1724 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1725 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1726 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1727 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_xts_key);
1728 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1729 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1730 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
1731 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1732 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1733 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1734 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_xts_iv);
1735
1736 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1737 cmdptrlist->cipher_des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1738
1739 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1740 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1741 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1742 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1743 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1744 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1745 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1746 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_des_iv);
1747
1748 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1749 cmdptrlist->cipher_des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1750
1751 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1752 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1753 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1754 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1755 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1756 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1757
1758 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1759 cmdptrlist->cipher_3des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1760
1761 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1762 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1763 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1764 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1765 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1766 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1767 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1768 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_des_iv);
1769
1770 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1771 cmdptrlist->cipher_3des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1772
1773 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1774 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1775 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1776 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1777 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1778 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1779
1780 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1781 cmdptrlist->cipher_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1782
1783 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1784 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1785 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1786
1787 return 0;
1788}
1789
1790static int _setup_auth_cmdptrlists(struct qce_device *pce_dev,
1791 unsigned char **pvaddr)
1792{
1793 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1794 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1795 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1796
1797 /*
1798 * Designate chunks of the allocated memory to various
1799 * command list pointers related to authentication operations
1800 * defined in ce_cmdptrlists_ops structure.
1801 */
1802 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1803 cmdptrlist->auth_sha1 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1804
1805 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1806 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1807 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1808 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1809 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1810 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1811 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1812 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1813 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1814 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1815 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1816 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1817
1818 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1819 cmdptrlist->auth_sha256 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1820
1821 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1822 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1823 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1824 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1825 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1826 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1827 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1828 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1829 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1830 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1831 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1832 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1833
1834 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1835 cmdptrlist->auth_sha1_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1836
1837 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1838 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1839 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1840 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1841 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1842 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1843 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1844 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1845 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1846 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1847 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1848 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1849 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1850
1851 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1852 cmdptrlist->auth_sha256_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1853
1854 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1855 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1856 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1857 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1858 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1859 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1860 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1861 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1862 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1863 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1864 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1865 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1866 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1867
1868 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1869 cmdptrlist->auth_aes_128_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1870
1871 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1872 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1873 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1874 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1875 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1876 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1877 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1878 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1879 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1880 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1881 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1882 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1883 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1884 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1885
1886 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1887 cmdptrlist->auth_aes_256_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1888
1889 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1890 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1891 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1892 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1893 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1894 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1895 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1896 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1897 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1898 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1899 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1900 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1901 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1902 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1903
1904 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1905
1906 return 0;
1907}
1908
1909static int _setup_aead_cmdptrlists(struct qce_device *pce_dev,
1910 unsigned char **pvaddr)
1911{
1912 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1913 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1914 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1915
1916 /*
1917 * Designate chunks of the allocated memory to various
1918 * command list pointers related to aead operations
1919 * defined in ce_cmdptrlists_ops structure.
1920 */
1921 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1922 cmdptrlist->aead_aes_128_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1923
1924 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1925 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1926 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1927 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1928 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1929 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1930 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1931 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1932 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1933 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1934 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1935 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1936 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1937
1938 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1939 cmdptrlist->aead_aes_256_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1940
1941 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1942 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1943 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1944 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1945 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1946 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1947 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1948 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1949 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1950 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1951 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1952 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1953 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1954
1955 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1956 cmdptrlist->aead_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1957
1958 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1959 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1960 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1961 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1962
1963 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1964
1965 return 0;
1966}
1967
1968static int qce_setup_cmdptrlists(struct qce_device *pce_dev,
1969 unsigned char **pvaddr)
1970{
1971 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1972 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1973 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1974 /*
1975 * Designate chunks of the allocated memory to various
1976 * command list pointers related to operations defined
1977 * in ce_cmdptrlists_ops structure.
1978 */
1979 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1980 cmdptrlist->probe_ce_hw = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1981
1982 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_hw_version);
1983 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1984
1985 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1986
1987 _setup_cipher_cmdptrlists(pce_dev, pvaddr);
1988 _setup_auth_cmdptrlists(pce_dev, pvaddr);
1989 _setup_aead_cmdptrlists(pce_dev, pvaddr);
1990
1991 return 0;
1992}
1993
1994
1995static int qce_setup_ce_dm_data(struct qce_device *pce_dev)
1996{
1997 unsigned char *vaddr;
1998
1999 /* 1. ce_in channel data xfer command src descriptors, 128 entries */
2000 vaddr = pce_dev->coh_vmem;
2001 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2002 pce_dev->ce_dm.ce_in_src_desc = (struct dmov_desc *) vaddr;
2003 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2004
2005 /* 2. ce_in channel data xfer command dst descriptors, 128 entries */
2006 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2007 pce_dev->ce_dm.ce_in_dst_desc = (struct dmov_desc *) vaddr;
2008 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2009
2010
2011 /* 3. ce_out channel data xfer command src descriptors, 128 entries */
2012 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2013 pce_dev->ce_dm.ce_out_src_desc = (struct dmov_desc *) vaddr;
2014 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2015
2016 /* 4. ce_out channel data xfer command dst descriptors, 128 entries. */
2017 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2018 pce_dev->ce_dm.ce_out_dst_desc = (struct dmov_desc *) vaddr;
2019 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2020
2021 qce_setup_cmd_buffers(pce_dev, &vaddr);
2022 qce_setup_cmdlists(pce_dev, &vaddr);
2023 qce_setup_cmdptrlists(pce_dev, &vaddr);
2024
2025 pce_dev->ce_dm.buffer.ignore_data = vaddr;
2026
2027 pce_dev->ce_dm.phy_ce_pad = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.pad);
2028 pce_dev->ce_dm.phy_ce_out_ignore =
2029 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.ignore_data);
2030
2031 pce_dev->ce_dm.chan_ce_in_cmd->user = (void *) pce_dev;
2032 pce_dev->ce_dm.chan_ce_in_cmd->exec_func = NULL;
2033
2034 pce_dev->ce_dm.chan_ce_out_cmd->user = (void *) pce_dev;
2035 pce_dev->ce_dm.chan_ce_out_cmd->exec_func = NULL;
2036
2037 return 0;
2038}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002039
2040static int _qce_start_dma(struct qce_device *pce_dev, bool ce_in, bool ce_out)
2041{
2042
2043 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002044 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002045 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002046 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002047
2048 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002049 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002050 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002051 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002052
2053 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002054 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
2055 pce_dev->ce_dm.chan_ce_in_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002056 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002057 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_out,
2058 pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002059
2060 return 0;
2061};
2062
2063int qce_aead_req(void *handle, struct qce_req *q_req)
2064{
2065 struct qce_device *pce_dev = (struct qce_device *) handle;
2066 struct aead_request *areq = (struct aead_request *) q_req->areq;
2067 uint32_t authsize = q_req->authsize;
2068 uint32_t totallen_in, totallen_out, out_len;
2069 uint32_t pad_len_in, pad_len_out;
2070 uint32_t pad_mac_len_out, pad_ptx_len_out;
2071 int rc = 0;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002072 int ce_block_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002073
Mona Hossain5f5dde12011-09-12 10:28:34 -07002074 ce_block_size = pce_dev->ce_dm.ce_block_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002075 if (q_req->dir == QCE_ENCRYPT) {
2076 q_req->cryptlen = areq->cryptlen;
2077 totallen_in = q_req->cryptlen + areq->assoclen;
2078 totallen_out = q_req->cryptlen + authsize + areq->assoclen;
2079 out_len = areq->cryptlen + authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002080 pad_len_in = ALIGN(totallen_in, ce_block_size) - totallen_in;
2081 pad_mac_len_out = ALIGN(authsize, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002082 authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002083 pad_ptx_len_out = ALIGN(q_req->cryptlen, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002084 q_req->cryptlen;
2085 pad_len_out = pad_ptx_len_out + pad_mac_len_out;
2086 totallen_out += pad_len_out;
2087 } else {
2088 q_req->cryptlen = areq->cryptlen - authsize;
2089 totallen_in = areq->cryptlen + areq->assoclen;
2090 totallen_out = q_req->cryptlen + areq->assoclen;
2091 out_len = areq->cryptlen - authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002092 pad_len_in = ALIGN(areq->cryptlen, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002093 areq->cryptlen;
2094 pad_len_out = pad_len_in + authsize;
2095 totallen_out += pad_len_out;
2096 }
2097
2098 _chain_buffer_in_init(pce_dev);
2099 _chain_buffer_out_init(pce_dev);
2100
2101 pce_dev->assoc_nents = 0;
2102 pce_dev->src_nents = 0;
2103 pce_dev->dst_nents = 0;
2104 pce_dev->ivsize = q_req->ivsize;
2105 pce_dev->authsize = q_req->authsize;
2106
2107 /* associated data input */
2108 pce_dev->assoc_nents = count_sg(areq->assoc, areq->assoclen);
2109 dma_map_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
2110 DMA_TO_DEVICE);
2111 if (_chain_sg_buffer_in(pce_dev, areq->assoc, areq->assoclen) < 0) {
2112 rc = -ENOMEM;
2113 goto bad;
2114 }
2115 /* cipher input */
2116 pce_dev->src_nents = count_sg(areq->src, areq->cryptlen);
2117 dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2118 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2119 DMA_TO_DEVICE);
2120 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->cryptlen) < 0) {
2121 rc = -ENOMEM;
2122 goto bad;
2123 }
2124 /* pad data in */
2125 if (pad_len_in) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002126 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002127 pad_len_in) < 0) {
2128 rc = -ENOMEM;
2129 goto bad;
2130 }
2131 }
2132
2133 /* ignore associated data */
Mona Hossain3b574d82011-09-01 15:02:01 -07002134 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_out_ignore,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002135 areq->assoclen) < 0) {
2136 rc = -ENOMEM;
2137 goto bad;
2138 }
2139 /* cipher + mac output for encryption */
2140 if (areq->src != areq->dst) {
2141 pce_dev->dst_nents = count_sg(areq->dst, out_len);
2142 dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2143 DMA_FROM_DEVICE);
2144 };
2145 if (_chain_sg_buffer_out(pce_dev, areq->dst, out_len) < 0) {
2146 rc = -ENOMEM;
2147 goto bad;
2148 }
2149 /* pad data out */
2150 if (pad_len_out) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002151 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002152 pad_len_out) < 0) {
2153 rc = -ENOMEM;
2154 goto bad;
2155 }
2156 }
2157
2158 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain5f5dde12011-09-12 10:28:34 -07002159 _ce_in_final(pce_dev, ALIGN(totallen_in, ce_block_size));
2160 _ce_out_final(pce_dev, ALIGN(totallen_out, ce_block_size));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002161
2162 /* set up crypto device */
2163 rc = _ce_setup_cipher(pce_dev, q_req, totallen_in, areq->assoclen);
2164 if (rc < 0)
2165 goto bad;
2166
2167 /* setup for callback, and issue command to adm */
2168 pce_dev->areq = q_req->areq;
2169 pce_dev->qce_cb = q_req->qce_cb;
2170
Mona Hossain3b574d82011-09-01 15:02:01 -07002171 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _aead_ce_in_call_back;
2172 pce_dev->ce_dm.chan_ce_out_cmd->complete_func = _aead_ce_out_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002173
2174 _ce_in_dump(pce_dev);
2175 _ce_out_dump(pce_dev);
2176
2177 rc = _qce_start_dma(pce_dev, true, true);
2178 if (rc == 0)
2179 return 0;
2180bad:
2181 if (pce_dev->assoc_nents) {
2182 dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
2183 DMA_TO_DEVICE);
2184 }
2185
2186 if (pce_dev->src_nents) {
2187 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2188 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2189 DMA_TO_DEVICE);
2190 }
2191 if (pce_dev->dst_nents) {
2192 dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2193 DMA_FROM_DEVICE);
2194 }
2195 return rc;
2196}
2197EXPORT_SYMBOL(qce_aead_req);
2198
2199int qce_ablk_cipher_req(void *handle, struct qce_req *c_req)
2200{
2201 int rc = 0;
2202 struct qce_device *pce_dev = (struct qce_device *) handle;
2203 struct ablkcipher_request *areq = (struct ablkcipher_request *)
2204 c_req->areq;
2205
Mona Hossain5f5dde12011-09-12 10:28:34 -07002206 uint32_t pad_len = ALIGN(areq->nbytes, pce_dev->ce_dm.ce_block_size)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002207 - areq->nbytes;
2208
2209 _chain_buffer_in_init(pce_dev);
2210 _chain_buffer_out_init(pce_dev);
2211
2212 pce_dev->src_nents = 0;
2213 pce_dev->dst_nents = 0;
2214
2215 /* cipher input */
2216 pce_dev->src_nents = count_sg(areq->src, areq->nbytes);
2217
2218 if (c_req->use_pmem != 1)
2219 dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2220 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2221 DMA_TO_DEVICE);
2222 else
2223 dma_map_pmem_sg(&c_req->pmem->src[0], pce_dev->src_nents,
2224 areq->src);
2225
2226 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->nbytes) < 0) {
2227 rc = -ENOMEM;
2228 goto bad;
2229 }
2230
2231 /* cipher output */
2232 if (areq->src != areq->dst) {
2233 pce_dev->dst_nents = count_sg(areq->dst, areq->nbytes);
2234 if (c_req->use_pmem != 1)
2235 dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2236 DMA_FROM_DEVICE);
2237 else
2238 dma_map_pmem_sg(&c_req->pmem->dst[0],
2239 pce_dev->dst_nents, areq->dst);
2240 };
2241 if (_chain_sg_buffer_out(pce_dev, areq->dst, areq->nbytes) < 0) {
2242 rc = -ENOMEM;
2243 goto bad;
2244 }
2245
2246 /* pad data */
2247 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002248 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002249 pad_len) < 0) {
2250 rc = -ENOMEM;
2251 goto bad;
2252 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002253 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002254 pad_len) < 0) {
2255 rc = -ENOMEM;
2256 goto bad;
2257 }
2258 }
2259
2260 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain390d92e2011-09-02 14:15:47 -07002261 _ce_in_final(pce_dev, 0);
2262 _ce_out_final(pce_dev, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002263
2264 _ce_in_dump(pce_dev);
2265 _ce_out_dump(pce_dev);
2266
2267 /* set up crypto device */
2268 rc = _ce_setup_cipher(pce_dev, c_req, areq->nbytes, 0);
2269 if (rc < 0)
2270 goto bad;
2271
2272 /* setup for callback, and issue command to adm */
2273 pce_dev->areq = areq;
2274 pce_dev->qce_cb = c_req->qce_cb;
2275 if (c_req->use_pmem == 1) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002276 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002277 _ablk_cipher_ce_in_call_back_pmem;
Mona Hossain3b574d82011-09-01 15:02:01 -07002278 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002279 _ablk_cipher_ce_out_call_back_pmem;
2280 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07002281 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002282 _ablk_cipher_ce_in_call_back;
Mona Hossain3b574d82011-09-01 15:02:01 -07002283 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002284 _ablk_cipher_ce_out_call_back;
2285 }
2286 rc = _qce_start_dma(pce_dev, true, true);
2287
2288 if (rc == 0)
2289 return 0;
2290bad:
2291 if (c_req->use_pmem != 1) {
2292 if (pce_dev->dst_nents) {
2293 dma_unmap_sg(pce_dev->pdev, areq->dst,
2294 pce_dev->dst_nents, DMA_FROM_DEVICE);
2295 }
2296 if (pce_dev->src_nents) {
2297 dma_unmap_sg(pce_dev->pdev, areq->src,
2298 pce_dev->src_nents,
2299 (areq->src == areq->dst) ?
2300 DMA_BIDIRECTIONAL :
2301 DMA_TO_DEVICE);
2302 }
2303 }
2304 return rc;
2305}
2306EXPORT_SYMBOL(qce_ablk_cipher_req);
2307
2308int qce_process_sha_req(void *handle, struct qce_sha_req *sreq)
2309{
2310 struct qce_device *pce_dev = (struct qce_device *) handle;
2311 int rc;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002312 uint32_t pad_len = ALIGN(sreq->size, pce_dev->ce_dm.ce_block_size) -
2313 sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002314 struct ahash_request *areq = (struct ahash_request *)sreq->areq;
2315
2316 _chain_buffer_in_init(pce_dev);
2317 pce_dev->src_nents = count_sg(sreq->src, sreq->size);
2318 dma_map_sg(pce_dev->pdev, sreq->src, pce_dev->src_nents,
2319 DMA_TO_DEVICE);
2320
2321 if (_chain_sg_buffer_in(pce_dev, sreq->src, sreq->size) < 0) {
2322 rc = -ENOMEM;
2323 goto bad;
2324 }
2325
2326 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002327 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002328 pad_len) < 0) {
2329 rc = -ENOMEM;
2330 goto bad;
2331 }
2332 }
Mona Hossain390d92e2011-09-02 14:15:47 -07002333 _ce_in_final(pce_dev, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002334
2335 _ce_in_dump(pce_dev);
2336
Mona Hossain3b574d82011-09-01 15:02:01 -07002337 rc = _ce_setup_hash(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002338
2339 if (rc < 0)
2340 goto bad;
2341
2342 pce_dev->areq = areq;
2343 pce_dev->qce_cb = sreq->qce_cb;
Mona Hossain3b574d82011-09-01 15:02:01 -07002344 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _sha_ce_in_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002345
2346 rc = _qce_start_dma(pce_dev, true, false);
2347
2348 if (rc == 0)
2349 return 0;
2350bad:
2351 if (pce_dev->src_nents) {
2352 dma_unmap_sg(pce_dev->pdev, sreq->src,
2353 pce_dev->src_nents, DMA_TO_DEVICE);
2354 }
2355
2356 return rc;
2357}
2358EXPORT_SYMBOL(qce_process_sha_req);
2359
2360/* crypto engine open function. */
2361void *qce_open(struct platform_device *pdev, int *rc)
2362{
2363 struct qce_device *pce_dev;
2364 struct resource *resource;
2365 struct clk *ce_core_clk;
2366 struct clk *ce_clk;
2367
2368 pce_dev = kzalloc(sizeof(struct qce_device), GFP_KERNEL);
2369 if (!pce_dev) {
2370 *rc = -ENOMEM;
2371 dev_err(&pdev->dev, "Can not allocate memory\n");
2372 return NULL;
2373 }
2374 pce_dev->pdev = &pdev->dev;
2375
2376 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2377 if (!resource) {
2378 *rc = -ENXIO;
2379 dev_err(pce_dev->pdev, "Missing MEM resource\n");
2380 goto err_pce_dev;
2381 };
2382 pce_dev->phy_iobase = resource->start;
2383 pce_dev->iobase = ioremap_nocache(resource->start,
2384 resource->end - resource->start + 1);
2385 if (!pce_dev->iobase) {
2386 *rc = -ENOMEM;
2387 dev_err(pce_dev->pdev, "Can not map io memory\n");
2388 goto err_pce_dev;
2389 }
2390
Mona Hossain3b574d82011-09-01 15:02:01 -07002391 pce_dev->ce_dm.chan_ce_in_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002392 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002393 pce_dev->ce_dm.chan_ce_out_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002394 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002395 if (pce_dev->ce_dm.chan_ce_in_cmd == NULL ||
2396 pce_dev->ce_dm.chan_ce_out_cmd == NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002397 dev_err(pce_dev->pdev, "Can not allocate memory\n");
2398 *rc = -ENOMEM;
2399 goto err_dm_chan_cmd;
2400 }
2401
2402 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2403 "crypto_channels");
2404 if (!resource) {
2405 *rc = -ENXIO;
2406 dev_err(pce_dev->pdev, "Missing DMA channel resource\n");
2407 goto err_dm_chan_cmd;
2408 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002409 pce_dev->ce_dm.chan_ce_in = resource->start;
2410 pce_dev->ce_dm.chan_ce_out = resource->end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002411 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2412 "crypto_crci_in");
2413 if (!resource) {
2414 *rc = -ENXIO;
2415 dev_err(pce_dev->pdev, "Missing DMA crci in resource\n");
2416 goto err_dm_chan_cmd;
2417 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002418 pce_dev->ce_dm.crci_in = resource->start;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002419 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2420 "crypto_crci_out");
2421 if (!resource) {
2422 *rc = -ENXIO;
2423 dev_err(pce_dev->pdev, "Missing DMA crci out resource\n");
2424 goto err_dm_chan_cmd;
2425 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002426 pce_dev->ce_dm.crci_out = resource->start;
2427 pce_dev->memsize = 2 * PAGE_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002428 pce_dev->coh_vmem = dma_alloc_coherent(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -07002429 pce_dev->memsize, &pce_dev->coh_pmem, GFP_KERNEL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002430
2431 if (pce_dev->coh_vmem == NULL) {
2432 *rc = -ENOMEM;
2433 dev_err(pce_dev->pdev, "Can not allocate coherent memory.\n");
2434 goto err;
2435 }
2436
2437 /* Get CE core clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002438 ce_core_clk = clk_get(pce_dev->pdev, "core_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002439 if (IS_ERR(ce_core_clk)) {
2440 *rc = PTR_ERR(ce_core_clk);
2441 goto err;
2442 }
2443 pce_dev->ce_core_clk = ce_core_clk;
2444 /* Get CE clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002445 ce_clk = clk_get(pce_dev->pdev, "iface_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002446 if (IS_ERR(ce_clk)) {
2447 *rc = PTR_ERR(ce_clk);
2448 clk_put(pce_dev->ce_core_clk);
2449 goto err;
2450 }
2451 pce_dev->ce_clk = ce_clk;
2452
2453 /* Enable CE core clk */
2454 *rc = clk_enable(pce_dev->ce_core_clk);
2455 if (*rc) {
2456 clk_put(pce_dev->ce_core_clk);
2457 clk_put(pce_dev->ce_clk);
2458 goto err;
2459 } else {
2460 /* Enable CE clk */
2461 *rc = clk_enable(pce_dev->ce_clk);
2462 if (*rc) {
2463 clk_disable(pce_dev->ce_core_clk);
2464 clk_put(pce_dev->ce_core_clk);
2465 clk_put(pce_dev->ce_clk);
2466 goto err;
2467
2468 }
2469 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002470 qce_setup_ce_dm_data(pce_dev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002471
Mona Hossain3b574d82011-09-01 15:02:01 -07002472 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
2473 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002474 if (_init_ce_engine(pce_dev)) {
2475 *rc = -ENXIO;
2476 goto err;
2477 }
2478 *rc = 0;
2479 return pce_dev;
2480
2481err:
2482 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002483 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
Mona Hossaine1b13f82011-08-30 09:35:49 -07002484 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002485err_dm_chan_cmd:
Mona Hossain3b574d82011-09-01 15:02:01 -07002486 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2487 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002488 if (pce_dev->iobase)
2489 iounmap(pce_dev->iobase);
2490
2491err_pce_dev:
2492
2493 kfree(pce_dev);
2494
2495 return NULL;
2496}
2497EXPORT_SYMBOL(qce_open);
2498
2499/* crypto engine close function. */
2500int qce_close(void *handle)
2501{
2502 struct qce_device *pce_dev = (struct qce_device *) handle;
2503
2504 if (handle == NULL)
2505 return -ENODEV;
2506 if (pce_dev->iobase)
2507 iounmap(pce_dev->iobase);
2508
2509 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002510 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
2511 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002512 clk_disable(pce_dev->ce_clk);
2513 clk_disable(pce_dev->ce_core_clk);
2514
2515 clk_put(pce_dev->ce_clk);
2516 clk_put(pce_dev->ce_core_clk);
2517
Mona Hossain3b574d82011-09-01 15:02:01 -07002518 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2519 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002520 kfree(handle);
2521
2522 return 0;
2523}
2524EXPORT_SYMBOL(qce_close);
2525
2526int qce_hw_support(void *handle, struct ce_hw_support *ce_support)
2527{
2528 if (ce_support == NULL)
2529 return -EINVAL;
2530
2531 ce_support->sha1_hmac_20 = false;
2532 ce_support->sha1_hmac = false;
2533 ce_support->sha256_hmac = false;
2534 ce_support->sha_hmac = false;
2535 ce_support->cmac = true;
2536 ce_support->aes_key_192 = false;
2537 ce_support->aes_xts = true;
2538 ce_support->aes_ccm = true;
2539 ce_support->ota = false;
2540 return 0;
2541}
2542EXPORT_SYMBOL(qce_hw_support);
2543
2544MODULE_LICENSE("GPL v2");
2545MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
2546MODULE_DESCRIPTION("Crypto Engine driver");
Mona Hossain5f5dde12011-09-12 10:28:34 -07002547MODULE_VERSION("2.10");