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 1496aef9a8SKim Phillips static const struct { 158e8ec596SKim Phillips u8 value; 168e8ec596SKim Phillips char *error_text; 178e8ec596SKim Phillips } desc_error_list[] = { 18281922a1SKim Phillips { 0x00, "No error." }, 198e8ec596SKim Phillips { 0x01, "SGT Length Error. The descriptor is trying to read " 208e8ec596SKim Phillips "more data than is contained in the SGT table." }, 21281922a1SKim Phillips { 0x02, "SGT Null Entry Error." }, 228e8ec596SKim Phillips { 0x03, "Job Ring Control Error. There is a bad value in the " 238e8ec596SKim Phillips "Job Ring Control register." }, 248e8ec596SKim Phillips { 0x04, "Invalid Descriptor Command. The Descriptor Command " 258e8ec596SKim Phillips "field is invalid." }, 268e8ec596SKim Phillips { 0x05, "Reserved." }, 278e8ec596SKim Phillips { 0x06, "Invalid KEY Command" }, 288e8ec596SKim Phillips { 0x07, "Invalid LOAD Command" }, 298e8ec596SKim Phillips { 0x08, "Invalid STORE Command" }, 308e8ec596SKim Phillips { 0x09, "Invalid OPERATION Command" }, 318e8ec596SKim Phillips { 0x0A, "Invalid FIFO LOAD Command" }, 328e8ec596SKim Phillips { 0x0B, "Invalid FIFO STORE Command" }, 33281922a1SKim Phillips { 0x0C, "Invalid MOVE/MOVE_LEN Command" }, 348e8ec596SKim Phillips { 0x0D, "Invalid JUMP Command. A nonlocal JUMP Command is " 358e8ec596SKim Phillips "invalid because the target is not a Job Header " 368e8ec596SKim Phillips "Command, or the jump is from a Trusted Descriptor to " 378e8ec596SKim Phillips "a Job Descriptor, or because the target Descriptor " 388e8ec596SKim Phillips "contains a Shared Descriptor." }, 398e8ec596SKim Phillips { 0x0E, "Invalid MATH Command" }, 408e8ec596SKim Phillips { 0x0F, "Invalid SIGNATURE Command" }, 418e8ec596SKim Phillips { 0x10, "Invalid Sequence Command. A SEQ IN PTR OR SEQ OUT PTR " 428e8ec596SKim Phillips "Command is invalid or a SEQ KEY, SEQ LOAD, SEQ FIFO " 438e8ec596SKim Phillips "LOAD, or SEQ FIFO STORE decremented the input or " 448e8ec596SKim Phillips "output sequence length below 0. This error may result " 458e8ec596SKim Phillips "if a built-in PROTOCOL Command has encountered a " 468e8ec596SKim Phillips "malformed PDU." }, 478e8ec596SKim Phillips { 0x11, "Skip data type invalid. The type must be 0xE or 0xF."}, 488e8ec596SKim Phillips { 0x12, "Shared Descriptor Header Error" }, 498e8ec596SKim Phillips { 0x13, "Header Error. Invalid length or parity, or certain " 508e8ec596SKim Phillips "other problems." }, 518e8ec596SKim Phillips { 0x14, "Burster Error. Burster has gotten to an illegal " 528e8ec596SKim Phillips "state" }, 538e8ec596SKim Phillips { 0x15, "Context Register Length Error. The descriptor is " 548e8ec596SKim Phillips "trying to read or write past the end of the Context " 558e8ec596SKim Phillips "Register. A SEQ LOAD or SEQ STORE with the VLF bit " 568e8ec596SKim Phillips "set was executed with too large a length in the " 578e8ec596SKim Phillips "variable length register (VSOL for SEQ STORE or VSIL " 588e8ec596SKim Phillips "for SEQ LOAD)." }, 598e8ec596SKim Phillips { 0x16, "DMA Error" }, 608e8ec596SKim Phillips { 0x17, "Reserved." }, 618e8ec596SKim Phillips { 0x1A, "Job failed due to JR reset" }, 628e8ec596SKim Phillips { 0x1B, "Job failed due to Fail Mode" }, 638e8ec596SKim Phillips { 0x1C, "DECO Watchdog timer timeout error" }, 648e8ec596SKim Phillips { 0x1D, "DECO tried to copy a key from another DECO but the " 658e8ec596SKim Phillips "other DECO's Key Registers were locked" }, 668e8ec596SKim Phillips { 0x1E, "DECO attempted to copy data from a DECO that had an " 678e8ec596SKim Phillips "unmasked Descriptor error" }, 688e8ec596SKim Phillips { 0x1F, "LIODN error. DECO was trying to share from itself or " 698e8ec596SKim Phillips "from another DECO but the two Non-SEQ LIODN values " 708e8ec596SKim Phillips "didn't match or the 'shared from' DECO's Descriptor " 718e8ec596SKim Phillips "required that the SEQ LIODNs be the same and they " 728e8ec596SKim Phillips "aren't." }, 738e8ec596SKim Phillips { 0x20, "DECO has completed a reset initiated via the DRR " 748e8ec596SKim Phillips "register" }, 758e8ec596SKim Phillips { 0x21, "Nonce error. When using EKT (CCM) key encryption " 768e8ec596SKim Phillips "option in the FIFO STORE Command, the Nonce counter " 778e8ec596SKim Phillips "reached its maximum value and this encryption mode " 788e8ec596SKim Phillips "can no longer be used." }, 798e8ec596SKim Phillips { 0x22, "Meta data is too large (> 511 bytes) for TLS decap " 808e8ec596SKim Phillips "(input frame; block ciphers) and IPsec decap (output " 818e8ec596SKim Phillips "frame, when doing the next header byte update) and " 828e8ec596SKim Phillips "DCRC (output frame)." }, 83281922a1SKim Phillips { 0x23, "Read Input Frame error" }, 84281922a1SKim Phillips { 0x24, "JDKEK, TDKEK or TDSK not loaded error" }, 858e8ec596SKim Phillips { 0x80, "DNR (do not run) error" }, 868e8ec596SKim Phillips { 0x81, "undefined protocol command" }, 878e8ec596SKim Phillips { 0x82, "invalid setting in PDB" }, 888e8ec596SKim Phillips { 0x83, "Anti-replay LATE error" }, 898e8ec596SKim Phillips { 0x84, "Anti-replay REPLAY error" }, 908e8ec596SKim Phillips { 0x85, "Sequence number overflow" }, 918e8ec596SKim Phillips { 0x86, "Sigver invalid signature" }, 928e8ec596SKim Phillips { 0x87, "DSA Sign Illegal test descriptor" }, 938e8ec596SKim Phillips { 0x88, "Protocol Format Error - A protocol has seen an error " 948e8ec596SKim Phillips "in the format of data received. When running RSA, " 958e8ec596SKim Phillips "this means that formatting with random padding was " 968e8ec596SKim Phillips "used, and did not follow the form: 0x00, 0x02, 8-to-N " 978e8ec596SKim Phillips "bytes of non-zero pad, 0x00, F data." }, 988e8ec596SKim Phillips { 0x89, "Protocol Size Error - A protocol has seen an error in " 998e8ec596SKim Phillips "size. When running RSA, pdb size N < (size of F) when " 1008e8ec596SKim Phillips "no formatting is used; or pdb size N < (F + 11) when " 1018e8ec596SKim Phillips "formatting is used." }, 1028e8ec596SKim Phillips { 0xC1, "Blob Command error: Undefined mode" }, 1038e8ec596SKim Phillips { 0xC2, "Blob Command error: Secure Memory Blob mode error" }, 1048e8ec596SKim Phillips { 0xC4, "Blob Command error: Black Blob key or input size " 1058e8ec596SKim Phillips "error" }, 1068e8ec596SKim Phillips { 0xC5, "Blob Command error: Invalid key destination" }, 1078e8ec596SKim Phillips { 0xC8, "Blob Command error: Trusted/Secure mode error" }, 1088e8ec596SKim Phillips { 0xF0, "IPsec TTL or hop limit field either came in as 0, " 1098e8ec596SKim Phillips "or was decremented to 0" }, 1108e8ec596SKim Phillips { 0xF1, "3GPP HFN matches or exceeds the Threshold" }, 1118e8ec596SKim Phillips }; 1129724d7adSMarek Vasut 1139724d7adSMarek Vasut static const char * const cha_id_list[] = { 1149724d7adSMarek Vasut "", 1159724d7adSMarek Vasut "AES", 1169724d7adSMarek Vasut "DES", 1179724d7adSMarek Vasut "ARC4", 1189724d7adSMarek Vasut "MDHA", 1199724d7adSMarek Vasut "RNG", 1209724d7adSMarek Vasut "SNOW f8", 1219724d7adSMarek Vasut "Kasumi f8/9", 1229724d7adSMarek Vasut "PKHA", 1239724d7adSMarek Vasut "CRCA", 1249724d7adSMarek Vasut "SNOW f9", 1259724d7adSMarek Vasut "ZUCE", 1269724d7adSMarek Vasut "ZUCA", 1279724d7adSMarek Vasut }; 1289724d7adSMarek Vasut 1299724d7adSMarek Vasut static const char * const err_id_list[] = { 1309724d7adSMarek Vasut "No error.", 1319724d7adSMarek Vasut "Mode error.", 1329724d7adSMarek Vasut "Data size error.", 1339724d7adSMarek Vasut "Key size error.", 1349724d7adSMarek Vasut "PKHA A memory size error.", 1359724d7adSMarek Vasut "PKHA B memory size error.", 1369724d7adSMarek Vasut "Data arrived out of sequence error.", 1379724d7adSMarek Vasut "PKHA divide-by-zero error.", 1389724d7adSMarek Vasut "PKHA modulus even error.", 1399724d7adSMarek Vasut "DES key parity error.", 1409724d7adSMarek Vasut "ICV check failed.", 1419724d7adSMarek Vasut "Hardware error.", 1429724d7adSMarek Vasut "Unsupported CCM AAD size.", 1439724d7adSMarek Vasut "Class 1 CHA is not reset", 1449724d7adSMarek Vasut "Invalid CHA combination was selected", 1459724d7adSMarek Vasut "Invalid CHA selected.", 1469724d7adSMarek Vasut }; 1479724d7adSMarek Vasut 1489724d7adSMarek Vasut static const char * const rng_err_id_list[] = { 1499724d7adSMarek Vasut "", 1509724d7adSMarek Vasut "", 1519724d7adSMarek Vasut "", 1529724d7adSMarek Vasut "Instantiate", 1539724d7adSMarek Vasut "Not instantiated", 1549724d7adSMarek Vasut "Test instantiate", 1559724d7adSMarek Vasut "Prediction resistance", 1569724d7adSMarek Vasut "Prediction resistance and test request", 1579724d7adSMarek Vasut "Uninstantiate", 1589724d7adSMarek Vasut "Secure key generation", 1599724d7adSMarek Vasut }; 1609724d7adSMarek Vasut 1619724d7adSMarek Vasut #define SPRINTFCAT(str, format, param, max_alloc) \ 1629724d7adSMarek Vasut { \ 1639724d7adSMarek Vasut char *tmp; \ 1649724d7adSMarek Vasut \ 1659724d7adSMarek Vasut tmp = kmalloc(sizeof(format) + max_alloc, GFP_ATOMIC); \ 1669724d7adSMarek Vasut sprintf(tmp, format, param); \ 1679724d7adSMarek Vasut strcat(str, tmp); \ 1689724d7adSMarek Vasut kfree(tmp); \ 1699724d7adSMarek Vasut } 1709724d7adSMarek Vasut 1718a475826SMarek Vasut static void report_ccb_status(struct device *jrdev, u32 status, 172e75880ddSMarek Vasut const char *error, char *__outstr) 1739724d7adSMarek Vasut { 1749724d7adSMarek Vasut u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >> 1759724d7adSMarek Vasut JRSTA_CCBERR_CHAID_SHIFT; 1769724d7adSMarek Vasut u8 err_id = status & JRSTA_CCBERR_ERRID_MASK; 177526243ccSMarek Vasut u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >> 178526243ccSMarek Vasut JRSTA_DECOERR_INDEX_SHIFT; 179*1e16322dSMarek Vasut char *idx_str; 180*1e16322dSMarek Vasut const char *cha_str = "unidentified cha_id value 0x"; 181*1e16322dSMarek Vasut char cha_err_code[3] = { 0 }; 182*1e16322dSMarek Vasut const char *err_str = "unidentified err_id value 0x"; 183*1e16322dSMarek Vasut char err_err_code[3] = { 0 }; 1848a475826SMarek Vasut 185526243ccSMarek Vasut if (status & JRSTA_DECOERR_JUMP) 186*1e16322dSMarek Vasut idx_str = "jump tgt desc idx"; 187526243ccSMarek Vasut else 188*1e16322dSMarek Vasut idx_str = "desc idx"; 189526243ccSMarek Vasut 190*1e16322dSMarek Vasut if (cha_id < ARRAY_SIZE(cha_id_list)) 191*1e16322dSMarek Vasut cha_str = cha_id_list[cha_id]; 192*1e16322dSMarek Vasut else 193*1e16322dSMarek Vasut snprintf(cha_err_code, sizeof(cha_err_code), "%02x", cha_id); 1949724d7adSMarek Vasut 1959724d7adSMarek Vasut if ((cha_id << JRSTA_CCBERR_CHAID_SHIFT) == JRSTA_CCBERR_CHAID_RNG && 1969724d7adSMarek Vasut err_id < ARRAY_SIZE(rng_err_id_list) && 1979724d7adSMarek Vasut strlen(rng_err_id_list[err_id])) { 1989724d7adSMarek Vasut /* RNG-only error */ 199*1e16322dSMarek Vasut err_str = rng_err_id_list[err_id]; 200*1e16322dSMarek Vasut } else if (err_id < ARRAY_SIZE(err_id_list)) 201*1e16322dSMarek Vasut err_str = err_id_list[err_id]; 202*1e16322dSMarek Vasut else 203*1e16322dSMarek Vasut snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id); 204e75880ddSMarek Vasut 205*1e16322dSMarek Vasut dev_err(jrdev, "%08x: %s: %s %d: %s%s: %s%s\n", 206*1e16322dSMarek Vasut status, error, idx_str, idx, 207*1e16322dSMarek Vasut cha_str, cha_err_code, 208*1e16322dSMarek Vasut err_str, err_err_code); 2099724d7adSMarek Vasut } 2109724d7adSMarek Vasut 2118a475826SMarek Vasut static void report_jump_status(struct device *jrdev, u32 status, 2128a475826SMarek Vasut const char *error, char *outstr) 2139724d7adSMarek Vasut { 214e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s: %s() not implemented\n", 215e75880ddSMarek Vasut status, error, __func__); 2169724d7adSMarek Vasut } 2179724d7adSMarek Vasut 2188a475826SMarek Vasut static void report_deco_status(struct device *jrdev, u32 status, 219e75880ddSMarek Vasut const char *error, char *__outstr) 2209724d7adSMarek Vasut { 221e75880ddSMarek Vasut char outstr[CAAM_ERROR_STR_MAX]; 222e75880ddSMarek Vasut 2238e8ec596SKim Phillips u8 desc_error = status & JRSTA_DECOERR_ERROR_MASK; 224526243ccSMarek Vasut u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >> 225526243ccSMarek Vasut JRSTA_DECOERR_INDEX_SHIFT; 226526243ccSMarek Vasut 2278e8ec596SKim Phillips int i; 2288a475826SMarek Vasut sprintf(outstr, "%s: ", error); 2298e8ec596SKim Phillips 230526243ccSMarek Vasut if (status & JRSTA_DECOERR_JUMP) 231526243ccSMarek Vasut strcat(outstr, "jump tgt desc idx "); 232526243ccSMarek Vasut else 233526243ccSMarek Vasut strcat(outstr, "desc idx "); 234526243ccSMarek Vasut 235526243ccSMarek Vasut SPRINTFCAT(outstr, "%d: ", idx, sizeof("255")); 2368e8ec596SKim Phillips 2376d00376aSDan Carpenter for (i = 0; i < ARRAY_SIZE(desc_error_list); i++) 2388e8ec596SKim Phillips if (desc_error_list[i].value == desc_error) 2398e8ec596SKim Phillips break; 2408e8ec596SKim Phillips 2416d00376aSDan Carpenter if (i != ARRAY_SIZE(desc_error_list) && desc_error_list[i].error_text) { 2428e8ec596SKim Phillips SPRINTFCAT(outstr, "%s", desc_error_list[i].error_text, 2438e8ec596SKim Phillips strlen(desc_error_list[i].error_text)); 2448e8ec596SKim Phillips } else { 2458e8ec596SKim Phillips SPRINTFCAT(outstr, "unidentified error value 0x%02x", 2468e8ec596SKim Phillips desc_error, sizeof("ff")); 2478e8ec596SKim Phillips } 248e75880ddSMarek Vasut 249e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s\n", status, outstr); 2508e8ec596SKim Phillips } 2518e8ec596SKim Phillips 2528a475826SMarek Vasut static void report_jr_status(struct device *jrdev, u32 status, 2538a475826SMarek Vasut const char *error, char *outstr) 2548e8ec596SKim Phillips { 255e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s: %s() not implemented\n", 256e75880ddSMarek Vasut status, error, __func__); 2578e8ec596SKim Phillips } 2588e8ec596SKim Phillips 2598a475826SMarek Vasut static void report_cond_code_status(struct device *jrdev, u32 status, 2608a475826SMarek Vasut const char *error, char *outstr) 2618e8ec596SKim Phillips { 262e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s: %s() not implemented\n", 263e75880ddSMarek Vasut status, error, __func__); 2648e8ec596SKim Phillips } 2658e8ec596SKim Phillips 266fa9659cdSMarek Vasut void caam_jr_strstatus(struct device *jrdev, u32 status) 2678e8ec596SKim Phillips { 26896aef9a8SKim Phillips static const struct stat_src { 2698a475826SMarek Vasut void (*report_ssed)(struct device *jrdev, u32 status, 2708a475826SMarek Vasut const char *error, char *outstr); 2718a475826SMarek Vasut const char *error; 2728e8ec596SKim Phillips } status_src[] = { 2738e8ec596SKim Phillips { NULL, "No error" }, 2748e8ec596SKim Phillips { NULL, NULL }, 2758e8ec596SKim Phillips { report_ccb_status, "CCB" }, 2768e8ec596SKim Phillips { report_jump_status, "Jump" }, 2778e8ec596SKim Phillips { report_deco_status, "DECO" }, 2788e8ec596SKim Phillips { NULL, NULL }, 2798e8ec596SKim Phillips { report_jr_status, "Job Ring" }, 2808e8ec596SKim Phillips { report_cond_code_status, "Condition Code" }, 2818e8ec596SKim Phillips }; 2828e8ec596SKim Phillips u32 ssrc = status >> JRSTA_SSRC_SHIFT; 2838e8ec596SKim Phillips 284867e1ee3SMarek Vasut /* 285867e1ee3SMarek Vasut * If there is no further error handling function, just 286867e1ee3SMarek Vasut * print the error code, error string and exit. 287867e1ee3SMarek Vasut */ 288867e1ee3SMarek Vasut if (!status_src[ssrc].report_ssed) { 289867e1ee3SMarek Vasut dev_err(jrdev, "%08x: %s: \n", status, status_src[ssrc].error); 290867e1ee3SMarek Vasut return; 291867e1ee3SMarek Vasut } 292867e1ee3SMarek Vasut 2938a475826SMarek Vasut status_src[ssrc].report_ssed(jrdev, status, 294e75880ddSMarek Vasut status_src[ssrc].error, NULL); 2958e8ec596SKim Phillips } 2968e8ec596SKim Phillips EXPORT_SYMBOL(caam_jr_strstatus); 297