18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Crypto engine API
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2016 Baolin Wang <baolin.wang@linaro.org>
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci#ifndef _CRYPTO_ENGINE_H
88c2ecf20Sopenharmony_ci#define _CRYPTO_ENGINE_H
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/crypto.h>
118c2ecf20Sopenharmony_ci#include <linux/list.h>
128c2ecf20Sopenharmony_ci#include <linux/kernel.h>
138c2ecf20Sopenharmony_ci#include <linux/kthread.h>
148c2ecf20Sopenharmony_ci#include <crypto/algapi.h>
158c2ecf20Sopenharmony_ci#include <crypto/aead.h>
168c2ecf20Sopenharmony_ci#include <crypto/akcipher.h>
178c2ecf20Sopenharmony_ci#include <crypto/hash.h>
188c2ecf20Sopenharmony_ci#include <crypto/skcipher.h>
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#define ENGINE_NAME_LEN	30
218c2ecf20Sopenharmony_ci/*
228c2ecf20Sopenharmony_ci * struct crypto_engine - crypto hardware engine
238c2ecf20Sopenharmony_ci * @name: the engine name
248c2ecf20Sopenharmony_ci * @idling: the engine is entering idle state
258c2ecf20Sopenharmony_ci * @busy: request pump is busy
268c2ecf20Sopenharmony_ci * @running: the engine is on working
278c2ecf20Sopenharmony_ci * @retry_support: indication that the hardware allows re-execution
288c2ecf20Sopenharmony_ci * of a failed backlog request
298c2ecf20Sopenharmony_ci * crypto-engine, in head position to keep order
308c2ecf20Sopenharmony_ci * @list: link with the global crypto engine list
318c2ecf20Sopenharmony_ci * @queue_lock: spinlock to syncronise access to request queue
328c2ecf20Sopenharmony_ci * @queue: the crypto queue of the engine
338c2ecf20Sopenharmony_ci * @rt: whether this queue is set to run as a realtime task
348c2ecf20Sopenharmony_ci * @prepare_crypt_hardware: a request will soon arrive from the queue
358c2ecf20Sopenharmony_ci * so the subsystem requests the driver to prepare the hardware
368c2ecf20Sopenharmony_ci * by issuing this call
378c2ecf20Sopenharmony_ci * @unprepare_crypt_hardware: there are currently no more requests on the
388c2ecf20Sopenharmony_ci * queue so the subsystem notifies the driver that it may relax the
398c2ecf20Sopenharmony_ci * hardware by issuing this call
408c2ecf20Sopenharmony_ci * @do_batch_requests: execute a batch of requests. Depends on multiple
418c2ecf20Sopenharmony_ci * requests support.
428c2ecf20Sopenharmony_ci * @kworker: kthread worker struct for request pump
438c2ecf20Sopenharmony_ci * @pump_requests: work struct for scheduling work to the request pump
448c2ecf20Sopenharmony_ci * @priv_data: the engine private data
458c2ecf20Sopenharmony_ci * @cur_req: the current request which is on processing
468c2ecf20Sopenharmony_ci */
478c2ecf20Sopenharmony_cistruct crypto_engine {
488c2ecf20Sopenharmony_ci	char			name[ENGINE_NAME_LEN];
498c2ecf20Sopenharmony_ci	bool			idling;
508c2ecf20Sopenharmony_ci	bool			busy;
518c2ecf20Sopenharmony_ci	bool			running;
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	bool			retry_support;
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	struct list_head	list;
568c2ecf20Sopenharmony_ci	spinlock_t		queue_lock;
578c2ecf20Sopenharmony_ci	struct crypto_queue	queue;
588c2ecf20Sopenharmony_ci	struct device		*dev;
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	bool			rt;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	int (*prepare_crypt_hardware)(struct crypto_engine *engine);
638c2ecf20Sopenharmony_ci	int (*unprepare_crypt_hardware)(struct crypto_engine *engine);
648c2ecf20Sopenharmony_ci	int (*do_batch_requests)(struct crypto_engine *engine);
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	struct kthread_worker           *kworker;
688c2ecf20Sopenharmony_ci	struct kthread_work             pump_requests;
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	void				*priv_data;
718c2ecf20Sopenharmony_ci	struct crypto_async_request	*cur_req;
728c2ecf20Sopenharmony_ci};
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci/*
758c2ecf20Sopenharmony_ci * struct crypto_engine_op - crypto hardware engine operations
768c2ecf20Sopenharmony_ci * @prepare__request: do some prepare if need before handle the current request
778c2ecf20Sopenharmony_ci * @unprepare_request: undo any work done by prepare_request()
788c2ecf20Sopenharmony_ci * @do_one_request: do encryption for current request
798c2ecf20Sopenharmony_ci */
808c2ecf20Sopenharmony_cistruct crypto_engine_op {
818c2ecf20Sopenharmony_ci	int (*prepare_request)(struct crypto_engine *engine,
828c2ecf20Sopenharmony_ci			       void *areq);
838c2ecf20Sopenharmony_ci	int (*unprepare_request)(struct crypto_engine *engine,
848c2ecf20Sopenharmony_ci				 void *areq);
858c2ecf20Sopenharmony_ci	int (*do_one_request)(struct crypto_engine *engine,
868c2ecf20Sopenharmony_ci			      void *areq);
878c2ecf20Sopenharmony_ci};
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_cistruct crypto_engine_ctx {
908c2ecf20Sopenharmony_ci	struct crypto_engine_op op;
918c2ecf20Sopenharmony_ci};
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ciint crypto_transfer_aead_request_to_engine(struct crypto_engine *engine,
948c2ecf20Sopenharmony_ci					   struct aead_request *req);
958c2ecf20Sopenharmony_ciint crypto_transfer_akcipher_request_to_engine(struct crypto_engine *engine,
968c2ecf20Sopenharmony_ci					       struct akcipher_request *req);
978c2ecf20Sopenharmony_ciint crypto_transfer_hash_request_to_engine(struct crypto_engine *engine,
988c2ecf20Sopenharmony_ci					       struct ahash_request *req);
998c2ecf20Sopenharmony_ciint crypto_transfer_skcipher_request_to_engine(struct crypto_engine *engine,
1008c2ecf20Sopenharmony_ci					       struct skcipher_request *req);
1018c2ecf20Sopenharmony_civoid crypto_finalize_aead_request(struct crypto_engine *engine,
1028c2ecf20Sopenharmony_ci				  struct aead_request *req, int err);
1038c2ecf20Sopenharmony_civoid crypto_finalize_akcipher_request(struct crypto_engine *engine,
1048c2ecf20Sopenharmony_ci				      struct akcipher_request *req, int err);
1058c2ecf20Sopenharmony_civoid crypto_finalize_hash_request(struct crypto_engine *engine,
1068c2ecf20Sopenharmony_ci				  struct ahash_request *req, int err);
1078c2ecf20Sopenharmony_civoid crypto_finalize_skcipher_request(struct crypto_engine *engine,
1088c2ecf20Sopenharmony_ci				      struct skcipher_request *req, int err);
1098c2ecf20Sopenharmony_ciint crypto_engine_start(struct crypto_engine *engine);
1108c2ecf20Sopenharmony_ciint crypto_engine_stop(struct crypto_engine *engine);
1118c2ecf20Sopenharmony_cistruct crypto_engine *crypto_engine_alloc_init(struct device *dev, bool rt);
1128c2ecf20Sopenharmony_cistruct crypto_engine *crypto_engine_alloc_init_and_set(struct device *dev,
1138c2ecf20Sopenharmony_ci						       bool retry_support,
1148c2ecf20Sopenharmony_ci						       int (*cbk_do_batch)(struct crypto_engine *engine),
1158c2ecf20Sopenharmony_ci						       bool rt, int qlen);
1168c2ecf20Sopenharmony_ciint crypto_engine_exit(struct crypto_engine *engine);
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci#endif /* _CRYPTO_ENGINE_H */
119