cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

zcrypt_cex4.c (22539B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 *  Copyright IBM Corp. 2012, 2022
      4 *  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 attributes
     77 */
     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 scnprintf(buf, PAGE_SIZE, "%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 attributes
    108  */
    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 += scnprintf(buf + n, PAGE_SIZE,
    127			       "AES NEW: %s 0x%016llx\n",
    128			       new_state[ci.new_aes_mk_state - '1'],
    129			       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		n += scnprintf(buf + n, PAGE_SIZE - n,
    135			       "AES CUR: %s 0x%016llx\n",
    136			       cao_state[ci.cur_aes_mk_state - '1'],
    137			       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		n += scnprintf(buf + n, PAGE_SIZE - n,
    143			       "AES OLD: %s 0x%016llx\n",
    144			       cao_state[ci.old_aes_mk_state - '1'],
    145			       ci.old_aes_mkvp);
    146	else
    147		n += scnprintf(buf + n, PAGE_SIZE - n, "AES OLD: - -\n");
    148
    149	if (ci.new_apka_mk_state >= '1' && ci.new_apka_mk_state <= '3')
    150		n += scnprintf(buf + n, PAGE_SIZE - n,
    151			       "APKA NEW: %s 0x%016llx\n",
    152			       new_state[ci.new_apka_mk_state - '1'],
    153			       ci.new_apka_mkvp);
    154	else
    155		n += scnprintf(buf + n, PAGE_SIZE - n, "APKA NEW: - -\n");
    156
    157	if (ci.cur_apka_mk_state >= '1' && ci.cur_apka_mk_state <= '2')
    158		n += scnprintf(buf + n, PAGE_SIZE - n,
    159			       "APKA CUR: %s 0x%016llx\n",
    160			       cao_state[ci.cur_apka_mk_state - '1'],
    161			       ci.cur_apka_mkvp);
    162	else
    163		n += scnprintf(buf + n, PAGE_SIZE - n, "APKA CUR: - -\n");
    164
    165	if (ci.old_apka_mk_state >= '1' && ci.old_apka_mk_state <= '2')
    166		n += scnprintf(buf + n, PAGE_SIZE - n,
    167			       "APKA OLD: %s 0x%016llx\n",
    168			       cao_state[ci.old_apka_mk_state - '1'],
    169			       ci.old_apka_mkvp);
    170	else
    171		n += scnprintf(buf + n, PAGE_SIZE - n, "APKA OLD: - -\n");
    172
    173	if (ci.new_asym_mk_state >= '1' && ci.new_asym_mk_state <= '3')
    174		n += scnprintf(buf + n, PAGE_SIZE,
    175			       "ASYM NEW: %s 0x%016llx%016llx\n",
    176			       new_state[ci.new_asym_mk_state - '1'],
    177			       *((u64 *)(ci.new_asym_mkvp)),
    178			       *((u64 *)(ci.new_asym_mkvp + sizeof(u64))));
    179	else
    180		n += scnprintf(buf + n, PAGE_SIZE, "ASYM NEW: - -\n");
    181
    182	if (ci.cur_asym_mk_state >= '1' && ci.cur_asym_mk_state <= '2')
    183		n += scnprintf(buf + n, PAGE_SIZE - n,
    184			       "ASYM CUR: %s 0x%016llx%016llx\n",
    185			       cao_state[ci.cur_asym_mk_state - '1'],
    186			       *((u64 *)(ci.cur_asym_mkvp)),
    187			       *((u64 *)(ci.cur_asym_mkvp + sizeof(u64))));
    188	else
    189		n += scnprintf(buf + n, PAGE_SIZE - n, "ASYM CUR: - -\n");
    190
    191	if (ci.old_asym_mk_state >= '1' && ci.old_asym_mk_state <= '2')
    192		n += scnprintf(buf + n, PAGE_SIZE - n,
    193			       "ASYM OLD: %s 0x%016llx%016llx\n",
    194			       cao_state[ci.old_asym_mk_state - '1'],
    195			       *((u64 *)(ci.old_asym_mkvp)),
    196			       *((u64 *)(ci.old_asym_mkvp + sizeof(u64))));
    197	else
    198		n += scnprintf(buf + n, PAGE_SIZE - n, "ASYM OLD: - -\n");
    199
    200	return n;
    201}
    202
    203static struct device_attribute dev_attr_cca_mkvps =
    204	__ATTR(mkvps, 0444, cca_mkvps_show, NULL);
    205
    206static struct attribute *cca_queue_attrs[] = {
    207	&dev_attr_cca_mkvps.attr,
    208	NULL,
    209};
    210
    211static const struct attribute_group cca_queue_attr_grp = {
    212	.attrs = cca_queue_attrs,
    213};
    214
    215/*
    216 * EP11 card additional device attributes
    217 */
    218static ssize_t ep11_api_ordinalnr_show(struct device *dev,
    219				       struct device_attribute *attr,
    220				       char *buf)
    221{
    222	struct zcrypt_card *zc = dev_get_drvdata(dev);
    223	struct ep11_card_info ci;
    224	struct ap_card *ac = to_ap_card(dev);
    225
    226	memset(&ci, 0, sizeof(ci));
    227
    228	ep11_get_card_info(ac->id, &ci, zc->online);
    229
    230	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
    236static struct device_attribute dev_attr_ep11_api_ordinalnr =
    237	__ATTR(API_ordinalnr, 0444, ep11_api_ordinalnr_show, NULL);
    238
    239static ssize_t ep11_fw_version_show(struct device *dev,
    240				    struct device_attribute *attr,
    241				    char *buf)
    242{
    243	struct zcrypt_card *zc = dev_get_drvdata(dev);
    244	struct ep11_card_info ci;
    245	struct ap_card *ac = to_ap_card(dev);
    246
    247	memset(&ci, 0, sizeof(ci));
    248
    249	ep11_get_card_info(ac->id, &ci, zc->online);
    250
    251	if (ci.FW_version > 0)
    252		return scnprintf(buf, PAGE_SIZE, "%d.%d\n",
    253				 (int)(ci.FW_version >> 8),
    254				 (int)(ci.FW_version & 0xFF));
    255	else
    256		return scnprintf(buf, PAGE_SIZE, "\n");
    257}
    258
    259static struct device_attribute dev_attr_ep11_fw_version =
    260	__ATTR(FW_version, 0444, ep11_fw_version_show, NULL);
    261
    262static ssize_t ep11_serialnr_show(struct device *dev,
    263				  struct device_attribute *attr,
    264				  char *buf)
    265{
    266	struct zcrypt_card *zc = dev_get_drvdata(dev);
    267	struct ep11_card_info ci;
    268	struct ap_card *ac = to_ap_card(dev);
    269
    270	memset(&ci, 0, sizeof(ci));
    271
    272	ep11_get_card_info(ac->id, &ci, zc->online);
    273
    274	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
    280static struct device_attribute dev_attr_ep11_serialnr =
    281	__ATTR(serialnr, 0444, ep11_serialnr_show, NULL);
    282
    283static const struct {
    284	int	    mode_bit;
    285	const char *mode_txt;
    286} ep11_op_modes[] = {
    287	{ 0, "FIPS2009" },
    288	{ 1, "BSI2009" },
    289	{ 2, "FIPS2011" },
    290	{ 3, "BSI2011" },
    291	{ 6, "BSICC2017" },
    292	{ 0, NULL }
    293};
    294
    295static ssize_t ep11_card_op_modes_show(struct device *dev,
    296				       struct device_attribute *attr,
    297				       char *buf)
    298{
    299	struct zcrypt_card *zc = dev_get_drvdata(dev);
    300	int i, n = 0;
    301	struct ep11_card_info ci;
    302	struct ap_card *ac = to_ap_card(dev);
    303
    304	memset(&ci, 0, sizeof(ci));
    305
    306	ep11_get_card_info(ac->id, &ci, zc->online);
    307
    308	for (i = 0; ep11_op_modes[i].mode_txt; i++) {
    309		if (ci.op_mode & (1ULL << ep11_op_modes[i].mode_bit)) {
    310			if (n > 0)
    311				buf[n++] = ' ';
    312			n += scnprintf(buf + n, PAGE_SIZE - n,
    313				       "%s", ep11_op_modes[i].mode_txt);
    314		}
    315	}
    316	n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
    317
    318	return n;
    319}
    320
    321static struct device_attribute dev_attr_ep11_card_op_modes =
    322	__ATTR(op_modes, 0444, ep11_card_op_modes_show, NULL);
    323
    324static struct attribute *ep11_card_attrs[] = {
    325	&dev_attr_ep11_api_ordinalnr.attr,
    326	&dev_attr_ep11_fw_version.attr,
    327	&dev_attr_ep11_serialnr.attr,
    328	&dev_attr_ep11_card_op_modes.attr,
    329	NULL,
    330};
    331
    332static const struct attribute_group ep11_card_attr_grp = {
    333	.attrs = ep11_card_attrs,
    334};
    335
    336/*
    337 * EP11 queue additional device attributes
    338 */
    339
    340static ssize_t ep11_mkvps_show(struct device *dev,
    341			       struct device_attribute *attr,
    342			       char *buf)
    343{
    344	struct zcrypt_queue *zq = dev_get_drvdata(dev);
    345	int n = 0;
    346	struct ep11_domain_info di;
    347	static const char * const cwk_state[] = { "invalid", "valid" };
    348	static const char * const nwk_state[] = { "empty", "uncommitted",
    349						  "committed" };
    350
    351	memset(&di, 0, sizeof(di));
    352
    353	if (zq->online)
    354		ep11_get_domain_info(AP_QID_CARD(zq->queue->qid),
    355				     AP_QID_QUEUE(zq->queue->qid),
    356				     &di);
    357
    358	if (di.cur_wk_state == '0') {
    359		n = scnprintf(buf, PAGE_SIZE, "WK CUR: %s -\n",
    360			      cwk_state[di.cur_wk_state - '0']);
    361	} else if (di.cur_wk_state == '1') {
    362		n = scnprintf(buf, PAGE_SIZE, "WK CUR: %s 0x",
    363			      cwk_state[di.cur_wk_state - '0']);
    364		bin2hex(buf + n, di.cur_wkvp, sizeof(di.cur_wkvp));
    365		n += 2 * sizeof(di.cur_wkvp);
    366		n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
    367	} else {
    368		n = scnprintf(buf, PAGE_SIZE, "WK CUR: - -\n");
    369	}
    370
    371	if (di.new_wk_state == '0') {
    372		n += scnprintf(buf + n, PAGE_SIZE - n, "WK NEW: %s -\n",
    373			       nwk_state[di.new_wk_state - '0']);
    374	} else if (di.new_wk_state >= '1' && di.new_wk_state <= '2') {
    375		n += scnprintf(buf + n, PAGE_SIZE - n, "WK NEW: %s 0x",
    376			       nwk_state[di.new_wk_state - '0']);
    377		bin2hex(buf + n, di.new_wkvp, sizeof(di.new_wkvp));
    378		n += 2 * sizeof(di.new_wkvp);
    379		n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
    380	} else {
    381		n += scnprintf(buf + n, PAGE_SIZE - n, "WK NEW: - -\n");
    382	}
    383
    384	return n;
    385}
    386
    387static struct device_attribute dev_attr_ep11_mkvps =
    388	__ATTR(mkvps, 0444, ep11_mkvps_show, NULL);
    389
    390static ssize_t ep11_queue_op_modes_show(struct device *dev,
    391					struct device_attribute *attr,
    392					char *buf)
    393{
    394	struct zcrypt_queue *zq = dev_get_drvdata(dev);
    395	int i, n = 0;
    396	struct ep11_domain_info di;
    397
    398	memset(&di, 0, sizeof(di));
    399
    400	if (zq->online)
    401		ep11_get_domain_info(AP_QID_CARD(zq->queue->qid),
    402				     AP_QID_QUEUE(zq->queue->qid),
    403				     &di);
    404
    405	for (i = 0; ep11_op_modes[i].mode_txt; i++) {
    406		if (di.op_mode & (1ULL << ep11_op_modes[i].mode_bit)) {
    407			if (n > 0)
    408				buf[n++] = ' ';
    409			n += scnprintf(buf + n, PAGE_SIZE - n,
    410				       "%s", ep11_op_modes[i].mode_txt);
    411		}
    412	}
    413	n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
    414
    415	return n;
    416}
    417
    418static struct device_attribute dev_attr_ep11_queue_op_modes =
    419	__ATTR(op_modes, 0444, ep11_queue_op_modes_show, NULL);
    420
    421static struct attribute *ep11_queue_attrs[] = {
    422	&dev_attr_ep11_mkvps.attr,
    423	&dev_attr_ep11_queue_op_modes.attr,
    424	NULL,
    425};
    426
    427static const struct attribute_group ep11_queue_attr_grp = {
    428	.attrs = ep11_queue_attrs,
    429};
    430
    431/*
    432 * Probe function for CEX[45678] card device. It always
    433 * accepts the AP device since the bus_match already checked
    434 * the hardware type.
    435 * @ap_dev: pointer to the AP device.
    436 */
    437static int zcrypt_cex4_card_probe(struct ap_device *ap_dev)
    438{
    439	/*
    440	 * Normalized speed ratings per crypto adapter
    441	 * MEX_1k, MEX_2k, MEX_4k, CRT_1k, CRT_2k, CRT_4k, RNG, SECKEY
    442	 */
    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	static const int CEX8A_SPEED_IDX[NUM_OPS] = {
    452		  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	static const int CEX8C_SPEED_IDX[NUM_OPS] = {
    463		 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	static const int CEX8P_SPEED_IDX[NUM_OPS] = {
    474		  0,   0,   0,	 0,   0,   0,	0,   8};
    475
    476	struct ap_card *ac = to_ap_card(&ap_dev->device);
    477	struct zcrypt_card *zc;
    478	int rc = 0;
    479
    480	zc = zcrypt_card_alloc();
    481	if (!zc)
    482		return -ENOMEM;
    483	zc->card = ac;
    484	dev_set_drvdata(&ap_dev->device, zc);
    485	if (ap_test_bit(&ac->functions, AP_FUNC_ACCEL)) {
    486		if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
    487			zc->type_string = "CEX4A";
    488			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			zc->type_string = "CEX5A";
    492			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			zc->type_string = "CEX6A";
    496			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			zc->speed_rating = CEX7A_SPEED_IDX;
    501			/* wrong user space type, just for compatibility
    502			 * with the ZCRYPT_STATUS_MASK ioctl.
    503			 */
    504			zc->user_space_type = ZCRYPT_CEX6;
    505		} else {
    506			zc->type_string = "CEX8A";
    507			zc->speed_rating = CEX8A_SPEED_IDX;
    508			/* wrong user space type, just for compatibility
    509			 * with the ZCRYPT_STATUS_MASK ioctl.
    510			 */
    511			zc->user_space_type = ZCRYPT_CEX6;
    512		}
    513		zc->min_mod_size = CEX4A_MIN_MOD_SIZE;
    514		if (ap_test_bit(&ac->functions, AP_FUNC_MEX4K) &&
    515		    ap_test_bit(&ac->functions, AP_FUNC_CRT4K)) {
    516			zc->max_mod_size = CEX4A_MAX_MOD_SIZE_4K;
    517			zc->max_exp_bit_length =
    518				CEX4A_MAX_MOD_SIZE_4K;
    519		} else {
    520			zc->max_mod_size = CEX4A_MAX_MOD_SIZE_2K;
    521			zc->max_exp_bit_length =
    522				CEX4A_MAX_MOD_SIZE_2K;
    523		}
    524	} else if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) {
    525		if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
    526			zc->type_string = "CEX4C";
    527			zc->speed_rating = CEX4C_SPEED_IDX;
    528			/* wrong user space type, must be CEX3C
    529			 * just keep it for cca compatibility
    530			 */
    531			zc->user_space_type = ZCRYPT_CEX3C;
    532		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {
    533			zc->type_string = "CEX5C";
    534			zc->speed_rating = CEX5C_SPEED_IDX;
    535			/* wrong user space type, must be CEX3C
    536			 * just keep it for cca compatibility
    537			 */
    538			zc->user_space_type = ZCRYPT_CEX3C;
    539		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {
    540			zc->type_string = "CEX6C";
    541			zc->speed_rating = CEX6C_SPEED_IDX;
    542			/* wrong user space type, must be CEX3C
    543			 * just keep it for cca compatibility
    544			 */
    545			zc->user_space_type = ZCRYPT_CEX3C;
    546		} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX7) {
    547			zc->type_string = "CEX7C";
    548			zc->speed_rating = CEX7C_SPEED_IDX;
    549			/* wrong user space type, must be CEX3C
    550			 * just keep it for cca compatibility
    551			 */
    552			zc->user_space_type = ZCRYPT_CEX3C;
    553		} else {
    554			zc->type_string = "CEX8C";
    555			zc->speed_rating = CEX8C_SPEED_IDX;
    556			/* wrong user space type, must be CEX3C
    557			 * just keep it for cca compatibility
    558			 */
    559			zc->user_space_type = ZCRYPT_CEX3C;
    560		}
    561		zc->min_mod_size = CEX4C_MIN_MOD_SIZE;
    562		zc->max_mod_size = CEX4C_MAX_MOD_SIZE;
    563		zc->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;
    564	} else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) {
    565		if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
    566			zc->type_string = "CEX4P";
    567			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			zc->type_string = "CEX5P";
    571			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			zc->type_string = "CEX6P";
    575			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			zc->speed_rating = CEX7P_SPEED_IDX;
    580			/* wrong user space type, just for compatibility
    581			 * with the ZCRYPT_STATUS_MASK ioctl.
    582			 */
    583			zc->user_space_type = ZCRYPT_CEX6;
    584		} else {
    585			zc->type_string = "CEX8P";
    586			zc->speed_rating = CEX8P_SPEED_IDX;
    587			/* wrong user space type, just for compatibility
    588			 * with the ZCRYPT_STATUS_MASK ioctl.
    589			 */
    590			zc->user_space_type = ZCRYPT_CEX6;
    591		}
    592		zc->min_mod_size = CEX4C_MIN_MOD_SIZE;
    593		zc->max_mod_size = CEX4C_MAX_MOD_SIZE;
    594		zc->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;
    595	} else {
    596		zcrypt_card_free(zc);
    597		return -ENODEV;
    598	}
    599	zc->online = 1;
    600
    601	rc = zcrypt_card_register(zc);
    602	if (rc) {
    603		zcrypt_card_free(zc);
    604		return rc;
    605	}
    606
    607	if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) {
    608		rc = sysfs_create_group(&ap_dev->device.kobj,
    609					&cca_card_attr_grp);
    610		if (rc) {
    611			zcrypt_card_unregister(zc);
    612			zcrypt_card_free(zc);
    613		}
    614	} else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) {
    615		rc = sysfs_create_group(&ap_dev->device.kobj,
    616					&ep11_card_attr_grp);
    617		if (rc) {
    618			zcrypt_card_unregister(zc);
    619			zcrypt_card_free(zc);
    620		}
    621	}
    622
    623	return rc;
    624}
    625
    626/*
    627 * This is called to remove the CEX[45678] card driver
    628 * information if an AP card device is removed.
    629 */
    630static 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		sysfs_remove_group(&ap_dev->device.kobj, &cca_card_attr_grp);
    637	else if (ap_test_bit(&ac->functions, AP_FUNC_EP11))
    638		sysfs_remove_group(&ap_dev->device.kobj, &ep11_card_attr_grp);
    639
    640	zcrypt_card_unregister(zc);
    641}
    642
    643static struct ap_driver zcrypt_cex4_card_driver = {
    644	.probe = zcrypt_cex4_card_probe,
    645	.remove = zcrypt_cex4_card_remove,
    646	.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 * accepts the AP device since the bus_match already checked
    653 * the hardware type.
    654 * @ap_dev: pointer to the AP device.
    655 */
    656static int zcrypt_cex4_queue_probe(struct ap_device *ap_dev)
    657{
    658	struct ap_queue *aq = to_ap_queue(&ap_dev->device);
    659	struct zcrypt_queue *zq;
    660	int rc;
    661
    662	if (ap_test_bit(&aq->card->functions, AP_FUNC_ACCEL)) {
    663		zq = zcrypt_queue_alloc(aq->card->maxmsgsize);
    664		if (!zq)
    665			return -ENOMEM;
    666		zq->ops = zcrypt_msgtype(MSGTYPE50_NAME,
    667					 MSGTYPE50_VARIANT_DEFAULT);
    668	} else if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) {
    669		zq = zcrypt_queue_alloc(aq->card->maxmsgsize);
    670		if (!zq)
    671			return -ENOMEM;
    672		zq->ops = zcrypt_msgtype(MSGTYPE06_NAME,
    673					 MSGTYPE06_VARIANT_DEFAULT);
    674	} else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) {
    675		zq = zcrypt_queue_alloc(aq->card->maxmsgsize);
    676		if (!zq)
    677			return -ENOMEM;
    678		zq->ops = zcrypt_msgtype(MSGTYPE06_NAME,
    679					 MSGTYPE06_VARIANT_EP11);
    680	} else {
    681		return -ENODEV;
    682	}
    683
    684	zq->queue = aq;
    685	zq->online = 1;
    686	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	rc = zcrypt_queue_register(zq);
    692	if (rc) {
    693		zcrypt_queue_free(zq);
    694		return rc;
    695	}
    696
    697	if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) {
    698		rc = sysfs_create_group(&ap_dev->device.kobj,
    699					&cca_queue_attr_grp);
    700		if (rc) {
    701			zcrypt_queue_unregister(zq);
    702			zcrypt_queue_free(zq);
    703		}
    704	} else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) {
    705		rc = sysfs_create_group(&ap_dev->device.kobj,
    706					&ep11_queue_attr_grp);
    707		if (rc) {
    708			zcrypt_queue_unregister(zq);
    709			zcrypt_queue_free(zq);
    710		}
    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 */
    720static void zcrypt_cex4_queue_remove(struct ap_device *ap_dev)
    721{
    722	struct zcrypt_queue *zq = dev_get_drvdata(&ap_dev->device);
    723	struct ap_queue *aq = to_ap_queue(&ap_dev->device);
    724
    725	if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO))
    726		sysfs_remove_group(&ap_dev->device.kobj, &cca_queue_attr_grp);
    727	else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11))
    728		sysfs_remove_group(&ap_dev->device.kobj, &ep11_queue_attr_grp);
    729
    730	zcrypt_queue_unregister(zq);
    731}
    732
    733static struct ap_driver zcrypt_cex4_queue_driver = {
    734	.probe = zcrypt_cex4_queue_probe,
    735	.remove = zcrypt_cex4_queue_remove,
    736	.ids = zcrypt_cex4_queue_ids,
    737	.flags = AP_DRIVER_FLAG_DEFAULT,
    738};
    739
    740int __init zcrypt_cex4_init(void)
    741{
    742	int rc;
    743
    744	rc = ap_driver_register(&zcrypt_cex4_card_driver,
    745				THIS_MODULE, "cex4card");
    746	if (rc)
    747		return rc;
    748
    749	rc = ap_driver_register(&zcrypt_cex4_queue_driver,
    750				THIS_MODULE, "cex4queue");
    751	if (rc)
    752		ap_driver_unregister(&zcrypt_cex4_card_driver);
    753
    754	return rc;
    755}
    756
    757void __exit zcrypt_cex4_exit(void)
    758{
    759	ap_driver_unregister(&zcrypt_cex4_queue_driver);
    760	ap_driver_unregister(&zcrypt_cex4_card_driver);
    761}
    762
    763module_init(zcrypt_cex4_init);
    764module_exit(zcrypt_cex4_exit);