diff options
Diffstat (limited to 'drivers/crypto/talitos.c')
-rw-r--r-- | drivers/crypto/talitos.c | 95 |
1 files changed, 48 insertions, 47 deletions
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index a0b0a6319088..a073e6b6a3c8 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c | |||
@@ -341,7 +341,8 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch) | |||
341 | status = error; | 341 | status = error; |
342 | 342 | ||
343 | dma_unmap_single(dev, request->dma_desc, | 343 | dma_unmap_single(dev, request->dma_desc, |
344 | sizeof(struct talitos_desc), DMA_BIDIRECTIONAL); | 344 | sizeof(struct talitos_desc), |
345 | DMA_BIDIRECTIONAL); | ||
345 | 346 | ||
346 | /* copy entries so we can call callback outside lock */ | 347 | /* copy entries so we can call callback outside lock */ |
347 | saved_req.desc = request->desc; | 348 | saved_req.desc = request->desc; |
@@ -415,7 +416,8 @@ static struct talitos_desc *current_desc(struct device *dev, int ch) | |||
415 | /* | 416 | /* |
416 | * user diagnostics; report root cause of error based on execution unit status | 417 | * user diagnostics; report root cause of error based on execution unit status |
417 | */ | 418 | */ |
418 | static void report_eu_error(struct device *dev, int ch, struct talitos_desc *desc) | 419 | static void report_eu_error(struct device *dev, int ch, |
420 | struct talitos_desc *desc) | ||
419 | { | 421 | { |
420 | struct talitos_private *priv = dev_get_drvdata(dev); | 422 | struct talitos_private *priv = dev_get_drvdata(dev); |
421 | int i; | 423 | int i; |
@@ -863,8 +865,8 @@ static void ipsec_esp_encrypt_done(struct device *dev, | |||
863 | } | 865 | } |
864 | 866 | ||
865 | static void ipsec_esp_decrypt_swauth_done(struct device *dev, | 867 | static void ipsec_esp_decrypt_swauth_done(struct device *dev, |
866 | struct talitos_desc *desc, void *context, | 868 | struct talitos_desc *desc, |
867 | int err) | 869 | void *context, int err) |
868 | { | 870 | { |
869 | struct aead_request *req = context; | 871 | struct aead_request *req = context; |
870 | struct talitos_edesc *edesc = | 872 | struct talitos_edesc *edesc = |
@@ -895,8 +897,8 @@ static void ipsec_esp_decrypt_swauth_done(struct device *dev, | |||
895 | } | 897 | } |
896 | 898 | ||
897 | static void ipsec_esp_decrypt_hwauth_done(struct device *dev, | 899 | static void ipsec_esp_decrypt_hwauth_done(struct device *dev, |
898 | struct talitos_desc *desc, void *context, | 900 | struct talitos_desc *desc, |
899 | int err) | 901 | void *context, int err) |
900 | { | 902 | { |
901 | struct aead_request *req = context; | 903 | struct aead_request *req = context; |
902 | struct talitos_edesc *edesc = | 904 | struct talitos_edesc *edesc = |
@@ -905,10 +907,9 @@ static void ipsec_esp_decrypt_hwauth_done(struct device *dev, | |||
905 | ipsec_esp_unmap(dev, edesc, req); | 907 | ipsec_esp_unmap(dev, edesc, req); |
906 | 908 | ||
907 | /* check ICV auth status */ | 909 | /* check ICV auth status */ |
908 | if (!err) | 910 | if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) != |
909 | if ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) != | 911 | DESC_HDR_LO_ICCR1_PASS)) |
910 | DESC_HDR_LO_ICCR1_PASS) | 912 | err = -EBADMSG; |
911 | err = -EBADMSG; | ||
912 | 913 | ||
913 | kfree(edesc); | 914 | kfree(edesc); |
914 | 915 | ||
@@ -996,10 +997,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, | |||
996 | desc->ptr[4].len = cpu_to_be16(cryptlen); | 997 | desc->ptr[4].len = cpu_to_be16(cryptlen); |
997 | desc->ptr[4].j_extent = authsize; | 998 | desc->ptr[4].j_extent = authsize; |
998 | 999 | ||
999 | sg_count = talitos_map_sg(dev, areq->src, | 1000 | sg_count = talitos_map_sg(dev, areq->src, edesc->src_nents ? : 1, |
1000 | edesc->src_nents ? : 1, | 1001 | (areq->src == areq->dst) ? DMA_BIDIRECTIONAL |
1001 | (areq->src == areq->dst) ? DMA_BIDIRECTIONAL : | 1002 | : DMA_TO_DEVICE, |
1002 | DMA_TO_DEVICE, | ||
1003 | edesc->src_is_chained); | 1003 | edesc->src_is_chained); |
1004 | 1004 | ||
1005 | if (sg_count == 1) { | 1005 | if (sg_count == 1) { |
@@ -1008,19 +1008,21 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, | |||
1008 | sg_link_tbl_len = cryptlen; | 1008 | sg_link_tbl_len = cryptlen; |
1009 | 1009 | ||
1010 | if ((edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV) && | 1010 | if ((edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV) && |
1011 | (edesc->desc.hdr & DESC_HDR_MODE0_ENCRYPT) == 0) { | 1011 | (edesc->desc.hdr & DESC_HDR_MODE0_ENCRYPT) == 0) |
1012 | sg_link_tbl_len = cryptlen + authsize; | 1012 | sg_link_tbl_len = cryptlen + authsize; |
1013 | } | 1013 | |
1014 | sg_count = sg_to_link_tbl(areq->src, sg_count, sg_link_tbl_len, | 1014 | sg_count = sg_to_link_tbl(areq->src, sg_count, sg_link_tbl_len, |
1015 | &edesc->link_tbl[0]); | 1015 | &edesc->link_tbl[0]); |
1016 | if (sg_count > 1) { | 1016 | if (sg_count > 1) { |
1017 | desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP; | 1017 | desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP; |
1018 | desc->ptr[4].ptr = cpu_to_be32(edesc->dma_link_tbl); | 1018 | desc->ptr[4].ptr = cpu_to_be32(edesc->dma_link_tbl); |
1019 | dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl, | 1019 | dma_sync_single_for_device(dev, edesc->dma_link_tbl, |
1020 | edesc->dma_len, DMA_BIDIRECTIONAL); | 1020 | edesc->dma_len, |
1021 | DMA_BIDIRECTIONAL); | ||
1021 | } else { | 1022 | } else { |
1022 | /* Only one segment now, so no link tbl needed */ | 1023 | /* Only one segment now, so no link tbl needed */ |
1023 | desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src)); | 1024 | desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq-> |
1025 | src)); | ||
1024 | } | 1026 | } |
1025 | } | 1027 | } |
1026 | 1028 | ||
@@ -1028,12 +1030,11 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, | |||
1028 | desc->ptr[5].len = cpu_to_be16(cryptlen); | 1030 | desc->ptr[5].len = cpu_to_be16(cryptlen); |
1029 | desc->ptr[5].j_extent = authsize; | 1031 | desc->ptr[5].j_extent = authsize; |
1030 | 1032 | ||
1031 | if (areq->src != areq->dst) { | 1033 | if (areq->src != areq->dst) |
1032 | sg_count = talitos_map_sg(dev, areq->dst, | 1034 | sg_count = talitos_map_sg(dev, areq->dst, |
1033 | edesc->dst_nents ? : 1, | 1035 | edesc->dst_nents ? : 1, |
1034 | DMA_FROM_DEVICE, | 1036 | DMA_FROM_DEVICE, |
1035 | edesc->dst_is_chained); | 1037 | edesc->dst_is_chained); |
1036 | } | ||
1037 | 1038 | ||
1038 | if (sg_count == 1) { | 1039 | if (sg_count == 1) { |
1039 | desc->ptr[5].ptr = cpu_to_be32(sg_dma_address(areq->dst)); | 1040 | desc->ptr[5].ptr = cpu_to_be32(sg_dma_address(areq->dst)); |
@@ -1078,7 +1079,6 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, | |||
1078 | return ret; | 1079 | return ret; |
1079 | } | 1080 | } |
1080 | 1081 | ||
1081 | |||
1082 | /* | 1082 | /* |
1083 | * derive number of elements in scatterlist | 1083 | * derive number of elements in scatterlist |
1084 | */ | 1084 | */ |
@@ -1191,8 +1191,6 @@ static int aead_encrypt(struct aead_request *req) | |||
1191 | return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_encrypt_done); | 1191 | return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_encrypt_done); |
1192 | } | 1192 | } |
1193 | 1193 | ||
1194 | |||
1195 | |||
1196 | static int aead_decrypt(struct aead_request *req) | 1194 | static int aead_decrypt(struct aead_request *req) |
1197 | { | 1195 | { |
1198 | struct crypto_aead *authenc = crypto_aead_reqtfm(req); | 1196 | struct crypto_aead *authenc = crypto_aead_reqtfm(req); |
@@ -1211,38 +1209,38 @@ static int aead_decrypt(struct aead_request *req) | |||
1211 | return PTR_ERR(edesc); | 1209 | return PTR_ERR(edesc); |
1212 | 1210 | ||
1213 | if ((priv->features & TALITOS_FTR_HW_AUTH_CHECK) && | 1211 | if ((priv->features & TALITOS_FTR_HW_AUTH_CHECK) && |
1214 | (((!edesc->src_nents && !edesc->dst_nents) || | 1212 | ((!edesc->src_nents && !edesc->dst_nents) || |
1215 | priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT))) { | 1213 | priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) { |
1216 | 1214 | ||
1217 | /* decrypt and check the ICV */ | 1215 | /* decrypt and check the ICV */ |
1218 | edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND | | 1216 | edesc->desc.hdr = ctx->desc_hdr_template | |
1217 | DESC_HDR_DIR_INBOUND | | ||
1219 | DESC_HDR_MODE1_MDEU_CICV; | 1218 | DESC_HDR_MODE1_MDEU_CICV; |
1220 | 1219 | ||
1221 | /* reset integrity check result bits */ | 1220 | /* reset integrity check result bits */ |
1222 | edesc->desc.hdr_lo = 0; | 1221 | edesc->desc.hdr_lo = 0; |
1223 | 1222 | ||
1224 | return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_decrypt_hwauth_done); | 1223 | return ipsec_esp(edesc, req, NULL, 0, |
1224 | ipsec_esp_decrypt_hwauth_done); | ||
1225 | 1225 | ||
1226 | } else { | 1226 | } |
1227 | |||
1228 | /* Have to check the ICV with software */ | ||
1229 | 1227 | ||
1230 | edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND; | 1228 | /* Have to check the ICV with software */ |
1229 | edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND; | ||
1231 | 1230 | ||
1232 | /* stash incoming ICV for later cmp with ICV generated by the h/w */ | 1231 | /* stash incoming ICV for later cmp with ICV generated by the h/w */ |
1233 | if (edesc->dma_len) | 1232 | if (edesc->dma_len) |
1234 | icvdata = &edesc->link_tbl[edesc->src_nents + | 1233 | icvdata = &edesc->link_tbl[edesc->src_nents + |
1235 | edesc->dst_nents + 2]; | 1234 | edesc->dst_nents + 2]; |
1236 | else | 1235 | else |
1237 | icvdata = &edesc->link_tbl[0]; | 1236 | icvdata = &edesc->link_tbl[0]; |
1238 | 1237 | ||
1239 | sg = sg_last(req->src, edesc->src_nents ? : 1); | 1238 | sg = sg_last(req->src, edesc->src_nents ? : 1); |
1240 | 1239 | ||
1241 | memcpy(icvdata, (char *)sg_virt(sg) + sg->length - ctx->authsize, | 1240 | memcpy(icvdata, (char *)sg_virt(sg) + sg->length - ctx->authsize, |
1242 | ctx->authsize); | 1241 | ctx->authsize); |
1243 | 1242 | ||
1244 | return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_decrypt_swauth_done); | 1243 | return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_decrypt_swauth_done); |
1245 | } | ||
1246 | } | 1244 | } |
1247 | 1245 | ||
1248 | static int aead_givencrypt(struct aead_givcrypt_request *req) | 1246 | static int aead_givencrypt(struct aead_givcrypt_request *req) |
@@ -1368,11 +1366,13 @@ static int common_nonsnoop(struct talitos_edesc *edesc, | |||
1368 | if (sg_count > 1) { | 1366 | if (sg_count > 1) { |
1369 | desc->ptr[3].j_extent |= DESC_PTR_LNKTBL_JUMP; | 1367 | desc->ptr[3].j_extent |= DESC_PTR_LNKTBL_JUMP; |
1370 | desc->ptr[3].ptr = cpu_to_be32(edesc->dma_link_tbl); | 1368 | desc->ptr[3].ptr = cpu_to_be32(edesc->dma_link_tbl); |
1371 | dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl, | 1369 | dma_sync_single_for_device(dev, edesc->dma_link_tbl, |
1372 | edesc->dma_len, DMA_BIDIRECTIONAL); | 1370 | edesc->dma_len, |
1371 | DMA_BIDIRECTIONAL); | ||
1373 | } else { | 1372 | } else { |
1374 | /* Only one segment now, so no link tbl needed */ | 1373 | /* Only one segment now, so no link tbl needed */ |
1375 | desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq->src)); | 1374 | desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq-> |
1375 | src)); | ||
1376 | } | 1376 | } |
1377 | } | 1377 | } |
1378 | 1378 | ||
@@ -1419,7 +1419,8 @@ static int common_nonsnoop(struct talitos_edesc *edesc, | |||
1419 | return ret; | 1419 | return ret; |
1420 | } | 1420 | } |
1421 | 1421 | ||
1422 | static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *areq) | 1422 | static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request * |
1423 | areq) | ||
1423 | { | 1424 | { |
1424 | struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq); | 1425 | struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq); |
1425 | struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher); | 1426 | struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher); |