/**********************************************************************
*			LEAKYBUCKET.C
*	This file contains the routines related to Leaky Bucket Algorithm.
***********************************************************************/
#include "headers.h"

/**
 * UpdateTokenCount() - Calculates the token count for each channel
 * and updates the same in Adapter structure
 * @Adapter:	Pointer to the Adapter structure.
 *
 * Return: None
 */
static VOID UpdateTokenCount(register struct bcm_mini_adapter *Adapter)
{
	ULONG liCurrentTime;
	INT i = 0;
	struct timeval tv;
	struct bcm_packet_info *curr_pi;

	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++) {
		curr_pi = &Adapter->PackInfo[i];

		if (TRUE == curr_pi->bValid && (1 == curr_pi->ucDirection)) {
			liCurrentTime = ((tv.tv_sec -
				curr_pi->stLastUpdateTokenAt.tv_sec)*1000 +
				(tv.tv_usec - curr_pi->stLastUpdateTokenAt.tv_usec) /
				1000);
			if (0 != liCurrentTime) {
				curr_pi->uiCurrentTokenCount += (ULONG)
					((curr_pi->uiMaxAllowedRate) *
					((ULONG)((liCurrentTime)))/1000);
				memcpy(&curr_pi->stLastUpdateTokenAt, &tv,
				       sizeof(struct timeval));
				curr_pi->liLastUpdateTokenAt = liCurrentTime;
				if (curr_pi->uiCurrentTokenCount >=
				    curr_pi->uiMaxBucketSize) {
					curr_pi->uiCurrentTokenCount =
						curr_pi->uiMaxBucketSize;
				}
			}
		}
	}
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
			"<=====\n");
}


/**
 * IsPacketAllowedForFlow() - This function checks whether the given
 * packet from the specified queue can be allowed for transmission by
 * checking the token count.
 * @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.
 */
static ULONG GetSFTokenCount(struct bcm_mini_adapter *Adapter, struct bcm_packet_info *psSF)
{
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
			"IsPacketAllowedForFlow ===>");

	/* Validate the parameters */
	if (NULL == Adapter || (psSF < Adapter->PackInfo &&
	    (uintptr_t)psSF > (uintptr_t) &Adapter->PackInfo[HiPriority])) {
		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));
		return 0;
	}

	if (false != psSF->bValid && psSF->ucDirection) {
		if (0 != psSF->uiCurrentTokenCount) {
			return psSF->uiCurrentTokenCount;
		} else {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS,
					DBG_LVL_ALL,
					"Not enough tokens in queue %zd Available %u\n",
					psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount);
			psSF->uiPendedLast = 1;
		}
	} else {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
				"IPAFF: Queue %zd not valid\n",
				psSF-Adapter->PackInfo);
	}
	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)
*/
static INT SendPacketFromQueue(struct bcm_mini_adapter *Adapter,/**<Logical Adapter*/
			       struct bcm_packet_info *psSF, /**<Queue identifier*/
			       struct sk_buff *Packet)	/**<Pointer to the packet to be sent*/
{
	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;
}

static void get_data_packet(struct bcm_mini_adapter *ad,
			    struct bcm_packet_info *ps_sf)
{
	int packet_len;
	struct sk_buff *qpacket;

	if (!ps_sf->ucDirection)
		return;

	BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
			"UpdateTokenCount ");
	if (ad->IdleMode || ad->bPreparingForLowPowerMode)
		return; /* in idle mode */

	/* Check for Free Descriptors */
	if (atomic_read(&ad->CurrNumFreeTxDesc) <=
	    MINIMUM_PENDING_DESCRIPTORS) {
		BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
				" No Free Tx Descriptor(%d) is available for Data pkt..",
				atomic_read(&ad->CurrNumFreeTxDesc));
		return;
	}

	spin_lock_bh(&ps_sf->SFQueueLock);
	qpacket = ps_sf->FirstTxQueue;

	if (qpacket) {
		BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
				"Dequeuing Data Packet");

		if (ps_sf->bEthCSSupport)
			packet_len = qpacket->len;
		else
			packet_len = qpacket->len - ETH_HLEN;

		packet_len <<= 3;
		if (packet_len <= GetSFTokenCount(ad, ps_sf)) {
			BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
					DBG_LVL_ALL, "Allowed bytes %d",
					(packet_len >> 3));

			DEQUEUEPACKET(ps_sf->FirstTxQueue, ps_sf->LastTxQueue);
			ps_sf->uiCurrentBytesOnHost -= (qpacket->len);
			ps_sf->uiCurrentPacketsOnHost--;
				atomic_dec(&ad->TotalPacketCount);
			spin_unlock_bh(&ps_sf->SFQueueLock);

			SendPacketFromQueue(ad, ps_sf, qpacket);
			ps_sf->uiPendedLast = false;
		} else {
			BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
					DBG_LVL_ALL, "For Queue: %zd\n",
					ps_sf - ad->PackInfo);
			BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
					DBG_LVL_ALL,
					"\nAvailable Tokens = %d required = %d\n",
					ps_sf->uiCurrentTokenCount,
					packet_len);
			/*
			this part indicates that because of
			non-availability of the tokens
			pkt has not been send out hence setting the
			pending flag indicating the host to send it out
			first next iteration.
			*/
			ps_sf->uiPendedLast = TRUE;
			spin_unlock_bh(&ps_sf->SFQueueLock);
		}
	} else {
		spin_unlock_bh(&ps_sf->SFQueueLock);
	}
}

static void send_control_packet(struct bcm_mini_adapter *ad,
				struct bcm_packet_info *ps_sf)
{
	char *ctrl_packet = NULL;
	INT status = 0;

	if ((atomic_read(&ad->CurrNumFreeTxDesc) > 0) &&
	    (atomic_read(&ad->index_rd_txcntrlpkt) !=
	     atomic_read(&ad->index_wr_txcntrlpkt))) {
		ctrl_packet = ad->txctlpacket
		[(atomic_read(&ad->index_rd_txcntrlpkt)%MAX_CNTRL_PKTS)];
		if (ctrl_packet) {
			BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
					DBG_LVL_ALL,
					"Sending Control packet");
			status = SendControlPacket(ad, ctrl_packet);
			if (STATUS_SUCCESS == status) {
				spin_lock_bh(&ps_sf->SFQueueLock);
				ps_sf->NumOfPacketsSent++;
				ps_sf->uiSentBytes += ((struct bcm_leader *)ctrl_packet)->PLength;
				ps_sf->uiSentPackets++;
				atomic_dec(&ad->TotalPacketCount);
				ps_sf->uiCurrentBytesOnHost -= ((struct bcm_leader *)ctrl_packet)->PLength;
				ps_sf->uiCurrentPacketsOnHost--;
				atomic_inc(&ad->index_rd_txcntrlpkt);
				spin_unlock_bh(&ps_sf->SFQueueLock);
			} else {
				BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
						DBG_LVL_ALL,
						"SendControlPacket Failed\n");
			}
		} else {
			BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
					DBG_LVL_ALL,
					" Control Pkt is not available, Indexing is wrong....");
		}
	}
}

/**
 * CheckAndSendPacketFromIndex() - This function dequeues the
 * data/control packet from the specified queue for transmission.
 * @Adapter:	Pointer to the driver control structure.
 * @iQIndex:	The queue Identifier.
 *
 * Returns: None.
 */
static VOID CheckAndSendPacketFromIndex(struct bcm_mini_adapter *Adapter,
					struct bcm_packet_info *psSF)
{
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
			"%zd ====>", (psSF-Adapter->PackInfo));
	if ((psSF != &Adapter->PackInfo[HiPriority]) &&
	    Adapter->LinkUpStatus &&
	    atomic_read(&psSF->uiPerSFTxResourceCount)) { /* Get data packet */

		get_data_packet(Adapter, psSF);
	} else {
		send_control_packet(Adapter, psSF);
	}
}


/**
 * transmit_packets() - This function transmits the packets from
 * different queues, if free descriptors are available on target.
 * @Adapter:	Pointer to the Adapter structure.
 *
 * Returns: None.
 */
VOID transmit_packets(struct bcm_mini_adapter *Adapter)
{
	UINT uiPrevTotalCount = 0;
	int iIndex = 0;

	bool 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,
			"\nUpdateTokenCount ====>\n");

	UpdateTokenCount(Adapter);

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
			"\nPruneQueueAllSF ====>\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 */

	update_per_cid_rx(Adapter);
	Adapter->txtransmit_running = 0;
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
			"<======");
}
