root/drivers/crypto/qat/qat_c62xvf/adf_drv.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. adf_cleanup_pci_dev
  2. adf_cleanup_accel
  3. adf_probe
  4. adf_remove
  5. adfdrv_init
  6. adfdrv_release

   1 /*
   2   This file is provided under a dual BSD/GPLv2 license.  When using or
   3   redistributing this file, you may do so under either license.
   4 
   5   GPL LICENSE SUMMARY
   6   Copyright(c) 2014 Intel Corporation.
   7   This program is free software; you can redistribute it and/or modify
   8   it under the terms of version 2 of the GNU General Public License as
   9   published by the Free Software Foundation.
  10 
  11   This program is distributed in the hope that it will be useful, but
  12   WITHOUT ANY WARRANTY; without even the implied warranty of
  13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14   General Public License for more details.
  15 
  16   Contact Information:
  17   qat-linux@intel.com
  18 
  19   BSD LICENSE
  20   Copyright(c) 2014 Intel Corporation.
  21   Redistribution and use in source and binary forms, with or without
  22   modification, are permitted provided that the following conditions
  23   are met:
  24 
  25     * Redistributions of source code must retain the above copyright
  26       notice, this list of conditions and the following disclaimer.
  27     * Redistributions in binary form must reproduce the above copyright
  28       notice, this list of conditions and the following disclaimer in
  29       the documentation and/or other materials provided with the
  30       distribution.
  31     * Neither the name of Intel Corporation nor the names of its
  32       contributors may be used to endorse or promote products derived
  33       from this software without specific prior written permission.
  34 
  35   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  36   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  37   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  38   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  39   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  42   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  43   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  44   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  45   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  46 */
  47 #include <linux/kernel.h>
  48 #include <linux/module.h>
  49 #include <linux/pci.h>
  50 #include <linux/init.h>
  51 #include <linux/types.h>
  52 #include <linux/fs.h>
  53 #include <linux/slab.h>
  54 #include <linux/errno.h>
  55 #include <linux/device.h>
  56 #include <linux/dma-mapping.h>
  57 #include <linux/platform_device.h>
  58 #include <linux/workqueue.h>
  59 #include <linux/io.h>
  60 #include <adf_accel_devices.h>
  61 #include <adf_common_drv.h>
  62 #include <adf_cfg.h>
  63 #include "adf_c62xvf_hw_data.h"
  64 
  65 #define ADF_SYSTEM_DEVICE(device_id) \
  66         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
  67 
  68 static const struct pci_device_id adf_pci_tbl[] = {
  69         ADF_SYSTEM_DEVICE(ADF_C62XIOV_PCI_DEVICE_ID),
  70         {0,}
  71 };
  72 MODULE_DEVICE_TABLE(pci, adf_pci_tbl);
  73 
  74 static int adf_probe(struct pci_dev *dev, const struct pci_device_id *ent);
  75 static void adf_remove(struct pci_dev *dev);
  76 
  77 static struct pci_driver adf_driver = {
  78         .id_table = adf_pci_tbl,
  79         .name = ADF_C62XVF_DEVICE_NAME,
  80         .probe = adf_probe,
  81         .remove = adf_remove,
  82 };
  83 
  84 static void adf_cleanup_pci_dev(struct adf_accel_dev *accel_dev)
  85 {
  86         pci_release_regions(accel_dev->accel_pci_dev.pci_dev);
  87         pci_disable_device(accel_dev->accel_pci_dev.pci_dev);
  88 }
  89 
  90 static void adf_cleanup_accel(struct adf_accel_dev *accel_dev)
  91 {
  92         struct adf_accel_pci *accel_pci_dev = &accel_dev->accel_pci_dev;
  93         struct adf_accel_dev *pf;
  94         int i;
  95 
  96         for (i = 0; i < ADF_PCI_MAX_BARS; i++) {
  97                 struct adf_bar *bar = &accel_pci_dev->pci_bars[i];
  98 
  99                 if (bar->virt_addr)
 100                         pci_iounmap(accel_pci_dev->pci_dev, bar->virt_addr);
 101         }
 102 
 103         if (accel_dev->hw_device) {
 104                 switch (accel_pci_dev->pci_dev->device) {
 105                 case ADF_C62XIOV_PCI_DEVICE_ID:
 106                         adf_clean_hw_data_c62xiov(accel_dev->hw_device);
 107                         break;
 108                 default:
 109                         break;
 110                 }
 111                 kfree(accel_dev->hw_device);
 112                 accel_dev->hw_device = NULL;
 113         }
 114         adf_cfg_dev_remove(accel_dev);
 115         debugfs_remove(accel_dev->debugfs_dir);
 116         pf = adf_devmgr_pci_to_accel_dev(accel_pci_dev->pci_dev->physfn);
 117         adf_devmgr_rm_dev(accel_dev, pf);
 118 }
 119 
 120 static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 121 {
 122         struct adf_accel_dev *accel_dev;
 123         struct adf_accel_dev *pf;
 124         struct adf_accel_pci *accel_pci_dev;
 125         struct adf_hw_device_data *hw_data;
 126         char name[ADF_DEVICE_NAME_LENGTH];
 127         unsigned int i, bar_nr;
 128         unsigned long bar_mask;
 129         int ret;
 130 
 131         switch (ent->device) {
 132         case ADF_C62XIOV_PCI_DEVICE_ID:
 133                 break;
 134         default:
 135                 dev_err(&pdev->dev, "Invalid device 0x%x.\n", ent->device);
 136                 return -ENODEV;
 137         }
 138 
 139         accel_dev = kzalloc_node(sizeof(*accel_dev), GFP_KERNEL,
 140                                  dev_to_node(&pdev->dev));
 141         if (!accel_dev)
 142                 return -ENOMEM;
 143 
 144         accel_dev->is_vf = true;
 145         pf = adf_devmgr_pci_to_accel_dev(pdev->physfn);
 146         accel_pci_dev = &accel_dev->accel_pci_dev;
 147         accel_pci_dev->pci_dev = pdev;
 148 
 149         /* Add accel device to accel table */
 150         if (adf_devmgr_add_dev(accel_dev, pf)) {
 151                 dev_err(&pdev->dev, "Failed to add new accelerator device.\n");
 152                 kfree(accel_dev);
 153                 return -EFAULT;
 154         }
 155         INIT_LIST_HEAD(&accel_dev->crypto_list);
 156 
 157         accel_dev->owner = THIS_MODULE;
 158         /* Allocate and configure device configuration structure */
 159         hw_data = kzalloc_node(sizeof(*hw_data), GFP_KERNEL,
 160                                dev_to_node(&pdev->dev));
 161         if (!hw_data) {
 162                 ret = -ENOMEM;
 163                 goto out_err;
 164         }
 165         accel_dev->hw_device = hw_data;
 166         adf_init_hw_data_c62xiov(accel_dev->hw_device);
 167 
 168         /* Get Accelerators and Accelerators Engines masks */
 169         hw_data->accel_mask = hw_data->get_accel_mask(hw_data->fuses);
 170         hw_data->ae_mask = hw_data->get_ae_mask(hw_data->fuses);
 171         accel_pci_dev->sku = hw_data->get_sku(hw_data);
 172 
 173         /* Create dev top level debugfs entry */
 174         snprintf(name, sizeof(name), "%s%s_%02x:%02d.%d",
 175                  ADF_DEVICE_NAME_PREFIX, hw_data->dev_class->name,
 176                  pdev->bus->number, PCI_SLOT(pdev->devfn),
 177                  PCI_FUNC(pdev->devfn));
 178 
 179         accel_dev->debugfs_dir = debugfs_create_dir(name, NULL);
 180 
 181         /* Create device configuration table */
 182         ret = adf_cfg_dev_add(accel_dev);
 183         if (ret)
 184                 goto out_err;
 185 
 186         /* enable PCI device */
 187         if (pci_enable_device(pdev)) {
 188                 ret = -EFAULT;
 189                 goto out_err;
 190         }
 191 
 192         /* set dma identifier */
 193         if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 194                 if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
 195                         dev_err(&pdev->dev, "No usable DMA configuration\n");
 196                         ret = -EFAULT;
 197                         goto out_err_disable;
 198                 } else {
 199                         pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 200                 }
 201 
 202         } else {
 203                 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 204         }
 205 
 206         if (pci_request_regions(pdev, ADF_C62XVF_DEVICE_NAME)) {
 207                 ret = -EFAULT;
 208                 goto out_err_disable;
 209         }
 210 
 211         /* Find and map all the device's BARS */
 212         i = 0;
 213         bar_mask = pci_select_bars(pdev, IORESOURCE_MEM);
 214         for_each_set_bit(bar_nr, &bar_mask, ADF_PCI_MAX_BARS * 2) {
 215                 struct adf_bar *bar = &accel_pci_dev->pci_bars[i++];
 216 
 217                 bar->base_addr = pci_resource_start(pdev, bar_nr);
 218                 if (!bar->base_addr)
 219                         break;
 220                 bar->size = pci_resource_len(pdev, bar_nr);
 221                 bar->virt_addr = pci_iomap(accel_pci_dev->pci_dev, bar_nr, 0);
 222                 if (!bar->virt_addr) {
 223                         dev_err(&pdev->dev, "Failed to map BAR %d\n", bar_nr);
 224                         ret = -EFAULT;
 225                         goto out_err_free_reg;
 226                 }
 227         }
 228         pci_set_master(pdev);
 229         /* Completion for VF2PF request/response message exchange */
 230         init_completion(&accel_dev->vf.iov_msg_completion);
 231 
 232         ret = qat_crypto_dev_config(accel_dev);
 233         if (ret)
 234                 goto out_err_free_reg;
 235 
 236         set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status);
 237 
 238         ret = adf_dev_init(accel_dev);
 239         if (ret)
 240                 goto out_err_dev_shutdown;
 241 
 242         ret = adf_dev_start(accel_dev);
 243         if (ret)
 244                 goto out_err_dev_stop;
 245 
 246         return ret;
 247 
 248 out_err_dev_stop:
 249         adf_dev_stop(accel_dev);
 250 out_err_dev_shutdown:
 251         adf_dev_shutdown(accel_dev);
 252 out_err_free_reg:
 253         pci_release_regions(accel_pci_dev->pci_dev);
 254 out_err_disable:
 255         pci_disable_device(accel_pci_dev->pci_dev);
 256 out_err:
 257         adf_cleanup_accel(accel_dev);
 258         kfree(accel_dev);
 259         return ret;
 260 }
 261 
 262 static void adf_remove(struct pci_dev *pdev)
 263 {
 264         struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
 265 
 266         if (!accel_dev) {
 267                 pr_err("QAT: Driver removal failed\n");
 268                 return;
 269         }
 270         adf_dev_stop(accel_dev);
 271         adf_dev_shutdown(accel_dev);
 272         adf_cleanup_accel(accel_dev);
 273         adf_cleanup_pci_dev(accel_dev);
 274         kfree(accel_dev);
 275 }
 276 
 277 static int __init adfdrv_init(void)
 278 {
 279         request_module("intel_qat");
 280 
 281         if (pci_register_driver(&adf_driver)) {
 282                 pr_err("QAT: Driver initialization failed\n");
 283                 return -EFAULT;
 284         }
 285         return 0;
 286 }
 287 
 288 static void __exit adfdrv_release(void)
 289 {
 290         pci_unregister_driver(&adf_driver);
 291         adf_clean_vf_map(true);
 292 }
 293 
 294 module_init(adfdrv_init);
 295 module_exit(adfdrv_release);
 296 
 297 MODULE_LICENSE("Dual BSD/GPL");
 298 MODULE_AUTHOR("Intel");
 299 MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");
 300 MODULE_VERSION(ADF_DRV_VERSION);

/* [<][>][^][v][top][bottom][index][help] */