Skip to content

Commit

Permalink
crypto: marvell - Move tdma chain out of mv_cesa_tdma_req and remove it
Browse files Browse the repository at this point in the history
Currently, the only way to access the tdma chain is to use the 'req'
union from a mv_cesa_{ablkcipher,ahash}. This will soon become a problem
if we want to handle the TDMA chaining vs standard/non-DMA processing in
a generic way (with generic functions at the cesa.c level detecting
whether the request should be queued at the DMA level or not). Hence the
decision to move the chain field a the mv_cesa_req level at the expense
of adding 2 void * fields to all request contexts (including non-DMA
ones) and to remove the type completly. To limit the overhead, we get
rid of the type field, which can now be deduced from the req->chain.first
value. Once these changes are done the union is no longer needed, so
remove it and move mv_cesa_ablkcipher_std_req and mv_cesa_req
to mv_cesa_ablkcipher_req directly. There are also no needs to keep the
'base' field into the union of mv_cesa_ahash_req, so move it into the
upper structure.

Signed-off-by: Romain Perier <romain.perier@free-electrons.com>
Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
  • Loading branch information
Romain Perier authored and Herbert Xu committed Jun 23, 2016
1 parent bac8e80 commit 53da740
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 98 deletions.
3 changes: 2 additions & 1 deletion drivers/crypto/marvell/cesa.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ static irqreturn_t mv_cesa_int(int irq, void *priv)
return ret;
}

