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