diff options
Diffstat (limited to 'drivers/crypto/caam/error.c')
-rw-r--r-- | drivers/crypto/caam/error.c | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/drivers/crypto/caam/error.c b/drivers/crypto/caam/error.c new file mode 100644 index 000000000000..bd57a6825f57 --- /dev/null +++ b/drivers/crypto/caam/error.c | |||
@@ -0,0 +1,248 @@ | |||
1 | /* | ||
2 | * CAAM Error Reporting | ||
3 | * | ||
4 | * Copyright 2009-2011 Freescale Semiconductor, Inc. | ||
5 | */ | ||
6 | |||
7 | #include "compat.h" | ||
8 | #include "regs.h" | ||
9 | #include "intern.h" | ||
10 | #include "desc.h" | ||
11 | #include "jr.h" | ||
12 | #include "error.h" | ||
13 | |||
14 | #define SPRINTFCAT(str, format, param, max_alloc) \ | ||
15 | { \ | ||
16 | char *tmp; \ | ||
17 | \ | ||
18 | tmp = kmalloc(sizeof(format) + max_alloc, GFP_ATOMIC); \ | ||
19 | sprintf(tmp, format, param); \ | ||
20 | strcat(str, tmp); \ | ||
21 | kfree(tmp); \ | ||
22 | } | ||
23 | |||
24 | static void report_jump_idx(u32 status, char *outstr) | ||
25 | { | ||
26 | u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >> | ||
27 | JRSTA_DECOERR_INDEX_SHIFT; | ||
28 | |||
29 | if (status & JRSTA_DECOERR_JUMP) | ||
30 | strcat(outstr, "jump tgt desc idx "); | ||
31 | else | ||
32 | strcat(outstr, "desc idx "); | ||
33 | |||
34 | SPRINTFCAT(outstr, "%d: ", idx, sizeof("255")); | ||
35 | } | ||
36 | |||
37 | static void report_ccb_status(u32 status, char *outstr) | ||
38 | { | ||
39 | char *cha_id_list[] = { | ||
40 | "", | ||
41 | "AES", | ||
42 | "DES, 3DES", | ||
43 | "ARC4", | ||
44 | "MD5, SHA-1, SH-224, SHA-256, SHA-384, SHA-512", | ||
45 | "RNG", | ||
46 | "SNOW f8", | ||
47 | "Kasumi f8, f9", | ||
48 | "All Public Key Algorithms", | ||
49 | "CRC", | ||
50 | "SNOW f9", | ||
51 | }; | ||
52 | char *err_id_list[] = { | ||
53 | "None. No error.", | ||
54 | "Mode error.", | ||
55 | "Data size error.", | ||
56 | "Key size error.", | ||
57 | "PKHA A memory size error.", | ||
58 | "PKHA B memory size error.", | ||
59 | "Data arrived out of sequence error.", | ||
60 | "PKHA divide-by-zero error.", | ||
61 | "PKHA modulus even error.", | ||
62 | "DES key parity error.", | ||
63 | "ICV check failed.", | ||
64 | "Hardware error.", | ||
65 | "Unsupported CCM AAD size.", | ||
66 | "Class 1 CHA is not reset", | ||
67 | "Invalid CHA combination was selected", | ||
68 | "Invalid CHA selected.", | ||
69 | }; | ||
70 | u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >> | ||
71 | JRSTA_CCBERR_CHAID_SHIFT; | ||
72 | u8 err_id = status & JRSTA_CCBERR_ERRID_MASK; | ||
73 | |||
74 | report_jump_idx(status, outstr); | ||
75 | |||
76 | if (cha_id < sizeof(cha_id_list)) { | ||
77 | SPRINTFCAT(outstr, "%s: ", cha_id_list[cha_id], | ||
78 | strlen(cha_id_list[cha_id])); | ||
79 | } else { | ||
80 | SPRINTFCAT(outstr, "unidentified cha_id value 0x%02x: ", | ||
81 | cha_id, sizeof("ff")); | ||
82 | } | ||
83 | |||
84 | if (err_id < sizeof(err_id_list)) { | ||
85 | SPRINTFCAT(outstr, "%s", err_id_list[err_id], | ||
86 | strlen(err_id_list[err_id])); | ||
87 | } else { | ||
88 | SPRINTFCAT(outstr, "unidentified err_id value 0x%02x", | ||
89 | err_id, sizeof("ff")); | ||
90 | } | ||
91 | } | ||
92 | |||
93 | static void report_jump_status(u32 status, char *outstr) | ||
94 | { | ||
95 | SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__)); | ||
96 | } | ||
97 | |||
98 | static void report_deco_status(u32 status, char *outstr) | ||
99 | { | ||
100 | const struct { | ||
101 | u8 value; | ||
102 | char *error_text; | ||
103 | } desc_error_list[] = { | ||
104 | { 0x00, "None. No error." }, | ||
105 | { 0x01, "SGT Length Error. The descriptor is trying to read " | ||
106 | "more data than is contained in the SGT table." }, | ||
107 | { 0x02, "Reserved." }, | ||
108 | { 0x03, "Job Ring Control Error. There is a bad value in the " | ||
109 | "Job Ring Control register." }, | ||
110 | { 0x04, "Invalid Descriptor Command. The Descriptor Command " | ||
111 | "field is invalid." }, | ||
112 | { 0x05, "Reserved." }, | ||
113 | { 0x06, "Invalid KEY Command" }, | ||
114 | { 0x07, "Invalid LOAD Command" }, | ||
115 | { 0x08, "Invalid STORE Command" }, | ||
116 | { 0x09, "Invalid OPERATION Command" }, | ||
117 | { 0x0A, "Invalid FIFO LOAD Command" }, | ||
118 | { 0x0B, "Invalid FIFO STORE Command" }, | ||
119 | { 0x0C, "Invalid MOVE Command" }, | ||
120 | { 0x0D, "Invalid JUMP Command. A nonlocal JUMP Command is " | ||
121 | "invalid because the target is not a Job Header " | ||
122 | "Command, or the jump is from a Trusted Descriptor to " | ||
123 | "a Job Descriptor, or because the target Descriptor " | ||
124 | "contains a Shared Descriptor." }, | ||
125 | { 0x0E, "Invalid MATH Command" }, | ||
126 | { 0x0F, "Invalid SIGNATURE Command" }, | ||
127 | { 0x10, "Invalid Sequence Command. A SEQ IN PTR OR SEQ OUT PTR " | ||
128 | "Command is invalid or a SEQ KEY, SEQ LOAD, SEQ FIFO " | ||
129 | "LOAD, or SEQ FIFO STORE decremented the input or " | ||
130 | "output sequence length below 0. This error may result " | ||
131 | "if a built-in PROTOCOL Command has encountered a " | ||
132 | "malformed PDU." }, | ||
133 | { 0x11, "Skip data type invalid. The type must be 0xE or 0xF."}, | ||
134 | { 0x12, "Shared Descriptor Header Error" }, | ||
135 | { 0x13, "Header Error. Invalid length or parity, or certain " | ||
136 | "other problems." }, | ||
137 | { 0x14, "Burster Error. Burster has gotten to an illegal " | ||
138 | "state" }, | ||
139 | { 0x15, "Context Register Length Error. The descriptor is " | ||
140 | "trying to read or write past the end of the Context " | ||
141 | "Register. A SEQ LOAD or SEQ STORE with the VLF bit " | ||
142 | "set was executed with too large a length in the " | ||
143 | "variable length register (VSOL for SEQ STORE or VSIL " | ||
144 | "for SEQ LOAD)." }, | ||
145 | { 0x16, "DMA Error" }, | ||
146 | { 0x17, "Reserved." }, | ||
147 | { 0x1A, "Job failed due to JR reset" }, | ||
148 | { 0x1B, "Job failed due to Fail Mode" }, | ||
149 | { 0x1C, "DECO Watchdog timer timeout error" }, | ||
150 | { 0x1D, "DECO tried to copy a key from another DECO but the " | ||
151 | "other DECO's Key Registers were locked" }, | ||
152 | { 0x1E, "DECO attempted to copy data from a DECO that had an " | ||
153 | "unmasked Descriptor error" }, | ||
154 | { 0x1F, "LIODN error. DECO was trying to share from itself or " | ||
155 | "from another DECO but the two Non-SEQ LIODN values " | ||
156 | "didn't match or the 'shared from' DECO's Descriptor " | ||
157 | "required that the SEQ LIODNs be the same and they " | ||
158 | "aren't." }, | ||
159 | { 0x20, "DECO has completed a reset initiated via the DRR " | ||
160 | "register" }, | ||
161 | { 0x21, "Nonce error. When using EKT (CCM) key encryption " | ||
162 | "option in the FIFO STORE Command, the Nonce counter " | ||
163 | "reached its maximum value and this encryption mode " | ||
164 | "can no longer be used." }, | ||
165 | { 0x22, "Meta data is too large (> 511 bytes) for TLS decap " | ||
166 | "(input frame; block ciphers) and IPsec decap (output " | ||
167 | "frame, when doing the next header byte update) and " | ||
168 | "DCRC (output frame)." }, | ||
169 | { 0x80, "DNR (do not run) error" }, | ||
170 | { 0x81, "undefined protocol command" }, | ||
171 | { 0x82, "invalid setting in PDB" }, | ||
172 | { 0x83, "Anti-replay LATE error" }, | ||
173 | { 0x84, "Anti-replay REPLAY error" }, | ||
174 | { 0x85, "Sequence number overflow" }, | ||
175 | { 0x86, "Sigver invalid signature" }, | ||
176 | { 0x87, "DSA Sign Illegal test descriptor" }, | ||
177 | { 0x88, "Protocol Format Error - A protocol has seen an error " | ||
178 | "in the format of data received. When running RSA, " | ||
179 | "this means that formatting with random padding was " | ||
180 | "used, and did not follow the form: 0x00, 0x02, 8-to-N " | ||
181 | "bytes of non-zero pad, 0x00, F data." }, | ||
182 | { 0x89, "Protocol Size Error - A protocol has seen an error in " | ||
183 | "size. When running RSA, pdb size N < (size of F) when " | ||
184 | "no formatting is used; or pdb size N < (F + 11) when " | ||
185 | "formatting is used." }, | ||
186 | { 0xC1, "Blob Command error: Undefined mode" }, | ||
187 | { 0xC2, "Blob Command error: Secure Memory Blob mode error" }, | ||
188 | { 0xC4, "Blob Command error: Black Blob key or input size " | ||
189 | "error" }, | ||
190 | { 0xC5, "Blob Command error: Invalid key destination" }, | ||
191 | { 0xC8, "Blob Command error: Trusted/Secure mode error" }, | ||
192 | { 0xF0, "IPsec TTL or hop limit field either came in as 0, " | ||
193 | "or was decremented to 0" }, | ||
194 | { 0xF1, "3GPP HFN matches or exceeds the Threshold" }, | ||
195 | }; | ||
196 | u8 desc_error = status & JRSTA_DECOERR_ERROR_MASK; | ||
197 | int i; | ||
198 | |||
199 | report_jump_idx(status, outstr); | ||
200 | |||
201 | for (i = 0; i < sizeof(desc_error_list); i++) | ||
202 | if (desc_error_list[i].value == desc_error) | ||
203 | break; | ||
204 | |||
205 | if (i != sizeof(desc_error_list) && desc_error_list[i].error_text) { | ||
206 | SPRINTFCAT(outstr, "%s", desc_error_list[i].error_text, | ||
207 | strlen(desc_error_list[i].error_text)); | ||
208 | } else { | ||
209 | SPRINTFCAT(outstr, "unidentified error value 0x%02x", | ||
210 | desc_error, sizeof("ff")); | ||
211 | } | ||
212 | } | ||
213 | |||
214 | static void report_jr_status(u32 status, char *outstr) | ||
215 | { | ||
216 | SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__)); | ||
217 | } | ||
218 | |||
219 | static void report_cond_code_status(u32 status, char *outstr) | ||
220 | { | ||
221 | SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__)); | ||
222 | } | ||
223 | |||
224 | char *caam_jr_strstatus(char *outstr, u32 status) | ||
225 | { | ||
226 | struct stat_src { | ||
227 | void (*report_ssed)(u32 status, char *outstr); | ||
228 | char *error; | ||
229 | } status_src[] = { | ||
230 | { NULL, "No error" }, | ||
231 | { NULL, NULL }, | ||
232 | { report_ccb_status, "CCB" }, | ||
233 | { report_jump_status, "Jump" }, | ||
234 | { report_deco_status, "DECO" }, | ||
235 | { NULL, NULL }, | ||
236 | { report_jr_status, "Job Ring" }, | ||
237 | { report_cond_code_status, "Condition Code" }, | ||
238 | }; | ||
239 | u32 ssrc = status >> JRSTA_SSRC_SHIFT; | ||
240 | |||
241 | sprintf(outstr, "%s: ", status_src[ssrc].error); | ||
242 | |||
243 | if (status_src[ssrc].report_ssed) | ||
244 | status_src[ssrc].report_ssed(status, outstr); | ||
245 | |||
246 | return outstr; | ||
247 | } | ||
248 | EXPORT_SYMBOL(caam_jr_strstatus); | ||