Kernel  |  3.14

下载     查看原文件
C++程序  |  755行  |  16.68 KB
/*
 * 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) {
		// 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) {
		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) {
		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;
}