^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2016 Broadcom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "cipher.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "util.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /* offset of SPU_OFIFO_CTRL register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define SPU_OFIFO_CTRL 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define SPU_FIFO_WATERMARK 0x1FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * spu_sg_at_offset() - Find the scatterlist entry at a given distance from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * start of a scatterlist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * @sg: [in] Start of a scatterlist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * @skip: [in] Distance from the start of the scatterlist, in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * @sge: [out] Scatterlist entry at skip bytes from start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * @sge_offset: [out] Number of bytes from start of sge buffer to get to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * requested distance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Return: 0 if entry found at requested distance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * < 0 otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int spu_sg_at_offset(struct scatterlist *sg, unsigned int skip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct scatterlist **sge, unsigned int *sge_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* byte index from start of sg to the end of the previous entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) unsigned int index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* byte index from start of sg to the end of the current entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned int next_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) next_index = sg->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) while (next_index <= skip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) sg = sg_next(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) index = next_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (!sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) next_index += sg->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) *sge_offset = skip - index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *sge = sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* Copy len bytes of sg data, starting at offset skip, to a dest buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) void sg_copy_part_to_buf(struct scatterlist *src, u8 *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) unsigned int len, unsigned int skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) size_t copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned int nents = sg_nents(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) copied = sg_pcopy_to_buffer(src, nents, dest, len, skip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (copied != len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) flow_log("%s copied %u bytes of %u requested. ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) __func__, (u32)copied, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) flow_log("sg with %u entries and skip %u\n", nents, skip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * Copy data into a scatterlist starting at a specified offset in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * scatterlist. Specifically, copy len bytes of data in the buffer src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * into the scatterlist dest, starting skip bytes into the scatterlist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) void sg_copy_part_from_buf(struct scatterlist *dest, u8 *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) unsigned int len, unsigned int skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) size_t copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) unsigned int nents = sg_nents(dest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) copied = sg_pcopy_from_buffer(dest, nents, src, len, skip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (copied != len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) flow_log("%s copied %u bytes of %u requested. ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) __func__, (u32)copied, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) flow_log("sg with %u entries and skip %u\n", nents, skip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * spu_sg_count() - Determine number of elements in scatterlist to provide a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * specified number of bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * @sg_list: scatterlist to examine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * @skip: index of starting point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * @nbytes: consider elements of scatterlist until reaching this number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * Return: the number of sg entries contributing to nbytes of data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int spu_sg_count(struct scatterlist *sg_list, unsigned int skip, int nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int sg_nents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (!sg_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (spu_sg_at_offset(sg_list, skip, &sg, &offset) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) while (sg && (nbytes > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) sg_nents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) nbytes -= (sg->length - offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) sg = sg_next(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return sg_nents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * spu_msg_sg_add() - Copy scatterlist entries from one sg to another, up to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * given length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * @to_sg: scatterlist to copy to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * @from_sg: scatterlist to copy from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * @from_skip: number of bytes to skip in from_sg. Non-zero when previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * request included part of the buffer in entry in from_sg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * Assumes from_skip < from_sg->length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * @from_nents number of entries in from_sg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * @length number of bytes to copy. may reach this limit before exhausting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * from_sg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * Copies the entries themselves, not the data in the entries. Assumes to_sg has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * enough entries. Does not limit the size of an individual buffer in to_sg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * to_sg, from_sg, skip are all updated to end of copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * Return: Number of bytes copied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) u32 spu_msg_sg_add(struct scatterlist **to_sg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct scatterlist **from_sg, u32 *from_skip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) u8 from_nents, u32 length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct scatterlist *sg; /* an entry in from_sg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct scatterlist *to = *to_sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct scatterlist *from = *from_sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u32 skip = *from_skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) u32 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u32 entry_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u32 frag_len = 0; /* length of entry added to to_sg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u32 copied = 0; /* number of bytes copied so far */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (length == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) for_each_sg(from, sg, from_nents, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* number of bytes in this from entry not yet used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) entry_len = sg->length - skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) frag_len = min(entry_len, length - copied);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) offset = sg->offset + skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (frag_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) sg_set_page(to++, sg_page(sg), frag_len, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) copied += frag_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (copied == entry_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* used up all of from entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) skip = 0; /* start at beginning of next entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (copied == length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) *to_sg = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) *from_sg = sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (frag_len < entry_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) *from_skip = skip + frag_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) *from_skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) void add_to_ctr(u8 *ctr_pos, unsigned int increment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) __be64 *high_be = (__be64 *)ctr_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) __be64 *low_be = high_be + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u64 orig_low = __be64_to_cpu(*low_be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) u64 new_low = orig_low + (u64)increment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) *low_be = __cpu_to_be64(new_low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (new_low < orig_low)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* there was a carry from the low 8 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) *high_be = __cpu_to_be64(__be64_to_cpu(*high_be) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct sdesc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct shash_desc shash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) char ctx[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * do_shash() - Do a synchronous hash operation in software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * @name: The name of the hash algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * @result: Buffer where digest is to be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * @data1: First part of data to hash. May be NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * @data1_len: Length of data1, in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * @data2: Second part of data to hash. May be NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * @data2_len: Length of data2, in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * @key: Key (if keyed hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * @key_len: Length of key, in bytes (or 0 if non-keyed hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * Note that the crypto API will not select this driver's own transform because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * this driver only registers asynchronous algos.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * Return: 0 if hash successfully stored in result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * < 0 otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int do_shash(unsigned char *name, unsigned char *result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) const u8 *data1, unsigned int data1_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) const u8 *data2, unsigned int data2_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) const u8 *key, unsigned int key_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) unsigned int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct crypto_shash *hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct sdesc *sdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) hash = crypto_alloc_shash(name, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (IS_ERR(hash)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) rc = PTR_ERR(hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) pr_err("%s: Crypto %s allocation error %d\n", __func__, name, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) size = sizeof(struct shash_desc) + crypto_shash_descsize(hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) sdesc = kmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (!sdesc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) goto do_shash_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) sdesc->shash.tfm = hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (key_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) rc = crypto_shash_setkey(hash, key, key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) pr_err("%s: Could not setkey %s shash\n", __func__, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) goto do_shash_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) rc = crypto_shash_init(&sdesc->shash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) pr_err("%s: Could not init %s shash\n", __func__, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) goto do_shash_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) rc = crypto_shash_update(&sdesc->shash, data1, data1_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) pr_err("%s: Could not update1\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) goto do_shash_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (data2 && data2_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) rc = crypto_shash_update(&sdesc->shash, data2, data2_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) pr_err("%s: Could not update2\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) goto do_shash_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) rc = crypto_shash_final(&sdesc->shash, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) pr_err("%s: Could not generate %s hash\n", __func__, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) do_shash_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) crypto_free_shash(hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) kfree(sdesc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* Dump len bytes of a scatterlist starting at skip bytes into the sg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) void __dump_sg(struct scatterlist *sg, unsigned int skip, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) u8 dbuf[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) unsigned int idx = skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) unsigned int num_out = 0; /* number of bytes dumped so far */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (packet_debug_logging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) while (num_out < len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) count = (len - num_out > 16) ? 16 : len - num_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) sg_copy_part_to_buf(sg, dbuf, count, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) num_out += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) print_hex_dump(KERN_ALERT, " sg: ", DUMP_PREFIX_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 4, 1, dbuf, count, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) idx += 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (debug_logging_sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) msleep(debug_logging_sleep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* Returns the name for a given cipher alg/mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) char *spu_alg_name(enum spu_cipher_alg alg, enum spu_cipher_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) switch (alg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) case CIPHER_ALG_RC4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return "rc4";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) case CIPHER_ALG_AES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) case CIPHER_MODE_CBC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return "cbc(aes)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) case CIPHER_MODE_ECB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return "ecb(aes)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) case CIPHER_MODE_OFB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return "ofb(aes)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) case CIPHER_MODE_CFB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return "cfb(aes)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) case CIPHER_MODE_CTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return "ctr(aes)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) case CIPHER_MODE_XTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return "xts(aes)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) case CIPHER_MODE_GCM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return "gcm(aes)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return "aes";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case CIPHER_ALG_DES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) case CIPHER_MODE_CBC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return "cbc(des)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) case CIPHER_MODE_ECB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return "ecb(des)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) case CIPHER_MODE_CTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return "ctr(des)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return "des";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) case CIPHER_ALG_3DES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) case CIPHER_MODE_CBC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return "cbc(des3_ede)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) case CIPHER_MODE_ECB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return "ecb(des3_ede)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) case CIPHER_MODE_CTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return "ctr(des3_ede)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return "3des";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return "other";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static ssize_t spu_debugfs_read(struct file *filp, char __user *ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) size_t count, loff_t *offp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct bcm_device_private *ipriv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ssize_t ret, out_offset, out_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) u32 fifo_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) u32 spu_ofifo_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) u32 alg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) u32 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) u32 op_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) out_count = 2048;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) buf = kmalloc(out_count, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) ipriv = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) out_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) "Number of SPUs.........%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) ipriv->spu.num_spu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) "Current sessions.......%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) atomic_read(&ipriv->session_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) "Session count..........%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) atomic_read(&ipriv->stream_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) "Cipher setkey..........%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) atomic_read(&ipriv->setkey_cnt[SPU_OP_CIPHER]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) "Cipher Ops.............%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) atomic_read(&ipriv->op_counts[SPU_OP_CIPHER]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) for (alg = 0; alg < CIPHER_ALG_LAST; alg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) for (mode = 0; mode < CIPHER_MODE_LAST; mode++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) op_cnt = atomic_read(&ipriv->cipher_cnt[alg][mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (op_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) out_offset += scnprintf(buf + out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) " %-13s%11u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) spu_alg_name(alg, mode), op_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) "Hash Ops...............%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) atomic_read(&ipriv->op_counts[SPU_OP_HASH]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) for (alg = 0; alg < HASH_ALG_LAST; alg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) op_cnt = atomic_read(&ipriv->hash_cnt[alg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (op_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) out_offset += scnprintf(buf + out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) " %-13s%11u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) hash_alg_name[alg], op_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) "HMAC setkey............%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) atomic_read(&ipriv->setkey_cnt[SPU_OP_HMAC]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) "HMAC Ops...............%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) atomic_read(&ipriv->op_counts[SPU_OP_HMAC]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) for (alg = 0; alg < HASH_ALG_LAST; alg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) op_cnt = atomic_read(&ipriv->hmac_cnt[alg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (op_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) out_offset += scnprintf(buf + out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) " %-13s%11u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) hash_alg_name[alg], op_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) "AEAD setkey............%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) atomic_read(&ipriv->setkey_cnt[SPU_OP_AEAD]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) "AEAD Ops...............%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) atomic_read(&ipriv->op_counts[SPU_OP_AEAD]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) for (alg = 0; alg < AEAD_TYPE_LAST; alg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) op_cnt = atomic_read(&ipriv->aead_cnt[alg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (op_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) out_offset += scnprintf(buf + out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) " %-13s%11u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) aead_alg_name[alg], op_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) "Bytes of req data......%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) (u64)atomic64_read(&ipriv->bytes_out));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) "Bytes of resp data.....%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) (u64)atomic64_read(&ipriv->bytes_in));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) "Mailbox full...........%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) atomic_read(&ipriv->mb_no_spc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) "Mailbox send failures..%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) atomic_read(&ipriv->mb_send_fail));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) out_offset += scnprintf(buf + out_offset, out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) "Check ICV errors.......%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) atomic_read(&ipriv->bad_icv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (ipriv->spu.spu_type == SPU_TYPE_SPUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) for (i = 0; i < ipriv->spu.num_spu; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) spu_ofifo_ctrl = ioread32(ipriv->spu.reg_vbase[i] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) SPU_OFIFO_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) fifo_len = spu_ofifo_ctrl & SPU_FIFO_WATERMARK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) out_offset += scnprintf(buf + out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) out_count - out_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) "SPU %d output FIFO high water.....%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) i, fifo_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (out_offset > out_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) out_offset = out_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ret = simple_read_from_buffer(ubuf, count, offp, buf, out_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static const struct file_operations spu_debugfs_stats = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) .open = simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) .read = spu_debugfs_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * Create the debug FS directories. If the top-level directory has not yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * been created, create it now. Create a stats file in this directory for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * a SPU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) void spu_setup_debugfs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (!debugfs_initialized())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (!iproc_priv.debugfs_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) iproc_priv.debugfs_dir = debugfs_create_dir(KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (!iproc_priv.debugfs_stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /* Create file with permissions S_IRUSR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) debugfs_create_file("stats", 0400, iproc_priv.debugfs_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) &iproc_priv, &spu_debugfs_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) void spu_free_debugfs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) debugfs_remove_recursive(iproc_priv.debugfs_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) iproc_priv.debugfs_dir = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * format_value_ccm() - Format a value into a buffer, using a specified number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * of bytes (i.e. maybe writing value X into a 4 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * buffer, or maybe into a 12 byte buffer), as per the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * SPU CCM spec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * @val: value to write (up to max of unsigned int)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * @buf: (pointer to) buffer to write the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * @len: number of bytes to use (0 to 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) void format_value_ccm(unsigned int val, u8 *buf, u8 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /* First clear full output buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) memset(buf, 0, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /* Then, starting from right side, fill in with data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) buf[len - i - 1] = (val >> (8 * i)) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (i >= 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) break; /* Only handle up to 32 bits of 'val' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }