linux/drivers/crypto/intel/keembay/ocs-hcu.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Intel Keem Bay OCS HCU Crypto Driver.
 *
 * Copyright (C) 2018-2020 Intel Corporation
 */

#include <linux/delay.h>
#include <linux/device.h>
#include <linux/iopoll.h>
#include <linux/irq.h>
#include <linux/module.h>

#include <crypto/sha2.h>

#include "ocs-hcu.h"

/* Registers. */
#define OCS_HCU_MODE
#define OCS_HCU_CHAIN
#define OCS_HCU_OPERATION
#define OCS_HCU_KEY_0
#define OCS_HCU_ISR
#define OCS_HCU_IER
#define OCS_HCU_STATUS
#define OCS_HCU_MSG_LEN_LO
#define OCS_HCU_MSG_LEN_HI
#define OCS_HCU_KEY_BYTE_ORDER_CFG
#define OCS_HCU_DMA_SRC_ADDR
#define OCS_HCU_DMA_SRC_SIZE
#define OCS_HCU_DMA_DST_SIZE
#define OCS_HCU_DMA_DMA_MODE
#define OCS_HCU_DMA_NEXT_SRC_DESCR
#define OCS_HCU_DMA_MSI_ISR
#define OCS_HCU_DMA_MSI_IER
#define OCS_HCU_DMA_MSI_MASK

/* Register bit definitions. */
#define HCU_MODE_ALGO_SHIFT
#define HCU_MODE_HMAC_SHIFT

#define HCU_STATUS_BUSY

#define HCU_BYTE_ORDER_SWAP

#define HCU_IRQ_HASH_DONE
#define HCU_IRQ_HASH_ERR_MASK

#define HCU_DMA_IRQ_SRC_DONE
#define HCU_DMA_IRQ_SAI_ERR
#define HCU_DMA_IRQ_BAD_COMP_ERR
#define HCU_DMA_IRQ_INBUF_RD_ERR
#define HCU_DMA_IRQ_INBUF_WD_ERR
#define HCU_DMA_IRQ_OUTBUF_WR_ERR
#define HCU_DMA_IRQ_OUTBUF_RD_ERR
#define HCU_DMA_IRQ_CRD_ERR
#define HCU_DMA_IRQ_ERR_MASK

#define HCU_DMA_SNOOP_MASK
#define HCU_DMA_SRC_LL_EN
#define HCU_DMA_EN

#define OCS_HCU_ENDIANNESS_VALUE

#define HCU_DMA_MSI_UNMASK
#define HCU_DMA_MSI_DISABLE
#define HCU_IRQ_DISABLE

#define OCS_HCU_START
#define OCS_HCU_TERMINATE

#define OCS_LL_DMA_FLAG_TERMINATE

#define OCS_HCU_HW_KEY_LEN_U32

#define HCU_DATA_WRITE_ENDIANNESS_OFFSET

#define OCS_HCU_NUM_CHAINS_SHA256_224_SM3
#define OCS_HCU_NUM_CHAINS_SHA384_512

/*
 * While polling on a busy HCU, wait maximum 200us between one check and the
 * other.
 */
#define OCS_HCU_WAIT_BUSY_RETRY_DELAY_US
/* Wait on a busy HCU for maximum 1 second. */
#define OCS_HCU_WAIT_BUSY_TIMEOUT_US

/**
 * struct ocs_hcu_dma_entry - An entry in an OCS DMA linked list.
 * @src_addr:  Source address of the data.
 * @src_len:   Length of data to be fetched.
 * @nxt_desc:  Next descriptor to fetch.
 * @ll_flags:  Flags (Freeze @ terminate) for the DMA engine.
 */
struct ocs_hcu_dma_entry {};

/**
 * struct ocs_hcu_dma_list - OCS-specific DMA linked list.
 * @head:	The head of the list (points to the array backing the list).
 * @tail:	The current tail of the list; NULL if the list is empty.
 * @dma_addr:	The DMA address of @head (i.e., the DMA address of the backing
 *		array).
 * @max_nents:	Maximum number of entries in the list (i.e., number of elements
 *		in the backing array).
 *
 * The OCS DMA list is an array-backed list of OCS DMA descriptors. The array
 * backing the list is allocated with dma_alloc_coherent() and pointed by
 * @head.
 */
struct ocs_hcu_dma_list {};

static inline u32 ocs_hcu_num_chains(enum ocs_hcu_algo algo)
{}

static inline u32 ocs_hcu_digest_size(enum ocs_hcu_algo algo)
{}

/**
 * ocs_hcu_wait_busy() - Wait for HCU OCS hardware to became usable.
 * @hcu_dev:	OCS HCU device to wait for.
 *
 * Return: 0 if device free, -ETIMEOUT if device busy and internal timeout has
 *	   expired.
 */
static int ocs_hcu_wait_busy(struct ocs_hcu_dev *hcu_dev)
{}

static void ocs_hcu_done_irq_en(struct ocs_hcu_dev *hcu_dev)
{}

static void ocs_hcu_dma_irq_en(struct ocs_hcu_dev *hcu_dev)
{}

static void ocs_hcu_irq_dis(struct ocs_hcu_dev *hcu_dev)
{}

static int ocs_hcu_wait_and_disable_irq(struct ocs_hcu_dev *hcu_dev)
{}

/**
 * ocs_hcu_get_intermediate_data() - Get intermediate data.
 * @hcu_dev:	The target HCU device.
 * @data:	Where to store the intermediate.
 * @algo:	The algorithm being used.
 *
 * This function is used to save the current hashing process state in order to
 * continue it in the future.
 *
 * Note: once all data has been processed, the intermediate data actually
 * contains the hashing result. So this function is also used to retrieve the
 * final result of a hashing process.
 *
 * Return: 0 on success, negative error code otherwise.
 */
static int ocs_hcu_get_intermediate_data(struct ocs_hcu_dev *hcu_dev,
					 struct ocs_hcu_idata *data,
					 enum ocs_hcu_algo algo)
{}

/**
 * ocs_hcu_set_intermediate_data() - Set intermediate data.
 * @hcu_dev:	The target HCU device.
 * @data:	The intermediate data to be set.
 * @algo:	The algorithm being used.
 *
 * This function is used to continue a previous hashing process.
 */
static void ocs_hcu_set_intermediate_data(struct ocs_hcu_dev *hcu_dev,
					  const struct ocs_hcu_idata *data,
					  enum ocs_hcu_algo algo)
{}

static int ocs_hcu_get_digest(struct ocs_hcu_dev *hcu_dev,
			      enum ocs_hcu_algo algo, u8 *dgst, size_t dgst_len)
{}

/**
 * ocs_hcu_hw_cfg() - Configure the HCU hardware.
 * @hcu_dev:	The HCU device to configure.
 * @algo:	The algorithm to be used by the HCU device.
 * @use_hmac:	Whether or not HW HMAC should be used.
 *
 * Return: 0 on success, negative error code otherwise.
 */
static int ocs_hcu_hw_cfg(struct ocs_hcu_dev *hcu_dev, enum ocs_hcu_algo algo,
			  bool use_hmac)
{}

/**
 * ocs_hcu_clear_key() - Clear key stored in OCS HMAC KEY registers.
 * @hcu_dev:	The OCS HCU device whose key registers should be cleared.
 */
static void ocs_hcu_clear_key(struct ocs_hcu_dev *hcu_dev)
{}

/**
 * ocs_hcu_write_key() - Write key to OCS HMAC KEY registers.
 * @hcu_dev:	The OCS HCU device the key should be written to.
 * @key:	The key to be written.
 * @len:	The size of the key to write. It must be OCS_HCU_HW_KEY_LEN.
 *
 * Return:	0 on success, negative error code otherwise.
 */
static int ocs_hcu_write_key(struct ocs_hcu_dev *hcu_dev, const u8 *key, size_t len)
{}

/**
 * ocs_hcu_ll_dma_start() - Start OCS HCU hashing via DMA
 * @hcu_dev:	The OCS HCU device to use.
 * @dma_list:	The OCS DMA list mapping the data to hash.
 * @finalize:	Whether or not this is the last hashing operation and therefore
 *		the final hash should be compute even if data is not
 *		block-aligned.
 *
 * Return: 0 on success, negative error code otherwise.
 */
static int ocs_hcu_ll_dma_start(struct ocs_hcu_dev *hcu_dev,
				const struct ocs_hcu_dma_list *dma_list,
				bool finalize)
{}

