mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 10:11:26 +03:00
Compare commits
4 Commits
l4t/l4t-r3
...
l4t/l4t-r3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
087418781c | ||
|
|
fe0a030fee | ||
|
|
7ad4c09866 | ||
|
|
f41b74b8c3 |
@@ -42,6 +42,7 @@ struct tegra_aes_reqctx {
|
||||
u32 crypto_config;
|
||||
u32 len;
|
||||
u32 *iv;
|
||||
u32 *cmdbuf;
|
||||
};
|
||||
|
||||
struct tegra_aead_ctx {
|
||||
@@ -69,6 +70,7 @@ struct tegra_aead_reqctx {
|
||||
u32 key_id;
|
||||
u32 iv[4];
|
||||
u8 authdata[16];
|
||||
u32 *cmdbuf;
|
||||
};
|
||||
|
||||
struct tegra_cmac_ctx {
|
||||
@@ -93,6 +95,7 @@ struct tegra_cmac_reqctx {
|
||||
u32 key_id;
|
||||
u32 *iv;
|
||||
u32 result[CMAC_RESULT_REG_COUNT];
|
||||
u32 *cmdbuf;
|
||||
};
|
||||
|
||||
/* increment counter (128-bit int) */
|
||||
@@ -213,7 +216,7 @@ static int tegra234_aes_cfg(u32 alg, bool encrypt)
|
||||
static unsigned int tegra_aes_prep_cmd(struct tegra_se *se, struct tegra_aes_reqctx *rctx)
|
||||
{
|
||||
unsigned int data_count, res_bits, i = 0, j;
|
||||
u32 *cpuvaddr = se->cmdbuf->addr;
|
||||
u32 *cpuvaddr = rctx->cmdbuf;
|
||||
dma_addr_t addr = rctx->datbuf.addr;
|
||||
|
||||
data_count = rctx->len / AES_BLOCK_SIZE;
|
||||
@@ -292,16 +295,17 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
|
||||
|
||||
/* Prepare the command and submit for execution */
|
||||
cmdlen = tegra_aes_prep_cmd(se, rctx);
|
||||
ret = tegra_se_host1x_submit(se, cmdlen);
|
||||
ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen);
|
||||
|
||||
/* Copy the result */
|
||||
tegra_aes_update_iv(req, ctx);
|
||||
scatterwalk_map_and_copy(rctx->datbuf.buf, req->dst, 0, req->cryptlen, 1);
|
||||
|
||||
/* Free the buffer */
|
||||
dma_free_coherent(ctx->se->dev, rctx->datbuf.size,
|
||||
dma_free_coherent(se->dev, rctx->datbuf.size,
|
||||
rctx->datbuf.buf, rctx->datbuf.addr);
|
||||
|
||||
kfree(rctx->cmdbuf);
|
||||
crypto_finalize_skcipher_request(se->engine, req, ret);
|
||||
|
||||
return 0;
|
||||
@@ -459,6 +463,13 @@ static int tegra_aes_crypt(struct skcipher_request *req, bool encrypt)
|
||||
if (!req->cryptlen)
|
||||
return 0;
|
||||
|
||||
if (ctx->alg == SE_ALG_ECB)
|
||||
req->iv = NULL;
|
||||
|
||||
rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL);
|
||||
if (!rctx->cmdbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
rctx->encrypt = encrypt;
|
||||
rctx->config = tegra234_aes_cfg(ctx->alg, encrypt);
|
||||
rctx->crypto_config = tegra234_aes_crypto_cfg(ctx->alg, encrypt);
|
||||
@@ -597,7 +608,7 @@ static struct tegra_se_alg tegra_aes_algs[] = {
|
||||
static unsigned int tegra_gmac_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx)
|
||||
{
|
||||
unsigned int data_count, res_bits, i = 0;
|
||||
u32 *cpuvaddr = se->cmdbuf->addr;
|
||||
u32 *cpuvaddr = rctx->cmdbuf;
|
||||
|
||||
data_count = (rctx->assoclen / AES_BLOCK_SIZE);
|
||||
res_bits = (rctx->assoclen % AES_BLOCK_SIZE) * 8;
|
||||
@@ -635,7 +646,7 @@ static unsigned int tegra_gmac_prep_cmd(struct tegra_se *se, struct tegra_aead_r
|
||||
static unsigned int tegra_gcm_crypt_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx)
|
||||
{
|
||||
unsigned int data_count, res_bits, i = 0, j;
|
||||
u32 *cpuvaddr = se->cmdbuf->addr, op;
|
||||
u32 *cpuvaddr = rctx->cmdbuf, op;
|
||||
|
||||
data_count = (rctx->cryptlen / AES_BLOCK_SIZE);
|
||||
res_bits = (rctx->cryptlen % AES_BLOCK_SIZE) * 8;
|
||||
@@ -755,7 +766,7 @@ static int tegra_gcm_do_gmac(struct tegra_aead_ctx *ctx, struct tegra_aead_reqct
|
||||
|
||||
cmdlen = tegra_gmac_prep_cmd(se, rctx);
|
||||
|
||||
return tegra_se_host1x_submit(se, cmdlen);
|
||||
return tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen);
|
||||
}
|
||||
|
||||
static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx *rctx)
|
||||
@@ -772,7 +783,7 @@ static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
|
||||
|
||||
/* Prepare command and submit */
|
||||
cmdlen = tegra_gcm_crypt_prep_cmd(se, rctx);
|
||||
ret = tegra_se_host1x_submit(se, cmdlen);
|
||||
ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -786,7 +797,7 @@ static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
|
||||
static int tegra_gcm_do_final(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx *rctx)
|
||||
{
|
||||
struct tegra_se *se = ctx->se;
|
||||
u32 *cpuvaddr = se->cmdbuf->addr;
|
||||
u32 *cpuvaddr = rctx->cmdbuf;
|
||||
int cmdlen, ret, offset;
|
||||
|
||||
rctx->config = tegra234_aes_cfg(SE_ALG_GCM_FINAL, rctx->encrypt);
|
||||
@@ -795,7 +806,7 @@ static int tegra_gcm_do_final(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
|
||||
|
||||
/* Prepare command and submit */
|
||||
cmdlen = tegra_gcm_prep_final_cmd(se, cpuvaddr, rctx);
|
||||
ret = tegra_se_host1x_submit(se, cmdlen);
|
||||
ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -840,7 +851,7 @@ static inline int tegra_ccm_check_iv(const u8 *iv)
|
||||
static unsigned int tegra_cbcmac_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx)
|
||||
{
|
||||
unsigned int data_count, i = 0;
|
||||
u32 *cpuvaddr = se->cmdbuf->addr;
|
||||
u32 *cpuvaddr = rctx->cmdbuf;
|
||||
|
||||
data_count = (rctx->inbuf.size / AES_BLOCK_SIZE) - 1;
|
||||
|
||||
@@ -873,7 +884,7 @@ static unsigned int tegra_cbcmac_prep_cmd(struct tegra_se *se, struct tegra_aead
|
||||
static unsigned int tegra_ctr_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx)
|
||||
{
|
||||
unsigned int i = 0, j;
|
||||
u32 *cpuvaddr = se->cmdbuf->addr;
|
||||
u32 *cpuvaddr = rctx->cmdbuf;
|
||||
|
||||
cpuvaddr[i++] = host1x_opcode_setpayload(SE_CRYPTO_CTR_REG_COUNT);
|
||||
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->linear_ctr);
|
||||
@@ -923,7 +934,7 @@ static int tegra_ccm_do_cbcmac(struct tegra_aead_ctx *ctx, struct tegra_aead_req
|
||||
/* Prepare command and submit */
|
||||
cmdlen = tegra_cbcmac_prep_cmd(se, rctx);
|
||||
|
||||
return tegra_se_host1x_submit(se, cmdlen);
|
||||
return tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen);
|
||||
}
|
||||
|
||||
static int tegra_ccm_set_msg_len(u8 *block, unsigned int msglen, int csize)
|
||||
@@ -1130,7 +1141,7 @@ static int tegra_ccm_do_ctr(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx
|
||||
|
||||
/* Prepare command and submit */
|
||||
cmdlen = tegra_ctr_prep_cmd(se, rctx);
|
||||
ret = tegra_se_host1x_submit(se, cmdlen);
|
||||
ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1231,6 +1242,7 @@ outbuf_err:
|
||||
dma_free_coherent(ctx->se->dev, rctx->inbuf.size,
|
||||
rctx->inbuf.buf, rctx->inbuf.addr);
|
||||
|
||||
kfree(rctx->cmdbuf);
|
||||
crypto_finalize_aead_request(ctx->se->engine, req, ret);
|
||||
|
||||
return 0;
|
||||
@@ -1304,6 +1316,7 @@ outbuf_err:
|
||||
rctx->inbuf.buf, rctx->inbuf.addr);
|
||||
|
||||
/* Finalize the request if there are no errors */
|
||||
kfree(rctx->cmdbuf);
|
||||
crypto_finalize_aead_request(ctx->se->engine, req, ret);
|
||||
|
||||
return 0;
|
||||
@@ -1434,6 +1447,10 @@ static int tegra_aead_crypt(struct aead_request *req, bool encrypt)
|
||||
struct tegra_aead_ctx *ctx = crypto_aead_ctx(tfm);
|
||||
struct tegra_aead_reqctx *rctx = aead_request_ctx(req);
|
||||
|
||||
rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL);
|
||||
if (!rctx->cmdbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
rctx->encrypt = encrypt;
|
||||
|
||||
return crypto_transfer_aead_request_to_engine(ctx->se->engine, req);
|
||||
@@ -1465,7 +1482,7 @@ static int tegra_aead_setkey(struct crypto_aead *tfm,
|
||||
static unsigned int tegra_cmac_prep_cmd(struct tegra_se *se, struct tegra_cmac_reqctx *rctx)
|
||||
{
|
||||
unsigned int data_count, res_bits = 0, i = 0, j;
|
||||
u32 *cpuvaddr = se->cmdbuf->addr, op;
|
||||
u32 *cpuvaddr = rctx->cmdbuf, op;
|
||||
|
||||
data_count = (rctx->datbuf.size / AES_BLOCK_SIZE);
|
||||
|
||||
@@ -1572,6 +1589,11 @@ static int tegra_cmac_do_update(struct ahash_request *req)
|
||||
return 0;
|
||||
}
|
||||
|
||||
rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->datbuf.size,
|
||||
&rctx->datbuf.addr, GFP_KERNEL);
|
||||
if (!rctx->datbuf.buf)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Copy the previous residue first */
|
||||
if (rctx->residue.size)
|
||||
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
|
||||
@@ -1595,7 +1617,7 @@ static int tegra_cmac_do_update(struct ahash_request *req)
|
||||
|
||||
cmdlen = tegra_cmac_prep_cmd(se, rctx);
|
||||
|
||||
ret = tegra_se_host1x_submit(se, cmdlen);
|
||||
ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen);
|
||||
/*
|
||||
* If this is not the final update, copy the intermediate results
|
||||
* from the registers so that it can be used in the next 'update'
|
||||
@@ -1618,17 +1640,29 @@ static int tegra_cmac_do_final(struct ahash_request *req)
|
||||
|
||||
if (!req->nbytes && !rctx->total_len && ctx->fallback_tfm) {
|
||||
return crypto_shash_tfm_digest(ctx->fallback_tfm,
|
||||
rctx->datbuf.buf, 0, req->result);
|
||||
NULL, 0, req->result);
|
||||
}
|
||||
|
||||
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
|
||||
rctx->datbuf.size = rctx->residue.size;
|
||||
rctx->total_len += rctx->residue.size;
|
||||
rctx->config = tegra234_aes_cfg(SE_ALG_CMAC, 0);
|
||||
|
||||
if (rctx->residue.size) {
|
||||
rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->residue.size,
|
||||
&rctx->datbuf.addr, GFP_KERNEL);
|
||||
if (!rctx->datbuf.buf) {
|
||||
ret = -ENOMEM;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
|
||||
}
|
||||
|
||||
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
|
||||
|
||||
/* Prepare command and submit */
|
||||
cmdlen = tegra_cmac_prep_cmd(se, rctx);
|
||||
ret = tegra_se_host1x_submit(se, cmdlen);
|
||||
ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@@ -1640,10 +1674,14 @@ static int tegra_cmac_do_final(struct ahash_request *req)
|
||||
writel(0, se->base + se->hw->regs->result + (i * 4));
|
||||
|
||||
out:
|
||||
dma_free_coherent(se->dev, SE_SHA_BUFLEN,
|
||||
rctx->datbuf.buf, rctx->datbuf.addr);
|
||||
if (rctx->residue.size)
|
||||
dma_free_coherent(se->dev, rctx->datbuf.size,
|
||||
rctx->datbuf.buf, rctx->datbuf.addr);
|
||||
out_free:
|
||||
dma_free_coherent(se->dev, crypto_ahash_blocksize(tfm) * 2,
|
||||
rctx->residue.buf, rctx->residue.addr);
|
||||
kfree(rctx->cmdbuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1754,18 +1792,16 @@ static int tegra_cmac_init(struct ahash_request *req)
|
||||
rctx->task = SHA_FIRST;
|
||||
rctx->blk_size = crypto_ahash_blocksize(tfm);
|
||||
|
||||
rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL);
|
||||
if (!rctx->cmdbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size * 2,
|
||||
&rctx->residue.addr, GFP_KERNEL);
|
||||
if (!rctx->residue.buf)
|
||||
goto resbuf_fail;
|
||||
goto cmdbuf_free;
|
||||
|
||||
rctx->residue.size = 0;
|
||||
|
||||
rctx->datbuf.buf = dma_alloc_coherent(se->dev, SE_SHA_BUFLEN,
|
||||
&rctx->datbuf.addr, GFP_KERNEL);
|
||||
if (!rctx->datbuf.buf)
|
||||
goto datbuf_fail;
|
||||
|
||||
rctx->datbuf.size = 0;
|
||||
|
||||
/* Clear any previous result */
|
||||
@@ -1774,10 +1810,9 @@ static int tegra_cmac_init(struct ahash_request *req)
|
||||
|
||||
return 0;
|
||||
|
||||
datbuf_fail:
|
||||
dma_free_coherent(se->dev, rctx->blk_size, rctx->residue.buf,
|
||||
rctx->residue.addr);
|
||||
resbuf_fail:
|
||||
cmdbuf_free:
|
||||
kfree(rctx->cmdbuf);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ struct tegra_sha_reqctx {
|
||||
unsigned int blk_size;
|
||||
unsigned int task;
|
||||
u32 key_id;
|
||||
u32 *cmdbuf;
|
||||
u32 result[HASH_RESULT_REG_COUNT];
|
||||
struct ahash_request fallback_req;
|
||||
};
|
||||
@@ -305,7 +306,7 @@ static int tegra_sha_do_update(struct ahash_request *req)
|
||||
struct tegra_sha_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
|
||||
struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
|
||||
unsigned int nblks, nresidue, size, ret;
|
||||
u32 *cpuvaddr = ctx->se->cmdbuf->addr;
|
||||
u32 *cpuvaddr = rctx->cmdbuf;
|
||||
|
||||
nresidue = (req->nbytes + rctx->residue.size) % rctx->blk_size;
|
||||
nblks = (req->nbytes + rctx->residue.size) / rctx->blk_size;
|
||||
@@ -335,6 +336,11 @@ static int tegra_sha_do_update(struct ahash_request *req)
|
||||
return 0;
|
||||
}
|
||||
|
||||
rctx->datbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->datbuf.size,
|
||||
&rctx->datbuf.addr, GFP_KERNEL);
|
||||
if (!rctx->datbuf.buf)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Copy the previous residue first */
|
||||
if (rctx->residue.size)
|
||||
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
|
||||
@@ -361,7 +367,7 @@ static int tegra_sha_do_update(struct ahash_request *req)
|
||||
|
||||
size = tegra_sha_prep_cmd(ctx->se, cpuvaddr, rctx);
|
||||
|
||||
ret = tegra_se_host1x_submit(ctx->se, size);
|
||||
ret = tegra_se_host1x_submit(ctx->se, rctx->cmdbuf, size);
|
||||
|
||||
/*
|
||||
* If this is not the final update, copy the intermediate results
|
||||
@@ -371,6 +377,9 @@ static int tegra_sha_do_update(struct ahash_request *req)
|
||||
if (!(rctx->task & SHA_FINAL))
|
||||
tegra_sha_copy_hash_result(ctx->se, rctx);
|
||||
|
||||
dma_free_coherent(ctx->se->dev, rctx->datbuf.size,
|
||||
rctx->datbuf.buf, rctx->datbuf.addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -380,19 +389,28 @@ static int tegra_sha_do_final(struct ahash_request *req)
|
||||
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
||||
struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
|
||||
struct tegra_se *se = ctx->se;
|
||||
u32 *cpuvaddr = se->cmdbuf->addr;
|
||||
u32 *cpuvaddr = rctx->cmdbuf;
|
||||
int size, ret = 0;
|
||||
|
||||
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
|
||||
rctx->datbuf.size = rctx->residue.size;
|
||||
rctx->total_len += rctx->residue.size;
|
||||
|
||||
rctx->config = tegra_sha_get_config(rctx->alg) |
|
||||
SE_SHA_DST_MEMORY;
|
||||
|
||||
size = tegra_sha_prep_cmd(se, cpuvaddr, rctx);
|
||||
if (rctx->residue.size) {
|
||||
rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->residue.size,
|
||||
&rctx->datbuf.addr, GFP_KERNEL);
|
||||
if (!rctx->datbuf.buf) {
|
||||
ret = -ENOMEM;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = tegra_se_host1x_submit(se, size);
|
||||
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
|
||||
}
|
||||
|
||||
size = tegra_sha_prep_cmd(se, cpuvaddr, rctx);
|
||||
ret = tegra_se_host1x_submit(se, rctx->cmdbuf, size);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@@ -400,12 +418,16 @@ static int tegra_sha_do_final(struct ahash_request *req)
|
||||
memcpy(req->result, rctx->digest.buf, rctx->digest.size);
|
||||
|
||||
out:
|
||||
dma_free_coherent(se->dev, SE_SHA_BUFLEN,
|
||||
rctx->datbuf.buf, rctx->datbuf.addr);
|
||||
if (rctx->residue.size)
|
||||
dma_free_coherent(se->dev, rctx->datbuf.size,
|
||||
rctx->datbuf.buf, rctx->datbuf.addr);
|
||||
out_free:
|
||||
dma_free_coherent(se->dev, crypto_ahash_blocksize(tfm),
|
||||
rctx->residue.buf, rctx->residue.addr);
|
||||
dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
|
||||
rctx->digest.addr);
|
||||
kfree(rctx->cmdbuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -530,6 +552,10 @@ static int tegra_sha_init(struct ahash_request *req)
|
||||
rctx->blk_size = crypto_ahash_blocksize(tfm);
|
||||
rctx->digest.size = crypto_ahash_digestsize(tfm);
|
||||
|
||||
rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL);
|
||||
if (!rctx->cmdbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
rctx->digest.buf = dma_alloc_coherent(se->dev, rctx->digest.size,
|
||||
&rctx->digest.addr, GFP_KERNEL);
|
||||
if (!rctx->digest.buf)
|
||||
@@ -540,20 +566,14 @@ static int tegra_sha_init(struct ahash_request *req)
|
||||
if (!rctx->residue.buf)
|
||||
goto resbuf_fail;
|
||||
|
||||
rctx->datbuf.buf = dma_alloc_coherent(se->dev, SE_SHA_BUFLEN,
|
||||
&rctx->datbuf.addr, GFP_KERNEL);
|
||||
if (!rctx->datbuf.buf)
|
||||
goto datbuf_fail;
|
||||
|
||||
return 0;
|
||||
|
||||
datbuf_fail:
|
||||
dma_free_coherent(se->dev, rctx->blk_size, rctx->residue.buf,
|
||||
rctx->residue.addr);
|
||||
resbuf_fail:
|
||||
dma_free_coherent(se->dev, SE_SHA_BUFLEN, rctx->datbuf.buf,
|
||||
rctx->datbuf.addr);
|
||||
dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
|
||||
rctx->digest.addr);
|
||||
digbuf_fail:
|
||||
kfree(rctx->cmdbuf);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,11 +115,11 @@ static int tegra_key_insert(struct tegra_se *se, const u8 *key,
|
||||
u32 keylen, u16 slot, u32 alg)
|
||||
{
|
||||
const u32 *keyval = (u32 *)key;
|
||||
u32 *addr = se->cmdbuf->addr, size;
|
||||
u32 addr[100], size;
|
||||
|
||||
size = tegra_key_prep_ins_cmd(se, addr, keyval, keylen, slot, alg);
|
||||
|
||||
return tegra_se_host1x_submit(se, size);
|
||||
return tegra_se_host1x_submit(se, addr, size);
|
||||
}
|
||||
|
||||
void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg)
|
||||
|
||||
@@ -141,9 +141,10 @@ static struct tegra_se_cmdbuf *tegra_se_host1x_bo_alloc(struct tegra_se *se, ssi
|
||||
return cmdbuf;
|
||||
}
|
||||
|
||||
int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
|
||||
int tegra_se_host1x_submit(struct tegra_se *se, u32 *cpuvaddr, u32 size)
|
||||
{
|
||||
struct host1x_job *job;
|
||||
struct tegra_se_cmdbuf *cmdbuf;
|
||||
int ret;
|
||||
|
||||
job = host1x_job_alloc(se->channel, 1, 0, true);
|
||||
@@ -152,6 +153,12 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmdbuf = tegra_se_host1x_bo_alloc(se, SZ_4K);
|
||||
if (!cmdbuf)
|
||||
goto job_put;
|
||||
|
||||
memcpy(cmdbuf->addr, cpuvaddr, size * 4);
|
||||
|
||||
job->syncpt = host1x_syncpt_get(se->syncpt);
|
||||
job->syncpt_incrs = 1;
|
||||
job->client = &se->client;
|
||||
@@ -160,14 +167,14 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
|
||||
job->engine_fallback_streamid = se->stream_id;
|
||||
job->engine_streamid_offset = SE_STREAM_ID;
|
||||
|
||||
se->cmdbuf->words = size;
|
||||
cmdbuf->words = size;
|
||||
|
||||
host1x_job_add_gather(job, &se->cmdbuf->bo, size, 0);
|
||||
host1x_job_add_gather(job, &cmdbuf->bo, size, 0);
|
||||
|
||||
ret = host1x_job_pin(job, se->dev);
|
||||
if (ret) {
|
||||
dev_err(se->dev, "failed to pin host1x job\n");
|
||||
goto job_put;
|
||||
goto cmdbuf_put;
|
||||
}
|
||||
|
||||
ret = host1x_job_submit(job);
|
||||
@@ -184,10 +191,14 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
|
||||
}
|
||||
|
||||
host1x_job_put(job);
|
||||
tegra_se_cmdbuf_put(&cmdbuf->bo);
|
||||
|
||||
return 0;
|
||||
|
||||
job_unpin:
|
||||
host1x_job_unpin(job);
|
||||
cmdbuf_put:
|
||||
tegra_se_cmdbuf_put(&cmdbuf->bo);
|
||||
job_put:
|
||||
host1x_job_put(job);
|
||||
|
||||
@@ -214,22 +225,14 @@ static int tegra_se_client_init(struct host1x_client *client)
|
||||
|
||||
se->syncpt_id = host1x_syncpt_id(se->syncpt);
|
||||
|
||||
se->cmdbuf = tegra_se_host1x_bo_alloc(se, SZ_4K);
|
||||
if (!se->cmdbuf) {
|
||||
ret = -ENOMEM;
|
||||
goto syncpt_put;
|
||||
}
|
||||
|
||||
ret = se->hw->init_alg(se);
|
||||
if (ret) {
|
||||
dev_err(se->dev, "failed to register algorithms\n");
|
||||
goto cmdbuf_put;
|
||||
goto syncpt_put;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
cmdbuf_put:
|
||||
tegra_se_cmdbuf_put(&se->cmdbuf->bo);
|
||||
syncpt_put:
|
||||
host1x_syncpt_put(se->syncpt);
|
||||
channel_put:
|
||||
@@ -243,7 +246,6 @@ static int tegra_se_client_deinit(struct host1x_client *client)
|
||||
struct tegra_se *se = container_of(client, struct tegra_se, client);
|
||||
|
||||
se->hw->deinit_alg(se);
|
||||
tegra_se_cmdbuf_put(&se->cmdbuf->bo);
|
||||
host1x_syncpt_put(se->syncpt);
|
||||
host1x_channel_put(se->channel);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#define SE_OWNERSHIP_UID(x) FIELD_GET(GENMASK(7, 0), x)
|
||||
#define TEGRA_GPSE_ID 3
|
||||
|
||||
#define SE_MAX_CMDLEN (100 * 4) /* max 100 commands of 4 bytes each */
|
||||
#define SE_STREAM_ID 0x90
|
||||
|
||||
#define SE_SHA_CFG 0x4004
|
||||
@@ -342,7 +343,6 @@
|
||||
#define SE_CRYPTO_CTR_REG_COUNT 4
|
||||
#define SE_MAX_KEYSLOT 15
|
||||
#define SE_MAX_MEM_ALLOC SZ_4M
|
||||
#define SE_SHA_BUFLEN 0x2000
|
||||
|
||||
#define SHA_FIRST BIT(0)
|
||||
#define SHA_UPDATE BIT(1)
|
||||
@@ -442,7 +442,6 @@ struct tegra_se {
|
||||
const struct tegra_se_hw *hw;
|
||||
struct host1x_client client;
|
||||
struct host1x_channel *channel;
|
||||
struct tegra_se_cmdbuf *cmdbuf;
|
||||
struct crypto_engine *engine;
|
||||
struct host1x_syncpt *syncpt;
|
||||
struct device *dev;
|
||||
@@ -525,7 +524,7 @@ void tegra_deinit_hash(struct tegra_se *se);
|
||||
int tegra_key_submit(struct tegra_se *se, const u8 *key,
|
||||
u32 keylen, u32 alg, u32 *keyid);
|
||||
void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg);
|
||||
int tegra_se_host1x_submit(struct tegra_se *se, u32 size);
|
||||
int tegra_se_host1x_submit(struct tegra_se *se, u32 *cpuvaddr, u32 size);
|
||||
|
||||
/* HOST1x OPCODES */
|
||||
static inline u32 host1x_opcode_setpayload(unsigned int payload)
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2015-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
/*
|
||||
* NVIDIA Tegra CSI Device
|
||||
*
|
||||
* Copyright (c) 2015-2024, NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
@@ -687,7 +686,7 @@ static int tegra_csi_set_format(struct v4l2_subdev *subdev,
|
||||
}
|
||||
|
||||
static int tegra_csi_g_frame_interval(struct v4l2_subdev *sd,
|
||||
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_FRAME_INTERVAL)
|
||||
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_SET_FRAME_INTERVAL)
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
#endif
|
||||
struct v4l2_subdev_frame_interval *vfi)
|
||||
@@ -721,13 +720,13 @@ static int tegra_csi_enum_mbus_code(struct v4l2_subdev *sd,
|
||||
static struct v4l2_subdev_video_ops tegra_csi_video_ops = {
|
||||
.s_stream = tegra_csi_s_stream,
|
||||
.g_input_status = tegra_csi_g_input_status,
|
||||
#if !defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_FRAME_INTERVAL)
|
||||
#if !defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_SET_FRAME_INTERVAL)
|
||||
.g_frame_interval = tegra_csi_g_frame_interval,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct v4l2_subdev_pad_ops tegra_csi_pad_ops = {
|
||||
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_FRAME_INTERVAL)
|
||||
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_SET_FRAME_INTERVAL)
|
||||
.get_frame_interval = tegra_csi_g_frame_interval,
|
||||
#endif
|
||||
.get_fmt = tegra_csi_get_format,
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2018-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
/*
|
||||
* tegracam_v4l2 - tegra camera framework for v4l2 support
|
||||
*
|
||||
* Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <media/tegra-v4l2-camera.h>
|
||||
#include <media/tegracam_core.h>
|
||||
@@ -112,9 +114,30 @@ static int v4l2sd_g_input_status(struct v4l2_subdev *sd, u32 *status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_g_frame_interval(struct v4l2_subdev *sd,
|
||||
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_SET_FRAME_INTERVAL)
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
#endif
|
||||
struct v4l2_subdev_frame_interval *ival)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
struct camera_common_data *s_data = to_camera_common_data(&client->dev);
|
||||
|
||||
if (!s_data)
|
||||
return -EINVAL;
|
||||
|
||||
ival->interval.denominator = s_data->frmfmt[s_data->mode_prop_idx].framerates[0];
|
||||
ival->interval.numerator = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct v4l2_subdev_video_ops v4l2sd_video_ops = {
|
||||
.s_stream = v4l2sd_stream,
|
||||
.g_input_status = v4l2sd_g_input_status,
|
||||
#if !defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_SET_FRAME_INTERVAL)
|
||||
.g_frame_interval = cam_g_frame_interval,
|
||||
.s_frame_interval = cam_g_frame_interval,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct v4l2_subdev_core_ops v4l2sd_core_ops = {
|
||||
@@ -161,6 +184,10 @@ static int v4l2sd_set_fmt(struct v4l2_subdev *sd,
|
||||
}
|
||||
|
||||
static struct v4l2_subdev_pad_ops v4l2sd_pad_ops = {
|
||||
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_SET_FRAME_INTERVAL)
|
||||
.get_frame_interval = cam_g_frame_interval,
|
||||
.set_frame_interval = cam_g_frame_interval,
|
||||
#endif
|
||||
.set_fmt = v4l2sd_set_fmt,
|
||||
.get_fmt = v4l2sd_get_fmt,
|
||||
.enum_mbus_code = camera_common_enum_mbus_code,
|
||||
|
||||
@@ -2281,10 +2281,32 @@ static long tegra_channel_default_ioctl(struct file *file, void *fh,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Implemented vidioc_s_parm and vidioc_g_parm ioctl to support multiple frame
|
||||
* rates */
|
||||
static int tegra_channel_s_parm(struct file *file, void *fh,
|
||||
struct v4l2_streamparm *a)
|
||||
{
|
||||
struct tegra_channel *chan = video_drvdata(file);
|
||||
struct v4l2_subdev *sd = chan->subdev_on_csi;
|
||||
|
||||
return v4l2_s_parm_cap(chan->video, sd, a);
|
||||
}
|
||||
|
||||
static int tegra_channel_g_parm(struct file *file, void *fh,
|
||||
struct v4l2_streamparm *a)
|
||||
{
|
||||
struct tegra_channel *chan = video_drvdata(file);
|
||||
struct v4l2_subdev *sd = chan->subdev_on_csi;
|
||||
|
||||
return v4l2_g_parm_cap(chan->video, sd, a);
|
||||
}
|
||||
|
||||
static const struct v4l2_ioctl_ops tegra_channel_ioctl_ops = {
|
||||
.vidioc_querycap = tegra_channel_querycap,
|
||||
.vidioc_enum_framesizes = tegra_channel_enum_framesizes,
|
||||
.vidioc_enum_frameintervals = tegra_channel_enum_frameintervals,
|
||||
.vidioc_s_parm = tegra_channel_s_parm,
|
||||
.vidioc_g_parm = tegra_channel_g_parm,
|
||||
.vidioc_enum_fmt_vid_cap = tegra_channel_enum_format,
|
||||
.vidioc_g_fmt_vid_cap = tegra_channel_get_format,
|
||||
.vidioc_s_fmt_vid_cap = tegra_channel_set_format,
|
||||
|
||||
@@ -181,7 +181,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_async_subdev_nf_init
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_async_notifier_init
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_async_nf_init_has_v4l2_dev_arg
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += __v4l2_async_nf_add_subdev
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_subdev_pad_ops_struct_has_get_frame_interval
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_subdev_pad_ops_struct_has_get_set_frame_interval
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_subdev_pad_ops_struct_has_dv_timings
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += vm_area_struct_has_const_vm_flags
|
||||
NV_CONFTEST_GENERIC_COMPILE_TESTS += is_export_symbol_present_drm_gem_prime_fd_to_handle
|
||||
|
||||
@@ -8082,10 +8082,12 @@ compile_test() {
|
||||
compile_check_conftest "$CODE" "NV_V4L2_ASYNC_NF_ADD_SUBDEV_PRESENT" "" "functions"
|
||||
;;
|
||||
|
||||
v4l2_subdev_pad_ops_struct_has_get_frame_interval)
|
||||
v4l2_subdev_pad_ops_struct_has_get_set_frame_interval)
|
||||
#
|
||||
# Determine if struct v4l2_subdev_pad_ops has the 'get_frame_interval'
|
||||
# function pointer.
|
||||
# and 'set_frame_interval' function pointers. Note that it is only
|
||||
# necessary to check for the presence of one because both were added
|
||||
# by the same commit.
|
||||
#
|
||||
# Added by commit 287fe160834a ("media: v4l2-subdev: Turn
|
||||
# .[gs]_frame_interval into pad operations") in Linux v6.8.
|
||||
@@ -8098,7 +8100,7 @@ compile_test() {
|
||||
}
|
||||
"
|
||||
compile_check_conftest "$CODE" \
|
||||
"NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_FRAME_INTERVAL" "" "types"
|
||||
"NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_SET_FRAME_INTERVAL" "" "types"
|
||||
;;
|
||||
|
||||
v4l2_subdev_pad_ops_struct_has_dv_timings)
|
||||
|
||||
Reference in New Issue
Block a user