@@ -445,8 +445,8 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
printk("%saer_uncor_severity: 0x%08x\n",
pfx, aer->uncor_severity);
printk("%sTLP Header: %08x %08x %08x %08x\n", pfx,
- aer->header_log.dw0, aer->header_log.dw1,
- aer->header_log.dw2, aer->header_log.dw3);
+ aer->header_log.dw[0], aer->header_log.dw[1],
+ aer->header_log.dw[2], aer->header_log.dw[3]);
}
}
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 1999 - 2018 Intel Corporation. */
+#include <linux/aer.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
@@ -391,22 +392,6 @@ u16 ixgbe_read_pci_cfg_word(struct ixgbe_hw *hw, u32 reg)
return value;
}
-#ifdef CONFIG_PCI_IOV
-static u32 ixgbe_read_pci_cfg_dword(struct ixgbe_hw *hw, u32 reg)
-{
- struct ixgbe_adapter *adapter = hw->back;
- u32 value;
-
- if (ixgbe_removed(hw->hw_addr))
- return IXGBE_FAILED_READ_CFG_DWORD;
- pci_read_config_dword(adapter->pdev, reg, &value);
- if (value == IXGBE_FAILED_READ_CFG_DWORD &&
- ixgbe_check_cfg_remove(hw, adapter->pdev))
- return IXGBE_FAILED_READ_CFG_DWORD;
- return value;
-}
-#endif /* CONFIG_PCI_IOV */
-
void ixgbe_write_pci_cfg_word(struct ixgbe_hw *hw, u32 reg, u16 value)
{
struct ixgbe_adapter *adapter = hw->back;
@@ -11332,8 +11317,8 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
#ifdef CONFIG_PCI_IOV
struct ixgbe_hw *hw = &adapter->hw;
struct pci_dev *bdev, *vfdev;
- u32 dw0, dw1, dw2, dw3;
- int vf, pos;
+ struct pcie_tlp_log tlp_log;
+ int vf, pos, ret;
u16 req_id, pf_func;
if (adapter->hw.mac.type == ixgbe_mac_82598EB ||
@@ -11351,14 +11336,13 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
if (!pos)
goto skip_bad_vf_detection;
- dw0 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG);
- dw1 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 4);
- dw2 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 8);
- dw3 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 12);
- if (ixgbe_removed(hw->hw_addr))
+ ret = pcie_read_tlp_log(pdev, pos + PCI_ERR_HEADER_LOG, &tlp_log);
+ if (ret < 0) {
+ ixgbe_check_cfg_remove(hw, pdev);
goto skip_bad_vf_detection;
+ }
- req_id = dw1 >> 16;
+ req_id = tlp_log.dw[1] >> 16;
/* On the 82599 if bit 7 of the requestor ID is set then it's a VF */
if (!(req_id & 0x0080))
goto skip_bad_vf_detection;
@@ -11369,9 +11353,8 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
vf = FIELD_GET(0x7F, req_id);
e_dev_err("VF %d has caused a PCIe error\n", vf);
- e_dev_err("TLP: dw0: %8.8x\tdw1: %8.8x\tdw2: "
- "%8.8x\tdw3: %8.8x\n",
- dw0, dw1, dw2, dw3);
+ e_dev_err("TLP: dw0: %8.8x\tdw1: %8.8x\tdw2: %8.8x\tdw3: %8.8x\n",
+ tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], tlp_log.dw[3]);
switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB:
device_id = IXGBE_82599_VF_DEVICE_ID;
@@ -1067,6 +1067,32 @@ static void pci_enable_acs(struct pci_dev *dev)
pci_disable_acs_redir(dev);
}
+/**
+ * pcie_read_tlp_log - Reads TLP Header Log
+ * @dev: PCIe device
+ * @where: PCI Config offset of TLP Header Log
+ * @tlp_log: TLP Log structure to fill
+ *
+ * Fills @tlp_log from TLP Header Log registers.
+ *
+ * Return: 0 on success and filled TLP Log structure, <0 on error.
+ */
+int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log *tlp_log)
+{
+ int i, ret;
+
+ memset(tlp_log, 0, sizeof(*tlp_log));
+
+ for (i = 0; i < 4; i++) {
+ ret = pci_read_config_dword(dev, where + i * 4, &tlp_log->dw[i]);
+ if (ret)
+ return pcibios_err_to_errno(ret);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pcie_read_tlp_log);
+
/**
* pci_restore_bars - restore a device's BAR values (e.g. after wake-up)
* @dev: PCI device to have its BARs restored
@@ -409,7 +409,7 @@ struct aer_err_info {
unsigned int status; /* COR/UNCOR Error Status */
unsigned int mask; /* COR/UNCOR Error Mask */
- struct aer_header_log_regs tlp; /* TLP Header */
+ struct pcie_tlp_log tlp; /* TLP Header */
};
int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info);
@@ -664,11 +664,10 @@ static void pci_rootport_aer_stats_incr(struct pci_dev *pdev,
}
}
-static void __print_tlp_header(struct pci_dev *dev,
- struct aer_header_log_regs *t)
+static void __print_tlp_header(struct pci_dev *dev, struct pcie_tlp_log *t)
{
pci_err(dev, " TLP Header: %08x %08x %08x %08x\n",
- t->dw0, t->dw1, t->dw2, t->dw3);
+ t->dw[0], t->dw[1], t->dw[2], t->dw[3]);
}
static void __aer_print_error(struct pci_dev *dev,
@@ -1246,14 +1245,7 @@ int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
if (info->status & AER_LOG_TLP_MASKS) {
info->tlp_header_valid = 1;
- pci_read_config_dword(dev,
- aer + PCI_ERR_HEADER_LOG, &info->tlp.dw0);
- pci_read_config_dword(dev,
- aer + PCI_ERR_HEADER_LOG + 4, &info->tlp.dw1);
- pci_read_config_dword(dev,
- aer + PCI_ERR_HEADER_LOG + 8, &info->tlp.dw2);
- pci_read_config_dword(dev,
- aer + PCI_ERR_HEADER_LOG + 12, &info->tlp.dw3);
+ pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG, &info->tlp);
}
}
@@ -190,7 +190,8 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev)
static void dpc_process_rp_pio_error(struct pci_dev *pdev)
{
u16 cap = pdev->dpc_cap, dpc_status, first_error;
- u32 status, mask, sev, syserr, exc, dw0, dw1, dw2, dw3, log, prefix;
+ u32 status, mask, sev, syserr, exc, log, prefix;
+ struct pcie_tlp_log tlp_log;
int i;
pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS, &status);
@@ -216,16 +217,9 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev)
if (pdev->dpc_rp_log_size < 4)
goto clear_status;
- pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG,
- &dw0);
- pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 4,
- &dw1);
- pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 8,
- &dw2);
- pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 12,
- &dw3);
+ pcie_read_tlp_log(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG, &tlp_log);
pci_err(pdev, "TLP Header: %#010x %#010x %#010x %#010x\n",
- dw0, dw1, dw2, dw3);
+ tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], tlp_log.dw[3]);
if (pdev->dpc_rp_log_size < 5)
goto clear_status;
@@ -18,11 +18,8 @@
struct pci_dev;
-struct aer_header_log_regs {
- u32 dw0;
- u32 dw1;
- u32 dw2;
- u32 dw3;
+struct pcie_tlp_log {
+ u32 dw[4];
};
struct aer_capability_regs {
@@ -33,13 +30,15 @@ struct aer_capability_regs {
u32 cor_status;
u32 cor_mask;
u32 cap_control;
- struct aer_header_log_regs header_log;
+ struct pcie_tlp_log header_log;
u32 root_command;
u32 root_status;
u16 cor_err_source;
u16 uncor_err_source;
};
+int pcie_read_tlp_log(struct pci_dev *pdev, int where, struct pcie_tlp_log *tlp_log);
+
#if defined(CONFIG_PCIEAER)
int pci_aer_clear_nonfatal_status(struct pci_dev *dev);
int pcie_aer_is_native(struct pci_dev *dev);
@@ -300,7 +300,7 @@ TRACE_EVENT(aer_event,
const u32 status,
const u8 severity,
const u8 tlp_header_valid,
- struct aer_header_log_regs *tlp),
+ struct pcie_tlp_log *tlp),
TP_ARGS(dev_name, status, severity, tlp_header_valid, tlp),
@@ -318,10 +318,10 @@ TRACE_EVENT(aer_event,
__entry->severity = severity;
__entry->tlp_header_valid = tlp_header_valid;
if (tlp_header_valid) {
- __entry->tlp_header[0] = tlp->dw0;
- __entry->tlp_header[1] = tlp->dw1;
- __entry->tlp_header[2] = tlp->dw2;
- __entry->tlp_header[3] = tlp->dw3;
+ __entry->tlp_header[0] = tlp->dw[0];
+ __entry->tlp_header[1] = tlp->dw[1];
+ __entry->tlp_header[2] = tlp->dw[2];
+ __entry->tlp_header[3] = tlp->dw[3];
}
),