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) }, 257287Smg140465 { TLU_OE_BIT_DESC(LDN, non_fatal, pciex_ldn) }, 258287Smg140465 { 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 } 844*332Sjchu 845*332Sjchu /* Print register status */ 846*332Sjchu if (ss_reg & *log_mask) 847*332Sjchu DBG(DBG_ERR_INTR, rpdip, "<%x>=%16llx %s\n", 84827Sjchu status_addr, ss_reg, err_reg_tbl->msg); 84927Sjchu 85027Sjchu /* Clear the register and error */ 85127Sjchu CSR_XS(csr_base, clear_addr, ss_reg); 85227Sjchu } 85327Sjchu 85427Sjchu return (err); 85527Sjchu } 85627Sjchu 85727Sjchu /* 85827Sjchu * px_err_check_severity: 85927Sjchu * Check the severity of the fire error based on an earlier snapshot 86027Sjchu * 86127Sjchu * @param px_p leaf in which to take the snap shot. 86227Sjchu * @param derr fm err in which the ereport is to be based on 86327Sjchu * @param ss pre-allocated memory to store the snap shot. 86427Sjchu */ 86527Sjchu static int 86627Sjchu px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr, int err, int caller) 86727Sjchu { 86827Sjchu px_pec_t *pec_p = px_p->px_pec_p; 86927Sjchu boolean_t is_safeacc = B_FALSE; 870118Sjchu 871118Sjchu /* nothing to do if called with no error */ 872118Sjchu if (err == PX_OK) 873118Sjchu return (err); 87427Sjchu 87527Sjchu /* Cautious access error handling */ 87627Sjchu switch (derr->fme_flag) { 87727Sjchu case DDI_FM_ERR_EXPECTED: 87827Sjchu if (caller == PX_TRAP_CALL) { 87927Sjchu /* 88027Sjchu * for ddi_caut_get treat all events as nonfatal 88127Sjchu * The trampoline will set err_ena = 0, 88227Sjchu * err_status = NONFATAL. 88327Sjchu */ 88427Sjchu derr->fme_status = DDI_FM_NONFATAL; 88527Sjchu is_safeacc = B_TRUE; 88627Sjchu } else { 88727Sjchu /* 88827Sjchu * For ddi_caut_put treat all events as nonfatal. Here 88927Sjchu * we have the handle and can call ndi_fm_acc_err_set(). 89027Sjchu */ 89127Sjchu derr->fme_status = DDI_FM_NONFATAL; 89227Sjchu ndi_fm_acc_err_set(pec_p->pec_acc_hdl, derr); 89327Sjchu is_safeacc = B_TRUE; 89427Sjchu } 89527Sjchu break; 89627Sjchu case DDI_FM_ERR_PEEK: 89727Sjchu case DDI_FM_ERR_POKE: 89827Sjchu /* 89927Sjchu * For ddi_peek/poke treat all events as nonfatal. 90027Sjchu */ 90127Sjchu is_safeacc = B_TRUE; 90227Sjchu break; 90327Sjchu default: 90427Sjchu is_safeacc = B_FALSE; 90527Sjchu } 90627Sjchu 90727Sjchu /* 90827Sjchu * The third argument "err" is passed in as error status from checking 90927Sjchu * Fire register, re-adjust error status from safe access. 91027Sjchu */ 91127Sjchu if (is_safeacc && !(err & PX_FATAL_GOS)) 912118Sjchu return (PX_NONFATAL); 91327Sjchu 914118Sjchu return (err); 91527Sjchu } 91627Sjchu 91727Sjchu /* predefined convenience functions */ 91827Sjchu /* ARGSUSED */ 91927Sjchu int 92027Sjchu px_err_fatal_hw_handle(dev_info_t *rpdip, caddr_t csr_base, 92127Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 92227Sjchu px_err_bit_desc_t *err_bit_descr) 92327Sjchu { 92427Sjchu return (PX_FATAL_HW); 92527Sjchu } 92627Sjchu 92727Sjchu /* ARGSUSED */ 92827Sjchu int 92927Sjchu px_err_fatal_gos_handle(dev_info_t *rpdip, caddr_t csr_base, 93027Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 93127Sjchu px_err_bit_desc_t *err_bit_descr) 93227Sjchu { 93327Sjchu return (PX_FATAL_GOS); 93427Sjchu } 93527Sjchu 93627Sjchu /* ARGSUSED */ 93727Sjchu int 93827Sjchu px_err_fatal_stuck_handle(dev_info_t *rpdip, caddr_t csr_base, 93927Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 94027Sjchu px_err_bit_desc_t *err_bit_descr) 94127Sjchu { 94227Sjchu return (PX_STUCK_FATAL); 94327Sjchu } 94427Sjchu 94527Sjchu /* ARGSUSED */ 94627Sjchu int 94727Sjchu px_err_fatal_sw_handle(dev_info_t *rpdip, caddr_t csr_base, 94827Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 94927Sjchu px_err_bit_desc_t *err_bit_descr) 95027Sjchu { 95127Sjchu return (PX_FATAL_SW); 95227Sjchu } 95327Sjchu 95427Sjchu /* ARGSUSED */ 95527Sjchu int 95627Sjchu px_err_non_fatal_handle(dev_info_t *rpdip, caddr_t csr_base, 95727Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 95827Sjchu px_err_bit_desc_t *err_bit_descr) 95927Sjchu { 96027Sjchu return (PX_NONFATAL); 96127Sjchu } 96227Sjchu 96327Sjchu /* ARGSUSED */ 96427Sjchu int 96527Sjchu px_err_ok_handle(dev_info_t *rpdip, caddr_t csr_base, ddi_fm_error_t *derr, 96627Sjchu px_err_reg_desc_t *err_reg_descr, px_err_bit_desc_t *err_bit_descr) 96727Sjchu { 96827Sjchu return (PX_OK); 96927Sjchu } 97027Sjchu 97127Sjchu /* ARGSUSED */ 97227Sjchu int 97327Sjchu px_err_unknown_handle(dev_info_t *rpdip, caddr_t csr_base, ddi_fm_error_t *derr, 97427Sjchu px_err_reg_desc_t *err_reg_descr, px_err_bit_desc_t *err_bit_descr) 97527Sjchu { 97627Sjchu return (PX_ERR_UNKNOWN); 97727Sjchu } 97827Sjchu 97927Sjchu /* JBC FATAL - see io erpt doc, section 1.1 */ 98027Sjchu PX_ERPT_SEND_DEC(jbc_fatal) 98127Sjchu { 98227Sjchu char buf[FM_MAX_CLASS]; 98327Sjchu 98427Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 98527Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 98627Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 98727Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 98827Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 98927Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 99027Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 99127Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 99227Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 99327Sjchu ss_reg, 99427Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 99527Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 99627Sjchu FIRE_JBC_FEL1, DATA_TYPE_UINT64, 99727Sjchu CSR_XR(csr_base, FATAL_ERROR_LOG_1), 99827Sjchu FIRE_JBC_FEL2, DATA_TYPE_UINT64, 99927Sjchu CSR_XR(csr_base, FATAL_ERROR_LOG_2), 100027Sjchu NULL); 100127Sjchu 100227Sjchu return (PX_OK); 100327Sjchu } 100427Sjchu 100527Sjchu /* JBC MERGE - see io erpt doc, section 1.2 */ 100627Sjchu PX_ERPT_SEND_DEC(jbc_merge) 100727Sjchu { 100827Sjchu char buf[FM_MAX_CLASS]; 100927Sjchu 101027Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 101127Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 101227Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 101327Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 101427Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 101527Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 101627Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 101727Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 101827Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 101927Sjchu ss_reg, 102027Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 102127Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 102227Sjchu FIRE_JBC_MTEL, DATA_TYPE_UINT64, 102327Sjchu CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG), 102427Sjchu NULL); 102527Sjchu 102627Sjchu return (PX_OK); 102727Sjchu } 102827Sjchu 102927Sjchu /* 103027Sjchu * JBC Merge buffer nonfatal errors: 103127Sjchu * Merge buffer parity error (rd_buf): dma:read:M:nonfatal 103227Sjchu * Merge buffer parity error (wr_buf): dma:write:M:nonfatal 103327Sjchu */ 103427Sjchu /* ARGSUSED */ 103527Sjchu int 103627Sjchu px_err_jbc_merge_handle(dev_info_t *rpdip, caddr_t csr_base, 103727Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 103827Sjchu px_err_bit_desc_t *err_bit_descr) 103927Sjchu { 104027Sjchu uint64_t paddr; 104127Sjchu int ret; 104227Sjchu 104327Sjchu paddr = CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG); 104427Sjchu paddr &= MERGE_TRANSACTION_ERROR_LOG_ADDRESS_MASK; 104527Sjchu 104627Sjchu ret = px_handle_lookup( 104727Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 104827Sjchu 104927Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 105027Sjchu } 105127Sjchu 105227Sjchu /* JBC Jbusint IN - see io erpt doc, section 1.3 */ 105327Sjchu PX_ERPT_SEND_DEC(jbc_in) 105427Sjchu { 105527Sjchu char buf[FM_MAX_CLASS]; 105627Sjchu 105727Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 105827Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 105927Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 106027Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 106127Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 106227Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 106327Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 106427Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 106527Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 106627Sjchu ss_reg, 106727Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 106827Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 106927Sjchu FIRE_JBC_JITEL1, DATA_TYPE_UINT64, 107027Sjchu CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG), 107127Sjchu FIRE_JBC_JITEL2, DATA_TYPE_UINT64, 107227Sjchu CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG_2), 107327Sjchu NULL); 107427Sjchu 107527Sjchu return (PX_OK); 107627Sjchu } 107727Sjchu 107827Sjchu /* 107927Sjchu * JBC Jbusint IN nonfatal errors: PA logged in Jbusint In Transaction Error 108027Sjchu * Log Reg[42:0]. 108127Sjchu * CE async fault error: nonfatal 108227Sjchu * Jbus bus error: dma::nonfatal 108327Sjchu * Jbus unmapped error: pio|dma:rdwr:M:nonfatal 108427Sjchu * Write data parity error: pio/write:M:nonfatal 108527Sjchu * Read data parity error: pio/read:M:nonfatal 108627Sjchu * Illegal NCWR bytemask: pio:write:M:nonfatal 108727Sjchu * Illegal NCRD bytemask: pio:write:M:nonfatal 108827Sjchu * Invalid jbus transaction: nonfatal 108927Sjchu */ 109027Sjchu /* ARGSUSED */ 109127Sjchu int 109227Sjchu px_err_jbc_jbusint_in_handle(dev_info_t *rpdip, caddr_t csr_base, 109327Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 109427Sjchu px_err_bit_desc_t *err_bit_descr) 109527Sjchu { 109627Sjchu uint64_t paddr; 109727Sjchu int ret; 109827Sjchu 109927Sjchu paddr = CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG); 110027Sjchu paddr &= JBCINT_IN_TRANSACTION_ERROR_LOG_ADDRESS_MASK; 110127Sjchu 110227Sjchu ret = px_handle_lookup( 110327Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 110427Sjchu 110527Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 110627Sjchu } 110727Sjchu 110827Sjchu 110927Sjchu /* JBC Jbusint Out - see io erpt doc, section 1.4 */ 111027Sjchu PX_ERPT_SEND_DEC(jbc_out) 111127Sjchu { 111227Sjchu char buf[FM_MAX_CLASS]; 111327Sjchu 111427Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 111527Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 111627Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 111727Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 111827Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 111927Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 112027Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 112127Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 112227Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 112327Sjchu ss_reg, 112427Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 112527Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 112627Sjchu FIRE_JBC_JOTEL1, DATA_TYPE_UINT64, 112727Sjchu CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG), 112827Sjchu FIRE_JBC_JOTEL2, DATA_TYPE_UINT64, 112927Sjchu CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG_2), 113027Sjchu NULL); 113127Sjchu 113227Sjchu return (PX_OK); 113327Sjchu } 113427Sjchu 113527Sjchu /* JBC Dmcint ODCD - see io erpt doc, section 1.5 */ 113627Sjchu PX_ERPT_SEND_DEC(jbc_odcd) 113727Sjchu { 113827Sjchu char buf[FM_MAX_CLASS]; 113927Sjchu 114027Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 114127Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 114227Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 114327Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 114427Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 114527Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 114627Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 114727Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 114827Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 114927Sjchu ss_reg, 115027Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 115127Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 115227Sjchu FIRE_JBC_DMC_ODCD, DATA_TYPE_UINT64, 115327Sjchu CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG), 115427Sjchu NULL); 115527Sjchu 115627Sjchu return (PX_OK); 115727Sjchu } 115827Sjchu 115927Sjchu /* 116027Sjchu * JBC Dmcint ODCO nonfatal errer handling - 116127Sjchu * Unmapped PIO read error: pio:read:M:nonfatal 116227Sjchu * Unmapped PIO write error: pio:write:M:nonfatal 116327Sjchu * PIO data parity error: pio:write:M:nonfatal 116427Sjchu * Invalid PIO write to PCIe cfg/io, csr, ebus or i2c bus: pio:write:nonfatal 116527Sjchu * Invalid PIO read to PCIe cfg/io, csr, ebus or i2c bus: pio:read:nonfatal 116627Sjchu */ 116727Sjchu /* ARGSUSED */ 116827Sjchu int 116927Sjchu px_err_jbc_dmcint_odcd_handle(dev_info_t *rpdip, caddr_t csr_base, 117027Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 117127Sjchu px_err_bit_desc_t *err_bit_descr) 117227Sjchu { 117327Sjchu uint64_t paddr; 117427Sjchu int ret; 117527Sjchu 117627Sjchu paddr = CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG); 117727Sjchu paddr &= DMCINT_ODCD_ERROR_LOG_ADDRESS_MASK; 117827Sjchu 117927Sjchu ret = px_handle_lookup( 118027Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 118127Sjchu 118227Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 118327Sjchu } 118427Sjchu 118527Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */ 118627Sjchu PX_ERPT_SEND_DEC(jbc_idc) 118727Sjchu { 118827Sjchu char buf[FM_MAX_CLASS]; 118927Sjchu 119027Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 119127Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 119227Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 119327Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 119427Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 119527Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 119627Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 119727Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 119827Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 119927Sjchu ss_reg, 120027Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 120127Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 120227Sjchu FIRE_JBC_DMC_IDC, DATA_TYPE_UINT64, 120327Sjchu CSR_XR(csr_base, DMCINT_IDC_ERROR_LOG), 120427Sjchu NULL); 120527Sjchu 120627Sjchu return (PX_OK); 120727Sjchu } 120827Sjchu 120927Sjchu /* JBC CSR - see io erpt doc, section 1.7 */ 121027Sjchu PX_ERPT_SEND_DEC(jbc_csr) 121127Sjchu { 121227Sjchu char buf[FM_MAX_CLASS]; 121327Sjchu 121427Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 121527Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 121627Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 121727Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 121827Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 121927Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 122027Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 122127Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 122227Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 122327Sjchu ss_reg, 122427Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 122527Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 122627Sjchu "jbc-error-reg", DATA_TYPE_UINT64, 122727Sjchu CSR_XR(csr_base, CSR_ERROR_LOG), 122827Sjchu NULL); 122927Sjchu 123027Sjchu return (PX_OK); 123127Sjchu } 123227Sjchu 123327Sjchu /* 123427Sjchu * JBC CSR errer handling - 123527Sjchu * Ebus ready timeout error: pio:rdwr:M:nonfatal 123627Sjchu */ 123727Sjchu /* ARGSUSED */ 123827Sjchu int 123927Sjchu px_err_jbc_csr_handle(dev_info_t *rpdip, caddr_t csr_base, 124027Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 124127Sjchu px_err_bit_desc_t *err_bit_descr) 124227Sjchu { 124327Sjchu uint64_t paddr; 124427Sjchu int ret; 124527Sjchu 124627Sjchu paddr = CSR_XR(csr_base, CSR_ERROR_LOG); 124727Sjchu paddr &= CSR_ERROR_LOG_ADDRESS_MASK; 124827Sjchu 124927Sjchu ret = px_handle_lookup( 125027Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 125127Sjchu 125227Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 125327Sjchu } 125427Sjchu 125527Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */ 125627Sjchu 125727Sjchu /* DMC IMU RDS - see io erpt doc, section 2.1 */ 125827Sjchu PX_ERPT_SEND_DEC(imu_rds) 125927Sjchu { 126027Sjchu char buf[FM_MAX_CLASS]; 126127Sjchu 126227Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 126327Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 126427Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 126527Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 126627Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64, 126727Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 126827Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 126927Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 127027Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 127127Sjchu ss_reg, 127227Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 127327Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 127427Sjchu FIRE_IMU_RDS, DATA_TYPE_UINT64, 127527Sjchu CSR_XR(csr_base, IMU_RDS_ERROR_LOG), 127627Sjchu NULL); 127727Sjchu 127827Sjchu return (PX_OK); 127927Sjchu } 128027Sjchu 128127Sjchu /* imu function to handle all Received but Not Enabled errors */ 128227Sjchu /* ARGSUSED */ 128327Sjchu int 128427Sjchu px_err_imu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base, 128527Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 128627Sjchu px_err_bit_desc_t *err_bit_descr) 128727Sjchu { 128827Sjchu uint64_t imu_log_enable, imu_intr_enable; 128927Sjchu int mask = BITMASK(err_bit_descr->bit); 129027Sjchu int err = PX_NONFATAL; 129127Sjchu 129227Sjchu imu_log_enable = CSR_XR(csr_base, err_reg_descr->log_addr); 129327Sjchu imu_intr_enable = CSR_XR(csr_base, err_reg_descr->enable_addr); 129427Sjchu 129527Sjchu if (imu_log_enable & imu_intr_enable & mask) { 129627Sjchu err = PX_FATAL_SW; 129727Sjchu } else { 129827Sjchu /* 129927Sjchu * S/W bug - this error should always be enabled 130027Sjchu */ 130127Sjchu 130227Sjchu /* enable error & intr reporting for this bit */ 130327Sjchu CSR_XS(csr_base, IMU_ERROR_LOG_ENABLE, imu_log_enable | mask); 130427Sjchu CSR_XS(csr_base, IMU_INTERRUPT_ENABLE, imu_intr_enable | mask); 130527Sjchu err = PX_NONFATAL; 130627Sjchu } 130727Sjchu 130827Sjchu return (err); 130927Sjchu } 131027Sjchu 1311118Sjchu /* 1312118Sjchu * No platforms uses PME. Any PME received is simply logged 1313118Sjchu * for analysis. 1314118Sjchu */ 1315118Sjchu /* ARGSUSED */ 1316118Sjchu int 1317118Sjchu px_err_imu_pme_handle(dev_info_t *rpdip, caddr_t csr_base, 1318118Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1319118Sjchu px_err_bit_desc_t *err_bit_descr) 1320118Sjchu { 1321118Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 1322118Sjchu 1323118Sjchu px_p->px_pme_ignored++; 1324118Sjchu return (PX_NONFATAL); 1325118Sjchu } 1326118Sjchu 132727Sjchu /* handle EQ overflow */ 132827Sjchu /* ARGSUSED */ 132927Sjchu int 133027Sjchu px_err_imu_eq_ovfl_handle(dev_info_t *rpdip, caddr_t csr_base, 133127Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 133227Sjchu px_err_bit_desc_t *err_bit_descr) 133327Sjchu { 133427Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 133527Sjchu px_msiq_state_t *msiq_state_p = &px_p->px_ib_p->ib_msiq_state; 133627Sjchu msiqid_t eqno; 133727Sjchu pci_msiq_state_t msiq_state; 133827Sjchu int err = PX_NONFATAL; 133927Sjchu int i; 134027Sjchu 134127Sjchu eqno = msiq_state_p->msiq_1st_msiq_id; 134227Sjchu for (i = 0; i < msiq_state_p->msiq_cnt; i++) { 134327Sjchu if (px_lib_msiq_getstate(rpdip, eqno, &msiq_state) == 134427Sjchu DDI_SUCCESS) { 134527Sjchu if (msiq_state == PCI_MSIQ_STATE_ERROR) { 134627Sjchu err = PX_FATAL_SW; 134727Sjchu } 134827Sjchu } 134927Sjchu } 135027Sjchu 135127Sjchu return (err); 135227Sjchu } 135327Sjchu 135427Sjchu /* DMC IMU SCS - see io erpt doc, section 2.2 */ 135527Sjchu PX_ERPT_SEND_DEC(imu_scs) 135627Sjchu { 135727Sjchu char buf[FM_MAX_CLASS]; 135827Sjchu 135927Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 136027Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 136127Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 136227Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 136327Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64, 136427Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 136527Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 136627Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 136727Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 136827Sjchu ss_reg, 136927Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 137027Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 137127Sjchu FIRE_IMU_SCS, DATA_TYPE_UINT64, 137227Sjchu CSR_XR(csr_base, IMU_SCS_ERROR_LOG), 137327Sjchu NULL); 137427Sjchu 137527Sjchu return (PX_OK); 137627Sjchu } 137727Sjchu 137827Sjchu /* DMC IMU - see io erpt doc, section 2.3 */ 137927Sjchu PX_ERPT_SEND_DEC(imu) 138027Sjchu { 138127Sjchu char buf[FM_MAX_CLASS]; 138227Sjchu 138327Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 138427Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 138527Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 138627Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 138727Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64, 138827Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 138927Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 139027Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 139127Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 139227Sjchu ss_reg, 139327Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 139427Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 139527Sjchu NULL); 139627Sjchu 139727Sjchu return (PX_OK); 139827Sjchu } 139927Sjchu 140027Sjchu /* DMC MMU TFAR/TFSR - see io erpt doc, section 2.4 */ 140127Sjchu PX_ERPT_SEND_DEC(mmu_tfar_tfsr) 140227Sjchu { 140327Sjchu char buf[FM_MAX_CLASS]; 140427Sjchu 140527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 140627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 140727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 140827Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 140927Sjchu FIRE_MMU_ELE, DATA_TYPE_UINT64, 141027Sjchu CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE), 141127Sjchu FIRE_MMU_IE, DATA_TYPE_UINT64, 141227Sjchu CSR_XR(csr_base, MMU_INTERRUPT_ENABLE), 141327Sjchu FIRE_MMU_IS, DATA_TYPE_UINT64, 141427Sjchu ss_reg, 141527Sjchu FIRE_MMU_ESS, DATA_TYPE_UINT64, 141627Sjchu CSR_XR(csr_base, MMU_ERROR_STATUS_SET), 141727Sjchu FIRE_MMU_TFAR, DATA_TYPE_UINT64, 141827Sjchu CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS), 141927Sjchu FIRE_MMU_TFSR, DATA_TYPE_UINT64, 142027Sjchu CSR_XR(csr_base, MMU_TRANSLATION_FAULT_STATUS), 142127Sjchu NULL); 142227Sjchu 142327Sjchu return (PX_OK); 142427Sjchu } 142527Sjchu 142627Sjchu /* DMC MMU - see io erpt doc, section 2.5 */ 142727Sjchu PX_ERPT_SEND_DEC(mmu) 142827Sjchu { 142927Sjchu char buf[FM_MAX_CLASS]; 143027Sjchu 143127Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 143227Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 143327Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 143427Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 143527Sjchu FIRE_MMU_ELE, DATA_TYPE_UINT64, 143627Sjchu CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE), 143727Sjchu FIRE_MMU_IE, DATA_TYPE_UINT64, 143827Sjchu CSR_XR(csr_base, MMU_INTERRUPT_ENABLE), 143927Sjchu FIRE_MMU_IS, DATA_TYPE_UINT64, 144027Sjchu ss_reg, 144127Sjchu FIRE_MMU_ESS, DATA_TYPE_UINT64, 144227Sjchu CSR_XR(csr_base, MMU_ERROR_STATUS_SET), 144327Sjchu NULL); 144427Sjchu 144527Sjchu return (PX_OK); 144627Sjchu } 144727Sjchu 144827Sjchu /* imu function to handle all Received but Not Enabled errors */ 144927Sjchu int 145027Sjchu px_err_mmu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base, 145127Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 145227Sjchu px_err_bit_desc_t *err_bit_descr) 145327Sjchu { 1454260Set142600 uint64_t mmu_log_enable, mmu_intr_enable; 145527Sjchu uint64_t mask = BITMASK(err_bit_descr->bit); 1456260Set142600 uint64_t mmu_tfa, mmu_ctrl; 1457260Set142600 uint64_t mmu_enable_bit = 0; 145827Sjchu int err = PX_NONFATAL; 145927Sjchu int ret; 146027Sjchu 146127Sjchu mmu_log_enable = CSR_XR(csr_base, err_reg_descr->log_addr); 146227Sjchu mmu_intr_enable = CSR_XR(csr_base, err_reg_descr->enable_addr); 146327Sjchu 146427Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 1465260Set142600 mmu_ctrl = CSR_XR(csr_base, MMU_CONTROL_AND_STATUS); 146627Sjchu 1467260Set142600 switch (err_bit_descr->bit) { 1468260Set142600 case MMU_INTERRUPT_STATUS_BYP_ERR_P: 1469260Set142600 mmu_enable_bit = BITMASK(MMU_CONTROL_AND_STATUS_BE); 1470260Set142600 break; 1471260Set142600 case MMU_INTERRUPT_STATUS_TRN_ERR_P: 1472260Set142600 mmu_enable_bit = BITMASK(MMU_CONTROL_AND_STATUS_TE); 1473260Set142600 break; 1474260Set142600 default: 1475260Set142600 mmu_enable_bit = 0; 1476260Set142600 break; 1477260Set142600 } 1478260Set142600 1479260Set142600 /* 1480260Set142600 * If the interrupts are enabled and Translation/Bypass Enable bit 1481260Set142600 * was set, then panic. This error should not have occured. 1482260Set142600 */ 1483260Set142600 if (mmu_log_enable & mmu_intr_enable & 1484260Set142600 (mmu_ctrl & mmu_enable_bit)) { 148527Sjchu err = PX_FATAL_SW; 148627Sjchu } else { 148727Sjchu ret = px_handle_lookup( 148827Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 148927Sjchu err = (ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL; 149027Sjchu 149127Sjchu /* 149227Sjchu * S/W bug - this error should always be enabled 149327Sjchu */ 149427Sjchu 149527Sjchu /* enable error & intr reporting for this bit */ 149627Sjchu CSR_XS(csr_base, MMU_ERROR_LOG_ENABLE, mmu_log_enable | mask); 149727Sjchu CSR_XS(csr_base, MMU_INTERRUPT_ENABLE, mmu_intr_enable | mask); 1498260Set142600 1499260Set142600 /* enable translation access/bypass enable */ 1500260Set142600 CSR_XS(csr_base, MMU_CONTROL_AND_STATUS, 1501260Set142600 mmu_ctrl | mmu_enable_bit); 150227Sjchu } 150327Sjchu 150427Sjchu return (err); 150527Sjchu } 150627Sjchu 150727Sjchu /* Generic error handling functions that involve MMU Translation Fault Addr */ 150827Sjchu /* ARGSUSED */ 150927Sjchu int 151027Sjchu px_err_mmu_tfa_handle(dev_info_t *rpdip, caddr_t csr_base, 151127Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 151227Sjchu px_err_bit_desc_t *err_bit_descr) 151327Sjchu { 151427Sjchu uint64_t mmu_tfa; 151527Sjchu uint_t ret; 151627Sjchu 151727Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 151827Sjchu ret = px_handle_lookup( 151927Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 152027Sjchu 152127Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 152227Sjchu } 152327Sjchu 152427Sjchu /* MMU Table walk errors */ 152527Sjchu /* ARGSUSED */ 152627Sjchu int 152727Sjchu px_err_mmu_tblwlk_handle(dev_info_t *rpdip, caddr_t csr_base, 152827Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 152927Sjchu px_err_bit_desc_t *err_bit_descr) 153027Sjchu { 153127Sjchu uint64_t mmu_tfa; 153227Sjchu uint_t ret; 153327Sjchu 153427Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 153527Sjchu ret = px_handle_lookup( 153627Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 153727Sjchu 153827Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 153927Sjchu } 154027Sjchu 1541118Sjchu /* 1542118Sjchu * TLU LUP event - power management code is interested in this event. 1543118Sjchu */ 1544118Sjchu /* ARGSUSED */ 1545118Sjchu int 1546118Sjchu px_err_tlu_lup_handle(dev_info_t *rpdip, caddr_t csr_base, 1547118Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1548118Sjchu px_err_bit_desc_t *err_bit_descr) 1549118Sjchu { 1550118Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 1551118Sjchu 1552118Sjchu /* 1553118Sjchu * Existense of pm info indicates the power management 1554118Sjchu * is interested in this event. 1555118Sjchu */ 1556118Sjchu if (!PCIE_PMINFO(rpdip) || !PCIE_NEXUS_PMINFO(rpdip)) 1557118Sjchu return (PX_OK); 1558118Sjchu 1559118Sjchu mutex_enter(&px_p->px_lup_lock); 1560118Sjchu px_p->px_lupsoft_pending++; 1561118Sjchu mutex_exit(&px_p->px_lup_lock); 1562118Sjchu 1563118Sjchu /* 1564118Sjchu * Post a soft interrupt to wake up threads waiting for this. 1565118Sjchu */ 1566118Sjchu ddi_trigger_softintr(px_p->px_lupsoft_id); 1567118Sjchu 1568118Sjchu return (PX_OK); 1569118Sjchu } 1570118Sjchu 157127Sjchu /* PEC ILU none - see io erpt doc, section 3.1 */ 157227Sjchu PX_ERPT_SEND_DEC(pec_ilu) 157327Sjchu { 157427Sjchu char buf[FM_MAX_CLASS]; 157527Sjchu 157627Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 157727Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 157827Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 157927Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 158027Sjchu FIRE_ILU_ELE, DATA_TYPE_UINT64, 158127Sjchu CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE), 158227Sjchu FIRE_ILU_IE, DATA_TYPE_UINT64, 158327Sjchu CSR_XR(csr_base, ILU_INTERRUPT_ENABLE), 158427Sjchu FIRE_ILU_IS, DATA_TYPE_UINT64, 158527Sjchu ss_reg, 158627Sjchu FIRE_ILU_ESS, DATA_TYPE_UINT64, 158727Sjchu CSR_XR(csr_base, ILU_ERROR_STATUS_SET), 158827Sjchu NULL); 158927Sjchu 159027Sjchu return (PX_OK); 159127Sjchu } 159227Sjchu 159327Sjchu /* PCI-E Correctable Errors - see io erpt doc, section 3.6 */ 159427Sjchu PX_ERPT_SEND_DEC(pciex_ce) 159527Sjchu { 159627Sjchu char buf[FM_MAX_CLASS]; 159727Sjchu 159827Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 159927Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 160027Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 160127Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 160227Sjchu FIRE_TLU_CELE, DATA_TYPE_UINT64, 160327Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE), 160427Sjchu FIRE_TLU_CIE, DATA_TYPE_UINT64, 160527Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE), 160627Sjchu FIRE_TLU_CIS, DATA_TYPE_UINT64, 160727Sjchu ss_reg, 160827Sjchu FIRE_TLU_CESS, DATA_TYPE_UINT64, 160927Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_STATUS_SET), 161027Sjchu NULL); 161127Sjchu 161227Sjchu return (PX_OK); 161327Sjchu } 161427Sjchu 161527Sjchu /* TLU Other Event Status (receive only) - see io erpt doc, section 3.7 */ 161627Sjchu PX_ERPT_SEND_DEC(pciex_rx_oe) 161727Sjchu { 161827Sjchu char buf[FM_MAX_CLASS]; 161927Sjchu 162027Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 162127Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 162227Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 162327Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 162427Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 162527Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 162627Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 162727Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 162827Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 162927Sjchu ss_reg, 163027Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 163127Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 163227Sjchu FIRE_TLU_RUEH1L, DATA_TYPE_UINT64, 163327Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG), 1634260Set142600 FIRE_TLU_RUEH2L, DATA_TYPE_UINT64, 163527Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG), 163627Sjchu NULL); 163727Sjchu 163827Sjchu return (PX_OK); 163927Sjchu } 164027Sjchu 164127Sjchu /* TLU Other Event Status (rx + tx) - see io erpt doc, section 3.8 */ 164227Sjchu PX_ERPT_SEND_DEC(pciex_rx_tx_oe) 164327Sjchu { 164427Sjchu char buf[FM_MAX_CLASS]; 164527Sjchu 164627Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 164727Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 164827Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 164927Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 165027Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 165127Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 165227Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 165327Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 165427Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 165527Sjchu ss_reg, 165627Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 165727Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 165827Sjchu FIRE_TLU_ROEEH1L, DATA_TYPE_UINT64, 165927Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG), 166027Sjchu FIRE_TLU_ROEEH2L, DATA_TYPE_UINT64, 166127Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG), 166227Sjchu FIRE_TLU_TOEEH1L, DATA_TYPE_UINT64, 166327Sjchu CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG), 1664260Set142600 FIRE_TLU_TOEEH2L, DATA_TYPE_UINT64, 166527Sjchu CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG), 166627Sjchu NULL); 166727Sjchu 166827Sjchu return (PX_OK); 166927Sjchu } 167027Sjchu 167127Sjchu /* TLU Other Event - see io erpt doc, section 3.9 */ 167227Sjchu PX_ERPT_SEND_DEC(pciex_oe) 167327Sjchu { 1674287Smg140465 char buf[FM_MAX_CLASS]; 167527Sjchu 167627Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 167727Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 167827Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 167927Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 168027Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 168127Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 168227Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 168327Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 168427Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 168527Sjchu ss_reg, 168627Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 168727Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 168827Sjchu NULL); 168927Sjchu 169027Sjchu return (PX_OK); 169127Sjchu } 1692287Smg140465 1693287Smg140465 /* TLU Other Event - Link Down see io erpt doc, section 3.9 */ 1694287Smg140465 PX_ERPT_SEND_DEC(pciex_ldn) 1695287Smg140465 { 1696287Smg140465 px_t *px_p = DIP_TO_STATE(rpdip); 1697287Smg140465 1698287Smg140465 /* 1699287Smg140465 * Don't post ereport, if ldn event is due to 1700287Smg140465 * power management. 1701287Smg140465 */ 1702287Smg140465 if (px_p->px_pm_flags & PX_LDN_EXPECTED) { 1703287Smg140465 px_p->px_pm_flags &= ~PX_LDN_EXPECTED; 1704287Smg140465 return (PX_OK); 1705287Smg140465 } 1706287Smg140465 return (PX_ERPT_SEND(pciex_oe)(rpdip, csr_base, ss_reg, derr, 1707287Smg140465 class_name)); 1708287Smg140465 1709287Smg140465 } 1710287Smg140465 1711287Smg140465 /* TLU Other Event - Link Up see io erpt doc, section 3.9 */ 1712287Smg140465 PX_ERPT_SEND_DEC(pciex_lup) 1713287Smg140465 { 1714287Smg140465 px_t *px_p = DIP_TO_STATE(rpdip); 1715287Smg140465 1716287Smg140465 /* 1717287Smg140465 * Don't post ereport, if lup event is due to 1718287Smg140465 * power management. 1719287Smg140465 */ 1720287Smg140465 if (px_p->px_pm_flags & PX_LUP_EXPECTED) { 1721287Smg140465 px_p->px_pm_flags &= ~PX_LUP_EXPECTED; 1722287Smg140465 return (PX_OK); 1723287Smg140465 } 1724287Smg140465 1725287Smg140465 return (PX_ERPT_SEND(pciex_oe)(rpdip, csr_base, ss_reg, derr, 1726287Smg140465 class_name)); 1727287Smg140465 } 1728