Skip to content
4 changes: 3 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ pkginclude_HEADERS = include/wd.h include/wd_cipher.h include/wd_aead.h \
include/wd_comp.h include/wd_dh.h include/wd_digest.h \
include/wd_rsa.h include/uacce.h include/wd_alg_common.h \
include/wd_ecc.h include/wd_sched.h include/wd_alg.h \
include/wd_zlibwrapper.h include/wd_dae.h include/wd_agg.h
include/wd_zlibwrapper.h include/wd_dae.h include/wd_agg.h \
include/wd_bmm.h

nobase_pkginclude_HEADERS = v1/wd.h v1/wd_cipher.h v1/wd_aead.h v1/uacce.h v1/wd_dh.h \
v1/wd_digest.h v1/wd_rsa.h v1/wd_bmm.h
Expand All @@ -60,6 +61,7 @@ libwd_la_SOURCES=wd.c wd_mempool.c wd.h wd_alg.c wd_alg.h \
v1/wd_bmm.c v1/wd_bmm.h \
v1/wd_ecc.c v1/wd_ecc.h \
v1/wd_sgl.c v1/wd_sgl.h \
wd_bmm.c \
aes.h sm4.h galois.h \
lib/crypto/aes.c lib/crypto/sm4.c lib/crypto/galois.c \
v1/drv/hisi_qm_udrv.c v1/drv/hisi_qm_udrv.h \
Expand Down
102 changes: 75 additions & 27 deletions drv/hisi_comp.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,14 @@ static int fill_buf_deflate_generic(struct hisi_zip_sqe *sqe,
if (msg->ctx_buf)
ctx_buf = msg->ctx_buf + RSV_OFFSET;

fill_buf_addr_deflate(sqe, src, dst, ctx_buf);
if (msg->blkpool) {
fill_buf_addr_deflate(sqe,
wd_blkpool_phy(msg->blkpool, src),
wd_blkpool_phy(msg->blkpool, dst),
wd_blkpool_phy(msg->blkpool, ctx_buf));
} else {
fill_buf_addr_deflate(sqe, src, dst, ctx_buf);
}

return 0;
}
Expand Down Expand Up @@ -464,32 +471,45 @@ static void fill_buf_type_sgl(struct hisi_zip_sqe *sqe)
}

