18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  Copyright IBM Corp. 2001, 2019
48c2ecf20Sopenharmony_ci *  Author(s): Robert Burroughs
58c2ecf20Sopenharmony_ci *	       Eric Rossman (edrossma@us.ibm.com)
68c2ecf20Sopenharmony_ci *	       Cornelia Huck <cornelia.huck@de.ibm.com>
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
98c2ecf20Sopenharmony_ci *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
108c2ecf20Sopenharmony_ci *				  Ralph Wuerthner <rwuerthn@de.ibm.com>
118c2ecf20Sopenharmony_ci *  MSGTYPE restruct:		  Holger Dengler <hd@linux.vnet.ibm.com>
128c2ecf20Sopenharmony_ci */
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#ifndef _ZCRYPT_API_H_
158c2ecf20Sopenharmony_ci#define _ZCRYPT_API_H_
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#include <linux/atomic.h>
188c2ecf20Sopenharmony_ci#include <asm/debug.h>
198c2ecf20Sopenharmony_ci#include <asm/zcrypt.h>
208c2ecf20Sopenharmony_ci#include "ap_bus.h"
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci/**
238c2ecf20Sopenharmony_ci * Supported device types
248c2ecf20Sopenharmony_ci */
258c2ecf20Sopenharmony_ci#define ZCRYPT_CEX2C		5
268c2ecf20Sopenharmony_ci#define ZCRYPT_CEX2A		6
278c2ecf20Sopenharmony_ci#define ZCRYPT_CEX3C		7
288c2ecf20Sopenharmony_ci#define ZCRYPT_CEX3A		8
298c2ecf20Sopenharmony_ci#define ZCRYPT_CEX4	       10
308c2ecf20Sopenharmony_ci#define ZCRYPT_CEX5	       11
318c2ecf20Sopenharmony_ci#define ZCRYPT_CEX6	       12
328c2ecf20Sopenharmony_ci#define ZCRYPT_CEX7	       13
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci/**
358c2ecf20Sopenharmony_ci * Large random numbers are pulled in 4096 byte chunks from the crypto cards
368c2ecf20Sopenharmony_ci * and stored in a page. Be careful when increasing this buffer due to size
378c2ecf20Sopenharmony_ci * limitations for AP requests.
388c2ecf20Sopenharmony_ci */
398c2ecf20Sopenharmony_ci#define ZCRYPT_RNG_BUFFER_SIZE	4096
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci/*
428c2ecf20Sopenharmony_ci * Identifier for Crypto Request Performance Index
438c2ecf20Sopenharmony_ci */
448c2ecf20Sopenharmony_cienum crypto_ops {
458c2ecf20Sopenharmony_ci	MEX_1K,
468c2ecf20Sopenharmony_ci	MEX_2K,
478c2ecf20Sopenharmony_ci	MEX_4K,
488c2ecf20Sopenharmony_ci	CRT_1K,
498c2ecf20Sopenharmony_ci	CRT_2K,
508c2ecf20Sopenharmony_ci	CRT_4K,
518c2ecf20Sopenharmony_ci	HWRNG,
528c2ecf20Sopenharmony_ci	SECKEY,
538c2ecf20Sopenharmony_ci	NUM_OPS
548c2ecf20Sopenharmony_ci};
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistruct zcrypt_queue;
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci/* struct to hold tracking information for a userspace request/response */
598c2ecf20Sopenharmony_cistruct zcrypt_track {
608c2ecf20Sopenharmony_ci	int again_counter;		/* retry attempts counter */
618c2ecf20Sopenharmony_ci	int last_qid;			/* last qid used */
628c2ecf20Sopenharmony_ci	int last_rc;			/* last return code */
638c2ecf20Sopenharmony_ci#ifdef CONFIG_ZCRYPT_DEBUG
648c2ecf20Sopenharmony_ci	struct ap_fi fi;		/* failure injection cmd */
658c2ecf20Sopenharmony_ci#endif
668c2ecf20Sopenharmony_ci};
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci/* defines related to message tracking */
698c2ecf20Sopenharmony_ci#define TRACK_AGAIN_MAX 10
708c2ecf20Sopenharmony_ci#define TRACK_AGAIN_CARD_WEIGHT_PENALTY  1000
718c2ecf20Sopenharmony_ci#define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY 10000
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_cistruct zcrypt_ops {
748c2ecf20Sopenharmony_ci	long (*rsa_modexpo)(struct zcrypt_queue *, struct ica_rsa_modexpo *,
758c2ecf20Sopenharmony_ci			    struct ap_message *);
768c2ecf20Sopenharmony_ci	long (*rsa_modexpo_crt)(struct zcrypt_queue *,
778c2ecf20Sopenharmony_ci				struct ica_rsa_modexpo_crt *,
788c2ecf20Sopenharmony_ci				struct ap_message *);
798c2ecf20Sopenharmony_ci	long (*send_cprb)(bool userspace, struct zcrypt_queue *, struct ica_xcRB *,
808c2ecf20Sopenharmony_ci			  struct ap_message *);
818c2ecf20Sopenharmony_ci	long (*send_ep11_cprb)(bool userspace, struct zcrypt_queue *, struct ep11_urb *,
828c2ecf20Sopenharmony_ci			       struct ap_message *);
838c2ecf20Sopenharmony_ci	long (*rng)(struct zcrypt_queue *, char *, struct ap_message *);
848c2ecf20Sopenharmony_ci	struct list_head list;		/* zcrypt ops list. */
858c2ecf20Sopenharmony_ci	struct module *owner;
868c2ecf20Sopenharmony_ci	int variant;
878c2ecf20Sopenharmony_ci	char name[128];
888c2ecf20Sopenharmony_ci};
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_cistruct zcrypt_card {
918c2ecf20Sopenharmony_ci	struct list_head list;		/* Device list. */
928c2ecf20Sopenharmony_ci	struct list_head zqueues;	/* List of zcrypt queues */
938c2ecf20Sopenharmony_ci	struct kref refcount;		/* device refcounting */
948c2ecf20Sopenharmony_ci	struct ap_card *card;		/* The "real" ap card device. */
958c2ecf20Sopenharmony_ci	int online;			/* User online/offline */
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	int user_space_type;		/* User space device id. */
988c2ecf20Sopenharmony_ci	char *type_string;		/* User space device name. */
998c2ecf20Sopenharmony_ci	int min_mod_size;		/* Min number of bits. */
1008c2ecf20Sopenharmony_ci	int max_mod_size;		/* Max number of bits. */
1018c2ecf20Sopenharmony_ci	int max_exp_bit_length;
1028c2ecf20Sopenharmony_ci	const int *speed_rating;	/* Speed idx of crypto ops. */
1038c2ecf20Sopenharmony_ci	atomic_t load;			/* Utilization of the crypto device */
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	int request_count;		/* # current requests. */
1068c2ecf20Sopenharmony_ci};
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_cistruct zcrypt_queue {
1098c2ecf20Sopenharmony_ci	struct list_head list;		/* Device list. */
1108c2ecf20Sopenharmony_ci	struct kref refcount;		/* device refcounting */
1118c2ecf20Sopenharmony_ci	struct zcrypt_card *zcard;
1128c2ecf20Sopenharmony_ci	struct zcrypt_ops *ops;		/* Crypto operations. */
1138c2ecf20Sopenharmony_ci	struct ap_queue *queue;		/* The "real" ap queue device. */
1148c2ecf20Sopenharmony_ci	int online;			/* User online/offline */
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	atomic_t load;			/* Utilization of the crypto device */
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci	int request_count;		/* # current requests. */
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	struct ap_message reply;	/* Per-device reply structure. */
1218c2ecf20Sopenharmony_ci};
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci/* transport layer rescanning */
1248c2ecf20Sopenharmony_ciextern atomic_t zcrypt_rescan_req;
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ciextern spinlock_t zcrypt_list_lock;
1278c2ecf20Sopenharmony_ciextern int zcrypt_device_count;
1288c2ecf20Sopenharmony_ciextern struct list_head zcrypt_card_list;
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci#define for_each_zcrypt_card(_zc) \
1318c2ecf20Sopenharmony_ci	list_for_each_entry(_zc, &zcrypt_card_list, list)
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci#define for_each_zcrypt_queue(_zq, _zc) \
1348c2ecf20Sopenharmony_ci	list_for_each_entry(_zq, &(_zc)->zqueues, list)
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_cistruct zcrypt_card *zcrypt_card_alloc(void);
1378c2ecf20Sopenharmony_civoid zcrypt_card_free(struct zcrypt_card *);
1388c2ecf20Sopenharmony_civoid zcrypt_card_get(struct zcrypt_card *);
1398c2ecf20Sopenharmony_ciint zcrypt_card_put(struct zcrypt_card *);
1408c2ecf20Sopenharmony_ciint zcrypt_card_register(struct zcrypt_card *);
1418c2ecf20Sopenharmony_civoid zcrypt_card_unregister(struct zcrypt_card *);
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_cistruct zcrypt_queue *zcrypt_queue_alloc(size_t);
1448c2ecf20Sopenharmony_civoid zcrypt_queue_free(struct zcrypt_queue *);
1458c2ecf20Sopenharmony_civoid zcrypt_queue_get(struct zcrypt_queue *);
1468c2ecf20Sopenharmony_ciint zcrypt_queue_put(struct zcrypt_queue *);
1478c2ecf20Sopenharmony_ciint zcrypt_queue_register(struct zcrypt_queue *);
1488c2ecf20Sopenharmony_civoid zcrypt_queue_unregister(struct zcrypt_queue *);
1498c2ecf20Sopenharmony_civoid zcrypt_queue_force_online(struct zcrypt_queue *, int);
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ciint zcrypt_rng_device_add(void);
1528c2ecf20Sopenharmony_civoid zcrypt_rng_device_remove(void);
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_civoid zcrypt_msgtype_register(struct zcrypt_ops *);
1558c2ecf20Sopenharmony_civoid zcrypt_msgtype_unregister(struct zcrypt_ops *);
1568c2ecf20Sopenharmony_cistruct zcrypt_ops *zcrypt_msgtype(unsigned char *, int);
1578c2ecf20Sopenharmony_ciint zcrypt_api_init(void);
1588c2ecf20Sopenharmony_civoid zcrypt_api_exit(void);
1598c2ecf20Sopenharmony_cilong zcrypt_send_cprb(struct ica_xcRB *xcRB);
1608c2ecf20Sopenharmony_cilong zcrypt_send_ep11_cprb(struct ep11_urb *urb);
1618c2ecf20Sopenharmony_civoid zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus);
1628c2ecf20Sopenharmony_ciint zcrypt_device_status_ext(int card, int queue,
1638c2ecf20Sopenharmony_ci			     struct zcrypt_device_status_ext *devstatus);
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_cistatic inline unsigned long z_copy_from_user(bool userspace,
1668c2ecf20Sopenharmony_ci					     void *to,
1678c2ecf20Sopenharmony_ci					     const void __user *from,
1688c2ecf20Sopenharmony_ci					     unsigned long n)
1698c2ecf20Sopenharmony_ci{
1708c2ecf20Sopenharmony_ci	if (likely(userspace))
1718c2ecf20Sopenharmony_ci		return copy_from_user(to, from, n);
1728c2ecf20Sopenharmony_ci	memcpy(to, (void __force *) from, n);
1738c2ecf20Sopenharmony_ci	return 0;
1748c2ecf20Sopenharmony_ci}
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_cistatic inline unsigned long z_copy_to_user(bool userspace,
1778c2ecf20Sopenharmony_ci					   void __user *to,
1788c2ecf20Sopenharmony_ci					   const void *from,
1798c2ecf20Sopenharmony_ci					   unsigned long n)
1808c2ecf20Sopenharmony_ci{
1818c2ecf20Sopenharmony_ci	if (likely(userspace))
1828c2ecf20Sopenharmony_ci		return copy_to_user(to, from, n);
1838c2ecf20Sopenharmony_ci	memcpy((void __force *) to, from, n);
1848c2ecf20Sopenharmony_ci	return 0;
1858c2ecf20Sopenharmony_ci}
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci#endif /* _ZCRYPT_API_H_ */
188