1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
28e8ec596SKim Phillips /*
38e8ec596SKim Phillips * CAAM Error Reporting
48e8ec596SKim Phillips *
58e8ec596SKim Phillips * Copyright 2009-2011 Freescale Semiconductor, Inc.
68e8ec596SKim Phillips */
78e8ec596SKim Phillips
88e8ec596SKim Phillips #include "compat.h"
98e8ec596SKim Phillips #include "regs.h"
108e8ec596SKim Phillips #include "desc.h"
118e8ec596SKim Phillips #include "error.h"
128e8ec596SKim Phillips
13972b812bSHoria Geantă #ifdef DEBUG
14972b812bSHoria Geantă #include <linux/highmem.h>
15972b812bSHoria Geantă
caam_dump_sg(const char * prefix_str,int prefix_type,int rowsize,int groupsize,struct scatterlist * sg,size_t tlen,bool ascii)168a82451bSSascha Hauer void caam_dump_sg(const char *prefix_str, int prefix_type,
17972b812bSHoria Geantă int rowsize, int groupsize, struct scatterlist *sg,
18972b812bSHoria Geantă size_t tlen, bool ascii)
19972b812bSHoria Geantă {
20972b812bSHoria Geantă struct scatterlist *it;
21972b812bSHoria Geantă void *it_page;
22972b812bSHoria Geantă size_t len;
23972b812bSHoria Geantă void *buf;
24972b812bSHoria Geantă
258c65d354SIuliana Prodan for (it = sg; it && tlen > 0 ; it = sg_next(it)) {
26972b812bSHoria Geantă /*
27972b812bSHoria Geantă * make sure the scatterlist's page
28972b812bSHoria Geantă * has a valid virtual memory mapping
29972b812bSHoria Geantă */
30972b812bSHoria Geantă it_page = kmap_atomic(sg_page(it));
31972b812bSHoria Geantă if (unlikely(!it_page)) {
32972b812bSHoria Geantă pr_err("caam_dump_sg: kmap failed\n");
33972b812bSHoria Geantă return;
34972b812bSHoria Geantă }
35972b812bSHoria Geantă
36972b812bSHoria Geantă buf = it_page + it->offset;
37972b812bSHoria Geantă len = min_t(size_t, tlen, it->length);
388a82451bSSascha Hauer print_hex_dump_debug(prefix_str, prefix_type, rowsize,
39972b812bSHoria Geantă groupsize, buf, len, ascii);
40972b812bSHoria Geantă tlen -= len;
41972b812bSHoria Geantă
42972b812bSHoria Geantă kunmap_atomic(it_page);
43972b812bSHoria Geantă }
44972b812bSHoria Geantă }
45972b812bSHoria Geantă #else
caam_dump_sg(const char * prefix_str,int prefix_type,int rowsize,int groupsize,struct scatterlist * sg,size_t tlen,bool ascii)468a82451bSSascha Hauer void caam_dump_sg(const char *prefix_str, int prefix_type,
47972b812bSHoria Geantă int rowsize, int groupsize, struct scatterlist *sg,
48972b812bSHoria Geantă size_t tlen, bool ascii)
49972b812bSHoria Geantă {}
50972b812bSHoria Geantă #endif /* DEBUG */
51972b812bSHoria Geantă EXPORT_SYMBOL(caam_dump_sg);
52972b812bSHoria Geantă
535b3b9871SHoria Geantă bool caam_little_end;
545b3b9871SHoria Geantă EXPORT_SYMBOL(caam_little_end);
555b3b9871SHoria Geantă
565b3b9871SHoria Geantă bool caam_imx;
575b3b9871SHoria Geantă EXPORT_SYMBOL(caam_imx);
585b3b9871SHoria Geantă
591a3daadcSAndrey Smirnov size_t caam_ptr_sz;
601a3daadcSAndrey Smirnov EXPORT_SYMBOL(caam_ptr_sz);
611a3daadcSAndrey Smirnov
6296aef9a8SKim Phillips static const struct {
638e8ec596SKim Phillips u8 value;
64e397ee0fSMarek Vasut const char *error_text;
658e8ec596SKim Phillips } desc_error_list[] = {
66281922a1SKim Phillips { 0x00, "No error." },
67da37503dSMarek Vasut { 0x01, "SGT Length Error. The descriptor is trying to read more data than is contained in the SGT table." },
68281922a1SKim Phillips { 0x02, "SGT Null Entry Error." },
69da37503dSMarek Vasut { 0x03, "Job Ring Control Error. There is a bad value in the Job Ring Control register." },
70da37503dSMarek Vasut { 0x04, "Invalid Descriptor Command. The Descriptor Command field is invalid." },
718e8ec596SKim Phillips { 0x05, "Reserved." },
728e8ec596SKim Phillips { 0x06, "Invalid KEY Command" },
738e8ec596SKim Phillips { 0x07, "Invalid LOAD Command" },
748e8ec596SKim Phillips { 0x08, "Invalid STORE Command" },
758e8ec596SKim Phillips { 0x09, "Invalid OPERATION Command" },
768e8ec596SKim Phillips { 0x0A, "Invalid FIFO LOAD Command" },
778e8ec596SKim Phillips { 0x0B, "Invalid FIFO STORE Command" },
78281922a1SKim Phillips { 0x0C, "Invalid MOVE/MOVE_LEN Command" },
79da37503dSMarek 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." },
808e8ec596SKim Phillips { 0x0E, "Invalid MATH Command" },
818e8ec596SKim Phillips { 0x0F, "Invalid SIGNATURE Command" },
82da37503dSMarek 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." },
838e8ec596SKim Phillips { 0x11, "Skip data type invalid. The type must be 0xE or 0xF."},
848e8ec596SKim Phillips { 0x12, "Shared Descriptor Header Error" },
85da37503dSMarek Vasut { 0x13, "Header Error. Invalid length or parity, or certain other problems." },
86da37503dSMarek Vasut { 0x14, "Burster Error. Burster has gotten to an illegal state" },
87da37503dSMarek 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)." },
888e8ec596SKim Phillips { 0x16, "DMA Error" },
898e8ec596SKim Phillips { 0x17, "Reserved." },
908e8ec596SKim Phillips { 0x1A, "Job failed due to JR reset" },
918e8ec596SKim Phillips { 0x1B, "Job failed due to Fail Mode" },
928e8ec596SKim Phillips { 0x1C, "DECO Watchdog timer timeout error" },
93da37503dSMarek Vasut { 0x1D, "DECO tried to copy a key from another DECO but the other DECO's Key Registers were locked" },
94da37503dSMarek Vasut { 0x1E, "DECO attempted to copy data from a DECO that had an unmasked Descriptor error" },
95da37503dSMarek 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." },
96da37503dSMarek Vasut { 0x20, "DECO has completed a reset initiated via the DRR register" },
97da37503dSMarek 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." },
98da37503dSMarek 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)." },
99281922a1SKim Phillips { 0x23, "Read Input Frame error" },
100281922a1SKim Phillips { 0x24, "JDKEK, TDKEK or TDSK not loaded error" },
1018e8ec596SKim Phillips { 0x80, "DNR (do not run) error" },
1028e8ec596SKim Phillips { 0x81, "undefined protocol command" },
1038e8ec596SKim Phillips { 0x82, "invalid setting in PDB" },
1048e8ec596SKim Phillips { 0x83, "Anti-replay LATE error" },
1058e8ec596SKim Phillips { 0x84, "Anti-replay REPLAY error" },
1068e8ec596SKim Phillips { 0x85, "Sequence number overflow" },
1078e8ec596SKim Phillips { 0x86, "Sigver invalid signature" },
1088e8ec596SKim Phillips { 0x87, "DSA Sign Illegal test descriptor" },
109da37503dSMarek 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." },
110da37503dSMarek 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." },
1118e8ec596SKim Phillips { 0xC1, "Blob Command error: Undefined mode" },
1128e8ec596SKim Phillips { 0xC2, "Blob Command error: Secure Memory Blob mode error" },
113da37503dSMarek Vasut { 0xC4, "Blob Command error: Black Blob key or input size error" },
1148e8ec596SKim Phillips { 0xC5, "Blob Command error: Invalid key destination" },
1158e8ec596SKim Phillips { 0xC8, "Blob Command error: Trusted/Secure mode error" },
116da37503dSMarek Vasut { 0xF0, "IPsec TTL or hop limit field either came in as 0, or was decremented to 0" },
1178e8ec596SKim Phillips { 0xF1, "3GPP HFN matches or exceeds the Threshold" },
1188e8ec596SKim Phillips };
1199724d7adSMarek Vasut
12094cebd9dSHoria Geantă static const struct {
12194cebd9dSHoria Geantă u8 value;
12294cebd9dSHoria Geantă const char *error_text;
12394cebd9dSHoria Geantă } qi_error_list[] = {
12451fab3d7SHoria Geantă { 0x00, "No error" },
12594cebd9dSHoria Geantă { 0x1F, "Job terminated by FQ or ICID flush" },
12694cebd9dSHoria Geantă { 0x20, "FD format error"},
12794cebd9dSHoria Geantă { 0x21, "FD command format error"},
12894cebd9dSHoria Geantă { 0x23, "FL format error"},
12994cebd9dSHoria Geantă { 0x25, "CRJD specified in FD, but not enabled in FLC"},
13094cebd9dSHoria Geantă { 0x30, "Max. buffer size too small"},
13194cebd9dSHoria Geantă { 0x31, "DHR exceeds max. buffer size (allocate mode, S/G format)"},
13294cebd9dSHoria Geantă { 0x32, "SGT exceeds max. buffer size (allocate mode, S/G format"},
13394cebd9dSHoria Geantă { 0x33, "Size over/underflow (allocate mode)"},
13494cebd9dSHoria Geantă { 0x34, "Size over/underflow (reuse mode)"},
13594cebd9dSHoria Geantă { 0x35, "Length exceeds max. short length (allocate mode, S/G/ format)"},
13694cebd9dSHoria Geantă { 0x36, "Memory footprint exceeds max. value (allocate mode, S/G/ format)"},
13794cebd9dSHoria Geantă { 0x41, "SBC frame format not supported (allocate mode)"},
13894cebd9dSHoria Geantă { 0x42, "Pool 0 invalid / pool 1 size < pool 0 size (allocate mode)"},
13994cebd9dSHoria Geantă { 0x43, "Annotation output enabled but ASAR = 0 (allocate mode)"},
14094cebd9dSHoria Geantă { 0x44, "Unsupported or reserved frame format or SGHR = 1 (reuse mode)"},
14194cebd9dSHoria Geantă { 0x45, "DHR correction underflow (reuse mode, single buffer format)"},
14294cebd9dSHoria Geantă { 0x46, "Annotation length exceeds offset (reuse mode)"},
14394cebd9dSHoria Geantă { 0x48, "Annotation output enabled but ASA limited by ASAR (reuse mode)"},
14494cebd9dSHoria Geantă { 0x49, "Data offset correction exceeds input frame data length (reuse mode)"},
1456ddc8e31SColin Ian King { 0x4B, "Annotation output enabled but ASA cannot be expanded (frame list)"},
14694cebd9dSHoria Geantă { 0x51, "Unsupported IF reuse mode"},
14794cebd9dSHoria Geantă { 0x52, "Unsupported FL use mode"},
14894cebd9dSHoria Geantă { 0x53, "Unsupported RJD use mode"},
14994cebd9dSHoria Geantă { 0x54, "Unsupported inline descriptor use mode"},
15094cebd9dSHoria Geantă { 0xC0, "Table buffer pool 0 depletion"},
15194cebd9dSHoria Geantă { 0xC1, "Table buffer pool 1 depletion"},
15294cebd9dSHoria Geantă { 0xC2, "Data buffer pool 0 depletion, no OF allocated"},
15394cebd9dSHoria Geantă { 0xC3, "Data buffer pool 1 depletion, no OF allocated"},
15494cebd9dSHoria Geantă { 0xC4, "Data buffer pool 0 depletion, partial OF allocated"},
15594cebd9dSHoria Geantă { 0xC5, "Data buffer pool 1 depletion, partial OF allocated"},
15694cebd9dSHoria Geantă { 0xD0, "FLC read error"},
15794cebd9dSHoria Geantă { 0xD1, "FL read error"},
15894cebd9dSHoria Geantă { 0xD2, "FL write error"},
15994cebd9dSHoria Geantă { 0xD3, "OF SGT write error"},
16094cebd9dSHoria Geantă { 0xD4, "PTA read error"},
16194cebd9dSHoria Geantă { 0xD5, "PTA write error"},
16294cebd9dSHoria Geantă { 0xD6, "OF SGT F-bit write error"},
16394cebd9dSHoria Geantă { 0xD7, "ASA write error"},
16494cebd9dSHoria Geantă { 0xE1, "FLC[ICR]=0 ICID error"},
16594cebd9dSHoria Geantă { 0xE2, "FLC[ICR]=1 ICID error"},
16694cebd9dSHoria Geantă { 0xE4, "source of ICID flush not trusted (BDI = 0)"},
16794cebd9dSHoria Geantă };
16894cebd9dSHoria Geantă
1699724d7adSMarek Vasut static const char * const cha_id_list[] = {
1709724d7adSMarek Vasut "",
1719724d7adSMarek Vasut "AES",
1729724d7adSMarek Vasut "DES",
1739724d7adSMarek Vasut "ARC4",
1749724d7adSMarek Vasut "MDHA",
1759724d7adSMarek Vasut "RNG",
1769724d7adSMarek Vasut "SNOW f8",
1779724d7adSMarek Vasut "Kasumi f8/9",
1789724d7adSMarek Vasut "PKHA",
1799724d7adSMarek Vasut "CRCA",
1809724d7adSMarek Vasut "SNOW f9",
1819724d7adSMarek Vasut "ZUCE",
1829724d7adSMarek Vasut "ZUCA",
1839724d7adSMarek Vasut };
1849724d7adSMarek Vasut
1859724d7adSMarek Vasut static const char * const err_id_list[] = {
1869724d7adSMarek Vasut "No error.",
1879724d7adSMarek Vasut "Mode error.",
1889724d7adSMarek Vasut "Data size error.",
1899724d7adSMarek Vasut "Key size error.",
1909724d7adSMarek Vasut "PKHA A memory size error.",
1919724d7adSMarek Vasut "PKHA B memory size error.",
1929724d7adSMarek Vasut "Data arrived out of sequence error.",
1939724d7adSMarek Vasut "PKHA divide-by-zero error.",
1949724d7adSMarek Vasut "PKHA modulus even error.",
1959724d7adSMarek Vasut "DES key parity error.",
1969724d7adSMarek Vasut "ICV check failed.",
1979724d7adSMarek Vasut "Hardware error.",
1989724d7adSMarek Vasut "Unsupported CCM AAD size.",
1999724d7adSMarek Vasut "Class 1 CHA is not reset",
2009724d7adSMarek Vasut "Invalid CHA combination was selected",
2019724d7adSMarek Vasut "Invalid CHA selected.",
2029724d7adSMarek Vasut };
2039724d7adSMarek Vasut
2049724d7adSMarek Vasut static const char * const rng_err_id_list[] = {
2059724d7adSMarek Vasut "",
2069724d7adSMarek Vasut "",
2079724d7adSMarek Vasut "",
2089724d7adSMarek Vasut "Instantiate",
2099724d7adSMarek Vasut "Not instantiated",
2109724d7adSMarek Vasut "Test instantiate",
2119724d7adSMarek Vasut "Prediction resistance",
2129724d7adSMarek Vasut "Prediction resistance and test request",
2139724d7adSMarek Vasut "Uninstantiate",
2149724d7adSMarek Vasut "Secure key generation",
215*ee0a6de9SHoria Geantă "",
216*ee0a6de9SHoria Geantă "Hardware error",
217*ee0a6de9SHoria Geantă "Continuous check"
2189724d7adSMarek Vasut };
2199724d7adSMarek Vasut
report_ccb_status(struct device * jrdev,const u32 status,const char * error)2201984aaeeSHoria Geantă static int report_ccb_status(struct device *jrdev, const u32 status,
221e397ee0fSMarek Vasut const char *error)
2229724d7adSMarek Vasut {
2239724d7adSMarek Vasut u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >>
2249724d7adSMarek Vasut JRSTA_CCBERR_CHAID_SHIFT;
2259724d7adSMarek Vasut u8 err_id = status & JRSTA_CCBERR_ERRID_MASK;
226526243ccSMarek Vasut u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >>
227526243ccSMarek Vasut JRSTA_DECOERR_INDEX_SHIFT;
2281e16322dSMarek Vasut char *idx_str;
2291e16322dSMarek Vasut const char *cha_str = "unidentified cha_id value 0x";
2301e16322dSMarek Vasut char cha_err_code[3] = { 0 };
2311e16322dSMarek Vasut const char *err_str = "unidentified err_id value 0x";
2321e16322dSMarek Vasut char err_err_code[3] = { 0 };
2338a475826SMarek Vasut
234526243ccSMarek Vasut if (status & JRSTA_DECOERR_JUMP)
2351e16322dSMarek Vasut idx_str = "jump tgt desc idx";
236526243ccSMarek Vasut else
2371e16322dSMarek Vasut idx_str = "desc idx";
238526243ccSMarek Vasut
2391e16322dSMarek Vasut if (cha_id < ARRAY_SIZE(cha_id_list))
2401e16322dSMarek Vasut cha_str = cha_id_list[cha_id];
2411e16322dSMarek Vasut else
2421e16322dSMarek Vasut snprintf(cha_err_code, sizeof(cha_err_code), "%02x", cha_id);
2439724d7adSMarek Vasut
2449724d7adSMarek Vasut if ((cha_id << JRSTA_CCBERR_CHAID_SHIFT) == JRSTA_CCBERR_CHAID_RNG &&
2459724d7adSMarek Vasut err_id < ARRAY_SIZE(rng_err_id_list) &&
2469724d7adSMarek Vasut strlen(rng_err_id_list[err_id])) {
2479724d7adSMarek Vasut /* RNG-only error */
2481e16322dSMarek Vasut err_str = rng_err_id_list[err_id];
2499305dff7SHoria Geantă } else {
2501e16322dSMarek Vasut err_str = err_id_list[err_id];
2519305dff7SHoria Geantă }
252e75880ddSMarek Vasut
2533f80be02SKim Phillips /*
2543f80be02SKim Phillips * CCB ICV check failures are part of normal operation life;
2553f80be02SKim Phillips * we leave the upper layers to do what they want with them.
2563f80be02SKim Phillips */
2571984aaeeSHoria Geantă if (err_id == JRSTA_CCBERR_ERRID_ICVCHK)
2581984aaeeSHoria Geantă return -EBADMSG;
2591984aaeeSHoria Geantă
2601984aaeeSHoria Geantă dev_err_ratelimited(jrdev, "%08x: %s: %s %d: %s%s: %s%s\n", status,
2611984aaeeSHoria Geantă error, idx_str, idx, cha_str, cha_err_code,
2621e16322dSMarek Vasut err_str, err_err_code);
2631984aaeeSHoria Geantă
2641984aaeeSHoria Geantă return -EINVAL;
2659724d7adSMarek Vasut }
2669724d7adSMarek Vasut
report_jump_status(struct device * jrdev,const u32 status,const char * error)2671984aaeeSHoria Geantă static int report_jump_status(struct device *jrdev, const u32 status,
268e397ee0fSMarek Vasut const char *error)
2699724d7adSMarek Vasut {
270e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s: %s() not implemented\n",
271e75880ddSMarek Vasut status, error, __func__);
2721984aaeeSHoria Geantă
2731984aaeeSHoria Geantă return -EINVAL;
2749724d7adSMarek Vasut }
2759724d7adSMarek Vasut
report_deco_status(struct device * jrdev,const u32 status,const char * error)2761984aaeeSHoria Geantă static int report_deco_status(struct device *jrdev, const u32 status,
277e397ee0fSMarek Vasut const char *error)
2789724d7adSMarek Vasut {
2794f0fa52aSMarek Vasut u8 err_id = status & JRSTA_DECOERR_ERROR_MASK;
280526243ccSMarek Vasut u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >>
281526243ccSMarek Vasut JRSTA_DECOERR_INDEX_SHIFT;
2824f0fa52aSMarek Vasut char *idx_str;
283e397ee0fSMarek Vasut const char *err_str = "unidentified error value 0x";
2844f0fa52aSMarek Vasut char err_err_code[3] = { 0 };
2858e8ec596SKim Phillips int i;
2868e8ec596SKim Phillips
287526243ccSMarek Vasut if (status & JRSTA_DECOERR_JUMP)
2884f0fa52aSMarek Vasut idx_str = "jump tgt desc idx";
289526243ccSMarek Vasut else
2904f0fa52aSMarek Vasut idx_str = "desc idx";
2918e8ec596SKim Phillips
2926d00376aSDan Carpenter for (i = 0; i < ARRAY_SIZE(desc_error_list); i++)
2934f0fa52aSMarek Vasut if (desc_error_list[i].value == err_id)
2948e8ec596SKim Phillips break;
2958e8ec596SKim Phillips
2964f0fa52aSMarek Vasut if (i != ARRAY_SIZE(desc_error_list) && desc_error_list[i].error_text)
2974f0fa52aSMarek Vasut err_str = desc_error_list[i].error_text;
2984f0fa52aSMarek Vasut else
2994f0fa52aSMarek Vasut snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id);
300e75880ddSMarek Vasut
3014f0fa52aSMarek Vasut dev_err(jrdev, "%08x: %s: %s %d: %s%s\n",
3024f0fa52aSMarek Vasut status, error, idx_str, idx, err_str, err_err_code);
3031984aaeeSHoria Geantă
3041984aaeeSHoria Geantă return -EINVAL;
3058e8ec596SKim Phillips }
3068e8ec596SKim Phillips
report_qi_status(struct device * qidev,const u32 status,const char * error)3071984aaeeSHoria Geantă static int report_qi_status(struct device *qidev, const u32 status,
30894cebd9dSHoria Geantă const char *error)
30994cebd9dSHoria Geantă {
31094cebd9dSHoria Geantă u8 err_id = status & JRSTA_QIERR_ERROR_MASK;
31194cebd9dSHoria Geantă const char *err_str = "unidentified error value 0x";
31294cebd9dSHoria Geantă char err_err_code[3] = { 0 };
31394cebd9dSHoria Geantă int i;
31494cebd9dSHoria Geantă
31594cebd9dSHoria Geantă for (i = 0; i < ARRAY_SIZE(qi_error_list); i++)
31694cebd9dSHoria Geantă if (qi_error_list[i].value == err_id)
31794cebd9dSHoria Geantă break;
31894cebd9dSHoria Geantă
31994cebd9dSHoria Geantă if (i != ARRAY_SIZE(qi_error_list) && qi_error_list[i].error_text)
32094cebd9dSHoria Geantă err_str = qi_error_list[i].error_text;
32194cebd9dSHoria Geantă else
32294cebd9dSHoria Geantă snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id);
32394cebd9dSHoria Geantă
32494cebd9dSHoria Geantă dev_err(qidev, "%08x: %s: %s%s\n",
32594cebd9dSHoria Geantă status, error, err_str, err_err_code);
3261984aaeeSHoria Geantă
3271984aaeeSHoria Geantă return -EINVAL;
32894cebd9dSHoria Geantă }
32994cebd9dSHoria Geantă
report_jr_status(struct device * jrdev,const u32 status,const char * error)3301984aaeeSHoria Geantă static int report_jr_status(struct device *jrdev, const u32 status,
331e397ee0fSMarek Vasut const char *error)
3328e8ec596SKim Phillips {
333e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s: %s() not implemented\n",
334e75880ddSMarek Vasut status, error, __func__);
3351984aaeeSHoria Geantă
3361984aaeeSHoria Geantă return -EINVAL;
3378e8ec596SKim Phillips }
3388e8ec596SKim Phillips
report_cond_code_status(struct device * jrdev,const u32 status,const char * error)3391984aaeeSHoria Geantă static int report_cond_code_status(struct device *jrdev, const u32 status,
340e397ee0fSMarek Vasut const char *error)
3418e8ec596SKim Phillips {
342e75880ddSMarek Vasut dev_err(jrdev, "%08x: %s: %s() not implemented\n",
343e75880ddSMarek Vasut status, error, __func__);
3441984aaeeSHoria Geantă
3451984aaeeSHoria Geantă return -EINVAL;
3468e8ec596SKim Phillips }
3478e8ec596SKim Phillips
caam_strstatus(struct device * jrdev,u32 status,bool qi_v2)3481984aaeeSHoria Geantă int caam_strstatus(struct device *jrdev, u32 status, bool qi_v2)
3498e8ec596SKim Phillips {
35096aef9a8SKim Phillips static const struct stat_src {
3511984aaeeSHoria Geantă int (*report_ssed)(struct device *jrdev, const u32 status,
352e397ee0fSMarek Vasut const char *error);
3538a475826SMarek Vasut const char *error;
35449783d0fSCristian Stoica } status_src[16] = {
3558e8ec596SKim Phillips { NULL, "No error" },
3568e8ec596SKim Phillips { NULL, NULL },
3578e8ec596SKim Phillips { report_ccb_status, "CCB" },
3588e8ec596SKim Phillips { report_jump_status, "Jump" },
3598e8ec596SKim Phillips { report_deco_status, "DECO" },
36094cebd9dSHoria Geantă { report_qi_status, "Queue Manager Interface" },
3618e8ec596SKim Phillips { report_jr_status, "Job Ring" },
3628e8ec596SKim Phillips { report_cond_code_status, "Condition Code" },
36349783d0fSCristian Stoica { NULL, NULL },
36449783d0fSCristian Stoica { NULL, NULL },
36549783d0fSCristian Stoica { NULL, NULL },
36649783d0fSCristian Stoica { NULL, NULL },
36749783d0fSCristian Stoica { NULL, NULL },
36849783d0fSCristian Stoica { NULL, NULL },
36949783d0fSCristian Stoica { NULL, NULL },
37049783d0fSCristian Stoica { NULL, NULL },
3718e8ec596SKim Phillips };
3728e8ec596SKim Phillips u32 ssrc = status >> JRSTA_SSRC_SHIFT;
373e397ee0fSMarek Vasut const char *error = status_src[ssrc].error;
3748e8ec596SKim Phillips
375867e1ee3SMarek Vasut /*
37649783d0fSCristian Stoica * If there is an error handling function, call it to report the error.
37749783d0fSCristian Stoica * Otherwise print the error source name.
378867e1ee3SMarek Vasut */
37949783d0fSCristian Stoica if (status_src[ssrc].report_ssed)
3801984aaeeSHoria Geantă return status_src[ssrc].report_ssed(jrdev, status, error);
3811984aaeeSHoria Geantă
3821984aaeeSHoria Geantă if (error)
38349783d0fSCristian Stoica dev_err(jrdev, "%d: %s\n", ssrc, error);
38449783d0fSCristian Stoica else
38549783d0fSCristian Stoica dev_err(jrdev, "%d: unknown error source\n", ssrc);
3861984aaeeSHoria Geantă
3871984aaeeSHoria Geantă return -EINVAL;
3888e8ec596SKim Phillips }
38994cebd9dSHoria Geantă EXPORT_SYMBOL(caam_strstatus);
3908d818c10SHoria Geantă
3918d818c10SHoria Geantă MODULE_LICENSE("GPL");
3928d818c10SHoria Geantă MODULE_DESCRIPTION("FSL CAAM error reporting");
3938d818c10SHoria Geantă MODULE_AUTHOR("Freescale Semiconductor");
394