xref: /freebsd/sys/dev/qat/qat_hw/qat_c4xxx/adf_c4xxx_ras.c (revision 8aa51e6d7de0a828020de64560d1385e15955a1c)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2025 Intel Corporation */
3 #include "adf_c4xxx_ras.h"
4 #include "adf_accel_devices.h"
5 #include "adf_c4xxx_hw_data.h"
6 #include <adf_dev_err.h>
7 #include "adf_c4xxx_inline.h"
8 #include <sys/priv.h>
9 
10 #define ADF_RAS_STR_LEN 64
11 
adf_sysctl_read_ras_correctable(SYSCTL_HANDLER_ARGS)12 static int adf_sysctl_read_ras_correctable(SYSCTL_HANDLER_ARGS)
13 {
14 	struct adf_accel_dev *accel_dev = arg1;
15 	unsigned long counter = 0;
16 
17 	if (priv_check(curthread, PRIV_DRIVER) != 0)
18 		return EPERM;
19 
20 	if (accel_dev->ras_counters)
21 		counter = atomic_read(&accel_dev->ras_counters[ADF_RAS_CORR]);
22 
23 	return SYSCTL_OUT(req, &counter, sizeof(counter));
24 }
25 
adf_sysctl_read_ras_uncorrectable(SYSCTL_HANDLER_ARGS)26 static int adf_sysctl_read_ras_uncorrectable(SYSCTL_HANDLER_ARGS)
27 {
28 	struct adf_accel_dev *accel_dev = arg1;
29 	unsigned long counter = 0;
30 
31 	if (priv_check(curthread, PRIV_DRIVER) != 0)
32 		return EPERM;
33 
34 	if (accel_dev->ras_counters)
35 		counter = atomic_read(&accel_dev->ras_counters[ADF_RAS_UNCORR]);
36 
37 	return SYSCTL_OUT(req, &counter, sizeof(counter));
38 }
39 
adf_sysctl_read_ras_fatal(SYSCTL_HANDLER_ARGS)40 static int adf_sysctl_read_ras_fatal(SYSCTL_HANDLER_ARGS)
41 {
42 	struct adf_accel_dev *accel_dev = arg1;
43 	unsigned long counter = 0;
44 
45 	if (priv_check(curthread, PRIV_DRIVER) != 0)
46 		return EPERM;
47 
48 	if (accel_dev->ras_counters)
49 		counter = atomic_read(&accel_dev->ras_counters[ADF_RAS_FATAL]);
50 
51 	return SYSCTL_OUT(req, &counter, sizeof(counter));
52 }
53 
adf_sysctl_write_ras_reset(SYSCTL_HANDLER_ARGS)54 static int adf_sysctl_write_ras_reset(SYSCTL_HANDLER_ARGS)
55 {
56 	struct adf_accel_dev *accel_dev = arg1;
57 	int value = 0;
58 	int ret = SYSCTL_IN(req, &value, sizeof(value));
59 
60 	if (priv_check(curthread, PRIV_DRIVER) != 0)
61 		return EPERM;
62 
63 	if (!ret && value != 0 && accel_dev->ras_counters) {
64 	}
65 
66 	return SYSCTL_OUT(req, &value, sizeof(value));
67 }
68 
69 int
adf_init_ras(struct adf_accel_dev * accel_dev)70 adf_init_ras(struct adf_accel_dev *accel_dev)
71 {
72 	struct sysctl_ctx_list *qat_sysctl_ctx;
73 	struct sysctl_oid *qat_sysctl_tree;
74 	struct sysctl_oid *ras_corr;
75 	struct sysctl_oid *ras_uncor;
76 	struct sysctl_oid *ras_fat;
77 	struct sysctl_oid *ras_res;
78 	int i;
79 
80 	accel_dev->ras_counters = kcalloc(ADF_RAS_ERRORS,
81 					  sizeof(*accel_dev->ras_counters),
82 					  GFP_KERNEL);
83 	if (!accel_dev->ras_counters)
84 		return -ENOMEM;
85 
86 	for (i = 0; i < ADF_RAS_ERRORS; ++i)
87 
88 		qat_sysctl_ctx =
89 		    device_get_sysctl_ctx(accel_dev->accel_pci_dev.pci_dev);
90 	qat_sysctl_tree =
91 	    device_get_sysctl_tree(accel_dev->accel_pci_dev.pci_dev);
92 	ras_corr = SYSCTL_ADD_OID(qat_sysctl_ctx,
93 				  SYSCTL_CHILDREN(qat_sysctl_tree),
94 				  OID_AUTO,
95 				  "ras_correctable",
96 				  CTLTYPE_ULONG | CTLFLAG_RD | CTLFLAG_DYN,
97 				  accel_dev,
98 				  0,
99 				  adf_sysctl_read_ras_correctable,
100 				  "LU",
101 				  "QAT RAS correctable");
102 	accel_dev->ras_correctable = ras_corr;
103 	if (!accel_dev->ras_correctable) {
104 		device_printf(GET_DEV(accel_dev),
105 			      "Failed to register ras_correctable sysctl\n");
106 		return -EINVAL;
107 	}
108 	ras_uncor = SYSCTL_ADD_OID(qat_sysctl_ctx,
109 				   SYSCTL_CHILDREN(qat_sysctl_tree),
110 				   OID_AUTO,
111 				   "ras_uncorrectable",
112 				   CTLTYPE_ULONG | CTLFLAG_RD | CTLFLAG_DYN,
113 				   accel_dev,
114 				   0,
115 				   adf_sysctl_read_ras_uncorrectable,
116 				   "LU",
117 				   "QAT RAS uncorrectable");
118 	accel_dev->ras_uncorrectable = ras_uncor;
119 	if (!accel_dev->ras_uncorrectable) {
120 		device_printf(GET_DEV(accel_dev),
121 			      "Failed to register ras_uncorrectable sysctl\n");
122 		return -EINVAL;
123 	}
124 
125 	ras_fat = SYSCTL_ADD_OID(qat_sysctl_ctx,
126 				 SYSCTL_CHILDREN(qat_sysctl_tree),
127 				 OID_AUTO,
128 				 "ras_fatal",
129 				 CTLTYPE_ULONG | CTLFLAG_RD | CTLFLAG_DYN,
130 				 accel_dev,
131 				 0,
132 				 adf_sysctl_read_ras_fatal,
133 				 "LU",
134 				 "QAT RAS fatal");
135 	accel_dev->ras_fatal = ras_fat;
136 	if (!accel_dev->ras_fatal) {
137 		device_printf(GET_DEV(accel_dev),
138 			      "Failed to register ras_fatal sysctl\n");
139 		return -EINVAL;
140 	}
141 
142 	ras_res = SYSCTL_ADD_OID(qat_sysctl_ctx,
143 				 SYSCTL_CHILDREN(qat_sysctl_tree),
144 				 OID_AUTO,
145 				 "ras_reset",
146 				 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_DYN,
147 				 accel_dev,
148 				 0,
149 				 adf_sysctl_write_ras_reset,
150 				 "I",
151 				 "QAT RAS reset");
152 	accel_dev->ras_reset = ras_res;
153 	if (!accel_dev->ras_reset) {
154 		device_printf(GET_DEV(accel_dev),
155 			      "Failed to register ras_reset sysctl\n");
156 		return -EINVAL;
157 	}
158 
159 	return 0;
160 }
161 
162 void
adf_exit_ras(struct adf_accel_dev * accel_dev)163 adf_exit_ras(struct adf_accel_dev *accel_dev)
164 {
165 	if (accel_dev->ras_counters) {
166 		remove_oid(accel_dev, accel_dev->ras_correctable);
167 		remove_oid(accel_dev, accel_dev->ras_uncorrectable);
168 		remove_oid(accel_dev, accel_dev->ras_fatal);
169 		remove_oid(accel_dev, accel_dev->ras_reset);
170 
171 		accel_dev->ras_correctable = NULL;
172 		accel_dev->ras_uncorrectable = NULL;
173 		accel_dev->ras_fatal = NULL;
174 		accel_dev->ras_reset = NULL;
175 
176 		kfree(accel_dev->ras_counters);
177 		accel_dev->ras_counters = NULL;
178 	}
179 }
180 
181 static inline void
adf_log_source_iastatssm(struct adf_accel_dev * accel_dev,struct resource * pmisc,u32 iastatssm,u32 accel_num)182 adf_log_source_iastatssm(struct adf_accel_dev *accel_dev,
183 			 struct resource *pmisc,
184 			 u32 iastatssm,
185 			 u32 accel_num)
186 {
187 	if (iastatssm & ADF_C4XXX_IASTATSSM_UERRSSMSH_MASK)
188 		device_printf(
189 		    GET_DEV(accel_dev),
190 		    "Uncorrectable error shared memory detected in accel: %u\n",
191 		    accel_num);
192 
193 	if (iastatssm & ADF_C4XXX_IASTATSSM_CERRSSMSH_MASK)
194 		device_printf(
195 		    GET_DEV(accel_dev),
196 		    "Correctable error shared memory detected in accel: %u\n",
197 		    accel_num);
198 
199 	if (iastatssm & ADF_C4XXX_IASTATSSM_UERRSSMMMP0_MASK)
200 		device_printf(
201 		    GET_DEV(accel_dev),
202 		    "Uncorrectable error MMP0 detected in accel: %u\n",
203 		    accel_num);
204 
205 	if (iastatssm & ADF_C4XXX_IASTATSSM_CERRSSMMMP0_MASK)
206 		device_printf(GET_DEV(accel_dev),
207 			      "Correctable error MMP0 detected in accel: %u\n",
208 			      accel_num);
209 
210 	if (iastatssm & ADF_C4XXX_IASTATSSM_UERRSSMMMP1_MASK)
211 		device_printf(
212 		    GET_DEV(accel_dev),
213 		    "Uncorrectable error MMP1 detected in accel: %u\n",
214 		    accel_num);
215 
216 	if (iastatssm & ADF_C4XXX_IASTATSSM_CERRSSMMMP1_MASK)
217 		device_printf(GET_DEV(accel_dev),
218 			      "Correctable error MMP1 detected in accel: %u\n",
219 			      accel_num);
220 
221 	if (iastatssm & ADF_C4XXX_IASTATSSM_UERRSSMMMP2_MASK)
222 		device_printf(
223 		    GET_DEV(accel_dev),
224 		    "Uncorrectable error MMP2 detected in accel: %u\n",
225 		    accel_num);
226 
227 	if (iastatssm & ADF_C4XXX_IASTATSSM_CERRSSMMMP2_MASK)
228 		device_printf(GET_DEV(accel_dev),
229 			      "Correctable error MMP2 detected in accel: %u\n",
230 			      accel_num);
231 
232 	if (iastatssm & ADF_C4XXX_IASTATSSM_UERRSSMMMP3_MASK)
233 		device_printf(
234 		    GET_DEV(accel_dev),
235 		    "Uncorrectable error MMP3 detected in accel: %u\n",
236 		    accel_num);
237 
238 	if (iastatssm & ADF_C4XXX_IASTATSSM_CERRSSMMMP3_MASK)
239 		device_printf(GET_DEV(accel_dev),
240 			      "Correctable error MMP3 detected in accel: %u\n",
241 			      accel_num);
242 
243 	if (iastatssm & ADF_C4XXX_IASTATSSM_UERRSSMMMP4_MASK)
244 		device_printf(
245 		    GET_DEV(accel_dev),
246 		    "Uncorrectable error MMP4 detected in accel: %u\n",
247 		    accel_num);
248 
249 	if (iastatssm & ADF_C4XXX_IASTATSSM_CERRSSMMMP4_MASK)
250 		device_printf(GET_DEV(accel_dev),
251 			      "Correctable error MMP4 detected in accel: %u\n",
252 			      accel_num);
253 
254 	if (iastatssm & ADF_C4XXX_IASTATSSM_PPERR_MASK)
255 		device_printf(
256 		    GET_DEV(accel_dev),
257 		    "Uncorrectable error Push or Pull detected in accel: %u\n",
258 		    accel_num);
259 
260 	if (iastatssm & ADF_C4XXX_IASTATSSM_CPPPAR_ERR_MASK)
261 		device_printf(
262 		    GET_DEV(accel_dev),
263 		    "Uncorrectable CPP parity error detected in accel: %u\n",
264 		    accel_num);
265 
266 	if (iastatssm & ADF_C4XXX_IASTATSSM_RFPAR_ERR_MASK)
267 		device_printf(
268 		    GET_DEV(accel_dev),
269 		    "Uncorrectable SSM RF parity error detected in accel: %u\n",
270 		    accel_num);
271 }
272 
273 static inline void
adf_clear_source_statssm(struct adf_accel_dev * accel_dev,struct resource * pmisc,u32 statssm,u32 accel_num)274 adf_clear_source_statssm(struct adf_accel_dev *accel_dev,
275 			 struct resource *pmisc,
276 			 u32 statssm,
277 			 u32 accel_num)
278 {
279 	if (statssm & ADF_C4XXX_IASTATSSM_UERRSSMSH_MASK)
280 		adf_csr_fetch_and_and(pmisc,
281 				      ADF_C4XXX_UERRSSMSH(accel_num),
282 				      ADF_C4XXX_UERRSSMSH_INTS_CLEAR_MASK);
283 
284 	if (statssm & ADF_C4XXX_IASTATSSM_CERRSSMSH_MASK)
285 		adf_csr_fetch_and_and(pmisc,
286 				      ADF_C4XXX_CERRSSMSH(accel_num),
287 				      ADF_C4XXX_CERRSSMSH_INTS_CLEAR_MASK);
288 
289 	if (statssm & ADF_C4XXX_IASTATSSM_UERRSSMMMP0_MASK)
290 		adf_csr_fetch_and_and(pmisc,
291 				      ADF_C4XXX_UERRSSMMMP(accel_num, 0),
292 				      ~ADF_C4XXX_UERRSSMMMP_INTS_CLEAR_MASK);
293 
294 	if (statssm & ADF_C4XXX_IASTATSSM_CERRSSMMMP0_MASK)
295 		adf_csr_fetch_and_and(pmisc,
296 				      ADF_C4XXX_CERRSSMMMP(accel_num, 0),
297 				      ~ADF_C4XXX_CERRSSMMMP_INTS_CLEAR_MASK);
298 
299 	if (statssm & ADF_C4XXX_IASTATSSM_UERRSSMMMP1_MASK)
300 		adf_csr_fetch_and_and(pmisc,
301 				      ADF_C4XXX_UERRSSMMMP(accel_num, 1),
302 				      ~ADF_C4XXX_UERRSSMMMP_INTS_CLEAR_MASK);
303 
304 	if (statssm & ADF_C4XXX_IASTATSSM_CERRSSMMMP1_MASK)
305 		adf_csr_fetch_and_and(pmisc,
306 				      ADF_C4XXX_CERRSSMMMP(accel_num, 1),
307 				      ~ADF_C4XXX_CERRSSMMMP_INTS_CLEAR_MASK);
308 
309 	if (statssm & ADF_C4XXX_IASTATSSM_UERRSSMMMP2_MASK)
310 		adf_csr_fetch_and_and(pmisc,
311 				      ADF_C4XXX_UERRSSMMMP(accel_num, 2),
312 				      ~ADF_C4XXX_UERRSSMMMP_INTS_CLEAR_MASK);
313 
314 	if (statssm & ADF_C4XXX_IASTATSSM_CERRSSMMMP2_MASK)
315 		adf_csr_fetch_and_and(pmisc,
316 				      ADF_C4XXX_CERRSSMMMP(accel_num, 2),
317 				      ~ADF_C4XXX_CERRSSMMMP_INTS_CLEAR_MASK);
318 
319 	if (statssm & ADF_C4XXX_IASTATSSM_UERRSSMMMP3_MASK)
320 		adf_csr_fetch_and_and(pmisc,
321 				      ADF_C4XXX_UERRSSMMMP(accel_num, 3),
322 				      ~ADF_C4XXX_UERRSSMMMP_INTS_CLEAR_MASK);
323 
324 	if (statssm & ADF_C4XXX_IASTATSSM_CERRSSMMMP3_MASK)
325 		adf_csr_fetch_and_and(pmisc,
326 				      ADF_C4XXX_CERRSSMMMP(accel_num, 3),
327 				      ~ADF_C4XXX_CERRSSMMMP_INTS_CLEAR_MASK);
328 
329 	if (statssm & ADF_C4XXX_IASTATSSM_UERRSSMMMP4_MASK)
330 		adf_csr_fetch_and_and(pmisc,
331 				      ADF_C4XXX_UERRSSMMMP(accel_num, 4),
332 				      ~ADF_C4XXX_UERRSSMMMP_INTS_CLEAR_MASK);
333 
334 	if (statssm & ADF_C4XXX_IASTATSSM_CERRSSMMMP4_MASK)
335 		adf_csr_fetch_and_and(pmisc,
336 				      ADF_C4XXX_CERRSSMMMP(accel_num, 4),
337 				      ~ADF_C4XXX_CERRSSMMMP_INTS_CLEAR_MASK);
338 
339 	if (statssm & ADF_C4XXX_IASTATSSM_PPERR_MASK)
340 		adf_csr_fetch_and_and(pmisc,
341 				      ADF_PPERR(accel_num),
342 				      ~ADF_C4XXX_PPERR_INTS_CLEAR_MASK);
343 
344 	if (statssm & ADF_C4XXX_IASTATSSM_RFPAR_ERR_MASK)
345 		adf_csr_fetch_and_or(pmisc,
346 				     ADF_C4XXX_SSMSOFTERRORPARITY(accel_num),
347 				     0UL);
348 
349 	if (statssm & ADF_C4XXX_IASTATSSM_CPPPAR_ERR_MASK)
350 		adf_csr_fetch_and_or(pmisc,
351 				     ADF_C4XXX_SSMCPPERR(accel_num),
352 				     0UL);
353 }
354 
355 static inline void
adf_process_errsou8(struct adf_accel_dev * accel_dev,struct resource * pmisc)356 adf_process_errsou8(struct adf_accel_dev *accel_dev, struct resource *pmisc)
357 {
358 	int i;
359 	u32 mecorrerr = ADF_CSR_RD(pmisc, ADF_C4XXX_HI_ME_COR_ERRLOG);
360 	const unsigned long tmp_mecorrerr = mecorrerr;
361 
362 	/* For each correctable error in ME increment RAS counter */
363 	for_each_set_bit(i,
364 			 &tmp_mecorrerr,
365 			 ADF_C4XXX_HI_ME_COR_ERRLOG_SIZE_IN_BITS)
366 	{
367 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_CORR]);
368 		device_printf(GET_DEV(accel_dev),
369 			      "Correctable error detected in AE%d\n",
370 			      i);
371 	}
372 
373 	/* Clear interrupt from errsou8 (RW1C) */
374 	ADF_CSR_WR(pmisc, ADF_C4XXX_HI_ME_COR_ERRLOG, mecorrerr);
375 }
376 
377 static inline void
adf_handle_ae_uncorr_err(struct adf_accel_dev * accel_dev,struct resource * pmisc)378 adf_handle_ae_uncorr_err(struct adf_accel_dev *accel_dev,
379 			 struct resource *pmisc)
380 {
381 	int i;
382 	u32 me_uncorr_err = ADF_CSR_RD(pmisc, ADF_C4XXX_HI_ME_UNCERR_LOG);
383 	const unsigned long tmp_me_uncorr_err = me_uncorr_err;
384 
385 	/* For each uncorrectable fatal error in AE increment RAS error
386 	 * counter.
387 	 */
388 	for_each_set_bit(i,
389 			 &tmp_me_uncorr_err,
390 			 ADF_C4XXX_HI_ME_UNCOR_ERRLOG_BITS)
391 	{
392 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_FATAL]);
393 		device_printf(GET_DEV(accel_dev),
394 			      "Uncorrectable error detected in AE%d\n",
395 			      i);
396 	}
397 
398 	/* Clear interrupt from me_uncorr_err (RW1C) */
399 	ADF_CSR_WR(pmisc, ADF_C4XXX_HI_ME_UNCERR_LOG, me_uncorr_err);
400 }
401 
402 static inline void
adf_handle_ri_mem_par_err(struct adf_accel_dev * accel_dev,struct resource * pmisc,bool * reset_required)403 adf_handle_ri_mem_par_err(struct adf_accel_dev *accel_dev,
404 			  struct resource *pmisc,
405 			  bool *reset_required)
406 {
407 	u32 ri_mem_par_err_sts = 0;
408 	u32 ri_mem_par_err_ferr = 0;
409 
410 	ri_mem_par_err_sts = ADF_CSR_RD(pmisc, ADF_C4XXX_RI_MEM_PAR_ERR_STS);
411 
412 	ri_mem_par_err_ferr = ADF_CSR_RD(pmisc, ADF_C4XXX_RI_MEM_PAR_ERR_FERR);
413 
414 	if (ri_mem_par_err_sts & ADF_C4XXX_RI_MEM_PAR_ERR_STS_MASK) {
415 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_UNCORR]);
416 		device_printf(
417 		    GET_DEV(accel_dev),
418 		    "Uncorrectable RI memory parity error detected.\n");
419 	}
420 
421 	if (ri_mem_par_err_sts & ADF_C4XXX_RI_MEM_MSIX_TBL_INT_MASK) {
422 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_FATAL]);
423 		device_printf(
424 		    GET_DEV(accel_dev),
425 		    "Uncorrectable fatal MSIX table parity error detected.\n");
426 		*reset_required = true;
427 	}
428 
429 	device_printf(GET_DEV(accel_dev),
430 		      "ri_mem_par_err_sts=0x%X\tri_mem_par_err_ferr=%u\n",
431 		      ri_mem_par_err_sts,
432 		      ri_mem_par_err_ferr);
433 
434 	ADF_CSR_WR(pmisc, ADF_C4XXX_RI_MEM_PAR_ERR_STS, ri_mem_par_err_sts);
435 }
436 
437 static inline void
adf_handle_ti_mem_par_err(struct adf_accel_dev * accel_dev,struct resource * pmisc)438 adf_handle_ti_mem_par_err(struct adf_accel_dev *accel_dev,
439 			  struct resource *pmisc)
440 {
441 	u32 ti_mem_par_err_sts0 = 0;
442 	u32 ti_mem_par_err_sts1 = 0;
443 	u32 ti_mem_par_err_ferr = 0;
444 
445 	ti_mem_par_err_sts0 = ADF_CSR_RD(pmisc, ADF_C4XXX_TI_MEM_PAR_ERR_STS0);
446 	ti_mem_par_err_sts1 = ADF_CSR_RD(pmisc, ADF_C4XXX_TI_MEM_PAR_ERR_STS1);
447 	ti_mem_par_err_ferr =
448 	    ADF_CSR_RD(pmisc, ADF_C4XXX_TI_MEM_PAR_ERR_FIRST_ERROR);
449 
450 	atomic_inc(&accel_dev->ras_counters[ADF_RAS_FATAL]);
451 	ti_mem_par_err_sts1 &= ADF_C4XXX_TI_MEM_PAR_ERR_STS1_MASK;
452 
453 	device_printf(GET_DEV(accel_dev),
454 		      "Uncorrectable TI memory parity error detected.\n");
455 	device_printf(GET_DEV(accel_dev),
456 		      "ti_mem_par_err_sts0=0x%X\tti_mem_par_err_sts1=0x%X\t"
457 		      "ti_mem_par_err_ferr=0x%X\n",
458 		      ti_mem_par_err_sts0,
459 		      ti_mem_par_err_sts1,
460 		      ti_mem_par_err_ferr);
461 
462 	ADF_CSR_WR(pmisc, ADF_C4XXX_TI_MEM_PAR_ERR_STS0, ti_mem_par_err_sts0);
463 	ADF_CSR_WR(pmisc, ADF_C4XXX_TI_MEM_PAR_ERR_STS1, ti_mem_par_err_sts1);
464 }
465 
466 static inline void
adf_log_fatal_cmd_par_err(struct adf_accel_dev * accel_dev,char * err_type)467 adf_log_fatal_cmd_par_err(struct adf_accel_dev *accel_dev, char *err_type)
468 {
469 	atomic_inc(&accel_dev->ras_counters[ADF_RAS_FATAL]);
470 	device_printf(GET_DEV(accel_dev),
471 		      "Fatal error detected: %s command parity\n",
472 		      err_type);
473 }
474 
475 static inline void
adf_handle_host_cpp_par_err(struct adf_accel_dev * accel_dev,struct resource * pmisc)476 adf_handle_host_cpp_par_err(struct adf_accel_dev *accel_dev,
477 			    struct resource *pmisc)
478 {
479 	u32 host_cpp_par_err = 0;
480 
481 	host_cpp_par_err =
482 	    ADF_CSR_RD(pmisc, ADF_C4XXX_HI_CPP_AGENT_CMD_PAR_ERR_LOG);
483 
484 	if (host_cpp_par_err & ADF_C4XXX_TI_CMD_PAR_ERR)
485 		adf_log_fatal_cmd_par_err(accel_dev, "TI");
486 
487 	if (host_cpp_par_err & ADF_C4XXX_RI_CMD_PAR_ERR)
488 		adf_log_fatal_cmd_par_err(accel_dev, "RI");
489 
490 	if (host_cpp_par_err & ADF_C4XXX_ICI_CMD_PAR_ERR)
491 		adf_log_fatal_cmd_par_err(accel_dev, "ICI");
492 
493 	if (host_cpp_par_err & ADF_C4XXX_ICE_CMD_PAR_ERR)
494 		adf_log_fatal_cmd_par_err(accel_dev, "ICE");
495 
496 	if (host_cpp_par_err & ADF_C4XXX_ARAM_CMD_PAR_ERR)
497 		adf_log_fatal_cmd_par_err(accel_dev, "ARAM");
498 
499 	if (host_cpp_par_err & ADF_C4XXX_CFC_CMD_PAR_ERR)
500 		adf_log_fatal_cmd_par_err(accel_dev, "CFC");
501 
502 	if (ADF_C4XXX_SSM_CMD_PAR_ERR(host_cpp_par_err))
503 		adf_log_fatal_cmd_par_err(accel_dev, "SSM");
504 
505 	/* Clear interrupt from host_cpp_par_err (RW1C) */
506 	ADF_CSR_WR(pmisc,
507 		   ADF_C4XXX_HI_CPP_AGENT_CMD_PAR_ERR_LOG,
508 		   host_cpp_par_err);
509 }
510 
511 static inline void
adf_process_errsou9(struct adf_accel_dev * accel_dev,struct resource * pmisc,u32 errsou,bool * reset_required)512 adf_process_errsou9(struct adf_accel_dev *accel_dev,
513 		    struct resource *pmisc,
514 		    u32 errsou,
515 		    bool *reset_required)
516 {
517 	if (errsou & ADF_C4XXX_ME_UNCORR_ERROR) {
518 		adf_handle_ae_uncorr_err(accel_dev, pmisc);
519 
520 		/* Notify caller that function level reset is required. */
521 		*reset_required = true;
522 	}
523 
524 	if (errsou & ADF_C4XXX_CPP_CMD_PAR_ERR) {
525 		adf_handle_host_cpp_par_err(accel_dev, pmisc);
526 		*reset_required = true;
527 	}
528 
529 	/* RI memory parity errors are uncorrectable non-fatal errors
530 	 * with exception of bit 22 MSIX table parity error, which should
531 	 * be treated as fatal error, followed by device restart.
532 	 */
533 	if (errsou & ADF_C4XXX_RI_MEM_PAR_ERR)
534 		adf_handle_ri_mem_par_err(accel_dev, pmisc, reset_required);
535 
536 	if (errsou & ADF_C4XXX_TI_MEM_PAR_ERR) {
537 		adf_handle_ti_mem_par_err(accel_dev, pmisc);
538 		*reset_required = true;
539 	}
540 }
541 
542 static inline void
adf_process_exprpssmcpr(struct adf_accel_dev * accel_dev,struct resource * pmisc,u32 accel)543 adf_process_exprpssmcpr(struct adf_accel_dev *accel_dev,
544 			struct resource *pmisc,
545 			u32 accel)
546 {
547 	u32 exprpssmcpr;
548 
549 	/* CPR0 */
550 	exprpssmcpr = ADF_CSR_RD(pmisc, ADF_C4XXX_EXPRPSSMCPR0(accel));
551 	if (exprpssmcpr & ADF_C4XXX_EXPRPSSM_FATAL_MASK) {
552 		device_printf(GET_DEV(accel_dev),
553 			      "Uncorrectable error CPR0 detected in accel %u\n",
554 			      accel);
555 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_UNCORR]);
556 	}
557 	if (exprpssmcpr & ADF_C4XXX_EXPRPSSM_SOFT_MASK) {
558 		device_printf(GET_DEV(accel_dev),
559 			      "Correctable error CPR0 detected in accel %u\n",
560 			      accel);
561 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_CORR]);
562 	}
563 	ADF_CSR_WR(pmisc, ADF_C4XXX_EXPRPSSMCPR0(accel), 0);
564 
565 	/* CPR1 */
566 	exprpssmcpr = ADF_CSR_RD(pmisc, ADF_C4XXX_EXPRPSSMCPR1(accel));
567 	if (exprpssmcpr & ADF_C4XXX_EXPRPSSM_FATAL_MASK) {
568 		device_printf(GET_DEV(accel_dev),
569 			      "Uncorrectable error CPR1 detected in accel %u\n",
570 			      accel);
571 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_UNCORR]);
572 	}
573 	if (exprpssmcpr & ADF_C4XXX_EXPRPSSM_SOFT_MASK) {
574 		device_printf(GET_DEV(accel_dev),
575 			      "Correctable error CPR1 detected in accel %u\n",
576 			      accel);
577 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_CORR]);
578 	}
579 	ADF_CSR_WR(pmisc, ADF_C4XXX_EXPRPSSMCPR1(accel), 0);
580 }
581 
582 static inline void
adf_process_exprpssmxlt(struct adf_accel_dev * accel_dev,struct resource * pmisc,u32 accel)583 adf_process_exprpssmxlt(struct adf_accel_dev *accel_dev,
584 			struct resource *pmisc,
585 			u32 accel)
586 {
587 	u32 exprpssmxlt;
588 
589 	/* XTL0 */
590 	exprpssmxlt = ADF_CSR_RD(pmisc, ADF_C4XXX_EXPRPSSMXLT0(accel));
591 	if (exprpssmxlt & ADF_C4XXX_EXPRPSSM_FATAL_MASK) {
592 		device_printf(GET_DEV(accel_dev),
593 			      "Uncorrectable error XLT0 detected in accel %u\n",
594 			      accel);
595 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_UNCORR]);
596 	}
597 	if (exprpssmxlt & ADF_C4XXX_EXPRPSSM_SOFT_MASK) {
598 		device_printf(GET_DEV(accel_dev),
599 			      "Correctable error XLT0 detected in accel %u\n",
600 			      accel);
601 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_CORR]);
602 	}
603 	ADF_CSR_WR(pmisc, ADF_C4XXX_EXPRPSSMXLT0(accel), 0);
604 
605 	/* XTL1 */
606 	exprpssmxlt = ADF_CSR_RD(pmisc, ADF_C4XXX_EXPRPSSMXLT1(accel));
607 	if (exprpssmxlt & ADF_C4XXX_EXPRPSSM_FATAL_MASK) {
608 		device_printf(GET_DEV(accel_dev),
609 			      "Uncorrectable error XLT1 detected in accel %u\n",
610 			      accel);
611 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_UNCORR]);
612 	}
613 	if (exprpssmxlt & ADF_C4XXX_EXPRPSSM_SOFT_MASK) {
614 		device_printf(GET_DEV(accel_dev),
615 			      "Correctable error XLT1 detected in accel %u\n",
616 			      accel);
617 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_CORR]);
618 	}
619 	ADF_CSR_WR(pmisc, ADF_C4XXX_EXPRPSSMXLT0(accel), 0);
620 }
621 
622 static inline void
adf_process_spp_par_err(struct adf_accel_dev * accel_dev,struct resource * pmisc,u32 accel,bool * reset_required)623 adf_process_spp_par_err(struct adf_accel_dev *accel_dev,
624 			struct resource *pmisc,
625 			u32 accel,
626 			bool *reset_required)
627 {
628 	/* All SPP parity errors are treated as uncorrectable fatal errors */
629 	atomic_inc(&accel_dev->ras_counters[ADF_RAS_FATAL]);
630 	*reset_required = true;
631 	device_printf(GET_DEV(accel_dev),
632 		      "Uncorrectable fatal SPP parity error detected\n");
633 }
634 
635 static inline void
adf_process_statssm(struct adf_accel_dev * accel_dev,struct resource * pmisc,u32 accel,bool * reset_required)636 adf_process_statssm(struct adf_accel_dev *accel_dev,
637 		    struct resource *pmisc,
638 		    u32 accel,
639 		    bool *reset_required)
640 {
641 	u32 i;
642 	u32 statssm = ADF_CSR_RD(pmisc, ADF_INTSTATSSM(accel));
643 	u32 iastatssm = ADF_CSR_RD(pmisc, ADF_C4XXX_IAINTSTATSSM(accel));
644 	bool type;
645 	const unsigned long tmp_iastatssm = iastatssm;
646 
647 	/* First collect all errors */
648 	for_each_set_bit(i, &tmp_iastatssm, ADF_C4XXX_IASTATSSM_BITS)
649 	{
650 		if (i == ADF_C4XXX_IASTATSSM_SLICE_HANG_ERR_BIT) {
651 			/* Slice Hang error is being handled in
652 			 * separate function adf_check_slice_hang_c4xxx(),
653 			 * which also increments RAS counters for
654 			 * SliceHang error.
655 			 */
656 			continue;
657 		}
658 		if (i == ADF_C4XXX_IASTATSSM_SPP_PAR_ERR_BIT) {
659 			adf_process_spp_par_err(accel_dev,
660 						pmisc,
661 						accel,
662 						reset_required);
663 			continue;
664 		}
665 
666 		type = (i % 2) ? ADF_RAS_CORR : ADF_RAS_UNCORR;
667 		if (i == ADF_C4XXX_IASTATSSM_CPP_PAR_ERR_BIT)
668 			type = ADF_RAS_UNCORR;
669 
670 		atomic_inc(&accel_dev->ras_counters[type]);
671 	}
672 
673 	/* If iastatssm is set, we need to log the error */
674 	if (iastatssm & ADF_C4XXX_IASTATSSM_MASK)
675 		adf_log_source_iastatssm(accel_dev, pmisc, iastatssm, accel);
676 	/* If statssm is set, we need to clear the error sources */
677 	if (statssm & ADF_C4XXX_IASTATSSM_MASK)
678 		adf_clear_source_statssm(accel_dev, pmisc, statssm, accel);
679 	/* Clear the iastatssm after clearing error sources */
680 	if (iastatssm & ADF_C4XXX_IASTATSSM_MASK)
681 		adf_csr_fetch_and_and(pmisc,
682 				      ADF_C4XXX_IAINTSTATSSM(accel),
683 				      ADF_C4XXX_IASTATSSM_CLR_MASK);
684 }
685 
686 static inline void
adf_process_errsou10(struct adf_accel_dev * accel_dev,struct resource * pmisc,u32 errsou,u32 num_accels,bool * reset_required)687 adf_process_errsou10(struct adf_accel_dev *accel_dev,
688 		     struct resource *pmisc,
689 		     u32 errsou,
690 		     u32 num_accels,
691 		     bool *reset_required)
692 {
693 	int accel;
694 	const unsigned long tmp_errsou = errsou;
695 
696 	for_each_set_bit(accel, &tmp_errsou, num_accels)
697 	{
698 		adf_process_statssm(accel_dev, pmisc, accel, reset_required);
699 		adf_process_exprpssmcpr(accel_dev, pmisc, accel);
700 		adf_process_exprpssmxlt(accel_dev, pmisc, accel);
701 	}
702 }
703 
704 /* ERRSOU 11 */
705 static inline void
adf_handle_ti_misc_err(struct adf_accel_dev * accel_dev,struct resource * pmisc)706 adf_handle_ti_misc_err(struct adf_accel_dev *accel_dev, struct resource *pmisc)
707 {
708 	u32 ti_misc_sts = 0;
709 	u32 err_type = 0;
710 
711 	ti_misc_sts = ADF_CSR_RD(pmisc, ADF_C4XXX_TI_MISC_STS);
712 	dev_dbg(GET_DEV(accel_dev), "ti_misc_sts = 0x%X\n", ti_misc_sts);
713 
714 	if (ti_misc_sts & ADF_C4XXX_TI_MISC_ERR_MASK) {
715 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_UNCORR]);
716 
717 		/* If TI misc error occurred then check its type */
718 		err_type = ADF_C4XXX_GET_TI_MISC_ERR_TYPE(ti_misc_sts);
719 		if (err_type == ADF_C4XXX_TI_BME_RESP_ORDER_ERR) {
720 			device_printf(
721 			    GET_DEV(accel_dev),
722 			    "Uncorrectable non-fatal BME response order error.\n");
723 
724 		} else if (err_type == ADF_C4XXX_TI_RESP_ORDER_ERR) {
725 			device_printf(
726 			    GET_DEV(accel_dev),
727 			    "Uncorrectable non-fatal response order error.\n");
728 		}
729 
730 		/* Clear the interrupt and allow the next error to be
731 		 * logged.
732 		 */
733 		ADF_CSR_WR(pmisc, ADF_C4XXX_TI_MISC_STS, BIT(0));
734 	}
735 }
736 
737 static inline void
adf_handle_ri_push_pull_par_err(struct adf_accel_dev * accel_dev,struct resource * pmisc)738 adf_handle_ri_push_pull_par_err(struct adf_accel_dev *accel_dev,
739 				struct resource *pmisc)
740 {
741 	u32 ri_cpp_int_sts = 0;
742 	u32 err_clear_mask = 0;
743 
744 	ri_cpp_int_sts = ADF_CSR_RD(pmisc, ADF_C4XXX_RI_CPP_INT_STS);
745 	dev_dbg(GET_DEV(accel_dev), "ri_cpp_int_sts = 0x%X\n", ri_cpp_int_sts);
746 
747 	if (ri_cpp_int_sts & ADF_C4XXX_RI_CPP_INT_STS_PUSH_ERR) {
748 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_UNCORR]);
749 		device_printf(
750 		    GET_DEV(accel_dev),
751 		    "CPP%d: Uncorrectable non-fatal RI push error detected.\n",
752 		    ADF_C4XXX_GET_CPP_BUS_FROM_STS(ri_cpp_int_sts));
753 
754 		err_clear_mask |= ADF_C4XXX_RI_CPP_INT_STS_PUSH_ERR;
755 	}
756 
757 	if (ri_cpp_int_sts & ADF_C4XXX_RI_CPP_INT_STS_PULL_ERR) {
758 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_UNCORR]);
759 		device_printf(
760 		    GET_DEV(accel_dev),
761 		    "CPP%d: Uncorrectable non-fatal RI pull error detected.\n",
762 		    ADF_C4XXX_GET_CPP_BUS_FROM_STS(ri_cpp_int_sts));
763 
764 		err_clear_mask |= ADF_C4XXX_RI_CPP_INT_STS_PULL_ERR;
765 	}
766 
767 	/* Clear the interrupt for handled errors and allow the next error
768 	 * to be logged.
769 	 */
770 	ADF_CSR_WR(pmisc, ADF_C4XXX_RI_CPP_INT_STS, err_clear_mask);
771 }
772 
773 static inline void
adf_handle_ti_push_pull_par_err(struct adf_accel_dev * accel_dev,struct resource * pmisc)774 adf_handle_ti_push_pull_par_err(struct adf_accel_dev *accel_dev,
775 				struct resource *pmisc)
776 {
777 	u32 ti_cpp_int_sts = 0;
778 	u32 err_clear_mask = 0;
779 
780 	ti_cpp_int_sts = ADF_CSR_RD(pmisc, ADF_C4XXX_TI_CPP_INT_STS);
781 	dev_dbg(GET_DEV(accel_dev), "ti_cpp_int_sts = 0x%X\n", ti_cpp_int_sts);
782 
783 	if (ti_cpp_int_sts & ADF_C4XXX_TI_CPP_INT_STS_PUSH_ERR) {
784 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_UNCORR]);
785 		device_printf(
786 		    GET_DEV(accel_dev),
787 		    "CPP%d: Uncorrectable non-fatal TI push error detected.\n",
788 		    ADF_C4XXX_GET_CPP_BUS_FROM_STS(ti_cpp_int_sts));
789 
790 		err_clear_mask |= ADF_C4XXX_TI_CPP_INT_STS_PUSH_ERR;
791 	}
792 
793 	if (ti_cpp_int_sts & ADF_C4XXX_TI_CPP_INT_STS_PULL_ERR) {
794 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_UNCORR]);
795 		device_printf(
796 		    GET_DEV(accel_dev),
797 		    "CPP%d: Uncorrectable non-fatal TI pull error detected.\n",
798 		    ADF_C4XXX_GET_CPP_BUS_FROM_STS(ti_cpp_int_sts));
799 
800 		err_clear_mask |= ADF_C4XXX_TI_CPP_INT_STS_PULL_ERR;
801 	}
802 
803 	/* Clear the interrupt for handled errors and allow the next error
804 	 * to be logged.
805 	 */
806 	ADF_CSR_WR(pmisc, ADF_C4XXX_TI_CPP_INT_STS, err_clear_mask);
807 }
808 
809 static inline void
adf_handle_aram_corr_err(struct adf_accel_dev * accel_dev,struct resource * aram_base_addr)810 adf_handle_aram_corr_err(struct adf_accel_dev *accel_dev,
811 			 struct resource *aram_base_addr)
812 {
813 	u32 aram_cerr = 0;
814 
815 	aram_cerr = ADF_CSR_RD(aram_base_addr, ADF_C4XXX_ARAMCERR);
816 	dev_dbg(GET_DEV(accel_dev), "aram_cerr = 0x%X\n", aram_cerr);
817 
818 	if (aram_cerr & ADF_C4XXX_ARAM_CORR_ERR_MASK) {
819 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_CORR]);
820 		device_printf(GET_DEV(accel_dev),
821 			      "Correctable ARAM error detected.\n");
822 	}
823 
824 	/* Clear correctable ARAM error interrupt. */
825 	ADF_C4XXX_CLEAR_CSR_BIT(aram_cerr, 0);
826 	ADF_CSR_WR(aram_base_addr, ADF_C4XXX_ARAMCERR, aram_cerr);
827 }
828 
829 static inline void
adf_handle_aram_uncorr_err(struct adf_accel_dev * accel_dev,struct resource * aram_base_addr)830 adf_handle_aram_uncorr_err(struct adf_accel_dev *accel_dev,
831 			   struct resource *aram_base_addr)
832 {
833 	u32 aram_uerr = 0;
834 
835 	aram_uerr = ADF_CSR_RD(aram_base_addr, ADF_C4XXX_ARAMUERR);
836 	dev_dbg(GET_DEV(accel_dev), "aram_uerr = 0x%X\n", aram_uerr);
837 
838 	if (aram_uerr & ADF_C4XXX_ARAM_UNCORR_ERR_MASK) {
839 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_UNCORR]);
840 		device_printf(GET_DEV(accel_dev),
841 			      "Uncorrectable non-fatal ARAM error detected.\n");
842 	}
843 
844 	/* Clear uncorrectable ARAM error interrupt. */
845 	ADF_C4XXX_CLEAR_CSR_BIT(aram_uerr, 0);
846 	ADF_CSR_WR(aram_base_addr, ADF_C4XXX_ARAMUERR, aram_uerr);
847 }
848 
849 static inline void
adf_handle_ti_pull_par_err(struct adf_accel_dev * accel_dev,struct resource * pmisc)850 adf_handle_ti_pull_par_err(struct adf_accel_dev *accel_dev,
851 			   struct resource *pmisc)
852 {
853 	u32 ti_cpp_int_sts = 0;
854 
855 	ti_cpp_int_sts = ADF_CSR_RD(pmisc, ADF_C4XXX_TI_CPP_INT_STS);
856 	dev_dbg(GET_DEV(accel_dev), "ti_cpp_int_sts = 0x%X\n", ti_cpp_int_sts);
857 
858 	if (ti_cpp_int_sts & ADF_C4XXX_TI_CPP_INT_STS_PUSH_DATA_PAR_ERR) {
859 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_UNCORR]);
860 		device_printf(
861 		    GET_DEV(accel_dev),
862 		    "CPP%d: Uncorrectable non-fatal TI pull data parity error detected.\n",
863 		    ADF_C4XXX_GET_CPP_BUS_FROM_STS(ti_cpp_int_sts));
864 	}
865 
866 	/* Clear the interrupt and allow the next error to be logged. */
867 	ADF_CSR_WR(pmisc,
868 		   ADF_C4XXX_TI_CPP_INT_STS,
869 		   ADF_C4XXX_TI_CPP_INT_STS_PUSH_DATA_PAR_ERR);
870 }
871 
872 static inline void
adf_handle_ri_push_par_err(struct adf_accel_dev * accel_dev,struct resource * pmisc)873 adf_handle_ri_push_par_err(struct adf_accel_dev *accel_dev,
874 			   struct resource *pmisc)
875 {
876 	u32 ri_cpp_int_sts = 0;
877 
878 	ri_cpp_int_sts = ADF_CSR_RD(pmisc, ADF_C4XXX_RI_CPP_INT_STS);
879 	dev_dbg(GET_DEV(accel_dev), "ri_cpp_int_sts = 0x%X\n", ri_cpp_int_sts);
880 
881 	if (ri_cpp_int_sts & ADF_C4XXX_RI_CPP_INT_STS_PUSH_DATA_PAR_ERR) {
882 		atomic_inc(&accel_dev->ras_counters[ADF_RAS_UNCORR]);
883 		device_printf(
884 		    GET_DEV(accel_dev),
885 		    "CPP%d: Uncorrectable non-fatal RI push data parity error detected.\n",
886 		    ADF_C4XXX_GET_CPP_BUS_FROM_STS(ri_cpp_int_sts));
887 	}
888 
889 	/* Clear the interrupt and allow the next error to be logged. */
890 	ADF_CSR_WR(pmisc,
891 		   ADF_C4XXX_RI_CPP_INT_STS,
892 		   ADF_C4XXX_RI_CPP_INT_STS_PUSH_DATA_PAR_ERR);
893 }
894 
895 static inline void
adf_log_inln_err(struct adf_accel_dev * accel_dev,u32 offset,u8 ras_type,char * msg)896 adf_log_inln_err(struct adf_accel_dev *accel_dev,
897 		 u32 offset,
898 		 u8 ras_type,
899 		 char *msg)
900 {
901 	if (ras_type >= ADF_RAS_ERRORS) {
902 		device_printf(GET_DEV(accel_dev),
903 			      "Invalid ras type %u\n",
904 			      ras_type);
905 		return;
906 	}
907 
908 	if (offset == ADF_C4XXX_INLINE_INGRESS_OFFSET) {
909 		if (ras_type == ADF_RAS_CORR)
910 			dev_dbg(GET_DEV(accel_dev), "Detect ici %s\n", msg);
911 		else
912 			device_printf(GET_DEV(accel_dev),
913 				      "Detect ici %s\n",
914 				      msg);
915 	} else {
916 		if (ras_type == ADF_RAS_CORR)
917 			dev_dbg(GET_DEV(accel_dev), "Detect ice %s\n", msg);
918 		else
919 			device_printf(GET_DEV(accel_dev),
920 				      "Detect ice %s\n",
921 				      msg);
922 	}
923 	atomic_inc(&accel_dev->ras_counters[ras_type]);
924 }
925 
926 static inline void
adf_handle_parser_uerr(struct adf_accel_dev * accel_dev,struct resource * aram_base_addr,u32 offset,bool * reset_required)927 adf_handle_parser_uerr(struct adf_accel_dev *accel_dev,
928 		       struct resource *aram_base_addr,
929 		       u32 offset,
930 		       bool *reset_required)
931 {
932 	u32 reg_val = 0;
933 
934 	reg_val = ADF_CSR_RD(aram_base_addr, ADF_C4XXX_IC_PARSER_UERR + offset);
935 	if (reg_val & ADF_C4XXX_PARSER_UERR_INTR) {
936 		/* Mask inten */
937 		reg_val &= ~ADF_C4XXX_PARSER_DESC_UERR_INTR_ENA;
938 		ADF_CSR_WR(aram_base_addr,
939 			   ADF_C4XXX_IC_PARSER_UERR + offset,
940 			   reg_val);
941 
942 		/* Fatal error then increase RAS error counter
943 		 * and reset CPM
944 		 */
945 		adf_log_inln_err(accel_dev,
946 				 offset,
947 				 ADF_RAS_FATAL,
948 				 "parser uncorr fatal err");
949 		*reset_required = true;
950 	}
951 }
952 
953 static inline void
adf_handle_mac_intr(struct adf_accel_dev * accel_dev,struct resource * aram_base_addr,u32 offset,bool * reset_required)954 adf_handle_mac_intr(struct adf_accel_dev *accel_dev,
955 		    struct resource *aram_base_addr,
956 		    u32 offset,
957 		    bool *reset_required)
958 {
959 	u64 reg_val;
960 
961 	reg_val = ADF_CSR_RD64(aram_base_addr, ADF_C4XXX_MAC_IP + offset);
962 
963 	/* Handle the MAC interrupts masked out in MAC_IM */
964 	if (reg_val & ADF_C4XXX_MAC_ERROR_TX_UNDERRUN)
965 		adf_log_inln_err(accel_dev,
966 				 offset,
967 				 ADF_RAS_CORR,
968 				 "err tx underrun");
969 
970 	if (reg_val & ADF_C4XXX_MAC_ERROR_TX_FCS)
971 		adf_log_inln_err(accel_dev, offset, ADF_RAS_CORR, "err tx fcs");
972 
973 	if (reg_val & ADF_C4XXX_MAC_ERROR_TX_DATA_CORRUPT)
974 		adf_log_inln_err(accel_dev,
975 				 offset,
976 				 ADF_RAS_CORR,
977 				 "err tx data corrupt");
978 
979 	if (reg_val & ADF_C4XXX_MAC_ERROR_RX_OVERRUN) {
980 		*reset_required = true;
981 		adf_log_inln_err(accel_dev,
982 				 offset,
983 				 ADF_RAS_FATAL,
984 				 "err rx overrun fatal err");
985 	}
986 
987 	if (reg_val & ADF_C4XXX_MAC_ERROR_RX_RUNT) {
988 		*reset_required = true;
989 		adf_log_inln_err(accel_dev,
990 				 offset,
991 				 ADF_RAS_FATAL,
992 				 "err rx runt fatal err");
993 	}
994 
995 	if (reg_val & ADF_C4XXX_MAC_ERROR_RX_UNDERSIZE) {
996 		*reset_required = true;
997 		adf_log_inln_err(accel_dev,
998 				 offset,
999 				 ADF_RAS_FATAL,
1000 				 "err rx undersize fatal err");
1001 	}
1002 
1003 	if (reg_val & ADF_C4XXX_MAC_ERROR_RX_JABBER) {
1004 		*reset_required = true;
1005 		adf_log_inln_err(accel_dev,
1006 				 offset,
1007 				 ADF_RAS_FATAL,
1008 				 "err rx jabber fatal err");
1009 	}
1010 
1011 	if (reg_val & ADF_C4XXX_MAC_ERROR_RX_OVERSIZE) {
1012 		*reset_required = true;
1013 		adf_log_inln_err(accel_dev,
1014 				 offset,
1015 				 ADF_RAS_FATAL,
1016 				 "err rx oversize fatal err");
1017 	}
1018 
1019 	if (reg_val & ADF_C4XXX_MAC_ERROR_RX_FCS)
1020 		adf_log_inln_err(accel_dev, offset, ADF_RAS_CORR, "err rx fcs");
1021 
1022 	if (reg_val & ADF_C4XXX_MAC_ERROR_RX_FRAME)
1023 		adf_log_inln_err(accel_dev,
1024 				 offset,
1025 				 ADF_RAS_CORR,
1026 				 "err rx frame");
1027 
1028 	if (reg_val & ADF_C4XXX_MAC_ERROR_RX_CODE)
1029 		adf_log_inln_err(accel_dev,
1030 				 offset,
1031 				 ADF_RAS_CORR,
1032 				 "err rx code");
1033 
1034 	if (reg_val & ADF_C4XXX_MAC_ERROR_RX_PREAMBLE)
1035 		adf_log_inln_err(accel_dev,
1036 				 offset,
1037 				 ADF_RAS_CORR,
1038 				 "err rx preamble");
1039 
1040 	if (reg_val & ADF_C4XXX_MAC_RX_LINK_UP)
1041 		adf_log_inln_err(accel_dev, offset, ADF_RAS_CORR, "rx link up");
1042 
1043 	if (reg_val & ADF_C4XXX_MAC_INVALID_SPEED)
1044 		adf_log_inln_err(accel_dev,
1045 				 offset,
1046 				 ADF_RAS_CORR,
1047 				 "invalid speed");
1048 
1049 	if (reg_val & ADF_C4XXX_MAC_PIA_RX_FIFO_OVERRUN) {
1050 		*reset_required = true;
1051 		adf_log_inln_err(accel_dev,
1052 				 offset,
1053 				 ADF_RAS_FATAL,
1054 				 "pia rx fifo overrun fatal err");
1055 	}
1056 
1057 	if (reg_val & ADF_C4XXX_MAC_PIA_TX_FIFO_OVERRUN) {
1058 		*reset_required = true;
1059 		adf_log_inln_err(accel_dev,
1060 				 offset,
1061 				 ADF_RAS_FATAL,
1062 				 "pia tx fifo overrun fatal err");
1063 	}
1064 
1065 	if (reg_val & ADF_C4XXX_MAC_PIA_TX_FIFO_UNDERRUN) {
1066 		*reset_required = true;
1067 		adf_log_inln_err(accel_dev,
1068 				 offset,
1069 				 ADF_RAS_FATAL,
1070 				 "pia tx fifo underrun fatal err");
1071 	}
1072 
1073 	/* Clear the interrupt and allow the next error to be logged. */
1074 	ADF_CSR_WR64(aram_base_addr, ADF_C4XXX_MAC_IP + offset, reg_val);
1075 }
1076 
1077 static inline bool
adf_handle_rf_par_err(struct adf_accel_dev * accel_dev,struct resource * aram_base_addr,u32 rf_par_addr,u32 rf_par_msk,u32 offset,char * msg)1078 adf_handle_rf_par_err(struct adf_accel_dev *accel_dev,
1079 		      struct resource *aram_base_addr,
1080 		      u32 rf_par_addr,
1081 		      u32 rf_par_msk,
1082 		      u32 offset,
1083 		      char *msg)
1084 {
1085 	u32 reg_val;
1086 	unsigned long intr_status;
1087 	int i;
1088 	char strbuf[ADF_C4XXX_MAX_STR_LEN];
1089 
1090 	/* Handle rf parity error */
1091 	reg_val = ADF_CSR_RD(aram_base_addr, rf_par_addr + offset);
1092 	intr_status = reg_val & rf_par_msk;
1093 	if (intr_status) {
1094 		for_each_set_bit(i, &intr_status, ADF_C4XXX_RF_PAR_ERR_BITS)
1095 		{
1096 			if (i % 2 == 0)
1097 				snprintf(strbuf,
1098 					 sizeof(strbuf),
1099 					 "%s mul par %u uncorr fatal err",
1100 					 msg,
1101 					 RF_PAR_MUL_MAP(i));
1102 
1103 			else
1104 				snprintf(strbuf,
1105 					 sizeof(strbuf),
1106 					 "%s par %u uncorr fatal err",
1107 					 msg,
1108 					 RF_PAR_MAP(i));
1109 
1110 			adf_log_inln_err(accel_dev,
1111 					 offset,
1112 					 ADF_RAS_FATAL,
1113 					 strbuf);
1114 		}
1115 
1116 		/* Clear the interrupt and allow the next error to be logged. */
1117 		ADF_CSR_WR(aram_base_addr, rf_par_addr + offset, reg_val);
1118 		return true;
1119 	}
1120 	return false;
1121 }
1122 
1123 static inline void
adf_handle_cd_rf_par_err(struct adf_accel_dev * accel_dev,struct resource * aram_base_addr,u32 offset,bool * reset_required)1124 adf_handle_cd_rf_par_err(struct adf_accel_dev *accel_dev,
1125 			 struct resource *aram_base_addr,
1126 			 u32 offset,
1127 			 bool *reset_required)
1128 {
1129 	/* Handle reg_cd_rf_parity_err[1] */
1130 	*reset_required |=
1131 	    adf_handle_rf_par_err(accel_dev,
1132 				  aram_base_addr,
1133 				  ADF_C4XXX_IC_CD_RF_PARITY_ERR_1,
1134 				  ADF_C4XXX_CD_RF_PAR_ERR_1_INTR,
1135 				  offset,
1136 				  "cd rf par[1]:") ?
1137 	    true :
1138 	    false;
1139 }
1140 
1141 static inline void
adf_handle_inln_rf_par_err(struct adf_accel_dev * accel_dev,struct resource * aram_base_addr,u32 offset,bool * reset_required)1142 adf_handle_inln_rf_par_err(struct adf_accel_dev *accel_dev,
1143 			   struct resource *aram_base_addr,
1144 			   u32 offset,
1145 			   bool *reset_required)
1146 {
1147 	/* Handle reg_inln_rf_parity_err[0] */
1148 	*reset_required |=
1149 	    adf_handle_rf_par_err(accel_dev,
1150 				  aram_base_addr,
1151 				  ADF_C4XXX_IC_INLN_RF_PARITY_ERR_0,
1152 				  ADF_C4XXX_INLN_RF_PAR_ERR_0_INTR,
1153 				  offset,
1154 				  "inln rf par[0]:") ?
1155 	    true :
1156 	    false;
1157 
1158 	/* Handle reg_inln_rf_parity_err[1] */
1159 	*reset_required |=
1160 	    adf_handle_rf_par_err(accel_dev,
1161 				  aram_base_addr,
1162 				  ADF_C4XXX_IC_INLN_RF_PARITY_ERR_1,
1163 				  ADF_C4XXX_INLN_RF_PAR_ERR_1_INTR,
1164 				  offset,
1165 				  "inln rf par[1]:") ?
1166 	    true :
1167 	    false;
1168 
1169 	/* Handle reg_inln_rf_parity_err[2] */
1170 	*reset_required |=
1171 	    adf_handle_rf_par_err(accel_dev,
1172 				  aram_base_addr,
1173 				  ADF_C4XXX_IC_INLN_RF_PARITY_ERR_2,
1174 				  ADF_C4XXX_INLN_RF_PAR_ERR_2_INTR,
1175 				  offset,
1176 				  "inln rf par[2]:") ?
1177 	    true :
1178 	    false;
1179 
1180 	/* Handle reg_inln_rf_parity_err[5] */
1181 	*reset_required |=
1182 	    adf_handle_rf_par_err(accel_dev,
1183 				  aram_base_addr,
1184 				  ADF_C4XXX_IC_INLN_RF_PARITY_ERR_5,
1185 				  ADF_C4XXX_INLN_RF_PAR_ERR_5_INTR,
1186 				  offset,
1187 				  "inln rf par[5]:") ?
1188 	    true :
1189 	    false;
1190 }
1191 
1192 static inline void
adf_handle_congest_mngt_intr(struct adf_accel_dev * accel_dev,struct resource * aram_base_addr,u32 offset,bool * reset_required)1193 adf_handle_congest_mngt_intr(struct adf_accel_dev *accel_dev,
1194 			     struct resource *aram_base_addr,
1195 			     u32 offset,
1196 			     bool *reset_required)
1197 {
1198 	u32 reg_val;
1199 
1200 	reg_val = ADF_CSR_RD(aram_base_addr,
1201 			     ADF_C4XXX_IC_CONGESTION_MGMT_INT + offset);
1202 
1203 	/* A mis-configuration of CPM, a mis-configuration of the Ethernet
1204 	 * Complex or that the traffic profile has deviated from that for
1205 	 * which the resources were configured
1206 	 */
1207 	if (reg_val & ADF_C4XXX_CONGESTION_MGMT_CTPB_GLOBAL_CROSSED) {
1208 		adf_log_inln_err(
1209 		    accel_dev,
1210 		    offset,
1211 		    ADF_RAS_FATAL,
1212 		    "congestion mgmt ctpb global crossed fatal err");
1213 		*reset_required = true;
1214 	}
1215 
1216 	if (reg_val & ADF_C4XXX_CONGESTION_MGMT_XOFF_CIRQ_OUT) {
1217 		adf_log_inln_err(accel_dev,
1218 				 offset,
1219 				 ADF_RAS_CORR,
1220 				 "congestion mgmt XOFF cirq out err");
1221 	}
1222 
1223 	if (reg_val & ADF_C4XXX_CONGESTION_MGMT_XOFF_CIRQ_IN) {
1224 		adf_log_inln_err(accel_dev,
1225 				 offset,
1226 				 ADF_RAS_CORR,
1227 				 "congestion mgmt XOFF cirq in err");
1228 	}
1229 
1230 	/* Clear the interrupt and allow the next error to be logged */
1231 	ADF_CSR_WR(aram_base_addr,
1232 		   ADF_C4XXX_IC_CONGESTION_MGMT_INT + offset,
1233 		   reg_val);
1234 }
1235 
1236 static inline void
adf_handle_inline_intr(struct adf_accel_dev * accel_dev,struct resource * aram_base_addr,u32 csr_offset,bool * reset_required)1237 adf_handle_inline_intr(struct adf_accel_dev *accel_dev,
1238 		       struct resource *aram_base_addr,
1239 		       u32 csr_offset,
1240 		       bool *reset_required)
1241 {
1242 	adf_handle_cd_rf_par_err(accel_dev,
1243 				 aram_base_addr,
1244 				 csr_offset,
1245 				 reset_required);
1246 
1247 	adf_handle_parser_uerr(accel_dev,
1248 			       aram_base_addr,
1249 			       csr_offset,
1250 			       reset_required);
1251 
1252 	adf_handle_inln_rf_par_err(accel_dev,
1253 				   aram_base_addr,
1254 				   csr_offset,
1255 				   reset_required);
1256 
1257 	adf_handle_congest_mngt_intr(accel_dev,
1258 				     aram_base_addr,
1259 				     csr_offset,
1260 				     reset_required);
1261 
1262 	adf_handle_mac_intr(accel_dev,
1263 			    aram_base_addr,
1264 			    csr_offset,
1265 			    reset_required);
1266 }
1267 
1268 static inline void
adf_process_errsou11(struct adf_accel_dev * accel_dev,struct resource * pmisc,u32 errsou,bool * reset_required)1269 adf_process_errsou11(struct adf_accel_dev *accel_dev,
1270 		     struct resource *pmisc,
1271 		     u32 errsou,
1272 		     bool *reset_required)
1273 {
1274 	struct resource *aram_base_addr =
1275 	    (&GET_BARS(accel_dev)[ADF_C4XXX_SRAM_BAR])->virt_addr;
1276 
1277 	if (errsou & ADF_C4XXX_TI_MISC)
1278 		adf_handle_ti_misc_err(accel_dev, pmisc);
1279 
1280 	if (errsou & ADF_C4XXX_RI_PUSH_PULL_PAR_ERR)
1281 		adf_handle_ri_push_pull_par_err(accel_dev, pmisc);
1282 
1283 	if (errsou & ADF_C4XXX_TI_PUSH_PULL_PAR_ERR)
1284 		adf_handle_ti_push_pull_par_err(accel_dev, pmisc);
1285 
1286 	if (errsou & ADF_C4XXX_ARAM_CORR_ERR)
1287 		adf_handle_aram_corr_err(accel_dev, aram_base_addr);
1288 
1289 	if (errsou & ADF_C4XXX_ARAM_UNCORR_ERR)
1290 		adf_handle_aram_uncorr_err(accel_dev, aram_base_addr);
1291 
1292 	if (errsou & ADF_C4XXX_TI_PULL_PAR_ERR)
1293 		adf_handle_ti_pull_par_err(accel_dev, pmisc);
1294 
1295 	if (errsou & ADF_C4XXX_RI_PUSH_PAR_ERR)
1296 		adf_handle_ri_push_par_err(accel_dev, pmisc);
1297 
1298 	if (errsou & ADF_C4XXX_INLINE_INGRESS_INTR)
1299 		adf_handle_inline_intr(accel_dev,
1300 				       aram_base_addr,
1301 				       ADF_C4XXX_INLINE_INGRESS_OFFSET,
1302 				       reset_required);
1303 
1304 	if (errsou & ADF_C4XXX_INLINE_EGRESS_INTR)
1305 		adf_handle_inline_intr(accel_dev,
1306 				       aram_base_addr,
1307 				       ADF_C4XXX_INLINE_EGRESS_OFFSET,
1308 				       reset_required);
1309 }
1310 
1311 bool
adf_ras_interrupts(struct adf_accel_dev * accel_dev,bool * reset_required)1312 adf_ras_interrupts(struct adf_accel_dev *accel_dev, bool *reset_required)
1313 {
1314 	u32 errsou = 0;
1315 	bool handled = false;
1316 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
1317 	u32 num_accels = hw_data->get_num_accels(hw_data);
1318 	struct resource *pmisc =
1319 	    (&GET_BARS(accel_dev)[ADF_C4XXX_PMISC_BAR])->virt_addr;
1320 
1321 	if (unlikely(!reset_required)) {
1322 		device_printf(GET_DEV(accel_dev),
1323 			      "Invalid pointer reset_required\n");
1324 		return false;
1325 	}
1326 
1327 	/* errsou8 */
1328 	errsou = ADF_CSR_RD(pmisc, ADF_C4XXX_ERRSOU8);
1329 	if (errsou & ADF_C4XXX_ERRSOU8_MECORR_MASK) {
1330 		adf_process_errsou8(accel_dev, pmisc);
1331 		handled = true;
1332 	}
1333 
1334 	/* errsou9 */
1335 	errsou = ADF_CSR_RD(pmisc, ADF_C4XXX_ERRSOU9);
1336 	if (errsou & ADF_C4XXX_ERRSOU9_ERROR_MASK) {
1337 		adf_process_errsou9(accel_dev, pmisc, errsou, reset_required);
1338 		handled = true;
1339 	}
1340 
1341 	/* errsou10 */
1342 	errsou = ADF_CSR_RD(pmisc, ADF_C4XXX_ERRSOU10);
1343 	if (errsou & ADF_C4XXX_ERRSOU10_RAS_MASK) {
1344 		adf_process_errsou10(
1345 		    accel_dev, pmisc, errsou, num_accels, reset_required);
1346 		handled = true;
1347 	}
1348 
1349 	/* errsou11 */
1350 	errsou = ADF_CSR_RD(pmisc, ADF_C4XXX_ERRSOU11);
1351 	if (errsou & ADF_C4XXX_ERRSOU11_ERROR_MASK) {
1352 		adf_process_errsou11(accel_dev, pmisc, errsou, reset_required);
1353 		handled = true;
1354 	}
1355 
1356 	return handled;
1357 }
1358