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_c62x/adf_c62x_hw_data.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 <adf_accel_devices.h>
    5 #include <adf_common_drv.h>
    6 #include <adf_cfg.h>
    7 #include <adf_pf2vf_msg.h>
    8 #include <adf_dev_err.h>
    9 #include <adf_gen2_hw_data.h>
   10 #include "adf_c62x_hw_data.h"
   11 #include "icp_qat_hw.h"
   12 #include "adf_cfg.h"
   13 #include "adf_heartbeat.h"
   14 
   15 /* Worker thread to service arbiter mappings */
   16 static const u32 thrd_to_arb_map[ADF_C62X_MAX_ACCELENGINES] =
   17     { 0x12222AAA, 0x11222AAA, 0x12222AAA, 0x11222AAA, 0x12222AAA,
   18       0x11222AAA, 0x12222AAA, 0x11222AAA, 0x12222AAA, 0x11222AAA };
   19 
   20 enum { DEV_C62X_SKU_1 = 0, DEV_C62X_SKU_2 = 1 };
   21 
   22 static u32 thrd_to_arb_map_gen[ADF_C62X_MAX_ACCELENGINES] = { 0 };
   23 
   24 static struct adf_hw_device_class c62x_class = {.name = ADF_C62X_DEVICE_NAME,
   25                                                 .type = DEV_C62X,
   26                                                 .instances = 0 };
   27 
   28 static u32
   29 get_accel_mask(struct adf_accel_dev *accel_dev)
   30 {
   31         device_t pdev = accel_dev->accel_pci_dev.pci_dev;
   32 
   33         u32 fuse;
   34         u32 straps;
   35 
   36         fuse = pci_read_config(pdev, ADF_DEVICE_FUSECTL_OFFSET, 4);
   37         straps = pci_read_config(pdev, ADF_C62X_SOFTSTRAP_CSR_OFFSET, 4);
   38 
   39         return (~(fuse | straps)) >> ADF_C62X_ACCELERATORS_REG_OFFSET &
   40             ADF_C62X_ACCELERATORS_MASK;
   41 }
   42 
   43 static u32
   44 get_ae_mask(struct adf_accel_dev *accel_dev)
   45 {
   46         device_t pdev = accel_dev->accel_pci_dev.pci_dev;
   47         u32 fuse;
   48         u32 me_straps;
   49         u32 me_disable;
   50         u32 ssms_disabled;
   51 
   52         fuse = pci_read_config(pdev, ADF_DEVICE_FUSECTL_OFFSET, 4);
   53         me_straps = pci_read_config(pdev, ADF_C62X_SOFTSTRAP_CSR_OFFSET, 4);
   54 
   55         /* If SSMs are disabled, then disable the corresponding MEs */
   56         ssms_disabled =
   57             (~get_accel_mask(accel_dev)) & ADF_C62X_ACCELERATORS_MASK;
   58         me_disable = 0x3;
   59         while (ssms_disabled) {
   60                 if (ssms_disabled & 1)
   61                         me_straps |= me_disable;
   62                 ssms_disabled >>= 1;
   63                 me_disable <<= 2;
   64         }
   65 
   66         return (~(fuse | me_straps)) & ADF_C62X_ACCELENGINES_MASK;
   67 }
   68 
   69 static u32
   70 get_num_accels(struct adf_hw_device_data *self)
   71 {
   72         u32 i, ctr = 0;
   73 
   74         if (!self || !self->accel_mask)
   75                 return 0;
   76 
   77         for (i = 0; i < ADF_C62X_MAX_ACCELERATORS; i++) {
   78                 if (self->accel_mask & (1 << i))
   79                         ctr++;
   80         }
   81         return ctr;
   82 }
   83 
   84 static u32
   85 get_num_aes(struct adf_hw_device_data *self)
   86 {
   87         u32 i, ctr = 0;
   88 
   89         if (!self || !self->ae_mask)
   90                 return 0;
   91 
   92         for (i = 0; i < ADF_C62X_MAX_ACCELENGINES; i++) {
   93                 if (self->ae_mask & (1 << i))
   94                         ctr++;
   95         }
   96         return ctr;
   97 }
   98 
   99 static u32
  100 get_misc_bar_id(struct adf_hw_device_data *self)
  101 {
  102         return ADF_C62X_PMISC_BAR;
  103 }
  104 
  105 static u32
  106 get_etr_bar_id(struct adf_hw_device_data *self)
  107 {
  108         return ADF_C62X_ETR_BAR;
  109 }
  110 
  111 static u32
  112 get_sram_bar_id(struct adf_hw_device_data *self)
  113 {
  114         return ADF_C62X_SRAM_BAR;
  115 }
  116 
  117 static enum dev_sku_info
  118 get_sku(struct adf_hw_device_data *self)
  119 {
  120         int aes = get_num_aes(self);
  121 
  122         if (aes == 8)
  123                 return DEV_SKU_2;
  124         else if (aes == 10)
  125                 return DEV_SKU_4;
  126 
  127         return DEV_SKU_UNKNOWN;
  128 }
  129 
  130 static void
  131 adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev,
  132                         u32 const **arb_map_config)
  133 {
  134         int i;
  135         struct adf_hw_device_data *hw_device = accel_dev->hw_device;
  136 
  137         for (i = 0; i < ADF_C62X_MAX_ACCELENGINES; i++) {
  138                 thrd_to_arb_map_gen[i] = 0;
  139                 if (hw_device->ae_mask & (1 << i))
  140                         thrd_to_arb_map_gen[i] = thrd_to_arb_map[i];
  141         }
  142         adf_cfg_gen_dispatch_arbiter(accel_dev,
  143                                      thrd_to_arb_map,
  144                                      thrd_to_arb_map_gen,
  145                                      ADF_C62X_MAX_ACCELENGINES);
  146         *arb_map_config = thrd_to_arb_map_gen;
  147 }
  148 
  149 static u32
  150 get_pf2vf_offset(u32 i)
  151 {
  152         return ADF_C62X_PF2VF_OFFSET(i);
  153 }
  154 
  155 static u32
  156 get_vintmsk_offset(u32 i)
  157 {
  158         return ADF_C62X_VINTMSK_OFFSET(i);
  159 }
  160 
  161 static void
  162 get_arb_info(struct arb_info *arb_csrs_info)
  163 {
  164         arb_csrs_info->arbiter_offset = ADF_C62X_ARB_OFFSET;
  165         arb_csrs_info->wrk_thd_2_srv_arb_map =
  166             ADF_C62X_ARB_WRK_2_SER_MAP_OFFSET;
  167         arb_csrs_info->wrk_cfg_offset = ADF_C62X_ARB_WQCFG_OFFSET;
  168 }
  169 
  170 static void
  171 get_admin_info(struct admin_info *admin_csrs_info)
  172 {
  173         admin_csrs_info->mailbox_offset = ADF_C62X_MAILBOX_BASE_OFFSET;
  174         admin_csrs_info->admin_msg_ur = ADF_C62X_ADMINMSGUR_OFFSET;
  175         admin_csrs_info->admin_msg_lr = ADF_C62X_ADMINMSGLR_OFFSET;
  176 }
  177 
  178 static void
  179 get_errsou_offset(u32 *errsou3, u32 *errsou5)
  180 {
  181         *errsou3 = ADF_C62X_ERRSOU3;
  182         *errsou5 = ADF_C62X_ERRSOU5;
  183 }
  184 
  185 static u32
  186 get_clock_speed(struct adf_hw_device_data *self)
  187 {
  188         /* CPP clock is half high-speed clock */
  189         return self->clock_frequency / 2;
  190 }
  191 
  192 static void
  193 adf_enable_error_correction(struct adf_accel_dev *accel_dev)
  194 {
  195         struct adf_hw_device_data *hw_device = accel_dev->hw_device;
  196         struct adf_bar *misc_bar = &GET_BARS(accel_dev)[ADF_C62X_PMISC_BAR];
  197         struct resource *csr = misc_bar->virt_addr;
  198         unsigned int val, i;
  199         unsigned int mask;
  200 
  201         /* Enable Accel Engine error detection & correction */
  202         mask = hw_device->ae_mask;
  203         for (i = 0; mask; i++, mask >>= 1) {
  204                 if (!(mask & 1))
  205                         continue;
  206                 val = ADF_CSR_RD(csr, ADF_C62X_AE_CTX_ENABLES(i));
  207                 val |= ADF_C62X_ENABLE_AE_ECC_ERR;
  208                 ADF_CSR_WR(csr, ADF_C62X_AE_CTX_ENABLES(i), val);
  209                 val = ADF_CSR_RD(csr, ADF_C62X_AE_MISC_CONTROL(i));
  210                 val |= ADF_C62X_ENABLE_AE_ECC_PARITY_CORR;
  211                 ADF_CSR_WR(csr, ADF_C62X_AE_MISC_CONTROL(i), val);
  212         }
  213 
  214         /* Enable shared memory error detection & correction */
  215         mask = hw_device->accel_mask;
  216         for (i = 0; mask; i++, mask >>= 1) {
  217                 if (!(mask & 1))
  218                         continue;
  219                 val = ADF_CSR_RD(csr, ADF_C62X_UERRSSMSH(i));
  220                 val |= ADF_C62X_ERRSSMSH_EN;
  221                 ADF_CSR_WR(csr, ADF_C62X_UERRSSMSH(i), val);
  222                 val = ADF_CSR_RD(csr, ADF_C62X_CERRSSMSH(i));
  223                 val |= ADF_C62X_ERRSSMSH_EN;
  224                 ADF_CSR_WR(csr, ADF_C62X_CERRSSMSH(i), val);
  225         }
  226 }
  227 
  228 static void
  229 adf_enable_ints(struct adf_accel_dev *accel_dev)
  230 {
  231         struct resource *addr;
  232 
  233         addr = (&GET_BARS(accel_dev)[ADF_C62X_PMISC_BAR])->virt_addr;
  234 
  235         /* Enable bundle and misc interrupts */
  236         ADF_CSR_WR(addr, ADF_C62X_SMIAPF0_MASK_OFFSET, ADF_C62X_SMIA0_MASK);
  237         ADF_CSR_WR(addr, ADF_C62X_SMIAPF1_MASK_OFFSET, ADF_C62X_SMIA1_MASK);
  238 }
  239 
  240 static u32
  241 get_ae_clock(struct adf_hw_device_data *self)
  242 {
  243         /*
  244          * Clock update interval is <16> ticks for c62x.
  245          */
  246         return self->clock_frequency / 16;
  247 }
  248 
  249 static int
  250 get_storage_enabled(struct adf_accel_dev *accel_dev, uint32_t *storage_enabled)
  251 {
  252         char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
  253         char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
  254 
  255         strlcpy(key, ADF_STORAGE_FIRMWARE_ENABLED, sizeof(key));
  256         if (!adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, key, val)) {
  257                 if (kstrtouint(val, 0, storage_enabled))
  258                         return -EFAULT;
  259         }
  260         return 0;
  261 }
  262 
  263 static int
  264 measure_clock(struct adf_accel_dev *accel_dev)
  265 {
  266         u32 frequency;
  267         int ret = 0;
  268 
  269         ret = adf_dev_measure_clock(accel_dev,
  270                                     &frequency,
  271                                     ADF_C62X_MIN_AE_FREQ,
  272                                     ADF_C62X_MAX_AE_FREQ);
  273         if (ret)
  274                 return ret;
  275 
  276         accel_dev->hw_device->clock_frequency = frequency;
  277         return 0;
  278 }
  279 
  280 static u32
  281 c62x_get_hw_cap(struct adf_accel_dev *accel_dev)
  282 {
  283         device_t pdev = accel_dev->accel_pci_dev.pci_dev;
  284         u32 legfuses;
  285         u32 capabilities;
  286         u32 straps;
  287         struct adf_hw_device_data *hw_data = accel_dev->hw_device;
  288         u32 fuses = hw_data->fuses;
  289 
  290         /* Read accelerator capabilities mask */
  291         legfuses = pci_read_config(pdev, ADF_DEVICE_LEGFUSE_OFFSET, 4);
  292 
  293         capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC +
  294             ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC +
  295             ICP_ACCEL_CAPABILITIES_CIPHER +
  296             ICP_ACCEL_CAPABILITIES_AUTHENTICATION +
  297             ICP_ACCEL_CAPABILITIES_COMPRESSION + ICP_ACCEL_CAPABILITIES_ZUC +
  298             ICP_ACCEL_CAPABILITIES_SHA3 + ICP_ACCEL_CAPABILITIES_HKDF +
  299             ICP_ACCEL_CAPABILITIES_ECEDMONT +
  300             ICP_ACCEL_CAPABILITIES_EXT_ALGCHAIN;
  301         if (legfuses & ICP_ACCEL_MASK_CIPHER_SLICE)
  302                 capabilities &= ~(ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC |
  303                                   ICP_ACCEL_CAPABILITIES_CIPHER |
  304                                   ICP_ACCEL_CAPABILITIES_HKDF |
  305                                   ICP_ACCEL_CAPABILITIES_EXT_ALGCHAIN);
  306         if (legfuses & ICP_ACCEL_MASK_AUTH_SLICE)
  307                 capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION;
  308         if (legfuses & ICP_ACCEL_MASK_PKE_SLICE)
  309                 capabilities &= ~(ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC |
  310                                   ICP_ACCEL_CAPABILITIES_ECEDMONT);
  311         if (legfuses & ICP_ACCEL_MASK_COMPRESS_SLICE)
  312                 capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION;
  313         if (legfuses & ICP_ACCEL_MASK_EIA3_SLICE)
  314                 capabilities &= ~ICP_ACCEL_CAPABILITIES_ZUC;
  315         if (legfuses & ICP_ACCEL_MASK_SHA3_SLICE)
  316                 capabilities &= ~ICP_ACCEL_CAPABILITIES_SHA3;
  317 
  318         straps = pci_read_config(pdev, ADF_C62X_SOFTSTRAP_CSR_OFFSET, 4);
  319         if ((straps | fuses) & ADF_C62X_POWERGATE_PKE)
  320                 capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC;
  321         if ((straps | fuses) & ADF_C62X_POWERGATE_DC)
  322                 capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION;
  323 
  324         return capabilities;
  325 }
  326 
  327 static const char *
  328 get_obj_name(struct adf_accel_dev *accel_dev,
  329              enum adf_accel_unit_services service)
  330 {
  331         return ADF_CXXX_AE_FW_NAME_CUSTOM1;
  332 }
  333 
  334 static uint32_t
  335 get_objs_num(struct adf_accel_dev *accel_dev)
  336 {
  337         return 1;
  338 }
  339 
  340 static uint32_t
  341 get_obj_cfg_ae_mask(struct adf_accel_dev *accel_dev,
  342                     enum adf_accel_unit_services services)
  343 {
  344         return accel_dev->hw_device->ae_mask;
  345 }
  346 
  347 void
  348 adf_init_hw_data_c62x(struct adf_hw_device_data *hw_data)
  349 {
  350         hw_data->dev_class = &c62x_class;
  351         hw_data->instance_id = c62x_class.instances++;
  352         hw_data->num_banks = ADF_C62X_ETR_MAX_BANKS;
  353         hw_data->num_rings_per_bank = ADF_ETR_MAX_RINGS_PER_BANK;
  354         hw_data->num_accel = ADF_C62X_MAX_ACCELERATORS;
  355         hw_data->num_logical_accel = 1;
  356         hw_data->num_engines = ADF_C62X_MAX_ACCELENGINES;
  357         hw_data->tx_rx_gap = ADF_C62X_RX_RINGS_OFFSET;
  358         hw_data->tx_rings_mask = ADF_C62X_TX_RINGS_MASK;
  359         hw_data->alloc_irq = adf_isr_resource_alloc;
  360         hw_data->free_irq = adf_isr_resource_free;
  361         hw_data->enable_error_correction = adf_enable_error_correction;
  362         hw_data->print_err_registers = adf_print_err_registers;
  363         hw_data->get_accel_mask = get_accel_mask;
  364         hw_data->get_ae_mask = get_ae_mask;
  365         hw_data->get_num_accels = get_num_accels;
  366         hw_data->get_num_aes = get_num_aes;
  367         hw_data->get_sram_bar_id = get_sram_bar_id;
  368         hw_data->get_etr_bar_id = get_etr_bar_id;
  369         hw_data->get_misc_bar_id = get_misc_bar_id;
  370         hw_data->get_pf2vf_offset = get_pf2vf_offset;
  371         hw_data->get_vintmsk_offset = get_vintmsk_offset;
  372         hw_data->get_arb_info = get_arb_info;
  373         hw_data->get_admin_info = get_admin_info;
  374         hw_data->get_errsou_offset = get_errsou_offset;
  375         hw_data->get_clock_speed = get_clock_speed;
  376         hw_data->get_sku = get_sku;
  377         hw_data->heartbeat_ctr_num = ADF_NUM_HB_CNT_PER_AE;
  378         hw_data->fw_name = ADF_C62X_FW;
  379         hw_data->fw_mmp_name = ADF_C62X_MMP;
  380         hw_data->init_admin_comms = adf_init_admin_comms;
  381         hw_data->exit_admin_comms = adf_exit_admin_comms;
  382         hw_data->disable_iov = adf_disable_sriov;
  383         hw_data->send_admin_init = adf_send_admin_init;
  384         hw_data->init_arb = adf_init_gen2_arb;
  385         hw_data->exit_arb = adf_exit_arb;
  386         hw_data->get_arb_mapping = adf_get_arbiter_mapping;
  387         hw_data->enable_ints = adf_enable_ints;
  388         hw_data->set_ssm_wdtimer = adf_set_ssm_wdtimer;
  389         hw_data->check_slice_hang = adf_check_slice_hang;
  390         hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms;
  391         hw_data->disable_vf2pf_comms = adf_pf_disable_vf2pf_comms;
  392         hw_data->restore_device = adf_dev_restore;
  393         hw_data->reset_device = adf_reset_flr;
  394         hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION;
  395         hw_data->get_objs_num = get_objs_num;
  396         hw_data->get_obj_name = get_obj_name;
  397         hw_data->get_obj_cfg_ae_mask = get_obj_cfg_ae_mask;
  398         hw_data->clock_frequency = ADF_C62X_AE_FREQ;
  399         hw_data->measure_clock = measure_clock;
  400         hw_data->get_ae_clock = get_ae_clock;
  401         hw_data->get_accel_cap = c62x_get_hw_cap;
  402         hw_data->reset_device = adf_reset_flr;
  403         hw_data->extended_dc_capabilities = 0;
  404         hw_data->get_storage_enabled = get_storage_enabled;
  405         hw_data->query_storage_cap = 1;
  406         hw_data->get_heartbeat_status = adf_get_heartbeat_status;
  407         hw_data->get_ae_clock = get_ae_clock;
  408         hw_data->storage_enable = 0;
  409         hw_data->get_fw_image_type = adf_cfg_get_fw_image_type;
  410         hw_data->config_device = adf_config_device;
  411         hw_data->get_ring_to_svc_map = adf_cfg_get_services_enabled;
  412         hw_data->set_asym_rings_mask = adf_cfg_set_asym_rings_mask;
  413         hw_data->ring_to_svc_map = ADF_DEFAULT_RING_TO_SRV_MAP;
  414         hw_data->pre_reset = adf_dev_pre_reset;
  415         hw_data->post_reset = adf_dev_post_reset;
  416 
  417         adf_gen2_init_hw_csr_info(&hw_data->csr_info);
  418 }
  419 
  420 void
  421 adf_clean_hw_data_c62x(struct adf_hw_device_data *hw_data)
  422 {
  423         hw_data->dev_class->instances--;
  424 }

Cache object: ce2be376057fb0ed0f2e03e7af0ea2ee


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