| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * AMD Cryptographic Coprocessor (CCP) driver |
|---|
| 3 | 4 | * |
|---|
| 4 | | - * Copyright (C) 2016,2017 Advanced Micro Devices, Inc. |
|---|
| 5 | + * Copyright (C) 2016,2019 Advanced Micro Devices, Inc. |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Author: Gary R Hook <gary.hook@amd.com> |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 10 | | - * published by the Free Software Foundation. |
|---|
| 11 | 8 | */ |
|---|
| 12 | 9 | |
|---|
| 13 | | -#include <linux/module.h> |
|---|
| 14 | 10 | #include <linux/kernel.h> |
|---|
| 15 | | -#include <linux/pci.h> |
|---|
| 16 | 11 | #include <linux/kthread.h> |
|---|
| 17 | | -#include <linux/debugfs.h> |
|---|
| 18 | 12 | #include <linux/dma-mapping.h> |
|---|
| 19 | 13 | #include <linux/interrupt.h> |
|---|
| 20 | 14 | #include <linux/compiler.h> |
|---|
| .. | .. |
|---|
| 227 | 221 | static int ccp5_do_cmd(struct ccp5_desc *desc, |
|---|
| 228 | 222 | struct ccp_cmd_queue *cmd_q) |
|---|
| 229 | 223 | { |
|---|
| 230 | | - u32 *mP; |
|---|
| 231 | | - __le32 *dP; |
|---|
| 224 | + __le32 *mP; |
|---|
| 225 | + u32 *dP; |
|---|
| 232 | 226 | u32 tail; |
|---|
| 233 | 227 | int i; |
|---|
| 234 | 228 | int ret = 0; |
|---|
| .. | .. |
|---|
| 241 | 235 | } |
|---|
| 242 | 236 | mutex_lock(&cmd_q->q_mutex); |
|---|
| 243 | 237 | |
|---|
| 244 | | - mP = (u32 *) &cmd_q->qbase[cmd_q->qidx]; |
|---|
| 245 | | - dP = (__le32 *) desc; |
|---|
| 238 | + mP = (__le32 *)&cmd_q->qbase[cmd_q->qidx]; |
|---|
| 239 | + dP = (u32 *)desc; |
|---|
| 246 | 240 | for (i = 0; i < 8; i++) |
|---|
| 247 | 241 | mP[i] = cpu_to_le32(dP[i]); /* handle endianness */ |
|---|
| 248 | 242 | |
|---|
| .. | .. |
|---|
| 795 | 789 | |
|---|
| 796 | 790 | /* Find available queues */ |
|---|
| 797 | 791 | qmr = ioread32(ccp->io_regs + Q_MASK_REG); |
|---|
| 798 | | - for (i = 0; i < MAX_HW_QUEUES; i++) { |
|---|
| 792 | + /* |
|---|
| 793 | + * Check for a access to the registers. If this read returns |
|---|
| 794 | + * 0xffffffff, it's likely that the system is running a broken |
|---|
| 795 | + * BIOS which disallows access to the device. Stop here and fail |
|---|
| 796 | + * the initialization (but not the load, as the PSP could get |
|---|
| 797 | + * properly initialized). |
|---|
| 798 | + */ |
|---|
| 799 | + if (qmr == 0xffffffff) { |
|---|
| 800 | + dev_notice(dev, "ccp: unable to access the device: you might be running a broken BIOS.\n"); |
|---|
| 801 | + return 1; |
|---|
| 802 | + } |
|---|
| 799 | 803 | |
|---|
| 804 | + for (i = 0; (i < MAX_HW_QUEUES) && (ccp->cmd_q_count < ccp->max_q_count); i++) { |
|---|
| 800 | 805 | if (!(qmr & (1 << i))) |
|---|
| 801 | 806 | continue; |
|---|
| 802 | 807 | |
|---|
| .. | .. |
|---|
| 809 | 814 | if (!dma_pool) { |
|---|
| 810 | 815 | dev_err(dev, "unable to allocate dma pool\n"); |
|---|
| 811 | 816 | ret = -ENOMEM; |
|---|
| 817 | + goto e_pool; |
|---|
| 812 | 818 | } |
|---|
| 813 | 819 | |
|---|
| 814 | 820 | cmd_q = &ccp->cmd_q[ccp->cmd_q_count]; |
|---|
| .. | .. |
|---|
| 822 | 828 | /* Page alignment satisfies our needs for N <= 128 */ |
|---|
| 823 | 829 | BUILD_BUG_ON(COMMANDS_PER_QUEUE > 128); |
|---|
| 824 | 830 | cmd_q->qsize = Q_SIZE(Q_DESC_SIZE); |
|---|
| 825 | | - cmd_q->qbase = dma_zalloc_coherent(dev, cmd_q->qsize, |
|---|
| 831 | + cmd_q->qbase = dmam_alloc_coherent(dev, cmd_q->qsize, |
|---|
| 826 | 832 | &cmd_q->qbase_dma, |
|---|
| 827 | 833 | GFP_KERNEL); |
|---|
| 828 | 834 | if (!cmd_q->qbase) { |
|---|
| .. | .. |
|---|
| 860 | 866 | |
|---|
| 861 | 867 | if (ccp->cmd_q_count == 0) { |
|---|
| 862 | 868 | dev_notice(dev, "no command queues available\n"); |
|---|
| 863 | | - ret = -EIO; |
|---|
| 869 | + ret = 1; |
|---|
| 864 | 870 | goto e_pool; |
|---|
| 865 | 871 | } |
|---|
| 866 | 872 | |
|---|
| .. | .. |
|---|
| 973 | 979 | if (ret) |
|---|
| 974 | 980 | goto e_hwrng; |
|---|
| 975 | 981 | |
|---|
| 982 | +#ifdef CONFIG_CRYPTO_DEV_CCP_DEBUGFS |
|---|
| 976 | 983 | /* Set up debugfs entries */ |
|---|
| 977 | 984 | ccp5_debugfs_setup(ccp); |
|---|
| 985 | +#endif |
|---|
| 978 | 986 | |
|---|
| 979 | 987 | return 0; |
|---|
| 980 | 988 | |
|---|
| .. | .. |
|---|
| 998 | 1006 | |
|---|
| 999 | 1007 | static void ccp5_destroy(struct ccp_device *ccp) |
|---|
| 1000 | 1008 | { |
|---|
| 1001 | | - struct device *dev = ccp->dev; |
|---|
| 1002 | 1009 | struct ccp_cmd_queue *cmd_q; |
|---|
| 1003 | 1010 | struct ccp_cmd *cmd; |
|---|
| 1004 | 1011 | unsigned int i; |
|---|
| .. | .. |
|---|
| 1012 | 1019 | /* Remove this device from the list of available units first */ |
|---|
| 1013 | 1020 | ccp_del_device(ccp); |
|---|
| 1014 | 1021 | |
|---|
| 1022 | +#ifdef CONFIG_CRYPTO_DEV_CCP_DEBUGFS |
|---|
| 1015 | 1023 | /* We're in the process of tearing down the entire driver; |
|---|
| 1016 | 1024 | * when all the devices are gone clean up debugfs |
|---|
| 1017 | 1025 | */ |
|---|
| 1018 | 1026 | if (ccp_present()) |
|---|
| 1019 | 1027 | ccp5_debugfs_destroy(); |
|---|
| 1028 | +#endif |
|---|
| 1020 | 1029 | |
|---|
| 1021 | 1030 | /* Disable and clear interrupts */ |
|---|
| 1022 | 1031 | ccp5_disable_queue_interrupts(ccp); |
|---|
| .. | .. |
|---|
| 1038 | 1047 | kthread_stop(ccp->cmd_q[i].kthread); |
|---|
| 1039 | 1048 | |
|---|
| 1040 | 1049 | sp_free_ccp_irq(ccp->sp, ccp); |
|---|
| 1041 | | - |
|---|
| 1042 | | - for (i = 0; i < ccp->cmd_q_count; i++) { |
|---|
| 1043 | | - cmd_q = &ccp->cmd_q[i]; |
|---|
| 1044 | | - dma_free_coherent(dev, cmd_q->qsize, cmd_q->qbase, |
|---|
| 1045 | | - cmd_q->qbase_dma); |
|---|
| 1046 | | - } |
|---|
| 1047 | 1050 | |
|---|
| 1048 | 1051 | /* Flush the cmd and backlog queue */ |
|---|
| 1049 | 1052 | while (!list_empty(&ccp->cmd)) { |
|---|