linux/drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.c
<<
>>
Prefs
   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 <adf_accel_devices.h>
  48#include <adf_common_drv.h>
  49#include <adf_pf2vf_msg.h>
  50#include "adf_c62x_hw_data.h"
  51
  52/* Worker thread to service arbiter mappings based on dev SKUs */
  53static const u32 thrd_to_arb_map_8_me_sku[] = {
  54        0x12222AAA, 0x11222AAA, 0x12222AAA, 0x11222AAA, 0x12222AAA,
  55        0x11222AAA, 0x12222AAA, 0x11222AAA, 0, 0
  56};
  57
  58static const u32 thrd_to_arb_map_10_me_sku[] = {
  59        0x12222AAA, 0x11222AAA, 0x12222AAA, 0x11222AAA, 0x12222AAA,
  60        0x11222AAA, 0x12222AAA, 0x11222AAA, 0x12222AAA, 0x11222AAA
  61};
  62
  63static struct adf_hw_device_class c62x_class = {
  64        .name = ADF_C62X_DEVICE_NAME,
  65        .type = DEV_C62X,
  66        .instances = 0
  67};
  68
  69static u32 get_accel_mask(u32 fuse)
  70{
  71        return (~fuse) >> ADF_C62X_ACCELERATORS_REG_OFFSET &
  72                          ADF_C62X_ACCELERATORS_MASK;
  73}
  74
  75static u32 get_ae_mask(u32 fuse)
  76{
  77        return (~fuse) & ADF_C62X_ACCELENGINES_MASK;
  78}
  79
  80static u32 get_num_accels(struct adf_hw_device_data *self)
  81{
  82        u32 i, ctr = 0;
  83
  84        if (!self || !self->accel_mask)
  85                return 0;
  86
  87        for (i = 0; i < ADF_C62X_MAX_ACCELERATORS; i++) {
  88                if (self->accel_mask & (1 << i))
  89                        ctr++;
  90        }
  91        return ctr;
  92}
  93
  94static u32 get_num_aes(struct adf_hw_device_data *self)
  95{
  96        u32 i, ctr = 0;
  97
  98        if (!self || !self->ae_mask)
  99                return 0;
 100
 101        for (i = 0; i < ADF_C62X_MAX_ACCELENGINES; i++) {
 102                if (self->ae_mask & (1 << i))
 103                        ctr++;
 104        }
 105        return ctr;
 106}
 107
 108static u32 get_misc_bar_id(struct adf_hw_device_data *self)
 109{
 110        return ADF_C62X_PMISC_BAR;
 111}
 112
 113static u32 get_etr_bar_id(struct adf_hw_device_data *self)
 114{
 115        return ADF_C62X_ETR_BAR;
 116}
 117
 118static u32 get_sram_bar_id(struct adf_hw_device_data *self)
 119{
 120        return ADF_C62X_SRAM_BAR;
 121}
 122
 123static enum dev_sku_info get_sku(struct adf_hw_device_data *self)
 124{
 125        int aes = get_num_aes(self);
 126
 127        if (aes == 8)
 128                return DEV_SKU_2;
 129        else if (aes == 10)
 130                return DEV_SKU_4;
 131
 132        return DEV_SKU_UNKNOWN;
 133}
 134
 135static void adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev,
 136                                    u32 const **arb_map_config)
 137{
 138        switch (accel_dev->accel_pci_dev.sku) {
 139        case DEV_SKU_2:
 140                *arb_map_config = thrd_to_arb_map_8_me_sku;
 141                break;
 142        case DEV_SKU_4:
 143                *arb_map_config = thrd_to_arb_map_10_me_sku;
 144                break;
 145        default:
 146                dev_err(&GET_DEV(accel_dev),
 147                        "The configuration doesn't match any SKU");
 148                *arb_map_config = NULL;
 149        }
 150}
 151
 152static u32 get_pf2vf_offset(u32 i)
 153{
 154        return ADF_C62X_PF2VF_OFFSET(i);
 155}
 156
 157static u32 get_vintmsk_offset(u32 i)
 158{
 159        return ADF_C62X_VINTMSK_OFFSET(i);
 160}
 161
 162static void adf_enable_error_correction(struct adf_accel_dev *accel_dev)
 163{
 164        struct adf_hw_device_data *hw_device = accel_dev->hw_device;
 165        struct adf_bar *misc_bar = &GET_BARS(accel_dev)[ADF_C62X_PMISC_BAR];
 166        void __iomem *csr = misc_bar->virt_addr;
 167        unsigned int val, i;
 168
 169        /* Enable Accel Engine error detection & correction */
 170        for (i = 0; i < hw_device->get_num_aes(hw_device); i++) {
 171                val = ADF_CSR_RD(csr, ADF_C62X_AE_CTX_ENABLES(i));
 172                val |= ADF_C62X_ENABLE_AE_ECC_ERR;
 173                ADF_CSR_WR(csr, ADF_C62X_AE_CTX_ENABLES(i), val);
 174                val = ADF_CSR_RD(csr, ADF_C62X_AE_MISC_CONTROL(i));
 175                val |= ADF_C62X_ENABLE_AE_ECC_PARITY_CORR;
 176                ADF_CSR_WR(csr, ADF_C62X_AE_MISC_CONTROL(i), val);
 177        }
 178
 179        /* Enable shared memory error detection & correction */
 180        for (i = 0; i < hw_device->get_num_accels(hw_device); i++) {
 181                val = ADF_CSR_RD(csr, ADF_C62X_UERRSSMSH(i));
 182                val |= ADF_C62X_ERRSSMSH_EN;
 183                ADF_CSR_WR(csr, ADF_C62X_UERRSSMSH(i), val);
 184                val = ADF_CSR_RD(csr, ADF_C62X_CERRSSMSH(i));
 185                val |= ADF_C62X_ERRSSMSH_EN;
 186                ADF_CSR_WR(csr, ADF_C62X_CERRSSMSH(i), val);
 187        }
 188}
 189
 190static void adf_enable_ints(struct adf_accel_dev *accel_dev)
 191{
 192        void __iomem *addr;
 193
 194        addr = (&GET_BARS(accel_dev)[ADF_C62X_PMISC_BAR])->virt_addr;
 195
 196        /* Enable bundle and misc interrupts */
 197        ADF_CSR_WR(addr, ADF_C62X_SMIAPF0_MASK_OFFSET,
 198                   ADF_C62X_SMIA0_MASK);
 199        ADF_CSR_WR(addr, ADF_C62X_SMIAPF1_MASK_OFFSET,
 200                   ADF_C62X_SMIA1_MASK);
 201}
 202
 203static int adf_pf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev)
 204{
 205        return 0;
 206}
 207
 208void adf_init_hw_data_c62x(struct adf_hw_device_data *hw_data)
 209{
 210        hw_data->dev_class = &c62x_class;
 211        hw_data->instance_id = c62x_class.instances++;
 212        hw_data->num_banks = ADF_C62X_ETR_MAX_BANKS;
 213        hw_data->num_accel = ADF_C62X_MAX_ACCELERATORS;
 214        hw_data->num_logical_accel = 1;
 215        hw_data->num_engines = ADF_C62X_MAX_ACCELENGINES;
 216        hw_data->tx_rx_gap = ADF_C62X_RX_RINGS_OFFSET;
 217        hw_data->tx_rings_mask = ADF_C62X_TX_RINGS_MASK;
 218        hw_data->alloc_irq = adf_isr_resource_alloc;
 219        hw_data->free_irq = adf_isr_resource_free;
 220        hw_data->enable_error_correction = adf_enable_error_correction;
 221        hw_data->get_accel_mask = get_accel_mask;
 222        hw_data->get_ae_mask = get_ae_mask;
 223        hw_data->get_num_accels = get_num_accels;
 224        hw_data->get_num_aes = get_num_aes;
 225        hw_data->get_sram_bar_id = get_sram_bar_id;
 226        hw_data->get_etr_bar_id = get_etr_bar_id;
 227        hw_data->get_misc_bar_id = get_misc_bar_id;
 228        hw_data->get_pf2vf_offset = get_pf2vf_offset;
 229        hw_data->get_vintmsk_offset = get_vintmsk_offset;
 230        hw_data->get_sku = get_sku;
 231        hw_data->fw_name = ADF_C62X_FW;
 232        hw_data->fw_mmp_name = ADF_C62X_MMP;
 233        hw_data->init_admin_comms = adf_init_admin_comms;
 234        hw_data->exit_admin_comms = adf_exit_admin_comms;
 235        hw_data->disable_iov = adf_disable_sriov;
 236        hw_data->send_admin_init = adf_send_admin_init;
 237        hw_data->init_arb = adf_init_arb;
 238        hw_data->exit_arb = adf_exit_arb;
 239        hw_data->get_arb_mapping = adf_get_arbiter_mapping;
 240        hw_data->enable_ints = adf_enable_ints;
 241        hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms;
 242        hw_data->reset_device = adf_reset_flr;
 243        hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION;
 244}
 245
 246void adf_clean_hw_data_c62x(struct adf_hw_device_data *hw_data)
 247{
 248        hw_data->dev_class->instances--;
 249}
 250