/*
 * 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: vntwifi.c
 *
 * Purpose: export functions for vntwifi lib
 *
 * Functions:
 *
 * Revision History:
 *
 * Author: Yiching Chen
 *
 * Date: feb. 2, 2005
 *
 */

#include "vntwifi.h"
#include "IEEE11h.h"
#include "country.h"
#include "device.h"
#include "wmgr.h"
#include "datarate.h"

/*---------------------  Static Definitions -------------------------*/
//static int          msglevel                =MSG_LEVEL_DEBUG;
//static int          msglevel                =MSG_LEVEL_INFO;

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

/*---------------------  Static Variables  --------------------------*/

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

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

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

/*+
 *
 * Description:
 *    Set Operation Mode
 *
 * Parameters:
 *  In:
 *      pMgmtHandle - pointer to management object
 *      eOPMode     - Operation Mode
 *  Out:
 *      none
 *
 * Return Value: none
 *
 -*/
void
VNTWIFIvSetOPMode(
	void *pMgmtHandle,
	WMAC_CONFIG_MODE eOPMode
)
{
	PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;

	pMgmt->eConfigMode = eOPMode;
}

/*+
 *
 * Description:
 *    Set Operation Mode
 *
 * Parameters:
 *  In:
 *      pMgmtHandle - pointer to management object
 *      wBeaconPeriod - Beacon Period
 *      wATIMWindow - ATIM window
 *      uChannel - channel number
 *  Out:
 *      none
 *
 * Return Value: none
 *
 -*/
void
VNTWIFIvSetIBSSParameter(
	void *pMgmtHandle,
	unsigned short wBeaconPeriod,
	unsigned short wATIMWindow,
	unsigned int uChannel
)
{
	PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;

	pMgmt->wIBSSBeaconPeriod = wBeaconPeriod;
	pMgmt->wIBSSATIMWindow = wATIMWindow;
	pMgmt->uIBSSChannel = uChannel;
}

/*+
 *
 * Description:
 *    Get current SSID
 *
 * Parameters:
 *  In:
 *      pMgmtHandle - pointer to management object
 *  Out:
 *      none
 *
 * Return Value: current SSID pointer.
 *
 -*/
PWLAN_IE_SSID
VNTWIFIpGetCurrentSSID(
	void *pMgmtHandle
)
{
	PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
	return (PWLAN_IE_SSID) pMgmt->abyCurrSSID;
}

/*+
 *
 * Description:
 *    Get current link channel
 *
 * Parameters:
 *  In:
 *      pMgmtHandle - pointer to management object
 *  Out:
 *      none
 *
 * Return Value: current Channel.
 *
 -*/
unsigned int
VNTWIFIpGetCurrentChannel(
	void *pMgmtHandle
)
{
	PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
	if (pMgmtHandle != NULL) {
		return pMgmt->uCurrChannel;
	}
	return 0;
}

/*+
 *
 * Description:
 *    Get current Assoc ID
 *
 * Parameters:
 *  In:
 *      pMgmtHandle - pointer to management object
 *  Out:
 *      none
 *
 * Return Value: current Assoc ID
 *
 -*/
unsigned short
VNTWIFIwGetAssocID(
	void *pMgmtHandle
)
{
	PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
	return pMgmt->wCurrAID;
}

/*+
 *
 * Description:
 *    This routine return max support rate of IES
 *
 * Parameters:
 *  In:
 *      pSupportRateIEs
 *      pExtSupportRateIEs
 *
 *  Out:
 *
 * Return Value: max support rate
 *
 -*/
unsigned char
VNTWIFIbyGetMaxSupportRate(
	PWLAN_IE_SUPP_RATES pSupportRateIEs,
	PWLAN_IE_SUPP_RATES pExtSupportRateIEs
)
{
	unsigned char byMaxSupportRate = RATE_1M;
	unsigned char bySupportRate = RATE_1M;
	unsigned int ii = 0;

	if (pSupportRateIEs) {
		for (ii = 0; ii < pSupportRateIEs->len; ii++) {
			bySupportRate = DATARATEbyGetRateIdx(pSupportRateIEs->abyRates[ii]);
			if (bySupportRate > byMaxSupportRate) {
				byMaxSupportRate = bySupportRate;
			}
		}
	}
	if (pExtSupportRateIEs) {
		for (ii = 0; ii < pExtSupportRateIEs->len; ii++) {
			bySupportRate = DATARATEbyGetRateIdx(pExtSupportRateIEs->abyRates[ii]);
			if (bySupportRate > byMaxSupportRate) {
				byMaxSupportRate = bySupportRate;
			}
		}
	}

	return byMaxSupportRate;
}