int mv_cesa_queue_req(struct crypto_async_request *req)
int mv_cesa_queue_req(struct crypto_async_request *req,
struct mv_cesa_req *creq)
{
int ret;
int i;
Expand Down
44 changes: 16 additions & 28 deletions drivers/crypto/marvell/cesa.h
Original file line number Diff line number Diff line change
Expand Up @@ -509,21 +509,11 @@ enum mv_cesa_req_type {

/**
* struct mv_cesa_req - CESA request
* @type: request type
* @engine: engine associated with this request
* @chain: list of tdma descriptors associated with this request
*/
struct mv_cesa_req {
enum mv_cesa_req_type type;
struct mv_cesa_engine *engine;
};

/**
* struct mv_cesa_tdma_req - CESA TDMA request
* @base: base information
* @chain: TDMA chain
*/
struct mv_cesa_tdma_req {
struct mv_cesa_req base;
struct mv_cesa_tdma_chain chain;
};

Expand All @@ -540,13 +530,11 @@ struct mv_cesa_sg_std_iter {

/**
* struct mv_cesa_ablkcipher_std_req - cipher standard request
* @base: base information
* @op: operation context
* @offset: current operation offset
* @size: size of the crypto operation
*/
struct mv_cesa_ablkcipher_std_req {
struct mv_cesa_req base;
struct mv_cesa_op_ctx op;
unsigned int offset;
unsigned int size;
Expand All @@ -560,34 +548,27 @@ struct mv_cesa_ablkcipher_std_req {
* @dst_nents: number of entries in the dest sg list
*/
struct mv_cesa_ablkcipher_req {
union {
struct mv_cesa_req base;
struct mv_cesa_tdma_req dma;
struct mv_cesa_ablkcipher_std_req std;
} req;
struct mv_cesa_req base;
struct mv_cesa_ablkcipher_std_req std;
int src_nents;
int dst_nents;
};

/**
* struct mv_cesa_ahash_std_req - standard hash request
* @base: base information
* @offset: current operation offset
*/
struct mv_cesa_ahash_std_req {
struct mv_cesa_req base;
unsigned int offset;
};

/**
* struct mv_cesa_ahash_dma_req - DMA hash request
* @base: base information
* @padding: padding buffer
* @padding_dma: DMA address of the padding buffer
* @cache_dma: DMA address of the cache buffer
*/
struct mv_cesa_ahash_dma_req {
struct mv_cesa_tdma_req base;
u8 *padding;
dma_addr_t padding_dma;
u8 *cache;
Expand All @@ -606,8 +587,8 @@ struct mv_cesa_ahash_dma_req {
* @state: hash state
*/
struct mv_cesa_ahash_req {
struct mv_cesa_req base;
union {
struct mv_cesa_req base;
struct mv_cesa_ahash_dma_req dma;
struct mv_cesa_ahash_std_req std;
} req;
Expand All @@ -625,6 +606,12 @@ struct mv_cesa_ahash_req {

extern struct mv_cesa_dev *cesa_dev;

static inline enum mv_cesa_req_type
mv_cesa_req_get_type(struct mv_cesa_req *req)
{
return req->chain.first ? CESA_DMA_REQ : CESA_STD_REQ;
}

static inline void mv_cesa_update_op_cfg(struct mv_cesa_op_ctx *op,
u32 cfg, u32 mask)
{
Expand Down Expand Up @@ -697,7 +684,8 @@ static inline bool mv_cesa_mac_op_is_first_frag(const struct mv_cesa_op_ctx *op)
CESA_SA_DESC_CFG_FIRST_FRAG;
}

int mv_cesa_queue_req(struct crypto_async_request *req);
int mv_cesa_queue_req(struct crypto_async_request *req,
struct mv_cesa_req *creq);

/*
* Helper function that indicates whether a crypto request needs to be
Expand Down Expand Up @@ -767,9 +755,9 @@ static inline bool mv_cesa_req_dma_iter_next_op(struct mv_cesa_dma_iter *iter)
return iter->op_len;
}

void mv_cesa_dma_step(struct mv_cesa_tdma_req *dreq);
void mv_cesa_dma_step(struct mv_cesa_req *dreq);

static inline int mv_cesa_dma_process(struct mv_cesa_tdma_req *dreq,
static inline int mv_cesa_dma_process(struct mv_cesa_req *dreq,
u32 status)
{
if (!(status & CESA_SA_INT_ACC0_IDMA_DONE))
Expand All @@ -781,10 +769,10 @@ static inline int mv_cesa_dma_process(struct mv_cesa_tdma_req *dreq,
return 0;
}

void mv_cesa_dma_prepare(struct mv_cesa_tdma_req *dreq,
void mv_cesa_dma_prepare(struct mv_cesa_req *dreq,
struct mv_cesa_engine *engine);
void mv_cesa_dma_cleanup(struct mv_cesa_req *dreq);

void mv_cesa_dma_cleanup(struct mv_cesa_tdma_req *dreq);

static inline void
mv_cesa_tdma_desc_iter_init(struct mv_cesa_tdma_chain *chain)
Expand Down
63 changes: 33 additions & 30 deletions drivers/crypto/marvell/cipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,22 @@ mv_cesa_ablkcipher_dma_cleanup(struct ablkcipher_request *req)
dma_unmap_sg(cesa_dev->dev, req->src, creq->src_nents,
DMA_BIDIRECTIONAL);
}
mv_cesa_dma_cleanup(&creq->req.dma);
mv_cesa_dma_cleanup(&creq->base);
}

static inline void mv_cesa_ablkcipher_cleanup(struct ablkcipher_request *req)
{
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(req);

if (creq->req.base.type == CESA_DMA_REQ)
if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ)
mv_cesa_ablkcipher_dma_cleanup(req);
}

static void mv_cesa_ablkcipher_std_step(struct ablkcipher_request *req)
{
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(req);
struct mv_cesa_ablkcipher_std_req *sreq = &creq->req.std;
struct mv_cesa_engine *engine = sreq->base.engine;
struct mv_cesa_ablkcipher_std_req *sreq = &creq->std;
struct mv_cesa_engine *engine = creq->base.engine;
size_t len = min_t(size_t, req->nbytes - sreq->offset,
CESA_SA_SRAM_PAYLOAD_SIZE);

Expand Down Expand Up @@ -115,8 +115,8 @@ static int mv_cesa_ablkcipher_std_process(struct ablkcipher_request *req,
u32 status)
{
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(req);
struct mv_cesa_ablkcipher_std_req *sreq = &creq->req.std;
struct mv_cesa_engine *engine = sreq->base.engine;
struct mv_cesa_ablkcipher_std_req *sreq = &creq->std;
struct mv_cesa_engine *engine = creq->base.engine;
size_t len;
unsigned int ivsize;

Expand All @@ -140,20 +140,19 @@ static int mv_cesa_ablkcipher_process(struct crypto_async_request *req,
{
struct ablkcipher_request *ablkreq = ablkcipher_request_cast(req);
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(ablkreq);
struct mv_cesa_tdma_req *dreq;
struct mv_cesa_req *basereq = &creq->base;
unsigned int ivsize;
int ret;

if (creq->req.base.type == CESA_STD_REQ)
if (mv_cesa_req_get_type(basereq) == CESA_STD_REQ)
return mv_cesa_ablkcipher_std_process(ablkreq, status);

ret = mv_cesa_dma_process(&creq->req.dma, status);
ret = mv_cesa_dma_process(basereq, status);
if (ret)
return ret;

dreq = &creq->req.dma;
ivsize = crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(ablkreq));
memcpy_fromio(ablkreq->info, dreq->chain.last->data, ivsize);
memcpy_fromio(ablkreq->info, basereq->chain.last->data, ivsize);

return 0;
}
Expand All @@ -163,8 +162,8 @@ static void mv_cesa_ablkcipher_step(struct crypto_async_request *req)
struct ablkcipher_request *ablkreq = ablkcipher_request_cast(req);
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(ablkreq);

if (creq->req.base.type == CESA_DMA_REQ)
mv_cesa_dma_step(&creq->req.dma);
if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ)
mv_cesa_dma_step(&creq->base);
else
mv_cesa_ablkcipher_std_step(ablkreq);
}
Expand All @@ -173,17 +172,17 @@ static inline void
mv_cesa_ablkcipher_dma_prepare(struct ablkcipher_request *req)
{
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(req);
struct mv_cesa_tdma_req *dreq = &creq->req.dma;
struct mv_cesa_req *basereq = &creq->base;

mv_cesa_dma_prepare(dreq, dreq->base.engine);
mv_cesa_dma_prepare(basereq, basereq->engine);
}

static inline void
mv_cesa_ablkcipher_std_prepare(struct ablkcipher_request *req)
{
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(req);
struct mv_cesa_ablkcipher_std_req *sreq = &creq->req.std;
struct mv_cesa_engine *engine = sreq->base.engine;
struct mv_cesa_ablkcipher_std_req *sreq = &creq->std;
struct mv_cesa_engine *engine = creq->base.engine;

sreq->size = 0;
sreq->offset = 0;
Expand All @@ -196,9 +195,9 @@ static inline void mv_cesa_ablkcipher_prepare(struct crypto_async_request *req,
{
struct ablkcipher_request *ablkreq = ablkcipher_request_cast(req);
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(ablkreq);
creq->req.base.engine = engine;
creq->base.engine = engine;

if (creq->req.base.type == CESA_DMA_REQ)
if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ)
mv_cesa_ablkcipher_dma_prepare(ablkreq);
else
mv_cesa_ablkcipher_std_prepare(ablkreq);
Expand Down Expand Up @@ -301,16 +300,15 @@ static int mv_cesa_ablkcipher_dma_req_init(struct ablkcipher_request *req,
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(req);
gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
GFP_KERNEL : GFP_ATOMIC;
struct mv_cesa_tdma_req *dreq = &creq->req.dma;
struct mv_cesa_req *basereq = &creq->base;
struct mv_cesa_ablkcipher_dma_iter iter;
struct mv_cesa_tdma_chain chain;
bool skip_ctx = false;
int ret;
unsigned int ivsize;

dreq->base.type = CESA_DMA_REQ;
dreq->chain.first = NULL;
dreq->chain.last = NULL;
basereq->chain.first = NULL;
basereq->chain.last = NULL;

if (req->src != req->dst) {
ret = dma_map_sg(cesa_dev->dev, req->src, creq->src_nents,
Expand Down Expand Up @@ -373,12 +371,12 @@ static int mv_cesa_ablkcipher_dma_req_init(struct ablkcipher_request *req,
if (ret)
goto err_free_tdma;

dreq->chain = chain;
basereq->chain = chain;

return 0;

err_free_tdma:
mv_cesa_dma_cleanup(dreq);
mv_cesa_dma_cleanup(basereq);
if (req->dst != req->src)
dma_unmap_sg(cesa_dev->dev, req->dst, creq->dst_nents,
DMA_FROM_DEVICE);
Expand All @@ -395,11 +393,13 @@ mv_cesa_ablkcipher_std_req_init(struct ablkcipher_request *req,
const struct mv_cesa_op_ctx *op_templ)
{
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(req);
struct mv_cesa_ablkcipher_std_req *sreq = &creq->req.std;
struct mv_cesa_ablkcipher_std_req *sreq = &creq->std;
struct mv_cesa_req *basereq = &creq->base;

sreq->base.type = CESA_STD_REQ;
sreq->op = *op_templ;
sreq->skip_ctx = false;
basereq->chain.first = NULL;
basereq->chain.last = NULL;

return 0;
}
Expand Down Expand Up @@ -441,6 +441,7 @@ static int mv_cesa_ablkcipher_req_init(struct ablkcipher_request *req,
static int mv_cesa_des_op(struct ablkcipher_request *req,
struct mv_cesa_op_ctx *tmpl)
{
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(req);
struct mv_cesa_des_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
int ret;

Expand All @@ -453,7 +454,7 @@ static int mv_cesa_des_op(struct ablkcipher_request *req,
if (ret)
return ret;

ret = mv_cesa_queue_req(&req->base);
ret = mv_cesa_queue_req(&req->base, &creq->base);
if (mv_cesa_req_needs_cleanup(&req->base, ret))
mv_cesa_ablkcipher_cleanup(req);

Expand Down Expand Up @@ -561,6 +562,7 @@ struct crypto_alg mv_cesa_cbc_des_alg = {
static int mv_cesa_des3_op(struct ablkcipher_request *req,
struct mv_cesa_op_ctx *tmpl)
{
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(req);
struct mv_cesa_des3_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
int ret;

Expand All @@ -573,7 +575,7 @@ static int mv_cesa_des3_op(struct ablkcipher_request *req,
if (ret)
return ret;

ret = mv_cesa_queue_req(&req->base);
ret = mv_cesa_queue_req(&req->base, &creq->base);
if (mv_cesa_req_needs_cleanup(&req->base, ret))
mv_cesa_ablkcipher_cleanup(req);

Expand Down Expand Up @@ -687,6 +689,7 @@ struct crypto_alg mv_cesa_cbc_des3_ede_alg = {
static int mv_cesa_aes_op(struct ablkcipher_request *req,
struct mv_cesa_op_ctx *tmpl)
{
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(req);
struct mv_cesa_aes_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
int ret, i;
u32 *key;
Expand Down Expand Up @@ -715,7 +718,7 @@ static int mv_cesa_aes_op(struct ablkcipher_request *req,
if (ret)
return ret;

ret = mv_cesa_queue_req(&req->base);
ret = mv_cesa_queue_req(&req->base, &creq->base);
if (mv_cesa_req_needs_cleanup(&req->base, ret))
mv_cesa_ablkcipher_cleanup(req);

Expand Down
Loading

0 comments on commit 53da740

Please sign in to comment.