#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/hw_random.h>
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/dmaengine.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
#include <linux/mod_devicetable.h>
#include <linux/delay.h>
#include <linux/crypto.h>
#include <crypto/scatterwalk.h>
#include <crypto/algapi.h>
#include <crypto/sha1.h>
#include <crypto/sha2.h>
#include <crypto/hash.h>
#include <crypto/internal/hash.h>
#include "atmel-sha-regs.h"
#include "atmel-authenc.h"
#define ATMEL_SHA_PRIORITY …
#define SHA_FLAGS_BUSY …
#define SHA_FLAGS_FINAL …
#define SHA_FLAGS_DMA_ACTIVE …
#define SHA_FLAGS_OUTPUT_READY …
#define SHA_FLAGS_INIT …
#define SHA_FLAGS_CPU …
#define SHA_FLAGS_DMA_READY …
#define SHA_FLAGS_DUMP_REG …
#define SHA_FLAGS_FINUP …
#define SHA_FLAGS_SG …
#define SHA_FLAGS_ERROR …
#define SHA_FLAGS_PAD …
#define SHA_FLAGS_RESTORE …
#define SHA_FLAGS_IDATAR0 …
#define SHA_FLAGS_WAIT_DATARDY …
#define SHA_OP_INIT …
#define SHA_OP_UPDATE …
#define SHA_OP_FINAL …
#define SHA_OP_DIGEST …
#define SHA_BUFFER_LEN …
#define ATMEL_SHA_DMA_THRESHOLD …
struct atmel_sha_caps { … };
struct atmel_sha_dev;
struct atmel_sha_reqctx { … };
atmel_sha_fn_t;
struct atmel_sha_ctx { … };
#define ATMEL_SHA_QUEUE_LENGTH …
struct atmel_sha_dma { … };
struct atmel_sha_dev { … };
struct atmel_sha_drv { … };
static struct atmel_sha_drv atmel_sha = …;
#ifdef VERBOSE_DEBUG
static const char *atmel_sha_reg_name(u32 offset, char *tmp, size_t sz, bool wr)
{
switch (offset) {
case SHA_CR:
return "CR";
case SHA_MR:
return "MR";
case SHA_IER:
return "IER";
case SHA_IDR:
return "IDR";
case SHA_IMR:
return "IMR";
case SHA_ISR:
return "ISR";
case SHA_MSR:
return "MSR";
case SHA_BCR:
return "BCR";
case SHA_REG_DIN(0):
case SHA_REG_DIN(1):
case SHA_REG_DIN(2):
case SHA_REG_DIN(3):
case SHA_REG_DIN(4):
case SHA_REG_DIN(5):
case SHA_REG_DIN(6):
case SHA_REG_DIN(7):
case SHA_REG_DIN(8):
case SHA_REG_DIN(9):
case SHA_REG_DIN(10):
case SHA_REG_DIN(11):
case SHA_REG_DIN(12):
case SHA_REG_DIN(13):
case SHA_REG_DIN(14):
case SHA_REG_DIN(15):
snprintf(tmp, sz, "IDATAR[%u]", (offset - SHA_REG_DIN(0)) >> 2);
break;
case SHA_REG_DIGEST(0):
case SHA_REG_DIGEST(1):
case SHA_REG_DIGEST(2):
case SHA_REG_DIGEST(3):
case SHA_REG_DIGEST(4):
case SHA_REG_DIGEST(5):
case SHA_REG_DIGEST(6):
case SHA_REG_DIGEST(7):
case SHA_REG_DIGEST(8):
case SHA_REG_DIGEST(9):
case SHA_REG_DIGEST(10):
case SHA_REG_DIGEST(11):
case SHA_REG_DIGEST(12):
case SHA_REG_DIGEST(13):
case SHA_REG_DIGEST(14):
case SHA_REG_DIGEST(15):
if (wr)
snprintf(tmp, sz, "IDATAR[%u]",
16u + ((offset - SHA_REG_DIGEST(0)) >> 2));
else
snprintf(tmp, sz, "ODATAR[%u]",
(offset - SHA_REG_DIGEST(0)) >> 2);
break;
case SHA_HW_VERSION:
return "HWVER";
default:
snprintf(tmp, sz, "0x%02x", offset);
break;
}
return tmp;
}
#endif
static inline u32 atmel_sha_read(struct atmel_sha_dev *dd, u32 offset)
{ … }
static inline void atmel_sha_write(struct atmel_sha_dev *dd,
u32 offset, u32 value)
{ … }
static inline int atmel_sha_complete(struct atmel_sha_dev *dd, int err)
{ … }
static size_t atmel_sha_append_sg(struct atmel_sha_reqctx *ctx)
{ … }
static void atmel_sha_fill_padding(struct atmel_sha_reqctx *ctx, int length)
{ … }
static struct atmel_sha_dev *atmel_sha_find_dev(struct atmel_sha_ctx *tctx)
{ … }
static int atmel_sha_init(struct ahash_request *req)
{ … }
static void atmel_sha_write_ctrl(struct atmel_sha_dev *dd, int dma)
{ … }
static inline int atmel_sha_wait_for_data_ready(struct atmel_sha_dev *dd,
atmel_sha_fn_t resume)
{ … }
static int atmel_sha_xmit_cpu(struct atmel_sha_dev *dd, const u8 *buf,
size_t length, int final)
{ … }
static int atmel_sha_xmit_pdc(struct atmel_sha_dev *dd, dma_addr_t dma_addr1,
size_t length1, dma_addr_t dma_addr2, size_t length2, int final)
{ … }
static void atmel_sha_dma_callback(void *data)
{ … }
static int atmel_sha_xmit_dma(struct atmel_sha_dev *dd, dma_addr_t dma_addr1,
size_t length1, dma_addr_t dma_addr2, size_t length2, int final)
{ … }
static int atmel_sha_xmit_start(struct atmel_sha_dev *dd, dma_addr_t dma_addr1,
size_t length1, dma_addr_t dma_addr2, size_t length2, int final)
{ … }
static int atmel_sha_update_cpu(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_xmit_dma_map(struct atmel_sha_dev *dd,
struct atmel_sha_reqctx *ctx,
size_t length, int final)
{ … }
static int atmel_sha_update_dma_slow(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_update_dma_start(struct atmel_sha_dev *dd)
{ … }
static void atmel_sha_update_dma_stop(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_update_req(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_final_req(struct atmel_sha_dev *dd)
{ … }
static void atmel_sha_copy_hash(struct ahash_request *req)
{ … }
static void atmel_sha_copy_ready_hash(struct ahash_request *req)
{ … }
static int atmel_sha_finish(struct ahash_request *req)
{ … }
static void atmel_sha_finish_req(struct ahash_request *req, int err)
{ … }
static int atmel_sha_hw_init(struct atmel_sha_dev *dd)
{ … }
static inline unsigned int atmel_sha_get_version(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_hw_version_init(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_handle_queue(struct atmel_sha_dev *dd,
struct ahash_request *req)
{ … }
static int atmel_sha_done(struct atmel_sha_dev *dd);
static int atmel_sha_start(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_enqueue(struct ahash_request *req, unsigned int op)
{ … }
static int atmel_sha_update(struct ahash_request *req)
{ … }
static int atmel_sha_final(struct ahash_request *req)
{ … }
static int atmel_sha_finup(struct ahash_request *req)
{ … }
static int atmel_sha_digest(struct ahash_request *req)
{ … }
static int atmel_sha_export(struct ahash_request *req, void *out)
{ … }
static int atmel_sha_import(struct ahash_request *req, const void *in)
{ … }
static int atmel_sha_cra_init(struct crypto_tfm *tfm)
{ … }
static void atmel_sha_alg_init(struct ahash_alg *alg)
{ … }
static struct ahash_alg sha_1_256_algs[] = …;
static struct ahash_alg sha_224_alg = …;
static struct ahash_alg sha_384_512_algs[] = …;
static void atmel_sha_queue_task(unsigned long data)
{ … }
static int atmel_sha_done(struct atmel_sha_dev *dd)
{ … }
static void atmel_sha_done_task(unsigned long data)
{ … }
static irqreturn_t atmel_sha_irq(int irq, void *dev_id)
{ … }
static bool atmel_sha_dma_check_aligned(struct atmel_sha_dev *dd,
struct scatterlist *sg,
size_t len)
{ … }
static void atmel_sha_dma_callback2(void *data)
{ … }
static int atmel_sha_dma_start(struct atmel_sha_dev *dd,
struct scatterlist *src,
size_t len,
atmel_sha_fn_t resume)
{ … }
static int atmel_sha_cpu_transfer(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_cpu_start(struct atmel_sha_dev *dd,
struct scatterlist *sg,
unsigned int len,
bool idatar0_only,
bool wait_data_ready,
atmel_sha_fn_t resume)
{ … }
static int atmel_sha_cpu_hash(struct atmel_sha_dev *dd,
const void *data, unsigned int datalen,
bool auto_padding,
atmel_sha_fn_t resume)
{ … }
struct atmel_sha_hmac_key { … };
static inline void atmel_sha_hmac_key_init(struct atmel_sha_hmac_key *hkey)
{ … }
static inline void atmel_sha_hmac_key_release(struct atmel_sha_hmac_key *hkey)
{ … }
static inline int atmel_sha_hmac_key_set(struct atmel_sha_hmac_key *hkey,
const u8 *key,
unsigned int keylen)
{ … }
static inline bool atmel_sha_hmac_key_get(const struct atmel_sha_hmac_key *hkey,
const u8 **key,
unsigned int *keylen)
{ … }
struct atmel_sha_hmac_ctx { … };
static int atmel_sha_hmac_setup(struct atmel_sha_dev *dd,
atmel_sha_fn_t resume);
static int atmel_sha_hmac_prehash_key(struct atmel_sha_dev *dd,
const u8 *key, unsigned int keylen);
static int atmel_sha_hmac_prehash_key_done(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_compute_ipad_hash(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_compute_opad_hash(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_setup_done(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_init_done(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_final(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_final_done(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_digest2(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_setup(struct atmel_sha_dev *dd,
atmel_sha_fn_t resume)
{ … }
static int atmel_sha_hmac_prehash_key(struct atmel_sha_dev *dd,
const u8 *key, unsigned int keylen)
{ … }
static int atmel_sha_hmac_prehash_key_done(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_hmac_compute_ipad_hash(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_hmac_compute_opad_hash(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_hmac_setup_done(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_hmac_start(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
unsigned int keylen)
{ … }
static int atmel_sha_hmac_init(struct ahash_request *req)
{ … }
static int atmel_sha_hmac_init_done(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_hmac_final(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_hmac_final_done(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_hmac_digest(struct ahash_request *req)
{ … }
static int atmel_sha_hmac_digest2(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_hmac_cra_init(struct crypto_tfm *tfm)
{ … }
static void atmel_sha_hmac_cra_exit(struct crypto_tfm *tfm)
{ … }
static void atmel_sha_hmac_alg_init(struct ahash_alg *alg)
{ … }
static struct ahash_alg sha_hmac_algs[] = …;
#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC)
static int atmel_sha_authenc_init2(struct atmel_sha_dev *dd);
static int atmel_sha_authenc_init_done(struct atmel_sha_dev *dd);
static int atmel_sha_authenc_final_done(struct atmel_sha_dev *dd);
struct atmel_sha_authenc_ctx { … };
struct atmel_sha_authenc_reqctx { … };
static void atmel_sha_authenc_complete(void *data, int err)
{ … }
static int atmel_sha_authenc_start(struct atmel_sha_dev *dd)
{ … }
bool atmel_sha_authenc_is_ready(void)
{ … }
EXPORT_SYMBOL_GPL(…);
unsigned int atmel_sha_authenc_get_reqsize(void)
{ … }
EXPORT_SYMBOL_GPL(…);
struct atmel_sha_authenc_ctx *atmel_sha_authenc_spawn(unsigned long mode)
{ … }
EXPORT_SYMBOL_GPL(…);
void atmel_sha_authenc_free(struct atmel_sha_authenc_ctx *auth)
{ … }
EXPORT_SYMBOL_GPL(…);
int atmel_sha_authenc_setkey(struct atmel_sha_authenc_ctx *auth,
const u8 *key, unsigned int keylen, u32 flags)
{ … }
EXPORT_SYMBOL_GPL(…);
int atmel_sha_authenc_schedule(struct ahash_request *req,
struct atmel_sha_authenc_ctx *auth,
atmel_aes_authenc_fn_t cb,
struct atmel_aes_dev *aes_dev)
{ … }
EXPORT_SYMBOL_GPL(…);
int atmel_sha_authenc_init(struct ahash_request *req,
struct scatterlist *assoc, unsigned int assoclen,
unsigned int textlen,
atmel_aes_authenc_fn_t cb,
struct atmel_aes_dev *aes_dev)
{ … }
EXPORT_SYMBOL_GPL(…);
static int atmel_sha_authenc_init2(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_authenc_init_done(struct atmel_sha_dev *dd)
{ … }
int atmel_sha_authenc_final(struct ahash_request *req,
u32 *digest, unsigned int digestlen,
atmel_aes_authenc_fn_t cb,
struct atmel_aes_dev *aes_dev)
{ … }
EXPORT_SYMBOL_GPL(…);
static int atmel_sha_authenc_final_done(struct atmel_sha_dev *dd)
{ … }
void atmel_sha_authenc_abort(struct ahash_request *req)
{ … }
EXPORT_SYMBOL_GPL(…);
#endif
static void atmel_sha_unregister_algs(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_register_algs(struct atmel_sha_dev *dd)
{ … }
static int atmel_sha_dma_init(struct atmel_sha_dev *dd)
{ … }
static void atmel_sha_dma_cleanup(struct atmel_sha_dev *dd)
{ … }
static void atmel_sha_get_cap(struct atmel_sha_dev *dd)
{ … }
static const struct of_device_id atmel_sha_dt_ids[] = …;
MODULE_DEVICE_TABLE(of, atmel_sha_dt_ids);
static int atmel_sha_probe(struct platform_device *pdev)
{ … }
static void atmel_sha_remove(struct platform_device *pdev)
{ … }
static struct platform_driver atmel_sha_driver = …;
module_platform_driver(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;
MODULE_AUTHOR(…) …;