13dec9fcdSqs148142 /* 23dec9fcdSqs148142 * CDDL HEADER START 33dec9fcdSqs148142 * 43dec9fcdSqs148142 * The contents of this file are subject to the terms of the 53dec9fcdSqs148142 * Common Development and Distribution License (the "License"). 63dec9fcdSqs148142 * You may not use this file except in compliance with the License. 73dec9fcdSqs148142 * 83dec9fcdSqs148142 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93dec9fcdSqs148142 * or http://www.opensolaris.org/os/licensing. 103dec9fcdSqs148142 * See the License for the specific language governing permissions 113dec9fcdSqs148142 * and limitations under the License. 123dec9fcdSqs148142 * 133dec9fcdSqs148142 * When distributing Covered Code, include this CDDL HEADER in each 143dec9fcdSqs148142 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153dec9fcdSqs148142 * If applicable, add the following below this CDDL HEADER, with the 163dec9fcdSqs148142 * fields enclosed by brackets "[]" replaced with your own identifying 173dec9fcdSqs148142 * information: Portions Copyright [yyyy] [name of copyright owner] 183dec9fcdSqs148142 * 193dec9fcdSqs148142 * CDDL HEADER END 203dec9fcdSqs148142 */ 21*f043ebedSMichael Speer 223dec9fcdSqs148142 /* 23837c1ac4SStephen Hanson * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 243dec9fcdSqs148142 * Use is subject to license terms. 253dec9fcdSqs148142 */ 263dec9fcdSqs148142 273dec9fcdSqs148142 #include <hxge_impl.h> 283dec9fcdSqs148142 #include <sys/ddifm.h> 293dec9fcdSqs148142 #include <sys/fm/protocol.h> 303dec9fcdSqs148142 #include <sys/fm/util.h> 313dec9fcdSqs148142 #include <sys/fm/io/ddi.h> 323dec9fcdSqs148142 333dec9fcdSqs148142 static hxge_fm_ereport_attr_t 343dec9fcdSqs148142 *hxge_fm_get_ereport_attr(hxge_fm_ereport_id_t ereport_id); 353dec9fcdSqs148142 363dec9fcdSqs148142 static int 373dec9fcdSqs148142 hxge_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data); 383dec9fcdSqs148142 393dec9fcdSqs148142 hxge_fm_ereport_attr_t hxge_fm_ereport_vmac[] = { 403dec9fcdSqs148142 {HXGE_FM_EREPORT_VMAC_LINK_DOWN, "10g_link_down", 413dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 423dec9fcdSqs148142 DDI_SERVICE_LOST} 433dec9fcdSqs148142 }; 443dec9fcdSqs148142 453dec9fcdSqs148142 hxge_fm_ereport_attr_t hxge_fm_ereport_pfc[] = { 463dec9fcdSqs148142 /* 473dec9fcdSqs148142 * The following are part of LDF 0, non-fatal 483dec9fcdSqs148142 */ 493dec9fcdSqs148142 {HXGE_FM_EREPORT_PFC_TCAM_PAR_ERR, "classifier_tcam_par_err", 503dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 513dec9fcdSqs148142 DDI_SERVICE_UNAFFECTED}, 523dec9fcdSqs148142 {HXGE_FM_EREPORT_PFC_VLAN_PAR_ERR, "classifier_vlan_par_err", 533dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 543dec9fcdSqs148142 DDI_SERVICE_UNAFFECTED}, 553dec9fcdSqs148142 {HXGE_FM_EREPORT_PFC_PKT_DROP, "classifier_pkt_drop_err", 563dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 573dec9fcdSqs148142 DDI_SERVICE_UNAFFECTED} 583dec9fcdSqs148142 }; 593dec9fcdSqs148142 603dec9fcdSqs148142 hxge_fm_ereport_attr_t hxge_fm_ereport_rdmc[] = { 613dec9fcdSqs148142 /* 623dec9fcdSqs148142 * The following are part of LDF1, fatal 633dec9fcdSqs148142 */ 643dec9fcdSqs148142 {HXGE_FM_EREPORT_RDMC_RBR_CPL_TO, "rxdma_rbr_cpl_to", 653dec9fcdSqs148142 DDI_FM_DEVICE_NO_RESPONSE, 663dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 673dec9fcdSqs148142 {HXGE_FM_EREPORT_RDMC_PEU_RESP_ERR, "rxdma_peu_resp_err", 683dec9fcdSqs148142 DDI_FM_DEVICE_INVAL_STATE, 693dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 703dec9fcdSqs148142 {HXGE_FM_EREPORT_RDMC_RCR_SHA_PAR, "rxdma_rcr_sha_par_err", 713dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 723dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 733dec9fcdSqs148142 {HXGE_FM_EREPORT_RDMC_RBR_PRE_PAR, "rxdma_rbr_pre_par_err", 743dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 753dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 763dec9fcdSqs148142 {HXGE_FM_EREPORT_RDMC_RBR_PRE_EMPTY, "rxdma_rbr_pre_empty_err", 773dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 783dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 793dec9fcdSqs148142 {HXGE_FM_EREPORT_RDMC_RCR_SHA_FULL, "rxdma_rcr_sha_full", 803dec9fcdSqs148142 DDI_FM_DEVICE_INVAL_STATE, 813dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 823dec9fcdSqs148142 {HXGE_FM_EREPORT_RDMC_RCRFULL, "rxdma_rcr_full", 833dec9fcdSqs148142 DDI_FM_DEVICE_INVAL_STATE, 843dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 853dec9fcdSqs148142 {HXGE_FM_EREPORT_RDMC_RBR_EMPTY, "rxdma_rbr_empty", 863dec9fcdSqs148142 DDI_FM_DEVICE_INVAL_STATE, 873dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 883dec9fcdSqs148142 {HXGE_FM_EREPORT_RDMC_RBRFULL, "rxdma_rbr_full", 893dec9fcdSqs148142 DDI_FM_DEVICE_INVAL_STATE, 903dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 913dec9fcdSqs148142 {HXGE_FM_EREPORT_RDMC_RCR_ERR, "rxdma_completion_err", 923dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 933dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 943dec9fcdSqs148142 /* 953dec9fcdSqs148142 * Control/Data ram received a ecc double bit error. 963dec9fcdSqs148142 * Fatal error. Part of Device Error 1 973dec9fcdSqs148142 */ 983dec9fcdSqs148142 {HXGE_FM_EREPORT_RDMC_CTRL_FIFO_DED, "rxdma_ctrl_fifo_ded", 993dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 1003dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 1013dec9fcdSqs148142 {HXGE_FM_EREPORT_RDMC_DATA_FIFO_DED, "rxdma_data_fifo_ded", 1023dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 1033dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 1043dec9fcdSqs148142 /* 1053dec9fcdSqs148142 * Control/Data ram received a ecc single bit error. 1063dec9fcdSqs148142 * Non-Fatal error. Part of Device Error 0 1073dec9fcdSqs148142 */ 1083dec9fcdSqs148142 {HXGE_FM_EREPORT_RDMC_CTRL_FIFO_SEC, "rxdma_ctrl_fifo_sec", 1093dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_CORR, 1103dec9fcdSqs148142 DDI_SERVICE_UNAFFECTED}, 1113dec9fcdSqs148142 {HXGE_FM_EREPORT_RDMC_DATA_FIFO_SEC, "rxdma_data_fifo_sec", 1123dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_CORR, 1133dec9fcdSqs148142 DDI_SERVICE_UNAFFECTED} 1143dec9fcdSqs148142 }; 1153dec9fcdSqs148142 1163dec9fcdSqs148142 hxge_fm_ereport_attr_t hxge_fm_ereport_tdmc[] = { 1173dec9fcdSqs148142 {HXGE_FM_EREPORT_TDMC_PEU_RESP_ERR, "txdma_peu_resp_err", 1183dec9fcdSqs148142 DDI_FM_DEVICE_INVAL_STATE, 1193dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 1203dec9fcdSqs148142 {HXGE_FM_EREPORT_TDMC_PKT_SIZE_HDR_ERR, "txdma_pkt_size_hdr_err", 1213dec9fcdSqs148142 DDI_FM_DEVICE_INVAL_STATE, 1223dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 1233dec9fcdSqs148142 {HXGE_FM_EREPORT_TDMC_RUNT_PKT_DROP_ERR, "txdma_runt_pkt_drop_err", 1243dec9fcdSqs148142 DDI_FM_DEVICE_INVAL_STATE, 1253dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 1263dec9fcdSqs148142 {HXGE_FM_EREPORT_TDMC_PKT_SIZE_ERR, "txdma_pkt_size_err", 1273dec9fcdSqs148142 DDI_FM_DEVICE_INVAL_STATE, 1283dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 1293dec9fcdSqs148142 {HXGE_FM_EREPORT_TDMC_TX_RNG_OFLOW, "txdma_tx_rng_oflow", 1303dec9fcdSqs148142 DDI_FM_DEVICE_INVAL_STATE, 1313dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 1323dec9fcdSqs148142 {HXGE_FM_EREPORT_TDMC_PREF_PAR_ERR, "txdma_pref_par_err", 1333dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 1343dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 1353dec9fcdSqs148142 {HXGE_FM_EREPORT_TDMC_TDR_PREF_CPL_TO, "txdma_tdr_pref_cpl_to", 1363dec9fcdSqs148142 DDI_FM_DEVICE_NO_RESPONSE, 1373dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 1383dec9fcdSqs148142 {HXGE_FM_EREPORT_TDMC_PKT_CPL_TO, "txdma_pkt_cpl_to", 1393dec9fcdSqs148142 DDI_FM_DEVICE_NO_RESPONSE, 1403dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 1413dec9fcdSqs148142 {HXGE_FM_EREPORT_TDMC_INVALID_SOP, "txdma_invalid_sop", 1423dec9fcdSqs148142 DDI_FM_DEVICE_INVAL_STATE, 1433dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 1443dec9fcdSqs148142 {HXGE_FM_EREPORT_TDMC_UNEXPECTED_SOP, "txdma_unexpected_sop", 1453dec9fcdSqs148142 DDI_FM_DEVICE_INVAL_STATE, 1463dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 1473dec9fcdSqs148142 {HXGE_FM_EREPORT_TDMC_REORD_TBL_PAR, "txdma_reord_tbl_par_err", 1483dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 1493dec9fcdSqs148142 DDI_SERVICE_DEGRADED}, 1503dec9fcdSqs148142 {HXGE_FM_EREPORT_TDMC_REORD_BUF_DED, "txdma_reord_buf_ded_err", 1513dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 1523dec9fcdSqs148142 DDI_SERVICE_DEGRADED} 1533dec9fcdSqs148142 }; 1543dec9fcdSqs148142 1553dec9fcdSqs148142 hxge_fm_ereport_attr_t hxge_fm_ereport_peu[] = { 1563dec9fcdSqs148142 {HXGE_FM_EREPORT_PEU_ERR, "peu_peu_err", 1573dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 1583dec9fcdSqs148142 DDI_SERVICE_LOST}, 1593dec9fcdSqs148142 {HXGE_FM_EREPORT_PEU_VNM_PIO_ERR, "peu_vnm_pio_err", 1603dec9fcdSqs148142 DDI_FM_DEVICE_INTERN_UNCORR, 1613dec9fcdSqs148142 DDI_SERVICE_LOST} 1623dec9fcdSqs148142 }; 1633dec9fcdSqs148142 1643dec9fcdSqs148142 hxge_fm_ereport_attr_t hxge_fm_ereport_sw[] = { 1653dec9fcdSqs148142 {HXGE_FM_EREPORT_SW_INVALID_CHAN_NUM, "invalid_chan_num", 1663dec9fcdSqs148142 DDI_FM_DEVICE_INVAL_STATE, 1673dec9fcdSqs148142 DDI_SERVICE_LOST}, 1683dec9fcdSqs148142 {HXGE_FM_EREPORT_SW_INVALID_PARAM, "invalid_param", 1693dec9fcdSqs148142 DDI_FM_DEVICE_INVAL_STATE, 1703dec9fcdSqs148142 DDI_SERVICE_LOST} 1713dec9fcdSqs148142 }; 1723dec9fcdSqs148142 1733dec9fcdSqs148142 void 1743dec9fcdSqs148142 hxge_fm_init(p_hxge_t hxgep, ddi_device_acc_attr_t *reg_attr, 175*f043ebedSMichael Speer ddi_device_acc_attr_t *desc_attr, ddi_dma_attr_t *dma_attr) 1763dec9fcdSqs148142 { 1773dec9fcdSqs148142 ddi_iblock_cookie_t iblk; 1783dec9fcdSqs148142 1793dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_fm_init")); 1803dec9fcdSqs148142 1813dec9fcdSqs148142 /* fm-capable in hxge.conf can be used to set fm_capabilities. */ 1823dec9fcdSqs148142 hxgep->fm_capabilities = ddi_prop_get_int(DDI_DEV_T_ANY, hxgep->dip, 1833dec9fcdSqs148142 DDI_PROP_DONTPASS, "fm-capable", 1843dec9fcdSqs148142 DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE); 1853dec9fcdSqs148142 1863dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, 1873dec9fcdSqs148142 "FM capable = %d\n", hxgep->fm_capabilities)); 1883dec9fcdSqs148142 1893dec9fcdSqs148142 /* 1903dec9fcdSqs148142 * Register capabilities with IO Fault Services. The capabilities 1913dec9fcdSqs148142 * set above may not be supported by the parent nexus, in that case 1923dec9fcdSqs148142 * some capability bits may be cleared. 1933dec9fcdSqs148142 */ 1943dec9fcdSqs148142 if (hxgep->fm_capabilities) 1953dec9fcdSqs148142 ddi_fm_init(hxgep->dip, &hxgep->fm_capabilities, &iblk); 1963dec9fcdSqs148142 1973dec9fcdSqs148142 /* 1983dec9fcdSqs148142 * Initialize pci ereport capabilities if ereport capable 1993dec9fcdSqs148142 */ 2003dec9fcdSqs148142 if (DDI_FM_EREPORT_CAP(hxgep->fm_capabilities) || 2013dec9fcdSqs148142 DDI_FM_ERRCB_CAP(hxgep->fm_capabilities)) { 2023dec9fcdSqs148142 pci_ereport_setup(hxgep->dip); 2033dec9fcdSqs148142 } 2043dec9fcdSqs148142 2053dec9fcdSqs148142 /* Register error callback if error callback capable */ 2063dec9fcdSqs148142 if (DDI_FM_ERRCB_CAP(hxgep->fm_capabilities)) { 2073dec9fcdSqs148142 ddi_fm_handler_register(hxgep->dip, 2083dec9fcdSqs148142 hxge_fm_error_cb, (void *) hxgep); 2093dec9fcdSqs148142 } 2103dec9fcdSqs148142 2113dec9fcdSqs148142 /* 2123dec9fcdSqs148142 * DDI_FLGERR_ACC indicates: 2133dec9fcdSqs148142 * o Driver will check its access handle(s) for faults on 2143dec9fcdSqs148142 * a regular basis by calling ddi_fm_acc_err_get 2153dec9fcdSqs148142 * o Driver is able to cope with incorrect results of I/O 2163dec9fcdSqs148142 * operations resulted from an I/O fault 2173dec9fcdSqs148142 */ 2183dec9fcdSqs148142 if (DDI_FM_ACC_ERR_CAP(hxgep->fm_capabilities)) { 2193dec9fcdSqs148142 reg_attr->devacc_attr_access = DDI_FLAGERR_ACC; 220*f043ebedSMichael Speer desc_attr->devacc_attr_access = DDI_FLAGERR_ACC; 2213dec9fcdSqs148142 } else { 2223dec9fcdSqs148142 reg_attr->devacc_attr_access = DDI_DEFAULT_ACC; 223*f043ebedSMichael Speer desc_attr->devacc_attr_access = DDI_DEFAULT_ACC; 2243dec9fcdSqs148142 } 2253dec9fcdSqs148142 2263dec9fcdSqs148142 /* 2273dec9fcdSqs148142 * DDI_DMA_FLAGERR indicates: 2283dec9fcdSqs148142 * o Driver will check its DMA handle(s) for faults on a 2293dec9fcdSqs148142 * regular basis using ddi_fm_dma_err_get 2303dec9fcdSqs148142 * o Driver is able to cope with incorrect results of DMA 2313dec9fcdSqs148142 * operations resulted from an I/O fault 2323dec9fcdSqs148142 */ 2333dec9fcdSqs148142 if (DDI_FM_DMA_ERR_CAP(hxgep->fm_capabilities)) 2343dec9fcdSqs148142 dma_attr->dma_attr_flags |= DDI_DMA_FLAGERR; 2353dec9fcdSqs148142 else 2363dec9fcdSqs148142 dma_attr->dma_attr_flags &= ~DDI_DMA_FLAGERR; 2373dec9fcdSqs148142 2383dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_fm_init")); 2393dec9fcdSqs148142 } 2403dec9fcdSqs148142 2413dec9fcdSqs148142 void 2423dec9fcdSqs148142 hxge_fm_fini(p_hxge_t hxgep) 2433dec9fcdSqs148142 { 2443dec9fcdSqs148142 /* Only unregister FMA capabilities if we registered some */ 2453dec9fcdSqs148142 if (hxgep->fm_capabilities) { 2463dec9fcdSqs148142 /* 2473dec9fcdSqs148142 * Release any resources allocated by pci_ereport_setup() 2483dec9fcdSqs148142 */ 2493dec9fcdSqs148142 if (DDI_FM_EREPORT_CAP(hxgep->fm_capabilities) || 2503dec9fcdSqs148142 DDI_FM_ERRCB_CAP(hxgep->fm_capabilities)) 2513dec9fcdSqs148142 pci_ereport_teardown(hxgep->dip); 2523dec9fcdSqs148142 2533dec9fcdSqs148142 /* 2543dec9fcdSqs148142 * Un-register error callback if error callback capable 2553dec9fcdSqs148142 */ 2563dec9fcdSqs148142 if (DDI_FM_ERRCB_CAP(hxgep->fm_capabilities)) 2573dec9fcdSqs148142 ddi_fm_handler_unregister(hxgep->dip); 2583dec9fcdSqs148142 2593dec9fcdSqs148142 /* Unregister from IO Fault Services */ 2603dec9fcdSqs148142 ddi_fm_fini(hxgep->dip); 2613dec9fcdSqs148142 } 2623dec9fcdSqs148142 } 2633dec9fcdSqs148142 2643dec9fcdSqs148142 2653dec9fcdSqs148142 /* 2663dec9fcdSqs148142 * Simply call pci_ereport_post which generates ereports for errors 2673dec9fcdSqs148142 * that occur in the PCI local bus configuration status registers. 2683dec9fcdSqs148142 */ 2693dec9fcdSqs148142 /*ARGSUSED*/ 2703dec9fcdSqs148142 static int 2713dec9fcdSqs148142 hxge_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, 2723dec9fcdSqs148142 const void *impl_data) 2733dec9fcdSqs148142 { 2743dec9fcdSqs148142 pci_ereport_post(dip, err, NULL); 2753dec9fcdSqs148142 return (err->fme_status); 2763dec9fcdSqs148142 } 2773dec9fcdSqs148142 2783dec9fcdSqs148142 2793dec9fcdSqs148142 static hxge_fm_ereport_attr_t * 2803dec9fcdSqs148142 hxge_fm_get_ereport_attr(hxge_fm_ereport_id_t ereport_id) 2813dec9fcdSqs148142 { 2823dec9fcdSqs148142 hxge_fm_ereport_attr_t *attr; 2833dec9fcdSqs148142 uint8_t blk_id; 2843dec9fcdSqs148142 uint8_t index; 2853dec9fcdSqs148142 2863dec9fcdSqs148142 /* Extract the block id and the index within the block */ 2873dec9fcdSqs148142 blk_id = ((ereport_id >> EREPORT_FM_ID_SHIFT) & EREPORT_FM_ID_MASK); 2883dec9fcdSqs148142 index = (ereport_id & EREPORT_INDEX_MASK); 2893dec9fcdSqs148142 2903dec9fcdSqs148142 /* Return the appropriate structure of type hxge_fm_ereport_attr_t */ 2913dec9fcdSqs148142 switch (blk_id) { 2923dec9fcdSqs148142 case FM_SW_ID: 2933dec9fcdSqs148142 attr = &hxge_fm_ereport_sw[index]; 2943dec9fcdSqs148142 break; 2953dec9fcdSqs148142 case FM_VMAC_ID: 2963dec9fcdSqs148142 attr = &hxge_fm_ereport_vmac[index]; 2973dec9fcdSqs148142 break; 2983dec9fcdSqs148142 case FM_PFC_ID: 2993dec9fcdSqs148142 attr = &hxge_fm_ereport_pfc[index]; 3003dec9fcdSqs148142 break; 3013dec9fcdSqs148142 case FM_RXDMA_ID: 3023dec9fcdSqs148142 attr = &hxge_fm_ereport_rdmc[index]; 3033dec9fcdSqs148142 break; 3043dec9fcdSqs148142 case FM_TXDMA_ID: 3053dec9fcdSqs148142 attr = &hxge_fm_ereport_tdmc[index]; 3063dec9fcdSqs148142 break; 3073dec9fcdSqs148142 case FM_PEU_ID: 3083dec9fcdSqs148142 attr = &hxge_fm_ereport_peu[index]; 3093dec9fcdSqs148142 break; 3103dec9fcdSqs148142 default: 3113dec9fcdSqs148142 attr = NULL; 3123dec9fcdSqs148142 } 3133dec9fcdSqs148142 3143dec9fcdSqs148142 return (attr); 3153dec9fcdSqs148142 } 3163dec9fcdSqs148142 3173dec9fcdSqs148142 static void 3183dec9fcdSqs148142 hxge_fm_ereport(p_hxge_t hxgep, uint8_t err_chan, 3193dec9fcdSqs148142 hxge_fm_ereport_attr_t *ereport) 3203dec9fcdSqs148142 { 3213dec9fcdSqs148142 uint64_t ena; 3223dec9fcdSqs148142 char eclass[FM_MAX_CLASS]; 3233dec9fcdSqs148142 char *err_str; 3243dec9fcdSqs148142 p_hxge_stats_t statsp; 3253dec9fcdSqs148142 3263dec9fcdSqs148142 (void) snprintf(eclass, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, 3273dec9fcdSqs148142 ereport->eclass); 3283dec9fcdSqs148142 3293dec9fcdSqs148142 err_str = ereport->str; 3303dec9fcdSqs148142 ena = fm_ena_generate(0, FM_ENA_FMT1); 3313dec9fcdSqs148142 statsp = hxgep->statsp; 3323dec9fcdSqs148142 3333dec9fcdSqs148142 switch (ereport->index) { 3343dec9fcdSqs148142 case HXGE_FM_EREPORT_VMAC_LINK_DOWN: 3353dec9fcdSqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP, 3363dec9fcdSqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, 3373dec9fcdSqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str, 3383dec9fcdSqs148142 NULL); 3393dec9fcdSqs148142 break; 3403dec9fcdSqs148142 case HXGE_FM_EREPORT_PFC_TCAM_PAR_ERR: 3413dec9fcdSqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP, 3423dec9fcdSqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, 3433dec9fcdSqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str, 3443dec9fcdSqs148142 ERNAME_PFC_TCAM_ERR, DATA_TYPE_UINT32, 3453dec9fcdSqs148142 statsp->pfc_stats.tcam_parity_err, 3463dec9fcdSqs148142 NULL); 3473dec9fcdSqs148142 break; 3483dec9fcdSqs148142 case HXGE_FM_EREPORT_PFC_VLAN_PAR_ERR: 3493dec9fcdSqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP, 3503dec9fcdSqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, 3513dec9fcdSqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str, 3523dec9fcdSqs148142 ERNAME_PFC_VLAN_ERR, DATA_TYPE_UINT32, 3533dec9fcdSqs148142 statsp->pfc_stats.vlan_parity_err, 3543dec9fcdSqs148142 NULL); 3553dec9fcdSqs148142 break; 3563dec9fcdSqs148142 case HXGE_FM_EREPORT_PFC_PKT_DROP: 3573dec9fcdSqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP, 3583dec9fcdSqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, 3593dec9fcdSqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str, 3603dec9fcdSqs148142 ERNAME_PFC_PKT_DROP, DATA_TYPE_UINT32, 3613dec9fcdSqs148142 statsp->pfc_stats.pkt_drop, 3623dec9fcdSqs148142 NULL); 3633dec9fcdSqs148142 break; 3643dec9fcdSqs148142 case HXGE_FM_EREPORT_RDMC_RBR_CPL_TO: 3653dec9fcdSqs148142 case HXGE_FM_EREPORT_RDMC_PEU_RESP_ERR: 3663dec9fcdSqs148142 case HXGE_FM_EREPORT_RDMC_RCRFULL: 3673dec9fcdSqs148142 case HXGE_FM_EREPORT_RDMC_RBR_EMPTY: 3683dec9fcdSqs148142 case HXGE_FM_EREPORT_RDMC_RBRFULL: 3693dec9fcdSqs148142 case HXGE_FM_EREPORT_RDMC_RBR_PRE_EMPTY: 3703dec9fcdSqs148142 case HXGE_FM_EREPORT_RDMC_RCR_SHA_FULL: 3713dec9fcdSqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP, 3723dec9fcdSqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, 3733dec9fcdSqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str, 3743dec9fcdSqs148142 ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan, 3753dec9fcdSqs148142 NULL); 3763dec9fcdSqs148142 break; 3773dec9fcdSqs148142 case HXGE_FM_EREPORT_RDMC_RBR_PRE_PAR: 3783dec9fcdSqs148142 case HXGE_FM_EREPORT_RDMC_RCR_SHA_PAR: { 3793dec9fcdSqs148142 uint32_t err_log; 3803dec9fcdSqs148142 hxge_rx_ring_stats_t *rdc_statsp; 3813dec9fcdSqs148142 3823dec9fcdSqs148142 rdc_statsp = &statsp->rdc_stats[err_chan]; 3833dec9fcdSqs148142 if (ereport->index == HXGE_FM_EREPORT_RDMC_RBR_PRE_PAR) 3843dec9fcdSqs148142 err_log = (uint32_t) 3853dec9fcdSqs148142 rdc_statsp->errlog.pre_par.value; 3863dec9fcdSqs148142 else 3873dec9fcdSqs148142 err_log = (uint32_t) 3883dec9fcdSqs148142 rdc_statsp->errlog.sha_par.value; 3893dec9fcdSqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP, 3903dec9fcdSqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, 3913dec9fcdSqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str, 3923dec9fcdSqs148142 ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan, 3933dec9fcdSqs148142 ERNAME_RDMC_PAR_ERR_LOG, DATA_TYPE_UINT8, err_log, 3943dec9fcdSqs148142 NULL); 3953dec9fcdSqs148142 } 3963dec9fcdSqs148142 break; 3973dec9fcdSqs148142 case HXGE_FM_EREPORT_RDMC_RCR_ERR: { 3983dec9fcdSqs148142 uint8_t err_type; 3993dec9fcdSqs148142 err_type = statsp->rdc_stats[err_chan].errlog.compl_err_type; 4003dec9fcdSqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP, 4013dec9fcdSqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, 4023dec9fcdSqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str, 4033dec9fcdSqs148142 ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan, 4043dec9fcdSqs148142 ERNAME_RDC_ERR_TYPE, DATA_TYPE_UINT8, err_type, 4053dec9fcdSqs148142 NULL); 4063dec9fcdSqs148142 } 4073dec9fcdSqs148142 break; 4083dec9fcdSqs148142 case HXGE_FM_EREPORT_RDMC_CTRL_FIFO_SEC: 4093dec9fcdSqs148142 case HXGE_FM_EREPORT_RDMC_CTRL_FIFO_DED: 4103dec9fcdSqs148142 case HXGE_FM_EREPORT_RDMC_DATA_FIFO_SEC: 4113dec9fcdSqs148142 case HXGE_FM_EREPORT_RDMC_DATA_FIFO_DED: 4123dec9fcdSqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP, 4133dec9fcdSqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, 4143dec9fcdSqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str, 4153dec9fcdSqs148142 NULL); 4163dec9fcdSqs148142 break; 4173dec9fcdSqs148142 4183dec9fcdSqs148142 case HXGE_FM_EREPORT_TDMC_PEU_RESP_ERR: 4193dec9fcdSqs148142 case HXGE_FM_EREPORT_TDMC_TX_RNG_OFLOW: 4203dec9fcdSqs148142 case HXGE_FM_EREPORT_TDMC_PKT_SIZE_HDR_ERR: 4213dec9fcdSqs148142 case HXGE_FM_EREPORT_TDMC_RUNT_PKT_DROP_ERR: 4223dec9fcdSqs148142 case HXGE_FM_EREPORT_TDMC_PKT_SIZE_ERR: 4233dec9fcdSqs148142 case HXGE_FM_EREPORT_TDMC_TDR_PREF_CPL_TO: 4243dec9fcdSqs148142 case HXGE_FM_EREPORT_TDMC_PKT_CPL_TO: 4253dec9fcdSqs148142 case HXGE_FM_EREPORT_TDMC_INVALID_SOP: 4263dec9fcdSqs148142 case HXGE_FM_EREPORT_TDMC_UNEXPECTED_SOP: 4273dec9fcdSqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP, 4283dec9fcdSqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, 4293dec9fcdSqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str, 4303dec9fcdSqs148142 ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan, 4313dec9fcdSqs148142 NULL); 4323dec9fcdSqs148142 break; 4333dec9fcdSqs148142 4343dec9fcdSqs148142 case HXGE_FM_EREPORT_TDMC_PREF_PAR_ERR: 4353dec9fcdSqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP, 4363dec9fcdSqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, 4373dec9fcdSqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str, 4383dec9fcdSqs148142 ERNAME_ERR_DCHAN, DATA_TYPE_UINT8, err_chan, 4393dec9fcdSqs148142 ERNAME_TDC_PREF_PAR_LOG, DATA_TYPE_UINT32, 4403dec9fcdSqs148142 statsp->tdc_stats[err_chan].errlog.value, NULL); 4413dec9fcdSqs148142 break; 4423dec9fcdSqs148142 case HXGE_FM_EREPORT_TDMC_REORD_TBL_PAR: 4433dec9fcdSqs148142 case HXGE_FM_EREPORT_TDMC_REORD_BUF_DED: 4443dec9fcdSqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP, 4453dec9fcdSqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, 4463dec9fcdSqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str, 4473dec9fcdSqs148142 NULL); 4483dec9fcdSqs148142 break; 4493dec9fcdSqs148142 4503dec9fcdSqs148142 case HXGE_FM_EREPORT_PEU_ERR: 4513dec9fcdSqs148142 case HXGE_FM_EREPORT_PEU_VNM_PIO_ERR: 4523dec9fcdSqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP, 4533dec9fcdSqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, 4543dec9fcdSqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str, 4553dec9fcdSqs148142 NULL); 4563dec9fcdSqs148142 break; 4573dec9fcdSqs148142 4583dec9fcdSqs148142 case HXGE_FM_EREPORT_SW_INVALID_CHAN_NUM: 4593dec9fcdSqs148142 case HXGE_FM_EREPORT_SW_INVALID_PARAM: 4603dec9fcdSqs148142 ddi_fm_ereport_post(hxgep->dip, eclass, ena, DDI_NOSLEEP, 4613dec9fcdSqs148142 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, 4623dec9fcdSqs148142 ERNAME_DETAILED_ERR_TYPE, DATA_TYPE_STRING, err_str, 4633dec9fcdSqs148142 NULL); 4643dec9fcdSqs148142 break; 4653dec9fcdSqs148142 } 4663dec9fcdSqs148142 } 4673dec9fcdSqs148142 4683dec9fcdSqs148142 void 4693dec9fcdSqs148142 hxge_fm_report_error(p_hxge_t hxgep, uint8_t err_chan, 4703dec9fcdSqs148142 hxge_fm_ereport_id_t fm_ereport_id) 4713dec9fcdSqs148142 { 4723dec9fcdSqs148142 hxge_fm_ereport_attr_t *fm_ereport_attr; 4733dec9fcdSqs148142 4743dec9fcdSqs148142 fm_ereport_attr = hxge_fm_get_ereport_attr(fm_ereport_id); 4753dec9fcdSqs148142 4763dec9fcdSqs148142 if (fm_ereport_attr != NULL && 4773dec9fcdSqs148142 (DDI_FM_EREPORT_CAP(hxgep->fm_capabilities))) { 4783dec9fcdSqs148142 hxge_fm_ereport(hxgep, err_chan, fm_ereport_attr); 4793dec9fcdSqs148142 ddi_fm_service_impact(hxgep->dip, fm_ereport_attr->impact); 4803dec9fcdSqs148142 } 4813dec9fcdSqs148142 } 4823dec9fcdSqs148142 4833dec9fcdSqs148142 int 4843dec9fcdSqs148142 fm_check_acc_handle(ddi_acc_handle_t handle) 4853dec9fcdSqs148142 { 4863dec9fcdSqs148142 ddi_fm_error_t err; 4873dec9fcdSqs148142 4883dec9fcdSqs148142 ddi_fm_acc_err_get(handle, &err, DDI_FME_VERSION); 4893dec9fcdSqs148142 ddi_fm_acc_err_clear(handle, DDI_FME_VERSION); 4903dec9fcdSqs148142 4913dec9fcdSqs148142 return (err.fme_status); 4923dec9fcdSqs148142 } 4933dec9fcdSqs148142 4943dec9fcdSqs148142 int 4953dec9fcdSqs148142 fm_check_dma_handle(ddi_dma_handle_t handle) 4963dec9fcdSqs148142 { 4973dec9fcdSqs148142 ddi_fm_error_t err; 4983dec9fcdSqs148142 4993dec9fcdSqs148142 ddi_fm_dma_err_get(handle, &err, DDI_FME_VERSION); 5003dec9fcdSqs148142 return (err.fme_status); 5013dec9fcdSqs148142 } 502