PCI/AER: Decode Error Source Requester ID
[linux-2.6-block.git] / drivers / pci / pcie / aer / aerdrv_errprint.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Format error messages and print them to console.
4  *
5  * Copyright (C) 2006 Intel Corp.
6  *      Tom Long Nguyen (tom.l.nguyen@intel.com)
7  *      Zhang Yanmin (yanmin.zhang@intel.com)
8  */
9
10 #include <linux/module.h>
11 #include <linux/pci.h>
12 #include <linux/kernel.h>
13 #include <linux/errno.h>
14 #include <linux/pm.h>
15 #include <linux/suspend.h>
16 #include <linux/cper.h>
17
18 #include "aerdrv.h"
19 #include <ras/ras_event.h>
20
21 #define AER_AGENT_RECEIVER              0
22 #define AER_AGENT_REQUESTER             1
23 #define AER_AGENT_COMPLETER             2
24 #define AER_AGENT_TRANSMITTER           3
25
26 #define AER_AGENT_REQUESTER_MASK(t)     ((t == AER_CORRECTABLE) ?       \
27         0 : (PCI_ERR_UNC_COMP_TIME|PCI_ERR_UNC_UNSUP))
28 #define AER_AGENT_COMPLETER_MASK(t)     ((t == AER_CORRECTABLE) ?       \
29         0 : PCI_ERR_UNC_COMP_ABORT)
30 #define AER_AGENT_TRANSMITTER_MASK(t)   ((t == AER_CORRECTABLE) ?       \
31         (PCI_ERR_COR_REP_ROLL|PCI_ERR_COR_REP_TIMER) : 0)
32
33 #define AER_GET_AGENT(t, e)                                             \
34         ((e & AER_AGENT_COMPLETER_MASK(t)) ? AER_AGENT_COMPLETER :      \
35         (e & AER_AGENT_REQUESTER_MASK(t)) ? AER_AGENT_REQUESTER :       \
36         (e & AER_AGENT_TRANSMITTER_MASK(t)) ? AER_AGENT_TRANSMITTER :   \
37         AER_AGENT_RECEIVER)
38
39 #define AER_PHYSICAL_LAYER_ERROR        0
40 #define AER_DATA_LINK_LAYER_ERROR       1
41 #define AER_TRANSACTION_LAYER_ERROR     2
42
43 #define AER_PHYSICAL_LAYER_ERROR_MASK(t) ((t == AER_CORRECTABLE) ?      \
44         PCI_ERR_COR_RCVR : 0)
45 #define AER_DATA_LINK_LAYER_ERROR_MASK(t) ((t == AER_CORRECTABLE) ?     \
46         (PCI_ERR_COR_BAD_TLP|                                           \
47         PCI_ERR_COR_BAD_DLLP|                                           \
48         PCI_ERR_COR_REP_ROLL|                                           \
49         PCI_ERR_COR_REP_TIMER) : PCI_ERR_UNC_DLP)
50
51 #define AER_GET_LAYER_ERROR(t, e)                                       \
52         ((e & AER_PHYSICAL_LAYER_ERROR_MASK(t)) ? AER_PHYSICAL_LAYER_ERROR : \
53         (e & AER_DATA_LINK_LAYER_ERROR_MASK(t)) ? AER_DATA_LINK_LAYER_ERROR : \
54         AER_TRANSACTION_LAYER_ERROR)
55
56 /*
57  * AER error strings
58  */
59 static const char *aer_error_severity_string[] = {
60         "Uncorrected (Non-Fatal)",
61         "Uncorrected (Fatal)",
62         "Corrected"
63 };
64
65 static const char *aer_error_layer[] = {
66         "Physical Layer",
67         "Data Link Layer",
68         "Transaction Layer"
69 };
70
71 static const char *aer_correctable_error_string[] = {
72         "Receiver Error",               /* Bit Position 0       */
73         NULL,
74         NULL,
75         NULL,
76         NULL,
77         NULL,
78         "Bad TLP",                      /* Bit Position 6       */
79         "Bad DLLP",                     /* Bit Position 7       */
80         "RELAY_NUM Rollover",           /* Bit Position 8       */
81         NULL,
82         NULL,
83         NULL,
84         "Replay Timer Timeout",         /* Bit Position 12      */
85         "Advisory Non-Fatal",           /* Bit Position 13      */
86         "Corrected Internal Error",     /* Bit Position 14      */
87         "Header Log Overflow",          /* Bit Position 15      */
88 };
89
90 static const char *aer_uncorrectable_error_string[] = {
91         "Undefined",                    /* Bit Position 0       */
92         NULL,
93         NULL,
94         NULL,
95         "Data Link Protocol",           /* Bit Position 4       */
96         "Surprise Down Error",          /* Bit Position 5       */
97         NULL,
98         NULL,
99         NULL,
100         NULL,
101         NULL,
102         NULL,
103         "Poisoned TLP",                 /* Bit Position 12      */
104         "Flow Control Protocol",        /* Bit Position 13      */
105         "Completion Timeout",           /* Bit Position 14      */
106         "Completer Abort",              /* Bit Position 15      */
107         "Unexpected Completion",        /* Bit Position 16      */
108         "Receiver Overflow",            /* Bit Position 17      */
109         "Malformed TLP",                /* Bit Position 18      */
110         "ECRC",                         /* Bit Position 19      */
111         "Unsupported Request",          /* Bit Position 20      */
112         "ACS Violation",                /* Bit Position 21      */
113         "Uncorrectable Internal Error", /* Bit Position 22      */
114         "MC Blocked TLP",               /* Bit Position 23      */
115         "AtomicOp Egress Blocked",      /* Bit Position 24      */
116         "TLP Prefix Blocked Error",     /* Bit Position 25      */
117 };
118
119 static const char *aer_agent_string[] = {
120         "Receiver ID",
121         "Requester ID",
122         "Completer ID",
123         "Transmitter ID"
124 };
125
126 static void __print_tlp_header(struct pci_dev *dev,
127                                struct aer_header_log_regs *t)
128 {
129         pci_err(dev, "  TLP Header: %08x %08x %08x %08x\n",
130                 t->dw0, t->dw1, t->dw2, t->dw3);
131 }
132
133 static void __aer_print_error(struct pci_dev *dev,
134                               struct aer_err_info *info)
135 {
136         int i, status;
137         const char *errmsg = NULL;
138         status = (info->status & ~info->mask);
139
140         for (i = 0; i < 32; i++) {
141                 if (!(status & (1 << i)))
142                         continue;
143
144                 if (info->severity == AER_CORRECTABLE)
145                         errmsg = i < ARRAY_SIZE(aer_correctable_error_string) ?
146                                 aer_correctable_error_string[i] : NULL;
147                 else
148                         errmsg = i < ARRAY_SIZE(aer_uncorrectable_error_string) ?
149                                 aer_uncorrectable_error_string[i] : NULL;
150
151                 if (errmsg)
152                         pci_err(dev, "   [%2d] %-22s%s\n", i, errmsg,
153                                 info->first_error == i ? " (First)" : "");
154                 else
155                         pci_err(dev, "   [%2d] Unknown Error Bit%s\n",
156                                 i, info->first_error == i ? " (First)" : "");
157         }
158 }
159
160 void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
161 {
162         int layer, agent;
163         int id = ((dev->bus->number << 8) | dev->devfn);
164
165         if (!info->status) {
166                 pci_err(dev, "PCIe Bus Error: severity=%s, type=Inaccessible, (Unregistered Agent ID)\n",
167                         aer_error_severity_string[info->severity]);
168                 goto out;
169         }
170
171         layer = AER_GET_LAYER_ERROR(info->severity, info->status);
172         agent = AER_GET_AGENT(info->severity, info->status);
173
174         pci_err(dev, "PCIe Bus Error: severity=%s, type=%s, (%s)\n",
175                 aer_error_severity_string[info->severity],
176                 aer_error_layer[layer], aer_agent_string[agent]);
177
178         pci_err(dev, "  device [%04x:%04x] error status/mask=%08x/%08x\n",
179                 dev->vendor, dev->device,
180                 info->status, info->mask);
181
182         __aer_print_error(dev, info);
183
184         if (info->tlp_header_valid)
185                 __print_tlp_header(dev, &info->tlp);
186
187 out:
188         if (info->id && info->error_dev_num > 1 && info->id == id)
189                 pci_err(dev, "  Error of this Agent is reported first\n");
190
191         trace_aer_event(dev_name(&dev->dev), (info->status & ~info->mask),
192                         info->severity, info->tlp_header_valid, &info->tlp);
193 }
194
195 void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info)
196 {
197         u8 bus = info->id >> 8;
198         u8 devfn = info->id & 0xff;
199
200         pci_info(dev, "AER: %s%s error received: %04x:%02x:%02x.%d\n",
201                 info->multi_error_valid ? "Multiple " : "",
202                 aer_error_severity_string[info->severity],
203                 pci_domain_nr(dev->bus), bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
204 }
205
206 #ifdef CONFIG_ACPI_APEI_PCIEAER
207 int cper_severity_to_aer(int cper_severity)
208 {
209         switch (cper_severity) {
210         case CPER_SEV_RECOVERABLE:
211                 return AER_NONFATAL;
212         case CPER_SEV_FATAL:
213                 return AER_FATAL;
214         default:
215                 return AER_CORRECTABLE;
216         }
217 }
218 EXPORT_SYMBOL_GPL(cper_severity_to_aer);
219
220 void cper_print_aer(struct pci_dev *dev, int aer_severity,
221                     struct aer_capability_regs *aer)
222 {
223         int layer, agent, tlp_header_valid = 0;
224         u32 status, mask;
225         struct aer_err_info info;
226
227         if (aer_severity == AER_CORRECTABLE) {
228                 status = aer->cor_status;
229                 mask = aer->cor_mask;
230         } else {
231                 status = aer->uncor_status;
232                 mask = aer->uncor_mask;
233                 tlp_header_valid = status & AER_LOG_TLP_MASKS;
234         }
235
236         layer = AER_GET_LAYER_ERROR(aer_severity, status);
237         agent = AER_GET_AGENT(aer_severity, status);
238
239         memset(&info, 0, sizeof(info));
240         info.severity = aer_severity;
241         info.status = status;
242         info.mask = mask;
243         info.first_error = PCI_ERR_CAP_FEP(aer->cap_control);
244
245         pci_err(dev, "aer_status: 0x%08x, aer_mask: 0x%08x\n", status, mask);
246         __aer_print_error(dev, &info);
247         pci_err(dev, "aer_layer=%s, aer_agent=%s\n",
248                 aer_error_layer[layer], aer_agent_string[agent]);
249
250         if (aer_severity != AER_CORRECTABLE)
251                 pci_err(dev, "aer_uncor_severity: 0x%08x\n",
252                         aer->uncor_severity);
253
254         if (tlp_header_valid)
255                 __print_tlp_header(dev, &aer->header_log);
256
257         trace_aer_event(dev_name(&dev->dev), (status & ~mask),
258                         aer_severity, tlp_header_valid, &aer->header_log);
259 }
260 #endif