blob: 893933bc32c28cfe4108260301bf0544dae389f6 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Qualcomm Crypto Engine driver.
2 *
3 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 and
7 * only version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#include <linux/types.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/mod_devicetable.h>
18#include <linux/device.h>
19#include <linux/clk.h>
20#include <linux/err.h>
21#include <linux/dma-mapping.h>
22#include <linux/io.h>
23#include <linux/platform_device.h>
24#include <linux/spinlock.h>
25#include <linux/delay.h>
26#include <linux/crypto.h>
Mona Hossain5c8ea1f2011-07-28 15:11:29 -070027#include <linux/qcedev.h>
Ramesh Masavarapu72077202011-11-02 10:34:26 -070028#include <linux/bitops.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070029#include <crypto/hash.h>
30#include <crypto/sha.h>
31#include <mach/dma.h>
32#include <mach/clk.h>
Ramesh Masavarapufa679d92011-10-13 23:42:59 -070033#include <mach/socinfo.h>
Mona Hossain5c8ea1f2011-07-28 15:11:29 -070034
35#include "qce.h"
Mona Hossain3b574d82011-09-01 15:02:01 -070036#include "qce40.h"
Mona Hossain5c8ea1f2011-07-28 15:11:29 -070037#include "qcryptohw_40.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070038
39/* ADM definitions */
40#define LI_SG_CMD (1 << 31) /* last index in the scatter gather cmd */
41#define SRC_INDEX_SG_CMD(index) ((index & 0x3fff) << 16)
42#define DST_INDEX_SG_CMD(index) (index & 0x3fff)
43#define ADM_DESC_LAST (1 << 31)
Mona Hossain3b574d82011-09-01 15:02:01 -070044#define QCE_FIFO_SIZE 0x8000
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070045/*
46 * CE HW device structure.
47 * Each engine has an instance of the structure.
48 * Each engine can only handle one crypto operation at one time. It is up to
49 * the sw above to ensure single threading of operation on an engine.
50 */
51struct qce_device {
52 struct device *pdev; /* Handle to platform_device structure */
Mona Hossain3b574d82011-09-01 15:02:01 -070053
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070054 unsigned char *coh_vmem; /* Allocated coherent virtual memory */
55 dma_addr_t coh_pmem; /* Allocated coherent physical memory */
Mona Hossain3b574d82011-09-01 15:02:01 -070056 int memsize; /* Memory allocated */
57
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070058 void __iomem *iobase; /* Virtual io base of CE HW */
59 unsigned int phy_iobase; /* Physical io base of CE HW */
Mona Hossain3b574d82011-09-01 15:02:01 -070060
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070061 struct clk *ce_core_clk; /* Handle to CE clk */
62 struct clk *ce_clk; /* Handle to CE clk */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070063
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070064 qce_comp_func_ptr_t qce_cb; /* qce callback function pointer */
65
66 int assoc_nents;
67 int ivsize;
68 int authsize;
69 int src_nents;
70 int dst_nents;
71
72 void *areq;
73 enum qce_cipher_mode_enum mode;
Mona Hossain3b574d82011-09-01 15:02:01 -070074 struct ce_dm_data ce_dm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070075};
76
77/* Standard initialization vector for SHA-1, source: FIPS 180-2 */
Mona Hossain3b574d82011-09-01 15:02:01 -070078static uint8_t _std_init_vector_sha1_uint8[] = {
79 0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89,
80 0x98, 0xBA, 0xDC, 0xFE, 0x10, 0x32, 0x54, 0x76,
81 0xC3, 0xD2, 0xE1, 0xF0
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070082};
Mona Hossain3b574d82011-09-01 15:02:01 -070083
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070084/* Standard initialization vector for SHA-256, source: FIPS 180-2 */
Mona Hossain3b574d82011-09-01 15:02:01 -070085static uint8_t _std_init_vector_sha256_uint8[] = {
86 0x6A, 0x09, 0xE6, 0x67, 0xBB, 0x67, 0xAE, 0x85,
87 0x3C, 0x6E, 0xF3, 0x72, 0xA5, 0x4F, 0xF5, 0x3A,
88 0x51, 0x0E, 0x52, 0x7F, 0x9B, 0x05, 0x68, 0x8C,
89 0x1F, 0x83, 0xD9, 0xAB, 0x5B, 0xE0, 0xCD, 0x19
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070090};
91
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070092static void _byte_stream_swap_to_net_words(uint32_t *iv, unsigned char *b,
93 unsigned int len)
94{
95 unsigned i, j;
96 unsigned char swap_iv[AES_IV_LENGTH];
97
98 memset(swap_iv, 0, AES_IV_LENGTH);
99 for (i = (AES_IV_LENGTH-len), j = len-1; i < AES_IV_LENGTH; i++, j--)
100 swap_iv[i] = b[j];
Mona Hossain3b574d82011-09-01 15:02:01 -0700101 memcpy(iv, swap_iv, AES_IV_LENGTH);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700102}
103
104static int count_sg(struct scatterlist *sg, int nbytes)
105{
106 int i;
107
108 for (i = 0; nbytes > 0; i++, sg = sg_next(sg))
109 nbytes -= sg->length;
110 return i;
111}
112
113static int dma_map_pmem_sg(struct buf_info *pmem, unsigned entries,
114 struct scatterlist *sg)
115{
116 int i;
117 for (i = 0; i < entries; i++) {
118
119 sg->dma_address = (dma_addr_t)pmem->offset;
120 sg++;
121 pmem++;
122 }
123 return 0;
124}
125
126static int _probe_ce_engine(struct qce_device *pce_dev)
127{
128 unsigned int val;
129 unsigned int rev;
130
Mona Hossain3b574d82011-09-01 15:02:01 -0700131 val = (uint32_t)(*((uint32_t *)pce_dev->ce_dm.buffer.version));
Mona Hossain5f5dde12011-09-12 10:28:34 -0700132 if (((val & 0xfffffff) != 0x0000043) &&
133 ((val & 0xfffffff) != 0x0000042) &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700134 ((val & 0xfffffff) != 0x0000040)) {
135 dev_err(pce_dev->pdev,
136 "Unknown Qualcomm crypto device at 0x%x 0x%x\n",
137 pce_dev->phy_iobase, val);
138 return -EIO;
139 };
140 rev = (val & CRYPTO_CORE_REV_MASK);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700141 if (rev >= 0x42) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700142 dev_info(pce_dev->pdev,
143 "Qualcomm Crypto 4.2 device found at 0x%x\n",
144 pce_dev->phy_iobase);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700145 pce_dev->ce_dm.ce_block_size = 64;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700146 } else {
147 if (rev == 0x40) {
148 dev_info(pce_dev->pdev,
149 "Qualcomm Crypto 4.0 device found at 0x%x\n",
150 pce_dev->phy_iobase);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700151 pce_dev->ce_dm.ce_block_size = 16;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700152 }
153 }
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700154 /*
155 * This is a temporary change - until Data Mover changes its
156 * configuration from 16 byte crci to 64 byte crci.
157 */
158 if (cpu_is_msm9615())
159 pce_dev->ce_dm.ce_block_size = 16;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700160
161 dev_info(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -0700162 "IO base 0x%x\n, ce_in channel %d , "
163 "ce_out channel %d\n, "
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700164 "crci_in %d, crci_out %d\n",
165 (unsigned int) pce_dev->iobase,
Mona Hossain3b574d82011-09-01 15:02:01 -0700166 pce_dev->ce_dm.chan_ce_in, pce_dev->ce_dm.chan_ce_out,
167 pce_dev->ce_dm.crci_in, pce_dev->ce_dm.crci_out);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700168
169 return 0;
170};
171
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700172static void config_ce_engine(struct qce_device *pce_dev)
173{
174 unsigned int val = 0;
Ramesh Masavarapu72077202011-11-02 10:34:26 -0700175 unsigned int ret = 0;
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700176
Ramesh Masavarapu72077202011-11-02 10:34:26 -0700177 /* Crypto config register returns a 0 when it is XPU protected. */
178 ret = readl_relaxed(pce_dev->iobase + CRYPTO_CONFIG_REG);
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700179
Ramesh Masavarapu72077202011-11-02 10:34:26 -0700180 /* Configure the crypto register if it is not XPU protected. */
181 if (ret) {
182 val = BIT(CRYPTO_MASK_DOUT_INTR) |
183 BIT(CRYPTO_MASK_DIN_INTR) |
184 BIT(CRYPTO_MASK_OP_DONE_INTR) |
185 BIT(CRYPTO_MASK_ERR_INTR);
186
187 writel_relaxed(val, pce_dev->iobase + CRYPTO_CONFIG_REG);
188 }
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700189}
Mona Hossain3b574d82011-09-01 15:02:01 -0700190
191static void _check_probe_done_call_back(struct msm_dmov_cmd *cmd_ptr,
192 unsigned int result, struct msm_dmov_errdata *err)
193{
194 struct qce_device *pce_dev;
195 pce_dev = (struct qce_device *) cmd_ptr->user;
196
197 if (result != ADM_STATUS_OK) {
198 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
199 result);
200 pce_dev->ce_dm.chan_ce_in_status = -1;
201 } else {
202 _probe_ce_engine(pce_dev);
203 pce_dev->ce_dm.chan_ce_in_status = 0;
204 }
205 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
206};
207
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700208static int _init_ce_engine(struct qce_device *pce_dev)
209{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700210 /* Reset ce */
211 clk_reset(pce_dev->ce_core_clk, CLK_RESET_ASSERT);
212 clk_reset(pce_dev->ce_core_clk, CLK_RESET_DEASSERT);
Mona Hossain3b574d82011-09-01 15:02:01 -0700213
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700214 /*
215 * Ensure previous instruction (any writes to CLK registers)
216 * to toggle the CLK reset lines was completed before configuring
217 * ce engine. The ce engine configuration settings should not be lost
218 * becasue of clk reset.
219 */
220 mb();
221
222 /* Configure the CE Engine */
223 config_ce_engine(pce_dev);
224
225 /*
226 * Ensure ce configuration is completed.
227 */
228 mb();
229
Mona Hossain3b574d82011-09-01 15:02:01 -0700230 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
231 _check_probe_done_call_back;
232 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
233 pce_dev->ce_dm.cmdptrlist.probe_ce_hw;
234 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
235 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
236 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
237 pce_dev->ce_dm.chan_ce_in_cmd);
238
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700239 return 0;
240};
241
Mona Hossain3b574d82011-09-01 15:02:01 -0700242static int _ce_setup_hash_cmdrptrlist(struct qce_device *pce_dev,
243 struct qce_sha_req *sreq)
244{
245 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
246
247 switch (sreq->alg) {
248 case QCE_HASH_SHA1:
249 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr = cmdptrlist->auth_sha1;
250 break;
251
252 case QCE_HASH_SHA256:
253 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr = cmdptrlist->auth_sha256;
254 break;
255 case QCE_HASH_SHA1_HMAC:
256 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
257 cmdptrlist->auth_sha1_hmac;
258 break;
259
260 case QCE_HASH_SHA256_HMAC:
261 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
262 cmdptrlist->auth_sha256_hmac;
263 break;
264 case QCE_HASH_AES_CMAC:
265 if (sreq->authklen == AES128_KEY_SIZE)
266 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
267 cmdptrlist->auth_aes_128_cmac;
268 else
269 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
270 cmdptrlist->auth_aes_256_cmac;
271 break;
272
273 default:
274 break;
275 }
276
277 return 0;
278}
279
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700280static int _ce_setup_hash(struct qce_device *pce_dev, struct qce_sha_req *sreq)
281{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700282 uint32_t diglen;
283 int i;
284 uint32_t auth_cfg = 0;
285 bool sha1 = false;
286
287 if (sreq->alg == QCE_HASH_AES_CMAC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700288
Mona Hossain3b574d82011-09-01 15:02:01 -0700289 memcpy(pce_dev->ce_dm.buffer.auth_key, sreq->authkey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700290 sreq->authklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700291 auth_cfg |= (1 << CRYPTO_LAST);
292 auth_cfg |= (CRYPTO_AUTH_MODE_CMAC << CRYPTO_AUTH_MODE);
293 auth_cfg |= (CRYPTO_AUTH_SIZE_ENUM_16_BYTES <<
294 CRYPTO_AUTH_SIZE);
295 auth_cfg |= CRYPTO_AUTH_ALG_AES << CRYPTO_AUTH_ALG;
296
297 switch (sreq->authklen) {
298 case AES128_KEY_SIZE:
299 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES128 <<
300 CRYPTO_AUTH_KEY_SIZE);
301 break;
302 case AES256_KEY_SIZE:
303 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES256 <<
304 CRYPTO_AUTH_KEY_SIZE);
305 break;
306 default:
307 break;
308 }
309
310 goto go_proc;
311 }
312
313 /* if not the last, the size has to be on the block boundary */
314 if (sreq->last_blk == 0 && (sreq->size % SHA256_BLOCK_SIZE))
315 return -EIO;
316
317 switch (sreq->alg) {
318 case QCE_HASH_SHA1:
319 case QCE_HASH_SHA1_HMAC:
320 diglen = SHA1_DIGEST_SIZE;
321 sha1 = true;
322 break;
323 case QCE_HASH_SHA256:
324 case QCE_HASH_SHA256_HMAC:
325 diglen = SHA256_DIGEST_SIZE;
326 break;
327 default:
328 return -EINVAL;
329 }
330
331 if ((sreq->alg == QCE_HASH_SHA1_HMAC) ||
332 (sreq->alg == QCE_HASH_SHA256_HMAC)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700333
Mona Hossain3b574d82011-09-01 15:02:01 -0700334 memcpy(pce_dev->ce_dm.buffer.auth_key, sreq->authkey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700335 sreq->authklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700336 auth_cfg |= (CRYPTO_AUTH_MODE_HMAC << CRYPTO_AUTH_MODE);
337 } else {
338 auth_cfg |= (CRYPTO_AUTH_MODE_HASH << CRYPTO_AUTH_MODE);
339 }
340
341 /* write 20/32 bytes, 5/8 words into auth_iv for SHA1/SHA256 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700342 if (sreq->first_blk) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700343 if (sha1)
344 memcpy(pce_dev->ce_dm.buffer.auth_iv,
345 _std_init_vector_sha1_uint8, diglen);
346 else
347 memcpy(pce_dev->ce_dm.buffer.auth_iv,
348 _std_init_vector_sha256_uint8, diglen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700349 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700350 memcpy(pce_dev->ce_dm.buffer.auth_iv, sreq->digest,
351 diglen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700352 }
353
Mona Hossain3b574d82011-09-01 15:02:01 -0700354 /* write auth_bytecnt 0/1/2/3, start with 0 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700355 for (i = 0; i < 4; i++)
Mona Hossain3b574d82011-09-01 15:02:01 -0700356 *(((uint32_t *)(pce_dev->ce_dm.buffer.auth_byte_count) + i)) =
357 sreq->auth_data[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700358
359 /* write seg_cfg */
360 if (sha1)
361 auth_cfg |= (CRYPTO_AUTH_SIZE_SHA1 << CRYPTO_AUTH_SIZE);
362 else
363 auth_cfg |= (CRYPTO_AUTH_SIZE_SHA256 << CRYPTO_AUTH_SIZE);
364
365 if (sreq->last_blk)
366 auth_cfg |= 1 << CRYPTO_LAST;
367
368 auth_cfg |= CRYPTO_AUTH_ALG_SHA << CRYPTO_AUTH_ALG;
369
370go_proc:
371 auth_cfg |= (CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);
372
Mona Hossain3b574d82011-09-01 15:02:01 -0700373 /* write auth seg cfg */
374 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start)) =
375 auth_cfg;
376 /* write auth seg size */
377 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start) + 1) =
378 sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700379
Mona Hossain3b574d82011-09-01 15:02:01 -0700380 /* write auth seg size start*/
381 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start)+2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700382
Mona Hossain3b574d82011-09-01 15:02:01 -0700383 /* write seg size */
384 *((uint32_t *)(pce_dev->ce_dm.buffer.seg_size)) = sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700385
Mona Hossain3b574d82011-09-01 15:02:01 -0700386 _ce_setup_hash_cmdrptrlist(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700387
Mona Hossain3b574d82011-09-01 15:02:01 -0700388 return 0;
389}
390
391static int _ce_setup_cipher_cmdrptrlist(struct qce_device *pce_dev,
392 struct qce_req *creq)
393{
394 struct ce_cmdptrlists_ops *cmdptrlist =
395 &pce_dev->ce_dm.cmdptrlist;
396
397 if (creq->alg != CIPHER_ALG_AES) {
398 switch (creq->alg) {
399 case CIPHER_ALG_DES:
400 if (creq->mode == QCE_MODE_ECB) {
401 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
402 cmdptrlist->cipher_des_ecb;
403 } else {
404 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
405 cmdptrlist->cipher_des_cbc;
406 }
407 break;
408
409 case CIPHER_ALG_3DES:
410 if (creq->mode == QCE_MODE_ECB) {
411 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
412 cmdptrlist->cipher_3des_ecb;
413 } else {
414 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
415 cmdptrlist->cipher_3des_cbc;
416 }
417 break;
418 default:
419 break;
420 }
421 } else {
422 switch (creq->mode) {
423 case QCE_MODE_ECB:
424 if (creq->encklen == AES128_KEY_SIZE) {
425 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
426 cmdptrlist->cipher_aes_128_ecb;
427 } else {
428 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
429 cmdptrlist->cipher_aes_256_ecb;
430 }
431 break;
432
433 case QCE_MODE_CBC:
434 if (creq->encklen == AES128_KEY_SIZE) {
435 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
436 cmdptrlist->cipher_aes_128_cbc_ctr;
437 } else {
438 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
439 cmdptrlist->cipher_aes_256_cbc_ctr;
440 }
441 break;
442
443 case QCE_MODE_CTR:
444 if (creq->encklen == AES128_KEY_SIZE) {
445 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
446 cmdptrlist->cipher_aes_128_cbc_ctr;
447 } else {
448 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
449 cmdptrlist->cipher_aes_256_cbc_ctr;
450 }
451 break;
452
453 case QCE_MODE_XTS:
454 if (creq->encklen == AES128_KEY_SIZE) {
455 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
456 cmdptrlist->cipher_aes_128_xts;
457 } else {
458 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
459 cmdptrlist->cipher_aes_256_xts;
460 }
461 break;
462 case QCE_MODE_CCM:
463 if (creq->encklen == AES128_KEY_SIZE) {
464 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
465 cmdptrlist->aead_aes_128_ccm;
466 } else {
467 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
468 cmdptrlist->aead_aes_256_ccm;
469 }
470 break;
471 default:
472 break;
473 }
474 }
475
476 if (creq->mode == QCE_MODE_CCM)
477 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
478 cmdptrlist->aead_ce_out;
479 else
480 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
481 cmdptrlist->cipher_ce_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700482
483 return 0;
484}
485
486static int _ce_setup_cipher(struct qce_device *pce_dev, struct qce_req *creq,
487 uint32_t totallen_in, uint32_t coffset)
488{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700489 uint32_t enck_size_in_word = creq->encklen / sizeof(uint32_t);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700490 uint32_t encr_cfg = 0;
491 uint32_t ivsize = creq->ivsize;
Mona Hossain3b574d82011-09-01 15:02:01 -0700492 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700493
494 if (creq->mode == QCE_MODE_XTS)
Mona Hossain3b574d82011-09-01 15:02:01 -0700495 memcpy(buffer->encr_key, creq->enckey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700496 creq->encklen/2);
497 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700498 memcpy(buffer->encr_key, creq->enckey, creq->encklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700499
500 if ((creq->op == QCE_REQ_AEAD) && (creq->mode == QCE_MODE_CCM)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700501 uint32_t noncelen32 = MAX_NONCE/sizeof(uint32_t);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700502 uint32_t auth_cfg = 0;
503
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700504 /* write nonce */
Mona Hossain3b574d82011-09-01 15:02:01 -0700505 memcpy(buffer->auth_nonce_info, creq->nonce, MAX_NONCE);
506 memcpy(buffer->auth_key, creq->enckey, creq->encklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700507
508 auth_cfg |= (noncelen32 << CRYPTO_AUTH_NONCE_NUM_WORDS);
509 auth_cfg &= ~(1 << CRYPTO_USE_HW_KEY_AUTH);
510 auth_cfg |= (1 << CRYPTO_LAST);
511 if (creq->dir == QCE_ENCRYPT)
512 auth_cfg |= (CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);
513 else
514 auth_cfg |= (CRYPTO_AUTH_POS_AFTER << CRYPTO_AUTH_POS);
515 auth_cfg |= (((creq->authsize >> 1) - 2) << CRYPTO_AUTH_SIZE);
516 auth_cfg |= (CRYPTO_AUTH_MODE_CCM << CRYPTO_AUTH_MODE);
517 if (creq->authklen == AES128_KEY_SIZE)
518 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES128 <<
519 CRYPTO_AUTH_KEY_SIZE);
520 else {
521 if (creq->authklen == AES256_KEY_SIZE)
522 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES256 <<
523 CRYPTO_AUTH_KEY_SIZE);
524 }
525 auth_cfg |= (CRYPTO_AUTH_ALG_AES << CRYPTO_AUTH_ALG);
Mona Hossain3b574d82011-09-01 15:02:01 -0700526 *((uint32_t *)(buffer->auth_seg_cfg_size_start)) = auth_cfg;
527
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700528 if (creq->dir == QCE_ENCRYPT)
Mona Hossain3b574d82011-09-01 15:02:01 -0700529 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 1) =
530 totallen_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700531 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700532 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 1) =
533 (totallen_in - creq->authsize);
534 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700535 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700536
537 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700538
539 switch (creq->mode) {
540 case QCE_MODE_ECB:
541 encr_cfg |= (CRYPTO_ENCR_MODE_ECB << CRYPTO_ENCR_MODE);
542 break;
543
544 case QCE_MODE_CBC:
545 encr_cfg |= (CRYPTO_ENCR_MODE_CBC << CRYPTO_ENCR_MODE);
546 break;
547
548 case QCE_MODE_XTS:
549 encr_cfg |= (CRYPTO_ENCR_MODE_XTS << CRYPTO_ENCR_MODE);
550 break;
551
552 case QCE_MODE_CCM:
553 encr_cfg |= (CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE);
554 break;
555
556 case QCE_MODE_CTR:
557 default:
558 encr_cfg |= (CRYPTO_ENCR_MODE_CTR << CRYPTO_ENCR_MODE);
559 break;
560 }
561 pce_dev->mode = creq->mode;
562
563 switch (creq->alg) {
564 case CIPHER_ALG_DES:
Mona Hossain3b574d82011-09-01 15:02:01 -0700565 if (creq->mode != QCE_MODE_ECB)
566 memcpy(buffer->encr_cntr_iv, creq->iv, ivsize);
567
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700568 encr_cfg |= ((CRYPTO_ENCR_KEY_SZ_DES << CRYPTO_ENCR_KEY_SZ) |
569 (CRYPTO_ENCR_ALG_DES << CRYPTO_ENCR_ALG));
570 break;
571
572 case CIPHER_ALG_3DES:
Mona Hossain3b574d82011-09-01 15:02:01 -0700573 if (creq->mode != QCE_MODE_ECB)
574 memcpy(buffer->encr_cntr_iv, creq->iv, ivsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700575
576 encr_cfg |= ((CRYPTO_ENCR_KEY_SZ_3DES << CRYPTO_ENCR_KEY_SZ) |
577 (CRYPTO_ENCR_ALG_DES << CRYPTO_ENCR_ALG));
578 break;
579
580 case CIPHER_ALG_AES:
581 default:
582 if (creq->mode == QCE_MODE_XTS) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700583 memcpy(buffer->encr_xts_key, (creq->enckey +
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700584 creq->encklen/2), creq->encklen/2);
Mona Hossain3b574d82011-09-01 15:02:01 -0700585 *((uint32_t *)(buffer->encr_xts_du_size)) =
586 creq->cryptlen;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700587
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700588 }
589 if (creq->mode != QCE_MODE_ECB) {
590 if (creq->mode == QCE_MODE_XTS)
Mona Hossain3b574d82011-09-01 15:02:01 -0700591 _byte_stream_swap_to_net_words(
592 (uint32_t *)(buffer->encr_cntr_iv),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700593 creq->iv, ivsize);
594 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700595 memcpy(buffer->encr_cntr_iv, creq->iv,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700596 ivsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700597 }
598 /* set number of counter bits */
Mona Hossain3b574d82011-09-01 15:02:01 -0700599 *((uint32_t *)(buffer->encr_mask)) = (uint32_t)0xffffffff;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700600
601 if (creq->op == QCE_REQ_ABLK_CIPHER_NO_KEY) {
602 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES128 <<
603 CRYPTO_ENCR_KEY_SZ);
604 encr_cfg |= CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG;
605 } else {
606 uint32_t key_size;
607
608 if (creq->mode == QCE_MODE_XTS) {
609 key_size = creq->encklen/2;
610 enck_size_in_word = key_size/sizeof(uint32_t);
611 } else {
612 key_size = creq->encklen;
613 }
614
615 switch (key_size) {
616 case AES128_KEY_SIZE:
617 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES128 <<
618 CRYPTO_ENCR_KEY_SZ);
619 break;
620 case AES256_KEY_SIZE:
621 default:
622 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES256 <<
623 CRYPTO_ENCR_KEY_SZ);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700624 break;
625 } /* end of switch (creq->encklen) */
626
627 encr_cfg |= CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700628 } /* else of if (creq->op == QCE_REQ_ABLK_CIPHER_NO_KEY) */
629 break;
630 } /* end of switch (creq->mode) */
631
632 /* write encr seg cfg */
633 encr_cfg |= ((creq->dir == QCE_ENCRYPT) ? 1 : 0) << CRYPTO_ENCODE;
634
635 /* write encr seg cfg */
Mona Hossain3b574d82011-09-01 15:02:01 -0700636 *((uint32_t *)(buffer->encr_seg_cfg_size_start)) = encr_cfg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700637 /* write encr seg size */
638 if ((creq->mode == QCE_MODE_CCM) && (creq->dir == QCE_DECRYPT))
Mona Hossain3b574d82011-09-01 15:02:01 -0700639 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 1) =
640 (creq->cryptlen + creq->authsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700641 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700642 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 1) =
643 creq->cryptlen;
644
645
646 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 2) =
647 (coffset & 0xffff);
648
649 *((uint32_t *)(buffer->seg_size)) = totallen_in;
650
651 _ce_setup_cipher_cmdrptrlist(pce_dev, creq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700652 return 0;
653};
654
655static int _aead_complete(struct qce_device *pce_dev)
656{
657 struct aead_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700658
659 areq = (struct aead_request *) pce_dev->areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700660
661 if (areq->src != areq->dst) {
662 dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
663 DMA_FROM_DEVICE);
664 }
665 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
666 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
667 DMA_TO_DEVICE);
668
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700669 dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
670 DMA_TO_DEVICE);
671
Mona Hossain3b574d82011-09-01 15:02:01 -0700672 /* check MAC */
673 if (pce_dev->mode == QCE_MODE_CCM) {
674 uint32_t result;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700675
Mona Hossain3b574d82011-09-01 15:02:01 -0700676 result =
677 (uint32_t)(*((uint32_t *)pce_dev->ce_dm.buffer.status));
678 result &= (1 << CRYPTO_MAC_FAILED);
679 result |= (pce_dev->ce_dm.chan_ce_in_status |
680 pce_dev->ce_dm.chan_ce_out_status);
681 pce_dev->qce_cb(areq, pce_dev->ce_dm.buffer.auth_result, NULL,
682 result);
683 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700684 return 0;
685};
686
687static void _sha_complete(struct qce_device *pce_dev)
688{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700689 struct ahash_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700690
691 areq = (struct ahash_request *) pce_dev->areq;
692 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
693 DMA_TO_DEVICE);
694
Mona Hossain3b574d82011-09-01 15:02:01 -0700695 pce_dev->qce_cb(areq, pce_dev->ce_dm.buffer.auth_result,
696 pce_dev->ce_dm.buffer.auth_byte_count,
697 pce_dev->ce_dm.chan_ce_in_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700698
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700699};
700
701static int _ablk_cipher_complete(struct qce_device *pce_dev)
702{
703 struct ablkcipher_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700704
705 areq = (struct ablkcipher_request *) pce_dev->areq;
706
707 if (areq->src != areq->dst) {
708 dma_unmap_sg(pce_dev->pdev, areq->dst,
709 pce_dev->dst_nents, DMA_FROM_DEVICE);
710 }
711 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
712 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
713 DMA_TO_DEVICE);
Mona Hossain3b574d82011-09-01 15:02:01 -0700714
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700715 if (pce_dev->mode == QCE_MODE_ECB) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700716 pce_dev->qce_cb(areq, NULL, NULL,
717 pce_dev->ce_dm.chan_ce_in_status |
718 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700719 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700720
Mona Hossain3b574d82011-09-01 15:02:01 -0700721 pce_dev->qce_cb(areq, NULL, pce_dev->ce_dm.buffer.encr_cntr_iv,
722 pce_dev->ce_dm.chan_ce_in_status |
723 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700724 }
725
726 return 0;
727};
728
729static int _ablk_cipher_use_pmem_complete(struct qce_device *pce_dev)
730{
731 struct ablkcipher_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700732
733 areq = (struct ablkcipher_request *) pce_dev->areq;
734
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700735 if (pce_dev->mode == QCE_MODE_ECB) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700736 pce_dev->qce_cb(areq, NULL, NULL,
737 pce_dev->ce_dm.chan_ce_in_status |
738 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700739 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700740 pce_dev->qce_cb(areq, NULL, pce_dev->ce_dm.buffer.encr_cntr_iv,
741 pce_dev->ce_dm.chan_ce_in_status |
742 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700743 }
744
745 return 0;
746};
747
748static int qce_split_and_insert_dm_desc(struct dmov_desc *pdesc,
749 unsigned int plen, unsigned int paddr, int *index)
750{
Mona Hossain3b574d82011-09-01 15:02:01 -0700751 while (plen > QCE_FIFO_SIZE) {
752 pdesc->len = QCE_FIFO_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700753 if (paddr > 0) {
754 pdesc->addr = paddr;
Mona Hossain3b574d82011-09-01 15:02:01 -0700755 paddr += QCE_FIFO_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700756 }
757 plen -= pdesc->len;
758 if (plen > 0) {
759 *index = (*index) + 1;
760 if ((*index) >= QCE_MAX_NUM_DESC)
761 return -ENOMEM;
762 pdesc++;
763 }
764 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700765 if ((plen > 0) && (plen <= QCE_FIFO_SIZE)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700766 pdesc->len = plen;
767 if (paddr > 0)
768 pdesc->addr = paddr;
769 }
770
771 return 0;
772}
773
774static int _chain_sg_buffer_in(struct qce_device *pce_dev,
775 struct scatterlist *sg, unsigned int nbytes)
776{
777 unsigned int len;
778 unsigned int dlen;
779 struct dmov_desc *pdesc;
780
Mona Hossain3b574d82011-09-01 15:02:01 -0700781 pdesc = pce_dev->ce_dm.ce_in_src_desc +
782 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700783 /*
784 * Two consective chunks may be handled by the old
785 * buffer descriptor.
786 */
787 while (nbytes > 0) {
788 len = min(nbytes, sg_dma_len(sg));
789 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
790 nbytes -= len;
791 if (dlen == 0) {
792 pdesc->addr = sg_dma_address(sg);
793 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700794 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700795 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700796 sg_dma_address(sg),
797 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700798 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
799 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700800 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700801 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700802 pdesc->addr,
803 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700804 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700805 pce_dev->ce_dm.ce_in_src_desc_index++;
806 if (pce_dev->ce_dm.ce_in_src_desc_index >=
807 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700808 return -ENOMEM;
809 pdesc++;
810 pdesc->len = len;
811 pdesc->addr = sg_dma_address(sg);
Mona Hossain3b574d82011-09-01 15:02:01 -0700812 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700813 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700814 sg_dma_address(sg),
815 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700816 }
817 if (nbytes > 0)
818 sg = sg_next(sg);
819 }
820 return 0;
821}
822
823static int _chain_pm_buffer_in(struct qce_device *pce_dev,
824 unsigned int pmem, unsigned int nbytes)
825{
826 unsigned int dlen;
827 struct dmov_desc *pdesc;
828
Mona Hossain3b574d82011-09-01 15:02:01 -0700829 pdesc = pce_dev->ce_dm.ce_in_src_desc +
830 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700831 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
832 if (dlen == 0) {
833 pdesc->addr = pmem;
834 pdesc->len = nbytes;
835 } else if (pmem == (pdesc->addr + dlen)) {
836 pdesc->len = dlen + nbytes;
837 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700838 pce_dev->ce_dm.ce_in_src_desc_index++;
839 if (pce_dev->ce_dm.ce_in_src_desc_index >=
840 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700841 return -ENOMEM;
842 pdesc++;
843 pdesc->len = nbytes;
844 pdesc->addr = pmem;
845 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700846 return 0;
847}
848
849static void _chain_buffer_in_init(struct qce_device *pce_dev)
850{
851 struct dmov_desc *pdesc;
852
Mona Hossain3b574d82011-09-01 15:02:01 -0700853 pce_dev->ce_dm.ce_in_src_desc_index = 0;
854 pce_dev->ce_dm.ce_in_dst_desc_index = 0;
855 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700856 pdesc->len = 0;
857}
858
859static void _ce_in_final(struct qce_device *pce_dev, unsigned total)
860{
861 struct dmov_desc *pdesc;
862 dmov_sg *pcmd;
863
Mona Hossain3b574d82011-09-01 15:02:01 -0700864 pdesc = pce_dev->ce_dm.ce_in_src_desc +
865 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700866 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700867
868 pdesc = pce_dev->ce_dm.ce_in_dst_desc;
869 if (total > QCE_FIFO_SIZE) {
870 qce_split_and_insert_dm_desc(pdesc, total, 0,
871 &pce_dev->ce_dm.ce_in_dst_desc_index);
872 pdesc = pce_dev->ce_dm.ce_in_dst_desc +
873 pce_dev->ce_dm.ce_in_dst_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -0700874 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700875 } else
876 pdesc->len = ADM_DESC_LAST | total;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700877
Mona Hossain3b574d82011-09-01 15:02:01 -0700878 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700879 pcmd->cmd |= CMD_LC;
Mona Hossain3b574d82011-09-01 15:02:01 -0700880
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700881}
882
883#ifdef QCE_DEBUG
884static void _ce_in_dump(struct qce_device *pce_dev)
885{
886 int i;
887 struct dmov_desc *pdesc;
888
889 dev_info(pce_dev->pdev, "_ce_in_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700890 for (i = 0; i <= pce_dev->ce_dm.ce_in_src_desc_index; i++) {
891 pdesc = pce_dev->ce_dm.ce_in_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700892 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
893 pdesc->len);
894 }
895 dev_info(pce_dev->pdev, "_ce_in_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700896 for (i = 0; i <= pce_dev->ce_dm.ce_in_dst_desc_index; i++) {
897 pdesc = pce_dev->ce_dm.ce_in_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700898 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
899 pdesc->len);
900 }
901};
902
903static void _ce_out_dump(struct qce_device *pce_dev)
904{
905 int i;
906 struct dmov_desc *pdesc;
907
908 dev_info(pce_dev->pdev, "_ce_out_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700909 for (i = 0; i <= pce_dev->ce_dm.ce_out_src_desc_index; i++) {
910 pdesc = pce_dev->ce_dm.ce_out_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700911 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
912 pdesc->len);
913 }
914
915 dev_info(pce_dev->pdev, "_ce_out_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700916 for (i = 0; i <= pce_dev->ce_dm.ce_out_dst_desc_index; i++) {
917 pdesc = pce_dev->ce_dm.ce_out_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700918 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
919 pdesc->len);
920 }
921};
922
923#else
924
925static void _ce_in_dump(struct qce_device *pce_dev)
926{
927};
928
929static void _ce_out_dump(struct qce_device *pce_dev)
930{
931};
932
933#endif
934
935static int _chain_sg_buffer_out(struct qce_device *pce_dev,
936 struct scatterlist *sg, unsigned int nbytes)
937{
938 unsigned int len;
939 unsigned int dlen;
940 struct dmov_desc *pdesc;
941
Mona Hossain3b574d82011-09-01 15:02:01 -0700942 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
943 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700944 /*
945 * Two consective chunks may be handled by the old
946 * buffer descriptor.
947 */
948 while (nbytes > 0) {
949 len = min(nbytes, sg_dma_len(sg));
950 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
951 nbytes -= len;
952 if (dlen == 0) {
953 pdesc->addr = sg_dma_address(sg);
954 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700955 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700956 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
957 sg_dma_address(sg),
Mona Hossain3b574d82011-09-01 15:02:01 -0700958 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700959 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
960 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700961 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700962 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
963 pdesc->addr,
Mona Hossain3b574d82011-09-01 15:02:01 -0700964 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700965
966 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700967 pce_dev->ce_dm.ce_out_dst_desc_index++;
968 if (pce_dev->ce_dm.ce_out_dst_desc_index >=
969 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700970 return -EIO;
971 pdesc++;
972 pdesc->len = len;
973 pdesc->addr = sg_dma_address(sg);
Mona Hossain3b574d82011-09-01 15:02:01 -0700974 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700975 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
976 sg_dma_address(sg),
Mona Hossain3b574d82011-09-01 15:02:01 -0700977 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700978
979 }
980 if (nbytes > 0)
981 sg = sg_next(sg);
982 }
983 return 0;
984}
985
986static int _chain_pm_buffer_out(struct qce_device *pce_dev,
987 unsigned int pmem, unsigned int nbytes)
988{
989 unsigned int dlen;
990 struct dmov_desc *pdesc;
991
Mona Hossain3b574d82011-09-01 15:02:01 -0700992 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
993 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700994 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
995
996 if (dlen == 0) {
997 pdesc->addr = pmem;
998 pdesc->len = nbytes;
999 } else if (pmem == (pdesc->addr + dlen)) {
1000 pdesc->len = dlen + nbytes;
1001 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001002 pce_dev->ce_dm.ce_out_dst_desc_index++;
1003 if (pce_dev->ce_dm.ce_out_dst_desc_index >= QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001004 return -EIO;
1005 pdesc++;
1006 pdesc->len = nbytes;
1007 pdesc->addr = pmem;
1008 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001009 return 0;
1010};
1011
1012static void _chain_buffer_out_init(struct qce_device *pce_dev)
1013{
1014 struct dmov_desc *pdesc;
1015
Mona Hossain3b574d82011-09-01 15:02:01 -07001016 pce_dev->ce_dm.ce_out_dst_desc_index = 0;
1017 pce_dev->ce_dm.ce_out_src_desc_index = 0;
1018 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001019 pdesc->len = 0;
1020};
1021
1022static void _ce_out_final(struct qce_device *pce_dev, unsigned total)
1023{
1024 struct dmov_desc *pdesc;
1025 dmov_sg *pcmd;
1026
Mona Hossain3b574d82011-09-01 15:02:01 -07001027 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
1028 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001029 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001030
Mona Hossain3b574d82011-09-01 15:02:01 -07001031 pdesc = pce_dev->ce_dm.ce_out_src_desc +
1032 pce_dev->ce_dm.ce_out_src_desc_index;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001033 if (total > QCE_FIFO_SIZE) {
1034 qce_split_and_insert_dm_desc(pdesc, total, 0,
1035 &pce_dev->ce_dm.ce_out_src_desc_index);
1036 pdesc = pce_dev->ce_dm.ce_out_src_desc +
1037 pce_dev->ce_dm.ce_out_src_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -07001038 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001039 } else
1040 pdesc->len = ADM_DESC_LAST | total;
Mona Hossain3b574d82011-09-01 15:02:01 -07001041
1042 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001043 pcmd->cmd |= CMD_LC;
1044};
1045
1046static void _aead_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1047 unsigned int result, struct msm_dmov_errdata *err)
1048{
1049 struct qce_device *pce_dev;
1050
1051 pce_dev = (struct qce_device *) cmd_ptr->user;
1052 if (result != ADM_STATUS_OK) {
1053 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1054 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001055 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001056 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001057 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001058 }
1059
Mona Hossain3b574d82011-09-01 15:02:01 -07001060 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1061 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1062 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1063 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001064
1065 /* done */
1066 _aead_complete(pce_dev);
1067 }
1068};
1069
1070static void _aead_ce_out_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_out_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_out_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_out_state = QCE_CHAN_STATE_COMP;
1085 if (pce_dev->ce_dm.chan_ce_in_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 _aead_complete(pce_dev);
1091 }
1092
1093};
1094
1095static void _sha_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1096 unsigned int result, struct msm_dmov_errdata *err)
1097{
1098 struct qce_device *pce_dev;
1099
1100 pce_dev = (struct qce_device *) cmd_ptr->user;
1101 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_in_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_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001107 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001108 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001109 _sha_complete(pce_dev);
1110};
1111
1112static void _ablk_cipher_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1113 unsigned int result, struct msm_dmov_errdata *err)
1114{
1115 struct qce_device *pce_dev;
1116
1117 pce_dev = (struct qce_device *) cmd_ptr->user;
1118 if (result != ADM_STATUS_OK) {
1119 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1120 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001121 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001122 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001123 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001124 }
1125
Mona Hossain3b574d82011-09-01 15:02:01 -07001126 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1127 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1128 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1129 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001130
1131 /* done */
1132 _ablk_cipher_complete(pce_dev);
1133 }
1134};
1135
1136static void _ablk_cipher_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1137 unsigned int result, struct msm_dmov_errdata *err)
1138{
1139 struct qce_device *pce_dev;
1140
1141 pce_dev = (struct qce_device *) cmd_ptr->user;
Mona Hossain3b574d82011-09-01 15:02:01 -07001142
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001143 if (result != ADM_STATUS_OK) {
1144 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1145 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001146 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001147 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001148 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001149 };
1150
Mona Hossain3b574d82011-09-01 15:02:01 -07001151 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1152 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1153 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1154 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001155
1156 /* done */
1157 _ablk_cipher_complete(pce_dev);
1158 }
1159};
1160
1161
1162static void _ablk_cipher_ce_in_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1163 unsigned int result, struct msm_dmov_errdata *err)
1164{
1165 struct qce_device *pce_dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001166 pce_dev = (struct qce_device *) cmd_ptr->user;
1167 if (result != ADM_STATUS_OK) {
1168 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1169 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001170 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001171 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001172 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001173 }
1174
Mona Hossain3b574d82011-09-01 15:02:01 -07001175 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1176 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1177 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1178 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001179
1180 /* done */
1181 _ablk_cipher_use_pmem_complete(pce_dev);
1182 }
1183};
1184
1185static void _ablk_cipher_ce_out_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1186 unsigned int result, struct msm_dmov_errdata *err)
1187{
1188 struct qce_device *pce_dev;
1189
1190 pce_dev = (struct qce_device *) cmd_ptr->user;
1191 if (result != ADM_STATUS_OK) {
1192 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1193 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001194 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001195 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001196 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001197 };
1198
Mona Hossain3b574d82011-09-01 15:02:01 -07001199 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1200 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1201 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1202 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001203
1204 /* done */
1205 _ablk_cipher_use_pmem_complete(pce_dev);
1206 }
1207};
1208
Mona Hossain3b574d82011-09-01 15:02:01 -07001209static int qce_setup_cmd_buffers(struct qce_device *pce_dev,
1210 unsigned char **pvaddr)
1211{
1212 struct ce_reg_buffers *addr = (struct ce_reg_buffers *)(*pvaddr);
1213 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
1214
1215 /*
1216 * Designate chunks of the allocated memory to various
1217 * buffer pointers
1218 */
1219 buffer->reset_buf_64 = addr->reset_buf_64;
1220 buffer->version = addr->version;
1221 buffer->encr_seg_cfg_size_start = addr->encr_seg_cfg_size_start;
1222 buffer->encr_key = addr->encr_key;
1223 buffer->encr_xts_key = addr->encr_xts_key;
1224 buffer->encr_xts_du_size = addr->encr_xts_du_size;
1225 buffer->encr_cntr_iv = addr->encr_cntr_iv;
1226 buffer->encr_mask = addr->encr_mask;
1227 buffer->auth_seg_cfg_size_start = addr->auth_seg_cfg_size_start;
1228 buffer->auth_key = addr->auth_key;
1229 buffer->auth_iv = addr->auth_iv;
1230 buffer->auth_result = addr->auth_result;
1231 buffer->auth_nonce_info = addr->auth_nonce_info;
1232 buffer->auth_byte_count = addr->auth_byte_count;
1233 buffer->seg_size = addr->seg_size;
1234 buffer->go_proc = addr->go_proc;
1235 buffer->status = addr->status;
1236 buffer->pad = addr->pad;
1237
1238 memset(buffer->reset_buf_64, 0, 64);
1239 *((uint32_t *)buffer->encr_mask) = (uint32_t)(0xffffffff);
1240 *((uint32_t *)buffer->go_proc) = (uint32_t)(1 << CRYPTO_GO);
1241
1242 *pvaddr += sizeof(struct ce_reg_buffers);
1243
1244 return 0;
1245
1246}
1247
1248static int _setup_cipher_cmdlists(struct qce_device *pce_dev,
1249 unsigned char **pvaddr)
1250{
1251 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1252
1253 /*
1254 * Designate chunks of the allocated memory to various
1255 * command list pointers related to cipher operation
1256 */
1257 pce_dev->ce_dm.cmdlist.set_cipher_cfg = pscmd;
1258 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1259 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG +
1260 pce_dev->phy_iobase);
1261 pscmd->len = CRYPTO_REG_SIZE * 3;
1262 pscmd->src =
1263 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_seg_cfg_size_start);
1264 pscmd++;
1265
1266 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_key = pscmd;
1267 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1268 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1269 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1270 pscmd->len = CRYPTO_REG_SIZE * 4;
1271 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1272 pscmd++;
1273
1274 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_key = pscmd;
1275 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1276 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1277 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1278 pscmd->len = CRYPTO_REG_SIZE * 8;
1279 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1280 pscmd++;
1281
1282 pce_dev->ce_dm.cmdlist.set_cipher_des_key = pscmd;
1283 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1284 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1285 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1286 pscmd->len = CRYPTO_REG_SIZE * 2;
1287 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1288 pscmd++;
1289
1290 pce_dev->ce_dm.cmdlist.set_cipher_3des_key = pscmd;
1291 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1292 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1293 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1294 pscmd->len = CRYPTO_REG_SIZE * 6;
1295 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1296 pscmd++;
1297
1298 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_xts_key = pscmd;
1299 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1300 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1301 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1302 pce_dev->phy_iobase);
1303 pscmd->len = CRYPTO_REG_SIZE * 4;
1304 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1305 pscmd++;
1306
1307 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_xts_key = pscmd;
1308 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1309 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1310 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1311 pce_dev->phy_iobase);
1312 pscmd->len = CRYPTO_REG_SIZE * 8;
1313 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1314 pscmd++;
1315
1316 pce_dev->ce_dm.cmdlist.set_cipher_xts_du_size = pscmd;
1317 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1318 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_DU_SIZE_REG +
1319 pce_dev->phy_iobase);
1320 pscmd->len = CRYPTO_REG_SIZE * 4;
1321 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_du_size);
1322 pscmd++;
1323
1324 pce_dev->ce_dm.cmdlist.set_cipher_aes_iv = pscmd;
1325 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1326 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1327 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1328 pscmd->len = CRYPTO_REG_SIZE * 4;
1329 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1330 pscmd++;
1331
1332 pce_dev->ce_dm.cmdlist.get_cipher_aes_iv = pscmd;
1333 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1334 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1335 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1336 pscmd->len = CRYPTO_REG_SIZE * 4;
1337 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1338 pscmd++;
1339
1340 pce_dev->ce_dm.cmdlist.get_cipher_aes_xts_iv = pscmd;
1341 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1342 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1343 pscmd->len = CRYPTO_REG_SIZE * 4;
1344 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1345 pscmd++;
1346
1347 pce_dev->ce_dm.cmdlist.set_cipher_des_iv = pscmd;
1348 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1349 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1350 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1351 pscmd->len = CRYPTO_REG_SIZE * 2;
1352 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1353 pscmd++;
1354
1355 pce_dev->ce_dm.cmdlist.get_cipher_des_iv = pscmd;
1356 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1357 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1358 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1359 pscmd->len = CRYPTO_REG_SIZE * 2;
1360 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1361 pscmd++;
1362
1363 pce_dev->ce_dm.cmdlist.set_cipher_mask = pscmd;
1364 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1365 pscmd->dst = (unsigned) (CRYPTO_CNTR_MASK_REG + pce_dev->phy_iobase);
1366 pscmd->len = CRYPTO_REG_SIZE;
1367 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_mask);
1368 pscmd++;
1369
1370 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1371
1372 pce_dev->ce_dm.cmdlist.reset_cipher_key = pscmd;
1373 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1374 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1375 pscmd->len = CRYPTO_REG_SIZE * 8;
1376 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1377 pscmd++;
1378
1379 pce_dev->ce_dm.cmdlist.reset_cipher_xts_key = pscmd;
1380 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1381 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1382 pce_dev->phy_iobase);
1383 pscmd->len = CRYPTO_REG_SIZE * 8;
1384 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1385 pscmd++;
1386
1387 pce_dev->ce_dm.cmdlist.reset_cipher_iv = pscmd;
1388 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1389 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1390 pscmd->len = CRYPTO_REG_SIZE * 4;
1391 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1392 pscmd++;
1393
1394 pce_dev->ce_dm.cmdlist.reset_cipher_cfg = pscmd;
1395 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1396 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG + pce_dev->phy_iobase);
1397 pscmd->len = CRYPTO_REG_SIZE;
1398 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1399 pscmd++;
1400
1401 *pvaddr = (unsigned char *) pscmd;
1402
1403 return 0;
1404}
1405
1406static int _setup_auth_cmdlists(struct qce_device *pce_dev,
1407 unsigned char **pvaddr)
1408{
1409 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1410
1411 /*
1412 * Designate chunks of the allocated memory to various
1413 * command list pointers related to authentication operation
1414 */
1415 pce_dev->ce_dm.cmdlist.set_auth_cfg = pscmd;
1416 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1417 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1418 pscmd->len = CRYPTO_REG_SIZE * 3;
1419 pscmd->src =
1420 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start);
1421 pscmd++;
1422
1423 pce_dev->ce_dm.cmdlist.set_auth_key_128 = pscmd;
1424 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1425 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1426 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1427 pscmd->len = CRYPTO_REG_SIZE * 4;
1428 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1429 pscmd++;
1430
1431 pce_dev->ce_dm.cmdlist.set_auth_key_256 = pscmd;
1432 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1433 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1434 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1435 pscmd->len = CRYPTO_REG_SIZE * 8;
1436 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1437 pscmd++;
1438
1439 pce_dev->ce_dm.cmdlist.set_auth_key_512 = pscmd;
1440 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1441 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1442 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1443 pscmd->len = CRYPTO_REG_SIZE * 16;
1444 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1445 pscmd++;
1446
1447 pce_dev->ce_dm.cmdlist.set_auth_iv_16 = pscmd;
1448 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1449 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1450 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1451 pscmd->len = CRYPTO_REG_SIZE * 4;
1452 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1453 pscmd++;
1454
1455 pce_dev->ce_dm.cmdlist.get_auth_result_16 = pscmd;
1456 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1457 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1458 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1459 pscmd->len = CRYPTO_REG_SIZE * 4;
1460 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1461 pscmd++;
1462
1463 pce_dev->ce_dm.cmdlist.set_auth_iv_20 = pscmd;
1464 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1465 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1466 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1467 pscmd->len = CRYPTO_REG_SIZE * 5;
1468 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1469 pscmd++;
1470
1471 pce_dev->ce_dm.cmdlist.get_auth_result_20 = pscmd;
1472 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1473 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1474 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1475 pscmd->len = CRYPTO_REG_SIZE * 5;
1476 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1477 pscmd++;
1478
1479 pce_dev->ce_dm.cmdlist.set_auth_iv_32 = pscmd;
1480 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1481 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1482 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1483 pscmd->len = CRYPTO_REG_SIZE * 8;
1484 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1485 pscmd++;
1486
1487
1488 pce_dev->ce_dm.cmdlist.get_auth_result_32 = pscmd;
1489 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1490 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1491 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1492 pscmd->len = CRYPTO_REG_SIZE * 8;
1493 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1494 pscmd++;
1495
1496 pce_dev->ce_dm.cmdlist.set_auth_byte_count = pscmd;
1497 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1498 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1499 pce_dev->phy_iobase);
1500 pscmd->len = CRYPTO_REG_SIZE * 4;
1501 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1502 pscmd++;
1503
1504 pce_dev->ce_dm.cmdlist.get_auth_byte_count = pscmd;
1505 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1506 pscmd->src = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1507 pce_dev->phy_iobase);
1508 pscmd->len = CRYPTO_REG_SIZE * 4;
1509 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1510 pscmd++;
1511
1512 pce_dev->ce_dm.cmdlist.set_auth_nonce_info = pscmd;
1513 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1514 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1515 pscmd->dst = (unsigned) (CRYPTO_AUTH_INFO_NONCE0_REG +
1516 pce_dev->phy_iobase);
1517 pscmd->len = CRYPTO_REG_SIZE * 4;
1518 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_nonce_info);
1519 pscmd++;
1520
1521 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1522
1523 pce_dev->ce_dm.cmdlist.reset_auth_key = pscmd;
1524 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1525 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1526 pscmd->len = CRYPTO_REG_SIZE * 16;
1527 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1528 pscmd++;
1529
1530 pce_dev->ce_dm.cmdlist.reset_auth_iv = pscmd;
1531 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1532 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1533 pscmd->len = CRYPTO_REG_SIZE * 16;
1534 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1535 pscmd++;
1536
1537 pce_dev->ce_dm.cmdlist.reset_auth_cfg = pscmd;
1538 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1539 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1540 pscmd->len = CRYPTO_REG_SIZE;
1541 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1542 pscmd++;
1543
1544
1545 pce_dev->ce_dm.cmdlist.reset_auth_byte_count = pscmd;
1546 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1547 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1548 pce_dev->phy_iobase);
1549 pscmd->len = CRYPTO_REG_SIZE * 4;
1550 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1551 pscmd++;
1552
1553 /* WAIT UNTIL MAC OP IS DONE*/
1554
1555 pce_dev->ce_dm.cmdlist.get_status_wait = pscmd;
1556 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1557 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1558 pscmd->len = CRYPTO_REG_SIZE;
1559 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1560 pscmd++;
1561
1562 *pvaddr = (unsigned char *) pscmd;
1563
1564 return 0;
1565}
1566
1567static int qce_setup_cmdlists(struct qce_device *pce_dev,
1568 unsigned char **pvaddr)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001569{
1570 dmov_sg *pcmd;
Mona Hossain3b574d82011-09-01 15:02:01 -07001571 dmov_s *pscmd;
1572 unsigned char *vaddr = *pvaddr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001573 struct dmov_desc *pdesc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001574 int i = 0;
1575
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001576 /*
Mona Hossain3b574d82011-09-01 15:02:01 -07001577 * Designate chunks of the allocated memory to various
1578 * command list pointers related to operation define
1579 * in ce_cmdlists structure.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001580 */
Mona Hossain3b574d82011-09-01 15:02:01 -07001581 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
1582 *pvaddr = (unsigned char *) vaddr;
1583
1584 _setup_cipher_cmdlists(pce_dev, pvaddr);
1585 _setup_auth_cmdlists(pce_dev, pvaddr);
1586
1587 pscmd = (dmov_s *)(*pvaddr);
1588
1589 /* GET HW VERSION COMMAND LIST */
1590 pce_dev->ce_dm.cmdlist.get_hw_version = pscmd;
1591 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1592 pscmd->src = (unsigned) (CRYPTO_VERSION_REG + pce_dev->phy_iobase);
1593 pscmd->len = CRYPTO_REG_SIZE;
1594 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.version);
1595 pscmd++;
1596
1597
1598 /* SET SEG SIZE REGISTER and OCB COMMAND LIST */
1599 pce_dev->ce_dm.cmdlist.set_seg_size_ocb = pscmd;
1600 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1601 pscmd->dst = (unsigned) (CRYPTO_SEG_SIZE_REG + pce_dev->phy_iobase);
1602 pscmd->len = CRYPTO_REG_SIZE;
1603 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.seg_size);
1604 pscmd++;
1605
1606
1607 /* OCU COMMAND LIST */
1608 pce_dev->ce_dm.cmdlist.get_status_ocu = pscmd;
1609 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCU;
1610 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1611 pscmd->len = CRYPTO_REG_SIZE;
1612 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1613 pscmd++;
1614
1615 /* SET GO_PROC REGISTERS COMMAND LIST */
1616 pce_dev->ce_dm.cmdlist.set_go_proc = pscmd;
1617 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1618 pscmd->dst = (unsigned) (CRYPTO_GOPROC_REG + pce_dev->phy_iobase);
1619 pscmd->len = CRYPTO_REG_SIZE;
1620 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.go_proc);
1621 pscmd++;
1622
1623 pcmd = (dmov_sg *)pscmd;
1624 pce_dev->ce_dm.cmdlist.ce_data_in = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001625 /* swap byte and half word , dst crci , scatter gather */
1626 pcmd->cmd = CMD_DST_SWAP_BYTES | CMD_DST_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001627 CMD_DST_CRCI(pce_dev->ce_dm.crci_in) | CMD_MODE_SG;
1628
1629 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001630 pdesc->addr = 0; /* to be filled in each operation */
1631 pdesc->len = 0; /* to be filled in each operation */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001632
Mona Hossain3b574d82011-09-01 15:02:01 -07001633 pdesc = pce_dev->ce_dm.ce_in_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001634 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1635 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1636 pdesc->len = 0; /* to be filled in each operation */
1637 pdesc++;
1638 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001639 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_src_desc);
1640 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001641 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1642 DST_INDEX_SG_CMD(0);
Mona Hossain3b574d82011-09-01 15:02:01 -07001643
1644
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001645 pcmd++;
Mona Hossain3b574d82011-09-01 15:02:01 -07001646 pce_dev->ce_dm.cmdlist.ce_data_out = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001647 /* swap byte, half word, source crci, scatter gather */
1648 pcmd->cmd = CMD_SRC_SWAP_BYTES | CMD_SRC_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001649 CMD_SRC_CRCI(pce_dev->ce_dm.crci_out) | CMD_MODE_SG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001650
Mona Hossain3b574d82011-09-01 15:02:01 -07001651 pdesc = pce_dev->ce_dm.ce_out_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001652 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1653 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1654 pdesc->len = 0; /* to be filled in each operation */
1655 pdesc++;
1656 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001657
Mona Hossain3b574d82011-09-01 15:02:01 -07001658 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001659 pdesc->addr = 0; /* to be filled in each operation */
1660 pdesc->len = 0; /* to be filled in each operation */
Mona Hossain3b574d82011-09-01 15:02:01 -07001661
1662 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_src_desc);
1663 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001664 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1665 DST_INDEX_SG_CMD(0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001666 pcmd++;
1667
Mona Hossain3b574d82011-09-01 15:02:01 -07001668 *pvaddr = (unsigned char *) pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001669
1670 return 0;
Mona Hossain3b574d82011-09-01 15:02:01 -07001671}
1672
1673static int _setup_cipher_cmdptrlists(struct qce_device *pce_dev,
1674 unsigned char **pvaddr)
1675{
1676 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1677 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1678 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1679
1680 /*
1681 * Designate chunks of the allocated memory to various
1682 * command list pointers related to cipher operations defined
1683 * in ce_cmdptrlists_ops structure.
1684 */
1685 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1686 cmdptrlist->cipher_aes_128_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1687
1688 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1689 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1690 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1691 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1692 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1693 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1694 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1695 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1696 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_iv);
1697
1698 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1699 cmdptrlist->cipher_aes_256_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1700
1701 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1702 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1703 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1704 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1705 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1706 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1707 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1708 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1709 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_iv);
1710
1711 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1712 cmdptrlist->cipher_aes_128_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1713
1714 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1715 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1716 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1717 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1718 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1719 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1720 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1721
1722 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1723 cmdptrlist->cipher_aes_256_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1724
1725 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1726 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1727 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1728 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1729 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1730 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1731 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1732
1733 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1734 cmdptrlist->cipher_aes_128_xts = 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_aes_128_key);
1739 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_xts_key);
1740 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1741 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1742 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
1743 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1744 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1745 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1746 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_xts_iv);
1747
1748 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1749 cmdptrlist->cipher_aes_256_xts = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1750
1751 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1752 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1753 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1754 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_xts_key);
1755 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1756 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1757 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
1758 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1759 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1760 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1761 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_aes_xts_iv);
1762
1763 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1764 cmdptrlist->cipher_des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1765
1766 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1767 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1768 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1769 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1770 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1771 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1772 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1773 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_des_iv);
1774
1775 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1776 cmdptrlist->cipher_des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1777
1778 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1779 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1780 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1781 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1782 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1783 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1784
1785 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1786 cmdptrlist->cipher_3des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1787
1788 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1789 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1790 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1791 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1792 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1793 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1794 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1795 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_cipher_des_iv);
1796
1797 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1798 cmdptrlist->cipher_3des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1799
1800 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1801 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1802 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1803 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1804 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1805 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1806
1807 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1808 cmdptrlist->cipher_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1809
1810 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1811 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1812 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1813
1814 return 0;
1815}
1816
1817static int _setup_auth_cmdptrlists(struct qce_device *pce_dev,
1818 unsigned char **pvaddr)
1819{
1820 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1821 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1822 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1823
1824 /*
1825 * Designate chunks of the allocated memory to various
1826 * command list pointers related to authentication operations
1827 * defined in ce_cmdptrlists_ops structure.
1828 */
1829 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1830 cmdptrlist->auth_sha1 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1831
1832 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1833 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1834 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1835 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1836 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1837 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1838 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1839 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1840 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1841 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1842 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1843 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1844
1845 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1846 cmdptrlist->auth_sha256 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1847
1848 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1849 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1850 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1851 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1852 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1853 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1854 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1855 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1856 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1857 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1858 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1859 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1860
1861 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1862 cmdptrlist->auth_sha1_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1863
1864 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1865 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1866 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1867 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1868 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1869 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1870 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1871 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1872 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1873 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1874 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1875 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1876 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1877
1878 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1879 cmdptrlist->auth_sha256_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1880
1881 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1882 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1883 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1884 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1885 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1886 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1887 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1888 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1889 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1890 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1891 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1892 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1893 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1894
1895 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1896 cmdptrlist->auth_aes_128_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1897
1898 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1899 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1900 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1901 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1902 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1903 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1904 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1905 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1906 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1907 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1908 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1909 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1910 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1911 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1912
1913 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1914 cmdptrlist->auth_aes_256_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1915
1916 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1917 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1918 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1919 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1920 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1921 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1922 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1923 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1924 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1925 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1926 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1927 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1928 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1929 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1930
1931 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1932
1933 return 0;
1934}
1935
1936static int _setup_aead_cmdptrlists(struct qce_device *pce_dev,
1937 unsigned char **pvaddr)
1938{
1939 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1940 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1941 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1942
1943 /*
1944 * Designate chunks of the allocated memory to various
1945 * command list pointers related to aead operations
1946 * defined in ce_cmdptrlists_ops structure.
1947 */
1948 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1949 cmdptrlist->aead_aes_128_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1950
1951 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1952 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1953 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1954 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1955 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1956 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1957 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1958 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1959 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1960 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1961 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1962 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1963 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1964
1965 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1966 cmdptrlist->aead_aes_256_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1967
1968 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1969 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1970 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1971 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1972 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1973 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1974 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1975 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1976 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1977 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1978 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1979 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1980 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1981
1982 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1983 cmdptrlist->aead_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1984
1985 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1986 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1987 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1988 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1989
1990 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1991
1992 return 0;
1993}
1994
1995static int qce_setup_cmdptrlists(struct qce_device *pce_dev,
1996 unsigned char **pvaddr)
1997{
1998 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1999 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
2000 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
2001 /*
2002 * Designate chunks of the allocated memory to various
2003 * command list pointers related to operations defined
2004 * in ce_cmdptrlists_ops structure.
2005 */
2006 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
2007 cmdptrlist->probe_ce_hw = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
2008
2009 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_hw_version);
2010 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
2011
2012 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
2013
2014 _setup_cipher_cmdptrlists(pce_dev, pvaddr);
2015 _setup_auth_cmdptrlists(pce_dev, pvaddr);
2016 _setup_aead_cmdptrlists(pce_dev, pvaddr);
2017
2018 return 0;
2019}
2020
2021
2022static int qce_setup_ce_dm_data(struct qce_device *pce_dev)
2023{
2024 unsigned char *vaddr;
2025
2026 /* 1. ce_in channel data xfer command src descriptors, 128 entries */
2027 vaddr = pce_dev->coh_vmem;
2028 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2029 pce_dev->ce_dm.ce_in_src_desc = (struct dmov_desc *) vaddr;
2030 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2031
2032 /* 2. ce_in channel data xfer command dst descriptors, 128 entries */
2033 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2034 pce_dev->ce_dm.ce_in_dst_desc = (struct dmov_desc *) vaddr;
2035 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2036
2037
2038 /* 3. ce_out channel data xfer command src descriptors, 128 entries */
2039 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2040 pce_dev->ce_dm.ce_out_src_desc = (struct dmov_desc *) vaddr;
2041 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2042
2043 /* 4. ce_out channel data xfer command dst descriptors, 128 entries. */
2044 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2045 pce_dev->ce_dm.ce_out_dst_desc = (struct dmov_desc *) vaddr;
2046 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2047
2048 qce_setup_cmd_buffers(pce_dev, &vaddr);
2049 qce_setup_cmdlists(pce_dev, &vaddr);
2050 qce_setup_cmdptrlists(pce_dev, &vaddr);
2051
2052 pce_dev->ce_dm.buffer.ignore_data = vaddr;
2053
2054 pce_dev->ce_dm.phy_ce_pad = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.pad);
2055 pce_dev->ce_dm.phy_ce_out_ignore =
2056 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.ignore_data);
2057
2058 pce_dev->ce_dm.chan_ce_in_cmd->user = (void *) pce_dev;
2059 pce_dev->ce_dm.chan_ce_in_cmd->exec_func = NULL;
2060
2061 pce_dev->ce_dm.chan_ce_out_cmd->user = (void *) pce_dev;
2062 pce_dev->ce_dm.chan_ce_out_cmd->exec_func = NULL;
2063
2064 return 0;
2065}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002066
2067static int _qce_start_dma(struct qce_device *pce_dev, bool ce_in, bool ce_out)
2068{
2069
2070 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002071 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002072 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002073 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002074
2075 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002076 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002077 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002078 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002079
2080 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002081 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
2082 pce_dev->ce_dm.chan_ce_in_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002083 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002084 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_out,
2085 pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002086
2087 return 0;
2088};
2089
2090int qce_aead_req(void *handle, struct qce_req *q_req)
2091{
2092 struct qce_device *pce_dev = (struct qce_device *) handle;
2093 struct aead_request *areq = (struct aead_request *) q_req->areq;
2094 uint32_t authsize = q_req->authsize;
2095 uint32_t totallen_in, totallen_out, out_len;
2096 uint32_t pad_len_in, pad_len_out;
2097 uint32_t pad_mac_len_out, pad_ptx_len_out;
2098 int rc = 0;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002099 int ce_block_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002100
Mona Hossain5f5dde12011-09-12 10:28:34 -07002101 ce_block_size = pce_dev->ce_dm.ce_block_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002102 if (q_req->dir == QCE_ENCRYPT) {
2103 q_req->cryptlen = areq->cryptlen;
2104 totallen_in = q_req->cryptlen + areq->assoclen;
2105 totallen_out = q_req->cryptlen + authsize + areq->assoclen;
2106 out_len = areq->cryptlen + authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002107 pad_len_in = ALIGN(totallen_in, ce_block_size) - totallen_in;
2108 pad_mac_len_out = ALIGN(authsize, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002109 authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002110 pad_ptx_len_out = ALIGN(q_req->cryptlen, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002111 q_req->cryptlen;
2112 pad_len_out = pad_ptx_len_out + pad_mac_len_out;
2113 totallen_out += pad_len_out;
2114 } else {
2115 q_req->cryptlen = areq->cryptlen - authsize;
2116 totallen_in = areq->cryptlen + areq->assoclen;
2117 totallen_out = q_req->cryptlen + areq->assoclen;
2118 out_len = areq->cryptlen - authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002119 pad_len_in = ALIGN(areq->cryptlen, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002120 areq->cryptlen;
2121 pad_len_out = pad_len_in + authsize;
2122 totallen_out += pad_len_out;
2123 }
2124
2125 _chain_buffer_in_init(pce_dev);
2126 _chain_buffer_out_init(pce_dev);
2127
2128 pce_dev->assoc_nents = 0;
2129 pce_dev->src_nents = 0;
2130 pce_dev->dst_nents = 0;
2131 pce_dev->ivsize = q_req->ivsize;
2132 pce_dev->authsize = q_req->authsize;
2133
2134 /* associated data input */
2135 pce_dev->assoc_nents = count_sg(areq->assoc, areq->assoclen);
2136 dma_map_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
2137 DMA_TO_DEVICE);
2138 if (_chain_sg_buffer_in(pce_dev, areq->assoc, areq->assoclen) < 0) {
2139 rc = -ENOMEM;
2140 goto bad;
2141 }
2142 /* cipher input */
2143 pce_dev->src_nents = count_sg(areq->src, areq->cryptlen);
2144 dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2145 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2146 DMA_TO_DEVICE);
2147 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->cryptlen) < 0) {
2148 rc = -ENOMEM;
2149 goto bad;
2150 }
2151 /* pad data in */
2152 if (pad_len_in) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002153 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002154 pad_len_in) < 0) {
2155 rc = -ENOMEM;
2156 goto bad;
2157 }
2158 }
2159
2160 /* ignore associated data */
Mona Hossain3b574d82011-09-01 15:02:01 -07002161 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_out_ignore,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002162 areq->assoclen) < 0) {
2163 rc = -ENOMEM;
2164 goto bad;
2165 }
2166 /* cipher + mac output for encryption */
2167 if (areq->src != areq->dst) {
2168 pce_dev->dst_nents = count_sg(areq->dst, out_len);
2169 dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2170 DMA_FROM_DEVICE);
2171 };
2172 if (_chain_sg_buffer_out(pce_dev, areq->dst, out_len) < 0) {
2173 rc = -ENOMEM;
2174 goto bad;
2175 }
2176 /* pad data out */
2177 if (pad_len_out) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002178 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002179 pad_len_out) < 0) {
2180 rc = -ENOMEM;
2181 goto bad;
2182 }
2183 }
2184
2185 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain5f5dde12011-09-12 10:28:34 -07002186 _ce_in_final(pce_dev, ALIGN(totallen_in, ce_block_size));
2187 _ce_out_final(pce_dev, ALIGN(totallen_out, ce_block_size));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002188
2189 /* set up crypto device */
2190 rc = _ce_setup_cipher(pce_dev, q_req, totallen_in, areq->assoclen);
2191 if (rc < 0)
2192 goto bad;
2193
2194 /* setup for callback, and issue command to adm */
2195 pce_dev->areq = q_req->areq;
2196 pce_dev->qce_cb = q_req->qce_cb;
2197
Mona Hossain3b574d82011-09-01 15:02:01 -07002198 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _aead_ce_in_call_back;
2199 pce_dev->ce_dm.chan_ce_out_cmd->complete_func = _aead_ce_out_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002200
2201 _ce_in_dump(pce_dev);
2202 _ce_out_dump(pce_dev);
2203
2204 rc = _qce_start_dma(pce_dev, true, true);
2205 if (rc == 0)
2206 return 0;
2207bad:
2208 if (pce_dev->assoc_nents) {
2209 dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
2210 DMA_TO_DEVICE);
2211 }
2212
2213 if (pce_dev->src_nents) {
2214 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2215 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2216 DMA_TO_DEVICE);
2217 }
2218 if (pce_dev->dst_nents) {
2219 dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2220 DMA_FROM_DEVICE);
2221 }
2222 return rc;
2223}
2224EXPORT_SYMBOL(qce_aead_req);
2225
2226int qce_ablk_cipher_req(void *handle, struct qce_req *c_req)
2227{
2228 int rc = 0;
2229 struct qce_device *pce_dev = (struct qce_device *) handle;
2230 struct ablkcipher_request *areq = (struct ablkcipher_request *)
2231 c_req->areq;
2232
Mona Hossain5f5dde12011-09-12 10:28:34 -07002233 uint32_t pad_len = ALIGN(areq->nbytes, pce_dev->ce_dm.ce_block_size)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002234 - areq->nbytes;
2235
2236 _chain_buffer_in_init(pce_dev);
2237 _chain_buffer_out_init(pce_dev);
2238
2239 pce_dev->src_nents = 0;
2240 pce_dev->dst_nents = 0;
2241
2242 /* cipher input */
2243 pce_dev->src_nents = count_sg(areq->src, areq->nbytes);
2244
2245 if (c_req->use_pmem != 1)
2246 dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2247 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2248 DMA_TO_DEVICE);
2249 else
2250 dma_map_pmem_sg(&c_req->pmem->src[0], pce_dev->src_nents,
2251 areq->src);
2252
2253 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->nbytes) < 0) {
2254 rc = -ENOMEM;
2255 goto bad;
2256 }
2257
2258 /* cipher output */
2259 if (areq->src != areq->dst) {
2260 pce_dev->dst_nents = count_sg(areq->dst, areq->nbytes);
2261 if (c_req->use_pmem != 1)
2262 dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2263 DMA_FROM_DEVICE);
2264 else
2265 dma_map_pmem_sg(&c_req->pmem->dst[0],
2266 pce_dev->dst_nents, areq->dst);
2267 };
2268 if (_chain_sg_buffer_out(pce_dev, areq->dst, areq->nbytes) < 0) {
2269 rc = -ENOMEM;
2270 goto bad;
2271 }
2272
2273 /* pad data */
2274 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002275 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002276 pad_len) < 0) {
2277 rc = -ENOMEM;
2278 goto bad;
2279 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002280 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002281 pad_len) < 0) {
2282 rc = -ENOMEM;
2283 goto bad;
2284 }
2285 }
2286
2287 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain2563cbc2011-09-14 15:24:08 -07002288 _ce_in_final(pce_dev, areq->nbytes + pad_len);
2289 _ce_out_final(pce_dev, areq->nbytes + pad_len);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002290
2291 _ce_in_dump(pce_dev);
2292 _ce_out_dump(pce_dev);
2293
2294 /* set up crypto device */
2295 rc = _ce_setup_cipher(pce_dev, c_req, areq->nbytes, 0);
2296 if (rc < 0)
2297 goto bad;
2298
2299 /* setup for callback, and issue command to adm */
2300 pce_dev->areq = areq;
2301 pce_dev->qce_cb = c_req->qce_cb;
2302 if (c_req->use_pmem == 1) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002303 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002304 _ablk_cipher_ce_in_call_back_pmem;
Mona Hossain3b574d82011-09-01 15:02:01 -07002305 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002306 _ablk_cipher_ce_out_call_back_pmem;
2307 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07002308 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002309 _ablk_cipher_ce_in_call_back;
Mona Hossain3b574d82011-09-01 15:02:01 -07002310 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002311 _ablk_cipher_ce_out_call_back;
2312 }
2313 rc = _qce_start_dma(pce_dev, true, true);
2314
2315 if (rc == 0)
2316 return 0;
2317bad:
2318 if (c_req->use_pmem != 1) {
2319 if (pce_dev->dst_nents) {
2320 dma_unmap_sg(pce_dev->pdev, areq->dst,
2321 pce_dev->dst_nents, DMA_FROM_DEVICE);
2322 }
2323 if (pce_dev->src_nents) {
2324 dma_unmap_sg(pce_dev->pdev, areq->src,
2325 pce_dev->src_nents,
2326 (areq->src == areq->dst) ?
2327 DMA_BIDIRECTIONAL :
2328 DMA_TO_DEVICE);
2329 }
2330 }
2331 return rc;
2332}
2333EXPORT_SYMBOL(qce_ablk_cipher_req);
2334
2335int qce_process_sha_req(void *handle, struct qce_sha_req *sreq)
2336{
2337 struct qce_device *pce_dev = (struct qce_device *) handle;
2338 int rc;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002339 uint32_t pad_len = ALIGN(sreq->size, pce_dev->ce_dm.ce_block_size) -
2340 sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002341 struct ahash_request *areq = (struct ahash_request *)sreq->areq;
2342
2343 _chain_buffer_in_init(pce_dev);
2344 pce_dev->src_nents = count_sg(sreq->src, sreq->size);
2345 dma_map_sg(pce_dev->pdev, sreq->src, pce_dev->src_nents,
2346 DMA_TO_DEVICE);
2347
2348 if (_chain_sg_buffer_in(pce_dev, sreq->src, sreq->size) < 0) {
2349 rc = -ENOMEM;
2350 goto bad;
2351 }
2352
2353 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002354 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002355 pad_len) < 0) {
2356 rc = -ENOMEM;
2357 goto bad;
2358 }
2359 }
Mona Hossain2563cbc2011-09-14 15:24:08 -07002360 _ce_in_final(pce_dev, sreq->size + pad_len);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002361
2362 _ce_in_dump(pce_dev);
2363
Mona Hossain3b574d82011-09-01 15:02:01 -07002364 rc = _ce_setup_hash(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002365
2366 if (rc < 0)
2367 goto bad;
2368
2369 pce_dev->areq = areq;
2370 pce_dev->qce_cb = sreq->qce_cb;
Mona Hossain3b574d82011-09-01 15:02:01 -07002371 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _sha_ce_in_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002372
2373 rc = _qce_start_dma(pce_dev, true, false);
2374
2375 if (rc == 0)
2376 return 0;
2377bad:
2378 if (pce_dev->src_nents) {
2379 dma_unmap_sg(pce_dev->pdev, sreq->src,
2380 pce_dev->src_nents, DMA_TO_DEVICE);
2381 }
2382
2383 return rc;
2384}
2385EXPORT_SYMBOL(qce_process_sha_req);
2386
2387/* crypto engine open function. */
2388void *qce_open(struct platform_device *pdev, int *rc)
2389{
2390 struct qce_device *pce_dev;
2391 struct resource *resource;
2392 struct clk *ce_core_clk;
2393 struct clk *ce_clk;
2394
2395 pce_dev = kzalloc(sizeof(struct qce_device), GFP_KERNEL);
2396 if (!pce_dev) {
2397 *rc = -ENOMEM;
2398 dev_err(&pdev->dev, "Can not allocate memory\n");
2399 return NULL;
2400 }
2401 pce_dev->pdev = &pdev->dev;
2402
2403 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2404 if (!resource) {
2405 *rc = -ENXIO;
2406 dev_err(pce_dev->pdev, "Missing MEM resource\n");
2407 goto err_pce_dev;
2408 };
2409 pce_dev->phy_iobase = resource->start;
2410 pce_dev->iobase = ioremap_nocache(resource->start,
2411 resource->end - resource->start + 1);
2412 if (!pce_dev->iobase) {
2413 *rc = -ENOMEM;
2414 dev_err(pce_dev->pdev, "Can not map io memory\n");
2415 goto err_pce_dev;
2416 }
2417
Mona Hossain3b574d82011-09-01 15:02:01 -07002418 pce_dev->ce_dm.chan_ce_in_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002419 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002420 pce_dev->ce_dm.chan_ce_out_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002421 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002422 if (pce_dev->ce_dm.chan_ce_in_cmd == NULL ||
2423 pce_dev->ce_dm.chan_ce_out_cmd == NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002424 dev_err(pce_dev->pdev, "Can not allocate memory\n");
2425 *rc = -ENOMEM;
2426 goto err_dm_chan_cmd;
2427 }
2428
2429 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2430 "crypto_channels");
2431 if (!resource) {
2432 *rc = -ENXIO;
2433 dev_err(pce_dev->pdev, "Missing DMA channel resource\n");
2434 goto err_dm_chan_cmd;
2435 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002436 pce_dev->ce_dm.chan_ce_in = resource->start;
2437 pce_dev->ce_dm.chan_ce_out = resource->end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002438 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2439 "crypto_crci_in");
2440 if (!resource) {
2441 *rc = -ENXIO;
2442 dev_err(pce_dev->pdev, "Missing DMA crci in resource\n");
2443 goto err_dm_chan_cmd;
2444 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002445 pce_dev->ce_dm.crci_in = resource->start;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002446 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2447 "crypto_crci_out");
2448 if (!resource) {
2449 *rc = -ENXIO;
2450 dev_err(pce_dev->pdev, "Missing DMA crci out resource\n");
2451 goto err_dm_chan_cmd;
2452 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002453 pce_dev->ce_dm.crci_out = resource->start;
2454 pce_dev->memsize = 2 * PAGE_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002455 pce_dev->coh_vmem = dma_alloc_coherent(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -07002456 pce_dev->memsize, &pce_dev->coh_pmem, GFP_KERNEL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002457
2458 if (pce_dev->coh_vmem == NULL) {
2459 *rc = -ENOMEM;
2460 dev_err(pce_dev->pdev, "Can not allocate coherent memory.\n");
2461 goto err;
2462 }
2463
2464 /* Get CE core clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002465 ce_core_clk = clk_get(pce_dev->pdev, "core_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002466 if (IS_ERR(ce_core_clk)) {
2467 *rc = PTR_ERR(ce_core_clk);
2468 goto err;
2469 }
2470 pce_dev->ce_core_clk = ce_core_clk;
2471 /* Get CE clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002472 ce_clk = clk_get(pce_dev->pdev, "iface_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002473 if (IS_ERR(ce_clk)) {
2474 *rc = PTR_ERR(ce_clk);
2475 clk_put(pce_dev->ce_core_clk);
2476 goto err;
2477 }
2478 pce_dev->ce_clk = ce_clk;
2479
2480 /* Enable CE core clk */
2481 *rc = clk_enable(pce_dev->ce_core_clk);
2482 if (*rc) {
2483 clk_put(pce_dev->ce_core_clk);
2484 clk_put(pce_dev->ce_clk);
2485 goto err;
2486 } else {
2487 /* Enable CE clk */
2488 *rc = clk_enable(pce_dev->ce_clk);
2489 if (*rc) {
2490 clk_disable(pce_dev->ce_core_clk);
2491 clk_put(pce_dev->ce_core_clk);
2492 clk_put(pce_dev->ce_clk);
2493 goto err;
2494
2495 }
2496 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002497 qce_setup_ce_dm_data(pce_dev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002498
Mona Hossain3b574d82011-09-01 15:02:01 -07002499 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
2500 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002501 if (_init_ce_engine(pce_dev)) {
2502 *rc = -ENXIO;
2503 goto err;
2504 }
2505 *rc = 0;
2506 return pce_dev;
2507
2508err:
2509 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002510 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
Mona Hossaine1b13f82011-08-30 09:35:49 -07002511 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002512err_dm_chan_cmd:
Mona Hossain3b574d82011-09-01 15:02:01 -07002513 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2514 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002515 if (pce_dev->iobase)
2516 iounmap(pce_dev->iobase);
2517
2518err_pce_dev:
2519
2520 kfree(pce_dev);
2521
2522 return NULL;
2523}
2524EXPORT_SYMBOL(qce_open);
2525
2526/* crypto engine close function. */
2527int qce_close(void *handle)
2528{
2529 struct qce_device *pce_dev = (struct qce_device *) handle;
2530
2531 if (handle == NULL)
2532 return -ENODEV;
2533 if (pce_dev->iobase)
2534 iounmap(pce_dev->iobase);
2535
2536 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002537 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
2538 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002539 clk_disable(pce_dev->ce_clk);
2540 clk_disable(pce_dev->ce_core_clk);
2541
2542 clk_put(pce_dev->ce_clk);
2543 clk_put(pce_dev->ce_core_clk);
2544
Mona Hossain3b574d82011-09-01 15:02:01 -07002545 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2546 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002547 kfree(handle);
2548
2549 return 0;
2550}
2551EXPORT_SYMBOL(qce_close);
2552
2553int qce_hw_support(void *handle, struct ce_hw_support *ce_support)
2554{
2555 if (ce_support == NULL)
2556 return -EINVAL;
2557
2558 ce_support->sha1_hmac_20 = false;
2559 ce_support->sha1_hmac = false;
2560 ce_support->sha256_hmac = false;
2561 ce_support->sha_hmac = false;
2562 ce_support->cmac = true;
2563 ce_support->aes_key_192 = false;
2564 ce_support->aes_xts = true;
2565 ce_support->aes_ccm = true;
2566 ce_support->ota = false;
2567 return 0;
2568}
2569EXPORT_SYMBOL(qce_hw_support);
2570
2571MODULE_LICENSE("GPL v2");
2572MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
2573MODULE_DESCRIPTION("Crypto Engine driver");
Ramesh Masavarapu72077202011-11-02 10:34:26 -07002574MODULE_VERSION("2.13");