/*
 * 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 int msglevel = MSG_LEVEL_INFO;
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
)
{
	PSDevice  pDevice = (PSDevice) 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;

	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "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));
			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "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));
				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "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);

	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "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
)
{
	PSDevice        pDevice = (PSDevice) 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);

	return;
}

/*+
 *
 * 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;
}
