/*
 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that 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.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * File: datarate.c
 *
 * Purpose: Handles the auto fallback & data rates functions
 *
 * Author: Lyndon Chen
 *
 * Date: July 17, 2002
 *
 * Functions:
 *      RATEvParseMaxRate - Parsing the highest basic & support rate in rate field of frame
 *      RATEvTxRateFallBack - Rate fallback Algorithm Implementaion
 *      RATEuSetIE- Set rate IE field.
 *
 * Revision History:
 *
 */

#include "ttype.h"
#include "tmacro.h"
#include "mac.h"
#include "80211mgr.h"
#include "bssdb.h"
#include "datarate.h"
#include "card.h"
#include "baseband.h"
#include "srom.h"

/*---------------------  Static Definitions -------------------------*/

/*---------------------  Static Classes  ----------------------------*/

extern unsigned short TxRate_iwconfig; /* 2008-5-8 <add> by chester */
/*---------------------  Static Variables  --------------------------*/
static const unsigned char acbyIERate[MAX_RATE] = {
0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C
};

#define AUTORATE_TXOK_CNT       0x0400
#define AUTORATE_TXFAIL_CNT     0x0064
#define AUTORATE_TIMEOUT        10

/*---------------------  Static Functions  --------------------------*/

void s_vResetCounter(
	PKnownNodeDB psNodeDBTable
);

void
s_vResetCounter(
	PKnownNodeDB psNodeDBTable
)
{
	unsigned char ii;

	/* clear statistic counter for auto_rate */
	for (ii = 0; ii <= MAX_RATE; ii++) {
		psNodeDBTable->uTxOk[ii] = 0;
		psNodeDBTable->uTxFail[ii] = 0;
	}
}

/*---------------------  Export Variables  --------------------------*/

/*---------------------  Export Functions  --------------------------*/

/*+
 *
 * Description:
 *      Get RateIdx from the value in SuppRates IE or ExtSuppRates IE
 *
 * Parameters:
 *  In:
 *      unsigned char - Rate value in SuppRates IE or ExtSuppRates IE
 *  Out:
 *      none
 *
 * Return Value: RateIdx
 *
 -*/
unsigned char
DATARATEbyGetRateIdx(
	unsigned char byRate
)
{
	unsigned char ii;

	/* Erase basicRate flag. */
	byRate = byRate & 0x7F;/* 0111 1111 */

	for (ii = 0; ii < MAX_RATE; ii++) {
		if (acbyIERate[ii] == byRate)
			return ii;
	}
	return 0;
}

/*+
 *
 * Routine Description:
 *      Rate fallback Algorithm Implementation
 *
 * Parameters:
 *  In:
 *      pDevice         - Pointer to the adapter
 *      psNodeDBTable   - Pointer to Node Data Base
 *  Out:
 *      none
 *
 * Return Value: none
 *
 -*/
#define AUTORATE_TXCNT_THRESHOLD        20
#define AUTORATE_INC_THRESHOLD          30

/*+
 *
 * Description:
 *      Get RateIdx from the value in SuppRates IE or ExtSuppRates IE
 *
 * Parameters:
 *  In:
 *      unsigned char - Rate value in SuppRates IE or ExtSuppRates IE
 *  Out:
 *      none
 *
 * Return Value: RateIdx
 *
 -*/
unsigned short
wGetRateIdx(
	unsigned char byRate
)
{
	unsigned short ii;

	/* Erase basicRate flag. */
	byRate = byRate & 0x7F;/* 0111 1111 */

	for (ii = 0; ii < MAX_RATE; ii++) {
		if (acbyIERate[ii] == byRate)
			return ii;
	}

	return 0;
}

/*+
 *
 * Description:
 *      Parsing the highest basic & support rate in rate field of frame.
 *
 * Parameters:
 *  In:
 *      pDevice         - Pointer to the adapter
 *      pItemRates      - Pointer to Rate field defined in 802.11 spec.
 *      pItemExtRates      - Pointer to Extended Rate field defined in 802.11 spec.
 *  Out:
 *      pwMaxBasicRate  - Maximum Basic Rate
 *      pwMaxSuppRate   - Maximum Supported Rate
 *      pbyTopCCKRate   - Maximum Basic Rate in CCK mode
 *      pbyTopOFDMRate  - Maximum Basic Rate in OFDM mode
 *
 * Return Value: none
 *
 -*/
