提交 a7d1fa45 编写于 作者: Y Yu'an Wang 提交者: Yang Yingliang

zip: use offset fields in sqe to avoid SG_SPLIT

driver inclusion
category: feature
bugzilla: NA
CVE: NA

In this patch, we try to use the offset fields in sqe to avoid split
scatterlists. We can configure sgl offset fields in ZIP sqe to let
ZIP engine read/write sgl data with skipped data. Hence no need to
splite the sgl.
Signed-off-by: NYu'an Wang <wangyuan46@huawei.com>
Reviewed-by: NCheng Hu <hucheng.hu@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 755f04f7
...@@ -28,7 +28,6 @@ config CRYPTO_DEV_HISI_ZIP ...@@ -28,7 +28,6 @@ config CRYPTO_DEV_HISI_ZIP
tristate "Support for HISI ZIP Driver" tristate "Support for HISI ZIP Driver"
depends on ARM64 && ACPI depends on ARM64 && ACPI
select CRYPTO_DEV_HISI_QM select CRYPTO_DEV_HISI_QM
select SG_SPLIT
help help
Support for HiSilicon HIP08 ZIP Driver. Support for HiSilicon HIP08 ZIP Driver.
......
...@@ -5,12 +5,13 @@ ...@@ -5,12 +5,13 @@
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include "zip.h" #include "zip.h"
#ifndef CONFIG_SG_SPLIT
#include <../lib/sg_split.c>
#endif
/* hisi_zip_sqe dw3 */ /* hisi_zip_sqe dw3 */
#define HZIP_BD_STATUS_M GENMASK(7, 0) #define HZIP_BD_STATUS_M GENMASK(7, 0)
/* hisi_zip_sqe dw7 */
#define HZIP_IN_SGE_DATA_OFFSET_M GENMASK(23, 0)
/* hisi_zip_sqe dw8 */
#define HZIP_OUT_SGE_DATA_OFFSET_M GENMASK(23, 0)
/* hisi_zip_sqe dw9 */ /* hisi_zip_sqe dw9 */
#define HZIP_REQ_TYPE_M GENMASK(7, 0) #define HZIP_REQ_TYPE_M GENMASK(7, 0)
#define HZIP_ALG_TYPE_ZLIB 0x02 #define HZIP_ALG_TYPE_ZLIB 0x02
...@@ -66,10 +67,8 @@ enum { ...@@ -66,10 +67,8 @@ enum {
struct hisi_zip_req { struct hisi_zip_req {
struct acomp_req *req; struct acomp_req *req;
struct scatterlist *src; u32 sskip;
struct scatterlist *dst; u32 dskip;
size_t slen;
size_t dlen;
struct hisi_acc_hw_sgl *hw_src; struct hisi_acc_hw_sgl *hw_src;
struct hisi_acc_hw_sgl *hw_dst; struct hisi_acc_hw_sgl *hw_dst;
dma_addr_t dma_src; dma_addr_t dma_src;
...@@ -139,13 +138,15 @@ static void hisi_zip_config_tag(struct hisi_zip_sqe *sqe, u32 tag) ...@@ -139,13 +138,15 @@ static void hisi_zip_config_tag(struct hisi_zip_sqe *sqe, u32 tag)
static void hisi_zip_fill_sqe(struct hisi_zip_sqe *sqe, u8 req_type, static void hisi_zip_fill_sqe(struct hisi_zip_sqe *sqe, u8 req_type,
dma_addr_t s_addr, dma_addr_t d_addr, u32 slen, dma_addr_t s_addr, dma_addr_t d_addr, u32 slen,
u32 dlen) u32 dlen, u32 sskip, u32 dskip)
{ {
memset(sqe, 0, sizeof(struct hisi_zip_sqe)); memset(sqe, 0, sizeof(struct hisi_zip_sqe));
sqe->input_data_length = slen; sqe->input_data_length = slen - sskip;
sqe->dw7 = FIELD_PREP(HZIP_IN_SGE_DATA_OFFSET_M, sskip);
sqe->dw8 = FIELD_PREP(HZIP_OUT_SGE_DATA_OFFSET_M, dskip);
sqe->dw9 = FIELD_PREP(HZIP_REQ_TYPE_M, req_type); sqe->dw9 = FIELD_PREP(HZIP_REQ_TYPE_M, req_type);
sqe->dest_avail_out = dlen; sqe->dest_avail_out = dlen - dskip;
sqe->source_addr_l = lower_32_bits(s_addr); sqe->source_addr_l = lower_32_bits(s_addr);
sqe->source_addr_h = upper_32_bits(s_addr); sqe->source_addr_h = upper_32_bits(s_addr);
sqe->dest_addr_l = lower_32_bits(d_addr); sqe->dest_addr_l = lower_32_bits(d_addr);
...@@ -348,11 +349,6 @@ static void hisi_zip_remove_req(struct hisi_zip_qp_ctx *qp_ctx, ...@@ -348,11 +349,6 @@ static void hisi_zip_remove_req(struct hisi_zip_qp_ctx *qp_ctx,
{ {
struct hisi_zip_req_q *req_q = &qp_ctx->req_q; struct hisi_zip_req_q *req_q = &qp_ctx->req_q;
if (qp_ctx->qp->alg_type == HZIP_ALG_TYPE_COMP)
kfree(req->dst);
else
kfree(req->src);
write_lock(&req_q->req_lock); write_lock(&req_q->req_lock);
clear_bit(req->req_id, req_q->req_bitmap); clear_bit(req->req_id, req_q->req_bitmap);
memset(req, 0, sizeof(struct hisi_zip_req)); memset(req, 0, sizeof(struct hisi_zip_req));
...@@ -379,8 +375,8 @@ static void hisi_zip_acomp_cb(struct hisi_qp *qp, void *data) ...@@ -379,8 +375,8 @@ static void hisi_zip_acomp_cb(struct hisi_qp *qp, void *data)
} }
dlen = sqe->produced; dlen = sqe->produced;
hisi_acc_sg_buf_unmap(dev, req->src, req->hw_src); hisi_acc_sg_buf_unmap(dev, acomp_req->src, req->hw_src);
hisi_acc_sg_buf_unmap(dev, req->dst, req->hw_dst); hisi_acc_sg_buf_unmap(dev, acomp_req->dst, req->hw_dst);
head_size = (qp->alg_type == 0) ? TO_HEAD_SIZE(qp->req_type) : 0; head_size = (qp->alg_type == 0) ? TO_HEAD_SIZE(qp->req_type) : 0;
acomp_req->dlen = dlen + head_size; acomp_req->dlen = dlen + head_size;
...@@ -484,20 +480,6 @@ static int get_comp_head_size(struct scatterlist *src, u8 req_type) ...@@ -484,20 +480,6 @@ static int get_comp_head_size(struct scatterlist *src, u8 req_type)
} }
} }
static int get_sg_skip_bytes(struct scatterlist *sgl, size_t bytes,
size_t remains, struct scatterlist **out)
{
#define SPLIT_NUM 2
size_t split_sizes[SPLIT_NUM];
int out_mapped_nents[SPLIT_NUM];
split_sizes[0] = bytes;
split_sizes[1] = remains;
return sg_split(sgl, 0, 0, SPLIT_NUM, split_sizes, out,
out_mapped_nents, GFP_KERNEL);
}
static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req, static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req,
struct hisi_zip_qp_ctx *qp_ctx, struct hisi_zip_qp_ctx *qp_ctx,
size_t head_size, bool is_comp) size_t head_size, bool is_comp)
...@@ -505,32 +487,7 @@ static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req, ...@@ -505,32 +487,7 @@ static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req,
struct hisi_zip_req_q *req_q = &qp_ctx->req_q; struct hisi_zip_req_q *req_q = &qp_ctx->req_q;
struct hisi_zip_req *q = req_q->q; struct hisi_zip_req *q = req_q->q;
struct hisi_zip_req *req_cache; struct hisi_zip_req *req_cache;
struct scatterlist *out[SPLIT_NUM]; int req_id;
struct scatterlist *sgl;
size_t len;
u16 req_id;
int ret;
/*
* remove/add zlib/gzip head, as hardware operations do not include
* comp head. so split req->src to get sgl without heads in acomp, or
* add comp head to req->dst ahead of that hardware output compressed
* data in sgl splited from req->dst without comp head.
*/
if (is_comp) {
sgl = req->dst;
len = req->dlen - head_size;
} else {
sgl = req->src;
len = req->slen - head_size;
}
ret = get_sg_skip_bytes(sgl, head_size, len, out);
if (ret)
return ERR_PTR(ret);
/* sgl for comp head is useless, so free it now */
kfree(out[0]);
write_lock(&req_q->req_lock); write_lock(&req_q->req_lock);
...@@ -538,7 +495,6 @@ static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req, ...@@ -538,7 +495,6 @@ static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req,
if (req_id >= req_q->size) { if (req_id >= req_q->size) {
write_unlock(&req_q->req_lock); write_unlock(&req_q->req_lock);
dev_dbg(&qp_ctx->qp->qm->pdev->dev, "req cache is full!\n"); dev_dbg(&qp_ctx->qp->qm->pdev->dev, "req cache is full!\n");
kfree(out[1]);
return ERR_PTR(-EBUSY); return ERR_PTR(-EBUSY);
} }
set_bit(req_id, req_q->req_bitmap); set_bit(req_id, req_q->req_bitmap);
...@@ -546,16 +502,13 @@ static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req, ...@@ -546,16 +502,13 @@ static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req,
req_cache = q + req_id; req_cache = q + req_id;
req_cache->req_id = req_id; req_cache->req_id = req_id;
req_cache->req = req; req_cache->req = req;
if (is_comp) { if (is_comp) {
req_cache->src = req->src; req_cache->sskip = 0;
req_cache->dst = out[1]; req_cache->dskip = head_size;
req_cache->slen = req->slen;
req_cache->dlen = req->dlen - head_size;
} else { } else {
req_cache->src = out[1]; req_cache->sskip = head_size;
req_cache->dst = req->dst; req_cache->dskip = 0;
req_cache->slen = req->slen - head_size;
req_cache->dlen = req->dlen;
} }
write_unlock(&req_q->req_lock); write_unlock(&req_q->req_lock);
...@@ -567,6 +520,7 @@ static int hisi_zip_do_work(struct hisi_zip_req *req, ...@@ -567,6 +520,7 @@ static int hisi_zip_do_work(struct hisi_zip_req *req,
struct hisi_zip_qp_ctx *qp_ctx) struct hisi_zip_qp_ctx *qp_ctx)
{ {
struct hisi_zip_sqe *zip_sqe = &qp_ctx->zip_sqe; struct hisi_zip_sqe *zip_sqe = &qp_ctx->zip_sqe;
struct acomp_req *a_req = req->req;
struct hisi_qp *qp = qp_ctx->qp; struct hisi_qp *qp = qp_ctx->qp;
struct device *dev = &qp->qm->pdev->dev; struct device *dev = &qp->qm->pdev->dev;
struct hisi_acc_sgl_pool *pool = qp_ctx->sgl_pool; struct hisi_acc_sgl_pool *pool = qp_ctx->sgl_pool;
...@@ -574,10 +528,10 @@ static int hisi_zip_do_work(struct hisi_zip_req *req, ...@@ -574,10 +528,10 @@ static int hisi_zip_do_work(struct hisi_zip_req *req,
dma_addr_t output; dma_addr_t output;
int ret; int ret;
if (!req->src || !req->slen || !req->dst || !req->dlen) if (!a_req->src || !a_req->slen || !a_req->dst || !a_req->dlen)
return -EINVAL; return -EINVAL;
req->hw_src = hisi_acc_sg_buf_map_to_hw_sgl(dev, req->src, pool, req->hw_src = hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->src, pool,
req->req_id << 1, &input); req->req_id << 1, &input);
if (IS_ERR(req->hw_src)) { if (IS_ERR(req->hw_src)) {
dev_err(dev, "the src map to hw SGL failed!\n"); dev_err(dev, "the src map to hw SGL failed!\n");
...@@ -585,7 +539,7 @@ static int hisi_zip_do_work(struct hisi_zip_req *req, ...@@ -585,7 +539,7 @@ static int hisi_zip_do_work(struct hisi_zip_req *req,
} }
req->dma_src = input; req->dma_src = input;
req->hw_dst = hisi_acc_sg_buf_map_to_hw_sgl(dev, req->dst, pool, req->hw_dst = hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->dst, pool,
(req->req_id << 1) + 1, (req->req_id << 1) + 1,
&output); &output);
if (IS_ERR(req->hw_dst)) { if (IS_ERR(req->hw_dst)) {
...@@ -595,8 +549,8 @@ static int hisi_zip_do_work(struct hisi_zip_req *req, ...@@ -595,8 +549,8 @@ static int hisi_zip_do_work(struct hisi_zip_req *req,
} }
req->dma_dst = output; req->dma_dst = output;
hisi_zip_fill_sqe(zip_sqe, qp->req_type, input, output, req->slen, hisi_zip_fill_sqe(zip_sqe, qp->req_type, input, output, a_req->slen,
req->dlen); a_req->dlen, req->sskip, req->dskip);
hisi_zip_config_buf_type(zip_sqe, HZIP_SGL); hisi_zip_config_buf_type(zip_sqe, HZIP_SGL);
hisi_zip_config_tag(zip_sqe, req->req_id); hisi_zip_config_tag(zip_sqe, req->req_id);
...@@ -610,10 +564,10 @@ static int hisi_zip_do_work(struct hisi_zip_req *req, ...@@ -610,10 +564,10 @@ static int hisi_zip_do_work(struct hisi_zip_req *req,
return -EINPROGRESS; return -EINPROGRESS;
err_unmap_output: err_unmap_output:
hisi_acc_sg_buf_unmap(dev, req->dst, req->hw_dst); hisi_acc_sg_buf_unmap(dev, a_req->dst, req->hw_dst);
err_unmap_input: err_unmap_input:
hisi_acc_sg_buf_unmap(dev, req->src, req->hw_src); hisi_acc_sg_buf_unmap(dev, a_req->src, req->hw_src);
return ret; return ret;
} }
static int hisi_zip_acompress(struct acomp_req *acomp_req) static int hisi_zip_acompress(struct acomp_req *acomp_req)
......
...@@ -787,9 +787,6 @@ static void hisi_zip_log_hw_error(struct hisi_qm *qm, u32 err_sts) ...@@ -787,9 +787,6 @@ static void hisi_zip_log_hw_error(struct hisi_qm *qm, u32 err_sts)
((err_val >> ((err_val >>
HZIP_SRAM_ECC_ERR_NUM_SHIFT) & HZIP_SRAM_ECC_ERR_NUM_SHIFT) &
0xFF)); 0xFF));
dev_err(dev, "hisi-zip multi ecc sram addr=0x%x\n",
(err_val >>
HZIP_SRAM_ECC_ERR_ADDR_SHIFT));
} }
} }
err++; err++;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册