2012-06-23 04:48:45 +04:00
/*
* CAAM / SEC 4. x functions for using scatterlists in caam driver
*
* Copyright 2008 - 2011 Freescale Semiconductor , Inc .
*
*/
2016-05-19 18:11:26 +03:00
# include "regs.h"
2012-06-23 04:48:46 +04:00
struct sec4_sg_entry ;
2012-06-23 04:48:45 +04:00
/*
* convert single dma address to h / w link table format
*/
2012-06-23 04:48:46 +04:00
static inline void dma_to_sec4_sg_one ( struct sec4_sg_entry * sec4_sg_ptr ,
2016-05-19 18:11:18 +03:00
dma_addr_t dma , u32 len , u16 offset )
2012-06-23 04:48:45 +04:00
{
2016-09-30 12:09:39 +03:00
sec4_sg_ptr - > ptr = cpu_to_caam_dma64 ( dma ) ;
2016-05-19 18:11:26 +03:00
sec4_sg_ptr - > len = cpu_to_caam32 ( len ) ;
sec4_sg_ptr - > bpid_offset = cpu_to_caam32 ( offset & SEC4_SG_OFFSET_MASK ) ;
2012-06-23 04:48:45 +04:00
# ifdef DEBUG
2012-06-23 04:48:46 +04:00
print_hex_dump ( KERN_ERR , " sec4_sg_ptr@: " ,
DUMP_PREFIX_ADDRESS , 16 , 4 , sec4_sg_ptr ,
sizeof ( struct sec4_sg_entry ) , 1 ) ;
2012-06-23 04:48:45 +04:00
# endif
}
/*
* convert scatterlist to h / w link table format
* but does not have final bit ; instead , returns last entry
*/
2012-06-23 04:48:46 +04:00
static inline struct sec4_sg_entry *
sg_to_sec4_sg ( struct scatterlist * sg , int sg_count ,
2016-05-19 18:11:18 +03:00
struct sec4_sg_entry * sec4_sg_ptr , u16 offset )
2012-06-23 04:48:45 +04:00
{
while ( sg_count ) {
2012-06-23 04:48:46 +04:00
dma_to_sec4_sg_one ( sec4_sg_ptr , sg_dma_address ( sg ) ,
2012-06-23 04:48:45 +04:00
sg_dma_len ( sg ) , offset ) ;
2012-06-23 04:48:46 +04:00
sec4_sg_ptr + + ;
2015-01-20 11:06:16 +03:00
sg = sg_next ( sg ) ;
2012-06-23 04:48:45 +04:00
sg_count - - ;
}
2012-06-23 04:48:46 +04:00
return sec4_sg_ptr - 1 ;
2012-06-23 04:48:45 +04:00
}
/*
* convert scatterlist to h / w link table format
* scatterlist must have been previously dma mapped
*/
2012-06-23 04:48:46 +04:00
static inline void sg_to_sec4_sg_last ( struct scatterlist * sg , int sg_count ,
struct sec4_sg_entry * sec4_sg_ptr ,
2016-05-19 18:11:18 +03:00
u16 offset )
2012-06-23 04:48:45 +04:00
{
2012-06-23 04:48:46 +04:00
sec4_sg_ptr = sg_to_sec4_sg ( sg , sg_count , sec4_sg_ptr , offset ) ;
2016-05-19 18:11:26 +03:00
sec4_sg_ptr - > len | = cpu_to_caam32 ( SEC4_SG_LEN_FIN ) ;
2012-06-23 04:48:45 +04:00
}
2015-06-08 11:38:24 +03:00
static inline struct sec4_sg_entry * sg_to_sec4_sg_len (
struct scatterlist * sg , unsigned int total ,
struct sec4_sg_entry * sec4_sg_ptr )
{
do {
unsigned int len = min ( sg_dma_len ( sg ) , total ) ;
dma_to_sec4_sg_one ( sec4_sg_ptr , sg_dma_address ( sg ) , len , 0 ) ;
sec4_sg_ptr + + ;
sg = sg_next ( sg ) ;
total - = len ;
} while ( total ) ;
return sec4_sg_ptr - 1 ;
}
2012-06-23 04:48:45 +04:00
/* derive number of elements in scatterlist, but return 0 for 1 */
2015-09-23 14:55:27 +03:00
static inline int sg_count ( struct scatterlist * sg_list , int nbytes )
2012-06-23 04:48:45 +04:00
{
2015-09-23 14:55:27 +03:00
int sg_nents = sg_nents_for_len ( sg_list , nbytes ) ;
2012-06-23 04:48:45 +04:00
if ( likely ( sg_nents = = 1 ) )
return 0 ;
return sg_nents ;
}