void
RATEvParseMaxRate(
	void *pDeviceHandler,
	PWLAN_IE_SUPP_RATES pItemRates,
	PWLAN_IE_SUPP_RATES pItemExtRates,
	bool bUpdateBasicRate,
	unsigned short *pwMaxBasicRate,
	unsigned short *pwMaxSuppRate,
	unsigned short *pwSuppRate,
	unsigned char *pbyTopCCKRate,
	unsigned char *pbyTopOFDMRate
)
{
	struct vnt_private *pDevice = pDeviceHandler;
	unsigned int ii;
	unsigned char byHighSuppRate = 0;
	unsigned char byRate = 0;
	unsigned short wOldBasicRate = pDevice->wBasicRate;
	unsigned int uRateLen;

	if (pItemRates == NULL)
		return;

	*pwSuppRate = 0;
	uRateLen = pItemRates->len;

	pr_debug("ParseMaxRate Len: %d\n", uRateLen);
	if (pDevice->eCurrentPHYType != PHY_TYPE_11B) {
		if (uRateLen > WLAN_RATES_MAXLEN)
			uRateLen = WLAN_RATES_MAXLEN;
	} else {
		if (uRateLen > WLAN_RATES_MAXLEN_11B)
			uRateLen = WLAN_RATES_MAXLEN_11B;
	}

	for (ii = 0; ii < uRateLen; ii++) {
		byRate = (unsigned char)(pItemRates->abyRates[ii]);
		if (WLAN_MGMT_IS_BASICRATE(byRate) && bUpdateBasicRate)  {
			/* Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate */
			CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate));
			pr_debug("ParseMaxRate AddBasicRate: %d\n",
				 wGetRateIdx(byRate));
		}
		byRate = (unsigned char)(pItemRates->abyRates[ii]&0x7F);
		if (byHighSuppRate == 0)
			byHighSuppRate = byRate;
		if (byRate > byHighSuppRate)
			byHighSuppRate = byRate;
		*pwSuppRate |= (1<<wGetRateIdx(byRate));
	}
	if ((pItemExtRates != NULL) && (pItemExtRates->byElementID == WLAN_EID_EXTSUPP_RATES) &&
	    (pDevice->eCurrentPHYType != PHY_TYPE_11B)) {
		unsigned int uExtRateLen = pItemExtRates->len;

		if (uExtRateLen > WLAN_RATES_MAXLEN)
			uExtRateLen = WLAN_RATES_MAXLEN;

		for (ii = 0; ii < uExtRateLen; ii++) {
			byRate = (unsigned char)(pItemExtRates->abyRates[ii]);
			/* select highest basic rate */
			if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) {
				/* Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate */
				CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate));
				pr_debug("ParseMaxRate AddBasicRate: %d\n",
					 wGetRateIdx(byRate));
			}
			byRate = (unsigned char)(pItemExtRates->abyRates[ii]&0x7F);
			if (byHighSuppRate == 0)
				byHighSuppRate = byRate;
			if (byRate > byHighSuppRate)
				byHighSuppRate = byRate;
			*pwSuppRate |= (1<<wGetRateIdx(byRate));
		}
	}

	if ((pDevice->byPacketType == PK_TYPE_11GB) && CARDbIsOFDMinBasicRate((void *)pDevice))
		pDevice->byPacketType = PK_TYPE_11GA;

	*pbyTopCCKRate = pDevice->byTopCCKBasicRate;
	*pbyTopOFDMRate = pDevice->byTopOFDMBasicRate;
	*pwMaxSuppRate = wGetRateIdx(byHighSuppRate);
	if ((pDevice->byPacketType == PK_TYPE_11B) || (pDevice->byPacketType == PK_TYPE_11GB))
		*pwMaxBasicRate = pDevice->byTopCCKBasicRate;
	else
		*pwMaxBasicRate = pDevice->byTopOFDMBasicRate;
	if (wOldBasicRate != pDevice->wBasicRate)
		CARDvSetRSPINF((void *)pDevice, pDevice->eCurrentPHYType);

	pr_debug("Exit ParseMaxRate\n");
}

/*+
 *
 * Routine Description:
 *      Rate fallback Algorithm Implementaion
 *
 * Parameters:
 *  In:
 *      pDevice         - Pointer to the adapter
 *      psNodeDBTable   - Pointer to Node Data Base
 *  Out:
 *      none
 *
 * Return Value: none
 *
 -*/
#define AUTORATE_TXCNT_THRESHOLD        20
#define AUTORATE_INC_THRESHOLD          30

