Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / s390 / crypto / zcrypt_cex4.c
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
13 #include "ap_bus.h"
14 #include "zcrypt_api.h"
15 #include "zcrypt_msgtype6.h"
16 #include "zcrypt_msgtype50.h"
17 #include "zcrypt_error.h"
18 #include "zcrypt_cex4.h"
19
20 #define CEX4A_MIN_MOD_SIZE        1     /*    8 bits    */
21 #define CEX4A_MAX_MOD_SIZE_2K   256     /* 2048 bits    */
22 #define CEX4A_MAX_MOD_SIZE_4K   512     /* 4096 bits    */
23
24 #define CEX4C_MIN_MOD_SIZE       16     /*  256 bits    */
25 #define CEX4C_MAX_MOD_SIZE      512     /* 4096 bits    */
26
27 #define CEX4A_SPEED_RATING      900      /* TODO new card, new speed rating */
28 #define CEX4C_SPEED_RATING      6500     /* TODO new card, new speed rating */
29 #define CEX4P_SPEED_RATING      7000     /* TODO new card, new speed rating */
30 #define CEX5A_SPEED_RATING      450      /* TODO new card, new speed rating */
31 #define CEX5C_SPEED_RATING      3250     /* TODO new card, new speed rating */
32 #define CEX5P_SPEED_RATING      3500     /* TODO new card, new speed rating */
33
34 #define CEX4A_MAX_MESSAGE_SIZE  MSGTYPE50_CRB3_MAX_MSG_SIZE
35 #define CEX4C_MAX_MESSAGE_SIZE  MSGTYPE06_MAX_MSG_SIZE
36
37 /* Waiting time for requests to be processed.
38  * Currently there are some types of request which are not deterministic.
39  * But the maximum time limit managed by the stomper code is set to 60sec.
40  * Hence we have to wait at least that time period.
41  */
42 #define CEX4_CLEANUP_TIME       (61*HZ)
43
44 static struct ap_device_id zcrypt_cex4_ids[] = {
45         { AP_DEVICE(AP_DEVICE_TYPE_CEX4)  },
46         { AP_DEVICE(AP_DEVICE_TYPE_CEX5)  },
47         { /* end of list */ },
48 };
49
50 MODULE_DEVICE_TABLE(ap, zcrypt_cex4_ids);
51 MODULE_AUTHOR("IBM Corporation");
52 MODULE_DESCRIPTION("CEX4 Cryptographic Card device driver, " \
53                    "Copyright IBM Corp. 2012");
54 MODULE_LICENSE("GPL");
55
56 static int zcrypt_cex4_probe(struct ap_device *ap_dev);
57 static void zcrypt_cex4_remove(struct ap_device *ap_dev);
58
59 static struct ap_driver zcrypt_cex4_driver = {
60         .probe = zcrypt_cex4_probe,
61         .remove = zcrypt_cex4_remove,
62         .ids = zcrypt_cex4_ids,
63         .request_timeout = CEX4_CLEANUP_TIME,
64 };
65
66 /**
67  * Probe function for CEX4 cards. It always accepts the AP device
68  * since the bus_match already checked the hardware type.
69  * @ap_dev: pointer to the AP device.
70  */
71 static int zcrypt_cex4_probe(struct ap_device *ap_dev)
72 {
73         struct zcrypt_device *zdev = NULL;
74         int rc = 0;
75
76         switch (ap_dev->device_type) {
77         case AP_DEVICE_TYPE_CEX4:
78         case AP_DEVICE_TYPE_CEX5:
79                 if (ap_test_bit(&ap_dev->functions, AP_FUNC_ACCEL)) {
80                         zdev = zcrypt_device_alloc(CEX4A_MAX_MESSAGE_SIZE);
81                         if (!zdev)
82                                 return -ENOMEM;
83                         if (ap_dev->device_type == AP_DEVICE_TYPE_CEX4) {
84                                 zdev->type_string = "CEX4A";
85                                 zdev->speed_rating = CEX4A_SPEED_RATING;
86                         } else {
87                                 zdev->type_string = "CEX5A";
88                                 zdev->speed_rating = CEX5A_SPEED_RATING;
89                         }
90                         zdev->user_space_type = ZCRYPT_CEX3A;
91                         zdev->min_mod_size = CEX4A_MIN_MOD_SIZE;
92                         if (ap_test_bit(&ap_dev->functions, AP_FUNC_MEX4K) &&
93                             ap_test_bit(&ap_dev->functions, AP_FUNC_CRT4K)) {
94                                 zdev->max_mod_size =
95                                         CEX4A_MAX_MOD_SIZE_4K;
96                                 zdev->max_exp_bit_length =
97                                         CEX4A_MAX_MOD_SIZE_4K;
98                         } else {
99                                 zdev->max_mod_size =
100                                         CEX4A_MAX_MOD_SIZE_2K;
101                                 zdev->max_exp_bit_length =
102                                         CEX4A_MAX_MOD_SIZE_2K;
103                         }
104                         zdev->short_crt = 1;
105                         zdev->ops = zcrypt_msgtype_request(MSGTYPE50_NAME,
106                                                            MSGTYPE50_VARIANT_DEFAULT);
107                 } else if (ap_test_bit(&ap_dev->functions, AP_FUNC_COPRO)) {
108                         zdev = zcrypt_device_alloc(CEX4C_MAX_MESSAGE_SIZE);
109                         if (!zdev)
110                                 return -ENOMEM;
111                         if (ap_dev->device_type == AP_DEVICE_TYPE_CEX4) {
112                                 zdev->type_string = "CEX4C";
113                                 zdev->speed_rating = CEX4C_SPEED_RATING;
114                         } else {
115                                 zdev->type_string = "CEX5C";
116                                 zdev->speed_rating = CEX5C_SPEED_RATING;
117                         }
118                         zdev->user_space_type = ZCRYPT_CEX3C;
119                         zdev->min_mod_size = CEX4C_MIN_MOD_SIZE;
120                         zdev->max_mod_size = CEX4C_MAX_MOD_SIZE;
121                         zdev->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;
122                         zdev->short_crt = 0;
123                         zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME,
124                                                            MSGTYPE06_VARIANT_DEFAULT);
125                 } else if (ap_test_bit(&ap_dev->functions, AP_FUNC_EP11)) {
126                         zdev = zcrypt_device_alloc(CEX4C_MAX_MESSAGE_SIZE);
127                         if (!zdev)
128                                 return -ENOMEM;
129                         if (ap_dev->device_type == AP_DEVICE_TYPE_CEX4) {
130                                 zdev->type_string = "CEX4P";
131                                 zdev->speed_rating = CEX4P_SPEED_RATING;
132                         } else {
133                                 zdev->type_string = "CEX5P";
134                                 zdev->speed_rating = CEX5P_SPEED_RATING;
135                         }
136                         zdev->user_space_type = ZCRYPT_CEX4;
137                         zdev->min_mod_size = CEX4C_MIN_MOD_SIZE;
138                         zdev->max_mod_size = CEX4C_MAX_MOD_SIZE;
139                         zdev->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;
140                         zdev->short_crt = 0;
141                         zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME,
142                                                         MSGTYPE06_VARIANT_EP11);
143                 }
144                 break;
145         }
146         if (!zdev)
147                 return -ENODEV;
148         zdev->ap_dev = ap_dev;
149         zdev->online = 1;
150         ap_dev->reply = &zdev->reply;
151         ap_dev->private = zdev;
152         rc = zcrypt_device_register(zdev);
153         if (rc) {
154                 zcrypt_msgtype_release(zdev->ops);
155                 ap_dev->private = NULL;
156                 zcrypt_device_free(zdev);
157         }
158         return rc;
159 }
160
161 /**
162  * This is called to remove the extended CEX4 driver information
163  * if an AP device is removed.
164  */
165 static void zcrypt_cex4_remove(struct ap_device *ap_dev)
166 {
167         struct zcrypt_device *zdev = ap_dev->private;
168         struct zcrypt_ops *zops;
169
170         if (zdev) {
171                 zops = zdev->ops;
172                 zcrypt_device_unregister(zdev);
173                 zcrypt_msgtype_release(zops);
174         }
175 }
176
177 int __init zcrypt_cex4_init(void)
178 {
179         return ap_driver_register(&zcrypt_cex4_driver, THIS_MODULE, "cex4");
180 }
181
182 void __exit zcrypt_cex4_exit(void)
183 {
184         ap_driver_unregister(&zcrypt_cex4_driver);
185 }
186
187 module_init(zcrypt_cex4_init);
188 module_exit(zcrypt_cex4_exit);