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; 16e397ee0fSMarek Vasut const char *error_text; 178e8ec596SKim Phillips } desc_error_list[] = { 18281922a1SKim Phillips { 0x00, "No error." }, 19da37503dSMarek Vasut { 0x01, "SGT Length Error. The descriptor is trying to read more data than is contained in the SGT table." }, 20281922a1SKim Phillips { 0x02, "SGT Null Entry Error." }, 21da37503dSMarek Vasut { 0x03, "Job Ring Control Error. There is a bad value in the Job Ring Control register." }, 22da37503dSMarek Vasut { 0x04, "Invalid Descriptor Command. The Descriptor Command field is invalid." }, 238e8ec596SKim Phillips { 0x05, "Reserved." }, 248e8ec596SKim Phillips { 0x06, "Invalid KEY Command" }, 258e8ec596SKim Phillips { 0x07, "Invalid LOAD Command" }, 268e8ec596SKim Phillips { 0x08, "Invalid STORE Command" }, 278e8ec596SKim Phillips { 0x09, "Invalid OPERATION Command" }, 288e8ec596SKim Phillips { 0x0A, "Invalid FIFO LOAD Command" }, 298e8ec596SKim Phillips { 0x0B, "Invalid FIFO STORE Command" }, 30281922a1SKim Phillips { 0x0C, "Invalid MOVE/MOVE_LEN Command" }, 31da37503dSMarek Vasut { 0x0D, "Invalid JUMP Command. A nonlocal JUMP Command is invalid because the target is not a Job Header Command, or the jump is from a Trusted Descriptor to a Job Descriptor, or because the target Descriptor contains a Shared Descriptor." }, 328e8ec596SKim Phillips { 0x0E, "Invalid MATH Command" }, 338e8ec596SKim Phillips { 0x0F, "Invalid SIGNATURE Command" }, 34da37503dSMarek Vasut { 0x10, "Invalid Sequence Command. A SEQ IN PTR OR SEQ OUT PTR Command is invalid or a SEQ KEY, SEQ LOAD, SEQ FIFO LOAD, or SEQ FIFO STORE decremented the input or output sequence length below 0. This error may result if a built-in PROTOCOL Command has encountered a malformed PDU." }, 358e8ec596SKim Phillips { 0x11, "Skip data type invalid. The type must be 0xE or 0xF."}, 368e8ec596SKim Phillips { 0x12, "Shared Descriptor Header Error" }, 37da37503dSMarek Vasut { 0x13, "Header Error. Invalid length or parity, or certain other problems." }, 38da37503dSMarek Vasut { 0x14, "Burster Error. Burster has gotten to an illegal state" }, 39da37503dSMarek Vasut { 0x15, "Context Register Length Error. The descriptor is trying to read or write past the end of the Context Register. A SEQ LOAD or SEQ STORE with the VLF bit set was executed with too large a length in the variable length register (VSOL for SEQ STORE or VSIL for SEQ LOAD)." }, 408e8ec596SKim Phillips { 0x16, "DMA Error" }, 418e8ec596SKim Phillips { 0x17, "Reserved." }, 428e8ec596SKim Phillips { 0x1A, "Job failed due to JR reset" }, 438e8ec596SKim Phillips { 0x1B, "Job failed due to Fail Mode" }, 448e8ec596SKim Phillips { 0x1C, "DECO Watchdog timer timeout error" }, 45da37503dSMarek Vasut { 0x1D, "DECO tried to copy a key from another DECO but the other DECO's Key Registers were locked" }, 46da37503dSMarek Vasut { 0x1E, "DECO attempted to copy data from a DECO that had an unmasked Descriptor error" }, 47da37503dSMarek Vasut { 0x1F, "LIODN error. DECO was trying to share from itself or from another DECO but the two Non-SEQ LIODN values didn't match or the 'shared from' DECO's Descriptor required that the SEQ LIODNs be the same and they aren't." }, 48da37503dSMarek Vasut { 0x20, "DECO has completed a reset initiated via the DRR register" }, 49da37503dSMarek Vasut { 0x21, "Nonce error. When using EKT (CCM) key encryption option in the FIFO STORE Command, the Nonce counter reached its maximum value and this encryption mode can no longer be used." }, 50da37503dSMarek Vasut { 0x22, "Meta data is too large (> 511 bytes) for TLS decap (input frame; block ciphers) and IPsec decap (output frame, when doing the next header byte update) and DCRC (output frame)." }, 51281922a1SKim Phillips { 0x23, "Read Input Frame error" }, 52281922a1SKim Phillips { 0x24, "JDKEK, TDKEK or TDSK not loaded error" }, 538e8ec596SKim Phillips { 0x80, "DNR (do not run) error" }, 548e8ec596SKim Phillips { 0x81, "undefined protocol command" }, 558e8ec596SKim Phillips { 0x82, "invalid setting in PDB" }, 568e8ec596SKim Phillips { 0x83, "Anti-replay LATE error" }, 578e8ec596SKim Phillips { 0x84, "Anti-replay REPLAY error" }, 588e8ec596SKim Phillips { 0x85, "Sequence number overflow" }, 598e8ec596SKim Phillips { 0x86, "Sigver invalid signature" }, 608e8ec596SKim Phillips { 0x87, "DSA Sign Illegal test descriptor" }, 61da37503dSMarek Vasut { 0x88, "Protocol Format Error - A protocol has seen an error in the format of data received. When running RSA, this means that formatting with random padding was used, and did not follow the form: 0x00, 0x02, 8-to-N bytes of non-zero pad, 0x00, F data." }, 62da37503dSMarek Vasut { 0x89, "Protocol Size Error - A protocol has seen an error in size. When running RSA, pdb size N < (size of F) when no formatting is used; or pdb size N < (F + 11) when formatting is used." }, 638e8ec596SKim Phillips { 0xC1, "Blob Command error: Undefined mode" }, 648e8ec596SKim Phillips { 0xC2, "Blob Command error: Secure Memory Blob mode error" }, 65da37503dSMarek Vasut { 0xC4, "Blob Command error: Black Blob key or input size error" }, 668e8ec596SKim Phillips { 0xC5, "Blob Command error: Invalid key destination" }, 678e8ec596SKim Phillips { 0xC8, "Blob Command error: Trusted/Secure mode error" }, 68da37503dSMarek Vasut { 0xF0, "IPsec TTL or hop limit field either came in as 0, or was decremented to 0" }, 698e8ec596SKim Phillips { 0xF1, "3GPP HFN matches or exceeds the Threshold" }, 708e8ec596SKim Phillips }; 719724d7adSMarek Vasut 729724d7adSMarek Vasut static const char * const cha_id_list[] = { 739724d7adSMarek Vasut "", 749724d7adSMarek Vasut "AES", 759724d7adSMarek Vasut "DES", 769724d7adSMarek Vasut "ARC4", 779724d7adSMarek Vasut "MDHA", 789724d7adSMarek Vasut "RNG", 799724d7adSMarek Vasut "SNOW f8", 809724d7adSMarek Vasut "Kasumi f8/9", 819724d7adSMarek Vasut "PKHA", 829724d7adSMarek Vasut "CRCA", 839724d7adSMarek Vasut "SNOW f9", 849724d7adSMarek Vasut "ZUCE", 859724d7adSMarek Vasut "ZUCA", 869724d7adSMarek Vasut }; 879724d7adSMarek Vasut 889724d7adSMarek Vasut static const char * const err_id_list[] = { 899724d7adSMarek Vasut "No error.", 909724d7adSMarek Vasut "Mode error.", 919724d7adSMarek Vasut "Data size error.", 929724d7adSMarek Vasut "Key size error.", 939724d7adSMarek Vasut "PKHA A memory size error.", 949724d7adSMarek Vasut "PKHA B memory size error.", 959724d7adSMarek Vasut "Data arrived out of sequence error.", 969724d7adSMarek Vasut "PKHA divide-by-zero error.", 979724d7adSMarek Vasut "PKHA modulus even error.", 989724d7adSMarek Vasut "DES key parity error.", 999724d7adSMarek Vasut "ICV check failed.", 1009724d7adSMarek Vasut "Hardware error.", 1019724d7adSMarek Vasut "Unsupported CCM AAD size.", 1029724d7adSMarek Vasut "Class 1 CHA is not reset", 1039724d7adSMarek Vasut "Invalid CHA combination was selected", 1049724d7adSMarek Vasut "Invalid CHA selected.", 1059724d7adSMarek Vasut }; 1069724d7adSMarek Vasut 1079724d7adSMarek Vasut static const char * const rng_err_id_list[] = { 1089724d7adSMarek Vasut "", 1099724d7adSMarek Vasut "", 1109724d7adSMarek Vasut "", 1119724d7adSMarek Vasut "Instantiate", 1129724d7adSMarek Vasut "Not instantiated", 1139724d7adSMarek Vasut "Test instantiate", 1149724d7adSMarek Vasut "Prediction resistance", 1159724d7adSMarek Vasut "Prediction resistance and test request", 1169724d7adSMarek Vasut "Uninstantiate", 1179724d7adSMarek Vasut "Secure key generation", 1189724d7adSMarek Vasut }; 1199724d7adSMarek Vasut 120e397ee0fSMarek Vasut static void report_ccb_status(struct device *jrdev, const u32 status, 121e397ee0fSMarek Vasut const char *error) 1229724d7adSMarek Vasut { 1239724d7adSMarek Vasut u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >> 1249724d7adSMarek Vasut JRSTA_CCBERR_CHAID_SHIFT; 1259724d7adSMarek Vasut u8 err_id = status & JRSTA_CCBERR_ERRID_MASK; 126526243ccSMarek Vasut u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >> 127526243ccSMarek Vasut JRSTA_DECOERR_INDEX_SHIFT; 1281e16322dSMarek Vasut char *idx_str; 1291e16322dSMarek Vasut const char *cha_str = "unidentified cha_id value 0x"; 1301e16322dSMarek Vasut char cha_err_code[3] = { 0 }; 1311e16322dSMarek Vasut const char *err_str = "unidentified err_id value 0x"; 1321e16322dSMarek Vasut char err_err_code[3] = { 0 }; 1338a475826SMarek Vasut 134526243ccSMarek Vasut if (status & JRSTA_DECOERR_JUMP) 1351e16322dSMarek Vasut idx_str = "jump tgt desc idx"; 136526243ccSMarek Vasut else 1371e16322dSMarek Vasut idx_str = "desc idx"; 138526243ccSMarek Vasut 1391e16322dSMarek Vasut if (cha_id < ARRAY_SIZE(cha_id_list)) 1401e16322dSMarek Vasut cha_str = cha_id_list[cha_id]; 1411e16322dSMarek Vasut else 1421e16322dSMarek Vasut snprintf(cha_err_code, sizeof(cha_err_code), "%02x", cha_id); 1439724d7adSMarek Vasut 1449724d7adSMarek Vasut if ((cha_id << JRSTA_CCBERR_CHAID_SHIFT) == JRSTA_CCBERR_CHAID_RNG && 1459724d7adSMarek Vasut err_id < ARRAY_SIZE(rng_err_id_list) && 1469724d7adSMarek Vasut strlen(rng_err_id_list[err_id])) { 1479724d7adSMarek Vasut /* RNG-only error */ 1481e16322dSMarek Vasut err_str = rng_err_id_list[err_id]; 149*9305dff7SHoria Geantă } else { 1501e16322dSMarek Vasut err_str = err_id_list[err_id]; 151*9305dff7SHoria Geantă } 152e75880ddSMarek Vasut 1533f80be02SKim Phillips /* 1543f80be02SKim Phillips * CCB ICV check failures are part of normal operation life; 1553f80be02SKim Phillips * we leave the upper layers to do what they want with them. 1563f80be02SKim Phillips */ 1573f80be02SKim Phillips if (err_id != JRSTA_CCBERR_ERRID_ICVCHK) 1581e16322dSMarek Vasut dev_err(jrdev, "%08x: %s: %s %d: %s%s: %s%s\n", 1591e16322dSMarek Vasut status, error, idx_str, idx, 1601e16322dSMarek Vasut cha_str, cha_err_code, 1611e16322dSMarek Vasut err_str, err_err_code); 1629724d7adSMarek Vasut } 1639724d7adSMarek Vasut 164e397ee0fSMarek Vasut static void report_jump_status(struct device *jrdev, const u32 status, 165e397ee0fSMarek Vasut const char *error) 1669724d7adSMarek Vasut { 167e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s: %s() not implemented\n", 168e75880ddSMarek Vasut status, error, __func__); 1699724d7adSMarek Vasut } 1709724d7adSMarek Vasut 171e397ee0fSMarek Vasut static void report_deco_status(struct device *jrdev, const u32 status, 172e397ee0fSMarek Vasut const char *error) 1739724d7adSMarek Vasut { 1744f0fa52aSMarek Vasut u8 err_id = status & JRSTA_DECOERR_ERROR_MASK; 175526243ccSMarek Vasut u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >> 176526243ccSMarek Vasut JRSTA_DECOERR_INDEX_SHIFT; 1774f0fa52aSMarek Vasut char *idx_str; 178e397ee0fSMarek Vasut const char *err_str = "unidentified error value 0x"; 1794f0fa52aSMarek Vasut char err_err_code[3] = { 0 }; 1808e8ec596SKim Phillips int i; 1818e8ec596SKim Phillips 182526243ccSMarek Vasut if (status & JRSTA_DECOERR_JUMP) 1834f0fa52aSMarek Vasut idx_str = "jump tgt desc idx"; 184526243ccSMarek Vasut else 1854f0fa52aSMarek Vasut idx_str = "desc idx"; 1868e8ec596SKim Phillips 1876d00376aSDan Carpenter for (i = 0; i < ARRAY_SIZE(desc_error_list); i++) 1884f0fa52aSMarek Vasut if (desc_error_list[i].value == err_id) 1898e8ec596SKim Phillips break; 1908e8ec596SKim Phillips 1914f0fa52aSMarek Vasut if (i != ARRAY_SIZE(desc_error_list) && desc_error_list[i].error_text) 1924f0fa52aSMarek Vasut err_str = desc_error_list[i].error_text; 1934f0fa52aSMarek Vasut else 1944f0fa52aSMarek Vasut snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id); 195e75880ddSMarek Vasut 1964f0fa52aSMarek Vasut dev_err(jrdev, "%08x: %s: %s %d: %s%s\n", 1974f0fa52aSMarek Vasut status, error, idx_str, idx, err_str, err_err_code); 1988e8ec596SKim Phillips } 1998e8ec596SKim Phillips 200e397ee0fSMarek Vasut static void report_jr_status(struct device *jrdev, const u32 status, 201e397ee0fSMarek Vasut const char *error) 2028e8ec596SKim Phillips { 203e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s: %s() not implemented\n", 204e75880ddSMarek Vasut status, error, __func__); 2058e8ec596SKim Phillips } 2068e8ec596SKim Phillips 207e397ee0fSMarek Vasut static void report_cond_code_status(struct device *jrdev, const u32 status, 208e397ee0fSMarek Vasut const char *error) 2098e8ec596SKim Phillips { 210e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s: %s() not implemented\n", 211e75880ddSMarek Vasut status, error, __func__); 2128e8ec596SKim Phillips } 2138e8ec596SKim Phillips 214fa9659cdSMarek Vasut void caam_jr_strstatus(struct device *jrdev, u32 status) 2158e8ec596SKim Phillips { 21696aef9a8SKim Phillips static const struct stat_src { 217e397ee0fSMarek Vasut void (*report_ssed)(struct device *jrdev, const u32 status, 218e397ee0fSMarek Vasut const char *error); 2198a475826SMarek Vasut const char *error; 22049783d0fSCristian Stoica } status_src[16] = { 2218e8ec596SKim Phillips { NULL, "No error" }, 2228e8ec596SKim Phillips { NULL, NULL }, 2238e8ec596SKim Phillips { report_ccb_status, "CCB" }, 2248e8ec596SKim Phillips { report_jump_status, "Jump" }, 2258e8ec596SKim Phillips { report_deco_status, "DECO" }, 22649783d0fSCristian Stoica { NULL, "Queue Manager Interface" }, 2278e8ec596SKim Phillips { report_jr_status, "Job Ring" }, 2288e8ec596SKim Phillips { report_cond_code_status, "Condition Code" }, 22949783d0fSCristian Stoica { NULL, NULL }, 23049783d0fSCristian Stoica { NULL, NULL }, 23149783d0fSCristian Stoica { NULL, NULL }, 23249783d0fSCristian Stoica { NULL, NULL }, 23349783d0fSCristian Stoica { NULL, NULL }, 23449783d0fSCristian Stoica { NULL, NULL }, 23549783d0fSCristian Stoica { NULL, NULL }, 23649783d0fSCristian Stoica { NULL, NULL }, 2378e8ec596SKim Phillips }; 2388e8ec596SKim Phillips u32 ssrc = status >> JRSTA_SSRC_SHIFT; 239e397ee0fSMarek Vasut const char *error = status_src[ssrc].error; 2408e8ec596SKim Phillips 241867e1ee3SMarek Vasut /* 24249783d0fSCristian Stoica * If there is an error handling function, call it to report the error. 24349783d0fSCristian Stoica * Otherwise print the error source name. 244867e1ee3SMarek Vasut */ 24549783d0fSCristian Stoica if (status_src[ssrc].report_ssed) 246e397ee0fSMarek Vasut status_src[ssrc].report_ssed(jrdev, status, error); 24749783d0fSCristian Stoica else if (error) 24849783d0fSCristian Stoica dev_err(jrdev, "%d: %s\n", ssrc, error); 24949783d0fSCristian Stoica else 25049783d0fSCristian Stoica dev_err(jrdev, "%d: unknown error source\n", ssrc); 2518e8ec596SKim Phillips } 2528e8ec596SKim Phillips EXPORT_SYMBOL(caam_jr_strstatus); 253