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
))
43 pos
= pci_find_ext_capability(dev
, PCI_EXT_CAP_ID_ERR
);
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
))
71 pos
= pci_find_ext_capability(dev
, PCI_EXT_CAP_ID_ERR
);
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
))