PCI/AER: Generalize TLP Header Log reading
authorIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Tue, 6 Feb 2024 13:57:15 +0000 (15:57 +0200)
committerBjorn Helgaas <bhelgaas@google.com>
Fri, 8 Mar 2024 21:26:46 +0000 (15:26 -0600)
Both AER and DPC RP PIO provide TLP Header Log registers (PCIe r6.1 secs
7.8.4 & 7.9.14) to convey error diagnostics but the struct is named after
AER as the struct aer_header_log_regs. Also, not all places that handle TLP
Header Log use the struct and the struct members are named individually.

Generalize the struct name and members, and use it consistently where TLP
Header Log is being handled so that a pcie_read_tlp_log() helper can be
easily added.

Link: https://lore.kernel.org/r/20240206135717.8565-3-ilpo.jarvinen@linux.intel.com
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
[bhelgaas: drop ixgbe changes for now, tidy whitespace]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/firmware/efi/cper.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pcie/aer.c
drivers/pci/pcie/dpc.c
include/linux/aer.h
include/ras/ras_event.h

index 35c37f667781c7071c714aef274e68dbddca026b..d3f98161171eced48b2e576300dffcd82d3f7d75 100644 (file)
@@ -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]);
        }
 }
 
index d8f11a078924c1336326456b0e3f37f7b0e66df9..a0af94cfcf7dc2247250c1b87d8e977f8b6dcf3c 100644 (file)
@@ -1067,6 +1067,34 @@ disable_acs_redir:
        pci_disable_acs_redir(dev);
 }
 
+/**
+ * pcie_read_tlp_log - read TLP Header Log
+ * @dev: PCIe device
+ * @where: PCI Config offset of TLP Header Log
+ * @tlp_log: TLP Log structure to fill
+ *
+ * Fill @tlp_log from TLP Header Log registers, e.g., AER or DPC.
+ *
+ * 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
index 2336a8d1edab27646220794a3a4cdd085ba7b3e9..a59ba6fde2a08bbf10f0048c0b773bc5fdf84d2b 100644 (file)
@@ -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);
index e31e6a9a7773215e34107e8541845a008d140ecd..ac6293c249766460ddf74ea05a1147651faa21c9 100644 (file)
@@ -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);
                }
        }
 
index 94111e4382413dc57ff10a079e1bdfc50c0e978e..c197bc7f7f2cb72d1d45926d4af896be059c07d3 100644 (file)
@@ -190,7 +190,8 @@ out:
 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;
index ae0fae70d4bd2c15a7109ba89dcfd5974177a930..4b97f38f3fcf22faffb00a2839b306453a453da4 100644 (file)
 
 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 *dev, int where, struct pcie_tlp_log *log);
+
 #if defined(CONFIG_PCIEAER)
 int pci_aer_clear_nonfatal_status(struct pci_dev *dev);
 int pcie_aer_is_native(struct pci_dev *dev);
index cbd3ddd7c33d4d12326bafbc3c33c60c6317358e..c011ea236e9b7fe0fd403262214f223334a7adb0 100644 (file)
@@ -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];
                }
        ),