1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #include <stddef.h> 27 #include <strings.h> 28 #include <sys/fm/util.h> 29 30 #include "fabric-xlate.h" 31 32 #define FAB_LOOKUP(sz, name, field) \ 33 (void) nvlist_lookup_uint ## sz(nvl, name, field) 34 35 static boolean_t fab_xlate_fake_rp = B_TRUE; 36 static fab_err_tbl_t *fab_master_err_tbl; 37 38 /* 39 * Translation tables for converting "fabric" error bits into "pci" ereports. 40 * <Ereport Class Name>, <Error Bit Mask>, <Preparation Function> 41 */ 42 43 /* MACRO for table entries with no TGT ereports */ 44 #define NT(class, bit, prep) class, bit, prep, NULL 45 /* Translate Fabric ereports to ereport.io.pci.* */ 46 fab_erpt_tbl_t fab_pci_erpt_tbl[] = { 47 PCI_DET_PERR, PCI_STAT_PERROR, NULL, 48 PCI_MDPE, PCI_STAT_S_PERROR, NULL, 49 PCI_SIG_SERR, PCI_STAT_S_SYSERR, NULL, 50 PCI_MA, PCI_STAT_R_MAST_AB, NULL, 51 PCI_REC_TA, PCI_STAT_R_TARG_AB, NULL, 52 PCI_SIG_TA, PCI_STAT_S_TARG_AB, NULL, 53 NULL, 0, NULL 54 }; 55 56 /* Translate Fabric ereports to ereport.io.pci.sec-* */ 57 static fab_erpt_tbl_t fab_pci_bdg_erpt_tbl[] = { 58 PCI_DET_PERR, PCI_STAT_PERROR, NULL, 59 PCI_MDPE, PCI_STAT_S_PERROR, NULL, 60 PCI_REC_SERR, PCI_STAT_S_SYSERR, NULL, 61 #ifdef sparc 62 PCI_MA, PCI_STAT_R_MAST_AB, NULL, 63 #endif 64 PCI_REC_TA, PCI_STAT_R_TARG_AB, NULL, 65 PCI_SIG_TA, PCI_STAT_S_TARG_AB, NULL, 66 NULL, 0, NULL, 67 }; 68 69 70 /* Translate Fabric ereports to ereport.io.pci.dto */ 71 static fab_erpt_tbl_t fab_pci_bdg_ctl_erpt_tbl[] = { 72 PCI_DTO, PCI_BCNF_BCNTRL_DTO_STAT, NULL, 73 NULL, 0, NULL 74 }; 75 76 /* Translate Fabric ereports to ereport.io.pciex.* */ 77 static fab_erpt_tbl_t fab_pcie_ce_erpt_tbl[] = { 78 PCIEX_RE, PCIE_AER_CE_RECEIVER_ERR, NULL, 79 PCIEX_RNR, PCIE_AER_CE_REPLAY_ROLLOVER, NULL, 80 PCIEX_RTO, PCIE_AER_CE_REPLAY_TO, NULL, 81 PCIEX_BDP, PCIE_AER_CE_BAD_DLLP, NULL, 82 PCIEX_BTP, PCIE_AER_CE_BAD_TLP, NULL, 83 PCIEX_ANFE, PCIE_AER_CE_AD_NFE, NULL, 84 NULL, 0, NULL 85 }; 86 87 /* 88 * Translate Fabric ereports to ereport.io.pciex.* 89 * The Target Ereports for this section is only used on leaf devices, with the 90 * exception of TO 91 */ 92 static fab_erpt_tbl_t fab_pcie_ue_erpt_tbl[] = { 93 PCIEX_TE, PCIE_AER_UCE_TRAINING, NULL, 94 PCIEX_DLP, PCIE_AER_UCE_DLP, NULL, 95 PCIEX_SD, PCIE_AER_UCE_SD, NULL, 96 PCIEX_ROF, PCIE_AER_UCE_RO, NULL, 97 PCIEX_FCP, PCIE_AER_UCE_FCP, NULL, 98 PCIEX_MFP, PCIE_AER_UCE_MTLP, NULL, 99 PCIEX_CTO, PCIE_AER_UCE_TO, PCI_TARG_MA, 100 PCIEX_UC, PCIE_AER_UCE_UC, NULL, 101 PCIEX_ECRC, PCIE_AER_UCE_ECRC, NULL, 102 PCIEX_CA, PCIE_AER_UCE_CA, PCI_TARG_REC_TA, 103 #ifdef sparc 104 PCIEX_UR, PCIE_AER_UCE_UR, PCI_TARG_MA, 105 #endif 106 PCIEX_POIS, PCIE_AER_UCE_PTLP, PCI_TARG_MDPE, 107 NULL, 0, NULL 108 }; 109 110 /* Translate Fabric ereports to ereport.io.pciex.* */ 111 static fab_erpt_tbl_t fab_pcie_sue_erpt_tbl[] = { 112 PCIEX_S_TA_SC, PCIE_AER_SUCE_TA_ON_SC, PCI_TARG_REC_TA, 113 PCIEX_S_MA_SC, PCIE_AER_SUCE_MA_ON_SC, PCI_TARG_MA, 114 PCIEX_S_RTA, PCIE_AER_SUCE_RCVD_TA, PCI_TARG_REC_TA, 115 #ifdef sparc 116 PCIEX_S_RMA, PCIE_AER_SUCE_RCVD_MA, PCI_TARG_MA, 117 #endif 118 PCIEX_S_USC, PCIE_AER_SUCE_USC_ERR, NULL, 119 PCIEX_S_USCMD, PCIE_AER_SUCE_USC_MSG_DATA_ERR, PCI_TARG_REC_TA, 120 PCIEX_S_UDE, PCIE_AER_SUCE_UC_DATA_ERR, PCI_TARG_MDPE, 121 PCIEX_S_UAT, PCIE_AER_SUCE_UC_ATTR_ERR, PCI_TARG_MDPE, 122 PCIEX_S_UADR, PCIE_AER_SUCE_UC_ADDR_ERR, PCI_TARG_MDPE, 123 PCIEX_S_TEX, PCIE_AER_SUCE_TIMER_EXPIRED, NULL, 124 PCIEX_S_PERR, PCIE_AER_SUCE_PERR_ASSERT, PCI_TARG_MDPE, 125 PCIEX_S_SERR, PCIE_AER_SUCE_SERR_ASSERT, NULL, 126 PCIEX_INTERR, PCIE_AER_SUCE_INTERNAL_ERR, NULL, 127 NULL, 0, NULL 128 }; 129 130 /* Translate Fabric ereports to ereport.io.pcix.* */ 131 static fab_erpt_tbl_t fab_pcix_erpt_tbl[] = { 132 PCIX_SPL_DIS, PCI_PCIX_SPL_DSCD, NULL, 133 PCIX_UNEX_SPL, PCI_PCIX_UNEX_SPL, NULL, 134 PCIX_RX_SPL_MSG, PCI_PCIX_RX_SPL_MSG, NULL, 135 NULL, 0, NULL 136 }; 137 static fab_erpt_tbl_t *fab_pcix_bdg_erpt_tbl = fab_pcix_erpt_tbl; 138 139 /* Translate Fabric ereports to ereport.io.pcix.sec-* */ 140 static fab_erpt_tbl_t fab_pcix_bdg_sec_erpt_tbl[] = { 141 PCIX_SPL_DIS, PCI_PCIX_BSS_SPL_DSCD, NULL, 142 PCIX_UNEX_SPL, PCI_PCIX_BSS_UNEX_SPL, NULL, 143 PCIX_BSS_SPL_OR, PCI_PCIX_BSS_SPL_OR, NULL, 144 PCIX_BSS_SPL_DLY, PCI_PCIX_BSS_SPL_DLY, NULL, 145 NULL, 0, NULL 146 }; 147 148 /* Translate Fabric ereports to ereport.io.pciex.* */ 149 static fab_erpt_tbl_t fab_pcie_nadv_erpt_tbl[] = { 150 #ifdef sparc 151 PCIEX_UR, PCIE_DEVSTS_UR_DETECTED, NULL, 152 #endif 153 PCIEX_FAT, PCIE_DEVSTS_FE_DETECTED, NULL, 154 PCIEX_NONFAT, PCIE_DEVSTS_NFE_DETECTED, NULL, 155 PCIEX_CORR, PCIE_DEVSTS_CE_DETECTED, NULL, 156 NULL, 0, NULL 157 }; 158 159 /* Translate Fabric ereports to ereport.io.pciex.* */ 160 static fab_erpt_tbl_t fab_pcie_rc_erpt_tbl[] = { 161 PCIEX_RC_FE_MSG, PCIE_AER_RE_STS_FE_MSGS_RCVD, NULL, 162 PCIEX_RC_NFE_MSG, PCIE_AER_RE_STS_NFE_MSGS_RCVD, NULL, 163 PCIEX_RC_CE_MSG, PCIE_AER_RE_STS_CE_RCVD, NULL, 164 PCIEX_RC_MCE_MSG, PCIE_AER_RE_STS_MUL_CE_RCVD, NULL, 165 PCIEX_RC_MUE_MSG, PCIE_AER_RE_STS_MUL_FE_NFE_RCVD, NULL, 166 NULL, 0, NULL 167 }; 168 169 /* 170 * Translate Fabric ereports to pseudo ereport.io.pciex.* RC Fabric Messages. 171 * If the RP is not a PCIe compliant RP or does not support AER, rely on the 172 * leaf fabric ereport to help create a xxx_MSG ereport coming from the RC. 173 */ 174 static fab_erpt_tbl_t fab_pcie_fake_rc_erpt_tbl[] = { 175 PCIEX_RC_FE_MSG, PCIE_DEVSTS_FE_DETECTED, NULL, 176 PCIEX_RC_NFE_MSG, PCIE_DEVSTS_NFE_DETECTED, NULL, 177 PCIEX_RC_CE_MSG, PCIE_DEVSTS_CE_DETECTED, NULL, 178 NULL, 0, NULL, 179 }; 180 181 /* ARGSUSED */ 182 void 183 fab_pci_fabric_to_data(fmd_hdl_t *hdl, nvlist_t *nvl, fab_data_t *data) 184 { 185 data->nvl = nvl; 186 187 /* Generic PCI device information */ 188 FAB_LOOKUP(16, "bdf", &data->bdf); 189 FAB_LOOKUP(16, "device_id", &data->device_id); 190 FAB_LOOKUP(16, "vendor_id", &data->vendor_id); 191 FAB_LOOKUP(8, "rev_id", &data->rev_id); 192 FAB_LOOKUP(16, "dev_type", &data->dev_type); 193 FAB_LOOKUP(16, "pcie_off", &data->pcie_off); 194 FAB_LOOKUP(16, "pcix_off", &data->pcix_off); 195 FAB_LOOKUP(16, "aer_off", &data->aer_off); 196 FAB_LOOKUP(16, "ecc_ver", &data->ecc_ver); 197 198 /* Misc ereport information */ 199 FAB_LOOKUP(32, "remainder", &data->remainder); 200 FAB_LOOKUP(32, "severity", &data->severity); 201 202 /* PCI registers */ 203 FAB_LOOKUP(16, "pci_status", &data->pci_err_status); 204 FAB_LOOKUP(16, "pci_command", &data->pci_cfg_comm); 205 206 /* PCI bridge registers */ 207 FAB_LOOKUP(16, "pci_bdg_sec_status", &data->pci_bdg_sec_stat); 208 FAB_LOOKUP(16, "pci_bdg_ctrl", &data->pci_bdg_ctrl); 209 210 /* PCIx registers */ 211 FAB_LOOKUP(32, "pcix_status", &data->pcix_status); 212 FAB_LOOKUP(16, "pcix_command", &data->pcix_command); 213 214 /* PCIx ECC Registers */ 215 FAB_LOOKUP(16, "pcix_ecc_control_0", &data->pcix_ecc_control_0); 216 FAB_LOOKUP(16, "pcix_ecc_status_0", &data->pcix_ecc_status_0); 217 FAB_LOOKUP(32, "pcix_ecc_fst_addr_0", &data->pcix_ecc_fst_addr_0); 218 FAB_LOOKUP(32, "pcix_ecc_sec_addr_0", &data->pcix_ecc_sec_addr_0); 219 FAB_LOOKUP(32, "pcix_ecc_attr_0", &data->pcix_ecc_attr_0); 220 221 /* PCIx ECC Bridge Registers */ 222 FAB_LOOKUP(16, "pcix_ecc_control_1", &data->pcix_ecc_control_1); 223 FAB_LOOKUP(16, "pcix_ecc_status_1", &data->pcix_ecc_status_1); 224 FAB_LOOKUP(32, "pcix_ecc_fst_addr_1", &data->pcix_ecc_fst_addr_1); 225 FAB_LOOKUP(32, "pcix_ecc_sec_addr_1", &data->pcix_ecc_sec_addr_1); 226 FAB_LOOKUP(32, "pcix_ecc_attr_1", &data->pcix_ecc_attr_1); 227 228 /* PCIx Bridge */ 229 FAB_LOOKUP(32, "pcix_bdg_status", &data->pcix_bdg_stat); 230 FAB_LOOKUP(16, "pcix_bdg_sec_status", &data->pcix_bdg_sec_stat); 231 232 /* PCIe registers */ 233 FAB_LOOKUP(16, "pcie_status", &data->pcie_err_status); 234 FAB_LOOKUP(16, "pcie_command", &data->pcie_err_ctl); 235 FAB_LOOKUP(32, "pcie_dev_cap", &data->pcie_dev_cap); 236 237 /* PCIe AER registers */ 238 FAB_LOOKUP(32, "pcie_adv_ctl", &data->pcie_adv_ctl); 239 FAB_LOOKUP(32, "pcie_ue_status", &data->pcie_ue_status); 240 FAB_LOOKUP(32, "pcie_ue_mask", &data->pcie_ue_mask); 241 FAB_LOOKUP(32, "pcie_ue_sev", &data->pcie_ue_sev); 242 FAB_LOOKUP(32, "pcie_ue_hdr0", &data->pcie_ue_hdr[0]); 243 FAB_LOOKUP(32, "pcie_ue_hdr1", &data->pcie_ue_hdr[1]); 244 FAB_LOOKUP(32, "pcie_ue_hdr2", &data->pcie_ue_hdr[2]); 245 FAB_LOOKUP(32, "pcie_ue_hdr3", &data->pcie_ue_hdr[3]); 246 FAB_LOOKUP(32, "pcie_ce_status", &data->pcie_ce_status); 247 FAB_LOOKUP(32, "pcie_ce_mask", &data->pcie_ce_mask); 248 FAB_LOOKUP(32, "pcie_ue_tgt_trans", &data->pcie_ue_tgt_trans); 249 FAB_LOOKUP(64, "pcie_ue_tgt_addr", &data->pcie_ue_tgt_addr); 250 FAB_LOOKUP(16, "pcie_ue_tgt_bdf", &data->pcie_ue_tgt_bdf); 251 252 /* PCIe BDG AER registers */ 253 FAB_LOOKUP(32, "pcie_sue_adv_ctl", &data->pcie_sue_ctl); 254 FAB_LOOKUP(32, "pcie_sue_status", &data->pcie_sue_status); 255 FAB_LOOKUP(32, "pcie_sue_mask", &data->pcie_sue_mask); 256 FAB_LOOKUP(32, "pcie_sue_sev", &data->pcie_sue_sev); 257 FAB_LOOKUP(32, "pcie_sue_hdr0", &data->pcie_sue_hdr[0]); 258 FAB_LOOKUP(32, "pcie_sue_hdr1", &data->pcie_sue_hdr[1]); 259 FAB_LOOKUP(32, "pcie_sue_hdr2", &data->pcie_sue_hdr[2]); 260 FAB_LOOKUP(32, "pcie_sue_hdr3", &data->pcie_sue_hdr[3]); 261 FAB_LOOKUP(32, "pcie_sue_tgt_trans", &data->pcie_sue_tgt_trans); 262 FAB_LOOKUP(64, "pcie_sue_tgt_addr", &data->pcie_sue_tgt_addr); 263 FAB_LOOKUP(16, "pcie_sue_tgt_bdf", &data->pcie_sue_tgt_bdf); 264 265 /* PCIe RP registers */ 266 FAB_LOOKUP(32, "pcie_rp_status", &data->pcie_rp_status); 267 FAB_LOOKUP(16, "pcie_rp_control", &data->pcie_rp_ctl); 268 269 /* PCIe RP AER registers */ 270 FAB_LOOKUP(32, "pcie_adv_rp_status", &data->pcie_rp_err_status); 271 FAB_LOOKUP(32, "pcie_adv_rp_command", &data->pcie_rp_err_cmd); 272 FAB_LOOKUP(16, "pcie_adv_rp_ce_src_id", &data->pcie_rp_ce_src_id); 273 FAB_LOOKUP(16, "pcie_adv_rp_ue_src_id", &data->pcie_rp_ue_src_id); 274 } 275 276 static int 277 fab_prep_pci_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt, 278 fab_erpt_tbl_t *tbl) 279 { 280 const char *class = tbl->err_class; 281 int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 282 283 /* Generate an ereport for this error bit. */ 284 (void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s", 285 PCI_ERROR_SUBCLASS, class); 286 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 287 288 (void) nvlist_add_uint16(erpt, PCI_CONFIG_STATUS, data->pci_err_status); 289 (void) nvlist_add_uint16(erpt, PCI_CONFIG_COMMAND, data->pci_cfg_comm); 290 291 return (err); 292 } 293 294 static int 295 fab_prep_pci_bdg_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt, 296 fab_erpt_tbl_t *tbl) 297 { 298 const char *class = tbl->err_class; 299 int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 300 301 /* Generate an ereport for this error bit. */ 302 (void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s-%s", 303 PCI_ERROR_SUBCLASS, PCI_SEC_ERROR_SUBCLASS, class); 304 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 305 306 (void) nvlist_add_uint16(erpt, PCI_SEC_CONFIG_STATUS, 307 data->pci_bdg_sec_stat); 308 (void) nvlist_add_uint16(erpt, PCI_BCNTRL, data->pci_bdg_ctrl); 309 310 return (err); 311 } 312 313 static int 314 fab_prep_pci_bdg_ctl_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt, 315 fab_erpt_tbl_t *tbl) 316 { 317 const char *class = tbl->err_class; 318 int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 319 320 /* Generate an ereport for this error bit. */ 321 (void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s", 322 PCI_ERROR_SUBCLASS, class); 323 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 324 325 (void) nvlist_add_uint16(erpt, PCI_SEC_CONFIG_STATUS, 326 data->pci_bdg_sec_stat); 327 (void) nvlist_add_uint16(erpt, PCI_BCNTRL, data->pci_bdg_ctrl); 328 329 return (err); 330 } 331 332 333 static int 334 fab_prep_pcie_ce_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt, 335 fab_erpt_tbl_t *tbl) 336 { 337 const char *class = tbl->err_class; 338 int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 339 340 /* Generate an ereport for this error bit. */ 341 (void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s", 342 PCIEX_ERROR_SUBCLASS, class); 343 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 344 345 (void) nvlist_add_uint16(erpt, PCIEX_DEVSTS_REG, data->pcie_err_status); 346 (void) nvlist_add_uint32(erpt, PCIEX_CE_STATUS_REG, 347 data->pcie_ce_status); 348 349 return (err); 350 } 351 352 static int 353 fab_prep_pcie_ue_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt, 354 fab_erpt_tbl_t *tbl) 355 { 356 const char *class = tbl->err_class; 357 uint32_t first_err = 1 << (data->pcie_adv_ctl & 358 PCIE_AER_CTL_FST_ERR_PTR_MASK); 359 int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 360 361 /* Generate an ereport for this error bit. */ 362 (void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s", 363 PCIEX_ERROR_SUBCLASS, class); 364 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 365 366 (void) nvlist_add_uint16(erpt, PCIEX_DEVSTS_REG, data->pcie_err_status); 367 (void) nvlist_add_uint32(erpt, PCIEX_UE_STATUS_REG, 368 data->pcie_ue_status); 369 (void) nvlist_add_uint32(erpt, PCIEX_UE_SEV_REG, data->pcie_ue_sev); 370 (void) nvlist_add_uint32(erpt, PCIEX_ADV_CTL, data->pcie_adv_ctl); 371 372 fmd_hdl_debug(hdl, "Bit 0x%x First Err 0x%x", tbl->reg_bit, first_err); 373 374 if ((tbl->reg_bit == first_err) && data->pcie_ue_tgt_bdf) { 375 (void) nvlist_add_uint16(erpt, PCIEX_SRC_ID, 376 data->pcie_ue_tgt_bdf); 377 (void) nvlist_add_boolean_value(erpt, PCIEX_SRC_VALID, B_TRUE); 378 } else { 379 (void) nvlist_add_uint16(erpt, PCIEX_SRC_ID, 0); 380 (void) nvlist_add_boolean_value(erpt, PCIEX_SRC_VALID, B_FALSE); 381 } 382 383 if ((tbl->reg_bit == first_err) && !data->pcie_ue_no_tgt_erpt && 384 data->pcie_ue_tgt_trans) { 385 if (tbl->tgt_class) 386 fab_send_tgt_erpt(hdl, data, tbl->tgt_class, B_TRUE); 387 } 388 389 return (err); 390 } 391 392 static int 393 fab_prep_pcie_sue_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt, 394 fab_erpt_tbl_t *tbl) 395 { 396 const char *class = tbl->err_class; 397 uint32_t first_err = 1 << (data->pcie_sue_ctl & 398 PCIE_AER_SCTL_FST_ERR_PTR_MASK); 399 int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 400 401 /* Generate an ereport for this error bit. */ 402 (void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s", 403 PCIEX_ERROR_SUBCLASS, class); 404 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 405 406 (void) nvlist_add_uint32(erpt, PCIEX_SEC_UE_STATUS, 407 data->pcie_sue_status); 408 409 fmd_hdl_debug(hdl, "Bit 0x%x First Err 0x%x", tbl->reg_bit, first_err); 410 411 if ((tbl->reg_bit == first_err) && data->pcie_sue_tgt_bdf) { 412 (void) nvlist_add_uint16(erpt, PCIEX_SRC_ID, 413 data->pcie_sue_tgt_bdf); 414 (void) nvlist_add_boolean_value(erpt, PCIEX_SRC_VALID, B_TRUE); 415 } else { 416 (void) nvlist_add_uint16(erpt, PCIEX_SRC_ID, 0); 417 (void) nvlist_add_boolean_value(erpt, PCIEX_SRC_VALID, B_FALSE); 418 } 419 420 if ((tbl->reg_bit == first_err) && !data->pcie_ue_no_tgt_erpt && 421 data->pcie_sue_tgt_trans) { 422 if (tbl->tgt_class) 423 fab_send_tgt_erpt(hdl, data, tbl->tgt_class, B_FALSE); 424 } 425 426 return (err); 427 } 428 429 static int 430 fab_prep_pcix_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt, 431 fab_erpt_tbl_t *tbl) 432 { 433 const char *class = tbl->err_class; 434 int err = 0; 435 436 /* Only send if this is not a bridge */ 437 if (!data->pcix_status || data->pcix_bdg_sec_stat) 438 return (1); 439 440 err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 441 442 /* Generate an ereport for this error bit. */ 443 (void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s", 444 PCIX_ERROR_SUBCLASS, class); 445 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 446 447 (void) nvlist_add_uint8(erpt, PCIX_COMMAND, data->pcix_command); 448 (void) nvlist_add_uint32(erpt, PCIX_STATUS, data->pcix_status); 449 450 return (err); 451 } 452 453 static void 454 fab_send_pcix_ecc_erpt(fmd_hdl_t *hdl, fab_data_t *data) 455 { 456 nvlist_t *erpt; 457 int ecc_phase = (data->pcix_ecc_status_0 & PCI_PCIX_ECC_PHASE) >> 0x4; 458 int ecc_corr = data->pcix_ecc_status_0 & PCI_PCIX_ECC_CORR; 459 int sec_ue = data->pcix_ecc_status_0 & PCI_PCIX_ECC_S_UE; 460 int sec_ce = data->pcix_ecc_status_0 & PCI_PCIX_ECC_S_CE; 461 uint32_t ctlstat = (data->pcix_ecc_control_0 << 16) | 462 data->pcix_ecc_status_0; 463 464 switch (ecc_phase) { 465 case PCI_PCIX_ECC_PHASE_NOERR: 466 break; 467 case PCI_PCIX_ECC_PHASE_FADDR: 468 case PCI_PCIX_ECC_PHASE_SADDR: 469 (void) snprintf(fab_buf, FM_MAX_CLASS, 470 "%s.%s", PCIX_ERROR_SUBCLASS, 471 ecc_corr ? PCIX_ECC_CE_ADDR : PCIX_ECC_UE_ADDR); 472 break; 473 case PCI_PCIX_ECC_PHASE_ATTR: 474 (void) snprintf(fab_buf, FM_MAX_CLASS, 475 "%s.%s", PCIX_ERROR_SUBCLASS, 476 ecc_corr ? PCIX_ECC_CE_ATTR : PCIX_ECC_UE_ATTR); 477 break; 478 case PCI_PCIX_ECC_PHASE_DATA32: 479 case PCI_PCIX_ECC_PHASE_DATA64: 480 (void) snprintf(fab_buf, FM_MAX_CLASS, 481 "%s.%s", PCIX_ERROR_SUBCLASS, 482 ecc_corr ? PCIX_ECC_CE_DATA : PCIX_ECC_UE_DATA); 483 break; 484 } 485 486 if (ecc_phase) { 487 if (nvlist_alloc(&erpt, NV_UNIQUE_NAME, 0) != 0) 488 goto done; 489 (void) fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 490 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 491 (void) nvlist_add_uint16(erpt, PCIX_COMMAND, 492 data->pcix_command); 493 (void) nvlist_add_uint32(erpt, PCIX_STATUS, data->pcix_status); 494 (void) nvlist_add_uint32(erpt, PCIX_ECC_CTLSTAT, ctlstat); 495 (void) nvlist_add_uint32(erpt, PCIX_ECC_ATTR, 496 data->pcix_ecc_attr_0); 497 fmd_hdl_debug(hdl, "Sending ecc ereport: %s\n", fab_buf); 498 fmd_xprt_post(hdl, fab_fmd_xprt, erpt, 0); 499 if (fmd_xprt_error(hdl, fab_fmd_xprt)) 500 fmd_hdl_debug(hdl, "Failed to send ECC ereport\n"); 501 } 502 503 if (sec_ce || sec_ue) { 504 (void) snprintf(fab_buf, FM_MAX_CLASS, 505 "%s.%s", PCIX_ERROR_SUBCLASS, 506 sec_ce ? PCIX_ECC_S_CE : PCIX_ECC_S_UE); 507 if (nvlist_alloc(&erpt, NV_UNIQUE_NAME, 0) != 0) 508 goto done; 509 (void) fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 510 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 511 (void) nvlist_add_uint16(erpt, PCIX_COMMAND, 512 data->pcix_command); 513 (void) nvlist_add_uint32(erpt, PCIX_STATUS, data->pcix_status); 514 (void) nvlist_add_uint32(erpt, PCIX_ECC_CTLSTAT, ctlstat); 515 (void) nvlist_add_uint32(erpt, PCIX_ECC_ATTR, 516 data->pcix_ecc_attr_0); 517 fmd_hdl_debug(hdl, "Sending ecc ereport: %s\n", fab_buf); 518 fmd_xprt_post(hdl, fab_fmd_xprt, erpt, 0); 519 if (fmd_xprt_error(hdl, fab_fmd_xprt)) 520 fmd_hdl_debug(hdl, "Failed to send ECC ereport\n"); 521 } 522 523 return; 524 done: 525 fmd_hdl_debug(hdl, "Failed to send ECC ereport\n"); 526 } 527 528 static int 529 fab_prep_pcix_bdg_sec_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt, 530 fab_erpt_tbl_t *tbl) 531 { 532 const char *class = tbl->err_class; 533 int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 534 535 /* Generate an ereport for this error bit. */ 536 (void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s%s", 537 PCIX_ERROR_SUBCLASS, PCIX_SEC_ERROR_SUBCLASS, class); 538 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 539 540 (void) nvlist_add_uint16(erpt, PCIX_SEC_STATUS, 541 data->pcix_bdg_sec_stat); 542 (void) nvlist_add_uint32(erpt, PCIX_BDG_STAT, data->pcix_bdg_stat); 543 544 return (err); 545 } 546 547 static int 548 fab_prep_pcix_bdg_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt, 549 fab_erpt_tbl_t *tbl) 550 { 551 const char *class = tbl->err_class; 552 int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 553 554 /* Generate an ereport for this error bit. */ 555 (void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s", 556 PCIX_ERROR_SUBCLASS, class); 557 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 558 559 (void) nvlist_add_uint16(erpt, PCIX_SEC_STATUS, 560 data->pcix_bdg_sec_stat); 561 (void) nvlist_add_uint32(erpt, PCIX_BDG_STAT, data->pcix_bdg_stat); 562 563 return (err); 564 } 565 566 static void 567 fab_send_pcix_bdg_ecc_erpt(fmd_hdl_t *hdl, fab_data_t *data) 568 { 569 nvlist_t *erpt; 570 int ecc_phase = (data->pcix_ecc_status_1 & PCI_PCIX_ECC_PHASE) >> 0x4; 571 int ecc_corr = data->pcix_ecc_status_1 & PCI_PCIX_ECC_CORR; 572 int sec_ue = data->pcix_ecc_status_1 & PCI_PCIX_ECC_S_UE; 573 int sec_ce = data->pcix_ecc_status_1 & PCI_PCIX_ECC_S_CE; 574 uint32_t ctlstat = (data->pcix_ecc_control_1 << 16) | 575 data->pcix_ecc_status_1; 576 577 switch (ecc_phase) { 578 case PCI_PCIX_ECC_PHASE_NOERR: 579 break; 580 case PCI_PCIX_ECC_PHASE_FADDR: 581 case PCI_PCIX_ECC_PHASE_SADDR: 582 (void) snprintf(fab_buf, FM_MAX_CLASS, 583 "%s.%s%s", PCIX_ERROR_SUBCLASS, PCIX_SEC_ERROR_SUBCLASS, 584 ecc_corr ? PCIX_ECC_CE_ADDR : PCIX_ECC_UE_ADDR); 585 break; 586 case PCI_PCIX_ECC_PHASE_ATTR: 587 (void) snprintf(fab_buf, FM_MAX_CLASS, 588 "%s.%s%s", PCIX_ERROR_SUBCLASS, PCIX_SEC_ERROR_SUBCLASS, 589 ecc_corr ? PCIX_ECC_CE_ATTR : PCIX_ECC_UE_ATTR); 590 break; 591 case PCI_PCIX_ECC_PHASE_DATA32: 592 case PCI_PCIX_ECC_PHASE_DATA64: 593 (void) snprintf(fab_buf, FM_MAX_CLASS, 594 "%s.%s%s", PCIX_ERROR_SUBCLASS, PCIX_SEC_ERROR_SUBCLASS, 595 ecc_corr ? PCIX_ECC_CE_DATA : PCIX_ECC_UE_DATA); 596 break; 597 } 598 if (ecc_phase) { 599 if (nvlist_alloc(&erpt, NV_UNIQUE_NAME, 0) != 0) 600 goto done; 601 (void) fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 602 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 603 (void) nvlist_add_uint16(erpt, PCIX_SEC_STATUS, 604 data->pcix_bdg_sec_stat); 605 (void) nvlist_add_uint32(erpt, PCIX_BDG_STAT, 606 data->pcix_bdg_stat); 607 (void) nvlist_add_uint32(erpt, PCIX_ECC_CTLSTAT, ctlstat); 608 (void) nvlist_add_uint32(erpt, PCIX_ECC_ATTR, 609 data->pcix_ecc_attr_1); 610 fmd_hdl_debug(hdl, "Sending ecc ereport: %s\n", fab_buf); 611 fmd_xprt_post(hdl, fab_fmd_xprt, erpt, 0); 612 if (fmd_xprt_error(hdl, fab_fmd_xprt)) 613 fmd_hdl_debug(hdl, "Failed to send ECC ereport\n"); 614 } 615 616 if (sec_ce || sec_ue) { 617 (void) snprintf(fab_buf, FM_MAX_CLASS, 618 "%s.%s%s", PCIX_ERROR_SUBCLASS, PCIX_SEC_ERROR_SUBCLASS, 619 sec_ce ? PCIX_ECC_S_CE : PCIX_ECC_S_UE); 620 if (nvlist_alloc(&erpt, NV_UNIQUE_NAME, 0) != 0) 621 goto done; 622 (void) fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 623 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 624 (void) nvlist_add_uint16(erpt, PCIX_SEC_STATUS, 625 data->pcix_bdg_sec_stat); 626 (void) nvlist_add_uint32(erpt, PCIX_BDG_STAT, 627 data->pcix_bdg_stat); 628 (void) nvlist_add_uint32(erpt, PCIX_ECC_CTLSTAT, ctlstat); 629 (void) nvlist_add_uint32(erpt, PCIX_ECC_ATTR, 630 data->pcix_ecc_attr_1); 631 fmd_hdl_debug(hdl, "Sending ecc ereport: %s\n", fab_buf); 632 fmd_xprt_post(hdl, fab_fmd_xprt, erpt, 0); 633 if (fmd_xprt_error(hdl, fab_fmd_xprt)) 634 fmd_hdl_debug(hdl, "Failed to send ECC ereport\n"); 635 } 636 return; 637 done: 638 fmd_hdl_debug(hdl, "Failed to send ECC ereport\n"); 639 } 640 641 static int 642 fab_prep_pcie_nadv_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt, 643 fab_erpt_tbl_t *tbl) 644 { 645 const char *class = tbl->err_class; 646 int err = 0; 647 648 /* Don't send this for PCI device, Root Ports, or PCIe with AER */ 649 if ((data->dev_type == PCIE_PCIECAP_DEV_TYPE_PCI_DEV) || 650 (data->dev_type == PCIE_PCIECAP_DEV_TYPE_ROOT) || 651 data->aer_off) 652 return (1); 653 654 err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 655 656 /* Generate an ereport for this error bit. */ 657 (void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s", 658 PCIEX_ERROR_SUBCLASS, class); 659 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 660 661 (void) nvlist_add_uint16(erpt, PCIEX_DEVSTS_REG, data->pcie_err_status); 662 663 return (err); 664 } 665 666 static int 667 fab_prep_pcie_rc_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt, 668 fab_erpt_tbl_t *tbl) 669 { 670 const char *class = tbl->err_class; 671 uint32_t status = data->pcie_rp_err_status; 672 int err = 0; 673 int isFE = 0, isNFE = 0; 674 675 fmd_hdl_debug(hdl, "XLATE RP Error Class %s", class); 676 677 if (!data->aer_off) 678 return (-1); 679 680 /* Only send a FE Msg if the 1st UE error is FE */ 681 if (STRCMP(class, PCIEX_RC_FE_MSG)) 682 if (!(status & PCIE_AER_RE_STS_FIRST_UC_FATAL)) 683 return (-1); 684 else 685 isFE = 1; 686 687 /* Only send a NFE Msg is the 1st UE error is NFE */ 688 if (STRCMP(class, PCIEX_RC_NFE_MSG)) 689 if (status & PCIE_AER_RE_STS_FIRST_UC_FATAL) 690 return (-1); 691 else 692 isNFE = 1; 693 694 fmd_hdl_debug(hdl, "XLATE RP Error"); 695 696 err |= fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE); 697 698 /* Generate an ereport for this error bit. */ 699 (void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s", 700 PCIEX_ERROR_SUBCLASS, class); 701 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 702 703 (void) nvlist_add_uint32(erpt, PCIEX_ROOT_ERRSTS_REG, status); 704 if ((isFE || isNFE) && data->pcie_rp_ue_src_id) { 705 (void) nvlist_add_uint16(erpt, PCIEX_SRC_ID, 706 data->pcie_rp_ue_src_id); 707 (void) nvlist_add_boolean_value(erpt, PCIEX_SRC_VALID, B_TRUE); 708 } 709 if (STRCMP(class, PCIEX_RC_CE_MSG) && data->pcie_rp_ce_src_id) { 710 (void) nvlist_add_uint16(erpt, PCIEX_SRC_ID, 711 data->pcie_rp_ce_src_id); 712 (void) nvlist_add_boolean_value(erpt, PCIEX_SRC_VALID, B_TRUE); 713 } 714 715 return (err); 716 } 717 718 static int 719 fab_prep_pcie_fake_rc_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt, 720 fab_erpt_tbl_t *tbl) 721 { 722 const char *class = tbl->err_class; 723 uint32_t rc_err_sts = 0; 724 int err = 0; 725 726 /* 727 * Don't send this for PCI device or Root Ports. Only send it on 728 * systems with non-compliant RPs. 729 */ 730 if ((data->dev_type == PCIE_PCIECAP_DEV_TYPE_PCI_DEV) || 731 (data->dev_type == PCIE_PCIECAP_DEV_TYPE_ROOT) || 732 (!fab_xlate_fake_rp)) 733 return (-1); 734 735 err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_TRUE); 736 737 /* Generate an ereport for this error bit. */ 738 (void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s", 739 PCIEX_ERROR_SUBCLASS, class); 740 (void) nvlist_add_string(erpt, FM_CLASS, fab_buf); 741 742 /* Send PCIe RC Ereports */ 743 if (data->pcie_err_status & PCIE_DEVSTS_CE_DETECTED) { 744 rc_err_sts |= PCIE_AER_RE_STS_CE_RCVD; 745 } 746 747 /* NFE/FE src id takes precedence over CE src id */ 748 if (data->pcie_err_status & PCIE_DEVSTS_NFE_DETECTED) { 749 rc_err_sts |= PCIE_AER_RE_STS_NFE_MSGS_RCVD; 750 rc_err_sts |= PCIE_AER_RE_STS_FE_NFE_RCVD; 751 } 752 if (data->pcie_err_status & PCIE_DEVSTS_FE_DETECTED) { 753 rc_err_sts |= PCIE_AER_RE_STS_FE_MSGS_RCVD; 754 rc_err_sts |= PCIE_AER_RE_STS_FE_NFE_RCVD; 755 } 756 if ((data->pcie_err_status & PCIE_DEVSTS_NFE_DETECTED) && 757 (data->pcie_err_status & PCIE_DEVSTS_FE_DETECTED)) { 758 rc_err_sts |= PCIE_AER_RE_STS_FIRST_UC_FATAL; 759 rc_err_sts |= PCIE_AER_RE_STS_MUL_FE_NFE_RCVD; 760 } 761 762 (void) nvlist_add_uint32(erpt, PCIEX_ROOT_ERRSTS_REG, rc_err_sts); 763 764 if (!(rc_err_sts & PCIE_AER_RE_STS_MUL_FE_NFE_RCVD)) { 765 (void) nvlist_add_uint16(erpt, PCIEX_SRC_ID, data->bdf); 766 (void) nvlist_add_boolean_value(erpt, PCIEX_SRC_VALID, B_TRUE); 767 } 768 769 return (err); 770 } 771 772 void 773 fab_xlate_pcie_erpts(fmd_hdl_t *hdl, fab_data_t *data) 774 { 775 fab_err_tbl_t *tbl; 776 777 fmd_hdl_debug(hdl, "Sending Ereports Now"); 778 779 /* Go through the error logs and send the relavant reports */ 780 for (tbl = fab_master_err_tbl; tbl->erpt_tbl; tbl++) { 781 fab_send_erpt(hdl, data, tbl); 782 } 783 784 /* Send PCI-X ECC Ereports */ 785 fab_send_pcix_ecc_erpt(hdl, data); 786 fab_send_pcix_bdg_ecc_erpt(hdl, data); 787 } 788 789 void 790 fab_xlate_fabric_erpts(fmd_hdl_t *hdl, nvlist_t *nvl, const char *class) 791 { 792 fab_data_t data = {0}; 793 794 fmd_hdl_debug(hdl, "fabric ereport received: %s\n", class); 795 796 fab_pci_fabric_to_data(hdl, nvl, &data); 797 fab_xlate_pcie_erpts(hdl, &data); 798 } 799 800 void 801 fab_set_fake_rp(fmd_hdl_t *hdl) 802 { 803 char *rppath = fab_get_rpdev(hdl), *str = NULL; 804 int count = 0; 805 806 if (!rppath) { 807 fmd_hdl_debug(hdl, "Can't find root port dev path"); 808 return; 809 } 810 811 /* 812 * For the path '/pci@xxx' is fake root port, 813 * and '/pci@xxx/pci@y' is real root port. 814 */ 815 str = rppath; 816 while (*str) { 817 if (*str == '/') 818 count++; 819 str++; 820 } 821 822 if (count == 1) 823 fab_xlate_fake_rp = B_TRUE; 824 else 825 /* 826 * If count is 0, then it should still be B_FALSE 827 */ 828 fab_xlate_fake_rp = B_FALSE; 829 830 fmd_hdl_strfree(hdl, rppath); 831 } 832 833 #define SET_TBL(n, err, reg, sz) \ 834 fab_master_err_tbl[n].erpt_tbl = fab_ ## err ## _erpt_tbl; \ 835 fab_master_err_tbl[n].reg_offset = offsetof(fab_data_t, reg); \ 836 fab_master_err_tbl[n].reg_size = sz; \ 837 fab_master_err_tbl[n].fab_prep = fab_prep_ ## err ## _erpt; 838 839 void 840 fab_setup_master_table() 841 { 842 /* Setup the master error table */ 843 fab_master_err_tbl = (fab_err_tbl_t *)calloc(13, 844 sizeof (fab_err_tbl_t)); 845 846 SET_TBL(0, pci, pci_err_status, 16); 847 SET_TBL(1, pci_bdg, pci_bdg_sec_stat, 16); 848 SET_TBL(2, pci_bdg_ctl, pci_bdg_ctrl, 16); 849 SET_TBL(3, pcie_ce, pcie_ce_status, 32); 850 SET_TBL(4, pcie_ue, pcie_ue_status, 32); 851 SET_TBL(5, pcie_sue, pcie_sue_status, 32); 852 SET_TBL(6, pcix, pcix_status, 32); 853 SET_TBL(7, pcix_bdg_sec, pcix_bdg_sec_stat, 16); 854 SET_TBL(8, pcix_bdg, pcix_bdg_stat, 32); 855 SET_TBL(9, pcie_nadv, pcie_err_status, 16); 856 SET_TBL(10, pcie_rc, pcie_rp_err_status, 32); 857 SET_TBL(11, pcie_fake_rc, pcie_err_status, 16); 858 } 859