blob: d725851f6b4d81a0b217c820322266bacf5941b2 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Qualcomm Crypto Engine driver.
2 *
3 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 and
7 * only version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#include <linux/types.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/mod_devicetable.h>
18#include <linux/device.h>
19#include <linux/clk.h>
20#include <linux/err.h>
21#include <linux/dma-mapping.h>
22#include <linux/io.h>
23#include <linux/platform_device.h>
24#include <linux/spinlock.h>
25#include <linux/delay.h>
26#include <linux/crypto.h>
Mona Hossain5c8ea1f2011-07-28 15:11:29 -070027#include <linux/qcedev.h>
Ramesh Masavarapu72077202011-11-02 10:34:26 -070028#include <linux/bitops.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070029#include <crypto/hash.h>
30#include <crypto/sha.h>
31#include <mach/dma.h>
32#include <mach/clk.h>
Ramesh Masavarapufa679d92011-10-13 23:42:59 -070033#include <mach/socinfo.h>
Mona Hossain5c8ea1f2011-07-28 15:11:29 -070034
35#include "qce.h"
Mona Hossain3b574d82011-09-01 15:02:01 -070036#include "qce40.h"
Mona Hossain5c8ea1f2011-07-28 15:11:29 -070037#include "qcryptohw_40.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070038
39/* ADM definitions */
40#define LI_SG_CMD (1 << 31) /* last index in the scatter gather cmd */
41#define SRC_INDEX_SG_CMD(index) ((index & 0x3fff) << 16)
42#define DST_INDEX_SG_CMD(index) (index & 0x3fff)
43#define ADM_DESC_LAST (1 << 31)
Mona Hossain3b574d82011-09-01 15:02:01 -070044#define QCE_FIFO_SIZE 0x8000
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070045/*
46 * CE HW device structure.
47 * Each engine has an instance of the structure.
48 * Each engine can only handle one crypto operation at one time. It is up to
49 * the sw above to ensure single threading of operation on an engine.
50 */
51struct qce_device {
52 struct device *pdev; /* Handle to platform_device structure */
Mona Hossain3b574d82011-09-01 15:02:01 -070053
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070054 unsigned char *coh_vmem; /* Allocated coherent virtual memory */
55 dma_addr_t coh_pmem; /* Allocated coherent physical memory */
Mona Hossain3b574d82011-09-01 15:02:01 -070056 int memsize; /* Memory allocated */
57
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070058 void __iomem *iobase; /* Virtual io base of CE HW */
59 unsigned int phy_iobase; /* Physical io base of CE HW */
Mona Hossain3b574d82011-09-01 15:02:01 -070060
Ramesh Masavarapu28311912011-10-27 11:04:12 -070061 struct clk *ce_core_src_clk; /* Handle to CE src clk*/
62 struct clk *ce_core_clk; /* Handle to CE clk */
63 struct clk *ce_clk; /* Handle to CE clk */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070064
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070065 qce_comp_func_ptr_t qce_cb; /* qce callback function pointer */
66
67 int assoc_nents;
68 int ivsize;
69 int authsize;
70 int src_nents;
71 int dst_nents;
72
73 void *areq;
74 enum qce_cipher_mode_enum mode;
Mona Hossain3b574d82011-09-01 15:02:01 -070075 struct ce_dm_data ce_dm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070076};
77
78/* Standard initialization vector for SHA-1, source: FIPS 180-2 */
Mona Hossain3b574d82011-09-01 15:02:01 -070079static uint8_t _std_init_vector_sha1_uint8[] = {
80 0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89,
81 0x98, 0xBA, 0xDC, 0xFE, 0x10, 0x32, 0x54, 0x76,
82 0xC3, 0xD2, 0xE1, 0xF0
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070083};
Mona Hossain3b574d82011-09-01 15:02:01 -070084
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070085/* Standard initialization vector for SHA-256, source: FIPS 180-2 */
Mona Hossain3b574d82011-09-01 15:02:01 -070086static uint8_t _std_init_vector_sha256_uint8[] = {
87 0x6A, 0x09, 0xE6, 0x67, 0xBB, 0x67, 0xAE, 0x85,
88 0x3C, 0x6E, 0xF3, 0x72, 0xA5, 0x4F, 0xF5, 0x3A,
89 0x51, 0x0E, 0x52, 0x7F, 0x9B, 0x05, 0x68, 0x8C,
90 0x1F, 0x83, 0xD9, 0xAB, 0x5B, 0xE0, 0xCD, 0x19
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070091};
92
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070093static void _byte_stream_swap_to_net_words(uint32_t *iv, unsigned char *b,
94 unsigned int len)
95{
96 unsigned i, j;
97 unsigned char swap_iv[AES_IV_LENGTH];
98
99 memset(swap_iv, 0, AES_IV_LENGTH);
100 for (i = (AES_IV_LENGTH-len), j = len-1; i < AES_IV_LENGTH; i++, j--)
101 swap_iv[i] = b[j];
Mona Hossain3b574d82011-09-01 15:02:01 -0700102 memcpy(iv, swap_iv, AES_IV_LENGTH);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700103}
104
105static int count_sg(struct scatterlist *sg, int nbytes)
106{
107 int i;
108
109 for (i = 0; nbytes > 0; i++, sg = sg_next(sg))
110 nbytes -= sg->length;
111 return i;
112}
113
114static int dma_map_pmem_sg(struct buf_info *pmem, unsigned entries,
115 struct scatterlist *sg)
116{
117 int i;
118 for (i = 0; i < entries; i++) {
119
120 sg->dma_address = (dma_addr_t)pmem->offset;
121 sg++;
122 pmem++;
123 }
124 return 0;
125}
126
127static int _probe_ce_engine(struct qce_device *pce_dev)
128{
129 unsigned int val;
130 unsigned int rev;
131
Mona Hossain3b574d82011-09-01 15:02:01 -0700132 val = (uint32_t)(*((uint32_t *)pce_dev->ce_dm.buffer.version));
Mona Hossain5f5dde12011-09-12 10:28:34 -0700133 if (((val & 0xfffffff) != 0x0000043) &&
134 ((val & 0xfffffff) != 0x0000042) &&
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700135 ((val & 0xfffffff) != 0x0000040)) {
136 dev_err(pce_dev->pdev,
137 "Unknown Qualcomm crypto device at 0x%x 0x%x\n",
138 pce_dev->phy_iobase, val);
139 return -EIO;
140 };
141 rev = (val & CRYPTO_CORE_REV_MASK);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700142 if (rev >= 0x42) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700143 dev_info(pce_dev->pdev,
144 "Qualcomm Crypto 4.2 device found at 0x%x\n",
145 pce_dev->phy_iobase);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700146 pce_dev->ce_dm.ce_block_size = 64;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700147 } else {
148 if (rev == 0x40) {
149 dev_info(pce_dev->pdev,
150 "Qualcomm Crypto 4.0 device found at 0x%x\n",
151 pce_dev->phy_iobase);
Mona Hossain5f5dde12011-09-12 10:28:34 -0700152 pce_dev->ce_dm.ce_block_size = 16;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700153 }
154 }
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700155 /*
156 * This is a temporary change - until Data Mover changes its
157 * configuration from 16 byte crci to 64 byte crci.
158 */
159 if (cpu_is_msm9615())
160 pce_dev->ce_dm.ce_block_size = 16;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700161
162 dev_info(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -0700163 "IO base 0x%x\n, ce_in channel %d , "
164 "ce_out channel %d\n, "
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700165 "crci_in %d, crci_out %d\n",
166 (unsigned int) pce_dev->iobase,
Mona Hossain3b574d82011-09-01 15:02:01 -0700167 pce_dev->ce_dm.chan_ce_in, pce_dev->ce_dm.chan_ce_out,
168 pce_dev->ce_dm.crci_in, pce_dev->ce_dm.crci_out);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700169
170 return 0;
171};
172
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700173static void config_ce_engine(struct qce_device *pce_dev)
174{
175 unsigned int val = 0;
Ramesh Masavarapu72077202011-11-02 10:34:26 -0700176 unsigned int ret = 0;
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700177
Ramesh Masavarapu72077202011-11-02 10:34:26 -0700178 /* Crypto config register returns a 0 when it is XPU protected. */
179 ret = readl_relaxed(pce_dev->iobase + CRYPTO_CONFIG_REG);
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700180
Ramesh Masavarapu72077202011-11-02 10:34:26 -0700181 /* Configure the crypto register if it is not XPU protected. */
182 if (ret) {
183 val = BIT(CRYPTO_MASK_DOUT_INTR) |
184 BIT(CRYPTO_MASK_DIN_INTR) |
185 BIT(CRYPTO_MASK_OP_DONE_INTR) |
186 BIT(CRYPTO_MASK_ERR_INTR);
187
188 writel_relaxed(val, pce_dev->iobase + CRYPTO_CONFIG_REG);
189 }
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700190}
Mona Hossain3b574d82011-09-01 15:02:01 -0700191
192static void _check_probe_done_call_back(struct msm_dmov_cmd *cmd_ptr,
193 unsigned int result, struct msm_dmov_errdata *err)
194{
195 struct qce_device *pce_dev;
196 pce_dev = (struct qce_device *) cmd_ptr->user;
197
198 if (result != ADM_STATUS_OK) {
199 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
200 result);
201 pce_dev->ce_dm.chan_ce_in_status = -1;
202 } else {
203 _probe_ce_engine(pce_dev);
204 pce_dev->ce_dm.chan_ce_in_status = 0;
205 }
206 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
207};
208
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700209static int _init_ce_engine(struct qce_device *pce_dev)
210{
Mona Hossainb8db7432011-11-17 12:33:24 -0800211 int status;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700212 /* Reset ce */
213 clk_reset(pce_dev->ce_core_clk, CLK_RESET_ASSERT);
214 clk_reset(pce_dev->ce_core_clk, CLK_RESET_DEASSERT);
Mona Hossain3b574d82011-09-01 15:02:01 -0700215
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700216 /*
217 * Ensure previous instruction (any writes to CLK registers)
218 * to toggle the CLK reset lines was completed before configuring
219 * ce engine. The ce engine configuration settings should not be lost
220 * becasue of clk reset.
221 */
222 mb();
223
224 /* Configure the CE Engine */
225 config_ce_engine(pce_dev);
226
227 /*
Mona Hossainb8db7432011-11-17 12:33:24 -0800228 * Clear ACCESS_VIOL bit in CRYPTO_STATUS REGISTER
229 */
230 status = readl_relaxed(pce_dev->iobase + CRYPTO_STATUS_REG);
231 *((uint32_t *)(pce_dev->ce_dm.buffer.status)) = status & (~0x40000);
232 /*
Ramesh Masavarapufa679d92011-10-13 23:42:59 -0700233 * Ensure ce configuration is completed.
234 */
235 mb();
236
Mona Hossain3b574d82011-09-01 15:02:01 -0700237 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
238 _check_probe_done_call_back;
239 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
240 pce_dev->ce_dm.cmdptrlist.probe_ce_hw;
241 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
242 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
243 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
244 pce_dev->ce_dm.chan_ce_in_cmd);
245
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700246 return 0;
247};
248
Mona Hossain3b574d82011-09-01 15:02:01 -0700249static int _ce_setup_hash_cmdrptrlist(struct qce_device *pce_dev,
250 struct qce_sha_req *sreq)
251{
252 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
253
254 switch (sreq->alg) {
255 case QCE_HASH_SHA1:
256 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr = cmdptrlist->auth_sha1;
257 break;
258
259 case QCE_HASH_SHA256:
260 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr = cmdptrlist->auth_sha256;
261 break;
262 case QCE_HASH_SHA1_HMAC:
263 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
264 cmdptrlist->auth_sha1_hmac;
265 break;
266
267 case QCE_HASH_SHA256_HMAC:
268 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
269 cmdptrlist->auth_sha256_hmac;
270 break;
271 case QCE_HASH_AES_CMAC:
272 if (sreq->authklen == AES128_KEY_SIZE)
273 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
274 cmdptrlist->auth_aes_128_cmac;
275 else
276 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
277 cmdptrlist->auth_aes_256_cmac;
278 break;
279
280 default:
281 break;
282 }
283
284 return 0;
285}
286
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700287static int _ce_setup_hash(struct qce_device *pce_dev, struct qce_sha_req *sreq)
288{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700289 uint32_t diglen;
290 int i;
291 uint32_t auth_cfg = 0;
292 bool sha1 = false;
293
294 if (sreq->alg == QCE_HASH_AES_CMAC) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700295
Mona Hossain3b574d82011-09-01 15:02:01 -0700296 memcpy(pce_dev->ce_dm.buffer.auth_key, sreq->authkey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700297 sreq->authklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700298 auth_cfg |= (1 << CRYPTO_LAST);
299 auth_cfg |= (CRYPTO_AUTH_MODE_CMAC << CRYPTO_AUTH_MODE);
300 auth_cfg |= (CRYPTO_AUTH_SIZE_ENUM_16_BYTES <<
301 CRYPTO_AUTH_SIZE);
302 auth_cfg |= CRYPTO_AUTH_ALG_AES << CRYPTO_AUTH_ALG;
303
304 switch (sreq->authklen) {
305 case AES128_KEY_SIZE:
306 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES128 <<
307 CRYPTO_AUTH_KEY_SIZE);
308 break;
309 case AES256_KEY_SIZE:
310 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES256 <<
311 CRYPTO_AUTH_KEY_SIZE);
312 break;
313 default:
314 break;
315 }
316
317 goto go_proc;
318 }
319
320 /* if not the last, the size has to be on the block boundary */
321 if (sreq->last_blk == 0 && (sreq->size % SHA256_BLOCK_SIZE))
322 return -EIO;
323
324 switch (sreq->alg) {
325 case QCE_HASH_SHA1:
326 case QCE_HASH_SHA1_HMAC:
327 diglen = SHA1_DIGEST_SIZE;
328 sha1 = true;
329 break;
330 case QCE_HASH_SHA256:
331 case QCE_HASH_SHA256_HMAC:
332 diglen = SHA256_DIGEST_SIZE;
333 break;
334 default:
335 return -EINVAL;
336 }
337
338 if ((sreq->alg == QCE_HASH_SHA1_HMAC) ||
339 (sreq->alg == QCE_HASH_SHA256_HMAC)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700340
Mona Hossain3b574d82011-09-01 15:02:01 -0700341 memcpy(pce_dev->ce_dm.buffer.auth_key, sreq->authkey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700342 sreq->authklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700343 auth_cfg |= (CRYPTO_AUTH_MODE_HMAC << CRYPTO_AUTH_MODE);
344 } else {
345 auth_cfg |= (CRYPTO_AUTH_MODE_HASH << CRYPTO_AUTH_MODE);
346 }
347
348 /* write 20/32 bytes, 5/8 words into auth_iv for SHA1/SHA256 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700349 if (sreq->first_blk) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700350 if (sha1)
351 memcpy(pce_dev->ce_dm.buffer.auth_iv,
352 _std_init_vector_sha1_uint8, diglen);
353 else
354 memcpy(pce_dev->ce_dm.buffer.auth_iv,
355 _std_init_vector_sha256_uint8, diglen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700356 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700357 memcpy(pce_dev->ce_dm.buffer.auth_iv, sreq->digest,
358 diglen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700359 }
360
Mona Hossain3b574d82011-09-01 15:02:01 -0700361 /* write auth_bytecnt 0/1/2/3, start with 0 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700362 for (i = 0; i < 4; i++)
Mona Hossain3b574d82011-09-01 15:02:01 -0700363 *(((uint32_t *)(pce_dev->ce_dm.buffer.auth_byte_count) + i)) =
364 sreq->auth_data[i];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700365
366 /* write seg_cfg */
367 if (sha1)
368 auth_cfg |= (CRYPTO_AUTH_SIZE_SHA1 << CRYPTO_AUTH_SIZE);
369 else
370 auth_cfg |= (CRYPTO_AUTH_SIZE_SHA256 << CRYPTO_AUTH_SIZE);
371
372 if (sreq->last_blk)
373 auth_cfg |= 1 << CRYPTO_LAST;
374
375 auth_cfg |= CRYPTO_AUTH_ALG_SHA << CRYPTO_AUTH_ALG;
376
377go_proc:
378 auth_cfg |= (CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);
379
Mona Hossain3b574d82011-09-01 15:02:01 -0700380 /* write auth seg cfg */
381 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start)) =
382 auth_cfg;
383 /* write auth seg size */
384 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start) + 1) =
385 sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700386
Mona Hossain3b574d82011-09-01 15:02:01 -0700387 /* write auth seg size start*/
388 *((uint32_t *)(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start)+2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700389
Mona Hossain3b574d82011-09-01 15:02:01 -0700390 /* write seg size */
391 *((uint32_t *)(pce_dev->ce_dm.buffer.seg_size)) = sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700392
Mona Hossain3b574d82011-09-01 15:02:01 -0700393 _ce_setup_hash_cmdrptrlist(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700394
Mona Hossain3b574d82011-09-01 15:02:01 -0700395 return 0;
396}
397
398static int _ce_setup_cipher_cmdrptrlist(struct qce_device *pce_dev,
399 struct qce_req *creq)
400{
401 struct ce_cmdptrlists_ops *cmdptrlist =
402 &pce_dev->ce_dm.cmdptrlist;
403
404 if (creq->alg != CIPHER_ALG_AES) {
405 switch (creq->alg) {
406 case CIPHER_ALG_DES:
407 if (creq->mode == QCE_MODE_ECB) {
408 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
409 cmdptrlist->cipher_des_ecb;
410 } else {
411 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
412 cmdptrlist->cipher_des_cbc;
413 }
414 break;
415
416 case CIPHER_ALG_3DES:
417 if (creq->mode == QCE_MODE_ECB) {
418 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
419 cmdptrlist->cipher_3des_ecb;
420 } else {
421 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
422 cmdptrlist->cipher_3des_cbc;
423 }
424 break;
425 default:
426 break;
427 }
428 } else {
429 switch (creq->mode) {
430 case QCE_MODE_ECB:
431 if (creq->encklen == AES128_KEY_SIZE) {
432 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
433 cmdptrlist->cipher_aes_128_ecb;
434 } else {
435 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
436 cmdptrlist->cipher_aes_256_ecb;
437 }
438 break;
439
440 case QCE_MODE_CBC:
441 if (creq->encklen == AES128_KEY_SIZE) {
442 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
443 cmdptrlist->cipher_aes_128_cbc_ctr;
444 } else {
445 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
446 cmdptrlist->cipher_aes_256_cbc_ctr;
447 }
448 break;
449
450 case QCE_MODE_CTR:
451 if (creq->encklen == AES128_KEY_SIZE) {
452 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
453 cmdptrlist->cipher_aes_128_cbc_ctr;
454 } else {
455 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
456 cmdptrlist->cipher_aes_256_cbc_ctr;
457 }
458 break;
459
460 case QCE_MODE_XTS:
461 if (creq->encklen == AES128_KEY_SIZE) {
462 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
463 cmdptrlist->cipher_aes_128_xts;
464 } else {
465 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
466 cmdptrlist->cipher_aes_256_xts;
467 }
468 break;
469 case QCE_MODE_CCM:
470 if (creq->encklen == AES128_KEY_SIZE) {
471 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
472 cmdptrlist->aead_aes_128_ccm;
473 } else {
474 pce_dev->ce_dm.chan_ce_in_cmd->cmdptr =
475 cmdptrlist->aead_aes_256_ccm;
476 }
477 break;
478 default:
479 break;
480 }
481 }
482
Mona Hossainb8db7432011-11-17 12:33:24 -0800483 switch (creq->mode) {
484 case QCE_MODE_CCM:
Mona Hossain3b574d82011-09-01 15:02:01 -0700485 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
Mona Hossainb8db7432011-11-17 12:33:24 -0800486 cmdptrlist->aead_ce_out;
487 break;
488 case QCE_MODE_ECB:
Mona Hossain3b574d82011-09-01 15:02:01 -0700489 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
Mona Hossainb8db7432011-11-17 12:33:24 -0800490 cmdptrlist->cipher_ce_out;
491 break;
492 default:
493 pce_dev->ce_dm.chan_ce_out_cmd->cmdptr =
494 cmdptrlist->cipher_ce_out_get_iv;
495 break;
496 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700497
498 return 0;
499}
500
501static int _ce_setup_cipher(struct qce_device *pce_dev, struct qce_req *creq,
502 uint32_t totallen_in, uint32_t coffset)
503{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700504 uint32_t enck_size_in_word = creq->encklen / sizeof(uint32_t);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700505 uint32_t encr_cfg = 0;
506 uint32_t ivsize = creq->ivsize;
Mona Hossain3b574d82011-09-01 15:02:01 -0700507 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700508
509 if (creq->mode == QCE_MODE_XTS)
Mona Hossain3b574d82011-09-01 15:02:01 -0700510 memcpy(buffer->encr_key, creq->enckey,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700511 creq->encklen/2);
512 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700513 memcpy(buffer->encr_key, creq->enckey, creq->encklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700514
515 if ((creq->op == QCE_REQ_AEAD) && (creq->mode == QCE_MODE_CCM)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700516 uint32_t noncelen32 = MAX_NONCE/sizeof(uint32_t);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700517 uint32_t auth_cfg = 0;
518
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700519 /* write nonce */
Mona Hossain3b574d82011-09-01 15:02:01 -0700520 memcpy(buffer->auth_nonce_info, creq->nonce, MAX_NONCE);
521 memcpy(buffer->auth_key, creq->enckey, creq->encklen);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700522
523 auth_cfg |= (noncelen32 << CRYPTO_AUTH_NONCE_NUM_WORDS);
524 auth_cfg &= ~(1 << CRYPTO_USE_HW_KEY_AUTH);
525 auth_cfg |= (1 << CRYPTO_LAST);
526 if (creq->dir == QCE_ENCRYPT)
527 auth_cfg |= (CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);
528 else
529 auth_cfg |= (CRYPTO_AUTH_POS_AFTER << CRYPTO_AUTH_POS);
530 auth_cfg |= (((creq->authsize >> 1) - 2) << CRYPTO_AUTH_SIZE);
531 auth_cfg |= (CRYPTO_AUTH_MODE_CCM << CRYPTO_AUTH_MODE);
532 if (creq->authklen == AES128_KEY_SIZE)
533 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES128 <<
534 CRYPTO_AUTH_KEY_SIZE);
535 else {
536 if (creq->authklen == AES256_KEY_SIZE)
537 auth_cfg |= (CRYPTO_AUTH_KEY_SZ_AES256 <<
538 CRYPTO_AUTH_KEY_SIZE);
539 }
540 auth_cfg |= (CRYPTO_AUTH_ALG_AES << CRYPTO_AUTH_ALG);
Mona Hossain3b574d82011-09-01 15:02:01 -0700541 *((uint32_t *)(buffer->auth_seg_cfg_size_start)) = auth_cfg;
542
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700543 if (creq->dir == QCE_ENCRYPT)
Mona Hossain3b574d82011-09-01 15:02:01 -0700544 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 1) =
545 totallen_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700546 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700547 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 1) =
548 (totallen_in - creq->authsize);
549 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700550 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700551
552 *((uint32_t *)(buffer->auth_seg_cfg_size_start) + 2) = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700553
554 switch (creq->mode) {
555 case QCE_MODE_ECB:
556 encr_cfg |= (CRYPTO_ENCR_MODE_ECB << CRYPTO_ENCR_MODE);
557 break;
558
559 case QCE_MODE_CBC:
560 encr_cfg |= (CRYPTO_ENCR_MODE_CBC << CRYPTO_ENCR_MODE);
561 break;
562
563 case QCE_MODE_XTS:
564 encr_cfg |= (CRYPTO_ENCR_MODE_XTS << CRYPTO_ENCR_MODE);
565 break;
566
567 case QCE_MODE_CCM:
568 encr_cfg |= (CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE);
569 break;
570
571 case QCE_MODE_CTR:
572 default:
573 encr_cfg |= (CRYPTO_ENCR_MODE_CTR << CRYPTO_ENCR_MODE);
574 break;
575 }
576 pce_dev->mode = creq->mode;
577
578 switch (creq->alg) {
579 case CIPHER_ALG_DES:
Mona Hossain3b574d82011-09-01 15:02:01 -0700580 if (creq->mode != QCE_MODE_ECB)
581 memcpy(buffer->encr_cntr_iv, creq->iv, ivsize);
582
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700583 encr_cfg |= ((CRYPTO_ENCR_KEY_SZ_DES << CRYPTO_ENCR_KEY_SZ) |
584 (CRYPTO_ENCR_ALG_DES << CRYPTO_ENCR_ALG));
585 break;
586
587 case CIPHER_ALG_3DES:
Mona Hossain3b574d82011-09-01 15:02:01 -0700588 if (creq->mode != QCE_MODE_ECB)
589 memcpy(buffer->encr_cntr_iv, creq->iv, ivsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700590
591 encr_cfg |= ((CRYPTO_ENCR_KEY_SZ_3DES << CRYPTO_ENCR_KEY_SZ) |
592 (CRYPTO_ENCR_ALG_DES << CRYPTO_ENCR_ALG));
593 break;
594
595 case CIPHER_ALG_AES:
596 default:
597 if (creq->mode == QCE_MODE_XTS) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700598 memcpy(buffer->encr_xts_key, (creq->enckey +
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700599 creq->encklen/2), creq->encklen/2);
Mona Hossain3b574d82011-09-01 15:02:01 -0700600 *((uint32_t *)(buffer->encr_xts_du_size)) =
601 creq->cryptlen;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700602
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700603 }
604 if (creq->mode != QCE_MODE_ECB) {
605 if (creq->mode == QCE_MODE_XTS)
Mona Hossain3b574d82011-09-01 15:02:01 -0700606 _byte_stream_swap_to_net_words(
607 (uint32_t *)(buffer->encr_cntr_iv),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700608 creq->iv, ivsize);
609 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700610 memcpy(buffer->encr_cntr_iv, creq->iv,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700611 ivsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700612 }
613 /* set number of counter bits */
Mona Hossain3b574d82011-09-01 15:02:01 -0700614 *((uint32_t *)(buffer->encr_mask)) = (uint32_t)0xffffffff;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700615
616 if (creq->op == QCE_REQ_ABLK_CIPHER_NO_KEY) {
617 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES128 <<
618 CRYPTO_ENCR_KEY_SZ);
619 encr_cfg |= CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG;
620 } else {
621 uint32_t key_size;
622
623 if (creq->mode == QCE_MODE_XTS) {
624 key_size = creq->encklen/2;
625 enck_size_in_word = key_size/sizeof(uint32_t);
626 } else {
627 key_size = creq->encklen;
628 }
629
630 switch (key_size) {
631 case AES128_KEY_SIZE:
632 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES128 <<
633 CRYPTO_ENCR_KEY_SZ);
634 break;
635 case AES256_KEY_SIZE:
636 default:
637 encr_cfg |= (CRYPTO_ENCR_KEY_SZ_AES256 <<
638 CRYPTO_ENCR_KEY_SZ);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700639 break;
640 } /* end of switch (creq->encklen) */
641
642 encr_cfg |= CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700643 } /* else of if (creq->op == QCE_REQ_ABLK_CIPHER_NO_KEY) */
644 break;
645 } /* end of switch (creq->mode) */
646
647 /* write encr seg cfg */
648 encr_cfg |= ((creq->dir == QCE_ENCRYPT) ? 1 : 0) << CRYPTO_ENCODE;
649
650 /* write encr seg cfg */
Mona Hossain3b574d82011-09-01 15:02:01 -0700651 *((uint32_t *)(buffer->encr_seg_cfg_size_start)) = encr_cfg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700652 /* write encr seg size */
653 if ((creq->mode == QCE_MODE_CCM) && (creq->dir == QCE_DECRYPT))
Mona Hossain3b574d82011-09-01 15:02:01 -0700654 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 1) =
655 (creq->cryptlen + creq->authsize);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700656 else
Mona Hossain3b574d82011-09-01 15:02:01 -0700657 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 1) =
658 creq->cryptlen;
659
660
661 *((uint32_t *)(buffer->encr_seg_cfg_size_start) + 2) =
662 (coffset & 0xffff);
663
664 *((uint32_t *)(buffer->seg_size)) = totallen_in;
665
666 _ce_setup_cipher_cmdrptrlist(pce_dev, creq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700667 return 0;
668};
669
670static int _aead_complete(struct qce_device *pce_dev)
671{
672 struct aead_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700673
674 areq = (struct aead_request *) pce_dev->areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700675
676 if (areq->src != areq->dst) {
677 dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
678 DMA_FROM_DEVICE);
679 }
680 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
681 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
682 DMA_TO_DEVICE);
683
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700684 dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
685 DMA_TO_DEVICE);
686
Mona Hossain3b574d82011-09-01 15:02:01 -0700687 /* check MAC */
688 if (pce_dev->mode == QCE_MODE_CCM) {
689 uint32_t result;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700690
Mona Hossain3b574d82011-09-01 15:02:01 -0700691 result =
692 (uint32_t)(*((uint32_t *)pce_dev->ce_dm.buffer.status));
693 result &= (1 << CRYPTO_MAC_FAILED);
694 result |= (pce_dev->ce_dm.chan_ce_in_status |
695 pce_dev->ce_dm.chan_ce_out_status);
696 pce_dev->qce_cb(areq, pce_dev->ce_dm.buffer.auth_result, NULL,
697 result);
698 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700699 return 0;
700};
701
702static void _sha_complete(struct qce_device *pce_dev)
703{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700704 struct ahash_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700705
706 areq = (struct ahash_request *) pce_dev->areq;
707 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
708 DMA_TO_DEVICE);
709
Mona Hossain3b574d82011-09-01 15:02:01 -0700710 pce_dev->qce_cb(areq, pce_dev->ce_dm.buffer.auth_result,
711 pce_dev->ce_dm.buffer.auth_byte_count,
712 pce_dev->ce_dm.chan_ce_in_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700713
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700714};
715
716static int _ablk_cipher_complete(struct qce_device *pce_dev)
717{
718 struct ablkcipher_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700719
720 areq = (struct ablkcipher_request *) pce_dev->areq;
721
722 if (areq->src != areq->dst) {
723 dma_unmap_sg(pce_dev->pdev, areq->dst,
724 pce_dev->dst_nents, DMA_FROM_DEVICE);
725 }
726 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
727 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
728 DMA_TO_DEVICE);
Mona Hossain3b574d82011-09-01 15:02:01 -0700729
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700730 if (pce_dev->mode == QCE_MODE_ECB) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700731 pce_dev->qce_cb(areq, NULL, NULL,
732 pce_dev->ce_dm.chan_ce_in_status |
733 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700734 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700735
Mona Hossain3b574d82011-09-01 15:02:01 -0700736 pce_dev->qce_cb(areq, NULL, pce_dev->ce_dm.buffer.encr_cntr_iv,
737 pce_dev->ce_dm.chan_ce_in_status |
738 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700739 }
740
741 return 0;
742};
743
744static int _ablk_cipher_use_pmem_complete(struct qce_device *pce_dev)
745{
746 struct ablkcipher_request *areq;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700747
748 areq = (struct ablkcipher_request *) pce_dev->areq;
749
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700750 if (pce_dev->mode == QCE_MODE_ECB) {
Mona Hossain3b574d82011-09-01 15:02:01 -0700751 pce_dev->qce_cb(areq, NULL, NULL,
752 pce_dev->ce_dm.chan_ce_in_status |
753 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700754 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700755 pce_dev->qce_cb(areq, NULL, pce_dev->ce_dm.buffer.encr_cntr_iv,
756 pce_dev->ce_dm.chan_ce_in_status |
757 pce_dev->ce_dm.chan_ce_out_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700758 }
759
760 return 0;
761};
762
763static int qce_split_and_insert_dm_desc(struct dmov_desc *pdesc,
764 unsigned int plen, unsigned int paddr, int *index)
765{
Mona Hossain3b574d82011-09-01 15:02:01 -0700766 while (plen > QCE_FIFO_SIZE) {
767 pdesc->len = QCE_FIFO_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700768 if (paddr > 0) {
769 pdesc->addr = paddr;
Mona Hossain3b574d82011-09-01 15:02:01 -0700770 paddr += QCE_FIFO_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700771 }
772 plen -= pdesc->len;
773 if (plen > 0) {
774 *index = (*index) + 1;
775 if ((*index) >= QCE_MAX_NUM_DESC)
776 return -ENOMEM;
777 pdesc++;
778 }
779 }
Mona Hossain3b574d82011-09-01 15:02:01 -0700780 if ((plen > 0) && (plen <= QCE_FIFO_SIZE)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700781 pdesc->len = plen;
782 if (paddr > 0)
783 pdesc->addr = paddr;
784 }
785
786 return 0;
787}
788
789static int _chain_sg_buffer_in(struct qce_device *pce_dev,
790 struct scatterlist *sg, unsigned int nbytes)
791{
792 unsigned int len;
793 unsigned int dlen;
794 struct dmov_desc *pdesc;
795
Mona Hossain3b574d82011-09-01 15:02:01 -0700796 pdesc = pce_dev->ce_dm.ce_in_src_desc +
797 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700798 /*
799 * Two consective chunks may be handled by the old
800 * buffer descriptor.
801 */
802 while (nbytes > 0) {
803 len = min(nbytes, sg_dma_len(sg));
804 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
805 nbytes -= len;
806 if (dlen == 0) {
807 pdesc->addr = sg_dma_address(sg);
808 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700809 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700810 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700811 sg_dma_address(sg),
812 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700813 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
814 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700815 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700816 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700817 pdesc->addr,
818 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700819 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700820 pce_dev->ce_dm.ce_in_src_desc_index++;
821 if (pce_dev->ce_dm.ce_in_src_desc_index >=
822 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700823 return -ENOMEM;
824 pdesc++;
825 pdesc->len = len;
826 pdesc->addr = sg_dma_address(sg);
Mona Hossain3b574d82011-09-01 15:02:01 -0700827 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700828 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
Mona Hossain3b574d82011-09-01 15:02:01 -0700829 sg_dma_address(sg),
830 &pce_dev->ce_dm.ce_in_src_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700831 }
832 if (nbytes > 0)
833 sg = sg_next(sg);
834 }
835 return 0;
836}
837
838static int _chain_pm_buffer_in(struct qce_device *pce_dev,
839 unsigned int pmem, unsigned int nbytes)
840{
841 unsigned int dlen;
842 struct dmov_desc *pdesc;
843
Mona Hossain3b574d82011-09-01 15:02:01 -0700844 pdesc = pce_dev->ce_dm.ce_in_src_desc +
845 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700846 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
847 if (dlen == 0) {
848 pdesc->addr = pmem;
849 pdesc->len = nbytes;
850 } else if (pmem == (pdesc->addr + dlen)) {
851 pdesc->len = dlen + nbytes;
852 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700853 pce_dev->ce_dm.ce_in_src_desc_index++;
854 if (pce_dev->ce_dm.ce_in_src_desc_index >=
855 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700856 return -ENOMEM;
857 pdesc++;
858 pdesc->len = nbytes;
859 pdesc->addr = pmem;
860 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700861 return 0;
862}
863
864static void _chain_buffer_in_init(struct qce_device *pce_dev)
865{
866 struct dmov_desc *pdesc;
867
Mona Hossain3b574d82011-09-01 15:02:01 -0700868 pce_dev->ce_dm.ce_in_src_desc_index = 0;
869 pce_dev->ce_dm.ce_in_dst_desc_index = 0;
870 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700871 pdesc->len = 0;
872}
873
874static void _ce_in_final(struct qce_device *pce_dev, unsigned total)
875{
876 struct dmov_desc *pdesc;
877 dmov_sg *pcmd;
878
Mona Hossain3b574d82011-09-01 15:02:01 -0700879 pdesc = pce_dev->ce_dm.ce_in_src_desc +
880 pce_dev->ce_dm.ce_in_src_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700881 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700882
883 pdesc = pce_dev->ce_dm.ce_in_dst_desc;
884 if (total > QCE_FIFO_SIZE) {
885 qce_split_and_insert_dm_desc(pdesc, total, 0,
886 &pce_dev->ce_dm.ce_in_dst_desc_index);
887 pdesc = pce_dev->ce_dm.ce_in_dst_desc +
888 pce_dev->ce_dm.ce_in_dst_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -0700889 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -0700890 } else
891 pdesc->len = ADM_DESC_LAST | total;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700892
Mona Hossain3b574d82011-09-01 15:02:01 -0700893 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_in;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700894 pcmd->cmd |= CMD_LC;
Mona Hossain3b574d82011-09-01 15:02:01 -0700895
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700896}
897
898#ifdef QCE_DEBUG
899static void _ce_in_dump(struct qce_device *pce_dev)
900{
901 int i;
902 struct dmov_desc *pdesc;
903
904 dev_info(pce_dev->pdev, "_ce_in_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700905 for (i = 0; i <= pce_dev->ce_dm.ce_in_src_desc_index; i++) {
906 pdesc = pce_dev->ce_dm.ce_in_src_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700907 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
908 pdesc->len);
909 }
910 dev_info(pce_dev->pdev, "_ce_in_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700911 for (i = 0; i <= pce_dev->ce_dm.ce_in_dst_desc_index; i++) {
912 pdesc = pce_dev->ce_dm.ce_in_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700913 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
914 pdesc->len);
915 }
916};
917
918static void _ce_out_dump(struct qce_device *pce_dev)
919{
920 int i;
921 struct dmov_desc *pdesc;
922
923 dev_info(pce_dev->pdev, "_ce_out_dump: src\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700924 for (i = 0; i <= pce_dev->ce_dm.ce_out_src_desc_index; i++) {
925 pdesc = pce_dev->ce_dm.ce_out_src_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 dev_info(pce_dev->pdev, "_ce_out_dump: dst\n");
Mona Hossain3b574d82011-09-01 15:02:01 -0700931 for (i = 0; i <= pce_dev->ce_dm.ce_out_dst_desc_index; i++) {
932 pdesc = pce_dev->ce_dm.ce_out_dst_desc + i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700933 dev_info(pce_dev->pdev, "%x , %x\n", pdesc->addr,
934 pdesc->len);
935 }
936};
937
938#else
939
940static void _ce_in_dump(struct qce_device *pce_dev)
941{
942};
943
944static void _ce_out_dump(struct qce_device *pce_dev)
945{
946};
947
948#endif
949
950static int _chain_sg_buffer_out(struct qce_device *pce_dev,
951 struct scatterlist *sg, unsigned int nbytes)
952{
953 unsigned int len;
954 unsigned int dlen;
955 struct dmov_desc *pdesc;
956
Mona Hossain3b574d82011-09-01 15:02:01 -0700957 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
958 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700959 /*
960 * Two consective chunks may be handled by the old
961 * buffer descriptor.
962 */
963 while (nbytes > 0) {
964 len = min(nbytes, sg_dma_len(sg));
965 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
966 nbytes -= len;
967 if (dlen == 0) {
968 pdesc->addr = sg_dma_address(sg);
969 pdesc->len = len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700970 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700971 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
972 sg_dma_address(sg),
Mona Hossain3b574d82011-09-01 15:02:01 -0700973 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700974 } else if (sg_dma_address(sg) == (pdesc->addr + dlen)) {
975 pdesc->len = dlen + len;
Mona Hossain3b574d82011-09-01 15:02:01 -0700976 if (pdesc->len > QCE_FIFO_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700977 qce_split_and_insert_dm_desc(pdesc, pdesc->len,
978 pdesc->addr,
Mona Hossain3b574d82011-09-01 15:02:01 -0700979 &pce_dev->ce_dm.ce_out_dst_desc_index);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700980
981 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -0700982 pce_dev->ce_dm.ce_out_dst_desc_index++;
983 if (pce_dev->ce_dm.ce_out_dst_desc_index >=
984 QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700985 return -EIO;
986 pdesc++;
987 pdesc->len = len;
988 pdesc->addr = sg_dma_address(sg);
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 sg_dma_address(sg),
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 }
995 if (nbytes > 0)
996 sg = sg_next(sg);
997 }
998 return 0;
999}
1000
1001static int _chain_pm_buffer_out(struct qce_device *pce_dev,
1002 unsigned int pmem, unsigned int nbytes)
1003{
1004 unsigned int dlen;
1005 struct dmov_desc *pdesc;
1006
Mona Hossain3b574d82011-09-01 15:02:01 -07001007 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
1008 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001009 dlen = pdesc->len & ADM_DESC_LENGTH_MASK;
1010
1011 if (dlen == 0) {
1012 pdesc->addr = pmem;
1013 pdesc->len = nbytes;
1014 } else if (pmem == (pdesc->addr + dlen)) {
1015 pdesc->len = dlen + nbytes;
1016 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001017 pce_dev->ce_dm.ce_out_dst_desc_index++;
1018 if (pce_dev->ce_dm.ce_out_dst_desc_index >= QCE_MAX_NUM_DESC)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001019 return -EIO;
1020 pdesc++;
1021 pdesc->len = nbytes;
1022 pdesc->addr = pmem;
1023 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001024 return 0;
1025};
1026
1027static void _chain_buffer_out_init(struct qce_device *pce_dev)
1028{
1029 struct dmov_desc *pdesc;
1030
Mona Hossain3b574d82011-09-01 15:02:01 -07001031 pce_dev->ce_dm.ce_out_dst_desc_index = 0;
1032 pce_dev->ce_dm.ce_out_src_desc_index = 0;
1033 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001034 pdesc->len = 0;
1035};
1036
1037static void _ce_out_final(struct qce_device *pce_dev, unsigned total)
1038{
1039 struct dmov_desc *pdesc;
1040 dmov_sg *pcmd;
1041
Mona Hossain3b574d82011-09-01 15:02:01 -07001042 pdesc = pce_dev->ce_dm.ce_out_dst_desc +
1043 pce_dev->ce_dm.ce_out_dst_desc_index;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001044 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001045
Mona Hossain3b574d82011-09-01 15:02:01 -07001046 pdesc = pce_dev->ce_dm.ce_out_src_desc +
1047 pce_dev->ce_dm.ce_out_src_desc_index;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001048 if (total > QCE_FIFO_SIZE) {
1049 qce_split_and_insert_dm_desc(pdesc, total, 0,
1050 &pce_dev->ce_dm.ce_out_src_desc_index);
1051 pdesc = pce_dev->ce_dm.ce_out_src_desc +
1052 pce_dev->ce_dm.ce_out_src_desc_index;
Mona Hossain390d92e2011-09-02 14:15:47 -07001053 pdesc->len |= ADM_DESC_LAST;
Mona Hossain2563cbc2011-09-14 15:24:08 -07001054 } else
1055 pdesc->len = ADM_DESC_LAST | total;
Mona Hossain3b574d82011-09-01 15:02:01 -07001056
1057 pcmd = (dmov_sg *) pce_dev->ce_dm.cmdlist.ce_data_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001058 pcmd->cmd |= CMD_LC;
1059};
1060
1061static void _aead_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1062 unsigned int result, struct msm_dmov_errdata *err)
1063{
1064 struct qce_device *pce_dev;
1065
1066 pce_dev = (struct qce_device *) cmd_ptr->user;
1067 if (result != ADM_STATUS_OK) {
1068 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1069 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001070 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001071 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001072 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001073 }
1074
Mona Hossain3b574d82011-09-01 15:02:01 -07001075 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1076 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1077 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1078 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001079
1080 /* done */
1081 _aead_complete(pce_dev);
1082 }
1083};
1084
1085static void _aead_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1086 unsigned int result, struct msm_dmov_errdata *err)
1087{
1088 struct qce_device *pce_dev;
1089
1090 pce_dev = (struct qce_device *) cmd_ptr->user;
1091 if (result != ADM_STATUS_OK) {
1092 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1093 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001094 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001095 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001096 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001097 };
1098
Mona Hossain3b574d82011-09-01 15:02:01 -07001099 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1100 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1101 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1102 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001103
1104 /* done */
1105 _aead_complete(pce_dev);
1106 }
1107
1108};
1109
1110static void _sha_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1111 unsigned int result, struct msm_dmov_errdata *err)
1112{
1113 struct qce_device *pce_dev;
1114
1115 pce_dev = (struct qce_device *) cmd_ptr->user;
1116 if (result != ADM_STATUS_OK) {
1117 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1118 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001119 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001120 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001121 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001122 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001123 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001124 _sha_complete(pce_dev);
1125};
1126
1127static void _ablk_cipher_ce_in_call_back(struct msm_dmov_cmd *cmd_ptr,
1128 unsigned int result, struct msm_dmov_errdata *err)
1129{
1130 struct qce_device *pce_dev;
1131
1132 pce_dev = (struct qce_device *) cmd_ptr->user;
1133 if (result != ADM_STATUS_OK) {
1134 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1135 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001136 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001137 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001138 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001139 }
1140
Mona Hossain3b574d82011-09-01 15:02:01 -07001141 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1142 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1143 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1144 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001145
1146 /* done */
1147 _ablk_cipher_complete(pce_dev);
1148 }
1149};
1150
1151static void _ablk_cipher_ce_out_call_back(struct msm_dmov_cmd *cmd_ptr,
1152 unsigned int result, struct msm_dmov_errdata *err)
1153{
1154 struct qce_device *pce_dev;
1155
1156 pce_dev = (struct qce_device *) cmd_ptr->user;
Mona Hossain3b574d82011-09-01 15:02:01 -07001157
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001158 if (result != ADM_STATUS_OK) {
1159 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1160 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001161 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001162 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001163 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001164 };
1165
Mona Hossain3b574d82011-09-01 15:02:01 -07001166 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1167 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1168 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1169 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001170
1171 /* done */
1172 _ablk_cipher_complete(pce_dev);
1173 }
1174};
1175
1176
1177static void _ablk_cipher_ce_in_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1178 unsigned int result, struct msm_dmov_errdata *err)
1179{
1180 struct qce_device *pce_dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001181 pce_dev = (struct qce_device *) cmd_ptr->user;
1182 if (result != ADM_STATUS_OK) {
1183 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1184 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001185 pce_dev->ce_dm.chan_ce_in_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001186 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001187 pce_dev->ce_dm.chan_ce_in_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001188 }
1189
Mona Hossain3b574d82011-09-01 15:02:01 -07001190 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
1191 if (pce_dev->ce_dm.chan_ce_out_state == QCE_CHAN_STATE_COMP) {
1192 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1193 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001194
1195 /* done */
1196 _ablk_cipher_use_pmem_complete(pce_dev);
1197 }
1198};
1199
1200static void _ablk_cipher_ce_out_call_back_pmem(struct msm_dmov_cmd *cmd_ptr,
1201 unsigned int result, struct msm_dmov_errdata *err)
1202{
1203 struct qce_device *pce_dev;
1204
1205 pce_dev = (struct qce_device *) cmd_ptr->user;
1206 if (result != ADM_STATUS_OK) {
1207 dev_err(pce_dev->pdev, "Qualcomm ADM status error %x\n",
1208 result);
Mona Hossain3b574d82011-09-01 15:02:01 -07001209 pce_dev->ce_dm.chan_ce_out_status = -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001210 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07001211 pce_dev->ce_dm.chan_ce_out_status = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001212 };
1213
Mona Hossain3b574d82011-09-01 15:02:01 -07001214 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
1215 if (pce_dev->ce_dm.chan_ce_in_state == QCE_CHAN_STATE_COMP) {
1216 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
1217 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001218
1219 /* done */
1220 _ablk_cipher_use_pmem_complete(pce_dev);
1221 }
1222};
1223
Mona Hossain3b574d82011-09-01 15:02:01 -07001224static int qce_setup_cmd_buffers(struct qce_device *pce_dev,
1225 unsigned char **pvaddr)
1226{
1227 struct ce_reg_buffers *addr = (struct ce_reg_buffers *)(*pvaddr);
1228 struct ce_reg_buffer_addr *buffer = &pce_dev->ce_dm.buffer;
1229
1230 /*
1231 * Designate chunks of the allocated memory to various
1232 * buffer pointers
1233 */
1234 buffer->reset_buf_64 = addr->reset_buf_64;
1235 buffer->version = addr->version;
1236 buffer->encr_seg_cfg_size_start = addr->encr_seg_cfg_size_start;
1237 buffer->encr_key = addr->encr_key;
1238 buffer->encr_xts_key = addr->encr_xts_key;
1239 buffer->encr_xts_du_size = addr->encr_xts_du_size;
1240 buffer->encr_cntr_iv = addr->encr_cntr_iv;
1241 buffer->encr_mask = addr->encr_mask;
1242 buffer->auth_seg_cfg_size_start = addr->auth_seg_cfg_size_start;
1243 buffer->auth_key = addr->auth_key;
1244 buffer->auth_iv = addr->auth_iv;
1245 buffer->auth_result = addr->auth_result;
1246 buffer->auth_nonce_info = addr->auth_nonce_info;
1247 buffer->auth_byte_count = addr->auth_byte_count;
1248 buffer->seg_size = addr->seg_size;
1249 buffer->go_proc = addr->go_proc;
1250 buffer->status = addr->status;
1251 buffer->pad = addr->pad;
1252
1253 memset(buffer->reset_buf_64, 0, 64);
1254 *((uint32_t *)buffer->encr_mask) = (uint32_t)(0xffffffff);
1255 *((uint32_t *)buffer->go_proc) = (uint32_t)(1 << CRYPTO_GO);
1256
1257 *pvaddr += sizeof(struct ce_reg_buffers);
1258
1259 return 0;
1260
1261}
1262
1263static int _setup_cipher_cmdlists(struct qce_device *pce_dev,
1264 unsigned char **pvaddr)
1265{
1266 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1267
1268 /*
1269 * Designate chunks of the allocated memory to various
1270 * command list pointers related to cipher operation
1271 */
1272 pce_dev->ce_dm.cmdlist.set_cipher_cfg = pscmd;
1273 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1274 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG +
1275 pce_dev->phy_iobase);
1276 pscmd->len = CRYPTO_REG_SIZE * 3;
1277 pscmd->src =
1278 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_seg_cfg_size_start);
1279 pscmd++;
1280
1281 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_key = pscmd;
1282 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1283 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1284 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1285 pscmd->len = CRYPTO_REG_SIZE * 4;
1286 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1287 pscmd++;
1288
1289 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_key = pscmd;
1290 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1291 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1292 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1293 pscmd->len = CRYPTO_REG_SIZE * 8;
1294 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1295 pscmd++;
1296
1297 pce_dev->ce_dm.cmdlist.set_cipher_des_key = pscmd;
1298 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1299 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1300 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1301 pscmd->len = CRYPTO_REG_SIZE * 2;
1302 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1303 pscmd++;
1304
1305 pce_dev->ce_dm.cmdlist.set_cipher_3des_key = pscmd;
1306 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1307 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1308 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1309 pscmd->len = CRYPTO_REG_SIZE * 6;
1310 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_key);
1311 pscmd++;
1312
1313 pce_dev->ce_dm.cmdlist.set_cipher_aes_128_xts_key = pscmd;
1314 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1315 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1316 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1317 pce_dev->phy_iobase);
1318 pscmd->len = CRYPTO_REG_SIZE * 4;
1319 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1320 pscmd++;
1321
1322 pce_dev->ce_dm.cmdlist.set_cipher_aes_256_xts_key = pscmd;
1323 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1324 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1325 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1326 pce_dev->phy_iobase);
1327 pscmd->len = CRYPTO_REG_SIZE * 8;
1328 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_key);
1329 pscmd++;
1330
1331 pce_dev->ce_dm.cmdlist.set_cipher_xts_du_size = pscmd;
1332 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1333 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_DU_SIZE_REG +
1334 pce_dev->phy_iobase);
1335 pscmd->len = CRYPTO_REG_SIZE * 4;
1336 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_xts_du_size);
1337 pscmd++;
1338
1339 pce_dev->ce_dm.cmdlist.set_cipher_aes_iv = pscmd;
1340 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1341 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1342 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1343 pscmd->len = CRYPTO_REG_SIZE * 4;
1344 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1345 pscmd++;
1346
Mona Hossain3b574d82011-09-01 15:02:01 -07001347 pce_dev->ce_dm.cmdlist.set_cipher_des_iv = pscmd;
1348 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1349 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1350 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1351 pscmd->len = CRYPTO_REG_SIZE * 2;
1352 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1353 pscmd++;
1354
Mona Hossainb8db7432011-11-17 12:33:24 -08001355 pce_dev->ce_dm.cmdlist.get_cipher_iv = pscmd;
Mona Hossain3b574d82011-09-01 15:02:01 -07001356 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1357 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1358 pscmd->src = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
Mona Hossainb8db7432011-11-17 12:33:24 -08001359 pscmd->len = CRYPTO_REG_SIZE * 4;
Mona Hossain3b574d82011-09-01 15:02:01 -07001360 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_cntr_iv);
1361 pscmd++;
1362
1363 pce_dev->ce_dm.cmdlist.set_cipher_mask = pscmd;
1364 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1365 pscmd->dst = (unsigned) (CRYPTO_CNTR_MASK_REG + pce_dev->phy_iobase);
1366 pscmd->len = CRYPTO_REG_SIZE;
1367 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.encr_mask);
1368 pscmd++;
1369
1370 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1371
1372 pce_dev->ce_dm.cmdlist.reset_cipher_key = pscmd;
1373 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1374 pscmd->dst = (unsigned) (CRYPTO_ENCR_KEY0_REG + pce_dev->phy_iobase);
1375 pscmd->len = CRYPTO_REG_SIZE * 8;
1376 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1377 pscmd++;
1378
1379 pce_dev->ce_dm.cmdlist.reset_cipher_xts_key = pscmd;
1380 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1381 pscmd->dst = (unsigned) (CRYPTO_ENCR_XTS_KEY0_REG +
1382 pce_dev->phy_iobase);
1383 pscmd->len = CRYPTO_REG_SIZE * 8;
1384 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1385 pscmd++;
1386
1387 pce_dev->ce_dm.cmdlist.reset_cipher_iv = pscmd;
1388 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1389 pscmd->dst = (unsigned) (CRYPTO_CNTR0_IV0_REG + pce_dev->phy_iobase);
1390 pscmd->len = CRYPTO_REG_SIZE * 4;
1391 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1392 pscmd++;
1393
1394 pce_dev->ce_dm.cmdlist.reset_cipher_cfg = pscmd;
1395 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1396 pscmd->dst = (unsigned) (CRYPTO_ENCR_SEG_CFG_REG + pce_dev->phy_iobase);
1397 pscmd->len = CRYPTO_REG_SIZE;
1398 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1399 pscmd++;
1400
1401 *pvaddr = (unsigned char *) pscmd;
1402
1403 return 0;
1404}
1405
1406static int _setup_auth_cmdlists(struct qce_device *pce_dev,
1407 unsigned char **pvaddr)
1408{
1409 dmov_s *pscmd = (dmov_s *)(*pvaddr);
1410
1411 /*
1412 * Designate chunks of the allocated memory to various
1413 * command list pointers related to authentication operation
1414 */
1415 pce_dev->ce_dm.cmdlist.set_auth_cfg = pscmd;
1416 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1417 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1418 pscmd->len = CRYPTO_REG_SIZE * 3;
1419 pscmd->src =
1420 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_seg_cfg_size_start);
1421 pscmd++;
1422
1423 pce_dev->ce_dm.cmdlist.set_auth_key_128 = pscmd;
1424 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1425 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1426 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1427 pscmd->len = CRYPTO_REG_SIZE * 4;
1428 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1429 pscmd++;
1430
1431 pce_dev->ce_dm.cmdlist.set_auth_key_256 = pscmd;
1432 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1433 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1434 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1435 pscmd->len = CRYPTO_REG_SIZE * 8;
1436 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1437 pscmd++;
1438
1439 pce_dev->ce_dm.cmdlist.set_auth_key_512 = pscmd;
1440 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1441 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1442 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1443 pscmd->len = CRYPTO_REG_SIZE * 16;
1444 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_key);
1445 pscmd++;
1446
1447 pce_dev->ce_dm.cmdlist.set_auth_iv_16 = pscmd;
1448 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1449 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1450 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1451 pscmd->len = CRYPTO_REG_SIZE * 4;
1452 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1453 pscmd++;
1454
1455 pce_dev->ce_dm.cmdlist.get_auth_result_16 = pscmd;
1456 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1457 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1458 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1459 pscmd->len = CRYPTO_REG_SIZE * 4;
1460 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1461 pscmd++;
1462
1463 pce_dev->ce_dm.cmdlist.set_auth_iv_20 = pscmd;
1464 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1465 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1466 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1467 pscmd->len = CRYPTO_REG_SIZE * 5;
1468 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1469 pscmd++;
1470
1471 pce_dev->ce_dm.cmdlist.get_auth_result_20 = pscmd;
1472 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1473 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1474 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1475 pscmd->len = CRYPTO_REG_SIZE * 5;
1476 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1477 pscmd++;
1478
1479 pce_dev->ce_dm.cmdlist.set_auth_iv_32 = pscmd;
1480 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1481 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1482 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1483 pscmd->len = CRYPTO_REG_SIZE * 8;
1484 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_iv);
1485 pscmd++;
1486
1487
1488 pce_dev->ce_dm.cmdlist.get_auth_result_32 = pscmd;
1489 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1490 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1491 pscmd->src = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1492 pscmd->len = CRYPTO_REG_SIZE * 8;
1493 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_result);
1494 pscmd++;
1495
1496 pce_dev->ce_dm.cmdlist.set_auth_byte_count = pscmd;
1497 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1498 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1499 pce_dev->phy_iobase);
1500 pscmd->len = CRYPTO_REG_SIZE * 4;
1501 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1502 pscmd++;
1503
1504 pce_dev->ce_dm.cmdlist.get_auth_byte_count = pscmd;
1505 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1506 pscmd->src = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1507 pce_dev->phy_iobase);
1508 pscmd->len = CRYPTO_REG_SIZE * 4;
1509 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_byte_count);
1510 pscmd++;
1511
1512 pce_dev->ce_dm.cmdlist.set_auth_nonce_info = pscmd;
1513 pscmd->cmd = CMD_LC | CMD_SRC_SWAP_BYTES |
1514 CMD_SRC_SWAP_SHORTS | CMD_MODE_SINGLE;
1515 pscmd->dst = (unsigned) (CRYPTO_AUTH_INFO_NONCE0_REG +
1516 pce_dev->phy_iobase);
1517 pscmd->len = CRYPTO_REG_SIZE * 4;
1518 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.auth_nonce_info);
1519 pscmd++;
1520
1521 /* RESET CIPHER AND AUTH REGISTERS COMMAND LISTS*/
1522
1523 pce_dev->ce_dm.cmdlist.reset_auth_key = pscmd;
1524 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1525 pscmd->dst = (unsigned) (CRYPTO_AUTH_KEY0_REG + pce_dev->phy_iobase);
1526 pscmd->len = CRYPTO_REG_SIZE * 16;
1527 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1528 pscmd++;
1529
1530 pce_dev->ce_dm.cmdlist.reset_auth_iv = pscmd;
1531 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1532 pscmd->dst = (unsigned) (CRYPTO_AUTH_IV0_REG + pce_dev->phy_iobase);
1533 pscmd->len = CRYPTO_REG_SIZE * 16;
1534 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1535 pscmd++;
1536
1537 pce_dev->ce_dm.cmdlist.reset_auth_cfg = pscmd;
1538 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1539 pscmd->dst = (unsigned) (CRYPTO_AUTH_SEG_CFG_REG + pce_dev->phy_iobase);
1540 pscmd->len = CRYPTO_REG_SIZE;
1541 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1542 pscmd++;
1543
1544
1545 pce_dev->ce_dm.cmdlist.reset_auth_byte_count = pscmd;
1546 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1547 pscmd->dst = (unsigned) (CRYPTO_AUTH_BYTECNT0_REG +
1548 pce_dev->phy_iobase);
1549 pscmd->len = CRYPTO_REG_SIZE * 4;
1550 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.reset_buf_64);
1551 pscmd++;
1552
1553 /* WAIT UNTIL MAC OP IS DONE*/
1554
1555 pce_dev->ce_dm.cmdlist.get_status_wait = pscmd;
1556 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1557 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1558 pscmd->len = CRYPTO_REG_SIZE;
1559 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1560 pscmd++;
1561
1562 *pvaddr = (unsigned char *) pscmd;
1563
1564 return 0;
1565}
1566
1567static int qce_setup_cmdlists(struct qce_device *pce_dev,
1568 unsigned char **pvaddr)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001569{
1570 dmov_sg *pcmd;
Mona Hossain3b574d82011-09-01 15:02:01 -07001571 dmov_s *pscmd;
1572 unsigned char *vaddr = *pvaddr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001573 struct dmov_desc *pdesc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001574 int i = 0;
1575
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001576 /*
Mona Hossain3b574d82011-09-01 15:02:01 -07001577 * Designate chunks of the allocated memory to various
1578 * command list pointers related to operation define
1579 * in ce_cmdlists structure.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001580 */
Mona Hossain3b574d82011-09-01 15:02:01 -07001581 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
1582 *pvaddr = (unsigned char *) vaddr;
1583
1584 _setup_cipher_cmdlists(pce_dev, pvaddr);
1585 _setup_auth_cmdlists(pce_dev, pvaddr);
1586
1587 pscmd = (dmov_s *)(*pvaddr);
1588
1589 /* GET HW VERSION COMMAND LIST */
1590 pce_dev->ce_dm.cmdlist.get_hw_version = pscmd;
1591 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1592 pscmd->src = (unsigned) (CRYPTO_VERSION_REG + pce_dev->phy_iobase);
1593 pscmd->len = CRYPTO_REG_SIZE;
1594 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.version);
1595 pscmd++;
1596
1597
1598 /* SET SEG SIZE REGISTER and OCB COMMAND LIST */
1599 pce_dev->ce_dm.cmdlist.set_seg_size_ocb = pscmd;
1600 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCB;
1601 pscmd->dst = (unsigned) (CRYPTO_SEG_SIZE_REG + pce_dev->phy_iobase);
1602 pscmd->len = CRYPTO_REG_SIZE;
1603 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.seg_size);
1604 pscmd++;
1605
1606
1607 /* OCU COMMAND LIST */
1608 pce_dev->ce_dm.cmdlist.get_status_ocu = pscmd;
1609 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCU;
1610 pscmd->src = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1611 pscmd->len = CRYPTO_REG_SIZE;
1612 pscmd->dst = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1613 pscmd++;
1614
Mona Hossainb8db7432011-11-17 12:33:24 -08001615 /* CLEAR STATUS COMMAND LIST */
1616 pce_dev->ce_dm.cmdlist.clear_status = pscmd;
1617 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE | CMD_OCU;
1618 pscmd->dst = (unsigned) (CRYPTO_STATUS_REG + pce_dev->phy_iobase);
1619 pscmd->len = CRYPTO_REG_SIZE;
1620 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.status);
1621 pscmd++;
1622
Mona Hossain3b574d82011-09-01 15:02:01 -07001623 /* SET GO_PROC REGISTERS COMMAND LIST */
1624 pce_dev->ce_dm.cmdlist.set_go_proc = pscmd;
1625 pscmd->cmd = CMD_LC | CMD_MODE_SINGLE;
1626 pscmd->dst = (unsigned) (CRYPTO_GOPROC_REG + pce_dev->phy_iobase);
1627 pscmd->len = CRYPTO_REG_SIZE;
1628 pscmd->src = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.go_proc);
1629 pscmd++;
1630
1631 pcmd = (dmov_sg *)pscmd;
1632 pce_dev->ce_dm.cmdlist.ce_data_in = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001633 /* swap byte and half word , dst crci , scatter gather */
1634 pcmd->cmd = CMD_DST_SWAP_BYTES | CMD_DST_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001635 CMD_DST_CRCI(pce_dev->ce_dm.crci_in) | CMD_MODE_SG;
1636
1637 pdesc = pce_dev->ce_dm.ce_in_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001638 pdesc->addr = 0; /* to be filled in each operation */
1639 pdesc->len = 0; /* to be filled in each operation */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001640
Mona Hossain3b574d82011-09-01 15:02:01 -07001641 pdesc = pce_dev->ce_dm.ce_in_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001642 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1643 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1644 pdesc->len = 0; /* to be filled in each operation */
1645 pdesc++;
1646 }
Mona Hossain3b574d82011-09-01 15:02:01 -07001647 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_src_desc);
1648 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_in_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001649 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1650 DST_INDEX_SG_CMD(0);
Mona Hossain3b574d82011-09-01 15:02:01 -07001651
1652
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001653 pcmd++;
Mona Hossain3b574d82011-09-01 15:02:01 -07001654 pce_dev->ce_dm.cmdlist.ce_data_out = pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001655 /* swap byte, half word, source crci, scatter gather */
1656 pcmd->cmd = CMD_SRC_SWAP_BYTES | CMD_SRC_SWAP_SHORTS |
Mona Hossain3b574d82011-09-01 15:02:01 -07001657 CMD_SRC_CRCI(pce_dev->ce_dm.crci_out) | CMD_MODE_SG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001658
Mona Hossain3b574d82011-09-01 15:02:01 -07001659 pdesc = pce_dev->ce_dm.ce_out_src_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001660 for (i = 0; i < QCE_MAX_NUM_DESC; i++) {
1661 pdesc->addr = (CRYPTO_DATA_SHADOW0 + pce_dev->phy_iobase);
1662 pdesc->len = 0; /* to be filled in each operation */
1663 pdesc++;
1664 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001665
Mona Hossain3b574d82011-09-01 15:02:01 -07001666 pdesc = pce_dev->ce_dm.ce_out_dst_desc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001667 pdesc->addr = 0; /* to be filled in each operation */
1668 pdesc->len = 0; /* to be filled in each operation */
Mona Hossain3b574d82011-09-01 15:02:01 -07001669
1670 pcmd->src_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_src_desc);
1671 pcmd->dst_dscr = GET_PHYS_ADDR(pce_dev->ce_dm.ce_out_dst_desc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001672 pcmd->_reserved = LI_SG_CMD | SRC_INDEX_SG_CMD(0) |
1673 DST_INDEX_SG_CMD(0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001674 pcmd++;
1675
Mona Hossain3b574d82011-09-01 15:02:01 -07001676 *pvaddr = (unsigned char *) pcmd;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001677
1678 return 0;
Mona Hossain3b574d82011-09-01 15:02:01 -07001679}
1680
1681static int _setup_cipher_cmdptrlists(struct qce_device *pce_dev,
1682 unsigned char **pvaddr)
1683{
1684 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1685 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1686 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1687
1688 /*
1689 * Designate chunks of the allocated memory to various
1690 * command list pointers related to cipher operations defined
1691 * in ce_cmdptrlists_ops structure.
1692 */
1693 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1694 cmdptrlist->cipher_aes_128_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1695
1696 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1697 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1698 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1699 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1700 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1701 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1702 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001703 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001704
1705 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1706 cmdptrlist->cipher_aes_256_cbc_ctr = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1707
1708 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1709 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1710 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1711 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1712 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1713 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1714 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001715 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001716
1717 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1718 cmdptrlist->cipher_aes_128_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1719
1720 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1721 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1722 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1723 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1724 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1725 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1726 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1727
1728 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1729 cmdptrlist->cipher_aes_256_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1730
1731 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1732 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1733 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1734 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1735 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1736 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1737 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1738
1739 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1740 cmdptrlist->cipher_aes_128_xts = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1741
1742 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1743 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1744 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1745 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_xts_key);
1746 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1747 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1748 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
1749 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1750 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001751 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001752
1753 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1754 cmdptrlist->cipher_aes_256_xts = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1755
1756 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1757 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1758 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1759 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_xts_key);
1760 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1761 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1762 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_xts_du_size);
1763 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1764 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001765 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001766
1767 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1768 cmdptrlist->cipher_des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1769
1770 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1771 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1772 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1773 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1774 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1775 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001776 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001777
1778 cmd_ptr_vaddr = (uint32_t *)ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1779 cmdptrlist->cipher_des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1780
1781 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1782 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1783 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_key);
1784 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1785 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1786 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1787
1788 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1789 cmdptrlist->cipher_3des_cbc = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1790
1791 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1792 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1793 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1794 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_des_iv);
1795 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1796 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
Mona Hossainb8db7432011-11-17 12:33:24 -08001797 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
Mona Hossain3b574d82011-09-01 15:02:01 -07001798
1799 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1800 cmdptrlist->cipher_3des_ecb = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1801
1802 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1803 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1804 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_3des_key);
1805 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_cfg);
1806 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1807 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1808
1809 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1810 cmdptrlist->cipher_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1811
1812 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1813 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
Mona Hossainb8db7432011-11-17 12:33:24 -08001814
1815 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1816 cmdptrlist->cipher_ce_out_get_iv = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1817
1818 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1819 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_cipher_iv);
1820 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1821
Mona Hossain3b574d82011-09-01 15:02:01 -07001822 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1823
1824 return 0;
1825}
1826
1827static int _setup_auth_cmdptrlists(struct qce_device *pce_dev,
1828 unsigned char **pvaddr)
1829{
1830 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1831 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1832 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1833
1834 /*
1835 * Designate chunks of the allocated memory to various
1836 * command list pointers related to authentication operations
1837 * defined in ce_cmdptrlists_ops structure.
1838 */
1839 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1840 cmdptrlist->auth_sha1 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1841
1842 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1843 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1844 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1845 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1846 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1847 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1848 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1849 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1850 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1851 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1852 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1853 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1854
1855 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1856 cmdptrlist->auth_sha256 = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1857
1858 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1859 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1860 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1861 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1862 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1863 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1864 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1865 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1866 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1867 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1868 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1869 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1870
1871 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1872 cmdptrlist->auth_sha1_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1873
1874 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1875 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1876 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1877 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1878 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_20);
1879 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1880 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1881 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1882 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1883 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1884 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1885 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
1886 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1887
1888 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1889 cmdptrlist->auth_sha256_hmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1890
1891 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1892 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1893 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_512);
1894 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1895 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_iv_32);
1896 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_byte_count);
1897 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1898 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1899 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1900 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1901 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1902 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
1903 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1904
1905 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1906 cmdptrlist->auth_aes_128_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1907
1908 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1909 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1910 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1911 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1912 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1913 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1914 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1915 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1916 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1917 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1918 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1919 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1920 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1921 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1922
1923 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1924 cmdptrlist->auth_aes_256_cmac = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1925
1926 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1927 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_cipher_cfg);
1928 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1929 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1930 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1931 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1932 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1933 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1934 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
1935 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1936 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1937 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
1938 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_16);
1939 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1940
1941 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
1942
1943 return 0;
1944}
1945
1946static int _setup_aead_cmdptrlists(struct qce_device *pce_dev,
1947 unsigned char **pvaddr)
1948{
1949 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
1950 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
1951 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
1952
1953 /*
1954 * Designate chunks of the allocated memory to various
1955 * command list pointers related to aead operations
1956 * defined in ce_cmdptrlists_ops structure.
1957 */
1958 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1959 cmdptrlist->aead_aes_128_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1960
1961 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1962 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1963 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1964 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1965 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_128);
1966 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1967 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1968 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1969 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_128_key);
1970 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1971 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1972 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1973 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1974
1975 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1976 cmdptrlist->aead_aes_256_ccm = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1977
1978 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_seg_size_ocb);
1979 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_iv);
1980 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_key);
1981 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->reset_auth_byte_count);
1982 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_key_256);
1983 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_nonce_info);
1984 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_auth_cfg);
1985 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_cfg);
1986 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_256_key);
1987 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_aes_iv);
1988 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_cipher_mask);
1989 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->set_go_proc);
1990 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->ce_data_in);
1991
1992 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
1993 cmdptrlist->aead_ce_out = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
1994
1995 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_out);
1996 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1997 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
1998 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
1999
2000 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
2001
2002 return 0;
2003}
2004
2005static int qce_setup_cmdptrlists(struct qce_device *pce_dev,
2006 unsigned char **pvaddr)
2007{
2008 uint32_t * cmd_ptr_vaddr = (uint32_t *)(*pvaddr);
2009 struct ce_cmdlists *cmdlist = &pce_dev->ce_dm.cmdlist;
2010 struct ce_cmdptrlists_ops *cmdptrlist = &pce_dev->ce_dm.cmdptrlist;
2011 /*
2012 * Designate chunks of the allocated memory to various
2013 * command list pointers related to operations defined
2014 * in ce_cmdptrlists_ops structure.
2015 */
2016 cmd_ptr_vaddr = (uint32_t *) ALIGN(((unsigned int) cmd_ptr_vaddr), 16);
2017 cmdptrlist->probe_ce_hw = QCE_SET_CMD_PTR(cmd_ptr_vaddr);
2018
2019 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_hw_version);
Mona Hossainb8db7432011-11-17 12:33:24 -08002020 *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->clear_status);
Mona Hossain3b574d82011-09-01 15:02:01 -07002021 *cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
2022
2023 *pvaddr = (unsigned char *) cmd_ptr_vaddr;
2024
2025 _setup_cipher_cmdptrlists(pce_dev, pvaddr);
2026 _setup_auth_cmdptrlists(pce_dev, pvaddr);
2027 _setup_aead_cmdptrlists(pce_dev, pvaddr);
2028
2029 return 0;
2030}
2031
2032
2033static int qce_setup_ce_dm_data(struct qce_device *pce_dev)
2034{
2035 unsigned char *vaddr;
2036
2037 /* 1. ce_in channel data xfer command src descriptors, 128 entries */
2038 vaddr = pce_dev->coh_vmem;
2039 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2040 pce_dev->ce_dm.ce_in_src_desc = (struct dmov_desc *) vaddr;
2041 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2042
2043 /* 2. ce_in channel data xfer command dst descriptors, 128 entries */
2044 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2045 pce_dev->ce_dm.ce_in_dst_desc = (struct dmov_desc *) vaddr;
2046 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2047
2048
2049 /* 3. ce_out channel data xfer command src descriptors, 128 entries */
2050 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2051 pce_dev->ce_dm.ce_out_src_desc = (struct dmov_desc *) vaddr;
2052 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2053
2054 /* 4. ce_out channel data xfer command dst descriptors, 128 entries. */
2055 vaddr = (unsigned char *) ALIGN(((unsigned int)vaddr), 16);
2056 pce_dev->ce_dm.ce_out_dst_desc = (struct dmov_desc *) vaddr;
2057 vaddr = vaddr + (sizeof(struct dmov_desc) * QCE_MAX_NUM_DESC);
2058
2059 qce_setup_cmd_buffers(pce_dev, &vaddr);
2060 qce_setup_cmdlists(pce_dev, &vaddr);
2061 qce_setup_cmdptrlists(pce_dev, &vaddr);
2062
2063 pce_dev->ce_dm.buffer.ignore_data = vaddr;
2064
2065 pce_dev->ce_dm.phy_ce_pad = GET_PHYS_ADDR(pce_dev->ce_dm.buffer.pad);
2066 pce_dev->ce_dm.phy_ce_out_ignore =
2067 GET_PHYS_ADDR(pce_dev->ce_dm.buffer.ignore_data);
2068
2069 pce_dev->ce_dm.chan_ce_in_cmd->user = (void *) pce_dev;
2070 pce_dev->ce_dm.chan_ce_in_cmd->exec_func = NULL;
2071
2072 pce_dev->ce_dm.chan_ce_out_cmd->user = (void *) pce_dev;
2073 pce_dev->ce_dm.chan_ce_out_cmd->exec_func = NULL;
2074
2075 return 0;
2076}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002077
2078static int _qce_start_dma(struct qce_device *pce_dev, bool ce_in, bool ce_out)
2079{
2080
2081 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002082 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002083 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002084 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002085
2086 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002087 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IN_PROG;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002088 else
Mona Hossain3b574d82011-09-01 15:02:01 -07002089 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_COMP;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002090
2091 if (ce_in)
Mona Hossain3b574d82011-09-01 15:02:01 -07002092 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_in,
2093 pce_dev->ce_dm.chan_ce_in_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002094 if (ce_out)
Mona Hossain3b574d82011-09-01 15:02:01 -07002095 msm_dmov_enqueue_cmd(pce_dev->ce_dm.chan_ce_out,
2096 pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002097
2098 return 0;
2099};
2100
2101int qce_aead_req(void *handle, struct qce_req *q_req)
2102{
2103 struct qce_device *pce_dev = (struct qce_device *) handle;
2104 struct aead_request *areq = (struct aead_request *) q_req->areq;
2105 uint32_t authsize = q_req->authsize;
2106 uint32_t totallen_in, totallen_out, out_len;
2107 uint32_t pad_len_in, pad_len_out;
2108 uint32_t pad_mac_len_out, pad_ptx_len_out;
2109 int rc = 0;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002110 int ce_block_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002111
Mona Hossain5f5dde12011-09-12 10:28:34 -07002112 ce_block_size = pce_dev->ce_dm.ce_block_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002113 if (q_req->dir == QCE_ENCRYPT) {
2114 q_req->cryptlen = areq->cryptlen;
2115 totallen_in = q_req->cryptlen + areq->assoclen;
2116 totallen_out = q_req->cryptlen + authsize + areq->assoclen;
2117 out_len = areq->cryptlen + authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002118 pad_len_in = ALIGN(totallen_in, ce_block_size) - totallen_in;
2119 pad_mac_len_out = ALIGN(authsize, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002120 authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002121 pad_ptx_len_out = ALIGN(q_req->cryptlen, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002122 q_req->cryptlen;
2123 pad_len_out = pad_ptx_len_out + pad_mac_len_out;
2124 totallen_out += pad_len_out;
2125 } else {
2126 q_req->cryptlen = areq->cryptlen - authsize;
2127 totallen_in = areq->cryptlen + areq->assoclen;
2128 totallen_out = q_req->cryptlen + areq->assoclen;
2129 out_len = areq->cryptlen - authsize;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002130 pad_len_in = ALIGN(areq->cryptlen, ce_block_size) -
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002131 areq->cryptlen;
2132 pad_len_out = pad_len_in + authsize;
2133 totallen_out += pad_len_out;
2134 }
2135
2136 _chain_buffer_in_init(pce_dev);
2137 _chain_buffer_out_init(pce_dev);
2138
2139 pce_dev->assoc_nents = 0;
2140 pce_dev->src_nents = 0;
2141 pce_dev->dst_nents = 0;
2142 pce_dev->ivsize = q_req->ivsize;
2143 pce_dev->authsize = q_req->authsize;
2144
2145 /* associated data input */
2146 pce_dev->assoc_nents = count_sg(areq->assoc, areq->assoclen);
2147 dma_map_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
2148 DMA_TO_DEVICE);
2149 if (_chain_sg_buffer_in(pce_dev, areq->assoc, areq->assoclen) < 0) {
2150 rc = -ENOMEM;
2151 goto bad;
2152 }
2153 /* cipher input */
2154 pce_dev->src_nents = count_sg(areq->src, areq->cryptlen);
2155 dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2156 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2157 DMA_TO_DEVICE);
2158 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->cryptlen) < 0) {
2159 rc = -ENOMEM;
2160 goto bad;
2161 }
2162 /* pad data in */
2163 if (pad_len_in) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002164 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002165 pad_len_in) < 0) {
2166 rc = -ENOMEM;
2167 goto bad;
2168 }
2169 }
2170
2171 /* ignore associated data */
Mona Hossain3b574d82011-09-01 15:02:01 -07002172 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_out_ignore,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002173 areq->assoclen) < 0) {
2174 rc = -ENOMEM;
2175 goto bad;
2176 }
2177 /* cipher + mac output for encryption */
2178 if (areq->src != areq->dst) {
2179 pce_dev->dst_nents = count_sg(areq->dst, out_len);
2180 dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2181 DMA_FROM_DEVICE);
2182 };
2183 if (_chain_sg_buffer_out(pce_dev, areq->dst, out_len) < 0) {
2184 rc = -ENOMEM;
2185 goto bad;
2186 }
2187 /* pad data out */
2188 if (pad_len_out) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002189 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002190 pad_len_out) < 0) {
2191 rc = -ENOMEM;
2192 goto bad;
2193 }
2194 }
2195
2196 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain5f5dde12011-09-12 10:28:34 -07002197 _ce_in_final(pce_dev, ALIGN(totallen_in, ce_block_size));
2198 _ce_out_final(pce_dev, ALIGN(totallen_out, ce_block_size));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002199
2200 /* set up crypto device */
2201 rc = _ce_setup_cipher(pce_dev, q_req, totallen_in, areq->assoclen);
2202 if (rc < 0)
2203 goto bad;
2204
2205 /* setup for callback, and issue command to adm */
2206 pce_dev->areq = q_req->areq;
2207 pce_dev->qce_cb = q_req->qce_cb;
2208
Mona Hossain3b574d82011-09-01 15:02:01 -07002209 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _aead_ce_in_call_back;
2210 pce_dev->ce_dm.chan_ce_out_cmd->complete_func = _aead_ce_out_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002211
2212 _ce_in_dump(pce_dev);
2213 _ce_out_dump(pce_dev);
2214
2215 rc = _qce_start_dma(pce_dev, true, true);
2216 if (rc == 0)
2217 return 0;
2218bad:
2219 if (pce_dev->assoc_nents) {
2220 dma_unmap_sg(pce_dev->pdev, areq->assoc, pce_dev->assoc_nents,
2221 DMA_TO_DEVICE);
2222 }
2223
2224 if (pce_dev->src_nents) {
2225 dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2226 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2227 DMA_TO_DEVICE);
2228 }
2229 if (pce_dev->dst_nents) {
2230 dma_unmap_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2231 DMA_FROM_DEVICE);
2232 }
2233 return rc;
2234}
2235EXPORT_SYMBOL(qce_aead_req);
2236
2237int qce_ablk_cipher_req(void *handle, struct qce_req *c_req)
2238{
2239 int rc = 0;
2240 struct qce_device *pce_dev = (struct qce_device *) handle;
2241 struct ablkcipher_request *areq = (struct ablkcipher_request *)
2242 c_req->areq;
2243
Mona Hossain5f5dde12011-09-12 10:28:34 -07002244 uint32_t pad_len = ALIGN(areq->nbytes, pce_dev->ce_dm.ce_block_size)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002245 - areq->nbytes;
2246
2247 _chain_buffer_in_init(pce_dev);
2248 _chain_buffer_out_init(pce_dev);
2249
2250 pce_dev->src_nents = 0;
2251 pce_dev->dst_nents = 0;
2252
2253 /* cipher input */
2254 pce_dev->src_nents = count_sg(areq->src, areq->nbytes);
2255
2256 if (c_req->use_pmem != 1)
2257 dma_map_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
2258 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
2259 DMA_TO_DEVICE);
2260 else
2261 dma_map_pmem_sg(&c_req->pmem->src[0], pce_dev->src_nents,
2262 areq->src);
2263
2264 if (_chain_sg_buffer_in(pce_dev, areq->src, areq->nbytes) < 0) {
2265 rc = -ENOMEM;
2266 goto bad;
2267 }
2268
2269 /* cipher output */
2270 if (areq->src != areq->dst) {
2271 pce_dev->dst_nents = count_sg(areq->dst, areq->nbytes);
2272 if (c_req->use_pmem != 1)
2273 dma_map_sg(pce_dev->pdev, areq->dst, pce_dev->dst_nents,
2274 DMA_FROM_DEVICE);
2275 else
2276 dma_map_pmem_sg(&c_req->pmem->dst[0],
2277 pce_dev->dst_nents, areq->dst);
2278 };
2279 if (_chain_sg_buffer_out(pce_dev, areq->dst, areq->nbytes) < 0) {
2280 rc = -ENOMEM;
2281 goto bad;
2282 }
2283
2284 /* pad data */
2285 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002286 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002287 pad_len) < 0) {
2288 rc = -ENOMEM;
2289 goto bad;
2290 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002291 if (_chain_pm_buffer_out(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002292 pad_len) < 0) {
2293 rc = -ENOMEM;
2294 goto bad;
2295 }
2296 }
2297
2298 /* finalize the ce_in and ce_out channels command lists */
Mona Hossain2563cbc2011-09-14 15:24:08 -07002299 _ce_in_final(pce_dev, areq->nbytes + pad_len);
2300 _ce_out_final(pce_dev, areq->nbytes + pad_len);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002301
2302 _ce_in_dump(pce_dev);
2303 _ce_out_dump(pce_dev);
2304
2305 /* set up crypto device */
2306 rc = _ce_setup_cipher(pce_dev, c_req, areq->nbytes, 0);
2307 if (rc < 0)
2308 goto bad;
2309
2310 /* setup for callback, and issue command to adm */
2311 pce_dev->areq = areq;
2312 pce_dev->qce_cb = c_req->qce_cb;
2313 if (c_req->use_pmem == 1) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002314 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002315 _ablk_cipher_ce_in_call_back_pmem;
Mona Hossain3b574d82011-09-01 15:02:01 -07002316 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002317 _ablk_cipher_ce_out_call_back_pmem;
2318 } else {
Mona Hossain3b574d82011-09-01 15:02:01 -07002319 pce_dev->ce_dm.chan_ce_in_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002320 _ablk_cipher_ce_in_call_back;
Mona Hossain3b574d82011-09-01 15:02:01 -07002321 pce_dev->ce_dm.chan_ce_out_cmd->complete_func =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002322 _ablk_cipher_ce_out_call_back;
2323 }
2324 rc = _qce_start_dma(pce_dev, true, true);
2325
2326 if (rc == 0)
2327 return 0;
2328bad:
2329 if (c_req->use_pmem != 1) {
2330 if (pce_dev->dst_nents) {
2331 dma_unmap_sg(pce_dev->pdev, areq->dst,
2332 pce_dev->dst_nents, DMA_FROM_DEVICE);
2333 }
2334 if (pce_dev->src_nents) {
2335 dma_unmap_sg(pce_dev->pdev, areq->src,
2336 pce_dev->src_nents,
2337 (areq->src == areq->dst) ?
2338 DMA_BIDIRECTIONAL :
2339 DMA_TO_DEVICE);
2340 }
2341 }
2342 return rc;
2343}
2344EXPORT_SYMBOL(qce_ablk_cipher_req);
2345
2346int qce_process_sha_req(void *handle, struct qce_sha_req *sreq)
2347{
2348 struct qce_device *pce_dev = (struct qce_device *) handle;
2349 int rc;
Mona Hossain5f5dde12011-09-12 10:28:34 -07002350 uint32_t pad_len = ALIGN(sreq->size, pce_dev->ce_dm.ce_block_size) -
2351 sreq->size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002352 struct ahash_request *areq = (struct ahash_request *)sreq->areq;
2353
2354 _chain_buffer_in_init(pce_dev);
2355 pce_dev->src_nents = count_sg(sreq->src, sreq->size);
2356 dma_map_sg(pce_dev->pdev, sreq->src, pce_dev->src_nents,
2357 DMA_TO_DEVICE);
2358
2359 if (_chain_sg_buffer_in(pce_dev, sreq->src, sreq->size) < 0) {
2360 rc = -ENOMEM;
2361 goto bad;
2362 }
2363
2364 if (pad_len) {
Mona Hossain3b574d82011-09-01 15:02:01 -07002365 if (_chain_pm_buffer_in(pce_dev, pce_dev->ce_dm.phy_ce_pad,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002366 pad_len) < 0) {
2367 rc = -ENOMEM;
2368 goto bad;
2369 }
2370 }
Mona Hossain2563cbc2011-09-14 15:24:08 -07002371 _ce_in_final(pce_dev, sreq->size + pad_len);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002372
2373 _ce_in_dump(pce_dev);
2374
Mona Hossain3b574d82011-09-01 15:02:01 -07002375 rc = _ce_setup_hash(pce_dev, sreq);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002376
2377 if (rc < 0)
2378 goto bad;
2379
2380 pce_dev->areq = areq;
2381 pce_dev->qce_cb = sreq->qce_cb;
Mona Hossain3b574d82011-09-01 15:02:01 -07002382 pce_dev->ce_dm.chan_ce_in_cmd->complete_func = _sha_ce_in_call_back;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002383
2384 rc = _qce_start_dma(pce_dev, true, false);
2385
2386 if (rc == 0)
2387 return 0;
2388bad:
2389 if (pce_dev->src_nents) {
2390 dma_unmap_sg(pce_dev->pdev, sreq->src,
2391 pce_dev->src_nents, DMA_TO_DEVICE);
2392 }
2393
2394 return rc;
2395}
2396EXPORT_SYMBOL(qce_process_sha_req);
2397
2398/* crypto engine open function. */
2399void *qce_open(struct platform_device *pdev, int *rc)
2400{
2401 struct qce_device *pce_dev;
2402 struct resource *resource;
2403 struct clk *ce_core_clk;
2404 struct clk *ce_clk;
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002405 struct clk *ce_core_src_clk;
2406 int ret = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002407
2408 pce_dev = kzalloc(sizeof(struct qce_device), GFP_KERNEL);
2409 if (!pce_dev) {
2410 *rc = -ENOMEM;
2411 dev_err(&pdev->dev, "Can not allocate memory\n");
2412 return NULL;
2413 }
2414 pce_dev->pdev = &pdev->dev;
2415
2416 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2417 if (!resource) {
2418 *rc = -ENXIO;
2419 dev_err(pce_dev->pdev, "Missing MEM resource\n");
2420 goto err_pce_dev;
2421 };
2422 pce_dev->phy_iobase = resource->start;
2423 pce_dev->iobase = ioremap_nocache(resource->start,
2424 resource->end - resource->start + 1);
2425 if (!pce_dev->iobase) {
2426 *rc = -ENOMEM;
2427 dev_err(pce_dev->pdev, "Can not map io memory\n");
2428 goto err_pce_dev;
2429 }
2430
Mona Hossain3b574d82011-09-01 15:02:01 -07002431 pce_dev->ce_dm.chan_ce_in_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002432 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002433 pce_dev->ce_dm.chan_ce_out_cmd = kzalloc(sizeof(struct msm_dmov_cmd),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002434 GFP_KERNEL);
Mona Hossain3b574d82011-09-01 15:02:01 -07002435 if (pce_dev->ce_dm.chan_ce_in_cmd == NULL ||
2436 pce_dev->ce_dm.chan_ce_out_cmd == NULL) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002437 dev_err(pce_dev->pdev, "Can not allocate memory\n");
2438 *rc = -ENOMEM;
2439 goto err_dm_chan_cmd;
2440 }
2441
2442 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2443 "crypto_channels");
2444 if (!resource) {
2445 *rc = -ENXIO;
2446 dev_err(pce_dev->pdev, "Missing DMA channel resource\n");
2447 goto err_dm_chan_cmd;
2448 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002449 pce_dev->ce_dm.chan_ce_in = resource->start;
2450 pce_dev->ce_dm.chan_ce_out = resource->end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002451 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2452 "crypto_crci_in");
2453 if (!resource) {
2454 *rc = -ENXIO;
2455 dev_err(pce_dev->pdev, "Missing DMA crci in resource\n");
2456 goto err_dm_chan_cmd;
2457 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002458 pce_dev->ce_dm.crci_in = resource->start;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002459 resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
2460 "crypto_crci_out");
2461 if (!resource) {
2462 *rc = -ENXIO;
2463 dev_err(pce_dev->pdev, "Missing DMA crci out resource\n");
2464 goto err_dm_chan_cmd;
2465 };
Mona Hossain3b574d82011-09-01 15:02:01 -07002466 pce_dev->ce_dm.crci_out = resource->start;
2467 pce_dev->memsize = 2 * PAGE_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002468 pce_dev->coh_vmem = dma_alloc_coherent(pce_dev->pdev,
Mona Hossain3b574d82011-09-01 15:02:01 -07002469 pce_dev->memsize, &pce_dev->coh_pmem, GFP_KERNEL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002470
2471 if (pce_dev->coh_vmem == NULL) {
2472 *rc = -ENOMEM;
2473 dev_err(pce_dev->pdev, "Can not allocate coherent memory.\n");
2474 goto err;
2475 }
2476
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002477 /* Get CE3 src core clk. */
2478 ce_core_src_clk = clk_get(pce_dev->pdev, "ce3_core_src_clk");
2479 if (!IS_ERR(ce_core_src_clk)) {
2480 pce_dev->ce_core_src_clk = ce_core_src_clk;
2481
2482 /* Set the core src clk @100Mhz */
2483 ret = clk_set_rate(pce_dev->ce_core_src_clk, 100000000);
2484 if (ret) {
2485 clk_put(pce_dev->ce_core_src_clk);
2486 goto err;
2487 }
2488 } else
2489 pce_dev->ce_core_src_clk = NULL;
2490
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002491 /* Get CE core clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002492 ce_core_clk = clk_get(pce_dev->pdev, "core_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002493 if (IS_ERR(ce_core_clk)) {
2494 *rc = PTR_ERR(ce_core_clk);
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002495 if (pce_dev->ce_core_src_clk != NULL)
2496 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002497 goto err;
2498 }
2499 pce_dev->ce_core_clk = ce_core_clk;
2500 /* Get CE clk */
Matt Wagantallc4b3a4d2011-08-17 16:58:39 -07002501 ce_clk = clk_get(pce_dev->pdev, "iface_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002502 if (IS_ERR(ce_clk)) {
2503 *rc = PTR_ERR(ce_clk);
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002504 if (pce_dev->ce_core_src_clk != NULL)
2505 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002506 clk_put(pce_dev->ce_core_clk);
2507 goto err;
2508 }
2509 pce_dev->ce_clk = ce_clk;
2510
2511 /* Enable CE core clk */
2512 *rc = clk_enable(pce_dev->ce_core_clk);
2513 if (*rc) {
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002514 if (pce_dev->ce_core_src_clk != NULL)
2515 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002516 clk_put(pce_dev->ce_core_clk);
2517 clk_put(pce_dev->ce_clk);
2518 goto err;
2519 } else {
2520 /* Enable CE clk */
2521 *rc = clk_enable(pce_dev->ce_clk);
2522 if (*rc) {
2523 clk_disable(pce_dev->ce_core_clk);
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002524 if (pce_dev->ce_core_src_clk != NULL)
2525 clk_put(pce_dev->ce_core_src_clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002526 clk_put(pce_dev->ce_core_clk);
2527 clk_put(pce_dev->ce_clk);
2528 goto err;
2529
2530 }
2531 }
Mona Hossain3b574d82011-09-01 15:02:01 -07002532 qce_setup_ce_dm_data(pce_dev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002533
Mona Hossain3b574d82011-09-01 15:02:01 -07002534 pce_dev->ce_dm.chan_ce_in_state = QCE_CHAN_STATE_IDLE;
2535 pce_dev->ce_dm.chan_ce_out_state = QCE_CHAN_STATE_IDLE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002536 if (_init_ce_engine(pce_dev)) {
2537 *rc = -ENXIO;
2538 goto err;
2539 }
2540 *rc = 0;
2541 return pce_dev;
2542
2543err:
2544 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002545 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
Mona Hossaine1b13f82011-08-30 09:35:49 -07002546 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002547err_dm_chan_cmd:
Mona Hossain3b574d82011-09-01 15:02:01 -07002548 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2549 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002550 if (pce_dev->iobase)
2551 iounmap(pce_dev->iobase);
2552
2553err_pce_dev:
2554
2555 kfree(pce_dev);
2556
2557 return NULL;
2558}
2559EXPORT_SYMBOL(qce_open);
2560
2561/* crypto engine close function. */
2562int qce_close(void *handle)
2563{
2564 struct qce_device *pce_dev = (struct qce_device *) handle;
2565
2566 if (handle == NULL)
2567 return -ENODEV;
2568 if (pce_dev->iobase)
2569 iounmap(pce_dev->iobase);
2570
2571 if (pce_dev->coh_vmem)
Mona Hossain3b574d82011-09-01 15:02:01 -07002572 dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
2573 pce_dev->coh_vmem, pce_dev->coh_pmem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002574 clk_disable(pce_dev->ce_clk);
2575 clk_disable(pce_dev->ce_core_clk);
2576
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002577 if (pce_dev->ce_core_src_clk != NULL)
2578 clk_put(pce_dev->ce_core_src_clk);
2579
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002580 clk_put(pce_dev->ce_clk);
2581 clk_put(pce_dev->ce_core_clk);
2582
Mona Hossain3b574d82011-09-01 15:02:01 -07002583 kfree(pce_dev->ce_dm.chan_ce_in_cmd);
2584 kfree(pce_dev->ce_dm.chan_ce_out_cmd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002585 kfree(handle);
2586
2587 return 0;
2588}
2589EXPORT_SYMBOL(qce_close);
2590
2591int qce_hw_support(void *handle, struct ce_hw_support *ce_support)
2592{
2593 if (ce_support == NULL)
2594 return -EINVAL;
2595
2596 ce_support->sha1_hmac_20 = false;
2597 ce_support->sha1_hmac = false;
2598 ce_support->sha256_hmac = false;
2599 ce_support->sha_hmac = false;
2600 ce_support->cmac = true;
2601 ce_support->aes_key_192 = false;
2602 ce_support->aes_xts = true;
2603 ce_support->aes_ccm = true;
2604 ce_support->ota = false;
2605 return 0;
2606}
2607EXPORT_SYMBOL(qce_hw_support);
2608
2609MODULE_LICENSE("GPL v2");
2610MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
2611MODULE_DESCRIPTION("Crypto Engine driver");
Ramesh Masavarapu28311912011-10-27 11:04:12 -07002612MODULE_VERSION("2.14");