129310e5eSGavin Shan /*
229310e5eSGavin Shan  * The file intends to implement the platform dependent EEH operations on
329310e5eSGavin Shan  * powernv platform. Actually, the powernv was created in order to fully
429310e5eSGavin Shan  * hypervisor support.
529310e5eSGavin Shan  *
629310e5eSGavin Shan  * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2013.
729310e5eSGavin Shan  *
829310e5eSGavin Shan  * This program is free software; you can redistribute it and/or modify
929310e5eSGavin Shan  * it under the terms of the GNU General Public License as published by
1029310e5eSGavin Shan  * the Free Software Foundation; either version 2 of the License, or
1129310e5eSGavin Shan  * (at your option) any later version.
1229310e5eSGavin Shan  */
1329310e5eSGavin Shan 
1429310e5eSGavin Shan #include <linux/atomic.h>
154cf17445SGavin Shan #include <linux/debugfs.h>
1629310e5eSGavin Shan #include <linux/delay.h>
1729310e5eSGavin Shan #include <linux/export.h>
1829310e5eSGavin Shan #include <linux/init.h>
1929310e5eSGavin Shan #include <linux/list.h>
2029310e5eSGavin Shan #include <linux/msi.h>
2129310e5eSGavin Shan #include <linux/of.h>
2229310e5eSGavin Shan #include <linux/pci.h>
2329310e5eSGavin Shan #include <linux/proc_fs.h>
2429310e5eSGavin Shan #include <linux/rbtree.h>
2529310e5eSGavin Shan #include <linux/sched.h>
2629310e5eSGavin Shan #include <linux/seq_file.h>
2729310e5eSGavin Shan #include <linux/spinlock.h>
2829310e5eSGavin Shan 
2929310e5eSGavin Shan #include <asm/eeh.h>
3029310e5eSGavin Shan #include <asm/eeh_event.h>
3129310e5eSGavin Shan #include <asm/firmware.h>
3229310e5eSGavin Shan #include <asm/io.h>
3329310e5eSGavin Shan #include <asm/iommu.h>
3429310e5eSGavin Shan #include <asm/machdep.h>
3529310e5eSGavin Shan #include <asm/msi_bitmap.h>
3629310e5eSGavin Shan #include <asm/opal.h>
3729310e5eSGavin Shan #include <asm/ppc-pci.h>
3829310e5eSGavin Shan 
3929310e5eSGavin Shan #include "powernv.h"
4029310e5eSGavin Shan #include "pci.h"
4129310e5eSGavin Shan 
424cf17445SGavin Shan static bool pnv_eeh_nb_init = false;
434cf17445SGavin Shan 
4429310e5eSGavin Shan /**
4501f3bfb7SGavin Shan  * pnv_eeh_init - EEH platform dependent initialization
4629310e5eSGavin Shan  *
4729310e5eSGavin Shan  * EEH platform dependent initialization on powernv
4829310e5eSGavin Shan  */
4901f3bfb7SGavin Shan static int pnv_eeh_init(void)
5029310e5eSGavin Shan {
51dc561fb9SGavin Shan 	struct pci_controller *hose;
52dc561fb9SGavin Shan 	struct pnv_phb *phb;
53dc561fb9SGavin Shan 
5429310e5eSGavin Shan 	/* We require OPALv3 */
5529310e5eSGavin Shan 	if (!firmware_has_feature(FW_FEATURE_OPALv3)) {
560dae2743SGavin Shan 		pr_warn("%s: OPALv3 is required !\n",
570dae2743SGavin Shan 			__func__);
5829310e5eSGavin Shan 		return -EINVAL;
5929310e5eSGavin Shan 	}
6029310e5eSGavin Shan 
6105b1721dSGavin Shan 	/* Set probe mode */
6205b1721dSGavin Shan 	eeh_add_flag(EEH_PROBE_MODE_DEV);
6329310e5eSGavin Shan 
64dc561fb9SGavin Shan 	/*
65dc561fb9SGavin Shan 	 * P7IOC blocks PCI config access to frozen PE, but PHB3
66dc561fb9SGavin Shan 	 * doesn't do that. So we have to selectively enable I/O
67dc561fb9SGavin Shan 	 * prior to collecting error log.
68dc561fb9SGavin Shan 	 */
69dc561fb9SGavin Shan 	list_for_each_entry(hose, &hose_list, list_node) {
70dc561fb9SGavin Shan 		phb = hose->private_data;
71dc561fb9SGavin Shan 
72dc561fb9SGavin Shan 		if (phb->model == PNV_PHB_MODEL_P7IOC)
73dc561fb9SGavin Shan 			eeh_add_flag(EEH_ENABLE_IO_FOR_LOG);
742aa5cf9eSGavin Shan 
752aa5cf9eSGavin Shan 		/*
762aa5cf9eSGavin Shan 		 * PE#0 should be regarded as valid by EEH core
772aa5cf9eSGavin Shan 		 * if it's not the reserved one. Currently, we
782aa5cf9eSGavin Shan 		 * have the reserved PE#0 and PE#127 for PHB3
792aa5cf9eSGavin Shan 		 * and P7IOC separately. So we should regard
802aa5cf9eSGavin Shan 		 * PE#0 as valid for P7IOC.
812aa5cf9eSGavin Shan 		 */
822aa5cf9eSGavin Shan 		if (phb->ioda.reserved_pe != 0)
832aa5cf9eSGavin Shan 			eeh_add_flag(EEH_VALID_PE_ZERO);
842aa5cf9eSGavin Shan 
85dc561fb9SGavin Shan 		break;
86dc561fb9SGavin Shan 	}
87dc561fb9SGavin Shan 
8829310e5eSGavin Shan 	return 0;
8929310e5eSGavin Shan }
9029310e5eSGavin Shan 
914cf17445SGavin Shan static int pnv_eeh_event(struct notifier_block *nb,
924cf17445SGavin Shan 			 unsigned long events, void *change)
934cf17445SGavin Shan {
944cf17445SGavin Shan 	uint64_t changed_evts = (uint64_t)change;
954cf17445SGavin Shan 
964cf17445SGavin Shan 	/*
974cf17445SGavin Shan 	 * We simply send special EEH event if EEH has
984cf17445SGavin Shan 	 * been enabled, or clear pending events in
994cf17445SGavin Shan 	 * case that we enable EEH soon
1004cf17445SGavin Shan 	 */
1014cf17445SGavin Shan 	if (!(changed_evts & OPAL_EVENT_PCI_ERROR) ||
1024cf17445SGavin Shan 	    !(events & OPAL_EVENT_PCI_ERROR))
1034cf17445SGavin Shan 		return 0;
1044cf17445SGavin Shan 
1054cf17445SGavin Shan 	if (eeh_enabled())
1064cf17445SGavin Shan 		eeh_send_failure_event(NULL);
1074cf17445SGavin Shan 	else
1084cf17445SGavin Shan 		opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul);
1094cf17445SGavin Shan 
1104cf17445SGavin Shan 	return 0;
1114cf17445SGavin Shan }
1124cf17445SGavin Shan 
1134cf17445SGavin Shan static struct notifier_block pnv_eeh_nb = {
1144cf17445SGavin Shan 	.notifier_call	= pnv_eeh_event,
1154cf17445SGavin Shan 	.next		= NULL,
1164cf17445SGavin Shan 	.priority	= 0
1174cf17445SGavin Shan };
1184cf17445SGavin Shan 
1194cf17445SGavin Shan #ifdef CONFIG_DEBUG_FS
1204cf17445SGavin Shan static ssize_t pnv_eeh_ei_write(struct file *filp,
1214cf17445SGavin Shan 				const char __user *user_buf,
1224cf17445SGavin Shan 				size_t count, loff_t *ppos)
1234cf17445SGavin Shan {
1244cf17445SGavin Shan 	struct pci_controller *hose = filp->private_data;
1254cf17445SGavin Shan 	struct eeh_dev *edev;
1264cf17445SGavin Shan 	struct eeh_pe *pe;
1274cf17445SGavin Shan 	int pe_no, type, func;
1284cf17445SGavin Shan 	unsigned long addr, mask;
1294cf17445SGavin Shan 	char buf[50];
1304cf17445SGavin Shan 	int ret;
1314cf17445SGavin Shan 
1324cf17445SGavin Shan 	if (!eeh_ops || !eeh_ops->err_inject)
1334cf17445SGavin Shan 		return -ENXIO;
1344cf17445SGavin Shan 
1354cf17445SGavin Shan 	/* Copy over argument buffer */
1364cf17445SGavin Shan 	ret = simple_write_to_buffer(buf, sizeof(buf), ppos, user_buf, count);
1374cf17445SGavin Shan 	if (!ret)
1384cf17445SGavin Shan 		return -EFAULT;
1394cf17445SGavin Shan 
1404cf17445SGavin Shan 	/* Retrieve parameters */
1414cf17445SGavin Shan 	ret = sscanf(buf, "%x:%x:%x:%lx:%lx",
1424cf17445SGavin Shan 		     &pe_no, &type, &func, &addr, &mask);
1434cf17445SGavin Shan 	if (ret != 5)
1444cf17445SGavin Shan 		return -EINVAL;
1454cf17445SGavin Shan 
1464cf17445SGavin Shan 	/* Retrieve PE */
1474cf17445SGavin Shan 	edev = kzalloc(sizeof(*edev), GFP_KERNEL);
1484cf17445SGavin Shan 	if (!edev)
1494cf17445SGavin Shan 		return -ENOMEM;
1504cf17445SGavin Shan 	edev->phb = hose;
1514cf17445SGavin Shan 	edev->pe_config_addr = pe_no;
1524cf17445SGavin Shan 	pe = eeh_pe_get(edev);
1534cf17445SGavin Shan 	kfree(edev);
1544cf17445SGavin Shan 	if (!pe)
1554cf17445SGavin Shan 		return -ENODEV;
1564cf17445SGavin Shan 
1574cf17445SGavin Shan 	/* Do error injection */
1584cf17445SGavin Shan 	ret = eeh_ops->err_inject(pe, type, func, addr, mask);
1594cf17445SGavin Shan 	return ret < 0 ? ret : count;
1604cf17445SGavin Shan }
1614cf17445SGavin Shan 
1624cf17445SGavin Shan static const struct file_operations pnv_eeh_ei_fops = {
1634cf17445SGavin Shan 	.open	= simple_open,
1644cf17445SGavin Shan 	.llseek	= no_llseek,
1654cf17445SGavin Shan 	.write	= pnv_eeh_ei_write,
1664cf17445SGavin Shan };
1674cf17445SGavin Shan 
1684cf17445SGavin Shan static int pnv_eeh_dbgfs_set(void *data, int offset, u64 val)
1694cf17445SGavin Shan {
1704cf17445SGavin Shan 	struct pci_controller *hose = data;
1714cf17445SGavin Shan 	struct pnv_phb *phb = hose->private_data;
1724cf17445SGavin Shan 
1734cf17445SGavin Shan 	out_be64(phb->regs + offset, val);
1744cf17445SGavin Shan 	return 0;
1754cf17445SGavin Shan }
1764cf17445SGavin Shan 
1774cf17445SGavin Shan static int pnv_eeh_dbgfs_get(void *data, int offset, u64 *val)
1784cf17445SGavin Shan {
1794cf17445SGavin Shan 	struct pci_controller *hose = data;
1804cf17445SGavin Shan 	struct pnv_phb *phb = hose->private_data;
1814cf17445SGavin Shan 
1824cf17445SGavin Shan 	*val = in_be64(phb->regs + offset);
1834cf17445SGavin Shan 	return 0;
1844cf17445SGavin Shan }
1854cf17445SGavin Shan 
1864cf17445SGavin Shan static int pnv_eeh_outb_dbgfs_set(void *data, u64 val)
1874cf17445SGavin Shan {
1884cf17445SGavin Shan 	return pnv_eeh_dbgfs_set(data, 0xD10, val);
1894cf17445SGavin Shan }
1904cf17445SGavin Shan 
1914cf17445SGavin Shan static int pnv_eeh_outb_dbgfs_get(void *data, u64 *val)
1924cf17445SGavin Shan {
1934cf17445SGavin Shan 	return pnv_eeh_dbgfs_get(data, 0xD10, val);
1944cf17445SGavin Shan }
1954cf17445SGavin Shan 
1964cf17445SGavin Shan static int pnv_eeh_inbA_dbgfs_set(void *data, u64 val)
1974cf17445SGavin Shan {
1984cf17445SGavin Shan 	return pnv_eeh_dbgfs_set(data, 0xD90, val);
1994cf17445SGavin Shan }
2004cf17445SGavin Shan 
2014cf17445SGavin Shan static int pnv_eeh_inbA_dbgfs_get(void *data, u64 *val)
2024cf17445SGavin Shan {
2034cf17445SGavin Shan 	return pnv_eeh_dbgfs_get(data, 0xD90, val);
2044cf17445SGavin Shan }
2054cf17445SGavin Shan 
2064cf17445SGavin Shan static int pnv_eeh_inbB_dbgfs_set(void *data, u64 val)
2074cf17445SGavin Shan {
2084cf17445SGavin Shan 	return pnv_eeh_dbgfs_set(data, 0xE10, val);
2094cf17445SGavin Shan }
2104cf17445SGavin Shan 
2114cf17445SGavin Shan static int pnv_eeh_inbB_dbgfs_get(void *data, u64 *val)
2124cf17445SGavin Shan {
2134cf17445SGavin Shan 	return pnv_eeh_dbgfs_get(data, 0xE10, val);
2144cf17445SGavin Shan }
2154cf17445SGavin Shan 
2164cf17445SGavin Shan DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_outb_dbgfs_ops, pnv_eeh_outb_dbgfs_get,
2174cf17445SGavin Shan 			pnv_eeh_outb_dbgfs_set, "0x%llx\n");
2184cf17445SGavin Shan DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_inbA_dbgfs_ops, pnv_eeh_inbA_dbgfs_get,
2194cf17445SGavin Shan 			pnv_eeh_inbA_dbgfs_set, "0x%llx\n");
2204cf17445SGavin Shan DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_inbB_dbgfs_ops, pnv_eeh_inbB_dbgfs_get,
2214cf17445SGavin Shan 			pnv_eeh_inbB_dbgfs_set, "0x%llx\n");
2224cf17445SGavin Shan #endif /* CONFIG_DEBUG_FS */
2234cf17445SGavin Shan 
22429310e5eSGavin Shan /**
22501f3bfb7SGavin Shan  * pnv_eeh_post_init - EEH platform dependent post initialization
22629310e5eSGavin Shan  *
22729310e5eSGavin Shan  * EEH platform dependent post initialization on powernv. When
22829310e5eSGavin Shan  * the function is called, the EEH PEs and devices should have
22929310e5eSGavin Shan  * been built. If the I/O cache staff has been built, EEH is
23029310e5eSGavin Shan  * ready to supply service.
23129310e5eSGavin Shan  */
23201f3bfb7SGavin Shan static int pnv_eeh_post_init(void)
23329310e5eSGavin Shan {
23429310e5eSGavin Shan 	struct pci_controller *hose;
23529310e5eSGavin Shan 	struct pnv_phb *phb;
23629310e5eSGavin Shan 	int ret = 0;
23729310e5eSGavin Shan 
2384cf17445SGavin Shan 	/* Register OPAL event notifier */
2394cf17445SGavin Shan 	if (!pnv_eeh_nb_init) {
2404cf17445SGavin Shan 		ret = opal_notifier_register(&pnv_eeh_nb);
2414cf17445SGavin Shan 		if (ret) {
2424cf17445SGavin Shan 			pr_warn("%s: Can't register OPAL event notifier (%d)\n",
2434cf17445SGavin Shan 				__func__, ret);
2444cf17445SGavin Shan 			return ret;
2454cf17445SGavin Shan 		}
2464cf17445SGavin Shan 
2474cf17445SGavin Shan 		pnv_eeh_nb_init = true;
2484cf17445SGavin Shan 	}
2494cf17445SGavin Shan 
25029310e5eSGavin Shan 	list_for_each_entry(hose, &hose_list, list_node) {
25129310e5eSGavin Shan 		phb = hose->private_data;
25229310e5eSGavin Shan 
2534cf17445SGavin Shan 		/*
2544cf17445SGavin Shan 		 * If EEH is enabled, we're going to rely on that.
2554cf17445SGavin Shan 		 * Otherwise, we restore to conventional mechanism
2564cf17445SGavin Shan 		 * to clear frozen PE during PCI config access.
2574cf17445SGavin Shan 		 */
2584cf17445SGavin Shan 		if (eeh_enabled())
2594cf17445SGavin Shan 			phb->flags |= PNV_PHB_FLAG_EEH;
2604cf17445SGavin Shan 		else
2614cf17445SGavin Shan 			phb->flags &= ~PNV_PHB_FLAG_EEH;
2624cf17445SGavin Shan 
2634cf17445SGavin Shan 		/* Create debugfs entries */
2644cf17445SGavin Shan #ifdef CONFIG_DEBUG_FS
2654cf17445SGavin Shan 		if (phb->has_dbgfs || !phb->dbgfs)
2664cf17445SGavin Shan 			continue;
2674cf17445SGavin Shan 
2684cf17445SGavin Shan 		phb->has_dbgfs = 1;
2694cf17445SGavin Shan 		debugfs_create_file("err_injct", 0200,
2704cf17445SGavin Shan 				    phb->dbgfs, hose,
2714cf17445SGavin Shan 				    &pnv_eeh_ei_fops);
2724cf17445SGavin Shan 
2734cf17445SGavin Shan 		debugfs_create_file("err_injct_outbound", 0600,
2744cf17445SGavin Shan 				    phb->dbgfs, hose,
2754cf17445SGavin Shan 				    &pnv_eeh_outb_dbgfs_ops);
2764cf17445SGavin Shan 		debugfs_create_file("err_injct_inboundA", 0600,
2774cf17445SGavin Shan 				    phb->dbgfs, hose,
2784cf17445SGavin Shan 				    &pnv_eeh_inbA_dbgfs_ops);
2794cf17445SGavin Shan 		debugfs_create_file("err_injct_inboundB", 0600,
2804cf17445SGavin Shan 				    phb->dbgfs, hose,
2814cf17445SGavin Shan 				    &pnv_eeh_inbB_dbgfs_ops);
2824cf17445SGavin Shan #endif /* CONFIG_DEBUG_FS */
28329310e5eSGavin Shan 	}
2844cf17445SGavin Shan 
28529310e5eSGavin Shan 
28629310e5eSGavin Shan 	return ret;
28729310e5eSGavin Shan }
28829310e5eSGavin Shan 
28929310e5eSGavin Shan /**
29001f3bfb7SGavin Shan  * pnv_eeh_dev_probe - Do probe on PCI device
29129310e5eSGavin Shan  * @dev: PCI device
29229310e5eSGavin Shan  * @flag: unused
29329310e5eSGavin Shan  *
29429310e5eSGavin Shan  * When EEH module is installed during system boot, all PCI devices
29529310e5eSGavin Shan  * are checked one by one to see if it supports EEH. The function
29629310e5eSGavin Shan  * is introduced for the purpose. By default, EEH has been enabled
29729310e5eSGavin Shan  * on all PCI devices. That's to say, we only need do necessary
29829310e5eSGavin Shan  * initialization on the corresponding eeh device and create PE
29929310e5eSGavin Shan  * accordingly.
30029310e5eSGavin Shan  *
30129310e5eSGavin Shan  * It's notable that's unsafe to retrieve the EEH device through
30229310e5eSGavin Shan  * the corresponding PCI device. During the PCI device hotplug, which
30329310e5eSGavin Shan  * was possiblly triggered by EEH core, the binding between EEH device
30429310e5eSGavin Shan  * and the PCI device isn't built yet.
30529310e5eSGavin Shan  */
30601f3bfb7SGavin Shan static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag)
30729310e5eSGavin Shan {
30829310e5eSGavin Shan 	struct pci_controller *hose = pci_bus_to_host(dev->bus);
30929310e5eSGavin Shan 	struct pnv_phb *phb = hose->private_data;
31029310e5eSGavin Shan 	struct device_node *dn = pci_device_to_OF_node(dev);
31129310e5eSGavin Shan 	struct eeh_dev *edev = of_node_to_eeh_dev(dn);
312dadcd6d6SMike Qiu 	int ret;
31329310e5eSGavin Shan 
31429310e5eSGavin Shan 	/*
31529310e5eSGavin Shan 	 * When probing the root bridge, which doesn't have any
31629310e5eSGavin Shan 	 * subordinate PCI devices. We don't have OF node for
31729310e5eSGavin Shan 	 * the root bridge. So it's not reasonable to continue
31829310e5eSGavin Shan 	 * the probing.
31929310e5eSGavin Shan 	 */
320f5c57710SGavin Shan 	if (!dn || !edev || edev->pe)
32129310e5eSGavin Shan 		return 0;
32229310e5eSGavin Shan 
32329310e5eSGavin Shan 	/* Skip for PCI-ISA bridge */
32429310e5eSGavin Shan 	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
32529310e5eSGavin Shan 		return 0;
32629310e5eSGavin Shan 
32729310e5eSGavin Shan 	/* Initialize eeh device */
32829310e5eSGavin Shan 	edev->class_code = dev->class;
329ab55d218SGavin Shan 	edev->mode	&= 0xFFFFFF00;
3304b83bd45SGavin Shan 	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
3314b83bd45SGavin Shan 		edev->mode |= EEH_DEV_BRIDGE;
3322a18dfc6SGavin Shan 	edev->pcix_cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
3334b83bd45SGavin Shan 	if (pci_is_pcie(dev)) {
3344b83bd45SGavin Shan 		edev->pcie_cap = pci_pcie_cap(dev);
3354b83bd45SGavin Shan 
3364b83bd45SGavin Shan 		if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
3374b83bd45SGavin Shan 			edev->mode |= EEH_DEV_ROOT_PORT;
3384b83bd45SGavin Shan 		else if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM)
3394b83bd45SGavin Shan 			edev->mode |= EEH_DEV_DS_PORT;
3402a18dfc6SGavin Shan 
3412a18dfc6SGavin Shan 		edev->aer_cap = pci_find_ext_capability(dev,
3422a18dfc6SGavin Shan 							PCI_EXT_CAP_ID_ERR);
3434b83bd45SGavin Shan 	}
3444b83bd45SGavin Shan 
34529310e5eSGavin Shan 	edev->config_addr	= ((dev->bus->number << 8) | dev->devfn);
34629310e5eSGavin Shan 	edev->pe_config_addr	= phb->bdfn_to_pe(phb, dev->bus, dev->devfn & 0xff);
34729310e5eSGavin Shan 
34829310e5eSGavin Shan 	/* Create PE */
349dadcd6d6SMike Qiu 	ret = eeh_add_to_parent_pe(edev);
350dadcd6d6SMike Qiu 	if (ret) {
351dadcd6d6SMike Qiu 		pr_warn("%s: Can't add PCI dev %s to parent PE (%d)\n",
352dadcd6d6SMike Qiu 			__func__, pci_name(dev), ret);
353dadcd6d6SMike Qiu 		return ret;
354dadcd6d6SMike Qiu 	}
355dadcd6d6SMike Qiu 
356dadcd6d6SMike Qiu 	/*
357b6541db1SGavin Shan 	 * If the PE contains any one of following adapters, the
358b6541db1SGavin Shan 	 * PCI config space can't be accessed when dumping EEH log.
359b6541db1SGavin Shan 	 * Otherwise, we will run into fenced PHB caused by shortage
360b6541db1SGavin Shan 	 * of outbound credits in the adapter. The PCI config access
361b6541db1SGavin Shan 	 * should be blocked until PE reset. MMIO access is dropped
362b6541db1SGavin Shan 	 * by hardware certainly. In order to drop PCI config requests,
363b6541db1SGavin Shan 	 * one more flag (EEH_PE_CFG_RESTRICTED) is introduced, which
364b6541db1SGavin Shan 	 * will be checked in the backend for PE state retrival. If
365b6541db1SGavin Shan 	 * the PE becomes frozen for the first time and the flag has
366b6541db1SGavin Shan 	 * been set for the PE, we will set EEH_PE_CFG_BLOCKED for
367b6541db1SGavin Shan 	 * that PE to block its config space.
368b6541db1SGavin Shan 	 *
369b6541db1SGavin Shan 	 * Broadcom Austin 4-ports NICs (14e4:1657)
370179ea48bSGavin Shan 	 * Broadcom Shiner 2-ports 10G NICs (14e4:168e)
371b6541db1SGavin Shan 	 */
372179ea48bSGavin Shan 	if ((dev->vendor == PCI_VENDOR_ID_BROADCOM && dev->device == 0x1657) ||
373179ea48bSGavin Shan 	    (dev->vendor == PCI_VENDOR_ID_BROADCOM && dev->device == 0x168e))
374b6541db1SGavin Shan 		edev->pe->state |= EEH_PE_CFG_RESTRICTED;
375b6541db1SGavin Shan 
376b6541db1SGavin Shan 	/*
377dadcd6d6SMike Qiu 	 * Cache the PE primary bus, which can't be fetched when
378dadcd6d6SMike Qiu 	 * full hotplug is in progress. In that case, all child
379dadcd6d6SMike Qiu 	 * PCI devices of the PE are expected to be removed prior
380dadcd6d6SMike Qiu 	 * to PE reset.
381dadcd6d6SMike Qiu 	 */
382dadcd6d6SMike Qiu 	if (!edev->pe->bus)
383dadcd6d6SMike Qiu 		edev->pe->bus = dev->bus;
38429310e5eSGavin Shan 
38529310e5eSGavin Shan 	/*
38629310e5eSGavin Shan 	 * Enable EEH explicitly so that we will do EEH check
38729310e5eSGavin Shan 	 * while accessing I/O stuff
38829310e5eSGavin Shan 	 */
38905b1721dSGavin Shan 	eeh_add_flag(EEH_ENABLED);
39029310e5eSGavin Shan 
39129310e5eSGavin Shan 	/* Save memory bars */
39229310e5eSGavin Shan 	eeh_save_bars(edev);
39329310e5eSGavin Shan 
39429310e5eSGavin Shan 	return 0;
39529310e5eSGavin Shan }
39629310e5eSGavin Shan 
39729310e5eSGavin Shan /**
39801f3bfb7SGavin Shan  * pnv_eeh_set_option - Initialize EEH or MMIO/DMA reenable
39929310e5eSGavin Shan  * @pe: EEH PE
40029310e5eSGavin Shan  * @option: operation to be issued
40129310e5eSGavin Shan  *
40229310e5eSGavin Shan  * The function is used to control the EEH functionality globally.
40329310e5eSGavin Shan  * Currently, following options are support according to PAPR:
40429310e5eSGavin Shan  * Enable EEH, Disable EEH, Enable MMIO and Enable DMA
40529310e5eSGavin Shan  */
40601f3bfb7SGavin Shan static int pnv_eeh_set_option(struct eeh_pe *pe, int option)
40729310e5eSGavin Shan {
40829310e5eSGavin Shan 	struct pci_controller *hose = pe->phb;
40929310e5eSGavin Shan 	struct pnv_phb *phb = hose->private_data;
41029310e5eSGavin Shan 	int ret = -EEXIST;
41129310e5eSGavin Shan 
41229310e5eSGavin Shan 	/*
41329310e5eSGavin Shan 	 * What we need do is pass it down for hardware
41429310e5eSGavin Shan 	 * implementation to handle it.
41529310e5eSGavin Shan 	 */
41629310e5eSGavin Shan 	if (phb->eeh_ops && phb->eeh_ops->set_option)
41729310e5eSGavin Shan 		ret = phb->eeh_ops->set_option(pe, option);
41829310e5eSGavin Shan 
41929310e5eSGavin Shan 	return ret;
42029310e5eSGavin Shan }
42129310e5eSGavin Shan 
42229310e5eSGavin Shan /**
42301f3bfb7SGavin Shan  * pnv_eeh_get_pe_addr - Retrieve PE address
42429310e5eSGavin Shan  * @pe: EEH PE
42529310e5eSGavin Shan  *
42629310e5eSGavin Shan  * Retrieve the PE address according to the given tranditional
42729310e5eSGavin Shan  * PCI BDF (Bus/Device/Function) address.
42829310e5eSGavin Shan  */
42901f3bfb7SGavin Shan static int pnv_eeh_get_pe_addr(struct eeh_pe *pe)
43029310e5eSGavin Shan {
43129310e5eSGavin Shan 	return pe->addr;
43229310e5eSGavin Shan }
43329310e5eSGavin Shan 
43429310e5eSGavin Shan /**
43501f3bfb7SGavin Shan  * pnv_eeh_get_state - Retrieve PE state
43629310e5eSGavin Shan  * @pe: EEH PE
43729310e5eSGavin Shan  * @delay: delay while PE state is temporarily unavailable
43829310e5eSGavin Shan  *
43929310e5eSGavin Shan  * Retrieve the state of the specified PE. For IODA-compitable
44029310e5eSGavin Shan  * platform, it should be retrieved from IODA table. Therefore,
44129310e5eSGavin Shan  * we prefer passing down to hardware implementation to handle
44229310e5eSGavin Shan  * it.
44329310e5eSGavin Shan  */
44401f3bfb7SGavin Shan static int pnv_eeh_get_state(struct eeh_pe *pe, int *delay)
44529310e5eSGavin Shan {
44629310e5eSGavin Shan 	struct pci_controller *hose = pe->phb;
44729310e5eSGavin Shan 	struct pnv_phb *phb = hose->private_data;
44829310e5eSGavin Shan 	int ret = EEH_STATE_NOT_SUPPORT;
44929310e5eSGavin Shan 
45029310e5eSGavin Shan 	if (phb->eeh_ops && phb->eeh_ops->get_state) {
45129310e5eSGavin Shan 		ret = phb->eeh_ops->get_state(pe);
45229310e5eSGavin Shan 
45329310e5eSGavin Shan 		/*
45429310e5eSGavin Shan 		 * If the PE state is temporarily unavailable,
45529310e5eSGavin Shan 		 * to inform the EEH core delay for default
45629310e5eSGavin Shan 		 * period (1 second)
45729310e5eSGavin Shan 		 */
45829310e5eSGavin Shan 		if (delay) {
45929310e5eSGavin Shan 			*delay = 0;
46029310e5eSGavin Shan 			if (ret & EEH_STATE_UNAVAILABLE)
46129310e5eSGavin Shan 				*delay = 1000;
46229310e5eSGavin Shan 		}
46329310e5eSGavin Shan 	}
46429310e5eSGavin Shan 
46529310e5eSGavin Shan 	return ret;
46629310e5eSGavin Shan }
46729310e5eSGavin Shan 
46829310e5eSGavin Shan /**
46901f3bfb7SGavin Shan  * pnv_eeh_reset - Reset the specified PE
47029310e5eSGavin Shan  * @pe: EEH PE
47129310e5eSGavin Shan  * @option: reset option
47229310e5eSGavin Shan  *
47329310e5eSGavin Shan  * Reset the specified PE
47429310e5eSGavin Shan  */
47501f3bfb7SGavin Shan static int pnv_eeh_reset(struct eeh_pe *pe, int option)
47629310e5eSGavin Shan {
47729310e5eSGavin Shan 	struct pci_controller *hose = pe->phb;
47829310e5eSGavin Shan 	struct pnv_phb *phb = hose->private_data;
47929310e5eSGavin Shan 	int ret = -EEXIST;
48029310e5eSGavin Shan 
48129310e5eSGavin Shan 	if (phb->eeh_ops && phb->eeh_ops->reset)
48229310e5eSGavin Shan 		ret = phb->eeh_ops->reset(pe, option);
48329310e5eSGavin Shan 
48429310e5eSGavin Shan 	return ret;
48529310e5eSGavin Shan }
48629310e5eSGavin Shan 
48729310e5eSGavin Shan /**
48801f3bfb7SGavin Shan  * pnv_eeh_wait_state - Wait for PE state
48929310e5eSGavin Shan  * @pe: EEH PE
49029310e5eSGavin Shan  * @max_wait: maximal period in microsecond
49129310e5eSGavin Shan  *
49229310e5eSGavin Shan  * Wait for the state of associated PE. It might take some time
49329310e5eSGavin Shan  * to retrieve the PE's state.
49429310e5eSGavin Shan  */
49501f3bfb7SGavin Shan static int pnv_eeh_wait_state(struct eeh_pe *pe, int max_wait)
49629310e5eSGavin Shan {
49729310e5eSGavin Shan 	int ret;
49829310e5eSGavin Shan 	int mwait;
49929310e5eSGavin Shan 
50029310e5eSGavin Shan 	while (1) {
50101f3bfb7SGavin Shan 		ret = pnv_eeh_get_state(pe, &mwait);
50229310e5eSGavin Shan 
50329310e5eSGavin Shan 		/*
50429310e5eSGavin Shan 		 * If the PE's state is temporarily unavailable,
50529310e5eSGavin Shan 		 * we have to wait for the specified time. Otherwise,
50629310e5eSGavin Shan 		 * the PE's state will be returned immediately.
50729310e5eSGavin Shan 		 */
50829310e5eSGavin Shan 		if (ret != EEH_STATE_UNAVAILABLE)
50929310e5eSGavin Shan 			return ret;
51029310e5eSGavin Shan 
51129310e5eSGavin Shan 		max_wait -= mwait;
51229310e5eSGavin Shan 		if (max_wait <= 0) {
5130dae2743SGavin Shan 			pr_warn("%s: Timeout getting PE#%x's state (%d)\n",
51429310e5eSGavin Shan 				__func__, pe->addr, max_wait);
51529310e5eSGavin Shan 			return EEH_STATE_NOT_SUPPORT;
51629310e5eSGavin Shan 		}
51729310e5eSGavin Shan 
51829310e5eSGavin Shan 		msleep(mwait);
51929310e5eSGavin Shan 	}
52029310e5eSGavin Shan 
52129310e5eSGavin Shan 	return EEH_STATE_NOT_SUPPORT;
52229310e5eSGavin Shan }
52329310e5eSGavin Shan 
52429310e5eSGavin Shan /**
52501f3bfb7SGavin Shan  * pnv_eeh_get_log - Retrieve error log
52629310e5eSGavin Shan  * @pe: EEH PE
52729310e5eSGavin Shan  * @severity: temporary or permanent error log
52829310e5eSGavin Shan  * @drv_log: driver log to be combined with retrieved error log
52929310e5eSGavin Shan  * @len: length of driver log
53029310e5eSGavin Shan  *
53129310e5eSGavin Shan  * Retrieve the temporary or permanent error from the PE.
53229310e5eSGavin Shan  */
53301f3bfb7SGavin Shan static int pnv_eeh_get_log(struct eeh_pe *pe, int severity,
53429310e5eSGavin Shan 			   char *drv_log, unsigned long len)
53529310e5eSGavin Shan {
53629310e5eSGavin Shan 	struct pci_controller *hose = pe->phb;
53729310e5eSGavin Shan 	struct pnv_phb *phb = hose->private_data;
53829310e5eSGavin Shan 	int ret = -EEXIST;
53929310e5eSGavin Shan 
54029310e5eSGavin Shan 	if (phb->eeh_ops && phb->eeh_ops->get_log)
54129310e5eSGavin Shan 		ret = phb->eeh_ops->get_log(pe, severity, drv_log, len);
54229310e5eSGavin Shan 
54329310e5eSGavin Shan 	return ret;
54429310e5eSGavin Shan }
54529310e5eSGavin Shan 
54629310e5eSGavin Shan /**
54701f3bfb7SGavin Shan  * pnv_eeh_configure_bridge - Configure PCI bridges in the indicated PE
54829310e5eSGavin Shan  * @pe: EEH PE
54929310e5eSGavin Shan  *
55029310e5eSGavin Shan  * The function will be called to reconfigure the bridges included
55129310e5eSGavin Shan  * in the specified PE so that the mulfunctional PE would be recovered
55229310e5eSGavin Shan  * again.
55329310e5eSGavin Shan  */
55401f3bfb7SGavin Shan static int pnv_eeh_configure_bridge(struct eeh_pe *pe)
55529310e5eSGavin Shan {
55629310e5eSGavin Shan 	struct pci_controller *hose = pe->phb;
55729310e5eSGavin Shan 	struct pnv_phb *phb = hose->private_data;
55829310e5eSGavin Shan 	int ret = 0;
55929310e5eSGavin Shan 
56029310e5eSGavin Shan 	if (phb->eeh_ops && phb->eeh_ops->configure_bridge)
56129310e5eSGavin Shan 		ret = phb->eeh_ops->configure_bridge(pe);
56229310e5eSGavin Shan 
56329310e5eSGavin Shan 	return ret;
56429310e5eSGavin Shan }
56529310e5eSGavin Shan 
56629310e5eSGavin Shan /**
56701f3bfb7SGavin Shan  * pnv_pe_err_inject - Inject specified error to the indicated PE
568131c123aSGavin Shan  * @pe: the indicated PE
569131c123aSGavin Shan  * @type: error type
570131c123aSGavin Shan  * @func: specific error type
571131c123aSGavin Shan  * @addr: address
572131c123aSGavin Shan  * @mask: address mask
573131c123aSGavin Shan  *
574131c123aSGavin Shan  * The routine is called to inject specified error, which is
575131c123aSGavin Shan  * determined by @type and @func, to the indicated PE for
576131c123aSGavin Shan  * testing purpose.
577131c123aSGavin Shan  */
57801f3bfb7SGavin Shan static int pnv_eeh_err_inject(struct eeh_pe *pe, int type, int func,
579131c123aSGavin Shan 			      unsigned long addr, unsigned long mask)
580131c123aSGavin Shan {
581131c123aSGavin Shan 	struct pci_controller *hose = pe->phb;
582131c123aSGavin Shan 	struct pnv_phb *phb = hose->private_data;
583fa646c3cSGavin Shan 	s64 rc;
584131c123aSGavin Shan 
585fa646c3cSGavin Shan 	/* Sanity check on error type */
586fa646c3cSGavin Shan 	if (type != OPAL_ERR_INJECT_TYPE_IOA_BUS_ERR &&
587fa646c3cSGavin Shan 	    type != OPAL_ERR_INJECT_TYPE_IOA_BUS_ERR64) {
588fa646c3cSGavin Shan 		pr_warn("%s: Invalid error type %d\n",
589fa646c3cSGavin Shan 			__func__, type);
590fa646c3cSGavin Shan 		return -ERANGE;
591fa646c3cSGavin Shan 	}
592131c123aSGavin Shan 
593fa646c3cSGavin Shan 	if (func < OPAL_ERR_INJECT_FUNC_IOA_LD_MEM_ADDR ||
594fa646c3cSGavin Shan 	    func > OPAL_ERR_INJECT_FUNC_IOA_DMA_WR_TARGET) {
595fa646c3cSGavin Shan 		pr_warn("%s: Invalid error function %d\n",
596fa646c3cSGavin Shan 			__func__, func);
597fa646c3cSGavin Shan 		return -ERANGE;
598fa646c3cSGavin Shan 	}
599fa646c3cSGavin Shan 
600fa646c3cSGavin Shan 	/* Firmware supports error injection ? */
601fa646c3cSGavin Shan 	if (!opal_check_token(OPAL_PCI_ERR_INJECT)) {
602fa646c3cSGavin Shan 		pr_warn("%s: Firmware doesn't support error injection\n",
603fa646c3cSGavin Shan 			__func__);
604fa646c3cSGavin Shan 		return -ENXIO;
605fa646c3cSGavin Shan 	}
606fa646c3cSGavin Shan 
607fa646c3cSGavin Shan 	/* Do error injection */
608fa646c3cSGavin Shan 	rc = opal_pci_err_inject(phb->opal_id, pe->addr,
609fa646c3cSGavin Shan 				 type, func, addr, mask);
610fa646c3cSGavin Shan 	if (rc != OPAL_SUCCESS) {
611fa646c3cSGavin Shan 		pr_warn("%s: Failure %lld injecting error "
612fa646c3cSGavin Shan 			"%d-%d to PHB#%x-PE#%x\n",
613fa646c3cSGavin Shan 			__func__, rc, type, func,
614fa646c3cSGavin Shan 			hose->global_number, pe->addr);
615fa646c3cSGavin Shan 		return -EIO;
616fa646c3cSGavin Shan 	}
617fa646c3cSGavin Shan 
618fa646c3cSGavin Shan 	return 0;
619131c123aSGavin Shan }
620131c123aSGavin Shan 
62101f3bfb7SGavin Shan static inline bool pnv_eeh_cfg_blocked(struct device_node *dn)
622d2cfbcd7SGavin Shan {
623d2cfbcd7SGavin Shan 	struct eeh_dev *edev = of_node_to_eeh_dev(dn);
624d2cfbcd7SGavin Shan 
625d2cfbcd7SGavin Shan 	if (!edev || !edev->pe)
626d2cfbcd7SGavin Shan 		return false;
627d2cfbcd7SGavin Shan 
628d2cfbcd7SGavin Shan 	if (edev->pe->state & EEH_PE_CFG_BLOCKED)
629d2cfbcd7SGavin Shan 		return true;
630d2cfbcd7SGavin Shan 
631d2cfbcd7SGavin Shan 	return false;
632d2cfbcd7SGavin Shan }
633d2cfbcd7SGavin Shan 
63401f3bfb7SGavin Shan static int pnv_eeh_read_config(struct device_node *dn,
635d2cfbcd7SGavin Shan 			       int where, int size, u32 *val)
636d2cfbcd7SGavin Shan {
63701f3bfb7SGavin Shan 	if (pnv_eeh_cfg_blocked(dn)) {
638d2cfbcd7SGavin Shan 		*val = 0xFFFFFFFF;
639d2cfbcd7SGavin Shan 		return PCIBIOS_SET_FAILED;
640d2cfbcd7SGavin Shan 	}
641d2cfbcd7SGavin Shan 
642d2cfbcd7SGavin Shan 	return pnv_pci_cfg_read(dn, where, size, val);
643d2cfbcd7SGavin Shan }
644d2cfbcd7SGavin Shan 
64501f3bfb7SGavin Shan static int pnv_eeh_write_config(struct device_node *dn,
646d2cfbcd7SGavin Shan 				int where, int size, u32 val)
647d2cfbcd7SGavin Shan {
64801f3bfb7SGavin Shan 	if (pnv_eeh_cfg_blocked(dn))
649d2cfbcd7SGavin Shan 		return PCIBIOS_SET_FAILED;
650d2cfbcd7SGavin Shan 
651d2cfbcd7SGavin Shan 	return pnv_pci_cfg_write(dn, where, size, val);
652d2cfbcd7SGavin Shan }
653d2cfbcd7SGavin Shan 
654131c123aSGavin Shan /**
65501f3bfb7SGavin Shan  * pnv_eeh_next_error - Retrieve next EEH error to handle
65629310e5eSGavin Shan  * @pe: Affected PE
65729310e5eSGavin Shan  *
65829310e5eSGavin Shan  * Using OPAL API, to retrieve next EEH error for EEH core to handle
65929310e5eSGavin Shan  */
66001f3bfb7SGavin Shan static int pnv_eeh_next_error(struct eeh_pe **pe)
66129310e5eSGavin Shan {
66229310e5eSGavin Shan 	struct pci_controller *hose;
66329310e5eSGavin Shan 	struct pnv_phb *phb = NULL;
66429310e5eSGavin Shan 
66529310e5eSGavin Shan 	list_for_each_entry(hose, &hose_list, list_node) {
66629310e5eSGavin Shan 		phb = hose->private_data;
66729310e5eSGavin Shan 		break;
66829310e5eSGavin Shan 	}
66929310e5eSGavin Shan 
67029310e5eSGavin Shan 	if (phb && phb->eeh_ops->next_error)
67129310e5eSGavin Shan 		return phb->eeh_ops->next_error(pe);
67229310e5eSGavin Shan 
67329310e5eSGavin Shan 	return -EEXIST;
67429310e5eSGavin Shan }
67529310e5eSGavin Shan 
67601f3bfb7SGavin Shan static int pnv_eeh_restore_config(struct device_node *dn)
6779be3beccSGavin Shan {
6789be3beccSGavin Shan 	struct eeh_dev *edev = of_node_to_eeh_dev(dn);
6799be3beccSGavin Shan 	struct pnv_phb *phb;
6809be3beccSGavin Shan 	s64 ret;
6819be3beccSGavin Shan 
6829be3beccSGavin Shan 	if (!edev)
6839be3beccSGavin Shan 		return -EEXIST;
6849be3beccSGavin Shan 
6859be3beccSGavin Shan 	phb = edev->phb->private_data;
6869be3beccSGavin Shan 	ret = opal_pci_reinit(phb->opal_id,
6879be3beccSGavin Shan 			      OPAL_REINIT_PCI_DEV, edev->config_addr);
6889be3beccSGavin Shan 	if (ret) {
6899be3beccSGavin Shan 		pr_warn("%s: Can't reinit PCI dev 0x%x (%lld)\n",
6909be3beccSGavin Shan 			__func__, edev->config_addr, ret);
6919be3beccSGavin Shan 		return -EIO;
6929be3beccSGavin Shan 	}
6939be3beccSGavin Shan 
6949be3beccSGavin Shan 	return 0;
6959be3beccSGavin Shan }
6969be3beccSGavin Shan 
69701f3bfb7SGavin Shan static struct eeh_ops pnv_eeh_ops = {
69829310e5eSGavin Shan 	.name                   = "powernv",
69901f3bfb7SGavin Shan 	.init                   = pnv_eeh_init,
70001f3bfb7SGavin Shan 	.post_init              = pnv_eeh_post_init,
70129310e5eSGavin Shan 	.of_probe               = NULL,
70201f3bfb7SGavin Shan 	.dev_probe              = pnv_eeh_dev_probe,
70301f3bfb7SGavin Shan 	.set_option             = pnv_eeh_set_option,
70401f3bfb7SGavin Shan 	.get_pe_addr            = pnv_eeh_get_pe_addr,
70501f3bfb7SGavin Shan 	.get_state              = pnv_eeh_get_state,
70601f3bfb7SGavin Shan 	.reset                  = pnv_eeh_reset,
70701f3bfb7SGavin Shan 	.wait_state             = pnv_eeh_wait_state,
70801f3bfb7SGavin Shan 	.get_log                = pnv_eeh_get_log,
70901f3bfb7SGavin Shan 	.configure_bridge       = pnv_eeh_configure_bridge,
71001f3bfb7SGavin Shan 	.err_inject		= pnv_eeh_err_inject,
71101f3bfb7SGavin Shan 	.read_config            = pnv_eeh_read_config,
71201f3bfb7SGavin Shan 	.write_config           = pnv_eeh_write_config,
71301f3bfb7SGavin Shan 	.next_error		= pnv_eeh_next_error,
71401f3bfb7SGavin Shan 	.restore_config		= pnv_eeh_restore_config
71529310e5eSGavin Shan };
71629310e5eSGavin Shan 
71729310e5eSGavin Shan /**
71829310e5eSGavin Shan  * eeh_powernv_init - Register platform dependent EEH operations
71929310e5eSGavin Shan  *
72029310e5eSGavin Shan  * EEH initialization on powernv platform. This function should be
72129310e5eSGavin Shan  * called before any EEH related functions.
72229310e5eSGavin Shan  */
72329310e5eSGavin Shan static int __init eeh_powernv_init(void)
72429310e5eSGavin Shan {
72529310e5eSGavin Shan 	int ret = -EINVAL;
72629310e5eSGavin Shan 
727bb593c00SGavin Shan 	eeh_set_pe_aux_size(PNV_PCI_DIAG_BUF_SIZE);
72801f3bfb7SGavin Shan 	ret = eeh_ops_register(&pnv_eeh_ops);
72929310e5eSGavin Shan 	if (!ret)
73029310e5eSGavin Shan 		pr_info("EEH: PowerNV platform initialized\n");
73129310e5eSGavin Shan 	else
73229310e5eSGavin Shan 		pr_info("EEH: Failed to initialize PowerNV platform (%d)\n", ret);
73329310e5eSGavin Shan 
73429310e5eSGavin Shan 	return ret;
73529310e5eSGavin Shan }
736b14726c5SMichael Ellerman machine_early_initcall(powernv, eeh_powernv_init);
737