@@ -911,45 +911,28 @@ struct talitos_edesc {
911
911
static void talitos_sg_unmap (struct device * dev ,
912
912
struct talitos_edesc * edesc ,
913
913
struct scatterlist * src ,
914
- struct scatterlist * dst )
914
+ struct scatterlist * dst ,
915
+ unsigned int len , unsigned int offset )
915
916
{
917
+ struct talitos_private * priv = dev_get_drvdata (dev );
918
+ bool is_sec1 = has_ftr_sec1 (priv );
916
919
unsigned int src_nents = edesc -> src_nents ? : 1 ;
917
920
unsigned int dst_nents = edesc -> dst_nents ? : 1 ;
918
921
922
+ if (is_sec1 && dst && dst_nents > 1 ) {
923
+ dma_sync_single_for_device (dev , edesc -> dma_link_tbl + offset ,
924
+ len , DMA_FROM_DEVICE );
925
+ sg_pcopy_from_buffer (dst , dst_nents , edesc -> buf + offset , len ,
926
+ offset );
927
+ }
919
928
if (src != dst ) {
920
- dma_unmap_sg (dev , src , src_nents , DMA_TO_DEVICE );
929
+ if (src_nents == 1 || !is_sec1 )
930
+ dma_unmap_sg (dev , src , src_nents , DMA_TO_DEVICE );
921
931
922
- if (dst ) {
932
+ if (dst && ( dst_nents == 1 || ! is_sec1 ))
923
933
dma_unmap_sg (dev , dst , dst_nents , DMA_FROM_DEVICE );
924
- }
925
- } else
934
+ } else if (src_nents == 1 || !is_sec1 ) {
926
935
dma_unmap_sg (dev , src , src_nents , DMA_BIDIRECTIONAL );
927
- }
928
-
929
- static void unmap_sg_talitos_ptr (struct device * dev , struct scatterlist * src ,
930
- struct scatterlist * dst , unsigned int len ,
931
- struct talitos_edesc * edesc )
932
- {
933
- struct talitos_private * priv = dev_get_drvdata (dev );
934
- bool is_sec1 = has_ftr_sec1 (priv );
935
-
936
- if (is_sec1 ) {
937
- if (!edesc -> src_nents ) {
938
- dma_unmap_sg (dev , src , 1 ,
939
- dst != src ? DMA_TO_DEVICE
940
- : DMA_BIDIRECTIONAL );
941
- }
942
- if (dst && edesc -> dst_nents ) {
943
- dma_sync_single_for_device (dev ,
944
- edesc -> dma_link_tbl + len ,
945
- len , DMA_FROM_DEVICE );
946
- sg_copy_from_buffer (dst , edesc -> dst_nents ? : 1 ,
947
- edesc -> buf + len , len );
948
- } else if (dst && dst != src ) {
949
- dma_unmap_sg (dev , dst , 1 , DMA_FROM_DEVICE );
950
- }
951
- } else {
952
- talitos_sg_unmap (dev , edesc , src , dst );
953
936
}
954
937
}
955
938
@@ -962,7 +945,8 @@ static void ipsec_esp_unmap(struct device *dev,
962
945
unmap_single_talitos_ptr (dev , & edesc -> desc .ptr [2 ], DMA_TO_DEVICE );
963
946
unmap_single_talitos_ptr (dev , & edesc -> desc .ptr [0 ], DMA_TO_DEVICE );
964
947
965
- talitos_sg_unmap (dev , edesc , areq -> src , areq -> dst );
948
+ talitos_sg_unmap (dev , edesc , areq -> src , areq -> dst , areq -> cryptlen ,
949
+ areq -> assoclen );
966
950
967
951
if (edesc -> dma_len )
968
952
dma_unmap_single (dev , edesc -> dma_link_tbl , edesc -> dma_len ,
@@ -1110,99 +1094,37 @@ static inline int sg_to_link_tbl(struct scatterlist *sg, int sg_count,
1110
1094
link_tbl_ptr );
1111
1095
}
1112
1096
1113
- int map_sg_in_talitos_ptr (struct device * dev , struct scatterlist * src ,
1114
- unsigned int len , struct talitos_edesc * edesc ,
1115
- enum dma_data_direction dir , struct talitos_ptr * ptr )
1097
+ int talitos_sg_map (struct device * dev , struct scatterlist * src ,
1098
+ unsigned int len , struct talitos_edesc * edesc ,
1099
+ struct talitos_ptr * ptr ,
1100
+ int sg_count , unsigned int offset , int tbl_off )
1116
1101
{
1117
- int sg_count ;
1118
1102
struct talitos_private * priv = dev_get_drvdata (dev );
1119
1103
bool is_sec1 = has_ftr_sec1 (priv );
1120
1104
1121
1105
to_talitos_ptr_len (ptr , len , is_sec1 );
1106
+ to_talitos_ptr_ext_set (ptr , 0 , is_sec1 );
1122
1107
1123
- if (is_sec1 ) {
1124
- sg_count = edesc -> src_nents ? : 1 ;
1125
-
1126
- if (sg_count == 1 ) {
1127
- dma_map_sg (dev , src , 1 , dir );
1128
- to_talitos_ptr (ptr , sg_dma_address (src ), is_sec1 );
1129
- } else {
1130
- sg_copy_to_buffer (src , sg_count , edesc -> buf , len );
1131
- to_talitos_ptr (ptr , edesc -> dma_link_tbl , is_sec1 );
1132
- dma_sync_single_for_device (dev , edesc -> dma_link_tbl ,
1133
- len , DMA_TO_DEVICE );
1134
- }
1135
- } else {
1136
- to_talitos_ptr_ext_set (ptr , 0 , is_sec1 );
1137
-
1138
- sg_count = dma_map_sg (dev , src , edesc -> src_nents ? : 1 , dir );
1139
-
1140
- if (sg_count == 1 ) {
1141
- to_talitos_ptr (ptr , sg_dma_address (src ), is_sec1 );
1142
- } else {
1143
- sg_count = sg_to_link_tbl (src , sg_count , len ,
1144
- & edesc -> link_tbl [0 ]);
1145
- if (sg_count > 1 ) {
1146
- to_talitos_ptr (ptr , edesc -> dma_link_tbl , 0 );
1147
- to_talitos_ptr_ext_or (ptr , DESC_PTR_LNKTBL_JUMP ,
1148
- 0 );
1149
- dma_sync_single_for_device (dev ,
1150
- edesc -> dma_link_tbl ,
1151
- edesc -> dma_len ,
1152
- DMA_BIDIRECTIONAL );
1153
- } else {
1154
- /* Only one segment now, so no link tbl needed*/
1155
- to_talitos_ptr (ptr , sg_dma_address (src ),
1156
- is_sec1 );
1157
- }
1158
- }
1108
+ if (sg_count == 1 ) {
1109
+ to_talitos_ptr (ptr , sg_dma_address (src ) + offset , is_sec1 );
1110
+ return sg_count ;
1159
1111
}
1160
- return sg_count ;
1161
- }
1162
-
1163
- void map_sg_out_talitos_ptr (struct device * dev , struct scatterlist * dst ,
1164
- unsigned int len , struct talitos_edesc * edesc ,
1165
- enum dma_data_direction dir ,
1166
- struct talitos_ptr * ptr , int sg_count )
1167
- {
1168
- struct talitos_private * priv = dev_get_drvdata (dev );
1169
- bool is_sec1 = has_ftr_sec1 (priv );
1170
-
1171
- if (dir != DMA_NONE )
1172
- sg_count = dma_map_sg (dev , dst , edesc -> dst_nents ? : 1 , dir );
1173
-
1174
- to_talitos_ptr_len (ptr , len , is_sec1 );
1175
-
1176
1112
if (is_sec1 ) {
1177
- if (sg_count == 1 ) {
1178
- if (dir != DMA_NONE )
1179
- dma_map_sg (dev , dst , 1 , dir );
1180
- to_talitos_ptr (ptr , sg_dma_address (dst ), is_sec1 );
1181
- } else {
1182
- to_talitos_ptr (ptr , edesc -> dma_link_tbl + len , is_sec1 );
1183
- dma_sync_single_for_device (dev ,
1184
- edesc -> dma_link_tbl + len ,
1185
- len , DMA_FROM_DEVICE );
1186
- }
1187
- } else {
1188
- to_talitos_ptr_ext_set (ptr , 0 , is_sec1 );
1189
-
1190
- if (sg_count == 1 ) {
1191
- to_talitos_ptr (ptr , sg_dma_address (dst ), is_sec1 );
1192
- } else {
1193
- struct talitos_ptr * link_tbl_ptr =
1194
- & edesc -> link_tbl [edesc -> src_nents + 1 ];
1195
-
1196
- to_talitos_ptr (ptr , edesc -> dma_link_tbl +
1197
- (edesc -> src_nents + 1 ) *
1198
- sizeof (struct talitos_ptr ), 0 );
1199
- to_talitos_ptr_ext_or (ptr , DESC_PTR_LNKTBL_JUMP , 0 );
1200
- sg_to_link_tbl (dst , sg_count , len , link_tbl_ptr );
1201
- dma_sync_single_for_device (dev , edesc -> dma_link_tbl ,
1202
- edesc -> dma_len ,
1203
- DMA_BIDIRECTIONAL );
1204
- }
1113
+ to_talitos_ptr (ptr , edesc -> dma_link_tbl + offset , is_sec1 );
1114
+ return sg_count ;
1205
1115
}
1116
+ sg_count = sg_to_link_tbl_offset (src , sg_count , offset , len ,
1117
+ & edesc -> link_tbl [tbl_off ]);
1118
+ if (sg_count == 1 ) {
1119
+ /* Only one segment now, so no link tbl needed*/
1120
+ copy_talitos_ptr (ptr , & edesc -> link_tbl [tbl_off ], is_sec1 );
1121
+ return sg_count ;
1122
+ }
1123
+ to_talitos_ptr (ptr , edesc -> dma_link_tbl +
1124
+ tbl_off * sizeof (struct talitos_ptr ), is_sec1 );
1125
+ to_talitos_ptr_ext_or (ptr , DESC_PTR_LNKTBL_JUMP , is_sec1 );
1126
+
1127
+ return sg_count ;
1206
1128
}
1207
1129
1208
1130
/*
@@ -1363,7 +1285,7 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1363
1285
bool encrypt )
1364
1286
{
1365
1287
struct talitos_edesc * edesc ;
1366
- int src_nents , dst_nents , alloc_len , dma_len ;
1288
+ int src_nents , dst_nents , alloc_len , dma_len , src_len , dst_len ;
1367
1289
dma_addr_t iv_dma = 0 ;
1368
1290
gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
1369
1291
GFP_ATOMIC ;
@@ -1381,26 +1303,27 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1381
1303
iv_dma = dma_map_single (dev , iv , ivsize , DMA_TO_DEVICE );
1382
1304
1383
1305
if (!dst || dst == src ) {
1384
- src_nents = sg_nents_for_len ( src ,
1385
- assoclen + cryptlen + authsize );
1306
+ src_len = assoclen + cryptlen + authsize ;
1307
+ src_nents = sg_nents_for_len ( src , src_len );
1386
1308
if (src_nents < 0 ) {
1387
1309
dev_err (dev , "Invalid number of src SG.\n" );
1388
1310
err = ERR_PTR (- EINVAL );
1389
1311
goto error_sg ;
1390
1312
}
1391
1313
src_nents = (src_nents == 1 ) ? 0 : src_nents ;
1392
1314
dst_nents = dst ? src_nents : 0 ;
1315
+ dst_len = 0 ;
1393
1316
} else { /* dst && dst != src*/
1394
- src_nents = sg_nents_for_len ( src , assoclen + cryptlen +
1395
- ( encrypt ? 0 : authsize ) );
1317
+ src_len = assoclen + cryptlen + ( encrypt ? 0 : authsize );
1318
+ src_nents = sg_nents_for_len ( src , src_len );
1396
1319
if (src_nents < 0 ) {
1397
1320
dev_err (dev , "Invalid number of src SG.\n" );
1398
1321
err = ERR_PTR (- EINVAL );
1399
1322
goto error_sg ;
1400
1323
}
1401
1324
src_nents = (src_nents == 1 ) ? 0 : src_nents ;
1402
- dst_nents = sg_nents_for_len ( dst , assoclen + cryptlen +
1403
- ( encrypt ? authsize : 0 ) );
1325
+ dst_len = assoclen + cryptlen + ( encrypt ? authsize : 0 );
1326
+ dst_nents = sg_nents_for_len ( dst , dst_len );
1404
1327
if (dst_nents < 0 ) {
1405
1328
dev_err (dev , "Invalid number of dst SG.\n" );
1406
1329
err = ERR_PTR (- EINVAL );
@@ -1417,8 +1340,8 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1417
1340
alloc_len = sizeof (struct talitos_edesc );
1418
1341
if (src_nents || dst_nents ) {
1419
1342
if (is_sec1 )
1420
- dma_len = (src_nents ? cryptlen : 0 ) +
1421
- (dst_nents ? cryptlen : 0 );
1343
+ dma_len = (src_nents ? src_len : 0 ) +
1344
+ (dst_nents ? dst_len : 0 );
1422
1345
else
1423
1346
dma_len = (src_nents + dst_nents + 2 ) *
1424
1347
sizeof (struct talitos_ptr ) + authsize * 2 ;
@@ -1548,7 +1471,7 @@ static void common_nonsnoop_unmap(struct device *dev,
1548
1471
{
1549
1472
unmap_single_talitos_ptr (dev , & edesc -> desc .ptr [5 ], DMA_FROM_DEVICE );
1550
1473
1551
- unmap_sg_talitos_ptr (dev , areq -> src , areq -> dst , areq -> nbytes , edesc );
1474
+ talitos_sg_unmap (dev , edesc , areq -> src , areq -> dst , areq -> nbytes , 0 );
1552
1475
unmap_single_talitos_ptr (dev , & edesc -> desc .ptr [2 ], DMA_TO_DEVICE );
1553
1476
unmap_single_talitos_ptr (dev , & edesc -> desc .ptr [1 ], DMA_TO_DEVICE );
1554
1477
@@ -1586,6 +1509,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
1586
1509
unsigned int cryptlen = areq -> nbytes ;
1587
1510
unsigned int ivsize = crypto_ablkcipher_ivsize (cipher );
1588
1511
int sg_count , ret ;
1512
+ bool sync_needed = false;
1589
1513
struct talitos_private * priv = dev_get_drvdata (dev );
1590
1514
bool is_sec1 = has_ftr_sec1 (priv );
1591
1515
@@ -1601,19 +1525,33 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
1601
1525
map_single_talitos_ptr (dev , & desc -> ptr [2 ], ctx -> keylen ,
1602
1526
(char * )& ctx -> key , DMA_TO_DEVICE );
1603
1527
1528
+ sg_count = edesc -> src_nents ?: 1 ;
1529
+ if (is_sec1 && sg_count > 1 )
1530
+ sg_copy_to_buffer (areq -> src , sg_count , edesc -> buf ,
1531
+ cryptlen );
1532
+ else
1533
+ sg_count = dma_map_sg (dev , areq -> src , sg_count ,
1534
+ (areq -> src == areq -> dst ) ?
1535
+ DMA_BIDIRECTIONAL : DMA_TO_DEVICE );
1604
1536
/*
1605
1537
* cipher in
1606
1538
*/
1607
- sg_count = map_sg_in_talitos_ptr (dev , areq -> src , cryptlen , edesc ,
1608
- ( areq -> src == areq -> dst ) ?
1609
- DMA_BIDIRECTIONAL : DMA_TO_DEVICE ,
1610
- & desc -> ptr [ 3 ]) ;
1539
+ sg_count = talitos_sg_map (dev , areq -> src , cryptlen , edesc ,
1540
+ & desc -> ptr [ 3 ], sg_count , 0 , 0 );
1541
+ if ( sg_count > 1 )
1542
+ sync_needed = true ;
1611
1543
1612
1544
/* cipher out */
1613
- map_sg_out_talitos_ptr (dev , areq -> dst , cryptlen , edesc ,
1614
- (areq -> src == areq -> dst ) ? DMA_NONE
1615
- : DMA_FROM_DEVICE ,
1616
- & desc -> ptr [4 ], sg_count );
1545
+ if (areq -> src != areq -> dst ) {
1546
+ sg_count = edesc -> dst_nents ? : 1 ;
1547
+ if (!is_sec1 || sg_count == 1 )
1548
+ dma_map_sg (dev , areq -> dst , sg_count , DMA_FROM_DEVICE );
1549
+ }
1550
+
1551
+ ret = talitos_sg_map (dev , areq -> dst , cryptlen , edesc , & desc -> ptr [4 ],
1552
+ sg_count , 0 , (edesc -> src_nents + 1 ));
1553
+ if (ret > 1 )
1554
+ sync_needed = true;
1617
1555
1618
1556
/* iv out */
1619
1557
map_single_talitos_ptr (dev , & desc -> ptr [5 ], ivsize , ctx -> iv ,
@@ -1622,6 +1560,10 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
1622
1560
/* last DWORD empty */
1623
1561
desc -> ptr [6 ] = zero_entry ;
1624
1562
1563
+ if (sync_needed )
1564
+ dma_sync_single_for_device (dev , edesc -> dma_link_tbl ,
1565
+ edesc -> dma_len , DMA_BIDIRECTIONAL );
1566
+
1625
1567
ret = talitos_submit (dev , ctx -> ch , desc , callback , areq );
1626
1568
if (ret != - EINPROGRESS ) {
1627
1569
common_nonsnoop_unmap (dev , edesc , areq );
@@ -1685,7 +1627,7 @@ static void common_nonsnoop_hash_unmap(struct device *dev,
1685
1627
1686
1628
unmap_single_talitos_ptr (dev , & edesc -> desc .ptr [5 ], DMA_FROM_DEVICE );
1687
1629
1688
- unmap_sg_talitos_ptr (dev , req_ctx -> psrc , NULL , 0 , edesc );
1630
+ talitos_sg_unmap (dev , edesc , req_ctx -> psrc , NULL , 0 , 0 );
1689
1631
1690
1632
/* When using hashctx-in, must unmap it. */
1691
1633
if (from_talitos_ptr_len (& edesc -> desc .ptr [1 ], is_sec1 ))
@@ -1756,8 +1698,10 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
1756
1698
struct device * dev = ctx -> dev ;
1757
1699
struct talitos_desc * desc = & edesc -> desc ;
1758
1700
int ret ;
1701
+ bool sync_needed = false;
1759
1702
struct talitos_private * priv = dev_get_drvdata (dev );
1760
1703
bool is_sec1 = has_ftr_sec1 (priv );
1704
+ int sg_count ;
1761
1705
1762
1706
/* first DWORD empty */
1763
1707
desc -> ptr [0 ] = zero_entry ;
@@ -1782,11 +1726,19 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
1782
1726
else
1783
1727
desc -> ptr [2 ] = zero_entry ;
1784
1728
1729
+ sg_count = edesc -> src_nents ?: 1 ;
1730
+ if (is_sec1 && sg_count > 1 )
1731
+ sg_copy_to_buffer (areq -> src , sg_count , edesc -> buf , length );
1732
+ else
1733
+ sg_count = dma_map_sg (dev , req_ctx -> psrc , sg_count ,
1734
+ DMA_TO_DEVICE );
1785
1735
/*
1786
1736
* data in
1787
1737
*/
1788
- map_sg_in_talitos_ptr (dev , req_ctx -> psrc , length , edesc ,
1789
- DMA_TO_DEVICE , & desc -> ptr [3 ]);
1738
+ sg_count = talitos_sg_map (dev , req_ctx -> psrc , length , edesc ,
1739
+ & desc -> ptr [3 ], sg_count , 0 , 0 );
1740
+ if (sg_count > 1 )
1741
+ sync_needed = true;
1790
1742
1791
1743
/* fifth DWORD empty */
1792
1744
desc -> ptr [4 ] = zero_entry ;
@@ -1807,6 +1759,10 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
1807
1759
if (is_sec1 && from_talitos_ptr_len (& desc -> ptr [3 ], true) == 0 )
1808
1760
talitos_handle_buggy_hash (ctx , edesc , & desc -> ptr [3 ]);
1809
1761
1762
+ if (sync_needed )
1763
+ dma_sync_single_for_device (dev , edesc -> dma_link_tbl ,
1764
+ edesc -> dma_len , DMA_BIDIRECTIONAL );
1765
+
1810
1766
ret = talitos_submit (dev , ctx -> ch , desc , callback , areq );
1811
1767
if (ret != - EINPROGRESS ) {
1812
1768
common_nonsnoop_hash_unmap (dev , edesc , areq );
0 commit comments