/*+
 *
 * Description:
 *    This routine return data rate of ACK packtet
 *
 * Parameters:
 *  In:
 *      byRxDataRate
 *      pSupportRateIEs
 *      pExtSupportRateIEs
 *
 *  Out:
 *
 * Return Value: max support rate
 *
 -*/
unsigned char
VNTWIFIbyGetACKTxRate(
	unsigned char byRxDataRate,
	PWLAN_IE_SUPP_RATES pSupportRateIEs,
	PWLAN_IE_SUPP_RATES pExtSupportRateIEs
)
{
	unsigned char byMaxAckRate;
	unsigned char byBasicRate;
	unsigned int ii;

	if (byRxDataRate <= RATE_11M) {
		byMaxAckRate = RATE_1M;
	} else  {
		// 24M is mandatory for 802.11a and 802.11g
		byMaxAckRate = RATE_24M;
	}
	if (pSupportRateIEs) {
		for (ii = 0; ii < pSupportRateIEs->len; ii++) {
			if (pSupportRateIEs->abyRates[ii] & 0x80) {
				byBasicRate = DATARATEbyGetRateIdx(pSupportRateIEs->abyRates[ii]);
				if ((byBasicRate <= byRxDataRate) &&
				    (byBasicRate > byMaxAckRate))  {
					byMaxAckRate = byBasicRate;
				}
			}
		}
	}
	if (pExtSupportRateIEs) {
		for (ii = 0; ii < pExtSupportRateIEs->len; ii++) {
			if (pExtSupportRateIEs->abyRates[ii] & 0x80) {
				byBasicRate = DATARATEbyGetRateIdx(pExtSupportRateIEs->abyRates[ii]);
				if ((byBasicRate <= byRxDataRate) &&
				    (byBasicRate > byMaxAckRate))  {
					byMaxAckRate = byBasicRate;
				}
			}
		}
	}

	return byMaxAckRate;
}

/*+
 *
 * Description:
 *    Set Authentication Mode
 *
 * Parameters:
 *  In:
 *      pMgmtHandle - pointer to management object
 *      eAuthMode   - Authentication mode
 *  Out:
 *      none
 *
 * Return Value: none
 *
 -*/
void
VNTWIFIvSetAuthenticationMode(
	void *pMgmtHandle,
	WMAC_AUTHENTICATION_MODE eAuthMode
)
{
	PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;

	pMgmt->eAuthenMode = eAuthMode;
	if ((eAuthMode == WMAC_AUTH_SHAREKEY) ||
	    (eAuthMode == WMAC_AUTH_AUTO)) {
		pMgmt->bShareKeyAlgorithm = true;
	} else {
		pMgmt->bShareKeyAlgorithm = false;
	}
}

/*+
 *
 * Description:
 *    Set Encryption Mode
 *
 * Parameters:
 *  In:
 *      pMgmtHandle - pointer to management object
 *      eAuthMode   - Authentication mode
 *  Out:
 *      none
 *
 * Return Value: none
 *
 -*/
void
VNTWIFIvSetEncryptionMode(
	void *pMgmtHandle,
	WMAC_ENCRYPTION_MODE eEncryptionMode
)
{
	PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;

	pMgmt->eEncryptionMode = eEncryptionMode;
	if ((eEncryptionMode == WMAC_ENCRYPTION_WEPEnabled) ||
	    (eEncryptionMode == WMAC_ENCRYPTION_TKIPEnabled) ||
	    (eEncryptionMode == WMAC_ENCRYPTION_AESEnabled)) {
		pMgmt->bPrivacyInvoked = true;
	} else {
		pMgmt->bPrivacyInvoked = false;
	}
}

bool
VNTWIFIbConfigPhyMode(
	void *pMgmtHandle,
	CARD_PHY_TYPE ePhyType
)
{
	PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;

	if ((ePhyType != PHY_TYPE_AUTO) &&
	    (ePhyType != pMgmt->eCurrentPHYMode)) {
		if (CARDbSetPhyParameter(pMgmt->pAdapter, ePhyType, 0, 0, NULL, NULL) == true) {
			pMgmt->eCurrentPHYMode = ePhyType;
		} else {
			return false;
		}
	}
	pMgmt->eConfigPHYMode = ePhyType;
	return true;
}

