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.
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.
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]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 #include <sys/fm/util.h>
30 #include "fabric-xlate.h"
32 #define FAB_LOOKUP(sz, name, field) \
33 (void) nvlist_lookup_uint ## sz(nvl, name, field)
35 static boolean_t fab_xlate_fake_rp
= B_TRUE
;
36 static fab_err_tbl_t
*fab_master_err_tbl
;
39 * Translation tables for converting "fabric" error bits into "pci" ereports.
40 * <Ereport Class Name>, <Error Bit Mask>, <Preparation Function>
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
,
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
,
62 PCI_MA
, PCI_STAT_R_MAST_AB
, NULL
,
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
,
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
,
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
,
88 * Translate Fabric ereports to ereport.io.pciex.*
89 * The Target Ereports for this section is only used on leaf devices, with the
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
,
104 PCIEX_UR
, PCIE_AER_UCE_UR
, PCI_TARG_MA
,
106 PCIEX_POIS
, PCIE_AER_UCE_PTLP
, PCI_TARG_MDPE
,
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
,
116 PCIEX_S_RMA
, PCIE_AER_SUCE_RCVD_MA
, PCI_TARG_MA
,
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
,
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
,
137 static fab_erpt_tbl_t
*fab_pcix_bdg_erpt_tbl
= fab_pcix_erpt_tbl
;
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
,
148 /* Translate Fabric ereports to ereport.io.pciex.* */
149 static fab_erpt_tbl_t fab_pcie_nadv_erpt_tbl
[] = {
151 PCIEX_UR
, PCIE_DEVSTS_UR_DETECTED
, NULL
,
153 PCIEX_FAT
, PCIE_DEVSTS_FE_DETECTED
, NULL
,
154 PCIEX_NONFAT
, PCIE_DEVSTS_NFE_DETECTED
, NULL
,
155 PCIEX_CORR
, PCIE_DEVSTS_CE_DETECTED
, NULL
,
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
,
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.
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
,
183 fab_pci_fabric_to_data(fmd_hdl_t
*hdl
, nvlist_t
*nvl
, fab_data_t
*data
)
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
);
198 /* Misc ereport information */
199 FAB_LOOKUP(32, "remainder", &data
->remainder
);
200 FAB_LOOKUP(32, "severity", &data
->severity
);
203 FAB_LOOKUP(16, "pci_status", &data
->pci_err_status
);
204 FAB_LOOKUP(16, "pci_command", &data
->pci_cfg_comm
);
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
);
211 FAB_LOOKUP(32, "pcix_status", &data
->pcix_status
);
212 FAB_LOOKUP(16, "pcix_command", &data
->pcix_command
);
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
);
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
);
229 FAB_LOOKUP(32, "pcix_bdg_status", &data
->pcix_bdg_stat
);
230 FAB_LOOKUP(16, "pcix_bdg_sec_status", &data
->pcix_bdg_sec_stat
);
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
);
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
);
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
);
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
);
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
);
277 fab_prep_pci_erpt(fmd_hdl_t
*hdl
, fab_data_t
*data
, nvlist_t
*erpt
,
280 const char *class = tbl
->err_class
;
281 int err
= fab_prep_basic_erpt(hdl
, data
->nvl
, erpt
, B_FALSE
);
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
);
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
);
295 fab_prep_pci_bdg_erpt(fmd_hdl_t
*hdl
, fab_data_t
*data
, nvlist_t
*erpt
,
298 const char *class = tbl
->err_class
;
299 int err
= fab_prep_basic_erpt(hdl
, data
->nvl
, erpt
, B_FALSE
);
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
);
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
);
314 fab_prep_pci_bdg_ctl_erpt(fmd_hdl_t
*hdl
, fab_data_t
*data
, nvlist_t
*erpt
,
317 const char *class = tbl
->err_class
;
318 int err
= fab_prep_basic_erpt(hdl
, data
->nvl
, erpt
, B_FALSE
);
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
);
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
);
334 fab_prep_pcie_ce_erpt(fmd_hdl_t
*hdl
, fab_data_t
*data
, nvlist_t
*erpt
,
337 const char *class = tbl
->err_class
;
338 int err
= fab_prep_basic_erpt(hdl
, data
->nvl
, erpt
, B_FALSE
);
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
);
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
);
353 fab_prep_pcie_ue_erpt(fmd_hdl_t
*hdl
, fab_data_t
*data
, nvlist_t
*erpt
,
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
);
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
);
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
);
372 fmd_hdl_debug(hdl
, "Bit 0x%x First Err 0x%x", tbl
->reg_bit
, first_err
);
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
);
379 (void) nvlist_add_uint16(erpt
, PCIEX_SRC_ID
, 0);
380 (void) nvlist_add_boolean_value(erpt
, PCIEX_SRC_VALID
, B_FALSE
);
383 if ((tbl
->reg_bit
== first_err
) && !data
->pcie_ue_no_tgt_erpt
&&
384 data
->pcie_ue_tgt_trans
) {
386 fab_send_tgt_erpt(hdl
, data
, tbl
->tgt_class
, B_TRUE
);
393 fab_prep_pcie_sue_erpt(fmd_hdl_t
*hdl
, fab_data_t
*data
, nvlist_t
*erpt
,
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
);
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
);
406 (void) nvlist_add_uint32(erpt
, PCIEX_SEC_UE_STATUS
,
407 data
->pcie_sue_status
);
409 fmd_hdl_debug(hdl
, "Bit 0x%x First Err 0x%x", tbl
->reg_bit
, first_err
);
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
);
416 (void) nvlist_add_uint16(erpt
, PCIEX_SRC_ID
, 0);
417 (void) nvlist_add_boolean_value(erpt
, PCIEX_SRC_VALID
, B_FALSE
);
420 if ((tbl
->reg_bit
== first_err
) && !data
->pcie_ue_no_tgt_erpt
&&
421 data
->pcie_sue_tgt_trans
) {
423 fab_send_tgt_erpt(hdl
, data
, tbl
->tgt_class
, B_FALSE
);
430 fab_prep_pcix_erpt(fmd_hdl_t
*hdl
, fab_data_t
*data
, nvlist_t
*erpt
,
433 const char *class = tbl
->err_class
;
436 /* Only send if this is not a bridge */
437 if (!data
->pcix_status
|| data
->pcix_bdg_sec_stat
)
440 err
= fab_prep_basic_erpt(hdl
, data
->nvl
, erpt
, B_FALSE
);
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
);
447 (void) nvlist_add_uint8(erpt
, PCIX_COMMAND
, data
->pcix_command
);
448 (void) nvlist_add_uint32(erpt
, PCIX_STATUS
, data
->pcix_status
);
454 fab_send_pcix_ecc_erpt(fmd_hdl_t
*hdl
, fab_data_t
*data
)
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
;
465 case PCI_PCIX_ECC_PHASE_NOERR
:
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
);
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
);
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
);
487 if (nvlist_alloc(&erpt
, NV_UNIQUE_NAME
, 0) != 0)
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
,
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");
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)
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
,
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");
525 fmd_hdl_debug(hdl
, "Failed to send ECC ereport\n");
529 fab_prep_pcix_bdg_sec_erpt(fmd_hdl_t
*hdl
, fab_data_t
*data
, nvlist_t
*erpt
,
532 const char *class = tbl
->err_class
;
533 int err
= fab_prep_basic_erpt(hdl
, data
->nvl
, erpt
, B_FALSE
);
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
);
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
);
548 fab_prep_pcix_bdg_erpt(fmd_hdl_t
*hdl
, fab_data_t
*data
, nvlist_t
*erpt
,
551 const char *class = tbl
->err_class
;
552 int err
= fab_prep_basic_erpt(hdl
, data
->nvl
, erpt
, B_FALSE
);
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
);
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
);
567 fab_send_pcix_bdg_ecc_erpt(fmd_hdl_t
*hdl
, fab_data_t
*data
)
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
;
578 case PCI_PCIX_ECC_PHASE_NOERR
:
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
);
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
);
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
);
599 if (nvlist_alloc(&erpt
, NV_UNIQUE_NAME
, 0) != 0)
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");
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)
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");
638 fmd_hdl_debug(hdl
, "Failed to send ECC ereport\n");
642 fab_prep_pcie_nadv_erpt(fmd_hdl_t
*hdl
, fab_data_t
*data
, nvlist_t
*erpt
,
645 const char *class = tbl
->err_class
;
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
) ||
654 err
= fab_prep_basic_erpt(hdl
, data
->nvl
, erpt
, B_FALSE
);
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
);
661 (void) nvlist_add_uint16(erpt
, PCIEX_DEVSTS_REG
, data
->pcie_err_status
);
667 fab_prep_pcie_rc_erpt(fmd_hdl_t
*hdl
, fab_data_t
*data
, nvlist_t
*erpt
,
670 const char *class = tbl
->err_class
;
671 uint32_t status
= data
->pcie_rp_err_status
;
673 int isFE
= 0, isNFE
= 0;
675 fmd_hdl_debug(hdl
, "XLATE RP Error Class %s", class);
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
))
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
)
694 fmd_hdl_debug(hdl
, "XLATE RP Error");
696 err
|= fab_prep_basic_erpt(hdl
, data
->nvl
, erpt
, B_FALSE
);
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
);
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
);
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
);
719 fab_prep_pcie_fake_rc_erpt(fmd_hdl_t
*hdl
, fab_data_t
*data
, nvlist_t
*erpt
,
722 const char *class = tbl
->err_class
;
723 uint32_t rc_err_sts
= 0;
727 * Don't send this for PCI device or Root Ports. Only send it on
728 * systems with non-compliant RPs.
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
))
735 err
= fab_prep_basic_erpt(hdl
, data
->nvl
, erpt
, B_TRUE
);
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
);
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
;
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
;
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
;
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
;
762 (void) nvlist_add_uint32(erpt
, PCIEX_ROOT_ERRSTS_REG
, rc_err_sts
);
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
);
773 fab_xlate_pcie_erpts(fmd_hdl_t
*hdl
, fab_data_t
*data
)
777 fmd_hdl_debug(hdl
, "Sending Ereports Now");
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
);
784 /* Send PCI-X ECC Ereports */
785 fab_send_pcix_ecc_erpt(hdl
, data
);
786 fab_send_pcix_bdg_ecc_erpt(hdl
, data
);
790 fab_xlate_fabric_erpts(fmd_hdl_t
*hdl
, nvlist_t
*nvl
, const char *class)
792 fab_data_t data
= {0};
794 fmd_hdl_debug(hdl
, "fabric ereport received: %s\n", class);
796 fab_pci_fabric_to_data(hdl
, nvl
, &data
);
797 fab_xlate_pcie_erpts(hdl
, &data
);
801 fab_set_fake_rp(fmd_hdl_t
*hdl
)
803 char *rppath
= fab_get_rpdev(hdl
), *str
= NULL
;
807 fmd_hdl_debug(hdl
, "Can't find root port dev path");
812 * For the path '/pci@xxx' is fake root port,
813 * and '/pci@xxx/pci@y' is real root port.
823 fab_xlate_fake_rp
= B_TRUE
;
826 * If count is 0, then it should still be B_FALSE
828 fab_xlate_fake_rp
= B_FALSE
;
830 fmd_hdl_strfree(hdl
, rppath
);
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;
840 fab_setup_master_table()
842 /* Setup the master error table */
843 fab_master_err_tbl
= (fab_err_tbl_t
*)calloc(13,
844 sizeof (fab_err_tbl_t
));
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);