// SPDX-License-Identifier: GPL-2.0 /* * Root Complex Event Collector Support * * Authors: * Sean V Kelley * Qiuxu Zhuo * * Copyright (C) 2020 Intel Corp. */ #include #include #include #include "../pci.h" void pci_rcec_init(struct pci_dev *dev) { struct rcec_ea *rcec_ea; u32 rcec, hdr, busn; u8 ver; /* Only for Root Complex Event Collectors */ if (pci_pcie_type(dev) != PCI_EXP_TYPE_RC_EC) return; rcec = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_RCEC); if (!rcec) return; rcec_ea = kzalloc(sizeof(*rcec_ea), GFP_KERNEL); if (!rcec_ea) return; pci_read_config_dword(dev, rcec + PCI_RCEC_RCIEP_BITMAP, &rcec_ea->bitmap); /* Check whether RCEC BUSN register is present */ pci_read_config_dword(dev, rcec, &hdr); ver = PCI_EXT_CAP_VER(hdr); if (ver >= PCI_RCEC_BUSN_REG_VER) { pci_read_config_dword(dev, rcec + PCI_RCEC_BUSN, &busn); rcec_ea->nextbusn = PCI_RCEC_BUSN_NEXT(busn); rcec_ea->lastbusn = PCI_RCEC_BUSN_LAST(busn); } else { /* Avoid later ver check by setting nextbusn */ rcec_ea->nextbusn = 0xff; rcec_ea->lastbusn = 0x00; } dev->rcec_ea = rcec_ea; } void pci_rcec_exit(struct pci_dev *dev) { kfree(dev->rcec_ea); dev->rcec_ea = NULL; }