Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright 2014 IBM Corp.
0004  */
0005 
0006 #include <linux/pci.h>
0007 #include <misc/cxl.h>
0008 #include "cxl.h"
0009 
0010 static int cxl_pci_probe_mode(struct pci_bus *bus)
0011 {
0012     return PCI_PROBE_NORMAL;
0013 }
0014 
0015 static int cxl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
0016 {
0017     return -ENODEV;
0018 }
0019 
0020 static void cxl_teardown_msi_irqs(struct pci_dev *pdev)
0021 {
0022     /*
0023      * MSI should never be set but need still need to provide this call
0024      * back.
0025      */
0026 }
0027 
0028 static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
0029 {
0030     struct pci_controller *phb;
0031     struct cxl_afu *afu;
0032     struct cxl_context *ctx;
0033 
0034     phb = pci_bus_to_host(dev->bus);
0035     afu = (struct cxl_afu *)phb->private_data;
0036 
0037     if (!cxl_ops->link_ok(afu->adapter, afu)) {
0038         dev_warn(&dev->dev, "%s: Device link is down, refusing to enable AFU\n", __func__);
0039         return false;
0040     }
0041 
0042     dev->dev.archdata.dma_offset = PAGE_OFFSET;
0043 
0044     /*
0045      * Allocate a context to do cxl things too.  If we eventually do real
0046      * DMA ops, we'll need a default context to attach them to
0047      */
0048     ctx = cxl_dev_context_init(dev);
0049     if (IS_ERR(ctx))
0050         return false;
0051     dev->dev.archdata.cxl_ctx = ctx;
0052 
0053     return (cxl_ops->afu_check_and_enable(afu) == 0);
0054 }
0055 
0056 static void cxl_pci_disable_device(struct pci_dev *dev)
0057 {
0058     struct cxl_context *ctx = cxl_get_context(dev);
0059 
0060     if (ctx) {
0061         if (ctx->status == STARTED) {
0062             dev_err(&dev->dev, "Default context started\n");
0063             return;
0064         }
0065         dev->dev.archdata.cxl_ctx = NULL;
0066         cxl_release_context(ctx);
0067     }
0068 }
0069 
0070 static resource_size_t cxl_pci_window_alignment(struct pci_bus *bus,
0071                         unsigned long type)
0072 {
0073     return 1;
0074 }
0075 
0076 static void cxl_pci_reset_secondary_bus(struct pci_dev *dev)
0077 {
0078     /* Should we do an AFU reset here ? */
0079 }
0080 
0081 static int cxl_pcie_cfg_record(u8 bus, u8 devfn)
0082 {
0083     return (bus << 8) + devfn;
0084 }
0085 
0086 static inline struct cxl_afu *pci_bus_to_afu(struct pci_bus *bus)
0087 {
0088     struct pci_controller *phb = bus ? pci_bus_to_host(bus) : NULL;
0089 
0090     return phb ? phb->private_data : NULL;
0091 }
0092 
0093 static void cxl_afu_configured_put(struct cxl_afu *afu)
0094 {
0095     atomic_dec_if_positive(&afu->configured_state);
0096 }
0097 
0098 static bool cxl_afu_configured_get(struct cxl_afu *afu)
0099 {
0100     return atomic_inc_unless_negative(&afu->configured_state);
0101 }
0102 
0103 static inline int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn,
0104                        struct cxl_afu *afu, int *_record)
0105 {
0106     int record;
0107 
0108     record = cxl_pcie_cfg_record(bus->number, devfn);
0109     if (record > afu->crs_num)
0110         return PCIBIOS_DEVICE_NOT_FOUND;
0111 
0112     *_record = record;
0113     return 0;
0114 }
0115 
0116 static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
0117                 int offset, int len, u32 *val)
0118 {
0119     int rc, record;
0120     struct cxl_afu *afu;
0121     u8 val8;
0122     u16 val16;
0123     u32 val32;
0124 
0125     afu = pci_bus_to_afu(bus);
0126     /* Grab a reader lock on afu. */
0127     if (afu == NULL || !cxl_afu_configured_get(afu))
0128         return PCIBIOS_DEVICE_NOT_FOUND;
0129 
0130     rc = cxl_pcie_config_info(bus, devfn, afu, &record);
0131     if (rc)
0132         goto out;
0133 
0134     switch (len) {
0135     case 1:
0136         rc = cxl_ops->afu_cr_read8(afu, record, offset, &val8);
0137         *val = val8;
0138         break;
0139     case 2:
0140         rc = cxl_ops->afu_cr_read16(afu, record, offset, &val16);
0141         *val = val16;
0142         break;
0143     case 4:
0144         rc = cxl_ops->afu_cr_read32(afu, record, offset, &val32);
0145         *val = val32;
0146         break;
0147     default:
0148         WARN_ON(1);
0149     }
0150 
0151 out:
0152     cxl_afu_configured_put(afu);
0153     return rc ? PCIBIOS_DEVICE_NOT_FOUND : 0;
0154 }
0155 
0156 static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
0157                  int offset, int len, u32 val)
0158 {
0159     int rc, record;
0160     struct cxl_afu *afu;
0161 
0162     afu = pci_bus_to_afu(bus);
0163     /* Grab a reader lock on afu. */
0164     if (afu == NULL || !cxl_afu_configured_get(afu))
0165         return PCIBIOS_DEVICE_NOT_FOUND;
0166 
0167     rc = cxl_pcie_config_info(bus, devfn, afu, &record);
0168     if (rc)
0169         goto out;
0170 
0171     switch (len) {
0172     case 1:
0173         rc = cxl_ops->afu_cr_write8(afu, record, offset, val & 0xff);
0174         break;
0175     case 2:
0176         rc = cxl_ops->afu_cr_write16(afu, record, offset, val & 0xffff);
0177         break;
0178     case 4:
0179         rc = cxl_ops->afu_cr_write32(afu, record, offset, val);
0180         break;
0181     default:
0182         WARN_ON(1);
0183     }
0184 
0185 out:
0186     cxl_afu_configured_put(afu);
0187     return rc ? PCIBIOS_SET_FAILED : 0;
0188 }
0189 
0190 static struct pci_ops cxl_pcie_pci_ops =
0191 {
0192     .read = cxl_pcie_read_config,
0193     .write = cxl_pcie_write_config,
0194 };
0195 
0196 
0197 static struct pci_controller_ops cxl_pci_controller_ops =
0198 {
0199     .probe_mode = cxl_pci_probe_mode,
0200     .enable_device_hook = cxl_pci_enable_device_hook,
0201     .disable_device = cxl_pci_disable_device,
0202     .release_device = cxl_pci_disable_device,
0203     .window_alignment = cxl_pci_window_alignment,
0204     .reset_secondary_bus = cxl_pci_reset_secondary_bus,
0205     .setup_msi_irqs = cxl_setup_msi_irqs,
0206     .teardown_msi_irqs = cxl_teardown_msi_irqs,
0207 };
0208 
0209 int cxl_pci_vphb_add(struct cxl_afu *afu)
0210 {
0211     struct pci_controller *phb;
0212     struct device_node *vphb_dn;
0213     struct device *parent;
0214 
0215     /*
0216      * If there are no AFU configuration records we won't have anything to
0217      * expose under the vPHB, so skip creating one, returning success since
0218      * this is still a valid case. This will also opt us out of EEH
0219      * handling since we won't have anything special to do if there are no
0220      * kernel drivers attached to the vPHB, and EEH handling is not yet
0221      * supported in the peer model.
0222      */
0223     if (!afu->crs_num)
0224         return 0;
0225 
0226     /* The parent device is the adapter. Reuse the device node of
0227      * the adapter.
0228      * We don't seem to care what device node is used for the vPHB,
0229      * but tools such as lsvpd walk up the device parents looking
0230      * for a valid location code, so we might as well show devices
0231      * attached to the adapter as being located on that adapter.
0232      */
0233     parent = afu->adapter->dev.parent;
0234     vphb_dn = parent->of_node;
0235 
0236     /* Alloc and setup PHB data structure */
0237     phb = pcibios_alloc_controller(vphb_dn);
0238     if (!phb)
0239         return -ENODEV;
0240 
0241     /* Setup parent in sysfs */
0242     phb->parent = parent;
0243 
0244     /* Setup the PHB using arch provided callback */
0245     phb->ops = &cxl_pcie_pci_ops;
0246     phb->cfg_addr = NULL;
0247     phb->cfg_data = NULL;
0248     phb->private_data = afu;
0249     phb->controller_ops = cxl_pci_controller_ops;
0250 
0251     /* Scan the bus */
0252     pcibios_scan_phb(phb);
0253     if (phb->bus == NULL)
0254         return -ENXIO;
0255 
0256     /* Set release hook on root bus */
0257     pci_set_host_bridge_release(to_pci_host_bridge(phb->bus->bridge),
0258                     pcibios_free_controller_deferred,
0259                     (void *) phb);
0260 
0261     /* Claim resources. This might need some rework as well depending
0262      * whether we are doing probe-only or not, like assigning unassigned
0263      * resources etc...
0264      */
0265     pcibios_claim_one_bus(phb->bus);
0266 
0267     /* Add probed PCI devices to the device model */
0268     pci_bus_add_devices(phb->bus);
0269 
0270     afu->phb = phb;
0271 
0272     return 0;
0273 }
0274 
0275 void cxl_pci_vphb_remove(struct cxl_afu *afu)
0276 {
0277     struct pci_controller *phb;
0278 
0279     /* If there is no configuration record we won't have one of these */
0280     if (!afu || !afu->phb)
0281         return;
0282 
0283     phb = afu->phb;
0284     afu->phb = NULL;
0285 
0286     pci_remove_root_bus(phb->bus);
0287     /*
0288      * We don't free phb here - that's handled by
0289      * pcibios_free_controller_deferred()
0290      */
0291 }
0292 
0293 bool cxl_pci_is_vphb_device(struct pci_dev *dev)
0294 {
0295     struct pci_controller *phb;
0296 
0297     phb = pci_bus_to_host(dev->bus);
0298 
0299     return (phb->ops == &cxl_pcie_pci_ops);
0300 }
0301 
0302 struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev)
0303 {
0304     struct pci_controller *phb;
0305 
0306     phb = pci_bus_to_host(dev->bus);
0307 
0308     return (struct cxl_afu *)phb->private_data;
0309 }
0310 EXPORT_SYMBOL_GPL(cxl_pci_to_afu);
0311 
0312 unsigned int cxl_pci_to_cfg_record(struct pci_dev *dev)
0313 {
0314     return cxl_pcie_cfg_record(dev->bus->number, dev->devfn);
0315 }
0316 EXPORT_SYMBOL_GPL(cxl_pci_to_cfg_record);