// SPDX-License-Identifier: GPL-2.0+
/*
 *  Copyright IBM Corp. 2001, 2012
 *  Author(s): Robert Burroughs
 *	       Eric Rossman (edrossma@us.ibm.com)
 *	       Cornelia Huck <cornelia.huck@de.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/init.h>
#include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/compat.h>
#include <linux/slab.h>
#include <linux/atomic.h>
#include <linux/uaccess.h>
#include <linux/hw_random.h>
#include <linux/debugfs.h>
#include <asm/debug.h>

#include "zcrypt_debug.h"
#include "zcrypt_api.h"

#include "zcrypt_msgtype6.h"
#include "zcrypt_msgtype50.h"

/*
 * Device attributes common for all crypto queue devices.
 */

static ssize_t online_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{
	struct zcrypt_queue *zq = to_ap_queue(dev)->private;

	return snprintf(buf, PAGE_SIZE, "%d\n", zq->online);
}

static ssize_t online_store(struct device *dev,
			    struct device_attribute *attr,
			    const char *buf, size_t count)
{
	struct zcrypt_queue *zq = to_ap_queue(dev)->private;
	struct zcrypt_card *zc = zq->zcard;
	int online;

	if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1)
		return -EINVAL;

	if (online && !zc->online)
		return -EINVAL;
	zq->online = online;

	ZCRYPT_DBF(DBF_INFO, "queue=%02x.%04x online=%d\n",
		   AP_QID_CARD(zq->queue->qid),
		   AP_QID_QUEUE(zq->queue->qid),
		   online);

	if (!online)
		ap_flush_queue(zq->queue);
	return count;
}

static DEVICE_ATTR_RW(online);

static ssize_t load_show(struct device *dev,
			 struct device_attribute *attr,
			 char *buf)
{
	struct zcrypt_queue *zq = to_ap_queue(dev)->private;

	return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&zq->load));
}

static DEVICE_ATTR_RO(load);

static struct attribute *zcrypt_queue_attrs[] = {
	&dev_attr_online.attr,
	&dev_attr_load.attr,
	NULL,
};

static const struct attribute_group zcrypt_queue_attr_group = {
	.attrs = zcrypt_queue_attrs,
};

void zcrypt_queue_force_online(struct zcrypt_queue *zq, int online)
{
	zq->online = online;
	if (!online)
		ap_flush_queue(zq->queue);
}

struct zcrypt_queue *zcrypt_queue_alloc(size_t max_response_size)
{
	struct zcrypt_queue *zq;

	zq = kzalloc(sizeof(struct zcrypt_queue), GFP_KERNEL);
	if (!zq)
		return NULL;
	zq->reply.message = kmalloc(max_response_size, GFP_KERNEL);
	if (!zq->reply.message)
		goto out_free;
	zq->reply.length = max_response_size;
	INIT_LIST_HEAD(&zq->list);
	kref_init(&zq->refcount);
	return zq;

out_free:
	kfree(zq);
	return NULL;
}
EXPORT_SYMBOL(zcrypt_queue_alloc);

void zcrypt_queue_free(struct zcrypt_queue *zq)
{
	kfree(zq->reply.message);
	kfree(zq);
}
EXPORT_SYMBOL(zcrypt_queue_free);

static void zcrypt_queue_release(struct kref *kref)
{
	struct zcrypt_queue *zq =
		container_of(kref, struct zcrypt_queue, refcount);
	zcrypt_queue_free(zq);
}

void zcrypt_queue_get(struct zcrypt_queue *zq)
{
	kref_get(&zq->refcount);
}
EXPORT_SYMBOL(zcrypt_queue_get);

int zcrypt_queue_put(struct zcrypt_queue *zq)
{
	return kref_put(&zq->refcount, zcrypt_queue_release);
}
EXPORT_SYMBOL(zcrypt_queue_put);

/**
 * zcrypt_queue_register() - Register a crypto queue device.
 * @zq: Pointer to a crypto queue device
 *
 * Register a crypto queue device. Returns 0 if successful.
 */
int zcrypt_queue_register(struct zcrypt_queue *zq)
{
	struct zcrypt_card *zc;
	int rc;

	spin_lock(&zcrypt_list_lock);
	zc = zq->queue->card->private;
	zcrypt_card_get(zc);
	zq->zcard = zc;
	zq->online = 1;	/* New devices are online by default. */

	ZCRYPT_DBF(DBF_INFO, "queue=%02x.%04x register online=1\n",
		   AP_QID_CARD(zq->queue->qid), AP_QID_QUEUE(zq->queue->qid));

	list_add_tail(&zq->list, &zc->zqueues);
	zcrypt_device_count++;
	spin_unlock(&zcrypt_list_lock);

	rc = sysfs_create_group(&zq->queue->ap_dev.device.kobj,
				&zcrypt_queue_attr_group);
	if (rc)
		goto out;
	get_device(&zq->queue->ap_dev.device);

	if (zq->ops->rng) {
		rc = zcrypt_rng_device_add();
		if (rc)
			goto out_unregister;
	}
	return 0;

out_unregister:
	sysfs_remove_group(&zq->queue->ap_dev.device.kobj,
			   &zcrypt_queue_attr_group);
	put_device(&zq->queue->ap_dev.device);
out:
	spin_lock(&zcrypt_list_lock);
	list_del_init(&zq->list);
	spin_unlock(&zcrypt_list_lock);
	zcrypt_card_put(zc);
	return rc;
}
EXPORT_SYMBOL(zcrypt_queue_register);

/**
 * zcrypt_queue_unregister(): Unregister a crypto queue device.
 * @zq: Pointer to crypto queue device
 *
 * Unregister a crypto queue device.
 */
void zcrypt_queue_unregister(struct zcrypt_queue *zq)
{
	struct zcrypt_card *zc;

	ZCRYPT_DBF(DBF_INFO, "queue=%02x.%04x unregister\n",
		   AP_QID_CARD(zq->queue->qid), AP_QID_QUEUE(zq->queue->qid));

	zc = zq->zcard;
	spin_lock(&zcrypt_list_lock);
	list_del_init(&zq->list);
	zcrypt_device_count--;
	spin_unlock(&zcrypt_list_lock);
	zcrypt_card_put(zc);
	if (zq->ops->rng)
		zcrypt_rng_device_remove();
	sysfs_remove_group(&zq->queue->ap_dev.device.kobj,
			   &zcrypt_queue_attr_group);
	put_device(&zq->queue->ap_dev.device);
	zcrypt_queue_put(zq);
}
EXPORT_SYMBOL(zcrypt_queue_unregister);
