2010-09-08 15:46:36 -06:00
/**********************************************************************
* LEAKYBUCKET . C
* This file contains the routines related to Leaky Bucket Algorithm .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "headers.h"
/*********************************************************************
* Function - UpdateTokenCount ( )
*
* Description - This function calculates the token count for each
* channel and updates the same in Adapter strucuture .
*
* Parameters - Adapter : Pointer to the Adapter structure .
*
* Returns - None
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-09-30 02:24:12 -06:00
static VOID UpdateTokenCount ( register PMINI_ADAPTER Adapter )
2010-09-08 15:46:36 -06:00
{
ULONG liCurrentTime ;
INT i = 0 ;
struct timeval tv ;
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TOKEN_COUNTS , DBG_LVL_ALL , " =====> \n " ) ;
if ( NULL = = Adapter )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TOKEN_COUNTS , DBG_LVL_ALL , " Adapter found NULL! \n " ) ;
return ;
}
do_gettimeofday ( & tv ) ;
for ( i = 0 ; i < NO_OF_QUEUES ; i + + )
{
if ( TRUE = = Adapter - > PackInfo [ i ] . bValid & &
( 1 = = Adapter - > PackInfo [ i ] . ucDirection ) )
{
liCurrentTime = ( ( tv . tv_sec -
Adapter - > PackInfo [ i ] . stLastUpdateTokenAt . tv_sec ) * 1000 +
( tv . tv_usec - Adapter - > PackInfo [ i ] . stLastUpdateTokenAt . tv_usec ) /
1000 ) ;
if ( 0 ! = liCurrentTime )
{
Adapter - > PackInfo [ i ] . uiCurrentTokenCount + = ( ULONG )
( ( Adapter - > PackInfo [ i ] . uiMaxAllowedRate ) *
( ( ULONG ) ( ( liCurrentTime ) ) ) / 1000 ) ;
memcpy ( & Adapter - > PackInfo [ i ] . stLastUpdateTokenAt ,
& tv , sizeof ( struct timeval ) ) ;
Adapter - > PackInfo [ i ] . liLastUpdateTokenAt = liCurrentTime ;
if ( ( Adapter - > PackInfo [ i ] . uiCurrentTokenCount ) > =
Adapter - > PackInfo [ i ] . uiMaxBucketSize )
{
Adapter - > PackInfo [ i ] . uiCurrentTokenCount =
Adapter - > PackInfo [ i ] . uiMaxBucketSize ;
}
}
}
}
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TOKEN_COUNTS , DBG_LVL_ALL , " <===== \n " ) ;
return ;
}
/*********************************************************************
* Function - IsPacketAllowedForFlow ( )
*
* Description - This function checks whether the given packet from the
* specified queue can be allowed for transmission by
* checking the token count .
*
* Parameters - Adapter : Pointer to the Adpater structure .
* - iQIndex : The queue Identifier .
* - ulPacketLength : Number of bytes to be transmitted .
*
* Returns - The number of bytes allowed for transmission .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-31 21:52:36 -06:00
static ULONG GetSFTokenCount ( PMINI_ADAPTER Adapter , PacketInfo * psSF )
2010-09-08 15:46:36 -06:00
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TOKEN_COUNTS , DBG_LVL_ALL , " IsPacketAllowedForFlow ===> " ) ;
/* Validate the parameters */
if ( NULL = = Adapter | | ( psSF < Adapter - > PackInfo & &
2010-09-30 02:24:11 -06:00
( uintptr_t ) psSF > ( uintptr_t ) & Adapter - > PackInfo [ HiPriority ] ) )
2010-09-08 15:46:36 -06:00
{
2010-11-01 06:42:44 -06:00
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TOKEN_COUNTS , DBG_LVL_ALL , " IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %zd \n " , Adapter , ( psSF - Adapter - > PackInfo ) ) ;
2010-09-08 15:46:36 -06:00
return 0 ;
}
if ( FALSE ! = psSF - > bValid & & psSF - > ucDirection )
{
if ( 0 ! = psSF - > uiCurrentTokenCount )
{
return psSF - > uiCurrentTokenCount ;
}
else
{
2010-11-01 06:42:44 -06:00
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TOKEN_COUNTS , DBG_LVL_ALL , " Not enough tokens in queue %zd Available %u \n " ,
2010-09-08 15:46:36 -06:00
psSF - Adapter - > PackInfo , psSF - > uiCurrentTokenCount ) ;
psSF - > uiPendedLast = 1 ;
}
}
else
{
2010-11-01 06:42:44 -06:00
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TOKEN_COUNTS , DBG_LVL_ALL , " IPAFF: Queue %zd not valid \n " , psSF - Adapter - > PackInfo ) ;
2010-09-08 15:46:36 -06:00
}
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TOKEN_COUNTS , DBG_LVL_ALL , " IsPacketAllowedForFlow <=== " ) ;
return 0 ;
}
/**
@ ingroup tx_functions
This function despatches packet from the specified queue .
@ return Zero ( success ) or Negative value ( failure )
*/
2010-10-31 21:52:36 -06:00
static INT SendPacketFromQueue ( PMINI_ADAPTER Adapter , /**<Logical Adapter*/
PacketInfo * psSF , /**<Queue identifier*/
struct sk_buff * Packet ) /**<Pointer to the packet to be sent*/
2010-09-08 15:46:36 -06:00
{
INT Status = STATUS_FAILURE ;
UINT uiIndex = 0 , PktLen = 0 ;
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , SEND_QUEUE , DBG_LVL_ALL , " =====> " ) ;
if ( ! Adapter | | ! Packet | | ! psSF )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , SEND_QUEUE , DBG_LVL_ALL , " Got NULL Adapter or Packet " ) ;
return - EINVAL ;
}
if ( psSF - > liDrainCalculated = = 0 )
{
psSF - > liDrainCalculated = jiffies ;
}
///send the packet to the fifo..
PktLen = Packet - > len ;
Status = SetupNextSend ( Adapter , Packet , psSF - > usVCID_Value ) ;
if ( Status = = 0 )
{
for ( uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex + + )
{ if ( ( PktLen < = MIBS_PKTSIZEHIST_RANGE * ( uiIndex + 1 ) ) & & ( PktLen > MIBS_PKTSIZEHIST_RANGE * ( uiIndex ) ) )
Adapter - > aTxPktSizeHist [ uiIndex ] + + ;
}
}
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , SEND_QUEUE , DBG_LVL_ALL , " <===== " ) ;
return Status ;
}
/************************************************************************
* Function - CheckAndSendPacketFromIndex ( )
*
* Description - This function dequeues the data / control packet from the
* specified queue for transmission .
*
* Parameters - Adapter : Pointer to the driver control structure .
* - iQIndex : The queue Identifier .
*
* Returns - None .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-31 21:52:36 -06:00
static VOID CheckAndSendPacketFromIndex ( PMINI_ADAPTER Adapter , PacketInfo * psSF )
2010-09-08 15:46:36 -06:00
{
struct sk_buff * QueuePacket = NULL ;
char * pControlPacket = NULL ;
INT Status = 0 ;
int iPacketLen = 0 ;
2010-11-01 06:42:44 -06:00
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " %zd ====> " , ( psSF - Adapter - > PackInfo ) ) ;
2010-09-30 02:24:11 -06:00
if ( ( psSF ! = & Adapter - > PackInfo [ HiPriority ] ) & & Adapter - > LinkUpStatus & & atomic_read ( & psSF - > uiPerSFTxResourceCount ) ) //Get data packet
2010-09-08 15:46:36 -06:00
{
if ( ! psSF - > ucDirection )
return ;
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " UpdateTokenCount " ) ;
if ( Adapter - > IdleMode | | Adapter - > bPreparingForLowPowerMode )
2010-11-01 11:57:35 -06:00
return ; /* in idle mode */
2010-09-08 15:46:36 -06:00
// Check for Free Descriptors
if ( atomic_read ( & Adapter - > CurrNumFreeTxDesc ) < = MINIMUM_PENDING_DESCRIPTORS )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " No Free Tx Descriptor(%d) is available for Data pkt.. " , atomic_read ( & Adapter - > CurrNumFreeTxDesc ) ) ;
return ;
}
spin_lock_bh ( & psSF - > SFQueueLock ) ;
QueuePacket = psSF - > FirstTxQueue ;
if ( QueuePacket )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " Dequeuing Data Packet " ) ;
if ( psSF - > bEthCSSupport )
iPacketLen = QueuePacket - > len ;
else
iPacketLen = QueuePacket - > len - ETH_HLEN ;
iPacketLen < < = 3 ;
if ( iPacketLen < = GetSFTokenCount ( Adapter , psSF ) )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " Allowed bytes %d " ,
( iPacketLen > > 3 ) ) ;
DEQUEUEPACKET ( psSF - > FirstTxQueue , psSF - > LastTxQueue ) ;
psSF - > uiCurrentBytesOnHost - = ( QueuePacket - > len ) ;
psSF - > uiCurrentPacketsOnHost - - ;
atomic_dec ( & Adapter - > TotalPacketCount ) ;
spin_unlock_bh ( & psSF - > SFQueueLock ) ;
Status = SendPacketFromQueue ( Adapter , psSF , QueuePacket ) ;
psSF - > uiPendedLast = FALSE ;
}
else
{
2010-11-01 06:42:44 -06:00
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " For Queue: %zd \n " , psSF - Adapter - > PackInfo ) ;
2010-09-08 15:46:36 -06:00
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " \n Available Tokens = %d required = %d \n " ,
psSF - > uiCurrentTokenCount , iPacketLen ) ;
2011-03-30 19:57:33 -06:00
//this part indicates that because of non-availability of the tokens
2010-09-08 15:46:36 -06:00
//pkt has not been send out hence setting the pending flag indicating the host to send it out
//first next iteration .
psSF - > uiPendedLast = TRUE ;
spin_unlock_bh ( & psSF - > SFQueueLock ) ;
}
}
else
{
spin_unlock_bh ( & psSF - > SFQueueLock ) ;
}
}
else
{
if ( ( atomic_read ( & Adapter - > CurrNumFreeTxDesc ) > 0 ) & &
( atomic_read ( & Adapter - > index_rd_txcntrlpkt ) ! =
atomic_read ( & Adapter - > index_wr_txcntrlpkt ) )
)
{
pControlPacket = Adapter - > txctlpacket
[ ( atomic_read ( & Adapter - > index_rd_txcntrlpkt ) % MAX_CNTRL_PKTS ) ] ;
if ( pControlPacket )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " Sending Control packet " ) ;
Status = SendControlPacket ( Adapter , pControlPacket ) ;
if ( STATUS_SUCCESS = = Status )
{
spin_lock_bh ( & psSF - > SFQueueLock ) ;
psSF - > NumOfPacketsSent + + ;
psSF - > uiSentBytes + = ( ( PLEADER ) pControlPacket ) - > PLength ;
psSF - > uiSentPackets + + ;
atomic_dec ( & Adapter - > TotalPacketCount ) ;
psSF - > uiCurrentBytesOnHost - = ( ( PLEADER ) pControlPacket ) - > PLength ;
psSF - > uiCurrentPacketsOnHost - - ;
atomic_inc ( & Adapter - > index_rd_txcntrlpkt ) ;
spin_unlock_bh ( & psSF - > SFQueueLock ) ;
}
else
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " SendControlPacket Failed \n " ) ;
}
else
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " Control Pkt is not available, Indexing is wrong.... " ) ;
}
}
}
}
/*******************************************************************
* Function - transmit_packets ( )
*
* Description - This function transmits the packets from different
* queues , if free descriptors are available on target .
*
* Parameters - Adapter : Pointer to the Adapter structure .
*
* Returns - None .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
VOID transmit_packets ( PMINI_ADAPTER Adapter )
{
UINT uiPrevTotalCount = 0 ;
int iIndex = 0 ;
BOOLEAN exit_flag = TRUE ;
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " =====> " ) ;
if ( NULL = = Adapter )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " Got NULL Adapter " ) ;
return ;
}
if ( Adapter - > device_removed = = TRUE )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " Device removed " ) ;
return ;
}
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " \n UpdateTokenCount ====> \n " ) ;
UpdateTokenCount ( Adapter ) ;
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " \n PruneQueueAllSF ====> \n " ) ;
PruneQueueAllSF ( Adapter ) ;
uiPrevTotalCount = atomic_read ( & Adapter - > TotalPacketCount ) ;
for ( iIndex = HiPriority ; iIndex > = 0 ; iIndex - - )
{
if ( ! uiPrevTotalCount | | ( TRUE = = Adapter - > device_removed ) )
break ;
if ( Adapter - > PackInfo [ iIndex ] . bValid & &
Adapter - > PackInfo [ iIndex ] . uiPendedLast & &
Adapter - > PackInfo [ iIndex ] . uiCurrentBytesOnHost )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " Calling CheckAndSendPacketFromIndex.. " ) ;
CheckAndSendPacketFromIndex ( Adapter , & Adapter - > PackInfo [ iIndex ] ) ;
uiPrevTotalCount - - ;
}
}
while ( uiPrevTotalCount > 0 & & ! Adapter - > device_removed )
{
exit_flag = TRUE ;
//second iteration to parse non-pending queues
for ( iIndex = HiPriority ; iIndex > = 0 ; iIndex - - )
{
if ( ! uiPrevTotalCount | | ( TRUE = = Adapter - > device_removed ) )
break ;
if ( Adapter - > PackInfo [ iIndex ] . bValid & &
Adapter - > PackInfo [ iIndex ] . uiCurrentBytesOnHost & &
! Adapter - > PackInfo [ iIndex ] . uiPendedLast )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " Calling CheckAndSendPacketFromIndex.. " ) ;
CheckAndSendPacketFromIndex ( Adapter , & Adapter - > PackInfo [ iIndex ] ) ;
uiPrevTotalCount - - ;
exit_flag = FALSE ;
}
}
if ( Adapter - > IdleMode | | Adapter - > bPreparingForLowPowerMode )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " In Idle Mode \n " ) ;
break ;
}
if ( exit_flag = = TRUE )
break ;
} /* end of inner while loop */
2010-11-01 11:57:35 -06:00
2010-09-08 15:46:36 -06:00
update_per_cid_rx ( Adapter ) ;
Adapter - > txtransmit_running = 0 ;
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_TX , TX_PACKETS , DBG_LVL_ALL , " <====== " ) ;
}