mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-23 14:54:03 +00:00
crypto: caam/qi - add ablkcipher and authenc algorithms
Add support to submit ablkcipher and authenc algorithms via the QI backend: -ablkcipher: cbc({aes,des,des3_ede}) ctr(aes), rfc3686(ctr(aes)) xts(aes) -authenc: authenc(hmac(md5),cbc({aes,des,des3_ede})) authenc(hmac(sha*),cbc({aes,des,des3_ede})) caam/qi being a new driver, let's wait some time to settle down without interfering with existing caam/jr driver. Accordingly, for now all caam/qi algorithms (caamalg_qi module) are marked to be of lower priority than caam/jr ones (caamalg module). Signed-off-by: Vakul Garg <vakul.garg@nxp.com> Signed-off-by: Alex Porosanu <alexandru.porosanu@nxp.com> Signed-off-by: Horia Geantă <horia.geanta@nxp.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
67c2315def
commit
b189817cf7
7 changed files with 2601 additions and 16 deletions
|
@ -87,6 +87,23 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
|
||||||
To compile this as a module, choose M here: the module
|
To compile this as a module, choose M here: the module
|
||||||
will be called caamalg.
|
will be called caamalg.
|
||||||
|
|
||||||
|
config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI
|
||||||
|
tristate "Queue Interface as Crypto API backend"
|
||||||
|
depends on CRYPTO_DEV_FSL_CAAM_JR && FSL_DPAA && NET
|
||||||
|
default y
|
||||||
|
select CRYPTO_AUTHENC
|
||||||
|
select CRYPTO_BLKCIPHER
|
||||||
|
help
|
||||||
|
Selecting this will use CAAM Queue Interface (QI) for sending
|
||||||
|
& receiving crypto jobs to/from CAAM. This gives better performance
|
||||||
|
than job ring interface when the number of cores are more than the
|
||||||
|
number of job rings assigned to the kernel. The number of portals
|
||||||
|
assigned to the kernel should also be more than the number of
|
||||||
|
job rings.
|
||||||
|
|
||||||
|
To compile this as a module, choose M here: the module
|
||||||
|
will be called caamalg_qi.
|
||||||
|
|
||||||
config CRYPTO_DEV_FSL_CAAM_AHASH_API
|
config CRYPTO_DEV_FSL_CAAM_AHASH_API
|
||||||
tristate "Register hash algorithm implementations with Crypto API"
|
tristate "Register hash algorithm implementations with Crypto API"
|
||||||
depends on CRYPTO_DEV_FSL_CAAM_JR
|
depends on CRYPTO_DEV_FSL_CAAM_JR
|
||||||
|
@ -136,4 +153,5 @@ config CRYPTO_DEV_FSL_CAAM_DEBUG
|
||||||
information in the CAAM driver.
|
information in the CAAM driver.
|
||||||
|
|
||||||
config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC
|
config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC
|
||||||
def_tristate CRYPTO_DEV_FSL_CAAM_CRYPTO_API
|
def_tristate (CRYPTO_DEV_FSL_CAAM_CRYPTO_API || \
|
||||||
|
CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI)
|
||||||
|
|
|
@ -8,6 +8,7 @@ endif
|
||||||
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o
|
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o
|
||||||
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR) += caam_jr.o
|
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR) += caam_jr.o
|
||||||
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
|
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
|
||||||
|
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += caamalg_qi.o
|
||||||
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC) += caamalg_desc.o
|
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC) += caamalg_desc.o
|
||||||
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
|
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
|
||||||
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
|
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
|
||||||
|
|
|
@ -266,8 +266,9 @@ static int aead_set_sh_desc(struct crypto_aead *aead)
|
||||||
|
|
||||||
/* aead_encrypt shared descriptor */
|
/* aead_encrypt shared descriptor */
|
||||||
desc = ctx->sh_desc_enc;
|
desc = ctx->sh_desc_enc;
|
||||||
cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata, ctx->authsize,
|
cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata, ivsize,
|
||||||
is_rfc3686, nonce, ctx1_iv_off);
|
ctx->authsize, is_rfc3686, nonce, ctx1_iv_off,
|
||||||
|
false);
|
||||||
dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
|
dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
|
||||||
desc_bytes(desc), DMA_TO_DEVICE);
|
desc_bytes(desc), DMA_TO_DEVICE);
|
||||||
|
|
||||||
|
@ -299,7 +300,7 @@ skip_enc:
|
||||||
desc = ctx->sh_desc_dec;
|
desc = ctx->sh_desc_dec;
|
||||||
cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata, ivsize,
|
cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata, ivsize,
|
||||||
ctx->authsize, alg->caam.geniv, is_rfc3686,
|
ctx->authsize, alg->caam.geniv, is_rfc3686,
|
||||||
nonce, ctx1_iv_off);
|
nonce, ctx1_iv_off, false);
|
||||||
dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
|
dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
|
||||||
desc_bytes(desc), DMA_TO_DEVICE);
|
desc_bytes(desc), DMA_TO_DEVICE);
|
||||||
|
|
||||||
|
@ -333,7 +334,7 @@ skip_enc:
|
||||||
desc = ctx->sh_desc_enc;
|
desc = ctx->sh_desc_enc;
|
||||||
cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata, ivsize,
|
cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata, ivsize,
|
||||||
ctx->authsize, is_rfc3686, nonce,
|
ctx->authsize, is_rfc3686, nonce,
|
||||||
ctx1_iv_off);
|
ctx1_iv_off, false);
|
||||||
dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
|
dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
|
||||||
desc_bytes(desc), DMA_TO_DEVICE);
|
desc_bytes(desc), DMA_TO_DEVICE);
|
||||||
|
|
||||||
|
|
|
@ -265,17 +265,19 @@ static void init_sh_desc_key_aead(u32 * const desc,
|
||||||
* split key is to be used, the size of the split key itself is
|
* split key is to be used, the size of the split key itself is
|
||||||
* specified. Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1,
|
* specified. Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1,
|
||||||
* SHA224, SHA256, SHA384, SHA512} ANDed with OP_ALG_AAI_HMAC_PRECOMP.
|
* SHA224, SHA256, SHA384, SHA512} ANDed with OP_ALG_AAI_HMAC_PRECOMP.
|
||||||
|
* @ivsize: initialization vector size
|
||||||
* @icvsize: integrity check value (ICV) size (truncated or full)
|
* @icvsize: integrity check value (ICV) size (truncated or full)
|
||||||
* @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
|
* @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
|
||||||
* @nonce: pointer to rfc3686 nonce
|
* @nonce: pointer to rfc3686 nonce
|
||||||
* @ctx1_iv_off: IV offset in CONTEXT1 register
|
* @ctx1_iv_off: IV offset in CONTEXT1 register
|
||||||
|
* @is_qi: true when called from caam/qi
|
||||||
*
|
*
|
||||||
* Note: Requires an MDHA split key.
|
* Note: Requires an MDHA split key.
|
||||||
*/
|
*/
|
||||||
void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
|
void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
|
||||||
struct alginfo *adata, unsigned int icvsize,
|
struct alginfo *adata, unsigned int ivsize,
|
||||||
const bool is_rfc3686, u32 *nonce,
|
unsigned int icvsize, const bool is_rfc3686,
|
||||||
const u32 ctx1_iv_off)
|
u32 *nonce, const u32 ctx1_iv_off, const bool is_qi)
|
||||||
{
|
{
|
||||||
/* Note: Context registers are saved. */
|
/* Note: Context registers are saved. */
|
||||||
init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce);
|
init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce);
|
||||||
|
@ -284,6 +286,25 @@ void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
|
||||||
append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
|
append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
|
||||||
OP_ALG_ENCRYPT);
|
OP_ALG_ENCRYPT);
|
||||||
|
|
||||||
|
if (is_qi) {
|
||||||
|
u32 *wait_load_cmd;
|
||||||
|
|
||||||
|
/* REG3 = assoclen */
|
||||||
|
append_seq_load(desc, 4, LDST_CLASS_DECO |
|
||||||
|
LDST_SRCDST_WORD_DECO_MATH3 |
|
||||||
|
(4 << LDST_OFFSET_SHIFT));
|
||||||
|
|
||||||
|
wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
|
||||||
|
JUMP_COND_CALM | JUMP_COND_NCP |
|
||||||
|
JUMP_COND_NOP | JUMP_COND_NIP |
|
||||||
|
JUMP_COND_NIFP);
|
||||||
|
set_jump_tgt_here(desc, wait_load_cmd);
|
||||||
|
|
||||||
|
append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
|
||||||
|
LDST_SRCDST_BYTE_CONTEXT |
|
||||||
|
(ctx1_iv_off << LDST_OFFSET_SHIFT));
|
||||||
|
}
|
||||||
|
|
||||||
/* Read and write assoclen bytes */
|
/* Read and write assoclen bytes */
|
||||||
append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
|
append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
|
||||||
append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
|
append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
|
||||||
|
@ -338,6 +359,7 @@ EXPORT_SYMBOL(cnstr_shdsc_aead_encap);
|
||||||
* @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
|
* @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
|
||||||
* @nonce: pointer to rfc3686 nonce
|
* @nonce: pointer to rfc3686 nonce
|
||||||
* @ctx1_iv_off: IV offset in CONTEXT1 register
|
* @ctx1_iv_off: IV offset in CONTEXT1 register
|
||||||
|
* @is_qi: true when called from caam/qi
|
||||||
*
|
*
|
||||||
* Note: Requires an MDHA split key.
|
* Note: Requires an MDHA split key.
|
||||||
*/
|
*/
|
||||||
|
@ -345,7 +367,7 @@ void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
|
||||||
struct alginfo *adata, unsigned int ivsize,
|
struct alginfo *adata, unsigned int ivsize,
|
||||||
unsigned int icvsize, const bool geniv,
|
unsigned int icvsize, const bool geniv,
|
||||||
const bool is_rfc3686, u32 *nonce,
|
const bool is_rfc3686, u32 *nonce,
|
||||||
const u32 ctx1_iv_off)
|
const u32 ctx1_iv_off, const bool is_qi)
|
||||||
{
|
{
|
||||||
/* Note: Context registers are saved. */
|
/* Note: Context registers are saved. */
|
||||||
init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce);
|
init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce);
|
||||||
|
@ -354,6 +376,26 @@ void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
|
||||||
append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
|
append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
|
||||||
OP_ALG_DECRYPT | OP_ALG_ICV_ON);
|
OP_ALG_DECRYPT | OP_ALG_ICV_ON);
|
||||||
|
|
||||||
|
if (is_qi) {
|
||||||
|
u32 *wait_load_cmd;
|
||||||
|
|
||||||
|
/* REG3 = assoclen */
|
||||||
|
append_seq_load(desc, 4, LDST_CLASS_DECO |
|
||||||
|
LDST_SRCDST_WORD_DECO_MATH3 |
|
||||||
|
(4 << LDST_OFFSET_SHIFT));
|
||||||
|
|
||||||
|
wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
|
||||||
|
JUMP_COND_CALM | JUMP_COND_NCP |
|
||||||
|
JUMP_COND_NOP | JUMP_COND_NIP |
|
||||||
|
JUMP_COND_NIFP);
|
||||||
|
set_jump_tgt_here(desc, wait_load_cmd);
|
||||||
|
|
||||||
|
if (!geniv)
|
||||||
|
append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
|
||||||
|
LDST_SRCDST_BYTE_CONTEXT |
|
||||||
|
(ctx1_iv_off << LDST_OFFSET_SHIFT));
|
||||||
|
}
|
||||||
|
|
||||||
/* Read and write assoclen bytes */
|
/* Read and write assoclen bytes */
|
||||||
append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
|
append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
|
||||||
if (geniv)
|
if (geniv)
|
||||||
|
@ -423,21 +465,44 @@ EXPORT_SYMBOL(cnstr_shdsc_aead_decap);
|
||||||
* @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
|
* @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
|
||||||
* @nonce: pointer to rfc3686 nonce
|
* @nonce: pointer to rfc3686 nonce
|
||||||
* @ctx1_iv_off: IV offset in CONTEXT1 register
|
* @ctx1_iv_off: IV offset in CONTEXT1 register
|
||||||
|
* @is_qi: true when called from caam/qi
|
||||||
*
|
*
|
||||||
* Note: Requires an MDHA split key.
|
* Note: Requires an MDHA split key.
|
||||||
*/
|
*/
|
||||||
void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
|
void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
|
||||||
struct alginfo *adata, unsigned int ivsize,
|
struct alginfo *adata, unsigned int ivsize,
|
||||||
unsigned int icvsize, const bool is_rfc3686,
|
unsigned int icvsize, const bool is_rfc3686,
|
||||||
u32 *nonce, const u32 ctx1_iv_off)
|
u32 *nonce, const u32 ctx1_iv_off,
|
||||||
|
const bool is_qi)
|
||||||
{
|
{
|
||||||
u32 geniv, moveiv;
|
u32 geniv, moveiv;
|
||||||
|
|
||||||
/* Note: Context registers are saved. */
|
/* Note: Context registers are saved. */
|
||||||
init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce);
|
init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce);
|
||||||
|
|
||||||
if (is_rfc3686)
|
if (is_qi) {
|
||||||
|
u32 *wait_load_cmd;
|
||||||
|
|
||||||
|
/* REG3 = assoclen */
|
||||||
|
append_seq_load(desc, 4, LDST_CLASS_DECO |
|
||||||
|
LDST_SRCDST_WORD_DECO_MATH3 |
|
||||||
|
(4 << LDST_OFFSET_SHIFT));
|
||||||
|
|
||||||
|
wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
|
||||||
|
JUMP_COND_CALM | JUMP_COND_NCP |
|
||||||
|
JUMP_COND_NOP | JUMP_COND_NIP |
|
||||||
|
JUMP_COND_NIFP);
|
||||||
|
set_jump_tgt_here(desc, wait_load_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_rfc3686) {
|
||||||
|
if (is_qi)
|
||||||
|
append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
|
||||||
|
LDST_SRCDST_BYTE_CONTEXT |
|
||||||
|
(ctx1_iv_off << LDST_OFFSET_SHIFT));
|
||||||
|
|
||||||
goto copy_iv;
|
goto copy_iv;
|
||||||
|
}
|
||||||
|
|
||||||
/* Generate IV */
|
/* Generate IV */
|
||||||
geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
|
geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
#define DESC_AEAD_ENC_LEN (DESC_AEAD_BASE + 11 * CAAM_CMD_SZ)
|
#define DESC_AEAD_ENC_LEN (DESC_AEAD_BASE + 11 * CAAM_CMD_SZ)
|
||||||
#define DESC_AEAD_DEC_LEN (DESC_AEAD_BASE + 15 * CAAM_CMD_SZ)
|
#define DESC_AEAD_DEC_LEN (DESC_AEAD_BASE + 15 * CAAM_CMD_SZ)
|
||||||
#define DESC_AEAD_GIVENC_LEN (DESC_AEAD_ENC_LEN + 7 * CAAM_CMD_SZ)
|
#define DESC_AEAD_GIVENC_LEN (DESC_AEAD_ENC_LEN + 7 * CAAM_CMD_SZ)
|
||||||
|
#define DESC_QI_AEAD_ENC_LEN (DESC_AEAD_ENC_LEN + 3 * CAAM_CMD_SZ)
|
||||||
|
#define DESC_QI_AEAD_DEC_LEN (DESC_AEAD_DEC_LEN + 3 * CAAM_CMD_SZ)
|
||||||
|
#define DESC_QI_AEAD_GIVENC_LEN (DESC_AEAD_GIVENC_LEN + 3 * CAAM_CMD_SZ)
|
||||||
|
|
||||||
/* Note: Nonce is counted in cdata.keylen */
|
/* Note: Nonce is counted in cdata.keylen */
|
||||||
#define DESC_AEAD_CTR_RFC3686_LEN (4 * CAAM_CMD_SZ)
|
#define DESC_AEAD_CTR_RFC3686_LEN (4 * CAAM_CMD_SZ)
|
||||||
|
@ -45,20 +48,22 @@ void cnstr_shdsc_aead_null_decap(u32 * const desc, struct alginfo *adata,
|
||||||
unsigned int icvsize);
|
unsigned int icvsize);
|
||||||
|
|
||||||
void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
|
void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
|
||||||
struct alginfo *adata, unsigned int icvsize,
|
struct alginfo *adata, unsigned int ivsize,
|
||||||
const bool is_rfc3686, u32 *nonce,
|
unsigned int icvsize, const bool is_rfc3686,
|
||||||
const u32 ctx1_iv_off);
|
u32 *nonce, const u32 ctx1_iv_off,
|
||||||
|
const bool is_qi);
|
||||||
|
|
||||||
void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
|
void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
|
||||||
struct alginfo *adata, unsigned int ivsize,
|
struct alginfo *adata, unsigned int ivsize,
|
||||||
unsigned int icvsize, const bool geniv,
|
unsigned int icvsize, const bool geniv,
|
||||||
const bool is_rfc3686, u32 *nonce,
|
const bool is_rfc3686, u32 *nonce,
|
||||||
const u32 ctx1_iv_off);
|
const u32 ctx1_iv_off, const bool is_qi);
|
||||||
|
|
||||||
void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
|
void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
|
||||||
struct alginfo *adata, unsigned int ivsize,
|
struct alginfo *adata, unsigned int ivsize,
|
||||||
unsigned int icvsize, const bool is_rfc3686,
|
unsigned int icvsize, const bool is_rfc3686,
|
||||||
u32 *nonce, const u32 ctx1_iv_off);
|
u32 *nonce, const u32 ctx1_iv_off,
|
||||||
|
const bool is_qi);
|
||||||
|
|
||||||
void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata,
|
void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata,
|
||||||
unsigned int icvsize);
|
unsigned int icvsize);
|
||||||
|
|
2387
drivers/crypto/caam/caamalg_qi.c
Normal file
2387
drivers/crypto/caam/caamalg_qi.c
Normal file
File diff suppressed because it is too large
Load diff
108
drivers/crypto/caam/sg_sw_qm.h
Normal file
108
drivers/crypto/caam/sg_sw_qm.h
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013-2016 Freescale Semiconductor, Inc.
|
||||||
|
* Copyright 2016-2017 NXP
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of Freescale Semiconductor nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* ALTERNATIVELY, this software may be distributed under the terms of the
|
||||||
|
* GNU General Public License ("GPL") as published by the Free Software
|
||||||
|
* Foundation, either version 2 of that License or (at your option) any
|
||||||
|
* later version.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SG_SW_QM_H
|
||||||
|
#define __SG_SW_QM_H
|
||||||
|
|
||||||
|
#include <soc/fsl/qman.h>
|
||||||
|
#include "regs.h"
|
||||||
|
|
||||||
|
static inline void __dma_to_qm_sg(struct qm_sg_entry *qm_sg_ptr, dma_addr_t dma,
|
||||||
|
u16 offset)
|
||||||
|
{
|
||||||
|
qm_sg_entry_set64(qm_sg_ptr, dma);
|
||||||
|
qm_sg_ptr->__reserved2 = 0;
|
||||||
|
qm_sg_ptr->bpid = 0;
|
||||||
|
qm_sg_ptr->offset = cpu_to_be16(offset & QM_SG_OFF_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dma_to_qm_sg_one(struct qm_sg_entry *qm_sg_ptr,
|
||||||
|
dma_addr_t dma, u32 len, u16 offset)
|
||||||
|
{
|
||||||
|
__dma_to_qm_sg(qm_sg_ptr, dma, offset);
|
||||||
|
qm_sg_entry_set_len(qm_sg_ptr, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dma_to_qm_sg_one_last(struct qm_sg_entry *qm_sg_ptr,
|
||||||
|
dma_addr_t dma, u32 len, u16 offset)
|
||||||
|
{
|
||||||
|
__dma_to_qm_sg(qm_sg_ptr, dma, offset);
|
||||||
|
qm_sg_entry_set_f(qm_sg_ptr, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dma_to_qm_sg_one_ext(struct qm_sg_entry *qm_sg_ptr,
|
||||||
|
dma_addr_t dma, u32 len, u16 offset)
|
||||||
|
{
|
||||||
|
__dma_to_qm_sg(qm_sg_ptr, dma, offset);
|
||||||
|
qm_sg_ptr->cfg = cpu_to_be32(QM_SG_EXT | (len & QM_SG_LEN_MASK));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dma_to_qm_sg_one_last_ext(struct qm_sg_entry *qm_sg_ptr,
|
||||||
|
dma_addr_t dma, u32 len,
|
||||||
|
u16 offset)
|
||||||
|
{
|
||||||
|
__dma_to_qm_sg(qm_sg_ptr, dma, offset);
|
||||||
|
qm_sg_ptr->cfg = cpu_to_be32(QM_SG_EXT | QM_SG_FIN |
|
||||||
|
(len & QM_SG_LEN_MASK));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* convert scatterlist to h/w link table format
|
||||||
|
* but does not have final bit; instead, returns last entry
|
||||||
|
*/
|
||||||
|
static inline struct qm_sg_entry *
|
||||||
|
sg_to_qm_sg(struct scatterlist *sg, int sg_count,
|
||||||
|
struct qm_sg_entry *qm_sg_ptr, u16 offset)
|
||||||
|
{
|
||||||
|
while (sg_count && sg) {
|
||||||
|
dma_to_qm_sg_one(qm_sg_ptr, sg_dma_address(sg),
|
||||||
|
sg_dma_len(sg), offset);
|
||||||
|
qm_sg_ptr++;
|
||||||
|
sg = sg_next(sg);
|
||||||
|
sg_count--;
|
||||||
|
}
|
||||||
|
return qm_sg_ptr - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* convert scatterlist to h/w link table format
|
||||||
|
* scatterlist must have been previously dma mapped
|
||||||
|
*/
|
||||||
|
static inline void sg_to_qm_sg_last(struct scatterlist *sg, int sg_count,
|
||||||
|
struct qm_sg_entry *qm_sg_ptr, u16 offset)
|
||||||
|
{
|
||||||
|
qm_sg_ptr = sg_to_qm_sg(sg, sg_count, qm_sg_ptr, offset);
|
||||||
|
qm_sg_entry_set_f(qm_sg_ptr, qm_sg_entry_get_len(qm_sg_ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __SG_SW_QM_H */
|
Loading…
Add table
Reference in a new issue