#include <sys/pcie_impl.h>
static int
px_cb_epkt_severity(dev_info_t *dip, ddi_fm_error_t *derr, px_rc_err_t *epkt,
pf_data_t *pfd_p)
{
int err = 0;
if (epkt->rc_descr.STOP == 1)
return (PX_PANIC);
switch (epkt->rc_descr.op) {
case OP_DMA:
switch (epkt->rc_descr.phase) {
case PH_ADDR:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_WRITE:
err = PX_PANIC;
break;
}
break;
}
break;
case PH_DATA:
switch (epkt->rc_descr.cond) {
case CND_INT:
switch (epkt->rc_descr.dir) {
case DIR_READ:
err = PX_PANIC;
break;
case DIR_RDWR:
err = PX_PANIC;
break;
case DIR_UNKNOWN:
err = PX_PANIC;
break;
case DIR_WRITE:
err = PX_PANIC;
break;
}
break;
case CND_TO:
switch (epkt->rc_descr.dir) {
case DIR_READ:
err = PX_PANIC;
break;
case DIR_WRITE:
err = PX_PANIC;
break;
}
break;
case CND_UE:
switch (epkt->rc_descr.dir) {
case DIR_READ:
err = PX_PANIC;
break;
}
break;
}
break;
case PH_UNKNOWN:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_READ:
err = PX_PANIC;
break;
}
break;
case CND_UNKNOWN:
switch (epkt->rc_descr.dir) {
case DIR_READ:
err = PX_PANIC;
break;
}
break;
}
break;
}
break;
case OP_PIO:
switch (epkt->rc_descr.phase) {
case PH_ADDR:
switch (epkt->rc_descr.cond) {
case CND_UNMAP:
switch (epkt->rc_descr.dir) {
case DIR_READ:
err = PX_PANIC;
break;
case DIR_WRITE:
err = PX_PANIC;
break;
}
break;
}
break;
case PH_DATA:
switch (epkt->rc_descr.cond) {
case CND_INT:
switch (epkt->rc_descr.dir) {
case DIR_RDWR:
err = PX_PANIC;
break;
case DIR_UNKNOWN:
err = PX_PANIC;
break;
case DIR_WRITE:
err = PX_PANIC;
break;
}
break;
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_WRITE:
err = PX_PANIC;
break;
}
break;
}
break;
case PH_UNKNOWN:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_READ:
err = PX_PANIC;
break;
case DIR_WRITE:
err = PX_PANIC;
break;
}
break;
case CND_TO:
switch (epkt->rc_descr.dir) {
case DIR_RDWR:
err = PX_PANIC;
break;
}
break;
}
break;
}
break;
case OP_UNKNOWN:
switch (epkt->rc_descr.phase) {
case PH_ADDR:
switch (epkt->rc_descr.cond) {
case CND_UNMAP:
switch (epkt->rc_descr.dir) {
case DIR_RDWR:
err = PX_PANIC;
break;
}
break;
}
break;
case PH_DATA:
switch (epkt->rc_descr.cond) {
case CND_INT:
switch (epkt->rc_descr.dir) {
case DIR_UNKNOWN:
err = PX_PANIC;
break;
}
break;
case CND_UE:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
}
break;
}
break;
case PH_UNKNOWN:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
}
}
}
}
return (err);
}
static int
px_mmu_epkt_severity(dev_info_t *dip, ddi_fm_error_t *derr, px_rc_err_t *epkt,
pf_data_t *pfd_p)
{
int err = 0;
if (epkt->rc_descr.STOP == 1)
return (PX_PANIC);
switch (epkt->rc_descr.op) {
case OP_BYPASS:
switch (epkt->rc_descr.phase) {
case PH_ADDR:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_RDWR:
err = PX_NO_PANIC;
break;
}
break;
}
break;
case PH_UNKNOWN:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_UNKNOWN:
err = PX_NO_PANIC;
break;
}
break;
}
break;
}
break;
case OP_TBW:
switch (epkt->rc_descr.phase) {
case PH_ADDR:
switch (epkt->rc_descr.cond) {
case CND_UNKNOWN:
switch (epkt->rc_descr.dir) {
case DIR_UNKNOWN:
err = PX_PANIC;
break;
}
break;
case CND_UNMAP:
switch (epkt->rc_descr.dir) {
case DIR_UNKNOWN:
err = PX_PANIC;
break;
}
break;
}
break;
case PH_DATA:
switch (epkt->rc_descr.cond) {
case CND_INT:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
}
break;
}
break;
case PH_UNKNOWN:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
}
break;
case CND_UNKNOWN:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
case DIR_UNKNOWN:
err = PX_PANIC;
break;
}
break;
}
break;
}
break;
case OP_XLAT:
switch (epkt->rc_descr.phase) {
case PH_ADDR:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_RDWR:
err = PX_NO_PANIC;
break;
}
break;
case CND_IRR:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
}
break;
case CND_PROT:
switch (epkt->rc_descr.dir) {
case DIR_RDWR:
err = PX_NO_PANIC;
break;
}
break;
case CND_UNMAP:
switch (epkt->rc_descr.dir) {
case DIR_RDWR:
err = PX_NO_PANIC;
break;
}
break;
}
break;
case PH_DATA:
switch (epkt->rc_descr.cond) {
case CND_INT:
switch (epkt->rc_descr.dir) {
case DIR_UNKNOWN:
err = PX_PANIC;
break;
}
break;
case CND_INV:
switch (epkt->rc_descr.dir) {
case DIR_RDWR:
err = PX_NO_PANIC;
break;
case DIR_UNKNOWN:
err = PX_NO_PANIC;
break;
}
break;
case CND_IRR:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
}
break;
case CND_PROT:
switch (epkt->rc_descr.dir) {
case DIR_RDWR:
err = PX_NO_PANIC;
break;
case DIR_WRITE:
err = PX_NO_PANIC;
break;
}
break;
}
break;
case PH_UNKNOWN:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
}
}
}
}
if (epkt->rc_descr.D && (err & (PX_PANIC | PX_PROTECTED)) &&
px_mmu_handle_lookup(dip, derr, epkt) == PF_HDL_FOUND)
err = PX_NO_PANIC;
return (err);
}
static int
px_intr_epkt_severity(dev_info_t *dip, ddi_fm_error_t *derr, px_rc_err_t *epkt,
pf_data_t *pfd_p)
{
int err = 0;
if (epkt->rc_descr.STOP == 1)
return (PX_PANIC);
switch (epkt->rc_descr.op) {
case OP_FIXED:
switch (epkt->rc_descr.phase) {
case PH_UNKNOWN:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_INGRESS:
err = PX_PANIC;
break;
}
break;
}
break;
}
break;
case OP_MSI32:
switch (epkt->rc_descr.phase) {
case PH_DATA:
switch (epkt->rc_descr.cond) {
case CND_INT:
switch (epkt->rc_descr.dir) {
case DIR_UNKNOWN:
err = PX_PANIC;
break;
}
break;
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
}
break;
}
break;
case PH_UNKNOWN:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
}
break;
}
break;
}
break;
case OP_MSI64:
switch (epkt->rc_descr.phase) {
case PH_DATA:
switch (epkt->rc_descr.cond) {
case CND_INT:
switch (epkt->rc_descr.dir) {
case DIR_UNKNOWN:
err = PX_PANIC;
break;
}
break;
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
}
break;
}
break;
case PH_UNKNOWN:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
}
break;
}
break;
}
break;
case OP_MSIQ:
switch (epkt->rc_descr.phase) {
case PH_DATA:
switch (epkt->rc_descr.cond) {
case CND_INT:
switch (epkt->rc_descr.dir) {
case DIR_UNKNOWN:
err = PX_PANIC;
break;
}
break;
}
break;
case PH_UNKNOWN:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
}
break;
case CND_OV:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = px_intr_handle_errors(dip, derr,
epkt, pfd_p);
break;
}
break;
}
break;
}
break;
case OP_PCIEMSG:
switch (epkt->rc_descr.phase) {
case PH_UNKNOWN:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_INGRESS:
err = PX_PANIC;
break;
}
break;
}
break;
}
break;
case OP_UNKNOWN:
switch (epkt->rc_descr.phase) {
case PH_DATA:
switch (epkt->rc_descr.cond) {
case CND_INT:
switch (epkt->rc_descr.dir) {
case DIR_UNKNOWN:
err = PX_PANIC;
break;
}
break;
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
}
break;
}
break;
case PH_UNKNOWN:
switch (epkt->rc_descr.cond) {
case CND_ILL:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
break;
}
}
}
}
return (err);
}
static int
px_port_epkt_severity(dev_info_t *dip, ddi_fm_error_t *derr, px_rc_err_t *epkt,
pf_data_t *pfd_p)
{
int err = 0;
if (epkt->rc_descr.STOP == 1)
return (PX_PANIC);
switch (epkt->rc_descr.op) {
case OP_DMA:
switch (epkt->rc_descr.phase) {
case PH_DATA:
switch (epkt->rc_descr.cond) {
case CND_INT:
switch (epkt->rc_descr.dir) {
case DIR_READ:
err = PX_PANIC;
PFD_SET_AFFECTED_FLAG(pfd_p,
PF_AFFECTED_BDF);
PFD_SET_AFFECTED_BDF(pfd_p,
(uint16_t)epkt->reserved);
break;
}
break;
}
break;
}
break;
case OP_LINK:
switch (epkt->rc_descr.phase) {
case PH_FC:
switch (epkt->rc_descr.cond) {
case CND_TO:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_PANIC;
PFD_SET_AFFECTED_FLAG(pfd_p,
PF_AFFECTED_BDF);
PFD_SET_AFFECTED_BDF(pfd_p,
(uint16_t)epkt->reserved);
break;
}
break;
}
break;
}
break;
case OP_PIO:
switch (epkt->rc_descr.phase) {
case PH_DATA:
switch (epkt->rc_descr.cond) {
case CND_INT:
switch (epkt->rc_descr.dir) {
case DIR_READ:
err = PX_PANIC;
PFD_SET_AFFECTED_FLAG(pfd_p,
PF_AFFECTED_BDF);
PFD_SET_AFFECTED_BDF(pfd_p,
(uint16_t)epkt->reserved);
break;
case DIR_UNKNOWN:
err = PX_PANIC;
PFD_SET_AFFECTED_FLAG(pfd_p,
PF_AFFECTED_BDF);
PFD_SET_AFFECTED_BDF(pfd_p,
(uint16_t)epkt->reserved);
break;
}
break;
}
break;
case PH_IRR:
switch (epkt->rc_descr.cond) {
case CND_INV:
switch (epkt->rc_descr.dir) {
case DIR_RDWR:
err = PX_PANIC;
break;
}
break;
case CND_RCA:
switch (epkt->rc_descr.dir) {
case DIR_WRITE:
err = px_port_handle_errors(dip, derr,
epkt, pfd_p);
break;
}
break;
case CND_RUR:
switch (epkt->rc_descr.dir) {
case DIR_WRITE:
err = px_port_handle_errors(dip, derr,
epkt, pfd_p);
break;
}
break;
case CND_TO:
switch (epkt->rc_descr.dir) {
case DIR_WRITE:
err = PX_PANIC;
break;
}
break;
case CND_UC:
switch (epkt->rc_descr.dir) {
case DIR_IRR:
err = PX_NO_PANIC;
break;
}
break;
}
break;
}
break;
case OP_UNKNOWN:
switch (epkt->rc_descr.phase) {
case PH_DATA:
switch (epkt->rc_descr.cond) {
case CND_INT:
switch (epkt->rc_descr.dir) {
case DIR_UNKNOWN:
err = PX_PANIC;
PFD_SET_AFFECTED_FLAG(pfd_p,
PF_AFFECTED_BDF);
PFD_SET_AFFECTED_BDF(pfd_p,
(uint16_t)epkt->reserved);
break;
}
}
}
}
return (err);
}