xref: /linux/drivers/s390/crypto/zcrypt_cex4.c (revision bfd5bb6f90af092aa345b15cd78143956a13c2a8)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  Copyright IBM Corp. 2012
4  *  Author(s): Holger Dengler <hd@linux.vnet.ibm.com>
5  */
6 
7 #include <linux/module.h>
8 #include <linux/slab.h>
9 #include <linux/init.h>
10 #include <linux/err.h>
11 #include <linux/atomic.h>
12 #include <linux/uaccess.h>
13 #include <linux/mod_devicetable.h>
14 
15 #include "ap_bus.h"
16 #include "zcrypt_api.h"
17 #include "zcrypt_msgtype6.h"
18 #include "zcrypt_msgtype50.h"
19 #include "zcrypt_error.h"
20 #include "zcrypt_cex4.h"
21 
22 #define CEX4A_MIN_MOD_SIZE	  1	/*    8 bits	*/
23 #define CEX4A_MAX_MOD_SIZE_2K	256	/* 2048 bits	*/
24 #define CEX4A_MAX_MOD_SIZE_4K	512	/* 4096 bits	*/
25 
26 #define CEX4C_MIN_MOD_SIZE	 16	/*  256 bits	*/
27 #define CEX4C_MAX_MOD_SIZE	512	/* 4096 bits	*/
28 
29 #define CEX4A_MAX_MESSAGE_SIZE	MSGTYPE50_CRB3_MAX_MSG_SIZE
30 #define CEX4C_MAX_MESSAGE_SIZE	MSGTYPE06_MAX_MSG_SIZE
31 
32 /* Waiting time for requests to be processed.
33  * Currently there are some types of request which are not deterministic.
34  * But the maximum time limit managed by the stomper code is set to 60sec.
35  * Hence we have to wait at least that time period.
36  */
37 #define CEX4_CLEANUP_TIME	(900*HZ)
38 
39 MODULE_AUTHOR("IBM Corporation");
40 MODULE_DESCRIPTION("CEX4 Cryptographic Card device driver, " \
41 		   "Copyright IBM Corp. 2012");
42 MODULE_LICENSE("GPL");
43 
44 static struct ap_device_id zcrypt_cex4_card_ids[] = {
45 	{ .dev_type = AP_DEVICE_TYPE_CEX4,
46 	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
47 	{ .dev_type = AP_DEVICE_TYPE_CEX5,
48 	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
49 	{ .dev_type = AP_DEVICE_TYPE_CEX6,
50 	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
51 	{ /* end of list */ },
52 };
53 
54 MODULE_DEVICE_TABLE(ap, zcrypt_cex4_card_ids);
55 
56 static struct ap_device_id zcrypt_cex4_queue_ids[] = {
57 	{ .dev_type = AP_DEVICE_TYPE_CEX4,
58 	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
59 	{ .dev_type = AP_DEVICE_TYPE_CEX5,
60 	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
61 	{ .dev_type = AP_DEVICE_TYPE_CEX6,
62 	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
63 	{ /* end of list */ },
64 };
65 
66 MODULE_DEVICE_TABLE(ap, zcrypt_cex4_queue_ids);
67 
68 /**
69  * Probe function for CEX4 card device. It always accepts the AP device
70  * since the bus_match already checked the hardware type.
71  * @ap_dev: pointer to the AP device.
72  */
73 static int zcrypt_cex4_card_probe(struct ap_device *ap_dev)
74 {
75 	/*
76 	 * Normalized speed ratings per crypto adapter
77 	 * MEX_1k, MEX_2k, MEX_4k, CRT_1k, CRT_2k, CRT_4k, RNG, SECKEY
78 	 */
79 	static const int CEX4A_SPEED_IDX[] = {
80 		 14, 19, 249, 42, 228, 1458, 0, 0};
81 	static const int CEX5A_SPEED_IDX[] = {
82 		  8,  9,  20, 18,  66,	458, 0, 0};
83 	static const int CEX6A_SPEED_IDX[] = {
84 		  6,  9,  20, 17,  65,	438, 0, 0};
85 
86 	static const int CEX4C_SPEED_IDX[] = {
87 		 59,  69, 308, 83, 278, 2204, 209, 40};
88 	static const int CEX5C_SPEED_IDX[] = {
89 		 24,  31,  50, 37,  90,  479,  27, 10};
90 	static const int CEX6C_SPEED_IDX[] = {
91 		 16,  20,  32, 27,  77,  455,  23,  9};
92 
93 	static const int CEX4P_SPEED_IDX[] = {
94 		224, 313, 3560, 359, 605, 2827, 0, 50};
95 	static const int CEX5P_SPEED_IDX[] = {
96 		 63,  84,  156,  83, 142,  533, 0, 10};
97 	static const int CEX6P_SPEED_IDX[] = {
98 		 55,  70,  121,  73, 129,  522, 0,  9};
99 
100 	struct ap_card *ac = to_ap_card(&ap_dev->device);
101 	struct zcrypt_card *zc;
102 	int rc = 0;
103 
104 	zc = zcrypt_card_alloc();
105 	if (!zc)
106 		return -ENOMEM;
107 	zc->card = ac;
108 	ac->private = zc;
109 	if (ap_test_bit(&ac->functions, AP_FUNC_ACCEL)) {
110 		if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
111 			zc->type_string = "CEX4A";
112 			zc->user_space_type = ZCRYPT_CEX4;
113 			memcpy(zc->speed_rating, CEX4A_SPEED_IDX,
114 			       sizeof(CEX4A_SPEED_IDX));
115 		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {
116 			zc->type_string = "CEX5A";
117 			zc->user_space_type = ZCRYPT_CEX5;
118 			memcpy(zc->speed_rating, CEX5A_SPEED_IDX,
119 			       sizeof(CEX5A_SPEED_IDX));
120 		} else {
121 			zc->type_string = "CEX6A";
122 			zc->user_space_type = ZCRYPT_CEX6;
123 			memcpy(zc->speed_rating, CEX6A_SPEED_IDX,
124 			       sizeof(CEX6A_SPEED_IDX));
125 		}
126 		zc->min_mod_size = CEX4A_MIN_MOD_SIZE;
127 		if (ap_test_bit(&ac->functions, AP_FUNC_MEX4K) &&
128 		    ap_test_bit(&ac->functions, AP_FUNC_CRT4K)) {
129 			zc->max_mod_size = CEX4A_MAX_MOD_SIZE_4K;
130 			zc->max_exp_bit_length =
131 				CEX4A_MAX_MOD_SIZE_4K;
132 		} else {
133 			zc->max_mod_size = CEX4A_MAX_MOD_SIZE_2K;
134 			zc->max_exp_bit_length =
135 				CEX4A_MAX_MOD_SIZE_2K;
136 		}
137 	} else if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) {
138 		if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
139 			zc->type_string = "CEX4C";
140 			/* wrong user space type, must be CEX4
141 			 * just keep it for cca compatibility
142 			 */
143 			zc->user_space_type = ZCRYPT_CEX3C;
144 			memcpy(zc->speed_rating, CEX4C_SPEED_IDX,
145 			       sizeof(CEX4C_SPEED_IDX));
146 		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {
147 			zc->type_string = "CEX5C";
148 			/* wrong user space type, must be CEX5
149 			 * just keep it for cca compatibility
150 			 */
151 			zc->user_space_type = ZCRYPT_CEX3C;
152 			memcpy(zc->speed_rating, CEX5C_SPEED_IDX,
153 			       sizeof(CEX5C_SPEED_IDX));
154 		} else {
155 			zc->type_string = "CEX6C";
156 			/* wrong user space type, must be CEX6
157 			 * just keep it for cca compatibility
158 			 */
159 			zc->user_space_type = ZCRYPT_CEX3C;
160 			memcpy(zc->speed_rating, CEX6C_SPEED_IDX,
161 			       sizeof(CEX6C_SPEED_IDX));
162 		}
163 		zc->min_mod_size = CEX4C_MIN_MOD_SIZE;
164 		zc->max_mod_size = CEX4C_MAX_MOD_SIZE;
165 		zc->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;
166 	} else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) {
167 		if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
168 			zc->type_string = "CEX4P";
169 			zc->user_space_type = ZCRYPT_CEX4;
170 			memcpy(zc->speed_rating, CEX4P_SPEED_IDX,
171 			       sizeof(CEX4P_SPEED_IDX));
172 		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {
173 			zc->type_string = "CEX5P";
174 			zc->user_space_type = ZCRYPT_CEX5;
175 			memcpy(zc->speed_rating, CEX5P_SPEED_IDX,
176 			       sizeof(CEX5P_SPEED_IDX));
177 		} else {
178 			zc->type_string = "CEX6P";
179 			zc->user_space_type = ZCRYPT_CEX6;
180 			memcpy(zc->speed_rating, CEX6P_SPEED_IDX,
181 			       sizeof(CEX6P_SPEED_IDX));
182 		}
183 		zc->min_mod_size = CEX4C_MIN_MOD_SIZE;
184 		zc->max_mod_size = CEX4C_MAX_MOD_SIZE;
185 		zc->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;
186 	} else {
187 		zcrypt_card_free(zc);
188 		return -ENODEV;
189 	}
190 	zc->online = 1;
191 
192 	rc = zcrypt_card_register(zc);
193 	if (rc) {
194 		ac->private = NULL;
195 		zcrypt_card_free(zc);
196 	}
197 
198 	return rc;
199 }
200 
201 /**
202  * This is called to remove the CEX4 card driver information
203  * if an AP card device is removed.
204  */
205 static void zcrypt_cex4_card_remove(struct ap_device *ap_dev)
206 {
207 	struct zcrypt_card *zc = to_ap_card(&ap_dev->device)->private;
208 
209 	if (zc)
210 		zcrypt_card_unregister(zc);
211 }
212 
213 static struct ap_driver zcrypt_cex4_card_driver = {
214 	.probe = zcrypt_cex4_card_probe,
215 	.remove = zcrypt_cex4_card_remove,
216 	.ids = zcrypt_cex4_card_ids,
217 };
218 
219 /**
220  * Probe function for CEX4 queue device. It always accepts the AP device
221  * since the bus_match already checked the hardware type.
222  * @ap_dev: pointer to the AP device.
223  */
224 static int zcrypt_cex4_queue_probe(struct ap_device *ap_dev)
225 {
226 	struct ap_queue *aq = to_ap_queue(&ap_dev->device);
227 	struct zcrypt_queue *zq;
228 	int rc;
229 
230 	if (ap_test_bit(&aq->card->functions, AP_FUNC_ACCEL)) {
231 		zq = zcrypt_queue_alloc(CEX4A_MAX_MESSAGE_SIZE);
232 		if (!zq)
233 			return -ENOMEM;
234 		zq->ops = zcrypt_msgtype(MSGTYPE50_NAME,
235 					 MSGTYPE50_VARIANT_DEFAULT);
236 	} else if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) {
237 		zq = zcrypt_queue_alloc(CEX4C_MAX_MESSAGE_SIZE);
238 		if (!zq)
239 			return -ENOMEM;
240 		zq->ops = zcrypt_msgtype(MSGTYPE06_NAME,
241 					 MSGTYPE06_VARIANT_DEFAULT);
242 	} else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) {
243 		zq = zcrypt_queue_alloc(CEX4C_MAX_MESSAGE_SIZE);
244 		if (!zq)
245 			return -ENOMEM;
246 		zq->ops = zcrypt_msgtype(MSGTYPE06_NAME,
247 					 MSGTYPE06_VARIANT_EP11);
248 	} else {
249 		return -ENODEV;
250 	}
251 	zq->queue = aq;
252 	zq->online = 1;
253 	atomic_set(&zq->load, 0);
254 	ap_queue_init_reply(aq, &zq->reply);
255 	aq->request_timeout = CEX4_CLEANUP_TIME,
256 	aq->private = zq;
257 	rc = zcrypt_queue_register(zq);
258 	if (rc) {
259 		aq->private = NULL;
260 		zcrypt_queue_free(zq);
261 	}
262 
263 	return rc;
264 }
265 
266 /**
267  * This is called to remove the CEX4 queue driver information
268  * if an AP queue device is removed.
269  */
270 static void zcrypt_cex4_queue_remove(struct ap_device *ap_dev)
271 {
272 	struct ap_queue *aq = to_ap_queue(&ap_dev->device);
273 	struct zcrypt_queue *zq = aq->private;
274 
275 	ap_queue_remove(aq);
276 	if (zq)
277 		zcrypt_queue_unregister(zq);
278 }
279 
280 static struct ap_driver zcrypt_cex4_queue_driver = {
281 	.probe = zcrypt_cex4_queue_probe,
282 	.remove = zcrypt_cex4_queue_remove,
283 	.suspend = ap_queue_suspend,
284 	.resume = ap_queue_resume,
285 	.ids = zcrypt_cex4_queue_ids,
286 };
287 
288 int __init zcrypt_cex4_init(void)
289 {
290 	int rc;
291 
292 	rc = ap_driver_register(&zcrypt_cex4_card_driver,
293 				THIS_MODULE, "cex4card");
294 	if (rc)
295 		return rc;
296 
297 	rc = ap_driver_register(&zcrypt_cex4_queue_driver,
298 				THIS_MODULE, "cex4queue");
299 	if (rc)
300 		ap_driver_unregister(&zcrypt_cex4_card_driver);
301 
302 	return rc;
303 }
304 
305 void __exit zcrypt_cex4_exit(void)
306 {
307 	ap_driver_unregister(&zcrypt_cex4_queue_driver);
308 	ap_driver_unregister(&zcrypt_cex4_card_driver);
309 }
310 
311 module_init(zcrypt_cex4_init);
312 module_exit(zcrypt_cex4_exit);
313