Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  Copyright IBM Corp. 2012, 2022
0004  *  Author(s): Holger Dengler <hd@linux.vnet.ibm.com>
0005  */
0006 
0007 #include <linux/module.h>
0008 #include <linux/slab.h>
0009 #include <linux/init.h>
0010 #include <linux/err.h>
0011 #include <linux/atomic.h>
0012 #include <linux/uaccess.h>
0013 #include <linux/mod_devicetable.h>
0014 
0015 #include "ap_bus.h"
0016 #include "zcrypt_api.h"
0017 #include "zcrypt_msgtype6.h"
0018 #include "zcrypt_msgtype50.h"
0019 #include "zcrypt_error.h"
0020 #include "zcrypt_cex4.h"
0021 #include "zcrypt_ccamisc.h"
0022 #include "zcrypt_ep11misc.h"
0023 
0024 #define CEX4A_MIN_MOD_SIZE    1 /*    8 bits    */
0025 #define CEX4A_MAX_MOD_SIZE_2K   256 /* 2048 bits    */
0026 #define CEX4A_MAX_MOD_SIZE_4K   512 /* 4096 bits    */
0027 
0028 #define CEX4C_MIN_MOD_SIZE   16 /*  256 bits    */
0029 #define CEX4C_MAX_MOD_SIZE  512 /* 4096 bits    */
0030 
0031 /* Waiting time for requests to be processed.
0032  * Currently there are some types of request which are not deterministic.
0033  * But the maximum time limit managed by the stomper code is set to 60sec.
0034  * Hence we have to wait at least that time period.
0035  */
0036 #define CEX4_CLEANUP_TIME   (900 * HZ)
0037 
0038 MODULE_AUTHOR("IBM Corporation");
0039 MODULE_DESCRIPTION("CEX[45678] Cryptographic Card device driver, " \
0040            "Copyright IBM Corp. 2022");
0041 MODULE_LICENSE("GPL");
0042 
0043 static struct ap_device_id zcrypt_cex4_card_ids[] = {
0044     { .dev_type = AP_DEVICE_TYPE_CEX4,
0045       .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
0046     { .dev_type = AP_DEVICE_TYPE_CEX5,
0047       .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
0048     { .dev_type = AP_DEVICE_TYPE_CEX6,
0049       .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
0050     { .dev_type = AP_DEVICE_TYPE_CEX7,
0051       .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
0052     { .dev_type = AP_DEVICE_TYPE_CEX8,
0053       .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
0054     { /* end of list */ },
0055 };
0056 
0057 MODULE_DEVICE_TABLE(ap, zcrypt_cex4_card_ids);
0058 
0059 static struct ap_device_id zcrypt_cex4_queue_ids[] = {
0060     { .dev_type = AP_DEVICE_TYPE_CEX4,
0061       .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
0062     { .dev_type = AP_DEVICE_TYPE_CEX5,
0063       .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
0064     { .dev_type = AP_DEVICE_TYPE_CEX6,
0065       .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
0066     { .dev_type = AP_DEVICE_TYPE_CEX7,
0067       .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
0068     { .dev_type = AP_DEVICE_TYPE_CEX8,
0069       .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
0070     { /* end of list */ },
0071 };
0072 
0073 MODULE_DEVICE_TABLE(ap, zcrypt_cex4_queue_ids);
0074 
0075 /*
0076  * CCA card additional device attributes
0077  */
0078 static ssize_t cca_serialnr_show(struct device *dev,
0079                  struct device_attribute *attr,
0080                  char *buf)
0081 {
0082     struct zcrypt_card *zc = dev_get_drvdata(dev);
0083     struct cca_info ci;
0084     struct ap_card *ac = to_ap_card(dev);
0085 
0086     memset(&ci, 0, sizeof(ci));
0087 
0088     if (ap_domain_index >= 0)
0089         cca_get_info(ac->id, ap_domain_index, &ci, zc->online);
0090 
0091     return scnprintf(buf, PAGE_SIZE, "%s\n", ci.serial);
0092 }
0093 
0094 static struct device_attribute dev_attr_cca_serialnr =
0095     __ATTR(serialnr, 0444, cca_serialnr_show, NULL);
0096 
0097 static struct attribute *cca_card_attrs[] = {
0098     &dev_attr_cca_serialnr.attr,
0099     NULL,
0100 };
0101 
0102 static const struct attribute_group cca_card_attr_grp = {
0103     .attrs = cca_card_attrs,
0104 };
0105 
0106  /*
0107   * CCA queue additional device attributes
0108   */
0109 static ssize_t cca_mkvps_show(struct device *dev,
0110                   struct device_attribute *attr,
0111                   char *buf)
0112 {
0113     struct zcrypt_queue *zq = dev_get_drvdata(dev);
0114     int n = 0;
0115     struct cca_info ci;
0116     static const char * const cao_state[] = { "invalid", "valid" };
0117     static const char * const new_state[] = { "empty", "partial", "full" };
0118 
0119     memset(&ci, 0, sizeof(ci));
0120 
0121     cca_get_info(AP_QID_CARD(zq->queue->qid),
0122              AP_QID_QUEUE(zq->queue->qid),
0123              &ci, zq->online);
0124 
0125     if (ci.new_aes_mk_state >= '1' && ci.new_aes_mk_state <= '3')
0126         n += scnprintf(buf + n, PAGE_SIZE,
0127                    "AES NEW: %s 0x%016llx\n",
0128                    new_state[ci.new_aes_mk_state - '1'],
0129                    ci.new_aes_mkvp);
0130     else
0131         n += scnprintf(buf + n, PAGE_SIZE, "AES NEW: - -\n");
0132 
0133     if (ci.cur_aes_mk_state >= '1' && ci.cur_aes_mk_state <= '2')
0134         n += scnprintf(buf + n, PAGE_SIZE - n,
0135                    "AES CUR: %s 0x%016llx\n",
0136                    cao_state[ci.cur_aes_mk_state - '1'],
0137                    ci.cur_aes_mkvp);
0138     else
0139         n += scnprintf(buf + n, PAGE_SIZE - n, "AES CUR: - -\n");
0140 
0141     if (ci.old_aes_mk_state >= '1' && ci.old_aes_mk_state <= '2')
0142         n += scnprintf(buf + n, PAGE_SIZE - n,
0143                    "AES OLD: %s 0x%016llx\n",
0144                    cao_state[ci.old_aes_mk_state - '1'],
0145                    ci.old_aes_mkvp);
0146     else
0147         n += scnprintf(buf + n, PAGE_SIZE - n, "AES OLD: - -\n");
0148 
0149     if (ci.new_apka_mk_state >= '1' && ci.new_apka_mk_state <= '3')
0150         n += scnprintf(buf + n, PAGE_SIZE - n,
0151                    "APKA NEW: %s 0x%016llx\n",
0152                    new_state[ci.new_apka_mk_state - '1'],
0153                    ci.new_apka_mkvp);
0154     else
0155         n += scnprintf(buf + n, PAGE_SIZE - n, "APKA NEW: - -\n");
0156 
0157     if (ci.cur_apka_mk_state >= '1' && ci.cur_apka_mk_state <= '2')
0158         n += scnprintf(buf + n, PAGE_SIZE - n,
0159                    "APKA CUR: %s 0x%016llx\n",
0160                    cao_state[ci.cur_apka_mk_state - '1'],
0161                    ci.cur_apka_mkvp);
0162     else
0163         n += scnprintf(buf + n, PAGE_SIZE - n, "APKA CUR: - -\n");
0164 
0165     if (ci.old_apka_mk_state >= '1' && ci.old_apka_mk_state <= '2')
0166         n += scnprintf(buf + n, PAGE_SIZE - n,
0167                    "APKA OLD: %s 0x%016llx\n",
0168                    cao_state[ci.old_apka_mk_state - '1'],
0169                    ci.old_apka_mkvp);
0170     else
0171         n += scnprintf(buf + n, PAGE_SIZE - n, "APKA OLD: - -\n");
0172 
0173     if (ci.new_asym_mk_state >= '1' && ci.new_asym_mk_state <= '3')
0174         n += scnprintf(buf + n, PAGE_SIZE,
0175                    "ASYM NEW: %s 0x%016llx%016llx\n",
0176                    new_state[ci.new_asym_mk_state - '1'],
0177                    *((u64 *)(ci.new_asym_mkvp)),
0178                    *((u64 *)(ci.new_asym_mkvp + sizeof(u64))));
0179     else
0180         n += scnprintf(buf + n, PAGE_SIZE, "ASYM NEW: - -\n");
0181 
0182     if (ci.cur_asym_mk_state >= '1' && ci.cur_asym_mk_state <= '2')
0183         n += scnprintf(buf + n, PAGE_SIZE - n,
0184                    "ASYM CUR: %s 0x%016llx%016llx\n",
0185                    cao_state[ci.cur_asym_mk_state - '1'],
0186                    *((u64 *)(ci.cur_asym_mkvp)),
0187                    *((u64 *)(ci.cur_asym_mkvp + sizeof(u64))));
0188     else
0189         n += scnprintf(buf + n, PAGE_SIZE - n, "ASYM CUR: - -\n");
0190 
0191     if (ci.old_asym_mk_state >= '1' && ci.old_asym_mk_state <= '2')
0192         n += scnprintf(buf + n, PAGE_SIZE - n,
0193                    "ASYM OLD: %s 0x%016llx%016llx\n",
0194                    cao_state[ci.old_asym_mk_state - '1'],
0195                    *((u64 *)(ci.old_asym_mkvp)),
0196                    *((u64 *)(ci.old_asym_mkvp + sizeof(u64))));
0197     else
0198         n += scnprintf(buf + n, PAGE_SIZE - n, "ASYM OLD: - -\n");
0199 
0200     return n;
0201 }
0202 
0203 static struct device_attribute dev_attr_cca_mkvps =
0204     __ATTR(mkvps, 0444, cca_mkvps_show, NULL);
0205 
0206 static struct attribute *cca_queue_attrs[] = {
0207     &dev_attr_cca_mkvps.attr,
0208     NULL,
0209 };
0210 
0211 static const struct attribute_group cca_queue_attr_grp = {
0212     .attrs = cca_queue_attrs,
0213 };
0214 
0215 /*
0216  * EP11 card additional device attributes
0217  */
0218 static ssize_t ep11_api_ordinalnr_show(struct device *dev,
0219                        struct device_attribute *attr,
0220                        char *buf)
0221 {
0222     struct zcrypt_card *zc = dev_get_drvdata(dev);
0223     struct ep11_card_info ci;
0224     struct ap_card *ac = to_ap_card(dev);
0225 
0226     memset(&ci, 0, sizeof(ci));
0227 
0228     ep11_get_card_info(ac->id, &ci, zc->online);
0229 
0230     if (ci.API_ord_nr > 0)
0231         return scnprintf(buf, PAGE_SIZE, "%u\n", ci.API_ord_nr);
0232     else
0233         return scnprintf(buf, PAGE_SIZE, "\n");
0234 }
0235 
0236 static struct device_attribute dev_attr_ep11_api_ordinalnr =
0237     __ATTR(API_ordinalnr, 0444, ep11_api_ordinalnr_show, NULL);
0238 
0239 static ssize_t ep11_fw_version_show(struct device *dev,
0240                     struct device_attribute *attr,
0241                     char *buf)
0242 {
0243     struct zcrypt_card *zc = dev_get_drvdata(dev);
0244     struct ep11_card_info ci;
0245     struct ap_card *ac = to_ap_card(dev);
0246 
0247     memset(&ci, 0, sizeof(ci));
0248 
0249     ep11_get_card_info(ac->id, &ci, zc->online);
0250 
0251     if (ci.FW_version > 0)
0252         return scnprintf(buf, PAGE_SIZE, "%d.%d\n",
0253                  (int)(ci.FW_version >> 8),
0254                  (int)(ci.FW_version & 0xFF));
0255     else
0256         return scnprintf(buf, PAGE_SIZE, "\n");
0257 }
0258 
0259 static struct device_attribute dev_attr_ep11_fw_version =
0260     __ATTR(FW_version, 0444, ep11_fw_version_show, NULL);
0261 
0262 static ssize_t ep11_serialnr_show(struct device *dev,
0263                   struct device_attribute *attr,
0264                   char *buf)
0265 {
0266     struct zcrypt_card *zc = dev_get_drvdata(dev);
0267     struct ep11_card_info ci;
0268     struct ap_card *ac = to_ap_card(dev);
0269 
0270     memset(&ci, 0, sizeof(ci));
0271 
0272     ep11_get_card_info(ac->id, &ci, zc->online);
0273 
0274     if (ci.serial[0])
0275         return scnprintf(buf, PAGE_SIZE, "%16.16s\n", ci.serial);
0276     else
0277         return scnprintf(buf, PAGE_SIZE, "\n");
0278 }
0279 
0280 static struct device_attribute dev_attr_ep11_serialnr =
0281     __ATTR(serialnr, 0444, ep11_serialnr_show, NULL);
0282 
0283 static const struct {
0284     int     mode_bit;
0285     const char *mode_txt;
0286 } ep11_op_modes[] = {
0287     { 0, "FIPS2009" },
0288     { 1, "BSI2009" },
0289     { 2, "FIPS2011" },
0290     { 3, "BSI2011" },
0291     { 6, "BSICC2017" },
0292     { 0, NULL }
0293 };
0294 
0295 static ssize_t ep11_card_op_modes_show(struct device *dev,
0296                        struct device_attribute *attr,
0297                        char *buf)
0298 {
0299     struct zcrypt_card *zc = dev_get_drvdata(dev);
0300     int i, n = 0;
0301     struct ep11_card_info ci;
0302     struct ap_card *ac = to_ap_card(dev);
0303 
0304     memset(&ci, 0, sizeof(ci));
0305 
0306     ep11_get_card_info(ac->id, &ci, zc->online);
0307 
0308     for (i = 0; ep11_op_modes[i].mode_txt; i++) {
0309         if (ci.op_mode & (1ULL << ep11_op_modes[i].mode_bit)) {
0310             if (n > 0)
0311                 buf[n++] = ' ';
0312             n += scnprintf(buf + n, PAGE_SIZE - n,
0313                        "%s", ep11_op_modes[i].mode_txt);
0314         }
0315     }
0316     n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
0317 
0318     return n;
0319 }
0320 
0321 static struct device_attribute dev_attr_ep11_card_op_modes =
0322     __ATTR(op_modes, 0444, ep11_card_op_modes_show, NULL);
0323 
0324 static struct attribute *ep11_card_attrs[] = {
0325     &dev_attr_ep11_api_ordinalnr.attr,
0326     &dev_attr_ep11_fw_version.attr,
0327     &dev_attr_ep11_serialnr.attr,
0328     &dev_attr_ep11_card_op_modes.attr,
0329     NULL,
0330 };
0331 
0332 static const struct attribute_group ep11_card_attr_grp = {
0333     .attrs = ep11_card_attrs,
0334 };
0335 
0336 /*
0337  * EP11 queue additional device attributes
0338  */
0339 
0340 static ssize_t ep11_mkvps_show(struct device *dev,
0341                    struct device_attribute *attr,
0342                    char *buf)
0343 {
0344     struct zcrypt_queue *zq = dev_get_drvdata(dev);
0345     int n = 0;
0346     struct ep11_domain_info di;
0347     static const char * const cwk_state[] = { "invalid", "valid" };
0348     static const char * const nwk_state[] = { "empty", "uncommitted",
0349                           "committed" };
0350 
0351     memset(&di, 0, sizeof(di));
0352 
0353     if (zq->online)
0354         ep11_get_domain_info(AP_QID_CARD(zq->queue->qid),
0355                      AP_QID_QUEUE(zq->queue->qid),
0356                      &di);
0357 
0358     if (di.cur_wk_state == '0') {
0359         n = scnprintf(buf, PAGE_SIZE, "WK CUR: %s -\n",
0360                   cwk_state[di.cur_wk_state - '0']);
0361     } else if (di.cur_wk_state == '1') {
0362         n = scnprintf(buf, PAGE_SIZE, "WK CUR: %s 0x",
0363                   cwk_state[di.cur_wk_state - '0']);
0364         bin2hex(buf + n, di.cur_wkvp, sizeof(di.cur_wkvp));
0365         n += 2 * sizeof(di.cur_wkvp);
0366         n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
0367     } else {
0368         n = scnprintf(buf, PAGE_SIZE, "WK CUR: - -\n");
0369     }
0370 
0371     if (di.new_wk_state == '0') {
0372         n += scnprintf(buf + n, PAGE_SIZE - n, "WK NEW: %s -\n",
0373                    nwk_state[di.new_wk_state - '0']);
0374     } else if (di.new_wk_state >= '1' && di.new_wk_state <= '2') {
0375         n += scnprintf(buf + n, PAGE_SIZE - n, "WK NEW: %s 0x",
0376                    nwk_state[di.new_wk_state - '0']);
0377         bin2hex(buf + n, di.new_wkvp, sizeof(di.new_wkvp));
0378         n += 2 * sizeof(di.new_wkvp);
0379         n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
0380     } else {
0381         n += scnprintf(buf + n, PAGE_SIZE - n, "WK NEW: - -\n");
0382     }
0383 
0384     return n;
0385 }
0386 
0387 static struct device_attribute dev_attr_ep11_mkvps =
0388     __ATTR(mkvps, 0444, ep11_mkvps_show, NULL);
0389 
0390 static ssize_t ep11_queue_op_modes_show(struct device *dev,
0391                     struct device_attribute *attr,
0392                     char *buf)
0393 {
0394     struct zcrypt_queue *zq = dev_get_drvdata(dev);
0395     int i, n = 0;
0396     struct ep11_domain_info di;
0397 
0398     memset(&di, 0, sizeof(di));
0399 
0400     if (zq->online)
0401         ep11_get_domain_info(AP_QID_CARD(zq->queue->qid),
0402                      AP_QID_QUEUE(zq->queue->qid),
0403                      &di);
0404 
0405     for (i = 0; ep11_op_modes[i].mode_txt; i++) {
0406         if (di.op_mode & (1ULL << ep11_op_modes[i].mode_bit)) {
0407             if (n > 0)
0408                 buf[n++] = ' ';
0409             n += scnprintf(buf + n, PAGE_SIZE - n,
0410                        "%s", ep11_op_modes[i].mode_txt);
0411         }
0412     }
0413     n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
0414 
0415     return n;
0416 }
0417 
0418 static struct device_attribute dev_attr_ep11_queue_op_modes =
0419     __ATTR(op_modes, 0444, ep11_queue_op_modes_show, NULL);
0420 
0421 static struct attribute *ep11_queue_attrs[] = {
0422     &dev_attr_ep11_mkvps.attr,
0423     &dev_attr_ep11_queue_op_modes.attr,
0424     NULL,
0425 };
0426 
0427 static const struct attribute_group ep11_queue_attr_grp = {
0428     .attrs = ep11_queue_attrs,
0429 };
0430 
0431 /*
0432  * Probe function for CEX[45678] card device. It always
0433  * accepts the AP device since the bus_match already checked
0434  * the hardware type.
0435  * @ap_dev: pointer to the AP device.
0436  */
0437 static int zcrypt_cex4_card_probe(struct ap_device *ap_dev)
0438 {
0439     /*
0440      * Normalized speed ratings per crypto adapter
0441      * MEX_1k, MEX_2k, MEX_4k, CRT_1k, CRT_2k, CRT_4k, RNG, SECKEY
0442      */
0443     static const int CEX4A_SPEED_IDX[NUM_OPS] = {
0444          14,  19, 249, 42, 228, 1458, 0, 0};
0445     static const int CEX5A_SPEED_IDX[NUM_OPS] = {
0446           8,   9,  20, 18,  66,  458, 0, 0};
0447     static const int CEX6A_SPEED_IDX[NUM_OPS] = {
0448           6,   9,  20, 17,  65,  438, 0, 0};
0449     static const int CEX7A_SPEED_IDX[NUM_OPS] = {
0450           6,   8,  17, 15,  54,  362, 0, 0};
0451     static const int CEX8A_SPEED_IDX[NUM_OPS] = {
0452           6,   8,  17, 15,  54,  362, 0, 0};
0453 
0454     static const int CEX4C_SPEED_IDX[NUM_OPS] = {
0455          59,  69, 308, 83, 278, 2204, 209, 40};
0456     static const int CEX5C_SPEED_IDX[] = {
0457          24,  31,  50, 37,  90,  479,  27, 10};
0458     static const int CEX6C_SPEED_IDX[NUM_OPS] = {
0459          16,  20,  32, 27,  77,  455,  24,  9};
0460     static const int CEX7C_SPEED_IDX[NUM_OPS] = {
0461          14,  16,  26, 23,  64,  376,  23,  8};
0462     static const int CEX8C_SPEED_IDX[NUM_OPS] = {
0463          14,  16,  26, 23,  64,  376,  23,  8};
0464 
0465     static const int CEX4P_SPEED_IDX[NUM_OPS] = {
0466           0,   0,   0,   0,   0,   0,   0,  50};
0467     static const int CEX5P_SPEED_IDX[NUM_OPS] = {
0468           0,   0,   0,   0,   0,   0,   0,  10};
0469     static const int CEX6P_SPEED_IDX[NUM_OPS] = {
0470           0,   0,   0,   0,   0,   0,   0,   9};
0471     static const int CEX7P_SPEED_IDX[NUM_OPS] = {
0472           0,   0,   0,   0,   0,   0,   0,   8};
0473     static const int CEX8P_SPEED_IDX[NUM_OPS] = {
0474           0,   0,   0,   0,   0,   0,   0,   8};
0475 
0476     struct ap_card *ac = to_ap_card(&ap_dev->device);
0477     struct zcrypt_card *zc;
0478     int rc = 0;
0479 
0480     zc = zcrypt_card_alloc();
0481     if (!zc)
0482         return -ENOMEM;
0483     zc->card = ac;
0484     dev_set_drvdata(&ap_dev->device, zc);
0485     if (ap_test_bit(&ac->functions, AP_FUNC_ACCEL)) {
0486         if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
0487             zc->type_string = "CEX4A";
0488             zc->user_space_type = ZCRYPT_CEX4;
0489             zc->speed_rating = CEX4A_SPEED_IDX;
0490         } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {
0491             zc->type_string = "CEX5A";
0492             zc->user_space_type = ZCRYPT_CEX5;
0493             zc->speed_rating = CEX5A_SPEED_IDX;
0494         } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {
0495             zc->type_string = "CEX6A";
0496             zc->user_space_type = ZCRYPT_CEX6;
0497             zc->speed_rating = CEX6A_SPEED_IDX;
0498         } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX7) {
0499             zc->type_string = "CEX7A";
0500             zc->speed_rating = CEX7A_SPEED_IDX;
0501             /* wrong user space type, just for compatibility
0502              * with the ZCRYPT_STATUS_MASK ioctl.
0503              */
0504             zc->user_space_type = ZCRYPT_CEX6;
0505         } else {
0506             zc->type_string = "CEX8A";
0507             zc->speed_rating = CEX8A_SPEED_IDX;
0508             /* wrong user space type, just for compatibility
0509              * with the ZCRYPT_STATUS_MASK ioctl.
0510              */
0511             zc->user_space_type = ZCRYPT_CEX6;
0512         }
0513         zc->min_mod_size = CEX4A_MIN_MOD_SIZE;
0514         if (ap_test_bit(&ac->functions, AP_FUNC_MEX4K) &&
0515             ap_test_bit(&ac->functions, AP_FUNC_CRT4K)) {
0516             zc->max_mod_size = CEX4A_MAX_MOD_SIZE_4K;
0517             zc->max_exp_bit_length =
0518                 CEX4A_MAX_MOD_SIZE_4K;
0519         } else {
0520             zc->max_mod_size = CEX4A_MAX_MOD_SIZE_2K;
0521             zc->max_exp_bit_length =
0522                 CEX4A_MAX_MOD_SIZE_2K;
0523         }
0524     } else if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) {
0525         if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
0526             zc->type_string = "CEX4C";
0527             zc->speed_rating = CEX4C_SPEED_IDX;
0528             /* wrong user space type, must be CEX3C
0529              * just keep it for cca compatibility
0530              */
0531             zc->user_space_type = ZCRYPT_CEX3C;
0532         } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {
0533             zc->type_string = "CEX5C";
0534             zc->speed_rating = CEX5C_SPEED_IDX;
0535             /* wrong user space type, must be CEX3C
0536              * just keep it for cca compatibility
0537              */
0538             zc->user_space_type = ZCRYPT_CEX3C;
0539         } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {
0540             zc->type_string = "CEX6C";
0541             zc->speed_rating = CEX6C_SPEED_IDX;
0542             /* wrong user space type, must be CEX3C
0543              * just keep it for cca compatibility
0544              */
0545             zc->user_space_type = ZCRYPT_CEX3C;
0546         } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX7) {
0547             zc->type_string = "CEX7C";
0548             zc->speed_rating = CEX7C_SPEED_IDX;
0549             /* wrong user space type, must be CEX3C
0550              * just keep it for cca compatibility
0551              */
0552             zc->user_space_type = ZCRYPT_CEX3C;
0553         } else {
0554             zc->type_string = "CEX8C";
0555             zc->speed_rating = CEX8C_SPEED_IDX;
0556             /* wrong user space type, must be CEX3C
0557              * just keep it for cca compatibility
0558              */
0559             zc->user_space_type = ZCRYPT_CEX3C;
0560         }
0561         zc->min_mod_size = CEX4C_MIN_MOD_SIZE;
0562         zc->max_mod_size = CEX4C_MAX_MOD_SIZE;
0563         zc->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;
0564     } else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) {
0565         if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
0566             zc->type_string = "CEX4P";
0567             zc->user_space_type = ZCRYPT_CEX4;
0568             zc->speed_rating = CEX4P_SPEED_IDX;
0569         } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {
0570             zc->type_string = "CEX5P";
0571             zc->user_space_type = ZCRYPT_CEX5;
0572             zc->speed_rating = CEX5P_SPEED_IDX;
0573         } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {
0574             zc->type_string = "CEX6P";
0575             zc->user_space_type = ZCRYPT_CEX6;
0576             zc->speed_rating = CEX6P_SPEED_IDX;
0577         } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX7) {
0578             zc->type_string = "CEX7P";
0579             zc->speed_rating = CEX7P_SPEED_IDX;
0580             /* wrong user space type, just for compatibility
0581              * with the ZCRYPT_STATUS_MASK ioctl.
0582              */
0583             zc->user_space_type = ZCRYPT_CEX6;
0584         } else {
0585             zc->type_string = "CEX8P";
0586             zc->speed_rating = CEX8P_SPEED_IDX;
0587             /* wrong user space type, just for compatibility
0588              * with the ZCRYPT_STATUS_MASK ioctl.
0589              */
0590             zc->user_space_type = ZCRYPT_CEX6;
0591         }
0592         zc->min_mod_size = CEX4C_MIN_MOD_SIZE;
0593         zc->max_mod_size = CEX4C_MAX_MOD_SIZE;
0594         zc->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;
0595     } else {
0596         zcrypt_card_free(zc);
0597         return -ENODEV;
0598     }
0599     zc->online = 1;
0600 
0601     rc = zcrypt_card_register(zc);
0602     if (rc) {
0603         zcrypt_card_free(zc);
0604         return rc;
0605     }
0606 
0607     if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) {
0608         rc = sysfs_create_group(&ap_dev->device.kobj,
0609                     &cca_card_attr_grp);
0610         if (rc) {
0611             zcrypt_card_unregister(zc);
0612             zcrypt_card_free(zc);
0613         }
0614     } else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) {
0615         rc = sysfs_create_group(&ap_dev->device.kobj,
0616                     &ep11_card_attr_grp);
0617         if (rc) {
0618             zcrypt_card_unregister(zc);
0619             zcrypt_card_free(zc);
0620         }
0621     }
0622 
0623     return rc;
0624 }
0625 
0626 /*
0627  * This is called to remove the CEX[45678] card driver
0628  * information if an AP card device is removed.
0629  */
0630 static void zcrypt_cex4_card_remove(struct ap_device *ap_dev)
0631 {
0632     struct zcrypt_card *zc = dev_get_drvdata(&ap_dev->device);
0633     struct ap_card *ac = to_ap_card(&ap_dev->device);
0634 
0635     if (ap_test_bit(&ac->functions, AP_FUNC_COPRO))
0636         sysfs_remove_group(&ap_dev->device.kobj, &cca_card_attr_grp);
0637     else if (ap_test_bit(&ac->functions, AP_FUNC_EP11))
0638         sysfs_remove_group(&ap_dev->device.kobj, &ep11_card_attr_grp);
0639 
0640     zcrypt_card_unregister(zc);
0641 }
0642 
0643 static struct ap_driver zcrypt_cex4_card_driver = {
0644     .probe = zcrypt_cex4_card_probe,
0645     .remove = zcrypt_cex4_card_remove,
0646     .ids = zcrypt_cex4_card_ids,
0647     .flags = AP_DRIVER_FLAG_DEFAULT,
0648 };
0649 
0650 /*
0651  * Probe function for CEX[45678] queue device. It always
0652  * accepts the AP device since the bus_match already checked
0653  * the hardware type.
0654  * @ap_dev: pointer to the AP device.
0655  */
0656 static int zcrypt_cex4_queue_probe(struct ap_device *ap_dev)
0657 {
0658     struct ap_queue *aq = to_ap_queue(&ap_dev->device);
0659     struct zcrypt_queue *zq;
0660     int rc;
0661 
0662     if (ap_test_bit(&aq->card->functions, AP_FUNC_ACCEL)) {
0663         zq = zcrypt_queue_alloc(aq->card->maxmsgsize);
0664         if (!zq)
0665             return -ENOMEM;
0666         zq->ops = zcrypt_msgtype(MSGTYPE50_NAME,
0667                      MSGTYPE50_VARIANT_DEFAULT);
0668     } else if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) {
0669         zq = zcrypt_queue_alloc(aq->card->maxmsgsize);
0670         if (!zq)
0671             return -ENOMEM;
0672         zq->ops = zcrypt_msgtype(MSGTYPE06_NAME,
0673                      MSGTYPE06_VARIANT_DEFAULT);
0674     } else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) {
0675         zq = zcrypt_queue_alloc(aq->card->maxmsgsize);
0676         if (!zq)
0677             return -ENOMEM;
0678         zq->ops = zcrypt_msgtype(MSGTYPE06_NAME,
0679                      MSGTYPE06_VARIANT_EP11);
0680     } else {
0681         return -ENODEV;
0682     }
0683 
0684     zq->queue = aq;
0685     zq->online = 1;
0686     atomic_set(&zq->load, 0);
0687     ap_queue_init_state(aq);
0688     ap_queue_init_reply(aq, &zq->reply);
0689     aq->request_timeout = CEX4_CLEANUP_TIME;
0690     dev_set_drvdata(&ap_dev->device, zq);
0691     rc = zcrypt_queue_register(zq);
0692     if (rc) {
0693         zcrypt_queue_free(zq);
0694         return rc;
0695     }
0696 
0697     if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) {
0698         rc = sysfs_create_group(&ap_dev->device.kobj,
0699                     &cca_queue_attr_grp);
0700         if (rc) {
0701             zcrypt_queue_unregister(zq);
0702             zcrypt_queue_free(zq);
0703         }
0704     } else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) {
0705         rc = sysfs_create_group(&ap_dev->device.kobj,
0706                     &ep11_queue_attr_grp);
0707         if (rc) {
0708             zcrypt_queue_unregister(zq);
0709             zcrypt_queue_free(zq);
0710         }
0711     }
0712 
0713     return rc;
0714 }
0715 
0716 /*
0717  * This is called to remove the CEX[45678] queue driver
0718  * information if an AP queue device is removed.
0719  */
0720 static void zcrypt_cex4_queue_remove(struct ap_device *ap_dev)
0721 {
0722     struct zcrypt_queue *zq = dev_get_drvdata(&ap_dev->device);
0723     struct ap_queue *aq = to_ap_queue(&ap_dev->device);
0724 
0725     if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO))
0726         sysfs_remove_group(&ap_dev->device.kobj, &cca_queue_attr_grp);
0727     else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11))
0728         sysfs_remove_group(&ap_dev->device.kobj, &ep11_queue_attr_grp);
0729 
0730     zcrypt_queue_unregister(zq);
0731 }
0732 
0733 static struct ap_driver zcrypt_cex4_queue_driver = {
0734     .probe = zcrypt_cex4_queue_probe,
0735     .remove = zcrypt_cex4_queue_remove,
0736     .ids = zcrypt_cex4_queue_ids,
0737     .flags = AP_DRIVER_FLAG_DEFAULT,
0738 };
0739 
0740 int __init zcrypt_cex4_init(void)
0741 {
0742     int rc;
0743 
0744     rc = ap_driver_register(&zcrypt_cex4_card_driver,
0745                 THIS_MODULE, "cex4card");
0746     if (rc)
0747         return rc;
0748 
0749     rc = ap_driver_register(&zcrypt_cex4_queue_driver,
0750                 THIS_MODULE, "cex4queue");
0751     if (rc)
0752         ap_driver_unregister(&zcrypt_cex4_card_driver);
0753 
0754     return rc;
0755 }
0756 
0757 void __exit zcrypt_cex4_exit(void)
0758 {
0759     ap_driver_unregister(&zcrypt_cex4_queue_driver);
0760     ap_driver_unregister(&zcrypt_cex4_card_driver);
0761 }
0762 
0763 module_init(zcrypt_cex4_init);
0764 module_exit(zcrypt_cex4_exit);