void
RATEvTxRateFallBack(
	void *pDeviceHandler,
	PKnownNodeDB psNodeDBTable
)
{
	struct vnt_private *pDevice = pDeviceHandler;
	unsigned short wIdxDownRate = 0;
	unsigned int ii;
	bool bAutoRate[MAX_RATE]    = {true, true, true, true, false, false, true, true, true, true, true, true};
	unsigned long dwThroughputTbl[MAX_RATE] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540};
	unsigned long dwThroughput = 0;
	unsigned short wIdxUpRate = 0;
	unsigned long dwTxDiff = 0;

	if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING)
		/* Don't do Fallback when scanning Channel */
		return;

	psNodeDBTable->uTimeCount++;

	if (psNodeDBTable->uTxFail[MAX_RATE] > psNodeDBTable->uTxOk[MAX_RATE])
		dwTxDiff = psNodeDBTable->uTxFail[MAX_RATE] - psNodeDBTable->uTxOk[MAX_RATE];

	if ((psNodeDBTable->uTxOk[MAX_RATE] < AUTORATE_TXOK_CNT) &&
	    (dwTxDiff < AUTORATE_TXFAIL_CNT) &&
	    (psNodeDBTable->uTimeCount < AUTORATE_TIMEOUT)) {
		return;
	}

	if (psNodeDBTable->uTimeCount >= AUTORATE_TIMEOUT)
		psNodeDBTable->uTimeCount = 0;

	for (ii = 0; ii < MAX_RATE; ii++) {
		if (psNodeDBTable->wSuppRate & (0x0001<<ii)) {
			if (bAutoRate[ii])
				wIdxUpRate = (unsigned short) ii;

		} else {
			bAutoRate[ii] = false;
		}
	}

	for (ii = 0; ii <= psNodeDBTable->wTxDataRate; ii++) {
		if ((psNodeDBTable->uTxOk[ii] != 0) ||
		    (psNodeDBTable->uTxFail[ii] != 0)) {
			dwThroughputTbl[ii] *= psNodeDBTable->uTxOk[ii];
			if (ii < RATE_11M)
				psNodeDBTable->uTxFail[ii] *= 4;

			dwThroughputTbl[ii] /= (psNodeDBTable->uTxOk[ii] + psNodeDBTable->uTxFail[ii]);
		}
	}
	dwThroughput = dwThroughputTbl[psNodeDBTable->wTxDataRate];

	wIdxDownRate = psNodeDBTable->wTxDataRate;
	for (ii = psNodeDBTable->wTxDataRate; ii > 0;) {
		ii--;
		if ((dwThroughputTbl[ii] > dwThroughput) && bAutoRate[ii]) {
			dwThroughput = dwThroughputTbl[ii];
			wIdxDownRate = (unsigned short) ii;
		}
	}
	psNodeDBTable->wTxDataRate = wIdxDownRate;
	if (psNodeDBTable->uTxOk[MAX_RATE]) {
		if (psNodeDBTable->uTxOk[MAX_RATE] >
		    (psNodeDBTable->uTxFail[MAX_RATE] * 4)) {
			psNodeDBTable->wTxDataRate = wIdxUpRate;
		}
	} else {
		/* adhoc, if uTxOk =0 & uTxFail = 0 */
		if (psNodeDBTable->uTxFail[MAX_RATE] == 0)
			psNodeDBTable->wTxDataRate = wIdxUpRate;
	}

	/* 2008-5-8 <add> by chester */
	TxRate_iwconfig = psNodeDBTable->wTxDataRate;
	s_vResetCounter(psNodeDBTable);
}

/*+
 *
 * Description:
 *    This routine is used to assemble available Rate IE.
 *
 * Parameters:
 *  In:
 *    pDevice
 *  Out:
 *
 * Return Value: None
 *
 -*/
unsigned char
RATEuSetIE(
	PWLAN_IE_SUPP_RATES pSrcRates,
	PWLAN_IE_SUPP_RATES pDstRates,
	unsigned int uRateLen
)
{
	unsigned int ii, uu, uRateCnt = 0;

	if ((pSrcRates == NULL) || (pDstRates == NULL))
		return 0;

	if (pSrcRates->len == 0)
		return 0;

	for (ii = 0; ii < uRateLen; ii++) {
		for (uu = 0; uu < pSrcRates->len; uu++) {
			if ((pSrcRates->abyRates[uu] & 0x7F) == acbyIERate[ii]) {
				pDstRates->abyRates[uRateCnt++] = pSrcRates->abyRates[uu];
				break;
			}
		}
	}
	return (unsigned char)uRateCnt;
}
