blob: b97c5d5ee5a4aba9e70f88f791b674046092a6f7 [file] [log] [blame]
Martin Schwidefsky963ed932006-09-20 15:58:29 +02001/*
Ralph Wuerthner54321142006-09-20 15:58:36 +02002 * zcrypt 2.1.0
Martin Schwidefsky963ed932006-09-20 15:58:29 +02003 *
Holger Dengler5e55a482012-08-28 16:45:36 +02004 * Copyright IBM Corp. 2001, 2012
Martin Schwidefsky963ed932006-09-20 15:58:29 +02005 * Author(s): Robert Burroughs
6 * Eric Rossman (edrossma@us.ibm.com)
7 *
8 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
9 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
10 * Ralph Wuerthner <rwuerthn@de.ibm.com>
Holger Dengler5e55a482012-08-28 16:45:36 +020011 * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com>
Martin Schwidefsky963ed932006-09-20 15:58:29 +020012 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#include <linux/module.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090029#include <linux/slab.h>
Martin Schwidefsky963ed932006-09-20 15:58:29 +020030#include <linux/init.h>
31#include <linux/err.h>
Arun Sharma600634972011-07-26 16:09:06 -070032#include <linux/atomic.h>
Linus Torvalds7c0f6ba2016-12-24 11:46:01 -080033#include <linux/uaccess.h>
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +020034#include <linux/mod_devicetable.h>
Martin Schwidefsky963ed932006-09-20 15:58:29 +020035
36#include "ap_bus.h"
37#include "zcrypt_api.h"
38#include "zcrypt_error.h"
39#include "zcrypt_cex2a.h"
Holger Dengler5e55a482012-08-28 16:45:36 +020040#include "zcrypt_msgtype50.h"
Martin Schwidefsky963ed932006-09-20 15:58:29 +020041
42#define CEX2A_MIN_MOD_SIZE 1 /* 8 bits */
43#define CEX2A_MAX_MOD_SIZE 256 /* 2048 bits */
Felix Beck8e89b6b2009-12-07 12:51:57 +010044#define CEX3A_MIN_MOD_SIZE CEX2A_MIN_MOD_SIZE
Felix Beck3e309a62011-01-05 12:47:45 +010045#define CEX3A_MAX_MOD_SIZE 512 /* 4096 bits */
Martin Schwidefsky963ed932006-09-20 15:58:29 +020046
Martin Schwidefsky963ed932006-09-20 15:58:29 +020047#define CEX2A_MAX_MESSAGE_SIZE 0x390 /* sizeof(struct type50_crb2_msg) */
48#define CEX2A_MAX_RESPONSE_SIZE 0x110 /* max outputdatalength + type80_hdr */
49
Felix Beck3e309a62011-01-05 12:47:45 +010050#define CEX3A_MAX_RESPONSE_SIZE 0x210 /* 512 bit modulus
51 * (max outputdatalength) +
52 * type80_hdr*/
53#define CEX3A_MAX_MESSAGE_SIZE sizeof(struct type50_crb3_msg)
Felix Beck8e89b6b2009-12-07 12:51:57 +010054
Martin Schwidefsky963ed932006-09-20 15:58:29 +020055#define CEX2A_CLEANUP_TIME (15*HZ)
Felix Beck8e89b6b2009-12-07 12:51:57 +010056#define CEX3A_CLEANUP_TIME CEX2A_CLEANUP_TIME
Martin Schwidefsky963ed932006-09-20 15:58:29 +020057
Martin Schwidefsky963ed932006-09-20 15:58:29 +020058MODULE_AUTHOR("IBM Corporation");
Holger Dengler5e55a482012-08-28 16:45:36 +020059MODULE_DESCRIPTION("CEX2A Cryptographic Coprocessor device driver, " \
60 "Copyright IBM Corp. 2001, 2012");
Martin Schwidefsky963ed932006-09-20 15:58:29 +020061MODULE_LICENSE("GPL");
Martin Schwidefsky963ed932006-09-20 15:58:29 +020062
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +020063static struct ap_device_id zcrypt_cex2a_card_ids[] = {
64 { .dev_type = AP_DEVICE_TYPE_CEX2A,
65 .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
66 { .dev_type = AP_DEVICE_TYPE_CEX3A,
67 .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
68 { /* end of list */ },
Martin Schwidefsky963ed932006-09-20 15:58:29 +020069};
70
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +020071MODULE_DEVICE_TABLE(ap, zcrypt_cex2a_card_ids);
72
73static struct ap_device_id zcrypt_cex2a_queue_ids[] = {
74 { .dev_type = AP_DEVICE_TYPE_CEX2A,
75 .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
76 { .dev_type = AP_DEVICE_TYPE_CEX3A,
77 .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
78 { /* end of list */ },
79};
80
81MODULE_DEVICE_TABLE(ap, zcrypt_cex2a_queue_ids);
82
Martin Schwidefsky963ed932006-09-20 15:58:29 +020083/**
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +020084 * Probe function for CEX2A card devices. It always accepts the AP device
85 * since the bus_match already checked the card type.
Martin Schwidefsky963ed932006-09-20 15:58:29 +020086 * @ap_dev: pointer to the AP device.
87 */
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +020088static int zcrypt_cex2a_card_probe(struct ap_device *ap_dev)
Martin Schwidefsky963ed932006-09-20 15:58:29 +020089{
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +020090 /*
91 * Normalized speed ratings per crypto adapter
92 * MEX_1k, MEX_2k, MEX_4k, CRT_1k, CRT_2k, CRT_4k, RNG, SECKEY
93 */
94 static const int CEX2A_SPEED_IDX[] = {
95 800, 1000, 2000, 900, 1200, 2400, 0, 0};
96 static const int CEX3A_SPEED_IDX[] = {
97 400, 500, 1000, 450, 550, 1200, 0, 0};
98
99 struct ap_card *ac = to_ap_card(&ap_dev->device);
100 struct zcrypt_card *zc;
Felix Beck8e89b6b2009-12-07 12:51:57 +0100101 int rc = 0;
Martin Schwidefsky963ed932006-09-20 15:58:29 +0200102
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200103 zc = zcrypt_card_alloc();
104 if (!zc)
105 return -ENOMEM;
106 zc->card = ac;
107 ac->private = zc;
108
109 if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX2A) {
110 zc->min_mod_size = CEX2A_MIN_MOD_SIZE;
111 zc->max_mod_size = CEX2A_MAX_MOD_SIZE;
112 memcpy(zc->speed_rating, CEX2A_SPEED_IDX,
Ingo Tuchscherer34a15162016-08-25 11:14:15 +0200113 sizeof(CEX2A_SPEED_IDX));
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200114 zc->max_exp_bit_length = CEX2A_MAX_MOD_SIZE;
115 zc->type_string = "CEX2A";
116 zc->user_space_type = ZCRYPT_CEX2A;
117 } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX3A) {
118 zc->min_mod_size = CEX2A_MIN_MOD_SIZE;
119 zc->max_mod_size = CEX2A_MAX_MOD_SIZE;
120 zc->max_exp_bit_length = CEX2A_MAX_MOD_SIZE;
121 if (ap_test_bit(&ac->functions, AP_FUNC_MEX4K) &&
122 ap_test_bit(&ac->functions, AP_FUNC_CRT4K)) {
123 zc->max_mod_size = CEX3A_MAX_MOD_SIZE;
124 zc->max_exp_bit_length = CEX3A_MAX_MOD_SIZE;
Felix Beckc2567f82011-01-05 12:47:47 +0100125 }
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200126 memcpy(zc->speed_rating, CEX3A_SPEED_IDX,
Ingo Tuchscherer34a15162016-08-25 11:14:15 +0200127 sizeof(CEX3A_SPEED_IDX));
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200128 zc->type_string = "CEX3A";
129 zc->user_space_type = ZCRYPT_CEX3A;
130 } else {
131 zcrypt_card_free(zc);
Holger Dengler5e55a482012-08-28 16:45:36 +0200132 return -ENODEV;
Felix Beck8e89b6b2009-12-07 12:51:57 +0100133 }
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200134 zc->online = 1;
135
136 rc = zcrypt_card_register(zc);
137 if (rc) {
138 ac->private = NULL;
139 zcrypt_card_free(zc);
140 }
141
Martin Schwidefsky963ed932006-09-20 15:58:29 +0200142 return rc;
143}
144
145/**
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200146 * This is called to remove the CEX2A card driver information
147 * if an AP card device is removed.
Martin Schwidefsky963ed932006-09-20 15:58:29 +0200148 */
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200149static void zcrypt_cex2a_card_remove(struct ap_device *ap_dev)
Martin Schwidefsky963ed932006-09-20 15:58:29 +0200150{
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200151 struct zcrypt_card *zc = to_ap_card(&ap_dev->device)->private;
Martin Schwidefsky963ed932006-09-20 15:58:29 +0200152
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200153 if (zc)
154 zcrypt_card_unregister(zc);
Martin Schwidefsky963ed932006-09-20 15:58:29 +0200155}
156
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200157static struct ap_driver zcrypt_cex2a_card_driver = {
158 .probe = zcrypt_cex2a_card_probe,
159 .remove = zcrypt_cex2a_card_remove,
160 .ids = zcrypt_cex2a_card_ids,
161};
162
163/**
164 * Probe function for CEX2A queue devices. It always accepts the AP device
165 * since the bus_match already checked the queue type.
166 * @ap_dev: pointer to the AP device.
167 */
168static int zcrypt_cex2a_queue_probe(struct ap_device *ap_dev)
169{
170 struct ap_queue *aq = to_ap_queue(&ap_dev->device);
171 struct zcrypt_queue *zq = NULL;
172 int rc;
173
174 switch (ap_dev->device_type) {
175 case AP_DEVICE_TYPE_CEX2A:
176 zq = zcrypt_queue_alloc(CEX2A_MAX_RESPONSE_SIZE);
177 if (!zq)
178 return -ENOMEM;
179 break;
180 case AP_DEVICE_TYPE_CEX3A:
181 zq = zcrypt_queue_alloc(CEX3A_MAX_RESPONSE_SIZE);
182 if (!zq)
183 return -ENOMEM;
184 break;
185 }
186 if (!zq)
187 return -ENODEV;
188 zq->ops = zcrypt_msgtype(MSGTYPE50_NAME, MSGTYPE50_VARIANT_DEFAULT);
189 zq->queue = aq;
190 zq->online = 1;
191 atomic_set(&zq->load, 0);
192 ap_queue_init_reply(aq, &zq->reply);
193 aq->request_timeout = CEX2A_CLEANUP_TIME,
194 aq->private = zq;
195 rc = zcrypt_queue_register(zq);
196 if (rc) {
197 aq->private = NULL;
198 zcrypt_queue_free(zq);
199 }
200
201 return rc;
202}
203
204/**
205 * This is called to remove the CEX2A queue driver information
206 * if an AP queue device is removed.
207 */
208static void zcrypt_cex2a_queue_remove(struct ap_device *ap_dev)
209{
210 struct ap_queue *aq = to_ap_queue(&ap_dev->device);
211 struct zcrypt_queue *zq = aq->private;
212
213 ap_queue_remove(aq);
214 if (zq)
215 zcrypt_queue_unregister(zq);
216}
217
218static struct ap_driver zcrypt_cex2a_queue_driver = {
219 .probe = zcrypt_cex2a_queue_probe,
220 .remove = zcrypt_cex2a_queue_remove,
221 .suspend = ap_queue_suspend,
222 .resume = ap_queue_resume,
223 .ids = zcrypt_cex2a_queue_ids,
224};
225
Martin Schwidefsky963ed932006-09-20 15:58:29 +0200226int __init zcrypt_cex2a_init(void)
227{
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200228 int rc;
229
230 rc = ap_driver_register(&zcrypt_cex2a_card_driver,
231 THIS_MODULE, "cex2acard");
232 if (rc)
233 return rc;
234
235 rc = ap_driver_register(&zcrypt_cex2a_queue_driver,
236 THIS_MODULE, "cex2aqueue");
237 if (rc)
238 ap_driver_unregister(&zcrypt_cex2a_card_driver);
239
240 return rc;
Martin Schwidefsky963ed932006-09-20 15:58:29 +0200241}
242
243void __exit zcrypt_cex2a_exit(void)
244{
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200245 ap_driver_unregister(&zcrypt_cex2a_queue_driver);
246 ap_driver_unregister(&zcrypt_cex2a_card_driver);
Martin Schwidefsky963ed932006-09-20 15:58:29 +0200247}
248
Martin Schwidefsky963ed932006-09-20 15:58:29 +0200249module_init(zcrypt_cex2a_init);
250module_exit(zcrypt_cex2a_exit);