4df55fde49134f9735f84011f23a767c75e393c7Janie Lu/*
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * CDDL HEADER START
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu *
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * The contents of this file are subject to the terms of the
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * Common Development and Distribution License (the "License").
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * You may not use this file except in compliance with the License.
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu *
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * or http://www.opensolaris.org/os/licensing.
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * See the License for the specific language governing permissions
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * and limitations under the License.
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu *
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * When distributing Covered Code, include this CDDL HEADER in each
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * If applicable, add the following below this CDDL HEADER, with the
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * fields enclosed by brackets "[]" replaced with your own identifying
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * information: Portions Copyright [yyyy] [name of copyright owner]
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu *
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * CDDL HEADER END
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu/*
4f764f916501bcb9d3233dc547db1928fc2f22acCheng Sean Ye * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu#include <sys/types.h>
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu#include <px_err.h>
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu#include "fabric-xlate.h"
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu#define EPKT_DESC(b, o, p, c, d) (BLOCK_##b << 16 | OP_##o << 12 | \
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu PH_##p << 8 | CND_##c << 4 | DIR_##d)
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu/* EPKT Table used only for RC/RP errors */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lutypedef struct fab_epkt_tbl {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu uint32_t epkt_desc;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu uint32_t pcie_ue_sts; /* Equivalent PCIe UE Status */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu uint16_t pci_err_sts; /* Equivalent PCI Error Status */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu uint16_t pci_bdg_sts; /* Equivalent PCI Bridge Status */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu const char *tgt_class; /* Target Ereport Class */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu} fab_epkt_tbl_t;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lustatic fab_epkt_tbl_t fab_epkt_tbl[] = {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu EPKT_DESC(MMU, XLAT, DATA, INV, RDWR),
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu PCIE_AER_UCE_CA, 0, PCI_STAT_S_TARG_AB, 0,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu EPKT_DESC(MMU, XLAT, ADDR, UNMAP, RDWR),
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu PCIE_AER_UCE_CA, 0, PCI_STAT_S_TARG_AB, 0,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu EPKT_DESC(MMU, XLAT, DATA, PROT, RDWR),
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu PCIE_AER_UCE_CA, 0, PCI_STAT_S_TARG_AB, 0,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu EPKT_DESC(INTR, MSI32, DATA, ILL, IRR),
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu PCIE_AER_UCE_MTLP, PCI_STAT_S_SYSERR, 0, 0,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu EPKT_DESC(PORT, PIO, IRR, RCA, WRITE),
71b428bebcb3bd69d99d304083ab5f83cbd41bbeCheng Sean Ye 0, PCI_STAT_S_SYSERR, PCI_STAT_R_TARG_AB, 0,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu EPKT_DESC(PORT, PIO, IRR, RUR, WRITE),
71b428bebcb3bd69d99d304083ab5f83cbd41bbeCheng Sean Ye 0, PCI_STAT_S_SYSERR, PCI_STAT_R_MAST_AB, 0,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu EPKT_DESC(PORT, PIO, IRR, INV, RDWR),
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu PCIE_AER_UCE_MTLP, PCI_STAT_S_SYSERR, 0, 0,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu EPKT_DESC(PORT, PIO, IRR, TO, READ),
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu PCIE_AER_UCE_TO, PCI_STAT_S_SYSERR, 0, PCI_TARG_MA,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu EPKT_DESC(PORT, PIO, IRR, TO, WRITE),
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu PCIE_AER_UCE_TO, PCI_STAT_S_SYSERR, 0, PCI_TARG_MA,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu EPKT_DESC(PORT, PIO, IRR, UC, IRR),
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu PCIE_AER_UCE_UC, PCI_STAT_S_SYSERR, 0, 0,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu EPKT_DESC(PORT, LINK, FC, TO, IRR),
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu PCIE_AER_UCE_FCP, PCI_STAT_S_SYSERR, 0, 0,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu 0, 0, 0, 0, 0
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu};
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu/* ARGSUSED */
4df55fde49134f9735f84011f23a767c75e393c7Janie Luvoid
4df55fde49134f9735f84011f23a767c75e393c7Janie Lufab_epkt_to_data(fmd_hdl_t *hdl, nvlist_t *nvl, fab_data_t *data)
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu{
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data->nvl = nvl;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu /* Always Root Complex */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data->dev_type = PCIE_PCIECAP_DEV_TYPE_ROOT;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data->pcie_ue_sev = (PCIE_AER_UCE_DLP | PCIE_AER_UCE_SD |
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu PCIE_AER_UCE_FCP | PCIE_AER_UCE_RO | PCIE_AER_UCE_MTLP);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu}
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lustatic int
4df55fde49134f9735f84011f23a767c75e393c7Janie Lufab_xlate_epkt(fmd_hdl_t *hdl, fab_data_t *data, px_rc_err_t *epktp)
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu{
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fab_epkt_tbl_t *entry;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu uint32_t temp;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu for (entry = fab_epkt_tbl; entry->epkt_desc != 0; entry++) {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu temp = *(uint32_t *)&epktp->rc_descr >> 12;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu if (entry->epkt_desc == temp)
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu goto send;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu }
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu return (0);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lusend:
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fmd_hdl_debug(hdl, "Translate epkt DESC = %#x\n", temp);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu /* Fill in PCI Status Register */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data->pci_err_status = entry->pci_err_sts;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data->pci_bdg_sec_stat = entry->pci_bdg_sts;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu /* Fill in the device status register */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu if (epktp->rc_descr.STOP)
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data->pcie_err_status = PCIE_DEVSTS_FE_DETECTED;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu else if (epktp->rc_descr.C)
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data->pcie_err_status = PCIE_DEVSTS_CE_DETECTED;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu else
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data->pcie_err_status = PCIE_DEVSTS_NFE_DETECTED;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu /* Fill in the AER UE register */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data->pcie_ue_status = entry->pcie_ue_sts;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu /* Fill in the AER Control register */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu temp = entry->pcie_ue_sts;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu for (data->pcie_adv_ctl = (uint32_t)-1; temp; data->pcie_adv_ctl++)
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu temp = temp >> 1;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu /* Send target ereports */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data->pcie_ue_no_tgt_erpt = B_TRUE;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu if (entry->tgt_class && !epktp->rc_descr.STOP) {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu if (epktp->rc_descr.D) {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data->pcie_ue_tgt_trans = PF_ADDR_DMA;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data->pcie_ue_tgt_addr = epktp->addr;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu } else if (epktp->rc_descr.M) {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data->pcie_ue_tgt_trans = PF_ADDR_PIO;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data->pcie_ue_tgt_addr = epktp->addr;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu }
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu if (data->pcie_ue_tgt_trans)
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fab_send_tgt_erpt(hdl, data, entry->tgt_class,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu B_TRUE);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu }
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu return (1);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu}
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Luvoid
4df55fde49134f9735f84011f23a767c75e393c7Janie Lufab_xlate_epkt_erpts(fmd_hdl_t *hdl, nvlist_t *nvl, const char *class)
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu{
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fab_data_t data = {0};
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu px_rc_err_t epkt = {0};
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu pcie_tlp_hdr_t *tlp_hdr;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu void *ptr;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu uint8_t ver;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu int err;
4f764f916501bcb9d3233dc547db1928fc2f22acCheng Sean Ye char *devpath, *rppath = NULL;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu nvlist_t *detector;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fmd_hdl_debug(hdl, "epkt ereport received: %s\n", class);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fab_epkt_to_data(hdl, nvl, &data);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu err = nvlist_lookup_uint8(nvl, "epkt_ver", &ver);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu err |= nvlist_lookup_uint32(nvl, "desc", (uint32_t *)&epkt.rc_descr);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu err |= nvlist_lookup_uint32(nvl, "size", &epkt.size);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu err |= nvlist_lookup_uint64(nvl, "addr", &epkt.addr);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu err |= nvlist_lookup_uint64(nvl, "hdr1", &epkt.hdr[0]);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu err |= nvlist_lookup_uint64(nvl, "hdr2", &epkt.hdr[1]);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu err |= nvlist_lookup_uint64(nvl, "reserved", &epkt.reserved);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu if (err != 0) {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fmd_hdl_debug(hdl, "Failed to retrieve all epkt payloads");
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu return;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu }
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fmd_hdl_debug(hdl, "epkt flags: %c%c%c%c%c%c%c%c%c %s",
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu epkt.rc_descr.S ? 'S' : '-', epkt.rc_descr.M ? 'M' : '-',
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu epkt.rc_descr.S ? 'Q' : '-', epkt.rc_descr.D ? 'D' : '-',
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu epkt.rc_descr.R ? 'R' : '-', epkt.rc_descr.H ? 'H' : '-',
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu epkt.rc_descr.C ? 'C' : '-', epkt.rc_descr.I ? 'I' : '-',
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu epkt.rc_descr.B ? 'B' : '-', epkt.rc_descr.STOP ? "STOP" : "");
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu /*
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * If the least byte of the 'reserved' is non zero, it is device
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * and function of the port
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu if (epkt.reserved && 0xff)
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu rppath = fab_find_rppath_by_df(hdl, nvl, epkt.reserved & 0xff);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu if (epkt.rc_descr.H) {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data.pcie_ue_hdr[0] = (uint32_t)(epkt.hdr[0] >> 32);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data.pcie_ue_hdr[1] = (uint32_t)epkt.hdr[0];
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data.pcie_ue_hdr[2] = (uint32_t)(epkt.hdr[1] >> 32);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data.pcie_ue_hdr[3] = (uint32_t)(epkt.hdr[1]);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu tlp_hdr = (pcie_tlp_hdr_t *)&data.pcie_ue_hdr[0];
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu ptr = &data.pcie_ue_hdr[1];
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu switch (tlp_hdr->type) {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu case PCIE_TLP_TYPE_IO:
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu case PCIE_TLP_TYPE_MEM:
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu case PCIE_TLP_TYPE_MEMLK:
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu pcie_mem64_t *pmp = ptr;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data.pcie_ue_tgt_trans = PF_ADDR_PIO;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data.pcie_ue_tgt_bdf = pmp->rid;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu if (tlp_hdr->fmt & 0x1)
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data.pcie_ue_tgt_addr =
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu ((uint64_t)pmp->addr1 << 32) | pmp->addr0;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu else
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data.pcie_ue_tgt_addr =
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu ((pcie_memio32_t *)ptr)->addr0;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu break;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu }
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu case PCIE_TLP_TYPE_CFG0:
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu case PCIE_TLP_TYPE_CFG1:
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu pcie_cfg_t *pcp = ptr;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data.pcie_ue_tgt_trans = PF_ADDR_CFG;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data.pcie_ue_tgt_bdf =
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu (pcp->bus << 8) | (pcp->dev << 3) | pcp->func;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu break;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu }
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu case PCIE_TLP_TYPE_CPL:
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu case PCIE_TLP_TYPE_CPLLK:
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data.pcie_ue_tgt_bdf = ((pcie_cpl_t *)ptr)->rid;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu break;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu }
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fmd_hdl_debug(hdl, "HEADER 0 0x%x", data.pcie_ue_hdr[0]);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fmd_hdl_debug(hdl, "HEADER 1 0x%x", data.pcie_ue_hdr[1]);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fmd_hdl_debug(hdl, "HEADER 2 0x%x", data.pcie_ue_hdr[2]);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fmd_hdl_debug(hdl, "HEADER 3 0x%x", data.pcie_ue_hdr[3]);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fmd_hdl_debug(hdl, "In header bdf = %#hx addr = %#llx",
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data.pcie_ue_tgt_bdf,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu (uint64_t)data.pcie_ue_tgt_addr);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu /* find the root port to which this error is related */
4f764f916501bcb9d3233dc547db1928fc2f22acCheng Sean Ye if (rppath == NULL && data.pcie_ue_tgt_bdf)
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu rppath = fab_find_rppath_by_devbdf(hdl, nvl,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu data.pcie_ue_tgt_bdf);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu }
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4f764f916501bcb9d3233dc547db1928fc2f22acCheng Sean Ye /* find the root port by address */
4f764f916501bcb9d3233dc547db1928fc2f22acCheng Sean Ye if (rppath == NULL && epkt.rc_descr.M != 0) {
4f764f916501bcb9d3233dc547db1928fc2f22acCheng Sean Ye devpath = fab_find_addr(hdl, nvl, epkt.addr);
4f764f916501bcb9d3233dc547db1928fc2f22acCheng Sean Ye if (devpath) {
4f764f916501bcb9d3233dc547db1928fc2f22acCheng Sean Ye rppath = fab_find_rppath_by_devpath(hdl, devpath);
4f764f916501bcb9d3233dc547db1928fc2f22acCheng Sean Ye fmd_hdl_strfree(hdl, devpath);
4f764f916501bcb9d3233dc547db1928fc2f22acCheng Sean Ye }
4f764f916501bcb9d3233dc547db1928fc2f22acCheng Sean Ye }
4f764f916501bcb9d3233dc547db1928fc2f22acCheng Sean Ye
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu /*
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu * reset the detector in the original ereport to the root port
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu */
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye if (rppath) {
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye if (nvlist_alloc(&detector, NV_UNIQUE_NAME, 0) != 0) {
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye fmd_hdl_error(hdl, "failed to allocate nvlist");
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye fmd_hdl_strfree(hdl, rppath);
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye return;
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye }
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu (void) nvlist_add_string(detector, FM_VERSION,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu FM_DEV_SCHEME_VERSION);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu (void) nvlist_add_string(detector, FM_FMRI_SCHEME,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu FM_FMRI_SCHEME_DEV);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu (void) nvlist_add_string(detector, FM_FMRI_DEV_PATH, rppath);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu (void) nvlist_remove_all(nvl, FM_EREPORT_DETECTOR);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu (void) nvlist_add_nvlist(nvl, FM_EREPORT_DETECTOR, detector);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu nvlist_free(detector);
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye fmd_hdl_strfree(hdl, rppath);
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye } else {
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye /*
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye * We can not locate the root port the error originated from.
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye * Likely this is because the original ereport is malformed or
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye * the hw error register has corrupted contents. In this case,
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye * the best we can do is send ereports on all root ports.
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye *
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye * Set pcie_rp_send_all for fab_send_erpt() to process later.
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye */
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye fmd_hdl_debug(hdl, "RP not fond. Will translate on all RPs.\n");
036ec191c83e34650be17cd0fd75e7800aa95d35Cheng Sean Ye data.pcie_rp_send_all = B_TRUE;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu }
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu (void) fab_xlate_epkt(hdl, &data, &epkt);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fab_xlate_pcie_erpts(hdl, &data);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu}