blob: 5276bcca79d0685dcdc1b4de2b0a6235354ea051 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Qualcomm Crypto Engine driver.
2 *
Ramesh Masavarapu9e1c0a02012-02-07 08:56:40 -08003 * Copyright (c) 2011 - 2012, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004 *
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
Ramesh Masavarapu9e1c0a02012-02-07 08:56:40 -080045
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070046/*
47 * CE HW device structure.
48 * Each engine has an instance of the structure.
49 * Each engine can only handle one crypto operation at one time. It is up to
50 * the sw above to ensure single threading of operation on an engine.
51 */
52struct qce_device {
53 struct device *pdev; /* Handle to platform_device structure */
Mona Hossain3b574d82011-09-01 15:02:01 -070054
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070055 unsigned char *coh_vmem; /* Allocated coherent virtual memory */
56 dma_addr_t coh_pmem; /* Allocated coherent physical memory */
Mona Hossain3b574d82011-09-01 15:02:01 -070057 int memsize; /* Memory allocated */
58
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070059 void __iomem *iobase; /* Virtual io base of CE HW */
60 unsigned int phy_iobase; /* Physical io base of CE HW */
Mona Hossain3b574d82011-09-01 15:02:01 -070061
Ramesh Masavarapu28311912011-10-27 11:04:12 -070062 struct clk *ce_core_src_clk; /* Handle to CE src clk*/
63 struct clk *ce_core_clk; /* Handle to CE clk */
64 struct clk *ce_clk; /* Handle to CE clk */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070065
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070066 qce_comp_func_ptr_t qce_cb; /* qce callback function pointer */
67
68 int assoc_nents;
69 int ivsize;
70 int authsize;
71 int src_nents;
72 int dst_nents;
73
74 void *areq;
75 enum qce_cipher_mode_enum mode;
Mona Hossain3b574d82011-09-01 15:02:01 -070076 struct ce_dm_data ce_dm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070077};
78
79/* Standard initialization vector for SHA-1, source: FIPS 180-2 */
Mona Hossain3b574d82011-09-01 15:02:01 -070080static uint8_t _std_init_vector_sha1_uint8[] = {
81 0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89,
82 0x98, 0xBA, 0xDC, 0xFE, 0x10, 0x32, 0x54, 0x76,
83 0xC3, 0xD2, 0xE1, 0xF0
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070084};
Mona Hossain3b574d82011-09-01 15:02:01 -070085
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070086/* Standard initialization vector for SHA-256, source: FIPS 180-2 */
Mona Hossain3b574d82011-09-01 15:02:01 -070087static uint8_t _std_init_vector_sha256_uint8[] = {
88 0x6A, 0x09, 0xE6, 0x67, 0xBB, 0x67, 0xAE, 0x85,
89 0x3C, 0x6E, 0xF3, 0x72, 0xA5, 0x4F, 0xF5, 0x3A,
90 0x51, 0x0E, 0x52, 0x7F, 0x9B, 0x05, 0x68, 0x8C,
91 0x1F, 0x83, 0xD9, 0xAB, 0x5B, 0xE0, 0xCD, 0x19
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070092};
93
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070094static void _byte_stream_swap_to_net_words(uint32_t *iv, unsigned char *b,
95 unsigned int len)
96{
97 unsigned i, j;
98 unsigned char swap_iv[AES_IV_LENGTH];
99
100 memset(swap_iv, 0, AES_IV_LENGTH);
101 for (i = (AES_IV_LENGTH-len), j = len-1; i < AES_IV_LENGTH; i++, j--)
102 swap_iv[i] = b[j];
Mona Hossain3b574d82011-09-01 15:02:01 -0700103 memcpy(iv, swap_iv, AES_IV_LENGTH);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700104}
105
106static int count_sg(struct scatterlist *sg, int nbytes)
107{
108 int i;
109
110 for (i = 0; nbytes > 0; i++, sg = sg_next(sg))
111 nbytes -= sg->length;
112 return i;
113}
114
115static int dma_map_pmem_sg(struct buf_info *pmem, unsigned entries,
116 struct scatterlist *sg)
117{
118 int i;
119 for (i = 0; i < entries; i++) {
120
121 sg->dma_address = (dma_addr_t)pmem->offset;
122 sg++;
123 pmem++;
124 }
125 return 0;
126}
127
128static int _probe_ce_engine(struct qce_device *pce_dev)
129{
130 unsigned int val;
131 unsigned int rev;
Ramesh Masavarapu9e1c0a02012-02-07 08:56:40 -0800132 unsigned int ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700133
Mona Hossain3b574d82011-09-01 15:02:01 -0700134 val = (uint32_t)(*((uint32_t *)pce_dev->ce_dm.buffer.version));
Mona Hossain5f5dde12011-09-12 10:28:34 -0700135 if (((val & 0xfffffff) != 0x0000043) &&
136 ((val & 0xfffffff) != 0x0000042) &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700137 ((val & 0xfffffff) != 0x0000040)) {
138 dev_err(pce_dev->pdev,
139 "Unknown Qualcomm crypto device at 0x%x 0x%x\n",
140 pce_dev->phy_iobase, val);
141 return -EIO;
142 };
143 rev = (val & CRYPTO_CORE_REV_MASK);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700144 if (rev >= 0x42) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700145 dev_info(pce_dev->pdev,
146 "Qualcomm Crypto 4.2 device found at 0x%x\n",
147 pce_dev->phy_iobase);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700148 pce_dev->ce_dm.ce_block_size = 64;
Ramesh Masavarapu9e1c0a02012-02-07 08:56:40 -0800149
150 /* Configure the crypto register to support 64byte CRCI if it
151 * is not XPU protected and the HW version of device is greater
152 * than 0x42.
153 * Crypto config register returns a 0 when it is XPU protected.
154 */
155
156 ret = readl_relaxed(pce_dev->iobase + CRYPTO_CONFIG_REG);
157 if (ret) {
158 val = (CRYPTO_REQ_SIZE_ENUM_64_BYTES <<
159 CRYPTO_REQ_SIZE) |
160 (CRYPTO_FIFO_ENUM_64_BYTES <<
161 CRYPTO_FIFO_THRESHOLD);
162
163 writel_relaxed(val, pce_dev->iobase +
164 CRYPTO_CONFIG_REG);
165 } /* end of if (ret) */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700166 } else {
167 if (rev == 0x40) {
168 dev_info(pce_dev->pdev,
169 "Qualcomm Crypto 4.0 device found at 0x%x\n",
170 pce_dev->phy_iobase);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700171 pce_dev->ce_dm.ce_block_size = 16;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700172 }
173 }
174
175 dev_info(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -0700176 "IO base 0x%x\n, ce_in channel %d , "
177 "ce_out channel %d\n, "
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700178 "crci_in %d, crci_out %d\n",
179 (unsigned int) pce_dev->iobase,
Mona Hossain3b574d82011-09-01 15:02:01 -0700180 pce_dev->ce_dm.chan_ce_in, pce_dev->ce_dm.chan_ce_out,
181 pce_dev->ce_dm.crci_in, pce_dev->ce_dm.crci_out);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700182
183 return 0;
184};
185
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700186static void config_ce_engine(struct qce_device *pce_dev)
187{
188 unsigned int val = 0;
Ramesh Masavarapu72077202011-11-02 10:34:26 -0700189 unsigned int ret = 0;
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700190
Ramesh Masavarapu72077202011-11-02 10:34:26 -0700191 /* Crypto config register returns a 0 when it is XPU protected. */
192 ret = readl_relaxed(pce_dev->iobase + CRYPTO_CONFIG_REG);
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700193
Ramesh Masavarapu72077202011-11-02 10:34:26 -0700194 /* Configure the crypto register if it is not XPU protected. */
195 if (ret) {
196 val = BIT(CRYPTO_MASK_DOUT_INTR) |
197 BIT(CRYPTO_MASK_DIN_INTR) |
198 BIT(CRYPTO_MASK_OP_DONE_INTR) |
199 BIT(CRYPTO_MASK_ERR_INTR);
200
201 writel_relaxed(val, pce_dev->iobase + CRYPTO_CONFIG_REG);
202 }
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700203}
Mona Hossain3b574d82011-09-01 15:02:01 -0700204
205static void _check_probe_done_call_back(struct msm_dmov_cmd *cmd_ptr,
206 unsigned int result, struct msm_dmov_errdata *err)
207{
208 struct qce_device *pce_dev;
209 pce_dev = (struct qce_device *) cmd_ptr->user;
210
211 if (result != ADM_STATUS_OK) {
212 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
213 result);
214 pce_dev->ce_dm.chan_ce_in_status = -1;
215 } else {
216 _probe_ce_engine(pce_dev);
217 pce_dev->ce_dm.chan_ce_in_status = 0;
218 }
219 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
220};
221
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700222static int _init_ce_engine(struct qce_device *pce_dev)
223{
Mona Hossainb8db7432011-11-17 12:33:24 -0800224 int status;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700225 /* Reset ce */
226 clk_reset(pce_dev->ce_core_clk, CLK_RESET_ASSERT);
227 clk_reset(pce_dev->ce_core_clk, CLK_RESET_DEASSERT);
Mona Hossain3b574d82011-09-01 15:02:01 -0700228
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700229 /*
230 * Ensure previous instruction (any writes to CLK registers)
231 * to toggle the CLK reset lines was completed before configuring
232 * ce engine. The ce engine configuration settings should not be lost
233 * becasue of clk reset.
234 */
235 mb();
236
237 /* Configure the CE Engine */
238 config_ce_engine(pce_dev);
239
240 /*
Mona Hossainb8db7432011-11-17 12:33:24 -0800241 * Clear ACCESS_VIOL bit in CRYPTO_STATUS REGISTER
242 */
243 status = readl_relaxed(pce_dev->iobase + CRYPTO_STATUS_REG);
244 *((uint32_t *)(pce_dev->ce_dm.buffer.status)) = status & (~0x40000);
245 /*
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700246 * Ensure ce configuration is completed.
247 */
248 mb();
249
Mona Hossain3b574d82011-09-01 15:02:01 -0700250 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
251 _check_probe_done_call_back;
252 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
253 pce_dev->ce_dm.cmdptrlist.probe_ce_hw;
254 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
255 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
256 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
257 pce_dev->ce_dm.chan_ce_in_cmd);
258
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700259 return 0;
260};
261
Mona Hossain3b574d82011-09-01 15:02:01 -0700262static int _ce_setup_hash_cmdrptrlist(struct qce_device *pce_dev,
263 struct qce_sha_req *sreq)
264{
265 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
266
267 switch (sreq->alg) {
268 case QCE_HASH_SHA1:
269 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr = cmdptrlist->auth_sha1;
270 break;
271
272 case QCE_HASH_SHA256:
273 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr = cmdptrlist->auth_sha256;
274 break;
275 case QCE_HASH_SHA1_HMAC:
276 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
277 cmdptrlist->auth_sha1_hmac;
278 break;
279
280 case QCE_HASH_SHA256_HMAC:
281 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
282 cmdptrlist->auth_sha256_hmac;
283 break;
284 case QCE_HASH_AES_CMAC:
285 if (sreq->authklen == AES128_KEY_SIZE)
286 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
287 cmdptrlist->auth_aes_128_cmac;
288 else
289 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
290 cmdptrlist->auth_aes_256_cmac;
291 break;
292
293 default:
294 break;
295 }
296
297 return 0;
298}
299
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700300static int _ce_setup_hash(struct qce_device *pce_dev, struct qce_sha_req *sreq)
301{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700302 uint32_t diglen;
303 int i;
304 uint32_t auth_cfg = 0;
305 bool sha1 = false;
306
307 if (sreq->alg == QCE_HASH_AES_CMAC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700308
Mona Hossain3b574d82011-09-01 15:02:01 -0700309 memcpy(pce_dev->ce_dm.buffer.auth_key, sreq->authkey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700310 sreq->authklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700311 auth_cfg |= (1 << CRYPTO_LAST);
312 auth_cfg |= (CRYPTO_AUTH_MODE_CMAC << CRYPTO_AUTH_MODE);
313 auth_cfg |= (CRYPTO_AUTH_SIZE_ENUM_16_BYTES <<
314 CRYPTO_AUTH_SIZE);
315 auth_cfg |= CRYPTO_AUTH_ALG_AES << CRYPTO_AUTH_ALG;
316
317 switch (sreq->authklen) {
318 case AES128_KEY_SIZE:
319 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES128 <<
320 CRYPTO_AUTH_KEY_SIZE);
321 break;
322 case AES256_KEY_SIZE:
323 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES256 <<
324 CRYPTO_AUTH_KEY_SIZE);
325 break;
326 default:
327 break;
328 }
329
330 goto go_proc;
331 }
332
333 /* if not the last, the size has to be on the block boundary */
334 if (sreq->last_blk == 0 && (sreq->size % SHA256_BLOCK_SIZE))
335 return -EIO;
336
337 switch (sreq->alg) {
338 case QCE_HASH_SHA1:
339 case QCE_HASH_SHA1_HMAC:
340 diglen = SHA1_DIGEST_SIZE;
341 sha1 = true;
342 break;
343 case QCE_HASH_SHA256:
344 case QCE_HASH_SHA256_HMAC:
345 diglen = SHA256_DIGEST_SIZE;
346 break;
347 default:
348 return -EINVAL;
349 }
350
351 if ((sreq->alg == QCE_HASH_SHA1_HMAC) ||
352 (sreq->alg == QCE_HASH_SHA256_HMAC)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700353
Mona Hossain3b574d82011-09-01 15:02:01 -0700354 memcpy(pce_dev->ce_dm.buffer.auth_key, sreq->authkey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700355 sreq->authklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700356 auth_cfg |= (CRYPTO_AUTH_MODE_HMAC << CRYPTO_AUTH_MODE);
357 } else {
358 auth_cfg |= (CRYPTO_AUTH_MODE_HASH << CRYPTO_AUTH_MODE);
359 }
360
361 /* write 20/32 bytes, 5/8 words into auth_iv for SHA1/SHA256 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700362 if (sreq->first_blk) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700363 if (sha1)
364 memcpy(pce_dev->ce_dm.buffer.auth_iv,
365 _std_init_vector_sha1_uint8, diglen);
366 else
367 memcpy(pce_dev->ce_dm.buffer.auth_iv,
368 _std_init_vector_sha256_uint8, diglen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700369 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700370 memcpy(pce_dev->ce_dm.buffer.auth_iv, sreq->digest,
371 diglen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700372 }
373
Mona Hossain3b574d82011-09-01 15:02:01 -0700374 /* write auth_bytecnt 0/1/2/3, start with 0 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700375 for (i = 0; i < 4; i++)
Mona Hossain3b574d82011-09-01 15:02:01 -0700376 *(((uint32_t *)(pce_dev->ce_dm.buffer.auth_byte_count) + i)) =
377 sreq->auth_data[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700378
379 /* write seg_cfg */
380 if (sha1)
381 auth_cfg |= (CRYPTO_AUTH_SIZE_SHA1 << CRYPTO_AUTH_SIZE);
382 else
383 auth_cfg |= (CRYPTO_AUTH_SIZE_SHA256 << CRYPTO_AUTH_SIZE);
384
385 if (sreq->last_blk)
386 auth_cfg |= 1 << CRYPTO_LAST;
387
388 auth_cfg |= CRYPTO_AUTH_ALG_SHA << CRYPTO_AUTH_ALG;
389
390go_proc:
391 auth_cfg |= (CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);
392
Mona Hossain3b574d82011-09-01 15:02:01 -0700393 /* write auth seg cfg */
394 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start)) =
395 auth_cfg;
396 /* write auth seg size */
397 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start) + 1) =
398 sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700399
Mona Hossain3b574d82011-09-01 15:02:01 -0700400 /* write auth seg size start*/
401 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start)+2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700402
Mona Hossain3b574d82011-09-01 15:02:01 -0700403 /* write seg size */
404 *((uint32_t *)(pce_dev->ce_dm.buffer.seg_size)) = sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700405
Mona Hossain3b574d82011-09-01 15:02:01 -0700406 _ce_setup_hash_cmdrptrlist(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700407
Mona Hossain3b574d82011-09-01 15:02:01 -0700408 return 0;
409}
410
411static int _ce_setup_cipher_cmdrptrlist(struct qce_device *pce_dev,
412 struct qce_req *creq)
413{
414 struct ce_cmdptrlists_ops *cmdptrlist =
415 &pce_dev->ce_dm.cmdptrlist;
416
417 if (creq->alg != CIPHER_ALG_AES) {
418 switch (creq->alg) {
419 case CIPHER_ALG_DES:
420 if (creq->mode == QCE_MODE_ECB) {
421 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
422 cmdptrlist->cipher_des_ecb;
423 } else {
424 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
425 cmdptrlist->cipher_des_cbc;
426 }
427 break;
428
429 case CIPHER_ALG_3DES:
430 if (creq->mode == QCE_MODE_ECB) {
431 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
432 cmdptrlist->cipher_3des_ecb;
433 } else {
434 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
435 cmdptrlist->cipher_3des_cbc;
436 }
437 break;
438 default:
439 break;
440 }
441 } else {
442 switch (creq->mode) {
443 case QCE_MODE_ECB:
444 if (creq->encklen == AES128_KEY_SIZE) {
445 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
446 cmdptrlist->cipher_aes_128_ecb;
447 } else {
448 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
449 cmdptrlist->cipher_aes_256_ecb;
450 }
451 break;
452
453 case QCE_MODE_CBC:
454 if (creq->encklen == AES128_KEY_SIZE) {
455 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
456 cmdptrlist->cipher_aes_128_cbc_ctr;
457 } else {
458 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
459 cmdptrlist->cipher_aes_256_cbc_ctr;
460 }
461 break;
462
463 case QCE_MODE_CTR:
464 if (creq->encklen == AES128_KEY_SIZE) {
465 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
466 cmdptrlist->cipher_aes_128_cbc_ctr;
467 } else {
468 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
469 cmdptrlist->cipher_aes_256_cbc_ctr;
470 }
471 break;
472
473 case QCE_MODE_XTS:
474 if (creq->encklen == AES128_KEY_SIZE) {
475 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
476 cmdptrlist->cipher_aes_128_xts;
477 } else {
478 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
479 cmdptrlist->cipher_aes_256_xts;
480 }
481 break;
482 case QCE_MODE_CCM:
483 if (creq->encklen == AES128_KEY_SIZE) {
484 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
485 cmdptrlist->aead_aes_128_ccm;
486 } else {
487 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
488 cmdptrlist->aead_aes_256_ccm;
489 }
490 break;
491 default:
492 break;
493 }
494 }
495
Mona Hossainb8db7432011-11-17 12:33:24 -0800496 switch (creq->mode) {
497 case QCE_MODE_CCM:
Mona Hossain3b574d82011-09-01 15:02:01 -0700498 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
Mona Hossainb8db7432011-11-17 12:33:24 -0800499 cmdptrlist->aead_ce_out;
500 break;
501 case QCE_MODE_ECB:
Mona Hossain3b574d82011-09-01 15:02:01 -0700502 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
Mona Hossainb8db7432011-11-17 12:33:24 -0800503 cmdptrlist->cipher_ce_out;
504 break;
505 default:
506 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
507 cmdptrlist->cipher_ce_out_get_iv;
508 break;
509 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700510
511 return 0;
512}
513
514static int _ce_setup_cipher(struct qce_device *pce_dev, struct qce_req *creq,
515 uint32_t totallen_in, uint32_t coffset)
516{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700517 uint32_t enck_size_in_word = creq->encklen / sizeof(uint32_t);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700518 uint32_t encr_cfg = 0;
519 uint32_t ivsize = creq->ivsize;
Mona Hossain3b574d82011-09-01 15:02:01 -0700520 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700521
522 if (creq->mode == QCE_MODE_XTS)
Mona Hossain3b574d82011-09-01 15:02:01 -0700523 memcpy(buffer->encr_key, creq->enckey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700524 creq->encklen/2);
525 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700526 memcpy(buffer->encr_key, creq->enckey, creq->encklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700527
528 if ((creq->op == QCE_REQ_AEAD) && (creq->mode == QCE_MODE_CCM)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700529 uint32_t noncelen32 = MAX_NONCE/sizeof(uint32_t);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700530 uint32_t auth_cfg = 0;
531
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700532 /* write nonce */
Mona Hossain3b574d82011-09-01 15:02:01 -0700533 memcpy(buffer->auth_nonce_info, creq->nonce, MAX_NONCE);
534 memcpy(buffer->auth_key, creq->enckey, creq->encklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700535
536 auth_cfg |= (noncelen32 << CRYPTO_AUTH_NONCE_NUM_WORDS);
537 auth_cfg &= ~(1 << CRYPTO_USE_HW_KEY_AUTH);
538 auth_cfg |= (1 << CRYPTO_LAST);
539 if (creq->dir == QCE_ENCRYPT)
540 auth_cfg |= (CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);
541 else
542 auth_cfg |= (CRYPTO_AUTH_POS_AFTER << CRYPTO_AUTH_POS);
543 auth_cfg |= (((creq->authsize >> 1) - 2) << CRYPTO_AUTH_SIZE);
544 auth_cfg |= (CRYPTO_AUTH_MODE_CCM << CRYPTO_AUTH_MODE);
545 if (creq->authklen == AES128_KEY_SIZE)
546 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES128 <<
547 CRYPTO_AUTH_KEY_SIZE);
548 else {
549 if (creq->authklen == AES256_KEY_SIZE)
550 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES256 <<
551 CRYPTO_AUTH_KEY_SIZE);
552 }
553 auth_cfg |= (CRYPTO_AUTH_ALG_AES << CRYPTO_AUTH_ALG);
Mona Hossain3b574d82011-09-01 15:02:01 -0700554 *((uint32_t *)(buffer->auth_seg_cfg_size_start)) = auth_cfg;
555
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700556 if (creq->dir == QCE_ENCRYPT)
Mona Hossain3b574d82011-09-01 15:02:01 -0700557 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 1) =
558 totallen_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700559 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700560 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 1) =
561 (totallen_in - creq->authsize);
562 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700563 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700564
565 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700566
567 switch (creq->mode) {
568 case QCE_MODE_ECB:
569 encr_cfg |= (CRYPTO_ENCR_MODE_ECB << CRYPTO_ENCR_MODE);
570 break;
571
572 case QCE_MODE_CBC:
573 encr_cfg |= (CRYPTO_ENCR_MODE_CBC << CRYPTO_ENCR_MODE);
574 break;
575
576 case QCE_MODE_XTS:
577 encr_cfg |= (CRYPTO_ENCR_MODE_XTS << CRYPTO_ENCR_MODE);
578 break;
579
580 case QCE_MODE_CCM:
581 encr_cfg |= (CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE);
582 break;
583
584 case QCE_MODE_CTR:
585 default:
586 encr_cfg |= (CRYPTO_ENCR_MODE_CTR << CRYPTO_ENCR_MODE);
587 break;
588 }
589 pce_dev->mode = creq->mode;
590
591 switch (creq->alg) {
592 case CIPHER_ALG_DES:
Mona Hossain3b574d82011-09-01 15:02:01 -0700593 if (creq->mode != QCE_MODE_ECB)
594 memcpy(buffer->encr_cntr_iv, creq->iv, ivsize);
595
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700596 encr_cfg |= ((CRYPTO_ENCR_KEY_SZ_DES << CRYPTO_ENCR_KEY_SZ) |
597 (CRYPTO_ENCR_ALG_DES << CRYPTO_ENCR_ALG));
598 break;
599
600 case CIPHER_ALG_3DES:
Mona Hossain3b574d82011-09-01 15:02:01 -0700601 if (creq->mode != QCE_MODE_ECB)
602 memcpy(buffer->encr_cntr_iv, creq->iv, ivsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700603
604 encr_cfg |= ((CRYPTO_ENCR_KEY_SZ_3DES << CRYPTO_ENCR_KEY_SZ) |
605 (CRYPTO_ENCR_ALG_DES << CRYPTO_ENCR_ALG));
606 break;
607
608 case CIPHER_ALG_AES:
609 default:
610 if (creq->mode == QCE_MODE_XTS) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700611 memcpy(buffer->encr_xts_key, (creq->enckey +
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700612 creq->encklen/2), creq->encklen/2);
Mona Hossain3b574d82011-09-01 15:02:01 -0700613 *((uint32_t *)(buffer->encr_xts_du_size)) =
614 creq->cryptlen;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700615
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700616 }
617 if (creq->mode != QCE_MODE_ECB) {
618 if (creq->mode == QCE_MODE_XTS)
Mona Hossain3b574d82011-09-01 15:02:01 -0700619 _byte_stream_swap_to_net_words(
620 (uint32_t *)(buffer->encr_cntr_iv),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700621 creq->iv, ivsize);
622 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700623 memcpy(buffer->encr_cntr_iv, creq->iv,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700624 ivsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700625 }
626 /* set number of counter bits */
Mona Hossain3b574d82011-09-01 15:02:01 -0700627 *((uint32_t *)(buffer->encr_mask)) = (uint32_t)0xffffffff;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700628
629 if (creq->op == QCE_REQ_ABLK_CIPHER_NO_KEY) {
630 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES128 <<
631 CRYPTO_ENCR_KEY_SZ);
632 encr_cfg |= CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG;
633 } else {
634 uint32_t key_size;
635
636 if (creq->mode == QCE_MODE_XTS) {
637 key_size = creq->encklen/2;
638 enck_size_in_word = key_size/sizeof(uint32_t);
639 } else {
640 key_size = creq->encklen;
641 }
642
643 switch (key_size) {
644 case AES128_KEY_SIZE:
645 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES128 <<
646 CRYPTO_ENCR_KEY_SZ);
647 break;
648 case AES256_KEY_SIZE:
649 default:
650 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES256 <<
651 CRYPTO_ENCR_KEY_SZ);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700652 break;
653 } /* end of switch (creq->encklen) */
654
655 encr_cfg |= CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700656 } /* else of if (creq->op == QCE_REQ_ABLK_CIPHER_NO_KEY) */
657 break;
658 } /* end of switch (creq->mode) */
659
660 /* write encr seg cfg */
661 encr_cfg |= ((creq->dir == QCE_ENCRYPT) ? 1 : 0) << CRYPTO_ENCODE;
662
663 /* write encr seg cfg */
Mona Hossain3b574d82011-09-01 15:02:01 -0700664 *((uint32_t *)(buffer->encr_seg_cfg_size_start)) = encr_cfg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700665 /* write encr seg size */
666 if ((creq->mode == QCE_MODE_CCM) && (creq->dir == QCE_DECRYPT))
Mona Hossain3b574d82011-09-01 15:02:01 -0700667 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 1) =
668 (creq->cryptlen + creq->authsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700669 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700670 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 1) =
671 creq->cryptlen;
672
673
674 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 2) =
675 (coffset & 0xffff);
676
677 *((uint32_t *)(buffer->seg_size)) = totallen_in;
678
679 _ce_setup_cipher_cmdrptrlist(pce_dev, creq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700680 return 0;
681};
682
683static int _aead_complete(struct qce_device *pce_dev)
684{
685 struct aead_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700686
687 areq = (struct aead_request *) pce_dev->areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700688
689 if (areq->src != areq->dst) {
690 dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
691 DMA_FROM_DEVICE);
692 }
693 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
694 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
695 DMA_TO_DEVICE);
696
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700697 dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
698 DMA_TO_DEVICE);
699
Mona Hossain3b574d82011-09-01 15:02:01 -0700700 /* check MAC */
701 if (pce_dev->mode == QCE_MODE_CCM) {
702 uint32_t result;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700703
Mona Hossain3b574d82011-09-01 15:02:01 -0700704 result =
705 (uint32_t)(*((uint32_t *)pce_dev->ce_dm.buffer.status));
706 result &= (1 << CRYPTO_MAC_FAILED);
707 result |= (pce_dev->ce_dm.chan_ce_in_status |
708 pce_dev->ce_dm.chan_ce_out_status);
709 pce_dev->qce_cb(areq, pce_dev->ce_dm.buffer.auth_result, NULL,
710 result);
711 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700712 return 0;
713};
714
715static void _sha_complete(struct qce_device *pce_dev)
716{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700717 struct ahash_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700718
719 areq = (struct ahash_request *) pce_dev->areq;
720 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
721 DMA_TO_DEVICE);
722
Mona Hossain3b574d82011-09-01 15:02:01 -0700723 pce_dev->qce_cb(areq, pce_dev->ce_dm.buffer.auth_result,
724 pce_dev->ce_dm.buffer.auth_byte_count,
725 pce_dev->ce_dm.chan_ce_in_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700726
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700727};
728
729static int _ablk_cipher_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
735 if (areq->src != areq->dst) {
736 dma_unmap_sg(pce_dev->pdev, areq->dst,
737 pce_dev->dst_nents, DMA_FROM_DEVICE);
738 }
739 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
740 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
741 DMA_TO_DEVICE);
Mona Hossain3b574d82011-09-01 15:02:01 -0700742
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700743 if (pce_dev->mode == QCE_MODE_ECB) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700744 pce_dev->qce_cb(areq, NULL, NULL,
745 pce_dev->ce_dm.chan_ce_in_status |
746 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700747 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700748
Mona Hossain3b574d82011-09-01 15:02:01 -0700749 pce_dev->qce_cb(areq, NULL, pce_dev->ce_dm.buffer.encr_cntr_iv,
750 pce_dev->ce_dm.chan_ce_in_status |
751 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700752 }
753
754 return 0;
755};
756
757static int _ablk_cipher_use_pmem_complete(struct qce_device *pce_dev)
758{
759 struct ablkcipher_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700760
761 areq = (struct ablkcipher_request *) pce_dev->areq;
762
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700763 if (pce_dev->mode == QCE_MODE_ECB) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700764 pce_dev->qce_cb(areq, NULL, NULL,
765 pce_dev->ce_dm.chan_ce_in_status |
766 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700767 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700768 pce_dev->qce_cb(areq, NULL, pce_dev->ce_dm.buffer.encr_cntr_iv,
769 pce_dev->ce_dm.chan_ce_in_status |
770 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700771 }
772
773 return 0;
774};
775
776static int qce_split_and_insert_dm_desc(struct dmov_desc *pdesc,
777 unsigned int plen, unsigned int paddr, int *index)
778{
Mona Hossain3b574d82011-09-01 15:02:01 -0700779 while (plen > QCE_FIFO_SIZE) {
780 pdesc->len = QCE_FIFO_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700781 if (paddr > 0) {
782 pdesc->addr = paddr;
Mona Hossain3b574d82011-09-01 15:02:01 -0700783 paddr += QCE_FIFO_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700784 }
785 plen -= pdesc->len;
786 if (plen > 0) {
787 *index = (*index) + 1;
788 if ((*index) >= QCE_MAX_NUM_DESC)
789 return -ENOMEM;
790 pdesc++;
791 }
792 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700793 if ((plen > 0) && (plen <= QCE_FIFO_SIZE)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700794 pdesc->len = plen;
795 if (paddr > 0)
796 pdesc->addr = paddr;
797 }
798
799 return 0;
800}
801
802static int _chain_sg_buffer_in(struct qce_device *pce_dev,
803 struct scatterlist *sg, unsigned int nbytes)
804{
805 unsigned int len;
806 unsigned int dlen;
807 struct dmov_desc *pdesc;
808
Mona Hossain3b574d82011-09-01 15:02:01 -0700809 pdesc = pce_dev->ce_dm.ce_in_src_desc +
810 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700811 /*
812 * Two consective chunks may be handled by the old
813 * buffer descriptor.
814 */
815 while (nbytes > 0) {
816 len = min(nbytes, sg_dma_len(sg));
817 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
818 nbytes -= len;
819 if (dlen == 0) {
820 pdesc->addr = sg_dma_address(sg);
821 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700822 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700823 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700824 sg_dma_address(sg),
825 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700826 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
827 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700828 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700829 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700830 pdesc->addr,
831 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700832 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700833 pce_dev->ce_dm.ce_in_src_desc_index++;
834 if (pce_dev->ce_dm.ce_in_src_desc_index >=
835 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700836 return -ENOMEM;
837 pdesc++;
838 pdesc->len = len;
839 pdesc->addr = sg_dma_address(sg);
Mona Hossain3b574d82011-09-01 15:02:01 -0700840 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700841 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700842 sg_dma_address(sg),
843 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700844 }
845 if (nbytes > 0)
846 sg = sg_next(sg);
847 }
848 return 0;
849}
850
851static int _chain_pm_buffer_in(struct qce_device *pce_dev,
852 unsigned int pmem, unsigned int nbytes)
853{
854 unsigned int dlen;
855 struct dmov_desc *pdesc;
856
Mona Hossain3b574d82011-09-01 15:02:01 -0700857 pdesc = pce_dev->ce_dm.ce_in_src_desc +
858 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700859 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
860 if (dlen == 0) {
861 pdesc->addr = pmem;
862 pdesc->len = nbytes;
863 } else if (pmem == (pdesc->addr + dlen)) {
864 pdesc->len = dlen + nbytes;
865 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700866 pce_dev->ce_dm.ce_in_src_desc_index++;
867 if (pce_dev->ce_dm.ce_in_src_desc_index >=
868 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700869 return -ENOMEM;
870 pdesc++;
871 pdesc->len = nbytes;
872 pdesc->addr = pmem;
873 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700874 return 0;
875}
876
877static void _chain_buffer_in_init(struct qce_device *pce_dev)
878{
879 struct dmov_desc *pdesc;
880
Mona Hossain3b574d82011-09-01 15:02:01 -0700881 pce_dev->ce_dm.ce_in_src_desc_index = 0;
882 pce_dev->ce_dm.ce_in_dst_desc_index = 0;
883 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700884 pdesc->len = 0;
885}
886
887static void _ce_in_final(struct qce_device *pce_dev, unsigned total)
888{
889 struct dmov_desc *pdesc;
890 dmov_sg *pcmd;
891
Mona Hossain3b574d82011-09-01 15:02:01 -0700892 pdesc = pce_dev->ce_dm.ce_in_src_desc +
893 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700894 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700895
896 pdesc = pce_dev->ce_dm.ce_in_dst_desc;
897 if (total > QCE_FIFO_SIZE) {
898 qce_split_and_insert_dm_desc(pdesc, total, 0,
899 &pce_dev->ce_dm.ce_in_dst_desc_index);
900 pdesc = pce_dev->ce_dm.ce_in_dst_desc +
901 pce_dev->ce_dm.ce_in_dst_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -0700902 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700903 } else
904 pdesc->len = ADM_DESC_LAST | total;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700905
Mona Hossain3b574d82011-09-01 15:02:01 -0700906 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700907 pcmd->cmd |= CMD_LC;
Mona Hossain3b574d82011-09-01 15:02:01 -0700908
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700909}
910
911#ifdef QCE_DEBUG
912static void _ce_in_dump(struct qce_device *pce_dev)
913{
914 int i;
915 struct dmov_desc *pdesc;
916
917 dev_info(pce_dev->pdev, "_ce_in_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700918 for (i = 0; i <= pce_dev->ce_dm.ce_in_src_desc_index; i++) {
919 pdesc = pce_dev->ce_dm.ce_in_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700920 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
921 pdesc->len);
922 }
923 dev_info(pce_dev->pdev, "_ce_in_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700924 for (i = 0; i <= pce_dev->ce_dm.ce_in_dst_desc_index; i++) {
925 pdesc = pce_dev->ce_dm.ce_in_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700926 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
927 pdesc->len);
928 }
929};
930
931static void _ce_out_dump(struct qce_device *pce_dev)
932{
933 int i;
934 struct dmov_desc *pdesc;
935
936 dev_info(pce_dev->pdev, "_ce_out_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700937 for (i = 0; i <= pce_dev->ce_dm.ce_out_src_desc_index; i++) {
938 pdesc = pce_dev->ce_dm.ce_out_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700939 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
940 pdesc->len);
941 }
942
943 dev_info(pce_dev->pdev, "_ce_out_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700944 for (i = 0; i <= pce_dev->ce_dm.ce_out_dst_desc_index; i++) {
945 pdesc = pce_dev->ce_dm.ce_out_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700946 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
947 pdesc->len);
948 }
949};
950
951#else
952
953static void _ce_in_dump(struct qce_device *pce_dev)
954{
955};
956
957static void _ce_out_dump(struct qce_device *pce_dev)
958{
959};
960
961#endif
962
963static int _chain_sg_buffer_out(struct qce_device *pce_dev,
964 struct scatterlist *sg, unsigned int nbytes)
965{
966 unsigned int len;
967 unsigned int dlen;
968 struct dmov_desc *pdesc;
969
Mona Hossain3b574d82011-09-01 15:02:01 -0700970 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
971 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700972 /*
973 * Two consective chunks may be handled by the old
974 * buffer descriptor.
975 */
976 while (nbytes > 0) {
977 len = min(nbytes, sg_dma_len(sg));
978 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
979 nbytes -= len;
980 if (dlen == 0) {
981 pdesc->addr = sg_dma_address(sg);
982 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700983 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700984 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
985 sg_dma_address(sg),
Mona Hossain3b574d82011-09-01 15:02:01 -0700986 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700987 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
988 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700989 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700990 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
991 pdesc->addr,
Mona Hossain3b574d82011-09-01 15:02:01 -0700992 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700993
994 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700995 pce_dev->ce_dm.ce_out_dst_desc_index++;
996 if (pce_dev->ce_dm.ce_out_dst_desc_index >=
997 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700998 return -EIO;
999 pdesc++;
1000 pdesc->len = len;
1001 pdesc->addr = sg_dma_address(sg);
Mona Hossain3b574d82011-09-01 15:02:01 -07001002 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001003 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
1004 sg_dma_address(sg),
Mona Hossain3b574d82011-09-01 15:02:01 -07001005 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001006
1007 }
1008 if (nbytes > 0)
1009 sg = sg_next(sg);
1010 }
1011 return 0;
1012}
1013
1014static int _chain_pm_buffer_out(struct qce_device *pce_dev,
1015 unsigned int pmem, unsigned int nbytes)
1016{
1017 unsigned int dlen;
1018 struct dmov_desc *pdesc;
1019
Mona Hossain3b574d82011-09-01 15:02:01 -07001020 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
1021 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001022 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
1023
1024 if (dlen == 0) {
1025 pdesc->addr = pmem;
1026 pdesc->len = nbytes;
1027 } else if (pmem == (pdesc->addr + dlen)) {
1028 pdesc->len = dlen + nbytes;
1029 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001030 pce_dev->ce_dm.ce_out_dst_desc_index++;
1031 if (pce_dev->ce_dm.ce_out_dst_desc_index >= QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001032 return -EIO;
1033 pdesc++;
1034 pdesc->len = nbytes;
1035 pdesc->addr = pmem;
1036 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001037 return 0;
1038};
1039
1040static void _chain_buffer_out_init(struct qce_device *pce_dev)
1041{
1042 struct dmov_desc *pdesc;
1043
Mona Hossain3b574d82011-09-01 15:02:01 -07001044 pce_dev->ce_dm.ce_out_dst_desc_index = 0;
1045 pce_dev->ce_dm.ce_out_src_desc_index = 0;
1046 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001047 pdesc->len = 0;
1048};
1049
1050static void _ce_out_final(struct qce_device *pce_dev, unsigned total)
1051{
1052 struct dmov_desc *pdesc;
1053 dmov_sg *pcmd;
1054
Mona Hossain3b574d82011-09-01 15:02:01 -07001055 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
1056 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001057 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001058
Mona Hossain3b574d82011-09-01 15:02:01 -07001059 pdesc = pce_dev->ce_dm.ce_out_src_desc +
1060 pce_dev->ce_dm.ce_out_src_desc_index;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001061 if (total > QCE_FIFO_SIZE) {
1062 qce_split_and_insert_dm_desc(pdesc, total, 0,
1063 &pce_dev->ce_dm.ce_out_src_desc_index);
1064 pdesc = pce_dev->ce_dm.ce_out_src_desc +
1065 pce_dev->ce_dm.ce_out_src_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -07001066 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001067 } else
1068 pdesc->len = ADM_DESC_LAST | total;
Mona Hossain3b574d82011-09-01 15:02:01 -07001069
1070 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001071 pcmd->cmd |= CMD_LC;
1072};
1073
1074static void _aead_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1075 unsigned int result, struct msm_dmov_errdata *err)
1076{
1077 struct qce_device *pce_dev;
1078
1079 pce_dev = (struct qce_device *) cmd_ptr->user;
1080 if (result != ADM_STATUS_OK) {
1081 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1082 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001083 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001084 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001085 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001086 }
1087
Mona Hossain3b574d82011-09-01 15:02:01 -07001088 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1089 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1090 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1091 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001092
1093 /* done */
1094 _aead_complete(pce_dev);
1095 }
1096};
1097
1098static void _aead_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1099 unsigned int result, struct msm_dmov_errdata *err)
1100{
1101 struct qce_device *pce_dev;
1102
1103 pce_dev = (struct qce_device *) cmd_ptr->user;
1104 if (result != ADM_STATUS_OK) {
1105 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1106 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001107 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001108 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001109 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001110 };
1111
Mona Hossain3b574d82011-09-01 15:02:01 -07001112 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1113 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1114 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1115 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001116
1117 /* done */
1118 _aead_complete(pce_dev);
1119 }
1120
1121};
1122
1123static void _sha_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1124 unsigned int result, struct msm_dmov_errdata *err)
1125{
1126 struct qce_device *pce_dev;
1127
1128 pce_dev = (struct qce_device *) cmd_ptr->user;
1129 if (result != ADM_STATUS_OK) {
1130 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1131 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001132 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001133 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001134 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001135 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001136 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001137 _sha_complete(pce_dev);
1138};
1139
1140static void _ablk_cipher_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1141 unsigned int result, struct msm_dmov_errdata *err)
1142{
1143 struct qce_device *pce_dev;
1144
1145 pce_dev = (struct qce_device *) cmd_ptr->user;
1146 if (result != ADM_STATUS_OK) {
1147 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1148 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001149 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001150 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001151 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001152 }
1153
Mona Hossain3b574d82011-09-01 15:02:01 -07001154 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1155 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1156 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1157 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001158
1159 /* done */
1160 _ablk_cipher_complete(pce_dev);
1161 }
1162};
1163
1164static void _ablk_cipher_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1165 unsigned int result, struct msm_dmov_errdata *err)
1166{
1167 struct qce_device *pce_dev;
1168
1169 pce_dev = (struct qce_device *) cmd_ptr->user;
Mona Hossain3b574d82011-09-01 15:02:01 -07001170
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001171 if (result != ADM_STATUS_OK) {
1172 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1173 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001174 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001175 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001176 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001177 };
1178
Mona Hossain3b574d82011-09-01 15:02:01 -07001179 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1180 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1181 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1182 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001183
1184 /* done */
1185 _ablk_cipher_complete(pce_dev);
1186 }
1187};
1188
1189
1190static void _ablk_cipher_ce_in_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1191 unsigned int result, struct msm_dmov_errdata *err)
1192{
1193 struct qce_device *pce_dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001194 pce_dev = (struct qce_device *) cmd_ptr->user;
1195 if (result != ADM_STATUS_OK) {
1196 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1197 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001198 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001199 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001200 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001201 }
1202
Mona Hossain3b574d82011-09-01 15:02:01 -07001203 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1204 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1205 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1206 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001207
1208 /* done */
1209 _ablk_cipher_use_pmem_complete(pce_dev);
1210 }
1211};
1212
1213static void _ablk_cipher_ce_out_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1214 unsigned int result, struct msm_dmov_errdata *err)
1215{
1216 struct qce_device *pce_dev;
1217
1218 pce_dev = (struct qce_device *) cmd_ptr->user;
1219 if (result != ADM_STATUS_OK) {
1220 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1221 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001222 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001223 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001224 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001225 };
1226
Mona Hossain3b574d82011-09-01 15:02:01 -07001227 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1228 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1229 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1230 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001231
1232 /* done */
1233 _ablk_cipher_use_pmem_complete(pce_dev);
1234 }
1235};
1236
Mona Hossain3b574d82011-09-01 15:02:01 -07001237static int qce_setup_cmd_buffers(struct qce_device *pce_dev,
1238 unsigned char **pvaddr)
1239{
1240 struct ce_reg_buffers *addr = (struct ce_reg_buffers *)(*pvaddr);
1241 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
1242
1243 /*
1244 * Designate chunks of the allocated memory to various
1245 * buffer pointers
1246 */
1247 buffer->reset_buf_64 = addr->reset_buf_64;
1248 buffer->version = addr->version;
1249 buffer->encr_seg_cfg_size_start = addr->encr_seg_cfg_size_start;
1250 buffer->encr_key = addr->encr_key;
1251 buffer->encr_xts_key = addr->encr_xts_key;
1252 buffer->encr_xts_du_size = addr->encr_xts_du_size;
1253 buffer->encr_cntr_iv = addr->encr_cntr_iv;
1254 buffer->encr_mask = addr->encr_mask;
1255 buffer->auth_seg_cfg_size_start = addr->auth_seg_cfg_size_start;
1256 buffer->auth_key = addr->auth_key;
1257 buffer->auth_iv = addr->auth_iv;
1258 buffer->auth_result = addr->auth_result;
1259 buffer->auth_nonce_info = addr->auth_nonce_info;
1260 buffer->auth_byte_count = addr->auth_byte_count;
1261 buffer->seg_size = addr->seg_size;
1262 buffer->go_proc = addr->go_proc;
1263 buffer->status = addr->status;
1264 buffer->pad = addr->pad;
1265
1266 memset(buffer->reset_buf_64, 0, 64);
1267 *((uint32_t *)buffer->encr_mask) = (uint32_t)(0xffffffff);
1268 *((uint32_t *)buffer->go_proc) = (uint32_t)(1 << CRYPTO_GO);
1269
1270 *pvaddr += sizeof(struct ce_reg_buffers);
1271
1272 return 0;
1273
1274}
1275
1276static int _setup_cipher_cmdlists(struct qce_device *pce_dev,
1277 unsigned char **pvaddr)
1278{
1279 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1280
1281 /*
1282 * Designate chunks of the allocated memory to various
1283 * command list pointers related to cipher operation
1284 */
1285 pce_dev->ce_dm.cmdlist.set_cipher_cfg = pscmd;
1286 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1287 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG +
1288 pce_dev->phy_iobase);
1289 pscmd->len = CRYPTO_REG_SIZE * 3;
1290 pscmd->src =
1291 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_seg_cfg_size_start);
1292 pscmd++;
1293
1294 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_key = pscmd;
1295 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1296 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1297 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1298 pscmd->len = CRYPTO_REG_SIZE * 4;
1299 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1300 pscmd++;
1301
1302 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_key = pscmd;
1303 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1304 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1305 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1306 pscmd->len = CRYPTO_REG_SIZE * 8;
1307 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1308 pscmd++;
1309
1310 pce_dev->ce_dm.cmdlist.set_cipher_des_key = pscmd;
1311 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1312 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1313 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1314 pscmd->len = CRYPTO_REG_SIZE * 2;
1315 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1316 pscmd++;
1317
1318 pce_dev->ce_dm.cmdlist.set_cipher_3des_key = pscmd;
1319 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1320 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1321 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1322 pscmd->len = CRYPTO_REG_SIZE * 6;
1323 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1324 pscmd++;
1325
1326 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_xts_key = pscmd;
1327 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1328 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1329 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1330 pce_dev->phy_iobase);
1331 pscmd->len = CRYPTO_REG_SIZE * 4;
1332 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1333 pscmd++;
1334
1335 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_xts_key = pscmd;
1336 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1337 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1338 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1339 pce_dev->phy_iobase);
1340 pscmd->len = CRYPTO_REG_SIZE * 8;
1341 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1342 pscmd++;
1343
1344 pce_dev->ce_dm.cmdlist.set_cipher_xts_du_size = pscmd;
1345 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1346 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_DU_SIZE_REG +
1347 pce_dev->phy_iobase);
1348 pscmd->len = CRYPTO_REG_SIZE * 4;
1349 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_du_size);
1350 pscmd++;
1351
1352 pce_dev->ce_dm.cmdlist.set_cipher_aes_iv = pscmd;
1353 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1354 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1355 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1356 pscmd->len = CRYPTO_REG_SIZE * 4;
1357 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1358 pscmd++;
1359
Mona Hossain3b574d82011-09-01 15:02:01 -07001360 pce_dev->ce_dm.cmdlist.set_cipher_des_iv = pscmd;
1361 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1362 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1363 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1364 pscmd->len = CRYPTO_REG_SIZE * 2;
1365 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1366 pscmd++;
1367
Mona Hossainb8db7432011-11-17 12:33:24 -08001368 pce_dev->ce_dm.cmdlist.get_cipher_iv = pscmd;
Mona Hossain3b574d82011-09-01 15:02:01 -07001369 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1370 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1371 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
Mona Hossainb8db7432011-11-17 12:33:24 -08001372 pscmd->len = CRYPTO_REG_SIZE * 4;
Mona Hossain3b574d82011-09-01 15:02:01 -07001373 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1374 pscmd++;
1375
1376 pce_dev->ce_dm.cmdlist.set_cipher_mask = pscmd;
1377 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1378 pscmd->dst = (unsigned) (CRYPTO_CNTR_MASK_REG + pce_dev->phy_iobase);
1379 pscmd->len = CRYPTO_REG_SIZE;
1380 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_mask);
1381 pscmd++;
1382
1383 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1384
1385 pce_dev->ce_dm.cmdlist.reset_cipher_key = pscmd;
1386 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1387 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1388 pscmd->len = CRYPTO_REG_SIZE * 8;
1389 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1390 pscmd++;
1391
1392 pce_dev->ce_dm.cmdlist.reset_cipher_xts_key = pscmd;
1393 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1394 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1395 pce_dev->phy_iobase);
1396 pscmd->len = CRYPTO_REG_SIZE * 8;
1397 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1398 pscmd++;
1399
1400 pce_dev->ce_dm.cmdlist.reset_cipher_iv = pscmd;
1401 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1402 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1403 pscmd->len = CRYPTO_REG_SIZE * 4;
1404 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1405 pscmd++;
1406
1407 pce_dev->ce_dm.cmdlist.reset_cipher_cfg = pscmd;
1408 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1409 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG + pce_dev->phy_iobase);
1410 pscmd->len = CRYPTO_REG_SIZE;
1411 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1412 pscmd++;
1413
1414 *pvaddr = (unsigned char *) pscmd;
1415
1416 return 0;
1417}
1418
1419static int _setup_auth_cmdlists(struct qce_device *pce_dev,
1420 unsigned char **pvaddr)
1421{
1422 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1423
1424 /*
1425 * Designate chunks of the allocated memory to various
1426 * command list pointers related to authentication operation
1427 */
1428 pce_dev->ce_dm.cmdlist.set_auth_cfg = pscmd;
1429 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1430 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1431 pscmd->len = CRYPTO_REG_SIZE * 3;
1432 pscmd->src =
1433 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start);
1434 pscmd++;
1435
1436 pce_dev->ce_dm.cmdlist.set_auth_key_128 = pscmd;
1437 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1438 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1439 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1440 pscmd->len = CRYPTO_REG_SIZE * 4;
1441 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1442 pscmd++;
1443
1444 pce_dev->ce_dm.cmdlist.set_auth_key_256 = pscmd;
1445 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1446 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1447 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1448 pscmd->len = CRYPTO_REG_SIZE * 8;
1449 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1450 pscmd++;
1451
1452 pce_dev->ce_dm.cmdlist.set_auth_key_512 = pscmd;
1453 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1454 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1455 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1456 pscmd->len = CRYPTO_REG_SIZE * 16;
1457 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1458 pscmd++;
1459
1460 pce_dev->ce_dm.cmdlist.set_auth_iv_16 = pscmd;
1461 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1462 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1463 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1464 pscmd->len = CRYPTO_REG_SIZE * 4;
1465 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1466 pscmd++;
1467
1468 pce_dev->ce_dm.cmdlist.get_auth_result_16 = pscmd;
1469 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1470 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1471 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1472 pscmd->len = CRYPTO_REG_SIZE * 4;
1473 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1474 pscmd++;
1475
1476 pce_dev->ce_dm.cmdlist.set_auth_iv_20 = pscmd;
1477 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1478 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1479 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1480 pscmd->len = CRYPTO_REG_SIZE * 5;
1481 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1482 pscmd++;
1483
1484 pce_dev->ce_dm.cmdlist.get_auth_result_20 = pscmd;
1485 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1486 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1487 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1488 pscmd->len = CRYPTO_REG_SIZE * 5;
1489 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1490 pscmd++;
1491
1492 pce_dev->ce_dm.cmdlist.set_auth_iv_32 = pscmd;
1493 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1494 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1495 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1496 pscmd->len = CRYPTO_REG_SIZE * 8;
1497 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1498 pscmd++;
1499
1500
1501 pce_dev->ce_dm.cmdlist.get_auth_result_32 = pscmd;
1502 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1503 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1504 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1505 pscmd->len = CRYPTO_REG_SIZE * 8;
1506 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1507 pscmd++;
1508
1509 pce_dev->ce_dm.cmdlist.set_auth_byte_count = pscmd;
1510 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1511 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1512 pce_dev->phy_iobase);
1513 pscmd->len = CRYPTO_REG_SIZE * 4;
1514 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1515 pscmd++;
1516
1517 pce_dev->ce_dm.cmdlist.get_auth_byte_count = pscmd;
1518 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1519 pscmd->src = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1520 pce_dev->phy_iobase);
1521 pscmd->len = CRYPTO_REG_SIZE * 4;
1522 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1523 pscmd++;
1524
1525 pce_dev->ce_dm.cmdlist.set_auth_nonce_info = pscmd;
1526 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1527 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1528 pscmd->dst = (unsigned) (CRYPTO_AUTH_INFO_NONCE0_REG +
1529 pce_dev->phy_iobase);
1530 pscmd->len = CRYPTO_REG_SIZE * 4;
1531 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_nonce_info);
1532 pscmd++;
1533
1534 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1535
1536 pce_dev->ce_dm.cmdlist.reset_auth_key = pscmd;
1537 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1538 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1539 pscmd->len = CRYPTO_REG_SIZE * 16;
1540 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1541 pscmd++;
1542
1543 pce_dev->ce_dm.cmdlist.reset_auth_iv = pscmd;
1544 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1545 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1546 pscmd->len = CRYPTO_REG_SIZE * 16;
1547 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1548 pscmd++;
1549
1550 pce_dev->ce_dm.cmdlist.reset_auth_cfg = pscmd;
1551 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1552 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1553 pscmd->len = CRYPTO_REG_SIZE;
1554 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1555 pscmd++;
1556
1557
1558 pce_dev->ce_dm.cmdlist.reset_auth_byte_count = pscmd;
1559 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1560 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1561 pce_dev->phy_iobase);
1562 pscmd->len = CRYPTO_REG_SIZE * 4;
1563 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1564 pscmd++;
1565
1566 /* WAIT UNTIL MAC OP IS DONE*/
1567
1568 pce_dev->ce_dm.cmdlist.get_status_wait = pscmd;
1569 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1570 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1571 pscmd->len = CRYPTO_REG_SIZE;
1572 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1573 pscmd++;
1574
1575 *pvaddr = (unsigned char *) pscmd;
1576
1577 return 0;
1578}
1579
1580static int qce_setup_cmdlists(struct qce_device *pce_dev,
1581 unsigned char **pvaddr)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001582{
1583 dmov_sg *pcmd;
Mona Hossain3b574d82011-09-01 15:02:01 -07001584 dmov_s *pscmd;
1585 unsigned char *vaddr = *pvaddr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001586 struct dmov_desc *pdesc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001587 int i = 0;
1588
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001589 /*
Mona Hossain3b574d82011-09-01 15:02:01 -07001590 * Designate chunks of the allocated memory to various
1591 * command list pointers related to operation define
1592 * in ce_cmdlists structure.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001593 */
Mona Hossain3b574d82011-09-01 15:02:01 -07001594 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
1595 *pvaddr = (unsigned char *) vaddr;
1596
1597 _setup_cipher_cmdlists(pce_dev, pvaddr);
1598 _setup_auth_cmdlists(pce_dev, pvaddr);
1599
1600 pscmd = (dmov_s *)(*pvaddr);
1601
1602 /* GET HW VERSION COMMAND LIST */
1603 pce_dev->ce_dm.cmdlist.get_hw_version = pscmd;
1604 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1605 pscmd->src = (unsigned) (CRYPTO_VERSION_REG + pce_dev->phy_iobase);
1606 pscmd->len = CRYPTO_REG_SIZE;
1607 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.version);
1608 pscmd++;
1609
1610
1611 /* SET SEG SIZE REGISTER and OCB COMMAND LIST */
1612 pce_dev->ce_dm.cmdlist.set_seg_size_ocb = pscmd;
1613 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1614 pscmd->dst = (unsigned) (CRYPTO_SEG_SIZE_REG + pce_dev->phy_iobase);
1615 pscmd->len = CRYPTO_REG_SIZE;
1616 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.seg_size);
1617 pscmd++;
1618
1619
1620 /* OCU COMMAND LIST */
1621 pce_dev->ce_dm.cmdlist.get_status_ocu = pscmd;
1622 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCU;
1623 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1624 pscmd->len = CRYPTO_REG_SIZE;
1625 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1626 pscmd++;
1627
Mona Hossainb8db7432011-11-17 12:33:24 -08001628 /* CLEAR STATUS COMMAND LIST */
1629 pce_dev->ce_dm.cmdlist.clear_status = pscmd;
1630 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCU;
1631 pscmd->dst = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1632 pscmd->len = CRYPTO_REG_SIZE;
1633 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1634 pscmd++;
1635
Mona Hossain3b574d82011-09-01 15:02:01 -07001636 /* SET GO_PROC REGISTERS COMMAND LIST */
1637 pce_dev->ce_dm.cmdlist.set_go_proc = pscmd;
1638 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1639 pscmd->dst = (unsigned) (CRYPTO_GOPROC_REG + pce_dev->phy_iobase);
1640 pscmd->len = CRYPTO_REG_SIZE;
1641 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.go_proc);
1642 pscmd++;
1643
1644 pcmd = (dmov_sg *)pscmd;
1645 pce_dev->ce_dm.cmdlist.ce_data_in = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001646 /* swap byte and half word , dst crci , scatter gather */
1647 pcmd->cmd = CMD_DST_SWAP_BYTES | CMD_DST_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001648 CMD_DST_CRCI(pce_dev->ce_dm.crci_in) | CMD_MODE_SG;
1649
1650 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001651 pdesc->addr = 0; /* to be filled in each operation */
1652 pdesc->len = 0; /* to be filled in each operation */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001653
Mona Hossain3b574d82011-09-01 15:02:01 -07001654 pdesc = pce_dev->ce_dm.ce_in_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001655 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1656 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1657 pdesc->len = 0; /* to be filled in each operation */
1658 pdesc++;
1659 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001660 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_src_desc);
1661 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001662 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1663 DST_INDEX_SG_CMD(0);
Mona Hossain3b574d82011-09-01 15:02:01 -07001664
1665
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001666 pcmd++;
Mona Hossain3b574d82011-09-01 15:02:01 -07001667 pce_dev->ce_dm.cmdlist.ce_data_out = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001668 /* swap byte, half word, source crci, scatter gather */
1669 pcmd->cmd = CMD_SRC_SWAP_BYTES | CMD_SRC_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001670 CMD_SRC_CRCI(pce_dev->ce_dm.crci_out) | CMD_MODE_SG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001671
Mona Hossain3b574d82011-09-01 15:02:01 -07001672 pdesc = pce_dev->ce_dm.ce_out_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001673 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1674 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1675 pdesc->len = 0; /* to be filled in each operation */
1676 pdesc++;
1677 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001678
Mona Hossain3b574d82011-09-01 15:02:01 -07001679 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001680 pdesc->addr = 0; /* to be filled in each operation */
1681 pdesc->len = 0; /* to be filled in each operation */
Mona Hossain3b574d82011-09-01 15:02:01 -07001682
1683 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_src_desc);
1684 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001685 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1686 DST_INDEX_SG_CMD(0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001687 pcmd++;
1688
Mona Hossain3b574d82011-09-01 15:02:01 -07001689 *pvaddr = (unsigned char *) pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001690
1691 return 0;
Mona Hossain3b574d82011-09-01 15:02:01 -07001692}
1693
1694static int _setup_cipher_cmdptrlists(struct qce_device *pce_dev,
1695 unsigned char **pvaddr)
1696{
1697 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1698 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1699 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1700
1701 /*
1702 * Designate chunks of the allocated memory to various
1703 * command list pointers related to cipher operations defined
1704 * in ce_cmdptrlists_ops structure.
1705 */
1706 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1707 cmdptrlist->cipher_aes_128_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1708
1709 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1710 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1711 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1712 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1713 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1714 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1715 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001716 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001717
1718 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1719 cmdptrlist->cipher_aes_256_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1720
1721 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1722 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1723 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1724 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1725 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1726 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1727 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001728 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001729
1730 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1731 cmdptrlist->cipher_aes_128_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1732
1733 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1734 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1735 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1736 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1737 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1738 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1739 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1740
1741 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1742 cmdptrlist->cipher_aes_256_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1743
1744 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1745 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1746 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1747 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1748 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1749 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1750 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1751
1752 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1753 cmdptrlist->cipher_aes_128_xts = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1754
1755 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1756 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1757 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1758 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_xts_key);
1759 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1760 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1761 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
1762 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1763 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001764 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001765
1766 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1767 cmdptrlist->cipher_aes_256_xts = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1768
1769 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1770 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1771 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1772 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_xts_key);
1773 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1774 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1775 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
1776 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1777 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001778 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001779
1780 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1781 cmdptrlist->cipher_des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1782
1783 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1784 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1785 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1786 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1787 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1788 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001789 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001790
1791 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1792 cmdptrlist->cipher_des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1793
1794 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1795 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1796 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1797 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1798 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1799 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1800
1801 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1802 cmdptrlist->cipher_3des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1803
1804 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1805 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1806 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1807 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1808 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1809 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001810 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001811
1812 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1813 cmdptrlist->cipher_3des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1814
1815 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1816 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1817 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1818 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1819 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1820 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1821
1822 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1823 cmdptrlist->cipher_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1824
1825 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1826 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
Mona Hossainb8db7432011-11-17 12:33:24 -08001827
1828 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1829 cmdptrlist->cipher_ce_out_get_iv = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1830
1831 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1832 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_cipher_iv);
1833 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1834
Mona Hossain3b574d82011-09-01 15:02:01 -07001835 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1836
1837 return 0;
1838}
1839
1840static int _setup_auth_cmdptrlists(struct qce_device *pce_dev,
1841 unsigned char **pvaddr)
1842{
1843 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1844 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1845 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1846
1847 /*
1848 * Designate chunks of the allocated memory to various
1849 * command list pointers related to authentication operations
1850 * defined in ce_cmdptrlists_ops structure.
1851 */
1852 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1853 cmdptrlist->auth_sha1 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1854
1855 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1856 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1857 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1858 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1859 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1860 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1861 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1862 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1863 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1864 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1865 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1866 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1867
1868 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1869 cmdptrlist->auth_sha256 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1870
1871 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1872 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1873 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1874 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1875 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1876 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1877 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1878 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1879 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1880 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1881 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1882 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1883
1884 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1885 cmdptrlist->auth_sha1_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1886
1887 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1888 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1889 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1890 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1891 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1892 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1893 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1894 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1895 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1896 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1897 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1898 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1899 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1900
1901 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1902 cmdptrlist->auth_sha256_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1903
1904 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1905 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1906 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1907 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1908 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1909 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1910 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1911 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1912 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1913 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1914 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1915 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1916 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1917
1918 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1919 cmdptrlist->auth_aes_128_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1920
1921 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1922 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1923 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1924 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1925 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1926 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1927 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1928 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1929 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1930 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1931 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1932 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1933 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1934 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1935
1936 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1937 cmdptrlist->auth_aes_256_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1938
1939 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1940 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1941 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1942 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1943 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1944 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1945 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1946 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1947 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1948 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1949 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1950 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1951 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1952 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1953
1954 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1955
1956 return 0;
1957}
1958
1959static int _setup_aead_cmdptrlists(struct qce_device *pce_dev,
1960 unsigned char **pvaddr)
1961{
1962 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1963 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1964 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1965
1966 /*
1967 * Designate chunks of the allocated memory to various
1968 * command list pointers related to aead operations
1969 * defined in ce_cmdptrlists_ops structure.
1970 */
1971 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1972 cmdptrlist->aead_aes_128_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1973
1974 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1975 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1976 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1977 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1978 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1979 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1980 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1981 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1982 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1983 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1984 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1985 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1986 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1987
1988 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1989 cmdptrlist->aead_aes_256_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1990
1991 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1992 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1993 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1994 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1995 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1996 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1997 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1998 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1999 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
2000 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
2001 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
2002 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
2003 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
2004
2005 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
2006 cmdptrlist->aead_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
2007
2008 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
2009 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
2010 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
2011 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
2012
2013 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
2014
2015 return 0;
2016}
2017
2018static int qce_setup_cmdptrlists(struct qce_device *pce_dev,
2019 unsigned char **pvaddr)
2020{
2021 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
2022 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
2023 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
2024 /*
2025 * Designate chunks of the allocated memory to various
2026 * command list pointers related to operations defined
2027 * in ce_cmdptrlists_ops structure.
2028 */
2029 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
2030 cmdptrlist->probe_ce_hw = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
2031
2032 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_hw_version);
Mona Hossainb8db7432011-11-17 12:33:24 -08002033 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->clear_status);
Mona Hossain3b574d82011-09-01 15:02:01 -07002034 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
2035
2036 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
2037
2038 _setup_cipher_cmdptrlists(pce_dev, pvaddr);
2039 _setup_auth_cmdptrlists(pce_dev, pvaddr);
2040 _setup_aead_cmdptrlists(pce_dev, pvaddr);
2041
2042 return 0;
2043}
2044
2045
2046static int qce_setup_ce_dm_data(struct qce_device *pce_dev)
2047{
2048 unsigned char *vaddr;
2049
2050 /* 1. ce_in channel data xfer command src descriptors, 128 entries */
2051 vaddr = pce_dev->coh_vmem;
2052 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2053 pce_dev->ce_dm.ce_in_src_desc = (struct dmov_desc *) vaddr;
2054 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2055
2056 /* 2. ce_in channel data xfer command dst descriptors, 128 entries */
2057 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2058 pce_dev->ce_dm.ce_in_dst_desc = (struct dmov_desc *) vaddr;
2059 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2060
2061
2062 /* 3. ce_out channel data xfer command src descriptors, 128 entries */
2063 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2064 pce_dev->ce_dm.ce_out_src_desc = (struct dmov_desc *) vaddr;
2065 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2066
2067 /* 4. ce_out channel data xfer command dst descriptors, 128 entries. */
2068 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2069 pce_dev->ce_dm.ce_out_dst_desc = (struct dmov_desc *) vaddr;
2070 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2071
2072 qce_setup_cmd_buffers(pce_dev, &vaddr);
2073 qce_setup_cmdlists(pce_dev, &vaddr);
2074 qce_setup_cmdptrlists(pce_dev, &vaddr);
2075
2076 pce_dev->ce_dm.buffer.ignore_data = vaddr;
2077
2078 pce_dev->ce_dm.phy_ce_pad = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.pad);
2079 pce_dev->ce_dm.phy_ce_out_ignore =
2080 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.ignore_data);
2081
2082 pce_dev->ce_dm.chan_ce_in_cmd->user = (void *) pce_dev;
2083 pce_dev->ce_dm.chan_ce_in_cmd->exec_func = NULL;
2084
2085 pce_dev->ce_dm.chan_ce_out_cmd->user = (void *) pce_dev;
2086 pce_dev->ce_dm.chan_ce_out_cmd->exec_func = NULL;
2087
2088 return 0;
2089}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002090
2091static int _qce_start_dma(struct qce_device *pce_dev, bool ce_in, bool ce_out)
2092{
2093
2094 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002095 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002096 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002097 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002098
2099 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002100 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002101 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002102 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002103
2104 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002105 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
2106 pce_dev->ce_dm.chan_ce_in_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002107 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002108 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_out,
2109 pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002110
2111 return 0;
2112};
2113
2114int qce_aead_req(void *handle, struct qce_req *q_req)
2115{
2116 struct qce_device *pce_dev = (struct qce_device *) handle;
2117 struct aead_request *areq = (struct aead_request *) q_req->areq;
2118 uint32_t authsize = q_req->authsize;
2119 uint32_t totallen_in, totallen_out, out_len;
2120 uint32_t pad_len_in, pad_len_out;
2121 uint32_t pad_mac_len_out, pad_ptx_len_out;
2122 int rc = 0;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002123 int ce_block_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002124
Mona Hossain5f5dde12011-09-12 10:28:34 -07002125 ce_block_size = pce_dev->ce_dm.ce_block_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002126 if (q_req->dir == QCE_ENCRYPT) {
2127 q_req->cryptlen = areq->cryptlen;
2128 totallen_in = q_req->cryptlen + areq->assoclen;
2129 totallen_out = q_req->cryptlen + authsize + areq->assoclen;
2130 out_len = areq->cryptlen + authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002131 pad_len_in = ALIGN(totallen_in, ce_block_size) - totallen_in;
2132 pad_mac_len_out = ALIGN(authsize, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002133 authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002134 pad_ptx_len_out = ALIGN(q_req->cryptlen, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002135 q_req->cryptlen;
2136 pad_len_out = pad_ptx_len_out + pad_mac_len_out;
2137 totallen_out += pad_len_out;
2138 } else {
2139 q_req->cryptlen = areq->cryptlen - authsize;
2140 totallen_in = areq->cryptlen + areq->assoclen;
2141 totallen_out = q_req->cryptlen + areq->assoclen;
2142 out_len = areq->cryptlen - authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002143 pad_len_in = ALIGN(areq->cryptlen, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002144 areq->cryptlen;
2145 pad_len_out = pad_len_in + authsize;
2146 totallen_out += pad_len_out;
2147 }
2148
2149 _chain_buffer_in_init(pce_dev);
2150 _chain_buffer_out_init(pce_dev);
2151
2152 pce_dev->assoc_nents = 0;
2153 pce_dev->src_nents = 0;
2154 pce_dev->dst_nents = 0;
2155 pce_dev->ivsize = q_req->ivsize;
2156 pce_dev->authsize = q_req->authsize;
2157
2158 /* associated data input */
2159 pce_dev->assoc_nents = count_sg(areq->assoc, areq->assoclen);
2160 dma_map_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
2161 DMA_TO_DEVICE);
2162 if (_chain_sg_buffer_in(pce_dev, areq->assoc, areq->assoclen) < 0) {
2163 rc = -ENOMEM;
2164 goto bad;
2165 }
2166 /* cipher input */
2167 pce_dev->src_nents = count_sg(areq->src, areq->cryptlen);
2168 dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2169 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2170 DMA_TO_DEVICE);
2171 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->cryptlen) < 0) {
2172 rc = -ENOMEM;
2173 goto bad;
2174 }
2175 /* pad data in */
2176 if (pad_len_in) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002177 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002178 pad_len_in) < 0) {
2179 rc = -ENOMEM;
2180 goto bad;
2181 }
2182 }
2183
2184 /* ignore associated data */
Mona Hossain3b574d82011-09-01 15:02:01 -07002185 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_out_ignore,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002186 areq->assoclen) < 0) {
2187 rc = -ENOMEM;
2188 goto bad;
2189 }
2190 /* cipher + mac output for encryption */
2191 if (areq->src != areq->dst) {
2192 pce_dev->dst_nents = count_sg(areq->dst, out_len);
2193 dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2194 DMA_FROM_DEVICE);
2195 };
2196 if (_chain_sg_buffer_out(pce_dev, areq->dst, out_len) < 0) {
2197 rc = -ENOMEM;
2198 goto bad;
2199 }
2200 /* pad data out */
2201 if (pad_len_out) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002202 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002203 pad_len_out) < 0) {
2204 rc = -ENOMEM;
2205 goto bad;
2206 }
2207 }
2208
2209 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain5f5dde12011-09-12 10:28:34 -07002210 _ce_in_final(pce_dev, ALIGN(totallen_in, ce_block_size));
2211 _ce_out_final(pce_dev, ALIGN(totallen_out, ce_block_size));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002212
2213 /* set up crypto device */
2214 rc = _ce_setup_cipher(pce_dev, q_req, totallen_in, areq->assoclen);
2215 if (rc < 0)
2216 goto bad;
2217
2218 /* setup for callback, and issue command to adm */
2219 pce_dev->areq = q_req->areq;
2220 pce_dev->qce_cb = q_req->qce_cb;
2221
Mona Hossain3b574d82011-09-01 15:02:01 -07002222 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _aead_ce_in_call_back;
2223 pce_dev->ce_dm.chan_ce_out_cmd->complete_func = _aead_ce_out_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002224
2225 _ce_in_dump(pce_dev);
2226 _ce_out_dump(pce_dev);
2227
2228 rc = _qce_start_dma(pce_dev, true, true);
2229 if (rc == 0)
2230 return 0;
2231bad:
2232 if (pce_dev->assoc_nents) {
2233 dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
2234 DMA_TO_DEVICE);
2235 }
2236
2237 if (pce_dev->src_nents) {
2238 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2239 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2240 DMA_TO_DEVICE);
2241 }
2242 if (pce_dev->dst_nents) {
2243 dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2244 DMA_FROM_DEVICE);
2245 }
2246 return rc;
2247}
2248EXPORT_SYMBOL(qce_aead_req);
2249
2250int qce_ablk_cipher_req(void *handle, struct qce_req *c_req)
2251{
2252 int rc = 0;
2253 struct qce_device *pce_dev = (struct qce_device *) handle;
2254 struct ablkcipher_request *areq = (struct ablkcipher_request *)
2255 c_req->areq;
2256
Mona Hossain5f5dde12011-09-12 10:28:34 -07002257 uint32_t pad_len = ALIGN(areq->nbytes, pce_dev->ce_dm.ce_block_size)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002258 - areq->nbytes;
2259
2260 _chain_buffer_in_init(pce_dev);
2261 _chain_buffer_out_init(pce_dev);
2262
2263 pce_dev->src_nents = 0;
2264 pce_dev->dst_nents = 0;
2265
2266 /* cipher input */
2267 pce_dev->src_nents = count_sg(areq->src, areq->nbytes);
2268
2269 if (c_req->use_pmem != 1)
2270 dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2271 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2272 DMA_TO_DEVICE);
2273 else
2274 dma_map_pmem_sg(&c_req->pmem->src[0], pce_dev->src_nents,
2275 areq->src);
2276
2277 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->nbytes) < 0) {
2278 rc = -ENOMEM;
2279 goto bad;
2280 }
2281
2282 /* cipher output */
2283 if (areq->src != areq->dst) {
2284 pce_dev->dst_nents = count_sg(areq->dst, areq->nbytes);
2285 if (c_req->use_pmem != 1)
2286 dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2287 DMA_FROM_DEVICE);
2288 else
2289 dma_map_pmem_sg(&c_req->pmem->dst[0],
2290 pce_dev->dst_nents, areq->dst);
2291 };
2292 if (_chain_sg_buffer_out(pce_dev, areq->dst, areq->nbytes) < 0) {
2293 rc = -ENOMEM;
2294 goto bad;
2295 }
2296
2297 /* pad data */
2298 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002299 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002300 pad_len) < 0) {
2301 rc = -ENOMEM;
2302 goto bad;
2303 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002304 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002305 pad_len) < 0) {
2306 rc = -ENOMEM;
2307 goto bad;
2308 }
2309 }
2310
2311 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain2563cbc2011-09-14 15:24:08 -07002312 _ce_in_final(pce_dev, areq->nbytes + pad_len);
2313 _ce_out_final(pce_dev, areq->nbytes + pad_len);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002314
2315 _ce_in_dump(pce_dev);
2316 _ce_out_dump(pce_dev);
2317
2318 /* set up crypto device */
2319 rc = _ce_setup_cipher(pce_dev, c_req, areq->nbytes, 0);
2320 if (rc < 0)
2321 goto bad;
2322
2323 /* setup for callback, and issue command to adm */
2324 pce_dev->areq = areq;
2325 pce_dev->qce_cb = c_req->qce_cb;
2326 if (c_req->use_pmem == 1) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002327 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002328 _ablk_cipher_ce_in_call_back_pmem;
Mona Hossain3b574d82011-09-01 15:02:01 -07002329 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002330 _ablk_cipher_ce_out_call_back_pmem;
2331 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07002332 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002333 _ablk_cipher_ce_in_call_back;
Mona Hossain3b574d82011-09-01 15:02:01 -07002334 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002335 _ablk_cipher_ce_out_call_back;
2336 }
2337 rc = _qce_start_dma(pce_dev, true, true);
2338
2339 if (rc == 0)
2340 return 0;
2341bad:
2342 if (c_req->use_pmem != 1) {
2343 if (pce_dev->dst_nents) {
2344 dma_unmap_sg(pce_dev->pdev, areq->dst,
2345 pce_dev->dst_nents, DMA_FROM_DEVICE);
2346 }
2347 if (pce_dev->src_nents) {
2348 dma_unmap_sg(pce_dev->pdev, areq->src,
2349 pce_dev->src_nents,
2350 (areq->src == areq->dst) ?
2351 DMA_BIDIRECTIONAL :
2352 DMA_TO_DEVICE);
2353 }
2354 }
2355 return rc;
2356}
2357EXPORT_SYMBOL(qce_ablk_cipher_req);
2358
2359int qce_process_sha_req(void *handle, struct qce_sha_req *sreq)
2360{
2361 struct qce_device *pce_dev = (struct qce_device *) handle;
2362 int rc;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002363 uint32_t pad_len = ALIGN(sreq->size, pce_dev->ce_dm.ce_block_size) -
2364 sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002365 struct ahash_request *areq = (struct ahash_request *)sreq->areq;
2366
2367 _chain_buffer_in_init(pce_dev);
2368 pce_dev->src_nents = count_sg(sreq->src, sreq->size);
2369 dma_map_sg(pce_dev->pdev, sreq->src, pce_dev->src_nents,
2370 DMA_TO_DEVICE);
2371
2372 if (_chain_sg_buffer_in(pce_dev, sreq->src, sreq->size) < 0) {
2373 rc = -ENOMEM;
2374 goto bad;
2375 }
2376
2377 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002378 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002379 pad_len) < 0) {
2380 rc = -ENOMEM;
2381 goto bad;
2382 }
2383 }
Mona Hossain2563cbc2011-09-14 15:24:08 -07002384 _ce_in_final(pce_dev, sreq->size + pad_len);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002385
2386 _ce_in_dump(pce_dev);
2387
Mona Hossain3b574d82011-09-01 15:02:01 -07002388 rc = _ce_setup_hash(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002389
2390 if (rc < 0)
2391 goto bad;
2392
2393 pce_dev->areq = areq;
2394 pce_dev->qce_cb = sreq->qce_cb;
Mona Hossain3b574d82011-09-01 15:02:01 -07002395 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _sha_ce_in_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002396
2397 rc = _qce_start_dma(pce_dev, true, false);
2398
2399 if (rc == 0)
2400 return 0;
2401bad:
2402 if (pce_dev->src_nents) {
2403 dma_unmap_sg(pce_dev->pdev, sreq->src,
2404 pce_dev->src_nents, DMA_TO_DEVICE);
2405 }
2406
2407 return rc;
2408}
2409EXPORT_SYMBOL(qce_process_sha_req);
2410
2411/* crypto engine open function. */
2412void *qce_open(struct platform_device *pdev, int *rc)
2413{
2414 struct qce_device *pce_dev;
2415 struct resource *resource;
2416 struct clk *ce_core_clk;
2417 struct clk *ce_clk;
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002418 struct clk *ce_core_src_clk;
2419 int ret = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002420
2421 pce_dev = kzalloc(sizeof(struct qce_device), GFP_KERNEL);
2422 if (!pce_dev) {
2423 *rc = -ENOMEM;
2424 dev_err(&pdev->dev, "Can not allocate memory\n");
2425 return NULL;
2426 }
2427 pce_dev->pdev = &pdev->dev;
2428
2429 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2430 if (!resource) {
2431 *rc = -ENXIO;
2432 dev_err(pce_dev->pdev, "Missing MEM resource\n");
2433 goto err_pce_dev;
2434 };
2435 pce_dev->phy_iobase = resource->start;
2436 pce_dev->iobase = ioremap_nocache(resource->start,
2437 resource->end - resource->start + 1);
2438 if (!pce_dev->iobase) {
2439 *rc = -ENOMEM;
2440 dev_err(pce_dev->pdev, "Can not map io memory\n");
2441 goto err_pce_dev;
2442 }
2443
Mona Hossain3b574d82011-09-01 15:02:01 -07002444 pce_dev->ce_dm.chan_ce_in_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002445 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002446 pce_dev->ce_dm.chan_ce_out_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002447 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002448 if (pce_dev->ce_dm.chan_ce_in_cmd == NULL ||
2449 pce_dev->ce_dm.chan_ce_out_cmd == NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002450 dev_err(pce_dev->pdev, "Can not allocate memory\n");
2451 *rc = -ENOMEM;
2452 goto err_dm_chan_cmd;
2453 }
2454
2455 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2456 "crypto_channels");
2457 if (!resource) {
2458 *rc = -ENXIO;
2459 dev_err(pce_dev->pdev, "Missing DMA channel resource\n");
2460 goto err_dm_chan_cmd;
2461 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002462 pce_dev->ce_dm.chan_ce_in = resource->start;
2463 pce_dev->ce_dm.chan_ce_out = resource->end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002464 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2465 "crypto_crci_in");
2466 if (!resource) {
2467 *rc = -ENXIO;
2468 dev_err(pce_dev->pdev, "Missing DMA crci in resource\n");
2469 goto err_dm_chan_cmd;
2470 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002471 pce_dev->ce_dm.crci_in = resource->start;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002472 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2473 "crypto_crci_out");
2474 if (!resource) {
2475 *rc = -ENXIO;
2476 dev_err(pce_dev->pdev, "Missing DMA crci out resource\n");
2477 goto err_dm_chan_cmd;
2478 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002479 pce_dev->ce_dm.crci_out = resource->start;
2480 pce_dev->memsize = 2 * PAGE_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002481 pce_dev->coh_vmem = dma_alloc_coherent(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -07002482 pce_dev->memsize, &pce_dev->coh_pmem, GFP_KERNEL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002483
2484 if (pce_dev->coh_vmem == NULL) {
2485 *rc = -ENOMEM;
2486 dev_err(pce_dev->pdev, "Can not allocate coherent memory.\n");
2487 goto err;
2488 }
2489
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002490 /* Get CE3 src core clk. */
2491 ce_core_src_clk = clk_get(pce_dev->pdev, "ce3_core_src_clk");
2492 if (!IS_ERR(ce_core_src_clk)) {
2493 pce_dev->ce_core_src_clk = ce_core_src_clk;
2494
2495 /* Set the core src clk @100Mhz */
2496 ret = clk_set_rate(pce_dev->ce_core_src_clk, 100000000);
2497 if (ret) {
2498 clk_put(pce_dev->ce_core_src_clk);
2499 goto err;
2500 }
2501 } else
2502 pce_dev->ce_core_src_clk = NULL;
2503
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002504 /* Get CE core clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002505 ce_core_clk = clk_get(pce_dev->pdev, "core_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002506 if (IS_ERR(ce_core_clk)) {
2507 *rc = PTR_ERR(ce_core_clk);
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002508 if (pce_dev->ce_core_src_clk != NULL)
2509 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002510 goto err;
2511 }
2512 pce_dev->ce_core_clk = ce_core_clk;
2513 /* Get CE clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002514 ce_clk = clk_get(pce_dev->pdev, "iface_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002515 if (IS_ERR(ce_clk)) {
2516 *rc = PTR_ERR(ce_clk);
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002517 if (pce_dev->ce_core_src_clk != NULL)
2518 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002519 clk_put(pce_dev->ce_core_clk);
2520 goto err;
2521 }
2522 pce_dev->ce_clk = ce_clk;
2523
2524 /* Enable CE core clk */
2525 *rc = clk_enable(pce_dev->ce_core_clk);
2526 if (*rc) {
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002527 if (pce_dev->ce_core_src_clk != NULL)
2528 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002529 clk_put(pce_dev->ce_core_clk);
2530 clk_put(pce_dev->ce_clk);
2531 goto err;
2532 } else {
2533 /* Enable CE clk */
2534 *rc = clk_enable(pce_dev->ce_clk);
2535 if (*rc) {
2536 clk_disable(pce_dev->ce_core_clk);
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002537 if (pce_dev->ce_core_src_clk != NULL)
2538 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002539 clk_put(pce_dev->ce_core_clk);
2540 clk_put(pce_dev->ce_clk);
2541 goto err;
2542
2543 }
2544 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002545 qce_setup_ce_dm_data(pce_dev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002546
Mona Hossain3b574d82011-09-01 15:02:01 -07002547 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
2548 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002549 if (_init_ce_engine(pce_dev)) {
2550 *rc = -ENXIO;
2551 goto err;
2552 }
2553 *rc = 0;
2554 return pce_dev;
2555
2556err:
2557 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002558 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
Mona Hossaine1b13f82011-08-30 09:35:49 -07002559 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002560err_dm_chan_cmd:
Mona Hossain3b574d82011-09-01 15:02:01 -07002561 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2562 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002563 if (pce_dev->iobase)
2564 iounmap(pce_dev->iobase);
2565
2566err_pce_dev:
2567
2568 kfree(pce_dev);
2569
2570 return NULL;
2571}
2572EXPORT_SYMBOL(qce_open);
2573
2574/* crypto engine close function. */
2575int qce_close(void *handle)
2576{
2577 struct qce_device *pce_dev = (struct qce_device *) handle;
2578
2579 if (handle == NULL)
2580 return -ENODEV;
2581 if (pce_dev->iobase)
2582 iounmap(pce_dev->iobase);
2583
2584 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002585 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
2586 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002587 clk_disable(pce_dev->ce_clk);
2588 clk_disable(pce_dev->ce_core_clk);
2589
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002590 if (pce_dev->ce_core_src_clk != NULL)
2591 clk_put(pce_dev->ce_core_src_clk);
2592
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002593 clk_put(pce_dev->ce_clk);
2594 clk_put(pce_dev->ce_core_clk);
2595
Mona Hossain3b574d82011-09-01 15:02:01 -07002596 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2597 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002598 kfree(handle);
2599
2600 return 0;
2601}
2602EXPORT_SYMBOL(qce_close);
2603
2604int qce_hw_support(void *handle, struct ce_hw_support *ce_support)
2605{
2606 if (ce_support == NULL)
2607 return -EINVAL;
2608
2609 ce_support->sha1_hmac_20 = false;
2610 ce_support->sha1_hmac = false;
2611 ce_support->sha256_hmac = false;
2612 ce_support->sha_hmac = false;
2613 ce_support->cmac = true;
2614 ce_support->aes_key_192 = false;
2615 ce_support->aes_xts = true;
2616 ce_support->aes_ccm = true;
2617 ce_support->ota = false;
2618 return 0;
2619}
2620EXPORT_SYMBOL(qce_hw_support);
2621
2622MODULE_LICENSE("GPL v2");
2623MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
2624MODULE_DESCRIPTION("Crypto Engine driver");
Ramesh Masavarapu9e1c0a02012-02-07 08:56:40 -08002625MODULE_VERSION("2.15");