Linux Audio

Check our new training course

Linux BSP development engineering services

Need help to port Linux and bootloaders to your hardware?
Loading...
Note: File does not exist in v6.8.
  1/*
  2 *    Enables/disables PCIe ECRC checking.
  3 *
  4 *    (C) Copyright 2009 Hewlett-Packard Development Company, L.P.
  5 *    Andrew Patterson <andrew.patterson@hp.com>
  6 *
  7 *    This program is free software; you can redistribute it and/or modify
  8 *    it under the terms of the GNU General Public License as published by
  9 *    the Free Software Foundation; version 2 of the License.
 10 *
 11 *    This program is distributed in the hope that it will be useful,
 12 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 *    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 14 *    General Public License for more details.
 15 *
 16 *    You should have received a copy of the GNU General Public License
 17 *    along with this program; if not, write to the Free Software
 18 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 19 *    02111-1307, USA.
 20 *
 21 */
 22
 23#include <linux/kernel.h>
 24#include <linux/module.h>
 25#include <linux/moduleparam.h>
 26#include <linux/pci.h>
 27#include <linux/pci_regs.h>
 28#include <linux/errno.h>
 29#include "../../pci.h"
 30
 31#define ECRC_POLICY_DEFAULT 0		/* ECRC set by BIOS */
 32#define ECRC_POLICY_OFF     1		/* ECRC off for performance */
 33#define ECRC_POLICY_ON      2		/* ECRC on for data integrity */
 34
 35static int ecrc_policy = ECRC_POLICY_DEFAULT;
 36
 37static const char *ecrc_policy_str[] = {
 38	[ECRC_POLICY_DEFAULT] = "bios",
 39	[ECRC_POLICY_OFF] = "off",
 40	[ECRC_POLICY_ON] = "on"
 41};
 42
 43/**
 44 * enable_ercr_checking - enable PCIe ECRC checking for a device
 45 * @dev: the PCI device
 46 *
 47 * Returns 0 on success, or negative on failure.
 48 */
 49static int enable_ecrc_checking(struct pci_dev *dev)
 50{
 51	int pos;
 52	u32 reg32;
 53
 54	if (!pci_is_pcie(dev))
 55		return -ENODEV;
 56
 57	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 58	if (!pos)
 59		return -ENODEV;
 60
 61	pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
 62	if (reg32 & PCI_ERR_CAP_ECRC_GENC)
 63		reg32 |= PCI_ERR_CAP_ECRC_GENE;
 64	if (reg32 & PCI_ERR_CAP_ECRC_CHKC)
 65		reg32 |= PCI_ERR_CAP_ECRC_CHKE;
 66	pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
 67
 68	return 0;
 69}
 70
 71/**
 72 * disable_ercr_checking - disables PCIe ECRC checking for a device
 73 * @dev: the PCI device
 74 *
 75 * Returns 0 on success, or negative on failure.
 76 */
 77static int disable_ecrc_checking(struct pci_dev *dev)
 78{
 79	int pos;
 80	u32 reg32;
 81
 82	if (!pci_is_pcie(dev))
 83		return -ENODEV;
 84
 85	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 86	if (!pos)
 87		return -ENODEV;
 88
 89	pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
 90	reg32 &= ~(PCI_ERR_CAP_ECRC_GENE | PCI_ERR_CAP_ECRC_CHKE);
 91	pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
 92
 93	return 0;
 94}
 95
 96/**
 97 * pcie_set_ecrc_checking - set/unset PCIe ECRC checking for a device based on global policy
 98 * @dev: the PCI device
 99 */
100void pcie_set_ecrc_checking(struct pci_dev *dev)
101{
102	switch (ecrc_policy) {
103	case ECRC_POLICY_DEFAULT:
104		return;
105	case ECRC_POLICY_OFF:
106		disable_ecrc_checking(dev);
107		break;
108	case ECRC_POLICY_ON:
109		enable_ecrc_checking(dev);
110		break;
111	default:
112		return;
113	}
114}
115
116/**
117 * pcie_ecrc_get_policy - parse kernel command-line ecrc option
118 */
119void pcie_ecrc_get_policy(char *str)
120{
121	int i;
122
123	for (i = 0; i < ARRAY_SIZE(ecrc_policy_str); i++)
124		if (!strncmp(str, ecrc_policy_str[i],
125			     strlen(ecrc_policy_str[i])))
126			break;
127	if (i >= ARRAY_SIZE(ecrc_policy_str))
128		return;
129
130	ecrc_policy = i;
131}