d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * CDDL HEADER START
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango *
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * The contents of this file are subject to the terms of the
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Common Development and Distribution License (the "License").
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * You may not use this file except in compliance with the License.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango *
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * or http://www.opensolaris.org/os/licensing.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * See the License for the specific language governing permissions
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * and limitations under the License.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango *
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * When distributing Covered Code, include this CDDL HEADER in each
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * If applicable, add the following below this CDDL HEADER, with the
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * fields enclosed by brackets "[]" replaced with your own identifying
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * information: Portions Copyright [yyyy] [name of copyright owner]
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango *
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * CDDL HEADER END
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Use is subject to license terms.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/* x86 specific code used by the pcieb driver */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#include <sys/types.h>
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#include <sys/ddi.h>
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#include <sys/kmem.h>
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#include <sys/sysmacros.h>
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#include <sys/sunddi.h>
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#include <sys/sunndi.h>
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#include <sys/pcie.h>
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#include <sys/pci_cap.h>
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#include <sys/pcie_impl.h>
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#include <sys/pcie_acpi.h>
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#include <sys/hotplug/hpctrl.h>
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#include <io/pciex/pcieb.h>
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#include <io/pciex/pcie_nb5000.h>
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/* Flag to turn off intel error handling workarounds */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangoint pcieb_intel_workaround_disable = 0;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangovoid
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_peekpoke_cb(dev_info_t *dip, ddi_fm_error_t *derr) {
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro pf_eh_enter(PCIE_DIP2BUS(dip));
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango (void) pf_scan_fabric(dip, derr, NULL);
fc256490629fe68815f7e0f23cf9b3545720cfacJason Beloro pf_eh_exit(PCIE_DIP2BUS(dip));
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hansonvoid
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hansonpcieb_set_prot_scan(dev_info_t *dip, ddi_acc_impl_t *hdlp)
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson{
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson pcieb_devstate_t *pcieb = ddi_get_soft_state(pcieb_state,
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson ddi_get_instance(dip));
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson hdlp->ahi_err_mutexp = &pcieb->pcieb_err_mutex;
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson hdlp->ahi_peekpoke_mutexp = &pcieb->pcieb_peek_poke_mutex;
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson hdlp->ahi_scan_dip = dip;
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson hdlp->ahi_scan = pcieb_peekpoke_cb;
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson}
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangoint
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_plat_peekpoke(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango void *arg, void *result)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcieb_devstate_t *pcieb = ddi_get_soft_state(pcieb_state,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ddi_get_instance(dip));
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (!PCIE_IS_RP(PCIE_DIP2BUS(dip)))
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return (ddi_ctlops(dip, rdip, ctlop, arg, result));
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return (pci_peekpoke_check(dip, rdip, ctlop, arg, result,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ddi_ctlops, &pcieb->pcieb_err_mutex,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango &pcieb->pcieb_peek_poke_mutex,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcieb_peekpoke_cb));
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/* x86 specific workarounds needed at the end of pcieb attach */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangovoid
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_plat_attach_workaround(dev_info_t *dip)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Must apply workaround only after all initialization is done */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcieb_intel_error_workaround(dip);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcieb_intel_mps_workaround(dip);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/* Workarounds to enable error handling on certain Intel chipsets */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangovoid
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_intel_error_workaround(dev_info_t *dip)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcieb_devstate_t *pcieb = ddi_get_soft_state(pcieb_state,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ddi_get_instance(dip));
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcieb_intel_serr_workaround(dip, pcieb->pcieb_no_aer_msi);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcieb_intel_rber_workaround(dip);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcieb_intel_sw_workaround(dip);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangoint
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_plat_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ddi_intr_handle_impl_t *hdlp, void *result)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return (i_ddi_intr_ops(dip, rdip, intr_op, hdlp, result));
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/* shpc is not supported on x86 */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*ARGSUSED*/
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangoint
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_plat_pcishpc_probe(dev_info_t *dip, ddi_acc_handle_t config_handle)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return (DDI_FAILURE);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Dummy functions to get around the fact that there's no shpc module on x86
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * today
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*ARGSUSED*/
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangoint
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcishpc_init(dev_info_t *dip)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return (DDI_FAILURE);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*ARGSUSED*/
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangoint
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcishpc_uninit(dev_info_t *dip)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return (DDI_FAILURE);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*ARGSUSED*/
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangoint
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcishpc_intr(dev_info_t *dip)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return (DDI_INTR_UNCLAIMED);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*ARGSUSED*/
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangoboolean_t
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_plat_pwr_disable(dev_info_t *dip)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Always disable on x86 */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return (B_TRUE);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangoboolean_t
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_plat_msi_supported(dev_info_t *dip)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcie_bus_t *bus_p = PCIE_DIP2UPBUS(dip);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint16_t vendor_id, device_id;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango vendor_id = bus_p->bus_dev_ven_id & 0xFFFF;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango device_id = bus_p->bus_dev_ven_id >> 16;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Intel ESB2 switches have a errata which prevents using MSIs
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * for hotplug.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return (((vendor_id == INTEL_VENDOR_ID) &&
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango INTEL_ESB2_SW_PCIE_DEV_ID(device_id)) ? B_FALSE : B_TRUE);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangovoid
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_plat_intr_attach(pcieb_devstate_t *pcieb)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * _OSC initialization needs to be done before interrupts are
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * initialized.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcieb_init_osc(pcieb->pcieb_dip);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangovoid
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_plat_initchild(dev_info_t *child)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango struct ddi_parent_private_data *pdptr;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (ddi_getprop(DDI_DEV_T_NONE, child, DDI_PROP_DONTPASS, "interrupts",
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango -1) != -1) {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pdptr = kmem_zalloc((sizeof (struct ddi_parent_private_data) +
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango sizeof (struct intrspec)), KM_SLEEP);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pdptr->par_intr = (struct intrspec *)(pdptr + 1);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pdptr->par_nintr = 1;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ddi_set_parent_data(child, pdptr);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango } else
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ddi_set_parent_data(child, NULL);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangovoid
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_plat_uninitchild(dev_info_t *child)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango struct ddi_parent_private_data *pdptr;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if ((pdptr = ddi_get_parent_data(child)) != NULL)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango kmem_free(pdptr, (sizeof (*pdptr) + sizeof (struct intrspec)));
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ddi_set_parent_data(child, NULL);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/* _OSC related */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangovoid
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_init_osc(dev_info_t *devi) {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcie_bus_t *bus_p = PCIE_DIP2UPBUS(devi);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint32_t osc_flags = OSC_CONTROL_PCIE_ADV_ERR;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Call _OSC method for 2 reasons:
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * 1. Hotplug: To determine if it is native or ACPI mode.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango *
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * 2. Error handling: Inform firmware that OS can support AER error
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * handling. Currently we don't care for what the BIOS response was
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * and instead setup interrupts for error handling as if it were
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * supported.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango *
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * For hotpluggable slots the _OSC method has already been called as
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * part of the hotplug initialization.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * For non-hotpluggable slots we need to call the _OSC method only for
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Root Ports (for AER support).
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (!pcie_is_osc(devi) && PCIE_IS_RP(bus_p) && PCIE_HAS_AER(bus_p))
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango (void) pcie_acpi_osc(devi, &osc_flags);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Intel chip specific workarounds. Right now they're limited to the 5000, 5400
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * and 7300 series chipsets.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangotypedef struct x86_error_reg {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint32_t offset;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint_t size;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint32_t mask;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint32_t value1; /* Value for MSI case */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint32_t value2; /* Value for machinecheck case */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango} x86_error_reg_t;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangotypedef struct x86_error_tbl {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint16_t vendor_id;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint16_t device_id_low;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint16_t device_id_high;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint8_t rev_id_low;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint8_t rev_id_high;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango x86_error_reg_t *error_regs;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango int error_regs_len;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango} x86_error_tbl_t;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Chipset and device specific settings that are required for error handling
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * (reporting, fowarding, and response at the RC) beyond the standard
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * registers in the PCIE and AER caps.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango *
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * The Northbridge Root Port settings also apply to the ESI port. The ESI
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * port is a special leaf device but functions like a root port connected
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * to the Southbridge and receives all the onboard Southbridge errors
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * including those from Southbridge Root Ports. However, this does not
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * include the Southbridge Switch Ports which act like normal switch ports
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * and is connected to the Northbridge through a separate link.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango *
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * PCIE errors from the ESB2 Southbridge RPs are simply fowarded to the ESI
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * port on the Northbridge.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango *
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * If MSIs don't work we want UEs (Fatal and Non-Fatal) to panic the system,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * except for URs. We do this by having the Root Ports respond with a System
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Error and having that trigger a Machine Check (MCE).
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * 7300 Northbridge Root Ports
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangostatic x86_error_reg_t intel_7300_rp_regs[] = {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Command Register - Enable SERR */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x4, 16, 0xFFFF, 0x0, PCI_COMM_SERR_ENABLE},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Root Control Register - SERR on NFE/FE */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x88, 16, 0x0, 0x0, PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN |
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_ROOTCTL_SYS_ERR_ON_FE_EN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* AER UE Mask - Mask UR */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x108, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* PEXCTRL[21] check for certain malformed TLP types and MSI enable */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x48, 32, 0xFFFFFFFF, 0xC0200000, 0x200000},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* PEXCTRL3[7]. MSI RAS error enable */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x4D, 32, 0xFFFFFFFF, 0x1, 0x0},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* PEX_ERR_DOCMD[7:0] */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x144, 8, 0x0, 0x0, 0xF0},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* EMASK_UNCOR_PEX[21:0] UE mask */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x148, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* EMASK_RP_PEX[2:0] FE, UE, CE message detect mask */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x150, 8, 0x0, 0x0, 0x1},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango};
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#define INTEL_7300_RP_REGS_LEN \
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango (sizeof (intel_7300_rp_regs) / sizeof (x86_error_reg_t))
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * 5000 Northbridge Root Ports
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangostatic x86_error_reg_t intel_5000_rp_regs[] = {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Command Register - Enable SERR */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x4, 16, 0xFFFF, PCI_COMM_SERR_ENABLE, PCI_COMM_SERR_ENABLE},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Root Control Register - SERR on NFE/FE/CE */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x88, 16, 0x0, PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN |
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_ROOTCTL_SYS_ERR_ON_FE_EN |
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_ROOTCTL_SYS_ERR_ON_CE_EN,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN |
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_ROOTCTL_SYS_ERR_ON_FE_EN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* AER UE Mask - Mask UR */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x108, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* PEXCTRL[21] check for certain malformed TLP type */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x48, 32, 0xFFFFFFFF, 0xC0200000, 0x200000},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* PEXCTRL3[7]. MSI RAS error enable. */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x4D, 32, 0xFFFFFFFF, 0x1, 0x0},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* PEX_ERR_DOCMD[7:0] */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x144, 8, 0x0, 0x0, 0xF0},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* EMASK_UNCOR_PEX[21:0] UE mask */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x148, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* EMASK_RP_PEX[2:0] FE, UE, CE message detect mask */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x150, 8, 0x0, 0x0, 0x1},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango};
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#define INTEL_5000_RP_REGS_LEN \
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango (sizeof (intel_5000_rp_regs) / sizeof (x86_error_reg_t))
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * 5400 Northbridge Root Ports.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangostatic x86_error_reg_t intel_5400_rp_regs[] = {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Command Register - Enable SERR */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x4, 16, 0xFFFF, PCI_COMM_SERR_ENABLE, PCI_COMM_SERR_ENABLE},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Root Control Register - SERR on NFE/FE */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x88, 16, 0x0, PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN |
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_ROOTCTL_SYS_ERR_ON_FE_EN |
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_ROOTCTL_SYS_ERR_ON_CE_EN,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN |
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_ROOTCTL_SYS_ERR_ON_FE_EN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* AER UE Mask - Mask UR */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x108, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* PEXCTRL[21] check for certain malformed TLP types */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x48, 32, 0xFFFFFFFF, 0xC0200000, 0x200000},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* PEXCTRL3. MSI RAS error enable. */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x4E, 8, 0x0, 0x1, 0x0},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* PEX_ERR_DOCMD[11:0] */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x144, 16, 0x0, 0x0, 0xFF0},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* PEX_ERR_PIN_MASK[4:0] do not mask ERR[2:0] pins used by DOCMD */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x146, 16, 0x0, 0x10, 0x10},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* EMASK_UNCOR_PEX[21:0] UE mask */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x148, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* EMASK_RP_PEX[2:0] FE, UE, CE message detect mask */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x150, 8, 0x0, 0x0, 0x1},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango};
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#define INTEL_5400_RP_REGS_LEN \
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango (sizeof (intel_5400_rp_regs) / sizeof (x86_error_reg_t))
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * ESB2 Southbridge Root Ports
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangostatic x86_error_reg_t intel_esb2_rp_regs[] = {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Command Register - Enable SERR */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x4, 16, 0xFFFF, PCI_COMM_SERR_ENABLE, PCI_COMM_SERR_ENABLE},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Root Control Register - SERR on NFE/FE */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x5c, 16, 0x0, PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN |
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_ROOTCTL_SYS_ERR_ON_FE_EN |
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_ROOTCTL_SYS_ERR_ON_CE_EN,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN |
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_ROOTCTL_SYS_ERR_ON_FE_EN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* UEM[20:0] UE mask (write-once) */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x148, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango};
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#define INTEL_ESB2_RP_REGS_LEN \
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango (sizeof (intel_esb2_rp_regs) / sizeof (x86_error_reg_t))
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * ESB2 Southbridge Switch Ports
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangostatic x86_error_reg_t intel_esb2_sw_regs[] = {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Command Register - Enable SERR */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x4, 16, 0xFFFF, PCI_COMM_SERR_ENABLE, PCI_COMM_SERR_ENABLE},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* AER UE Mask - Mask UR */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x108, 32, 0x0, PCIE_AER_UCE_UR, PCIE_AER_UCE_UR},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango};
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango#define INTEL_ESB2_SW_REGS_LEN \
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango (sizeof (intel_esb2_sw_regs) / sizeof (x86_error_reg_t))
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangox86_error_tbl_t x86_error_init_tbl[] = {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Intel 7300: 3600 = ESI, 3604-360A = NB root ports */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x8086, 0x3600, 0x3600, 0x0, 0xFF,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango intel_7300_rp_regs, INTEL_7300_RP_REGS_LEN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x8086, 0x3604, 0x360A, 0x0, 0xFF,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango intel_7300_rp_regs, INTEL_7300_RP_REGS_LEN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Intel 5000: 25C0, 25D0, 25D4, 25D8 = ESI */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x8086, 0x25C0, 0x25C0, 0x0, 0xFF,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango intel_5000_rp_regs, INTEL_5000_RP_REGS_LEN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x8086, 0x25D0, 0x25D0, 0x0, 0xFF,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango intel_5000_rp_regs, INTEL_5000_RP_REGS_LEN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x8086, 0x25D4, 0x25D4, 0x0, 0xFF,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango intel_5000_rp_regs, INTEL_5000_RP_REGS_LEN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x8086, 0x25D8, 0x25D8, 0x0, 0xFF,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango intel_5000_rp_regs, INTEL_5000_RP_REGS_LEN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Intel 5000: 25E2-25E7 and 25F7-25FA = NB root ports */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x8086, 0x25E2, 0x25E7, 0x0, 0xFF,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango intel_5000_rp_regs, INTEL_5000_RP_REGS_LEN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x8086, 0x25F7, 0x25FA, 0x0, 0xFF,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango intel_5000_rp_regs, INTEL_5000_RP_REGS_LEN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Intel 5400: 4000-4001, 4003 = ESI and 4021-4029 = NB root ports */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x8086, 0x4000, 0x4001, 0x0, 0xFF,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango intel_5400_rp_regs, INTEL_5400_RP_REGS_LEN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x8086, 0x4003, 0x4003, 0x0, 0xFF,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango intel_5400_rp_regs, INTEL_5400_RP_REGS_LEN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x8086, 0x4021, 0x4029, 0x0, 0xFF,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango intel_5400_rp_regs, INTEL_5400_RP_REGS_LEN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Intel 631xESB/632xESB aka ESB2: 2690-2697 = SB root ports */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x8086, 0x2690, 0x2697, 0x0, 0xFF,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango intel_esb2_rp_regs, INTEL_ESB2_RP_REGS_LEN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* Intel Switches on esb2: 3500-3503, 3510-351B */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x8086, 0x3500, 0x3503, 0x0, 0xFF,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango intel_esb2_sw_regs, INTEL_ESB2_SW_REGS_LEN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango {0x8086, 0x3510, 0x351B, 0x0, 0xFF,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango intel_esb2_sw_regs, INTEL_ESB2_SW_REGS_LEN},
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /* XXX Intel PCIe-PCIx on esb2: 350C */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango};
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangostatic int x86_error_init_tbl_len =
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango sizeof (x86_error_init_tbl) / sizeof (x86_error_tbl_t);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * The main goal of this workaround is to set chipset specific settings if
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * MSIs happen to be enabled on this device. Otherwise make the system
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Machine Check/Panic if an UE is detected in the fabric.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangovoid
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_intel_serr_workaround(dev_info_t *dip, boolean_t mcheck)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint16_t vid, did;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint8_t rid;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango int i, j;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango x86_error_tbl_t *tbl;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango x86_error_reg_t *reg;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcie_bus_t *bus_p = PCIE_DIP2UPBUS(dip);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ddi_acc_handle_t cfg_hdl = bus_p->bus_cfg_hdl;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint16_t bdf = bus_p->bus_bdf;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (pcieb_intel_workaround_disable)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango vid = bus_p->bus_dev_ven_id & 0xFFFF;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango did = bus_p->bus_dev_ven_id >> 16;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango rid = bus_p->bus_rev_id;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIEB_DEBUG(DBG_ATTACH, dip, "VID:0x%x DID:0x%x RID:0x%x bdf=0x%x\n",
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango vid, did, rid, bdf);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango tbl = x86_error_init_tbl;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango for (i = 0; i < x86_error_init_tbl_len; i++, tbl++) {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (!((vid == tbl->vendor_id) &&
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango (did >= tbl->device_id_low) &&
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango (did <= tbl->device_id_high) &&
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango (rid >= tbl->rev_id_low) &&
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango (rid <= tbl->rev_id_high)))
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango continue;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (mcheck && PCIE_IS_RP(bus_p))
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcie_set_rber_fatal(dip, B_TRUE);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango reg = tbl->error_regs;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango for (j = 0; j < tbl->error_regs_len; j++, reg++) {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint32_t data = 0xDEADBEEF;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint32_t value = 0xDEADBEEF;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango switch (reg->size) {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango case 32:
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango data = (uint32_t)pci_config_get32(cfg_hdl,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango reg->offset);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango value = (mcheck ?
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ((data & reg->mask) | reg->value2) :
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ((data & reg->mask) | reg->value1));
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pci_config_put32(cfg_hdl, reg->offset, value);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango value = (uint32_t)pci_config_get32(cfg_hdl,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango reg->offset);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango break;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango case 16:
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango data = (uint32_t)pci_config_get16(cfg_hdl,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango reg->offset);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango value = (mcheck ?
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ((data & reg->mask) | reg->value2) :
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ((data & reg->mask) | reg->value1));
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pci_config_put16(cfg_hdl, reg->offset,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango (uint16_t)value);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango value = (uint32_t)pci_config_get16(cfg_hdl,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango reg->offset);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango break;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango case 8:
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango data = (uint32_t)pci_config_get8(cfg_hdl,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango reg->offset);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango value = (mcheck ?
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ((data & reg->mask) | reg->value2) :
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ((data & reg->mask) | reg->value1));
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pci_config_put8(cfg_hdl, reg->offset,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango (uint8_t)value);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango value = (uint32_t)pci_config_get8(cfg_hdl,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango reg->offset);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango break;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango }
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIEB_DEBUG(DBG_ATTACH, dip, "bdf:%x mcheck:%d size:%d "
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango "off:0x%x mask:0x%x value:0x%x + orig:0x%x -> "
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango "0x%x\n", bdf, mcheck, reg->size, reg->offset,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango reg->mask, (mcheck ? reg->value2 : reg->value1),
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango data, value);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango }
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango }
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * For devices that support Role Base Errors, make several UE have a FATAL
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * severity. That way a Fatal Message will be sent instead of a Correctable
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Message. Without full FMA support, CEs will be ignored.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangouint32_t pcieb_rber_sev = (PCIE_AER_UCE_TRAINING | PCIE_AER_UCE_DLP |
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_AER_UCE_SD | PCIE_AER_UCE_PTLP | PCIE_AER_UCE_FCP | PCIE_AER_UCE_TO |
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_AER_UCE_CA | PCIE_AER_UCE_RO | PCIE_AER_UCE_MTLP | PCIE_AER_UCE_ECRC);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangovoid
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_intel_rber_workaround(dev_info_t *dip)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint32_t rber;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcie_bus_t *bus_p = PCIE_DIP2UPBUS(dip);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (pcieb_intel_workaround_disable)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Check Root Port's machinecheck setting to determine if this
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * workaround is needed or not.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (!pcie_get_rber_fatal(dip))
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (!PCIE_IS_PCIE(bus_p) || !PCIE_HAS_AER(bus_p))
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango rber = PCIE_CAP_GET(16, bus_p, PCIE_DEVCAP) &
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_DEVCAP_ROLE_BASED_ERR_REP;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (!rber)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango PCIE_AER_PUT(32, bus_p, PCIE_AER_UCE_SERV, pcieb_rber_sev);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * The Intel 5000 Chipset has an errata that requires read completion
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * coalescing to be disabled if the Max Payload Size is set to 256 bytes.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangovoid
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_intel_mps_workaround(dev_info_t *dip)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint16_t vid, did;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint32_t pexctrl;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcie_bus_t *bus_p = PCIE_DIP2UPBUS(dip);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango vid = bus_p->bus_dev_ven_id & 0xFFFF;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango did = bus_p->bus_dev_ven_id >> 16;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
870de8c6fab3eadbb9685bc2a5f97dc7d14be288Alan Adamson, SD OSSD if ((vid == INTEL_VENDOR_ID) && (INTEL_NB5000_PCIE_DEV_ID(did) ||
870de8c6fab3eadbb9685bc2a5f97dc7d14be288Alan Adamson, SD OSSD INTEL_NB5100_PCIE_DEV_ID(did))) {
870de8c6fab3eadbb9685bc2a5f97dc7d14be288Alan Adamson, SD OSSD
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pexctrl = pci_config_get32(bus_p->bus_cfg_hdl,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango INTEL_NB5000_PEXCTRL_OFFSET);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Turn off coalescing (bit 10)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pexctrl &= ~INTEL_NB5000_PEXCTRL_COALESCE_EN;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pci_config_put32(bus_p->bus_cfg_hdl,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango INTEL_NB5000_PEXCTRL_OFFSET, pexctrl);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango }
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango/*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Workaround for certain switches regardless of platform
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangovoid
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_intel_sw_workaround(dev_info_t *dip)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango uint16_t vid, regw;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcie_bus_t *bus_p = PCIE_DIP2UPBUS(dip);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ddi_acc_handle_t cfg_hdl = bus_p->bus_cfg_hdl;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (pcieb_intel_workaround_disable)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (!PCIE_IS_SW(PCIE_DIP2BUS(dip)))
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango vid = bus_p->bus_dev_ven_id & 0xFFFF;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * Intel and PLX switches require SERR in CMD reg to foward error
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * messages, though this is not PCIE spec-compliant behavior.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * To prevent the switches themselves from reporting errors on URs
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * when the CMD reg has SERR enabled (which is expected according to
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * the PCIE spec) we rely on masking URs in the AER cap.
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (vid == 0x8086 || vid == 0x10B5) {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango regw = pci_config_get16(cfg_hdl, PCI_CONF_COMM);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pci_config_put16(cfg_hdl, PCI_CONF_COMM,
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango regw | PCI_COMM_SERR_ENABLE);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango }
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangoint
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elangopcieb_plat_ctlops(dev_info_t *rdip, ddi_ctl_enum_t ctlop, void *arg)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango{
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango struct detachspec *ds;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango struct attachspec *as;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango switch (ctlop) {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango case DDI_CTLOPS_DETACH:
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango ds = (struct detachspec *)arg;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango switch (ds->when) {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango case DDI_POST:
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (ds->cmd == DDI_SUSPEND) {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (pci_post_suspend(rdip) != DDI_SUCCESS)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return (DDI_FAILURE);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango }
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango break;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango default:
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango break;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango }
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango break;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango case DDI_CTLOPS_ATTACH:
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango as = (struct attachspec *)arg;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango switch (as->when) {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango case DDI_PRE:
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (as->cmd == DDI_RESUME) {
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango if (pci_pre_resume(rdip) != DDI_SUCCESS)
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return (DDI_FAILURE);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango }
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango break;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango case DDI_POST:
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango /*
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * For leaf devices supporting RBER and AER, we
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * need to apply this workaround on them after
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * attach to be notified of UEs that would
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * otherwise be ignored as CEs on Intel chipsets
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango * currently
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango */
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango pcieb_intel_rber_workaround(rdip);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango break;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango default:
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango break;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango }
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango break;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango default:
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango break;
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango }
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango return (DDI_SUCCESS);
d4bc0535efa2c2219e9f83246a5f371dc7f94273Krishna Elango}