16349Sqs148142 /*
26349Sqs148142 * CDDL HEADER START
36349Sqs148142 *
46349Sqs148142 * The contents of this file are subject to the terms of the
56349Sqs148142 * Common Development and Distribution License (the "License").
66349Sqs148142 * You may not use this file except in compliance with the License.
76349Sqs148142 *
86349Sqs148142 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96349Sqs148142 * or http://www.opensolaris.org/os/licensing.
106349Sqs148142 * See the License for the specific language governing permissions
116349Sqs148142 * and limitations under the License.
126349Sqs148142 *
136349Sqs148142 * When distributing Covered Code, include this CDDL HEADER in each
146349Sqs148142 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156349Sqs148142 * If applicable, add the following below this CDDL HEADER, with the
166349Sqs148142 * fields enclosed by brackets "[]" replaced with your own identifying
176349Sqs148142 * information: Portions Copyright [yyyy] [name of copyright owner]
186349Sqs148142 *
196349Sqs148142 * CDDL HEADER END
206349Sqs148142 */
21*11257SMichael.Speer@Sun.COM
226349Sqs148142 /*
2311236SStephen.Hanson@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
246349Sqs148142 * Use is subject to license terms.
256349Sqs148142 */
266349Sqs148142
276349Sqs148142 #include <hxge_impl.h>
286349Sqs148142 #include <sys/ddifm.h>
296349Sqs148142 #include <sys/fm/protocol.h>
306349Sqs148142 #include <sys/fm/util.h>
316349Sqs148142 #include <sys/fm/io/ddi.h>
326349Sqs148142
336349Sqs148142 static hxge_fm_ereport_attr_t
346349Sqs148142 *hxge_fm_get_ereport_attr(hxge_fm_ereport_id_t ereport_id);
356349Sqs148142
366349Sqs148142 static int
376349Sqs148142 hxge_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data);
386349Sqs148142
396349Sqs148142 hxge_fm_ereport_attr_t hxge_fm_ereport_vmac[] = {
406349Sqs148142 {HXGE_FM_EREPORT_VMAC_LINK_DOWN, "10g_link_down",
416349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
426349Sqs148142 DDI_SERVICE_LOST}
436349Sqs148142 };
446349Sqs148142
456349Sqs148142 hxge_fm_ereport_attr_t hxge_fm_ereport_pfc[] = {
466349Sqs148142 /*
476349Sqs148142 * The following are part of LDF 0, non-fatal
486349Sqs148142 */
496349Sqs148142 {HXGE_FM_EREPORT_PFC_TCAM_PAR_ERR, "classifier_tcam_par_err",
506349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
516349Sqs148142 DDI_SERVICE_UNAFFECTED},
526349Sqs148142 {HXGE_FM_EREPORT_PFC_VLAN_PAR_ERR, "classifier_vlan_par_err",
536349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
546349Sqs148142 DDI_SERVICE_UNAFFECTED},
556349Sqs148142 {HXGE_FM_EREPORT_PFC_PKT_DROP, "classifier_pkt_drop_err",
566349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
576349Sqs148142 DDI_SERVICE_UNAFFECTED}
586349Sqs148142 };
596349Sqs148142
606349Sqs148142 hxge_fm_ereport_attr_t hxge_fm_ereport_rdmc[] = {
616349Sqs148142 /*
626349Sqs148142 * The following are part of LDF1, fatal
636349Sqs148142 */
646349Sqs148142 {HXGE_FM_EREPORT_RDMC_RBR_CPL_TO, "rxdma_rbr_cpl_to",
656349Sqs148142 DDI_FM_DEVICE_NO_RESPONSE,
666349Sqs148142 DDI_SERVICE_DEGRADED},
676349Sqs148142 {HXGE_FM_EREPORT_RDMC_PEU_RESP_ERR, "rxdma_peu_resp_err",
686349Sqs148142 DDI_FM_DEVICE_INVAL_STATE,
696349Sqs148142 DDI_SERVICE_DEGRADED},
706349Sqs148142 {HXGE_FM_EREPORT_RDMC_RCR_SHA_PAR, "rxdma_rcr_sha_par_err",
716349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
726349Sqs148142 DDI_SERVICE_DEGRADED},
736349Sqs148142 {HXGE_FM_EREPORT_RDMC_RBR_PRE_PAR, "rxdma_rbr_pre_par_err",
746349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
756349Sqs148142 DDI_SERVICE_DEGRADED},
766349Sqs148142 {HXGE_FM_EREPORT_RDMC_RBR_PRE_EMPTY, "rxdma_rbr_pre_empty_err",
776349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
786349Sqs148142 DDI_SERVICE_DEGRADED},
796349Sqs148142 {HXGE_FM_EREPORT_RDMC_RCR_SHA_FULL, "rxdma_rcr_sha_full",
806349Sqs148142 DDI_FM_DEVICE_INVAL_STATE,
816349Sqs148142 DDI_SERVICE_DEGRADED},
826349Sqs148142 {HXGE_FM_EREPORT_RDMC_RCRFULL, "rxdma_rcr_full",
836349Sqs148142 DDI_FM_DEVICE_INVAL_STATE,
846349Sqs148142 DDI_SERVICE_DEGRADED},
856349Sqs148142 {HXGE_FM_EREPORT_RDMC_RBR_EMPTY, "rxdma_rbr_empty",
866349Sqs148142 DDI_FM_DEVICE_INVAL_STATE,
876349Sqs148142 DDI_SERVICE_DEGRADED},
886349Sqs148142 {HXGE_FM_EREPORT_RDMC_RBRFULL, "rxdma_rbr_full",
896349Sqs148142 DDI_FM_DEVICE_INVAL_STATE,
906349Sqs148142 DDI_SERVICE_DEGRADED},
916349Sqs148142 {HXGE_FM_EREPORT_RDMC_RCR_ERR, "rxdma_completion_err",
926349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
936349Sqs148142 DDI_SERVICE_DEGRADED},
946349Sqs148142 /*
956349Sqs148142 * Control/Data ram received a ecc double bit error.
966349Sqs148142 * Fatal error. Part of Device Error 1
976349Sqs148142 */
986349Sqs148142 {HXGE_FM_EREPORT_RDMC_CTRL_FIFO_DED, "rxdma_ctrl_fifo_ded",
996349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
1006349Sqs148142 DDI_SERVICE_DEGRADED},
1016349Sqs148142 {HXGE_FM_EREPORT_RDMC_DATA_FIFO_DED, "rxdma_data_fifo_ded",
1026349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
1036349Sqs148142 DDI_SERVICE_DEGRADED},
1046349Sqs148142 /*
1056349Sqs148142 * Control/Data ram received a ecc single bit error.
1066349Sqs148142 * Non-Fatal error. Part of Device Error 0
1076349Sqs148142 */
1086349Sqs148142 {HXGE_FM_EREPORT_RDMC_CTRL_FIFO_SEC, "rxdma_ctrl_fifo_sec",
1096349Sqs148142 DDI_FM_DEVICE_INTERN_CORR,
1106349Sqs148142 DDI_SERVICE_UNAFFECTED},
1116349Sqs148142 {HXGE_FM_EREPORT_RDMC_DATA_FIFO_SEC, "rxdma_data_fifo_sec",
1126349Sqs148142 DDI_FM_DEVICE_INTERN_CORR,
1136349Sqs148142 DDI_SERVICE_UNAFFECTED}
1146349Sqs148142 };
1156349Sqs148142
1166349Sqs148142 hxge_fm_ereport_attr_t hxge_fm_ereport_tdmc[] = {
1176349Sqs148142 {HXGE_FM_EREPORT_TDMC_PEU_RESP_ERR, "txdma_peu_resp_err",
1186349Sqs148142 DDI_FM_DEVICE_INVAL_STATE,
1196349Sqs148142 DDI_SERVICE_DEGRADED},
1206349Sqs148142 {HXGE_FM_EREPORT_TDMC_PKT_SIZE_HDR_ERR, "txdma_pkt_size_hdr_err",
1216349Sqs148142 DDI_FM_DEVICE_INVAL_STATE,
1226349Sqs148142 DDI_SERVICE_DEGRADED},
1236349Sqs148142 {HXGE_FM_EREPORT_TDMC_RUNT_PKT_DROP_ERR, "txdma_runt_pkt_drop_err",
1246349Sqs148142 DDI_FM_DEVICE_INVAL_STATE,
1256349Sqs148142 DDI_SERVICE_DEGRADED},
1266349Sqs148142 {HXGE_FM_EREPORT_TDMC_PKT_SIZE_ERR, "txdma_pkt_size_err",
1276349Sqs148142 DDI_FM_DEVICE_INVAL_STATE,
1286349Sqs148142 DDI_SERVICE_DEGRADED},
1296349Sqs148142 {HXGE_FM_EREPORT_TDMC_TX_RNG_OFLOW, "txdma_tx_rng_oflow",
1306349Sqs148142 DDI_FM_DEVICE_INVAL_STATE,
1316349Sqs148142 DDI_SERVICE_DEGRADED},
1326349Sqs148142 {HXGE_FM_EREPORT_TDMC_PREF_PAR_ERR, "txdma_pref_par_err",
1336349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
1346349Sqs148142 DDI_SERVICE_DEGRADED},
1356349Sqs148142 {HXGE_FM_EREPORT_TDMC_TDR_PREF_CPL_TO, "txdma_tdr_pref_cpl_to",
1366349Sqs148142 DDI_FM_DEVICE_NO_RESPONSE,
1376349Sqs148142 DDI_SERVICE_DEGRADED},
1386349Sqs148142 {HXGE_FM_EREPORT_TDMC_PKT_CPL_TO, "txdma_pkt_cpl_to",
1396349Sqs148142 DDI_FM_DEVICE_NO_RESPONSE,
1406349Sqs148142 DDI_SERVICE_DEGRADED},
1416349Sqs148142 {HXGE_FM_EREPORT_TDMC_INVALID_SOP, "txdma_invalid_sop",
1426349Sqs148142 DDI_FM_DEVICE_INVAL_STATE,
1436349Sqs148142 DDI_SERVICE_DEGRADED},
1446349Sqs148142 {HXGE_FM_EREPORT_TDMC_UNEXPECTED_SOP, "txdma_unexpected_sop",
1456349Sqs148142 DDI_FM_DEVICE_INVAL_STATE,
1466349Sqs148142 DDI_SERVICE_DEGRADED},
1476349Sqs148142 {HXGE_FM_EREPORT_TDMC_REORD_TBL_PAR, "txdma_reord_tbl_par_err",
1486349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
1496349Sqs148142 DDI_SERVICE_DEGRADED},
1506349Sqs148142 {HXGE_FM_EREPORT_TDMC_REORD_BUF_DED, "txdma_reord_buf_ded_err",
1516349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
1526349Sqs148142 DDI_SERVICE_DEGRADED}
1536349Sqs148142 };
1546349Sqs148142
1556349Sqs148142 hxge_fm_ereport_attr_t hxge_fm_ereport_peu[] = {
1566349Sqs148142 {HXGE_FM_EREPORT_PEU_ERR, "peu_peu_err",
1576349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
1586349Sqs148142 DDI_SERVICE_LOST},
1596349Sqs148142 {HXGE_FM_EREPORT_PEU_VNM_PIO_ERR, "peu_vnm_pio_err",
1606349Sqs148142 DDI_FM_DEVICE_INTERN_UNCORR,
1616349Sqs148142 DDI_SERVICE_LOST}
1626349Sqs148142 };
1636349Sqs148142
1646349Sqs148142 hxge_fm_ereport_attr_t hxge_fm_ereport_sw[] = {
1656349Sqs148142 {HXGE_FM_EREPORT_SW_INVALID_CHAN_NUM, "invalid_chan_num",
1666349Sqs148142 DDI_FM_DEVICE_INVAL_STATE,
1676349Sqs148142 DDI_SERVICE_LOST},
1686349Sqs148142 {HXGE_FM_EREPORT_SW_INVALID_PARAM, "invalid_param",
1696349Sqs148142 DDI_FM_DEVICE_INVAL_STATE,
1706349Sqs148142 DDI_SERVICE_LOST}
1716349Sqs148142 };
1726349Sqs148142
1736349Sqs148142 void
hxge_fm_init(p_hxge_t hxgep,ddi_device_acc_attr_t * reg_attr,ddi_device_acc_attr_t * desc_attr,ddi_dma_attr_t * dma_attr)1746349Sqs148142 hxge_fm_init(p_hxge_t hxgep, ddi_device_acc_attr_t *reg_attr,
175*11257SMichael.Speer@Sun.COM ddi_device_acc_attr_t *desc_attr, ddi_dma_attr_t *dma_attr)
1766349Sqs148142 {
1776349Sqs148142 ddi_iblock_cookie_t iblk;
1786349Sqs148142
1796349Sqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_fm_init"));
1806349Sqs148142
1816349Sqs148142 /* fm-capable in hxge.conf can be used to set fm_capabilities. */
1826349Sqs148142 hxgep->fm_capabilities = ddi_prop_get_int(DDI_DEV_T_ANY, hxgep->dip,
1836349Sqs148142 DDI_PROP_DONTPASS, "fm-capable",
1846349Sqs148142 DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE);
1856349Sqs148142
1866349Sqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL,
1876349Sqs148142 "FM capable = %d\n", hxgep->fm_capabilities));
1886349Sqs148142
1896349Sqs148142 /*
1906349Sqs148142 * Register capabilities with IO Fault Services. The capabilities
1916349Sqs148142 * set above may not be supported by the parent nexus, in that case
1926349Sqs148142 * some capability bits may be cleared.
1936349Sqs148142 */
1946349Sqs148142 if (hxgep->fm_capabilities)
1956349Sqs148142 ddi_fm_init(hxgep->dip, &hxgep->fm_capabilities, &iblk);
1966349Sqs148142
1976349Sqs148142 /*
1986349Sqs148142 * Initialize pci ereport capabilities if ereport capable
1996349Sqs148142 */
2006349Sqs148142 if (DDI_FM_EREPORT_CAP(hxgep->fm_capabilities) ||
2016349Sqs148142 DDI_FM_ERRCB_CAP(hxgep->fm_capabilities)) {
2026349Sqs148142 pci_ereport_setup(hxgep->dip);
2036349Sqs148142 }
2046349Sqs148142
2056349Sqs148142 /* Register error callback if error callback capable */
2066349Sqs148142 if (DDI_FM_ERRCB_CAP(hxgep->fm_capabilities)) {
2076349Sqs148142 ddi_fm_handler_register(hxgep->dip,
2086349Sqs148142 hxge_fm_error_cb, (void *) hxgep);
2096349Sqs148142 }
2106349Sqs148142
2116349Sqs148142 /*
2126349Sqs148142 * DDI_FLGERR_ACC indicates:
2136349Sqs148142 * o Driver will check its access handle(s) for faults on
2146349Sqs148142 * a regular basis by calling ddi_fm_acc_err_get
2156349Sqs148142 * o Driver is able to cope with incorrect results of I/O
2166349Sqs148142 * operations resulted from an I/O fault
2176349Sqs148142 */
2186349Sqs148142 if (DDI_FM_ACC_ERR_CAP(hxgep->fm_capabilities)) {
2196349Sqs148142 reg_attr->devacc_attr_access = DDI_FLAGERR_ACC;
220*11257SMichael.Speer@Sun.COM desc_attr->devacc_attr_access = DDI_FLAGERR_ACC;
2216349Sqs148142 } else {
2226349Sqs148142 reg_attr->devacc_attr_access = DDI_DEFAULT_ACC;
223*11257SMichael.Speer@Sun.COM desc_attr->devacc_attr_access = DDI_DEFAULT_ACC;
2246349Sqs148142 }
2256349Sqs148142
2266349Sqs148142 /*
2276349Sqs148142 * DDI_DMA_FLAGERR indicates:
2286349Sqs148142 * o Driver will check its DMA handle(s) for faults on a
2296349Sqs148142 * regular basis using ddi_fm_dma_err_get
2306349Sqs148142 * o Driver is able to cope with incorrect results of DMA
2316349Sqs148142 * operations resulted from an I/O fault
2326349Sqs148142 */
2336349Sqs148142 if (DDI_FM_DMA_ERR_CAP(hxgep->fm_capabilities))
2346349Sqs148142 dma_attr->dma_attr_flags |= DDI_DMA_FLAGERR;
2356349Sqs148142 else
2366349Sqs148142 dma_attr->dma_attr_flags &= ~DDI_DMA_FLAGERR;
2376349Sqs148142
2386349Sqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_fm_init"));
2396349Sqs148142 }
2406349Sqs148142
2416349Sqs148142 void
hxge_fm_fini(p_hxge_t hxgep)2426349Sqs148142 hxge_fm_fini(p_hxge_t hxgep)
2436349Sqs148142 {
2446349Sqs148142 /* Only unregister FMA capabilities if we registered some */
2456349Sqs148142 if (hxgep->fm_capabilities) {
2466349Sqs148142 /*
2476349Sqs148142 * Release any resources allocated by pci_ereport_setup()
2486349Sqs148142 */
2496349Sqs148142 if (DDI_FM_EREPORT_CAP(hxgep->fm_capabilities) ||
2506349Sqs148142 DDI_FM_ERRCB_CAP(hxgep->fm_capabilities))
2516349Sqs148142 pci_ereport_teardown(hxgep->dip);
2526349Sqs148142
2536349Sqs148142 /*
2546349Sqs148142 * Un-register error callback if error callback capable
2556349Sqs148142 */
2566349Sqs148142 if (DDI_FM_ERRCB_CAP(hxgep->fm_capabilities))
2576349Sqs148142 ddi_fm_handler_unregister(hxgep->dip);
2586349Sqs148142
2596349Sqs148142 /* Unregister from IO Fault Services */
2606349Sqs148142 ddi_fm_fini(hxgep->dip);
2616349Sqs148142 }
2626349Sqs148142 }
2636349Sqs148142
2646349Sqs148142
2656349Sqs148142 /*
2666349Sqs148142 * Simply call pci_ereport_post which generates ereports for errors
2676349Sqs148142 * that occur in the PCI local bus configuration status registers.
2686349Sqs148142 */
2696349Sqs148142 /*ARGSUSED*/
2706349Sqs148142 static int
hxge_fm_error_cb(dev_info_t * dip,ddi_fm_error_t * err,const void * impl_data)2716349Sqs148142 hxge_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err,
2726349Sqs148142 const void *impl_data)
2736349Sqs148142 {
2746349Sqs148142 pci_ereport_post(dip, err, NULL);
2756349Sqs148142 return (err->fme_status);
2766349Sqs148142 }
2776349Sqs148142
2786349Sqs148142
2796349Sqs148142 static hxge_fm_ereport_attr_t *
hxge_fm_get_ereport_attr(hxge_fm_ereport_id_t ereport_id)2806349Sqs148142 hxge_fm_get_ereport_attr(hxge_fm_ereport_id_t ereport_id)
2816349Sqs148142 {
2826349Sqs148142 hxge_fm_ereport_attr_t *attr;
2836349Sqs148142 uint8_t blk_id;
2846349Sqs148142 uint8_t index;
2856349Sqs148142
2866349Sqs148142 /* Extract the block id and the index within the block */
2876349Sqs148142 blk_id = ((ereport_id >> EREPORT_FM_ID_SHIFT) & EREPORT_FM_ID_MASK);
2886349Sqs148142 index = (ereport_id & EREPORT_INDEX_MASK);
2896349Sqs148142
2906349Sqs148142 /* Return the appropriate structure of type hxge_fm_ereport_attr_t */
2916349Sqs148142 switch (blk_id) {
2926349Sqs148142 case FM_SW_ID:
2936349Sqs148142 attr = &hxge_fm_ereport_sw[index];
2946349Sqs148142 break;
2956349Sqs148142 case FM_VMAC_ID:
2966349Sqs148142 attr = &hxge_fm_ereport_vmac[index];
2976349Sqs148142 break;
2986349Sqs148142 case FM_PFC_ID:
2996349Sqs148142 attr = &hxge_fm_ereport_pfc[index];
3006349Sqs148142 break;
3016349Sqs148142 case FM_RXDMA_ID:
3026349Sqs148142 attr = &hxge_fm_ereport_rdmc[index];
3036349Sqs148142 break;
3046349Sqs148142 case FM_TXDMA_ID:
3056349Sqs148142 attr = &hxge_fm_ereport_tdmc[index];
3066349Sqs148142 break;
3076349Sqs148142 case FM_PEU_ID:
3086349Sqs148142 attr = &hxge_fm_ereport_peu[index];
3096349Sqs148142 break;
3106349Sqs148142 default:
3116349Sqs148142 attr = NULL;
3126349Sqs148142 }
3136349Sqs148142
3146349Sqs148142 return (attr);
3156349Sqs148142 }
3166349Sqs148142
3176349Sqs148142 static void
hxge_fm_ereport(p_hxge_t hxgep,uint8_t err_chan,hxge_fm_ereport_attr_t * ereport)3186349Sqs148142 hxge_fm_ereport(p_hxge_t hxgep, uint8_t err_chan,
3196349Sqs148142 hxge_fm_ereport_attr_t *ereport)
3206349Sqs148142 {
3216349Sqs148142 uint64_t ena;
3226349Sqs148142 char eclass[FM_MAX_CLASS];
3236349Sqs148142 char *err_str;
3246349Sqs148142 p_hxge_stats_t statsp;
3256349Sqs148142
3266349Sqs148142 (void) snprintf(eclass, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE,
3276349Sqs148142 ereport->eclass);
3286349Sqs148142
3296349Sqs148142 err_str = ereport->str;
3306349Sqs148142 ena = fm_ena_generate(0, FM_ENA_FMT1);
3316349Sqs148142 statsp = hxgep->statsp;
3326349Sqs148142
3336349Sqs148142 switch (ereport->index) {
3346349Sqs148142 case HXGE_FM_EREPORT_VMAC_LINK_DOWN:
3356349Sqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP,
3366349Sqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
3376349Sqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
3386349Sqs148142 NULL);
3396349Sqs148142 break;
3406349Sqs148142 case HXGE_FM_EREPORT_PFC_TCAM_PAR_ERR:
3416349Sqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP,
3426349Sqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
3436349Sqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
3446349Sqs148142 ERNAME_PFC_TCAM_ERR, DATA_TYPE_UINT32,
3456349Sqs148142 statsp->pfc_stats.tcam_parity_err,
3466349Sqs148142 NULL);
3476349Sqs148142 break;
3486349Sqs148142 case HXGE_FM_EREPORT_PFC_VLAN_PAR_ERR:
3496349Sqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP,
3506349Sqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
3516349Sqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
3526349Sqs148142 ERNAME_PFC_VLAN_ERR, DATA_TYPE_UINT32,
3536349Sqs148142 statsp->pfc_stats.vlan_parity_err,
3546349Sqs148142 NULL);
3556349Sqs148142 break;
3566349Sqs148142 case HXGE_FM_EREPORT_PFC_PKT_DROP:
3576349Sqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP,
3586349Sqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
3596349Sqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
3606349Sqs148142 ERNAME_PFC_PKT_DROP, DATA_TYPE_UINT32,
3616349Sqs148142 statsp->pfc_stats.pkt_drop,
3626349Sqs148142 NULL);
3636349Sqs148142 break;
3646349Sqs148142 case HXGE_FM_EREPORT_RDMC_RBR_CPL_TO:
3656349Sqs148142 case HXGE_FM_EREPORT_RDMC_PEU_RESP_ERR:
3666349Sqs148142 case HXGE_FM_EREPORT_RDMC_RCRFULL:
3676349Sqs148142 case HXGE_FM_EREPORT_RDMC_RBR_EMPTY:
3686349Sqs148142 case HXGE_FM_EREPORT_RDMC_RBRFULL:
3696349Sqs148142 case HXGE_FM_EREPORT_RDMC_RBR_PRE_EMPTY:
3706349Sqs148142 case HXGE_FM_EREPORT_RDMC_RCR_SHA_FULL:
3716349Sqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP,
3726349Sqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
3736349Sqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
3746349Sqs148142 ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
3756349Sqs148142 NULL);
3766349Sqs148142 break;
3776349Sqs148142 case HXGE_FM_EREPORT_RDMC_RBR_PRE_PAR:
3786349Sqs148142 case HXGE_FM_EREPORT_RDMC_RCR_SHA_PAR: {
3796349Sqs148142 uint32_t err_log;
3806349Sqs148142 hxge_rx_ring_stats_t *rdc_statsp;
3816349Sqs148142
3826349Sqs148142 rdc_statsp = &statsp->rdc_stats[err_chan];
3836349Sqs148142 if (ereport->index == HXGE_FM_EREPORT_RDMC_RBR_PRE_PAR)
3846349Sqs148142 err_log = (uint32_t)
3856349Sqs148142 rdc_statsp->errlog.pre_par.value;
3866349Sqs148142 else
3876349Sqs148142 err_log = (uint32_t)
3886349Sqs148142 rdc_statsp->errlog.sha_par.value;
3896349Sqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP,
3906349Sqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
3916349Sqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
3926349Sqs148142 ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
3936349Sqs148142 ERNAME_RDMC_PAR_ERR_LOG, DATA_TYPE_UINT8, err_log,
3946349Sqs148142 NULL);
3956349Sqs148142 }
3966349Sqs148142 break;
3976349Sqs148142 case HXGE_FM_EREPORT_RDMC_RCR_ERR: {
3986349Sqs148142 uint8_t err_type;
3996349Sqs148142 err_type = statsp->rdc_stats[err_chan].errlog.compl_err_type;
4006349Sqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP,
4016349Sqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
4026349Sqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
4036349Sqs148142 ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
4046349Sqs148142 ERNAME_RDC_ERR_TYPE, DATA_TYPE_UINT8, err_type,
4056349Sqs148142 NULL);
4066349Sqs148142 }
4076349Sqs148142 break;
4086349Sqs148142 case HXGE_FM_EREPORT_RDMC_CTRL_FIFO_SEC:
4096349Sqs148142 case HXGE_FM_EREPORT_RDMC_CTRL_FIFO_DED:
4106349Sqs148142 case HXGE_FM_EREPORT_RDMC_DATA_FIFO_SEC:
4116349Sqs148142 case HXGE_FM_EREPORT_RDMC_DATA_FIFO_DED:
4126349Sqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP,
4136349Sqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
4146349Sqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
4156349Sqs148142 NULL);
4166349Sqs148142 break;
4176349Sqs148142
4186349Sqs148142 case HXGE_FM_EREPORT_TDMC_PEU_RESP_ERR:
4196349Sqs148142 case HXGE_FM_EREPORT_TDMC_TX_RNG_OFLOW:
4206349Sqs148142 case HXGE_FM_EREPORT_TDMC_PKT_SIZE_HDR_ERR:
4216349Sqs148142 case HXGE_FM_EREPORT_TDMC_RUNT_PKT_DROP_ERR:
4226349Sqs148142 case HXGE_FM_EREPORT_TDMC_PKT_SIZE_ERR:
4236349Sqs148142 case HXGE_FM_EREPORT_TDMC_TDR_PREF_CPL_TO:
4246349Sqs148142 case HXGE_FM_EREPORT_TDMC_PKT_CPL_TO:
4256349Sqs148142 case HXGE_FM_EREPORT_TDMC_INVALID_SOP:
4266349Sqs148142 case HXGE_FM_EREPORT_TDMC_UNEXPECTED_SOP:
4276349Sqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP,
4286349Sqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
4296349Sqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
4306349Sqs148142 ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
4316349Sqs148142 NULL);
4326349Sqs148142 break;
4336349Sqs148142
4346349Sqs148142 case HXGE_FM_EREPORT_TDMC_PREF_PAR_ERR:
4356349Sqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP,
4366349Sqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
4376349Sqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
4386349Sqs148142 ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan,
4396349Sqs148142 ERNAME_TDC_PREF_PAR_LOG, DATA_TYPE_UINT32,
4406349Sqs148142 statsp->tdc_stats[err_chan].errlog.value, NULL);
4416349Sqs148142 break;
4426349Sqs148142 case HXGE_FM_EREPORT_TDMC_REORD_TBL_PAR:
4436349Sqs148142 case HXGE_FM_EREPORT_TDMC_REORD_BUF_DED:
4446349Sqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP,
4456349Sqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
4466349Sqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
4476349Sqs148142 NULL);
4486349Sqs148142 break;
4496349Sqs148142
4506349Sqs148142 case HXGE_FM_EREPORT_PEU_ERR:
4516349Sqs148142 case HXGE_FM_EREPORT_PEU_VNM_PIO_ERR:
4526349Sqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP,
4536349Sqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
4546349Sqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
4556349Sqs148142 NULL);
4566349Sqs148142 break;
4576349Sqs148142
4586349Sqs148142 case HXGE_FM_EREPORT_SW_INVALID_CHAN_NUM:
4596349Sqs148142 case HXGE_FM_EREPORT_SW_INVALID_PARAM:
4606349Sqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP,
4616349Sqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
4626349Sqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str,
4636349Sqs148142 NULL);
4646349Sqs148142 break;
4656349Sqs148142 }
4666349Sqs148142 }
4676349Sqs148142
4686349Sqs148142 void
hxge_fm_report_error(p_hxge_t hxgep,uint8_t err_chan,hxge_fm_ereport_id_t fm_ereport_id)4696349Sqs148142 hxge_fm_report_error(p_hxge_t hxgep, uint8_t err_chan,
4706349Sqs148142 hxge_fm_ereport_id_t fm_ereport_id)
4716349Sqs148142 {
4726349Sqs148142 hxge_fm_ereport_attr_t *fm_ereport_attr;
4736349Sqs148142
4746349Sqs148142 fm_ereport_attr = hxge_fm_get_ereport_attr(fm_ereport_id);
4756349Sqs148142
4766349Sqs148142 if (fm_ereport_attr != NULL &&
4776349Sqs148142 (DDI_FM_EREPORT_CAP(hxgep->fm_capabilities))) {
4786349Sqs148142 hxge_fm_ereport(hxgep, err_chan, fm_ereport_attr);
4796349Sqs148142 ddi_fm_service_impact(hxgep->dip, fm_ereport_attr->impact);
4806349Sqs148142 }
4816349Sqs148142 }
4826349Sqs148142
4836349Sqs148142 int
fm_check_acc_handle(ddi_acc_handle_t handle)4846349Sqs148142 fm_check_acc_handle(ddi_acc_handle_t handle)
4856349Sqs148142 {
4866349Sqs148142 ddi_fm_error_t err;
4876349Sqs148142
4886349Sqs148142 ddi_fm_acc_err_get(handle, &err, DDI_FME_VERSION);
4896349Sqs148142 ddi_fm_acc_err_clear(handle, DDI_FME_VERSION);
4906349Sqs148142
4916349Sqs148142 return (err.fme_status);
4926349Sqs148142 }
4936349Sqs148142
4946349Sqs148142 int
fm_check_dma_handle(ddi_dma_handle_t handle)4956349Sqs148142 fm_check_dma_handle(ddi_dma_handle_t handle)
4966349Sqs148142 {
4976349Sqs148142 ddi_fm_error_t err;
4986349Sqs148142
4996349Sqs148142 ddi_fm_dma_err_get(handle, &err, DDI_FME_VERSION);
5006349Sqs148142 return (err.fme_status);
5016349Sqs148142 }
502