Commit 4bede34c authored by Nagadheeraj, Rottela's avatar Nagadheeraj, Rottela Committed by Herbert Xu

crypto: cavium/nitrox - crypto request format changes

nitrox_skcipher_crypt() will do the necessary formatting/ordering of
input and output sglists based on the algorithm requirements.
It will also accommodate the mandatory output buffers required for
NITROX hardware like Output request headers (ORH) and Completion headers.
Signed-off-by: default avatarNagadheeraj Rottela <rottela.nagadheeraj@cavium.com>
Reviewed-by: default avatarSrikanth Jampala <Jampala.Srikanth@cavium.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 180def6c
...@@ -155,13 +155,109 @@ static int nitrox_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, ...@@ -155,13 +155,109 @@ static int nitrox_aes_setkey(struct crypto_skcipher *cipher, const u8 *key,
return nitrox_skcipher_setkey(cipher, aes_keylen, key, keylen); return nitrox_skcipher_setkey(cipher, aes_keylen, key, keylen);
} }
static int alloc_src_sglist(struct skcipher_request *skreq, int ivsize)
{
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
int nents = sg_nents(skreq->src) + 1;
struct se_crypto_request *creq = &nkreq->creq;
char *iv;
struct scatterlist *sg;
/* Allocate buffer to hold IV and input scatterlist array */
nkreq->src = alloc_req_buf(nents, ivsize, creq->gfp);
if (!nkreq->src)
return -ENOMEM;
/* copy iv */
iv = nkreq->src;
memcpy(iv, skreq->iv, ivsize);
sg = (struct scatterlist *)(iv + ivsize);
creq->src = sg;
sg_init_table(sg, nents);
/* Input format:
* +----+----------------+
* | IV | SRC sg entries |
* +----+----------------+
*/
/* IV */
sg = create_single_sg(sg, iv, ivsize);
/* SRC entries */
create_multi_sg(sg, skreq->src);
return 0;
}
static int alloc_dst_sglist(struct skcipher_request *skreq, int ivsize)
{
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
int nents = sg_nents(skreq->dst) + 3;
int extralen = ORH_HLEN + COMP_HLEN;
struct se_crypto_request *creq = &nkreq->creq;
struct scatterlist *sg;
char *iv = nkreq->src;
/* Allocate buffer to hold ORH, COMPLETION and output scatterlist
* array
*/
nkreq->dst = alloc_req_buf(nents, extralen, creq->gfp);
if (!nkreq->dst)
return -ENOMEM;
creq->orh = (u64 *)(nkreq->dst);
set_orh_value(creq->orh);
creq->comp = (u64 *)(nkreq->dst + ORH_HLEN);
set_comp_value(creq->comp);
sg = (struct scatterlist *)(nkreq->dst + ORH_HLEN + COMP_HLEN);
creq->dst = sg;
sg_init_table(sg, nents);
/* Output format:
* +-----+----+----------------+-----------------+
* | ORH | IV | DST sg entries | COMPLETION Bytes|
* +-----+----+----------------+-----------------+
*/
/* ORH */
sg = create_single_sg(sg, creq->orh, ORH_HLEN);
/* IV */
sg = create_single_sg(sg, iv, ivsize);
/* DST entries */
sg = create_multi_sg(sg, skreq->dst);
/* COMPLETION Bytes */
create_single_sg(sg, creq->comp, COMP_HLEN);
return 0;
}
static void free_src_sglist(struct skcipher_request *skreq)
{
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
kfree(nkreq->src);
}
static void free_dst_sglist(struct skcipher_request *skreq)
{
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
kfree(nkreq->dst);
}
static void nitrox_skcipher_callback(struct skcipher_request *skreq, static void nitrox_skcipher_callback(struct skcipher_request *skreq,
int err) int err)
{ {
free_src_sglist(skreq);
free_dst_sglist(skreq);
if (err) { if (err) {
pr_err_ratelimited("request failed status 0x%0x\n", err); pr_err_ratelimited("request failed status 0x%0x\n", err);
err = -EINVAL; err = -EINVAL;
} }
skcipher_request_complete(skreq, err); skcipher_request_complete(skreq, err);
} }
...@@ -172,6 +268,7 @@ static int nitrox_skcipher_crypt(struct skcipher_request *skreq, bool enc) ...@@ -172,6 +268,7 @@ static int nitrox_skcipher_crypt(struct skcipher_request *skreq, bool enc)
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
int ivsize = crypto_skcipher_ivsize(cipher); int ivsize = crypto_skcipher_ivsize(cipher);
struct se_crypto_request *creq; struct se_crypto_request *creq;
int ret;
creq = &nkreq->creq; creq = &nkreq->creq;
creq->flags = skreq->base.flags; creq->flags = skreq->base.flags;
...@@ -192,11 +289,15 @@ static int nitrox_skcipher_crypt(struct skcipher_request *skreq, bool enc) ...@@ -192,11 +289,15 @@ static int nitrox_skcipher_crypt(struct skcipher_request *skreq, bool enc)
creq->ctx_handle = nctx->u.ctx_handle; creq->ctx_handle = nctx->u.ctx_handle;
creq->ctrl.s.ctxl = sizeof(struct flexi_crypto_context); creq->ctrl.s.ctxl = sizeof(struct flexi_crypto_context);
/* copy the iv */ ret = alloc_src_sglist(skreq, ivsize);
memcpy(creq->iv, skreq->iv, ivsize); if (ret)
creq->ivsize = ivsize; return ret;
creq->src = skreq->src;
creq->dst = skreq->dst; ret = alloc_dst_sglist(skreq, ivsize);
if (ret) {
free_src_sglist(skreq);
return ret;
}
nkreq->nctx = nctx; nkreq->nctx = nctx;
nkreq->skreq = skreq; nkreq->skreq = skreq;
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include "nitrox_dev.h" #include "nitrox_dev.h"
#define PENDING_SIG 0xFFFFFFFFFFFFFFFFUL
/** /**
* struct gphdr - General purpose Header * struct gphdr - General purpose Header
* @param0: first parameter. * @param0: first parameter.
...@@ -46,13 +48,6 @@ union se_req_ctrl { ...@@ -46,13 +48,6 @@ union se_req_ctrl {
} s; } s;
}; };
struct nitrox_sglist {
u16 len;
u16 raz0;
u32 raz1;
dma_addr_t dma;
};
#define MAX_IV_LEN 16 #define MAX_IV_LEN 16
/** /**
...@@ -62,8 +57,10 @@ struct nitrox_sglist { ...@@ -62,8 +57,10 @@ struct nitrox_sglist {
* @ctx_handle: Crypto context handle. * @ctx_handle: Crypto context handle.
* @gph: GP Header * @gph: GP Header
* @ctrl: Request Information. * @ctrl: Request Information.
* @in: Input sglist * @orh: ORH address
* @out: Output sglist * @comp: completion address
* @src: Input sglist
* @dst: Output sglist
*/ */
struct se_crypto_request { struct se_crypto_request {
u8 opcode; u8 opcode;
...@@ -73,9 +70,8 @@ struct se_crypto_request { ...@@ -73,9 +70,8 @@ struct se_crypto_request {
struct gphdr gph; struct gphdr gph;
union se_req_ctrl ctrl; union se_req_ctrl ctrl;
u64 *orh;
u8 iv[MAX_IV_LEN]; u64 *comp;
u16 ivsize;
struct scatterlist *src; struct scatterlist *src;
struct scatterlist *dst; struct scatterlist *dst;
...@@ -200,6 +196,8 @@ struct nitrox_kcrypt_request { ...@@ -200,6 +196,8 @@ struct nitrox_kcrypt_request {
struct se_crypto_request creq; struct se_crypto_request creq;
struct nitrox_crypto_ctx *nctx; struct nitrox_crypto_ctx *nctx;
struct skcipher_request *skreq; struct skcipher_request *skreq;
u8 *src;
u8 *dst;
}; };
/** /**
...@@ -376,26 +374,19 @@ struct nitrox_sgcomp { ...@@ -376,26 +374,19 @@ struct nitrox_sgcomp {
/* /*
* strutct nitrox_sgtable - SG list information * strutct nitrox_sgtable - SG list information
* @map_cnt: Number of buffers mapped * @sgmap_cnt: Number of buffers mapped
* @nr_comp: Number of sglist components
* @total_bytes: Total bytes in sglist. * @total_bytes: Total bytes in sglist.
* @len: Total sglist components length. * @sgcomp_len: Total sglist components length.
* @dma: DMA address of sglist component. * @sgcomp_dma: DMA address of sglist component.
* @dir: DMA direction. * @sg: crypto request buffer.
* @buf: crypto request buffer.
* @sglist: SG list of input/output buffers.
* @sgcomp: sglist component for NITROX. * @sgcomp: sglist component for NITROX.
*/ */
struct nitrox_sgtable { struct nitrox_sgtable {
u8 map_bufs_cnt; u8 sgmap_cnt;
u8 nr_sgcomp;
u16 total_bytes; u16 total_bytes;
u32 len; u32 sgcomp_len;
dma_addr_t dma; dma_addr_t sgcomp_dma;
enum dma_data_direction dir; struct scatterlist *sg;
struct scatterlist *buf;
struct nitrox_sglist *sglist;
struct nitrox_sgcomp *sgcomp; struct nitrox_sgcomp *sgcomp;
}; };
...@@ -405,10 +396,8 @@ struct nitrox_sgtable { ...@@ -405,10 +396,8 @@ struct nitrox_sgtable {
#define COMP_HLEN 8 #define COMP_HLEN 8
struct resp_hdr { struct resp_hdr {
u64 orh; u64 *orh;
dma_addr_t orh_dma; u64 *completion;
u64 completion;
dma_addr_t completion_dma;
}; };
typedef void (*completion_t)(struct skcipher_request *skreq, int err); typedef void (*completion_t)(struct skcipher_request *skreq, int err);
...@@ -434,7 +423,6 @@ struct nitrox_softreq { ...@@ -434,7 +423,6 @@ struct nitrox_softreq {
u32 flags; u32 flags;
gfp_t gfp; gfp_t gfp;
atomic_t status; atomic_t status;
bool inplace;
struct nitrox_device *ndev; struct nitrox_device *ndev;
struct nitrox_cmdq *cmdq; struct nitrox_cmdq *cmdq;
...@@ -450,4 +438,46 @@ struct nitrox_softreq { ...@@ -450,4 +438,46 @@ struct nitrox_softreq {
struct skcipher_request *skreq; struct skcipher_request *skreq;
}; };
static inline void *alloc_req_buf(int nents, int extralen, gfp_t gfp)
{
size_t size;
size = sizeof(struct scatterlist) * nents;
size += extralen;
return kzalloc(size, gfp);
}
static inline struct scatterlist *create_single_sg(struct scatterlist *sg,
void *buf, int buflen)
{
sg_set_buf(sg, buf, buflen);
sg++;
return sg;
}
static inline struct scatterlist *create_multi_sg(struct scatterlist *to_sg,
struct scatterlist *from_sg)
{
struct scatterlist *sg;
int i;
for_each_sg(from_sg, sg, sg_nents(from_sg), i) {
sg_set_buf(to_sg, sg_virt(sg), sg->length);
to_sg++;
}
return to_sg;
}
static inline void set_orh_value(u64 *orh)
{
WRITE_ONCE(*orh, PENDING_SIG);
}
static inline void set_comp_value(u64 *comp)
{
WRITE_ONCE(*comp, PENDING_SIG);
}
#endif /* __NITROX_REQ_H */ #endif /* __NITROX_REQ_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment