@@ -1092,11 +1092,12 @@ static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
10921092 */
10931093static int sg_to_link_tbl_offset (struct scatterlist * sg , int sg_count ,
10941094 unsigned int offset , int datalen , int elen ,
1095- struct talitos_ptr * link_tbl_ptr )
1095+ struct talitos_ptr * link_tbl_ptr , int align )
10961096{
10971097 int n_sg = elen ? sg_count + 1 : sg_count ;
10981098 int count = 0 ;
10991099 int cryptlen = datalen + elen ;
1100+ int padding = ALIGN (cryptlen , align ) - cryptlen ;
11001101
11011102 while (cryptlen && sg && n_sg -- ) {
11021103 unsigned int len = sg_dma_len (sg );
@@ -1120,7 +1121,7 @@ static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count,
11201121 offset += datalen ;
11211122 }
11221123 to_talitos_ptr (link_tbl_ptr + count ,
1123- sg_dma_address (sg ) + offset , len , 0 );
1124+ sg_dma_address (sg ) + offset , sg_next ( sg ) ? len : len + padding , 0 );
11241125 to_talitos_ptr_ext_set (link_tbl_ptr + count , 0 , 0 );
11251126 count ++ ;
11261127 cryptlen -= len ;
@@ -1143,33 +1144,34 @@ static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
11431144 unsigned int len , struct talitos_edesc * edesc ,
11441145 struct talitos_ptr * ptr , int sg_count ,
11451146 unsigned int offset , int tbl_off , int elen ,
1146- bool force )
1147+ bool force , int align )
11471148{
11481149 struct talitos_private * priv = dev_get_drvdata (dev );
11491150 bool is_sec1 = has_ftr_sec1 (priv );
1151+ int aligned_len = ALIGN (len , align );
11501152
11511153 if (!src ) {
11521154 to_talitos_ptr (ptr , 0 , 0 , is_sec1 );
11531155 return 1 ;
11541156 }
11551157 to_talitos_ptr_ext_set (ptr , elen , is_sec1 );
11561158 if (sg_count == 1 && !force ) {
1157- to_talitos_ptr (ptr , sg_dma_address (src ) + offset , len , is_sec1 );
1159+ to_talitos_ptr (ptr , sg_dma_address (src ) + offset , aligned_len , is_sec1 );
11581160 return sg_count ;
11591161 }
11601162 if (is_sec1 ) {
1161- to_talitos_ptr (ptr , edesc -> dma_link_tbl + offset , len , is_sec1 );
1163+ to_talitos_ptr (ptr , edesc -> dma_link_tbl + offset , aligned_len , is_sec1 );
11621164 return sg_count ;
11631165 }
11641166 sg_count = sg_to_link_tbl_offset (src , sg_count , offset , len , elen ,
1165- & edesc -> link_tbl [tbl_off ]);
1167+ & edesc -> link_tbl [tbl_off ], align );
11661168 if (sg_count == 1 && !force ) {
11671169 /* Only one segment now, so no link tbl needed*/
11681170 copy_talitos_ptr (ptr , & edesc -> link_tbl [tbl_off ], is_sec1 );
11691171 return sg_count ;
11701172 }
11711173 to_talitos_ptr (ptr , edesc -> dma_link_tbl +
1172- tbl_off * sizeof (struct talitos_ptr ), len , is_sec1 );
1174+ tbl_off * sizeof (struct talitos_ptr ), aligned_len , is_sec1 );
11731175 to_talitos_ptr_ext_or (ptr , DESC_PTR_LNKTBL_JUMP , is_sec1 );
11741176
11751177 return sg_count ;
@@ -1181,7 +1183,7 @@ static int talitos_sg_map(struct device *dev, struct scatterlist *src,
11811183 unsigned int offset , int tbl_off )
11821184{
11831185 return talitos_sg_map_ext (dev , src , len , edesc , ptr , sg_count , offset ,
1184- tbl_off , 0 , false);
1186+ tbl_off , 0 , false, 1 );
11851187}
11861188
11871189/*
@@ -1250,7 +1252,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
12501252
12511253 ret = talitos_sg_map_ext (dev , areq -> src , cryptlen , edesc , & desc -> ptr [4 ],
12521254 sg_count , areq -> assoclen , tbl_off , elen ,
1253- false);
1255+ false, 1 );
12541256
12551257 if (ret > 1 ) {
12561258 tbl_off += ret ;
@@ -1270,7 +1272,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
12701272 elen = 0 ;
12711273 ret = talitos_sg_map_ext (dev , areq -> dst , cryptlen , edesc , & desc -> ptr [5 ],
12721274 sg_count , areq -> assoclen , tbl_off , elen ,
1273- is_ipsec_esp && !encrypt );
1275+ is_ipsec_esp && !encrypt , 1 );
12741276 tbl_off += ret ;
12751277
12761278 if (!encrypt && is_ipsec_esp ) {
@@ -1576,6 +1578,8 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
15761578 bool sync_needed = false;
15771579 struct talitos_private * priv = dev_get_drvdata (dev );
15781580 bool is_sec1 = has_ftr_sec1 (priv );
1581+ bool is_ctr = (desc -> hdr & DESC_HDR_SEL0_MASK ) == DESC_HDR_SEL0_AESU &&
1582+ (desc -> hdr & DESC_HDR_MODE0_AESU_MASK ) == DESC_HDR_MODE0_AESU_CTR ;
15791583
15801584 /* first DWORD empty */
15811585
@@ -1596,8 +1600,8 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
15961600 /*
15971601 * cipher in
15981602 */
1599- sg_count = talitos_sg_map (dev , areq -> src , cryptlen , edesc ,
1600- & desc -> ptr [ 3 ], sg_count , 0 , 0 );
1603+ sg_count = talitos_sg_map_ext (dev , areq -> src , cryptlen , edesc , & desc -> ptr [ 3 ] ,
1604+ sg_count , 0 , 0 , 0 , false, is_ctr ? 16 : 1 );
16011605 if (sg_count > 1 )
16021606 sync_needed = true;
16031607
0 commit comments