8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / fm / modules / common / fabric-xlate / fx_fabric.c
blob5766d86f7dfbc5d71abbdbd243d47311c28f50d5
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 #include <stddef.h>
27 #include <strings.h>
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,
53 NULL, NULL, 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,
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,
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
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
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
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
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
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
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,
145 NULL, NULL, NULL
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
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
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,
178 NULL, NULL, NULL,
181 /* ARGSUSED */
182 void
183 fab_pci_fabric_to_data(fmd_hdl_t *hdl, nvlist_t *nvl, fab_data_t *data)
185 data->nvl = nvl;
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);
202 /* PCI registers */
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);
210 /* PCIx registers */
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);
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);
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);
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);
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)
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);
291 return (err);
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)
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);
310 return (err);
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)
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);
329 return (err);
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)
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);
349 return (err);
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)
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);
378 } else {
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) {
385 if (tbl->tgt_class)
386 fab_send_tgt_erpt(hdl, data, tbl->tgt_class, B_TRUE);
389 return (err);
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)
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);
415 } else {
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) {
422 if (tbl->tgt_class)
423 fab_send_tgt_erpt(hdl, data, tbl->tgt_class, B_FALSE);
426 return (err);
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)
433 const char *class = tbl->err_class;
434 int err = 0;
436 /* Only send if this is not a bridge */
437 if (!data->pcix_status || data->pcix_bdg_sec_stat)
438 return (1);
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);
450 return (err);
453 static void
454 fab_send_pcix_ecc_erpt(fmd_hdl_t *hdl, fab_data_t *data)
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;
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;
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");
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");
523 return;
524 done:
525 fmd_hdl_debug(hdl, "Failed to send ECC ereport\n");
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)
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);
544 return (err);
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)
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);
563 return (err);
566 static void
567 fab_send_pcix_bdg_ecc_erpt(fmd_hdl_t *hdl, fab_data_t *data)
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;
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;
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");
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");
636 return;
637 done:
638 fmd_hdl_debug(hdl, "Failed to send ECC ereport\n");
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)
645 const char *class = tbl->err_class;
646 int err = 0;
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);
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);
663 return (err);
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)
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;
675 fmd_hdl_debug(hdl, "XLATE RP Error Class %s", class);
677 if (!data->aer_off)
678 return (-1);
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;
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;
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);
715 return (err);
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)
722 const char *class = tbl->err_class;
723 uint32_t rc_err_sts = 0;
724 int err = 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))
733 return (-1);
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);
769 return (err);
772 void
773 fab_xlate_pcie_erpts(fmd_hdl_t *hdl, fab_data_t *data)
775 fab_err_tbl_t *tbl;
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);
789 void
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);
800 void
801 fab_set_fake_rp(fmd_hdl_t *hdl)
803 char *rppath = fab_get_rpdev(hdl), *str = NULL;
804 int count = 0;
806 if (!rppath) {
807 fmd_hdl_debug(hdl, "Can't find root port dev path");
808 return;
812 * For the path '/pci@xxx' is fake root port,
813 * and '/pci@xxx/pci@y' is real root port.
815 str = rppath;
816 while (*str) {
817 if (*str == '/')
818 count++;
819 str++;
822 if (count == 1)
823 fab_xlate_fake_rp = B_TRUE;
824 else
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;
839 void
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);