brintos

brintos / linux-shallow public Read only

0
0
Text · 21.1 KiB · 64df7d2 Raw
759 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 *  Copyright IBM Corp. 2012, 20224 *  Author(s): Holger Dengler <hd@linux.vnet.ibm.com>5 */6 7#include <linux/module.h>8#include <linux/slab.h>9#include <linux/init.h>10#include <linux/err.h>11#include <linux/atomic.h>12#include <linux/uaccess.h>13#include <linux/mod_devicetable.h>14 15#include "ap_bus.h"16#include "zcrypt_api.h"17#include "zcrypt_msgtype6.h"18#include "zcrypt_msgtype50.h"19#include "zcrypt_error.h"20#include "zcrypt_cex4.h"21#include "zcrypt_ccamisc.h"22#include "zcrypt_ep11misc.h"23 24#define CEX4A_MIN_MOD_SIZE	  1	/*    8 bits	*/25#define CEX4A_MAX_MOD_SIZE_2K	256	/* 2048 bits	*/26#define CEX4A_MAX_MOD_SIZE_4K	512	/* 4096 bits	*/27 28#define CEX4C_MIN_MOD_SIZE	 16	/*  256 bits	*/29#define CEX4C_MAX_MOD_SIZE	512	/* 4096 bits	*/30 31/* Waiting time for requests to be processed.32 * Currently there are some types of request which are not deterministic.33 * But the maximum time limit managed by the stomper code is set to 60sec.34 * Hence we have to wait at least that time period.35 */36#define CEX4_CLEANUP_TIME	(900 * HZ)37 38MODULE_AUTHOR("IBM Corporation");39MODULE_DESCRIPTION("CEX[45678] Cryptographic Card device driver, " \40		   "Copyright IBM Corp. 2022");41MODULE_LICENSE("GPL");42 43static struct ap_device_id zcrypt_cex4_card_ids[] = {44	{ .dev_type = AP_DEVICE_TYPE_CEX4,45	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },46	{ .dev_type = AP_DEVICE_TYPE_CEX5,47	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },48	{ .dev_type = AP_DEVICE_TYPE_CEX6,49	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },50	{ .dev_type = AP_DEVICE_TYPE_CEX7,51	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },52	{ .dev_type = AP_DEVICE_TYPE_CEX8,53	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },54	{ /* end of list */ },55};56 57MODULE_DEVICE_TABLE(ap, zcrypt_cex4_card_ids);58 59static struct ap_device_id zcrypt_cex4_queue_ids[] = {60	{ .dev_type = AP_DEVICE_TYPE_CEX4,61	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },62	{ .dev_type = AP_DEVICE_TYPE_CEX5,63	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },64	{ .dev_type = AP_DEVICE_TYPE_CEX6,65	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },66	{ .dev_type = AP_DEVICE_TYPE_CEX7,67	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },68	{ .dev_type = AP_DEVICE_TYPE_CEX8,69	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },70	{ /* end of list */ },71};72 73MODULE_DEVICE_TABLE(ap, zcrypt_cex4_queue_ids);74 75/*76 * CCA card additional device attributes77 */78static ssize_t cca_serialnr_show(struct device *dev,79				 struct device_attribute *attr,80				 char *buf)81{82	struct zcrypt_card *zc = dev_get_drvdata(dev);83	struct cca_info ci;84	struct ap_card *ac = to_ap_card(dev);85 86	memset(&ci, 0, sizeof(ci));87 88	if (ap_domain_index >= 0)89		cca_get_info(ac->id, ap_domain_index, &ci, zc->online);90 91	return sysfs_emit(buf, "%s\n", ci.serial);92}93 94static struct device_attribute dev_attr_cca_serialnr =95	__ATTR(serialnr, 0444, cca_serialnr_show, NULL);96 97static struct attribute *cca_card_attrs[] = {98	&dev_attr_cca_serialnr.attr,99	NULL,100};101 102static const struct attribute_group cca_card_attr_grp = {103	.attrs = cca_card_attrs,104};105 106 /*107  * CCA queue additional device attributes108  */109static ssize_t cca_mkvps_show(struct device *dev,110			      struct device_attribute *attr,111			      char *buf)112{113	struct zcrypt_queue *zq = dev_get_drvdata(dev);114	int n = 0;115	struct cca_info ci;116	static const char * const cao_state[] = { "invalid", "valid" };117	static const char * const new_state[] = { "empty", "partial", "full" };118 119	memset(&ci, 0, sizeof(ci));120 121	cca_get_info(AP_QID_CARD(zq->queue->qid),122		     AP_QID_QUEUE(zq->queue->qid),123		     &ci, zq->online);124 125	if (ci.new_aes_mk_state >= '1' && ci.new_aes_mk_state <= '3')126		n += sysfs_emit_at(buf, n, "AES NEW: %s 0x%016llx\n",127				   new_state[ci.new_aes_mk_state - '1'],128				   ci.new_aes_mkvp);129	else130		n += sysfs_emit_at(buf, n, "AES NEW: - -\n");131 132	if (ci.cur_aes_mk_state >= '1' && ci.cur_aes_mk_state <= '2')133		n += sysfs_emit_at(buf, n, "AES CUR: %s 0x%016llx\n",134				   cao_state[ci.cur_aes_mk_state - '1'],135				   ci.cur_aes_mkvp);136	else137		n += sysfs_emit_at(buf, n, "AES CUR: - -\n");138 139	if (ci.old_aes_mk_state >= '1' && ci.old_aes_mk_state <= '2')140		n += sysfs_emit_at(buf, n, "AES OLD: %s 0x%016llx\n",141				   cao_state[ci.old_aes_mk_state - '1'],142				   ci.old_aes_mkvp);143	else144		n += sysfs_emit_at(buf, n, "AES OLD: - -\n");145 146	if (ci.new_apka_mk_state >= '1' && ci.new_apka_mk_state <= '3')147		n += sysfs_emit_at(buf, n, "APKA NEW: %s 0x%016llx\n",148				   new_state[ci.new_apka_mk_state - '1'],149				   ci.new_apka_mkvp);150	else151		n += sysfs_emit_at(buf, n, "APKA NEW: - -\n");152 153	if (ci.cur_apka_mk_state >= '1' && ci.cur_apka_mk_state <= '2')154		n += sysfs_emit_at(buf, n, "APKA CUR: %s 0x%016llx\n",155				   cao_state[ci.cur_apka_mk_state - '1'],156				   ci.cur_apka_mkvp);157	else158		n += sysfs_emit_at(buf, n, "APKA CUR: - -\n");159 160	if (ci.old_apka_mk_state >= '1' && ci.old_apka_mk_state <= '2')161		n += sysfs_emit_at(buf, n, "APKA OLD: %s 0x%016llx\n",162				   cao_state[ci.old_apka_mk_state - '1'],163				   ci.old_apka_mkvp);164	else165		n += sysfs_emit_at(buf, n, "APKA OLD: - -\n");166 167	if (ci.new_asym_mk_state >= '1' && ci.new_asym_mk_state <= '3')168		n += sysfs_emit_at(buf, n, "ASYM NEW: %s 0x%016llx%016llx\n",169				   new_state[ci.new_asym_mk_state - '1'],170				   *((u64 *)(ci.new_asym_mkvp)),171				   *((u64 *)(ci.new_asym_mkvp + sizeof(u64))));172	else173		n += sysfs_emit_at(buf, n, "ASYM NEW: - -\n");174 175	if (ci.cur_asym_mk_state >= '1' && ci.cur_asym_mk_state <= '2')176		n += sysfs_emit_at(buf, n, "ASYM CUR: %s 0x%016llx%016llx\n",177				   cao_state[ci.cur_asym_mk_state - '1'],178				   *((u64 *)(ci.cur_asym_mkvp)),179				   *((u64 *)(ci.cur_asym_mkvp + sizeof(u64))));180	else181		n += sysfs_emit_at(buf, n, "ASYM CUR: - -\n");182 183	if (ci.old_asym_mk_state >= '1' && ci.old_asym_mk_state <= '2')184		n += sysfs_emit_at(buf, n, "ASYM OLD: %s 0x%016llx%016llx\n",185				   cao_state[ci.old_asym_mk_state - '1'],186				   *((u64 *)(ci.old_asym_mkvp)),187				   *((u64 *)(ci.old_asym_mkvp + sizeof(u64))));188	else189		n += sysfs_emit_at(buf, n, "ASYM OLD: - -\n");190 191	return n;192}193 194static struct device_attribute dev_attr_cca_mkvps =195	__ATTR(mkvps, 0444, cca_mkvps_show, NULL);196 197static struct attribute *cca_queue_attrs[] = {198	&dev_attr_cca_mkvps.attr,199	NULL,200};201 202static const struct attribute_group cca_queue_attr_grp = {203	.attrs = cca_queue_attrs,204};205 206/*207 * EP11 card additional device attributes208 */209static ssize_t ep11_api_ordinalnr_show(struct device *dev,210				       struct device_attribute *attr,211				       char *buf)212{213	struct zcrypt_card *zc = dev_get_drvdata(dev);214	struct ep11_card_info ci;215	struct ap_card *ac = to_ap_card(dev);216 217	memset(&ci, 0, sizeof(ci));218 219	ep11_get_card_info(ac->id, &ci, zc->online);220 221	if (ci.API_ord_nr > 0)222		return sysfs_emit(buf, "%u\n", ci.API_ord_nr);223	else224		return sysfs_emit(buf, "\n");225}226 227static struct device_attribute dev_attr_ep11_api_ordinalnr =228	__ATTR(API_ordinalnr, 0444, ep11_api_ordinalnr_show, NULL);229 230static ssize_t ep11_fw_version_show(struct device *dev,231				    struct device_attribute *attr,232				    char *buf)233{234	struct zcrypt_card *zc = dev_get_drvdata(dev);235	struct ep11_card_info ci;236	struct ap_card *ac = to_ap_card(dev);237 238	memset(&ci, 0, sizeof(ci));239 240	ep11_get_card_info(ac->id, &ci, zc->online);241 242	if (ci.FW_version > 0)243		return sysfs_emit(buf, "%d.%d\n",244				  (int)(ci.FW_version >> 8),245				  (int)(ci.FW_version & 0xFF));246	else247		return sysfs_emit(buf, "\n");248}249 250static struct device_attribute dev_attr_ep11_fw_version =251	__ATTR(FW_version, 0444, ep11_fw_version_show, NULL);252 253static ssize_t ep11_serialnr_show(struct device *dev,254				  struct device_attribute *attr,255				  char *buf)256{257	struct zcrypt_card *zc = dev_get_drvdata(dev);258	struct ep11_card_info ci;259	struct ap_card *ac = to_ap_card(dev);260 261	memset(&ci, 0, sizeof(ci));262 263	ep11_get_card_info(ac->id, &ci, zc->online);264 265	if (ci.serial[0])266		return sysfs_emit(buf, "%16.16s\n", ci.serial);267	else268		return sysfs_emit(buf, "\n");269}270 271static struct device_attribute dev_attr_ep11_serialnr =272	__ATTR(serialnr, 0444, ep11_serialnr_show, NULL);273 274static const struct {275	int	    mode_bit;276	const char *mode_txt;277} ep11_op_modes[] = {278	{ 0, "FIPS2009" },279	{ 1, "BSI2009" },280	{ 2, "FIPS2011" },281	{ 3, "BSI2011" },282	{ 4, "SIGG-IMPORT" },283	{ 5, "SIGG" },284	{ 6, "BSICC2017" },285	{ 7, "FIPS2021" },286	{ 8, "FIPS2024" },287	{ 0, NULL }288};289 290static ssize_t ep11_card_op_modes_show(struct device *dev,291				       struct device_attribute *attr,292				       char *buf)293{294	struct zcrypt_card *zc = dev_get_drvdata(dev);295	int i, n = 0;296	struct ep11_card_info ci;297	struct ap_card *ac = to_ap_card(dev);298 299	memset(&ci, 0, sizeof(ci));300 301	ep11_get_card_info(ac->id, &ci, zc->online);302 303	for (i = 0; ep11_op_modes[i].mode_txt; i++) {304		if (ci.op_mode & (1ULL << ep11_op_modes[i].mode_bit)) {305			if (n > 0)306				buf[n++] = ' ';307			n += sysfs_emit_at(buf, n, "%s",308					   ep11_op_modes[i].mode_txt);309		}310	}311	n += sysfs_emit_at(buf, n, "\n");312 313	return n;314}315 316static struct device_attribute dev_attr_ep11_card_op_modes =317	__ATTR(op_modes, 0444, ep11_card_op_modes_show, NULL);318 319static struct attribute *ep11_card_attrs[] = {320	&dev_attr_ep11_api_ordinalnr.attr,321	&dev_attr_ep11_fw_version.attr,322	&dev_attr_ep11_serialnr.attr,323	&dev_attr_ep11_card_op_modes.attr,324	NULL,325};326 327static const struct attribute_group ep11_card_attr_grp = {328	.attrs = ep11_card_attrs,329};330 331/*332 * EP11 queue additional device attributes333 */334 335static ssize_t ep11_mkvps_show(struct device *dev,336			       struct device_attribute *attr,337			       char *buf)338{339	struct zcrypt_queue *zq = dev_get_drvdata(dev);340	int n = 0;341	struct ep11_domain_info di;342	static const char * const cwk_state[] = { "invalid", "valid" };343	static const char * const nwk_state[] = { "empty", "uncommitted",344						  "committed" };345 346	memset(&di, 0, sizeof(di));347 348	if (zq->online)349		ep11_get_domain_info(AP_QID_CARD(zq->queue->qid),350				     AP_QID_QUEUE(zq->queue->qid),351				     &di);352 353	if (di.cur_wk_state == '0') {354		n = sysfs_emit(buf, "WK CUR: %s -\n",355			       cwk_state[di.cur_wk_state - '0']);356	} else if (di.cur_wk_state == '1') {357		n = sysfs_emit(buf, "WK CUR: %s 0x",358			       cwk_state[di.cur_wk_state - '0']);359		bin2hex(buf + n, di.cur_wkvp, sizeof(di.cur_wkvp));360		n += 2 * sizeof(di.cur_wkvp);361		n += sysfs_emit_at(buf, n, "\n");362	} else {363		n = sysfs_emit(buf, "WK CUR: - -\n");364	}365 366	if (di.new_wk_state == '0') {367		n += sysfs_emit_at(buf, n, "WK NEW: %s -\n",368				   nwk_state[di.new_wk_state - '0']);369	} else if (di.new_wk_state >= '1' && di.new_wk_state <= '2') {370		n += sysfs_emit_at(buf, n, "WK NEW: %s 0x",371				   nwk_state[di.new_wk_state - '0']);372		bin2hex(buf + n, di.new_wkvp, sizeof(di.new_wkvp));373		n += 2 * sizeof(di.new_wkvp);374		n += sysfs_emit_at(buf, n, "\n");375	} else {376		n += sysfs_emit_at(buf, n, "WK NEW: - -\n");377	}378 379	return n;380}381 382static struct device_attribute dev_attr_ep11_mkvps =383	__ATTR(mkvps, 0444, ep11_mkvps_show, NULL);384 385static ssize_t ep11_queue_op_modes_show(struct device *dev,386					struct device_attribute *attr,387					char *buf)388{389	struct zcrypt_queue *zq = dev_get_drvdata(dev);390	int i, n = 0;391	struct ep11_domain_info di;392 393	memset(&di, 0, sizeof(di));394 395	if (zq->online)396		ep11_get_domain_info(AP_QID_CARD(zq->queue->qid),397				     AP_QID_QUEUE(zq->queue->qid),398				     &di);399 400	for (i = 0; ep11_op_modes[i].mode_txt; i++) {401		if (di.op_mode & (1ULL << ep11_op_modes[i].mode_bit)) {402			if (n > 0)403				buf[n++] = ' ';404			n += sysfs_emit_at(buf, n, "%s",405					   ep11_op_modes[i].mode_txt);406		}407	}408	n += sysfs_emit_at(buf, n, "\n");409 410	return n;411}412 413static struct device_attribute dev_attr_ep11_queue_op_modes =414	__ATTR(op_modes, 0444, ep11_queue_op_modes_show, NULL);415 416static struct attribute *ep11_queue_attrs[] = {417	&dev_attr_ep11_mkvps.attr,418	&dev_attr_ep11_queue_op_modes.attr,419	NULL,420};421 422static const struct attribute_group ep11_queue_attr_grp = {423	.attrs = ep11_queue_attrs,424};425 426/*427 * Probe function for CEX[45678] card device. It always428 * accepts the AP device since the bus_match already checked429 * the hardware type.430 * @ap_dev: pointer to the AP device.431 */432static int zcrypt_cex4_card_probe(struct ap_device *ap_dev)433{434	/*435	 * Normalized speed ratings per crypto adapter436	 * MEX_1k, MEX_2k, MEX_4k, CRT_1k, CRT_2k, CRT_4k, RNG, SECKEY437	 */438	static const int CEX4A_SPEED_IDX[NUM_OPS] = {439		 14,  19, 249, 42, 228, 1458, 0, 0};440	static const int CEX5A_SPEED_IDX[NUM_OPS] = {441		  8,   9,  20, 18,  66,	 458, 0, 0};442	static const int CEX6A_SPEED_IDX[NUM_OPS] = {443		  6,   9,  20, 17,  65,	 438, 0, 0};444	static const int CEX7A_SPEED_IDX[NUM_OPS] = {445		  6,   8,  17, 15,  54,	 362, 0, 0};446	static const int CEX8A_SPEED_IDX[NUM_OPS] = {447		  6,   8,  17, 15,  54,	 362, 0, 0};448 449	static const int CEX4C_SPEED_IDX[NUM_OPS] = {450		 59,  69, 308, 83, 278, 2204, 209, 40};451	static const int CEX5C_SPEED_IDX[] = {452		 24,  31,  50, 37,  90,	 479,  27, 10};453	static const int CEX6C_SPEED_IDX[NUM_OPS] = {454		 16,  20,  32, 27,  77,	 455,  24,  9};455	static const int CEX7C_SPEED_IDX[NUM_OPS] = {456		 14,  16,  26, 23,  64,	 376,  23,  8};457	static const int CEX8C_SPEED_IDX[NUM_OPS] = {458		 14,  16,  26, 23,  64,	 376,  23,  8};459 460	static const int CEX4P_SPEED_IDX[NUM_OPS] = {461		  0,   0,   0,	 0,   0,   0,	0,  50};462	static const int CEX5P_SPEED_IDX[NUM_OPS] = {463		  0,   0,   0,	 0,   0,   0,	0,  10};464	static const int CEX6P_SPEED_IDX[NUM_OPS] = {465		  0,   0,   0,	 0,   0,   0,	0,   9};466	static const int CEX7P_SPEED_IDX[NUM_OPS] = {467		  0,   0,   0,	 0,   0,   0,	0,   8};468	static const int CEX8P_SPEED_IDX[NUM_OPS] = {469		  0,   0,   0,	 0,   0,   0,	0,   8};470 471	struct ap_card *ac = to_ap_card(&ap_dev->device);472	struct zcrypt_card *zc;473	int rc = 0;474 475	zc = zcrypt_card_alloc();476	if (!zc)477		return -ENOMEM;478	zc->card = ac;479	dev_set_drvdata(&ap_dev->device, zc);480	if (ac->hwinfo.accel) {481		if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {482			zc->type_string = "CEX4A";483			zc->user_space_type = ZCRYPT_CEX4;484			zc->speed_rating = CEX4A_SPEED_IDX;485		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {486			zc->type_string = "CEX5A";487			zc->user_space_type = ZCRYPT_CEX5;488			zc->speed_rating = CEX5A_SPEED_IDX;489		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {490			zc->type_string = "CEX6A";491			zc->user_space_type = ZCRYPT_CEX6;492			zc->speed_rating = CEX6A_SPEED_IDX;493		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX7) {494			zc->type_string = "CEX7A";495			zc->speed_rating = CEX7A_SPEED_IDX;496			/* wrong user space type, just for compatibility497			 * with the ZCRYPT_STATUS_MASK ioctl.498			 */499			zc->user_space_type = ZCRYPT_CEX6;500		} else {501			zc->type_string = "CEX8A";502			zc->speed_rating = CEX8A_SPEED_IDX;503			/* wrong user space type, just for compatibility504			 * with the ZCRYPT_STATUS_MASK ioctl.505			 */506			zc->user_space_type = ZCRYPT_CEX6;507		}508		zc->min_mod_size = CEX4A_MIN_MOD_SIZE;509		if (ac->hwinfo.mex4k && ac->hwinfo.crt4k) {510			zc->max_mod_size = CEX4A_MAX_MOD_SIZE_4K;511			zc->max_exp_bit_length =512				CEX4A_MAX_MOD_SIZE_4K;513		} else {514			zc->max_mod_size = CEX4A_MAX_MOD_SIZE_2K;515			zc->max_exp_bit_length =516				CEX4A_MAX_MOD_SIZE_2K;517		}518	} else if (ac->hwinfo.cca) {519		if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {520			zc->type_string = "CEX4C";521			zc->speed_rating = CEX4C_SPEED_IDX;522			/* wrong user space type, must be CEX3C523			 * just keep it for cca compatibility524			 */525			zc->user_space_type = ZCRYPT_CEX3C;526		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {527			zc->type_string = "CEX5C";528			zc->speed_rating = CEX5C_SPEED_IDX;529			/* wrong user space type, must be CEX3C530			 * just keep it for cca compatibility531			 */532			zc->user_space_type = ZCRYPT_CEX3C;533		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {534			zc->type_string = "CEX6C";535			zc->speed_rating = CEX6C_SPEED_IDX;536			/* wrong user space type, must be CEX3C537			 * just keep it for cca compatibility538			 */539			zc->user_space_type = ZCRYPT_CEX3C;540		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX7) {541			zc->type_string = "CEX7C";542			zc->speed_rating = CEX7C_SPEED_IDX;543			/* wrong user space type, must be CEX3C544			 * just keep it for cca compatibility545			 */546			zc->user_space_type = ZCRYPT_CEX3C;547		} else {548			zc->type_string = "CEX8C";549			zc->speed_rating = CEX8C_SPEED_IDX;550			/* wrong user space type, must be CEX3C551			 * just keep it for cca compatibility552			 */553			zc->user_space_type = ZCRYPT_CEX3C;554		}555		zc->min_mod_size = CEX4C_MIN_MOD_SIZE;556		zc->max_mod_size = CEX4C_MAX_MOD_SIZE;557		zc->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;558	} else if (ac->hwinfo.ep11) {559		if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {560			zc->type_string = "CEX4P";561			zc->user_space_type = ZCRYPT_CEX4;562			zc->speed_rating = CEX4P_SPEED_IDX;563		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {564			zc->type_string = "CEX5P";565			zc->user_space_type = ZCRYPT_CEX5;566			zc->speed_rating = CEX5P_SPEED_IDX;567		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {568			zc->type_string = "CEX6P";569			zc->user_space_type = ZCRYPT_CEX6;570			zc->speed_rating = CEX6P_SPEED_IDX;571		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX7) {572			zc->type_string = "CEX7P";573			zc->speed_rating = CEX7P_SPEED_IDX;574			/* wrong user space type, just for compatibility575			 * with the ZCRYPT_STATUS_MASK ioctl.576			 */577			zc->user_space_type = ZCRYPT_CEX6;578		} else {579			zc->type_string = "CEX8P";580			zc->speed_rating = CEX8P_SPEED_IDX;581			/* wrong user space type, just for compatibility582			 * with the ZCRYPT_STATUS_MASK ioctl.583			 */584			zc->user_space_type = ZCRYPT_CEX6;585		}586		zc->min_mod_size = CEX4C_MIN_MOD_SIZE;587		zc->max_mod_size = CEX4C_MAX_MOD_SIZE;588		zc->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;589	} else {590		zcrypt_card_free(zc);591		return -ENODEV;592	}593	zc->online = 1;594 595	rc = zcrypt_card_register(zc);596	if (rc) {597		zcrypt_card_free(zc);598		return rc;599	}600 601	if (ac->hwinfo.cca) {602		rc = sysfs_create_group(&ap_dev->device.kobj,603					&cca_card_attr_grp);604		if (rc) {605			zcrypt_card_unregister(zc);606			zcrypt_card_free(zc);607		}608	} else if (ac->hwinfo.ep11) {609		rc = sysfs_create_group(&ap_dev->device.kobj,610					&ep11_card_attr_grp);611		if (rc) {612			zcrypt_card_unregister(zc);613			zcrypt_card_free(zc);614		}615	}616 617	return rc;618}619 620/*621 * This is called to remove the CEX[45678] card driver622 * information if an AP card device is removed.623 */624static void zcrypt_cex4_card_remove(struct ap_device *ap_dev)625{626	struct zcrypt_card *zc = dev_get_drvdata(&ap_dev->device);627	struct ap_card *ac = to_ap_card(&ap_dev->device);628 629	if (ac->hwinfo.cca)630		sysfs_remove_group(&ap_dev->device.kobj, &cca_card_attr_grp);631	else if (ac->hwinfo.ep11)632		sysfs_remove_group(&ap_dev->device.kobj, &ep11_card_attr_grp);633 634	zcrypt_card_unregister(zc);635}636 637static struct ap_driver zcrypt_cex4_card_driver = {638	.probe = zcrypt_cex4_card_probe,639	.remove = zcrypt_cex4_card_remove,640	.ids = zcrypt_cex4_card_ids,641	.flags = AP_DRIVER_FLAG_DEFAULT,642};643 644/*645 * Probe function for CEX[45678] queue device. It always646 * accepts the AP device since the bus_match already checked647 * the hardware type.648 * @ap_dev: pointer to the AP device.649 */650static int zcrypt_cex4_queue_probe(struct ap_device *ap_dev)651{652	struct ap_queue *aq = to_ap_queue(&ap_dev->device);653	struct zcrypt_queue *zq;654	int rc;655 656	if (aq->card->hwinfo.accel) {657		zq = zcrypt_queue_alloc(aq->card->maxmsgsize);658		if (!zq)659			return -ENOMEM;660		zq->ops = zcrypt_msgtype(MSGTYPE50_NAME,661					 MSGTYPE50_VARIANT_DEFAULT);662	} else if (aq->card->hwinfo.cca) {663		zq = zcrypt_queue_alloc(aq->card->maxmsgsize);664		if (!zq)665			return -ENOMEM;666		zq->ops = zcrypt_msgtype(MSGTYPE06_NAME,667					 MSGTYPE06_VARIANT_DEFAULT);668	} else if (aq->card->hwinfo.ep11) {669		zq = zcrypt_queue_alloc(aq->card->maxmsgsize);670		if (!zq)671			return -ENOMEM;672		zq->ops = zcrypt_msgtype(MSGTYPE06_NAME,673					 MSGTYPE06_VARIANT_EP11);674	} else {675		return -ENODEV;676	}677 678	zq->queue = aq;679	zq->online = 1;680	atomic_set(&zq->load, 0);681	ap_queue_init_state(aq);682	ap_queue_init_reply(aq, &zq->reply);683	aq->request_timeout = CEX4_CLEANUP_TIME;684	dev_set_drvdata(&ap_dev->device, zq);685	rc = zcrypt_queue_register(zq);686	if (rc) {687		zcrypt_queue_free(zq);688		return rc;689	}690 691	if (aq->card->hwinfo.cca) {692		rc = sysfs_create_group(&ap_dev->device.kobj,693					&cca_queue_attr_grp);694		if (rc) {695			zcrypt_queue_unregister(zq);696			zcrypt_queue_free(zq);697		}698	} else if (aq->card->hwinfo.ep11) {699		rc = sysfs_create_group(&ap_dev->device.kobj,700					&ep11_queue_attr_grp);701		if (rc) {702			zcrypt_queue_unregister(zq);703			zcrypt_queue_free(zq);704		}705	}706 707	return rc;708}709 710/*711 * This is called to remove the CEX[45678] queue driver712 * information if an AP queue device is removed.713 */714static void zcrypt_cex4_queue_remove(struct ap_device *ap_dev)715{716	struct zcrypt_queue *zq = dev_get_drvdata(&ap_dev->device);717	struct ap_queue *aq = to_ap_queue(&ap_dev->device);718 719	if (aq->card->hwinfo.cca)720		sysfs_remove_group(&ap_dev->device.kobj, &cca_queue_attr_grp);721	else if (aq->card->hwinfo.ep11)722		sysfs_remove_group(&ap_dev->device.kobj, &ep11_queue_attr_grp);723 724	zcrypt_queue_unregister(zq);725}726 727static struct ap_driver zcrypt_cex4_queue_driver = {728	.probe = zcrypt_cex4_queue_probe,729	.remove = zcrypt_cex4_queue_remove,730	.ids = zcrypt_cex4_queue_ids,731	.flags = AP_DRIVER_FLAG_DEFAULT,732};733 734int __init zcrypt_cex4_init(void)735{736	int rc;737 738	rc = ap_driver_register(&zcrypt_cex4_card_driver,739				THIS_MODULE, "cex4card");740	if (rc)741		return rc;742 743	rc = ap_driver_register(&zcrypt_cex4_queue_driver,744				THIS_MODULE, "cex4queue");745	if (rc)746		ap_driver_unregister(&zcrypt_cex4_card_driver);747 748	return rc;749}750 751void __exit zcrypt_cex4_exit(void)752{753	ap_driver_unregister(&zcrypt_cex4_queue_driver);754	ap_driver_unregister(&zcrypt_cex4_card_driver);755}756 757module_init(zcrypt_cex4_init);758module_exit(zcrypt_cex4_exit);759