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, NULL, 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, NULL, NULL, 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, NULL, 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, NULL, 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, NULL, 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, NULL, 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, NULL, 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, NULL, 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, NULL, 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, NULL, 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, NULL, 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 }