struct ocs_hcu_dma_list *ocs_hcu_dma_list_alloc(struct ocs_hcu_dev *hcu_dev,
						int max_nents)
{}

void ocs_hcu_dma_list_free(struct ocs_hcu_dev *hcu_dev,
			   struct ocs_hcu_dma_list *dma_list)
{}

/* Add a new DMA entry at the end of the OCS DMA list. */
int ocs_hcu_dma_list_add_tail(struct ocs_hcu_dev *hcu_dev,
			      struct ocs_hcu_dma_list *dma_list,
			      dma_addr_t addr, u32 len)
{}

/**
 * ocs_hcu_hash_init() - Initialize hash operation context.
 * @ctx:	The context to initialize.
 * @algo:	The hashing algorithm to use.
 *
 * Return:	0 on success, negative error code otherwise.
 */
int ocs_hcu_hash_init(struct ocs_hcu_hash_ctx *ctx, enum ocs_hcu_algo algo)
{}

/**
 * ocs_hcu_hash_update() - Perform a hashing iteration.
 * @hcu_dev:	The OCS HCU device to use.
 * @ctx:	The OCS HCU hashing context.
 * @dma_list:	The OCS DMA list mapping the input data to process.
 *
 * Return: 0 on success; negative error code otherwise.
 */
int ocs_hcu_hash_update(struct ocs_hcu_dev *hcu_dev,
			struct ocs_hcu_hash_ctx *ctx,
			const struct ocs_hcu_dma_list *dma_list)
{}

/**
 * ocs_hcu_hash_finup() - Update and finalize hash computation.
 * @hcu_dev:	The OCS HCU device to use.
 * @ctx:	The OCS HCU hashing context.
 * @dma_list:	The OCS DMA list mapping the input data to process.
 * @dgst:	The buffer where to save the computed digest.
 * @dgst_len:	The length of @dgst.
 *
 * Return: 0 on success; negative error code otherwise.
 */
int ocs_hcu_hash_finup(struct ocs_hcu_dev *hcu_dev,
		       const struct ocs_hcu_hash_ctx *ctx,
		       const struct ocs_hcu_dma_list *dma_list,
		       u8 *dgst, size_t dgst_len)
{}

/**
 * ocs_hcu_hash_final() - Finalize hash computation.
 * @hcu_dev:		The OCS HCU device to use.
 * @ctx:		The OCS HCU hashing context.
 * @dgst:		The buffer where to save the computed digest.
 * @dgst_len:		The length of @dgst.
 *
 * Return: 0 on success; negative error code otherwise.
 */
int ocs_hcu_hash_final(struct ocs_hcu_dev *hcu_dev,
		       const struct ocs_hcu_hash_ctx *ctx, u8 *dgst,
		       size_t dgst_len)
{}

/**
 * ocs_hcu_digest() - Compute hash digest.
 * @hcu_dev:		The OCS HCU device to use.
 * @algo:		The hash algorithm to use.
 * @data:		The input data to process.
 * @data_len:		The length of @data.
 * @dgst:		The buffer where to save the computed digest.
 * @dgst_len:		The length of @dgst.
 *
 * Return: 0 on success; negative error code otherwise.
 */
int ocs_hcu_digest(struct ocs_hcu_dev *hcu_dev, enum ocs_hcu_algo algo,
		   void *data, size_t data_len, u8 *dgst, size_t dgst_len)
{}

/**
 * ocs_hcu_hmac() - Compute HMAC.
 * @hcu_dev:		The OCS HCU device to use.
 * @algo:		The hash algorithm to use with HMAC.
 * @key:		The key to use.
 * @dma_list:	The OCS DMA list mapping the input data to process.
 * @key_len:		The length of @key.
 * @dgst:		The buffer where to save the computed HMAC.
 * @dgst_len:		The length of @dgst.
 *
 * Return: 0 on success; negative error code otherwise.
 */
int ocs_hcu_hmac(struct ocs_hcu_dev *hcu_dev, enum ocs_hcu_algo algo,
		 const u8 *key, size_t key_len,
		 const struct ocs_hcu_dma_list *dma_list,
		 u8 *dgst, size_t dgst_len)
{}

irqreturn_t ocs_hcu_irq_handler(int irq, void *dev_id)
{}

MODULE_DESCRIPTION();
MODULE_LICENSE();