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_c3xxx/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_c3xxx_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_C3XXX, "qat_c3xxx", "qat_c3xxx");
   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_C3XXX_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_C3XXX_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_C3XXX_PCI_DEVICE_ID:
   69                         adf_clean_hw_data_c3xxx(accel_dev->hw_device);
   70                         break;
   71                 default:
   72                         break;
   73                 }
   74                 free(accel_dev->hw_device, M_QAT_C3XXX);
   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         if (pci_get_max_payload(dev) != 256)
   95                 pci_set_max_payload(dev, 256);
   96 
   97         accel_dev = device_get_softc(dev);
   98 
   99         INIT_LIST_HEAD(&accel_dev->crypto_list);
  100         accel_pci_dev = &accel_dev->accel_pci_dev;
  101         accel_pci_dev->pci_dev = dev;
  102 
  103         if (bus_get_domain(dev, &accel_pci_dev->node) != 0)
  104                 accel_pci_dev->node = 0;
  105 
  106         /* XXX: Revisit if we actually need a devmgr table at all. */
  107 
  108         /* Add accel device to accel table.
  109          * This should be called before adf_cleanup_accel is called */
  110         if (adf_devmgr_add_dev(accel_dev, NULL)) {
  111                 device_printf(dev, "Failed to add new accelerator device.\n");
  112                 return ENXIO;
  113         }
  114 
  115         /* Allocate and configure device configuration structure */
  116         hw_data = malloc(sizeof(*hw_data), M_QAT_C3XXX, M_WAITOK | M_ZERO);
  117 
  118         accel_dev->hw_device = hw_data;
  119         adf_init_hw_data_c3xxx(accel_dev->hw_device);
  120         accel_pci_dev->revid = pci_get_revid(dev);
  121         hw_data->fuses = pci_read_config(dev, ADF_DEVICE_FUSECTL_OFFSET, 4);
  122         if (accel_pci_dev->revid == 0x00) {
  123                 device_printf(dev, "A0 stepping is not supported.\n");
  124                 ret = ENODEV;
  125                 goto out_err;
  126         }
  127 
  128         /* Get PPAERUCM values and store */
  129         ret = adf_aer_store_ppaerucm_reg(dev, hw_data);
  130         if (ret)
  131                 goto out_err;
  132 
  133         /* Get Accelerators and Accelerators Engines masks */
  134         hw_data->accel_mask = hw_data->get_accel_mask(accel_dev);
  135         hw_data->ae_mask = hw_data->get_ae_mask(accel_dev);
  136         hw_data->admin_ae_mask = hw_data->ae_mask;
  137 
  138         accel_pci_dev->sku = hw_data->get_sku(hw_data);
  139         /* If the device has no acceleration engines then ignore it. */
  140         if (!hw_data->accel_mask || !hw_data->ae_mask ||
  141             ((~hw_data->ae_mask) & 0x01)) {
  142                 device_printf(dev, "No acceleration units found\n");
  143                 ret = ENXIO;
  144                 goto out_err;
  145         }
  146 
  147         /* Create device configuration table */
  148         ret = adf_cfg_dev_add(accel_dev);
  149         if (ret)
  150                 goto out_err;
  151         ret = adf_clock_debugfs_add(accel_dev);
  152         if (ret)
  153                 goto out_err;
  154 
  155         pci_set_max_read_req(dev, 1024);
  156 
  157         ret = bus_dma_tag_create(bus_get_dma_tag(dev),
  158                                  1,
  159                                  0,
  160                                  BUS_SPACE_MAXADDR,
  161                                  BUS_SPACE_MAXADDR,
  162                                  NULL,
  163                                  NULL,
  164                                  BUS_SPACE_MAXSIZE,
  165                                  /* BUS_SPACE_UNRESTRICTED */ 1,
  166                                  BUS_SPACE_MAXSIZE,
  167                                  0,
  168                                  NULL,
  169                                  NULL,
  170                                  &accel_dev->dma_tag);
  171         if (ret)
  172                 goto out_err;
  173 
  174         if (hw_data->get_accel_cap) {
  175                 hw_data->accel_capabilities_mask =
  176                     hw_data->get_accel_cap(accel_dev);
  177         }
  178 
  179         /* Find and map all the device's BARS */
  180         i = 0;
  181         for (bar_nr = 0; i < ADF_PCI_MAX_BARS && bar_nr < PCIR_MAX_BAR_0;
  182              bar_nr++) {
  183                 struct adf_bar *bar;
  184 
  185                 /*
  186                  * XXX: This isn't quite right as it will ignore a BAR
  187                  * that wasn't assigned a valid resource range by the
  188                  * firmware.
  189                  */
  190                 rid = PCIR_BAR(bar_nr);
  191                 if (bus_get_resource(dev, SYS_RES_MEMORY, rid, NULL, NULL) != 0)
  192                         continue;
  193                 bar = &accel_pci_dev->pci_bars[i++];
  194                 bar->virt_addr = bus_alloc_resource_any(dev,
  195                                                         SYS_RES_MEMORY,
  196                                                         &rid,
  197                                                         RF_ACTIVE);
  198                 if (bar->virt_addr == NULL) {
  199                         device_printf(dev, "Failed to map BAR %d\n", bar_nr);
  200                         ret = ENXIO;
  201                         goto out_err;
  202                 }
  203                 bar->base_addr = rman_get_start(bar->virt_addr);
  204                 bar->size = rman_get_size(bar->virt_addr);
  205         }
  206         pci_enable_busmaster(dev);
  207 
  208         if (!accel_dev->hw_device->config_device) {
  209                 ret = EFAULT;
  210                 goto out_err;
  211         }
  212 
  213         ret = accel_dev->hw_device->config_device(accel_dev);
  214         if (ret)
  215                 goto out_err;
  216 
  217         ret = adf_dev_init(accel_dev);
  218         if (ret)
  219                 goto out_dev_shutdown;
  220 
  221         ret = adf_dev_start(accel_dev);
  222         if (ret)
  223                 goto out_dev_stop;
  224 
  225         cfg_dev = accel_dev->cfg->dev;
  226         adf_cfg_device_clear(cfg_dev, accel_dev);
  227         free(cfg_dev, M_QAT);
  228         accel_dev->cfg->dev = NULL;
  229         return ret;
  230 out_dev_stop:
  231         adf_dev_stop(accel_dev);
  232 out_dev_shutdown:
  233         adf_dev_shutdown(accel_dev);
  234 out_err:
  235         adf_cleanup_accel(accel_dev);
  236         return ret;
  237 }
  238 
  239 static int
  240 adf_detach(device_t dev)
  241 {
  242         struct adf_accel_dev *accel_dev = device_get_softc(dev);
  243 
  244         if (adf_dev_stop(accel_dev)) {
  245                 device_printf(dev, "Failed to stop QAT accel dev\n");
  246                 return EBUSY;
  247         }
  248 
  249         adf_dev_shutdown(accel_dev);
  250 
  251         adf_cleanup_accel(accel_dev);
  252 
  253         return 0;
  254 }
  255 
  256 static device_method_t adf_methods[] = { DEVMETHOD(device_probe, adf_probe),
  257                                          DEVMETHOD(device_attach, adf_attach),
  258                                          DEVMETHOD(device_detach, adf_detach),
  259 
  260                                          DEVMETHOD_END };
  261 
  262 static driver_t adf_driver = { "qat",
  263                                adf_methods,
  264                                sizeof(struct adf_accel_dev) };
  265 
  266 DRIVER_MODULE_ORDERED(qat_c3xxx, pci, adf_driver, NULL, NULL, SI_ORDER_THIRD);
  267 MODULE_VERSION(qat_c3xxx, 1);
  268 MODULE_DEPEND(qat_c3xxx, qat_common, 1, 1, 1);
  269 MODULE_DEPEND(qat_c3xxx, qat_api, 1, 1, 1);
  270 MODULE_DEPEND(qat_c3xxx, linuxkpi, 1, 1, 1);

Cache object: 99ac3564b13e0127928ff3ae3d823c76


[ 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.