void
VNTWIFIbGetConfigPhyMode(
	void *pMgmtHandle,
	void *pePhyType
)
{
	PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;

	if ((pMgmt != NULL) && (pePhyType != NULL)) {
		*(PCARD_PHY_TYPE)pePhyType = pMgmt->eConfigPHYMode;
	}
}

/*+
 *
 * Description:
 *      Clear BSS List Database except current assoc BSS
 *
 * Parameters:
 *  In:
 *      pMgmtHandle     - Management Object structure
 *      bLinkPass       - Current Link status
 *  Out:
 *
 * Return Value: None.
 *
 -*/

/*+
 *
 * Description:
 *      Query BSS List in management database
 *
 * Parameters:
 *  In:
 *      pMgmtHandle     - Management Object structure
 *  Out:
 *      puBSSCount      - BSS count
 *      pvFirstBSS      - pointer to first BSS
 *
 * Return Value: None.
 *
 -*/

void
VNTWIFIvQueryBSSList(void *pMgmtHandle, unsigned int *puBSSCount, void **pvFirstBSS)
{
	unsigned int ii = 0;
	PSMgmtObject    pMgmt = (PSMgmtObject)pMgmtHandle;
	PKnownBSS       pBSS = NULL;
	unsigned int uCount = 0;

	*pvFirstBSS = NULL;

	for (ii = 0; ii < MAX_BSS_NUM; ii++) {
		pBSS = &(pMgmt->sBSSList[ii]);
		if (!pBSS->bActive) {
			continue;
		}
		if (*pvFirstBSS == NULL) {
			*pvFirstBSS = &(pMgmt->sBSSList[ii]);
		}
		uCount++;
	}
	*puBSSCount = uCount;
}

void
VNTWIFIvGetNextBSS(
	void *pMgmtHandle,
	void *pvCurrentBSS,
	void **pvNextBSS
)
{
	PKnownBSS       pBSS = (PKnownBSS) pvCurrentBSS;
	PSMgmtObject    pMgmt = (PSMgmtObject)pMgmtHandle;

	*pvNextBSS = NULL;

	while (*pvNextBSS == NULL) {
		pBSS++;
		if (pBSS > &(pMgmt->sBSSList[MAX_BSS_NUM])) {
			return;
		}
		if (pBSS->bActive == true) {
			*pvNextBSS = pBSS;
			return;
		}
	}
}

/*+
 *
 * Description:
 *      Update Tx attemps, Tx failure counter in Node DB
 *
 *  In:
 *  Out:
 *      none
 *
 * Return Value: none
 *
 -*/
void
VNTWIFIvUpdateNodeTxCounter(
	void *pMgmtHandle,
	unsigned char *pbyDestAddress,
	bool bTxOk,
	unsigned short wRate,
	unsigned char *pbyTxFailCount
)
{
	PSMgmtObject    pMgmt = (PSMgmtObject)pMgmtHandle;
	unsigned int uNodeIndex = 0;
	unsigned int ii;

	if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ||
	    (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
		if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex) == false) {
			return;
		}
	}
	pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts++;
	if (bTxOk == true) {
		// transmit success, TxAttempts at least plus one
		pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++;
		pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wRate]++;
	} else {
		pMgmt->sNodeDBTable[uNodeIndex].uTxFailures++;
	}
	pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += pbyTxFailCount[MAX_RATE];
	for (ii = 0; ii < MAX_RATE; ii++) {
		pMgmt->sNodeDBTable[uNodeIndex].uTxFail[ii] += pbyTxFailCount[ii];
	}
	return;
}

