This source file includes following definitions.
- to_dpc_dev
- pci_save_dpc_state
- pci_restore_dpc_state
- dpc_wait_rp_inactive
- dpc_reset_link
- dpc_process_rp_pio_error
- dpc_get_aer_uncorrect_severity
- dpc_handler
- dpc_irq
- dpc_probe
- dpc_remove
- pcie_dpc_init
1
2
3
4
5
6
7
8
9 #define dev_fmt(fmt) "DPC: " fmt
10
11 #include <linux/aer.h>
12 #include <linux/delay.h>
13 #include <linux/interrupt.h>
14 #include <linux/init.h>
15 #include <linux/pci.h>
16
17 #include "portdrv.h"
18 #include "../pci.h"
19
20 struct dpc_dev {
21 struct pcie_device *dev;
22 u16 cap_pos;
23 bool rp_extensions;
24 u8 rp_log_size;
25 };
26
27 static const char * const rp_pio_error_string[] = {
28 "Configuration Request received UR Completion",
29 "Configuration Request received CA Completion",
30 "Configuration Request Completion Timeout",
31 NULL,
32 NULL,
33 NULL,
34 NULL,
35 NULL,
36 "I/O Request received UR Completion",
37 "I/O Request received CA Completion",
38 "I/O Request Completion Timeout",
39 NULL,
40 NULL,
41 NULL,
42 NULL,
43 NULL,
44 "Memory Request received UR Completion",
45 "Memory Request received CA Completion",
46 "Memory Request Completion Timeout",
47 };
48
49 static struct dpc_dev *to_dpc_dev(struct pci_dev *dev)
50 {
51 struct device *device;
52
53 device = pcie_port_find_device(dev, PCIE_PORT_SERVICE_DPC);
54 if (!device)
55 return NULL;
56 return get_service_data(to_pcie_device(device));
57 }
58
59 void pci_save_dpc_state(struct pci_dev *dev)
60 {
61 struct dpc_dev *dpc;
62 struct pci_cap_saved_state *save_state;
63 u16 *cap;
64
65 if (!pci_is_pcie(dev))
66 return;
67
68 dpc = to_dpc_dev(dev);
69 if (!dpc)
70 return;
71
72 save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_DPC);
73 if (!save_state)
74 return;
75
76 cap = (u16 *)&save_state->cap.data[0];
77 pci_read_config_word(dev, dpc->cap_pos + PCI_EXP_DPC_CTL, cap);
78 }
79
80 void pci_restore_dpc_state(struct pci_dev *dev)
81 {
82 struct dpc_dev *dpc;
83 struct pci_cap_saved_state *save_state;
84 u16 *cap;
85
86 if (!pci_is_pcie(dev))
87 return;
88
89 dpc = to_dpc_dev(dev);
90 if (!dpc)
91 return;
92
93 save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_DPC);
94 if (!save_state)
95 return;
96
97 cap = (u16 *)&save_state->cap.data[0];
98 pci_write_config_word(dev, dpc->cap_pos + PCI_EXP_DPC_CTL, *cap);
99 }
100
101 static int dpc_wait_rp_inactive(struct dpc_dev *dpc)
102 {
103 unsigned long timeout = jiffies + HZ;
104 struct pci_dev *pdev = dpc->dev->port;
105 u16 cap = dpc->cap_pos, status;
106
107 pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);
108 while (status & PCI_EXP_DPC_RP_BUSY &&
109 !time_after(jiffies, timeout)) {
110 msleep(10);
111 pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);
112 }
113 if (status & PCI_EXP_DPC_RP_BUSY) {
114 pci_warn(pdev, "root port still busy\n");
115 return -EBUSY;
116 }
117 return 0;
118 }
119
120 static pci_ers_result_t dpc_reset_link(struct pci_dev *pdev)
121 {
122 struct dpc_dev *dpc;
123 u16 cap;
124
125
126
127
128
129 dpc = to_dpc_dev(pdev);
130 cap = dpc->cap_pos;
131
132
133
134
135
136 pcie_wait_for_link(pdev, false);
137
138 if (dpc->rp_extensions && dpc_wait_rp_inactive(dpc))
139 return PCI_ERS_RESULT_DISCONNECT;
140
141 pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
142 PCI_EXP_DPC_STATUS_TRIGGER);
143
144 if (!pcie_wait_for_link(pdev, true))
145 return PCI_ERS_RESULT_DISCONNECT;
146
147 return PCI_ERS_RESULT_RECOVERED;
148 }
149
150 static void dpc_process_rp_pio_error(struct dpc_dev *dpc)
151 {
152 struct pci_dev *pdev = dpc->dev->port;
153 u16 cap = dpc->cap_pos, dpc_status, first_error;
154 u32 status, mask, sev, syserr, exc, dw0, dw1, dw2, dw3, log, prefix;
155 int i;
156
157 pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS, &status);
158 pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_MASK, &mask);
159 pci_err(pdev, "rp_pio_status: %#010x, rp_pio_mask: %#010x\n",
160 status, mask);
161
162 pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_SEVERITY, &sev);
163 pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_SYSERROR, &syserr);
164 pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_EXCEPTION, &exc);
165 pci_err(pdev, "RP PIO severity=%#010x, syserror=%#010x, exception=%#010x\n",
166 sev, syserr, exc);
167
168
169 pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &dpc_status);
170 first_error = (dpc_status & 0x1f00) >> 8;
171
172 for (i = 0; i < ARRAY_SIZE(rp_pio_error_string); i++) {
173 if ((status & ~mask) & (1 << i))
174 pci_err(pdev, "[%2d] %s%s\n", i, rp_pio_error_string[i],
175 first_error == i ? " (First)" : "");
176 }
177
178 if (dpc->rp_log_size < 4)
179 goto clear_status;
180 pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG,
181 &dw0);
182 pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 4,
183 &dw1);
184 pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 8,
185 &dw2);
186 pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 12,
187 &dw3);
188 pci_err(pdev, "TLP Header: %#010x %#010x %#010x %#010x\n",
189 dw0, dw1, dw2, dw3);
190
191 if (dpc->rp_log_size < 5)
192 goto clear_status;
193 pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_IMPSPEC_LOG, &log);
194 pci_err(pdev, "RP PIO ImpSpec Log %#010x\n", log);
195
196 for (i = 0; i < dpc->rp_log_size - 5; i++) {
197 pci_read_config_dword(pdev,
198 cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG, &prefix);
199 pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, prefix);
200 }
201 clear_status:
202 pci_write_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS, status);
203 }
204
205 static int dpc_get_aer_uncorrect_severity(struct pci_dev *dev,
206 struct aer_err_info *info)
207 {
208 int pos = dev->aer_cap;
209 u32 status, mask, sev;
210
211 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
212 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &mask);
213 status &= ~mask;
214 if (!status)
215 return 0;
216
217 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &sev);
218 status &= sev;
219 if (status)
220 info->severity = AER_FATAL;
221 else
222 info->severity = AER_NONFATAL;
223
224 return 1;
225 }
226
227 static irqreturn_t dpc_handler(int irq, void *context)
228 {
229 struct aer_err_info info;
230 struct dpc_dev *dpc = context;
231 struct pci_dev *pdev = dpc->dev->port;
232 u16 cap = dpc->cap_pos, status, source, reason, ext_reason;
233
234 pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);
235 pci_read_config_word(pdev, cap + PCI_EXP_DPC_SOURCE_ID, &source);
236
237 pci_info(pdev, "containment event, status:%#06x source:%#06x\n",
238 status, source);
239
240 reason = (status & PCI_EXP_DPC_STATUS_TRIGGER_RSN) >> 1;
241 ext_reason = (status & PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT) >> 5;
242 pci_warn(pdev, "%s detected\n",
243 (reason == 0) ? "unmasked uncorrectable error" :
244 (reason == 1) ? "ERR_NONFATAL" :
245 (reason == 2) ? "ERR_FATAL" :
246 (ext_reason == 0) ? "RP PIO error" :
247 (ext_reason == 1) ? "software trigger" :
248 "reserved error");
249
250
251 if (dpc->rp_extensions && reason == 3 && ext_reason == 0)
252 dpc_process_rp_pio_error(dpc);
253 else if (reason == 0 &&
254 dpc_get_aer_uncorrect_severity(pdev, &info) &&
255 aer_get_device_error_info(pdev, &info)) {
256 aer_print_error(pdev, &info);
257 pci_cleanup_aer_uncorrect_error_status(pdev);
258 pci_aer_clear_fatal_status(pdev);
259 }
260
261
262 pcie_do_recovery(pdev, pci_channel_io_frozen, PCIE_PORT_SERVICE_DPC);
263
264 return IRQ_HANDLED;
265 }
266
267 static irqreturn_t dpc_irq(int irq, void *context)
268 {
269 struct dpc_dev *dpc = (struct dpc_dev *)context;
270 struct pci_dev *pdev = dpc->dev->port;
271 u16 cap = dpc->cap_pos, status;
272
273 pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);
274
275 if (!(status & PCI_EXP_DPC_STATUS_INTERRUPT) || status == (u16)(~0))
276 return IRQ_NONE;
277
278 pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
279 PCI_EXP_DPC_STATUS_INTERRUPT);
280 if (status & PCI_EXP_DPC_STATUS_TRIGGER)
281 return IRQ_WAKE_THREAD;
282 return IRQ_HANDLED;
283 }
284
285 #define FLAG(x, y) (((x) & (y)) ? '+' : '-')
286 static int dpc_probe(struct pcie_device *dev)
287 {
288 struct dpc_dev *dpc;
289 struct pci_dev *pdev = dev->port;
290 struct device *device = &dev->device;
291 int status;
292 u16 ctl, cap;
293
294 if (pcie_aer_get_firmware_first(pdev))
295 return -ENOTSUPP;
296
297 dpc = devm_kzalloc(device, sizeof(*dpc), GFP_KERNEL);
298 if (!dpc)
299 return -ENOMEM;
300
301 dpc->cap_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_DPC);
302 dpc->dev = dev;
303 set_service_data(dev, dpc);
304
305 status = devm_request_threaded_irq(device, dev->irq, dpc_irq,
306 dpc_handler, IRQF_SHARED,
307 "pcie-dpc", dpc);
308 if (status) {
309 pci_warn(pdev, "request IRQ%d failed: %d\n", dev->irq,
310 status);
311 return status;
312 }
313
314 pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CAP, &cap);
315 pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, &ctl);
316
317 dpc->rp_extensions = (cap & PCI_EXP_DPC_CAP_RP_EXT);
318 if (dpc->rp_extensions) {
319 dpc->rp_log_size = (cap & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8;
320 if (dpc->rp_log_size < 4 || dpc->rp_log_size > 9) {
321 pci_err(pdev, "RP PIO log size %u is invalid\n",
322 dpc->rp_log_size);
323 dpc->rp_log_size = 0;
324 }
325 }
326
327 ctl = (ctl & 0xfff4) | PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN;
328 pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, ctl);
329
330 pci_info(pdev, "error containment capabilities: Int Msg #%d, RPExt%c PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n",
331 cap & PCI_EXP_DPC_IRQ, FLAG(cap, PCI_EXP_DPC_CAP_RP_EXT),
332 FLAG(cap, PCI_EXP_DPC_CAP_POISONED_TLP),
333 FLAG(cap, PCI_EXP_DPC_CAP_SW_TRIGGER), dpc->rp_log_size,
334 FLAG(cap, PCI_EXP_DPC_CAP_DL_ACTIVE));
335
336 pci_add_ext_cap_save_buffer(pdev, PCI_EXT_CAP_ID_DPC, sizeof(u16));
337 return status;
338 }
339
340 static void dpc_remove(struct pcie_device *dev)
341 {
342 struct dpc_dev *dpc = get_service_data(dev);
343 struct pci_dev *pdev = dev->port;
344 u16 ctl;
345
346 pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, &ctl);
347 ctl &= ~(PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN);
348 pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, ctl);
349 }
350
351 static struct pcie_port_service_driver dpcdriver = {
352 .name = "dpc",
353 .port_type = PCIE_ANY_PORT,
354 .service = PCIE_PORT_SERVICE_DPC,
355 .probe = dpc_probe,
356 .remove = dpc_remove,
357 .reset_link = dpc_reset_link,
358 };
359
360 int __init pcie_dpc_init(void)
361 {
362 return pcie_port_service_register(&dpcdriver);
363 }