@@ -940,7 +940,13 @@ static void ipsec_esp_unmap(struct device *dev,
940
940
struct talitos_edesc * edesc ,
941
941
struct aead_request * areq )
942
942
{
943
- unmap_single_talitos_ptr (dev , & edesc -> desc .ptr [6 ], DMA_FROM_DEVICE );
943
+ struct crypto_aead * aead = crypto_aead_reqtfm (areq );
944
+ struct talitos_ctx * ctx = crypto_aead_ctx (aead );
945
+ unsigned int ivsize = crypto_aead_ivsize (aead );
946
+
947
+ if (edesc -> desc .hdr & DESC_HDR_TYPE_IPSEC_ESP )
948
+ unmap_single_talitos_ptr (dev , & edesc -> desc .ptr [6 ],
949
+ DMA_FROM_DEVICE );
944
950
unmap_single_talitos_ptr (dev , & edesc -> desc .ptr [3 ], DMA_TO_DEVICE );
945
951
unmap_single_talitos_ptr (dev , & edesc -> desc .ptr [2 ], DMA_TO_DEVICE );
946
952
unmap_single_talitos_ptr (dev , & edesc -> desc .ptr [0 ], DMA_TO_DEVICE );
@@ -951,6 +957,13 @@ static void ipsec_esp_unmap(struct device *dev,
951
957
if (edesc -> dma_len )
952
958
dma_unmap_single (dev , edesc -> dma_link_tbl , edesc -> dma_len ,
953
959
DMA_BIDIRECTIONAL );
960
+
961
+ if (!(edesc -> desc .hdr & DESC_HDR_TYPE_IPSEC_ESP )) {
962
+ unsigned int dst_nents = edesc -> dst_nents ? : 1 ;
963
+
964
+ sg_pcopy_to_buffer (areq -> dst , dst_nents , ctx -> iv , ivsize ,
965
+ areq -> assoclen + areq -> cryptlen - ivsize );
966
+ }
954
967
}
955
968
956
969
/*
@@ -960,6 +973,8 @@ static void ipsec_esp_encrypt_done(struct device *dev,
960
973
struct talitos_desc * desc , void * context ,
961
974
int err )
962
975
{
976
+ struct talitos_private * priv = dev_get_drvdata (dev );
977
+ bool is_sec1 = has_ftr_sec1 (priv );
963
978
struct aead_request * areq = context ;
964
979
struct crypto_aead * authenc = crypto_aead_reqtfm (areq );
965
980
unsigned int authsize = crypto_aead_authsize (authenc );
@@ -973,8 +988,11 @@ static void ipsec_esp_encrypt_done(struct device *dev,
973
988
974
989
/* copy the generated ICV to dst */
975
990
if (edesc -> icv_ool ) {
976
- icvdata = & edesc -> link_tbl [edesc -> src_nents +
977
- edesc -> dst_nents + 2 ];
991
+ if (is_sec1 )
992
+ icvdata = edesc -> buf + areq -> assoclen + areq -> cryptlen ;
993
+ else
994
+ icvdata = & edesc -> link_tbl [edesc -> src_nents +
995
+ edesc -> dst_nents + 2 ];
978
996
sg = sg_last (areq -> dst , edesc -> dst_nents );
979
997
memcpy ((char * )sg_virt (sg ) + sg -> length - authsize ,
980
998
icvdata , authsize );
@@ -995,6 +1013,8 @@ static void ipsec_esp_decrypt_swauth_done(struct device *dev,
995
1013
struct talitos_edesc * edesc ;
996
1014
struct scatterlist * sg ;
997
1015
char * oicv , * icv ;
1016
+ struct talitos_private * priv = dev_get_drvdata (dev );
1017
+ bool is_sec1 = has_ftr_sec1 (priv );
998
1018
999
1019
edesc = container_of (desc , struct talitos_edesc , desc );
1000
1020
@@ -1006,7 +1026,12 @@ static void ipsec_esp_decrypt_swauth_done(struct device *dev,
1006
1026
icv = (char * )sg_virt (sg ) + sg -> length - authsize ;
1007
1027
1008
1028
if (edesc -> dma_len ) {
1009
- oicv = (char * )& edesc -> link_tbl [edesc -> src_nents +
1029
+ if (is_sec1 )
1030
+ oicv = (char * )& edesc -> dma_link_tbl +
1031
+ req -> assoclen + req -> cryptlen ;
1032
+ else
1033
+ oicv = (char * )
1034
+ & edesc -> link_tbl [edesc -> src_nents +
1010
1035
edesc -> dst_nents + 2 ];
1011
1036
if (edesc -> icv_ool )
1012
1037
icv = oicv + authsize ;
@@ -1145,121 +1170,135 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
1145
1170
int tbl_off = 0 ;
1146
1171
int sg_count , ret ;
1147
1172
int sg_link_tbl_len ;
1173
+ bool sync_needed = false;
1174
+ struct talitos_private * priv = dev_get_drvdata (dev );
1175
+ bool is_sec1 = has_ftr_sec1 (priv );
1148
1176
1149
1177
/* hmac key */
1150
1178
map_single_talitos_ptr (dev , & desc -> ptr [0 ], ctx -> authkeylen , & ctx -> key ,
1151
1179
DMA_TO_DEVICE );
1152
1180
1153
- sg_count = dma_map_sg (dev , areq -> src , edesc -> src_nents ?: 1 ,
1154
- (areq -> src == areq -> dst ) ? DMA_BIDIRECTIONAL
1155
- : DMA_TO_DEVICE );
1156
- /* hmac data */
1157
- to_talitos_ptr_len (& desc -> ptr [1 ], areq -> assoclen , 0 );
1158
- if (sg_count > 1 &&
1159
- (ret = sg_to_link_tbl_offset (areq -> src , sg_count , 0 ,
1160
- areq -> assoclen ,
1161
- & edesc -> link_tbl [tbl_off ])) > 1 ) {
1162
- to_talitos_ptr (& desc -> ptr [1 ], edesc -> dma_link_tbl + tbl_off *
1163
- sizeof (struct talitos_ptr ), 0 );
1164
- to_talitos_ptr_ext_set (& desc -> ptr [1 ], DESC_PTR_LNKTBL_JUMP , 0 );
1181
+ sg_count = edesc -> src_nents ?: 1 ;
1182
+ if (is_sec1 && sg_count > 1 )
1183
+ sg_copy_to_buffer (areq -> src , sg_count , edesc -> buf ,
1184
+ areq -> assoclen + cryptlen );
1185
+ else
1186
+ sg_count = dma_map_sg (dev , areq -> src , sg_count ,
1187
+ (areq -> src == areq -> dst ) ?
1188
+ DMA_BIDIRECTIONAL : DMA_TO_DEVICE );
1165
1189
1166
- dma_sync_single_for_device (dev , edesc -> dma_link_tbl ,
1167
- edesc -> dma_len , DMA_BIDIRECTIONAL );
1190
+ /* hmac data */
1191
+ ret = talitos_sg_map (dev , areq -> src , areq -> assoclen , edesc ,
1192
+ & desc -> ptr [1 ], sg_count , 0 , tbl_off );
1168
1193
1194
+ if (ret > 1 ) {
1169
1195
tbl_off += ret ;
1170
- } else {
1171
- to_talitos_ptr (& desc -> ptr [1 ], sg_dma_address (areq -> src ), 0 );
1172
- to_talitos_ptr_ext_set (& desc -> ptr [1 ], 0 , 0 );
1196
+ sync_needed = true;
1173
1197
}
1174
1198
1175
1199
/* cipher iv */
1176
- to_talitos_ptr (& desc -> ptr [2 ], edesc -> iv_dma , 0 );
1177
- to_talitos_ptr_len (& desc -> ptr [2 ], ivsize , 0 );
1178
- to_talitos_ptr_ext_set (& desc -> ptr [2 ], 0 , 0 );
1200
+ if (desc -> hdr & DESC_HDR_TYPE_IPSEC_ESP ) {
1201
+ to_talitos_ptr (& desc -> ptr [2 ], edesc -> iv_dma , is_sec1 );
1202
+ to_talitos_ptr_len (& desc -> ptr [2 ], ivsize , is_sec1 );
1203
+ to_talitos_ptr_ext_set (& desc -> ptr [2 ], 0 , is_sec1 );
1204
+ } else {
1205
+ to_talitos_ptr (& desc -> ptr [3 ], edesc -> iv_dma , is_sec1 );
1206
+ to_talitos_ptr_len (& desc -> ptr [3 ], ivsize , is_sec1 );
1207
+ to_talitos_ptr_ext_set (& desc -> ptr [3 ], 0 , is_sec1 );
1208
+ }
1179
1209
1180
1210
/* cipher key */
1181
- map_single_talitos_ptr (dev , & desc -> ptr [3 ], ctx -> enckeylen ,
1182
- (char * )& ctx -> key + ctx -> authkeylen ,
1183
- DMA_TO_DEVICE );
1211
+ if (desc -> hdr & DESC_HDR_TYPE_IPSEC_ESP )
1212
+ map_single_talitos_ptr (dev , & desc -> ptr [3 ], ctx -> enckeylen ,
1213
+ (char * )& ctx -> key + ctx -> authkeylen ,
1214
+ DMA_TO_DEVICE );
1215
+ else
1216
+ map_single_talitos_ptr (dev , & desc -> ptr [2 ], ctx -> enckeylen ,
1217
+ (char * )& ctx -> key + ctx -> authkeylen ,
1218
+ DMA_TO_DEVICE );
1184
1219
1185
1220
/*
1186
1221
* cipher in
1187
1222
* map and adjust cipher len to aead request cryptlen.
1188
1223
* extent is bytes of HMAC postpended to ciphertext,
1189
1224
* typically 12 for ipsec
1190
1225
*/
1191
- to_talitos_ptr_len (& desc -> ptr [4 ], cryptlen , 0 );
1192
- to_talitos_ptr_ext_set (& desc -> ptr [4 ], authsize , 0 );
1226
+ to_talitos_ptr_len (& desc -> ptr [4 ], cryptlen , is_sec1 );
1227
+ to_talitos_ptr_ext_set (& desc -> ptr [4 ], 0 , is_sec1 );
1193
1228
1194
1229
sg_link_tbl_len = cryptlen ;
1195
- if (edesc -> desc .hdr & DESC_HDR_MODE1_MDEU_CICV )
1196
- sg_link_tbl_len += authsize ;
1197
1230
1198
- if (sg_count == 1 ) {
1199
- to_talitos_ptr (& desc -> ptr [4 ], sg_dma_address (areq -> src ) +
1200
- areq -> assoclen , 0 );
1201
- } else if ((ret = sg_to_link_tbl_offset (areq -> src , sg_count ,
1202
- areq -> assoclen , sg_link_tbl_len ,
1203
- & edesc -> link_tbl [tbl_off ])) >
1204
- 1 ) {
1205
- to_talitos_ptr_ext_or (& desc -> ptr [4 ], DESC_PTR_LNKTBL_JUMP , 0 );
1206
- to_talitos_ptr (& desc -> ptr [4 ], edesc -> dma_link_tbl +
1207
- tbl_off *
1208
- sizeof (struct talitos_ptr ), 0 );
1209
- dma_sync_single_for_device (dev , edesc -> dma_link_tbl ,
1210
- edesc -> dma_len ,
1211
- DMA_BIDIRECTIONAL );
1212
- tbl_off += ret ;
1213
- } else {
1214
- copy_talitos_ptr (& desc -> ptr [4 ], & edesc -> link_tbl [tbl_off ], 0 );
1231
+ if (desc -> hdr & DESC_HDR_TYPE_IPSEC_ESP ) {
1232
+ to_talitos_ptr_ext_set (& desc -> ptr [4 ], authsize , is_sec1 );
1233
+
1234
+ if (edesc -> desc .hdr & DESC_HDR_MODE1_MDEU_CICV )
1235
+ sg_link_tbl_len += authsize ;
1215
1236
}
1216
1237
1217
- /* cipher out */
1218
- to_talitos_ptr_len (& desc -> ptr [5 ], cryptlen , 0 );
1219
- to_talitos_ptr_ext_set (& desc -> ptr [5 ], authsize , 0 );
1238
+ sg_count = talitos_sg_map (dev , areq -> src , cryptlen , edesc ,
1239
+ & desc -> ptr [4 ], sg_count , areq -> assoclen ,
1240
+ tbl_off );
1241
+
1242
+ if (sg_count > 1 ) {
1243
+ tbl_off += sg_count ;
1244
+ sync_needed = true;
1245
+ }
1220
1246
1221
- if (areq -> src != areq -> dst )
1222
- sg_count = dma_map_sg (dev , areq -> dst , edesc -> dst_nents ? : 1 ,
1223
- DMA_FROM_DEVICE );
1247
+ /* cipher out */
1248
+ if (areq -> src != areq -> dst ) {
1249
+ sg_count = edesc -> dst_nents ? : 1 ;
1250
+ if (!is_sec1 || sg_count == 1 )
1251
+ dma_map_sg (dev , areq -> dst , sg_count , DMA_FROM_DEVICE );
1252
+ }
1224
1253
1225
- edesc -> icv_ool = false;
1254
+ sg_count = talitos_sg_map (dev , areq -> dst , cryptlen , edesc ,
1255
+ & desc -> ptr [5 ], sg_count , areq -> assoclen ,
1256
+ tbl_off );
1226
1257
1227
- if (sg_count == 1 ) {
1228
- to_talitos_ptr (& desc -> ptr [5 ], sg_dma_address (areq -> dst ) +
1229
- areq -> assoclen , 0 );
1230
- } else if ((sg_count =
1231
- sg_to_link_tbl_offset (areq -> dst , sg_count ,
1232
- areq -> assoclen , cryptlen ,
1233
- & edesc -> link_tbl [tbl_off ])) > 1 ) {
1234
- struct talitos_ptr * tbl_ptr = & edesc -> link_tbl [tbl_off ];
1235
-
1236
- to_talitos_ptr (& desc -> ptr [5 ], edesc -> dma_link_tbl +
1237
- tbl_off * sizeof (struct talitos_ptr ), 0 );
1238
-
1239
- /* Add an entry to the link table for ICV data */
1240
- tbl_ptr += sg_count - 1 ;
1241
- to_talitos_ptr_ext_set (tbl_ptr , 0 , 0 );
1242
- tbl_ptr ++ ;
1243
- to_talitos_ptr_ext_set (tbl_ptr , DESC_PTR_LNKTBL_RETURN , 0 );
1244
- to_talitos_ptr_len (tbl_ptr , authsize , 0 );
1245
-
1246
- /* icv data follows link tables */
1247
- to_talitos_ptr (tbl_ptr , edesc -> dma_link_tbl +
1248
- (edesc -> src_nents + edesc -> dst_nents +
1249
- 2 ) * sizeof (struct talitos_ptr ) +
1250
- authsize , 0 );
1251
- to_talitos_ptr_ext_or (& desc -> ptr [5 ], DESC_PTR_LNKTBL_JUMP , 0 );
1252
- dma_sync_single_for_device (ctx -> dev , edesc -> dma_link_tbl ,
1253
- edesc -> dma_len , DMA_BIDIRECTIONAL );
1258
+ if (desc -> hdr & DESC_HDR_TYPE_IPSEC_ESP )
1259
+ to_talitos_ptr_ext_or (& desc -> ptr [5 ], authsize , is_sec1 );
1254
1260
1261
+ if (sg_count > 1 ) {
1255
1262
edesc -> icv_ool = true;
1263
+ sync_needed = true;
1264
+
1265
+ if (desc -> hdr & DESC_HDR_TYPE_IPSEC_ESP ) {
1266
+ struct talitos_ptr * tbl_ptr = & edesc -> link_tbl [tbl_off ];
1267
+ int offset = (edesc -> src_nents + edesc -> dst_nents + 2 ) *
1268
+ sizeof (struct talitos_ptr ) + authsize ;
1269
+
1270
+ /* Add an entry to the link table for ICV data */
1271
+ tbl_ptr += sg_count - 1 ;
1272
+ to_talitos_ptr_ext_set (tbl_ptr , 0 , is_sec1 );
1273
+ tbl_ptr ++ ;
1274
+ to_talitos_ptr_ext_set (tbl_ptr , DESC_PTR_LNKTBL_RETURN ,
1275
+ is_sec1 );
1276
+ to_talitos_ptr_len (tbl_ptr , authsize , is_sec1 );
1277
+
1278
+ /* icv data follows link tables */
1279
+ to_talitos_ptr (tbl_ptr , edesc -> dma_link_tbl + offset ,
1280
+ is_sec1 );
1281
+ }
1256
1282
} else {
1257
- copy_talitos_ptr (& desc -> ptr [5 ], & edesc -> link_tbl [tbl_off ], 0 );
1283
+ edesc -> icv_ool = false;
1284
+ }
1285
+
1286
+ /* ICV data */
1287
+ if (!(desc -> hdr & DESC_HDR_TYPE_IPSEC_ESP )) {
1288
+ to_talitos_ptr_len (& desc -> ptr [6 ], authsize , is_sec1 );
1289
+ to_talitos_ptr (& desc -> ptr [6 ], edesc -> dma_link_tbl +
1290
+ areq -> assoclen + cryptlen , is_sec1 );
1258
1291
}
1259
1292
1260
1293
/* iv out */
1261
- map_single_talitos_ptr (dev , & desc -> ptr [6 ], ivsize , ctx -> iv ,
1262
- DMA_FROM_DEVICE );
1294
+ if (desc -> hdr & DESC_HDR_TYPE_IPSEC_ESP )
1295
+ map_single_talitos_ptr (dev , & desc -> ptr [6 ], ivsize , ctx -> iv ,
1296
+ DMA_FROM_DEVICE );
1297
+
1298
+ if (sync_needed )
1299
+ dma_sync_single_for_device (dev , edesc -> dma_link_tbl ,
1300
+ edesc -> dma_len ,
1301
+ DMA_BIDIRECTIONAL );
1263
1302
1264
1303
ret = talitos_submit (dev , ctx -> ch , desc , callback , areq );
1265
1304
if (ret != - EINPROGRESS ) {
0 commit comments