void
VNTWIFIvGetTxRate(
	void *pMgmtHandle,
	unsigned char *pbyDestAddress,
	unsigned short *pwTxDataRate,
	unsigned char *pbyACKRate,
	unsigned char *pbyCCKBasicRate,
	unsigned char *pbyOFDMBasicRate
)
{
	PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
	unsigned int uNodeIndex = 0;
	unsigned short wTxDataRate = RATE_1M;
	unsigned char byACKRate = RATE_1M;
	unsigned char byCCKBasicRate = RATE_1M;
	unsigned char byOFDMBasicRate = RATE_24M;
	PWLAN_IE_SUPP_RATES pSupportRateIEs = NULL;
	PWLAN_IE_SUPP_RATES pExtSupportRateIEs = NULL;

	if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ||
	    (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
		// Adhoc Tx rate decided from node DB
		if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex)) {
			wTxDataRate = (pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
			pSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrSuppRates);
			pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrExtSuppRates);
		} else {
			if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) {
				wTxDataRate = RATE_2M;
			} else {
				wTxDataRate = RATE_24M;
			}
			pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates;
			pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates;
		}
	} else { // Infrastructure: rate decided from AP Node, index = 0

		wTxDataRate = (pMgmt->sNodeDBTable[0].wTxDataRate);
#ifdef	PLICE_DEBUG
		printk(KERN_DEBUG "GetTxRate:AP MAC is %pM,TxRate is %d\n",
		       pMgmt->sNodeDBTable[0].abyMACAddr, wTxDataRate);
#endif

		pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates;
		pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates;
	}
	byACKRate = VNTWIFIbyGetACKTxRate((unsigned char) wTxDataRate,
					    pSupportRateIEs,
					    pExtSupportRateIEs
);
	if (byACKRate > (unsigned char) wTxDataRate) {
		byACKRate = (unsigned char) wTxDataRate;
	}
	byCCKBasicRate = VNTWIFIbyGetACKTxRate(RATE_11M,
						pSupportRateIEs,
						pExtSupportRateIEs
);
	byOFDMBasicRate = VNTWIFIbyGetACKTxRate(RATE_54M,
						pSupportRateIEs,
						pExtSupportRateIEs
);
	*pwTxDataRate = wTxDataRate;
	*pbyACKRate = byACKRate;
	*pbyCCKBasicRate = byCCKBasicRate;
	*pbyOFDMBasicRate = byOFDMBasicRate;
	return;
}

unsigned char
VNTWIFIbyGetKeyCypher(
	void *pMgmtHandle,
	bool bGroupKey
)
{
	PSMgmtObject    pMgmt = (PSMgmtObject)pMgmtHandle;

	if (bGroupKey == true) {
		return pMgmt->byCSSGK;
	} else {
		return pMgmt->byCSSPK;
	}
}

/*
  bool
  VNTWIFIbInit(
  void *pAdapterHandler,
  void **pMgmtHandler
) {
  PSMgmtObject        pMgmt = NULL;
  unsigned int ii;

  pMgmt = (PSMgmtObject)kmalloc(sizeof(SMgmtObject), (int)GFP_ATOMIC);
  if (pMgmt == NULL) {
  *pMgmtHandler = NULL;
  return false;
  }

  memset(pMgmt, 0, sizeof(SMgmtObject));
  pMgmt->pAdapter = (void *) pAdapterHandler;

  // should initial MAC address abyMACAddr
  for (ii=0; ii<WLAN_BSSID_LEN; ii++) {
  pMgmt->abyDesireBSSID[ii] = 0xFF;
  }
  pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0];
  pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0];
  pMgmt->byCSSPK = KEY_CTL_NONE;
  pMgmt->byCSSGK = KEY_CTL_NONE;
  pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;

  pMgmt->cbFreeCmdQueue = CMD_Q_SIZE;
  pMgmt->uCmdDequeueIdx = 0;
  pMgmt->uCmdEnqueueIdx = 0;
  pMgmt->eCommandState = WLAN_CMD_STATE_IDLE;
  pMgmt->bCmdStop = false;
  pMgmt->bCmdRunning = false;

  *pMgmtHandler = pMgmt;
  return true;
  }
*/

bool
VNTWIFIbSetPMKIDCache(
	void *pMgmtObject,
	unsigned long ulCount,
	void *pPMKIDInfo
)
{
	PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;

	if (ulCount > MAX_PMKID_CACHE) {
		return false;
	}
	pMgmt->gsPMKIDCache.BSSIDInfoCount = ulCount;
	memcpy(pMgmt->gsPMKIDCache.BSSIDInfo, pPMKIDInfo, (ulCount*sizeof(PMKIDInfo)));
	return true;
}

unsigned short
VNTWIFIwGetMaxSupportRate(
	void *pMgmtObject
)
{
	unsigned short wRate = RATE_54M;
	PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;

	for (wRate = RATE_54M; wRate > RATE_1M; wRate--) {
		if (pMgmt->sNodeDBTable[0].wSuppRate & (1<<wRate)) {
			return wRate;
		}
	}
	if (pMgmt->eCurrentPHYMode == PHY_TYPE_11A) {
		return RATE_6M;
	} else {
		return RATE_1M;
	}
}

