Path: blob/master/drivers/crypto/intel/qat/qat_420xx/adf_drv.c
29278 views
// SPDX-License-Identifier: GPL-2.0-only1/* Copyright(c) 2023 Intel Corporation */2#include <linux/device.h>3#include <linux/module.h>4#include <linux/pci.h>56#include <adf_accel_devices.h>7#include <adf_gen4_hw_data.h>8#include <adf_gen4_config.h>9#include <adf_cfg.h>10#include <adf_common_drv.h>11#include <adf_dbgfs.h>1213#include "adf_420xx_hw_data.h"1415static const struct pci_device_id adf_pci_tbl[] = {16{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_QAT_420XX) },17{ }18};19MODULE_DEVICE_TABLE(pci, adf_pci_tbl);2021static void adf_cleanup_accel(struct adf_accel_dev *accel_dev)22{23if (accel_dev->hw_device) {24adf_clean_hw_data_420xx(accel_dev->hw_device);25accel_dev->hw_device = NULL;26}27adf_dbgfs_exit(accel_dev);28adf_cfg_dev_remove(accel_dev);29adf_devmgr_rm_dev(accel_dev, NULL);30}3132static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)33{34struct adf_accel_dev *accel_dev;35struct adf_accel_pci *accel_pci_dev;36struct adf_hw_device_data *hw_data;37unsigned int i, bar_nr;38unsigned long bar_mask;39struct adf_bar *bar;40int ret;4142if (num_possible_nodes() > 1 && dev_to_node(&pdev->dev) < 0) {43/*44* If the accelerator is connected to a node with no memory45* there is no point in using the accelerator since the remote46* memory transaction will be very slow.47*/48dev_err(&pdev->dev, "Invalid NUMA configuration.\n");49return -EINVAL;50}5152accel_dev = devm_kzalloc(&pdev->dev, sizeof(*accel_dev), GFP_KERNEL);53if (!accel_dev)54return -ENOMEM;5556INIT_LIST_HEAD(&accel_dev->crypto_list);57accel_pci_dev = &accel_dev->accel_pci_dev;58accel_pci_dev->pci_dev = pdev;5960/*61* Add accel device to accel table62* This should be called before adf_cleanup_accel is called63*/64if (adf_devmgr_add_dev(accel_dev, NULL)) {65dev_err(&pdev->dev, "Failed to add new accelerator device.\n");66return -EFAULT;67}6869accel_dev->owner = THIS_MODULE;70/* Allocate and initialise device hardware meta-data structure */71hw_data = devm_kzalloc(&pdev->dev, sizeof(*hw_data), GFP_KERNEL);72if (!hw_data) {73ret = -ENOMEM;74goto out_err;75}7677accel_dev->hw_device = hw_data;78adf_init_hw_data_420xx(accel_dev->hw_device, ent->device);7980pci_read_config_byte(pdev, PCI_REVISION_ID, &accel_pci_dev->revid);81pci_read_config_dword(pdev, ADF_GEN4_FUSECTL4_OFFSET, &hw_data->fuses[ADF_FUSECTL4]);8283/* Get Accelerators and Accelerators Engines masks */84hw_data->accel_mask = hw_data->get_accel_mask(hw_data);85hw_data->ae_mask = hw_data->get_ae_mask(hw_data);86accel_pci_dev->sku = hw_data->get_sku(hw_data);87/* If the device has no acceleration engines then ignore it */88if (!hw_data->accel_mask || !hw_data->ae_mask ||89(~hw_data->ae_mask & 0x01)) {90dev_err(&pdev->dev, "No acceleration units found.\n");91ret = -EFAULT;92goto out_err;93}9495/* Create device configuration table */96ret = adf_cfg_dev_add(accel_dev);97if (ret)98goto out_err;99100/* Enable PCI device */101ret = pcim_enable_device(pdev);102if (ret) {103dev_err(&pdev->dev, "Can't enable PCI device.\n");104goto out_err;105}106107/* Set DMA identifier */108ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));109if (ret) {110dev_err(&pdev->dev, "No usable DMA configuration.\n");111goto out_err;112}113114ret = adf_gen4_cfg_dev_init(accel_dev);115if (ret) {116dev_err(&pdev->dev, "Failed to initialize configuration.\n");117goto out_err;118}119120/* Get accelerator capabilities mask */121hw_data->accel_capabilities_mask = hw_data->get_accel_cap(accel_dev);122if (!hw_data->accel_capabilities_mask) {123dev_err(&pdev->dev, "Failed to get capabilities mask.\n");124ret = -EINVAL;125goto out_err;126}127128/* Find and map all the device's BARS */129bar_mask = pci_select_bars(pdev, IORESOURCE_MEM) & ADF_GEN4_BAR_MASK;130131ret = pcim_request_all_regions(pdev, pci_name(pdev));132if (ret) {133dev_err(&pdev->dev, "Failed to request PCI regions.\n");134goto out_err;135}136137i = 0;138for_each_set_bit(bar_nr, &bar_mask, PCI_STD_NUM_BARS) {139bar = &accel_pci_dev->pci_bars[i++];140bar->virt_addr = pcim_iomap(pdev, bar_nr, 0);141if (!bar->virt_addr) {142dev_err(&pdev->dev, "Failed to ioremap PCI region.\n");143ret = -ENOMEM;144goto out_err;145}146}147148pci_set_master(pdev);149150if (pci_save_state(pdev)) {151dev_err(&pdev->dev, "Failed to save pci state.\n");152ret = -ENOMEM;153goto out_err;154}155156accel_dev->ras_errors.enabled = true;157adf_dbgfs_init(accel_dev);158159ret = adf_dev_up(accel_dev, true);160if (ret)161goto out_err_dev_stop;162163ret = adf_sysfs_init(accel_dev);164if (ret)165goto out_err_dev_stop;166167return ret;168169out_err_dev_stop:170adf_dev_down(accel_dev);171out_err:172adf_cleanup_accel(accel_dev);173return ret;174}175176static void adf_remove(struct pci_dev *pdev)177{178struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);179180if (!accel_dev) {181pr_err("QAT: Driver removal failed\n");182return;183}184adf_dev_down(accel_dev);185adf_cleanup_accel(accel_dev);186}187188static void adf_shutdown(struct pci_dev *pdev)189{190struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);191192adf_dev_down(accel_dev);193}194195static struct pci_driver adf_driver = {196.id_table = adf_pci_tbl,197.name = ADF_420XX_DEVICE_NAME,198.probe = adf_probe,199.remove = adf_remove,200.shutdown = adf_shutdown,201.sriov_configure = adf_sriov_configure,202.err_handler = &adf_err_handler,203};204205module_pci_driver(adf_driver);206207MODULE_LICENSE("GPL");208MODULE_AUTHOR("Intel");209MODULE_FIRMWARE(ADF_420XX_FW);210MODULE_FIRMWARE(ADF_420XX_MMP);211MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");212MODULE_VERSION(ADF_DRV_VERSION);213MODULE_SOFTDEP("pre: crypto-intel_qat");214MODULE_IMPORT_NS("CRYPTO_QAT");215216217