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]; 1491e16322dSMarek Vasut } else if (err_id < ARRAY_SIZE(err_id_list)) 1501e16322dSMarek Vasut err_str = err_id_list[err_id]; 1511e16322dSMarek Vasut else 1521e16322dSMarek Vasut snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id); 153e75880ddSMarek Vasut 154*3f80be02SKim Phillips /* 155*3f80be02SKim Phillips * CCB ICV check failures are part of normal operation life; 156*3f80be02SKim Phillips * we leave the upper layers to do what they want with them. 157*3f80be02SKim Phillips */ 158*3f80be02SKim Phillips if (err_id != JRSTA_CCBERR_ERRID_ICVCHK) 1591e16322dSMarek Vasut dev_err(jrdev, "%08x: %s: %s %d: %s%s: %s%s\n", 1601e16322dSMarek Vasut status, error, idx_str, idx, 1611e16322dSMarek Vasut cha_str, cha_err_code, 1621e16322dSMarek Vasut err_str, err_err_code); 1639724d7adSMarek Vasut } 1649724d7adSMarek Vasut 165e397ee0fSMarek Vasut static void report_jump_status(struct device *jrdev, const u32 status, 166e397ee0fSMarek Vasut const char *error) 1679724d7adSMarek Vasut { 168e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s: %s() not implemented\n", 169e75880ddSMarek Vasut status, error, __func__); 1709724d7adSMarek Vasut } 1719724d7adSMarek Vasut 172e397ee0fSMarek Vasut static void report_deco_status(struct device *jrdev, const u32 status, 173e397ee0fSMarek Vasut const char *error) 1749724d7adSMarek Vasut { 1754f0fa52aSMarek Vasut u8 err_id = status & JRSTA_DECOERR_ERROR_MASK; 176526243ccSMarek Vasut u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >> 177526243ccSMarek Vasut JRSTA_DECOERR_INDEX_SHIFT; 1784f0fa52aSMarek Vasut char *idx_str; 179e397ee0fSMarek Vasut const char *err_str = "unidentified error value 0x"; 1804f0fa52aSMarek Vasut char err_err_code[3] = { 0 }; 1818e8ec596SKim Phillips int i; 1828e8ec596SKim Phillips 183526243ccSMarek Vasut if (status & JRSTA_DECOERR_JUMP) 1844f0fa52aSMarek Vasut idx_str = "jump tgt desc idx"; 185526243ccSMarek Vasut else 1864f0fa52aSMarek Vasut idx_str = "desc idx"; 1878e8ec596SKim Phillips 1886d00376aSDan Carpenter for (i = 0; i < ARRAY_SIZE(desc_error_list); i++) 1894f0fa52aSMarek Vasut if (desc_error_list[i].value == err_id) 1908e8ec596SKim Phillips break; 1918e8ec596SKim Phillips 1924f0fa52aSMarek Vasut if (i != ARRAY_SIZE(desc_error_list) && desc_error_list[i].error_text) 1934f0fa52aSMarek Vasut err_str = desc_error_list[i].error_text; 1944f0fa52aSMarek Vasut else 1954f0fa52aSMarek Vasut snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id); 196e75880ddSMarek Vasut 1974f0fa52aSMarek Vasut dev_err(jrdev, "%08x: %s: %s %d: %s%s\n", 1984f0fa52aSMarek Vasut status, error, idx_str, idx, err_str, err_err_code); 1998e8ec596SKim Phillips } 2008e8ec596SKim Phillips 201e397ee0fSMarek Vasut static void report_jr_status(struct device *jrdev, const u32 status, 202e397ee0fSMarek Vasut const char *error) 2038e8ec596SKim Phillips { 204e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s: %s() not implemented\n", 205e75880ddSMarek Vasut status, error, __func__); 2068e8ec596SKim Phillips } 2078e8ec596SKim Phillips 208e397ee0fSMarek Vasut static void report_cond_code_status(struct device *jrdev, const u32 status, 209e397ee0fSMarek Vasut const char *error) 2108e8ec596SKim Phillips { 211e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s: %s() not implemented\n", 212e75880ddSMarek Vasut status, error, __func__); 2138e8ec596SKim Phillips } 2148e8ec596SKim Phillips 215fa9659cdSMarek Vasut void caam_jr_strstatus(struct device *jrdev, u32 status) 2168e8ec596SKim Phillips { 21796aef9a8SKim Phillips static const struct stat_src { 218e397ee0fSMarek Vasut void (*report_ssed)(struct device *jrdev, const u32 status, 219e397ee0fSMarek Vasut const char *error); 2208a475826SMarek Vasut const char *error; 22149783d0fSCristian Stoica } status_src[16] = { 2228e8ec596SKim Phillips { NULL, "No error" }, 2238e8ec596SKim Phillips { NULL, NULL }, 2248e8ec596SKim Phillips { report_ccb_status, "CCB" }, 2258e8ec596SKim Phillips { report_jump_status, "Jump" }, 2268e8ec596SKim Phillips { report_deco_status, "DECO" }, 22749783d0fSCristian Stoica { NULL, "Queue Manager Interface" }, 2288e8ec596SKim Phillips { report_jr_status, "Job Ring" }, 2298e8ec596SKim Phillips { report_cond_code_status, "Condition Code" }, 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 }, 23749783d0fSCristian Stoica { NULL, NULL }, 2388e8ec596SKim Phillips }; 2398e8ec596SKim Phillips u32 ssrc = status >> JRSTA_SSRC_SHIFT; 240e397ee0fSMarek Vasut const char *error = status_src[ssrc].error; 2418e8ec596SKim Phillips 242867e1ee3SMarek Vasut /* 24349783d0fSCristian Stoica * If there is an error handling function, call it to report the error. 24449783d0fSCristian Stoica * Otherwise print the error source name. 245867e1ee3SMarek Vasut */ 24649783d0fSCristian Stoica if (status_src[ssrc].report_ssed) 247e397ee0fSMarek Vasut status_src[ssrc].report_ssed(jrdev, status, error); 24849783d0fSCristian Stoica else if (error) 24949783d0fSCristian Stoica dev_err(jrdev, "%d: %s\n", ssrc, error); 25049783d0fSCristian Stoica else 25149783d0fSCristian Stoica dev_err(jrdev, "%d: unknown error source\n", ssrc); 2528e8ec596SKim Phillips } 2538e8ec596SKim Phillips EXPORT_SYMBOL(caam_jr_strstatus); 254