18e8ec596SKim Phillips /* 28e8ec596SKim Phillips * CAAM Error Reporting 38e8ec596SKim Phillips * 48e8ec596SKim Phillips * Copyright 2009-2011 Freescale Semiconductor, Inc. 58e8ec596SKim Phillips */ 68e8ec596SKim Phillips 78e8ec596SKim Phillips #include "compat.h" 88e8ec596SKim Phillips #include "regs.h" 98e8ec596SKim Phillips #include "intern.h" 108e8ec596SKim Phillips #include "desc.h" 118e8ec596SKim Phillips #include "jr.h" 128e8ec596SKim Phillips #include "error.h" 138e8ec596SKim Phillips 148e8ec596SKim Phillips #define SPRINTFCAT(str, format, param, max_alloc) \ 158e8ec596SKim Phillips { \ 168e8ec596SKim Phillips char *tmp; \ 178e8ec596SKim Phillips \ 188e8ec596SKim Phillips tmp = kmalloc(sizeof(format) + max_alloc, GFP_ATOMIC); \ 198e8ec596SKim Phillips sprintf(tmp, format, param); \ 208e8ec596SKim Phillips strcat(str, tmp); \ 218e8ec596SKim Phillips kfree(tmp); \ 228e8ec596SKim Phillips } 238e8ec596SKim Phillips 248e8ec596SKim Phillips static void report_jump_idx(u32 status, char *outstr) 258e8ec596SKim Phillips { 268e8ec596SKim Phillips u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >> 278e8ec596SKim Phillips JRSTA_DECOERR_INDEX_SHIFT; 288e8ec596SKim Phillips 298e8ec596SKim Phillips if (status & JRSTA_DECOERR_JUMP) 308e8ec596SKim Phillips strcat(outstr, "jump tgt desc idx "); 318e8ec596SKim Phillips else 328e8ec596SKim Phillips strcat(outstr, "desc idx "); 338e8ec596SKim Phillips 348e8ec596SKim Phillips SPRINTFCAT(outstr, "%d: ", idx, sizeof("255")); 358e8ec596SKim Phillips } 368e8ec596SKim Phillips 378e8ec596SKim Phillips static void report_ccb_status(u32 status, char *outstr) 388e8ec596SKim Phillips { 398e8ec596SKim Phillips char *cha_id_list[] = { 408e8ec596SKim Phillips "", 418e8ec596SKim Phillips "AES", 428e8ec596SKim Phillips "DES, 3DES", 438e8ec596SKim Phillips "ARC4", 448e8ec596SKim Phillips "MD5, SHA-1, SH-224, SHA-256, SHA-384, SHA-512", 458e8ec596SKim Phillips "RNG", 468e8ec596SKim Phillips "SNOW f8", 478e8ec596SKim Phillips "Kasumi f8, f9", 488e8ec596SKim Phillips "All Public Key Algorithms", 498e8ec596SKim Phillips "CRC", 508e8ec596SKim Phillips "SNOW f9", 518e8ec596SKim Phillips }; 528e8ec596SKim Phillips char *err_id_list[] = { 538e8ec596SKim Phillips "None. No error.", 548e8ec596SKim Phillips "Mode error.", 558e8ec596SKim Phillips "Data size error.", 568e8ec596SKim Phillips "Key size error.", 578e8ec596SKim Phillips "PKHA A memory size error.", 588e8ec596SKim Phillips "PKHA B memory size error.", 598e8ec596SKim Phillips "Data arrived out of sequence error.", 608e8ec596SKim Phillips "PKHA divide-by-zero error.", 618e8ec596SKim Phillips "PKHA modulus even error.", 628e8ec596SKim Phillips "DES key parity error.", 638e8ec596SKim Phillips "ICV check failed.", 648e8ec596SKim Phillips "Hardware error.", 658e8ec596SKim Phillips "Unsupported CCM AAD size.", 668e8ec596SKim Phillips "Class 1 CHA is not reset", 678e8ec596SKim Phillips "Invalid CHA combination was selected", 688e8ec596SKim Phillips "Invalid CHA selected.", 698e8ec596SKim Phillips }; 708e8ec596SKim Phillips u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >> 718e8ec596SKim Phillips JRSTA_CCBERR_CHAID_SHIFT; 728e8ec596SKim Phillips u8 err_id = status & JRSTA_CCBERR_ERRID_MASK; 738e8ec596SKim Phillips 748e8ec596SKim Phillips report_jump_idx(status, outstr); 758e8ec596SKim Phillips 76*6d00376aSDan Carpenter if (cha_id < ARRAY_SIZE(cha_id_list)) { 778e8ec596SKim Phillips SPRINTFCAT(outstr, "%s: ", cha_id_list[cha_id], 788e8ec596SKim Phillips strlen(cha_id_list[cha_id])); 798e8ec596SKim Phillips } else { 808e8ec596SKim Phillips SPRINTFCAT(outstr, "unidentified cha_id value 0x%02x: ", 818e8ec596SKim Phillips cha_id, sizeof("ff")); 828e8ec596SKim Phillips } 838e8ec596SKim Phillips 84*6d00376aSDan Carpenter if (err_id < ARRAY_SIZE(err_id_list)) { 858e8ec596SKim Phillips SPRINTFCAT(outstr, "%s", err_id_list[err_id], 868e8ec596SKim Phillips strlen(err_id_list[err_id])); 878e8ec596SKim Phillips } else { 888e8ec596SKim Phillips SPRINTFCAT(outstr, "unidentified err_id value 0x%02x", 898e8ec596SKim Phillips err_id, sizeof("ff")); 908e8ec596SKim Phillips } 918e8ec596SKim Phillips } 928e8ec596SKim Phillips 938e8ec596SKim Phillips static void report_jump_status(u32 status, char *outstr) 948e8ec596SKim Phillips { 958e8ec596SKim Phillips SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__)); 968e8ec596SKim Phillips } 978e8ec596SKim Phillips 988e8ec596SKim Phillips static void report_deco_status(u32 status, char *outstr) 998e8ec596SKim Phillips { 1008e8ec596SKim Phillips const struct { 1018e8ec596SKim Phillips u8 value; 1028e8ec596SKim Phillips char *error_text; 1038e8ec596SKim Phillips } desc_error_list[] = { 1048e8ec596SKim Phillips { 0x00, "None. No error." }, 1058e8ec596SKim Phillips { 0x01, "SGT Length Error. The descriptor is trying to read " 1068e8ec596SKim Phillips "more data than is contained in the SGT table." }, 1078e8ec596SKim Phillips { 0x02, "Reserved." }, 1088e8ec596SKim Phillips { 0x03, "Job Ring Control Error. There is a bad value in the " 1098e8ec596SKim Phillips "Job Ring Control register." }, 1108e8ec596SKim Phillips { 0x04, "Invalid Descriptor Command. The Descriptor Command " 1118e8ec596SKim Phillips "field is invalid." }, 1128e8ec596SKim Phillips { 0x05, "Reserved." }, 1138e8ec596SKim Phillips { 0x06, "Invalid KEY Command" }, 1148e8ec596SKim Phillips { 0x07, "Invalid LOAD Command" }, 1158e8ec596SKim Phillips { 0x08, "Invalid STORE Command" }, 1168e8ec596SKim Phillips { 0x09, "Invalid OPERATION Command" }, 1178e8ec596SKim Phillips { 0x0A, "Invalid FIFO LOAD Command" }, 1188e8ec596SKim Phillips { 0x0B, "Invalid FIFO STORE Command" }, 1198e8ec596SKim Phillips { 0x0C, "Invalid MOVE Command" }, 1208e8ec596SKim Phillips { 0x0D, "Invalid JUMP Command. A nonlocal JUMP Command is " 1218e8ec596SKim Phillips "invalid because the target is not a Job Header " 1228e8ec596SKim Phillips "Command, or the jump is from a Trusted Descriptor to " 1238e8ec596SKim Phillips "a Job Descriptor, or because the target Descriptor " 1248e8ec596SKim Phillips "contains a Shared Descriptor." }, 1258e8ec596SKim Phillips { 0x0E, "Invalid MATH Command" }, 1268e8ec596SKim Phillips { 0x0F, "Invalid SIGNATURE Command" }, 1278e8ec596SKim Phillips { 0x10, "Invalid Sequence Command. A SEQ IN PTR OR SEQ OUT PTR " 1288e8ec596SKim Phillips "Command is invalid or a SEQ KEY, SEQ LOAD, SEQ FIFO " 1298e8ec596SKim Phillips "LOAD, or SEQ FIFO STORE decremented the input or " 1308e8ec596SKim Phillips "output sequence length below 0. This error may result " 1318e8ec596SKim Phillips "if a built-in PROTOCOL Command has encountered a " 1328e8ec596SKim Phillips "malformed PDU." }, 1338e8ec596SKim Phillips { 0x11, "Skip data type invalid. The type must be 0xE or 0xF."}, 1348e8ec596SKim Phillips { 0x12, "Shared Descriptor Header Error" }, 1358e8ec596SKim Phillips { 0x13, "Header Error. Invalid length or parity, or certain " 1368e8ec596SKim Phillips "other problems." }, 1378e8ec596SKim Phillips { 0x14, "Burster Error. Burster has gotten to an illegal " 1388e8ec596SKim Phillips "state" }, 1398e8ec596SKim Phillips { 0x15, "Context Register Length Error. The descriptor is " 1408e8ec596SKim Phillips "trying to read or write past the end of the Context " 1418e8ec596SKim Phillips "Register. A SEQ LOAD or SEQ STORE with the VLF bit " 1428e8ec596SKim Phillips "set was executed with too large a length in the " 1438e8ec596SKim Phillips "variable length register (VSOL for SEQ STORE or VSIL " 1448e8ec596SKim Phillips "for SEQ LOAD)." }, 1458e8ec596SKim Phillips { 0x16, "DMA Error" }, 1468e8ec596SKim Phillips { 0x17, "Reserved." }, 1478e8ec596SKim Phillips { 0x1A, "Job failed due to JR reset" }, 1488e8ec596SKim Phillips { 0x1B, "Job failed due to Fail Mode" }, 1498e8ec596SKim Phillips { 0x1C, "DECO Watchdog timer timeout error" }, 1508e8ec596SKim Phillips { 0x1D, "DECO tried to copy a key from another DECO but the " 1518e8ec596SKim Phillips "other DECO's Key Registers were locked" }, 1528e8ec596SKim Phillips { 0x1E, "DECO attempted to copy data from a DECO that had an " 1538e8ec596SKim Phillips "unmasked Descriptor error" }, 1548e8ec596SKim Phillips { 0x1F, "LIODN error. DECO was trying to share from itself or " 1558e8ec596SKim Phillips "from another DECO but the two Non-SEQ LIODN values " 1568e8ec596SKim Phillips "didn't match or the 'shared from' DECO's Descriptor " 1578e8ec596SKim Phillips "required that the SEQ LIODNs be the same and they " 1588e8ec596SKim Phillips "aren't." }, 1598e8ec596SKim Phillips { 0x20, "DECO has completed a reset initiated via the DRR " 1608e8ec596SKim Phillips "register" }, 1618e8ec596SKim Phillips { 0x21, "Nonce error. When using EKT (CCM) key encryption " 1628e8ec596SKim Phillips "option in the FIFO STORE Command, the Nonce counter " 1638e8ec596SKim Phillips "reached its maximum value and this encryption mode " 1648e8ec596SKim Phillips "can no longer be used." }, 1658e8ec596SKim Phillips { 0x22, "Meta data is too large (> 511 bytes) for TLS decap " 1668e8ec596SKim Phillips "(input frame; block ciphers) and IPsec decap (output " 1678e8ec596SKim Phillips "frame, when doing the next header byte update) and " 1688e8ec596SKim Phillips "DCRC (output frame)." }, 1698e8ec596SKim Phillips { 0x80, "DNR (do not run) error" }, 1708e8ec596SKim Phillips { 0x81, "undefined protocol command" }, 1718e8ec596SKim Phillips { 0x82, "invalid setting in PDB" }, 1728e8ec596SKim Phillips { 0x83, "Anti-replay LATE error" }, 1738e8ec596SKim Phillips { 0x84, "Anti-replay REPLAY error" }, 1748e8ec596SKim Phillips { 0x85, "Sequence number overflow" }, 1758e8ec596SKim Phillips { 0x86, "Sigver invalid signature" }, 1768e8ec596SKim Phillips { 0x87, "DSA Sign Illegal test descriptor" }, 1778e8ec596SKim Phillips { 0x88, "Protocol Format Error - A protocol has seen an error " 1788e8ec596SKim Phillips "in the format of data received. When running RSA, " 1798e8ec596SKim Phillips "this means that formatting with random padding was " 1808e8ec596SKim Phillips "used, and did not follow the form: 0x00, 0x02, 8-to-N " 1818e8ec596SKim Phillips "bytes of non-zero pad, 0x00, F data." }, 1828e8ec596SKim Phillips { 0x89, "Protocol Size Error - A protocol has seen an error in " 1838e8ec596SKim Phillips "size. When running RSA, pdb size N < (size of F) when " 1848e8ec596SKim Phillips "no formatting is used; or pdb size N < (F + 11) when " 1858e8ec596SKim Phillips "formatting is used." }, 1868e8ec596SKim Phillips { 0xC1, "Blob Command error: Undefined mode" }, 1878e8ec596SKim Phillips { 0xC2, "Blob Command error: Secure Memory Blob mode error" }, 1888e8ec596SKim Phillips { 0xC4, "Blob Command error: Black Blob key or input size " 1898e8ec596SKim Phillips "error" }, 1908e8ec596SKim Phillips { 0xC5, "Blob Command error: Invalid key destination" }, 1918e8ec596SKim Phillips { 0xC8, "Blob Command error: Trusted/Secure mode error" }, 1928e8ec596SKim Phillips { 0xF0, "IPsec TTL or hop limit field either came in as 0, " 1938e8ec596SKim Phillips "or was decremented to 0" }, 1948e8ec596SKim Phillips { 0xF1, "3GPP HFN matches or exceeds the Threshold" }, 1958e8ec596SKim Phillips }; 1968e8ec596SKim Phillips u8 desc_error = status & JRSTA_DECOERR_ERROR_MASK; 1978e8ec596SKim Phillips int i; 1988e8ec596SKim Phillips 1998e8ec596SKim Phillips report_jump_idx(status, outstr); 2008e8ec596SKim Phillips 201*6d00376aSDan Carpenter for (i = 0; i < ARRAY_SIZE(desc_error_list); i++) 2028e8ec596SKim Phillips if (desc_error_list[i].value == desc_error) 2038e8ec596SKim Phillips break; 2048e8ec596SKim Phillips 205*6d00376aSDan Carpenter if (i != ARRAY_SIZE(desc_error_list) && desc_error_list[i].error_text) { 2068e8ec596SKim Phillips SPRINTFCAT(outstr, "%s", desc_error_list[i].error_text, 2078e8ec596SKim Phillips strlen(desc_error_list[i].error_text)); 2088e8ec596SKim Phillips } else { 2098e8ec596SKim Phillips SPRINTFCAT(outstr, "unidentified error value 0x%02x", 2108e8ec596SKim Phillips desc_error, sizeof("ff")); 2118e8ec596SKim Phillips } 2128e8ec596SKim Phillips } 2138e8ec596SKim Phillips 2148e8ec596SKim Phillips static void report_jr_status(u32 status, char *outstr) 2158e8ec596SKim Phillips { 2168e8ec596SKim Phillips SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__)); 2178e8ec596SKim Phillips } 2188e8ec596SKim Phillips 2198e8ec596SKim Phillips static void report_cond_code_status(u32 status, char *outstr) 2208e8ec596SKim Phillips { 2218e8ec596SKim Phillips SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__)); 2228e8ec596SKim Phillips } 2238e8ec596SKim Phillips 2248e8ec596SKim Phillips char *caam_jr_strstatus(char *outstr, u32 status) 2258e8ec596SKim Phillips { 2268e8ec596SKim Phillips struct stat_src { 2278e8ec596SKim Phillips void (*report_ssed)(u32 status, char *outstr); 2288e8ec596SKim Phillips char *error; 2298e8ec596SKim Phillips } status_src[] = { 2308e8ec596SKim Phillips { NULL, "No error" }, 2318e8ec596SKim Phillips { NULL, NULL }, 2328e8ec596SKim Phillips { report_ccb_status, "CCB" }, 2338e8ec596SKim Phillips { report_jump_status, "Jump" }, 2348e8ec596SKim Phillips { report_deco_status, "DECO" }, 2358e8ec596SKim Phillips { NULL, NULL }, 2368e8ec596SKim Phillips { report_jr_status, "Job Ring" }, 2378e8ec596SKim Phillips { report_cond_code_status, "Condition Code" }, 2388e8ec596SKim Phillips }; 2398e8ec596SKim Phillips u32 ssrc = status >> JRSTA_SSRC_SHIFT; 2408e8ec596SKim Phillips 2418e8ec596SKim Phillips sprintf(outstr, "%s: ", status_src[ssrc].error); 2428e8ec596SKim Phillips 2438e8ec596SKim Phillips if (status_src[ssrc].report_ssed) 2448e8ec596SKim Phillips status_src[ssrc].report_ssed(status, outstr); 2458e8ec596SKim Phillips 2468e8ec596SKim Phillips return outstr; 2478e8ec596SKim Phillips } 2488e8ec596SKim Phillips EXPORT_SYMBOL(caam_jr_strstatus); 249