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
;
205 * do_shash() - Do a synchronous hash operation in software
206 * @name: The name of the hash algorithm
207 * @result: Buffer where digest is to be written
208 * @data1: First part of data to hash. May be NULL.
209 * @data1_len: Length of data1, in bytes
210 * @data2: Second part of data to hash. May be NULL.
211 * @data2_len: Length of data2, in bytes
212 * @key: Key (if keyed hash)
213 * @key_len: Length of key, in bytes (or 0 if non-keyed hash)
215 * Note that the crypto API will not select this driver's own transform because
216 * this driver only registers asynchronous algos.
218 * Return: 0 if hash successfully stored in result
221 int do_shash(unsigned char *name
, unsigned char *result
,
222 const u8
*data1
, unsigned int data1_len
,
223 const u8
*data2
, unsigned int data2_len
,
224 const u8
*key
, unsigned int key_len
)
228 struct crypto_shash
*hash
;
231 hash
= crypto_alloc_shash(name
, 0, 0);
234 pr_err("%s: Crypto %s allocation error %d\n", __func__
, name
, rc
);
238 size
= sizeof(struct shash_desc
) + crypto_shash_descsize(hash
);
239 sdesc
= kmalloc(size
, GFP_KERNEL
);
244 sdesc
->shash
.tfm
= hash
;
245 sdesc
->shash
.flags
= 0x0;
248 rc
= crypto_shash_setkey(hash
, key
, key_len
);
250 pr_err("%s: Could not setkey %s shash\n", __func__
, name
);
255 rc
= crypto_shash_init(&sdesc
->shash
);
257 pr_err("%s: Could not init %s shash\n", __func__
, name
);
260 rc
= crypto_shash_update(&sdesc
->shash
, data1
, data1_len
);
262 pr_err("%s: Could not update1\n", __func__
);
265 if (data2
&& data2_len
) {
266 rc
= crypto_shash_update(&sdesc
->shash
, data2
, data2_len
);
268 pr_err("%s: Could not update2\n", __func__
);
272 rc
= crypto_shash_final(&sdesc
->shash
, result
);
274 pr_err("%s: Could not generate %s hash\n", __func__
, name
);
277 crypto_free_shash(hash
);
283 /* Dump len bytes of a scatterlist starting at skip bytes into the sg */
284 void __dump_sg(struct scatterlist
*sg
, unsigned int skip
, unsigned int len
)
287 unsigned int idx
= skip
;
288 unsigned int num_out
= 0; /* number of bytes dumped so far */
291 if (packet_debug_logging
) {
292 while (num_out
< len
) {
293 count
= (len
- num_out
> 16) ? 16 : len
- num_out
;
294 sg_copy_part_to_buf(sg
, dbuf
, count
, idx
);
296 print_hex_dump(KERN_ALERT
, " sg: ", DUMP_PREFIX_NONE
,
297 4, 1, dbuf
, count
, false);
301 if (debug_logging_sleep
)
302 msleep(debug_logging_sleep
);
305 /* Returns the name for a given cipher alg/mode */
306 char *spu_alg_name(enum spu_cipher_alg alg
, enum spu_cipher_mode mode
)
313 case CIPHER_MODE_CBC
:
315 case CIPHER_MODE_ECB
:
317 case CIPHER_MODE_OFB
:
319 case CIPHER_MODE_CFB
:
321 case CIPHER_MODE_CTR
:
323 case CIPHER_MODE_XTS
:
325 case CIPHER_MODE_GCM
:
333 case CIPHER_MODE_CBC
:
335 case CIPHER_MODE_ECB
:
337 case CIPHER_MODE_CTR
:
343 case CIPHER_ALG_3DES
:
345 case CIPHER_MODE_CBC
:
346 return "cbc(des3_ede)";
347 case CIPHER_MODE_ECB
:
348 return "ecb(des3_ede)";
349 case CIPHER_MODE_CTR
:
350 return "ctr(des3_ede)";
360 static ssize_t
spu_debugfs_read(struct file
*filp
, char __user
*ubuf
,
361 size_t count
, loff_t
*offp
)
363 struct device_private
*ipriv
;
365 ssize_t ret
, out_offset
, out_count
;
375 buf
= kmalloc(out_count
, GFP_KERNEL
);
379 ipriv
= filp
->private_data
;
381 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
382 "Number of SPUs.........%u\n",
384 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
385 "Current sessions.......%u\n",
386 atomic_read(&ipriv
->session_count
));
387 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
388 "Session count..........%u\n",
389 atomic_read(&ipriv
->stream_count
));
390 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
391 "Cipher setkey..........%u\n",
392 atomic_read(&ipriv
->setkey_cnt
[SPU_OP_CIPHER
]));
393 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
394 "Cipher Ops.............%u\n",
395 atomic_read(&ipriv
->op_counts
[SPU_OP_CIPHER
]));
396 for (alg
= 0; alg
< CIPHER_ALG_LAST
; alg
++) {
397 for (mode
= 0; mode
< CIPHER_MODE_LAST
; mode
++) {
398 op_cnt
= atomic_read(&ipriv
->cipher_cnt
[alg
][mode
]);
400 out_offset
+= snprintf(buf
+ out_offset
,
401 out_count
- out_offset
,
403 spu_alg_name(alg
, mode
), op_cnt
);
407 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
408 "Hash Ops...............%u\n",
409 atomic_read(&ipriv
->op_counts
[SPU_OP_HASH
]));
410 for (alg
= 0; alg
< HASH_ALG_LAST
; alg
++) {
411 op_cnt
= atomic_read(&ipriv
->hash_cnt
[alg
]);
413 out_offset
+= snprintf(buf
+ out_offset
,
414 out_count
- out_offset
,
416 hash_alg_name
[alg
], op_cnt
);
419 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
420 "HMAC setkey............%u\n",
421 atomic_read(&ipriv
->setkey_cnt
[SPU_OP_HMAC
]));
422 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
423 "HMAC Ops...............%u\n",
424 atomic_read(&ipriv
->op_counts
[SPU_OP_HMAC
]));
425 for (alg
= 0; alg
< HASH_ALG_LAST
; alg
++) {
426 op_cnt
= atomic_read(&ipriv
->hmac_cnt
[alg
]);
428 out_offset
+= snprintf(buf
+ out_offset
,
429 out_count
- out_offset
,
431 hash_alg_name
[alg
], op_cnt
);
434 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
435 "AEAD setkey............%u\n",
436 atomic_read(&ipriv
->setkey_cnt
[SPU_OP_AEAD
]));
438 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
439 "AEAD Ops...............%u\n",
440 atomic_read(&ipriv
->op_counts
[SPU_OP_AEAD
]));
441 for (alg
= 0; alg
< AEAD_TYPE_LAST
; alg
++) {
442 op_cnt
= atomic_read(&ipriv
->aead_cnt
[alg
]);
444 out_offset
+= snprintf(buf
+ out_offset
,
445 out_count
- out_offset
,
447 aead_alg_name
[alg
], op_cnt
);
450 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
451 "Bytes of req data......%llu\n",
452 (u64
)atomic64_read(&ipriv
->bytes_out
));
453 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
454 "Bytes of resp data.....%llu\n",
455 (u64
)atomic64_read(&ipriv
->bytes_in
));
456 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
457 "Mailbox full...........%u\n",
458 atomic_read(&ipriv
->mb_no_spc
));
459 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
460 "Mailbox send failures..%u\n",
461 atomic_read(&ipriv
->mb_send_fail
));
462 out_offset
+= snprintf(buf
+ out_offset
, out_count
- out_offset
,
463 "Check ICV errors.......%u\n",
464 atomic_read(&ipriv
->bad_icv
));
465 if (ipriv
->spu
.spu_type
== SPU_TYPE_SPUM
)
466 for (i
= 0; i
< ipriv
->spu
.num_spu
; i
++) {
467 spu_ofifo_ctrl
= ioread32(ipriv
->spu
.reg_vbase
[i
] +
469 fifo_len
= spu_ofifo_ctrl
& SPU_FIFO_WATERMARK
;
470 out_offset
+= snprintf(buf
+ out_offset
,
471 out_count
- out_offset
,
472 "SPU %d output FIFO high water.....%u\n",
476 if (out_offset
> out_count
)
477 out_offset
= out_count
;
479 ret
= simple_read_from_buffer(ubuf
, count
, offp
, buf
, out_offset
);
484 static const struct file_operations spu_debugfs_stats
= {
485 .owner
= THIS_MODULE
,
487 .read
= spu_debugfs_read
,
491 * Create the debug FS directories. If the top-level directory has not yet
492 * been created, create it now. Create a stats file in this directory for
495 void spu_setup_debugfs(void)
497 if (!debugfs_initialized())
500 if (!iproc_priv
.debugfs_dir
)
501 iproc_priv
.debugfs_dir
= debugfs_create_dir(KBUILD_MODNAME
,
504 if (!iproc_priv
.debugfs_stats
)
505 /* Create file with permissions S_IRUSR */
506 debugfs_create_file("stats", 0400, iproc_priv
.debugfs_dir
,
507 &iproc_priv
, &spu_debugfs_stats
);
510 void spu_free_debugfs(void)
512 debugfs_remove_recursive(iproc_priv
.debugfs_dir
);
513 iproc_priv
.debugfs_dir
= NULL
;
517 * format_value_ccm() - Format a value into a buffer, using a specified number
518 * of bytes (i.e. maybe writing value X into a 4 byte
519 * buffer, or maybe into a 12 byte buffer), as per the
522 * @val: value to write (up to max of unsigned int)
523 * @buf: (pointer to) buffer to write the value
524 * @len: number of bytes to use (0 to 255)
527 void format_value_ccm(unsigned int val
, u8
*buf
, u8 len
)
531 /* First clear full output buffer */
534 /* Then, starting from right side, fill in with data */
535 for (i
= 0; i
< len
; i
++) {
536 buf
[len
- i
- 1] = (val
>> (8 * i
)) & 0xff;
538 break; /* Only handle up to 32 bits of 'val' */