linux/drivers/crypto/qat/qat_common/adf_admin.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 <linux/types.h>
  48#include <linux/mutex.h>
  49#include <linux/slab.h>
  50#include <linux/delay.h>
  51#include <linux/pci.h>
  52#include <linux/dma-mapping.h>
  53#include "adf_accel_devices.h"
  54#include "adf_common_drv.h"
  55#include "icp_qat_fw_init_admin.h"
  56
  57/* Admin Messages Registers */
  58#define ADF_DH895XCC_ADMINMSGUR_OFFSET (0x3A000 + 0x574)
  59#define ADF_DH895XCC_ADMINMSGLR_OFFSET (0x3A000 + 0x578)
  60#define ADF_DH895XCC_MAILBOX_BASE_OFFSET 0x20970
  61#define ADF_DH895XCC_MAILBOX_STRIDE 0x1000
  62#define ADF_ADMINMSG_LEN 32
  63
  64static const u8 const_tab[1024] __aligned(1024) = {
  650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
  710x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00,
  720x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  730x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
  740x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01,
  750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
  760x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00,
  770x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
  780x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00,
  790x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
  800x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
  880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  890x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76,
  900x54, 0x32, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab,
  920x89, 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0,
  930x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  940x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
  950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x05, 0x9e,
  960xd8, 0x36, 0x7c, 0xd5, 0x07, 0x30, 0x70, 0xdd, 0x17, 0xf7, 0x0e, 0x59, 0x39,
  970xff, 0xc0, 0x0b, 0x31, 0x68, 0x58, 0x15, 0x11, 0x64, 0xf9, 0x8f, 0xa7, 0xbe,
  980xfa, 0x4f, 0xa4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae,
 1000x85, 0x3c, 0x6e, 0xf3, 0x72, 0xa5, 0x4f, 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f,
 1010x9b, 0x05, 0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0, 0xcd, 0x19, 0x05,
 1020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1030x00, 0x00, 0xcb, 0xbb, 0x9d, 0x5d, 0xc1, 0x05, 0x9e, 0xd8, 0x62, 0x9a, 0x29,
 1040x2a, 0x36, 0x7c, 0xd5, 0x07, 0x91, 0x59, 0x01, 0x5a, 0x30, 0x70, 0xdd, 0x17,
 1050x15, 0x2f, 0xec, 0xd8, 0xf7, 0x0e, 0x59, 0x39, 0x67, 0x33, 0x26, 0x67, 0xff,
 1060xc0, 0x0b, 0x31, 0x8e, 0xb4, 0x4a, 0x87, 0x68, 0x58, 0x15, 0x11, 0xdb, 0x0c,
 1070x2e, 0x0d, 0x64, 0xf9, 0x8f, 0xa7, 0x47, 0xb5, 0x48, 0x1d, 0xbe, 0xfa, 0x4f,
 1080xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1090x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb,
 1100x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94,
 1110xf8, 0x2b, 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51, 0x0e, 0x52,
 1120x7f, 0xad, 0xe6, 0x82, 0xd1, 0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
 1130x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b, 0x5b, 0xe0, 0xcd, 0x19, 0x13,
 1140x7e, 0x21, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 1430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 144
 145struct adf_admin_comms {
 146        dma_addr_t phy_addr;
 147        dma_addr_t const_tbl_addr;
 148        void *virt_addr;
 149        void *virt_tbl_addr;
 150        void __iomem *mailbox_addr;
 151        struct mutex lock;      /* protects adf_admin_comms struct */
 152};
 153
 154static int adf_put_admin_msg_sync(struct adf_accel_dev *accel_dev, u32 ae,
 155                                  void *in, void *out)
 156{
 157        struct adf_admin_comms *admin = accel_dev->admin;
 158        int offset = ae * ADF_ADMINMSG_LEN * 2;
 159        void __iomem *mailbox = admin->mailbox_addr;
 160        int mb_offset = ae * ADF_DH895XCC_MAILBOX_STRIDE;
 161        int times, received;
 162
 163        mutex_lock(&admin->lock);
 164
 165        if (ADF_CSR_RD(mailbox, mb_offset) == 1) {
 166                mutex_unlock(&admin->lock);
 167                return -EAGAIN;
 168        }
 169
 170        memcpy(admin->virt_addr + offset, in, ADF_ADMINMSG_LEN);
 171        ADF_CSR_WR(mailbox, mb_offset, 1);
 172        received = 0;
 173        for (times = 0; times < 50; times++) {
 174                msleep(20);
 175                if (ADF_CSR_RD(mailbox, mb_offset) == 0) {
 176                        received = 1;
 177                        break;
 178                }
 179        }
 180        if (received)
 181                memcpy(out, admin->virt_addr + offset +
 182                       ADF_ADMINMSG_LEN, ADF_ADMINMSG_LEN);
 183        else
 184                dev_err(&GET_DEV(accel_dev),
 185                        "Failed to send admin msg to accelerator\n");
 186
 187        mutex_unlock(&admin->lock);
 188        return received ? 0 : -EFAULT;
 189}
 190
 191static int adf_send_admin_cmd(struct adf_accel_dev *accel_dev, int cmd)
 192{
 193        struct adf_hw_device_data *hw_device = accel_dev->hw_device;
 194        struct icp_qat_fw_init_admin_req req;
 195        struct icp_qat_fw_init_admin_resp resp;
 196        int i;
 197
 198        memset(&req, 0, sizeof(struct icp_qat_fw_init_admin_req));
 199        req.init_admin_cmd_id = cmd;
 200
 201        if (cmd == ICP_QAT_FW_CONSTANTS_CFG) {
 202                req.init_cfg_sz = 1024;
 203                req.init_cfg_ptr = accel_dev->admin->const_tbl_addr;
 204        }
 205        for (i = 0; i < hw_device->get_num_aes(hw_device); i++) {
 206                memset(&resp, 0, sizeof(struct icp_qat_fw_init_admin_resp));
 207                if (adf_put_admin_msg_sync(accel_dev, i, &req, &resp) ||
 208                    resp.init_resp_hdr.status)
 209                        return -EFAULT;
 210        }
 211        return 0;
 212}
 213
 214/**
 215 * adf_send_admin_init() - Function sends init message to FW
 216 * @accel_dev: Pointer to acceleration device.
 217 *
 218 * Function sends admin init message to the FW
 219 *
 220 * Return: 0 on success, error code otherwise.
 221 */
 222int adf_send_admin_init(struct adf_accel_dev *accel_dev)
 223{
 224        int ret = adf_send_admin_cmd(accel_dev, ICP_QAT_FW_INIT_ME);
 225
 226        if (ret)
 227                return ret;
 228        return adf_send_admin_cmd(accel_dev, ICP_QAT_FW_CONSTANTS_CFG);
 229}
 230EXPORT_SYMBOL_GPL(adf_send_admin_init);
 231
 232int adf_init_admin_comms(struct adf_accel_dev *accel_dev)
 233{
 234        struct adf_admin_comms *admin;
 235        struct adf_hw_device_data *hw_data = accel_dev->hw_device;
 236        struct adf_bar *pmisc =
 237                &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)];
 238        void __iomem *csr = pmisc->virt_addr;
 239        void __iomem *mailbox = (void __iomem *)((uintptr_t)csr +
 240                                 ADF_DH895XCC_MAILBOX_BASE_OFFSET);
 241        u64 reg_val;
 242
 243        admin = kzalloc_node(sizeof(*accel_dev->admin), GFP_KERNEL,
 244                             dev_to_node(&GET_DEV(accel_dev)));
 245        if (!admin)
 246                return -ENOMEM;
 247        admin->virt_addr = dma_alloc_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
 248                                              &admin->phy_addr, GFP_KERNEL);
 249        if (!admin->virt_addr) {
 250                dev_err(&GET_DEV(accel_dev), "Failed to allocate dma buff\n");
 251                kfree(admin);
 252                return -ENOMEM;
 253        }
 254
 255        admin->virt_tbl_addr = dma_alloc_coherent(&GET_DEV(accel_dev),
 256                                                  PAGE_SIZE,
 257                                                  &admin->const_tbl_addr,
 258                                                  GFP_KERNEL);
 259        if (!admin->virt_tbl_addr) {
 260                dev_err(&GET_DEV(accel_dev), "Failed to allocate const_tbl\n");
 261                dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
 262                                  admin->virt_addr, admin->phy_addr);
 263                kfree(admin);
 264                return -ENOMEM;
 265        }
 266
 267        memcpy(admin->virt_tbl_addr, const_tab, sizeof(const_tab));
 268        reg_val = (u64)admin->phy_addr;
 269        ADF_CSR_WR(csr, ADF_DH895XCC_ADMINMSGUR_OFFSET, reg_val >> 32);
 270        ADF_CSR_WR(csr, ADF_DH895XCC_ADMINMSGLR_OFFSET, reg_val);
 271        mutex_init(&admin->lock);
 272        admin->mailbox_addr = mailbox;
 273        accel_dev->admin = admin;
 274        return 0;
 275}
 276EXPORT_SYMBOL_GPL(adf_init_admin_comms);
 277
 278void adf_exit_admin_comms(struct adf_accel_dev *accel_dev)
 279{
 280        struct adf_admin_comms *admin = accel_dev->admin;
 281
 282        if (!admin)
 283                return;
 284
 285        if (admin->virt_addr)
 286                dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
 287                                  admin->virt_addr, admin->phy_addr);
 288        if (admin->virt_tbl_addr)
 289                dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
 290                                  admin->virt_tbl_addr, admin->const_tbl_addr);
 291
 292        mutex_destroy(&admin->lock);
 293        kfree(admin);
 294        accel_dev->admin = NULL;
 295}
 296EXPORT_SYMBOL_GPL(adf_exit_admin_comms);
 297