// SPDX-License-Identifier: GPL-2.0+
/*
 *  Copyright IBM Corp. 2001, 2012
 *  Author(s): Robert Burroughs
 *	       Eric Rossman (edrossma@us.ibm.com)
 *
 *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
 *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
 *				  Ralph Wuerthner <rwuerthn@de.ibm.com>
 *  MSGTYPE restruct:		  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>
#include <linux/mod_devicetable.h>

#include "ap_bus.h"
#include "zcrypt_api.h"
#include "zcrypt_error.h"
#include "zcrypt_cex2a.h"
#include "zcrypt_msgtype50.h"

#define CEX2A_MIN_MOD_SIZE	  1	/*    8 bits	*/
#define CEX2A_MAX_MOD_SIZE	256	/* 2048 bits	*/
#define CEX3A_MIN_MOD_SIZE	CEX2A_MIN_MOD_SIZE
#define CEX3A_MAX_MOD_SIZE	512	/* 4096 bits	*/

#define CEX2A_MAX_MESSAGE_SIZE	0x390	/* sizeof(struct type50_crb2_msg)    */
#define CEX2A_MAX_RESPONSE_SIZE 0x110	/* max outputdatalength + type80_hdr */

#define CEX3A_MAX_RESPONSE_SIZE	0x210	/* 512 bit modulus
					 * (max outputdatalength) +
					 * type80_hdr*/
#define CEX3A_MAX_MESSAGE_SIZE	sizeof(struct type50_crb3_msg)

#define CEX2A_CLEANUP_TIME	(15*HZ)
#define CEX3A_CLEANUP_TIME	CEX2A_CLEANUP_TIME

MODULE_AUTHOR("IBM Corporation");
MODULE_DESCRIPTION("CEX2A/CEX3A Cryptographic Coprocessor device driver, " \
		   "Copyright IBM Corp. 2001, 2018");
MODULE_LICENSE("GPL");

static struct ap_device_id zcrypt_cex2a_card_ids[] = {
	{ .dev_type = AP_DEVICE_TYPE_CEX2A,
	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
	{ .dev_type = AP_DEVICE_TYPE_CEX3A,
	  .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
	{ /* end of list */ },
};

MODULE_DEVICE_TABLE(ap, zcrypt_cex2a_card_ids);

static struct ap_device_id zcrypt_cex2a_queue_ids[] = {
	{ .dev_type = AP_DEVICE_TYPE_CEX2A,
	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
	{ .dev_type = AP_DEVICE_TYPE_CEX3A,
	  .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
	{ /* end of list */ },
};

MODULE_DEVICE_TABLE(ap, zcrypt_cex2a_queue_ids);

/*
 * Probe function for CEX2A card devices. It always accepts the AP device
 * since the bus_match already checked the card type.
 * @ap_dev: pointer to the AP device.
 */
static int zcrypt_cex2a_card_probe(struct ap_device *ap_dev)
{
	/*
	 * Normalized speed ratings per crypto adapter
	 * MEX_1k, MEX_2k, MEX_4k, CRT_1k, CRT_2k, CRT_4k, RNG, SECKEY
	 */
	static const int CEX2A_SPEED_IDX[] = {
		800, 1000, 2000,  900, 1200, 2400, 0, 0};
	static const int CEX3A_SPEED_IDX[] = {
		400,  500, 1000,  450,	550, 1200, 0, 0};

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

	zc = zcrypt_card_alloc();
	if (!zc)
		return -ENOMEM;
	zc->card = ac;
	dev_set_drvdata(&ap_dev->device, zc);

	if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX2A) {
		zc->min_mod_size = CEX2A_MIN_MOD_SIZE;
		zc->max_mod_size = CEX2A_MAX_MOD_SIZE;
		zc->speed_rating = CEX2A_SPEED_IDX;
		zc->max_exp_bit_length = CEX2A_MAX_MOD_SIZE;
		zc->type_string = "CEX2A";
		zc->user_space_type = ZCRYPT_CEX2A;
	} else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX3A) {
		zc->min_mod_size = CEX2A_MIN_MOD_SIZE;
		zc->max_mod_size = CEX2A_MAX_MOD_SIZE;
		zc->max_exp_bit_length = CEX2A_MAX_MOD_SIZE;
		if (ap_test_bit(&ac->functions, AP_FUNC_MEX4K) &&
		    ap_test_bit(&ac->functions, AP_FUNC_CRT4K)) {
			zc->max_mod_size = CEX3A_MAX_MOD_SIZE;
			zc->max_exp_bit_length = CEX3A_MAX_MOD_SIZE;
		}
		zc->speed_rating = CEX3A_SPEED_IDX;
		zc->type_string = "CEX3A";
		zc->user_space_type = ZCRYPT_CEX3A;
	} else {
		zcrypt_card_free(zc);
		return -ENODEV;
	}
	zc->online = 1;

