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; 1791e16322dSMarek Vasut char *idx_str; 1801e16322dSMarek Vasut const char *cha_str = "unidentified cha_id value 0x"; 1811e16322dSMarek Vasut char cha_err_code[3] = { 0 }; 1821e16322dSMarek Vasut const char *err_str = "unidentified err_id value 0x"; 1831e16322dSMarek Vasut char err_err_code[3] = { 0 }; 1848a475826SMarek Vasut 185526243ccSMarek Vasut if (status & JRSTA_DECOERR_JUMP) 1861e16322dSMarek Vasut idx_str = "jump tgt desc idx"; 187526243ccSMarek Vasut else 1881e16322dSMarek Vasut idx_str = "desc idx"; 189526243ccSMarek Vasut 1901e16322dSMarek Vasut if (cha_id < ARRAY_SIZE(cha_id_list)) 1911e16322dSMarek Vasut cha_str = cha_id_list[cha_id]; 1921e16322dSMarek Vasut else 1931e16322dSMarek 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 */ 1991e16322dSMarek Vasut err_str = rng_err_id_list[err_id]; 2001e16322dSMarek Vasut } else if (err_id < ARRAY_SIZE(err_id_list)) 2011e16322dSMarek Vasut err_str = err_id_list[err_id]; 2021e16322dSMarek Vasut else 2031e16322dSMarek Vasut snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id); 204e75880ddSMarek Vasut 2051e16322dSMarek Vasut dev_err(jrdev, "%08x: %s: %s %d: %s%s: %s%s\n", 2061e16322dSMarek Vasut status, error, idx_str, idx, 2071e16322dSMarek Vasut cha_str, cha_err_code, 2081e16322dSMarek 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 { 221*4f0fa52aSMarek Vasut u8 err_id = status & JRSTA_DECOERR_ERROR_MASK; 222526243ccSMarek Vasut u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >> 223526243ccSMarek Vasut JRSTA_DECOERR_INDEX_SHIFT; 224*4f0fa52aSMarek Vasut char *idx_str; 225*4f0fa52aSMarek Vasut char *err_str = "unidentified error value 0x"; 226*4f0fa52aSMarek Vasut char err_err_code[3] = { 0 }; 2278e8ec596SKim Phillips int i; 2288e8ec596SKim Phillips 229526243ccSMarek Vasut if (status & JRSTA_DECOERR_JUMP) 230*4f0fa52aSMarek Vasut idx_str = "jump tgt desc idx"; 231526243ccSMarek Vasut else 232*4f0fa52aSMarek Vasut idx_str = "desc idx"; 2338e8ec596SKim Phillips 2346d00376aSDan Carpenter for (i = 0; i < ARRAY_SIZE(desc_error_list); i++) 235*4f0fa52aSMarek Vasut if (desc_error_list[i].value == err_id) 2368e8ec596SKim Phillips break; 2378e8ec596SKim Phillips 238*4f0fa52aSMarek Vasut if (i != ARRAY_SIZE(desc_error_list) && desc_error_list[i].error_text) 239*4f0fa52aSMarek Vasut err_str = desc_error_list[i].error_text; 240*4f0fa52aSMarek Vasut else 241*4f0fa52aSMarek Vasut snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id); 242e75880ddSMarek Vasut 243*4f0fa52aSMarek Vasut dev_err(jrdev, "%08x: %s: %s %d: %s%s\n", 244*4f0fa52aSMarek Vasut status, error, idx_str, idx, err_str, err_err_code); 2458e8ec596SKim Phillips } 2468e8ec596SKim Phillips 2478a475826SMarek Vasut static void report_jr_status(struct device *jrdev, u32 status, 2488a475826SMarek Vasut const char *error, char *outstr) 2498e8ec596SKim Phillips { 250e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s: %s() not implemented\n", 251e75880ddSMarek Vasut status, error, __func__); 2528e8ec596SKim Phillips } 2538e8ec596SKim Phillips 2548a475826SMarek Vasut static void report_cond_code_status(struct device *jrdev, u32 status, 2558a475826SMarek Vasut const char *error, char *outstr) 2568e8ec596SKim Phillips { 257e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s: %s() not implemented\n", 258e75880ddSMarek Vasut status, error, __func__); 2598e8ec596SKim Phillips } 2608e8ec596SKim Phillips 261fa9659cdSMarek Vasut void caam_jr_strstatus(struct device *jrdev, u32 status) 2628e8ec596SKim Phillips { 26396aef9a8SKim Phillips static const struct stat_src { 2648a475826SMarek Vasut void (*report_ssed)(struct device *jrdev, u32 status, 2658a475826SMarek Vasut const char *error, char *outstr); 2668a475826SMarek Vasut const char *error; 2678e8ec596SKim Phillips } status_src[] = { 2688e8ec596SKim Phillips { NULL, "No error" }, 2698e8ec596SKim Phillips { NULL, NULL }, 2708e8ec596SKim Phillips { report_ccb_status, "CCB" }, 2718e8ec596SKim Phillips { report_jump_status, "Jump" }, 2728e8ec596SKim Phillips { report_deco_status, "DECO" }, 2738e8ec596SKim Phillips { NULL, NULL }, 2748e8ec596SKim Phillips { report_jr_status, "Job Ring" }, 2758e8ec596SKim Phillips { report_cond_code_status, "Condition Code" }, 2768e8ec596SKim Phillips }; 2778e8ec596SKim Phillips u32 ssrc = status >> JRSTA_SSRC_SHIFT; 2788e8ec596SKim Phillips 279867e1ee3SMarek Vasut /* 280867e1ee3SMarek Vasut * If there is no further error handling function, just 281867e1ee3SMarek Vasut * print the error code, error string and exit. 282867e1ee3SMarek Vasut */ 283867e1ee3SMarek Vasut if (!status_src[ssrc].report_ssed) { 284867e1ee3SMarek Vasut dev_err(jrdev, "%08x: %s: \n", status, status_src[ssrc].error); 285867e1ee3SMarek Vasut return; 286867e1ee3SMarek Vasut } 287867e1ee3SMarek Vasut 2888a475826SMarek Vasut status_src[ssrc].report_ssed(jrdev, status, 289e75880ddSMarek Vasut status_src[ssrc].error, NULL); 2908e8ec596SKim Phillips } 2918e8ec596SKim Phillips EXPORT_SYMBOL(caam_jr_strstatus); 292