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