[S390] zcrypt: adjust speed rating between cex2 and pcixcc
[safe/jmp/linux-2.6] / drivers / s390 / crypto / zcrypt_pcixcc.c
1 /*
2  *  linux/drivers/s390/crypto/zcrypt_pcixcc.c
3  *
4  *  zcrypt 2.1.0
5  *
6  *  Copyright (C)  2001, 2006 IBM Corporation
7  *  Author(s): Robert Burroughs
8  *             Eric Rossman (edrossma@us.ibm.com)
9  *
10  *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11  *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12  *                                Ralph Wuerthner <rwuerthn@de.ibm.com>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2, or (at your option)
17  * any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  */
28
29 #include <linux/module.h>
30 #include <linux/init.h>
31 #include <linux/err.h>
32 #include <linux/delay.h>
33 #include <asm/atomic.h>
34 #include <asm/uaccess.h>
35
36 #include "ap_bus.h"
37 #include "zcrypt_api.h"
38 #include "zcrypt_error.h"
39 #include "zcrypt_pcicc.h"
40 #include "zcrypt_pcixcc.h"
41 #include "zcrypt_cca_key.h"
42
43 #define PCIXCC_MIN_MOD_SIZE      16     /*  128 bits    */
44 #define PCIXCC_MIN_MOD_SIZE_OLD  64     /*  512 bits    */
45 #define PCIXCC_MAX_MOD_SIZE     256     /* 2048 bits    */
46 #define CEX3C_MIN_MOD_SIZE      PCIXCC_MIN_MOD_SIZE
47 #define CEX3C_MAX_MOD_SIZE      PCIXCC_MAX_MOD_SIZE
48
49 #define PCIXCC_MCL2_SPEED_RATING        7870
50 #define PCIXCC_MCL3_SPEED_RATING        7870
51 #define CEX2C_SPEED_RATING              7000
52 #define CEX3C_SPEED_RATING              10000   /* FIXME: needs finetuning */
53
54 #define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c  /* max size type6 v2 crt message */
55 #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply      */
56
57 #define PCIXCC_MAX_XCRB_MESSAGE_SIZE (12*1024)
58 #define PCIXCC_MAX_XCRB_RESPONSE_SIZE PCIXCC_MAX_XCRB_MESSAGE_SIZE
59 #define PCIXCC_MAX_XCRB_DATA_SIZE (11*1024)
60 #define PCIXCC_MAX_XCRB_REPLY_SIZE (5*1024)
61
62 #define PCIXCC_MAX_RESPONSE_SIZE PCIXCC_MAX_XCRB_RESPONSE_SIZE
63
64 #define PCIXCC_CLEANUP_TIME     (15*HZ)
65
66 #define CEIL4(x) ((((x)+3)/4)*4)
67
68 struct response_type {
69         struct completion work;
70         int type;
71 };
72 #define PCIXCC_RESPONSE_TYPE_ICA  0
73 #define PCIXCC_RESPONSE_TYPE_XCRB 1
74
75 static struct ap_device_id zcrypt_pcixcc_ids[] = {
76         { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
77         { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
78         { AP_DEVICE(AP_DEVICE_TYPE_CEX3C) },
79         { /* end of list */ },
80 };
81
82 #ifndef CONFIG_ZCRYPT_MONOLITHIC
83 MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids);
84 MODULE_AUTHOR("IBM Corporation");
85 MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, "
86                    "Copyright 2001, 2006 IBM Corporation");
87 MODULE_LICENSE("GPL");
88 #endif
89
90 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev);
91 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev);
92 static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *,
93                                  struct ap_message *);
94
95 static struct ap_driver zcrypt_pcixcc_driver = {
96         .probe = zcrypt_pcixcc_probe,
97         .remove = zcrypt_pcixcc_remove,
98         .receive = zcrypt_pcixcc_receive,
99         .ids = zcrypt_pcixcc_ids,
100         .request_timeout = PCIXCC_CLEANUP_TIME,
101 };
102
103 /**
104  * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C
105  * card in a type6 message. The 3 fields that must be filled in at execution
106  * time are  req_parml, rpl_parml and usage_domain.
107  * Everything about this interface is ascii/big-endian, since the
108  * device does *not* have 'Intel inside'.
109  *
110  * The CPRBX is followed immediately by the parm block.
111  * The parm block contains:
112  * - function code ('PD' 0x5044 or 'PK' 0x504B)
113  * - rule block (one of:)
114  *   + 0x000A 'PKCS-1.2' (MCL2 'PD')
115  *   + 0x000A 'ZERO-PAD' (MCL2 'PK')
116  *   + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD')
117  *   + 0x000A 'MRP     ' (MCL3 'PK' or CEX2C 'PK')
118  * - VUD block
119  */
120 static struct CPRBX static_cprbx = {
121         .cprb_len       =  0x00DC,
122         .cprb_ver_id    =  0x02,
123         .func_id        = {0x54,0x32},
124 };
125
126 /**
127  * Convert a ICAMEX message to a type6 MEX message.
128  *
129  * @zdev: crypto device pointer
130  * @ap_msg: pointer to AP message
131  * @mex: pointer to user input data
132  *
133  * Returns 0 on success or -EFAULT.
134  */
135 static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev,
136                                        struct ap_message *ap_msg,
137                                        struct ica_rsa_modexpo *mex)
138 {
139         static struct type6_hdr static_type6_hdrX = {
140                 .type           =  0x06,
141                 .offset1        =  0x00000058,
142                 .agent_id       = {'C','A',},
143                 .function_code  = {'P','K'},
144         };
145         static struct function_and_rules_block static_pke_fnr = {
146                 .function_code  = {'P','K'},
147                 .ulen           = 10,
148                 .only_rule      = {'M','R','P',' ',' ',' ',' ',' '}
149         };
150         static struct function_and_rules_block static_pke_fnr_MCL2 = {
151                 .function_code  = {'P','K'},
152                 .ulen           = 10,
153                 .only_rule      = {'Z','E','R','O','-','P','A','D'}
154         };
155         struct {
156                 struct type6_hdr hdr;
157                 struct CPRBX cprbx;
158                 struct function_and_rules_block fr;
159                 unsigned short length;
160                 char text[0];
161         } __attribute__((packed)) *msg = ap_msg->message;
162         int size;
163
164         /* VUD.ciphertext */
165         msg->length = mex->inputdatalength + 2;
166         if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
167                 return -EFAULT;
168
169         /* Set up key which is located after the variable length text. */
170         size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1);
171         if (size < 0)
172                 return size;
173         size += sizeof(*msg) + mex->inputdatalength;
174
175         /* message header, cprbx and f&r */
176         msg->hdr = static_type6_hdrX;
177         msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
178         msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
179
180         msg->cprbx = static_cprbx;
181         msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
182         msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
183
184         msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
185                 static_pke_fnr_MCL2 : static_pke_fnr;
186
187         msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
188
189         ap_msg->length = size;
190         return 0;
191 }
192
193 /**
194  * Convert a ICACRT message to a type6 CRT message.
195  *
196  * @zdev: crypto device pointer
197  * @ap_msg: pointer to AP message
198  * @crt: pointer to user input data
199  *
200  * Returns 0 on success or -EFAULT.
201  */
202 static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev,
203                                        struct ap_message *ap_msg,
204                                        struct ica_rsa_modexpo_crt *crt)
205 {
206         static struct type6_hdr static_type6_hdrX = {
207                 .type           =  0x06,
208                 .offset1        =  0x00000058,
209                 .agent_id       = {'C','A',},
210                 .function_code  = {'P','D'},
211         };
212         static struct function_and_rules_block static_pkd_fnr = {
213                 .function_code  = {'P','D'},
214                 .ulen           = 10,
215                 .only_rule      = {'Z','E','R','O','-','P','A','D'}
216         };
217
218         static struct function_and_rules_block static_pkd_fnr_MCL2 = {
219                 .function_code  = {'P','D'},
220                 .ulen           = 10,
221                 .only_rule      = {'P','K','C','S','-','1','.','2'}
222         };
223         struct {
224                 struct type6_hdr hdr;
225                 struct CPRBX cprbx;
226                 struct function_and_rules_block fr;
227                 unsigned short length;
228                 char text[0];
229         } __attribute__((packed)) *msg = ap_msg->message;
230         int size;
231
232         /* VUD.ciphertext */
233         msg->length = crt->inputdatalength + 2;
234         if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
235                 return -EFAULT;
236
237         /* Set up key which is located after the variable length text. */
238         size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1);
239         if (size < 0)
240                 return size;
241         size += sizeof(*msg) + crt->inputdatalength;    /* total size of msg */
242
243         /* message header, cprbx and f&r */
244         msg->hdr = static_type6_hdrX;
245         msg->hdr.ToCardLen1 = size -  sizeof(msg->hdr);
246         msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
247
248         msg->cprbx = static_cprbx;
249         msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
250         msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
251                 size - sizeof(msg->hdr) - sizeof(msg->cprbx);
252
253         msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
254                 static_pkd_fnr_MCL2 : static_pkd_fnr;
255
256         ap_msg->length = size;
257         return 0;
258 }
259
260 /**
261  * Convert a XCRB message to a type6 CPRB message.
262  *
263  * @zdev: crypto device pointer
264  * @ap_msg: pointer to AP message
265  * @xcRB: pointer to user input data
266  *
267  * Returns 0 on success or -EFAULT.
268  */
269 struct type86_fmt2_msg {
270         struct type86_hdr hdr;
271         struct type86_fmt2_ext fmt2;
272 } __attribute__((packed));
273
274 static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
275                                        struct ap_message *ap_msg,
276                                        struct ica_xcRB *xcRB)
277 {
278         static struct type6_hdr static_type6_hdrX = {
279                 .type           =  0x06,
280                 .offset1        =  0x00000058,
281         };
282         struct {
283                 struct type6_hdr hdr;
284                 struct CPRBX cprbx;
285         } __attribute__((packed)) *msg = ap_msg->message;
286
287         int rcblen = CEIL4(xcRB->request_control_blk_length);
288         int replylen;
289         char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
290         char *function_code;
291
292         /* length checks */
293         ap_msg->length = sizeof(struct type6_hdr) +
294                 CEIL4(xcRB->request_control_blk_length) +
295                 xcRB->request_data_length;
296         if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE)
297                 return -EFAULT;
298         if (CEIL4(xcRB->reply_control_blk_length) > PCIXCC_MAX_XCRB_REPLY_SIZE)
299                 return -EFAULT;
300         if (CEIL4(xcRB->reply_data_length) > PCIXCC_MAX_XCRB_DATA_SIZE)
301                 return -EFAULT;
302         replylen = CEIL4(xcRB->reply_control_blk_length) +
303                 CEIL4(xcRB->reply_data_length) +
304                 sizeof(struct type86_fmt2_msg);
305         if (replylen > PCIXCC_MAX_XCRB_RESPONSE_SIZE) {
306                 xcRB->reply_control_blk_length = PCIXCC_MAX_XCRB_RESPONSE_SIZE -
307                         (sizeof(struct type86_fmt2_msg) +
308                             CEIL4(xcRB->reply_data_length));
309         }
310
311         /* prepare type6 header */
312         msg->hdr = static_type6_hdrX;
313         memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
314         msg->hdr.ToCardLen1 = xcRB->request_control_blk_length;
315         if (xcRB->request_data_length) {
316                 msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
317                 msg->hdr.ToCardLen2 = xcRB->request_data_length;
318         }
319         msg->hdr.FromCardLen1 = xcRB->reply_control_blk_length;
320         msg->hdr.FromCardLen2 = xcRB->reply_data_length;
321
322         /* prepare CPRB */
323         if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr,
324                     xcRB->request_control_blk_length))
325                 return -EFAULT;
326         if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
327             xcRB->request_control_blk_length)
328                 return -EFAULT;
329         function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
330         memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code));
331
332         if (memcmp(function_code, "US", 2) == 0)
333                 ap_msg->special = 1;
334         else
335                 ap_msg->special = 0;
336
337         /* copy data block */
338         if (xcRB->request_data_length &&
339             copy_from_user(req_data, xcRB->request_data_address,
340                 xcRB->request_data_length))
341                 return -EFAULT;
342         return 0;
343 }
344
345 /**
346  * Prepare a type6 CPRB message for random number generation
347  *
348  * @ap_dev: AP device pointer
349  * @ap_msg: pointer to AP message
350  */
351 static void rng_type6CPRB_msgX(struct ap_device *ap_dev,
352                                struct ap_message *ap_msg,
353                                unsigned random_number_length)
354 {
355         struct {
356                 struct type6_hdr hdr;
357                 struct CPRBX cprbx;
358                 char function_code[2];
359                 short int rule_length;
360                 char rule[8];
361                 short int verb_length;
362                 short int key_length;
363         } __attribute__((packed)) *msg = ap_msg->message;
364         static struct type6_hdr static_type6_hdrX = {
365                 .type           = 0x06,
366                 .offset1        = 0x00000058,
367                 .agent_id       = {'C', 'A'},
368                 .function_code  = {'R', 'L'},
369                 .ToCardLen1     = sizeof *msg - sizeof(msg->hdr),
370                 .FromCardLen1   = sizeof *msg - sizeof(msg->hdr),
371         };
372         static struct CPRBX local_cprbx = {
373                 .cprb_len       = 0x00dc,
374                 .cprb_ver_id    = 0x02,
375                 .func_id        = {0x54, 0x32},
376                 .req_parml      = sizeof *msg - sizeof(msg->hdr) -
377                                   sizeof(msg->cprbx),
378                 .rpl_msgbl      = sizeof *msg - sizeof(msg->hdr),
379         };
380
381         msg->hdr = static_type6_hdrX;
382         msg->hdr.FromCardLen2 = random_number_length,
383         msg->cprbx = local_cprbx;
384         msg->cprbx.rpl_datal = random_number_length,
385         msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid);
386         memcpy(msg->function_code, msg->hdr.function_code, 0x02);
387         msg->rule_length = 0x0a;
388         memcpy(msg->rule, "RANDOM  ", 8);
389         msg->verb_length = 0x02;
390         msg->key_length = 0x02;
391         ap_msg->length = sizeof *msg;
392 }
393
394 /**
395  * Copy results from a type 86 ICA reply message back to user space.
396  *
397  * @zdev: crypto device pointer
398  * @reply: reply AP message.
399  * @data: pointer to user output data
400  * @length: size of user output data
401  *
402  * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
403  */
404 struct type86x_reply {
405         struct type86_hdr hdr;
406         struct type86_fmt2_ext fmt2;
407         struct CPRBX cprbx;
408         unsigned char pad[4];   /* 4 byte function code/rules block ? */
409         unsigned short length;
410         char text[0];
411 } __attribute__((packed));
412
413 static int convert_type86_ica(struct zcrypt_device *zdev,
414                           struct ap_message *reply,
415                           char __user *outputdata,
416                           unsigned int outputdatalength)
417 {
418         static unsigned char static_pad[] = {
419                 0x00,0x02,
420                 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
421                 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
422                 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
423                 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
424                 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
425                 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
426                 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
427                 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
428                 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
429                 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
430                 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
431                 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
432                 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
433                 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
434                 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
435                 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
436                 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
437                 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
438                 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
439                 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
440                 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
441                 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
442                 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
443                 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
444                 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
445                 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
446                 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
447                 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
448                 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
449                 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
450                 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
451                 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
452         };
453         struct type86x_reply *msg = reply->message;
454         unsigned short service_rc, service_rs;
455         unsigned int reply_len, pad_len;
456         char *data;
457
458         service_rc = msg->cprbx.ccp_rtcode;
459         if (unlikely(service_rc != 0)) {
460                 service_rs = msg->cprbx.ccp_rscode;
461                 if (service_rc == 8 && service_rs == 66)
462                         return -EINVAL;
463                 if (service_rc == 8 && service_rs == 65)
464                         return -EINVAL;
465                 if (service_rc == 8 && service_rs == 770)
466                         return -EINVAL;
467                 if (service_rc == 8 && service_rs == 783) {
468                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
469                         return -EAGAIN;
470                 }
471                 if (service_rc == 12 && service_rs == 769)
472                         return -EINVAL;
473                 zdev->online = 0;
474                 return -EAGAIN; /* repeat the request on a different device. */
475         }
476         data = msg->text;
477         reply_len = msg->length - 2;
478         if (reply_len > outputdatalength)
479                 return -EINVAL;
480         /*
481          * For all encipher requests, the length of the ciphertext (reply_len)
482          * will always equal the modulus length. For MEX decipher requests
483          * the output needs to get padded. Minimum pad size is 10.
484          *
485          * Currently, the cases where padding will be added is for:
486          * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
487          *   ZERO-PAD and CRT is only supported for PKD requests)
488          * - PCICC, always
489          */
490         pad_len = outputdatalength - reply_len;
491         if (pad_len > 0) {
492                 if (pad_len < 10)
493                         return -EINVAL;
494                 /* 'restore' padding left in the PCICC/PCIXCC card. */
495                 if (copy_to_user(outputdata, static_pad, pad_len - 1))
496                         return -EFAULT;
497                 if (put_user(0, outputdata + pad_len - 1))
498                         return -EFAULT;
499         }
500         /* Copy the crypto response to user space. */
501         if (copy_to_user(outputdata + pad_len, data, reply_len))
502                 return -EFAULT;
503         return 0;
504 }
505
506 /**
507  * Copy results from a type 86 XCRB reply message back to user space.
508  *
509  * @zdev: crypto device pointer
510  * @reply: reply AP message.
511  * @xcRB: pointer to XCRB
512  *
513  * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
514  */
515 static int convert_type86_xcrb(struct zcrypt_device *zdev,
516                                struct ap_message *reply,
517                                struct ica_xcRB *xcRB)
518 {
519         struct type86_fmt2_msg *msg = reply->message;
520         char *data = reply->message;
521
522         /* Copy CPRB to user */
523         if (copy_to_user(xcRB->reply_control_blk_addr,
524                 data + msg->fmt2.offset1, msg->fmt2.count1))
525                 return -EFAULT;
526         xcRB->reply_control_blk_length = msg->fmt2.count1;
527
528         /* Copy data buffer to user */
529         if (msg->fmt2.count2)
530                 if (copy_to_user(xcRB->reply_data_addr,
531                         data + msg->fmt2.offset2, msg->fmt2.count2))
532                         return -EFAULT;
533         xcRB->reply_data_length = msg->fmt2.count2;
534         return 0;
535 }
536
537 static int convert_type86_rng(struct zcrypt_device *zdev,
538                           struct ap_message *reply,
539                           char *buffer)
540 {
541         struct {
542                 struct type86_hdr hdr;
543                 struct type86_fmt2_ext fmt2;
544                 struct CPRBX cprbx;
545         } __attribute__((packed)) *msg = reply->message;
546         char *data = reply->message;
547
548         if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
549                 return -EINVAL;
550         memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
551         return msg->fmt2.count2;
552 }
553
554 static int convert_response_ica(struct zcrypt_device *zdev,
555                             struct ap_message *reply,
556                             char __user *outputdata,
557                             unsigned int outputdatalength)
558 {
559         struct type86x_reply *msg = reply->message;
560
561         /* Response type byte is the second byte in the response. */
562         switch (((unsigned char *) reply->message)[1]) {
563         case TYPE82_RSP_CODE:
564         case TYPE88_RSP_CODE:
565                 return convert_error(zdev, reply);
566         case TYPE86_RSP_CODE:
567                 if (msg->hdr.reply_code)
568                         return convert_error(zdev, reply);
569                 if (msg->cprbx.cprb_ver_id == 0x02)
570                         return convert_type86_ica(zdev, reply,
571                                                   outputdata, outputdatalength);
572                 /* Fall through, no break, incorrect cprb version is an unknown
573                  * response */
574         default: /* Unknown response type, this should NEVER EVER happen */
575                 zdev->online = 0;
576                 return -EAGAIN; /* repeat the request on a different device. */
577         }
578 }
579
580 static int convert_response_xcrb(struct zcrypt_device *zdev,
581                             struct ap_message *reply,
582                             struct ica_xcRB *xcRB)
583 {
584         struct type86x_reply *msg = reply->message;
585
586         /* Response type byte is the second byte in the response. */
587         switch (((unsigned char *) reply->message)[1]) {
588         case TYPE82_RSP_CODE:
589         case TYPE88_RSP_CODE:
590                 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
591                 return convert_error(zdev, reply);
592         case TYPE86_RSP_CODE:
593                 if (msg->hdr.reply_code) {
594                         memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
595                         return convert_error(zdev, reply);
596                 }
597                 if (msg->cprbx.cprb_ver_id == 0x02)
598                         return convert_type86_xcrb(zdev, reply, xcRB);
599                 /* Fall through, no break, incorrect cprb version is an unknown
600                  * response */
601         default: /* Unknown response type, this should NEVER EVER happen */
602                 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
603                 zdev->online = 0;
604                 return -EAGAIN; /* repeat the request on a different device. */
605         }
606 }
607
608 static int convert_response_rng(struct zcrypt_device *zdev,
609                                  struct ap_message *reply,
610                                  char *data)
611 {
612         struct type86x_reply *msg = reply->message;
613
614         switch (msg->hdr.type) {
615         case TYPE82_RSP_CODE:
616         case TYPE88_RSP_CODE:
617                 return -EINVAL;
618         case TYPE86_RSP_CODE:
619                 if (msg->hdr.reply_code)
620                         return -EINVAL;
621                 if (msg->cprbx.cprb_ver_id == 0x02)
622                         return convert_type86_rng(zdev, reply, data);
623                 /* Fall through, no break, incorrect cprb version is an unknown
624                  * response */
625         default: /* Unknown response type, this should NEVER EVER happen */
626                 zdev->online = 0;
627                 return -EAGAIN; /* repeat the request on a different device. */
628         }
629 }
630
631 /**
632  * This function is called from the AP bus code after a crypto request
633  * "msg" has finished with the reply message "reply".
634  * It is called from tasklet context.
635  * @ap_dev: pointer to the AP device
636  * @msg: pointer to the AP message
637  * @reply: pointer to the AP reply message
638  */
639 static void zcrypt_pcixcc_receive(struct ap_device *ap_dev,
640                                   struct ap_message *msg,
641                                   struct ap_message *reply)
642 {
643         static struct error_hdr error_reply = {
644                 .type = TYPE82_RSP_CODE,
645                 .reply_code = REP82_ERROR_MACHINE_FAILURE,
646         };
647         struct response_type *resp_type =
648                 (struct response_type *) msg->private;
649         struct type86x_reply *t86r;
650         int length;
651
652         /* Copy the reply message to the request message buffer. */
653         if (IS_ERR(reply)) {
654                 memcpy(msg->message, &error_reply, sizeof(error_reply));
655                 goto out;
656         }
657         t86r = reply->message;
658         if (t86r->hdr.type == TYPE86_RSP_CODE &&
659                  t86r->cprbx.cprb_ver_id == 0x02) {
660                 switch (resp_type->type) {
661                 case PCIXCC_RESPONSE_TYPE_ICA:
662                         length = sizeof(struct type86x_reply)
663                                 + t86r->length - 2;
664                         length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
665                         memcpy(msg->message, reply->message, length);
666                         break;
667                 case PCIXCC_RESPONSE_TYPE_XCRB:
668                         length = t86r->fmt2.offset2 + t86r->fmt2.count2;
669                         length = min(PCIXCC_MAX_XCRB_RESPONSE_SIZE, length);
670                         memcpy(msg->message, reply->message, length);
671                         break;
672                 default:
673                         memcpy(msg->message, &error_reply, sizeof error_reply);
674                 }
675         } else
676                 memcpy(msg->message, reply->message, sizeof error_reply);
677 out:
678         complete(&(resp_type->work));
679 }
680
681 static atomic_t zcrypt_step = ATOMIC_INIT(0);
682
683 /**
684  * The request distributor calls this function if it picked the PCIXCC/CEX2C
685  * device to handle a modexpo request.
686  * @zdev: pointer to zcrypt_device structure that identifies the
687  *        PCIXCC/CEX2C device to the request distributor
688  * @mex: pointer to the modexpo request buffer
689  */
690 static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
691                                   struct ica_rsa_modexpo *mex)
692 {
693         struct ap_message ap_msg;
694         struct response_type resp_type = {
695                 .type = PCIXCC_RESPONSE_TYPE_ICA,
696         };
697         int rc;
698
699         ap_init_message(&ap_msg);
700         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
701         if (!ap_msg.message)
702                 return -ENOMEM;
703         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
704                                 atomic_inc_return(&zcrypt_step);
705         ap_msg.private = &resp_type;
706         rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
707         if (rc)
708                 goto out_free;
709         init_completion(&resp_type.work);
710         ap_queue_message(zdev->ap_dev, &ap_msg);
711         rc = wait_for_completion_interruptible(&resp_type.work);
712         if (rc == 0)
713                 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
714                                           mex->outputdatalength);
715         else
716                 /* Signal pending. */
717                 ap_cancel_message(zdev->ap_dev, &ap_msg);
718 out_free:
719         free_page((unsigned long) ap_msg.message);
720         return rc;
721 }
722
723 /**
724  * The request distributor calls this function if it picked the PCIXCC/CEX2C
725  * device to handle a modexpo_crt request.
726  * @zdev: pointer to zcrypt_device structure that identifies the
727  *        PCIXCC/CEX2C device to the request distributor
728  * @crt: pointer to the modexpoc_crt request buffer
729  */
730 static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
731                                       struct ica_rsa_modexpo_crt *crt)
732 {
733         struct ap_message ap_msg;
734         struct response_type resp_type = {
735                 .type = PCIXCC_RESPONSE_TYPE_ICA,
736         };
737         int rc;
738
739         ap_init_message(&ap_msg);
740         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
741         if (!ap_msg.message)
742                 return -ENOMEM;
743         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
744                                 atomic_inc_return(&zcrypt_step);
745         ap_msg.private = &resp_type;
746         rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
747         if (rc)
748                 goto out_free;
749         init_completion(&resp_type.work);
750         ap_queue_message(zdev->ap_dev, &ap_msg);
751         rc = wait_for_completion_interruptible(&resp_type.work);
752         if (rc == 0)
753                 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
754                                           crt->outputdatalength);
755         else
756                 /* Signal pending. */
757                 ap_cancel_message(zdev->ap_dev, &ap_msg);
758 out_free:
759         free_page((unsigned long) ap_msg.message);
760         return rc;
761 }
762
763 /**
764  * The request distributor calls this function if it picked the PCIXCC/CEX2C
765  * device to handle a send_cprb request.
766  * @zdev: pointer to zcrypt_device structure that identifies the
767  *        PCIXCC/CEX2C device to the request distributor
768  * @xcRB: pointer to the send_cprb request buffer
769  */
770 static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
771                                     struct ica_xcRB *xcRB)
772 {
773         struct ap_message ap_msg;
774         struct response_type resp_type = {
775                 .type = PCIXCC_RESPONSE_TYPE_XCRB,
776         };
777         int rc;
778
779         ap_init_message(&ap_msg);
780         ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
781         if (!ap_msg.message)
782                 return -ENOMEM;
783         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
784                                 atomic_inc_return(&zcrypt_step);
785         ap_msg.private = &resp_type;
786         rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
787         if (rc)
788                 goto out_free;
789         init_completion(&resp_type.work);
790         ap_queue_message(zdev->ap_dev, &ap_msg);
791         rc = wait_for_completion_interruptible(&resp_type.work);
792         if (rc == 0)
793                 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
794         else
795                 /* Signal pending. */
796                 ap_cancel_message(zdev->ap_dev, &ap_msg);
797 out_free:
798         kzfree(ap_msg.message);
799         return rc;
800 }
801
802 /**
803  * The request distributor calls this function if it picked the PCIXCC/CEX2C
804  * device to generate random data.
805  * @zdev: pointer to zcrypt_device structure that identifies the
806  *        PCIXCC/CEX2C device to the request distributor
807  * @buffer: pointer to a memory page to return random data
808  */
809
810 static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev,
811                                     char *buffer)
812 {
813         struct ap_message ap_msg;
814         struct response_type resp_type = {
815                 .type = PCIXCC_RESPONSE_TYPE_XCRB,
816         };
817         int rc;
818
819         ap_init_message(&ap_msg);
820         ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
821         if (!ap_msg.message)
822                 return -ENOMEM;
823         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
824                                 atomic_inc_return(&zcrypt_step);
825         ap_msg.private = &resp_type;
826         rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE);
827         init_completion(&resp_type.work);
828         ap_queue_message(zdev->ap_dev, &ap_msg);
829         rc = wait_for_completion_interruptible(&resp_type.work);
830         if (rc == 0)
831                 rc = convert_response_rng(zdev, &ap_msg, buffer);
832         else
833                 /* Signal pending. */
834                 ap_cancel_message(zdev->ap_dev, &ap_msg);
835         kfree(ap_msg.message);
836         return rc;
837 }
838
839 /**
840  * The crypto operations for a PCIXCC/CEX2C card.
841  */
842 static struct zcrypt_ops zcrypt_pcixcc_ops = {
843         .rsa_modexpo = zcrypt_pcixcc_modexpo,
844         .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
845         .send_cprb = zcrypt_pcixcc_send_cprb,
846 };
847
848 static struct zcrypt_ops zcrypt_pcixcc_with_rng_ops = {
849         .rsa_modexpo = zcrypt_pcixcc_modexpo,
850         .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
851         .send_cprb = zcrypt_pcixcc_send_cprb,
852         .rng = zcrypt_pcixcc_rng,
853 };
854
855 /**
856  * Micro-code detection function. Its sends a message to a pcixcc card
857  * to find out the microcode level.
858  * @ap_dev: pointer to the AP device.
859  */
860 static int zcrypt_pcixcc_mcl(struct ap_device *ap_dev)
861 {
862         static unsigned char msg[] = {
863                 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
864                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
865                 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
866                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
867                 0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
868                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
869                 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,
870                 0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
871                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
872                 0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
873                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
874                 0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
875                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,
876                 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
877                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
878                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
879                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
880                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
881                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
882                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
883                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
884                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
885                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
886                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
887                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
888                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
889                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
890                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
891                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
892                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
893                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
894                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
895                 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,
896                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
897                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
898                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
899                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
900                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
901                 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x0A,
902                 0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
903                 0x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,
904                 0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
905                 0x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,
906                 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
907                 0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,
908                 0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
909                 0x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,
910                 0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
911                 0x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,
912                 0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
913                 0x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,
914                 0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
915                 0x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,
916                 0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
917                 0x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,
918                 0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
919                 0xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,
920                 0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
921                 0xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,
922                 0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
923                 0x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,
924                 0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
925                 0x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,
926                 0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
927                 0xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,
928                 0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
929                 0x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,
930                 0xF1,0x3D,0x93,0x53
931         };
932         unsigned long long psmid;
933         struct CPRBX *cprbx;
934         char *reply;
935         int rc, i;
936
937         reply = (void *) get_zeroed_page(GFP_KERNEL);
938         if (!reply)
939                 return -ENOMEM;
940
941         rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, msg, sizeof(msg));
942         if (rc)
943                 goto out_free;
944
945         /* Wait for the test message to complete. */
946         for (i = 0; i < 6; i++) {
947                 mdelay(300);
948                 rc = ap_recv(ap_dev->qid, &psmid, reply, 4096);
949                 if (rc == 0 && psmid == 0x0102030405060708ULL)
950                         break;
951         }
952
953         if (i >= 6) {
954                 /* Got no answer. */
955                 rc = -ENODEV;
956                 goto out_free;
957         }
958
959         cprbx = (struct CPRBX *) (reply + 48);
960         if (cprbx->ccp_rtcode == 8 && cprbx->ccp_rscode == 33)
961                 rc = ZCRYPT_PCIXCC_MCL2;
962         else
963                 rc = ZCRYPT_PCIXCC_MCL3;
964 out_free:
965         free_page((unsigned long) reply);
966         return rc;
967 }
968
969 /**
970  * Large random number detection function. Its sends a message to a pcixcc
971  * card to find out if large random numbers are supported.
972  * @ap_dev: pointer to the AP device.
973  *
974  * Returns 1 if large random numbers are supported, 0 if not and < 0 on error.
975  */
976 static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
977 {
978         struct ap_message ap_msg;
979         unsigned long long psmid;
980         struct {
981                 struct type86_hdr hdr;
982                 struct type86_fmt2_ext fmt2;
983                 struct CPRBX cprbx;
984         } __attribute__((packed)) *reply;
985         int rc, i;
986
987         ap_init_message(&ap_msg);
988         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
989         if (!ap_msg.message)
990                 return -ENOMEM;
991
992         rng_type6CPRB_msgX(ap_dev, &ap_msg, 4);
993         rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, ap_msg.message,
994                      ap_msg.length);
995         if (rc)
996                 goto out_free;
997
998         /* Wait for the test message to complete. */
999         for (i = 0; i < 2 * HZ; i++) {
1000                 msleep(1000 / HZ);
1001                 rc = ap_recv(ap_dev->qid, &psmid, ap_msg.message, 4096);
1002                 if (rc == 0 && psmid == 0x0102030405060708ULL)
1003                         break;
1004         }
1005
1006         if (i >= 2 * HZ) {
1007                 /* Got no answer. */
1008                 rc = -ENODEV;
1009                 goto out_free;
1010         }
1011
1012         reply = ap_msg.message;
1013         if (reply->cprbx.ccp_rtcode == 0 && reply->cprbx.ccp_rscode == 0)
1014                 rc = 1;
1015         else
1016                 rc = 0;
1017 out_free:
1018         free_page((unsigned long) ap_msg.message);
1019         return rc;
1020 }
1021
1022 /**
1023  * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device
1024  * since the bus_match already checked the hardware type. The PCIXCC
1025  * cards come in two flavours: micro code level 2 and micro code level 3.
1026  * This is checked by sending a test message to the device.
1027  * @ap_dev: pointer to the AP device.
1028  */
1029 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
1030 {
1031         struct zcrypt_device *zdev;
1032         int rc = 0;
1033
1034         zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE);
1035         if (!zdev)
1036                 return -ENOMEM;
1037         zdev->ap_dev = ap_dev;
1038         zdev->online = 1;
1039         switch (ap_dev->device_type) {
1040         case AP_DEVICE_TYPE_PCIXCC:
1041                 rc = zcrypt_pcixcc_mcl(ap_dev);
1042                 if (rc < 0) {
1043                         zcrypt_device_free(zdev);
1044                         return rc;
1045                 }
1046                 zdev->user_space_type = rc;
1047                 if (rc == ZCRYPT_PCIXCC_MCL2) {
1048                         zdev->type_string = "PCIXCC_MCL2";
1049                         zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
1050                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
1051                         zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1052                 } else {
1053                         zdev->type_string = "PCIXCC_MCL3";
1054                         zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
1055                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1056                         zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1057                 }
1058                 break;
1059         case AP_DEVICE_TYPE_CEX2C:
1060                 zdev->user_space_type = ZCRYPT_CEX2C;
1061                 zdev->type_string = "CEX2C";
1062                 zdev->speed_rating = CEX2C_SPEED_RATING;
1063                 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1064                 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1065                 break;
1066         case AP_DEVICE_TYPE_CEX3C:
1067                 zdev->user_space_type = ZCRYPT_CEX3C;
1068                 zdev->type_string = "CEX3C";
1069                 zdev->speed_rating = CEX3C_SPEED_RATING;
1070                 zdev->min_mod_size = CEX3C_MIN_MOD_SIZE;
1071                 zdev->max_mod_size = CEX3C_MAX_MOD_SIZE;
1072                 break;
1073         default:
1074                 goto out_free;
1075         }
1076
1077         rc = zcrypt_pcixcc_rng_supported(ap_dev);
1078         if (rc < 0) {
1079                 zcrypt_device_free(zdev);
1080                 return rc;
1081         }
1082         if (rc)
1083                 zdev->ops = &zcrypt_pcixcc_with_rng_ops;
1084         else
1085                 zdev->ops = &zcrypt_pcixcc_ops;
1086         ap_dev->reply = &zdev->reply;
1087         ap_dev->private = zdev;
1088         rc = zcrypt_device_register(zdev);
1089         if (rc)
1090                 goto out_free;
1091         return 0;
1092
1093  out_free:
1094         ap_dev->private = NULL;
1095         zcrypt_device_free(zdev);
1096         return rc;
1097 }
1098
1099 /**
1100  * This is called to remove the extended PCIXCC/CEX2C driver information
1101  * if an AP device is removed.
1102  */
1103 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
1104 {
1105         struct zcrypt_device *zdev = ap_dev->private;
1106
1107         zcrypt_device_unregister(zdev);
1108 }
1109
1110 int __init zcrypt_pcixcc_init(void)
1111 {
1112         return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
1113 }
1114
1115 void zcrypt_pcixcc_exit(void)
1116 {
1117         ap_driver_unregister(&zcrypt_pcixcc_driver);
1118 }
1119
1120 #ifndef CONFIG_ZCRYPT_MONOLITHIC
1121 module_init(zcrypt_pcixcc_init);
1122 module_exit(zcrypt_pcixcc_exit);
1123 #endif