zcrypt_cex4.c 22.0 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
 *  Copyright IBM Corp. 2012, 2022
4 5 6 7 8 9 10 11 12
 *  Author(s): Holger Dengler <hd@linux.vnet.ibm.com>
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/atomic.h>
#include <linux/uaccess.h>
13
#include <linux/mod_devicetable.h>
14 15 16 17 18 19 20

#include "ap_bus.h"
#include "zcrypt_api.h"
#include "zcrypt_msgtype6.h"
#include "zcrypt_msgtype50.h"
#include "zcrypt_error.h"
#include "zcrypt_cex4.h"
21
#include "zcrypt_ccamisc.h"
22
#include "zcrypt_ep11misc.h"
23 24 25 26 27 28 29 30

#define CEX4A_MIN_MOD_SIZE	  1	/*    8 bits	*/
#define CEX4A_MAX_MOD_SIZE_2K	256	/* 2048 bits	*/
#define CEX4A_MAX_MOD_SIZE_4K	512	/* 4096 bits	*/

#define CEX4C_MIN_MOD_SIZE	 16	/*  256 bits	*/
#define CEX4C_MAX_MOD_SIZE	512	/* 4096 bits	*/

31 32 33 34 35
/* Waiting time for requests to be processed.
 * Currently there are some types of request which are not deterministic.
 * But the maximum time limit managed by the stomper code is set to 60sec.
 * Hence we have to wait at least that time period.
 */
H
Harald Freudenberger 已提交
36
#define CEX4_CLEANUP_TIME	(900 * HZ)
37 38

MODULE_AUTHOR("IBM Corporation");
39 40
MODULE_DESCRIPTION("CEX[45678] Cryptographic Card device driver, " \
		   "Copyright IBM Corp. 2022");
41 42
MODULE_LICENSE("GPL");

