0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/module.h>
0014 #include <linux/slab.h>
0015 #include <linux/init.h>
0016 #include <linux/err.h>
0017 #include <linux/atomic.h>
0018 #include <linux/uaccess.h>
0019 #include <linux/mod_devicetable.h>
0020
0021 #include "ap_bus.h"
0022 #include "zcrypt_api.h"
0023 #include "zcrypt_error.h"
0024 #include "zcrypt_cex2a.h"
0025 #include "zcrypt_msgtype50.h"
0026
0027 #define CEX2A_MIN_MOD_SIZE 1
0028 #define CEX2A_MAX_MOD_SIZE 256
0029 #define CEX3A_MIN_MOD_SIZE CEX2A_MIN_MOD_SIZE
0030 #define CEX3A_MAX_MOD_SIZE 512
0031
0032 #define CEX2A_MAX_MESSAGE_SIZE 0x390
0033 #define CEX2A_MAX_RESPONSE_SIZE 0x110
0034
0035 #define CEX3A_MAX_RESPONSE_SIZE 0x210
0036
0037
0038
0039 #define CEX3A_MAX_MESSAGE_SIZE sizeof(struct type50_crb3_msg)
0040
0041 #define CEX2A_CLEANUP_TIME (15 * HZ)
0042 #define CEX3A_CLEANUP_TIME CEX2A_CLEANUP_TIME
0043
0044 MODULE_AUTHOR("IBM Corporation");
0045 MODULE_DESCRIPTION("CEX2A/CEX3A Cryptographic Coprocessor device driver, " \
0046 "Copyright IBM Corp. 2001, 2018");
0047 MODULE_LICENSE("GPL");
0048
0049 static struct ap_device_id zcrypt_cex2a_card_ids[] = {
0050 { .dev_type = AP_DEVICE_TYPE_CEX2A,
0051 .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
0052 { .dev_type = AP_DEVICE_TYPE_CEX3A,
0053 .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
0054 { },
0055 };
0056
0057 MODULE_DEVICE_TABLE(ap, zcrypt_cex2a_card_ids);
0058
0059 static struct ap_device_id zcrypt_cex2a_queue_ids[] = {
0060 { .dev_type = AP_DEVICE_TYPE_CEX2A,
0061 .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
0062 { .dev_type = AP_DEVICE_TYPE_CEX3A,
0063 .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
0064 { },
0065 };
0066
0067 MODULE_DEVICE_TABLE(ap, zcrypt_cex2a_queue_ids);
0068
0069
0070
0071
0072
0073
0074 static int zcrypt_cex2a_card_probe(struct ap_device *ap_dev)
0075 {
0076
0077
0078
0079
0080 static const int CEX2A_SPEED_IDX[] = {
0081 800, 1000, 2000, 900, 1200, 2400, 0, 0};
0082 static const int CEX3A_SPEED_IDX[] = {
0083 400, 500, 1000, 450, 550, 1200, 0, 0};
0084
0085 struct ap_card *ac = to_ap_card(&ap_dev->device);
0086 struct zcrypt_card *zc;
0087 int rc = 0;
0088
0089 zc = zcrypt_card_alloc();
0090 if (!zc)
0091 return -ENOMEM;
0092 zc->card = ac;
0093 dev_set_drvdata(&ap_dev->device, zc);
0094
0095 if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX2A) {
0096 zc->min_mod_size = CEX2A_MIN_MOD_SIZE;
0097 zc->max_mod_size = CEX2A_MAX_MOD_SIZE;
0098 zc->speed_rating = CEX2A_SPEED_IDX;
0099 zc->max_exp_bit_length = CEX2A_MAX_MOD_SIZE;
0100 zc->type_string = "CEX2A";
0101 zc->user_space_type = ZCRYPT_CEX2A;
0102 } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX3A) {
0103 zc->min_mod_size = CEX2A_MIN_MOD_SIZE;
0104 zc->max_mod_size = CEX2A_MAX_MOD_SIZE;
0105 zc->max_exp_bit_length = CEX2A_MAX_MOD_SIZE;
0106 if (ap_test_bit(&ac->functions, AP_FUNC_MEX4K) &&
0107 ap_test_bit(&ac->functions, AP_FUNC_CRT4K)) {
0108 zc->max_mod_size = CEX3A_MAX_MOD_SIZE;
0109 zc->max_exp_bit_length = CEX3A_MAX_MOD_SIZE;
0110 }
0111 zc->speed_rating = CEX3A_SPEED_IDX;
0112 zc->type_string = "CEX3A";
0113 zc->user_space_type = ZCRYPT_CEX3A;
0114 } else {
0115 zcrypt_card_free(zc);
0116 return -ENODEV;
0117 }
0118 zc->online = 1;
0119
0120 rc = zcrypt_card_register(zc);
0121 if (rc)
0122 zcrypt_card_free(zc);
0123
0124 return rc;
0125 }
0126
0127
0128
0129
0130
0131 static void zcrypt_cex2a_card_remove(struct ap_device *ap_dev)
0132 {
0133 struct zcrypt_card *zc = dev_get_drvdata(&ap_dev->device);
0134
0135 zcrypt_card_unregister(zc);
0136 }
0137
0138 static struct ap_driver zcrypt_cex2a_card_driver = {
0139 .probe = zcrypt_cex2a_card_probe,
0140 .remove = zcrypt_cex2a_card_remove,
0141 .ids = zcrypt_cex2a_card_ids,
0142 .flags = AP_DRIVER_FLAG_DEFAULT,
0143 };
0144
0145
0146
0147
0148
0149
0150 static int zcrypt_cex2a_queue_probe(struct ap_device *ap_dev)
0151 {
0152 struct ap_queue *aq = to_ap_queue(&ap_dev->device);
0153 struct zcrypt_queue *zq = NULL;
0154 int rc;
0155
0156 switch (ap_dev->device_type) {
0157 case AP_DEVICE_TYPE_CEX2A:
0158 zq = zcrypt_queue_alloc(CEX2A_MAX_RESPONSE_SIZE);
0159 if (!zq)
0160 return -ENOMEM;
0161 break;
0162 case AP_DEVICE_TYPE_CEX3A:
0163 zq = zcrypt_queue_alloc(CEX3A_MAX_RESPONSE_SIZE);
0164 if (!zq)
0165 return -ENOMEM;
0166 break;
0167 }
0168 if (!zq)
0169 return -ENODEV;
0170 zq->ops = zcrypt_msgtype(MSGTYPE50_NAME, MSGTYPE50_VARIANT_DEFAULT);
0171 zq->queue = aq;
0172 zq->online = 1;
0173 atomic_set(&zq->load, 0);
0174 ap_queue_init_state(aq);
0175 ap_queue_init_reply(aq, &zq->reply);
0176 aq->request_timeout = CEX2A_CLEANUP_TIME;
0177 dev_set_drvdata(&ap_dev->device, zq);
0178 rc = zcrypt_queue_register(zq);
0179 if (rc)
0180 zcrypt_queue_free(zq);
0181
0182 return rc;
0183 }
0184
0185
0186
0187
0188
0189 static void zcrypt_cex2a_queue_remove(struct ap_device *ap_dev)
0190 {
0191 struct zcrypt_queue *zq = dev_get_drvdata(&ap_dev->device);
0192
0193 zcrypt_queue_unregister(zq);
0194 }
0195
0196 static struct ap_driver zcrypt_cex2a_queue_driver = {
0197 .probe = zcrypt_cex2a_queue_probe,
0198 .remove = zcrypt_cex2a_queue_remove,
0199 .ids = zcrypt_cex2a_queue_ids,
0200 .flags = AP_DRIVER_FLAG_DEFAULT,
0201 };
0202
0203 int __init zcrypt_cex2a_init(void)
0204 {
0205 int rc;
0206
0207 rc = ap_driver_register(&zcrypt_cex2a_card_driver,
0208 THIS_MODULE, "cex2acard");
0209 if (rc)
0210 return rc;
0211
0212 rc = ap_driver_register(&zcrypt_cex2a_queue_driver,
0213 THIS_MODULE, "cex2aqueue");
0214 if (rc)
0215 ap_driver_unregister(&zcrypt_cex2a_card_driver);
0216
0217 return rc;
0218 }
0219
0220 void __exit zcrypt_cex2a_exit(void)
0221 {
0222 ap_driver_unregister(&zcrypt_cex2a_queue_driver);
0223 ap_driver_unregister(&zcrypt_cex2a_card_driver);
0224 }
0225
0226 module_init(zcrypt_cex2a_init);
0227 module_exit(zcrypt_cex2a_exit);