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