2 * Copyright 2016 Broadcom
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2, as
6 * published by the Free Software Foundation (the "GPL").
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License version 2 (GPLv2) for more details.
13 * You should have received a copy of the GNU General Public License
14 * version 2 (GPLv2) along with this source code.
17 #include <linux/debugfs.h>
22 /* offset of SPU_OFIFO_CTRL register */
23 #define SPU_OFIFO_CTRL 0x40
24 #define SPU_FIFO_WATERMARK 0x1FF
27 * spu_sg_at_offset() - Find the scatterlist entry at a given distance from the
28 * start of a scatterlist.
29 * @sg: [in] Start of a scatterlist
30 * @skip: [in] Distance from the start of the scatterlist, in bytes
31 * @sge: [out] Scatterlist entry at skip bytes from start
32 * @sge_offset: [out] Number of bytes from start of sge buffer to get to
35 * Return: 0 if entry found at requested distance
38 int spu_sg_at_offset(struct scatterlist
*sg
, unsigned int skip
,
39 struct scatterlist
**sge
, unsigned int *sge_offset
)
41 /* byte index from start of sg to the end of the previous entry */
42 unsigned int index
= 0;
43 /* byte index from start of sg to the end of the current entry */
44 unsigned int next_index
;
46 next_index
= sg
->length
;
47 while (next_index
<= skip
) {
52 next_index
+= sg
->length
;
55 *sge_offset
= skip
- index
;
60 /* Copy len bytes of sg data, starting at offset skip, to a dest buffer */
61 void sg_copy_part_to_buf(struct scatterlist
*src
, u8
*dest
,
62 unsigned int len
, unsigned int skip
)
65 unsigned int nents
= sg_nents(src
);
67 copied
= sg_pcopy_to_buffer(src
, nents
, dest
, len
, skip
);
69 flow_log("%s copied %u bytes of %u requested. ",
70 __func__
, (u32
)copied
, len
);
71 flow_log("sg with %u entries and skip %u\n", nents
, skip
);
76 * Copy data into a scatterlist starting at a specified offset in the
77 * scatterlist. Specifically, copy len bytes of data in the buffer src
78 * into the scatterlist dest, starting skip bytes into the scatterlist.
80 void sg_copy_part_from_buf(struct scatterlist
*dest
, u8
*src
,
81 unsigned int len
, unsigned int skip
)
84 unsigned int nents
= sg_nents(dest
);
86 copied
= sg_pcopy_from_buffer(dest
, nents
, src
, len
, skip
);
88 flow_log("%s copied %u bytes of %u requested. ",
89 __func__
, (u32
)copied
, len
);
90 flow_log("sg with %u entries and skip %u\n", nents
, skip
);
95 * spu_sg_count() - Determine number of elements in scatterlist to provide a
96 * specified number of bytes.
97 * @sg_list: scatterlist to examine
98 * @skip: index of starting point
99 * @nbytes: consider elements of scatterlist until reaching this number of
102 * Return: the number of sg entries contributing to nbytes of data
104 int spu_sg_count(struct scatterlist
*sg_list
, unsigned int skip
, int nbytes
)
106 struct scatterlist
*sg
;
113 if (spu_sg_at_offset(sg_list
, skip
, &sg
, &offset
) < 0)
116 while (sg
&& (nbytes
> 0)) {
118 nbytes
-= (sg
->length
- offset
);
126 * spu_msg_sg_add() - Copy scatterlist entries from one sg to another, up to a
128 * @to_sg: scatterlist to copy to
129 * @from_sg: scatterlist to copy from
130 * @from_skip: number of bytes to skip in from_sg. Non-zero when previous
131 * request included part of the buffer in entry in from_sg.
132 * Assumes from_skip < from_sg->length.
133 * @from_nents number of entries in from_sg
134 * @length number of bytes to copy. may reach this limit before exhausting
137 * Copies the entries themselves, not the data in the entries. Assumes to_sg has
138 * enough entries. Does not limit the size of an individual buffer in to_sg.
140 * to_sg, from_sg, skip are all updated to end of copy
142 * Return: Number of bytes copied
144 u32
spu_msg_sg_add(struct scatterlist
**to_sg
,
145 struct scatterlist
**from_sg
, u32
*from_skip
,
146 u8 from_nents
, u32 length
)
148 struct scatterlist
*sg
; /* an entry in from_sg */
149 struct scatterlist
*to
= *to_sg
;
150 struct scatterlist
*from
= *from_sg
;
151 u32 skip
= *from_skip
;
155 u32 frag_len
= 0; /* length of entry added to to_sg */
156 u32 copied
= 0; /* number of bytes copied so far */
161 for_each_sg(from
, sg
, from_nents
, i
) {
162 /* number of bytes in this from entry not yet used */
163 entry_len
= sg
->length
- skip
;
164 frag_len
= min(entry_len
, length
- copied
);
165 offset
= sg
->offset
+ skip
;
167 sg_set_page(to
++, sg_page(sg
), frag_len
, offset
);
169 if (copied
== entry_len
) {
170 /* used up all of from entry */
171 skip
= 0; /* start at beginning of next entry */
173 if (copied
== length
)
178 if (frag_len
< entry_len
)
179 *from_skip
= skip
+ frag_len
;
186 void add_to_ctr(u8
*ctr_pos
, unsigned int increment
)
188 __be64
*high_be
= (__be64
*)ctr_pos
;
189 __be64
*low_be
= high_be
+ 1;
190 u64 orig_low
= __be64_to_cpu(*low_be
);
191 u64 new_low
= orig_low
+ (u64
)increment
;
193 *low_be
= __cpu_to_be64(new_low
);
194 if (new_low
< orig_low
)
195 /* there was a carry from the low 8 bytes */
196 *high_be
= __cpu_to_be64(__be64_to_cpu(*high_be
) + 1);
200 struct shash_desc shash
;
204 /* do a synchronous decrypt operation */
205 int do_decrypt(char *alg_name
,
206 void *key_ptr
, unsigned int key_len
,
207 void *iv_ptr
, void *src_ptr
, void *dst_ptr
,
208 unsigned int block_len
)
210 struct scatterlist sg_in
[1], sg_out
[1];
211 struct crypto_blkcipher
*tfm
=
212 crypto_alloc_blkcipher(alg_name
, 0, CRYPTO_ALG_ASYNC
);
213 struct blkcipher_desc desc
= {.tfm
= tfm
, .flags
= 0 };
218 flow_log("%s() name:%s block_len:%u\n", __func__
, alg_name
, block_len
);
223 crypto_blkcipher_setkey((void *)tfm
, key_ptr
, key_len
);
225 sg_init_table(sg_in
, 1);
226 sg_set_buf(sg_in
, src_ptr
, block_len
);
228 sg_init_table(sg_out
, 1);
229 sg_set_buf(sg_out
, dst_ptr
, block_len
);
231 iv
= crypto_blkcipher_crt(tfm
)->iv
;
232 ivsize
= crypto_blkcipher_ivsize(tfm
);
233 memcpy(iv
, iv_ptr
, ivsize
);
235 ret
= crypto_blkcipher_decrypt(&desc
, sg_out
, sg_in
, block_len
);
236 crypto_free_blkcipher(tfm
);
239 pr_err("aes_decrypt failed %d\n", ret
);
245 * do_shash() - Do a synchronous hash operation in software
246 * @name: The name of the hash algorithm
247 * @result: Buffer where digest is to be written
248 * @data1: First part of data to hash. May be NULL.
249 * @data1_len: Length of data1, in bytes
250 * @data2: Second part of data to hash. May be NULL.
251 * @data2_len: Length of data2, in bytes
252 * @key: Key (if keyed hash)
253 * @key_len: Length of key, in bytes (or 0 if non-keyed hash)
255 * Note that the crypto API will not select this driver's own transform because
256 * this driver only registers asynchronous algos.
258 * Return: 0 if hash successfully stored in result
261 int do_shash(unsigned char *name
, unsigned char *result
,
262 const u8
*data1
, unsigned int data1_len
,
263 const u8
*data2
, unsigned int data2_len
,
264 const u8
*key
, unsigned int key_len
)
268 struct crypto_shash
*hash
;
271 hash
= crypto_alloc_shash(name
, 0, 0);
274 pr_err("%s: Crypto %s allocation error %d", __func__
, name
, rc
);
278 size
= sizeof(struct shash_desc
) + crypto_shash_descsize(hash
);
279 sdesc
= kmalloc(size
, GFP_KERNEL
);
282 pr_err("%s: Memory allocation failure", __func__
);
285 sdesc
->shash
.tfm
= hash
;
286 sdesc
->shash
.flags
= 0x0;
289 rc
= crypto_shash_setkey(hash
, key
, key_len
);
291 pr_err("%s: Could not setkey %s shash", __func__
, name
);
296 rc
= crypto_shash_init(&sdesc
->shash
);
298 pr_err("%s: Could not init %s shash", __func__
, name
);
301 rc
= crypto_shash_update(&sdesc
->shash
, data1
, data1_len
);
303 pr_err("%s: Could not update1", __func__
);
306 if (data2
&& data2_len
) {
307 rc
= crypto_shash_update(&sdesc
->shash
, data2
, data2_len
);
309 pr_err("%s: Could not update2", __func__
);
313 rc
= crypto_shash_final(&sdesc
->shash
, result
);
315 pr_err("%s: Could not generate %s hash", __func__
, name
);
318 crypto_free_shash(hash
);
324 /* Dump len bytes of a scatterlist starting at skip bytes into the sg */
325 void __dump_sg(struct scatterlist
*sg
, unsigned int skip
, unsigned int len
)
328 unsigned int idx
= skip
;
329 unsigned int num_out
= 0; /* number of bytes dumped so far */
332 if (packet_debug_logging
) {
333 while (num_out
< len
) {
334 count
= (len
- num_out
> 16) ? 16 : len
- num_out
;
335 sg_copy_part_to_buf(sg
, dbuf
, count
, idx
);
337 print_hex_dump(KERN_ALERT
, " sg: ", DUMP_PREFIX_NONE
,
338 4, 1, dbuf
, count
, false);
342 if (debug_logging_sleep
)
343 msleep(debug_logging_sleep
);
346 /* Returns the name for a given cipher alg/mode */
347 char *spu_alg_name(enum spu_cipher_alg alg
, enum spu_cipher_mode mode
)
354 case CIPHER_MODE_CBC
:
356 case CIPHER_MODE_ECB
:
358 case CIPHER_MODE_OFB
:
360 case CIPHER_MODE_CFB
:
362 case CIPHER_MODE_CTR
:
364 case CIPHER_MODE_XTS
:
366 case CIPHER_MODE_GCM
:
374 case CIPHER_MODE_CBC
:
376 case CIPHER_MODE_ECB
:
378 case CIPHER_MODE_CTR
:
384 case CIPHER_ALG_3DES
:
386 case CIPHER_MODE_CBC
:
387 return "cbc(des3_ede)";
388 case CIPHER_MODE_ECB
:
389 return "ecb(des3_ede)";
390 case CIPHER_MODE_CTR
:
391 return "ctr(des3_ede)";
401 static ssize_t
spu_debugfs_read(struct file
*filp
, char __user
*ubuf
,
402 size_t count
, loff_t
*offp
)
404 struct device_private
*ipriv
;
406 ssize_t ret
, out_offset
, out_count
;
416 buf
= kmalloc(out_count
, GFP_KERNEL
);
420 ipriv
= filp
->private_data
;
422 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
423 "Number of SPUs.........%u\n",
425 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
426 "Current sessions.......%u\n",
427 atomic_read(&ipriv
->session_count
));
428 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
429 "Session count..........%u\n",
430 atomic_read(&ipriv
->stream_count
));
431 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
432 "Cipher setkey..........%u\n",
433 atomic_read(&ipriv
->setkey_cnt
[SPU_OP_CIPHER
]));
434 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
435 "Cipher Ops.............%u\n",
436 atomic_read(&ipriv
->op_counts
[SPU_OP_CIPHER
]));
437 for (alg
= 0; alg
< CIPHER_ALG_LAST
; alg
++) {
438 for (mode
= 0; mode
< CIPHER_MODE_LAST
; mode
++) {
439 op_cnt
= atomic_read(&ipriv
->cipher_cnt
[alg
][mode
]);
441 out_offset
+= snprintf(buf
+ out_offset
,
442 out_count
- out_offset
,
444 spu_alg_name(alg
, mode
), op_cnt
);
448 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
449 "Hash Ops...............%u\n",
450 atomic_read(&ipriv
->op_counts
[SPU_OP_HASH
]));
451 for (alg
= 0; alg
< HASH_ALG_LAST
; alg
++) {
452 op_cnt
= atomic_read(&ipriv
->hash_cnt
[alg
]);
454 out_offset
+= snprintf(buf
+ out_offset
,
455 out_count
- out_offset
,
457 hash_alg_name
[alg
], op_cnt
);
460 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
461 "HMAC setkey............%u\n",
462 atomic_read(&ipriv
->setkey_cnt
[SPU_OP_HMAC
]));
463 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
464 "HMAC Ops...............%u\n",
465 atomic_read(&ipriv
->op_counts
[SPU_OP_HMAC
]));
466 for (alg
= 0; alg
< HASH_ALG_LAST
; alg
++) {
467 op_cnt
= atomic_read(&ipriv
->hmac_cnt
[alg
]);
469 out_offset
+= snprintf(buf
+ out_offset
,
470 out_count
- out_offset
,
472 hash_alg_name
[alg
], op_cnt
);
475 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
476 "AEAD setkey............%u\n",
477 atomic_read(&ipriv
->setkey_cnt
[SPU_OP_AEAD
]));
479 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
480 "AEAD Ops...............%u\n",
481 atomic_read(&ipriv
->op_counts
[SPU_OP_AEAD
]));
482 for (alg
= 0; alg
< AEAD_TYPE_LAST
; alg
++) {
483 op_cnt
= atomic_read(&ipriv
->aead_cnt
[alg
]);
485 out_offset
+= snprintf(buf
+ out_offset
,
486 out_count
- out_offset
,
488 aead_alg_name
[alg
], op_cnt
);
491 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
492 "Bytes of req data......%llu\n",
493 (u64
)atomic64_read(&ipriv
->bytes_out
));
494 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
495 "Bytes of resp data.....%llu\n",
496 (u64
)atomic64_read(&ipriv
->bytes_in
));
497 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
498 "Mailbox full...........%u\n",
499 atomic_read(&ipriv
->mb_no_spc
));
500 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
501 "Mailbox send failures..%u\n",
502 atomic_read(&ipriv
->mb_send_fail
));
503 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
504 "Check ICV errors.......%u\n",
505 atomic_read(&ipriv
->bad_icv
));
506 if (ipriv
->spu
.spu_type
== SPU_TYPE_SPUM
)
507 for (i
= 0; i
< ipriv
->spu
.num_spu
; i
++) {
508 spu_ofifo_ctrl
= ioread32(ipriv
->spu
.reg_vbase
[i
] +
510 fifo_len
= spu_ofifo_ctrl
& SPU_FIFO_WATERMARK
;
511 out_offset
+= snprintf(buf
+ out_offset
,
512 out_count
- out_offset
,
513 "SPU %d output FIFO high water.....%u\n",
517 if (out_offset
> out_count
)
518 out_offset
= out_count
;
520 ret
= simple_read_from_buffer(ubuf
, count
, offp
, buf
, out_offset
);
525 static const struct file_operations spu_debugfs_stats
= {
526 .owner
= THIS_MODULE
,
528 .read
= spu_debugfs_read
,
532 * Create the debug FS directories. If the top-level directory has not yet
533 * been created, create it now. Create a stats file in this directory for
536 void spu_setup_debugfs(void)
538 if (!debugfs_initialized())
541 if (!iproc_priv
.debugfs_dir
)
542 iproc_priv
.debugfs_dir
= debugfs_create_dir(KBUILD_MODNAME
,
545 if (!iproc_priv
.debugfs_stats
)
546 /* Create file with permissions S_IRUSR */
547 debugfs_create_file("stats", 0400, iproc_priv
.debugfs_dir
,
548 &iproc_priv
, &spu_debugfs_stats
);
551 void spu_free_debugfs(void)
553 debugfs_remove_recursive(iproc_priv
.debugfs_dir
);
554 iproc_priv
.debugfs_dir
= NULL
;
558 * format_value_ccm() - Format a value into a buffer, using a specified number
559 * of bytes (i.e. maybe writing value X into a 4 byte
560 * buffer, or maybe into a 12 byte buffer), as per the
563 * @val: value to write (up to max of unsigned int)
564 * @buf: (pointer to) buffer to write the value
565 * @len: number of bytes to use (0 to 255)
568 void format_value_ccm(unsigned int val
, u8
*buf
, u8 len
)
572 /* First clear full output buffer */
575 /* Then, starting from right side, fill in with data */
576 for (i
= 0; i
< len
; i
++) {
577 buf
[len
- i
- 1] = (val
>> (8 * i
)) & 0xff;
579 break; /* Only handle up to 32 bits of 'val' */