1 // SPDX-License-Identifier: GPL-2.0
3 * Enables/disables PCIe ECRC checking.
5 * (C) Copyright 2009 Hewlett-Packard Development Company, L.P.
6 * Andrew Patterson <andrew.patterson@hp.com>
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/moduleparam.h>
12 #include <linux/pci.h>
13 #include <linux/pci_regs.h>
14 #include <linux/errno.h>
15 #include "../../pci.h"
17 #define ECRC_POLICY_DEFAULT 0 /* ECRC set by BIOS */
18 #define ECRC_POLICY_OFF 1 /* ECRC off for performance */
19 #define ECRC_POLICY_ON 2 /* ECRC on for data integrity */
21 static int ecrc_policy = ECRC_POLICY_DEFAULT;
23 static const char *ecrc_policy_str[] = {
24 [ECRC_POLICY_DEFAULT] = "bios",
25 [ECRC_POLICY_OFF] = "off",
26 [ECRC_POLICY_ON] = "on"
30 * enable_ercr_checking - enable PCIe ECRC checking for a device
31 * @dev: the PCI device
33 * Returns 0 on success, or negative on failure.
35 static int enable_ecrc_checking(struct pci_dev *dev)
40 if (!pci_is_pcie(dev))
47 pci_read_config_dword(dev, pos + PCI_ERR_CAP, ®32);
48 if (reg32 & PCI_ERR_CAP_ECRC_GENC)
49 reg32 |= PCI_ERR_CAP_ECRC_GENE;
50 if (reg32 & PCI_ERR_CAP_ECRC_CHKC)
51 reg32 |= PCI_ERR_CAP_ECRC_CHKE;
52 pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
58 * disable_ercr_checking - disables PCIe ECRC checking for a device
59 * @dev: the PCI device
61 * Returns 0 on success, or negative on failure.
63 static int disable_ecrc_checking(struct pci_dev *dev)
68 if (!pci_is_pcie(dev))
75 pci_read_config_dword(dev, pos + PCI_ERR_CAP, ®32);
76 reg32 &= ~(PCI_ERR_CAP_ECRC_GENE | PCI_ERR_CAP_ECRC_CHKE);
77 pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
83 * pcie_set_ecrc_checking - set/unset PCIe ECRC checking for a device based on global policy
84 * @dev: the PCI device
86 void pcie_set_ecrc_checking(struct pci_dev *dev)
88 switch (ecrc_policy) {
89 case ECRC_POLICY_DEFAULT:
92 disable_ecrc_checking(dev);
95 enable_ecrc_checking(dev);
103 * pcie_ecrc_get_policy - parse kernel command-line ecrc option
105 void pcie_ecrc_get_policy(char *str)
109 for (i = 0; i < ARRAY_SIZE(ecrc_policy_str); i++)
110 if (!strncmp(str, ecrc_policy_str[i],
111 strlen(ecrc_policy_str[i])))
113 if (i >= ARRAY_SIZE(ecrc_policy_str))