static int fill_buf_addr_deflate_sgl(handle_t h_qp, struct hisi_zip_sqe *sqe,
struct wd_comp_msg *msg,
struct wd_datalist *list_src,
struct wd_datalist *list_dst)
{
void *hw_sgl_in, *hw_sgl_out;
handle_t h_sgl_pool;

h_sgl_pool = hisi_qm_get_sglpool(h_qp);
if (msg->h_sgl_pool)
h_sgl_pool = msg->h_sgl_pool;
else
h_sgl_pool = hisi_qm_get_sglpool(h_qp);
if (unlikely(!h_sgl_pool)) {
WD_ERR("failed to get sglpool!\n");
return -WD_EINVAL;
}

hw_sgl_in = hisi_qm_get_hw_sgl(h_sgl_pool, list_src);
hw_sgl_in = hisi_qm_get_hw_sgl(h_sgl_pool, list_src, msg->blkpool);
if (unlikely(!hw_sgl_in)) {
WD_ERR("failed to get hw sgl in!\n");
return -WD_ENOMEM;
return -WD_EBUSY;
}

hw_sgl_out = hisi_qm_get_hw_sgl(h_sgl_pool, list_dst);
hw_sgl_out = hisi_qm_get_hw_sgl(h_sgl_pool, list_dst, msg->blkpool);
if (unlikely(!hw_sgl_out)) {
WD_ERR("failed to get hw sgl out!\n");
hisi_qm_put_hw_sgl(h_sgl_pool, hw_sgl_in);
return -WD_ENOMEM;
return -WD_EBUSY;
}

fill_buf_addr_deflate(sqe, hw_sgl_in, hw_sgl_out, NULL);
if (msg->h_sgl_pool) {
fill_buf_addr_deflate(sqe,
wd_blkpool_phy(msg->blkpool, hw_sgl_in),
wd_blkpool_phy(msg->blkpool, hw_sgl_out),
NULL);
msg->hw_sgl_in = hw_sgl_in;
msg->hw_sgl_out = hw_sgl_out;
} else {
fill_buf_addr_deflate(sqe, hw_sgl_in, hw_sgl_out, NULL);
}

return 0;
}
Expand Down Expand Up @@ -543,7 +563,7 @@ static int fill_buf_deflate_sgl_generic(handle_t h_qp, struct hisi_zip_sqe *sqe,

fill_buf_type_sgl(sqe);

ret = fill_buf_addr_deflate_sgl(h_qp, sqe, list_src, list_dst);
ret = fill_buf_addr_deflate_sgl(h_qp, sqe, msg, list_src, list_dst);
if (unlikely(ret))
return ret;

Expand Down Expand Up @@ -738,34 +758,48 @@ static int fill_buf_lz77_zstd_sgl(handle_t h_qp, struct hisi_zip_sqe *sqe,

fill_buf_size_lz77_zstd(sqe, in_size, lits_size, out_size - lits_size);

h_sgl_pool = hisi_qm_get_sglpool(h_qp);
if (msg->h_sgl_pool)
h_sgl_pool = msg->h_sgl_pool;
else
h_sgl_pool = hisi_qm_get_sglpool(h_qp);
if (unlikely(!h_sgl_pool)) {
WD_ERR("failed to get sglpool!\n");
return -WD_EINVAL;
}

hw_sgl_in = hisi_qm_get_hw_sgl(h_sgl_pool, req->list_src);
hw_sgl_in = hisi_qm_get_hw_sgl(h_sgl_pool, req->list_src, msg->blkpool);
if (unlikely(!hw_sgl_in)) {
WD_ERR("failed to get hw sgl in!\n");
return -WD_ENOMEM;
}

hw_sgl_out_lit = hisi_qm_get_hw_sgl(h_sgl_pool, req->list_dst);
hw_sgl_out_lit = hisi_qm_get_hw_sgl(h_sgl_pool, req->list_dst, msg->blkpool);
if (unlikely(!hw_sgl_out_lit)) {
WD_ERR("failed to get hw sgl out for literals!\n");
ret = -WD_ENOMEM;
goto err_free_sgl_in;
}

hw_sgl_out_seq = hisi_qm_get_hw_sgl(h_sgl_pool, seq_start);
hw_sgl_out_seq = hisi_qm_get_hw_sgl(h_sgl_pool, seq_start, msg->blkpool);
if (unlikely(!hw_sgl_out_seq)) {
WD_ERR("failed to get hw sgl out for sequences!\n");
ret = -WD_ENOMEM;
goto err_free_sgl_out_lit;
}

fill_buf_addr_lz77_zstd(sqe, hw_sgl_in, hw_sgl_out_lit,
if (msg->h_sgl_pool) {
fill_buf_addr_lz77_zstd(sqe,
wd_blkpool_phy(msg->blkpool, hw_sgl_in),
wd_blkpool_phy(msg->blkpool, hw_sgl_out_lit),
wd_blkpool_phy(msg->blkpool, hw_sgl_out_seq),
NULL);
msg->hw_sgl_in = hw_sgl_in;
msg->hw_sgl_out = hw_sgl_out_lit;
msg->hw_sgl_out_seq = hw_sgl_out_seq;
} else {
fill_buf_addr_lz77_zstd(sqe, hw_sgl_in, hw_sgl_out_lit,
hw_sgl_out_seq, NULL);
}

return 0;

Expand Down Expand Up @@ -1116,27 +1150,41 @@ static int fill_zip_comp_sqe(struct hisi_qp *qp, struct wd_comp_msg *msg,
}

static void free_hw_sgl(handle_t h_qp, struct hisi_zip_sqe *sqe,
struct wd_comp_msg *msg,
enum wd_comp_alg_type alg_type)
{
void *hw_sgl_in, *hw_sgl_out;
handle_t h_sgl_pool;

h_sgl_pool = hisi_qm_get_sglpool(h_qp);
if (unlikely(!h_sgl_pool)) {
WD_ERR("failed to get sglpool to free hw sgl!\n");
return;
}
if (msg->h_sgl_pool) {
h_sgl_pool = msg->h_sgl_pool;
if (unlikely(!h_sgl_pool)) {
WD_ERR("failed to get sglpool to free hw sgl!\n");
return;
}
hisi_qm_put_hw_sgl(h_sgl_pool, msg->hw_sgl_in);
hisi_qm_put_hw_sgl(h_sgl_pool, msg->hw_sgl_out);
if (alg_type == WD_LZ77_ZSTD)
hisi_qm_put_hw_sgl(h_sgl_pool, msg->hw_sgl_out_seq);
} else {

hw_sgl_in = VA_ADDR(sqe->source_addr_h, sqe->source_addr_l);
hisi_qm_put_hw_sgl(h_sgl_pool, hw_sgl_in);
h_sgl_pool = hisi_qm_get_sglpool(h_qp);
if (unlikely(!h_sgl_pool)) {
WD_ERR("failed to get sglpool to free hw sgl!\n");
return;
}

hw_sgl_out = VA_ADDR(sqe->dest_addr_h, sqe->dest_addr_l);
hisi_qm_put_hw_sgl(h_sgl_pool, hw_sgl_out);
hw_sgl_in = VA_ADDR(sqe->source_addr_h, sqe->source_addr_l);
hisi_qm_put_hw_sgl(h_sgl_pool, hw_sgl_in);

if (alg_type == WD_LZ77_ZSTD) {
hw_sgl_out = VA_ADDR(sqe->literals_addr_h,
sqe->literals_addr_l);
hw_sgl_out = VA_ADDR(sqe->dest_addr_h, sqe->dest_addr_l);
hisi_qm_put_hw_sgl(h_sgl_pool, hw_sgl_out);

if (alg_type == WD_LZ77_ZSTD) {
hw_sgl_out = VA_ADDR(sqe->literals_addr_h,
sqe->literals_addr_l);
hisi_qm_put_hw_sgl(h_sgl_pool, hw_sgl_out);
}
}
}

Expand All @@ -1163,7 +1211,7 @@ static int hisi_zip_comp_send(struct wd_alg_driver *drv, handle_t ctx, void *com
ret = hisi_qm_send(h_qp, &sqe, 1, &count);
if (unlikely(ret < 0)) {
if (msg->req.data_fmt == WD_SGL_BUF)
free_hw_sgl(h_qp, &sqe, msg->alg_type);
free_hw_sgl(h_qp, &sqe, msg, msg->alg_type);
if (ret != -WD_EBUSY)
WD_ERR("failed to send to hardware, ret = %d!\n", ret);

Expand Down Expand Up @@ -1304,7 +1352,7 @@ static int parse_zip_sqe(struct hisi_qp *qp, struct hisi_zip_sqe *sqe,
recv_msg->alg_type = alg_type;

if (buf_type == WD_SGL_BUF)
free_hw_sgl((handle_t)qp, sqe, alg_type);
free_hw_sgl((handle_t)qp, sqe, recv_msg, alg_type);

if (unlikely(recv_msg->req.status == WD_IN_EPARA))
dump_zip_msg(recv_msg);
Expand Down
33 changes: 23 additions & 10 deletions drv/hisi_qm_udrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "hisi_qm_udrv.h"
#include "wd_util.h"
#include "wd_bmm.h"

#define QM_DBELL_CMD_SQ 0
#define QM_DBELL_CMD_CQ 1
Expand Down Expand Up @@ -82,7 +83,7 @@ struct hisi_sge {

/* use default hw sgl head size 64B, in little-endian */
struct hisi_sgl {
/* the next sgl address */
/* the next sgl dma address */
uintptr_t next_dma;
/* the sge num of all the sgl */
__le16 entry_sum_in_chain;
Expand All @@ -91,7 +92,9 @@ struct hisi_sgl {
/* the sge num in this sgl */
__le16 entry_length_in_sgl;
__le16 pad0;
__le64 pad1[5];
__le64 pad1[4];
/* the next sgl address */
struct hisi_sgl *next;
/* valid sge buffs total size */
__le64 entry_size_in_sgl;
struct hisi_sge sge_entries[];
Expand Down Expand Up @@ -655,6 +658,7 @@ static struct hisi_sgl *hisi_qm_align_sgl(const void *sgl, __u32 sge_num)
sgl_align->entry_sum_in_chain = sge_num;
sgl_align->entry_sum_in_sgl = 0;
sgl_align->entry_length_in_sgl = sge_num;
sgl_align->next = 0;
sgl_align->next_dma = 0;

return sgl_align;
Expand Down Expand Up @@ -776,6 +780,7 @@ static int hisi_qm_sgl_push(struct hisi_sgl_pool *pool, struct hisi_sgl *hw_sgl)
return -WD_EINVAL;
}

hw_sgl->next = 0;
hw_sgl->next_dma = 0;
hw_sgl->entry_sum_in_sgl = 0;
hw_sgl->entry_sum_in_chain = pool->sge_num;
Expand All @@ -800,7 +805,7 @@ void hisi_qm_put_hw_sgl(handle_t sgl_pool, void *hw_sgl)
return;

while (cur) {
next = (struct hisi_sgl *)cur->next_dma;
next = (struct hisi_sgl *)cur->next;
ret = hisi_qm_sgl_push(pool, cur);
if (ret)
break;
Expand Down Expand Up @@ -832,7 +837,7 @@ static void hisi_qm_dump_sgl(void *sgl)
WD_DEBUG("[sgl-%d]->sge_entries[%d].len: %u\n", k, i,
tmp->sge_entries[i].len);

tmp = (struct hisi_sgl *)tmp->next_dma;
tmp = (struct hisi_sgl *)tmp->next;
k++;

if (!tmp) {
Expand All @@ -842,7 +847,8 @@ static void hisi_qm_dump_sgl(void *sgl)
}
}

void *hisi_qm_get_hw_sgl(handle_t sgl_pool, struct wd_datalist *sgl)
void *hisi_qm_get_hw_sgl(handle_t sgl_pool, struct wd_datalist *sgl,
void *blkpool)
{
struct hisi_sgl_pool *pool = (struct hisi_sgl_pool *)sgl_pool;
struct wd_datalist *tmp = sgl;
Expand Down Expand Up @@ -872,7 +878,10 @@ void *hisi_qm_get_hw_sgl(handle_t sgl_pool, struct wd_datalist *sgl)
goto err_out;
}

cur->sge_entries[i].buff = (uintptr_t)tmp->data;
if (blkpool)
cur->sge_entries[i].buff = (uintptr_t)wd_blkpool_phy(blkpool, tmp->data);
else
cur->sge_entries[i].buff = (uintptr_t)tmp->data;
cur->sge_entries[i].len = tmp->len;
cur->entry_sum_in_sgl++;
cur->entry_size_in_sgl += tmp->len;
Expand All @@ -890,7 +899,11 @@ void *hisi_qm_get_hw_sgl(handle_t sgl_pool, struct wd_datalist *sgl)
WD_ERR("invalid: the sgl pool is not enough!\n");
goto err_out;
}
cur->next_dma = (uintptr_t)next;
if (blkpool)
cur->next_dma = (uintptr_t)wd_blkpool_phy(blkpool, next);
else
cur->next_dma = (uintptr_t)next;
cur->next = next;
cur = next;
head->entry_sum_in_chain += pool->sge_num;
/* In the new sgl chain, the subscript must be reset */
Expand Down Expand Up @@ -949,7 +962,7 @@ static void hisi_qm_sgl_copy_inner(void *pbuff, struct hisi_sgl *hw_sgl,
offset += tmp->sge_entries[i].len;
}

tmp = (struct hisi_sgl *)tmp->next_dma;
tmp = (struct hisi_sgl *)tmp->next;
i = 0;
}
}
Expand Down Expand Up @@ -981,7 +994,7 @@ static void hisi_qm_pbuff_copy_inner(void *pbuff, struct hisi_sgl *hw_sgl,
offset += tmp->sge_entries[i].len;
}

tmp = (struct hisi_sgl *)tmp->next_dma;
tmp = (struct hisi_sgl *)tmp->next;
i = 0;
}
}
Expand All @@ -1000,7 +1013,7 @@ void hisi_qm_sgl_copy(void *pbuff, void *hw_sgl, __u32 offset, __u32 size,
while (len + tmp->entry_size_in_sgl <= offset) {
len += tmp->entry_size_in_sgl;

tmp = (struct hisi_sgl *)tmp->next_dma;
tmp = (struct hisi_sgl *)tmp->next;
if (!tmp)
return;
}
Expand Down
3 changes: 2 additions & 1 deletion drv/hisi_qm_udrv.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ void hisi_qm_destroy_sglpool(handle_t sgl_pool);
*
* Return the hw sgl addr which can fill into the sqe.
*/
void *hisi_qm_get_hw_sgl(handle_t sgl_pool, struct wd_datalist *sgl);
void *hisi_qm_get_hw_sgl(handle_t sgl_pool, struct wd_datalist *sgl,
void *blkpool);

/**
* hisi_qm_put_hw_sgl - Reback the hw sgl to the sgl pool.
Expand Down
Loading