linux/drivers/pci/pcie/aer/aerdrv.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * Copyright (C) 2006 Intel Corp.
   4 *      Tom Long Nguyen (tom.l.nguyen@intel.com)
   5 *      Zhang Yanmin (yanmin.zhang@intel.com)
   6 *
   7 */
   8
   9#ifndef _AERDRV_H_
  10#define _AERDRV_H_
  11
  12#include <linux/workqueue.h>
  13#include <linux/pcieport_if.h>
  14#include <linux/aer.h>
  15#include <linux/interrupt.h>
  16
  17#define SYSTEM_ERROR_INTR_ON_MESG_MASK  (PCI_EXP_RTCTL_SECEE|   \
  18                                        PCI_EXP_RTCTL_SENFEE|   \
  19                                        PCI_EXP_RTCTL_SEFEE)
  20#define ROOT_PORT_INTR_ON_MESG_MASK     (PCI_ERR_ROOT_CMD_COR_EN|       \
  21                                        PCI_ERR_ROOT_CMD_NONFATAL_EN|   \
  22                                        PCI_ERR_ROOT_CMD_FATAL_EN)
  23#define ERR_COR_ID(d)                   (d & 0xffff)
  24#define ERR_UNCOR_ID(d)                 (d >> 16)
  25
  26#define AER_ERROR_SOURCES_MAX           100
  27
  28#define AER_LOG_TLP_MASKS               (PCI_ERR_UNC_POISON_TLP|        \
  29                                        PCI_ERR_UNC_ECRC|               \
  30                                        PCI_ERR_UNC_UNSUP|              \
  31                                        PCI_ERR_UNC_COMP_ABORT|         \
  32                                        PCI_ERR_UNC_UNX_COMP|           \
  33                                        PCI_ERR_UNC_MALF_TLP)
  34
  35#define AER_MAX_MULTI_ERR_DEVICES       5       /* Not likely to have more */
  36struct aer_err_info {
  37        struct pci_dev *dev[AER_MAX_MULTI_ERR_DEVICES];
  38        int error_dev_num;
  39
  40        unsigned int id:16;
  41
  42        unsigned int severity:2;        /* 0:NONFATAL | 1:FATAL | 2:COR */
  43        unsigned int __pad1:5;
  44        unsigned int multi_error_valid:1;
  45
  46        unsigned int first_error:5;
  47        unsigned int __pad2:2;
  48        unsigned int tlp_header_valid:1;
  49
  50        unsigned int status;            /* COR/UNCOR Error Status */
  51        unsigned int mask;              /* COR/UNCOR Error Mask */
  52        struct aer_header_log_regs tlp; /* TLP Header */
  53};
  54
  55struct aer_err_source {
  56        unsigned int status;
  57        unsigned int id;
  58};
  59
  60struct aer_rpc {
  61        struct pcie_device *rpd;        /* Root Port device */
  62        struct work_struct dpc_handler;
  63        struct aer_err_source e_sources[AER_ERROR_SOURCES_MAX];
  64        struct aer_err_info e_info;
  65        unsigned short prod_idx;        /* Error Producer Index */
  66        unsigned short cons_idx;        /* Error Consumer Index */
  67        int isr;
  68        spinlock_t e_lock;              /*
  69                                         * Lock access to Error Status/ID Regs
  70                                         * and error producer/consumer index
  71                                         */
  72        struct mutex rpc_mutex;         /*
  73                                         * only one thread could do
  74                                         * recovery on the same
  75                                         * root port hierarchy
  76                                         */
  77};
  78
  79struct aer_broadcast_data {
  80        enum pci_channel_state state;
  81        enum pci_ers_result result;
  82};
  83
  84static inline pci_ers_result_t merge_result(enum pci_ers_result orig,
  85                enum pci_ers_result new)
  86{
  87        if (new == PCI_ERS_RESULT_NO_AER_DRIVER)
  88                return PCI_ERS_RESULT_NO_AER_DRIVER;
  89
  90        if (new == PCI_ERS_RESULT_NONE)
  91                return orig;
  92
  93        switch (orig) {
  94        case PCI_ERS_RESULT_CAN_RECOVER:
  95        case PCI_ERS_RESULT_RECOVERED:
  96                orig = new;
  97                break;
  98        case PCI_ERS_RESULT_DISCONNECT:
  99                if (new == PCI_ERS_RESULT_NEED_RESET)
 100                        orig = PCI_ERS_RESULT_NEED_RESET;
 101                break;
 102        default:
 103                break;
 104        }
 105
 106        return orig;
 107}
 108
 109extern struct bus_type pcie_port_bus_type;
 110void aer_isr(struct work_struct *work);
 111void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
 112void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info);
 113irqreturn_t aer_irq(int irq, void *context);
 114
 115#ifdef CONFIG_ACPI_APEI
 116int pcie_aer_get_firmware_first(struct pci_dev *pci_dev);
 117#else
 118static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev)
 119{
 120        if (pci_dev->__aer_firmware_first_valid)
 121                return pci_dev->__aer_firmware_first;
 122        return 0;
 123}
 124#endif
 125#endif /* _AERDRV_H_ */
 126