43 44 45 46 47
static struct ap_device_id zcrypt_cex4_card_ids[] = {
	{ .dev_type = AP_DEVICE_TYPE_CEX4,
	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
	{ .dev_type = AP_DEVICE_TYPE_CEX5,
	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
48 49
	{ .dev_type = AP_DEVICE_TYPE_CEX6,
	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
50 51
	{ .dev_type = AP_DEVICE_TYPE_CEX7,
	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
52 53
	{ .dev_type = AP_DEVICE_TYPE_CEX8,
	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
54 55 56 57
	{ /* end of list */ },
};

MODULE_DEVICE_TABLE(ap, zcrypt_cex4_card_ids);
58

59 60 61 62 63
static struct ap_device_id zcrypt_cex4_queue_ids[] = {
	{ .dev_type = AP_DEVICE_TYPE_CEX4,
	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
	{ .dev_type = AP_DEVICE_TYPE_CEX5,
	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
64 65
	{ .dev_type = AP_DEVICE_TYPE_CEX6,
	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
66 67
	{ .dev_type = AP_DEVICE_TYPE_CEX7,
	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
68 69
	{ .dev_type = AP_DEVICE_TYPE_CEX8,
	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
70
	{ /* end of list */ },
71 72
};

73 74
MODULE_DEVICE_TABLE(ap, zcrypt_cex4_queue_ids);

75
/*
76
 * CCA card additional device attributes
77
 */
78 79 80
static ssize_t cca_serialnr_show(struct device *dev,
				 struct device_attribute *attr,
				 char *buf)
81
{
82
	struct zcrypt_card *zc = dev_get_drvdata(dev);
83 84 85 86 87 88 89 90
	struct cca_info ci;
	struct ap_card *ac = to_ap_card(dev);

	memset(&ci, 0, sizeof(ci));

	if (ap_domain_index >= 0)
		cca_get_info(ac->id, ap_domain_index, &ci, zc->online);

91
	return scnprintf(buf, PAGE_SIZE, "%s\n", ci.serial);
92
}
93 94 95

static struct device_attribute dev_attr_cca_serialnr =
	__ATTR(serialnr, 0444, cca_serialnr_show, NULL);
96 97

static struct attribute *cca_card_attrs[] = {
98
	&dev_attr_cca_serialnr.attr,
99 100 101
	NULL,
};

102
static const struct attribute_group cca_card_attr_grp = {
103 104 105
	.attrs = cca_card_attrs,
};

106 107 108 109 110 111
 /*
  * CCA queue additional device attributes
  */
static ssize_t cca_mkvps_show(struct device *dev,
			      struct device_attribute *attr,
			      char *buf)
112
{
113
	struct zcrypt_queue *zq = dev_get_drvdata(dev);
114 115 116 117 118 119 120 121 122 123 124
	int n = 0;
	struct cca_info ci;
	static const char * const cao_state[] = { "invalid", "valid" };
	static const char * const new_state[] = { "empty", "partial", "full" };

	memset(&ci, 0, sizeof(ci));

	cca_get_info(AP_QID_CARD(zq->queue->qid),
		     AP_QID_QUEUE(zq->queue->qid),
		     &ci, zq->online);

125
	if (ci.new_aes_mk_state >= '1' && ci.new_aes_mk_state <= '3')
126 127 128 129
		n += scnprintf(buf + n, PAGE_SIZE,
			       "AES NEW: %s 0x%016llx\n",
			       new_state[ci.new_aes_mk_state - '1'],
			       ci.new_aes_mkvp);
130
	else
131
		n += scnprintf(buf + n, PAGE_SIZE, "AES NEW: - -\n");
132

133
	if (ci.cur_aes_mk_state >= '1' && ci.cur_aes_mk_state <= '2')
134 135
		n += scnprintf(buf + n, PAGE_SIZE - n,
			       "AES CUR: %s 0x%016llx\n",
136 137
			       cao_state[ci.cur_aes_mk_state - '1'],
			       ci.cur_aes_mkvp);
138
	else
139
		n += scnprintf(buf + n, PAGE_SIZE - n, "AES CUR: - -\n");
140

141
	if (ci.old_aes_mk_state >= '1' && ci.old_aes_mk_state <= '2')
142 143
		n += scnprintf(buf + n, PAGE_SIZE - n,
			       "AES OLD: %s 0x%016llx\n",
144 145
			       cao_state[ci.old_aes_mk_state - '1'],
			       ci.old_aes_mkvp);
146
	else
147
		n += scnprintf(buf + n, PAGE_SIZE - n, "AES OLD: - -\n");
148

149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
	if (ci.new_apka_mk_state >= '1' && ci.new_apka_mk_state <= '3')
		n += scnprintf(buf + n, PAGE_SIZE - n,
			       "APKA NEW: %s 0x%016llx\n",
			       new_state[ci.new_apka_mk_state - '1'],
			       ci.new_apka_mkvp);
	else
		n += scnprintf(buf + n, PAGE_SIZE - n, "APKA NEW: - -\n");

	if (ci.cur_apka_mk_state >= '1' && ci.cur_apka_mk_state <= '2')
		n += scnprintf(buf + n, PAGE_SIZE - n,
			       "APKA CUR: %s 0x%016llx\n",
			       cao_state[ci.cur_apka_mk_state - '1'],
			       ci.cur_apka_mkvp);
	else
		n += scnprintf(buf + n, PAGE_SIZE - n, "APKA CUR: - -\n");

	if (ci.old_apka_mk_state >= '1' && ci.old_apka_mk_state <= '2')
		n += scnprintf(buf + n, PAGE_SIZE - n,
			       "APKA OLD: %s 0x%016llx\n",
			       cao_state[ci.old_apka_mk_state - '1'],
			       ci.old_apka_mkvp);
	else
		n += scnprintf(buf + n, PAGE_SIZE - n, "APKA OLD: - -\n");

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
	if (ci.new_asym_mk_state >= '1' && ci.new_asym_mk_state <= '3')
		n += scnprintf(buf + n, PAGE_SIZE,
			       "ASYM NEW: %s 0x%016llx%016llx\n",
			       new_state[ci.new_asym_mk_state - '1'],
			       *((u64 *)(ci.new_asym_mkvp)),
			       *((u64 *)(ci.new_asym_mkvp + sizeof(u64))));
	else
		n += scnprintf(buf + n, PAGE_SIZE, "ASYM NEW: - -\n");

	if (ci.cur_asym_mk_state >= '1' && ci.cur_asym_mk_state <= '2')
		n += scnprintf(buf + n, PAGE_SIZE - n,
			       "ASYM CUR: %s 0x%016llx%016llx\n",
			       cao_state[ci.cur_asym_mk_state - '1'],
			       *((u64 *)(ci.cur_asym_mkvp)),
			       *((u64 *)(ci.cur_asym_mkvp + sizeof(u64))));
	else
		n += scnprintf(buf + n, PAGE_SIZE - n, "ASYM CUR: - -\n");

	if (ci.old_asym_mk_state >= '1' && ci.old_asym_mk_state <= '2')
		n += scnprintf(buf + n, PAGE_SIZE - n,
			       "ASYM OLD: %s 0x%016llx%016llx\n",
			       cao_state[ci.old_asym_mk_state - '1'],
			       *((u64 *)(ci.old_asym_mkvp)),
			       *((u64 *)(ci.old_asym_mkvp + sizeof(u64))));
	else
		n += scnprintf(buf + n, PAGE_SIZE - n, "ASYM OLD: - -\n");

200 201
	return n;
}
202 203 204

static struct device_attribute dev_attr_cca_mkvps =
	__ATTR(mkvps, 0444, cca_mkvps_show, NULL);
205 206

static struct attribute *cca_queue_attrs[] = {
207
	&dev_attr_cca_mkvps.attr,
208 209 210
	NULL,
};

211
static const struct attribute_group cca_queue_attr_grp = {
212 213 214
	.attrs = cca_queue_attrs,
};

215 216 217 218 219 220 221
/*
 * EP11 card additional device attributes
 */
static ssize_t ep11_api_ordinalnr_show(struct device *dev,
				       struct device_attribute *attr,
				       char *buf)
{
222
	struct zcrypt_card *zc = dev_get_drvdata(dev);
223 224 225 226 227 228 229 230
	struct ep11_card_info ci;
	struct ap_card *ac = to_ap_card(dev);

	memset(&ci, 0, sizeof(ci));

	ep11_get_card_info(ac->id, &ci, zc->online);

	if (ci.API_ord_nr > 0)
231
		return scnprintf(buf, PAGE_SIZE, "%u\n", ci.API_ord_nr);
232
	else
233
		return scnprintf(buf, PAGE_SIZE, "\n");
234 235 236 237 238 239 240 241 242
}

static struct device_attribute dev_attr_ep11_api_ordinalnr =
	__ATTR(API_ordinalnr, 0444, ep11_api_ordinalnr_show, NULL);

static ssize_t ep11_fw_version_show(struct device *dev,
				    struct device_attribute *attr,
				    char *buf)
{
243
	struct zcrypt_card *zc = dev_get_drvdata(dev);
244 245 246 247 248 249 250 251
	struct ep11_card_info ci;
	struct ap_card *ac = to_ap_card(dev);

	memset(&ci, 0, sizeof(ci));

	ep11_get_card_info(ac->id, &ci, zc->online);

	if (ci.FW_version > 0)
252 253 254
		return scnprintf(buf, PAGE_SIZE, "%d.%d\n",
				 (int)(ci.FW_version >> 8),
				 (int)(ci.FW_version & 0xFF));
255
	else
256
		return scnprintf(buf, PAGE_SIZE, "\n");
257 258 259 260 261 262 263 264 265
}

static struct device_attribute dev_attr_ep11_fw_version =
	__ATTR(FW_version, 0444, ep11_fw_version_show, NULL);

static ssize_t ep11_serialnr_show(struct device *dev,
				  struct device_attribute *attr,
				  char *buf)
{
266
	struct zcrypt_card *zc = dev_get_drvdata(dev);
267 268 269 270 271 272 273 274
	struct ep11_card_info ci;
	struct ap_card *ac = to_ap_card(dev);

	memset(&ci, 0, sizeof(ci));

	ep11_get_card_info(ac->id, &ci, zc->online);

	if (ci.serial[0])
275
		return scnprintf(buf, PAGE_SIZE, "%16.16s\n", ci.serial);
276
	else
277
		return scnprintf(buf, PAGE_SIZE, "\n");
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
}

static struct device_attribute dev_attr_ep11_serialnr =
	__ATTR(serialnr, 0444, ep11_serialnr_show, NULL);

static const struct {
	int	    mode_bit;
	const char *mode_txt;
} ep11_op_modes[] = {
	{ 0, "FIPS2009" },
	{ 1, "BSI2009" },
	{ 2, "FIPS2011" },
	{ 3, "BSI2011" },
	{ 6, "BSICC2017" },
	{ 0, NULL }
};

static ssize_t ep11_card_op_modes_show(struct device *dev,
				       struct device_attribute *attr,
				       char *buf)
{
299
	struct zcrypt_card *zc = dev_get_drvdata(dev);
300 301 302 303 304 305 306 307 308
	int i, n = 0;
	struct ep11_card_info ci;
	struct ap_card *ac = to_ap_card(dev);

	memset(&ci, 0, sizeof(ci));

	ep11_get_card_info(ac->id, &ci, zc->online);

	for (i = 0; ep11_op_modes[i].mode_txt; i++) {
309
		if (ci.op_mode & (1ULL << ep11_op_modes[i].mode_bit)) {
310 311
			if (n > 0)
				buf[n++] = ' ';
312 313
			n += scnprintf(buf + n, PAGE_SIZE - n,
				       "%s", ep11_op_modes[i].mode_txt);
314 315
		}
	}
316
	n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343

	return n;
}

static struct device_attribute dev_attr_ep11_card_op_modes =
	__ATTR(op_modes, 0444, ep11_card_op_modes_show, NULL);

static struct attribute *ep11_card_attrs[] = {
	&dev_attr_ep11_api_ordinalnr.attr,
	&dev_attr_ep11_fw_version.attr,
	&dev_attr_ep11_serialnr.attr,
	&dev_attr_ep11_card_op_modes.attr,
	NULL,
};

static const struct attribute_group ep11_card_attr_grp = {
	.attrs = ep11_card_attrs,
};

/*
 * EP11 queue additional device attributes
 */

static ssize_t ep11_mkvps_show(struct device *dev,
			       struct device_attribute *attr,
			       char *buf)
{
344
	struct zcrypt_queue *zq = dev_get_drvdata(dev);
345 346 347 348 349 350 351 352 353 354 355 356 357 358
	int n = 0;
	struct ep11_domain_info di;
	static const char * const cwk_state[] = { "invalid", "valid" };
	static const char * const nwk_state[] = { "empty", "uncommitted",
						  "committed" };

	memset(&di, 0, sizeof(di));

	if (zq->online)
		ep11_get_domain_info(AP_QID_CARD(zq->queue->qid),
				     AP_QID_QUEUE(zq->queue->qid),
				     &di);

	if (di.cur_wk_state == '0') {
359 360
		n = scnprintf(buf, PAGE_SIZE, "WK CUR: %s -\n",
			      cwk_state[di.cur_wk_state - '0']);
361
	} else if (di.cur_wk_state == '1') {
362 363
		n = scnprintf(buf, PAGE_SIZE, "WK CUR: %s 0x",
			      cwk_state[di.cur_wk_state - '0']);
364 365
		bin2hex(buf + n, di.cur_wkvp, sizeof(di.cur_wkvp));
		n += 2 * sizeof(di.cur_wkvp);
366
		n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
H
Harald Freudenberger 已提交
367
	} else {
368
		n = scnprintf(buf, PAGE_SIZE, "WK CUR: - -\n");
H
Harald Freudenberger 已提交
369
	}
370 371

	if (di.new_wk_state == '0') {
372 373
		n += scnprintf(buf + n, PAGE_SIZE - n, "WK NEW: %s -\n",
			       nwk_state[di.new_wk_state - '0']);
374
	} else if (di.new_wk_state >= '1' && di.new_wk_state <= '2') {
375 376
		n += scnprintf(buf + n, PAGE_SIZE - n, "WK NEW: %s 0x",
			       nwk_state[di.new_wk_state - '0']);
377 378
		bin2hex(buf + n, di.new_wkvp, sizeof(di.new_wkvp));
		n += 2 * sizeof(di.new_wkvp);
379
		n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
H
Harald Freudenberger 已提交
380
	} else {
381
		n += scnprintf(buf + n, PAGE_SIZE - n, "WK NEW: - -\n");
H
Harald Freudenberger 已提交
382
	}
383 384 385 386 387 388 389 390 391 392 393

	return n;
}

static struct device_attribute dev_attr_ep11_mkvps =
	__ATTR(mkvps, 0444, ep11_mkvps_show, NULL);

static ssize_t ep11_queue_op_modes_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
394
	struct zcrypt_queue *zq = dev_get_drvdata(dev);
395 396 397 398 399 400 401 402 403 404 405
	int i, n = 0;
	struct ep11_domain_info di;

	memset(&di, 0, sizeof(di));

	if (zq->online)
		ep11_get_domain_info(AP_QID_CARD(zq->queue->qid),
				     AP_QID_QUEUE(zq->queue->qid),
				     &di);

	for (i = 0; ep11_op_modes[i].mode_txt; i++) {
406
		if (di.op_mode & (1ULL << ep11_op_modes[i].mode_bit)) {
407 408
			if (n > 0)
				buf[n++] = ' ';
409 410
			n += scnprintf(buf + n, PAGE_SIZE - n,
				       "%s", ep11_op_modes[i].mode_txt);
411 412
		}
	}
413
	n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430

	return n;
}

static struct device_attribute dev_attr_ep11_queue_op_modes =
	__ATTR(op_modes, 0444, ep11_queue_op_modes_show, NULL);

static struct attribute *ep11_queue_attrs[] = {
	&dev_attr_ep11_mkvps.attr,
	&dev_attr_ep11_queue_op_modes.attr,
	NULL,
};

static const struct attribute_group ep11_queue_attr_grp = {
	.attrs = ep11_queue_attrs,
};

431
/*
432
 * Probe function for CEX[45678] card device. It always
433 434
 * accepts the AP device since the bus_match already checked
 * the hardware type.
435 436
 * @ap_dev: pointer to the AP device.
 */
437
static int zcrypt_cex4_card_probe(struct ap_device *ap_dev)
438
{
439 440 441 442
	/*
	 * Normalized speed ratings per crypto adapter
	 * MEX_1k, MEX_2k, MEX_4k, CRT_1k, CRT_2k, CRT_4k, RNG, SECKEY
	 */
443
	static const int CEX4A_SPEED_IDX[NUM_OPS] = {
444
		 14,  19, 249, 42, 228, 1458, 0, 0};
445
	static const int CEX5A_SPEED_IDX[NUM_OPS] = {
446
		  8,   9,  20, 18,  66,	 458, 0, 0};
447
	static const int CEX6A_SPEED_IDX[NUM_OPS] = {
448
		  6,   9,  20, 17,  65,	 438, 0, 0};
449
	static const int CEX7A_SPEED_IDX[NUM_OPS] = {
450
		  6,   8,  17, 15,  54,	 362, 0, 0};
451 452
	static const int CEX8A_SPEED_IDX[NUM_OPS] = {
		  6,   8,  17, 15,  54,	 362, 0, 0};
453

454
	static const int CEX4C_SPEED_IDX[NUM_OPS] = {
455
		 59,  69, 308, 83, 278, 2204, 209, 40};
456
	static const int CEX5C_SPEED_IDX[] = {
457
		 24,  31,  50, 37,  90,	 479,  27, 10};
458
	static const int CEX6C_SPEED_IDX[NUM_OPS] = {
459
		 16,  20,  32, 27,  77,	 455,  24,  9};
460
	static const int CEX7C_SPEED_IDX[NUM_OPS] = {
461
		 14,  16,  26, 23,  64,	 376,  23,  8};
462 463
	static const int CEX8C_SPEED_IDX[NUM_OPS] = {
		 14,  16,  26, 23,  64,	 376,  23,  8};
464

465
	static const int CEX4P_SPEED_IDX[NUM_OPS] = {
466
		  0,   0,   0,	 0,   0,   0,	0,  50};
467
	static const int CEX5P_SPEED_IDX[NUM_OPS] = {
468
		  0,   0,   0,	 0,   0,   0,	0,  10};
469
	static const int CEX6P_SPEED_IDX[NUM_OPS] = {
470
		  0,   0,   0,	 0,   0,   0,	0,   9};
471
	static const int CEX7P_SPEED_IDX[NUM_OPS] = {
472
		  0,   0,   0,	 0,   0,   0,	0,   8};
473 474
	static const int CEX8P_SPEED_IDX[NUM_OPS] = {
		  0,   0,   0,	 0,   0,   0,	0,   8};
475 476 477

	struct ap_card *ac = to_ap_card(&ap_dev->device);
	struct zcrypt_card *zc;
478 479
	int rc = 0;

480 481 482 483
	zc = zcrypt_card_alloc();
	if (!zc)
		return -ENOMEM;
	zc->card = ac;
484
	dev_set_drvdata(&ap_dev->device, zc);
485 486 487 488
	if (ap_test_bit(&ac->functions, AP_FUNC_ACCEL)) {
		if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
			zc->type_string = "CEX4A";
			zc->user_space_type = ZCRYPT_CEX4;
489
			zc->speed_rating = CEX4A_SPEED_IDX;
490
		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {
491 492
			zc->type_string = "CEX5A";
			zc->user_space_type = ZCRYPT_CEX5;
493
			zc->speed_rating = CEX5A_SPEED_IDX;
494
		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {
495 496
			zc->type_string = "CEX6A";
			zc->user_space_type = ZCRYPT_CEX6;
497
			zc->speed_rating = CEX6A_SPEED_IDX;
498
		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX7) {
499
			zc->type_string = "CEX7A";
500 501 502 503 504 505 506 507
			zc->speed_rating = CEX7A_SPEED_IDX;
			/* wrong user space type, just for compatibility
			 * with the ZCRYPT_STATUS_MASK ioctl.
			 */
			zc->user_space_type = ZCRYPT_CEX6;
		} else {
			zc->type_string = "CEX8A";
			zc->speed_rating = CEX8A_SPEED_IDX;
508 509 510 511
			/* wrong user space type, just for compatibility
			 * with the ZCRYPT_STATUS_MASK ioctl.
			 */
			zc->user_space_type = ZCRYPT_CEX6;
512
		}
513 514 515 516 517 518 519 520 521 522 523 524 525 526
		zc->min_mod_size = CEX4A_MIN_MOD_SIZE;
		if (ap_test_bit(&ac->functions, AP_FUNC_MEX4K) &&
		    ap_test_bit(&ac->functions, AP_FUNC_CRT4K)) {
			zc->max_mod_size = CEX4A_MAX_MOD_SIZE_4K;
			zc->max_exp_bit_length =
				CEX4A_MAX_MOD_SIZE_4K;
		} else {
			zc->max_mod_size = CEX4A_MAX_MOD_SIZE_2K;
			zc->max_exp_bit_length =
				CEX4A_MAX_MOD_SIZE_2K;
		}
	} else if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) {
		if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
			zc->type_string = "CEX4C";
527 528
			zc->speed_rating = CEX4C_SPEED_IDX;
			/* wrong user space type, must be CEX3C
529 530 531
			 * just keep it for cca compatibility
			 */
			zc->user_space_type = ZCRYPT_CEX3C;
532
		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {
533
			zc->type_string = "CEX5C";
534 535
			zc->speed_rating = CEX5C_SPEED_IDX;
			/* wrong user space type, must be CEX3C
536 537 538
			 * just keep it for cca compatibility
			 */
			zc->user_space_type = ZCRYPT_CEX3C;
539
		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {
540
			zc->type_string = "CEX6C";
541 542
			zc->speed_rating = CEX6C_SPEED_IDX;
			/* wrong user space type, must be CEX3C
543 544 545
			 * just keep it for cca compatibility
			 */
			zc->user_space_type = ZCRYPT_CEX3C;
546
		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX7) {
547
			zc->type_string = "CEX7C";
548 549 550 551 552 553 554 555 556
			zc->speed_rating = CEX7C_SPEED_IDX;
			/* wrong user space type, must be CEX3C
			 * just keep it for cca compatibility
			 */
			zc->user_space_type = ZCRYPT_CEX3C;
		} else {
			zc->type_string = "CEX8C";
			zc->speed_rating = CEX8C_SPEED_IDX;
			/* wrong user space type, must be CEX3C
557 558 559
			 * just keep it for cca compatibility
			 */
			zc->user_space_type = ZCRYPT_CEX3C;
560 561 562 563 564 565 566 567
		}
		zc->min_mod_size = CEX4C_MIN_MOD_SIZE;
		zc->max_mod_size = CEX4C_MAX_MOD_SIZE;
		zc->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;
	} else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) {
		if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
			zc->type_string = "CEX4P";
			zc->user_space_type = ZCRYPT_CEX4;
568
			zc->speed_rating = CEX4P_SPEED_IDX;
569
		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {
570 571
			zc->type_string = "CEX5P";
			zc->user_space_type = ZCRYPT_CEX5;
572
			zc->speed_rating = CEX5P_SPEED_IDX;
573
		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {
574 575
			zc->type_string = "CEX6P";
			zc->user_space_type = ZCRYPT_CEX6;
576
			zc->speed_rating = CEX6P_SPEED_IDX;
577
		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX7) {
578
			zc->type_string = "CEX7P";
579 580 581 582 583 584 585 586
			zc->speed_rating = CEX7P_SPEED_IDX;
			/* wrong user space type, just for compatibility
			 * with the ZCRYPT_STATUS_MASK ioctl.
			 */
			zc->user_space_type = ZCRYPT_CEX6;
		} else {
			zc->type_string = "CEX8P";
			zc->speed_rating = CEX8P_SPEED_IDX;
587 588 589 590
			/* wrong user space type, just for compatibility
			 * with the ZCRYPT_STATUS_MASK ioctl.
			 */
			zc->user_space_type = ZCRYPT_CEX6;
591 592 593 594 595 596
		}
		zc->min_mod_size = CEX4C_MIN_MOD_SIZE;
		zc->max_mod_size = CEX4C_MAX_MOD_SIZE;
		zc->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;
	} else {
		zcrypt_card_free(zc);
597
		return -ENODEV;
598 599 600 601
	}
	zc->online = 1;

	rc = zcrypt_card_register(zc);
602
	if (rc) {
603
		zcrypt_card_free(zc);
604
		return rc;
605
	}
606

607 608
	if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) {
		rc = sysfs_create_group(&ap_dev->device.kobj,
609
					&cca_card_attr_grp);
610
		if (rc) {
611
			zcrypt_card_unregister(zc);
612 613
			zcrypt_card_free(zc);
		}
614 615 616
	} else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) {
		rc = sysfs_create_group(&ap_dev->device.kobj,
					&ep11_card_attr_grp);
617
		if (rc) {
618
			zcrypt_card_unregister(zc);
619 620
			zcrypt_card_free(zc);
		}
621 622
	}

623 624 625
	return rc;
}

626
/*
627
 * This is called to remove the CEX[45678] card driver
628
 * information if an AP card device is removed.
629
 */
630
static void zcrypt_cex4_card_remove(struct ap_device *ap_dev)
631
{
632
	struct zcrypt_card *zc = dev_get_drvdata(&ap_dev->device);
633
	struct ap_card *ac = to_ap_card(&ap_dev->device);
634

635
	if (ap_test_bit(&ac->functions, AP_FUNC_COPRO))
636 637 638
		sysfs_remove_group(&ap_dev->device.kobj, &cca_card_attr_grp);
	else if (ap_test_bit(&ac->functions, AP_FUNC_EP11))
		sysfs_remove_group(&ap_dev->device.kobj, &ep11_card_attr_grp);
639 640

	zcrypt_card_unregister(zc);
641 642 643 644 645 646
}

static struct ap_driver zcrypt_cex4_card_driver = {
	.probe = zcrypt_cex4_card_probe,
	.remove = zcrypt_cex4_card_remove,
	.ids = zcrypt_cex4_card_ids,
647
	.flags = AP_DRIVER_FLAG_DEFAULT,
648 649
};

650
/*
651
 * Probe function for CEX[45678] queue device. It always
652 653
 * accepts the AP device since the bus_match already checked
 * the hardware type.
654 655 656 657 658 659 660 661 662
 * @ap_dev: pointer to the AP device.
 */
static int zcrypt_cex4_queue_probe(struct ap_device *ap_dev)
{
	struct ap_queue *aq = to_ap_queue(&ap_dev->device);
	struct zcrypt_queue *zq;
	int rc;

	if (ap_test_bit(&aq->card->functions, AP_FUNC_ACCEL)) {
663
		zq = zcrypt_queue_alloc(aq->card->maxmsgsize);
664 665 666 667 668
		if (!zq)
			return -ENOMEM;
		zq->ops = zcrypt_msgtype(MSGTYPE50_NAME,
					 MSGTYPE50_VARIANT_DEFAULT);
	} else if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) {
669
		zq = zcrypt_queue_alloc(aq->card->maxmsgsize);
670 671 672 673 674
		if (!zq)
			return -ENOMEM;
		zq->ops = zcrypt_msgtype(MSGTYPE06_NAME,
					 MSGTYPE06_VARIANT_DEFAULT);
	} else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) {
675
		zq = zcrypt_queue_alloc(aq->card->maxmsgsize);
676 677 678 679 680 681
		if (!zq)
			return -ENOMEM;
		zq->ops = zcrypt_msgtype(MSGTYPE06_NAME,
					 MSGTYPE06_VARIANT_EP11);
	} else {
		return -ENODEV;
682
	}
683

684 685 686
	zq->queue = aq;
	zq->online = 1;
	atomic_set(&zq->load, 0);
687
	ap_queue_init_state(aq);
688
	ap_queue_init_reply(aq, &zq->reply);
689
	aq->request_timeout = CEX4_CLEANUP_TIME;
690
	dev_set_drvdata(&ap_dev->device, zq);
691 692 693
	rc = zcrypt_queue_register(zq);
	if (rc) {
		zcrypt_queue_free(zq);
694
		return rc;
695 696 697 698
	}

	if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) {
		rc = sysfs_create_group(&ap_dev->device.kobj,
699
					&cca_queue_attr_grp);
700
		if (rc) {
701
			zcrypt_queue_unregister(zq);
702 703
			zcrypt_queue_free(zq);
		}
704 705 706
	} else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) {
		rc = sysfs_create_group(&ap_dev->device.kobj,
					&ep11_queue_attr_grp);
707
		if (rc) {
708
			zcrypt_queue_unregister(zq);
709 710
			zcrypt_queue_free(zq);
		}
711 712 713
	}

	return rc;
714 715
}

716
/*
717
 * This is called to remove the CEX[45678] queue driver
718
 * information if an AP queue device is removed.
719 720 721
 */
static void zcrypt_cex4_queue_remove(struct ap_device *ap_dev)
{
722
	struct zcrypt_queue *zq = dev_get_drvdata(&ap_dev->device);
723 724
	struct ap_queue *aq = to_ap_queue(&ap_dev->device);

725
	if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO))
726 727 728
		sysfs_remove_group(&ap_dev->device.kobj, &cca_queue_attr_grp);
	else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11))
		sysfs_remove_group(&ap_dev->device.kobj, &ep11_queue_attr_grp);
729 730

	zcrypt_queue_unregister(zq);
731 732 733 734 735 736
}

static struct ap_driver zcrypt_cex4_queue_driver = {
	.probe = zcrypt_cex4_queue_probe,
	.remove = zcrypt_cex4_queue_remove,
	.ids = zcrypt_cex4_queue_ids,
737
	.flags = AP_DRIVER_FLAG_DEFAULT,
738 739
};

740 741
int __init zcrypt_cex4_init(void)
{
742 743 744 745 746 747 748 749 750 751 752 753 754
	int rc;

	rc = ap_driver_register(&zcrypt_cex4_card_driver,
				THIS_MODULE, "cex4card");
	if (rc)
		return rc;

	rc = ap_driver_register(&zcrypt_cex4_queue_driver,
				THIS_MODULE, "cex4queue");
	if (rc)
		ap_driver_unregister(&zcrypt_cex4_card_driver);

	return rc;
755 756 757 758
}

void __exit zcrypt_cex4_exit(void)
{
759 760
	ap_driver_unregister(&zcrypt_cex4_queue_driver);
	ap_driver_unregister(&zcrypt_cex4_card_driver);
761 762 763 764
}

module_init(zcrypt_cex4_init);
module_exit(zcrypt_cex4_exit);