The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/qat/qat_hw/qat_c4xxx/adf_drv.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* SPDX-License-Identifier: BSD-3-Clause */
    2 /* Copyright(c) 2007-2022 Intel Corporation */
    3 /* $FreeBSD$ */
    4 #include "qat_freebsd.h"
    5 #include "adf_cfg.h"
    6 #include "adf_common_drv.h"
    7 #include "adf_accel_devices.h"
    8 #include "adf_c4xxx_hw_data.h"
    9 #include "adf_fw_counters.h"
   10 #include "adf_cfg_device.h"
   11 #include <sys/types.h>
   12 #include <sys/kernel.h>
   13 #include <sys/malloc.h>
   14 #include <machine/bus_dma.h>
   15 #include <dev/pci/pcireg.h>
   16 #include "adf_heartbeat_dbg.h"
   17 #include "adf_cnvnr_freq_counters.h"
   18 
   19 static MALLOC_DEFINE(M_QAT_C4XXX, "qat_c4xx", "qat_c4xx");
   20 
   21 #define ADF_SYSTEM_DEVICE(device_id)                                           \
   22         {                                                                      \
   23                 PCI_VENDOR_ID_INTEL, device_id                                 \
   24         }
   25 
   26 static const struct pci_device_id adf_pci_tbl[] =
   27     { ADF_SYSTEM_DEVICE(ADF_C4XXX_PCI_DEVICE_ID),
   28       {
   29           0,
   30       } };
   31 
   32 static int
   33 adf_probe(device_t dev)
   34 {
   35         const struct pci_device_id *id;
   36 
   37         for (id = adf_pci_tbl; id->vendor != 0; id++) {
   38                 if (pci_get_vendor(dev) == id->vendor &&
   39                     pci_get_device(dev) == id->device) {
   40                         device_set_desc(dev,
   41                                         "Intel " ADF_C4XXX_DEVICE_NAME
   42                                         " QuickAssist");
   43                         return BUS_PROBE_GENERIC;
   44                 }
   45         }
   46         return ENXIO;
   47 }
   48 
   49 static void
   50 adf_cleanup_accel(struct adf_accel_dev *accel_dev)
   51 {
   52         struct adf_accel_pci *accel_pci_dev = &accel_dev->accel_pci_dev;
   53         int i;
   54 
   55         if (accel_dev->dma_tag)
   56                 bus_dma_tag_destroy(accel_dev->dma_tag);
   57         for (i = 0; i < ADF_PCI_MAX_BARS; i++) {
   58                 struct adf_bar *bar = &accel_pci_dev->pci_bars[i];
   59 
   60                 if (bar->virt_addr)
   61                         bus_free_resource(accel_pci_dev->pci_dev,
   62                                           SYS_RES_MEMORY,
   63                                           bar->virt_addr);
   64         }
   65 
   66         if (accel_dev->hw_device) {
   67                 switch (pci_get_device(accel_pci_dev->pci_dev)) {
   68                 case ADF_C4XXX_PCI_DEVICE_ID:
   69                         adf_clean_hw_data_c4xxx(accel_dev->hw_device);
   70                         break;
   71                 default:
   72                         break;
   73                 }
   74                 free(accel_dev->hw_device, M_QAT_C4XXX);
   75                 accel_dev->hw_device = NULL;
   76         }
   77         adf_cfg_dev_remove(accel_dev);
   78         adf_devmgr_rm_dev(accel_dev, NULL);
   79 }
   80 
   81 static int
   82 adf_attach(device_t dev)
   83 {
   84         struct adf_accel_dev *accel_dev;
   85         struct adf_accel_pci *accel_pci_dev;
   86         struct adf_hw_device_data *hw_data;
   87         unsigned int i, bar_nr;
   88         int ret, rid;
   89         struct adf_cfg_device *cfg_dev = NULL;
   90 
   91         /* Set pci MaxPayLoad to 256. Implemented to avoid the issue of
   92          * Pci-passthrough causing Maxpayload to be reset to 128 bytes
   93          * when the device is reset.
   94          */
   95         if (pci_get_max_payload(dev) != 256)
   96                 pci_set_max_payload(dev, 256);
   97 
   98         accel_dev = device_get_softc(dev);
   99 
  100         INIT_LIST_HEAD(&accel_dev->crypto_list);
  101         accel_pci_dev = &accel_dev->accel_pci_dev;
  102         accel_pci_dev->pci_dev = dev;
  103 
  104         if (bus_get_domain(dev, &accel_pci_dev->node) != 0)
  105                 accel_pci_dev->node = 0;
  106 
  107         /* XXX: Revisit if we actually need a devmgr table at all. */
  108 
  109         /* Add accel device to accel table.
  110          * This should be called before adf_cleanup_accel is called
  111          */
  112         if (adf_devmgr_add_dev(accel_dev, NULL)) {
  113                 device_printf(dev, "Failed to add new accelerator device.\n");
  114                 return ENXIO;
  115         }
  116 
  117         /* Allocate and configure device configuration structure */
  118         hw_data = malloc(sizeof(*hw_data), M_QAT_C4XXX, M_WAITOK | M_ZERO);
  119 
  120         accel_dev->hw_device = hw_data;
  121         adf_init_hw_data_c4xxx(accel_dev->hw_device);
  122         accel_pci_dev->revid = pci_get_revid(dev);
  123         hw_data->fuses = pci_read_config(dev, ADF_DEVICE_FUSECTL_OFFSET, 4);
  124 
  125         /* Get PPAERUCM values and store */
  126         ret = adf_aer_store_ppaerucm_reg(dev, hw_data);
  127         if (ret)
  128                 goto out_err;
  129 
  130         /* Get Accelerators and Accelerators Engines masks */
  131         hw_data->accel_mask = hw_data->get_accel_mask(accel_dev);
  132         hw_data->ae_mask = hw_data->get_ae_mask(accel_dev);
  133         hw_data->admin_ae_mask = hw_data->ae_mask;
  134 
  135         /* If the device has no acceleration engines then ignore it. */
  136         if (!hw_data->accel_mask || !hw_data->ae_mask ||
  137             (~hw_data->ae_mask & 0x01)) {
  138                 device_printf(dev, "No acceleration units found\n");
  139                 ret = ENXIO;
  140                 goto out_err;
  141         }
  142 
  143         /* Create device configuration table */
  144         ret = adf_cfg_dev_add(accel_dev);
  145         if (ret)
  146                 goto out_err;
  147 
  148         ret = adf_clock_debugfs_add(accel_dev);
  149         if (ret)
  150                 goto out_err;
  151 
  152         pci_set_max_read_req(dev, 1024);
  153 
  154         ret = bus_dma_tag_create(bus_get_dma_tag(dev),
  155                                  1,
  156                                  0,
  157                                  BUS_SPACE_MAXADDR,
  158                                  BUS_SPACE_MAXADDR,
  159                                  NULL,
  160                                  NULL,
  161                                  BUS_SPACE_MAXSIZE,
  162                                  /*BUS_SPACE_UNRESTRICTED*/ 1,
  163                                  BUS_SPACE_MAXSIZE,
  164                                  0,
  165                                  NULL,
  166                                  NULL,
  167                                  &accel_dev->dma_tag);
  168         if (ret)
  169                 goto out_err;
  170 
  171         if (hw_data->get_accel_cap) {
  172                 hw_data->accel_capabilities_mask =
  173                     hw_data->get_accel_cap(accel_dev);
  174         }
  175 
  176         accel_pci_dev->sku = hw_data->get_sku(hw_data);
  177 
  178         /* Find and map all the device's BARS */
  179         i = 0;
  180         for (bar_nr = 0; i < ADF_PCI_MAX_BARS && bar_nr < PCIR_MAX_BAR_0;
  181              bar_nr++) {
  182                 struct adf_bar *bar;
  183 
  184                 /*
  185                  * XXX: This isn't quite right as it will ignore a BAR
  186                  * that wasn't assigned a valid resource range by the
  187                  * firmware.
  188                  */
  189                 rid = PCIR_BAR(bar_nr);
  190                 if (bus_get_resource(dev, SYS_RES_MEMORY, rid, NULL, NULL) != 0)
  191                         continue;
  192                 bar = &accel_pci_dev->pci_bars[i++];
  193                 bar->virt_addr = bus_alloc_resource_any(dev,
  194                                                         SYS_RES_MEMORY,
  195                                                         &rid,
  196                                                         RF_ACTIVE);
  197                 if (!bar->virt_addr) {
  198                         device_printf(dev, "Failed to map BAR %d\n", bar_nr);
  199                         ret = ENXIO;
  200                         goto out_err;
  201                 }
  202                 bar->base_addr = rman_get_start(bar->virt_addr);
  203                 bar->size = rman_get_start(bar->virt_addr);
  204         }
  205         pci_enable_busmaster(dev);
  206 
  207         if (!accel_dev->hw_device->config_device) {
  208                 ret = EFAULT;
  209                 goto out_err;
  210         }
  211 
  212         ret = accel_dev->hw_device->config_device(accel_dev);
  213         if (ret)
  214                 goto out_err;
  215 
  216         ret = adf_dev_init(accel_dev);
  217         if (ret)
  218                 goto out_dev_shutdown;
  219 
  220         ret = adf_dev_start(accel_dev);
  221         if (ret)
  222                 goto out_dev_stop;
  223 
  224         cfg_dev = accel_dev->cfg->dev;
  225         adf_cfg_device_clear(cfg_dev, accel_dev);
  226         free(cfg_dev, M_QAT);
  227         accel_dev->cfg->dev = NULL;
  228         return ret;
  229 out_dev_stop:
  230         adf_dev_stop(accel_dev);
  231 out_dev_shutdown:
  232         adf_dev_shutdown(accel_dev);
  233 out_err:
  234         adf_cleanup_accel(accel_dev);
  235         return ret;
  236 }
  237 
  238 static int
  239 adf_detach(device_t dev)
  240 {
  241         struct adf_accel_dev *accel_dev = device_get_softc(dev);
  242 
  243         if (adf_dev_stop(accel_dev)) {
  244                 device_printf(dev, "Failed to stop QAT accel dev\n");
  245                 return EBUSY;
  246         }
  247 
  248         adf_dev_shutdown(accel_dev);
  249 
  250         adf_cleanup_accel(accel_dev);
  251 
  252         return 0;
  253 }
  254 
  255 static device_method_t adf_methods[] = { DEVMETHOD(device_probe, adf_probe),
  256                                          DEVMETHOD(device_attach, adf_attach),
  257                                          DEVMETHOD(device_detach, adf_detach),
  258 
  259                                          DEVMETHOD_END };
  260 
  261 static driver_t adf_driver = { "qat",
  262                                adf_methods,
  263                                sizeof(struct adf_accel_dev) };
  264 
  265 DRIVER_MODULE_ORDERED(qat_c4xxx, pci, adf_driver, NULL, NULL, SI_ORDER_THIRD);
  266 MODULE_VERSION(qat_c4xxx, 1);
  267 MODULE_DEPEND(qat_c4xxx, qat_common, 1, 1, 1);
  268 MODULE_DEPEND(qat_c4xxx, qat_api, 1, 1, 1);
  269 MODULE_DEPEND(qat_c4xxx, linuxkpi, 1, 1, 1);

Cache object: 6a0ab0c384e8bc3fedae90aae61db711


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.