void
VNTWIFIvSet11h(
	void *pMgmtObject,
	bool b11hEnable
)
{
	PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;

	pMgmt->b11hEnable = b11hEnable;
}

bool
VNTWIFIbMeasureReport(
	void *pMgmtObject,
	bool bEndOfReport,
	void *pvMeasureEID,
	unsigned char byReportMode,
	unsigned char byBasicMap,
	unsigned char byCCAFraction,
	unsigned char *pbyRPIs
)
{
	PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
	unsigned char *pbyCurrentEID = (unsigned char *)(pMgmt->pCurrMeasureEIDRep);

	//spin_lock_irq(&pDevice->lock);
	if ((pvMeasureEID != NULL) &&
	    (pMgmt->uLengthOfRepEIDs < (WLAN_A3FR_MAXLEN - sizeof(MEASEURE_REP) - sizeof(WLAN_80211HDR_A3) - 3))
) {
		pMgmt->pCurrMeasureEIDRep->byElementID = WLAN_EID_MEASURE_REP;
		pMgmt->pCurrMeasureEIDRep->len = 3;
		pMgmt->pCurrMeasureEIDRep->byToken = ((PWLAN_IE_MEASURE_REQ)pvMeasureEID)->byToken;
		pMgmt->pCurrMeasureEIDRep->byMode = byReportMode;
		pMgmt->pCurrMeasureEIDRep->byType = ((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->byType;
		switch (pMgmt->pCurrMeasureEIDRep->byType) {
		case MEASURE_TYPE_BASIC:
			pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_BASIC);
			memcpy(&(pMgmt->pCurrMeasureEIDRep->sRep.sBasic),
			       &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq),
			       sizeof(MEASEURE_REQ));
			pMgmt->pCurrMeasureEIDRep->sRep.sBasic.byMap = byBasicMap;
			break;
		case MEASURE_TYPE_CCA:
			pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_CCA);
			memcpy(&(pMgmt->pCurrMeasureEIDRep->sRep.sCCA),
			       &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq),
			       sizeof(MEASEURE_REQ));
			pMgmt->pCurrMeasureEIDRep->sRep.sCCA.byCCABusyFraction = byCCAFraction;
			break;
		case MEASURE_TYPE_RPI:
			pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_RPI);
			memcpy(&(pMgmt->pCurrMeasureEIDRep->sRep.sRPI),
			       &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq),
			       sizeof(MEASEURE_REQ));
			memcpy(pMgmt->pCurrMeasureEIDRep->sRep.sRPI.abyRPIdensity, pbyRPIs, 8);
			break;
		default:
			break;
		}
		pbyCurrentEID += (2 + pMgmt->pCurrMeasureEIDRep->len);
		pMgmt->uLengthOfRepEIDs += (2 + pMgmt->pCurrMeasureEIDRep->len);
		pMgmt->pCurrMeasureEIDRep = (PWLAN_IE_MEASURE_REP) pbyCurrentEID;
	}
	if (bEndOfReport == true) {
		IEEE11hbMSRRepTx(pMgmt);
	}
	//spin_unlock_irq(&pDevice->lock);
	return true;
}

bool
VNTWIFIbChannelSwitch(
	void *pMgmtObject,
	unsigned char byNewChannel
)
{
	PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;

	//spin_lock_irq(&pDevice->lock);
	pMgmt->uCurrChannel = byNewChannel;
	pMgmt->bSwitchChannel = false;
	//spin_unlock_irq(&pDevice->lock);
	return true;
}

/*
  bool
  VNTWIFIbRadarPresent(
  void *pMgmtObject,
  unsigned char byChannel
) {
  PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
  if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
  (byChannel == (unsigned char) pMgmt->uCurrChannel) &&
  (pMgmt->bSwitchChannel != true) &&
  (pMgmt->b11hEnable == true)) {
  if (!compare_ether_addr(pMgmt->abyIBSSDFSOwner, CARDpGetCurrentAddress(pMgmt->pAdapter))) {
  pMgmt->byNewChannel = CARDbyAutoChannelSelect(pMgmt->pAdapter,(unsigned char) pMgmt->uCurrChannel);
  pMgmt->bSwitchChannel = true;
  }
  BEACONbSendBeacon(pMgmt);
  CARDbChannelSwitch(pMgmt->pAdapter, 0, pMgmt->byNewChannel, 10);
  }
  return true;
  }
*/
