127Sjchu /* 227Sjchu * CDDL HEADER START 327Sjchu * 427Sjchu * The contents of this file are subject to the terms of the 527Sjchu * Common Development and Distribution License, Version 1.0 only 627Sjchu * (the "License"). You may not use this file except in compliance 727Sjchu * with the License. 827Sjchu * 927Sjchu * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 1027Sjchu * or http://www.opensolaris.org/os/licensing. 1127Sjchu * See the License for the specific language governing permissions 1227Sjchu * and limitations under the License. 1327Sjchu * 1427Sjchu * When distributing Covered Code, include this CDDL HEADER in each 1527Sjchu * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1627Sjchu * If applicable, add the following below this CDDL HEADER, with the 1727Sjchu * fields enclosed by brackets "[]" replaced with your own identifying 1827Sjchu * information: Portions Copyright [yyyy] [name of copyright owner] 1927Sjchu * 2027Sjchu * CDDL HEADER END 2127Sjchu */ 2227Sjchu /* 2327Sjchu * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 2427Sjchu * Use is subject to license terms. 2527Sjchu */ 2627Sjchu 2727Sjchu #pragma ident "%Z%%M% %I% %E% SMI" 2827Sjchu 2927Sjchu /* 3027Sjchu * sun4u Fire Error Handling 3127Sjchu */ 3227Sjchu 3327Sjchu #include <sys/types.h> 3427Sjchu #include <sys/ddi.h> 3527Sjchu #include <sys/sunddi.h> 3627Sjchu #include <sys/fm/protocol.h> 3727Sjchu #include <sys/fm/util.h> 3827Sjchu #include <sys/pcie.h> 3927Sjchu #include <sys/pcie_impl.h> 4027Sjchu #include "px_obj.h" 4127Sjchu #include <px_regs.h> 4227Sjchu #include <px_csr.h> 4327Sjchu #include <sys/membar.h> 44118Sjchu #include "pcie_pwr.h" 4527Sjchu #include "px_lib4u.h" 4627Sjchu #include "px_err.h" 4727Sjchu #include "px_err_impl.h" 4827Sjchu 4927Sjchu /* 5027Sjchu * JBC error bit table 5127Sjchu */ 5227Sjchu #define JBC_BIT_DESC(bit, hdl, erpt) \ 5327Sjchu JBC_INTERRUPT_STATUS_ ## bit ## _P, \ 5427Sjchu 0, \ 5527Sjchu PX_ERR_BIT_HANDLE(hdl), \ 5627Sjchu PX_ERPT_SEND(erpt), \ 5727Sjchu PX_ERR_JBC_CLASS(bit) 5827Sjchu px_err_bit_desc_t px_err_cb_tbl[] = { 5927Sjchu /* JBC FATAL - see io erpt doc, section 1.1 */ 6027Sjchu { JBC_BIT_DESC(MB_PEA, fatal_hw, jbc_fatal) }, 6127Sjchu { JBC_BIT_DESC(CPE, fatal_hw, jbc_fatal) }, 6227Sjchu { JBC_BIT_DESC(APE, fatal_hw, jbc_fatal) }, 6327Sjchu { JBC_BIT_DESC(PIO_CPE, fatal_hw, jbc_fatal) }, 6427Sjchu { JBC_BIT_DESC(JTCEEW, fatal_hw, jbc_fatal) }, 6527Sjchu { JBC_BIT_DESC(JTCEEI, fatal_hw, jbc_fatal) }, 6627Sjchu { JBC_BIT_DESC(JTCEER, fatal_hw, jbc_fatal) }, 6727Sjchu 6827Sjchu /* JBC MERGE - see io erpt doc, section 1.2 */ 6927Sjchu { JBC_BIT_DESC(MB_PER, jbc_merge, jbc_merge) }, 7027Sjchu { JBC_BIT_DESC(MB_PEW, jbc_merge, jbc_merge) }, 7127Sjchu 7227Sjchu /* JBC Jbusint IN - see io erpt doc, section 1.3 */ 7327Sjchu { JBC_BIT_DESC(UE_ASYN, fatal_gos, jbc_in) }, 7427Sjchu { JBC_BIT_DESC(CE_ASYN, jbc_jbusint_in, jbc_in) }, 7527Sjchu { JBC_BIT_DESC(JTE, fatal_gos, jbc_in) }, 7627Sjchu { JBC_BIT_DESC(JBE, jbc_jbusint_in, jbc_in) }, 7727Sjchu { JBC_BIT_DESC(JUE, jbc_jbusint_in, jbc_in) }, 7827Sjchu { JBC_BIT_DESC(ICISE, fatal_gos, jbc_in) }, 7927Sjchu { JBC_BIT_DESC(WR_DPE, jbc_jbusint_in, jbc_in) }, 8027Sjchu { JBC_BIT_DESC(RD_DPE, jbc_jbusint_in, jbc_in) }, 8127Sjchu { JBC_BIT_DESC(ILL_BMW, jbc_jbusint_in, jbc_in) }, 8227Sjchu { JBC_BIT_DESC(ILL_BMR, jbc_jbusint_in, jbc_in) }, 8327Sjchu { JBC_BIT_DESC(BJC, jbc_jbusint_in, jbc_in) }, 8427Sjchu 8527Sjchu /* JBC Jbusint Out - see io erpt doc, section 1.4 */ 8627Sjchu { JBC_BIT_DESC(IJP, fatal_gos, jbc_out) }, 8727Sjchu 8827Sjchu /* JBC Dmcint ODCD - see io erpt doc, section 1.5 */ 8927Sjchu { JBC_BIT_DESC(PIO_UNMAP_RD, jbc_dmcint_odcd, jbc_odcd) }, 9027Sjchu { JBC_BIT_DESC(ILL_ACC_RD, jbc_dmcint_odcd, jbc_odcd) }, 9127Sjchu { JBC_BIT_DESC(PIO_UNMAP, jbc_dmcint_odcd, jbc_odcd) }, 9227Sjchu { JBC_BIT_DESC(PIO_DPE, jbc_dmcint_odcd, jbc_odcd) }, 9327Sjchu { JBC_BIT_DESC(PIO_CPE, non_fatal, jbc_odcd) }, 9427Sjchu { JBC_BIT_DESC(ILL_ACC, jbc_dmcint_odcd, jbc_odcd) }, 9527Sjchu 9627Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */ 9727Sjchu { JBC_BIT_DESC(UNSOL_RD, non_fatal, jbc_idc) }, 9827Sjchu { JBC_BIT_DESC(UNSOL_INTR, non_fatal, jbc_idc) }, 9927Sjchu 10027Sjchu /* JBC CSR - see io erpt doc, section 1.7 */ 10127Sjchu { JBC_BIT_DESC(EBUS_TO, jbc_csr, jbc_csr) } 10227Sjchu }; 10327Sjchu 10427Sjchu #define px_err_cb_keys \ 10527Sjchu (sizeof (px_err_cb_tbl)) / (sizeof (px_err_bit_desc_t)) 10627Sjchu 10727Sjchu /* 10827Sjchu * DMC error bit tables 10927Sjchu */ 11027Sjchu #define IMU_BIT_DESC(bit, hdl, erpt) \ 11127Sjchu IMU_INTERRUPT_STATUS_ ## bit ## _P, \ 11227Sjchu 0, \ 11327Sjchu PX_ERR_BIT_HANDLE(hdl), \ 11427Sjchu PX_ERPT_SEND(erpt), \ 11527Sjchu PX_ERR_DMC_CLASS(bit) 11627Sjchu px_err_bit_desc_t px_err_imu_tbl[] = { 11727Sjchu /* DMC IMU RDS - see io erpt doc, section 2.1 */ 11827Sjchu { IMU_BIT_DESC(MSI_MAL_ERR, non_fatal, imu_rds) }, 11927Sjchu { IMU_BIT_DESC(MSI_PAR_ERR, fatal_stuck, imu_rds) }, 12027Sjchu { IMU_BIT_DESC(PMEACK_MES_NOT_EN, imu_rbne, imu_rds) }, 121118Sjchu { IMU_BIT_DESC(PMPME_MES_NOT_EN, imu_pme, imu_rds) }, 12227Sjchu { IMU_BIT_DESC(FATAL_MES_NOT_EN, imu_rbne, imu_rds) }, 12327Sjchu { IMU_BIT_DESC(NONFATAL_MES_NOT_EN, imu_rbne, imu_rds) }, 12427Sjchu { IMU_BIT_DESC(COR_MES_NOT_EN, imu_rbne, imu_rds) }, 12527Sjchu { IMU_BIT_DESC(MSI_NOT_EN, imu_rbne, imu_rds) }, 12627Sjchu 12727Sjchu /* DMC IMU SCS - see io erpt doc, section 2.2 */ 12827Sjchu { IMU_BIT_DESC(EQ_NOT_EN, imu_rbne, imu_rds) }, 12927Sjchu 13027Sjchu /* DMC IMU - see io erpt doc, section 2.3 */ 13127Sjchu { IMU_BIT_DESC(EQ_OVER, imu_eq_ovfl, imu) } 13227Sjchu }; 13327Sjchu 13427Sjchu #define px_err_imu_keys (sizeof (px_err_imu_tbl)) / (sizeof (px_err_bit_desc_t)) 13527Sjchu 13627Sjchu /* mmu errors */ 13727Sjchu #define MMU_BIT_DESC(bit, hdl, erpt) \ 13827Sjchu MMU_INTERRUPT_STATUS_ ## bit ## _P, \ 13927Sjchu 0, \ 14027Sjchu PX_ERR_BIT_HANDLE(hdl), \ 14127Sjchu PX_ERPT_SEND(erpt), \ 14227Sjchu PX_ERR_DMC_CLASS(bit) 14327Sjchu px_err_bit_desc_t px_err_mmu_tbl[] = { 14427Sjchu /* DMC MMU TFAR/TFSR - see io erpt doc, section 2.4 */ 14527Sjchu { MMU_BIT_DESC(BYP_ERR, mmu_rbne, mmu_tfar_tfsr) }, 14627Sjchu { MMU_BIT_DESC(BYP_OOR, mmu_tfa, mmu_tfar_tfsr) }, 14727Sjchu { MMU_BIT_DESC(TRN_ERR, mmu_rbne, mmu_tfar_tfsr) }, 14827Sjchu { MMU_BIT_DESC(TRN_OOR, mmu_tfa, mmu_tfar_tfsr) }, 14927Sjchu { MMU_BIT_DESC(TTE_INV, mmu_tfa, mmu_tfar_tfsr) }, 15027Sjchu { MMU_BIT_DESC(TTE_PRT, mmu_tfa, mmu_tfar_tfsr) }, 15127Sjchu { MMU_BIT_DESC(TTC_DPE, mmu_tfa, mmu_tfar_tfsr) }, 15227Sjchu { MMU_BIT_DESC(TBW_DME, mmu_tblwlk, mmu_tfar_tfsr) }, 15327Sjchu { MMU_BIT_DESC(TBW_UDE, mmu_tblwlk, mmu_tfar_tfsr) }, 15427Sjchu { MMU_BIT_DESC(TBW_ERR, mmu_tblwlk, mmu_tfar_tfsr) }, 15527Sjchu { MMU_BIT_DESC(TBW_DPE, mmu_tblwlk, mmu_tfar_tfsr) }, 15627Sjchu 15727Sjchu /* DMC MMU - see io erpt doc, section 2.5 */ 15827Sjchu { MMU_BIT_DESC(TTC_CAE, non_fatal, mmu) } 15927Sjchu }; 16027Sjchu #define px_err_mmu_keys (sizeof (px_err_mmu_tbl)) / (sizeof (px_err_bit_desc_t)) 16127Sjchu 16227Sjchu /* 16327Sjchu * PEC error bit tables 16427Sjchu */ 16527Sjchu #define ILU_BIT_DESC(bit, hdl, erpt) \ 16627Sjchu ILU_INTERRUPT_STATUS_ ## bit ## _P, \ 16727Sjchu 0, \ 16827Sjchu PX_ERR_BIT_HANDLE(hdl), \ 16927Sjchu PX_ERPT_SEND(erpt), \ 17027Sjchu PX_ERR_PEC_CLASS(bit) 17127Sjchu px_err_bit_desc_t px_err_ilu_tbl[] = { 17227Sjchu /* PEC ILU none - see io erpt doc, section 3.1 */ 17327Sjchu { ILU_BIT_DESC(IHB_PE, fatal_gos, pec_ilu) } 17427Sjchu }; 17527Sjchu #define px_err_ilu_keys \ 17627Sjchu (sizeof (px_err_ilu_tbl)) / (sizeof (px_err_bit_desc_t)) 17727Sjchu 17827Sjchu /* 17927Sjchu * PEC UE errors implementation is incomplete pending PCIE generic 18027Sjchu * fabric rules. 18127Sjchu */ 18227Sjchu /* pec ue errors */ 18327Sjchu #define TLU_UC_BIT_DESC(bit, hdl, erpt) \ 18427Sjchu TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \ 18527Sjchu 0, \ 18627Sjchu NULL, \ 18727Sjchu NULL, \ 18827Sjchu "" 18927Sjchu px_err_bit_desc_t px_err_tlu_ue_tbl[] = { 19027Sjchu /* PCI-E Receive Uncorrectable Errors - see io erpt doc, section 3.2 */ 19127Sjchu { TLU_UC_BIT_DESC(UR, NULL, NULL) }, 19227Sjchu { TLU_UC_BIT_DESC(ROF, NULL, NULL) }, 19327Sjchu { TLU_UC_BIT_DESC(UC, NULL, NULL) }, 19427Sjchu 19527Sjchu /* PCI-E Transmit Uncorrectable Errors - see io erpt doc, section 3.3 */ 19627Sjchu { TLU_UC_BIT_DESC(CTO, NULL, NULL) }, 19727Sjchu 19827Sjchu /* PCI-E Rx/Tx Uncorrectable Errors - see io erpt doc, section 3.4 */ 19927Sjchu { TLU_UC_BIT_DESC(MFP, NULL, NULL) }, 20027Sjchu { TLU_UC_BIT_DESC(PP, NULL, NULL) }, 20127Sjchu 20227Sjchu /* Other PCI-E Uncorrectable Errors - see io erpt doc, section 3.5 */ 20327Sjchu { TLU_UC_BIT_DESC(FCP, NULL, NULL) }, 20427Sjchu { TLU_UC_BIT_DESC(DLP, NULL, NULL) }, 20527Sjchu { TLU_UC_BIT_DESC(TE, NULL, NULL) }, 20627Sjchu { TLU_UC_BIT_DESC(CA, NULL, NULL) } 20727Sjchu }; 20827Sjchu #define px_err_tlu_ue_keys \ 20927Sjchu (sizeof (px_err_tlu_ue_tbl)) / (sizeof (px_err_bit_desc_t)) 21027Sjchu 21127Sjchu /* 21227Sjchu * PEC CE errors implementation is incomplete pending PCIE generic 21327Sjchu * fabric rules. 21427Sjchu */ 21527Sjchu /* pec ce errors */ 21627Sjchu #define TLU_CE_BIT_DESC(bit, hdl, erpt) \ 21727Sjchu TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \ 21827Sjchu 0, \ 21927Sjchu NULL, \ 22027Sjchu NULL, \ 22127Sjchu "" 22227Sjchu px_err_bit_desc_t px_err_tlu_ce_tbl[] = { 22327Sjchu /* PCI-E Correctable Errors - see io erpt doc, section 3.6 */ 22427Sjchu { TLU_CE_BIT_DESC(RTO, NULL, NULL) }, 22527Sjchu { TLU_CE_BIT_DESC(RNR, NULL, NULL) }, 22627Sjchu { TLU_CE_BIT_DESC(BDP, NULL, NULL) }, 22727Sjchu { TLU_CE_BIT_DESC(BTP, NULL, NULL) }, 22827Sjchu { TLU_CE_BIT_DESC(RE, NULL, NULL) } 22927Sjchu }; 23027Sjchu #define px_err_tlu_ce_keys \ 23127Sjchu (sizeof (px_err_tlu_ce_tbl)) / (sizeof (px_err_bit_desc_t)) 23227Sjchu 23327Sjchu /* pec oe errors */ 23427Sjchu #define TLU_OE_BIT_DESC(bit, hdl, erpt) \ 23527Sjchu TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _P, \ 23627Sjchu 0, \ 23727Sjchu PX_ERR_BIT_HANDLE(hdl), \ 23827Sjchu PX_ERPT_SEND(erpt), \ 23927Sjchu PX_ERR_PEC_CLASS(bit) 24027Sjchu px_err_bit_desc_t px_err_tlu_oe_tbl[] = { 24127Sjchu /* 24227Sjchu * TLU Other Event Status (receive only) - see io erpt doc, section 3.7 24327Sjchu */ 24427Sjchu { TLU_OE_BIT_DESC(MRC, fatal_hw, pciex_rx_oe) }, 24527Sjchu 24627Sjchu /* TLU Other Event Status (rx + tx) - see io erpt doc, section 3.8 */ 24727Sjchu { TLU_OE_BIT_DESC(WUC, fatal_stuck, pciex_rx_tx_oe) }, 24827Sjchu { TLU_OE_BIT_DESC(RUC, fatal_stuck, pciex_rx_tx_oe) }, 24927Sjchu { TLU_OE_BIT_DESC(CRS, non_fatal, pciex_rx_tx_oe) }, 25027Sjchu 25127Sjchu /* TLU Other Event - see io erpt doc, section 3.9 */ 25227Sjchu { TLU_OE_BIT_DESC(IIP, fatal_gos, pciex_oe) }, 25327Sjchu { TLU_OE_BIT_DESC(EDP, fatal_gos, pciex_oe) }, 25427Sjchu { TLU_OE_BIT_DESC(EHP, fatal_gos, pciex_oe) }, 25527Sjchu { TLU_OE_BIT_DESC(LIN, non_fatal, pciex_oe) }, 25627Sjchu { TLU_OE_BIT_DESC(LRS, non_fatal, pciex_oe) }, 257*287Smg140465 { TLU_OE_BIT_DESC(LDN, non_fatal, pciex_ldn) }, 258*287Smg140465 { TLU_OE_BIT_DESC(LUP, tlu_lup, pciex_lup) }, 25927Sjchu { TLU_OE_BIT_DESC(ERU, fatal_gos, pciex_oe) }, 26027Sjchu { TLU_OE_BIT_DESC(ERO, fatal_gos, pciex_oe) }, 26127Sjchu { TLU_OE_BIT_DESC(EMP, fatal_gos, pciex_oe) }, 26227Sjchu { TLU_OE_BIT_DESC(EPE, fatal_gos, pciex_oe) }, 26327Sjchu { TLU_OE_BIT_DESC(ERP, fatal_gos, pciex_oe) }, 26427Sjchu { TLU_OE_BIT_DESC(EIP, fatal_gos, pciex_oe) } 26527Sjchu }; 26627Sjchu 26727Sjchu #define px_err_tlu_oe_keys \ 26827Sjchu (sizeof (px_err_tlu_oe_tbl)) / (sizeof (px_err_bit_desc_t)) 26927Sjchu 27027Sjchu /* 27127Sjchu * All the following tables below are for LPU Interrupts. These interrupts 27227Sjchu * are *NOT* error interrupts, but event status interrupts. 27327Sjchu * 27427Sjchu * These events are probably of most interest to: 27527Sjchu * o Hotplug 27627Sjchu * o Power Management 27727Sjchu * o etc... 27827Sjchu * 27927Sjchu * There are also a few events that would be interresting for FMA. 28027Sjchu * Again none of the regiseters below state that an error has occured 28127Sjchu * or that data has been lost. If anything, they give status that an 28227Sjchu * error is *about* to occur. examples 28327Sjchu * o INT_SKP_ERR - indicates clock between fire and child is too far 28427Sjchu * off and is most unlikely able to compensate 28527Sjchu * o INT_TX_PAR_ERR - A parity error occured in ONE lane. This is 28627Sjchu * HW recoverable, but will like end up as a future 28727Sjchu * fabric error as well. 28827Sjchu * 28927Sjchu * For now, we don't care about any of these errors and should be ignore, 29027Sjchu * but cleared. 29127Sjchu */ 29227Sjchu 29327Sjchu /* LPU Link Interrupt Table */ 29427Sjchu #define LPUL_BIT_DESC(bit, hdl, erpt) \ 29527Sjchu LPU_LINK_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \ 29627Sjchu 0, \ 29727Sjchu NULL, \ 29827Sjchu NULL, \ 29927Sjchu "" 30027Sjchu px_err_bit_desc_t px_err_lpul_tbl[] = { 30127Sjchu { LPUL_BIT_DESC(LINK_ERR_ACT, NULL, NULL) } 30227Sjchu }; 30327Sjchu #define px_err_lpul_keys \ 30427Sjchu (sizeof (px_err_lpul_tbl)) / (sizeof (px_err_bit_desc_t)) 30527Sjchu 30627Sjchu /* LPU Physical Interrupt Table */ 30727Sjchu #define LPUP_BIT_DESC(bit, hdl, erpt) \ 30827Sjchu LPU_PHY_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \ 30927Sjchu 0, \ 31027Sjchu NULL, \ 31127Sjchu NULL, \ 31227Sjchu "" 31327Sjchu px_err_bit_desc_t px_err_lpup_tbl[] = { 31427Sjchu { LPUP_BIT_DESC(PHY_LAYER_ERR, NULL, NULL) } 31527Sjchu }; 31627Sjchu #define px_err_lpup_keys \ 31727Sjchu (sizeof (px_err_lpup_tbl)) / (sizeof (px_err_bit_desc_t)) 31827Sjchu 31927Sjchu /* LPU Receive Interrupt Table */ 32027Sjchu #define LPUR_BIT_DESC(bit, hdl, erpt) \ 32127Sjchu LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \ 32227Sjchu 0, \ 32327Sjchu NULL, \ 32427Sjchu NULL, \ 32527Sjchu "" 32627Sjchu px_err_bit_desc_t px_err_lpur_tbl[] = { 32727Sjchu { LPUR_BIT_DESC(RCV_PHY, NULL, NULL) } 32827Sjchu }; 32927Sjchu #define px_err_lpur_keys \ 33027Sjchu (sizeof (px_err_lpur_tbl)) / (sizeof (px_err_bit_desc_t)) 33127Sjchu 33227Sjchu /* LPU Transmit Interrupt Table */ 33327Sjchu #define LPUX_BIT_DESC(bit, hdl, erpt) \ 33427Sjchu LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \ 33527Sjchu 0, \ 33627Sjchu NULL, \ 33727Sjchu NULL, \ 33827Sjchu "" 33927Sjchu px_err_bit_desc_t px_err_lpux_tbl[] = { 34027Sjchu { LPUX_BIT_DESC(UNMSK, NULL, NULL) } 34127Sjchu }; 34227Sjchu #define px_err_lpux_keys \ 34327Sjchu (sizeof (px_err_lpux_tbl)) / (sizeof (px_err_bit_desc_t)) 34427Sjchu 34527Sjchu /* LPU LTSSM Interrupt Table */ 34627Sjchu #define LPUS_BIT_DESC(bit, hdl, erpt) \ 34727Sjchu LPU_LTSSM_INTERRUPT_AND_STATUS_INT_ ## bit, \ 34827Sjchu 0, \ 34927Sjchu NULL, \ 35027Sjchu NULL, \ 35127Sjchu "" 35227Sjchu px_err_bit_desc_t px_err_lpus_tbl[] = { 35327Sjchu { LPUS_BIT_DESC(ANY, NULL, NULL) } 35427Sjchu }; 35527Sjchu #define px_err_lpus_keys \ 35627Sjchu (sizeof (px_err_lpus_tbl)) / (sizeof (px_err_bit_desc_t)) 35727Sjchu 35827Sjchu /* LPU Gigablaze Glue Interrupt Table */ 35927Sjchu #define LPUG_BIT_DESC(bit, hdl, erpt) \ 36027Sjchu LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_INT_ ## bit, \ 36127Sjchu 0, \ 36227Sjchu NULL, \ 36327Sjchu NULL, \ 36427Sjchu "" 36527Sjchu px_err_bit_desc_t px_err_lpug_tbl[] = { 36627Sjchu { LPUG_BIT_DESC(GLOBL_UNMSK, NULL, NULL) } 36727Sjchu }; 36827Sjchu #define px_err_lpug_keys \ 36927Sjchu (sizeof (px_err_lpug_tbl)) / (sizeof (px_err_bit_desc_t)) 37027Sjchu 37127Sjchu 37227Sjchu /* Mask and Tables */ 37327Sjchu #define MnT6(pre) \ 37427Sjchu B_FALSE, \ 37527Sjchu &px_ ## pre ## _intr_mask, \ 37627Sjchu &px_ ## pre ## _log_mask, \ 37727Sjchu &px_ ## pre ## _count_mask, \ 37827Sjchu px_err_ ## pre ## _tbl, \ 37927Sjchu px_err_ ## pre ## _keys, \ 38027Sjchu 0 38127Sjchu 38227Sjchu /* LPU Registers Addresses */ 38327Sjchu #define LR4(pre) \ 38427Sjchu NULL, \ 38527Sjchu LPU_ ## pre ## _INTERRUPT_MASK, \ 38627Sjchu LPU_ ## pre ## _INTERRUPT_AND_STATUS, \ 38727Sjchu LPU_ ## pre ## _INTERRUPT_AND_STATUS 38827Sjchu 38927Sjchu /* LPU Registers Addresses with Irregularities */ 39027Sjchu #define LR4_FIXME(pre) \ 39127Sjchu NULL, \ 39227Sjchu LPU_ ## pre ## _INTERRUPT_MASK, \ 39327Sjchu LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS, \ 39427Sjchu LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS 39527Sjchu 39627Sjchu /* TLU Registers Addresses */ 39727Sjchu #define TR4(pre) \ 39827Sjchu TLU_ ## pre ## _LOG_ENABLE, \ 39927Sjchu TLU_ ## pre ## _INTERRUPT_ENABLE, \ 40027Sjchu TLU_ ## pre ## _INTERRUPT_STATUS, \ 40127Sjchu TLU_ ## pre ## _STATUS_CLEAR 40227Sjchu 40327Sjchu /* Registers Addresses for JBC, MMU, IMU and ILU */ 40427Sjchu #define R4(pre) \ 40527Sjchu pre ## _ERROR_LOG_ENABLE, \ 40627Sjchu pre ## _INTERRUPT_ENABLE, \ 40727Sjchu pre ## _INTERRUPT_STATUS, \ 40827Sjchu pre ## _ERROR_STATUS_CLEAR 40927Sjchu 41027Sjchu /* 41127Sjchu * Register error handling tables. 41227Sjchu * The ID Field (first field) is identified by an enum px_err_id_t. 41327Sjchu * It is located in px_err.h 41427Sjchu */ 41527Sjchu px_err_reg_desc_t px_err_reg_tbl[] = { 41627Sjchu { MnT6(cb), R4(JBC), "JBC Error"}, 41727Sjchu { MnT6(mmu), R4(MMU), "IMU Error"}, 41827Sjchu { MnT6(imu), R4(IMU), "ILU Error"}, 41927Sjchu { MnT6(tlu_ue), TR4(UNCORRECTABLE_ERROR), "TLU UE"}, 42027Sjchu { MnT6(tlu_ce), TR4(CORRECTABLE_ERROR), "TLU CE"}, 42127Sjchu { MnT6(tlu_oe), TR4(OTHER_EVENT), "TLU OE"}, 42227Sjchu { MnT6(ilu), R4(ILU), "MMU Error"}, 42327Sjchu { MnT6(lpul), LR4(LINK_LAYER), "LPU Link Layer"}, 42427Sjchu { MnT6(lpup), LR4_FIXME(PHY), "LPU Phy Layer"}, 42527Sjchu { MnT6(lpur), LR4(RECEIVE_PHY), "LPU RX Phy Layer"}, 42627Sjchu { MnT6(lpux), LR4(TRANSMIT_PHY), "LPU TX Phy Layer"}, 42727Sjchu { MnT6(lpus), LR4(LTSSM), "LPU LTSSM"}, 42827Sjchu { MnT6(lpug), LR4(GIGABLAZE_GLUE), "LPU GigaBlaze Glue"} 42927Sjchu }; 43027Sjchu #define PX_ERR_REG_KEYS (sizeof (px_err_reg_tbl)) / (sizeof (px_err_reg_tbl[0])) 43127Sjchu 43227Sjchu typedef struct px_err_ss { 43327Sjchu uint64_t err_status[PX_ERR_REG_KEYS]; 43427Sjchu } px_err_ss_t; 43527Sjchu 43627Sjchu static void px_err_snapshot(px_t *px_p, px_err_ss_t *ss, boolean_t chkjbc); 43727Sjchu static int px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr, 43827Sjchu px_err_ss_t *ss); 43927Sjchu static int px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr, 44027Sjchu int err, int caller); 44127Sjchu 44227Sjchu /* 44327Sjchu * px_err_cb_intr: 44427Sjchu * Interrupt handler for the JBC block. 44527Sjchu * o lock 44627Sjchu * o create derr 44727Sjchu * o px_err_handle(leaf1, with jbc) 44827Sjchu * o px_err_handle(leaf2, without jbc) 44927Sjchu * o dispatch (leaf1) 45027Sjchu * o dispatch (leaf2) 45127Sjchu * o unlock 45227Sjchu * o handle error: fatal? fm_panic() : return INTR_CLAIMED) 45327Sjchu */ 45427Sjchu uint_t 45527Sjchu px_err_cb_intr(caddr_t arg) 45627Sjchu { 45727Sjchu px_fault_t *px_fault_p = (px_fault_t *)arg; 45827Sjchu dev_info_t *rpdip = px_fault_p->px_fh_dip; 45927Sjchu dev_info_t *leafdip; 46027Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 46127Sjchu px_cb_t *cb_p = px_p->px_cb_p; 462118Sjchu int err = PX_OK; 463118Sjchu int ret = DDI_FM_OK; 46427Sjchu int fatal = 0; 46527Sjchu int nonfatal = 0; 46627Sjchu int unknown = 0; 46727Sjchu int i; 46827Sjchu boolean_t chkjbc = B_TRUE; 46927Sjchu ddi_fm_error_t derr; 47027Sjchu 47127Sjchu /* Create the derr */ 47227Sjchu bzero(&derr, sizeof (ddi_fm_error_t)); 47327Sjchu derr.fme_version = DDI_FME_VERSION; 47427Sjchu derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1); 47527Sjchu derr.fme_flag = DDI_FM_ERR_UNEXPECTED; 47627Sjchu 47727Sjchu mutex_enter(&cb_p->xbc_fm_mutex); 47827Sjchu 47927Sjchu /* send ereport/handle/clear for ALL fire leaves */ 48027Sjchu for (i = 0; i < PX_CB_MAX_LEAF; i++) { 48127Sjchu if ((px_p = cb_p->xbc_px_list[i]) == NULL) 48227Sjchu continue; 48327Sjchu 48427Sjchu err |= px_err_handle(px_p, &derr, PX_INTR_CALL, chkjbc); 48527Sjchu chkjbc = B_FALSE; 48627Sjchu } 48727Sjchu 48827Sjchu /* Check all child devices for errors on ALL fire leaves */ 48927Sjchu for (i = 0; i < PX_CB_MAX_LEAF; i++) { 49027Sjchu if ((px_p = cb_p->xbc_px_list[i]) != NULL) { 49127Sjchu leafdip = px_p->px_dip; 49227Sjchu ret = ndi_fm_handler_dispatch(leafdip, NULL, &derr); 49327Sjchu switch (ret) { 49427Sjchu case DDI_FM_FATAL: 49527Sjchu fatal++; 49627Sjchu break; 49727Sjchu case DDI_FM_NONFATAL: 49827Sjchu nonfatal++; 49927Sjchu break; 50027Sjchu case DDI_FM_UNKNOWN: 50127Sjchu unknown++; 50227Sjchu break; 50327Sjchu default: 50427Sjchu break; 50527Sjchu } 50627Sjchu } 50727Sjchu } 50827Sjchu 50927Sjchu /* Set the intr state to idle for the leaf that received the mondo */ 51027Sjchu (void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino, 51127Sjchu INTR_IDLE_STATE); 51227Sjchu 51327Sjchu mutex_exit(&cb_p->xbc_fm_mutex); 51427Sjchu 51527Sjchu /* 51627Sjchu * PX_FATAL_HW error is diagnosed after system recovered from 51727Sjchu * HW initiated reset, therefore no furthur handling is required. 51827Sjchu */ 51927Sjchu if (fatal || err & (PX_FATAL_GOS | PX_FATAL_SW)) 52027Sjchu fm_panic("Fatal System Bus Error has occurred\n"); 52127Sjchu 52227Sjchu return (DDI_INTR_CLAIMED); 52327Sjchu } 52427Sjchu 52527Sjchu /* 52627Sjchu * px_err_dmc_pec_intr: 52727Sjchu * Interrupt handler for the DMC/PEC block. 52827Sjchu * o lock 52927Sjchu * o create derr 53027Sjchu * o px_err_handle(leaf, with jbc) 53127Sjchu * o dispatch (leaf) 53227Sjchu * o unlock 53327Sjchu * o handle error: fatal? fm_panic() : return INTR_CLAIMED) 53427Sjchu */ 53527Sjchu uint_t 53627Sjchu px_err_dmc_pec_intr(caddr_t arg) 53727Sjchu { 53827Sjchu px_fault_t *px_fault_p = (px_fault_t *)arg; 53927Sjchu dev_info_t *rpdip = px_fault_p->px_fh_dip; 54027Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 54127Sjchu px_cb_t *cb_p = px_p->px_cb_p; 542118Sjchu int err = PX_OK; 543118Sjchu int ret = DDI_FM_OK; 54427Sjchu ddi_fm_error_t derr; 54527Sjchu 54627Sjchu /* Create the derr */ 54727Sjchu bzero(&derr, sizeof (ddi_fm_error_t)); 54827Sjchu derr.fme_version = DDI_FME_VERSION; 54927Sjchu derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1); 55027Sjchu derr.fme_flag = DDI_FM_ERR_UNEXPECTED; 55127Sjchu 55227Sjchu mutex_enter(&cb_p->xbc_fm_mutex); 55327Sjchu 55427Sjchu /* send ereport/handle/clear fire registers */ 55527Sjchu err |= px_err_handle(px_p, &derr, PX_INTR_CALL, B_TRUE); 55627Sjchu 55727Sjchu /* Check all child devices for errors */ 55827Sjchu ret = ndi_fm_handler_dispatch(rpdip, NULL, &derr); 55927Sjchu 56027Sjchu /* Set the interrupt state to idle */ 56127Sjchu (void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino, 56227Sjchu INTR_IDLE_STATE); 56327Sjchu 56427Sjchu mutex_exit(&cb_p->xbc_fm_mutex); 56527Sjchu 56627Sjchu /* 56727Sjchu * PX_FATAL_HW indicates a condition recovered from Fatal-Reset, 56827Sjchu * therefore it does not cause panic. 56927Sjchu */ 57027Sjchu if ((err & (PX_FATAL_GOS | PX_FATAL_SW)) || (ret == DDI_FM_FATAL)) 57127Sjchu fm_panic("Fatal System Port Error has occurred\n"); 57227Sjchu 57327Sjchu return (DDI_INTR_CLAIMED); 57427Sjchu } 57527Sjchu 57627Sjchu /* 57727Sjchu * Error register are being handled by px_hlib xxx_init functions. 57827Sjchu * They are also called again by px_err_add_intr for mondo62 and 63 57927Sjchu * from px_cb_attach and px_attach 58027Sjchu */ 58127Sjchu void 58227Sjchu px_err_reg_enable(px_t *px_p, px_err_id_t id) 58327Sjchu { 58427Sjchu px_err_reg_desc_t *reg_desc = &px_err_reg_tbl[id]; 58527Sjchu uint64_t intr_mask = *reg_desc->intr_mask_p; 58627Sjchu uint64_t log_mask = *reg_desc->log_mask_p; 58727Sjchu caddr_t csr_base; 58827Sjchu pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 58927Sjchu 59027Sjchu if (id == PX_ERR_JBC) 59127Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC]; 59227Sjchu else 59327Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 59427Sjchu 59527Sjchu reg_desc->enabled = B_TRUE; 59627Sjchu 59727Sjchu /* Enable logs if it exists */ 59827Sjchu if (reg_desc->log_addr != NULL) 59927Sjchu CSR_XS(csr_base, reg_desc->log_addr, log_mask); 60027Sjchu 60127Sjchu /* 60227Sjchu * For readability you in code you set 1 to enable an interrupt. 60327Sjchu * But in Fire it's backwards. You set 1 to *disable* an intr. 60427Sjchu * Reverse the user tunable intr mask field. 60527Sjchu * 60627Sjchu * Disable All Errors 60727Sjchu * Clear All Errors 60827Sjchu * Enable Errors 60927Sjchu */ 61027Sjchu CSR_XS(csr_base, reg_desc->enable_addr, 0); 61127Sjchu CSR_XS(csr_base, reg_desc->clear_addr, -1); 61227Sjchu CSR_XS(csr_base, reg_desc->enable_addr, intr_mask); 61327Sjchu DBG(DBG_ATTACH, NULL, "%s Mask: 0x%llx\n", 61427Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->enable_addr)); 61527Sjchu DBG(DBG_ATTACH, NULL, "%s Status: 0x%llx\n", 61627Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->status_addr)); 61727Sjchu DBG(DBG_ATTACH, NULL, "%s Clear: 0x%llx\n", 61827Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->clear_addr)); 61927Sjchu if (reg_desc->log_addr != NULL) { 62027Sjchu DBG(DBG_ATTACH, NULL, "%s Log: 0x%llx\n", 62127Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->log_addr)); 62227Sjchu } 62327Sjchu } 62427Sjchu 62527Sjchu void 62627Sjchu px_err_reg_disable(px_t *px_p, px_err_id_t id) 62727Sjchu { 62827Sjchu px_err_reg_desc_t *reg_desc = &px_err_reg_tbl[id]; 62927Sjchu caddr_t csr_base; 63027Sjchu 63127Sjchu if (id == PX_ERR_JBC) 63227Sjchu csr_base = (caddr_t)px_p->px_inos[PX_INTR_XBC]; 63327Sjchu else 63427Sjchu csr_base = (caddr_t)px_p->px_inos[PX_INTR_PEC]; 63527Sjchu 63627Sjchu reg_desc->enabled = B_FALSE; 63727Sjchu 63827Sjchu switch (id) { 63927Sjchu case PX_ERR_JBC: 64027Sjchu case PX_ERR_MMU: 64127Sjchu case PX_ERR_IMU: 64227Sjchu case PX_ERR_TLU_UE: 64327Sjchu case PX_ERR_TLU_CE: 64427Sjchu case PX_ERR_TLU_OE: 64527Sjchu case PX_ERR_ILU: 64627Sjchu if (reg_desc->log_addr != NULL) { 64727Sjchu CSR_XS(csr_base, reg_desc->log_addr, 0); 64827Sjchu } 64927Sjchu CSR_XS(csr_base, reg_desc->enable_addr, 0); 65027Sjchu break; 65127Sjchu case PX_ERR_LPU_LINK: 65227Sjchu case PX_ERR_LPU_PHY: 65327Sjchu case PX_ERR_LPU_RX: 65427Sjchu case PX_ERR_LPU_TX: 65527Sjchu case PX_ERR_LPU_LTSSM: 65627Sjchu case PX_ERR_LPU_GIGABLZ: 65727Sjchu if (reg_desc->log_addr != NULL) { 65827Sjchu CSR_XS(csr_base, reg_desc->log_addr, -1); 65927Sjchu } 66027Sjchu CSR_XS(csr_base, reg_desc->enable_addr, -1); 66127Sjchu break; 66227Sjchu } 66327Sjchu } 66427Sjchu 66527Sjchu /* 66627Sjchu * px_err_handle: 66727Sjchu * Common function called by trap, mondo and fabric intr. 66827Sjchu * o Snap shot current fire registers 66927Sjchu * o check for safe access 67027Sjchu * o send ereport and clear snap shot registers 67127Sjchu * o check severity of snap shot registers 67227Sjchu * 67327Sjchu * @param px_p leaf in which to check access 67427Sjchu * @param derr fm err data structure to be updated 67527Sjchu * @param caller PX_TRAP_CALL | PX_INTR_CALL 67627Sjchu * @param chkjbc whether to handle jbc registers 67727Sjchu * @return err PX_OK | PX_NONFATAL | 67827Sjchu * PX_FATAL_GOS | PX_FATAL_HW | PX_STUCK_FATAL 67927Sjchu */ 68027Sjchu int 68127Sjchu px_err_handle(px_t *px_p, ddi_fm_error_t *derr, int caller, 68227Sjchu boolean_t chkjbc) 68327Sjchu { 68427Sjchu px_cb_t *cb_p = px_p->px_cb_p; /* for fm_mutex */ 68527Sjchu px_err_ss_t ss; 686118Sjchu int err = PX_OK; 68727Sjchu 68827Sjchu ASSERT(MUTEX_HELD(&cb_p->xbc_fm_mutex)); 68927Sjchu 69027Sjchu /* snap shot the current fire registers */ 69127Sjchu px_err_snapshot(px_p, &ss, chkjbc); 69227Sjchu 69327Sjchu /* check for safe access */ 69427Sjchu px_err_safeacc_check(px_p, derr); 69527Sjchu 69627Sjchu /* send ereports/handle/clear registers */ 69727Sjchu err = px_err_erpt_and_clr(px_p, derr, &ss); 69827Sjchu 69927Sjchu /* check for error severity */ 70027Sjchu err = px_err_check_severity(px_p, derr, err, caller); 70127Sjchu 70227Sjchu /* Mark the On Trap Handle if an error occured */ 70327Sjchu if (err != PX_OK) { 70427Sjchu px_pec_t *pec_p = px_p->px_pec_p; 70527Sjchu on_trap_data_t *otd = pec_p->pec_ontrap_data; 70627Sjchu 707118Sjchu if ((otd != NULL) && (otd->ot_prot & OT_DATA_ACCESS)) 70827Sjchu otd->ot_trap |= OT_DATA_ACCESS; 70927Sjchu } 71027Sjchu 71127Sjchu return (err); 71227Sjchu } 71327Sjchu 71427Sjchu /* 71527Sjchu * Static function 71627Sjchu */ 71727Sjchu 71827Sjchu /* 71927Sjchu * px_err_snapshot: 72027Sjchu * Take a current snap shot of all the fire error registers. This includes 72127Sjchu * JBC, DMC, and PEC, unless chkjbc == false; 72227Sjchu * 72327Sjchu * @param px_p leaf in which to take the snap shot. 72427Sjchu * @param ss pre-allocated memory to store the snap shot. 72527Sjchu * @param chkjbc boolean on whether to store jbc register. 72627Sjchu */ 72727Sjchu static void 72827Sjchu px_err_snapshot(px_t *px_p, px_err_ss_t *ss, boolean_t chkjbc) 72927Sjchu { 73027Sjchu pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 73127Sjchu caddr_t xbc_csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC]; 73227Sjchu caddr_t pec_csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 73327Sjchu px_err_reg_desc_t *reg_desc; 73427Sjchu int reg_id; 73527Sjchu 73627Sjchu /* snapshot JBC interrupt status */ 73727Sjchu reg_id = PX_ERR_JBC; 73827Sjchu if (chkjbc == B_TRUE) { 73927Sjchu reg_desc = &px_err_reg_tbl[reg_id]; 74027Sjchu ss->err_status[reg_id] = CSR_XR(xbc_csr_base, 74127Sjchu reg_desc->status_addr); 74227Sjchu } else { 74327Sjchu ss->err_status[reg_id] = 0; 74427Sjchu } 74527Sjchu 74627Sjchu /* snapshot DMC/PEC interrupt status */ 74727Sjchu for (reg_id = 1; reg_id < PX_ERR_REG_KEYS; reg_id += 1) { 74827Sjchu reg_desc = &px_err_reg_tbl[reg_id]; 74927Sjchu ss->err_status[reg_id] = CSR_XR(pec_csr_base, 75027Sjchu reg_desc->status_addr); 75127Sjchu } 75227Sjchu } 75327Sjchu 75427Sjchu /* 75527Sjchu * px_err_erpt_and_clr: 75627Sjchu * This function does the following thing to all the fire registers based 75727Sjchu * on an earlier snap shot. 75827Sjchu * o Send ereport 75927Sjchu * o Handle the error 76027Sjchu * o Clear the error 76127Sjchu * 76227Sjchu * @param px_p leaf in which to take the snap shot. 76327Sjchu * @param derr fm err in which the ereport is to be based on 76427Sjchu * @param ss pre-allocated memory to store the snap shot. 76527Sjchu */ 76627Sjchu static int 76727Sjchu px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr, px_err_ss_t *ss) 76827Sjchu { 76927Sjchu dev_info_t *rpdip = px_p->px_dip; 77027Sjchu px_cb_t *cb_p = px_p->px_cb_p; /* for fm_mutex */ 77127Sjchu pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 77227Sjchu caddr_t csr_base; 77327Sjchu px_err_reg_desc_t *err_reg_tbl; 77427Sjchu px_err_bit_desc_t *err_bit_tbl; 77527Sjchu px_err_bit_desc_t *err_bit_desc; 77627Sjchu 77727Sjchu uint64_t *log_mask, *count_mask; 77827Sjchu uint64_t status_addr, clear_addr; 77927Sjchu uint64_t ss_reg; 78027Sjchu 78127Sjchu int (*err_handler)(); 78227Sjchu int (*erpt_handler)(); 78327Sjchu int reg_id, key; 78427Sjchu int err = PX_OK; 78527Sjchu 78627Sjchu ASSERT(MUTEX_HELD(&cb_p->xbc_fm_mutex)); 78727Sjchu 78827Sjchu /* send erport/handle/clear JBC errors */ 78927Sjchu for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id += 1) { 79027Sjchu /* Get the correct register description table */ 79127Sjchu err_reg_tbl = &px_err_reg_tbl[reg_id]; 79227Sjchu 79327Sjchu /* Get the correct CSR BASE */ 79427Sjchu if (reg_id == PX_ERR_JBC) { 79527Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC]; 79627Sjchu } else { 79727Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 79827Sjchu } 79927Sjchu 80027Sjchu /* Get pointers to masks and register addresses */ 80127Sjchu log_mask = err_reg_tbl->log_mask_p; 80227Sjchu count_mask = err_reg_tbl->count_mask_p; 80327Sjchu status_addr = err_reg_tbl->status_addr; 80427Sjchu clear_addr = err_reg_tbl->clear_addr; 80527Sjchu ss_reg = ss->err_status[reg_id]; 80627Sjchu 80727Sjchu /* Get the register BIT description table */ 80827Sjchu err_bit_tbl = err_reg_tbl->err_bit_tbl; 80927Sjchu 81027Sjchu /* For each known bit in the register send erpt and handle */ 81127Sjchu for (key = 0; key < err_reg_tbl->err_bit_keys; key += 1) { 81227Sjchu /* Get the bit description table for this register */ 81327Sjchu err_bit_desc = &err_bit_tbl[key]; 81427Sjchu 81527Sjchu /* 81627Sjchu * If the ss_reg is set for this bit, 81727Sjchu * send ereport and handle 81827Sjchu */ 81927Sjchu if (BIT_TST(ss_reg, err_bit_desc->bit)) { 82027Sjchu /* Increment the counter if necessary */ 82127Sjchu if (BIT_TST(*count_mask, err_bit_desc->bit)) { 82227Sjchu err_bit_desc->counter++; 82327Sjchu } 82427Sjchu 82527Sjchu /* Error Handle for this bit */ 82627Sjchu err_handler = err_bit_desc->err_handler; 82727Sjchu if (err_handler) 82827Sjchu err |= err_handler(rpdip, 82927Sjchu csr_base, 83027Sjchu derr, 83127Sjchu err_reg_tbl, 83227Sjchu err_bit_desc); 83327Sjchu 83427Sjchu /* Send the ereport for this bit */ 83527Sjchu erpt_handler = err_bit_desc->erpt_handler; 83627Sjchu if (erpt_handler) 83727Sjchu (void) erpt_handler(rpdip, 83827Sjchu csr_base, 83927Sjchu ss_reg, 84027Sjchu derr, 84127Sjchu err_bit_desc->class_name); 84227Sjchu } 84327Sjchu } 84427Sjchu /* Log register status */ 84527Sjchu if ((px_err_log_all) || (ss_reg & *log_mask)) 84627Sjchu LOG(DBG_ERR_INTR, rpdip, "<%x>=%16llx %s\n", 84727Sjchu status_addr, ss_reg, err_reg_tbl->msg); 84827Sjchu 84927Sjchu /* Clear the register and error */ 85027Sjchu CSR_XS(csr_base, clear_addr, ss_reg); 85127Sjchu } 85227Sjchu 85327Sjchu return (err); 85427Sjchu } 85527Sjchu 85627Sjchu /* 85727Sjchu * px_err_check_severity: 85827Sjchu * Check the severity of the fire error based on an earlier snapshot 85927Sjchu * 86027Sjchu * @param px_p leaf in which to take the snap shot. 86127Sjchu * @param derr fm err in which the ereport is to be based on 86227Sjchu * @param ss pre-allocated memory to store the snap shot. 86327Sjchu */ 86427Sjchu static int 86527Sjchu px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr, int err, int caller) 86627Sjchu { 86727Sjchu px_pec_t *pec_p = px_p->px_pec_p; 86827Sjchu boolean_t is_safeacc = B_FALSE; 869118Sjchu 870118Sjchu /* nothing to do if called with no error */ 871118Sjchu if (err == PX_OK) 872118Sjchu return (err); 87327Sjchu 87427Sjchu /* Cautious access error handling */ 87527Sjchu switch (derr->fme_flag) { 87627Sjchu case DDI_FM_ERR_EXPECTED: 87727Sjchu if (caller == PX_TRAP_CALL) { 87827Sjchu /* 87927Sjchu * for ddi_caut_get treat all events as nonfatal 88027Sjchu * The trampoline will set err_ena = 0, 88127Sjchu * err_status = NONFATAL. 88227Sjchu */ 88327Sjchu derr->fme_status = DDI_FM_NONFATAL; 88427Sjchu is_safeacc = B_TRUE; 88527Sjchu } else { 88627Sjchu /* 88727Sjchu * For ddi_caut_put treat all events as nonfatal. Here 88827Sjchu * we have the handle and can call ndi_fm_acc_err_set(). 88927Sjchu */ 89027Sjchu derr->fme_status = DDI_FM_NONFATAL; 89127Sjchu ndi_fm_acc_err_set(pec_p->pec_acc_hdl, derr); 89227Sjchu is_safeacc = B_TRUE; 89327Sjchu } 89427Sjchu break; 89527Sjchu case DDI_FM_ERR_PEEK: 89627Sjchu case DDI_FM_ERR_POKE: 89727Sjchu /* 89827Sjchu * For ddi_peek/poke treat all events as nonfatal. 89927Sjchu */ 90027Sjchu is_safeacc = B_TRUE; 90127Sjchu break; 90227Sjchu default: 90327Sjchu is_safeacc = B_FALSE; 90427Sjchu } 90527Sjchu 90627Sjchu /* 90727Sjchu * The third argument "err" is passed in as error status from checking 90827Sjchu * Fire register, re-adjust error status from safe access. 90927Sjchu */ 91027Sjchu if (is_safeacc && !(err & PX_FATAL_GOS)) 911118Sjchu return (PX_NONFATAL); 91227Sjchu 913118Sjchu return (err); 91427Sjchu } 91527Sjchu 91627Sjchu /* predefined convenience functions */ 91727Sjchu /* ARGSUSED */ 91827Sjchu int 91927Sjchu px_err_fatal_hw_handle(dev_info_t *rpdip, caddr_t csr_base, 92027Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 92127Sjchu px_err_bit_desc_t *err_bit_descr) 92227Sjchu { 92327Sjchu return (PX_FATAL_HW); 92427Sjchu } 92527Sjchu 92627Sjchu /* ARGSUSED */ 92727Sjchu int 92827Sjchu px_err_fatal_gos_handle(dev_info_t *rpdip, caddr_t csr_base, 92927Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 93027Sjchu px_err_bit_desc_t *err_bit_descr) 93127Sjchu { 93227Sjchu return (PX_FATAL_GOS); 93327Sjchu } 93427Sjchu 93527Sjchu /* ARGSUSED */ 93627Sjchu int 93727Sjchu px_err_fatal_stuck_handle(dev_info_t *rpdip, caddr_t csr_base, 93827Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 93927Sjchu px_err_bit_desc_t *err_bit_descr) 94027Sjchu { 94127Sjchu return (PX_STUCK_FATAL); 94227Sjchu } 94327Sjchu 94427Sjchu /* ARGSUSED */ 94527Sjchu int 94627Sjchu px_err_fatal_sw_handle(dev_info_t *rpdip, caddr_t csr_base, 94727Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 94827Sjchu px_err_bit_desc_t *err_bit_descr) 94927Sjchu { 95027Sjchu return (PX_FATAL_SW); 95127Sjchu } 95227Sjchu 95327Sjchu /* ARGSUSED */ 95427Sjchu int 95527Sjchu px_err_non_fatal_handle(dev_info_t *rpdip, caddr_t csr_base, 95627Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 95727Sjchu px_err_bit_desc_t *err_bit_descr) 95827Sjchu { 95927Sjchu return (PX_NONFATAL); 96027Sjchu } 96127Sjchu 96227Sjchu /* ARGSUSED */ 96327Sjchu int 96427Sjchu px_err_ok_handle(dev_info_t *rpdip, caddr_t csr_base, ddi_fm_error_t *derr, 96527Sjchu px_err_reg_desc_t *err_reg_descr, px_err_bit_desc_t *err_bit_descr) 96627Sjchu { 96727Sjchu return (PX_OK); 96827Sjchu } 96927Sjchu 97027Sjchu /* ARGSUSED */ 97127Sjchu int 97227Sjchu px_err_unknown_handle(dev_info_t *rpdip, caddr_t csr_base, ddi_fm_error_t *derr, 97327Sjchu px_err_reg_desc_t *err_reg_descr, px_err_bit_desc_t *err_bit_descr) 97427Sjchu { 97527Sjchu return (PX_ERR_UNKNOWN); 97627Sjchu } 97727Sjchu 97827Sjchu /* JBC FATAL - see io erpt doc, section 1.1 */ 97927Sjchu PX_ERPT_SEND_DEC(jbc_fatal) 98027Sjchu { 98127Sjchu char buf[FM_MAX_CLASS]; 98227Sjchu 98327Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 98427Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 98527Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 98627Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 98727Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 98827Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 98927Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 99027Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 99127Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 99227Sjchu ss_reg, 99327Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 99427Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 99527Sjchu FIRE_JBC_FEL1, DATA_TYPE_UINT64, 99627Sjchu CSR_XR(csr_base, FATAL_ERROR_LOG_1), 99727Sjchu FIRE_JBC_FEL2, DATA_TYPE_UINT64, 99827Sjchu CSR_XR(csr_base, FATAL_ERROR_LOG_2), 99927Sjchu NULL); 100027Sjchu 100127Sjchu return (PX_OK); 100227Sjchu } 100327Sjchu 100427Sjchu /* JBC MERGE - see io erpt doc, section 1.2 */ 100527Sjchu PX_ERPT_SEND_DEC(jbc_merge) 100627Sjchu { 100727Sjchu char buf[FM_MAX_CLASS]; 100827Sjchu 100927Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 101027Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 101127Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 101227Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 101327Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 101427Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 101527Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 101627Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 101727Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 101827Sjchu ss_reg, 101927Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 102027Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 102127Sjchu FIRE_JBC_MTEL, DATA_TYPE_UINT64, 102227Sjchu CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG), 102327Sjchu NULL); 102427Sjchu 102527Sjchu return (PX_OK); 102627Sjchu } 102727Sjchu 102827Sjchu /* 102927Sjchu * JBC Merge buffer nonfatal errors: 103027Sjchu * Merge buffer parity error (rd_buf): dma:read:M:nonfatal 103127Sjchu * Merge buffer parity error (wr_buf): dma:write:M:nonfatal 103227Sjchu */ 103327Sjchu /* ARGSUSED */ 103427Sjchu int 103527Sjchu px_err_jbc_merge_handle(dev_info_t *rpdip, caddr_t csr_base, 103627Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 103727Sjchu px_err_bit_desc_t *err_bit_descr) 103827Sjchu { 103927Sjchu uint64_t paddr; 104027Sjchu int ret; 104127Sjchu 104227Sjchu paddr = CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG); 104327Sjchu paddr &= MERGE_TRANSACTION_ERROR_LOG_ADDRESS_MASK; 104427Sjchu 104527Sjchu ret = px_handle_lookup( 104627Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 104727Sjchu 104827Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 104927Sjchu } 105027Sjchu 105127Sjchu /* JBC Jbusint IN - see io erpt doc, section 1.3 */ 105227Sjchu PX_ERPT_SEND_DEC(jbc_in) 105327Sjchu { 105427Sjchu char buf[FM_MAX_CLASS]; 105527Sjchu 105627Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 105727Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 105827Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 105927Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 106027Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 106127Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 106227Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 106327Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 106427Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 106527Sjchu ss_reg, 106627Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 106727Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 106827Sjchu FIRE_JBC_JITEL1, DATA_TYPE_UINT64, 106927Sjchu CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG), 107027Sjchu FIRE_JBC_JITEL2, DATA_TYPE_UINT64, 107127Sjchu CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG_2), 107227Sjchu NULL); 107327Sjchu 107427Sjchu return (PX_OK); 107527Sjchu } 107627Sjchu 107727Sjchu /* 107827Sjchu * JBC Jbusint IN nonfatal errors: PA logged in Jbusint In Transaction Error 107927Sjchu * Log Reg[42:0]. 108027Sjchu * CE async fault error: nonfatal 108127Sjchu * Jbus bus error: dma::nonfatal 108227Sjchu * Jbus unmapped error: pio|dma:rdwr:M:nonfatal 108327Sjchu * Write data parity error: pio/write:M:nonfatal 108427Sjchu * Read data parity error: pio/read:M:nonfatal 108527Sjchu * Illegal NCWR bytemask: pio:write:M:nonfatal 108627Sjchu * Illegal NCRD bytemask: pio:write:M:nonfatal 108727Sjchu * Invalid jbus transaction: nonfatal 108827Sjchu */ 108927Sjchu /* ARGSUSED */ 109027Sjchu int 109127Sjchu px_err_jbc_jbusint_in_handle(dev_info_t *rpdip, caddr_t csr_base, 109227Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 109327Sjchu px_err_bit_desc_t *err_bit_descr) 109427Sjchu { 109527Sjchu uint64_t paddr; 109627Sjchu int ret; 109727Sjchu 109827Sjchu paddr = CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG); 109927Sjchu paddr &= JBCINT_IN_TRANSACTION_ERROR_LOG_ADDRESS_MASK; 110027Sjchu 110127Sjchu ret = px_handle_lookup( 110227Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 110327Sjchu 110427Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 110527Sjchu } 110627Sjchu 110727Sjchu 110827Sjchu /* JBC Jbusint Out - see io erpt doc, section 1.4 */ 110927Sjchu PX_ERPT_SEND_DEC(jbc_out) 111027Sjchu { 111127Sjchu char buf[FM_MAX_CLASS]; 111227Sjchu 111327Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 111427Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 111527Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 111627Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 111727Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 111827Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 111927Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 112027Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 112127Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 112227Sjchu ss_reg, 112327Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 112427Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 112527Sjchu FIRE_JBC_JOTEL1, DATA_TYPE_UINT64, 112627Sjchu CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG), 112727Sjchu FIRE_JBC_JOTEL2, DATA_TYPE_UINT64, 112827Sjchu CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG_2), 112927Sjchu NULL); 113027Sjchu 113127Sjchu return (PX_OK); 113227Sjchu } 113327Sjchu 113427Sjchu /* JBC Dmcint ODCD - see io erpt doc, section 1.5 */ 113527Sjchu PX_ERPT_SEND_DEC(jbc_odcd) 113627Sjchu { 113727Sjchu char buf[FM_MAX_CLASS]; 113827Sjchu 113927Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 114027Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 114127Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 114227Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 114327Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 114427Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 114527Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 114627Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 114727Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 114827Sjchu ss_reg, 114927Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 115027Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 115127Sjchu FIRE_JBC_DMC_ODCD, DATA_TYPE_UINT64, 115227Sjchu CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG), 115327Sjchu NULL); 115427Sjchu 115527Sjchu return (PX_OK); 115627Sjchu } 115727Sjchu 115827Sjchu /* 115927Sjchu * JBC Dmcint ODCO nonfatal errer handling - 116027Sjchu * Unmapped PIO read error: pio:read:M:nonfatal 116127Sjchu * Unmapped PIO write error: pio:write:M:nonfatal 116227Sjchu * PIO data parity error: pio:write:M:nonfatal 116327Sjchu * Invalid PIO write to PCIe cfg/io, csr, ebus or i2c bus: pio:write:nonfatal 116427Sjchu * Invalid PIO read to PCIe cfg/io, csr, ebus or i2c bus: pio:read:nonfatal 116527Sjchu */ 116627Sjchu /* ARGSUSED */ 116727Sjchu int 116827Sjchu px_err_jbc_dmcint_odcd_handle(dev_info_t *rpdip, caddr_t csr_base, 116927Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 117027Sjchu px_err_bit_desc_t *err_bit_descr) 117127Sjchu { 117227Sjchu uint64_t paddr; 117327Sjchu int ret; 117427Sjchu 117527Sjchu paddr = CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG); 117627Sjchu paddr &= DMCINT_ODCD_ERROR_LOG_ADDRESS_MASK; 117727Sjchu 117827Sjchu ret = px_handle_lookup( 117927Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 118027Sjchu 118127Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 118227Sjchu } 118327Sjchu 118427Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */ 118527Sjchu PX_ERPT_SEND_DEC(jbc_idc) 118627Sjchu { 118727Sjchu char buf[FM_MAX_CLASS]; 118827Sjchu 118927Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 119027Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 119127Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 119227Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 119327Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 119427Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 119527Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 119627Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 119727Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 119827Sjchu ss_reg, 119927Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 120027Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 120127Sjchu FIRE_JBC_DMC_IDC, DATA_TYPE_UINT64, 120227Sjchu CSR_XR(csr_base, DMCINT_IDC_ERROR_LOG), 120327Sjchu NULL); 120427Sjchu 120527Sjchu return (PX_OK); 120627Sjchu } 120727Sjchu 120827Sjchu /* JBC CSR - see io erpt doc, section 1.7 */ 120927Sjchu PX_ERPT_SEND_DEC(jbc_csr) 121027Sjchu { 121127Sjchu char buf[FM_MAX_CLASS]; 121227Sjchu 121327Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 121427Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 121527Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 121627Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 121727Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 121827Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 121927Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 122027Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 122127Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 122227Sjchu ss_reg, 122327Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 122427Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 122527Sjchu "jbc-error-reg", DATA_TYPE_UINT64, 122627Sjchu CSR_XR(csr_base, CSR_ERROR_LOG), 122727Sjchu NULL); 122827Sjchu 122927Sjchu return (PX_OK); 123027Sjchu } 123127Sjchu 123227Sjchu /* 123327Sjchu * JBC CSR errer handling - 123427Sjchu * Ebus ready timeout error: pio:rdwr:M:nonfatal 123527Sjchu */ 123627Sjchu /* ARGSUSED */ 123727Sjchu int 123827Sjchu px_err_jbc_csr_handle(dev_info_t *rpdip, caddr_t csr_base, 123927Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 124027Sjchu px_err_bit_desc_t *err_bit_descr) 124127Sjchu { 124227Sjchu uint64_t paddr; 124327Sjchu int ret; 124427Sjchu 124527Sjchu paddr = CSR_XR(csr_base, CSR_ERROR_LOG); 124627Sjchu paddr &= CSR_ERROR_LOG_ADDRESS_MASK; 124727Sjchu 124827Sjchu ret = px_handle_lookup( 124927Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 125027Sjchu 125127Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 125227Sjchu } 125327Sjchu 125427Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */ 125527Sjchu 125627Sjchu /* DMC IMU RDS - see io erpt doc, section 2.1 */ 125727Sjchu PX_ERPT_SEND_DEC(imu_rds) 125827Sjchu { 125927Sjchu char buf[FM_MAX_CLASS]; 126027Sjchu 126127Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 126227Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 126327Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 126427Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 126527Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64, 126627Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 126727Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 126827Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 126927Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 127027Sjchu ss_reg, 127127Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 127227Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 127327Sjchu FIRE_IMU_RDS, DATA_TYPE_UINT64, 127427Sjchu CSR_XR(csr_base, IMU_RDS_ERROR_LOG), 127527Sjchu NULL); 127627Sjchu 127727Sjchu return (PX_OK); 127827Sjchu } 127927Sjchu 128027Sjchu /* imu function to handle all Received but Not Enabled errors */ 128127Sjchu /* ARGSUSED */ 128227Sjchu int 128327Sjchu px_err_imu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base, 128427Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 128527Sjchu px_err_bit_desc_t *err_bit_descr) 128627Sjchu { 128727Sjchu uint64_t imu_log_enable, imu_intr_enable; 128827Sjchu int mask = BITMASK(err_bit_descr->bit); 128927Sjchu int err = PX_NONFATAL; 129027Sjchu 129127Sjchu imu_log_enable = CSR_XR(csr_base, err_reg_descr->log_addr); 129227Sjchu imu_intr_enable = CSR_XR(csr_base, err_reg_descr->enable_addr); 129327Sjchu 129427Sjchu if (imu_log_enable & imu_intr_enable & mask) { 129527Sjchu err = PX_FATAL_SW; 129627Sjchu } else { 129727Sjchu /* 129827Sjchu * S/W bug - this error should always be enabled 129927Sjchu */ 130027Sjchu 130127Sjchu /* enable error & intr reporting for this bit */ 130227Sjchu CSR_XS(csr_base, IMU_ERROR_LOG_ENABLE, imu_log_enable | mask); 130327Sjchu CSR_XS(csr_base, IMU_INTERRUPT_ENABLE, imu_intr_enable | mask); 130427Sjchu err = PX_NONFATAL; 130527Sjchu } 130627Sjchu 130727Sjchu return (err); 130827Sjchu } 130927Sjchu 1310118Sjchu /* 1311118Sjchu * No platforms uses PME. Any PME received is simply logged 1312118Sjchu * for analysis. 1313118Sjchu */ 1314118Sjchu /* ARGSUSED */ 1315118Sjchu int 1316118Sjchu px_err_imu_pme_handle(dev_info_t *rpdip, caddr_t csr_base, 1317118Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1318118Sjchu px_err_bit_desc_t *err_bit_descr) 1319118Sjchu { 1320118Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 1321118Sjchu 1322118Sjchu px_p->px_pme_ignored++; 1323118Sjchu return (PX_NONFATAL); 1324118Sjchu } 1325118Sjchu 132627Sjchu /* handle EQ overflow */ 132727Sjchu /* ARGSUSED */ 132827Sjchu int 132927Sjchu px_err_imu_eq_ovfl_handle(dev_info_t *rpdip, caddr_t csr_base, 133027Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 133127Sjchu px_err_bit_desc_t *err_bit_descr) 133227Sjchu { 133327Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 133427Sjchu px_msiq_state_t *msiq_state_p = &px_p->px_ib_p->ib_msiq_state; 133527Sjchu msiqid_t eqno; 133627Sjchu pci_msiq_state_t msiq_state; 133727Sjchu int err = PX_NONFATAL; 133827Sjchu int i; 133927Sjchu 134027Sjchu eqno = msiq_state_p->msiq_1st_msiq_id; 134127Sjchu for (i = 0; i < msiq_state_p->msiq_cnt; i++) { 134227Sjchu if (px_lib_msiq_getstate(rpdip, eqno, &msiq_state) == 134327Sjchu DDI_SUCCESS) { 134427Sjchu if (msiq_state == PCI_MSIQ_STATE_ERROR) { 134527Sjchu err = PX_FATAL_SW; 134627Sjchu } 134727Sjchu } 134827Sjchu } 134927Sjchu 135027Sjchu return (err); 135127Sjchu } 135227Sjchu 135327Sjchu /* DMC IMU SCS - see io erpt doc, section 2.2 */ 135427Sjchu PX_ERPT_SEND_DEC(imu_scs) 135527Sjchu { 135627Sjchu char buf[FM_MAX_CLASS]; 135727Sjchu 135827Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 135927Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 136027Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 136127Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 136227Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64, 136327Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 136427Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 136527Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 136627Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 136727Sjchu ss_reg, 136827Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 136927Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 137027Sjchu FIRE_IMU_SCS, DATA_TYPE_UINT64, 137127Sjchu CSR_XR(csr_base, IMU_SCS_ERROR_LOG), 137227Sjchu NULL); 137327Sjchu 137427Sjchu return (PX_OK); 137527Sjchu } 137627Sjchu 137727Sjchu /* DMC IMU - see io erpt doc, section 2.3 */ 137827Sjchu PX_ERPT_SEND_DEC(imu) 137927Sjchu { 138027Sjchu char buf[FM_MAX_CLASS]; 138127Sjchu 138227Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 138327Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 138427Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 138527Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 138627Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64, 138727Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 138827Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 138927Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 139027Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 139127Sjchu ss_reg, 139227Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 139327Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 139427Sjchu NULL); 139527Sjchu 139627Sjchu return (PX_OK); 139727Sjchu } 139827Sjchu 139927Sjchu /* DMC MMU TFAR/TFSR - see io erpt doc, section 2.4 */ 140027Sjchu PX_ERPT_SEND_DEC(mmu_tfar_tfsr) 140127Sjchu { 140227Sjchu char buf[FM_MAX_CLASS]; 140327Sjchu 140427Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 140527Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 140627Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 140727Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 140827Sjchu FIRE_MMU_ELE, DATA_TYPE_UINT64, 140927Sjchu CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE), 141027Sjchu FIRE_MMU_IE, DATA_TYPE_UINT64, 141127Sjchu CSR_XR(csr_base, MMU_INTERRUPT_ENABLE), 141227Sjchu FIRE_MMU_IS, DATA_TYPE_UINT64, 141327Sjchu ss_reg, 141427Sjchu FIRE_MMU_ESS, DATA_TYPE_UINT64, 141527Sjchu CSR_XR(csr_base, MMU_ERROR_STATUS_SET), 141627Sjchu FIRE_MMU_TFAR, DATA_TYPE_UINT64, 141727Sjchu CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS), 141827Sjchu FIRE_MMU_TFSR, DATA_TYPE_UINT64, 141927Sjchu CSR_XR(csr_base, MMU_TRANSLATION_FAULT_STATUS), 142027Sjchu NULL); 142127Sjchu 142227Sjchu return (PX_OK); 142327Sjchu } 142427Sjchu 142527Sjchu /* DMC MMU - see io erpt doc, section 2.5 */ 142627Sjchu PX_ERPT_SEND_DEC(mmu) 142727Sjchu { 142827Sjchu char buf[FM_MAX_CLASS]; 142927Sjchu 143027Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 143127Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 143227Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 143327Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 143427Sjchu FIRE_MMU_ELE, DATA_TYPE_UINT64, 143527Sjchu CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE), 143627Sjchu FIRE_MMU_IE, DATA_TYPE_UINT64, 143727Sjchu CSR_XR(csr_base, MMU_INTERRUPT_ENABLE), 143827Sjchu FIRE_MMU_IS, DATA_TYPE_UINT64, 143927Sjchu ss_reg, 144027Sjchu FIRE_MMU_ESS, DATA_TYPE_UINT64, 144127Sjchu CSR_XR(csr_base, MMU_ERROR_STATUS_SET), 144227Sjchu NULL); 144327Sjchu 144427Sjchu return (PX_OK); 144527Sjchu } 144627Sjchu 144727Sjchu /* imu function to handle all Received but Not Enabled errors */ 144827Sjchu int 144927Sjchu px_err_mmu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base, 145027Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 145127Sjchu px_err_bit_desc_t *err_bit_descr) 145227Sjchu { 1453260Set142600 uint64_t mmu_log_enable, mmu_intr_enable; 145427Sjchu uint64_t mask = BITMASK(err_bit_descr->bit); 1455260Set142600 uint64_t mmu_tfa, mmu_ctrl; 1456260Set142600 uint64_t mmu_enable_bit = 0; 145727Sjchu int err = PX_NONFATAL; 145827Sjchu int ret; 145927Sjchu 146027Sjchu mmu_log_enable = CSR_XR(csr_base, err_reg_descr->log_addr); 146127Sjchu mmu_intr_enable = CSR_XR(csr_base, err_reg_descr->enable_addr); 146227Sjchu 146327Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 1464260Set142600 mmu_ctrl = CSR_XR(csr_base, MMU_CONTROL_AND_STATUS); 146527Sjchu 1466260Set142600 switch (err_bit_descr->bit) { 1467260Set142600 case MMU_INTERRUPT_STATUS_BYP_ERR_P: 1468260Set142600 mmu_enable_bit = BITMASK(MMU_CONTROL_AND_STATUS_BE); 1469260Set142600 break; 1470260Set142600 case MMU_INTERRUPT_STATUS_TRN_ERR_P: 1471260Set142600 mmu_enable_bit = BITMASK(MMU_CONTROL_AND_STATUS_TE); 1472260Set142600 break; 1473260Set142600 default: 1474260Set142600 mmu_enable_bit = 0; 1475260Set142600 break; 1476260Set142600 } 1477260Set142600 1478260Set142600 /* 1479260Set142600 * If the interrupts are enabled and Translation/Bypass Enable bit 1480260Set142600 * was set, then panic. This error should not have occured. 1481260Set142600 */ 1482260Set142600 if (mmu_log_enable & mmu_intr_enable & 1483260Set142600 (mmu_ctrl & mmu_enable_bit)) { 148427Sjchu err = PX_FATAL_SW; 148527Sjchu } else { 148627Sjchu ret = px_handle_lookup( 148727Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 148827Sjchu err = (ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL; 148927Sjchu 149027Sjchu /* 149127Sjchu * S/W bug - this error should always be enabled 149227Sjchu */ 149327Sjchu 149427Sjchu /* enable error & intr reporting for this bit */ 149527Sjchu CSR_XS(csr_base, MMU_ERROR_LOG_ENABLE, mmu_log_enable | mask); 149627Sjchu CSR_XS(csr_base, MMU_INTERRUPT_ENABLE, mmu_intr_enable | mask); 1497260Set142600 1498260Set142600 /* enable translation access/bypass enable */ 1499260Set142600 CSR_XS(csr_base, MMU_CONTROL_AND_STATUS, 1500260Set142600 mmu_ctrl | mmu_enable_bit); 150127Sjchu } 150227Sjchu 150327Sjchu return (err); 150427Sjchu } 150527Sjchu 150627Sjchu /* Generic error handling functions that involve MMU Translation Fault Addr */ 150727Sjchu /* ARGSUSED */ 150827Sjchu int 150927Sjchu px_err_mmu_tfa_handle(dev_info_t *rpdip, caddr_t csr_base, 151027Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 151127Sjchu px_err_bit_desc_t *err_bit_descr) 151227Sjchu { 151327Sjchu uint64_t mmu_tfa; 151427Sjchu uint_t ret; 151527Sjchu 151627Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 151727Sjchu ret = px_handle_lookup( 151827Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 151927Sjchu 152027Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 152127Sjchu } 152227Sjchu 152327Sjchu /* MMU Table walk errors */ 152427Sjchu /* ARGSUSED */ 152527Sjchu int 152627Sjchu px_err_mmu_tblwlk_handle(dev_info_t *rpdip, caddr_t csr_base, 152727Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 152827Sjchu px_err_bit_desc_t *err_bit_descr) 152927Sjchu { 153027Sjchu uint64_t mmu_tfa; 153127Sjchu uint_t ret; 153227Sjchu 153327Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 153427Sjchu ret = px_handle_lookup( 153527Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 153627Sjchu 153727Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 153827Sjchu } 153927Sjchu 1540118Sjchu /* 1541118Sjchu * TLU LUP event - power management code is interested in this event. 1542118Sjchu */ 1543118Sjchu /* ARGSUSED */ 1544118Sjchu int 1545118Sjchu px_err_tlu_lup_handle(dev_info_t *rpdip, caddr_t csr_base, 1546118Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1547118Sjchu px_err_bit_desc_t *err_bit_descr) 1548118Sjchu { 1549118Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 1550118Sjchu 1551118Sjchu /* 1552118Sjchu * Existense of pm info indicates the power management 1553118Sjchu * is interested in this event. 1554118Sjchu */ 1555118Sjchu if (!PCIE_PMINFO(rpdip) || !PCIE_NEXUS_PMINFO(rpdip)) 1556118Sjchu return (PX_OK); 1557118Sjchu 1558118Sjchu mutex_enter(&px_p->px_lup_lock); 1559118Sjchu px_p->px_lupsoft_pending++; 1560118Sjchu mutex_exit(&px_p->px_lup_lock); 1561118Sjchu 1562118Sjchu /* 1563118Sjchu * Post a soft interrupt to wake up threads waiting for this. 1564118Sjchu */ 1565118Sjchu ddi_trigger_softintr(px_p->px_lupsoft_id); 1566118Sjchu 1567118Sjchu return (PX_OK); 1568118Sjchu } 1569118Sjchu 157027Sjchu /* PEC ILU none - see io erpt doc, section 3.1 */ 157127Sjchu PX_ERPT_SEND_DEC(pec_ilu) 157227Sjchu { 157327Sjchu char buf[FM_MAX_CLASS]; 157427Sjchu 157527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 157627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 157727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 157827Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 157927Sjchu FIRE_ILU_ELE, DATA_TYPE_UINT64, 158027Sjchu CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE), 158127Sjchu FIRE_ILU_IE, DATA_TYPE_UINT64, 158227Sjchu CSR_XR(csr_base, ILU_INTERRUPT_ENABLE), 158327Sjchu FIRE_ILU_IS, DATA_TYPE_UINT64, 158427Sjchu ss_reg, 158527Sjchu FIRE_ILU_ESS, DATA_TYPE_UINT64, 158627Sjchu CSR_XR(csr_base, ILU_ERROR_STATUS_SET), 158727Sjchu NULL); 158827Sjchu 158927Sjchu return (PX_OK); 159027Sjchu } 159127Sjchu 159227Sjchu /* PCI-E Correctable Errors - see io erpt doc, section 3.6 */ 159327Sjchu PX_ERPT_SEND_DEC(pciex_ce) 159427Sjchu { 159527Sjchu char buf[FM_MAX_CLASS]; 159627Sjchu 159727Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 159827Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 159927Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 160027Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 160127Sjchu FIRE_TLU_CELE, DATA_TYPE_UINT64, 160227Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE), 160327Sjchu FIRE_TLU_CIE, DATA_TYPE_UINT64, 160427Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE), 160527Sjchu FIRE_TLU_CIS, DATA_TYPE_UINT64, 160627Sjchu ss_reg, 160727Sjchu FIRE_TLU_CESS, DATA_TYPE_UINT64, 160827Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_STATUS_SET), 160927Sjchu NULL); 161027Sjchu 161127Sjchu return (PX_OK); 161227Sjchu } 161327Sjchu 161427Sjchu /* TLU Other Event Status (receive only) - see io erpt doc, section 3.7 */ 161527Sjchu PX_ERPT_SEND_DEC(pciex_rx_oe) 161627Sjchu { 161727Sjchu char buf[FM_MAX_CLASS]; 161827Sjchu 161927Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 162027Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 162127Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 162227Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 162327Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 162427Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 162527Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 162627Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 162727Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 162827Sjchu ss_reg, 162927Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 163027Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 163127Sjchu FIRE_TLU_RUEH1L, DATA_TYPE_UINT64, 163227Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG), 1633260Set142600 FIRE_TLU_RUEH2L, DATA_TYPE_UINT64, 163427Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG), 163527Sjchu NULL); 163627Sjchu 163727Sjchu return (PX_OK); 163827Sjchu } 163927Sjchu 164027Sjchu /* TLU Other Event Status (rx + tx) - see io erpt doc, section 3.8 */ 164127Sjchu PX_ERPT_SEND_DEC(pciex_rx_tx_oe) 164227Sjchu { 164327Sjchu char buf[FM_MAX_CLASS]; 164427Sjchu 164527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 164627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 164727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 164827Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 164927Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 165027Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 165127Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 165227Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 165327Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 165427Sjchu ss_reg, 165527Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 165627Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 165727Sjchu FIRE_TLU_ROEEH1L, DATA_TYPE_UINT64, 165827Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG), 165927Sjchu FIRE_TLU_ROEEH2L, DATA_TYPE_UINT64, 166027Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG), 166127Sjchu FIRE_TLU_TOEEH1L, DATA_TYPE_UINT64, 166227Sjchu CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG), 1663260Set142600 FIRE_TLU_TOEEH2L, DATA_TYPE_UINT64, 166427Sjchu CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG), 166527Sjchu NULL); 166627Sjchu 166727Sjchu return (PX_OK); 166827Sjchu } 166927Sjchu 167027Sjchu /* TLU Other Event - see io erpt doc, section 3.9 */ 167127Sjchu PX_ERPT_SEND_DEC(pciex_oe) 167227Sjchu { 1673*287Smg140465 char buf[FM_MAX_CLASS]; 167427Sjchu 167527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 167627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 167727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 167827Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 167927Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 168027Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 168127Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 168227Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 168327Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 168427Sjchu ss_reg, 168527Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 168627Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 168727Sjchu NULL); 168827Sjchu 168927Sjchu return (PX_OK); 169027Sjchu } 1691*287Smg140465 1692*287Smg140465 /* TLU Other Event - Link Down see io erpt doc, section 3.9 */ 1693*287Smg140465 PX_ERPT_SEND_DEC(pciex_ldn) 1694*287Smg140465 { 1695*287Smg140465 px_t *px_p = DIP_TO_STATE(rpdip); 1696*287Smg140465 1697*287Smg140465 /* 1698*287Smg140465 * Don't post ereport, if ldn event is due to 1699*287Smg140465 * power management. 1700*287Smg140465 */ 1701*287Smg140465 if (px_p->px_pm_flags & PX_LDN_EXPECTED) { 1702*287Smg140465 px_p->px_pm_flags &= ~PX_LDN_EXPECTED; 1703*287Smg140465 return (PX_OK); 1704*287Smg140465 } 1705*287Smg140465 return (PX_ERPT_SEND(pciex_oe)(rpdip, csr_base, ss_reg, derr, 1706*287Smg140465 class_name)); 1707*287Smg140465 1708*287Smg140465 } 1709*287Smg140465 1710*287Smg140465 /* TLU Other Event - Link Up see io erpt doc, section 3.9 */ 1711*287Smg140465 PX_ERPT_SEND_DEC(pciex_lup) 1712*287Smg140465 { 1713*287Smg140465 px_t *px_p = DIP_TO_STATE(rpdip); 1714*287Smg140465 1715*287Smg140465 /* 1716*287Smg140465 * Don't post ereport, if lup event is due to 1717*287Smg140465 * power management. 1718*287Smg140465 */ 1719*287Smg140465 if (px_p->px_pm_flags & PX_LUP_EXPECTED) { 1720*287Smg140465 px_p->px_pm_flags &= ~PX_LUP_EXPECTED; 1721*287Smg140465 return (PX_OK); 1722*287Smg140465 } 1723*287Smg140465 1724*287Smg140465 return (PX_ERPT_SEND(pciex_oe)(rpdip, csr_base, ss_reg, derr, 1725*287Smg140465 class_name)); 1726*287Smg140465 } 1727