xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_fm.c (revision d362b749)
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  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/nxge/nxge_impl.h>
29 #include <sys/ddifm.h>
30 #include <sys/fm/protocol.h>
31 #include <sys/fm/util.h>
32 #include <sys/fm/io/ddi.h>
33 
34 static nxge_fm_ereport_attr_t
35 *nxge_fm_get_ereport_attr(nxge_fm_ereport_id_t);
36 
37 nxge_fm_ereport_attr_t	nxge_fm_ereport_pcs[] = {
38 	{NXGE_FM_EREPORT_XPCS_LINK_DOWN,	"10g_link_down",
39 						DDI_FM_DEVICE_INVAL_STATE,
40 						DDI_SERVICE_LOST},
41 	{NXGE_FM_EREPORT_XPCS_TX_LINK_FAULT,	"10g_tx_link_fault",
42 						DDI_FM_DEVICE_INVAL_STATE,
43 						DDI_SERVICE_DEGRADED},
44 	{NXGE_FM_EREPORT_XPCS_RX_LINK_FAULT,	"10g_rx_link_fault",
45 						DDI_FM_DEVICE_INVAL_STATE,
46 						DDI_SERVICE_DEGRADED},
47 	{NXGE_FM_EREPORT_PCS_LINK_DOWN,		"1g_link_down",
48 						DDI_FM_DEVICE_INVAL_STATE,
49 						DDI_SERVICE_LOST},
50 	{NXGE_FM_EREPORT_PCS_REMOTE_FAULT,	"1g_remote_fault",
51 						DDI_FM_DEVICE_INVAL_STATE,
52 						DDI_SERVICE_DEGRADED},
53 };
54 
55 nxge_fm_ereport_attr_t	nxge_fm_ereport_mif[] = {
56 	{NXGE_FM_EREPORT_MIF_ACCESS_FAIL,	"transceiver_access_fail"}
57 };
58 
59 nxge_fm_ereport_attr_t nxge_fm_ereport_fflp[] = {
60 	{NXGE_FM_EREPORT_FFLP_TCAM_ERR,		"classifier_tcam_err",
61 						DDI_FM_DEVICE_INTERN_UNCORR,
62 						DDI_SERVICE_UNAFFECTED},
63 	{NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR,	"classifier_vlan_par_err",
64 						DDI_FM_DEVICE_INTERN_UNCORR,
65 						DDI_SERVICE_UNAFFECTED},
66 	{NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR,	"classifier_hasht_data_err",
67 						DDI_FM_DEVICE_INTERN_UNCORR,
68 						DDI_SERVICE_UNAFFECTED},
69 	{NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR,	"classifier_hasht_lookup_err",
70 						DDI_FM_DEVICE_INTERN_UNCORR,
71 						DDI_SERVICE_UNAFFECTED},
72 	{NXGE_FM_EREPORT_FFLP_ACCESS_FAIL,	"classifier_access_fail",
73 						DDI_FM_DEVICE_NO_RESPONSE,
74 						DDI_SERVICE_DEGRADED}
75 };
76 
77 nxge_fm_ereport_attr_t nxge_fm_ereport_ipp[] = {
78 	{NXGE_FM_EREPORT_IPP_EOP_MISS,		"rx_eop_miss",
79 						DDI_FM_DEVICE_INVAL_STATE,
80 						DDI_SERVICE_LOST},
81 	{NXGE_FM_EREPORT_IPP_SOP_MISS,		"rx_sop_miss",
82 						DDI_FM_DEVICE_INVAL_STATE,
83 						DDI_SERVICE_LOST},
84 	{NXGE_FM_EREPORT_IPP_DFIFO_UE,		"rx_dfifo_ucorr_err",
85 						DDI_FM_DEVICE_INTERN_UNCORR,
86 						DDI_SERVICE_LOST},
87 	{NXGE_FM_EREPORT_IPP_DFIFO_CE,		"rx_dfifo_corr_err",
88 						DDI_FM_DEVICE_INTERN_CORR,
89 						DDI_SERVICE_UNAFFECTED},
90 	{NXGE_FM_EREPORT_IPP_PFIFO_PERR,	"rx_dfifo_parity_err",
91 						DDI_FM_DEVICE_INTERN_UNCORR,
92 						DDI_SERVICE_LOST},
93 	{NXGE_FM_EREPORT_IPP_ECC_ERR_MAX,	"rx_ecc_err_max",
94 						DDI_FM_DEVICE_INTERN_UNCORR,
95 						DDI_SERVICE_UNAFFECTED},
96 	{NXGE_FM_EREPORT_IPP_PFIFO_OVER,	"rx_pfifo_overflow",
97 						DDI_FM_DEVICE_INVAL_STATE,
98 						DDI_SERVICE_LOST},
99 	{NXGE_FM_EREPORT_IPP_PFIFO_UND,		"rx_pfifo_underrun",
100 						DDI_FM_DEVICE_INVAL_STATE,
101 						DDI_SERVICE_LOST},
102 	{NXGE_FM_EREPORT_IPP_BAD_CS_MX,		"rx_bad_cksum_max",
103 						DDI_FM_DEVICE_INTERN_UNCORR,
104 						DDI_SERVICE_UNAFFECTED},
105 	{NXGE_FM_EREPORT_IPP_PKT_DIS_MX,	"rx_pkt_discard_max",
106 						DDI_FM_DEVICE_INTERN_UNCORR,
107 						DDI_SERVICE_UNAFFECTED},
108 	{NXGE_FM_EREPORT_IPP_RESET_FAIL,	"rx_reset_fail",
109 						DDI_FM_DEVICE_NO_RESPONSE,
110 						DDI_SERVICE_LOST}
111 };
112 
113 nxge_fm_ereport_attr_t nxge_fm_ereport_rdmc[] = {
114 	{NXGE_FM_EREPORT_RDMC_DCF_ERR,		"rxdma_dcf_err",
115 						DDI_FM_DEVICE_INTERN_UNCORR,
116 						DDI_SERVICE_LOST},
117 	{NXGE_FM_EREPORT_RDMC_RCR_ACK_ERR,	"rxdma_rcr_ack_err",
118 						DDI_FM_DEVICE_INTERN_UNCORR,
119 						DDI_SERVICE_DEGRADED},
120 	{NXGE_FM_EREPORT_RDMC_DC_FIFO_ERR,	"rxdma_dc_fifo_err",
121 						DDI_FM_DEVICE_INTERN_UNCORR,
122 						DDI_SERVICE_LOST},
123 	{NXGE_FM_EREPORT_RDMC_RCR_SHA_PAR,	"rxdma_rcr_sha_par_err",
124 						DDI_FM_DEVICE_INTERN_UNCORR,
125 						DDI_SERVICE_DEGRADED},
126 	{NXGE_FM_EREPORT_RDMC_RBR_PRE_PAR,	"rxdma_rbr_pre_par_err",
127 						DDI_FM_DEVICE_INTERN_UNCORR,
128 						DDI_SERVICE_DEGRADED},
129 	{NXGE_FM_EREPORT_RDMC_RBR_TMOUT,	"rxdma_rbr_tmout",
130 						DDI_FM_DEVICE_NO_RESPONSE,
131 						DDI_SERVICE_DEGRADED},
132 	{NXGE_FM_EREPORT_RDMC_RSP_CNT_ERR,	"rxdma_rsp_cnt_err",
133 						DDI_FM_DEVICE_INVAL_STATE,
134 						DDI_SERVICE_DEGRADED},
135 	{NXGE_FM_EREPORT_RDMC_BYTE_EN_BUS,	"rxdma_byte_en_bus",
136 						DDI_FM_DEVICE_INVAL_STATE,
137 						DDI_SERVICE_DEGRADED},
138 	{NXGE_FM_EREPORT_RDMC_RSP_DAT_ERR,	"rxdma_rsp_dat_err",
139 						DDI_FM_DEVICE_INTERN_UNCORR,
140 						DDI_SERVICE_DEGRADED},
141 	{NXGE_FM_EREPORT_RDMC_ID_MISMATCH,	"rxdma_id_mismatch",
142 						DDI_FM_DEVICE_INVAL_STATE,
143 						DDI_SERVICE_LOST},
144 	{NXGE_FM_EREPORT_RDMC_ZCP_EOP_ERR,	"rxdma_zcp_eop_err",
145 						DDI_FM_DEVICE_INVAL_STATE,
146 						DDI_SERVICE_LOST},
147 	{NXGE_FM_EREPORT_RDMC_IPP_EOP_ERR,	"rxdma_ipp_eop_err",
148 						DDI_FM_DEVICE_INVAL_STATE,
149 						DDI_SERVICE_LOST},
150 	{NXGE_FM_EREPORT_RDMC_COMPLETION_ERR,	"rxdma_completion_err",
151 						DDI_FM_DEVICE_INTERN_UNCORR,
152 						DDI_SERVICE_UNAFFECTED},
153 	{NXGE_FM_EREPORT_RDMC_CONFIG_ERR,	"rxdma_config_err",
154 						DDI_FM_DEVICE_INVAL_STATE,
155 						DDI_SERVICE_DEGRADED},
156 	{NXGE_FM_EREPORT_RDMC_RCRINCON,		"rxdma_rcrincon",
157 						DDI_FM_DEVICE_INVAL_STATE,
158 						DDI_SERVICE_DEGRADED},
159 	{NXGE_FM_EREPORT_RDMC_RCRFULL,		"rxdma_rcrfull",
160 						DDI_FM_DEVICE_INVAL_STATE,
161 						DDI_SERVICE_DEGRADED},
162 	{NXGE_FM_EREPORT_RDMC_RBRFULL,		"rxdma_rbrfull",
163 						DDI_FM_DEVICE_INVAL_STATE,
164 						DDI_SERVICE_DEGRADED},
165 	{NXGE_FM_EREPORT_RDMC_RBRLOGPAGE,	"rxdma_rbrlogpage",
166 						DDI_FM_DEVICE_INVAL_STATE,
167 						DDI_SERVICE_DEGRADED},
168 	{NXGE_FM_EREPORT_RDMC_CFIGLOGPAGE,	"rxdma_cfiglogpage",
169 						DDI_FM_DEVICE_INVAL_STATE,
170 						DDI_SERVICE_DEGRADED}
171 };
172 
173 nxge_fm_ereport_attr_t nxge_fm_ereport_zcp[] = {
174 	{NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN,	"rxzcopy_rrfifo_underrun",
175 						DDI_FM_DEVICE_INVAL_STATE,
176 						DDI_SERVICE_UNAFFECTED},
177 	{NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR,
178 						"rxzcopy_rspfifo_uncorr_err",
179 						DDI_FM_DEVICE_INTERN_UNCORR,
180 						DDI_SERVICE_UNAFFECTED},
181 	{NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR,	"rxzcopy_stat_tbl_perr",
182 						DDI_FM_DEVICE_INTERN_UNCORR,
183 						DDI_SERVICE_UNAFFECTED},
184 	{NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR,	"rxzcopy_dyn_tbl_perr",
185 						DDI_FM_DEVICE_INTERN_UNCORR,
186 						DDI_SERVICE_UNAFFECTED},
187 	{NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR,	"rxzcopy_buf_tbl_perr",
188 						DDI_FM_DEVICE_INTERN_UNCORR,
189 						DDI_SERVICE_UNAFFECTED},
190 	{NXGE_FM_EREPORT_ZCP_CFIFO_ECC,		"rxzcopy_cfifo_ecc",
191 						DDI_FM_DEVICE_INTERN_CORR,
192 						DDI_SERVICE_UNAFFECTED},
193 	{NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN,	"rxzcopy_rrfifo_overrun",
194 						DDI_FM_DEVICE_INVAL_STATE,
195 						DDI_SERVICE_UNAFFECTED},
196 	{NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW,	"rxzcopy_buffer_overflow",
197 						DDI_FM_DEVICE_INVAL_STATE,
198 						DDI_SERVICE_LOST},
199 	{NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR,	"rxzcopy_tt_program_err",
200 						DDI_FM_DEVICE_INVAL_STATE,
201 						DDI_SERVICE_UNAFFECTED},
202 	{NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR,	"rxzcopy_rsp_tt_index_err",
203 						DDI_FM_DEVICE_INVAL_STATE,
204 						DDI_SERVICE_UNAFFECTED},
205 	{NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR,	"rxzcopy_slv_tt_index_err",
206 						DDI_FM_DEVICE_INVAL_STATE,
207 						DDI_SERVICE_UNAFFECTED},
208 	{NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR,	"rxzcopy_tt_index_err",
209 						DDI_FM_DEVICE_INVAL_STATE,
210 						DDI_SERVICE_UNAFFECTED},
211 	{NXGE_FM_EREPORT_ZCP_ACCESS_FAIL,	"rxzcopy_access_fail",
212 						DDI_FM_DEVICE_NO_RESPONSE,
213 						DDI_SERVICE_LOST},
214 };
215 
216 nxge_fm_ereport_attr_t nxge_fm_ereport_rxmac[] = {
217 	{NXGE_FM_EREPORT_RXMAC_UNDERFLOW,	"rxmac_underflow",
218 						DDI_FM_DEVICE_INVAL_STATE,
219 						DDI_SERVICE_UNAFFECTED},
220 	{NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP,	"rxmac_crc_errcnt_exp",
221 						DDI_FM_DEVICE_INTERN_UNCORR,
222 						DDI_SERVICE_UNAFFECTED},
223 	{NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP,
224 						"rxmac_length_errcnt_exp",
225 						DDI_FM_DEVICE_INTERN_UNCORR,
226 						DDI_SERVICE_UNAFFECTED},
227 	{NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP,	"rxmac_viol_errcnt_exp",
228 						DDI_FM_DEVICE_INTERN_UNCORR,
229 						DDI_SERVICE_UNAFFECTED},
230 	{NXGE_FM_EREPORT_RXMAC_RXFRAG_CNT_EXP,	"rxmac_rxfrag_cnt_exp",
231 						DDI_FM_DEVICE_INTERN_UNCORR,
232 						DDI_SERVICE_UNAFFECTED},
233 	{NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP,	"rxmac_align_ecnt_exp",
234 						DDI_FM_DEVICE_INTERN_UNCORR,
235 						DDI_SERVICE_UNAFFECTED},
236 	{NXGE_FM_EREPORT_RXMAC_LINKFAULT_CNT_EXP,
237 						"rxmac_linkfault_cnt_exp",
238 						DDI_FM_DEVICE_INTERN_UNCORR,
239 						DDI_SERVICE_UNAFFECTED},
240 	{NXGE_FM_EREPORT_RXMAC_RESET_FAIL,	"rxmac_reset_fail",
241 						DDI_FM_DEVICE_NO_RESPONSE,
242 						DDI_SERVICE_UNAFFECTED},
243 };
244 
245 nxge_fm_ereport_attr_t nxge_fm_ereport_tdmc[] = {
246 	{NXGE_FM_EREPORT_TDMC_PREF_BUF_PAR_ERR,	"txdma_pref_buf_par_err",
247 						DDI_FM_DEVICE_INTERN_UNCORR,
248 						DDI_SERVICE_DEGRADED},
249 	{NXGE_FM_EREPORT_TDMC_MBOX_ERR,		"txdma_mbox_err",
250 						DDI_FM_DEVICE_NO_RESPONSE,
251 						DDI_SERVICE_DEGRADED},
252 	{NXGE_FM_EREPORT_TDMC_NACK_PREF,	"txdma_nack_pref",
253 						DDI_FM_DEVICE_NO_RESPONSE,
254 						DDI_SERVICE_DEGRADED},
255 	{NXGE_FM_EREPORT_TDMC_NACK_PKT_RD,	"txdma_nack_pkt_rd",
256 						DDI_FM_DEVICE_NO_RESPONSE,
257 						DDI_SERVICE_DEGRADED},
258 	{NXGE_FM_EREPORT_TDMC_PKT_SIZE_ERR,	"txdma_pkt_size_err",
259 						DDI_FM_DEVICE_INVAL_STATE,
260 						DDI_SERVICE_DEGRADED},
261 	{NXGE_FM_EREPORT_TDMC_TX_RING_OFLOW,	"txdma_tx_ring_oflow",
262 						DDI_FM_DEVICE_INVAL_STATE,
263 						DDI_SERVICE_DEGRADED},
264 	{NXGE_FM_EREPORT_TDMC_CONF_PART_ERR,	"txdma_conf_part_err",
265 						DDI_FM_DEVICE_INVAL_STATE,
266 						DDI_SERVICE_DEGRADED},
267 	{NXGE_FM_EREPORT_TDMC_PKT_PRT_ERR,	"txdma_pkt_prt_err",
268 						DDI_FM_DEVICE_INTERN_UNCORR,
269 						DDI_SERVICE_DEGRADED},
270 	{NXGE_FM_EREPORT_TDMC_RESET_FAIL,	"txdma_reset_fail",
271 						DDI_FM_DEVICE_NO_RESPONSE,
272 						DDI_SERVICE_LOST},
273 };
274 
275 nxge_fm_ereport_attr_t nxge_fm_ereport_txc[] = {
276 	{NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR,	"tx_ro_correct_err",
277 						DDI_FM_DEVICE_INTERN_CORR,
278 						DDI_SERVICE_UNAFFECTED},
279 	{NXGE_FM_EREPORT_TXC_RO_UNCORRECT_ERR,	"tx_ro_uncorrect_err",
280 						DDI_FM_DEVICE_INTERN_UNCORR,
281 						DDI_SERVICE_UNAFFECTED},
282 	{NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR,	"tx_sf_correct_err",
283 						DDI_FM_DEVICE_INTERN_CORR,
284 						DDI_SERVICE_UNAFFECTED},
285 	{NXGE_FM_EREPORT_TXC_SF_UNCORRECT_ERR,	"tx_sf_uncorrect_err",
286 						DDI_FM_DEVICE_INTERN_UNCORR,
287 						DDI_SERVICE_UNAFFECTED},
288 	{NXGE_FM_EREPORT_TXC_ASSY_DEAD,		"tx_assembly_uncorrect_err",
289 						DDI_FM_DEVICE_INTERN_UNCORR,
290 						DDI_SERVICE_UNAFFECTED},
291 	{NXGE_FM_EREPORT_TXC_REORDER_ERR,	"tx_reorder_err",
292 						DDI_FM_DEVICE_INVAL_STATE,
293 						DDI_SERVICE_LOST},
294 };
295 
296 nxge_fm_ereport_attr_t nxge_fm_ereport_txmac[] = {
297 	{NXGE_FM_EREPORT_TXMAC_UNDERFLOW,	"txmac_underflow",
298 						DDI_FM_DEVICE_INVAL_STATE,
299 						DDI_SERVICE_UNAFFECTED},
300 	{NXGE_FM_EREPORT_TXMAC_OVERFLOW,	"txmac_overflow",
301 						DDI_FM_DEVICE_INVAL_STATE,
302 						DDI_SERVICE_UNAFFECTED},
303 	{NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR,	"txmac_txfifo_xfr_err",
304 						DDI_FM_DEVICE_INVAL_STATE,
305 						DDI_SERVICE_UNAFFECTED},
306 	{NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR,	"txmac_max_pkt_err",
307 						DDI_FM_DEVICE_INTERN_UNCORR,
308 						DDI_SERVICE_UNAFFECTED},
309 	{NXGE_FM_EREPORT_TXMAC_RESET_FAIL,	"txmac_reset_fail",
310 						DDI_FM_DEVICE_NO_RESPONSE,
311 						DDI_SERVICE_UNAFFECTED},
312 };
313 
314 nxge_fm_ereport_attr_t nxge_fm_ereport_espc[] = {
315 	{NXGE_FM_EREPORT_ESPC_ACCESS_FAIL,	"eprom_access_fail",
316 						DDI_FM_DEVICE_NO_RESPONSE,
317 						DDI_SERVICE_LOST},
318 };
319 
320 nxge_fm_ereport_attr_t nxge_fm_ereport_sw[] = {
321 	{NXGE_FM_EREPORT_SW_INVALID_PORT_NUM,	"invalid_port_num",
322 						DDI_FM_DEVICE_INVAL_STATE,
323 						DDI_SERVICE_LOST},
324 	{NXGE_FM_EREPORT_SW_INVALID_CHAN_NUM,	"invalid_chan_num",
325 						DDI_FM_DEVICE_INVAL_STATE,
326 						DDI_SERVICE_LOST},
327 	{NXGE_FM_EREPORT_SW_INVALID_PARAM,	"invalid_param",
328 						DDI_FM_DEVICE_INVAL_STATE,
329 						DDI_SERVICE_LOST},
330 };
331 
332 void
333 nxge_fm_init(p_nxge_t nxgep, ddi_device_acc_attr_t *reg_attr,
334 		ddi_device_acc_attr_t *desc_attr, ddi_dma_attr_t *dma_attr)
335 {
336 	ddi_iblock_cookie_t iblk;
337 
338 	nxgep->fm_capabilities = ddi_prop_get_int(DDI_DEV_T_ANY, nxgep->dip,
339 			DDI_PROP_DONTPASS, "fm-capable", 1);
340 	NXGE_DEBUG_MSG((nxgep, DDI_CTL,
341 		"FM capable = %d\n", nxgep->fm_capabilities));
342 
343 	/* Only register with IO Fault Services if we have some capability */
344 	if (nxgep->fm_capabilities) {
345 		reg_attr->devacc_attr_access = DDI_FLAGERR_ACC;
346 		desc_attr->devacc_attr_access = DDI_FLAGERR_ACC;
347 		dma_attr->dma_attr_flags |= DDI_DMA_FLAGERR;
348 
349 		/* Register capabilities with IO Fault Services */
350 		ddi_fm_init(nxgep->dip, &nxgep->fm_capabilities, &iblk);
351 
352 		/*
353 		 * Initialize pci ereport capabilities if ereport capable
354 		 */
355 		if (DDI_FM_EREPORT_CAP(nxgep->fm_capabilities) ||
356 		    DDI_FM_ERRCB_CAP(nxgep->fm_capabilities))
357 			pci_ereport_setup(nxgep->dip);
358 	} else {
359 		/*
360 		 * These fields have to be cleared of FMA if there are no
361 		 * FMA capabilities at runtime.
362 		 */
363 		reg_attr->devacc_attr_access = DDI_DEFAULT_ACC;
364 		desc_attr->devacc_attr_access = DDI_DEFAULT_ACC;
365 		dma_attr->dma_attr_flags &= ~DDI_DMA_FLAGERR;
366 	}
367 }
368 
369 void
370 nxge_fm_fini(p_nxge_t nxgep)
371 {
372 	/* Only unregister FMA capabilities if we registered some */
373 	if (nxgep->fm_capabilities) {
374 
375 		/*
376 		 * Release any resources allocated by pci_ereport_setup()
377 		 */
378 		if (DDI_FM_EREPORT_CAP(nxgep->fm_capabilities) ||
379 		    DDI_FM_ERRCB_CAP(nxgep->fm_capabilities))
380 			pci_ereport_teardown(nxgep->dip);
381 
382 		/*
383 		 * Un-register error callback if error callback capable
384 		 */
385 		if (DDI_FM_ERRCB_CAP(nxgep->fm_capabilities))
386 			ddi_fm_handler_unregister(nxgep->dip);
387 
388 		/* Unregister from IO Fault Services */
389 		ddi_fm_fini(nxgep->dip);
390 	}
391 }
392 
393 void
394 nxge_fm_npi_error_handler(p_nxge_t nxgep, npi_status_t status)
395 {
396 	uint8_t			block_id;
397 	uint8_t			error_type;
398 	nxge_fm_ereport_id_t	fm_ereport_id;
399 	nxge_fm_ereport_attr_t	*fm_ereport_attr;
400 	char			*class_name;
401 	uint64_t		ena;
402 	uint8_t			portn = 0;
403 	uint8_t			chan = 0;
404 	boolean_t		is_port;
405 	boolean_t		is_chan;
406 
407 	if (status == NPI_SUCCESS)
408 		return;
409 
410 	block_id = (status >> NPI_BLOCK_ID_SHIFT) & 0xF;
411 	error_type = status & 0xFF;
412 	is_port = (status & IS_PORT)? B_TRUE: B_FALSE;
413 	is_chan = (status & IS_CHAN)? B_TRUE: B_FALSE;
414 
415 	if (is_port)
416 		portn = (status >> NPI_PORT_CHAN_SHIFT) & 0xF;
417 	else if (is_chan)
418 		chan = (status >> NPI_PORT_CHAN_SHIFT) & 0xF;
419 
420 	/* Map error type into FM ereport id */
421 
422 	/* Handle all software errors */
423 
424 	if (((error_type >= COMMON_SW_ERR_START) &&
425 				(error_type <= COMMON_SW_ERR_END)) ||
426 		((error_type >= BLK_SPEC_SW_ERR_START) &&
427 				(error_type <= BLK_SPEC_SW_ERR_END))) {
428 		switch (error_type) {
429 		case PORT_INVALID:
430 			fm_ereport_id = NXGE_FM_EREPORT_SW_INVALID_PORT_NUM;
431 			break;
432 		case CHANNEL_INVALID:
433 			fm_ereport_id = NXGE_FM_EREPORT_SW_INVALID_CHAN_NUM;
434 			break;
435 		default:
436 			fm_ereport_id = NXGE_FM_EREPORT_SW_INVALID_PARAM;
437 		}
438 	} else if (((error_type >= COMMON_HW_ERR_START) &&
439 				(error_type <= COMMON_HW_ERR_END)) ||
440 		((error_type >= BLK_SPEC_HW_ERR_START) &&
441 				(error_type <= BLK_SPEC_SW_ERR_END))) {
442 		/* Handle hardware errors */
443 		switch (error_type) {
444 		case RESET_FAILED:
445 			switch (block_id) {
446 			case TXMAC_BLK_ID:
447 				fm_ereport_id =
448 					NXGE_FM_EREPORT_TXMAC_RESET_FAIL;
449 				break;
450 			case RXMAC_BLK_ID:
451 				fm_ereport_id =
452 					NXGE_FM_EREPORT_RXMAC_RESET_FAIL;
453 				break;
454 			case IPP_BLK_ID:
455 				fm_ereport_id = NXGE_FM_EREPORT_IPP_RESET_FAIL;
456 				break;
457 			case TXDMA_BLK_ID:
458 				fm_ereport_id = NXGE_FM_EREPORT_TDMC_RESET_FAIL;
459 				break;
460 			default:
461 				fm_ereport_id = NXGE_FM_EREPORT_UNKNOWN;
462 			}
463 			break;
464 		case WRITE_FAILED:
465 		case READ_FAILED:
466 			switch (block_id) {
467 			case MIF_BLK_ID:
468 				fm_ereport_id = NXGE_FM_EREPORT_MIF_ACCESS_FAIL;
469 				break;
470 			case ZCP_BLK_ID:
471 				fm_ereport_id = NXGE_FM_EREPORT_ZCP_ACCESS_FAIL;
472 				break;
473 			case ESPC_BLK_ID:
474 				fm_ereport_id =
475 					NXGE_FM_EREPORT_ESPC_ACCESS_FAIL;
476 				break;
477 			case FFLP_BLK_ID:
478 				fm_ereport_id =
479 					NXGE_FM_EREPORT_FFLP_ACCESS_FAIL;
480 				break;
481 			default:
482 				fm_ereport_id = NXGE_FM_EREPORT_UNKNOWN;
483 			}
484 			break;
485 		case TXDMA_HW_STOP_FAILED:
486 		case TXDMA_HW_RESUME_FAILED:
487 			fm_ereport_id = NXGE_FM_EREPORT_TDMC_RESET_FAIL;
488 			break;
489 		}
490 	}
491 
492 	fm_ereport_attr = nxge_fm_get_ereport_attr(fm_ereport_id);
493 	if (fm_ereport_attr == NULL)
494 		return;
495 	class_name = fm_ereport_attr->eclass;
496 
497 	ena = fm_ena_generate(0, FM_ENA_FMT1);
498 
499 	if ((is_port == B_FALSE) && (is_chan == B_FALSE)) {
500 		ddi_fm_ereport_post(nxgep->dip, class_name, ena,
501 			DDI_NOSLEEP,
502 			FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
503 			NULL);
504 	} else if ((is_port == B_TRUE) && (is_chan == B_FALSE)) {
505 		ddi_fm_ereport_post(nxgep->dip, class_name, ena, DDI_NOSLEEP,
506 			FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
507 			ERNAME_ERR_PORTN, DATA_TYPE_UINT8, portn,
508 			NULL);
509 	} else if ((is_port == B_FALSE) && (is_chan == B_TRUE)) {
510 		ddi_fm_ereport_post(nxgep->dip, class_name, ena, DDI_NOSLEEP,
511 			FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
512 			ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, chan,
513 			NULL);
514 	} else if ((is_port == B_TRUE) && (is_chan == B_TRUE)) {
515 		ddi_fm_ereport_post(nxgep->dip, class_name, ena, DDI_NOSLEEP,
516 			FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
517 			ERNAME_ERR_PORTN, DATA_TYPE_UINT8, portn,
518 			ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, chan,
519 			NULL);
520 	}
521 }
522 
523 static nxge_fm_ereport_attr_t *
524 nxge_fm_get_ereport_attr(nxge_fm_ereport_id_t ereport_id)
525 {
526 	nxge_fm_ereport_attr_t *attr;
527 	uint8_t	blk_id = ((ereport_id >> EREPORT_FM_ID_SHIFT) &
528 							EREPORT_FM_ID_MASK);
529 	uint8_t index = (ereport_id & EREPORT_INDEX_MASK);
530 
531 	switch (blk_id) {
532 	case FM_SW_ID:
533 		attr = &nxge_fm_ereport_sw[index];
534 		break;
535 	case FM_PCS_ID:
536 		attr = &nxge_fm_ereport_pcs[index];
537 		break;
538 	case FM_TXMAC_ID:
539 		attr = &nxge_fm_ereport_txmac[index];
540 		break;
541 	case FM_RXMAC_ID:
542 		attr = &nxge_fm_ereport_rxmac[index];
543 		break;
544 	case FM_MIF_ID:
545 		attr = &nxge_fm_ereport_mif[index];
546 		break;
547 	case FM_FFLP_ID:
548 		attr = &nxge_fm_ereport_fflp[index];
549 		break;
550 	case FM_ZCP_ID:
551 		attr = &nxge_fm_ereport_zcp[index];
552 		break;
553 	case FM_RXDMA_ID:
554 		attr = &nxge_fm_ereport_rdmc[index];
555 		break;
556 	case FM_TXDMA_ID:
557 		attr = &nxge_fm_ereport_tdmc[index];
558 		break;
559 	case FM_IPP_ID:
560 		attr = &nxge_fm_ereport_ipp[index];
561 		break;
562 	case FM_TXC_ID:
563 		attr = &nxge_fm_ereport_txc[index];
564 		break;
565 	case FM_ESPC_ID:
566 		attr = &nxge_fm_ereport_espc[index];
567 		break;
568 	default:
569 		attr = NULL;
570 	}
571 
572 	return (attr);
573 }
574 
575 static void
576 nxge_fm_ereport(p_nxge_t nxgep, uint8_t err_portn, uint8_t err_chan,
577 					nxge_fm_ereport_attr_t *ereport)
578 {
579 	uint64_t		ena;
580 	char			eclass[FM_MAX_CLASS];
581 	char			*err_str;
582 	p_nxge_stats_t		statsp;
583 
584 	(void) snprintf(eclass, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE,
585 			ereport->eclass);
586 	err_str = ereport->str;
587 	ena = fm_ena_generate(0, FM_ENA_FMT1);
588 	statsp = nxgep->statsp;
589 
590 	if (DDI_FM_EREPORT_CAP(nxgep->fm_capabilities)) {
591 		switch (ereport->index) {
592 		case NXGE_FM_EREPORT_XPCS_LINK_DOWN:
593 		case NXGE_FM_EREPORT_XPCS_TX_LINK_FAULT:
594 		case NXGE_FM_EREPORT_XPCS_RX_LINK_FAULT:
595 		case NXGE_FM_EREPORT_PCS_LINK_DOWN:
596 		case NXGE_FM_EREPORT_PCS_REMOTE_FAULT:
597 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
598 				DDI_NOSLEEP,
599 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
600 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
601 				NULL);
602 			break;
603 		case NXGE_FM_EREPORT_IPP_EOP_MISS:
604 		case NXGE_FM_EREPORT_IPP_SOP_MISS:
605 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
606 				DDI_NOSLEEP,
607 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
608 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
609 				ERNAME_DFIFO_RD_PTR, DATA_TYPE_UINT16,
610 					statsp->ipp_stats.errlog.dfifo_rd_ptr,
611 				ERNAME_IPP_STATE_MACH, DATA_TYPE_UINT32,
612 					statsp->ipp_stats.errlog.state_mach,
613 				NULL);
614 			break;
615 		case NXGE_FM_EREPORT_IPP_DFIFO_UE:
616 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
617 				DDI_NOSLEEP,
618 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
619 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
620 				ERNAME_DFIFO_ENTRY, DATA_TYPE_UINT16,
621 				nxgep->ipp.status.bits.w0.dfifo_ecc_err_idx,
622 				ERNAME_DFIFO_SYNDROME, DATA_TYPE_UINT16,
623 					statsp->ipp_stats.errlog.ecc_syndrome,
624 				NULL);
625 			break;
626 		case NXGE_FM_EREPORT_IPP_PFIFO_PERR:
627 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
628 				DDI_NOSLEEP,
629 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
630 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
631 				ERNAME_PFIFO_ENTRY, DATA_TYPE_UINT8,
632 				nxgep->ipp.status.bits.w0.pre_fifo_perr_idx,
633 				NULL);
634 			break;
635 		case NXGE_FM_EREPORT_IPP_DFIFO_CE:
636 		case NXGE_FM_EREPORT_IPP_ECC_ERR_MAX:
637 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
638 				DDI_NOSLEEP,
639 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
640 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
641 				NULL);
642 			break;
643 		case NXGE_FM_EREPORT_IPP_PFIFO_OVER:
644 		case NXGE_FM_EREPORT_IPP_PFIFO_UND:
645 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
646 				DDI_NOSLEEP,
647 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
648 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
649 				ERNAME_IPP_STATE_MACH, DATA_TYPE_UINT32,
650 					statsp->ipp_stats.errlog.state_mach,
651 				NULL);
652 			break;
653 		case NXGE_FM_EREPORT_IPP_BAD_CS_MX:
654 		case NXGE_FM_EREPORT_IPP_PKT_DIS_MX:
655 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
656 				DDI_NOSLEEP,
657 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
658 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
659 				NULL);
660 			break;
661 		case NXGE_FM_EREPORT_FFLP_TCAM_ERR:
662 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
663 				DDI_NOSLEEP,
664 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
665 				ERNAME_TCAM_ERR_LOG, DATA_TYPE_UINT32,
666 					statsp->fflp_stats.errlog.tcam,
667 				NULL);
668 			break;
669 		case NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR:
670 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
671 				DDI_NOSLEEP,
672 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
673 				ERNAME_VLANTAB_ERR_LOG, DATA_TYPE_UINT32,
674 					statsp->fflp_stats.errlog.vlan,
675 				NULL);
676 			break;
677 		case NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR:
678 		{
679 			int rdc_grp;
680 			hash_tbl_data_log_t hash_log;
681 
682 			for (rdc_grp = 0; rdc_grp < MAX_PARTITION; rdc_grp++) {
683 				hash_log.value = nxgep->classifier.fflp_stats->
684 						errlog.hash_pio[rdc_grp];
685 				if (hash_log.bits.ldw.pio_err) {
686 					ddi_fm_ereport_post(nxgep->dip, eclass,
687 						ena, DDI_NOSLEEP,
688 						FM_VERSION, DATA_TYPE_UINT8,
689 						FM_EREPORT_VERS0,
690 						ERNAME_HASHTAB_ERR_LOG,
691 						DATA_TYPE_UINT32,
692 						nxgep->classifier.fflp_stats->
693 						errlog.hash_pio[rdc_grp], NULL);
694 				}
695 			}
696 		}
697 			break;
698 		case NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR:
699 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
700 				DDI_NOSLEEP,
701 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
702 				ERNAME_HASHT_LOOKUP_ERR_LOG0, DATA_TYPE_UINT32,
703 					statsp->fflp_stats.errlog. hash_lookup1,
704 				ERNAME_HASHT_LOOKUP_ERR_LOG1, DATA_TYPE_UINT32,
705 					statsp->fflp_stats.errlog.hash_lookup2,
706 				NULL);
707 			break;
708 		case NXGE_FM_EREPORT_RDMC_DCF_ERR:
709 		case NXGE_FM_EREPORT_RDMC_RBR_TMOUT:
710 		case NXGE_FM_EREPORT_RDMC_RSP_CNT_ERR:
711 		case NXGE_FM_EREPORT_RDMC_BYTE_EN_BUS:
712 		case NXGE_FM_EREPORT_RDMC_RSP_DAT_ERR:
713 		case NXGE_FM_EREPORT_RDMC_RCR_ACK_ERR:
714 		case NXGE_FM_EREPORT_RDMC_DC_FIFO_ERR:
715 		case NXGE_FM_EREPORT_RDMC_CONFIG_ERR:
716 		case NXGE_FM_EREPORT_RDMC_RCRINCON:
717 		case NXGE_FM_EREPORT_RDMC_RCRFULL:
718 		case NXGE_FM_EREPORT_RDMC_RBRFULL:
719 		case NXGE_FM_EREPORT_RDMC_RBRLOGPAGE:
720 		case NXGE_FM_EREPORT_RDMC_CFIGLOGPAGE:
721 		case NXGE_FM_EREPORT_RDMC_ID_MISMATCH:
722 		case NXGE_FM_EREPORT_RDMC_ZCP_EOP_ERR:
723 		case NXGE_FM_EREPORT_RDMC_IPP_EOP_ERR:
724 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
725 				DDI_NOSLEEP,
726 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
727 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
728 				ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
729 				NULL);
730 			break;
731 		case NXGE_FM_EREPORT_RDMC_RBR_PRE_PAR:
732 		case NXGE_FM_EREPORT_RDMC_RCR_SHA_PAR:
733 			{
734 			uint32_t err_log;
735 			if (ereport->index == NXGE_FM_EREPORT_RDMC_RBR_PRE_PAR)
736 				err_log = (uint32_t)statsp->
737 				rdc_stats[err_chan].errlog.pre_par.value;
738 			else
739 				err_log = (uint32_t)statsp->
740 				rdc_stats[err_chan].errlog.sha_par.value;
741 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
742 				DDI_NOSLEEP,
743 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
744 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
745 				ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
746 				ERNAME_RDMC_PAR_ERR_LOG, DATA_TYPE_UINT8,
747 				err_log, NULL);
748 			}
749 			break;
750 		case NXGE_FM_EREPORT_RDMC_COMPLETION_ERR:
751 			{
752 			uint8_t err_type;
753 			err_type = statsp->
754 				rdc_stats[err_chan].errlog.compl_err_type;
755 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
756 				DDI_NOSLEEP,
757 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
758 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
759 				ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
760 				ERNAME_RDC_ERR_TYPE, DATA_TYPE_UINT8,
761 				err_type, NULL);
762 			}
763 			break;
764 
765 		case NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN:
766 		case NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN:
767 		case NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW:
768 			{
769 			uint32_t sm;
770 			sm = statsp->
771 				zcp_stats.errlog.state_mach.bits.ldw.state;
772 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
773 				DDI_NOSLEEP,
774 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
775 				sm, DATA_TYPE_UINT32,
776 				NULL);
777 			break;
778 			}
779 		case NXGE_FM_EREPORT_ZCP_CFIFO_ECC:
780 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
781 				DDI_NOSLEEP,
782 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
783 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8,
784 				err_portn,
785 				NULL);
786 			break;
787 		case NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR:
788 		case NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR:
789 		case NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR:
790 		case NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR:
791 		case NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR:
792 		case NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR:
793 		case NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR:
794 		case NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR:
795 		case NXGE_FM_EREPORT_RXMAC_UNDERFLOW:
796 		case NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP:
797 		case NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP:
798 		case NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP:
799 		case NXGE_FM_EREPORT_RXMAC_RXFRAG_CNT_EXP:
800 		case NXGE_FM_EREPORT_RXMAC_LINKFAULT_CNT_EXP:
801 		case NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP:
802 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
803 				DDI_NOSLEEP,
804 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
805 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
806 				NULL);
807 			break;
808 		case NXGE_FM_EREPORT_TDMC_MBOX_ERR:
809 		case NXGE_FM_EREPORT_TDMC_TX_RING_OFLOW:
810 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
811 				DDI_NOSLEEP,
812 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
813 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
814 				ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
815 				NULL);
816 			break;
817 		case NXGE_FM_EREPORT_TDMC_PREF_BUF_PAR_ERR:
818 		case NXGE_FM_EREPORT_TDMC_NACK_PREF:
819 		case NXGE_FM_EREPORT_TDMC_NACK_PKT_RD:
820 		case NXGE_FM_EREPORT_TDMC_PKT_SIZE_ERR:
821 		case NXGE_FM_EREPORT_TDMC_CONF_PART_ERR:
822 		case NXGE_FM_EREPORT_TDMC_PKT_PRT_ERR:
823 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
824 				DDI_NOSLEEP,
825 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
826 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
827 				ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
828 				ERNAME_TDMC_ERR_LOG1, DATA_TYPE_UINT32,
829 					statsp->
830 					tdc_stats[err_chan].errlog.logl.value,
831 				ERNAME_TDMC_ERR_LOG1, DATA_TYPE_UINT32,
832 				statsp->tdc_stats[err_chan].errlog.logh.value,
833 					DATA_TYPE_UINT32,
834 				NULL);
835 			break;
836 		case NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR:
837 		case NXGE_FM_EREPORT_TXC_RO_UNCORRECT_ERR:
838 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
839 				DDI_NOSLEEP,
840 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
841 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
842 				ERNAME_TXC_ROECC_ADDR, DATA_TYPE_UINT16,
843 					statsp->txc_stats.errlog.ro_st.roecc.
844 					bits.ldw.ecc_address,
845 				ERNAME_TXC_ROECC_DATA0, DATA_TYPE_UINT32,
846 					statsp->txc_stats.errlog.ro_st.d0.
847 					bits.ldw.ro_ecc_data0,
848 				ERNAME_TXC_ROECC_DATA1, DATA_TYPE_UINT32,
849 					statsp->txc_stats.errlog.ro_st.d1.
850 					bits.ldw.ro_ecc_data1,
851 				ERNAME_TXC_ROECC_DATA2, DATA_TYPE_UINT32,
852 					statsp->txc_stats.errlog.ro_st.d2.
853 					bits.ldw.ro_ecc_data2,
854 				ERNAME_TXC_ROECC_DATA3, DATA_TYPE_UINT32,
855 					statsp->txc_stats.errlog.ro_st.d3.
856 					bits.ldw.ro_ecc_data3,
857 				ERNAME_TXC_ROECC_DATA4, DATA_TYPE_UINT32,
858 					statsp->txc_stats.errlog.ro_st.d4.
859 					bits.ldw.ro_ecc_data4,
860 				NULL);
861 			break;
862 		case NXGE_FM_EREPORT_TXC_REORDER_ERR:
863 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
864 				DDI_NOSLEEP,
865 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
866 				ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING,
867 					err_str,
868 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
869 				ERNAME_TXC_RO_STATE0, DATA_TYPE_UINT32,
870 					(uint32_t)statsp->
871 					txc_stats.errlog.ro_st.st0.value,
872 				ERNAME_TXC_RO_STATE1, DATA_TYPE_UINT32,
873 					(uint32_t)statsp->
874 					txc_stats.errlog.ro_st.st1.value,
875 				ERNAME_TXC_RO_STATE2, DATA_TYPE_UINT32,
876 					(uint32_t)statsp->
877 					txc_stats.errlog.ro_st.st2.value,
878 				ERNAME_TXC_RO_STATE3, DATA_TYPE_UINT32,
879 					(uint32_t)statsp->
880 					txc_stats.errlog.ro_st.st3.value,
881 				ERNAME_TXC_RO_STATE_CTL, DATA_TYPE_UINT32,
882 					(uint32_t)statsp->
883 					txc_stats.errlog.ro_st.ctl.value,
884 				ERNAME_TXC_RO_TIDS, DATA_TYPE_UINT32,
885 					(uint32_t)statsp->
886 					txc_stats.errlog.ro_st.tids.value,
887 				NULL);
888 			break;
889 		case NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR:
890 		case NXGE_FM_EREPORT_TXC_SF_UNCORRECT_ERR:
891 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
892 				DDI_NOSLEEP,
893 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
894 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
895 				ERNAME_TXC_SFECC_ADDR, DATA_TYPE_UINT32,
896 					statsp->txc_stats.errlog.sf_st.sfecc.
897 					bits.ldw.ecc_address,
898 				ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
899 					statsp->txc_stats.errlog.sf_st.d0.
900 					bits.ldw.sf_ecc_data0,
901 				ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
902 					statsp->txc_stats.errlog.sf_st.d1.
903 					bits.ldw.sf_ecc_data1,
904 				ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
905 					statsp->txc_stats.errlog.sf_st.d2.
906 					bits.ldw.sf_ecc_data2,
907 				ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
908 					statsp->txc_stats.errlog.sf_st.d3.
909 					bits.ldw.sf_ecc_data3,
910 				ERNAME_TXC_SFECC_DATA0, DATA_TYPE_UINT32,
911 					statsp->txc_stats.errlog.sf_st.d4.
912 					bits.ldw.sf_ecc_data4,
913 				NULL);
914 			break;
915 		case NXGE_FM_EREPORT_TXMAC_UNDERFLOW:
916 		case NXGE_FM_EREPORT_TXMAC_OVERFLOW:
917 		case NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR:
918 		case NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR:
919 		case NXGE_FM_EREPORT_SW_INVALID_PORT_NUM:
920 		case NXGE_FM_EREPORT_SW_INVALID_CHAN_NUM:
921 		case NXGE_FM_EREPORT_SW_INVALID_PARAM:
922 			ddi_fm_ereport_post(nxgep->dip, eclass, ena,
923 				DDI_NOSLEEP,
924 				FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
925 				ERNAME_ERR_PORTN, DATA_TYPE_UINT8, err_portn,
926 				NULL);
927 			break;
928 		}
929 
930 	}
931 }
932 
933 void
934 nxge_fm_report_error(p_nxge_t nxgep, uint8_t err_portn, uint8_t err_chan,
935 					nxge_fm_ereport_id_t fm_ereport_id)
936 {
937 	nxge_fm_ereport_attr_t	*fm_ereport_attr;
938 
939 	fm_ereport_attr = nxge_fm_get_ereport_attr(fm_ereport_id);
940 
941 	if (fm_ereport_attr != NULL) {
942 		nxge_fm_ereport(nxgep, err_portn, err_chan, fm_ereport_attr);
943 		ddi_fm_service_impact(nxgep->dip, fm_ereport_attr->impact);
944 	}
945 }
946 
947 int
948 fm_check_acc_handle(ddi_acc_handle_t handle)
949 {
950 	ddi_fm_error_t err;
951 
952 	ddi_fm_acc_err_get(handle, &err, DDI_FME_VERSION);
953 #ifndef	NXGE_FM_S10
954 	ddi_fm_acc_err_clear(handle, DDI_FME_VERSION);
955 #endif
956 	return (err.fme_status);
957 }
958 
959 int
960 fm_check_dma_handle(ddi_dma_handle_t handle)
961 {
962 	ddi_fm_error_t err;
963 
964 	ddi_fm_dma_err_get(handle, &err, DDI_FME_VERSION);
965 	return (err.fme_status);
966 }
967