linux/drivers/crypto/qat/qat_4xxx/adf_drv.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
   2/* Copyright(c) 2020 Intel Corporation */
   3#include <linux/device.h>
   4#include <linux/module.h>
   5#include <linux/pci.h>
   6
   7#include <adf_accel_devices.h>
   8#include <adf_cfg.h>
   9#include <adf_common_drv.h>
  10
  11#include "adf_4xxx_hw_data.h"
  12#include "qat_crypto.h"
  13#include "adf_transport_access_macros.h"
  14
  15static const struct pci_device_id adf_pci_tbl[] = {
  16        { PCI_VDEVICE(INTEL, ADF_4XXX_PCI_DEVICE_ID), },
  17        { }
  18};
  19MODULE_DEVICE_TABLE(pci, adf_pci_tbl);
  20
  21static void adf_cleanup_accel(struct adf_accel_dev *accel_dev)
  22{
  23        if (accel_dev->hw_device) {
  24                adf_clean_hw_data_4xxx(accel_dev->hw_device);
  25                accel_dev->hw_device = NULL;
  26        }
  27        adf_cfg_dev_remove(accel_dev);
  28        debugfs_remove(accel_dev->debugfs_dir);
  29        adf_devmgr_rm_dev(accel_dev, NULL);
  30}
  31
  32static int adf_crypto_dev_config(struct adf_accel_dev *accel_dev)
  33{
  34        char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
  35        int banks = GET_MAX_BANKS(accel_dev);
  36        int cpus = num_online_cpus();
  37        unsigned long bank, val;
  38        int instances;
  39        int ret;
  40        int i;
  41
  42        if (adf_hw_dev_has_crypto(accel_dev))
  43                instances = min(cpus, banks / 2);
  44        else
  45                instances = 0;
  46
  47        ret = adf_cfg_section_add(accel_dev, ADF_KERNEL_SEC);
  48        if (ret)
  49                goto err;
  50
  51        ret = adf_cfg_section_add(accel_dev, "Accelerator0");
  52        if (ret)
  53                goto err;
  54
  55        for (i = 0; i < instances; i++) {
  56                val = i;
  57                bank = i * 2;
  58                snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_BANK_NUM, i);
  59                ret = adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
  60                                                  key, &bank, ADF_DEC);
  61                if (ret)
  62                        goto err;
  63
  64                bank += 1;
  65                snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_BANK_NUM, i);
  66                ret = adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
  67                                                  key, &bank, ADF_DEC);
  68                if (ret)
  69                        goto err;
  70
  71                snprintf(key, sizeof(key), ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY,
  72                         i);
  73                ret = adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
  74                                                  key, &val, ADF_DEC);
  75                if (ret)
  76                        goto err;
  77
  78                snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_SIZE, i);
  79                val = 128;
  80                ret = adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
  81                                                  key, &val, ADF_DEC);
  82                if (ret)
  83                        goto err;
  84
  85                val = 512;
  86                snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_SIZE, i);
  87                ret = adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
  88                                                  key, &val, ADF_DEC);
  89                if (ret)
  90                        goto err;
  91
  92                val = 0;
  93                snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_TX, i);
  94                ret = adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
  95                                                  key, &val, ADF_DEC);
  96                if (ret)
  97                        goto err;
  98
  99                val = 0;
 100                snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_TX, i);
 101                ret = adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
 102                                                  key, &val, ADF_DEC);
 103                if (ret)
 104                        goto err;
 105
 106                val = 1;
 107                snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_RX, i);
 108                ret = adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
 109                                                  key, &val, ADF_DEC);
 110                if (ret)
 111                        goto err;
 112
 113                val = 1;
 114                snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_RX, i);
 115                ret = adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
 116                                                  key, &val, ADF_DEC);
 117                if (ret)
 118                        goto err;
 119
 120                val = ADF_COALESCING_DEF_TIME;
 121                snprintf(key, sizeof(key), ADF_ETRMGR_COALESCE_TIMER_FORMAT, i);
 122                ret = adf_cfg_add_key_value_param(accel_dev, "Accelerator0",
 123                                                  key, &val, ADF_DEC);
 124                if (ret)
 125                        goto err;
 126        }
 127
 128        val = i;
 129        ret = adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, ADF_NUM_CY,
 130                                          &val, ADF_DEC);
 131        if (ret)
 132                goto err;
 133
 134        set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
 135        return 0;
 136err:
 137        dev_err(&GET_DEV(accel_dev), "Failed to start QAT accel dev\n");
 138        return ret;
 139}
 140
 141static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 142{
 143        struct adf_accel_dev *accel_dev;
 144        struct adf_accel_pci *accel_pci_dev;
 145        struct adf_hw_device_data *hw_data;
 146        char name[ADF_DEVICE_NAME_LENGTH];
 147        unsigned int i, bar_nr;
 148        unsigned long bar_mask;
 149        struct adf_bar *bar;
 150        int ret;
 151
 152        if (num_possible_nodes() > 1 && dev_to_node(&pdev->dev) < 0) {
 153                /*
 154                 * If the accelerator is connected to a node with no memory
 155                 * there is no point in using the accelerator since the remote
 156                 * memory transaction will be very slow.
 157                 */
 158                dev_err(&pdev->dev, "Invalid NUMA configuration.\n");
 159                return -EINVAL;
 160        }
 161
 162        accel_dev = devm_kzalloc(&pdev->dev, sizeof(*accel_dev), GFP_KERNEL);
 163        if (!accel_dev)
 164                return -ENOMEM;
 165
 166        INIT_LIST_HEAD(&accel_dev->crypto_list);
 167        accel_pci_dev = &accel_dev->accel_pci_dev;
 168        accel_pci_dev->pci_dev = pdev;
 169
 170        /*
 171         * Add accel device to accel table
 172         * This should be called before adf_cleanup_accel is called
 173         */
 174        if (adf_devmgr_add_dev(accel_dev, NULL)) {
 175                dev_err(&pdev->dev, "Failed to add new accelerator device.\n");
 176                return -EFAULT;
 177        }
 178
 179        accel_dev->owner = THIS_MODULE;
 180        /* Allocate and initialise device hardware meta-data structure */
 181        hw_data = devm_kzalloc(&pdev->dev, sizeof(*hw_data), GFP_KERNEL);
 182        if (!hw_data) {
 183                ret = -ENOMEM;
 184                goto out_err;
 185        }
 186
 187        accel_dev->hw_device = hw_data;
 188        adf_init_hw_data_4xxx(accel_dev->hw_device);
 189
 190        pci_read_config_byte(pdev, PCI_REVISION_ID, &accel_pci_dev->revid);
 191        pci_read_config_dword(pdev, ADF_4XXX_FUSECTL4_OFFSET, &hw_data->fuses);
 192
 193        /* Get Accelerators and Accelerators Engines masks */
 194        hw_data->accel_mask = hw_data->get_accel_mask(hw_data);
 195        hw_data->ae_mask = hw_data->get_ae_mask(hw_data);
 196        accel_pci_dev->sku = hw_data->get_sku(hw_data);
 197        /* If the device has no acceleration engines then ignore it */
 198        if (!hw_data->accel_mask || !hw_data->ae_mask ||
 199            (~hw_data->ae_mask & 0x01)) {
 200                dev_err(&pdev->dev, "No acceleration units found.\n");
 201                ret = -EFAULT;
 202                goto out_err;
 203        }
 204
 205        /* Create dev top level debugfs entry */
 206        snprintf(name, sizeof(name), "%s%s_%s", ADF_DEVICE_NAME_PREFIX,
 207                 hw_data->dev_class->name, pci_name(pdev));
 208
 209        accel_dev->debugfs_dir = debugfs_create_dir(name, NULL);
 210
 211        /* Create device configuration table */
 212        ret = adf_cfg_dev_add(accel_dev);
 213        if (ret)
 214                goto out_err;
 215
 216        /* Enable PCI device */
 217        ret = pcim_enable_device(pdev);
 218        if (ret) {
 219                dev_err(&pdev->dev, "Can't enable PCI device.\n");
 220                goto out_err;
 221        }
 222
 223        /* Set DMA identifier */
 224        ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
 225        if (ret) {
 226                dev_err(&pdev->dev, "No usable DMA configuration.\n");
 227                goto out_err;
 228        }
 229
 230        /* Get accelerator capabilities mask */
 231        hw_data->accel_capabilities_mask = hw_data->get_accel_cap(accel_dev);
 232
 233        /* Find and map all the device's BARS */
 234        bar_mask = pci_select_bars(pdev, IORESOURCE_MEM) & ADF_4XXX_BAR_MASK;
 235
 236        ret = pcim_iomap_regions_request_all(pdev, bar_mask, pci_name(pdev));
 237        if (ret) {
 238                dev_err(&pdev->dev, "Failed to map pci regions.\n");
 239                goto out_err;
 240        }
 241
 242        i = 0;
 243        for_each_set_bit(bar_nr, &bar_mask, PCI_STD_NUM_BARS) {
 244                bar = &accel_pci_dev->pci_bars[i++];
 245                bar->virt_addr = pcim_iomap_table(pdev)[bar_nr];
 246        }
 247
 248        pci_set_master(pdev);
 249
 250        if (adf_enable_aer(accel_dev)) {
 251                dev_err(&pdev->dev, "Failed to enable aer.\n");
 252                ret = -EFAULT;
 253                goto out_err;
 254        }
 255
 256        if (pci_save_state(pdev)) {
 257                dev_err(&pdev->dev, "Failed to save pci state.\n");
 258                ret = -ENOMEM;
 259                goto out_err_disable_aer;
 260        }
 261
 262        ret = adf_crypto_dev_config(accel_dev);
 263        if (ret)
 264                goto out_err_disable_aer;
 265
 266        ret = adf_dev_init(accel_dev);
 267        if (ret)
 268                goto out_err_dev_shutdown;
 269
 270        ret = adf_dev_start(accel_dev);
 271        if (ret)
 272                goto out_err_dev_stop;
 273
 274        return ret;
 275
 276out_err_dev_stop:
 277        adf_dev_stop(accel_dev);
 278out_err_dev_shutdown:
 279        adf_dev_shutdown(accel_dev);
 280out_err_disable_aer:
 281        adf_disable_aer(accel_dev);
 282out_err:
 283        adf_cleanup_accel(accel_dev);
 284        return ret;
 285}
 286
 287static void adf_remove(struct pci_dev *pdev)
 288{
 289        struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
 290
 291        if (!accel_dev) {
 292                pr_err("QAT: Driver removal failed\n");
 293                return;
 294        }
 295        adf_dev_stop(accel_dev);
 296        adf_dev_shutdown(accel_dev);
 297        adf_disable_aer(accel_dev);
 298        adf_cleanup_accel(accel_dev);
 299}
 300
 301static struct pci_driver adf_driver = {
 302        .id_table = adf_pci_tbl,
 303        .name = ADF_4XXX_DEVICE_NAME,
 304        .probe = adf_probe,
 305        .remove = adf_remove,
 306        .sriov_configure = adf_sriov_configure,
 307};
 308
 309module_pci_driver(adf_driver);
 310
 311MODULE_LICENSE("Dual BSD/GPL");
 312MODULE_AUTHOR("Intel");
 313MODULE_FIRMWARE(ADF_4XXX_FW);
 314MODULE_FIRMWARE(ADF_4XXX_MMP);
 315MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");
 316MODULE_VERSION(ADF_DRV_VERSION);
 317MODULE_SOFTDEP("pre: crypto-intel_qat");
 318