1*10187SKrishna.Elango@Sun.COM /* 2*10187SKrishna.Elango@Sun.COM * CDDL HEADER START 3*10187SKrishna.Elango@Sun.COM * 4*10187SKrishna.Elango@Sun.COM * The contents of this file are subject to the terms of the 5*10187SKrishna.Elango@Sun.COM * Common Development and Distribution License (the "License"). 6*10187SKrishna.Elango@Sun.COM * You may not use this file except in compliance with the License. 7*10187SKrishna.Elango@Sun.COM * 8*10187SKrishna.Elango@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*10187SKrishna.Elango@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*10187SKrishna.Elango@Sun.COM * See the License for the specific language governing permissions 11*10187SKrishna.Elango@Sun.COM * and limitations under the License. 12*10187SKrishna.Elango@Sun.COM * 13*10187SKrishna.Elango@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*10187SKrishna.Elango@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*10187SKrishna.Elango@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*10187SKrishna.Elango@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*10187SKrishna.Elango@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*10187SKrishna.Elango@Sun.COM * 19*10187SKrishna.Elango@Sun.COM * CDDL HEADER END 20*10187SKrishna.Elango@Sun.COM */ 21*10187SKrishna.Elango@Sun.COM /* 22*10187SKrishna.Elango@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*10187SKrishna.Elango@Sun.COM * Use is subject to license terms. 24*10187SKrishna.Elango@Sun.COM */ 25*10187SKrishna.Elango@Sun.COM 26*10187SKrishna.Elango@Sun.COM /* x86 specific code used by the pcieb driver */ 27*10187SKrishna.Elango@Sun.COM 28*10187SKrishna.Elango@Sun.COM #include <sys/types.h> 29*10187SKrishna.Elango@Sun.COM #include <sys/ddi.h> 30*10187SKrishna.Elango@Sun.COM #include <sys/kmem.h> 31*10187SKrishna.Elango@Sun.COM #include <sys/sysmacros.h> 32*10187SKrishna.Elango@Sun.COM #include <sys/sunddi.h> 33*10187SKrishna.Elango@Sun.COM #include <sys/sunndi.h> 34*10187SKrishna.Elango@Sun.COM #include <sys/pcie.h> 35*10187SKrishna.Elango@Sun.COM #include <sys/pci_cap.h> 36*10187SKrishna.Elango@Sun.COM #include <sys/pcie_impl.h> 37*10187SKrishna.Elango@Sun.COM #include <sys/pcie_acpi.h> 38*10187SKrishna.Elango@Sun.COM #include <sys/hotplug/hpctrl.h> 39*10187SKrishna.Elango@Sun.COM #include <io/pciex/pcieb.h> 40*10187SKrishna.Elango@Sun.COM #include <io/pciex/pcie_nb5000.h> 41*10187SKrishna.Elango@Sun.COM 42*10187SKrishna.Elango@Sun.COM /* Flag to turn off intel error handling workarounds */ 43*10187SKrishna.Elango@Sun.COM int pcieb_intel_workaround_disable = 0; 44*10187SKrishna.Elango@Sun.COM 45*10187SKrishna.Elango@Sun.COM void 46*10187SKrishna.Elango@Sun.COM pcieb_peekpoke_cb(dev_info_t *dip, ddi_fm_error_t *derr) { 47*10187SKrishna.Elango@Sun.COM (void) pf_scan_fabric(dip, derr, NULL); 48*10187SKrishna.Elango@Sun.COM } 49*10187SKrishna.Elango@Sun.COM 50*10187SKrishna.Elango@Sun.COM int 51*10187SKrishna.Elango@Sun.COM pcieb_plat_peekpoke(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop, 52*10187SKrishna.Elango@Sun.COM void *arg, void *result) 53*10187SKrishna.Elango@Sun.COM { 54*10187SKrishna.Elango@Sun.COM pcieb_devstate_t *pcieb = ddi_get_soft_state(pcieb_state, 55*10187SKrishna.Elango@Sun.COM ddi_get_instance(dip)); 56*10187SKrishna.Elango@Sun.COM 57*10187SKrishna.Elango@Sun.COM if (!PCIE_IS_RP(PCIE_DIP2BUS(dip))) 58*10187SKrishna.Elango@Sun.COM return (ddi_ctlops(dip, rdip, ctlop, arg, result)); 59*10187SKrishna.Elango@Sun.COM 60*10187SKrishna.Elango@Sun.COM return (pci_peekpoke_check(dip, rdip, ctlop, arg, result, 61*10187SKrishna.Elango@Sun.COM ddi_ctlops, &pcieb->pcieb_err_mutex, 62*10187SKrishna.Elango@Sun.COM &pcieb->pcieb_peek_poke_mutex, 63*10187SKrishna.Elango@Sun.COM pcieb_peekpoke_cb)); 64*10187SKrishna.Elango@Sun.COM } 65*10187SKrishna.Elango@Sun.COM 66*10187SKrishna.Elango@Sun.COM /* x86 specific workarounds needed at the end of pcieb attach */ 67*10187SKrishna.Elango@Sun.COM void 68*10187SKrishna.Elango@Sun.COM pcieb_plat_attach_workaround(dev_info_t *dip) 69*10187SKrishna.Elango@Sun.COM { 70*10187SKrishna.Elango@Sun.COM /* Must apply workaround only after all initialization is done */ 71*10187SKrishna.Elango@Sun.COM pcieb_intel_error_workaround(dip); 72*10187SKrishna.Elango@Sun.COM pcieb_intel_mps_workaround(dip); 73*10187SKrishna.Elango@Sun.COM 74*10187SKrishna.Elango@Sun.COM } 75*10187SKrishna.Elango@Sun.COM 76*10187SKrishna.Elango@Sun.COM /* Workarounds to enable error handling on certain Intel chipsets */ 77*10187SKrishna.Elango@Sun.COM void 78*10187SKrishna.Elango@Sun.COM pcieb_intel_error_workaround(dev_info_t *dip) 79*10187SKrishna.Elango@Sun.COM { 80*10187SKrishna.Elango@Sun.COM pcieb_devstate_t *pcieb = ddi_get_soft_state(pcieb_state, 81*10187SKrishna.Elango@Sun.COM ddi_get_instance(dip)); 82*10187SKrishna.Elango@Sun.COM 83*10187SKrishna.Elango@Sun.COM pcieb_intel_serr_workaround(dip, pcieb->pcieb_no_aer_msi); 84*10187SKrishna.Elango@Sun.COM pcieb_intel_rber_workaround(dip); 85*10187SKrishna.Elango@Sun.COM pcieb_intel_sw_workaround(dip); 86*10187SKrishna.Elango@Sun.COM } 87*10187SKrishna.Elango@Sun.COM 88*10187SKrishna.Elango@Sun.COM int 89*10187SKrishna.Elango@Sun.COM pcieb_plat_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op, 90*10187SKrishna.Elango@Sun.COM ddi_intr_handle_impl_t *hdlp, void *result) 91*10187SKrishna.Elango@Sun.COM { 92*10187SKrishna.Elango@Sun.COM return (i_ddi_intr_ops(dip, rdip, intr_op, hdlp, result)); 93*10187SKrishna.Elango@Sun.COM } 94*10187SKrishna.Elango@Sun.COM 95*10187SKrishna.Elango@Sun.COM /* shpc is not supported on x86 */ 96*10187SKrishna.Elango@Sun.COM /*ARGSUSED*/ 97*10187SKrishna.Elango@Sun.COM int 98*10187SKrishna.Elango@Sun.COM pcieb_plat_pcishpc_probe(dev_info_t *dip, ddi_acc_handle_t config_handle) 99*10187SKrishna.Elango@Sun.COM { 100*10187SKrishna.Elango@Sun.COM return (DDI_FAILURE); 101*10187SKrishna.Elango@Sun.COM } 102*10187SKrishna.Elango@Sun.COM 103*10187SKrishna.Elango@Sun.COM /* 104*10187SKrishna.Elango@Sun.COM * Dummy functions to get around the fact that there's no shpc module on x86 105*10187SKrishna.Elango@Sun.COM * today 106*10187SKrishna.Elango@Sun.COM */ 107*10187SKrishna.Elango@Sun.COM /*ARGSUSED*/ 108*10187SKrishna.Elango@Sun.COM int 109*10187SKrishna.Elango@Sun.COM pcishpc_init(dev_info_t *dip) 110*10187SKrishna.Elango@Sun.COM { 111*10187SKrishna.Elango@Sun.COM return (DDI_FAILURE); 112*10187SKrishna.Elango@Sun.COM } 113*10187SKrishna.Elango@Sun.COM 114*10187SKrishna.Elango@Sun.COM /*ARGSUSED*/ 115*10187SKrishna.Elango@Sun.COM int 116*10187SKrishna.Elango@Sun.COM pcishpc_uninit(dev_info_t *dip) 117*10187SKrishna.Elango@Sun.COM { 118*10187SKrishna.Elango@Sun.COM return (DDI_FAILURE); 119*10187SKrishna.Elango@Sun.COM } 120*10187SKrishna.Elango@Sun.COM 121*10187SKrishna.Elango@Sun.COM /*ARGSUSED*/ 122*10187SKrishna.Elango@Sun.COM int 123*10187SKrishna.Elango@Sun.COM pcishpc_intr(dev_info_t *dip) 124*10187SKrishna.Elango@Sun.COM { 125*10187SKrishna.Elango@Sun.COM return (DDI_INTR_UNCLAIMED); 126*10187SKrishna.Elango@Sun.COM } 127*10187SKrishna.Elango@Sun.COM 128*10187SKrishna.Elango@Sun.COM /*ARGSUSED*/ 129*10187SKrishna.Elango@Sun.COM boolean_t 130*10187SKrishna.Elango@Sun.COM pcieb_plat_pwr_disable(dev_info_t *dip) 131*10187SKrishna.Elango@Sun.COM { 132*10187SKrishna.Elango@Sun.COM /* Always disable on x86 */ 133*10187SKrishna.Elango@Sun.COM return (B_TRUE); 134*10187SKrishna.Elango@Sun.COM } 135*10187SKrishna.Elango@Sun.COM 136*10187SKrishna.Elango@Sun.COM boolean_t 137*10187SKrishna.Elango@Sun.COM pcieb_plat_msi_supported(dev_info_t *dip) 138*10187SKrishna.Elango@Sun.COM { 139*10187SKrishna.Elango@Sun.COM pcie_bus_t *bus_p = PCIE_DIP2UPBUS(dip); 140*10187SKrishna.Elango@Sun.COM uint16_t vendor_id, device_id; 141*10187SKrishna.Elango@Sun.COM vendor_id = bus_p->bus_dev_ven_id & 0xFFFF; 142*10187SKrishna.Elango@Sun.COM device_id = bus_p->bus_dev_ven_id >> 16; 143*10187SKrishna.Elango@Sun.COM 144*10187SKrishna.Elango@Sun.COM /* 145*10187SKrishna.Elango@Sun.COM * Intel ESB2 switches have a errata which prevents using MSIs 146*10187SKrishna.Elango@Sun.COM * for hotplug. 147*10187SKrishna.Elango@Sun.COM */ 148*10187SKrishna.Elango@Sun.COM return (((vendor_id == INTEL_VENDOR_ID) && 149*10187SKrishna.Elango@Sun.COM INTEL_ESB2_SW_PCIE_DEV_ID(device_id)) ? B_FALSE : B_TRUE); 150*10187SKrishna.Elango@Sun.COM } 151*10187SKrishna.Elango@Sun.COM 152*10187SKrishna.Elango@Sun.COM void 153*10187SKrishna.Elango@Sun.COM pcieb_plat_intr_attach(pcieb_devstate_t *pcieb) 154*10187SKrishna.Elango@Sun.COM { 155*10187SKrishna.Elango@Sun.COM /* 156*10187SKrishna.Elango@Sun.COM * _OSC initialization needs to be done before interrupts are 157*10187SKrishna.Elango@Sun.COM * initialized. 158*10187SKrishna.Elango@Sun.COM */ 159*10187SKrishna.Elango@Sun.COM pcieb_init_osc(pcieb->pcieb_dip); 160*10187SKrishna.Elango@Sun.COM } 161*10187SKrishna.Elango@Sun.COM 162*10187SKrishna.Elango@Sun.COM void 163*10187SKrishna.Elango@Sun.COM pcieb_plat_initchild(dev_info_t *child) 164*10187SKrishna.Elango@Sun.COM { 165*10187SKrishna.Elango@Sun.COM struct ddi_parent_private_data *pdptr; 166*10187SKrishna.Elango@Sun.COM if (ddi_getprop(DDI_DEV_T_NONE, child, DDI_PROP_DONTPASS, "interrupts", 167*10187SKrishna.Elango@Sun.COM -1) != -1) { 168*10187SKrishna.Elango@Sun.COM pdptr = kmem_zalloc((sizeof (struct ddi_parent_private_data) + 169*10187SKrishna.Elango@Sun.COM sizeof (struct intrspec)), KM_SLEEP); 170*10187SKrishna.Elango@Sun.COM pdptr->par_intr = (struct intrspec *)(pdptr + 1); 171*10187SKrishna.Elango@Sun.COM pdptr->par_nintr = 1; 172*10187SKrishna.Elango@Sun.COM ddi_set_parent_data(child, pdptr); 173*10187SKrishna.Elango@Sun.COM } else 174*10187SKrishna.Elango@Sun.COM ddi_set_parent_data(child, NULL); 175*10187SKrishna.Elango@Sun.COM } 176*10187SKrishna.Elango@Sun.COM 177*10187SKrishna.Elango@Sun.COM void 178*10187SKrishna.Elango@Sun.COM pcieb_plat_uninitchild(dev_info_t *child) 179*10187SKrishna.Elango@Sun.COM { 180*10187SKrishna.Elango@Sun.COM struct ddi_parent_private_data *pdptr; 181*10187SKrishna.Elango@Sun.COM 182*10187SKrishna.Elango@Sun.COM if ((pdptr = ddi_get_parent_data(child)) != NULL) 183*10187SKrishna.Elango@Sun.COM kmem_free(pdptr, (sizeof (*pdptr) + sizeof (struct intrspec))); 184*10187SKrishna.Elango@Sun.COM 185*10187SKrishna.Elango@Sun.COM ddi_set_parent_data(child, NULL); 186*10187SKrishna.Elango@Sun.COM } 187*10187SKrishna.Elango@Sun.COM 188*10187SKrishna.Elango@Sun.COM /* _OSC related */ 189*10187SKrishna.Elango@Sun.COM void 190*10187SKrishna.Elango@Sun.COM pcieb_init_osc(dev_info_t *devi) { 191*10187SKrishna.Elango@Sun.COM pcie_bus_t *bus_p = PCIE_DIP2UPBUS(devi); 192*10187SKrishna.Elango@Sun.COM uint32_t osc_flags = OSC_CONTROL_PCIE_ADV_ERR; 193*10187SKrishna.Elango@Sun.COM 194*10187SKrishna.Elango@Sun.COM /* 195*10187SKrishna.Elango@Sun.COM * Call _OSC method for 2 reasons: 196*10187SKrishna.Elango@Sun.COM * 1. Hotplug: To determine if it is native or ACPI mode. 197*10187SKrishna.Elango@Sun.COM * 198*10187SKrishna.Elango@Sun.COM * 2. Error handling: Inform firmware that OS can support AER error 199*10187SKrishna.Elango@Sun.COM * handling. Currently we don't care for what the BIOS response was 200*10187SKrishna.Elango@Sun.COM * and instead setup interrupts for error handling as if it were 201*10187SKrishna.Elango@Sun.COM * supported. 202*10187SKrishna.Elango@Sun.COM * 203*10187SKrishna.Elango@Sun.COM * For hotpluggable slots the _OSC method has already been called as 204*10187SKrishna.Elango@Sun.COM * part of the hotplug initialization. 205*10187SKrishna.Elango@Sun.COM * For non-hotpluggable slots we need to call the _OSC method only for 206*10187SKrishna.Elango@Sun.COM * Root Ports (for AER support). 207*10187SKrishna.Elango@Sun.COM */ 208*10187SKrishna.Elango@Sun.COM if (!pcie_is_osc(devi) && PCIE_IS_RP(bus_p) && PCIE_HAS_AER(bus_p)) 209*10187SKrishna.Elango@Sun.COM (void) pcie_acpi_osc(devi, &osc_flags); 210*10187SKrishna.Elango@Sun.COM } 211*10187SKrishna.Elango@Sun.COM 212*10187SKrishna.Elango@Sun.COM /* 213*10187SKrishna.Elango@Sun.COM * Intel chip specific workarounds. Right now they're limited to the 5000, 5400 214*10187SKrishna.Elango@Sun.COM * and 7300 series chipsets. 215*10187SKrishna.Elango@Sun.COM */ 216*10187SKrishna.Elango@Sun.COM typedef struct x86_error_reg { 217*10187SKrishna.Elango@Sun.COM uint32_t offset; 218*10187SKrishna.Elango@Sun.COM uint_t size; 219*10187SKrishna.Elango@Sun.COM uint32_t mask; 220*10187SKrishna.Elango@Sun.COM uint32_t value1; /* Value for MSI case */ 221*10187SKrishna.Elango@Sun.COM uint32_t value2; /* Value for machinecheck case */ 222*10187SKrishna.Elango@Sun.COM } x86_error_reg_t; 223*10187SKrishna.Elango@Sun.COM 224*10187SKrishna.Elango@Sun.COM typedef struct x86_error_tbl { 225*10187SKrishna.Elango@Sun.COM uint16_t vendor_id; 226*10187SKrishna.Elango@Sun.COM uint16_t device_id_low; 227*10187SKrishna.Elango@Sun.COM uint16_t device_id_high; 228*10187SKrishna.Elango@Sun.COM uint8_t rev_id_low; 229*10187SKrishna.Elango@Sun.COM uint8_t rev_id_high; 230*10187SKrishna.Elango@Sun.COM x86_error_reg_t *error_regs; 231*10187SKrishna.Elango@Sun.COM int error_regs_len; 232*10187SKrishna.Elango@Sun.COM } x86_error_tbl_t; 233*10187SKrishna.Elango@Sun.COM 234*10187SKrishna.Elango@Sun.COM /* 235*10187SKrishna.Elango@Sun.COM * Chipset and device specific settings that are required for error handling 236*10187SKrishna.Elango@Sun.COM * (reporting, fowarding, and response at the RC) beyond the standard 237*10187SKrishna.Elango@Sun.COM * registers in the PCIE and AER caps. 238*10187SKrishna.Elango@Sun.COM * 239*10187SKrishna.Elango@Sun.COM * The Northbridge Root Port settings also apply to the ESI port. The ESI 240*10187SKrishna.Elango@Sun.COM * port is a special leaf device but functions like a root port connected 241*10187SKrishna.Elango@Sun.COM * to the Southbridge and receives all the onboard Southbridge errors 242*10187SKrishna.Elango@Sun.COM * including those from Southbridge Root Ports. However, this does not 243*10187SKrishna.Elango@Sun.COM * include the Southbridge Switch Ports which act like normal switch ports 244*10187SKrishna.Elango@Sun.COM * and is connected to the Northbridge through a separate link. 245*10187SKrishna.Elango@Sun.COM * 246*10187SKrishna.Elango@Sun.COM * PCIE errors from the ESB2 Southbridge RPs are simply fowarded to the ESI 247*10187SKrishna.Elango@Sun.COM * port on the Northbridge. 248*10187SKrishna.Elango@Sun.COM * 249*10187SKrishna.Elango@Sun.COM * If MSIs don't work we want UEs (Fatal and Non-Fatal) to panic the system, 250*10187SKrishna.Elango@Sun.COM * except for URs. We do this by having the Root Ports respond with a System 251*10187SKrishna.Elango@Sun.COM * Error and having that trigger a Machine Check (MCE). 252*10187SKrishna.Elango@Sun.COM */ 253*10187SKrishna.Elango@Sun.COM 254*10187SKrishna.Elango@Sun.COM /* 255*10187SKrishna.Elango@Sun.COM * 7300 Northbridge Root Ports 256*10187SKrishna.Elango@Sun.COM */ 257*10187SKrishna.Elango@Sun.COM static x86_error_reg_t intel_7300_rp_regs[] = { 258*10187SKrishna.Elango@Sun.COM /* Command Register - Enable SERR */ 259*10187SKrishna.Elango@Sun.COM {0x4, 16, 0xFFFF, 0x0, PCI_COMM_SERR_ENABLE}, 260*10187SKrishna.Elango@Sun.COM 261*10187SKrishna.Elango@Sun.COM /* Root Control Register - SERR on NFE/FE */ 262*10187SKrishna.Elango@Sun.COM {0x88, 16, 0x0, 0x0, PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN | 263*10187SKrishna.Elango@Sun.COM PCIE_ROOTCTL_SYS_ERR_ON_FE_EN}, 264*10187SKrishna.Elango@Sun.COM 265*10187SKrishna.Elango@Sun.COM /* AER UE Mask - Mask UR */ 266*10187SKrishna.Elango@Sun.COM {0x108, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR}, 267*10187SKrishna.Elango@Sun.COM 268*10187SKrishna.Elango@Sun.COM /* PEXCTRL[21] check for certain malformed TLP types and MSI enable */ 269*10187SKrishna.Elango@Sun.COM {0x48, 32, 0xFFFFFFFF, 0xC0200000, 0x200000}, 270*10187SKrishna.Elango@Sun.COM /* PEXCTRL3[7]. MSI RAS error enable */ 271*10187SKrishna.Elango@Sun.COM {0x4D, 32, 0xFFFFFFFF, 0x1, 0x0}, 272*10187SKrishna.Elango@Sun.COM 273*10187SKrishna.Elango@Sun.COM /* PEX_ERR_DOCMD[7:0] */ 274*10187SKrishna.Elango@Sun.COM {0x144, 8, 0x0, 0x0, 0xF0}, 275*10187SKrishna.Elango@Sun.COM 276*10187SKrishna.Elango@Sun.COM /* EMASK_UNCOR_PEX[21:0] UE mask */ 277*10187SKrishna.Elango@Sun.COM {0x148, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR}, 278*10187SKrishna.Elango@Sun.COM 279*10187SKrishna.Elango@Sun.COM /* EMASK_RP_PEX[2:0] FE, UE, CE message detect mask */ 280*10187SKrishna.Elango@Sun.COM {0x150, 8, 0x0, 0x0, 0x1}, 281*10187SKrishna.Elango@Sun.COM }; 282*10187SKrishna.Elango@Sun.COM #define INTEL_7300_RP_REGS_LEN \ 283*10187SKrishna.Elango@Sun.COM (sizeof (intel_7300_rp_regs) / sizeof (x86_error_reg_t)) 284*10187SKrishna.Elango@Sun.COM 285*10187SKrishna.Elango@Sun.COM /* 286*10187SKrishna.Elango@Sun.COM * 5000 Northbridge Root Ports 287*10187SKrishna.Elango@Sun.COM */ 288*10187SKrishna.Elango@Sun.COM static x86_error_reg_t intel_5000_rp_regs[] = { 289*10187SKrishna.Elango@Sun.COM /* Command Register - Enable SERR */ 290*10187SKrishna.Elango@Sun.COM {0x4, 16, 0xFFFF, PCI_COMM_SERR_ENABLE, PCI_COMM_SERR_ENABLE}, 291*10187SKrishna.Elango@Sun.COM 292*10187SKrishna.Elango@Sun.COM /* Root Control Register - SERR on NFE/FE/CE */ 293*10187SKrishna.Elango@Sun.COM {0x88, 16, 0x0, PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN | 294*10187SKrishna.Elango@Sun.COM PCIE_ROOTCTL_SYS_ERR_ON_FE_EN | 295*10187SKrishna.Elango@Sun.COM PCIE_ROOTCTL_SYS_ERR_ON_CE_EN, 296*10187SKrishna.Elango@Sun.COM PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN | 297*10187SKrishna.Elango@Sun.COM PCIE_ROOTCTL_SYS_ERR_ON_FE_EN}, 298*10187SKrishna.Elango@Sun.COM 299*10187SKrishna.Elango@Sun.COM /* AER UE Mask - Mask UR */ 300*10187SKrishna.Elango@Sun.COM {0x108, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR}, 301*10187SKrishna.Elango@Sun.COM 302*10187SKrishna.Elango@Sun.COM /* PEXCTRL[21] check for certain malformed TLP type */ 303*10187SKrishna.Elango@Sun.COM {0x48, 32, 0xFFFFFFFF, 0xC0200000, 0x200000}, 304*10187SKrishna.Elango@Sun.COM /* PEXCTRL3[7]. MSI RAS error enable. */ 305*10187SKrishna.Elango@Sun.COM {0x4D, 32, 0xFFFFFFFF, 0x1, 0x0}, 306*10187SKrishna.Elango@Sun.COM 307*10187SKrishna.Elango@Sun.COM /* PEX_ERR_DOCMD[7:0] */ 308*10187SKrishna.Elango@Sun.COM {0x144, 8, 0x0, 0x0, 0xF0}, 309*10187SKrishna.Elango@Sun.COM 310*10187SKrishna.Elango@Sun.COM /* EMASK_UNCOR_PEX[21:0] UE mask */ 311*10187SKrishna.Elango@Sun.COM {0x148, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR}, 312*10187SKrishna.Elango@Sun.COM 313*10187SKrishna.Elango@Sun.COM /* EMASK_RP_PEX[2:0] FE, UE, CE message detect mask */ 314*10187SKrishna.Elango@Sun.COM {0x150, 8, 0x0, 0x0, 0x1}, 315*10187SKrishna.Elango@Sun.COM }; 316*10187SKrishna.Elango@Sun.COM #define INTEL_5000_RP_REGS_LEN \ 317*10187SKrishna.Elango@Sun.COM (sizeof (intel_5000_rp_regs) / sizeof (x86_error_reg_t)) 318*10187SKrishna.Elango@Sun.COM 319*10187SKrishna.Elango@Sun.COM /* 320*10187SKrishna.Elango@Sun.COM * 5400 Northbridge Root Ports. 321*10187SKrishna.Elango@Sun.COM */ 322*10187SKrishna.Elango@Sun.COM static x86_error_reg_t intel_5400_rp_regs[] = { 323*10187SKrishna.Elango@Sun.COM /* Command Register - Enable SERR */ 324*10187SKrishna.Elango@Sun.COM {0x4, 16, 0xFFFF, PCI_COMM_SERR_ENABLE, PCI_COMM_SERR_ENABLE}, 325*10187SKrishna.Elango@Sun.COM 326*10187SKrishna.Elango@Sun.COM /* Root Control Register - SERR on NFE/FE */ 327*10187SKrishna.Elango@Sun.COM {0x88, 16, 0x0, PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN | 328*10187SKrishna.Elango@Sun.COM PCIE_ROOTCTL_SYS_ERR_ON_FE_EN | 329*10187SKrishna.Elango@Sun.COM PCIE_ROOTCTL_SYS_ERR_ON_CE_EN, 330*10187SKrishna.Elango@Sun.COM PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN | 331*10187SKrishna.Elango@Sun.COM PCIE_ROOTCTL_SYS_ERR_ON_FE_EN}, 332*10187SKrishna.Elango@Sun.COM 333*10187SKrishna.Elango@Sun.COM /* AER UE Mask - Mask UR */ 334*10187SKrishna.Elango@Sun.COM {0x108, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR}, 335*10187SKrishna.Elango@Sun.COM 336*10187SKrishna.Elango@Sun.COM /* PEXCTRL[21] check for certain malformed TLP types */ 337*10187SKrishna.Elango@Sun.COM {0x48, 32, 0xFFFFFFFF, 0xC0200000, 0x200000}, 338*10187SKrishna.Elango@Sun.COM /* PEXCTRL3. MSI RAS error enable. */ 339*10187SKrishna.Elango@Sun.COM {0x4E, 8, 0x0, 0x1, 0x0}, 340*10187SKrishna.Elango@Sun.COM 341*10187SKrishna.Elango@Sun.COM /* PEX_ERR_DOCMD[11:0] */ 342*10187SKrishna.Elango@Sun.COM {0x144, 16, 0x0, 0x0, 0xFF0}, 343*10187SKrishna.Elango@Sun.COM 344*10187SKrishna.Elango@Sun.COM /* PEX_ERR_PIN_MASK[4:0] do not mask ERR[2:0] pins used by DOCMD */ 345*10187SKrishna.Elango@Sun.COM {0x146, 16, 0x0, 0x10, 0x10}, 346*10187SKrishna.Elango@Sun.COM 347*10187SKrishna.Elango@Sun.COM /* EMASK_UNCOR_PEX[21:0] UE mask */ 348*10187SKrishna.Elango@Sun.COM {0x148, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR}, 349*10187SKrishna.Elango@Sun.COM 350*10187SKrishna.Elango@Sun.COM /* EMASK_RP_PEX[2:0] FE, UE, CE message detect mask */ 351*10187SKrishna.Elango@Sun.COM {0x150, 8, 0x0, 0x0, 0x1}, 352*10187SKrishna.Elango@Sun.COM }; 353*10187SKrishna.Elango@Sun.COM #define INTEL_5400_RP_REGS_LEN \ 354*10187SKrishna.Elango@Sun.COM (sizeof (intel_5400_rp_regs) / sizeof (x86_error_reg_t)) 355*10187SKrishna.Elango@Sun.COM 356*10187SKrishna.Elango@Sun.COM 357*10187SKrishna.Elango@Sun.COM /* 358*10187SKrishna.Elango@Sun.COM * ESB2 Southbridge Root Ports 359*10187SKrishna.Elango@Sun.COM */ 360*10187SKrishna.Elango@Sun.COM static x86_error_reg_t intel_esb2_rp_regs[] = { 361*10187SKrishna.Elango@Sun.COM /* Command Register - Enable SERR */ 362*10187SKrishna.Elango@Sun.COM {0x4, 16, 0xFFFF, PCI_COMM_SERR_ENABLE, PCI_COMM_SERR_ENABLE}, 363*10187SKrishna.Elango@Sun.COM 364*10187SKrishna.Elango@Sun.COM /* Root Control Register - SERR on NFE/FE */ 365*10187SKrishna.Elango@Sun.COM {0x5c, 16, 0x0, PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN | 366*10187SKrishna.Elango@Sun.COM PCIE_ROOTCTL_SYS_ERR_ON_FE_EN | 367*10187SKrishna.Elango@Sun.COM PCIE_ROOTCTL_SYS_ERR_ON_CE_EN, 368*10187SKrishna.Elango@Sun.COM PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN | 369*10187SKrishna.Elango@Sun.COM PCIE_ROOTCTL_SYS_ERR_ON_FE_EN}, 370*10187SKrishna.Elango@Sun.COM 371*10187SKrishna.Elango@Sun.COM /* UEM[20:0] UE mask (write-once) */ 372*10187SKrishna.Elango@Sun.COM {0x148, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR}, 373*10187SKrishna.Elango@Sun.COM }; 374*10187SKrishna.Elango@Sun.COM #define INTEL_ESB2_RP_REGS_LEN \ 375*10187SKrishna.Elango@Sun.COM (sizeof (intel_esb2_rp_regs) / sizeof (x86_error_reg_t)) 376*10187SKrishna.Elango@Sun.COM 377*10187SKrishna.Elango@Sun.COM 378*10187SKrishna.Elango@Sun.COM /* 379*10187SKrishna.Elango@Sun.COM * ESB2 Southbridge Switch Ports 380*10187SKrishna.Elango@Sun.COM */ 381*10187SKrishna.Elango@Sun.COM static x86_error_reg_t intel_esb2_sw_regs[] = { 382*10187SKrishna.Elango@Sun.COM /* Command Register - Enable SERR */ 383*10187SKrishna.Elango@Sun.COM {0x4, 16, 0xFFFF, PCI_COMM_SERR_ENABLE, PCI_COMM_SERR_ENABLE}, 384*10187SKrishna.Elango@Sun.COM 385*10187SKrishna.Elango@Sun.COM /* AER UE Mask - Mask UR */ 386*10187SKrishna.Elango@Sun.COM {0x108, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR}, 387*10187SKrishna.Elango@Sun.COM }; 388*10187SKrishna.Elango@Sun.COM #define INTEL_ESB2_SW_REGS_LEN \ 389*10187SKrishna.Elango@Sun.COM (sizeof (intel_esb2_sw_regs) / sizeof (x86_error_reg_t)) 390*10187SKrishna.Elango@Sun.COM 391*10187SKrishna.Elango@Sun.COM 392*10187SKrishna.Elango@Sun.COM x86_error_tbl_t x86_error_init_tbl[] = { 393*10187SKrishna.Elango@Sun.COM /* Intel 7300: 3600 = ESI, 3604-360A = NB root ports */ 394*10187SKrishna.Elango@Sun.COM {0x8086, 0x3600, 0x3600, 0x0, 0xFF, 395*10187SKrishna.Elango@Sun.COM intel_7300_rp_regs, INTEL_7300_RP_REGS_LEN}, 396*10187SKrishna.Elango@Sun.COM {0x8086, 0x3604, 0x360A, 0x0, 0xFF, 397*10187SKrishna.Elango@Sun.COM intel_7300_rp_regs, INTEL_7300_RP_REGS_LEN}, 398*10187SKrishna.Elango@Sun.COM 399*10187SKrishna.Elango@Sun.COM /* Intel 5000: 25C0, 25D0, 25D4, 25D8 = ESI */ 400*10187SKrishna.Elango@Sun.COM {0x8086, 0x25C0, 0x25C0, 0x0, 0xFF, 401*10187SKrishna.Elango@Sun.COM intel_5000_rp_regs, INTEL_5000_RP_REGS_LEN}, 402*10187SKrishna.Elango@Sun.COM {0x8086, 0x25D0, 0x25D0, 0x0, 0xFF, 403*10187SKrishna.Elango@Sun.COM intel_5000_rp_regs, INTEL_5000_RP_REGS_LEN}, 404*10187SKrishna.Elango@Sun.COM {0x8086, 0x25D4, 0x25D4, 0x0, 0xFF, 405*10187SKrishna.Elango@Sun.COM intel_5000_rp_regs, INTEL_5000_RP_REGS_LEN}, 406*10187SKrishna.Elango@Sun.COM {0x8086, 0x25D8, 0x25D8, 0x0, 0xFF, 407*10187SKrishna.Elango@Sun.COM intel_5000_rp_regs, INTEL_5000_RP_REGS_LEN}, 408*10187SKrishna.Elango@Sun.COM 409*10187SKrishna.Elango@Sun.COM /* Intel 5000: 25E2-25E7 and 25F7-25FA = NB root ports */ 410*10187SKrishna.Elango@Sun.COM {0x8086, 0x25E2, 0x25E7, 0x0, 0xFF, 411*10187SKrishna.Elango@Sun.COM intel_5000_rp_regs, INTEL_5000_RP_REGS_LEN}, 412*10187SKrishna.Elango@Sun.COM {0x8086, 0x25F7, 0x25FA, 0x0, 0xFF, 413*10187SKrishna.Elango@Sun.COM intel_5000_rp_regs, INTEL_5000_RP_REGS_LEN}, 414*10187SKrishna.Elango@Sun.COM 415*10187SKrishna.Elango@Sun.COM /* Intel 5400: 4000-4001, 4003 = ESI and 4021-4029 = NB root ports */ 416*10187SKrishna.Elango@Sun.COM {0x8086, 0x4000, 0x4001, 0x0, 0xFF, 417*10187SKrishna.Elango@Sun.COM intel_5400_rp_regs, INTEL_5400_RP_REGS_LEN}, 418*10187SKrishna.Elango@Sun.COM {0x8086, 0x4003, 0x4003, 0x0, 0xFF, 419*10187SKrishna.Elango@Sun.COM intel_5400_rp_regs, INTEL_5400_RP_REGS_LEN}, 420*10187SKrishna.Elango@Sun.COM {0x8086, 0x4021, 0x4029, 0x0, 0xFF, 421*10187SKrishna.Elango@Sun.COM intel_5400_rp_regs, INTEL_5400_RP_REGS_LEN}, 422*10187SKrishna.Elango@Sun.COM 423*10187SKrishna.Elango@Sun.COM /* Intel 631xESB/632xESB aka ESB2: 2690-2697 = SB root ports */ 424*10187SKrishna.Elango@Sun.COM {0x8086, 0x2690, 0x2697, 0x0, 0xFF, 425*10187SKrishna.Elango@Sun.COM intel_esb2_rp_regs, INTEL_ESB2_RP_REGS_LEN}, 426*10187SKrishna.Elango@Sun.COM 427*10187SKrishna.Elango@Sun.COM /* Intel Switches on esb2: 3500-3503, 3510-351B */ 428*10187SKrishna.Elango@Sun.COM {0x8086, 0x3500, 0x3503, 0x0, 0xFF, 429*10187SKrishna.Elango@Sun.COM intel_esb2_sw_regs, INTEL_ESB2_SW_REGS_LEN}, 430*10187SKrishna.Elango@Sun.COM {0x8086, 0x3510, 0x351B, 0x0, 0xFF, 431*10187SKrishna.Elango@Sun.COM intel_esb2_sw_regs, INTEL_ESB2_SW_REGS_LEN}, 432*10187SKrishna.Elango@Sun.COM 433*10187SKrishna.Elango@Sun.COM /* XXX Intel PCIe-PCIx on esb2: 350C */ 434*10187SKrishna.Elango@Sun.COM }; 435*10187SKrishna.Elango@Sun.COM static int x86_error_init_tbl_len = 436*10187SKrishna.Elango@Sun.COM sizeof (x86_error_init_tbl) / sizeof (x86_error_tbl_t); 437*10187SKrishna.Elango@Sun.COM 438*10187SKrishna.Elango@Sun.COM /* 439*10187SKrishna.Elango@Sun.COM * The main goal of this workaround is to set chipset specific settings if 440*10187SKrishna.Elango@Sun.COM * MSIs happen to be enabled on this device. Otherwise make the system 441*10187SKrishna.Elango@Sun.COM * Machine Check/Panic if an UE is detected in the fabric. 442*10187SKrishna.Elango@Sun.COM */ 443*10187SKrishna.Elango@Sun.COM void 444*10187SKrishna.Elango@Sun.COM pcieb_intel_serr_workaround(dev_info_t *dip, boolean_t mcheck) 445*10187SKrishna.Elango@Sun.COM { 446*10187SKrishna.Elango@Sun.COM uint16_t vid, did; 447*10187SKrishna.Elango@Sun.COM uint8_t rid; 448*10187SKrishna.Elango@Sun.COM int i, j; 449*10187SKrishna.Elango@Sun.COM x86_error_tbl_t *tbl; 450*10187SKrishna.Elango@Sun.COM x86_error_reg_t *reg; 451*10187SKrishna.Elango@Sun.COM pcie_bus_t *bus_p = PCIE_DIP2UPBUS(dip); 452*10187SKrishna.Elango@Sun.COM ddi_acc_handle_t cfg_hdl = bus_p->bus_cfg_hdl; 453*10187SKrishna.Elango@Sun.COM uint16_t bdf = bus_p->bus_bdf; 454*10187SKrishna.Elango@Sun.COM 455*10187SKrishna.Elango@Sun.COM if (pcieb_intel_workaround_disable) 456*10187SKrishna.Elango@Sun.COM return; 457*10187SKrishna.Elango@Sun.COM 458*10187SKrishna.Elango@Sun.COM vid = bus_p->bus_dev_ven_id & 0xFFFF; 459*10187SKrishna.Elango@Sun.COM did = bus_p->bus_dev_ven_id >> 16; 460*10187SKrishna.Elango@Sun.COM rid = bus_p->bus_rev_id; 461*10187SKrishna.Elango@Sun.COM 462*10187SKrishna.Elango@Sun.COM PCIEB_DEBUG(DBG_ATTACH, dip, "VID:0x%x DID:0x%x RID:0x%x bdf=0x%x\n", 463*10187SKrishna.Elango@Sun.COM vid, did, rid, bdf); 464*10187SKrishna.Elango@Sun.COM 465*10187SKrishna.Elango@Sun.COM tbl = x86_error_init_tbl; 466*10187SKrishna.Elango@Sun.COM for (i = 0; i < x86_error_init_tbl_len; i++, tbl++) { 467*10187SKrishna.Elango@Sun.COM if (!((vid == tbl->vendor_id) && 468*10187SKrishna.Elango@Sun.COM (did >= tbl->device_id_low) && 469*10187SKrishna.Elango@Sun.COM (did <= tbl->device_id_high) && 470*10187SKrishna.Elango@Sun.COM (rid >= tbl->rev_id_low) && 471*10187SKrishna.Elango@Sun.COM (rid <= tbl->rev_id_high))) 472*10187SKrishna.Elango@Sun.COM continue; 473*10187SKrishna.Elango@Sun.COM 474*10187SKrishna.Elango@Sun.COM if (mcheck && PCIE_IS_RP(bus_p)) 475*10187SKrishna.Elango@Sun.COM pcie_set_rber_fatal(dip, B_TRUE); 476*10187SKrishna.Elango@Sun.COM 477*10187SKrishna.Elango@Sun.COM reg = tbl->error_regs; 478*10187SKrishna.Elango@Sun.COM for (j = 0; j < tbl->error_regs_len; j++, reg++) { 479*10187SKrishna.Elango@Sun.COM uint32_t data = 0xDEADBEEF; 480*10187SKrishna.Elango@Sun.COM uint32_t value = 0xDEADBEEF; 481*10187SKrishna.Elango@Sun.COM switch (reg->size) { 482*10187SKrishna.Elango@Sun.COM case 32: 483*10187SKrishna.Elango@Sun.COM data = (uint32_t)pci_config_get32(cfg_hdl, 484*10187SKrishna.Elango@Sun.COM reg->offset); 485*10187SKrishna.Elango@Sun.COM value = (mcheck ? 486*10187SKrishna.Elango@Sun.COM ((data & reg->mask) | reg->value2) : 487*10187SKrishna.Elango@Sun.COM ((data & reg->mask) | reg->value1)); 488*10187SKrishna.Elango@Sun.COM pci_config_put32(cfg_hdl, reg->offset, value); 489*10187SKrishna.Elango@Sun.COM value = (uint32_t)pci_config_get32(cfg_hdl, 490*10187SKrishna.Elango@Sun.COM reg->offset); 491*10187SKrishna.Elango@Sun.COM break; 492*10187SKrishna.Elango@Sun.COM case 16: 493*10187SKrishna.Elango@Sun.COM data = (uint32_t)pci_config_get16(cfg_hdl, 494*10187SKrishna.Elango@Sun.COM reg->offset); 495*10187SKrishna.Elango@Sun.COM value = (mcheck ? 496*10187SKrishna.Elango@Sun.COM ((data & reg->mask) | reg->value2) : 497*10187SKrishna.Elango@Sun.COM ((data & reg->mask) | reg->value1)); 498*10187SKrishna.Elango@Sun.COM pci_config_put16(cfg_hdl, reg->offset, 499*10187SKrishna.Elango@Sun.COM (uint16_t)value); 500*10187SKrishna.Elango@Sun.COM value = (uint32_t)pci_config_get16(cfg_hdl, 501*10187SKrishna.Elango@Sun.COM reg->offset); 502*10187SKrishna.Elango@Sun.COM break; 503*10187SKrishna.Elango@Sun.COM case 8: 504*10187SKrishna.Elango@Sun.COM data = (uint32_t)pci_config_get8(cfg_hdl, 505*10187SKrishna.Elango@Sun.COM reg->offset); 506*10187SKrishna.Elango@Sun.COM value = (mcheck ? 507*10187SKrishna.Elango@Sun.COM ((data & reg->mask) | reg->value2) : 508*10187SKrishna.Elango@Sun.COM ((data & reg->mask) | reg->value1)); 509*10187SKrishna.Elango@Sun.COM pci_config_put8(cfg_hdl, reg->offset, 510*10187SKrishna.Elango@Sun.COM (uint8_t)value); 511*10187SKrishna.Elango@Sun.COM value = (uint32_t)pci_config_get8(cfg_hdl, 512*10187SKrishna.Elango@Sun.COM reg->offset); 513*10187SKrishna.Elango@Sun.COM break; 514*10187SKrishna.Elango@Sun.COM } 515*10187SKrishna.Elango@Sun.COM 516*10187SKrishna.Elango@Sun.COM PCIEB_DEBUG(DBG_ATTACH, dip, "bdf:%x mcheck:%d size:%d " 517*10187SKrishna.Elango@Sun.COM "off:0x%x mask:0x%x value:0x%x + orig:0x%x -> " 518*10187SKrishna.Elango@Sun.COM "0x%x\n", bdf, mcheck, reg->size, reg->offset, 519*10187SKrishna.Elango@Sun.COM reg->mask, (mcheck ? reg->value2 : reg->value1), 520*10187SKrishna.Elango@Sun.COM data, value); 521*10187SKrishna.Elango@Sun.COM } 522*10187SKrishna.Elango@Sun.COM } 523*10187SKrishna.Elango@Sun.COM } 524*10187SKrishna.Elango@Sun.COM 525*10187SKrishna.Elango@Sun.COM /* 526*10187SKrishna.Elango@Sun.COM * For devices that support Role Base Errors, make several UE have a FATAL 527*10187SKrishna.Elango@Sun.COM * severity. That way a Fatal Message will be sent instead of a Correctable 528*10187SKrishna.Elango@Sun.COM * Message. Without full FMA support, CEs will be ignored. 529*10187SKrishna.Elango@Sun.COM */ 530*10187SKrishna.Elango@Sun.COM uint32_t pcieb_rber_sev = (PCIE_AER_UCE_TRAINING | PCIE_AER_UCE_DLP | 531*10187SKrishna.Elango@Sun.COM PCIE_AER_UCE_SD | PCIE_AER_UCE_PTLP | PCIE_AER_UCE_FCP | PCIE_AER_UCE_TO | 532*10187SKrishna.Elango@Sun.COM PCIE_AER_UCE_CA | PCIE_AER_UCE_RO | PCIE_AER_UCE_MTLP | PCIE_AER_UCE_ECRC); 533*10187SKrishna.Elango@Sun.COM 534*10187SKrishna.Elango@Sun.COM void 535*10187SKrishna.Elango@Sun.COM pcieb_intel_rber_workaround(dev_info_t *dip) 536*10187SKrishna.Elango@Sun.COM { 537*10187SKrishna.Elango@Sun.COM uint32_t rber; 538*10187SKrishna.Elango@Sun.COM pcie_bus_t *bus_p = PCIE_DIP2UPBUS(dip); 539*10187SKrishna.Elango@Sun.COM 540*10187SKrishna.Elango@Sun.COM if (pcieb_intel_workaround_disable) 541*10187SKrishna.Elango@Sun.COM return; 542*10187SKrishna.Elango@Sun.COM 543*10187SKrishna.Elango@Sun.COM /* 544*10187SKrishna.Elango@Sun.COM * Check Root Port's machinecheck setting to determine if this 545*10187SKrishna.Elango@Sun.COM * workaround is needed or not. 546*10187SKrishna.Elango@Sun.COM */ 547*10187SKrishna.Elango@Sun.COM if (!pcie_get_rber_fatal(dip)) 548*10187SKrishna.Elango@Sun.COM return; 549*10187SKrishna.Elango@Sun.COM 550*10187SKrishna.Elango@Sun.COM if (!PCIE_IS_PCIE(bus_p) || !PCIE_HAS_AER(bus_p)) 551*10187SKrishna.Elango@Sun.COM return; 552*10187SKrishna.Elango@Sun.COM 553*10187SKrishna.Elango@Sun.COM rber = PCIE_CAP_GET(16, bus_p, PCIE_DEVCAP) & 554*10187SKrishna.Elango@Sun.COM PCIE_DEVCAP_ROLE_BASED_ERR_REP; 555*10187SKrishna.Elango@Sun.COM if (!rber) 556*10187SKrishna.Elango@Sun.COM return; 557*10187SKrishna.Elango@Sun.COM 558*10187SKrishna.Elango@Sun.COM PCIE_AER_PUT(32, bus_p, PCIE_AER_UCE_SERV, pcieb_rber_sev); 559*10187SKrishna.Elango@Sun.COM } 560*10187SKrishna.Elango@Sun.COM 561*10187SKrishna.Elango@Sun.COM /* 562*10187SKrishna.Elango@Sun.COM * The Intel 5000 Chipset has an errata that requires read completion 563*10187SKrishna.Elango@Sun.COM * coalescing to be disabled if the Max Payload Size is set to 256 bytes. 564*10187SKrishna.Elango@Sun.COM */ 565*10187SKrishna.Elango@Sun.COM void 566*10187SKrishna.Elango@Sun.COM pcieb_intel_mps_workaround(dev_info_t *dip) 567*10187SKrishna.Elango@Sun.COM { 568*10187SKrishna.Elango@Sun.COM uint16_t vid, did; 569*10187SKrishna.Elango@Sun.COM uint32_t pexctrl; 570*10187SKrishna.Elango@Sun.COM pcie_bus_t *bus_p = PCIE_DIP2UPBUS(dip); 571*10187SKrishna.Elango@Sun.COM 572*10187SKrishna.Elango@Sun.COM vid = bus_p->bus_dev_ven_id & 0xFFFF; 573*10187SKrishna.Elango@Sun.COM did = bus_p->bus_dev_ven_id >> 16; 574*10187SKrishna.Elango@Sun.COM 575*10187SKrishna.Elango@Sun.COM if ((vid == INTEL_VENDOR_ID) && INTEL_NB5000_PCIE_DEV_ID(did)) { 576*10187SKrishna.Elango@Sun.COM pexctrl = pci_config_get32(bus_p->bus_cfg_hdl, 577*10187SKrishna.Elango@Sun.COM INTEL_NB5000_PEXCTRL_OFFSET); 578*10187SKrishna.Elango@Sun.COM /* 579*10187SKrishna.Elango@Sun.COM * Turn off coalescing (bit 10) 580*10187SKrishna.Elango@Sun.COM */ 581*10187SKrishna.Elango@Sun.COM pexctrl &= ~INTEL_NB5000_PEXCTRL_COALESCE_EN; 582*10187SKrishna.Elango@Sun.COM 583*10187SKrishna.Elango@Sun.COM pci_config_put32(bus_p->bus_cfg_hdl, 584*10187SKrishna.Elango@Sun.COM INTEL_NB5000_PEXCTRL_OFFSET, pexctrl); 585*10187SKrishna.Elango@Sun.COM } 586*10187SKrishna.Elango@Sun.COM } 587*10187SKrishna.Elango@Sun.COM 588*10187SKrishna.Elango@Sun.COM /* 589*10187SKrishna.Elango@Sun.COM * Workaround for certain switches regardless of platform 590*10187SKrishna.Elango@Sun.COM */ 591*10187SKrishna.Elango@Sun.COM void 592*10187SKrishna.Elango@Sun.COM pcieb_intel_sw_workaround(dev_info_t *dip) 593*10187SKrishna.Elango@Sun.COM { 594*10187SKrishna.Elango@Sun.COM uint16_t vid, regw; 595*10187SKrishna.Elango@Sun.COM pcie_bus_t *bus_p = PCIE_DIP2UPBUS(dip); 596*10187SKrishna.Elango@Sun.COM ddi_acc_handle_t cfg_hdl = bus_p->bus_cfg_hdl; 597*10187SKrishna.Elango@Sun.COM 598*10187SKrishna.Elango@Sun.COM if (pcieb_intel_workaround_disable) 599*10187SKrishna.Elango@Sun.COM return; 600*10187SKrishna.Elango@Sun.COM 601*10187SKrishna.Elango@Sun.COM if (!PCIE_IS_SW(PCIE_DIP2BUS(dip))) 602*10187SKrishna.Elango@Sun.COM return; 603*10187SKrishna.Elango@Sun.COM 604*10187SKrishna.Elango@Sun.COM vid = bus_p->bus_dev_ven_id & 0xFFFF; 605*10187SKrishna.Elango@Sun.COM /* 606*10187SKrishna.Elango@Sun.COM * Intel and PLX switches require SERR in CMD reg to foward error 607*10187SKrishna.Elango@Sun.COM * messages, though this is not PCIE spec-compliant behavior. 608*10187SKrishna.Elango@Sun.COM * To prevent the switches themselves from reporting errors on URs 609*10187SKrishna.Elango@Sun.COM * when the CMD reg has SERR enabled (which is expected according to 610*10187SKrishna.Elango@Sun.COM * the PCIE spec) we rely on masking URs in the AER cap. 611*10187SKrishna.Elango@Sun.COM */ 612*10187SKrishna.Elango@Sun.COM if (vid == 0x8086 || vid == 0x10B5) { 613*10187SKrishna.Elango@Sun.COM regw = pci_config_get16(cfg_hdl, PCI_CONF_COMM); 614*10187SKrishna.Elango@Sun.COM pci_config_put16(cfg_hdl, PCI_CONF_COMM, 615*10187SKrishna.Elango@Sun.COM regw | PCI_COMM_SERR_ENABLE); 616*10187SKrishna.Elango@Sun.COM } 617*10187SKrishna.Elango@Sun.COM } 618*10187SKrishna.Elango@Sun.COM 619*10187SKrishna.Elango@Sun.COM int 620*10187SKrishna.Elango@Sun.COM pcieb_plat_ctlops(dev_info_t *rdip, ddi_ctl_enum_t ctlop, void *arg) 621*10187SKrishna.Elango@Sun.COM { 622*10187SKrishna.Elango@Sun.COM struct detachspec *ds; 623*10187SKrishna.Elango@Sun.COM struct attachspec *as; 624*10187SKrishna.Elango@Sun.COM 625*10187SKrishna.Elango@Sun.COM switch (ctlop) { 626*10187SKrishna.Elango@Sun.COM case DDI_CTLOPS_DETACH: 627*10187SKrishna.Elango@Sun.COM ds = (struct detachspec *)arg; 628*10187SKrishna.Elango@Sun.COM switch (ds->when) { 629*10187SKrishna.Elango@Sun.COM case DDI_POST: 630*10187SKrishna.Elango@Sun.COM if (ds->cmd == DDI_SUSPEND) { 631*10187SKrishna.Elango@Sun.COM if (pci_post_suspend(rdip) != DDI_SUCCESS) 632*10187SKrishna.Elango@Sun.COM return (DDI_FAILURE); 633*10187SKrishna.Elango@Sun.COM } 634*10187SKrishna.Elango@Sun.COM break; 635*10187SKrishna.Elango@Sun.COM default: 636*10187SKrishna.Elango@Sun.COM break; 637*10187SKrishna.Elango@Sun.COM } 638*10187SKrishna.Elango@Sun.COM break; 639*10187SKrishna.Elango@Sun.COM case DDI_CTLOPS_ATTACH: 640*10187SKrishna.Elango@Sun.COM as = (struct attachspec *)arg; 641*10187SKrishna.Elango@Sun.COM switch (as->when) { 642*10187SKrishna.Elango@Sun.COM case DDI_PRE: 643*10187SKrishna.Elango@Sun.COM if (as->cmd == DDI_RESUME) { 644*10187SKrishna.Elango@Sun.COM if (pci_pre_resume(rdip) != DDI_SUCCESS) 645*10187SKrishna.Elango@Sun.COM return (DDI_FAILURE); 646*10187SKrishna.Elango@Sun.COM } 647*10187SKrishna.Elango@Sun.COM break; 648*10187SKrishna.Elango@Sun.COM case DDI_POST: 649*10187SKrishna.Elango@Sun.COM /* 650*10187SKrishna.Elango@Sun.COM * For leaf devices supporting RBER and AER, we 651*10187SKrishna.Elango@Sun.COM * need to apply this workaround on them after 652*10187SKrishna.Elango@Sun.COM * attach to be notified of UEs that would 653*10187SKrishna.Elango@Sun.COM * otherwise be ignored as CEs on Intel chipsets 654*10187SKrishna.Elango@Sun.COM * currently 655*10187SKrishna.Elango@Sun.COM */ 656*10187SKrishna.Elango@Sun.COM pcieb_intel_rber_workaround(rdip); 657*10187SKrishna.Elango@Sun.COM break; 658*10187SKrishna.Elango@Sun.COM default: 659*10187SKrishna.Elango@Sun.COM break; 660*10187SKrishna.Elango@Sun.COM } 661*10187SKrishna.Elango@Sun.COM break; 662*10187SKrishna.Elango@Sun.COM default: 663*10187SKrishna.Elango@Sun.COM break; 664*10187SKrishna.Elango@Sun.COM } 665*10187SKrishna.Elango@Sun.COM 666*10187SKrishna.Elango@Sun.COM return (DDI_SUCCESS); 667*10187SKrishna.Elango@Sun.COM } 668*10187SKrishna.Elango@Sun.COM 669*10187SKrishna.Elango@Sun.COM void 670*10187SKrishna.Elango@Sun.COM pcieb_plat_ioctl_hotplug(dev_info_t *dip, int rv, int cmd) 671*10187SKrishna.Elango@Sun.COM { 672*10187SKrishna.Elango@Sun.COM /* 673*10187SKrishna.Elango@Sun.COM * like in attach, since hotplugging can change error registers, 674*10187SKrishna.Elango@Sun.COM * we need to ensure that the proper bits are set on this port 675*10187SKrishna.Elango@Sun.COM * after a configure operation 676*10187SKrishna.Elango@Sun.COM */ 677*10187SKrishna.Elango@Sun.COM if ((rv == HPC_SUCCESS) && (cmd == DEVCTL_AP_CONFIGURE)) 678*10187SKrishna.Elango@Sun.COM pcieb_intel_error_workaround(dip); 679*10187SKrishna.Elango@Sun.COM } 680