static void adf_disable_msi(struct adf_accel_dev *accel_dev) { struct pci_dev *pdev = accel_to_pci_dev(accel_dev); kfree(accel_dev->vf.irq_name); pci_disable_msi(pdev); }
static void adf_dev_restore(struct adf_accel_dev *accel_dev) { struct pci_dev *pdev = accel_to_pci_dev(accel_dev); struct pci_dev *parent = pdev->bus->self; uint16_t ppdstat = 0, bridge_ctl = 0; int pending = 0; pr_info("QAT: Resetting device qat_dev%d\n", accel_dev->accel_id); pci_read_config_word(pdev, PPDSTAT_OFFSET, &ppdstat); pending = ppdstat & PCI_EXP_DEVSTA_TRPND; if (pending) { int ctr = 0; do { msleep(100); pci_read_config_word(pdev, PPDSTAT_OFFSET, &ppdstat); pending = ppdstat & PCI_EXP_DEVSTA_TRPND; } while (pending && ctr++ < 10); } if (pending) pr_info("QAT: Transaction still in progress. Proceeding\n"); pci_read_config_word(parent, PCI_BRIDGE_CONTROL, &bridge_ctl); bridge_ctl |= PCI_BRIDGE_CTL_BUS_RESET; pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl); msleep(100); bridge_ctl &= ~PCI_BRIDGE_CTL_BUS_RESET; pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl); msleep(100); pci_restore_state(pdev); pci_save_state(pdev); }
/** * adf_enable_aer() - Enable Advance Error Reporting for acceleration device * @accel_dev: Pointer to acceleration device. * @adf: PCI device driver owning the given acceleration device. * * Function enables PCI Advance Error Reporting for the * QAT acceleration device accel_dev. * To be used by QAT device specific drivers. * * Return: 0 on success, error code othewise. */ int adf_enable_aer(struct adf_accel_dev *accel_dev, struct pci_driver *adf) { struct pci_dev *pdev = accel_to_pci_dev(accel_dev); adf->err_handler = &adf_err_handler; pci_enable_pcie_error_reporting(pdev); return 0; }
/** * adf_vf_isr_resource_free() - Free IRQ for acceleration device * @accel_dev: Pointer to acceleration device. * * Function frees interrupts for acceleration device virtual function. */ void adf_vf_isr_resource_free(struct adf_accel_dev *accel_dev) { struct pci_dev *pdev = accel_to_pci_dev(accel_dev); irq_set_affinity_hint(pdev->irq, NULL); free_irq(pdev->irq, (void *)accel_dev); adf_cleanup_bh(accel_dev); adf_cleanup_pf2vf_bh(accel_dev); adf_disable_msi(accel_dev); }
static int adf_ctl_ioctl_get_status(struct file *fp, unsigned int cmd, unsigned long arg) { struct adf_hw_device_data *hw_data; struct adf_dev_status_info dev_info; struct adf_accel_dev *accel_dev; if (copy_from_user(&dev_info, (void __user *)arg, sizeof(struct adf_dev_status_info))) { pr_err("QAT: failed to copy from user.\n"); return -EFAULT; } accel_dev = adf_devmgr_get_dev_by_id(dev_info.accel_id); if (!accel_dev) { pr_err("QAT: Device %d not found\n", dev_info.accel_id); return -ENODEV; } hw_data = accel_dev->hw_device; dev_info.state = adf_dev_started(accel_dev) ? DEV_UP : DEV_DOWN; dev_info.num_ae = hw_data->get_num_aes(hw_data); dev_info.num_accel = hw_data->get_num_accels(hw_data); dev_info.num_logical_accel = hw_data->num_logical_accel; dev_info.banks_per_accel = hw_data->num_banks / hw_data->num_logical_accel; strlcpy(dev_info.name, hw_data->dev_class->name, sizeof(dev_info.name)); dev_info.instance_id = hw_data->instance_id; dev_info.type = hw_data->dev_class->type; dev_info.bus = accel_to_pci_dev(accel_dev)->bus->number; dev_info.dev = PCI_SLOT(accel_to_pci_dev(accel_dev)->devfn); dev_info.fun = PCI_FUNC(accel_to_pci_dev(accel_dev)->devfn); if (copy_to_user((void __user *)arg, &dev_info, sizeof(struct adf_dev_status_info))) { dev_err(&GET_DEV(accel_dev), "failed to copy status.\n"); return -EFAULT; } return 0; }
void adf_dev_restore(struct adf_accel_dev *accel_dev) { struct adf_hw_device_data *hw_device = accel_dev->hw_device; struct pci_dev *pdev = accel_to_pci_dev(accel_dev); if (hw_device->reset_device) { dev_info(&GET_DEV(accel_dev), "Resetting device qat_dev%d\n", accel_dev->accel_id); hw_device->reset_device(accel_dev); pci_restore_state(pdev); pci_save_state(pdev); } }
static int adf_request_msi_irq(struct adf_accel_dev *accel_dev) { struct pci_dev *pdev = accel_to_pci_dev(accel_dev); unsigned int cpu; int ret; snprintf(accel_dev->vf.irq_name, ADF_MAX_MSIX_VECTOR_NAME, "qat_%02x:%02d.%02d", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); ret = request_irq(pdev->irq, adf_isr, 0, accel_dev->vf.irq_name, (void *)accel_dev); if (ret) { dev_err(&GET_DEV(accel_dev), "failed to enable irq for %s\n", accel_dev->vf.irq_name); return ret; } cpu = accel_dev->accel_id % num_online_cpus(); irq_set_affinity_hint(pdev->irq, get_cpu_mask(cpu)); return ret; }
void adf_reset_sbr(struct adf_accel_dev *accel_dev) { struct pci_dev *pdev = accel_to_pci_dev(accel_dev); struct pci_dev *parent = pdev->bus->self; uint16_t bridge_ctl = 0; if (!parent) parent = pdev; if (!pci_wait_for_pending_transaction(pdev)) dev_info(&GET_DEV(accel_dev), "Transaction still in progress. Proceeding\n"); dev_info(&GET_DEV(accel_dev), "Secondary bus reset\n"); pci_read_config_word(parent, PCI_BRIDGE_CONTROL, &bridge_ctl); bridge_ctl |= PCI_BRIDGE_CTL_BUS_RESET; pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl); msleep(100); bridge_ctl &= ~PCI_BRIDGE_CTL_BUS_RESET; pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl); msleep(100); }
/** * adf_disable_aer() - Enable Advance Error Reporting for acceleration device * @accel_dev: Pointer to acceleration device. * * Function disables PCI Advance Error Reporting for the * QAT acceleration device accel_dev. * To be used by QAT device specific drivers. * * Return: void */ void adf_disable_aer(struct adf_accel_dev *accel_dev) { struct pci_dev *pdev = accel_to_pci_dev(accel_dev); pci_disable_pcie_error_reporting(pdev); }
void adf_reset_flr(struct adf_accel_dev *accel_dev) { pcie_flr(accel_to_pci_dev(accel_dev)); }