xref: /openbmc/linux/drivers/crypto/ccp/ccp-dev.h (revision 63b945091a070d8d4275dc0f7699ba22cd5f9435)
1*63b94509STom Lendacky /*
2*63b94509STom Lendacky  * AMD Cryptographic Coprocessor (CCP) driver
3*63b94509STom Lendacky  *
4*63b94509STom Lendacky  * Copyright (C) 2013 Advanced Micro Devices, Inc.
5*63b94509STom Lendacky  *
6*63b94509STom Lendacky  * Author: Tom Lendacky <thomas.lendacky@amd.com>
7*63b94509STom Lendacky  *
8*63b94509STom Lendacky  * This program is free software; you can redistribute it and/or modify
9*63b94509STom Lendacky  * it under the terms of the GNU General Public License version 2 as
10*63b94509STom Lendacky  * published by the Free Software Foundation.
11*63b94509STom Lendacky  */
12*63b94509STom Lendacky 
13*63b94509STom Lendacky #ifndef __CCP_DEV_H__
14*63b94509STom Lendacky #define __CCP_DEV_H__
15*63b94509STom Lendacky 
16*63b94509STom Lendacky #include <linux/device.h>
17*63b94509STom Lendacky #include <linux/pci.h>
18*63b94509STom Lendacky #include <linux/spinlock.h>
19*63b94509STom Lendacky #include <linux/mutex.h>
20*63b94509STom Lendacky #include <linux/list.h>
21*63b94509STom Lendacky #include <linux/wait.h>
22*63b94509STom Lendacky #include <linux/dmapool.h>
23*63b94509STom Lendacky #include <linux/hw_random.h>
24*63b94509STom Lendacky 
25*63b94509STom Lendacky 
26*63b94509STom Lendacky #define IO_OFFSET			0x20000
27*63b94509STom Lendacky 
28*63b94509STom Lendacky #define MAX_DMAPOOL_NAME_LEN		32
29*63b94509STom Lendacky 
30*63b94509STom Lendacky #define MAX_HW_QUEUES			5
31*63b94509STom Lendacky #define MAX_CMD_QLEN			100
32*63b94509STom Lendacky 
33*63b94509STom Lendacky #define TRNG_RETRIES			10
34*63b94509STom Lendacky 
35*63b94509STom Lendacky 
36*63b94509STom Lendacky /****** Register Mappings ******/
37*63b94509STom Lendacky #define Q_MASK_REG			0x000
38*63b94509STom Lendacky #define TRNG_OUT_REG			0x00c
39*63b94509STom Lendacky #define IRQ_MASK_REG			0x040
40*63b94509STom Lendacky #define IRQ_STATUS_REG			0x200
41*63b94509STom Lendacky 
42*63b94509STom Lendacky #define DEL_CMD_Q_JOB			0x124
43*63b94509STom Lendacky #define DEL_Q_ACTIVE			0x00000200
44*63b94509STom Lendacky #define DEL_Q_ID_SHIFT			6
45*63b94509STom Lendacky 
46*63b94509STom Lendacky #define CMD_REQ0			0x180
47*63b94509STom Lendacky #define CMD_REQ_INCR			0x04
48*63b94509STom Lendacky 
49*63b94509STom Lendacky #define CMD_Q_STATUS_BASE		0x210
50*63b94509STom Lendacky #define CMD_Q_INT_STATUS_BASE		0x214
51*63b94509STom Lendacky #define CMD_Q_STATUS_INCR		0x20
52*63b94509STom Lendacky 
53*63b94509STom Lendacky #define CMD_Q_CACHE			0x228
54*63b94509STom Lendacky #define CMD_Q_CACHE_INC			0x20
55*63b94509STom Lendacky 
56*63b94509STom Lendacky #define CMD_Q_ERROR(__qs)		((__qs) & 0x0000003f);
57*63b94509STom Lendacky #define CMD_Q_DEPTH(__qs)		(((__qs) >> 12) & 0x0000000f);
58*63b94509STom Lendacky 
59*63b94509STom Lendacky /****** REQ0 Related Values ******/
60*63b94509STom Lendacky #define REQ0_WAIT_FOR_WRITE		0x00000004
61*63b94509STom Lendacky #define REQ0_INT_ON_COMPLETE		0x00000002
62*63b94509STom Lendacky #define REQ0_STOP_ON_COMPLETE		0x00000001
63*63b94509STom Lendacky 
64*63b94509STom Lendacky #define REQ0_CMD_Q_SHIFT		9
65*63b94509STom Lendacky #define REQ0_JOBID_SHIFT		3
66*63b94509STom Lendacky 
67*63b94509STom Lendacky /****** REQ1 Related Values ******/
68*63b94509STom Lendacky #define REQ1_PROTECT_SHIFT		27
69*63b94509STom Lendacky #define REQ1_ENGINE_SHIFT		23
70*63b94509STom Lendacky #define REQ1_KEY_KSB_SHIFT		2
71*63b94509STom Lendacky 
72*63b94509STom Lendacky #define REQ1_EOM			0x00000002
73*63b94509STom Lendacky #define REQ1_INIT			0x00000001
74*63b94509STom Lendacky 
75*63b94509STom Lendacky /* AES Related Values */
76*63b94509STom Lendacky #define REQ1_AES_TYPE_SHIFT		21
77*63b94509STom Lendacky #define REQ1_AES_MODE_SHIFT		18
78*63b94509STom Lendacky #define REQ1_AES_ACTION_SHIFT		17
79*63b94509STom Lendacky #define REQ1_AES_CFB_SIZE_SHIFT		10
80*63b94509STom Lendacky 
81*63b94509STom Lendacky /* XTS-AES Related Values */
82*63b94509STom Lendacky #define REQ1_XTS_AES_SIZE_SHIFT		10
83*63b94509STom Lendacky 
84*63b94509STom Lendacky /* SHA Related Values */
85*63b94509STom Lendacky #define REQ1_SHA_TYPE_SHIFT		21
86*63b94509STom Lendacky 
87*63b94509STom Lendacky /* RSA Related Values */
88*63b94509STom Lendacky #define REQ1_RSA_MOD_SIZE_SHIFT		10
89*63b94509STom Lendacky 
90*63b94509STom Lendacky /* Pass-Through Related Values */
91*63b94509STom Lendacky #define REQ1_PT_BW_SHIFT		12
92*63b94509STom Lendacky #define REQ1_PT_BS_SHIFT		10
93*63b94509STom Lendacky 
94*63b94509STom Lendacky /* ECC Related Values */
95*63b94509STom Lendacky #define REQ1_ECC_AFFINE_CONVERT		0x00200000
96*63b94509STom Lendacky #define REQ1_ECC_FUNCTION_SHIFT		18
97*63b94509STom Lendacky 
98*63b94509STom Lendacky /****** REQ4 Related Values ******/
99*63b94509STom Lendacky #define REQ4_KSB_SHIFT			18
100*63b94509STom Lendacky #define REQ4_MEMTYPE_SHIFT		16
101*63b94509STom Lendacky 
102*63b94509STom Lendacky /****** REQ6 Related Values ******/
103*63b94509STom Lendacky #define REQ6_MEMTYPE_SHIFT		16
104*63b94509STom Lendacky 
105*63b94509STom Lendacky 
106*63b94509STom Lendacky /****** Key Storage Block ******/
107*63b94509STom Lendacky #define KSB_START			77
108*63b94509STom Lendacky #define KSB_END				127
109*63b94509STom Lendacky #define KSB_COUNT			(KSB_END - KSB_START + 1)
110*63b94509STom Lendacky #define CCP_KSB_BITS			256
111*63b94509STom Lendacky #define CCP_KSB_BYTES			32
112*63b94509STom Lendacky 
113*63b94509STom Lendacky #define CCP_JOBID_MASK			0x0000003f
114*63b94509STom Lendacky 
115*63b94509STom Lendacky #define CCP_DMAPOOL_MAX_SIZE		64
116*63b94509STom Lendacky #define CCP_DMAPOOL_ALIGN		(1 << 5)
117*63b94509STom Lendacky 
118*63b94509STom Lendacky #define CCP_REVERSE_BUF_SIZE		64
119*63b94509STom Lendacky 
120*63b94509STom Lendacky #define CCP_AES_KEY_KSB_COUNT		1
121*63b94509STom Lendacky #define CCP_AES_CTX_KSB_COUNT		1
122*63b94509STom Lendacky 
123*63b94509STom Lendacky #define CCP_XTS_AES_KEY_KSB_COUNT	1
124*63b94509STom Lendacky #define CCP_XTS_AES_CTX_KSB_COUNT	1
125*63b94509STom Lendacky 
126*63b94509STom Lendacky #define CCP_SHA_KSB_COUNT		1
127*63b94509STom Lendacky 
128*63b94509STom Lendacky #define CCP_RSA_MAX_WIDTH		4096
129*63b94509STom Lendacky 
130*63b94509STom Lendacky #define CCP_PASSTHRU_BLOCKSIZE		256
131*63b94509STom Lendacky #define CCP_PASSTHRU_MASKSIZE		32
132*63b94509STom Lendacky #define CCP_PASSTHRU_KSB_COUNT		1
133*63b94509STom Lendacky 
134*63b94509STom Lendacky #define CCP_ECC_MODULUS_BYTES		48      /* 384-bits */
135*63b94509STom Lendacky #define CCP_ECC_MAX_OPERANDS		6
136*63b94509STom Lendacky #define CCP_ECC_MAX_OUTPUTS		3
137*63b94509STom Lendacky #define CCP_ECC_SRC_BUF_SIZE		448
138*63b94509STom Lendacky #define CCP_ECC_DST_BUF_SIZE		192
139*63b94509STom Lendacky #define CCP_ECC_OPERAND_SIZE		64
140*63b94509STom Lendacky #define CCP_ECC_OUTPUT_SIZE		64
141*63b94509STom Lendacky #define CCP_ECC_RESULT_OFFSET		60
142*63b94509STom Lendacky #define CCP_ECC_RESULT_SUCCESS		0x0001
143*63b94509STom Lendacky 
144*63b94509STom Lendacky 
145*63b94509STom Lendacky struct ccp_device;
146*63b94509STom Lendacky struct ccp_cmd;
147*63b94509STom Lendacky 
148*63b94509STom Lendacky struct ccp_cmd_queue {
149*63b94509STom Lendacky 	struct ccp_device *ccp;
150*63b94509STom Lendacky 
151*63b94509STom Lendacky 	/* Queue identifier */
152*63b94509STom Lendacky 	u32 id;
153*63b94509STom Lendacky 
154*63b94509STom Lendacky 	/* Queue dma pool */
155*63b94509STom Lendacky 	struct dma_pool *dma_pool;
156*63b94509STom Lendacky 
157*63b94509STom Lendacky 	/* Queue reserved KSB regions */
158*63b94509STom Lendacky 	u32 ksb_key;
159*63b94509STom Lendacky 	u32 ksb_ctx;
160*63b94509STom Lendacky 
161*63b94509STom Lendacky 	/* Queue processing thread */
162*63b94509STom Lendacky 	struct task_struct *kthread;
163*63b94509STom Lendacky 	unsigned int active;
164*63b94509STom Lendacky 	unsigned int suspended;
165*63b94509STom Lendacky 
166*63b94509STom Lendacky 	/* Number of free command slots available */
167*63b94509STom Lendacky 	unsigned int free_slots;
168*63b94509STom Lendacky 
169*63b94509STom Lendacky 	/* Interrupt masks */
170*63b94509STom Lendacky 	u32 int_ok;
171*63b94509STom Lendacky 	u32 int_err;
172*63b94509STom Lendacky 
173*63b94509STom Lendacky 	/* Register addresses for queue */
174*63b94509STom Lendacky 	void __iomem *reg_status;
175*63b94509STom Lendacky 	void __iomem *reg_int_status;
176*63b94509STom Lendacky 
177*63b94509STom Lendacky 	/* Status values from job */
178*63b94509STom Lendacky 	u32 int_status;
179*63b94509STom Lendacky 	u32 q_status;
180*63b94509STom Lendacky 	u32 q_int_status;
181*63b94509STom Lendacky 	u32 cmd_error;
182*63b94509STom Lendacky 
183*63b94509STom Lendacky 	/* Interrupt wait queue */
184*63b94509STom Lendacky 	wait_queue_head_t int_queue;
185*63b94509STom Lendacky 	unsigned int int_rcvd;
186*63b94509STom Lendacky } ____cacheline_aligned;
187*63b94509STom Lendacky 
188*63b94509STom Lendacky struct ccp_device {
189*63b94509STom Lendacky 	struct device *dev;
190*63b94509STom Lendacky 
191*63b94509STom Lendacky 	/*
192*63b94509STom Lendacky 	 * Bus specific device information
193*63b94509STom Lendacky 	 */
194*63b94509STom Lendacky 	void *dev_specific;
195*63b94509STom Lendacky 	int (*get_irq)(struct ccp_device *ccp);
196*63b94509STom Lendacky 	void (*free_irq)(struct ccp_device *ccp);
197*63b94509STom Lendacky 
198*63b94509STom Lendacky 	/*
199*63b94509STom Lendacky 	 * I/O area used for device communication. The register mapping
200*63b94509STom Lendacky 	 * starts at an offset into the mapped bar.
201*63b94509STom Lendacky 	 *   The CMD_REQx registers and the Delete_Cmd_Queue_Job register
202*63b94509STom Lendacky 	 *   need to be protected while a command queue thread is accessing
203*63b94509STom Lendacky 	 *   them.
204*63b94509STom Lendacky 	 */
205*63b94509STom Lendacky 	struct mutex req_mutex ____cacheline_aligned;
206*63b94509STom Lendacky 	void __iomem *io_map;
207*63b94509STom Lendacky 	void __iomem *io_regs;
208*63b94509STom Lendacky 
209*63b94509STom Lendacky 	/*
210*63b94509STom Lendacky 	 * Master lists that all cmds are queued on. Because there can be
211*63b94509STom Lendacky 	 * more than one CCP command queue that can process a cmd a separate
212*63b94509STom Lendacky 	 * backlog list is neeeded so that the backlog completion call
213*63b94509STom Lendacky 	 * completes before the cmd is available for execution.
214*63b94509STom Lendacky 	 */
215*63b94509STom Lendacky 	spinlock_t cmd_lock ____cacheline_aligned;
216*63b94509STom Lendacky 	unsigned int cmd_count;
217*63b94509STom Lendacky 	struct list_head cmd;
218*63b94509STom Lendacky 	struct list_head backlog;
219*63b94509STom Lendacky 
220*63b94509STom Lendacky 	/*
221*63b94509STom Lendacky 	 * The command queues. These represent the queues available on the
222*63b94509STom Lendacky 	 * CCP that are available for processing cmds
223*63b94509STom Lendacky 	 */
224*63b94509STom Lendacky 	struct ccp_cmd_queue cmd_q[MAX_HW_QUEUES];
225*63b94509STom Lendacky 	unsigned int cmd_q_count;
226*63b94509STom Lendacky 
227*63b94509STom Lendacky 	/*
228*63b94509STom Lendacky 	 * Support for the CCP True RNG
229*63b94509STom Lendacky 	 */
230*63b94509STom Lendacky 	struct hwrng hwrng;
231*63b94509STom Lendacky 	unsigned int hwrng_retries;
232*63b94509STom Lendacky 
233*63b94509STom Lendacky 	/*
234*63b94509STom Lendacky 	 * A counter used to generate job-ids for cmds submitted to the CCP
235*63b94509STom Lendacky 	 */
236*63b94509STom Lendacky 	atomic_t current_id ____cacheline_aligned;
237*63b94509STom Lendacky 
238*63b94509STom Lendacky 	/*
239*63b94509STom Lendacky 	 * The CCP uses key storage blocks (KSB) to maintain context for certain
240*63b94509STom Lendacky 	 * operations. To prevent multiple cmds from using the same KSB range
241*63b94509STom Lendacky 	 * a command queue reserves a KSB range for the duration of the cmd.
242*63b94509STom Lendacky 	 * Each queue, will however, reserve 2 KSB blocks for operations that
243*63b94509STom Lendacky 	 * only require single KSB entries (eg. AES context/iv and key) in order
244*63b94509STom Lendacky 	 * to avoid allocation contention.  This will reserve at most 10 KSB
245*63b94509STom Lendacky 	 * entries, leaving 40 KSB entries available for dynamic allocation.
246*63b94509STom Lendacky 	 */
247*63b94509STom Lendacky 	struct mutex ksb_mutex ____cacheline_aligned;
248*63b94509STom Lendacky 	DECLARE_BITMAP(ksb, KSB_COUNT);
249*63b94509STom Lendacky 	wait_queue_head_t ksb_queue;
250*63b94509STom Lendacky 	unsigned int ksb_avail;
251*63b94509STom Lendacky 	unsigned int ksb_count;
252*63b94509STom Lendacky 	u32 ksb_start;
253*63b94509STom Lendacky 
254*63b94509STom Lendacky 	/* Suspend support */
255*63b94509STom Lendacky 	unsigned int suspending;
256*63b94509STom Lendacky 	wait_queue_head_t suspend_queue;
257*63b94509STom Lendacky };
258*63b94509STom Lendacky 
259*63b94509STom Lendacky 
260*63b94509STom Lendacky int ccp_pci_init(void);
261*63b94509STom Lendacky void ccp_pci_exit(void);
262*63b94509STom Lendacky 
263*63b94509STom Lendacky struct ccp_device *ccp_alloc_struct(struct device *dev);
264*63b94509STom Lendacky int ccp_init(struct ccp_device *ccp);
265*63b94509STom Lendacky void ccp_destroy(struct ccp_device *ccp);
266*63b94509STom Lendacky bool ccp_queues_suspended(struct ccp_device *ccp);
267*63b94509STom Lendacky 
268*63b94509STom Lendacky irqreturn_t ccp_irq_handler(int irq, void *data);
269*63b94509STom Lendacky 
270*63b94509STom Lendacky int ccp_run_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd);
271*63b94509STom Lendacky 
272*63b94509STom Lendacky #endif
273