0001
0002
0003
0004
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
0025 #define CEX4A_MAX_MOD_SIZE_2K 256
0026 #define CEX4A_MAX_MOD_SIZE_4K 512
0027
0028 #define CEX4C_MIN_MOD_SIZE 16
0029 #define CEX4C_MAX_MOD_SIZE 512
0030
0031
0032
0033
0034
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 { },
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 { },
0071 };
0072
0073 MODULE_DEVICE_TABLE(ap, zcrypt_cex4_queue_ids);
0074
0075
0076
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
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
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
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
0433
0434
0435
0436
0437 static int zcrypt_cex4_card_probe(struct ap_device *ap_dev)
0438 {
0439
0440
0441
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
0502
0503
0504 zc->user_space_type = ZCRYPT_CEX6;
0505 } else {
0506 zc->type_string = "CEX8A";
0507 zc->speed_rating = CEX8A_SPEED_IDX;
0508
0509
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
0529
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
0536
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
0543
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
0550
0551
0552 zc->user_space_type = ZCRYPT_CEX3C;
0553 } else {
0554 zc->type_string = "CEX8C";
0555 zc->speed_rating = CEX8C_SPEED_IDX;
0556
0557
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
0581
0582
0583 zc->user_space_type = ZCRYPT_CEX6;
0584 } else {
0585 zc->type_string = "CEX8P";
0586 zc->speed_rating = CEX8P_SPEED_IDX;
0587
0588
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
0628
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
0652
0653
0654
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
0718
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);