Commit | Line | Data |
---|---|---|
963ed931 | 1 | /* |
5432114b | 2 | * zcrypt 2.1.0 |
963ed931 | 3 | * |
5e55a488 | 4 | * Copyright IBM Corp. 2001, 2012 |
963ed931 MS |
5 | * 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> | |
5e55a488 | 11 | * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com> |
963ed931 MS |
12 | * |
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> | |
5a0e3ad6 | 29 | #include <linux/slab.h> |
963ed931 MS |
30 | #include <linux/init.h> |
31 | #include <linux/err.h> | |
60063497 | 32 | #include <linux/atomic.h> |
963ed931 MS |
33 | #include <asm/uaccess.h> |
34 | ||
35 | #include "ap_bus.h" | |
36 | #include "zcrypt_api.h" | |
37 | #include "zcrypt_error.h" | |
38 | #include "zcrypt_cex2a.h" | |
5e55a488 | 39 | #include "zcrypt_msgtype50.h" |
963ed931 MS |
40 | |
41 | #define CEX2A_MIN_MOD_SIZE 1 /* 8 bits */ | |
42 | #define CEX2A_MAX_MOD_SIZE 256 /* 2048 bits */ | |
8e89b6be | 43 | #define CEX3A_MIN_MOD_SIZE CEX2A_MIN_MOD_SIZE |
3e309a66 | 44 | #define CEX3A_MAX_MOD_SIZE 512 /* 4096 bits */ |
963ed931 MS |
45 | |
46 | #define CEX2A_SPEED_RATING 970 | |
7a6f5cd0 | 47 | #define CEX3A_SPEED_RATING 900 /* Fixme: Needs finetuning */ |
963ed931 MS |
48 | |
49 | #define CEX2A_MAX_MESSAGE_SIZE 0x390 /* sizeof(struct type50_crb2_msg) */ | |
50 | #define CEX2A_MAX_RESPONSE_SIZE 0x110 /* max outputdatalength + type80_hdr */ | |
51 | ||
3e309a66 FB |
52 | #define CEX3A_MAX_RESPONSE_SIZE 0x210 /* 512 bit modulus |
53 | * (max outputdatalength) + | |
54 | * type80_hdr*/ | |
55 | #define CEX3A_MAX_MESSAGE_SIZE sizeof(struct type50_crb3_msg) | |
8e89b6be | 56 | |
963ed931 | 57 | #define CEX2A_CLEANUP_TIME (15*HZ) |
8e89b6be | 58 | #define CEX3A_CLEANUP_TIME CEX2A_CLEANUP_TIME |
963ed931 MS |
59 | |
60 | static struct ap_device_id zcrypt_cex2a_ids[] = { | |
61 | { AP_DEVICE(AP_DEVICE_TYPE_CEX2A) }, | |
ffda4f71 | 62 | { AP_DEVICE(AP_DEVICE_TYPE_CEX3A) }, |
963ed931 MS |
63 | { /* end of list */ }, |
64 | }; | |
65 | ||
963ed931 MS |
66 | MODULE_DEVICE_TABLE(ap, zcrypt_cex2a_ids); |
67 | MODULE_AUTHOR("IBM Corporation"); | |
5e55a488 HD |
68 | MODULE_DESCRIPTION("CEX2A Cryptographic Coprocessor device driver, " \ |
69 | "Copyright IBM Corp. 2001, 2012"); | |
963ed931 | 70 | MODULE_LICENSE("GPL"); |
963ed931 MS |
71 | |
72 | static int zcrypt_cex2a_probe(struct ap_device *ap_dev); | |
73 | static void zcrypt_cex2a_remove(struct ap_device *ap_dev); | |
963ed931 MS |
74 | |
75 | static struct ap_driver zcrypt_cex2a_driver = { | |
76 | .probe = zcrypt_cex2a_probe, | |
77 | .remove = zcrypt_cex2a_remove, | |
963ed931 | 78 | .ids = zcrypt_cex2a_ids, |
af512ed0 | 79 | .request_timeout = CEX2A_CLEANUP_TIME, |
963ed931 MS |
80 | }; |
81 | ||
963ed931 MS |
82 | /** |
83 | * Probe function for CEX2A cards. It always accepts the AP device | |
84 | * since the bus_match already checked the hardware type. | |
85 | * @ap_dev: pointer to the AP device. | |
86 | */ | |
87 | static int zcrypt_cex2a_probe(struct ap_device *ap_dev) | |
88 | { | |
8e89b6be FB |
89 | struct zcrypt_device *zdev = NULL; |
90 | int rc = 0; | |
91 | ||
92 | switch (ap_dev->device_type) { | |
93 | case AP_DEVICE_TYPE_CEX2A: | |
94 | zdev = zcrypt_device_alloc(CEX2A_MAX_RESPONSE_SIZE); | |
95 | if (!zdev) | |
96 | return -ENOMEM; | |
97 | zdev->user_space_type = ZCRYPT_CEX2A; | |
98 | zdev->type_string = "CEX2A"; | |
99 | zdev->min_mod_size = CEX2A_MIN_MOD_SIZE; | |
100 | zdev->max_mod_size = CEX2A_MAX_MOD_SIZE; | |
101 | zdev->short_crt = 1; | |
102 | zdev->speed_rating = CEX2A_SPEED_RATING; | |
c2567f8f | 103 | zdev->max_exp_bit_length = CEX2A_MAX_MOD_SIZE; |
8e89b6be FB |
104 | break; |
105 | case AP_DEVICE_TYPE_CEX3A: | |
106 | zdev = zcrypt_device_alloc(CEX3A_MAX_RESPONSE_SIZE); | |
107 | if (!zdev) | |
108 | return -ENOMEM; | |
109 | zdev->user_space_type = ZCRYPT_CEX3A; | |
110 | zdev->type_string = "CEX3A"; | |
3e309a66 FB |
111 | zdev->min_mod_size = CEX2A_MIN_MOD_SIZE; |
112 | zdev->max_mod_size = CEX2A_MAX_MOD_SIZE; | |
c2567f8f | 113 | zdev->max_exp_bit_length = CEX2A_MAX_MOD_SIZE; |
b26bd941 HD |
114 | if (ap_test_bit(&ap_dev->functions, AP_FUNC_MEX4K) && |
115 | ap_test_bit(&ap_dev->functions, AP_FUNC_CRT4K)) { | |
3e309a66 | 116 | zdev->max_mod_size = CEX3A_MAX_MOD_SIZE; |
c2567f8f FB |
117 | zdev->max_exp_bit_length = CEX3A_MAX_MOD_SIZE; |
118 | } | |
8e89b6be FB |
119 | zdev->short_crt = 1; |
120 | zdev->speed_rating = CEX3A_SPEED_RATING; | |
121 | break; | |
122 | } | |
5e55a488 HD |
123 | if (!zdev) |
124 | return -ENODEV; | |
125 | zdev->ops = zcrypt_msgtype_request(MSGTYPE50_NAME, | |
126 | MSGTYPE50_VARIANT_DEFAULT); | |
127 | zdev->ap_dev = ap_dev; | |
128 | zdev->online = 1; | |
129 | ap_dev->reply = &zdev->reply; | |
130 | ap_dev->private = zdev; | |
131 | rc = zcrypt_device_register(zdev); | |
8e89b6be FB |
132 | if (rc) { |
133 | ap_dev->private = NULL; | |
5e55a488 | 134 | zcrypt_msgtype_release(zdev->ops); |
8e89b6be FB |
135 | zcrypt_device_free(zdev); |
136 | } | |
963ed931 MS |
137 | return rc; |
138 | } | |
139 | ||
140 | /** | |
141 | * This is called to remove the extended CEX2A driver information | |
142 | * if an AP device is removed. | |
143 | */ | |
144 | static void zcrypt_cex2a_remove(struct ap_device *ap_dev) | |
145 | { | |
146 | struct zcrypt_device *zdev = ap_dev->private; | |
5e55a488 | 147 | struct zcrypt_ops *zops = zdev->ops; |
963ed931 MS |
148 | |
149 | zcrypt_device_unregister(zdev); | |
5e55a488 | 150 | zcrypt_msgtype_release(zops); |
963ed931 MS |
151 | } |
152 | ||
153 | int __init zcrypt_cex2a_init(void) | |
154 | { | |
155 | return ap_driver_register(&zcrypt_cex2a_driver, THIS_MODULE, "cex2a"); | |
156 | } | |
157 | ||
158 | void __exit zcrypt_cex2a_exit(void) | |
159 | { | |
160 | ap_driver_unregister(&zcrypt_cex2a_driver); | |
161 | } | |
162 | ||
963ed931 MS |
163 | module_init(zcrypt_cex2a_init); |
164 | module_exit(zcrypt_cex2a_exit); |