2011-10-18 00:01:24 +00:00
/*******************************************************************************
Specialised functions for managing Ring mode
Copyright ( C ) 2011 STMicroelectronics Ltd
It defines all the functions used to handle the normal / enhanced
descriptors in case of the DMA is configured to work in chained or
in ring mode .
This program is free software ; you can redistribute it and / or modify it
under the terms and conditions of the GNU General Public License ,
version 2 , as published by the Free Software Foundation .
This program is distributed in the hope it will be useful , but WITHOUT
ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
more details .
The full GNU General Public License is included in this distribution in
the file called " COPYING " .
Author : Giuseppe Cavallaro < peppe . cavallaro @ st . com >
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "stmmac.h"
2018-04-16 16:08:16 +01:00
static int jumbo_frm ( void * p , struct sk_buff * skb , int csum )
2011-10-18 00:01:24 +00:00
{
2017-04-06 09:49:10 +01:00
struct stmmac_tx_queue * tx_q = ( struct stmmac_tx_queue * ) p ;
2011-10-18 00:01:24 +00:00
unsigned int nopaged_len = skb_headlen ( skb ) ;
2017-04-06 09:49:10 +01:00
struct stmmac_priv * priv = tx_q - > priv_data ;
unsigned int entry = tx_q - > cur_tx ;
2016-11-14 18:58:05 +01:00
unsigned int bmax , len , des2 ;
2017-04-06 09:49:10 +01:00
struct dma_desc * desc ;
2011-10-18 00:01:24 +00:00
2013-08-08 15:30:26 +09:00
if ( priv - > extend_desc )
2017-04-06 09:49:10 +01:00
desc = ( struct dma_desc * ) ( tx_q - > dma_etx + entry ) ;
2013-08-08 15:30:26 +09:00
else
2017-04-06 09:49:10 +01:00
desc = tx_q - > dma_tx + entry ;
2013-08-08 15:30:26 +09:00
2011-10-18 00:01:24 +00:00
if ( priv - > plat - > enh_desc )
bmax = BUF_SIZE_8KiB ;
else
bmax = BUF_SIZE_2KiB ;
len = nopaged_len - bmax ;
if ( nopaged_len > BUF_SIZE_8KiB ) {
2016-11-14 18:58:05 +01:00
des2 = dma_map_single ( priv - > device , skb - > data , bmax ,
DMA_TO_DEVICE ) ;
desc - > des2 = cpu_to_le32 ( des2 ) ;
if ( dma_mapping_error ( priv - > device , des2 ) )
2014-08-27 11:27:00 +02:00
return - 1 ;
2017-04-06 09:49:10 +01:00
tx_q - > tx_skbuff_dma [ entry ] . buf = des2 ;
tx_q - > tx_skbuff_dma [ entry ] . len = bmax ;
tx_q - > tx_skbuff_dma [ entry ] . is_jumbo = true ;
2016-02-29 14:27:31 +01:00
2016-11-14 18:58:05 +01:00
desc - > des3 = cpu_to_le32 ( des2 + BUF_SIZE_4KiB ) ;
2018-04-16 16:08:12 +01:00
stmmac_prepare_tx_desc ( priv , desc , 1 , bmax , csum ,
STMMAC_RING_MODE , 0 , false , skb - > len ) ;
2017-04-06 09:49:10 +01:00
tx_q - > tx_skbuff [ entry ] = NULL ;
2016-02-29 14:27:30 +01:00
entry = STMMAC_GET_ENTRY ( entry , DMA_TX_SIZE ) ;
2013-08-08 15:30:26 +09:00
if ( priv - > extend_desc )
2017-04-06 09:49:10 +01:00
desc = ( struct dma_desc * ) ( tx_q - > dma_etx + entry ) ;
2013-08-08 15:30:26 +09:00
else
2017-04-06 09:49:10 +01:00
desc = tx_q - > dma_tx + entry ;
2011-10-18 00:01:24 +00:00
2016-11-14 18:58:05 +01:00
des2 = dma_map_single ( priv - > device , skb - > data + bmax , len ,
DMA_TO_DEVICE ) ;
desc - > des2 = cpu_to_le32 ( des2 ) ;
if ( dma_mapping_error ( priv - > device , des2 ) )
2014-08-27 11:27:00 +02:00
return - 1 ;
2017-04-06 09:49:10 +01:00
tx_q - > tx_skbuff_dma [ entry ] . buf = des2 ;
tx_q - > tx_skbuff_dma [ entry ] . len = len ;
tx_q - > tx_skbuff_dma [ entry ] . is_jumbo = true ;
2016-02-29 14:27:31 +01:00
2016-11-14 18:58:05 +01:00
desc - > des3 = cpu_to_le32 ( des2 + BUF_SIZE_4KiB ) ;
2018-04-16 16:08:12 +01:00
stmmac_prepare_tx_desc ( priv , desc , 0 , len , csum ,
STMMAC_RING_MODE , 1 , true , skb - > len ) ;
2011-10-18 00:01:24 +00:00
} else {
2016-11-14 18:58:05 +01:00
des2 = dma_map_single ( priv - > device , skb - > data ,
nopaged_len , DMA_TO_DEVICE ) ;
desc - > des2 = cpu_to_le32 ( des2 ) ;
if ( dma_mapping_error ( priv - > device , des2 ) )
2014-08-27 11:27:00 +02:00
return - 1 ;
2017-04-06 09:49:10 +01:00
tx_q - > tx_skbuff_dma [ entry ] . buf = des2 ;
tx_q - > tx_skbuff_dma [ entry ] . len = nopaged_len ;
tx_q - > tx_skbuff_dma [ entry ] . is_jumbo = true ;
2016-11-14 18:58:05 +01:00
desc - > des3 = cpu_to_le32 ( des2 + BUF_SIZE_4KiB ) ;
2018-04-16 16:08:12 +01:00
stmmac_prepare_tx_desc ( priv , desc , 1 , nopaged_len , csum ,
STMMAC_RING_MODE , 0 , true , skb - > len ) ;
2011-10-18 00:01:24 +00:00
}
2017-04-06 09:49:10 +01:00
tx_q - > cur_tx = entry ;
2016-02-29 14:27:30 +01:00
2011-10-18 00:01:24 +00:00
return entry ;
}
2018-04-16 16:08:16 +01:00
static unsigned int is_jumbo_frm ( int len , int enh_desc )
2011-10-18 00:01:24 +00:00
{
unsigned int ret = 0 ;
if ( len > = BUF_SIZE_4KiB )
ret = 1 ;
return ret ;
}
2018-04-16 16:08:16 +01:00
static void refill_desc3 ( void * priv_ptr , struct dma_desc * p )
2011-10-18 00:01:24 +00:00
{
2013-03-26 04:43:10 +00:00
struct stmmac_priv * priv = ( struct stmmac_priv * ) priv_ptr ;
2014-03-10 13:40:33 +01:00
/* Fill DES3 in case of RING mode */
if ( priv - > dma_buf_sz > = BUF_SIZE_8KiB )
2016-11-14 18:58:05 +01:00
p - > des3 = cpu_to_le32 ( le32_to_cpu ( p - > des2 ) + BUF_SIZE_8KiB ) ;
2011-10-18 00:01:24 +00:00
}
2013-03-26 04:43:05 +00:00
/* In ring mode we need to fill the desc3 because it is used as buffer */
2018-04-16 16:08:16 +01:00
static void init_desc3 ( struct dma_desc * p )
2011-10-18 00:01:24 +00:00
{
2016-11-14 18:58:05 +01:00
p - > des3 = cpu_to_le32 ( le32_to_cpu ( p - > des2 ) + BUF_SIZE_8KiB ) ;
2011-10-18 00:01:24 +00:00
}
2018-04-16 16:08:16 +01:00
static void clean_desc3 ( void * priv_ptr , struct dma_desc * p )
2011-10-18 00:01:24 +00:00
{
2017-04-06 09:49:10 +01:00
struct stmmac_tx_queue * tx_q = ( struct stmmac_tx_queue * ) priv_ptr ;
struct stmmac_priv * priv = tx_q - > priv_data ;
unsigned int entry = tx_q - > dirty_tx ;
2016-02-29 14:27:33 +01:00
/* des3 is only used for jumbo frames tx or time stamping */
2017-04-06 09:49:10 +01:00
if ( unlikely ( tx_q - > tx_skbuff_dma [ entry ] . is_jumbo | |
( tx_q - > tx_skbuff_dma [ entry ] . last_segment & &
2016-02-29 14:27:33 +01:00
! priv - > extend_desc & & priv - > hwts_tx_en ) ) )
2011-10-18 00:01:24 +00:00
p - > des3 = 0 ;
}
2018-04-16 16:08:16 +01:00
static int set_16kib_bfsize ( int mtu )
2011-10-18 00:01:24 +00:00
{
int ret = 0 ;
if ( unlikely ( mtu > = BUF_SIZE_8KiB ) )
ret = BUF_SIZE_16KiB ;
return ret ;
}
2014-03-10 13:40:33 +01:00
const struct stmmac_mode_ops ring_mode_ops = {
2018-04-16 16:08:16 +01:00
. is_jumbo_frm = is_jumbo_frm ,
. jumbo_frm = jumbo_frm ,
. refill_desc3 = refill_desc3 ,
. init_desc3 = init_desc3 ,
. clean_desc3 = clean_desc3 ,
. set_16kib_bfsize = set_16kib_bfsize ,
2011-10-18 00:01:24 +00:00
} ;