blob: 90a7889188392db3379b841a2be7b1904662e509 [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_src_desc +
740 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700741 /*
742 * Two consective chunks may be handled by the old
743 * buffer descriptor.
744 */
745 while (nbytes > 0) {
746 len = min(nbytes, sg_dma_len(sg));
747 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
748 nbytes -= len;
749 if (dlen == 0) {
750 pdesc->addr = sg_dma_address(sg);
751 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700752 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700753 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700754 sg_dma_address(sg),
755 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700756 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
757 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700758 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700759 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700760 pdesc->addr,
761 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700762 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700763 pce_dev->ce_dm.ce_in_src_desc_index++;
764 if (pce_dev->ce_dm.ce_in_src_desc_index >=
765 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700766 return -ENOMEM;
767 pdesc++;
768 pdesc->len = len;
769 pdesc->addr = sg_dma_address(sg);
Mona Hossain3b574d82011-09-01 15:02:01 -0700770 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700771 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700772 sg_dma_address(sg),
773 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700774 }
775 if (nbytes > 0)
776 sg = sg_next(sg);
777 }
778 return 0;
779}
780
781static int _chain_pm_buffer_in(struct qce_device *pce_dev,
782 unsigned int pmem, unsigned int nbytes)
783{
784 unsigned int dlen;
785 struct dmov_desc *pdesc;
786
Mona Hossain3b574d82011-09-01 15:02:01 -0700787 pdesc = pce_dev->ce_dm.ce_in_src_desc +
788 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700789 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
790 if (dlen == 0) {
791 pdesc->addr = pmem;
792 pdesc->len = nbytes;
793 } else if (pmem == (pdesc->addr + dlen)) {
794 pdesc->len = dlen + nbytes;
795 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700796 pce_dev->ce_dm.ce_in_src_desc_index++;
797 if (pce_dev->ce_dm.ce_in_src_desc_index >=
798 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700799 return -ENOMEM;
800 pdesc++;
801 pdesc->len = nbytes;
802 pdesc->addr = pmem;
803 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700804 return 0;
805}
806
807static void _chain_buffer_in_init(struct qce_device *pce_dev)
808{
809 struct dmov_desc *pdesc;
810
Mona Hossain3b574d82011-09-01 15:02:01 -0700811 pce_dev->ce_dm.ce_in_src_desc_index = 0;
812 pce_dev->ce_dm.ce_in_dst_desc_index = 0;
813 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700814 pdesc->len = 0;
815}
816
817static void _ce_in_final(struct qce_device *pce_dev, unsigned total)
818{
819 struct dmov_desc *pdesc;
820 dmov_sg *pcmd;
821
Mona Hossain3b574d82011-09-01 15:02:01 -0700822 pdesc = pce_dev->ce_dm.ce_in_src_desc +
823 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700824 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700825
826 pdesc = pce_dev->ce_dm.ce_in_dst_desc;
827 if (total > QCE_FIFO_SIZE) {
828 qce_split_and_insert_dm_desc(pdesc, total, 0,
829 &pce_dev->ce_dm.ce_in_dst_desc_index);
830 pdesc = pce_dev->ce_dm.ce_in_dst_desc +
831 pce_dev->ce_dm.ce_in_dst_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -0700832 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700833 } else
834 pdesc->len = ADM_DESC_LAST | total;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700835
Mona Hossain3b574d82011-09-01 15:02:01 -0700836 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700837 pcmd->cmd |= CMD_LC;
Mona Hossain3b574d82011-09-01 15:02:01 -0700838
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700839}
840
841#ifdef QCE_DEBUG
842static void _ce_in_dump(struct qce_device *pce_dev)
843{
844 int i;
845 struct dmov_desc *pdesc;
846
847 dev_info(pce_dev->pdev, "_ce_in_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700848 for (i = 0; i <= pce_dev->ce_dm.ce_in_src_desc_index; i++) {
849 pdesc = pce_dev->ce_dm.ce_in_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700850 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
851 pdesc->len);
852 }
853 dev_info(pce_dev->pdev, "_ce_in_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700854 for (i = 0; i <= pce_dev->ce_dm.ce_in_dst_desc_index; i++) {
855 pdesc = pce_dev->ce_dm.ce_in_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700856 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
857 pdesc->len);
858 }
859};
860
861static void _ce_out_dump(struct qce_device *pce_dev)
862{
863 int i;
864 struct dmov_desc *pdesc;
865
866 dev_info(pce_dev->pdev, "_ce_out_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700867 for (i = 0; i <= pce_dev->ce_dm.ce_out_src_desc_index; i++) {
868 pdesc = pce_dev->ce_dm.ce_out_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700869 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
870 pdesc->len);
871 }
872
873 dev_info(pce_dev->pdev, "_ce_out_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700874 for (i = 0; i <= pce_dev->ce_dm.ce_out_dst_desc_index; i++) {
875 pdesc = pce_dev->ce_dm.ce_out_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700876 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
877 pdesc->len);
878 }
879};
880
881#else
882
883static void _ce_in_dump(struct qce_device *pce_dev)
884{
885};
886
887static void _ce_out_dump(struct qce_device *pce_dev)
888{
889};
890
891#endif
892
893static int _chain_sg_buffer_out(struct qce_device *pce_dev,
894 struct scatterlist *sg, unsigned int nbytes)
895{
896 unsigned int len;
897 unsigned int dlen;
898 struct dmov_desc *pdesc;
899
Mona Hossain3b574d82011-09-01 15:02:01 -0700900 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
901 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700902 /*
903 * Two consective chunks may be handled by the old
904 * buffer descriptor.
905 */
906 while (nbytes > 0) {
907 len = min(nbytes, sg_dma_len(sg));
908 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
909 nbytes -= len;
910 if (dlen == 0) {
911 pdesc->addr = sg_dma_address(sg);
912 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700913 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700914 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
915 sg_dma_address(sg),
Mona Hossain3b574d82011-09-01 15:02:01 -0700916 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700917 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
918 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700919 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700920 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
921 pdesc->addr,
Mona Hossain3b574d82011-09-01 15:02:01 -0700922 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700923
924 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700925 pce_dev->ce_dm.ce_out_dst_desc_index++;
926 if (pce_dev->ce_dm.ce_out_dst_desc_index >=
927 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700928 return -EIO;
929 pdesc++;
930 pdesc->len = len;
931 pdesc->addr = sg_dma_address(sg);
Mona Hossain3b574d82011-09-01 15:02:01 -0700932 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700933 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
934 sg_dma_address(sg),
Mona Hossain3b574d82011-09-01 15:02:01 -0700935 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700936
937 }
938 if (nbytes > 0)
939 sg = sg_next(sg);
940 }
941 return 0;
942}
943
944static int _chain_pm_buffer_out(struct qce_device *pce_dev,
945 unsigned int pmem, unsigned int nbytes)
946{
947 unsigned int dlen;
948 struct dmov_desc *pdesc;
949
Mona Hossain3b574d82011-09-01 15:02:01 -0700950 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
951 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700952 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
953
954 if (dlen == 0) {
955 pdesc->addr = pmem;
956 pdesc->len = nbytes;
957 } else if (pmem == (pdesc->addr + dlen)) {
958 pdesc->len = dlen + nbytes;
959 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700960 pce_dev->ce_dm.ce_out_dst_desc_index++;
961 if (pce_dev->ce_dm.ce_out_dst_desc_index >= QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700962 return -EIO;
963 pdesc++;
964 pdesc->len = nbytes;
965 pdesc->addr = pmem;
966 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700967 return 0;
968};
969
970static void _chain_buffer_out_init(struct qce_device *pce_dev)
971{
972 struct dmov_desc *pdesc;
973
Mona Hossain3b574d82011-09-01 15:02:01 -0700974 pce_dev->ce_dm.ce_out_dst_desc_index = 0;
975 pce_dev->ce_dm.ce_out_src_desc_index = 0;
976 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700977 pdesc->len = 0;
978};
979
980static void _ce_out_final(struct qce_device *pce_dev, unsigned total)
981{
982 struct dmov_desc *pdesc;
983 dmov_sg *pcmd;
984
Mona Hossain3b574d82011-09-01 15:02:01 -0700985 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
986 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700987 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700988
Mona Hossain3b574d82011-09-01 15:02:01 -0700989 pdesc = pce_dev->ce_dm.ce_out_src_desc +
990 pce_dev->ce_dm.ce_out_src_desc_index;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700991 if (total > QCE_FIFO_SIZE) {
992 qce_split_and_insert_dm_desc(pdesc, total, 0,
993 &pce_dev->ce_dm.ce_out_src_desc_index);
994 pdesc = pce_dev->ce_dm.ce_out_src_desc +
995 pce_dev->ce_dm.ce_out_src_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -0700996 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700997 } else
998 pdesc->len = ADM_DESC_LAST | total;
Mona Hossain3b574d82011-09-01 15:02:01 -0700999
1000 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001001 pcmd->cmd |= CMD_LC;
1002};
1003
1004static void _aead_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1005 unsigned int result, struct msm_dmov_errdata *err)
1006{
1007 struct qce_device *pce_dev;
1008
1009 pce_dev = (struct qce_device *) cmd_ptr->user;
1010 if (result != ADM_STATUS_OK) {
1011 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1012 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001013 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001014 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001015 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001016 }
1017
Mona Hossain3b574d82011-09-01 15:02:01 -07001018 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1019 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1020 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1021 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001022
1023 /* done */
1024 _aead_complete(pce_dev);
1025 }
1026};
1027
1028static void _aead_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1029 unsigned int result, struct msm_dmov_errdata *err)
1030{
1031 struct qce_device *pce_dev;
1032
1033 pce_dev = (struct qce_device *) cmd_ptr->user;
1034 if (result != ADM_STATUS_OK) {
1035 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1036 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001037 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001038 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001039 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001040 };
1041
Mona Hossain3b574d82011-09-01 15:02:01 -07001042 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1043 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1044 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1045 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001046
1047 /* done */
1048 _aead_complete(pce_dev);
1049 }
1050
1051};
1052
1053static void _sha_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1054 unsigned int result, struct msm_dmov_errdata *err)
1055{
1056 struct qce_device *pce_dev;
1057
1058 pce_dev = (struct qce_device *) cmd_ptr->user;
1059 if (result != ADM_STATUS_OK) {
1060 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1061 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001062 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001063 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001064 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001065 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001066 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001067 _sha_complete(pce_dev);
1068};
1069
1070static void _ablk_cipher_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1071 unsigned int result, struct msm_dmov_errdata *err)
1072{
1073 struct qce_device *pce_dev;
1074
1075 pce_dev = (struct qce_device *) cmd_ptr->user;
1076 if (result != ADM_STATUS_OK) {
1077 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1078 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001079 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001080 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001081 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001082 }
1083
Mona Hossain3b574d82011-09-01 15:02:01 -07001084 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1085 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1086 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1087 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001088
1089 /* done */
1090 _ablk_cipher_complete(pce_dev);
1091 }
1092};
1093
1094static void _ablk_cipher_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1095 unsigned int result, struct msm_dmov_errdata *err)
1096{
1097 struct qce_device *pce_dev;
1098
1099 pce_dev = (struct qce_device *) cmd_ptr->user;
Mona Hossain3b574d82011-09-01 15:02:01 -07001100
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001101 if (result != ADM_STATUS_OK) {
1102 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1103 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001104 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001105 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001106 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001107 };
1108
Mona Hossain3b574d82011-09-01 15:02:01 -07001109 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1110 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1111 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1112 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001113
1114 /* done */
1115 _ablk_cipher_complete(pce_dev);
1116 }
1117};
1118
1119
1120static void _ablk_cipher_ce_in_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1121 unsigned int result, struct msm_dmov_errdata *err)
1122{
1123 struct qce_device *pce_dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001124 pce_dev = (struct qce_device *) cmd_ptr->user;
1125 if (result != ADM_STATUS_OK) {
1126 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1127 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001128 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001129 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001130 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001131 }
1132
Mona Hossain3b574d82011-09-01 15:02:01 -07001133 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1134 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1135 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1136 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001137
1138 /* done */
1139 _ablk_cipher_use_pmem_complete(pce_dev);
1140 }
1141};
1142
1143static void _ablk_cipher_ce_out_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1144 unsigned int result, struct msm_dmov_errdata *err)
1145{
1146 struct qce_device *pce_dev;
1147
1148 pce_dev = (struct qce_device *) cmd_ptr->user;
1149 if (result != ADM_STATUS_OK) {
1150 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1151 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001152 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001153 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001154 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001155 };
1156
Mona Hossain3b574d82011-09-01 15:02:01 -07001157 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1158 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1159 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1160 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001161
1162 /* done */
1163 _ablk_cipher_use_pmem_complete(pce_dev);
1164 }
1165};
1166
Mona Hossain3b574d82011-09-01 15:02:01 -07001167static int qce_setup_cmd_buffers(struct qce_device *pce_dev,
1168 unsigned char **pvaddr)
1169{
1170 struct ce_reg_buffers *addr = (struct ce_reg_buffers *)(*pvaddr);
1171 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
1172
1173 /*
1174 * Designate chunks of the allocated memory to various
1175 * buffer pointers
1176 */
1177 buffer->reset_buf_64 = addr->reset_buf_64;
1178 buffer->version = addr->version;
1179 buffer->encr_seg_cfg_size_start = addr->encr_seg_cfg_size_start;
1180 buffer->encr_key = addr->encr_key;
1181 buffer->encr_xts_key = addr->encr_xts_key;
1182 buffer->encr_xts_du_size = addr->encr_xts_du_size;
1183 buffer->encr_cntr_iv = addr->encr_cntr_iv;
1184 buffer->encr_mask = addr->encr_mask;
1185 buffer->auth_seg_cfg_size_start = addr->auth_seg_cfg_size_start;
1186 buffer->auth_key = addr->auth_key;
1187 buffer->auth_iv = addr->auth_iv;
1188 buffer->auth_result = addr->auth_result;
1189 buffer->auth_nonce_info = addr->auth_nonce_info;
1190 buffer->auth_byte_count = addr->auth_byte_count;
1191 buffer->seg_size = addr->seg_size;
1192 buffer->go_proc = addr->go_proc;
1193 buffer->status = addr->status;
1194 buffer->pad = addr->pad;
1195
1196 memset(buffer->reset_buf_64, 0, 64);
1197 *((uint32_t *)buffer->encr_mask) = (uint32_t)(0xffffffff);
1198 *((uint32_t *)buffer->go_proc) = (uint32_t)(1 << CRYPTO_GO);
1199
1200 *pvaddr += sizeof(struct ce_reg_buffers);
1201
1202 return 0;
1203
1204}
1205
1206static int _setup_cipher_cmdlists(struct qce_device *pce_dev,
1207 unsigned char **pvaddr)
1208{
1209 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1210
1211 /*
1212 * Designate chunks of the allocated memory to various
1213 * command list pointers related to cipher operation
1214 */
1215 pce_dev->ce_dm.cmdlist.set_cipher_cfg = pscmd;
1216 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1217 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG +
1218 pce_dev->phy_iobase);
1219 pscmd->len = CRYPTO_REG_SIZE * 3;
1220 pscmd->src =
1221 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_seg_cfg_size_start);
1222 pscmd++;
1223
1224 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_key = pscmd;
1225 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1226 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1227 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1228 pscmd->len = CRYPTO_REG_SIZE * 4;
1229 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1230 pscmd++;
1231
1232 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_key = pscmd;
1233 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1234 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1235 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1236 pscmd->len = CRYPTO_REG_SIZE * 8;
1237 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1238 pscmd++;
1239
1240 pce_dev->ce_dm.cmdlist.set_cipher_des_key = pscmd;
1241 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1242 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1243 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1244 pscmd->len = CRYPTO_REG_SIZE * 2;
1245 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1246 pscmd++;
1247
1248 pce_dev->ce_dm.cmdlist.set_cipher_3des_key = pscmd;
1249 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1250 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1251 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1252 pscmd->len = CRYPTO_REG_SIZE * 6;
1253 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1254 pscmd++;
1255
1256 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_xts_key = pscmd;
1257 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1258 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1259 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1260 pce_dev->phy_iobase);
1261 pscmd->len = CRYPTO_REG_SIZE * 4;
1262 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1263 pscmd++;
1264
1265 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_xts_key = pscmd;
1266 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1267 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1268 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1269 pce_dev->phy_iobase);
1270 pscmd->len = CRYPTO_REG_SIZE * 8;
1271 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1272 pscmd++;
1273
1274 pce_dev->ce_dm.cmdlist.set_cipher_xts_du_size = pscmd;
1275 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1276 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_DU_SIZE_REG +
1277 pce_dev->phy_iobase);
1278 pscmd->len = CRYPTO_REG_SIZE * 4;
1279 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_du_size);
1280 pscmd++;
1281
1282 pce_dev->ce_dm.cmdlist.set_cipher_aes_iv = pscmd;
1283 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1284 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1285 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1286 pscmd->len = CRYPTO_REG_SIZE * 4;
1287 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1288 pscmd++;
1289
1290 pce_dev->ce_dm.cmdlist.get_cipher_aes_iv = pscmd;
1291 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1292 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1293 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1294 pscmd->len = CRYPTO_REG_SIZE * 4;
1295 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1296 pscmd++;
1297
1298 pce_dev->ce_dm.cmdlist.get_cipher_aes_xts_iv = pscmd;
1299 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1300 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1301 pscmd->len = CRYPTO_REG_SIZE * 4;
1302 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1303 pscmd++;
1304
1305 pce_dev->ce_dm.cmdlist.set_cipher_des_iv = pscmd;
1306 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1307 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1308 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1309 pscmd->len = CRYPTO_REG_SIZE * 2;
1310 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1311 pscmd++;
1312
1313 pce_dev->ce_dm.cmdlist.get_cipher_des_iv = pscmd;
1314 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1315 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1316 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1317 pscmd->len = CRYPTO_REG_SIZE * 2;
1318 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1319 pscmd++;
1320
1321 pce_dev->ce_dm.cmdlist.set_cipher_mask = pscmd;
1322 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1323 pscmd->dst = (unsigned) (CRYPTO_CNTR_MASK_REG + pce_dev->phy_iobase);
1324 pscmd->len = CRYPTO_REG_SIZE;
1325 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_mask);
1326 pscmd++;
1327
1328 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1329
1330 pce_dev->ce_dm.cmdlist.reset_cipher_key = pscmd;
1331 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1332 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1333 pscmd->len = CRYPTO_REG_SIZE * 8;
1334 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1335 pscmd++;
1336
1337 pce_dev->ce_dm.cmdlist.reset_cipher_xts_key = pscmd;
1338 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1339 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1340 pce_dev->phy_iobase);
1341 pscmd->len = CRYPTO_REG_SIZE * 8;
1342 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1343 pscmd++;
1344
1345 pce_dev->ce_dm.cmdlist.reset_cipher_iv = pscmd;
1346 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1347 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1348 pscmd->len = CRYPTO_REG_SIZE * 4;
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_cfg = pscmd;
1353 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1354 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG + pce_dev->phy_iobase);
1355 pscmd->len = CRYPTO_REG_SIZE;
1356 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1357 pscmd++;
1358
1359 *pvaddr = (unsigned char *) pscmd;
1360
1361 return 0;
1362}
1363
1364static int _setup_auth_cmdlists(struct qce_device *pce_dev,
1365 unsigned char **pvaddr)
1366{
1367 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1368
1369 /*
1370 * Designate chunks of the allocated memory to various
1371 * command list pointers related to authentication operation
1372 */
1373 pce_dev->ce_dm.cmdlist.set_auth_cfg = pscmd;
1374 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1375 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1376 pscmd->len = CRYPTO_REG_SIZE * 3;
1377 pscmd->src =
1378 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start);
1379 pscmd++;
1380
1381 pce_dev->ce_dm.cmdlist.set_auth_key_128 = pscmd;
1382 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1383 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1384 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1385 pscmd->len = CRYPTO_REG_SIZE * 4;
1386 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1387 pscmd++;
1388
1389 pce_dev->ce_dm.cmdlist.set_auth_key_256 = pscmd;
1390 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1391 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1392 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1393 pscmd->len = CRYPTO_REG_SIZE * 8;
1394 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1395 pscmd++;
1396
1397 pce_dev->ce_dm.cmdlist.set_auth_key_512 = pscmd;
1398 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1399 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1400 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1401 pscmd->len = CRYPTO_REG_SIZE * 16;
1402 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1403 pscmd++;
1404
1405 pce_dev->ce_dm.cmdlist.set_auth_iv_16 = pscmd;
1406 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1407 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1408 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1409 pscmd->len = CRYPTO_REG_SIZE * 4;
1410 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1411 pscmd++;
1412
1413 pce_dev->ce_dm.cmdlist.get_auth_result_16 = pscmd;
1414 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1415 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1416 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1417 pscmd->len = CRYPTO_REG_SIZE * 4;
1418 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1419 pscmd++;
1420
1421 pce_dev->ce_dm.cmdlist.set_auth_iv_20 = pscmd;
1422 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1423 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1424 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1425 pscmd->len = CRYPTO_REG_SIZE * 5;
1426 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1427 pscmd++;
1428
1429 pce_dev->ce_dm.cmdlist.get_auth_result_20 = pscmd;
1430 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1431 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1432 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1433 pscmd->len = CRYPTO_REG_SIZE * 5;
1434 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1435 pscmd++;
1436
1437 pce_dev->ce_dm.cmdlist.set_auth_iv_32 = pscmd;
1438 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1439 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1440 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1441 pscmd->len = CRYPTO_REG_SIZE * 8;
1442 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1443 pscmd++;
1444
1445
1446 pce_dev->ce_dm.cmdlist.get_auth_result_32 = pscmd;
1447 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1448 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1449 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1450 pscmd->len = CRYPTO_REG_SIZE * 8;
1451 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1452 pscmd++;
1453
1454 pce_dev->ce_dm.cmdlist.set_auth_byte_count = pscmd;
1455 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1456 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1457 pce_dev->phy_iobase);
1458 pscmd->len = CRYPTO_REG_SIZE * 4;
1459 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1460 pscmd++;
1461
1462 pce_dev->ce_dm.cmdlist.get_auth_byte_count = pscmd;
1463 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1464 pscmd->src = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1465 pce_dev->phy_iobase);
1466 pscmd->len = CRYPTO_REG_SIZE * 4;
1467 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1468 pscmd++;
1469
1470 pce_dev->ce_dm.cmdlist.set_auth_nonce_info = pscmd;
1471 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1472 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1473 pscmd->dst = (unsigned) (CRYPTO_AUTH_INFO_NONCE0_REG +
1474 pce_dev->phy_iobase);
1475 pscmd->len = CRYPTO_REG_SIZE * 4;
1476 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_nonce_info);
1477 pscmd++;
1478
1479 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1480
1481 pce_dev->ce_dm.cmdlist.reset_auth_key = pscmd;
1482 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1483 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1484 pscmd->len = CRYPTO_REG_SIZE * 16;
1485 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1486 pscmd++;
1487
1488 pce_dev->ce_dm.cmdlist.reset_auth_iv = pscmd;
1489 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1490 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1491 pscmd->len = CRYPTO_REG_SIZE * 16;
1492 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1493 pscmd++;
1494
1495 pce_dev->ce_dm.cmdlist.reset_auth_cfg = pscmd;
1496 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1497 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1498 pscmd->len = CRYPTO_REG_SIZE;
1499 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1500 pscmd++;
1501
1502
1503 pce_dev->ce_dm.cmdlist.reset_auth_byte_count = pscmd;
1504 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1505 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1506 pce_dev->phy_iobase);
1507 pscmd->len = CRYPTO_REG_SIZE * 4;
1508 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1509 pscmd++;
1510
1511 /* WAIT UNTIL MAC OP IS DONE*/
1512
1513 pce_dev->ce_dm.cmdlist.get_status_wait = pscmd;
1514 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1515 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1516 pscmd->len = CRYPTO_REG_SIZE;
1517 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1518 pscmd++;
1519
1520 *pvaddr = (unsigned char *) pscmd;
1521
1522 return 0;
1523}
1524
1525static int qce_setup_cmdlists(struct qce_device *pce_dev,
1526 unsigned char **pvaddr)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001527{
1528 dmov_sg *pcmd;
Mona Hossain3b574d82011-09-01 15:02:01 -07001529 dmov_s *pscmd;
1530 unsigned char *vaddr = *pvaddr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001531 struct dmov_desc *pdesc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001532 int i = 0;
1533
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001534 /*
Mona Hossain3b574d82011-09-01 15:02:01 -07001535 * Designate chunks of the allocated memory to various
1536 * command list pointers related to operation define
1537 * in ce_cmdlists structure.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001538 */
Mona Hossain3b574d82011-09-01 15:02:01 -07001539 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
1540 *pvaddr = (unsigned char *) vaddr;
1541
1542 _setup_cipher_cmdlists(pce_dev, pvaddr);
1543 _setup_auth_cmdlists(pce_dev, pvaddr);
1544
1545 pscmd = (dmov_s *)(*pvaddr);
1546
1547 /* GET HW VERSION COMMAND LIST */
1548 pce_dev->ce_dm.cmdlist.get_hw_version = pscmd;
1549 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1550 pscmd->src = (unsigned) (CRYPTO_VERSION_REG + pce_dev->phy_iobase);
1551 pscmd->len = CRYPTO_REG_SIZE;
1552 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.version);
1553 pscmd++;
1554
1555
1556 /* SET SEG SIZE REGISTER and OCB COMMAND LIST */
1557 pce_dev->ce_dm.cmdlist.set_seg_size_ocb = pscmd;
1558 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1559 pscmd->dst = (unsigned) (CRYPTO_SEG_SIZE_REG + pce_dev->phy_iobase);
1560 pscmd->len = CRYPTO_REG_SIZE;
1561 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.seg_size);
1562 pscmd++;
1563
1564
1565 /* OCU COMMAND LIST */
1566 pce_dev->ce_dm.cmdlist.get_status_ocu = pscmd;
1567 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCU;
1568 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1569 pscmd->len = CRYPTO_REG_SIZE;
1570 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1571 pscmd++;
1572
1573 /* SET GO_PROC REGISTERS COMMAND LIST */
1574 pce_dev->ce_dm.cmdlist.set_go_proc = pscmd;
1575 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1576 pscmd->dst = (unsigned) (CRYPTO_GOPROC_REG + pce_dev->phy_iobase);
1577 pscmd->len = CRYPTO_REG_SIZE;
1578 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.go_proc);
1579 pscmd++;
1580
1581 pcmd = (dmov_sg *)pscmd;
1582 pce_dev->ce_dm.cmdlist.ce_data_in = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001583 /* swap byte and half word , dst crci , scatter gather */
1584 pcmd->cmd = CMD_DST_SWAP_BYTES | CMD_DST_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001585 CMD_DST_CRCI(pce_dev->ce_dm.crci_in) | CMD_MODE_SG;
1586
1587 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001588 pdesc->addr = 0; /* to be filled in each operation */
1589 pdesc->len = 0; /* to be filled in each operation */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001590
Mona Hossain3b574d82011-09-01 15:02:01 -07001591 pdesc = pce_dev->ce_dm.ce_in_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001592 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1593 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1594 pdesc->len = 0; /* to be filled in each operation */
1595 pdesc++;
1596 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001597 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_src_desc);
1598 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001599 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1600 DST_INDEX_SG_CMD(0);
Mona Hossain3b574d82011-09-01 15:02:01 -07001601
1602
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001603 pcmd++;
Mona Hossain3b574d82011-09-01 15:02:01 -07001604 pce_dev->ce_dm.cmdlist.ce_data_out = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001605 /* swap byte, half word, source crci, scatter gather */
1606 pcmd->cmd = CMD_SRC_SWAP_BYTES | CMD_SRC_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001607 CMD_SRC_CRCI(pce_dev->ce_dm.crci_out) | CMD_MODE_SG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001608
Mona Hossain3b574d82011-09-01 15:02:01 -07001609 pdesc = pce_dev->ce_dm.ce_out_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001610 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1611 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1612 pdesc->len = 0; /* to be filled in each operation */
1613 pdesc++;
1614 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001615
Mona Hossain3b574d82011-09-01 15:02:01 -07001616 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001617 pdesc->addr = 0; /* to be filled in each operation */
1618 pdesc->len = 0; /* to be filled in each operation */
Mona Hossain3b574d82011-09-01 15:02:01 -07001619
1620 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_src_desc);
1621 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001622 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1623 DST_INDEX_SG_CMD(0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001624 pcmd++;
1625
Mona Hossain3b574d82011-09-01 15:02:01 -07001626 *pvaddr = (unsigned char *) pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001627
1628 return 0;
Mona Hossain3b574d82011-09-01 15:02:01 -07001629}
1630
1631static int _setup_cipher_cmdptrlists(struct qce_device *pce_dev,
1632 unsigned char **pvaddr)
1633{
1634 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1635 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1636 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1637
1638 /*
1639 * Designate chunks of the allocated memory to various
1640 * command list pointers related to cipher operations defined
1641 * in ce_cmdptrlists_ops structure.
1642 */
1643 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1644 cmdptrlist->cipher_aes_128_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1645
1646 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1647 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1648 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1649 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1650 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1651 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1652 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1653 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1654 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_iv);
1655
1656 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1657 cmdptrlist->cipher_aes_256_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1658
1659 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1660 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1661 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1662 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1663 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1664 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1665 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1666 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1667 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_iv);
1668
1669 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1670 cmdptrlist->cipher_aes_128_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1671
1672 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1673 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1674 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1675 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1676 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1677 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1678 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1679
1680 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1681 cmdptrlist->cipher_aes_256_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1682
1683 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1684 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1685 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1686 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1687 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1688 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1689 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1690
1691 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1692 cmdptrlist->cipher_aes_128_xts = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1693
1694 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1695 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1696 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1697 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_xts_key);
1698 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1699 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1700 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
1701 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1702 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1703 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1704 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_xts_iv);
1705
1706 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1707 cmdptrlist->cipher_aes_256_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_256_key);
1712 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_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_des_cbc = 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_des_key);
1727 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1728 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1729 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1730 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1731 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_des_iv);
1732
1733 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1734 cmdptrlist->cipher_des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1735
1736 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1737 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1738 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1739 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1740 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1741 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1742
1743 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1744 cmdptrlist->cipher_3des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1745
1746 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1747 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1748 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1749 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1750 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1751 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1752 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1753 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_des_iv);
1754
1755 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1756 cmdptrlist->cipher_3des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1757
1758 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1759 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1760 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1761 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1762 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1763 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1764
1765 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1766 cmdptrlist->cipher_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1767
1768 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1769 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1770 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1771
1772 return 0;
1773}
1774
1775static int _setup_auth_cmdptrlists(struct qce_device *pce_dev,
1776 unsigned char **pvaddr)
1777{
1778 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1779 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1780 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1781
1782 /*
1783 * Designate chunks of the allocated memory to various
1784 * command list pointers related to authentication operations
1785 * defined in ce_cmdptrlists_ops structure.
1786 */
1787 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1788 cmdptrlist->auth_sha1 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1789
1790 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1791 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1792 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1793 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1794 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1795 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1796 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1797 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1798 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1799 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1800 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1801 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1802
1803 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1804 cmdptrlist->auth_sha256 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1805
1806 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1807 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1808 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1809 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1810 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1811 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1812 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1813 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1814 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1815 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1816 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1817 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1818
1819 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1820 cmdptrlist->auth_sha1_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1821
1822 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1823 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1824 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1825 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1826 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1827 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1828 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1829 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1830 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1831 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1832 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1833 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1834 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1835
1836 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1837 cmdptrlist->auth_sha256_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1838
1839 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1840 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1841 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1842 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1843 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1844 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1845 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1846 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1847 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1848 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1849 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1850 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1851 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1852
1853 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1854 cmdptrlist->auth_aes_128_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1855
1856 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1857 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1858 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1859 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1860 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1861 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1862 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1863 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1864 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1865 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1866 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1867 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1868 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1869 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1870
1871 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1872 cmdptrlist->auth_aes_256_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1873
1874 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1875 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1876 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1877 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1878 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1879 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1880 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1881 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1882 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1883 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1884 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1885 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1886 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1887 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1888
1889 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1890
1891 return 0;
1892}
1893
1894static int _setup_aead_cmdptrlists(struct qce_device *pce_dev,
1895 unsigned char **pvaddr)
1896{
1897 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1898 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1899 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1900
1901 /*
1902 * Designate chunks of the allocated memory to various
1903 * command list pointers related to aead operations
1904 * defined in ce_cmdptrlists_ops structure.
1905 */
1906 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1907 cmdptrlist->aead_aes_128_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1908
1909 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1910 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1911 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1912 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1913 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1914 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1915 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1916 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1917 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1918 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1919 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1920 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1921 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1922
1923 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1924 cmdptrlist->aead_aes_256_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1925
1926 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1927 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1928 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1929 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1930 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1931 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1932 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1933 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1934 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1935 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1936 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1937 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1938 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1939
1940 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1941 cmdptrlist->aead_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1942
1943 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1944 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1945 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1946 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1947
1948 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1949
1950 return 0;
1951}
1952
1953static int qce_setup_cmdptrlists(struct qce_device *pce_dev,
1954 unsigned char **pvaddr)
1955{
1956 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1957 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1958 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1959 /*
1960 * Designate chunks of the allocated memory to various
1961 * command list pointers related to operations defined
1962 * in ce_cmdptrlists_ops structure.
1963 */
1964 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1965 cmdptrlist->probe_ce_hw = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1966
1967 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_hw_version);
1968 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1969
1970 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1971
1972 _setup_cipher_cmdptrlists(pce_dev, pvaddr);
1973 _setup_auth_cmdptrlists(pce_dev, pvaddr);
1974 _setup_aead_cmdptrlists(pce_dev, pvaddr);
1975
1976 return 0;
1977}
1978
1979
1980static int qce_setup_ce_dm_data(struct qce_device *pce_dev)
1981{
1982 unsigned char *vaddr;
1983
1984 /* 1. ce_in channel data xfer command src descriptors, 128 entries */
1985 vaddr = pce_dev->coh_vmem;
1986 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
1987 pce_dev->ce_dm.ce_in_src_desc = (struct dmov_desc *) vaddr;
1988 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
1989
1990 /* 2. ce_in channel data xfer command dst descriptors, 128 entries */
1991 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
1992 pce_dev->ce_dm.ce_in_dst_desc = (struct dmov_desc *) vaddr;
1993 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
1994
1995
1996 /* 3. ce_out channel data xfer command src descriptors, 128 entries */
1997 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
1998 pce_dev->ce_dm.ce_out_src_desc = (struct dmov_desc *) vaddr;
1999 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2000
2001 /* 4. ce_out channel data xfer command dst descriptors, 128 entries. */
2002 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2003 pce_dev->ce_dm.ce_out_dst_desc = (struct dmov_desc *) vaddr;
2004 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2005
2006 qce_setup_cmd_buffers(pce_dev, &vaddr);
2007 qce_setup_cmdlists(pce_dev, &vaddr);
2008 qce_setup_cmdptrlists(pce_dev, &vaddr);
2009
2010 pce_dev->ce_dm.buffer.ignore_data = vaddr;
2011
2012 pce_dev->ce_dm.phy_ce_pad = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.pad);
2013 pce_dev->ce_dm.phy_ce_out_ignore =
2014 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.ignore_data);
2015
2016 pce_dev->ce_dm.chan_ce_in_cmd->user = (void *) pce_dev;
2017 pce_dev->ce_dm.chan_ce_in_cmd->exec_func = NULL;
2018
2019 pce_dev->ce_dm.chan_ce_out_cmd->user = (void *) pce_dev;
2020 pce_dev->ce_dm.chan_ce_out_cmd->exec_func = NULL;
2021
2022 return 0;
2023}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002024
2025static int _qce_start_dma(struct qce_device *pce_dev, bool ce_in, bool ce_out)
2026{
2027
2028 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002029 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002030 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002031 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002032
2033 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002034 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002035 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002036 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002037
2038 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002039 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
2040 pce_dev->ce_dm.chan_ce_in_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002041 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002042 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_out,
2043 pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002044
2045 return 0;
2046};
2047
2048int qce_aead_req(void *handle, struct qce_req *q_req)
2049{
2050 struct qce_device *pce_dev = (struct qce_device *) handle;
2051 struct aead_request *areq = (struct aead_request *) q_req->areq;
2052 uint32_t authsize = q_req->authsize;
2053 uint32_t totallen_in, totallen_out, out_len;
2054 uint32_t pad_len_in, pad_len_out;
2055 uint32_t pad_mac_len_out, pad_ptx_len_out;
2056 int rc = 0;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002057 int ce_block_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002058
Mona Hossain5f5dde12011-09-12 10:28:34 -07002059 ce_block_size = pce_dev->ce_dm.ce_block_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002060 if (q_req->dir == QCE_ENCRYPT) {
2061 q_req->cryptlen = areq->cryptlen;
2062 totallen_in = q_req->cryptlen + areq->assoclen;
2063 totallen_out = q_req->cryptlen + authsize + areq->assoclen;
2064 out_len = areq->cryptlen + authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002065 pad_len_in = ALIGN(totallen_in, ce_block_size) - totallen_in;
2066 pad_mac_len_out = ALIGN(authsize, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002067 authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002068 pad_ptx_len_out = ALIGN(q_req->cryptlen, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002069 q_req->cryptlen;
2070 pad_len_out = pad_ptx_len_out + pad_mac_len_out;
2071 totallen_out += pad_len_out;
2072 } else {
2073 q_req->cryptlen = areq->cryptlen - authsize;
2074 totallen_in = areq->cryptlen + areq->assoclen;
2075 totallen_out = q_req->cryptlen + areq->assoclen;
2076 out_len = areq->cryptlen - authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002077 pad_len_in = ALIGN(areq->cryptlen, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002078 areq->cryptlen;
2079 pad_len_out = pad_len_in + authsize;
2080 totallen_out += pad_len_out;
2081 }
2082
2083 _chain_buffer_in_init(pce_dev);
2084 _chain_buffer_out_init(pce_dev);
2085
2086 pce_dev->assoc_nents = 0;
2087 pce_dev->src_nents = 0;
2088 pce_dev->dst_nents = 0;
2089 pce_dev->ivsize = q_req->ivsize;
2090 pce_dev->authsize = q_req->authsize;
2091
2092 /* associated data input */
2093 pce_dev->assoc_nents = count_sg(areq->assoc, areq->assoclen);
2094 dma_map_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
2095 DMA_TO_DEVICE);
2096 if (_chain_sg_buffer_in(pce_dev, areq->assoc, areq->assoclen) < 0) {
2097 rc = -ENOMEM;
2098 goto bad;
2099 }
2100 /* cipher input */
2101 pce_dev->src_nents = count_sg(areq->src, areq->cryptlen);
2102 dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2103 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2104 DMA_TO_DEVICE);
2105 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->cryptlen) < 0) {
2106 rc = -ENOMEM;
2107 goto bad;
2108 }
2109 /* pad data in */
2110 if (pad_len_in) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002111 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002112 pad_len_in) < 0) {
2113 rc = -ENOMEM;
2114 goto bad;
2115 }
2116 }
2117
2118 /* ignore associated data */
Mona Hossain3b574d82011-09-01 15:02:01 -07002119 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_out_ignore,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002120 areq->assoclen) < 0) {
2121 rc = -ENOMEM;
2122 goto bad;
2123 }
2124 /* cipher + mac output for encryption */
2125 if (areq->src != areq->dst) {
2126 pce_dev->dst_nents = count_sg(areq->dst, out_len);
2127 dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2128 DMA_FROM_DEVICE);
2129 };
2130 if (_chain_sg_buffer_out(pce_dev, areq->dst, out_len) < 0) {
2131 rc = -ENOMEM;
2132 goto bad;
2133 }
2134 /* pad data out */
2135 if (pad_len_out) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002136 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002137 pad_len_out) < 0) {
2138 rc = -ENOMEM;
2139 goto bad;
2140 }
2141 }
2142
2143 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain5f5dde12011-09-12 10:28:34 -07002144 _ce_in_final(pce_dev, ALIGN(totallen_in, ce_block_size));
2145 _ce_out_final(pce_dev, ALIGN(totallen_out, ce_block_size));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002146
2147 /* set up crypto device */
2148 rc = _ce_setup_cipher(pce_dev, q_req, totallen_in, areq->assoclen);
2149 if (rc < 0)
2150 goto bad;
2151
2152 /* setup for callback, and issue command to adm */
2153 pce_dev->areq = q_req->areq;
2154 pce_dev->qce_cb = q_req->qce_cb;
2155
Mona Hossain3b574d82011-09-01 15:02:01 -07002156 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _aead_ce_in_call_back;
2157 pce_dev->ce_dm.chan_ce_out_cmd->complete_func = _aead_ce_out_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002158
2159 _ce_in_dump(pce_dev);
2160 _ce_out_dump(pce_dev);
2161
2162 rc = _qce_start_dma(pce_dev, true, true);
2163 if (rc == 0)
2164 return 0;
2165bad:
2166 if (pce_dev->assoc_nents) {
2167 dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
2168 DMA_TO_DEVICE);
2169 }
2170
2171 if (pce_dev->src_nents) {
2172 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2173 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2174 DMA_TO_DEVICE);
2175 }
2176 if (pce_dev->dst_nents) {
2177 dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2178 DMA_FROM_DEVICE);
2179 }
2180 return rc;
2181}
2182EXPORT_SYMBOL(qce_aead_req);
2183
2184int qce_ablk_cipher_req(void *handle, struct qce_req *c_req)
2185{
2186 int rc = 0;
2187 struct qce_device *pce_dev = (struct qce_device *) handle;
2188 struct ablkcipher_request *areq = (struct ablkcipher_request *)
2189 c_req->areq;
2190
Mona Hossain5f5dde12011-09-12 10:28:34 -07002191 uint32_t pad_len = ALIGN(areq->nbytes, pce_dev->ce_dm.ce_block_size)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002192 - areq->nbytes;
2193
2194 _chain_buffer_in_init(pce_dev);
2195 _chain_buffer_out_init(pce_dev);
2196
2197 pce_dev->src_nents = 0;
2198 pce_dev->dst_nents = 0;
2199
2200 /* cipher input */
2201 pce_dev->src_nents = count_sg(areq->src, areq->nbytes);
2202
2203 if (c_req->use_pmem != 1)
2204 dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2205 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2206 DMA_TO_DEVICE);
2207 else
2208 dma_map_pmem_sg(&c_req->pmem->src[0], pce_dev->src_nents,
2209 areq->src);
2210
2211 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->nbytes) < 0) {
2212 rc = -ENOMEM;
2213 goto bad;
2214 }
2215
2216 /* cipher output */
2217 if (areq->src != areq->dst) {
2218 pce_dev->dst_nents = count_sg(areq->dst, areq->nbytes);
2219 if (c_req->use_pmem != 1)
2220 dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2221 DMA_FROM_DEVICE);
2222 else
2223 dma_map_pmem_sg(&c_req->pmem->dst[0],
2224 pce_dev->dst_nents, areq->dst);
2225 };
2226 if (_chain_sg_buffer_out(pce_dev, areq->dst, areq->nbytes) < 0) {
2227 rc = -ENOMEM;
2228 goto bad;
2229 }
2230
2231 /* pad data */
2232 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002233 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002234 pad_len) < 0) {
2235 rc = -ENOMEM;
2236 goto bad;
2237 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002238 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002239 pad_len) < 0) {
2240 rc = -ENOMEM;
2241 goto bad;
2242 }
2243 }
2244
2245 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain2563cbc2011-09-14 15:24:08 -07002246 _ce_in_final(pce_dev, areq->nbytes + pad_len);
2247 _ce_out_final(pce_dev, areq->nbytes + pad_len);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002248
2249 _ce_in_dump(pce_dev);
2250 _ce_out_dump(pce_dev);
2251
2252 /* set up crypto device */
2253 rc = _ce_setup_cipher(pce_dev, c_req, areq->nbytes, 0);
2254 if (rc < 0)
2255 goto bad;
2256
2257 /* setup for callback, and issue command to adm */
2258 pce_dev->areq = areq;
2259 pce_dev->qce_cb = c_req->qce_cb;
2260 if (c_req->use_pmem == 1) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002261 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002262 _ablk_cipher_ce_in_call_back_pmem;
Mona Hossain3b574d82011-09-01 15:02:01 -07002263 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002264 _ablk_cipher_ce_out_call_back_pmem;
2265 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07002266 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002267 _ablk_cipher_ce_in_call_back;
Mona Hossain3b574d82011-09-01 15:02:01 -07002268 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002269 _ablk_cipher_ce_out_call_back;
2270 }
2271 rc = _qce_start_dma(pce_dev, true, true);
2272
2273 if (rc == 0)
2274 return 0;
2275bad:
2276 if (c_req->use_pmem != 1) {
2277 if (pce_dev->dst_nents) {
2278 dma_unmap_sg(pce_dev->pdev, areq->dst,
2279 pce_dev->dst_nents, DMA_FROM_DEVICE);
2280 }
2281 if (pce_dev->src_nents) {
2282 dma_unmap_sg(pce_dev->pdev, areq->src,
2283 pce_dev->src_nents,
2284 (areq->src == areq->dst) ?
2285 DMA_BIDIRECTIONAL :
2286 DMA_TO_DEVICE);
2287 }
2288 }
2289 return rc;
2290}
2291EXPORT_SYMBOL(qce_ablk_cipher_req);
2292
2293int qce_process_sha_req(void *handle, struct qce_sha_req *sreq)
2294{
2295 struct qce_device *pce_dev = (struct qce_device *) handle;
2296 int rc;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002297 uint32_t pad_len = ALIGN(sreq->size, pce_dev->ce_dm.ce_block_size) -
2298 sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002299 struct ahash_request *areq = (struct ahash_request *)sreq->areq;
2300
2301 _chain_buffer_in_init(pce_dev);
2302 pce_dev->src_nents = count_sg(sreq->src, sreq->size);
2303 dma_map_sg(pce_dev->pdev, sreq->src, pce_dev->src_nents,
2304 DMA_TO_DEVICE);
2305
2306 if (_chain_sg_buffer_in(pce_dev, sreq->src, sreq->size) < 0) {
2307 rc = -ENOMEM;
2308 goto bad;
2309 }
2310
2311 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002312 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002313 pad_len) < 0) {
2314 rc = -ENOMEM;
2315 goto bad;
2316 }
2317 }
Mona Hossain2563cbc2011-09-14 15:24:08 -07002318 _ce_in_final(pce_dev, sreq->size + pad_len);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002319
2320 _ce_in_dump(pce_dev);
2321
Mona Hossain3b574d82011-09-01 15:02:01 -07002322 rc = _ce_setup_hash(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002323
2324 if (rc < 0)
2325 goto bad;
2326
2327 pce_dev->areq = areq;
2328 pce_dev->qce_cb = sreq->qce_cb;
Mona Hossain3b574d82011-09-01 15:02:01 -07002329 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _sha_ce_in_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002330
2331 rc = _qce_start_dma(pce_dev, true, false);
2332
2333 if (rc == 0)
2334 return 0;
2335bad:
2336 if (pce_dev->src_nents) {
2337 dma_unmap_sg(pce_dev->pdev, sreq->src,
2338 pce_dev->src_nents, DMA_TO_DEVICE);
2339 }
2340
2341 return rc;
2342}
2343EXPORT_SYMBOL(qce_process_sha_req);
2344
2345/* crypto engine open function. */
2346void *qce_open(struct platform_device *pdev, int *rc)
2347{
2348 struct qce_device *pce_dev;
2349 struct resource *resource;
2350 struct clk *ce_core_clk;
2351 struct clk *ce_clk;
2352
2353 pce_dev = kzalloc(sizeof(struct qce_device), GFP_KERNEL);
2354 if (!pce_dev) {
2355 *rc = -ENOMEM;
2356 dev_err(&pdev->dev, "Can not allocate memory\n");
2357 return NULL;
2358 }
2359 pce_dev->pdev = &pdev->dev;
2360
2361 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2362 if (!resource) {
2363 *rc = -ENXIO;
2364 dev_err(pce_dev->pdev, "Missing MEM resource\n");
2365 goto err_pce_dev;
2366 };
2367 pce_dev->phy_iobase = resource->start;
2368 pce_dev->iobase = ioremap_nocache(resource->start,
2369 resource->end - resource->start + 1);
2370 if (!pce_dev->iobase) {
2371 *rc = -ENOMEM;
2372 dev_err(pce_dev->pdev, "Can not map io memory\n");
2373 goto err_pce_dev;
2374 }
2375
Mona Hossain3b574d82011-09-01 15:02:01 -07002376 pce_dev->ce_dm.chan_ce_in_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002377 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002378 pce_dev->ce_dm.chan_ce_out_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002379 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002380 if (pce_dev->ce_dm.chan_ce_in_cmd == NULL ||
2381 pce_dev->ce_dm.chan_ce_out_cmd == NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002382 dev_err(pce_dev->pdev, "Can not allocate memory\n");
2383 *rc = -ENOMEM;
2384 goto err_dm_chan_cmd;
2385 }
2386
2387 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2388 "crypto_channels");
2389 if (!resource) {
2390 *rc = -ENXIO;
2391 dev_err(pce_dev->pdev, "Missing DMA channel resource\n");
2392 goto err_dm_chan_cmd;
2393 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002394 pce_dev->ce_dm.chan_ce_in = resource->start;
2395 pce_dev->ce_dm.chan_ce_out = resource->end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002396 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2397 "crypto_crci_in");
2398 if (!resource) {
2399 *rc = -ENXIO;
2400 dev_err(pce_dev->pdev, "Missing DMA crci in resource\n");
2401 goto err_dm_chan_cmd;
2402 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002403 pce_dev->ce_dm.crci_in = resource->start;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002404 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2405 "crypto_crci_out");
2406 if (!resource) {
2407 *rc = -ENXIO;
2408 dev_err(pce_dev->pdev, "Missing DMA crci out resource\n");
2409 goto err_dm_chan_cmd;
2410 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002411 pce_dev->ce_dm.crci_out = resource->start;
2412 pce_dev->memsize = 2 * PAGE_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002413 pce_dev->coh_vmem = dma_alloc_coherent(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -07002414 pce_dev->memsize, &pce_dev->coh_pmem, GFP_KERNEL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002415
2416 if (pce_dev->coh_vmem == NULL) {
2417 *rc = -ENOMEM;
2418 dev_err(pce_dev->pdev, "Can not allocate coherent memory.\n");
2419 goto err;
2420 }
2421
2422 /* Get CE core clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002423 ce_core_clk = clk_get(pce_dev->pdev, "core_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002424 if (IS_ERR(ce_core_clk)) {
2425 *rc = PTR_ERR(ce_core_clk);
2426 goto err;
2427 }
2428 pce_dev->ce_core_clk = ce_core_clk;
2429 /* Get CE clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002430 ce_clk = clk_get(pce_dev->pdev, "iface_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002431 if (IS_ERR(ce_clk)) {
2432 *rc = PTR_ERR(ce_clk);
2433 clk_put(pce_dev->ce_core_clk);
2434 goto err;
2435 }
2436 pce_dev->ce_clk = ce_clk;
2437
2438 /* Enable CE core clk */
2439 *rc = clk_enable(pce_dev->ce_core_clk);
2440 if (*rc) {
2441 clk_put(pce_dev->ce_core_clk);
2442 clk_put(pce_dev->ce_clk);
2443 goto err;
2444 } else {
2445 /* Enable CE clk */
2446 *rc = clk_enable(pce_dev->ce_clk);
2447 if (*rc) {
2448 clk_disable(pce_dev->ce_core_clk);
2449 clk_put(pce_dev->ce_core_clk);
2450 clk_put(pce_dev->ce_clk);
2451 goto err;
2452
2453 }
2454 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002455 qce_setup_ce_dm_data(pce_dev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002456
Mona Hossain3b574d82011-09-01 15:02:01 -07002457 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
2458 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002459 if (_init_ce_engine(pce_dev)) {
2460 *rc = -ENXIO;
2461 goto err;
2462 }
2463 *rc = 0;
2464 return pce_dev;
2465
2466err:
2467 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002468 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
Mona Hossaine1b13f82011-08-30 09:35:49 -07002469 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002470err_dm_chan_cmd:
Mona Hossain3b574d82011-09-01 15:02:01 -07002471 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2472 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002473 if (pce_dev->iobase)
2474 iounmap(pce_dev->iobase);
2475
2476err_pce_dev:
2477
2478 kfree(pce_dev);
2479
2480 return NULL;
2481}
2482EXPORT_SYMBOL(qce_open);
2483
2484/* crypto engine close function. */
2485int qce_close(void *handle)
2486{
2487 struct qce_device *pce_dev = (struct qce_device *) handle;
2488
2489 if (handle == NULL)
2490 return -ENODEV;
2491 if (pce_dev->iobase)
2492 iounmap(pce_dev->iobase);
2493
2494 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002495 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
2496 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002497 clk_disable(pce_dev->ce_clk);
2498 clk_disable(pce_dev->ce_core_clk);
2499
2500 clk_put(pce_dev->ce_clk);
2501 clk_put(pce_dev->ce_core_clk);
2502
Mona Hossain3b574d82011-09-01 15:02:01 -07002503 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2504 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002505 kfree(handle);
2506
2507 return 0;
2508}
2509EXPORT_SYMBOL(qce_close);
2510
2511int qce_hw_support(void *handle, struct ce_hw_support *ce_support)
2512{
2513 if (ce_support == NULL)
2514 return -EINVAL;
2515
2516 ce_support->sha1_hmac_20 = false;
2517 ce_support->sha1_hmac = false;
2518 ce_support->sha256_hmac = false;
2519 ce_support->sha_hmac = false;
2520 ce_support->cmac = true;
2521 ce_support->aes_key_192 = false;
2522 ce_support->aes_xts = true;
2523 ce_support->aes_ccm = true;
2524 ce_support->ota = false;
2525 return 0;
2526}
2527EXPORT_SYMBOL(qce_hw_support);
2528
2529MODULE_LICENSE("GPL v2");
2530MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
2531MODULE_DESCRIPTION("Crypto Engine driver");
Mona Hossain2563cbc2011-09-14 15:24:08 -07002532MODULE_VERSION("2.11");