1/*
2 * drivers/pci/pcie/aer/aerdrv_errprint.c
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License.  See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Format error messages and print them to console.
9 *
10 * Copyright (C) 2006 Intel Corp.
11 *	Tom Long Nguyen (tom.l.nguyen@intel.com)
12 *	Zhang Yanmin (yanmin.zhang@intel.com)
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/pci.h>
18#include <linux/kernel.h>
19#include <linux/errno.h>
20#include <linux/pm.h>
21#include <linux/suspend.h>
22
23#include "aerdrv.h"
24
25#define AER_AGENT_RECEIVER		0
26#define AER_AGENT_REQUESTER		1
27#define AER_AGENT_COMPLETER		2
28#define AER_AGENT_TRANSMITTER		3
29
30#define AER_AGENT_REQUESTER_MASK	(PCI_ERR_UNC_COMP_TIME|	\
31					PCI_ERR_UNC_UNSUP)
32
33#define AER_AGENT_COMPLETER_MASK	PCI_ERR_UNC_COMP_ABORT
34
35#define AER_AGENT_TRANSMITTER_MASK(t, e) (e & (PCI_ERR_COR_REP_ROLL| \
36	((t == AER_CORRECTABLE) ? PCI_ERR_COR_REP_TIMER: 0)))
37
38#define AER_GET_AGENT(t, e)						\
39	((e & AER_AGENT_COMPLETER_MASK) ? AER_AGENT_COMPLETER :		\
40	(e & AER_AGENT_REQUESTER_MASK) ? AER_AGENT_REQUESTER :		\
41	(AER_AGENT_TRANSMITTER_MASK(t, e)) ? AER_AGENT_TRANSMITTER :	\
42	AER_AGENT_RECEIVER)
43
44#define AER_PHYSICAL_LAYER_ERROR_MASK	PCI_ERR_COR_RCVR
45#define AER_DATA_LINK_LAYER_ERROR_MASK(t, e)	\
46		(PCI_ERR_UNC_DLP|		\
47		PCI_ERR_COR_BAD_TLP| 		\
48		PCI_ERR_COR_BAD_DLLP|		\
49		PCI_ERR_COR_REP_ROLL| 		\
50		((t == AER_CORRECTABLE) ?	\
51		PCI_ERR_COR_REP_TIMER: 0))
52
53#define AER_PHYSICAL_LAYER_ERROR	0
54#define AER_DATA_LINK_LAYER_ERROR	1
55#define AER_TRANSACTION_LAYER_ERROR	2
56
57#define AER_GET_LAYER_ERROR(t, e)				\
58	((e & AER_PHYSICAL_LAYER_ERROR_MASK) ?			\
59	AER_PHYSICAL_LAYER_ERROR :				\
60	(e & AER_DATA_LINK_LAYER_ERROR_MASK(t, e)) ?		\
61		AER_DATA_LINK_LAYER_ERROR : 			\
62		AER_TRANSACTION_LAYER_ERROR)
63
64/*
65 * AER error strings
66 */
67static char* aer_error_severity_string[] = {
68	"Uncorrected (Non-Fatal)",
69	"Uncorrected (Fatal)",
70	"Corrected"
71};
72
73static char* aer_error_layer[] = {
74	"Physical Layer",
75	"Data Link Layer",
76	"Transaction Layer"
77};
78static char* aer_correctable_error_string[] = {
79	"Receiver Error        ",	/* Bit Position 0 	*/
80	NULL,
81	NULL,
82	NULL,
83	NULL,
84	NULL,
85	"Bad TLP               ",	/* Bit Position 6 	*/
86	"Bad DLLP              ",	/* Bit Position 7 	*/
87	"RELAY_NUM Rollover    ",	/* Bit Position 8 	*/
88	NULL,
89	NULL,
90	NULL,
91	"Replay Timer Timeout  ",	/* Bit Position 12 	*/
92	"Advisory Non-Fatal    ", 	/* Bit Position 13	*/
93	NULL,
94	NULL,
95	NULL,
96	NULL,
97	NULL,
98	NULL,
99	NULL,
100	NULL,
101	NULL,
102	NULL,
103	NULL,
104	NULL,
105	NULL,
106	NULL,
107	NULL,
108	NULL,
109	NULL,
110	NULL,
111};
112
113static char* aer_uncorrectable_error_string[] = {
114	NULL,
115	NULL,
116	NULL,
117	NULL,
118	"Data Link Protocol    ",	/* Bit Position 4	*/
119	NULL,
120	NULL,
121	NULL,
122	NULL,
123	NULL,
124	NULL,
125	NULL,
126	"Poisoned TLP          ",	/* Bit Position 12 	*/
127	"Flow Control Protocol ",	/* Bit Position 13	*/
128	"Completion Timeout    ",	/* Bit Position 14 	*/
129	"Completer Abort       ",	/* Bit Position 15 	*/
130	"Unexpected Completion ",	/* Bit Position 16	*/
131	"Receiver Overflow     ",	/* Bit Position 17	*/
132	"Malformed TLP         ",	/* Bit Position 18	*/
133	"ECRC                  ",	/* Bit Position 19	*/
134	"Unsupported Request   ",	/* Bit Position 20	*/
135	NULL,
136	NULL,
137	NULL,
138	NULL,
139	NULL,
140	NULL,
141	NULL,
142	NULL,
143	NULL,
144	NULL,
145	NULL,
146};
147
148static char* aer_agent_string[] = {
149	"Receiver ID",
150	"Requester ID",
151	"Completer ID",
152	"Transmitter ID"
153};
154
155static char * aer_get_error_source_name(int severity,
156			unsigned int status,
157			char errmsg_buff[])
158{
159	int i;
160	char * errmsg = NULL;
161
162	for (i = 0; i < 32; i++) {
163		if (!(status & (1 << i)))
164			continue;
165
166		if (severity == AER_CORRECTABLE)
167			errmsg = aer_correctable_error_string[i];
168		else
169			errmsg = aer_uncorrectable_error_string[i];
170
171		if (!errmsg) {
172			sprintf(errmsg_buff, "Unknown Error Bit %2d  ", i);
173			errmsg = errmsg_buff;
174		}
175
176		break;
177	}
178
179	return errmsg;
180}
181
182static DEFINE_SPINLOCK(logbuf_lock);
183static char errmsg_buff[100];
184void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
185{
186	char * errmsg;
187	int err_layer, agent;
188	char * loglevel;
189
190	if (info->severity == AER_CORRECTABLE)
191		loglevel = KERN_WARNING;
192	else
193		loglevel = KERN_ERR;
194
195	printk("%s+------ PCI-Express Device Error ------+\n", loglevel);
196	printk("%sError Severity\t\t: %s\n", loglevel,
197		aer_error_severity_string[info->severity]);
198
199	if ( info->status == 0) {
200		printk("%sPCIE Bus Error type\t: (Unaccessible)\n", loglevel);
201		printk("%sUnaccessible Received\t: %s\n", loglevel,
202			info->flags & AER_MULTI_ERROR_VALID_FLAG ?
203				"Multiple" : "First");
204		printk("%sUnregistered Agent ID\t: %04x\n", loglevel,
205			(dev->bus->number << 8) | dev->devfn);
206	} else {
207		err_layer = AER_GET_LAYER_ERROR(info->severity, info->status);
208		printk("%sPCIE Bus Error type\t: %s\n", loglevel,
209			aer_error_layer[err_layer]);
210
211		spin_lock(&logbuf_lock);
212		errmsg = aer_get_error_source_name(info->severity,
213				info->status,
214				errmsg_buff);
215		printk("%s%s\t: %s\n", loglevel, errmsg,
216			info->flags & AER_MULTI_ERROR_VALID_FLAG ?
217				"Multiple" : "First");
218		spin_unlock(&logbuf_lock);
219
220		agent = AER_GET_AGENT(info->severity, info->status);
221		printk("%s%s\t\t: %04x\n", loglevel,
222			aer_agent_string[agent],
223			(dev->bus->number << 8) | dev->devfn);
224
225		printk("%sVendorID=%04xh, DeviceID=%04xh,"
226			" Bus=%02xh, Device=%02xh, Function=%02xh\n",
227			loglevel,
228			dev->vendor,
229			dev->device,
230			dev->bus->number,
231			PCI_SLOT(dev->devfn),
232			PCI_FUNC(dev->devfn));
233
234		if (info->flags & AER_TLP_HEADER_VALID_FLAG) {
235			unsigned char *tlp = (unsigned char *) &info->tlp;
236			printk("%sTLB Header:\n", loglevel);
237			printk("%s%02x%02x%02x%02x %02x%02x%02x%02x"
238				" %02x%02x%02x%02x %02x%02x%02x%02x\n",
239				loglevel,
240				*(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp,
241				*(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4),
242				*(tlp + 11), *(tlp + 10), *(tlp + 9),
243				*(tlp + 8), *(tlp + 15), *(tlp + 14),
244				*(tlp + 13), *(tlp + 12));
245		}
246	}
247}
248