	rc = zcrypt_card_register(zc);
	if (rc) {
		zcrypt_card_free(zc);
	}

	return rc;
}

/*
 * This is called to remove the CEX2A card driver information
 * if an AP card device is removed.
 */
static void zcrypt_cex2a_card_remove(struct ap_device *ap_dev)
{
	struct zcrypt_card *zc = dev_get_drvdata(&ap_dev->device);

	zcrypt_card_unregister(zc);
}

static struct ap_driver zcrypt_cex2a_card_driver = {
	.probe = zcrypt_cex2a_card_probe,
	.remove = zcrypt_cex2a_card_remove,
	.ids = zcrypt_cex2a_card_ids,
	.flags = AP_DRIVER_FLAG_DEFAULT,
};

/*
 * Probe function for CEX2A queue devices. It always accepts the AP device
 * since the bus_match already checked the queue type.
 * @ap_dev: pointer to the AP device.
 */
static int zcrypt_cex2a_queue_probe(struct ap_device *ap_dev)
{
	struct ap_queue *aq = to_ap_queue(&ap_dev->device);
	struct zcrypt_queue *zq = NULL;
	int rc;

	switch (ap_dev->device_type) {
	case AP_DEVICE_TYPE_CEX2A:
		zq = zcrypt_queue_alloc(CEX2A_MAX_RESPONSE_SIZE);
		if (!zq)
			return -ENOMEM;
		break;
	case AP_DEVICE_TYPE_CEX3A:
		zq = zcrypt_queue_alloc(CEX3A_MAX_RESPONSE_SIZE);
		if (!zq)
			return -ENOMEM;
		break;
	}
	if (!zq)
		return -ENODEV;
	zq->ops = zcrypt_msgtype(MSGTYPE50_NAME, MSGTYPE50_VARIANT_DEFAULT);
	zq->queue = aq;
	zq->online = 1;
	atomic_set(&zq->load, 0);
	ap_queue_init_state(aq);
	ap_queue_init_reply(aq, &zq->reply);
	aq->request_timeout = CEX2A_CLEANUP_TIME;
	dev_set_drvdata(&ap_dev->device, zq);
	rc = zcrypt_queue_register(zq);
	if (rc) {
		zcrypt_queue_free(zq);
	}

	return rc;
}

/*
 * This is called to remove the CEX2A queue driver information
 * if an AP queue device is removed.
 */
static void zcrypt_cex2a_queue_remove(struct ap_device *ap_dev)
{
	struct zcrypt_queue *zq = dev_get_drvdata(&ap_dev->device);

	zcrypt_queue_unregister(zq);
}

static struct ap_driver zcrypt_cex2a_queue_driver = {
	.probe = zcrypt_cex2a_queue_probe,
	.remove = zcrypt_cex2a_queue_remove,
	.ids = zcrypt_cex2a_queue_ids,
	.flags = AP_DRIVER_FLAG_DEFAULT,
};

int __init zcrypt_cex2a_init(void)
{
	int rc;

	rc = ap_driver_register(&zcrypt_cex2a_card_driver,
				THIS_MODULE, "cex2acard");
	if (rc)
		return rc;

	rc = ap_driver_register(&zcrypt_cex2a_queue_driver,
				THIS_MODULE, "cex2aqueue");
	if (rc)
		ap_driver_unregister(&zcrypt_cex2a_card_driver);

	return rc;
}

void __exit zcrypt_cex2a_exit(void)
{
	ap_driver_unregister(&zcrypt_cex2a_queue_driver);
	ap_driver_unregister(&zcrypt_cex2a_card_driver);
}

module_init(zcrypt_cex2a_init);
module_exit(zcrypt_cex2a_exit);
