|
@@ -1247,14 +1247,15 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
|
|
|
dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
|
|
|
}
|
|
|
|
|
|
- sg_count = talitos_sg_map(dev, areq->dst, cryptlen, edesc,
|
|
|
- &desc->ptr[5], sg_count, areq->assoclen,
|
|
|
- tbl_off);
|
|
|
+ ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[5],
|
|
|
+ sg_count, areq->assoclen, tbl_off);
|
|
|
|
|
|
if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
|
|
|
to_talitos_ptr_ext_or(&desc->ptr[5], authsize, is_sec1);
|
|
|
|
|
|
- if (sg_count > 1) {
|
|
|
+ /* ICV data */
|
|
|
+ if (ret > 1) {
|
|
|
+ tbl_off += ret;
|
|
|
edesc->icv_ool = true;
|
|
|
sync_needed = true;
|
|
|
|
|
@@ -1264,9 +1265,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
|
|
|
sizeof(struct talitos_ptr) + authsize;
|
|
|
|
|
|
/* Add an entry to the link table for ICV data */
|
|
|
- tbl_ptr += sg_count - 1;
|
|
|
- to_talitos_ptr_ext_set(tbl_ptr, 0, is_sec1);
|
|
|
- tbl_ptr++;
|
|
|
+ to_talitos_ptr_ext_set(tbl_ptr - 1, 0, is_sec1);
|
|
|
to_talitos_ptr_ext_set(tbl_ptr, DESC_PTR_LNKTBL_RETURN,
|
|
|
is_sec1);
|
|
|
to_talitos_ptr_len(tbl_ptr, authsize, is_sec1);
|
|
@@ -1274,18 +1273,33 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
|
|
|
/* icv data follows link tables */
|
|
|
to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl + offset,
|
|
|
is_sec1);
|
|
|
+ } else {
|
|
|
+ dma_addr_t addr = edesc->dma_link_tbl;
|
|
|
+
|
|
|
+ if (is_sec1)
|
|
|
+ addr += areq->assoclen + cryptlen;
|
|
|
+ else
|
|
|
+ addr += sizeof(struct talitos_ptr) * tbl_off;
|
|
|
+
|
|
|
+ to_talitos_ptr(&desc->ptr[6], addr, is_sec1);
|
|
|
+ to_talitos_ptr_len(&desc->ptr[6], authsize, is_sec1);
|
|
|
+ }
|
|
|
+ } else if (!(desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)) {
|
|
|
+ ret = talitos_sg_map(dev, areq->dst, authsize, edesc,
|
|
|
+ &desc->ptr[6], sg_count, areq->assoclen +
|
|
|
+ cryptlen,
|
|
|
+ tbl_off);
|
|
|
+ if (ret > 1) {
|
|
|
+ tbl_off += ret;
|
|
|
+ edesc->icv_ool = true;
|
|
|
+ sync_needed = true;
|
|
|
+ } else {
|
|
|
+ edesc->icv_ool = false;
|
|
|
}
|
|
|
} else {
|
|
|
edesc->icv_ool = false;
|
|
|
}
|
|
|
|
|
|
- /* ICV data */
|
|
|
- if (!(desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)) {
|
|
|
- to_talitos_ptr_len(&desc->ptr[6], authsize, is_sec1);
|
|
|
- to_talitos_ptr(&desc->ptr[6], edesc->dma_link_tbl +
|
|
|
- areq->assoclen + cryptlen, is_sec1);
|
|
|
- }
|
|
|
-
|
|
|
/* iv out */
|
|
|
if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
|
|
|
map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
|