blob: 6fb45f419a23a70adc2773c85ae979d5126f7402 [file] [log] [blame]
/******************************************************************************
*
* This file is provided under a dual license. When you use or
* distribute this software, you may choose to be licensed under
* version 2 of the GNU General Public License ("GPLv2 License")
* or BSD License.
*
* GPLv2 License
*
* Copyright(C) 2016 MediaTek Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* 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 http://www.gnu.org/licenses/gpl-2.0.html for more details.
*
* BSD LICENSE
*
* Copyright(C) 2016 MediaTek Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
/*
** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_oid.c#11
*/
/*! \file wlanoid.c
* \brief This file contains the WLAN OID processing routines of Windows driver for
* MediaTek Inc. 802.11 Wireless LAN Adapters.
*/
/******************************************************************************
* C O M P I L E R F L A G S
*******************************************************************************
*/
/******************************************************************************
* E X T E R N A L R E F E R E N C E S
*******************************************************************************
*/
#include "precomp.h"
#include "mgmt/rsn.h"
#include "gl_wext.h"
#include "debug.h"
#include <stddef.h>
/******************************************************************************
* C O N S T A N T S
*******************************************************************************
*/
/******************************************************************************
* D A T A T Y P E S
*******************************************************************************
*/
/******************************************************************************
* P U B L I C D A T A
*******************************************************************************
*/
PARAM_CUSTOM_KEY_CFG_STRUCT_T g_rDefaulteSetting[] = {
/*format :
*: {"firmware config parameter", "firmware config value"}
*/
{"AdapScan", "0x0"}
};
/******************************************************************************
* P R I V A T E D A T A
*******************************************************************************
*/
/******************************************************************************
* M A C R O S
*******************************************************************************
*/
/******************************************************************************
* F U N C T I O N D E C L A R A T I O N S
*******************************************************************************
*/
#if DBG && 0
static VOID SetRCID(BOOLEAN fgOneTb3, BOOL *fgRCID);
#endif
#if CFG_SLT_SUPPORT
static VOID SetTestChannel(UINT_8 *pucPrimaryChannel);
#endif
/******************************************************************************
* F U N C T I O N S
*******************************************************************************
*/
#if CFG_ENABLE_STATISTICS_BUFFERING
static BOOLEAN IsBufferedStatisticsUsable(P_ADAPTER_T prAdapter)
{
ASSERT(prAdapter);
if (prAdapter->fgIsStatValid == TRUE &&
(kalGetTimeTick() - prAdapter->rStatUpdateTime) <= CFG_STATISTICS_VALID_CYCLE)
return TRUE;
else
return FALSE;
}
#endif
#if DBG && 0
static VOID SetRCID(BOOLEAN fgOneTb3, BOOL *fgRCID)
{
if (fgOneTb3)
*fgRCID = 0;
else
*fgRCID = 1;
}
#endif
#if CFG_SLT_SUPPORT
static VOID SetTestChannel(UINT_8 *pucPrimaryChannel)
{
if (*pucPrimaryChannel < 5)
*pucPrimaryChannel = 8;
else if (*pucPrimaryChannel > 10)
*pucPrimaryChannel = 3;
}
#endif
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to query the supported physical layer network
* type that can be used by the driver.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
* the query.
* \param[in] u4QueryBufferLen The length of the query buffer.
* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
* bytes written into the query buffer. If the call
* failed due to invalid length of the query buffer,
* returns the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_INVALID_LENGTH
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidQueryNetworkTypesSupported(IN P_ADAPTER_T prAdapter,
OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
{
UINT_32 u4NumItem = 0;
ENUM_PARAM_NETWORK_TYPE_T eSupportedNetworks[PARAM_NETWORK_TYPE_NUM];
PPARAM_NETWORK_TYPE_LIST prSupported;
/* The array of all physical layer network subtypes that the driver supports. */
DEBUGFUNC("wlanoidQueryNetworkTypesSupported");
ASSERT(prAdapter);
ASSERT(pu4QueryInfoLen);
if (u4QueryBufferLen)
ASSERT(pvQueryBuffer);
/* Init. */
for (u4NumItem = 0; u4NumItem < PARAM_NETWORK_TYPE_NUM; u4NumItem++)
eSupportedNetworks[u4NumItem] = 0;
u4NumItem = 0;
eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_DS;
u4NumItem++;
eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_OFDM24;
u4NumItem++;
*pu4QueryInfoLen =
(UINT_32) OFFSET_OF(PARAM_NETWORK_TYPE_LIST, eNetworkType) +
(u4NumItem * sizeof(ENUM_PARAM_NETWORK_TYPE_T));
if (u4QueryBufferLen < *pu4QueryInfoLen)
return WLAN_STATUS_INVALID_LENGTH;
prSupported = (PPARAM_NETWORK_TYPE_LIST) pvQueryBuffer;
prSupported->NumberOfItems = u4NumItem;
kalMemCopy(prSupported->eNetworkType, eSupportedNetworks, u4NumItem * sizeof(ENUM_PARAM_NETWORK_TYPE_T));
DBGLOG(REQ, TRACE, "NDIS supported network type list: %ld\n", prSupported->NumberOfItems);
DBGLOG_MEM8(REQ, INFO, prSupported, *pu4QueryInfoLen);
return WLAN_STATUS_SUCCESS;
} /* wlanoidQueryNetworkTypesSupported */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to query the current physical layer network
* type used by the driver.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
* the query.
* \param[in] u4QueryBufferLen The length of the query buffer.
* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
* bytes written into the query buffer. If the
* call failed due to invalid length of the query
* buffer, returns the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_BUFFER_TOO_SHORT
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidQueryNetworkTypeInUse(IN P_ADAPTER_T prAdapter,
OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
{
/* TODO: need to check the OID handler content again!! */
ENUM_PARAM_NETWORK_TYPE_T rCurrentNetworkTypeInUse = PARAM_NETWORK_TYPE_OFDM24;
DEBUGFUNC("wlanoidQueryNetworkTypeInUse");
ASSERT(prAdapter);
ASSERT(pu4QueryInfoLen);
if (u4QueryBufferLen)
ASSERT(pvQueryBuffer);
if (u4QueryBufferLen < sizeof(ENUM_PARAM_NETWORK_TYPE_T)) {
*pu4QueryInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T);
return WLAN_STATUS_BUFFER_TOO_SHORT;
}
if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED)
rCurrentNetworkTypeInUse = (ENUM_PARAM_NETWORK_TYPE_T) (prAdapter->rWlanInfo.ucNetworkType);
else
rCurrentNetworkTypeInUse = (ENUM_PARAM_NETWORK_TYPE_T) (prAdapter->rWlanInfo.ucNetworkTypeInUse);
*(P_ENUM_PARAM_NETWORK_TYPE_T) pvQueryBuffer = rCurrentNetworkTypeInUse;
*pu4QueryInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T);
DBGLOG(REQ, TRACE, "Network type in use: %d\n", rCurrentNetworkTypeInUse);
return WLAN_STATUS_SUCCESS;
} /* wlanoidQueryNetworkTypeInUse */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to set the physical layer network type used
* by the driver.
*
* \param[in] pvAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns the
* amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS The given network type is supported and accepted.
* \retval WLAN_STATUS_INVALID_DATA The given network type is not in the
* supported list.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetNetworkTypeInUse(IN P_ADAPTER_T prAdapter,
IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
/* TODO: need to check the OID handler content again!! */
ENUM_PARAM_NETWORK_TYPE_T eNewNetworkType;
WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
DEBUGFUNC("wlanoidSetNetworkTypeInUse");
ASSERT(prAdapter);
ASSERT(pvSetBuffer);
ASSERT(pu4SetInfoLen);
if (u4SetBufferLen < sizeof(ENUM_PARAM_NETWORK_TYPE_T)) {
*pu4SetInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T);
return WLAN_STATUS_INVALID_LENGTH;
}
eNewNetworkType = *(P_ENUM_PARAM_NETWORK_TYPE_T) pvSetBuffer;
*pu4SetInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T);
DBGLOG(REQ, INFO, "New network type: %d mode\n", eNewNetworkType);
switch (eNewNetworkType) {
case PARAM_NETWORK_TYPE_DS:
prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_DS;
break;
case PARAM_NETWORK_TYPE_OFDM5:
prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_OFDM5;
break;
case PARAM_NETWORK_TYPE_OFDM24:
prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_OFDM24;
break;
case PARAM_NETWORK_TYPE_AUTOMODE:
prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_AUTOMODE;
break;
case PARAM_NETWORK_TYPE_FH:
DBGLOG(REQ, INFO, "Not support network type: %d\n", eNewNetworkType);
rStatus = WLAN_STATUS_NOT_SUPPORTED;
break;
default:
DBGLOG(REQ, INFO, "Unknown network type: %d\n", eNewNetworkType);
rStatus = WLAN_STATUS_INVALID_DATA;
break;
}
/* Verify if we support the new network type. */
if (rStatus != WLAN_STATUS_SUCCESS)
DBGLOG(REQ, WARN, "Unknown network type: %d\n", eNewNetworkType);
return rStatus;
} /* wlanoidSetNetworkTypeInUse */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to query the current BSSID.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
* the query.
* \param[in] u4QueryBufferLen The length of the query buffer.
* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
* bytes written into the query buffer. If the call
* failed due to invalid length of the query buffer,
* returns the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_ADAPTER_NOT_READY
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidQueryBssid(IN P_ADAPTER_T prAdapter,
OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
{
WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
DEBUGFUNC("wlanoidQueryBssid");
ASSERT(prAdapter);
if (u4QueryBufferLen < MAC_ADDR_LEN) {
ASSERT(pu4QueryInfoLen);
*pu4QueryInfoLen = MAC_ADDR_LEN;
return WLAN_STATUS_BUFFER_TOO_SHORT;
}
ASSERT(u4QueryBufferLen >= MAC_ADDR_LEN);
if (u4QueryBufferLen)
ASSERT(pvQueryBuffer);
ASSERT(pu4QueryInfoLen);
if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED)
kalMemCopy(pvQueryBuffer, prAdapter->rWlanInfo.rCurrBssId.arMacAddress, MAC_ADDR_LEN);
else if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS) {
PARAM_MAC_ADDRESS aucTemp; /*!< BSSID */
COPY_MAC_ADDR(aucTemp, prAdapter->rWlanInfo.rCurrBssId.arMacAddress);
aucTemp[0] &= ~BIT(0);
aucTemp[1] |= BIT(1);
COPY_MAC_ADDR(pvQueryBuffer, aucTemp);
} else
rStatus = WLAN_STATUS_ADAPTER_NOT_READY;
*pu4QueryInfoLen = MAC_ADDR_LEN;
return rStatus;
} /* wlanoidQueryBssid */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to query the list of all BSSIDs detected by
* the driver.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
* the query.
* \param[in] u4QueryBufferLen The length of the query buffer.
* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
* bytes written into the query buffer. If the call
* failed due to invalid length of the query buffer,
* returns the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_INVALID_LENGTH
* \retval WLAN_STATUS_ADAPTER_NOT_READY
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidQueryBssidList(IN P_ADAPTER_T prAdapter,
OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
{
P_GLUE_INFO_T prGlueInfo;
UINT_32 i, u4BssidListExLen;
P_PARAM_BSSID_LIST_EX_T prList;
P_PARAM_BSSID_EX_T prBssidEx;
PUINT_8 cp;
DEBUGFUNC("wlanoidQueryBssidList");
ASSERT(prAdapter);
ASSERT(pu4QueryInfoLen);
if (u4QueryBufferLen) {
ASSERT(pvQueryBuffer);
if (!pvQueryBuffer)
return WLAN_STATUS_INVALID_DATA;
}
prGlueInfo = prAdapter->prGlueInfo;
if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN,
"Fail in qeury BSSID list! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
u4BssidListExLen = 0;
if (prAdapter->fgIsRadioOff == FALSE) {
for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++)
u4BssidListExLen += ALIGN_4(prAdapter->rWlanInfo.arScanResult[i].u4Length);
}
if (u4BssidListExLen)
u4BssidListExLen += 4; /* u4NumberOfItems. */
else
u4BssidListExLen = sizeof(PARAM_BSSID_LIST_EX_T);
*pu4QueryInfoLen = u4BssidListExLen;
if (u4QueryBufferLen < *pu4QueryInfoLen)
return WLAN_STATUS_INVALID_LENGTH;
/* Clear the buffer */
kalMemZero(pvQueryBuffer, u4BssidListExLen);
prList = (P_PARAM_BSSID_LIST_EX_T) pvQueryBuffer;
cp = (PUINT_8) &prList->arBssid[0];
if (prAdapter->fgIsRadioOff == FALSE && prAdapter->rWlanInfo.u4ScanResultNum > 0) {
/* fill up for each entry */
for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) {
prBssidEx = (P_PARAM_BSSID_EX_T) cp;
/* copy structure */
kalMemCopy(prBssidEx,
&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs));
/*For WHQL test, Rssi should be in range -10 ~ -200 dBm */
if (prBssidEx->rRssi > PARAM_WHQL_RSSI_MAX_DBM)
prBssidEx->rRssi = PARAM_WHQL_RSSI_MAX_DBM;
if (prAdapter->rWlanInfo.arScanResult[i].u4IELength > 0) {
/* copy IEs */
kalMemCopy(prBssidEx->aucIEs,
prAdapter->rWlanInfo.apucScanResultIEs[i],
prAdapter->rWlanInfo.arScanResult[i].u4IELength);
}
/* 4-bytes alignement */
prBssidEx->u4Length = ALIGN_4(prBssidEx->u4Length);
cp += prBssidEx->u4Length;
prList->u4NumberOfItems++;
}
}
return WLAN_STATUS_SUCCESS;
} /* wlanoidQueryBssidList */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to request the driver to perform
* scanning.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_ADAPTER_NOT_READY
* \retval WLAN_STATUS_FAILURE
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetBssidListScan(IN P_ADAPTER_T prAdapter,
IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
P_PARAM_SSID_T prSsid;
PARAM_SSID_T rSsid;
DEBUGFUNC("wlanoidSetBssidListScan()");
if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN,
"Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
ASSERT(pu4SetInfoLen);
*pu4SetInfoLen = 0;
if (prAdapter->fgIsRadioOff) {
DBGLOG(REQ, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_SUCCESS;
}
if (pvSetBuffer != NULL && u4SetBufferLen != 0) {
COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, pvSetBuffer, u4SetBufferLen);
prSsid = &rSsid;
} else {
prSsid = NULL;
}
#if CFG_SUPPORT_RDD_TEST_MODE
if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) {
if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) {
if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED)
aisFsmScanRequest(prAdapter, prSsid, NULL, 0);
else
return WLAN_STATUS_FAILURE;
} else
return WLAN_STATUS_FAILURE;
} else
#endif
{
if (prAdapter->fgEnOnlineScan == TRUE)
aisFsmScanRequest(prAdapter, prSsid, NULL, 0);
else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED)
aisFsmScanRequest(prAdapter, prSsid, NULL, 0);
else
return WLAN_STATUS_FAILURE;
}
return WLAN_STATUS_SUCCESS;
} /* wlanoidSetBssidListScan */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to request the driver to perform
* scanning with attaching information elements(IEs) specified from user space
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_ADAPTER_NOT_READY
* \retval WLAN_STATUS_FAILURE
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetBssidListScanExt(IN P_ADAPTER_T prAdapter,
IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
P_PARAM_SCAN_REQUEST_EXT_T prScanRequest;
P_PARAM_SSID_T prSsid;
PUINT_8 pucIe;
UINT_32 u4IeLength;
DEBUGFUNC("wlanoidSetBssidListScanExt()");
if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN,
"Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
ASSERT(pu4SetInfoLen);
*pu4SetInfoLen = 0;
if (u4SetBufferLen != sizeof(PARAM_SCAN_REQUEST_EXT_T))
return WLAN_STATUS_INVALID_LENGTH;
if (prAdapter->fgIsRadioOff) {
DBGLOG(REQ, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_SUCCESS;
}
DBGLOG(AIS, INFO, "ScanEX\n");
if (pvSetBuffer != NULL && u4SetBufferLen != 0) {
prScanRequest = (P_PARAM_SCAN_REQUEST_EXT_T) pvSetBuffer;
prSsid = &(prScanRequest->rSsid);
pucIe = prScanRequest->pucIE;
u4IeLength = prScanRequest->u4IELength;
} else {
prScanRequest = NULL;
prSsid = NULL;
pucIe = NULL;
u4IeLength = 0;
}
#if CFG_SUPPORT_RDD_TEST_MODE
if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) {
if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) {
if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED)
aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength);
else
return WLAN_STATUS_FAILURE;
} else
return WLAN_STATUS_FAILURE;
} else
#endif
{
if (prAdapter->fgEnOnlineScan == TRUE)
aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength);
else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED)
aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength);
else
return WLAN_STATUS_FAILURE;
}
return WLAN_STATUS_SUCCESS;
} /* wlanoidSetBssidListScanWithIE */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to request the driver to perform
* scanning with attaching information elements(IEs) specified from user space
* and multiple SSID
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_ADAPTER_NOT_READY
* \retval WLAN_STATUS_FAILURE
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetBssidListScanAdv(IN P_ADAPTER_T prAdapter,
IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
P_PARAM_SCAN_REQUEST_ADV_T prScanRequest;
PARAM_SSID_T rSsid[CFG_SCAN_SSID_MAX_NUM];
PUINT_8 pucIe;
UINT_8 ucSsidNum;
UINT_32 i, u4IeLength;
DEBUGFUNC("wlanoidSetBssidListScanAdv()");
if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN,
"Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
ASSERT(pu4SetInfoLen);
*pu4SetInfoLen = 0;
if (u4SetBufferLen != sizeof(PARAM_SCAN_REQUEST_ADV_T))
return WLAN_STATUS_INVALID_LENGTH;
else if (pvSetBuffer == NULL)
return WLAN_STATUS_INVALID_DATA;
if (prAdapter->fgIsRadioOff) {
DBGLOG(REQ, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_SUCCESS;
}
prScanRequest = (P_PARAM_SCAN_REQUEST_ADV_T) pvSetBuffer;
ucSsidNum = (UINT_8) (prScanRequest->u4SsidNum);
for (i = 0; i < prScanRequest->u4SsidNum; i++) {
if (prScanRequest->rSsid[i].u4SsidLen > ELEM_MAX_LEN_SSID) {
DBGLOG(REQ, ERROR,
"[%s] SSID(%s) Length(%ld) is over than ELEM_MAX_LEN_SSID(%d)\n",
__func__, prScanRequest->rSsid[i].aucSsid,
prScanRequest->rSsid[i].u4SsidLen, ELEM_MAX_LEN_SSID);
DBGLOG_MEM8(REQ, ERROR, prScanRequest, sizeof(PARAM_SCAN_REQUEST_ADV_T));
}
COPY_SSID(rSsid[i].aucSsid,
rSsid[i].u4SsidLen, prScanRequest->rSsid[i].aucSsid, prScanRequest->rSsid[i].u4SsidLen);
}
pucIe = prScanRequest->pucIE;
u4IeLength = prScanRequest->u4IELength;
#if CFG_SUPPORT_RDD_TEST_MODE
if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) {
if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) {
if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED)
#if CFG_SCAN_CHANNEL_SPECIFIED
aisFsmScanRequestAdv(prAdapter, ucSsidNum, rSsid,
prScanRequest->ucChannelListNum, prScanRequest->arChnlInfoList,
pucIe, u4IeLength);
#else
aisFsmScanRequestAdv(prAdapter, ucSsidNum, rSsid, 0, NULL, pucIe, u4IeLength);
#endif
else
return WLAN_STATUS_FAILURE;
} else
return WLAN_STATUS_FAILURE;
} else
#endif
{
if (prAdapter->fgEnOnlineScan == TRUE)
#if CFG_SCAN_CHANNEL_SPECIFIED
aisFsmScanRequestAdv(prAdapter, ucSsidNum, rSsid,
prScanRequest->ucChannelListNum, prScanRequest->arChnlInfoList,
pucIe, u4IeLength);
#else
aisFsmScanRequestAdv(prAdapter, ucSsidNum, rSsid, 0, NULL, pucIe, u4IeLength);
#endif
else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED)
#if CFG_SCAN_CHANNEL_SPECIFIED
aisFsmScanRequestAdv(prAdapter, ucSsidNum, rSsid,
prScanRequest->ucChannelListNum, prScanRequest->arChnlInfoList,
pucIe, u4IeLength);
#else
aisFsmScanRequestAdv(prAdapter, ucSsidNum, rSsid, 0, NULL, pucIe, u4IeLength);
#endif
else
return WLAN_STATUS_FAILURE;
}
cnmTimerStartTimer(prAdapter, &prAdapter->rWifiVar.rAisFsmInfo.rScanDoneTimer,
SEC_TO_MSEC(AIS_SCN_DONE_TIMEOUT_SEC));
return WLAN_STATUS_SUCCESS;
} /* wlanoidSetBssidListScanAdv */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine will initiate the join procedure to attempt to associate
* with the specified BSSID.
*
* \param[in] pvAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_INVALID_LENGTH
* \retval WLAN_STATUS_INVALID_DATA
* \retval WLAN_STATUS_ADAPTER_NOT_READY
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetBssid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
P_GLUE_INFO_T prGlueInfo;
P_UINT_8 pAddr;
UINT_32 i;
INT_32 i4Idx = -1;
P_MSG_AIS_ABORT_T prAisAbortMsg;
UINT_8 ucReasonOfDisconnect;
ASSERT(prAdapter);
ASSERT(pu4SetInfoLen);
*pu4SetInfoLen = MAC_ADDR_LEN;
if (u4SetBufferLen != MAC_ADDR_LEN) {
*pu4SetInfoLen = MAC_ADDR_LEN;
return WLAN_STATUS_INVALID_LENGTH;
} else if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
prGlueInfo = prAdapter->prGlueInfo;
pAddr = (P_UINT_8) pvSetBuffer;
/* re-association check */
if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) {
if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr)) {
kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED);
ucReasonOfDisconnect = DISCONNECT_REASON_CODE_REASSOCIATION;
} else {
kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION;
}
} else {
ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION;
}
/* check if any scanned result matchs with the BSSID */
for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) {
if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) {
i4Idx = (INT_32) i;
break;
}
}
/* prepare message to AIS */
if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS
|| prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_DEDICATED_IBSS) {
/* IBSS *//* beacon period */
prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod;
prAdapter->rWifiVar.rConnSettings.u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow;
}
/* Set Connection Request Issued Flag */
prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE;
prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_BSSID;
/* Send AIS Abort Message */
prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T));
if (!prAisAbortMsg) {
DBGLOG(REQ, ERROR, "Fail in allocating AisAbortMsg.\n");
return WLAN_STATUS_FAILURE;
}
prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ;
prAisAbortMsg->ucReasonOfDisconnect = ucReasonOfDisconnect;
/* Update the information to CONNECTION_SETTINGS_T */
prAdapter->rWifiVar.rConnSettings.ucSSIDLen = 0;
prAdapter->rWifiVar.rConnSettings.aucSSID[0] = '\0';
COPY_MAC_ADDR(prAdapter->rWifiVar.rConnSettings.aucBSSID, pAddr);
if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr))
prAisAbortMsg->fgDelayIndication = TRUE;
else
prAisAbortMsg->fgDelayIndication = FALSE;
mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF);
return WLAN_STATUS_SUCCESS;
} /* end of wlanoidSetBssid() */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine will initiate the join procedure to attempt
* to associate with the new SSID. If the previous scanning
* result is aged, we will scan the channels at first.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_INVALID_DATA
* \retval WLAN_STATUS_ADAPTER_NOT_READY
* \retval WLAN_STATUS_INVALID_LENGTH
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetSsid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
P_GLUE_INFO_T prGlueInfo;
P_PARAM_SSID_T pParamSsid;
UINT_32 i;
INT_32 i4Idx = -1, i4MaxRSSI = INT_MIN;
P_MSG_AIS_ABORT_T prAisAbortMsg;
BOOLEAN fgIsValidSsid = TRUE;
ASSERT(prAdapter);
ASSERT(pu4SetInfoLen);
/* MSDN:
* Powering on the radio if the radio is powered off through a setting of OID_802_11_DISASSOCIATE
*/
if (prAdapter->fgIsRadioOff == TRUE)
prAdapter->fgIsRadioOff = FALSE;
if (u4SetBufferLen < sizeof(PARAM_SSID_T) || u4SetBufferLen > sizeof(PARAM_SSID_T))
return WLAN_STATUS_INVALID_LENGTH;
else if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
pParamSsid = (P_PARAM_SSID_T) pvSetBuffer;
if (pParamSsid->u4SsidLen > 32)
return WLAN_STATUS_INVALID_LENGTH;
prGlueInfo = prAdapter->prGlueInfo;
/* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */
/* re-association check */
if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) {
if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid,
prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen,
pParamSsid->aucSsid, pParamSsid->u4SsidLen)) {
kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED);
} else
kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
}
/* check if any scanned result matchs with the SSID */
for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) {
PUINT_8 aucSsid = prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid;
UINT_8 ucSsidLength = (UINT_8) prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen;
INT_32 i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi;
if (EQUAL_SSID(aucSsid, ucSsidLength, pParamSsid->aucSsid, pParamSsid->u4SsidLen) &&
i4RSSI >= i4MaxRSSI) {
i4Idx = (INT_32) i;
i4MaxRSSI = i4RSSI;
}
}
/* prepare message to AIS */
if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS
|| prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_DEDICATED_IBSS) {
/* IBSS *//* beacon period */
prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod;
prAdapter->rWifiVar.rConnSettings.u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow;
}
if (prAdapter->rWifiVar.fgSupportWZCDisassociation) {
if (pParamSsid->u4SsidLen == ELEM_MAX_LEN_SSID) {
fgIsValidSsid = FALSE;
for (i = 0; i < ELEM_MAX_LEN_SSID; i++) {
if (!((pParamSsid->aucSsid[i] > 0)
&& (pParamSsid->aucSsid[i] <= 0x1F))) {
fgIsValidSsid = TRUE;
break;
}
}
}
}
/* Set Connection Request Issued Flag */
if (fgIsValidSsid) {
prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE;
if (pParamSsid->u4SsidLen)
prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI;
else
/* wildcard SSID */
prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_SSID_ANY;
} else
prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE;
/* Send AIS Abort Message */
prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T));
if (!prAisAbortMsg) {
DBGLOG(REQ, ERROR, "Fail in allocating AisAbortMsg.\n");
return WLAN_STATUS_FAILURE;
}
prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ;
prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION;
COPY_SSID(prAdapter->rWifiVar.rConnSettings.aucSSID,
prAdapter->rWifiVar.rConnSettings.ucSSIDLen, pParamSsid->aucSsid, (UINT_8) pParamSsid->u4SsidLen);
if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid,
prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, pParamSsid->aucSsid, pParamSsid->u4SsidLen)) {
prAisAbortMsg->fgDelayIndication = TRUE;
} else {
/* Update the information to CONNECTION_SETTINGS_T */
prAisAbortMsg->fgDelayIndication = FALSE;
}
DBGLOG(SCN, INFO, "SSID %s\n", prAdapter->rWifiVar.rConnSettings.aucSSID);
mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF);
return WLAN_STATUS_SUCCESS;
} /* end of wlanoidSetSsid() */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine will initiate the join procedure to attempt
* to associate with the new BSS, base on given SSID, BSSID, and freqency.
* If the target connecting BSS is in the same ESS as current connected BSS, roaming
* will be performed.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_INVALID_DATA
* \retval WLAN_STATUS_ADAPTER_NOT_READY
* \retval WLAN_STATUS_INVALID_LENGTH
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetConnect(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
P_GLUE_INFO_T prGlueInfo;
P_PARAM_CONNECT_T pParamConn;
P_CONNECTION_SETTINGS_T prConnSettings;
UINT_32 i;
P_MSG_AIS_ABORT_T prAisAbortMsg;
BOOLEAN fgIsValidSsid = TRUE;
BOOLEAN fgEqualSsid = FALSE;
BOOLEAN fgEqualBssid = FALSE;
const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR;
ASSERT(prAdapter);
ASSERT(pu4SetInfoLen);
/* MSDN:
* Powering on the radio if the radio is powered off through a setting of OID_802_11_DISASSOCIATE
*/
if (prAdapter->fgIsRadioOff == TRUE)
prAdapter->fgIsRadioOff = FALSE;
if (u4SetBufferLen != sizeof(PARAM_CONNECT_T))
return WLAN_STATUS_INVALID_LENGTH;
else if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T));
if (!prAisAbortMsg) {
DBGLOG(REQ, ERROR, "Fail in allocating AisAbortMsg.\n");
return WLAN_STATUS_FAILURE;
}
prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ;
pParamConn = (P_PARAM_CONNECT_T) pvSetBuffer;
prConnSettings = &prAdapter->rWifiVar.rConnSettings;
if (pParamConn->u4SsidLen > 32)
return WLAN_STATUS_INVALID_LENGTH;
else if (!pParamConn->pucBssid && !pParamConn->pucSsid)
return WLAN_STATUS_INVALID_LENGTH;
prGlueInfo = prAdapter->prGlueInfo;
kalMemZero(prConnSettings->aucSSID, sizeof(prConnSettings->aucSSID));
prConnSettings->ucSSIDLen = 0;
kalMemZero(prConnSettings->aucBSSID, sizeof(prConnSettings->aucBSSID));
prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_ANY;
prConnSettings->fgIsConnByBssidIssued = FALSE;
if (pParamConn->pucSsid) {
prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI;
COPY_SSID(prConnSettings->aucSSID,
prConnSettings->ucSSIDLen, pParamConn->pucSsid, (UINT_8) pParamConn->u4SsidLen);
if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid,
prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen,
pParamConn->pucSsid, pParamConn->u4SsidLen))
fgEqualSsid = TRUE;
}
if (pParamConn->pucBssid) {
if (!EQUAL_MAC_ADDR(aucZeroMacAddr, pParamConn->pucBssid) && IS_UCAST_MAC_ADDR(pParamConn->pucBssid)) {
prConnSettings->eConnectionPolicy = CONNECT_BY_BSSID;
prConnSettings->fgIsConnByBssidIssued = TRUE;
COPY_MAC_ADDR(prConnSettings->aucBSSID, pParamConn->pucBssid);
if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pParamConn->pucBssid))
fgEqualBssid = TRUE;
} else
DBGLOG(INIT, INFO, "wrong bssid " MACSTR "to connect\n", MAC2STR(pParamConn->pucBssid));
} else
DBGLOG(INIT, INFO, "No Bssid set\n");
prConnSettings->u4FreqInKHz = pParamConn->u4CenterFreq;
/* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */
/* re-association check */
if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) {
if (fgEqualSsid) {
prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_REASSOCIATION;
if (fgEqualBssid)
kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED);
} else {
DBGLOG(INIT, INFO, "DisBySsid\n");
kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION;
}
} else
prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION;
#if 0
/* check if any scanned result matchs with the SSID */
for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) {
PUINT_8 aucSsid = prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid;
UINT_8 ucSsidLength = (UINT_8) prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen;
INT_32 i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi;
if (EQUAL_SSID(aucSsid, ucSsidLength, pParamConn->pucSsid, pParamConn->u4SsidLen) &&
i4RSSI >= i4MaxRSSI) {
i4Idx = (INT_32) i;
i4MaxRSSI = i4RSSI;
}
if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) {
i4Idx = (INT_32) i;
break;
}
}
#endif
/* prepare message to AIS */
if (prConnSettings->eOPMode == NET_TYPE_IBSS || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) {
/* IBSS *//* beacon period */
prConnSettings->u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod;
prConnSettings->u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow;
}
if (prAdapter->rWifiVar.fgSupportWZCDisassociation) {
if (pParamConn->u4SsidLen == ELEM_MAX_LEN_SSID) {
fgIsValidSsid = FALSE;
if (pParamConn->pucSsid) {
for (i = 0; i < ELEM_MAX_LEN_SSID; i++) {
if (!((pParamConn->pucSsid[i] > 0) && (pParamConn->pucSsid[i] <= 0x1F))) {
fgIsValidSsid = TRUE;
break;
}
}
} else {
DBGLOG(INIT, ERROR, "pParamConn->pucSsid is NULL\n");
}
}
}
/* Set Connection Request Issued Flag */
if (fgIsValidSsid)
prConnSettings->fgIsConnReqIssued = TRUE;
else
prConnSettings->fgIsConnReqIssued = FALSE;
if (fgEqualSsid || fgEqualBssid)
prAisAbortMsg->fgDelayIndication = TRUE;
else
/* Update the information to CONNECTION_SETTINGS_T */
prAisAbortMsg->fgDelayIndication = FALSE;
mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF);
DBGLOG(INIT, INFO, "ssid %s, bssid " MACSTR ", conn policy %d, disc reason %d\n",
prConnSettings->aucSSID, MAC2STR(prConnSettings->aucBSSID),
prConnSettings->eConnectionPolicy, prAisAbortMsg->ucReasonOfDisconnect);
return WLAN_STATUS_SUCCESS;
} /* end of wlanoidSetConnect */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to query the currently associated SSID.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of
* the query.
* \param[in] u4QueryBufferLen The length of the query buffer.
* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
* bytes written into the query buffer. If the call
* failed due to invalid length of the query buffer,
* returns the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_INVALID_LENGTH
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidQuerySsid(IN P_ADAPTER_T prAdapter,
OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
{
P_PARAM_SSID_T prAssociatedSsid;
DEBUGFUNC("wlanoidQuerySsid");
ASSERT(prAdapter);
ASSERT(pu4QueryInfoLen);
if (u4QueryBufferLen)
ASSERT(pvQueryBuffer);
*pu4QueryInfoLen = sizeof(PARAM_SSID_T);
/* Check for query buffer length */
if (u4QueryBufferLen < *pu4QueryInfoLen) {
DBGLOG(REQ, WARN, "Invalid length %lu\n", u4QueryBufferLen);
return WLAN_STATUS_INVALID_LENGTH;
}
prAssociatedSsid = (P_PARAM_SSID_T) pvQueryBuffer;
kalMemZero(prAssociatedSsid->aucSsid, sizeof(prAssociatedSsid->aucSsid));
if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) {
prAssociatedSsid->u4SsidLen = prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen;
if (prAssociatedSsid->u4SsidLen) {
kalMemCopy(prAssociatedSsid->aucSsid,
prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, prAssociatedSsid->u4SsidLen);
}
} else {
prAssociatedSsid->u4SsidLen = 0;
DBGLOG(REQ, TRACE, "Null SSID\n");
}
return WLAN_STATUS_SUCCESS;
} /* wlanoidQuerySsid */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to query the current 802.11 network type.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of
* the query.
* \param[in] u4QueryBufferLen The length of the query buffer.
* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
* bytes written into the query buffer. If the call
* failed due to invalid length of the query buffer,
* returns the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_BUFFER_TOO_SHORT
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidQueryInfrastructureMode(IN P_ADAPTER_T prAdapter,
OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
{
DEBUGFUNC("wlanoidQueryInfrastructureMode");
ASSERT(prAdapter);
ASSERT(pu4QueryInfoLen);
*pu4QueryInfoLen = sizeof(ENUM_PARAM_OP_MODE_T);
if (u4QueryBufferLen < sizeof(ENUM_PARAM_OP_MODE_T))
return WLAN_STATUS_BUFFER_TOO_SHORT;
if (u4QueryBufferLen)
ASSERT(pvQueryBuffer);
*(P_ENUM_PARAM_OP_MODE_T) pvQueryBuffer = prAdapter->rWifiVar.rConnSettings.eOPMode;
/*
** According to OID_802_11_INFRASTRUCTURE_MODE
** If there is no prior OID_802_11_INFRASTRUCTURE_MODE,
** NDIS_STATUS_ADAPTER_NOT_READY shall be returned.
*/
#if DBG
switch (*(P_ENUM_PARAM_OP_MODE_T) pvQueryBuffer) {
case NET_TYPE_IBSS:
DBGLOG(REQ, INFO, "IBSS mode\n");
break;
case NET_TYPE_INFRA:
DBGLOG(REQ, INFO, "Infrastructure mode\n");
break;
default:
DBGLOG(REQ, INFO, "Automatic mode\n");
}
#endif
return WLAN_STATUS_SUCCESS;
} /* wlanoidQueryInfrastructureMode */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to set mode to infrastructure or
* IBSS, or automatic switch between the two.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed due to invalid
* length of the set buffer, returns the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_INVALID_DATA
* \retval WLAN_STATUS_ADAPTER_NOT_READY
* \retval WLAN_STATUS_INVALID_LENGTH
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetInfrastructureMode(IN P_ADAPTER_T prAdapter,
IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
P_GLUE_INFO_T prGlueInfo;
ENUM_PARAM_OP_MODE_T eOpMode;
/* P_WLAN_TABLE_T prWlanTable; */
#if CFG_SUPPORT_802_11W
/* P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; */
#endif
/* P_BSS_INFO_T prBssInfo; */
/* UINT_8 i; */
DEBUGFUNC("wlanoidSetInfrastructureMode");
ASSERT(prAdapter);
ASSERT(pvSetBuffer);
ASSERT(pu4SetInfoLen);
prGlueInfo = prAdapter->prGlueInfo;
if (u4SetBufferLen < sizeof(ENUM_PARAM_OP_MODE_T))
return WLAN_STATUS_BUFFER_TOO_SHORT;
*pu4SetInfoLen = sizeof(ENUM_PARAM_OP_MODE_T);
if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN,
"Fail in set infrastructure mode! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
eOpMode = *(P_ENUM_PARAM_OP_MODE_T) pvSetBuffer;
/* Verify the new infrastructure mode. */
if (eOpMode >= NET_TYPE_NUM) {
DBGLOG(REQ, TRACE, "Invalid mode value %d\n", eOpMode);
return WLAN_STATUS_INVALID_DATA;
}
/* check if possible to switch to AdHoc mode */
if (eOpMode == NET_TYPE_IBSS || eOpMode == NET_TYPE_DEDICATED_IBSS) {
if (cnmAisIbssIsPermitted(prAdapter) == FALSE) {
DBGLOG(REQ, TRACE, "Mode value %d unallowed\n", eOpMode);
return WLAN_STATUS_FAILURE;
}
}
/* Save the new infrastructure mode setting. */
prAdapter->rWifiVar.rConnSettings.eOPMode = eOpMode;
prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE;
#if CFG_SUPPORT_WAPI
prAdapter->prGlueInfo->u2WapiAssocInfoIESz = 0;
kalMemZero(&prAdapter->prGlueInfo->aucWapiAssocInfoIEs, 42);
#endif
#if CFG_SUPPORT_802_11W
prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE;
prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled = FALSE;
#endif
#if CFG_SUPPORT_WPS2
kalMemZero(&prAdapter->prGlueInfo->aucWSCAssocInfoIE, 200);
prAdapter->prGlueInfo->u2WSCAssocInfoIELen = 0;
#endif
#if 0 /* STA record remove at AIS_ABORT nicUpdateBss and DISCONNECT */
for (i = 0; i < BSS_INFO_NUM; i++) {
prBssInfo = prAdapter->aprBssInfo[i];
if (prBssInfo->eNetworkType == NETWORK_TYPE_AIS)
cnmStaFreeAllStaByNetwork(prAdapter, prBssInfo->ucBssIndex, 0);
}
#endif
/* Clean up the Tx key flag */
prAdapter->prAisBssInfo->fgBcDefaultKeyExist = FALSE;
prAdapter->prAisBssInfo->ucBcDefaultKeyIdx = 0xFF;
/* prWlanTable = prAdapter->rWifiVar.arWtbl; */
/* prWlanTable[prAdapter->prAisBssInfo->ucBMCWlanIndex].ucKeyId = 0; */
#if DBG
DBGLOG(RSN, TRACE, "wlanoidSetInfrastructureMode\n");
#endif
return wlanSendSetQueryCmd(prAdapter,
CMD_ID_INFRASTRUCTURE,
TRUE,
FALSE,
TRUE,
nicCmdEventSetCommon, nicOidCmdTimeoutCommon, 0, NULL, pvSetBuffer, u4SetBufferLen);
} /* wlanoidSetInfrastructureMode */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to query the current 802.11 authentication
* mode.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
* the query.
* \param[in] u4QueryBufferLen The length of the query buffer.
* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
* bytes written into the query buffer. If the call
* failed due to invalid length of the query buffer,
* returns the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_BUFFER_TOO_SHORT
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidQueryAuthMode(IN P_ADAPTER_T prAdapter,
OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
{
DEBUGFUNC("wlanoidQueryAuthMode");
ASSERT(prAdapter);
if (u4QueryBufferLen)
ASSERT(pvQueryBuffer);
ASSERT(pu4QueryInfoLen);
*pu4QueryInfoLen = sizeof(ENUM_PARAM_AUTH_MODE_T);
if (u4QueryBufferLen < sizeof(ENUM_PARAM_AUTH_MODE_T))
return WLAN_STATUS_BUFFER_TOO_SHORT;
*(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer = prAdapter->rWifiVar.rConnSettings.eAuthMode;
#if DBG
switch (*(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer) {
case AUTH_MODE_OPEN:
DBGLOG(REQ, INFO, "Current auth mode: Open\n");
break;
case AUTH_MODE_SHARED:
DBGLOG(REQ, INFO, "Current auth mode: Shared\n");
break;
case AUTH_MODE_AUTO_SWITCH:
DBGLOG(REQ, INFO, "Current auth mode: Auto-switch\n");
break;
case AUTH_MODE_WPA:
DBGLOG(REQ, INFO, "Current auth mode: WPA\n");
break;
case AUTH_MODE_WPA_PSK:
DBGLOG(REQ, INFO, "Current auth mode: WPA PSK\n");
break;
case AUTH_MODE_WPA_NONE:
DBGLOG(REQ, INFO, "Current auth mode: WPA None\n");
break;
case AUTH_MODE_WPA2:
DBGLOG(REQ, INFO, "Current auth mode: WPA2\n");
break;
case AUTH_MODE_WPA2_PSK:
DBGLOG(REQ, INFO, "Current auth mode: WPA2 PSK\n");
break;
default:
DBGLOG(REQ, INFO, "Current auth mode: %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer);
break;
}
#endif
return WLAN_STATUS_SUCCESS;
} /* wlanoidQueryAuthMode */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to set the IEEE 802.11 authentication mode
* to the driver.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_INVALID_DATA
* \retval WLAN_STATUS_INVALID_LENGTH
* \retval WLAN_STATUS_ADAPTER_NOT_READY
* \retval WLAN_STATUS_NOT_ACCEPTED
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetAuthMode(IN P_ADAPTER_T prAdapter,
IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
P_GLUE_INFO_T prGlueInfo;
/* UINT_32 i, u4AkmSuite; */
/* P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry; */
DEBUGFUNC("wlanoidSetAuthMode");
ASSERT(prAdapter);
ASSERT(pu4SetInfoLen);
ASSERT(pvSetBuffer);
prGlueInfo = prAdapter->prGlueInfo;
*pu4SetInfoLen = sizeof(ENUM_PARAM_AUTH_MODE_T);
if (u4SetBufferLen < sizeof(ENUM_PARAM_AUTH_MODE_T))
return WLAN_STATUS_INVALID_LENGTH;
/* RF Test */
/* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */
/* return WLAN_STATUS_SUCCESS; */
/* } */
if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN,
"Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
/* Check if the new authentication mode is valid. */
if (*(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer >= AUTH_MODE_NUM) {
DBGLOG(REQ, TRACE, "Invalid auth mode %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer);
return WLAN_STATUS_INVALID_DATA;
}
switch (*(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer) {
case AUTH_MODE_WPA:
case AUTH_MODE_WPA_PSK:
case AUTH_MODE_WPA2:
case AUTH_MODE_WPA2_PSK:
/* infrastructure mode only */
if (prAdapter->rWifiVar.rConnSettings.eOPMode != NET_TYPE_INFRA)
return WLAN_STATUS_NOT_ACCEPTED;
break;
case AUTH_MODE_WPA_NONE:
/* ad hoc mode only */
if (prAdapter->rWifiVar.rConnSettings.eOPMode != NET_TYPE_IBSS)
return WLAN_STATUS_NOT_ACCEPTED;
break;
default:
break;
}
/* Save the new authentication mode. */
prAdapter->rWifiVar.rConnSettings.eAuthMode = *(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer;
#if 1 /* DBG */
switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) {
case AUTH_MODE_OPEN:
DBGLOG(RSN, TRACE, "New auth mode: open\n");
break;
case AUTH_MODE_SHARED:
DBGLOG(RSN, TRACE, "New auth mode: shared\n");
break;
case AUTH_MODE_AUTO_SWITCH:
DBGLOG(RSN, TRACE, "New auth mode: auto-switch\n");
break;
case AUTH_MODE_WPA:
DBGLOG(RSN, TRACE, "New auth mode: WPA\n");
break;
case AUTH_MODE_WPA_PSK:
DBGLOG(RSN, TRACE, "New auth mode: WPA PSK\n");
break;
case AUTH_MODE_WPA_NONE:
DBGLOG(RSN, TRACE, "New auth mode: WPA None\n");
break;
case AUTH_MODE_WPA2:
DBGLOG(RSN, TRACE, "New auth mode: WPA2\n");
break;
case AUTH_MODE_WPA2_PSK:
DBGLOG(RSN, TRACE, "New auth mode: WPA2 PSK\n");
break;
default:
DBGLOG(RSN, TRACE, "New auth mode: unknown (%d)\n", prAdapter->rWifiVar.rConnSettings.eAuthMode);
}
#endif
#if 0
if (prAdapter->rWifiVar.rConnSettings.eAuthMode >= AUTH_MODE_WPA) {
switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) {
case AUTH_MODE_WPA:
u4AkmSuite = WPA_AKM_SUITE_802_1X;
break;
case AUTH_MODE_WPA_PSK:
u4AkmSuite = WPA_AKM_SUITE_PSK;
break;
case AUTH_MODE_WPA_NONE:
u4AkmSuite = WPA_AKM_SUITE_NONE;
break;
case AUTH_MODE_WPA2:
u4AkmSuite = RSN_AKM_SUITE_802_1X;
break;
case AUTH_MODE_WPA2_PSK:
u4AkmSuite = RSN_AKM_SUITE_PSK;
break;
default:
u4AkmSuite = 0;
}
} else {
u4AkmSuite = 0;
}
/* Enable the specific AKM suite only. */
for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) {
prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i];
if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite)
prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE;
else
prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = FALSE;
#if CFG_SUPPORT_802_11W
if (kalGetMfpSetting(prAdapter->prGlueInfo) != RSN_AUTH_MFP_DISABLED) {
if ((u4AkmSuite == RSN_AKM_SUITE_PSK) &&
prEntry->dot11RSNAConfigAuthenticationSuite == RSN_AKM_SUITE_PSK_SHA256) {
DBGLOG(RSN, TRACE, "Enable RSN_AKM_SUITE_PSK_SHA256 AKM support\n");
prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE;
}
if ((u4AkmSuite == RSN_AKM_SUITE_802_1X) &&
prEntry->dot11RSNAConfigAuthenticationSuite == RSN_AKM_SUITE_802_1X_SHA256) {
DBGLOG(RSN, TRACE, "Enable RSN_AKM_SUITE_802_1X_SHA256 AKM support\n");
prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE;
}
}
#endif
}
#endif
return WLAN_STATUS_SUCCESS;
} /* wlanoidSetAuthMode */
#if 0
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to query the current 802.11 privacy filter
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
* the query.
* \param[in] u4QueryBufferLen The length of the query buffer.
* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
* bytes written into the query buffer. If the call
* failed due to invalid length of the query buffer,
* returns the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_BUFFER_TOO_SHORT
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidQueryPrivacyFilter(IN P_ADAPTER_T prAdapter,
OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
{
DEBUGFUNC("wlanoidQueryPrivacyFilter");
ASSERT(prAdapter);
ASSERT(pvQueryBuffer);
ASSERT(pu4QueryInfoLen);
*pu4QueryInfoLen = sizeof(ENUM_PARAM_PRIVACY_FILTER_T);
if (u4QueryBufferLen < sizeof(ENUM_PARAM_PRIVACY_FILTER_T))
return WLAN_STATUS_BUFFER_TOO_SHORT;
*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvQueryBuffer = prAdapter->rWlanInfo.ePrivacyFilter;
#if DBG
switch (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvQueryBuffer) {
case PRIVACY_FILTER_ACCEPT_ALL:
DBGLOG(REQ, INFO, "Current privacy mode: open mode\n");
break;
case PRIVACY_FILTER_8021xWEP:
DBGLOG(REQ, INFO, "Current privacy mode: filtering mode\n");
break;
default:
DBGLOG(REQ, INFO, "Current auth mode: %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer);
}
#endif
return WLAN_STATUS_SUCCESS;
} /* wlanoidQueryPrivacyFilter */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to set the IEEE 802.11 privacy filter
* to the driver.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_INVALID_DATA
* \retval WLAN_STATUS_INVALID_LENGTH
* \retval WLAN_STATUS_ADAPTER_NOT_READY
* \retval WLAN_STATUS_NOT_ACCEPTED
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetPrivacyFilter(IN P_ADAPTER_T prAdapter,
IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
P_GLUE_INFO_T prGlueInfo;
DEBUGFUNC("wlanoidSetPrivacyFilter");
ASSERT(prAdapter);
ASSERT(pu4SetInfoLen);
ASSERT(pvSetBuffer);
prGlueInfo = prAdapter->prGlueInfo;
*pu4SetInfoLen = sizeof(ENUM_PARAM_PRIVACY_FILTER_T);
if (u4SetBufferLen < sizeof(ENUM_PARAM_PRIVACY_FILTER_T))
return WLAN_STATUS_INVALID_LENGTH;
if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN,
"Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
/* Check if the new authentication mode is valid. */
if (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer >= PRIVACY_FILTER_NUM) {
DBGLOG(REQ, TRACE, "Invalid privacy filter %d\n", *(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer);
return WLAN_STATUS_INVALID_DATA;
}
switch (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer) {
default:
break;
}
/* Save the new authentication mode. */
prAdapter->rWlanInfo.ePrivacyFilter = *(ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer;
return WLAN_STATUS_SUCCESS;
} /* wlanoidSetPrivacyFilter */
#endif
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to reload the available default settings for
* the specified type field.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_ADAPTER_NOT_READY
* \retval WLAN_STATUS_INVALID_DATA
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetReloadDefaults(IN P_ADAPTER_T prAdapter,
IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
ENUM_PARAM_NETWORK_TYPE_T eNetworkType;
UINT_32 u4Len;
UINT_8 ucCmdSeqNum;
DEBUGFUNC("wlanoidSetReloadDefaults");
ASSERT(prAdapter);
ASSERT(pu4SetInfoLen);
*pu4SetInfoLen = sizeof(PARAM_RELOAD_DEFAULTS);
/* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */
/* return WLAN_STATUS_SUCCESS; */
/* } */
if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN,
"Fail in set Reload default! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
ASSERT(pvSetBuffer);
/* Verify the available reload options and reload the settings. */
switch (*(P_PARAM_RELOAD_DEFAULTS) pvSetBuffer) {
case ENUM_RELOAD_WEP_KEYS:
/* Reload available default WEP keys from the permanent
* storage.
*/
prAdapter->rWifiVar.rConnSettings.eAuthMode = AUTH_MODE_OPEN;
/* ENUM_ENCRYPTION_DISABLED; */
prAdapter->rWifiVar.rConnSettings.eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT;
{
P_GLUE_INFO_T prGlueInfo;
P_CMD_INFO_T prCmdInfo;
P_WIFI_CMD_T prWifiCmd;
P_CMD_802_11_KEY prCmdKey;
UINT_8 aucBCAddr[] = BC_MAC_ADDR;
prGlueInfo = prAdapter->prGlueInfo;
prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY)));
if (!prCmdInfo) {
DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
return WLAN_STATUS_FAILURE;
}
/* increase command sequence number */
ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
/* compose CMD_802_11_KEY cmd pkt */
prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL;
prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY);
prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon;
prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon;
prCmdInfo->fgIsOid = TRUE;
prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY;
prCmdInfo->fgSetQuery = TRUE;
prCmdInfo->fgNeedResp = FALSE;
prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
prCmdInfo->u4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T);
prCmdInfo->pvInformationBuffer = pvSetBuffer;
prCmdInfo->u4InformationBufferLength = u4SetBufferLen;
/* Setup WIFI_CMD_T */
prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen;
prWifiCmd->u2PQ_ID = CMD_PQ_ID;
prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID;
prWifiCmd->ucCID = prCmdInfo->ucCID;
prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer);
kalMemZero((PUINT_8) prCmdKey, sizeof(CMD_802_11_KEY));
prCmdKey->ucAddRemove = 0; /* Remove */
prCmdKey->ucKeyId = 0; /* (UINT_8)(prRemovedKey->u4KeyIndex & 0x000000ff); */
kalMemCopy(prCmdKey->aucPeerAddr, aucBCAddr, MAC_ADDR_LEN);
ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM);
prCmdKey->ucKeyType = 0;
/* insert into prCmdQueue */
kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
/* wakeup txServiceThread later */
GLUE_SET_EVENT(prGlueInfo);
return WLAN_STATUS_PENDING;
}
break;
default:
DBGLOG(REQ, TRACE, "Invalid reload option %d\n", *(P_PARAM_RELOAD_DEFAULTS) pvSetBuffer);
rStatus = WLAN_STATUS_INVALID_DATA;
}
/* OID_802_11_RELOAD_DEFAULTS requiest to reset to auto mode */
eNetworkType = PARAM_NETWORK_TYPE_AUTOMODE;
wlanoidSetNetworkTypeInUse(prAdapter, &eNetworkType, sizeof(eNetworkType), &u4Len);
return rStatus;
} /* wlanoidSetReloadDefaults */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to set a WEP key to the driver.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_INVALID_LENGTH
* \retval WLAN_STATUS_INVALID_DATA
* \retval WLAN_STATUS_ADAPTER_NOT_READY
* \retval WLAN_STATUS_BUFFER_TOO_SHORT
*/
/*----------------------------------------------------------------------------*/
#ifdef LINUX
UINT_8 keyBuffer[sizeof(PARAM_KEY_T) + 16 /* LEGACY_KEY_MAX_LEN */];
UINT_8 aucBCAddr[] = BC_MAC_ADDR;
#endif
WLAN_STATUS
wlanoidSetAddWep(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
#ifndef LINUX
UINT_8 keyBuffer[sizeof(PARAM_KEY_T) + 16 /* LEGACY_KEY_MAX_LEN */];
UINT_8 aucBCAddr[] = BC_MAC_ADDR;
#endif
P_PARAM_WEP_T prNewWepKey;
P_PARAM_KEY_T prParamKey = (P_PARAM_KEY_T) keyBuffer;
UINT_32 u4KeyId, u4SetLen;
DEBUGFUNC("wlanoidSetAddWep");
ASSERT(prAdapter);
*pu4SetInfoLen = OFFSET_OF(PARAM_WEP_T, aucKeyMaterial);
if (u4SetBufferLen < OFFSET_OF(PARAM_WEP_T, aucKeyMaterial)) {
ASSERT(pu4SetInfoLen);
return WLAN_STATUS_BUFFER_TOO_SHORT;
}
ASSERT(pvSetBuffer);
ASSERT(pu4SetInfoLen);
if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN, "Fail in set add WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
prNewWepKey = (P_PARAM_WEP_T) pvSetBuffer;
/* Verify the total buffer for minimum length. */
if (u4SetBufferLen < OFFSET_OF(PARAM_WEP_T, aucKeyMaterial) + prNewWepKey->u4KeyLength) {
DBGLOG(REQ, WARN, "Invalid total buffer length (%d) than minimum length (%d)\n",
(UINT_8) u4SetBufferLen, (UINT_8) OFFSET_OF(PARAM_WEP_T, aucKeyMaterial));
*pu4SetInfoLen = OFFSET_OF(PARAM_WEP_T, aucKeyMaterial);
return WLAN_STATUS_INVALID_DATA;
}
/* Verify the key structure length. */
if (prNewWepKey->u4Length > u4SetBufferLen) {
DBGLOG(REQ, WARN,
"Invalid key structure length (%d) greater than total buffer length (%d)\n",
(UINT_8) prNewWepKey->u4Length, (UINT_8) u4SetBufferLen);
*pu4SetInfoLen = u4SetBufferLen;
return WLAN_STATUS_INVALID_DATA;
}
/* Verify the key material length for maximum key material length:16 */
if (prNewWepKey->u4KeyLength > 16 /* LEGACY_KEY_MAX_LEN */) {
DBGLOG(REQ, WARN,
"Invalid key material length (%d) greater than maximum key material length (16)\n",
(UINT_8) prNewWepKey->u4KeyLength);
*pu4SetInfoLen = u4SetBufferLen;
return WLAN_STATUS_INVALID_DATA;
}
*pu4SetInfoLen = u4SetBufferLen;
u4KeyId = prNewWepKey->u4KeyIndex & BITS(0, 29) /* WEP_KEY_ID_FIELD */;
/* Verify whether key index is valid or not, current version
* driver support only 4 global WEP keys setting by this OID
*/
if (u4KeyId > MAX_KEY_NUM - 1) {
DBGLOG(REQ, ERROR, "Error, invalid WEP key ID: %d\n", (UINT_8) u4KeyId);
return WLAN_STATUS_INVALID_DATA;
}
prParamKey->u4KeyIndex = u4KeyId;
/* Transmit key */
if (prNewWepKey->u4KeyIndex & IS_TRANSMIT_KEY)
prParamKey->u4KeyIndex |= IS_TRANSMIT_KEY;
/* Per client key */
if (prNewWepKey->u4KeyIndex & IS_UNICAST_KEY)
prParamKey->u4KeyIndex |= IS_UNICAST_KEY;
prParamKey->u4KeyLength = prNewWepKey->u4KeyLength;
kalMemCopy(prParamKey->arBSSID, aucBCAddr, MAC_ADDR_LEN);
kalMemCopy(prParamKey->aucKeyMaterial, prNewWepKey->aucKeyMaterial, prNewWepKey->u4KeyLength);
prParamKey->ucBssIdx = prAdapter->prAisBssInfo->ucBssIndex;
if (prParamKey->u4KeyLength == WEP_40_LEN)
prParamKey->ucCipher = CIPHER_SUITE_WEP40;
else if (prParamKey->u4KeyLength == WEP_104_LEN)
prParamKey->ucCipher = CIPHER_SUITE_WEP104;
else if (prParamKey->u4KeyLength == WEP_128_LEN)
prParamKey->ucCipher = CIPHER_SUITE_WEP128;
prParamKey->u4Length = OFFSET_OF(PARAM_KEY_T, aucKeyMaterial) + prNewWepKey->u4KeyLength;
wlanoidSetAddKey(prAdapter, (PVOID) prParamKey, prParamKey->u4Length, &u4SetLen);
return WLAN_STATUS_PENDING;
} /* wlanoidSetAddWep */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to request the driver to remove the WEP key
* at the specified key index.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_INVALID_DATA
* \retval WLAN_STATUS_INVALID_LENGTH
* \retval WLAN_STATUS_ADAPTER_NOT_READY
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetRemoveWep(IN P_ADAPTER_T prAdapter,
IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
UINT_32 u4KeyId, u4SetLen;
PARAM_REMOVE_KEY_T rRemoveKey;
UINT_8 aucBCAddr[] = BC_MAC_ADDR;
DEBUGFUNC("wlanoidSetRemoveWep");
ASSERT(prAdapter);
ASSERT(pu4SetInfoLen);
*pu4SetInfoLen = sizeof(PARAM_KEY_INDEX);
if (u4SetBufferLen < sizeof(PARAM_KEY_INDEX))
return WLAN_STATUS_INVALID_LENGTH;
ASSERT(pvSetBuffer);
u4KeyId = *(PUINT_32) pvSetBuffer;
/* Dump PARAM_WEP content. */
DBGLOG(REQ, INFO, "Set: Dump PARAM_KEY_INDEX content\n");
DBGLOG(REQ, INFO, "Index : 0x%08lx\n", u4KeyId);
if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN,
"Fail in set remove WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
if (u4KeyId & IS_TRANSMIT_KEY) {
/* Bit 31 should not be set */
DBGLOG(REQ, ERROR, "Invalid WEP key index: 0x%08lx\n", u4KeyId);
return WLAN_STATUS_INVALID_DATA;
}
u4KeyId &= BITS(0, 7);
/* Verify whether key index is valid or not. Current version
* driver support only 4 global WEP keys.
*/
if (u4KeyId > MAX_KEY_NUM - 1) {
DBGLOG(REQ, ERROR, "invalid WEP key ID %lu\n", u4KeyId);
return WLAN_STATUS_INVALID_DATA;
}
rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T);
rRemoveKey.u4KeyIndex = *(PUINT_32) pvSetBuffer;
kalMemCopy(rRemoveKey.arBSSID, aucBCAddr, MAC_ADDR_LEN);
wlanoidSetRemoveKey(prAdapter, (PVOID)&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T), &u4SetLen);
return WLAN_STATUS_PENDING;
} /* wlanoidSetRemoveWep */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to set a key to the driver.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_ADAPTER_NOT_READY
* \retval WLAN_STATUS_INVALID_LENGTH
* \retval WLAN_STATUS_INVALID_DATA
*
* \note The setting buffer PARAM_KEY_T, which is set by NDIS, is unpacked.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
P_GLUE_INFO_T prGlueInfo;
P_CMD_INFO_T prCmdInfo;
P_WIFI_CMD_T prWifiCmd;
P_PARAM_KEY_T prNewKey;
P_CMD_802_11_KEY prCmdKey;
UINT_8 ucCmdSeqNum;
P_BSS_INFO_T prBssInfo;
P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
P_STA_RECORD_T prStaRec = NULL;
BOOL fgNoHandshakeSec = FALSE;
#if CFG_SUPPORT_TDLS
P_STA_RECORD_T prTmpStaRec;
#endif
DEBUGFUNC("wlanoidSetAddKey");
DBGLOG(REQ, LOUD, "\n");
ASSERT(prAdapter);
ASSERT(pvSetBuffer);
ASSERT(pu4SetInfoLen);
DBGLOG(RSN, INFO, "wlanoidSetAddKey\n");
if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(RSN, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
prNewKey = (P_PARAM_KEY_T) pvSetBuffer;
/* Verify the key structure length. */
if (prNewKey->u4Length > u4SetBufferLen) {
DBGLOG(RSN, WARN,
"Invalid key structure length (%d) greater than total buffer length (%d)\n",
(UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen);
*pu4SetInfoLen = u4SetBufferLen;
return WLAN_STATUS_INVALID_LENGTH;
}
/* Verify the key material length for key material buffer */
if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) {
DBGLOG(RSN, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength);
*pu4SetInfoLen = u4SetBufferLen;
return WLAN_STATUS_INVALID_DATA;
}
/* Exception check */
if (prNewKey->u4KeyIndex & 0x0fffff00)
return WLAN_STATUS_INVALID_DATA;
/* Exception check, pairwise key must with transmit bit enabled */
if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY)
return WLAN_STATUS_INVALID_DATA;
if (!(prNewKey->u4KeyLength == WEP_40_LEN || prNewKey->u4KeyLength == WEP_104_LEN ||
prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN)) {
return WLAN_STATUS_INVALID_DATA;
}
/* Exception check, pairwise key must with transmit bit enabled */
if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) {
if (/* ((prNewKey->u4KeyIndex & 0xff) != 0) || */
((prNewKey->arBSSID[0] == 0xff) && (prNewKey->arBSSID[1] == 0xff)
&& (prNewKey->arBSSID[2] == 0xff) && (prNewKey->arBSSID[3] == 0xff)
&& (prNewKey->arBSSID[4] == 0xff) && (prNewKey->arBSSID[5] == 0xff))) {
return WLAN_STATUS_INVALID_DATA;
}
}
*pu4SetInfoLen = u4SetBufferLen;
/* Dump PARAM_KEY content. */
DBGLOG(RSN, INFO, "Set: Dump PARAM_KEY content\n");
DBGLOG(RSN, INFO, "Length : 0x%08lx\n", prNewKey->u4Length);
DBGLOG(RSN, INFO, "Key Index : 0x%08lx\n", prNewKey->u4KeyIndex);
DBGLOG(RSN, INFO, "Key Length: 0x%08lx\n", prNewKey->u4KeyLength);
DBGLOG(RSN, INFO, "BSSID:\n");
DBGLOG(RSN, INFO, MACSTR "\n", MAC2STR(prNewKey->arBSSID));
DBGLOG(RSN, INFO, "Cipher : %d\n", prNewKey->ucCipher);
DBGLOG(RSN, TRACE, "Key RSC:\n");
DBGLOG_MEM8(RSN, TRACE, &prNewKey->rKeyRSC, sizeof(PARAM_KEY_RSC));
DBGLOG(RSN, INFO, "Key Material:\n");
DBGLOG_MEM8(RSN, INFO, prNewKey->aucKeyMaterial, prNewKey->u4KeyLength);
prGlueInfo = prAdapter->prGlueInfo;
prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prNewKey->ucBssIdx);
if (!prBssInfo) {
DBGLOG(REQ, INFO, "BSS Info not exist !!\n");
return WLAN_STATUS_SUCCESS;
}
/* Tx Rx KeyType addr
* STA, GC:
* case1: 1 1 0 BC addr (no sta record of AP at this moment) WEP,
* notice: tx at default key setting WEP key now save to BSS_INFO
* case2: 0 1 0 BSSID (sta record of AP) RSN BC key
* case3: 1 1 1 AP addr (sta record of AP) RSN STA key
*
* GO:
* case1: 1 1 0 BSSID (no sta record) WEP -- Not support
* case2: 1 0 0 BSSID (no sta record) RSN BC key
* case3: 1 1 1 STA addr STA key
*/
if (prNewKey->ucCipher == CIPHER_SUITE_WEP40 ||
prNewKey->ucCipher == CIPHER_SUITE_WEP104 || prNewKey->ucCipher == CIPHER_SUITE_WEP128) {
/* check if the key no need handshake, then save to bss wep key for global usage */
fgNoHandshakeSec = TRUE;
}
if (fgNoHandshakeSec) {
#if DBG
if (IS_BSS_AIS(prBssInfo)) {
if (prAdapter->rWifiVar.rConnSettings.eAuthMode >= AUTH_MODE_WPA
&& prAdapter->rWifiVar.rConnSettings.eAuthMode != AUTH_MODE_WPA_NONE) {
DBGLOG(RSN, WARN, "Set wep at not open/shared setting\n");
return WLAN_STATUS_SUCCESS;
}
}
#endif
}
if ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) {
prStaRec = cnmGetStaRecByAddress(prAdapter, prBssInfo->ucBssIndex, prNewKey->arBSSID);
if (!prStaRec) { /* Already disconnected ? */
DBGLOG(REQ, INFO, "[wlan] Not set the peer key while disconnect\n");
return WLAN_STATUS_SUCCESS;
}
}
prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY)));
if (!prCmdInfo) {
DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
return WLAN_STATUS_FAILURE;
}
/* increase command sequence number */
ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
DBGLOG(REQ, INFO, "ucCmdSeqNum = %d\n", ucCmdSeqNum);
/* compose CMD_802_11_KEY cmd pkt */
prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL;
prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY);
#if CFG_SUPPORT_REPLAY_DETECTION
prCmdInfo->pfCmdDoneHandler = nicCmdEventSetAddKey;
prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutSetAddKey;
#else
prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon;
prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon;
#endif
prCmdInfo->fgIsOid = TRUE;
prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY;
prCmdInfo->fgSetQuery = TRUE;
prCmdInfo->fgNeedResp = FALSE;
prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
prCmdInfo->u4SetInfoLen = u4SetBufferLen;
prCmdInfo->pvInformationBuffer = pvSetBuffer;
prCmdInfo->u4InformationBufferLength = u4SetBufferLen;
/* Setup WIFI_CMD_T */
prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen;
prWifiCmd->u2PQ_ID = CMD_PQ_ID;
prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID;
prWifiCmd->ucCID = prCmdInfo->ucCID;
prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer);
kalMemZero(prCmdKey, sizeof(CMD_802_11_KEY));
prCmdKey->ucAddRemove = 1; /* Add */
prCmdKey->ucTxKey = ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) ? 1 : 0;
prCmdKey->ucKeyType = ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) ? 1 : 0;
prCmdKey->ucIsAuthenticator = ((prNewKey->u4KeyIndex & IS_AUTHENTICATOR) == IS_AUTHENTICATOR) ? 1 : 0;
/* Copy the addr of the key */
if ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) {
if (prStaRec) {
/* Overwrite the fgNoHandshakeSec in case */
fgNoHandshakeSec = FALSE; /* Legacy 802.1x wep case ? */
/* ASSERT(FALSE); */
}
} else {
if (!IS_BSS_ACTIVE(prBssInfo))
DBGLOG(REQ, INFO, "[wlan] BSS info (%d) not active yet!", prNewKey->ucBssIdx);
}
prCmdKey->ucBssIdx = prBssInfo->ucBssIndex;
prCmdKey->ucKeyId = (UINT_8) (prNewKey->u4KeyIndex & 0xff);
/* Note: the key length may not correct for WPA-None */
prCmdKey->ucKeyLen = (UINT_8) prNewKey->u4KeyLength;
kalMemCopy(prCmdKey->aucKeyMaterial, (PUINT_8) prNewKey->aucKeyMaterial, prCmdKey->ucKeyLen);
if (prNewKey->ucCipher) {
prCmdKey->ucAlgorithmId = prNewKey->ucCipher;
if (IS_BSS_AIS(prBssInfo)) {
#if CFG_SUPPORT_802_11W
if (prCmdKey->ucAlgorithmId == CIPHER_SUITE_BIP) {
if (prCmdKey->ucKeyId >= 4) {
P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
prAisSpecBssInfo->fgBipKeyInstalled = TRUE;
}
}
#endif
if ((prCmdKey->ucAlgorithmId == CIPHER_SUITE_CCMP) && rsnCheckPmkidCandicate(prAdapter)) {
DBGLOG(RSN, TRACE, "Add key: Prepare a timer to indicate candidate PMKID Candidate\n");
cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer);
cnmTimerStartTimer(prAdapter,
&prAisSpecBssInfo->rPreauthenticationTimer,
SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC));
}
if (prCmdKey->ucAlgorithmId == CIPHER_SUITE_TKIP) {
/* Todo:: Support AP mode defragment */
/* for pairwise key only */
if ((prNewKey->u4KeyIndex & BITS(30, 31)) == ((IS_UNICAST_KEY) | (IS_TRANSMIT_KEY))) {
kalMemCopy(prAdapter->rWifiVar.rAisSpecificBssInfo.aucRxMicKey,
&prCmdKey->aucKeyMaterial[16], MIC_KEY_LEN);
kalMemCopy(prAdapter->rWifiVar.rAisSpecificBssInfo.aucTxMicKey,
&prCmdKey->aucKeyMaterial[24], MIC_KEY_LEN);
}
}
} else {
#if CFG_SUPPORT_802_11W
/* AP PMF */
if ((prCmdKey->ucKeyId >= 4 && prCmdKey->ucKeyId <= 5) &&
(prCmdKey->ucAlgorithmId == CIPHER_SUITE_BIP)) {
DBGLOG(RSN, INFO, "AP mode set BIP\n");
prBssInfo->rApPmfCfg.fgBipKeyInstalled = TRUE;
}
#endif
}
} else { /* Legacy windows NDIS no cipher info */
#if 0
if (prNewKey->u4KeyLength == 5) {
prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP40;
} else if (prNewKey->u4KeyLength == 13) {
prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP104;
} else if (prNewKey->u4KeyLength == 16) {
if (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA)
prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP128;
else {
if (IS_BSS_AIS(prBssInfo)) {
#if CFG_SUPPORT_802_11W
if (prCmdKey->ucKeyId >= 4) {
P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
prCmdKey->ucAlgorithmId = CIPHER_SUITE_BIP;
prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
prAisSpecBssInfo->fgBipKeyInstalled = TRUE;
} else
#endif
{
prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP;
if (rsnCheckPmkidCandicate(prAdapter)) {
DBGLOG(RSN, TRACE,
("Add key: Prepare a timer to indicate candidate PMKID\n"));
cnmTimerStopTimer(prAdapter,
&prAisSpecBssInfo->rPreauthenticationTimer);
cnmTimerStartTimer(prAdapter,
&prAisSpecBssInfo->rPreauthenticationTimer,
SEC_TO_MSEC
(WAIT_TIME_IND_PMKID_CANDICATE_SEC));
}
}
}
}
} else if (prNewKey->u4KeyLength == 32) {
if (IS_BSS_AIS(prBssInfo)) {
if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) {
if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION2_ENABLED) {
prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP;
} else if (prAdapter->rWifiVar.rConnSettings.eEncStatus ==
ENUM_ENCRYPTION3_ENABLED) {
prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP;
prCmdKey->ucKeyLen = CCMP_KEY_LEN;
}
} else {
prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP;
kalMemCopy(prAdapter->rWifiVar.rAisSpecificBssInfo.aucRxMicKey,
&prCmdKey->aucKeyMaterial[16], MIC_KEY_LEN);
kalMemCopy(prAdapter->rWifiVar.rAisSpecificBssInfo.aucTxMicKey,
&prCmdKey->aucKeyMaterial[24], MIC_KEY_LEN);
if (0 /* Todo::GCMP & GCMP-BIP ? */) {
if (rsnCheckPmkidCandicate(prAdapter)) {
DBGLOG(RSN, TRACE,
("Add key: Prepare a timer to indicate candidate PMKID\n"));
cnmTimerStopTimer(prAdapter,
&prAisSpecBssInfo->rPreauthenticationTimer);
cnmTimerStartTimer(prAdapter,
&prAisSpecBssInfo->rPreauthenticationTimer,
SEC_TO_MSEC
(WAIT_TIME_IND_PMKID_CANDICATE_SEC));
}
} else {
prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP;
}
}
}
#endif
}
{
#if CFG_SUPPORT_TDLS
prTmpStaRec = cnmGetStaRecByAddress(prAdapter, prBssInfo->ucBssIndex, prNewKey->arBSSID);
if (prTmpStaRec) {
if (IS_DLS_STA(prTmpStaRec)) {
prStaRec = prTmpStaRec;
prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; /*128 ,TODO GCMP 256 */
kalMemCopy(prCmdKey->aucPeerAddr, prStaRec->aucMacAddr, MAC_ADDR_LEN);
}
}
#endif
#if CFG_SUPPORT_802_11W
/* AP PMF */
if (prCmdKey->ucAlgorithmId == CIPHER_SUITE_BIP) {
if (prCmdKey->ucIsAuthenticator) {
DBGLOG(RSN, INFO, "Authenticator BIP bssid:%d\n", prBssInfo->ucBssIndex);
prCmdKey->ucWlanIndex =
secPrivacySeekForBcEntry(prAdapter,
prBssInfo->ucBssIndex,
prBssInfo->aucOwnMacAddr,
STA_REC_INDEX_NOT_FOUND,
prCmdKey->ucAlgorithmId, prCmdKey->ucKeyId);
} else {
prCmdKey->ucWlanIndex =
secPrivacySeekForBcEntry(prAdapter,
prBssInfo->ucBssIndex,
prBssInfo->prStaRecOfAP->aucMacAddr,
prBssInfo->prStaRecOfAP->ucIndex,
prCmdKey->ucAlgorithmId, prCmdKey->ucKeyId);
}
DBGLOG(RSN, INFO, "BIP BC wtbl index:%d\n", prCmdKey->ucWlanIndex);
} else
#endif
if (1) {
if (prStaRec) {
if (prCmdKey->ucKeyType) { /* RSN STA */
P_WLAN_TABLE_T prWtbl;
prWtbl = prAdapter->rWifiVar.arWtbl;
prWtbl[prStaRec->ucWlanIndex].ucKeyId = prCmdKey->ucKeyId;
prCmdKey->ucWlanIndex = prStaRec->ucWlanIndex;
prStaRec->fgTransmitKeyExist = TRUE; /* wait for CMD Done ? */
kalMemCopy(prCmdKey->aucPeerAddr, prNewKey->arBSSID, MAC_ADDR_LEN);
#if CFG_SUPPORT_802_11W
/* AP PMF */
DBGLOG(RSN, INFO, "Assign client PMF flag = %d\n",
prStaRec->rPmfCfg.fgApplyPmf);
prCmdKey->ucMgmtProtection = prStaRec->rPmfCfg.fgApplyPmf;
#endif
} else {
ASSERT(FALSE);
}
} else { /* Overwrite the old one for AP and STA WEP */
if (prBssInfo->prStaRecOfAP) {
DBGLOG(RSN, INFO, "AP REC\n");
prCmdKey->ucWlanIndex =
secPrivacySeekForBcEntry(prAdapter,
prBssInfo->ucBssIndex,
prBssInfo->prStaRecOfAP->aucMacAddr,
prBssInfo->prStaRecOfAP->ucIndex,
prCmdKey->ucAlgorithmId, prCmdKey->ucKeyId);
kalMemCopy(prCmdKey->aucPeerAddr,
prBssInfo->prStaRecOfAP->aucMacAddr, MAC_ADDR_LEN);
} else {
DBGLOG(RSN, INFO, "!AP && !STA REC\n");
prCmdKey->ucWlanIndex =
secPrivacySeekForBcEntry(prAdapter,
prBssInfo->ucBssIndex,
prBssInfo->aucOwnMacAddr, /* Should replace by BSSID later */
STA_REC_INDEX_NOT_FOUND,
prCmdKey->ucAlgorithmId,
prCmdKey->ucKeyId);
kalMemCopy(prCmdKey->aucPeerAddr, prBssInfo->aucOwnMacAddr, MAC_ADDR_LEN);
}
/* overflow check */
if (prCmdKey->ucKeyId >= MAX_KEY_NUM) {
DBGLOG(RSN, ERROR, "invalid keyId: %d\n", prCmdKey->ucKeyId);
prCmdKey->ucKeyId &= 0x3;
}
if (fgNoHandshakeSec) { /* WEP: STA and AP */
prBssInfo->wepkeyWlanIdx = prCmdKey->ucWlanIndex;
prBssInfo->wepkeyUsed[prCmdKey->ucKeyId] = TRUE;
} else if (!prBssInfo->prStaRecOfAP) { /* AP WPA/RSN */
prBssInfo->ucBMCWlanIndexS[prCmdKey->ucKeyId] = prCmdKey->ucWlanIndex;
prBssInfo->ucBMCWlanIndexSUsed[prCmdKey->ucKeyId] = TRUE;
} else { /* STA WPA/RSN, should not have tx but no sta record */
prBssInfo->ucBMCWlanIndexS[prCmdKey->ucKeyId] = prCmdKey->ucWlanIndex;
prBssInfo->ucBMCWlanIndexSUsed[prCmdKey->ucKeyId] = TRUE;
DBGLOG(RSN, INFO, "BMCWlanIndex kid = %d, index = %d\n", prCmdKey->ucKeyId,
prCmdKey->ucWlanIndex);
}
if (prCmdKey->ucTxKey) { /* */
prBssInfo->fgBcDefaultKeyExist = TRUE;
prBssInfo->ucBcDefaultKeyIdx = prCmdKey->ucKeyId;
}
}
}
}
#if DBG
DBGLOG(RSN, INFO, "Add key cmd to wlan index %d:", prCmdKey->ucWlanIndex);
DBGLOG(RSN, INFO, "(BSS = %d) " MACSTR "\n", prCmdKey->ucBssIdx, MAC2STR(prCmdKey->aucPeerAddr));
DBGLOG(RSN, INFO, "Tx = %d type = %d Auth = %d\n", prCmdKey->ucTxKey, prCmdKey->ucKeyType,
prCmdKey->ucIsAuthenticator);
DBGLOG(RSN, INFO, "cipher = %d keyid = %d keylen = %d\n", prCmdKey->ucAlgorithmId, prCmdKey->ucKeyId,
prCmdKey->ucKeyLen);
DBGLOG_MEM8(RSN, INFO, prCmdKey->aucKeyMaterial, prCmdKey->ucKeyLen);
DBGLOG(RSN, INFO, "wepkeyUsed = %d\n", prBssInfo->wepkeyUsed[prCmdKey->ucKeyId]);
DBGLOG(RSN, INFO, "wepkeyWlanIdx = %d:", prBssInfo->wepkeyWlanIdx);
DBGLOG(RSN, INFO, "ucBMCWlanIndexSUsed = %d\n", prBssInfo->ucBMCWlanIndexSUsed[prCmdKey->ucKeyId]);
DBGLOG(RSN, INFO, "ucBMCWlanIndexS = %d:", prBssInfo->ucBMCWlanIndexS[prCmdKey->ucKeyId]);
#endif
/* insert into prCmdQueue */
kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
/* wakeup txServiceThread later */
GLUE_SET_EVENT(prGlueInfo);
return WLAN_STATUS_PENDING;
} /* wlanoidSetAddKey */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to request the driver to remove the key at
* the specified key index.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_INVALID_DATA
* \retval WLAN_STATUS_INVALID_LENGTH
* \retval WLAN_STATUS_ADAPTER_NOT_READY
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetRemoveKey(IN P_ADAPTER_T prAdapter,
IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
P_GLUE_INFO_T prGlueInfo;
P_CMD_INFO_T prCmdInfo;
P_WIFI_CMD_T prWifiCmd;
P_PARAM_REMOVE_KEY_T prRemovedKey;
P_CMD_802_11_KEY prCmdKey;
UINT_8 ucCmdSeqNum;
P_WLAN_TABLE_T prWlanTable;
P_STA_RECORD_T prStaRec = NULL;
P_BSS_INFO_T prBssInfo;
/* UINT_8 i = 0; */
BOOL fgRemoveWepKey = FALSE;
UINT_32 ucRemoveBCKeyAtIdx = WTBL_RESERVED_ENTRY;
UINT_32 u4KeyIndex;
DEBUGFUNC("wlanoidSetRemoveKey");
ASSERT(prAdapter);
ASSERT(pu4SetInfoLen);
DBGLOG(RSN, INFO, "wlanoidSetRemoveKey\n");
*pu4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T);
if (u4SetBufferLen < sizeof(PARAM_REMOVE_KEY_T))
return WLAN_STATUS_INVALID_LENGTH;
if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN,
"Fail in set remove key! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
ASSERT(pvSetBuffer);
prRemovedKey = (P_PARAM_REMOVE_KEY_T) pvSetBuffer;
/* Dump PARAM_REMOVE_KEY content. */
DBGLOG(RSN, INFO, "Set: Dump PARAM_REMOVE_KEY content\n");
DBGLOG(RSN, INFO, "Length : 0x%08lx\n", prRemovedKey->u4Length);
DBGLOG(RSN, INFO, "Key Index : 0x%08lx\n", prRemovedKey->u4KeyIndex);
DBGLOG(RSN, INFO, "BSS_INDEX : %d\n", prRemovedKey->ucBssIdx);
DBGLOG(RSN, INFO, "BSSID:\n");
DBGLOG_MEM8(RSN, INFO, prRemovedKey->arBSSID, MAC_ADDR_LEN);
prGlueInfo = prAdapter->prGlueInfo;
prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prRemovedKey->ucBssIdx);
ASSERT(prBssInfo);
u4KeyIndex = prRemovedKey->u4KeyIndex & 0x000000FF;
#if CFG_SUPPORT_802_11W
ASSERT(u4KeyIndex < MAX_KEY_NUM + 2);
#else
/* ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); */
#endif
if (u4KeyIndex >= 4) {
DBGLOG(RSN, INFO, "Remove bip key Index : 0x%08lx\n", u4KeyIndex);
return WLAN_STATUS_SUCCESS;
}
/* Clean up the Tx key flag */
if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY) {
prStaRec = cnmGetStaRecByAddress(prAdapter, prRemovedKey->ucBssIdx, prRemovedKey->arBSSID);
if (!prStaRec)
return WLAN_STATUS_SUCCESS;
} else {
if (u4KeyIndex == prBssInfo->ucBcDefaultKeyIdx)
prBssInfo->fgBcDefaultKeyExist = FALSE;
}
if (!prStaRec) {
if (prBssInfo->wepkeyUsed[u4KeyIndex] == TRUE)
fgRemoveWepKey = TRUE;
if (fgRemoveWepKey) {
DBGLOG(RSN, INFO, "Remove wep key id = %d", u4KeyIndex);
prBssInfo->wepkeyUsed[u4KeyIndex] = FALSE;
if (prBssInfo->fgBcDefaultKeyExist &&
prBssInfo->ucBcDefaultKeyIdx == u4KeyIndex) {
prBssInfo->fgBcDefaultKeyExist = FALSE;
prBssInfo->ucBcDefaultKeyIdx = 0xff;
}
ASSERT(prBssInfo->wepkeyWlanIdx < WTBL_SIZE);
ucRemoveBCKeyAtIdx = prBssInfo->wepkeyWlanIdx;
} else {
DBGLOG(RSN, INFO, "Remove group key id = %d", u4KeyIndex);
if (prBssInfo->ucBMCWlanIndexSUsed[u4KeyIndex]) {
if (prBssInfo->fgBcDefaultKeyExist &&
prBssInfo->ucBcDefaultKeyIdx == u4KeyIndex) {
prBssInfo->fgBcDefaultKeyExist = FALSE;
prBssInfo->ucBcDefaultKeyIdx = 0xff;
}
if (u4KeyIndex != 0)
ASSERT(prBssInfo->ucBMCWlanIndexS[u4KeyIndex] < WTBL_SIZE);
ucRemoveBCKeyAtIdx = prBssInfo->ucBMCWlanIndexS[u4KeyIndex];
prBssInfo->ucBMCWlanIndexSUsed[u4KeyIndex]
= FALSE;
prBssInfo->ucBMCWlanIndexS[u4KeyIndex]
= WTBL_RESERVED_ENTRY;
}
}
DBGLOG(RSN, INFO, "ucRemoveBCKeyAtIdx = %d", ucRemoveBCKeyAtIdx);
if (ucRemoveBCKeyAtIdx >= WTBL_SIZE)
return WLAN_STATUS_SUCCESS;
}
prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY)));
if (!prCmdInfo) {
DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
return WLAN_STATUS_FAILURE;
}
prWlanTable = prAdapter->rWifiVar.arWtbl;
prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prRemovedKey->ucBssIdx);
/* increase command sequence number */
ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
/* compose CMD_802_11_KEY cmd pkt */
prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL;
/* prCmdInfo->ucBssIndex = prRemovedKey->ucBssIdx; */
prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY);
prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon;
prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon;
prCmdInfo->fgIsOid = TRUE;
prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY;
prCmdInfo->fgSetQuery = TRUE;
prCmdInfo->fgNeedResp = FALSE;
/* prCmdInfo->fgDriverDomainMCR = FALSE; */
prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
prCmdInfo->u4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T);
prCmdInfo->pvInformationBuffer = pvSetBuffer;
prCmdInfo->u4InformationBufferLength = u4SetBufferLen;
/* Setup WIFI_CMD_T */
prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen;
prWifiCmd->u2PQ_ID = CMD_PQ_ID;
prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID;
prWifiCmd->ucCID = prCmdInfo->ucCID;
prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer);
kalMemZero((PUINT_8) prCmdKey, sizeof(CMD_802_11_KEY));
prCmdKey->ucAddRemove = 0; /* Remove */
prCmdKey->ucKeyId = (UINT_8) u4KeyIndex;
kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prRemovedKey->arBSSID, MAC_ADDR_LEN);
prCmdKey->ucBssIdx = prRemovedKey->ucBssIdx;
if (prStaRec) {
prCmdKey->ucKeyType = 1;
prCmdKey->ucWlanIndex = prStaRec->ucWlanIndex;
prStaRec->fgTransmitKeyExist = FALSE;
} else if (ucRemoveBCKeyAtIdx < WTBL_SIZE) {
prCmdKey->ucWlanIndex = ucRemoveBCKeyAtIdx;
} else {
ASSERT(FALSE);
}
/* insert into prCmdQueue */
kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
/* wakeup txServiceThread later */
GLUE_SET_EVENT(prGlueInfo);
return WLAN_STATUS_PENDING;
} /* wlanoidSetRemoveKey */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to set the default key
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_ADAPTER_NOT_READY
* \retval WLAN_STATUS_INVALID_LENGTH
* \retval WLAN_STATUS_INVALID_DATA
*
* \note The setting buffer PARAM_KEY_T, which is set by NDIS, is unpacked.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetDefaultKey(IN P_ADAPTER_T prAdapter,
IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
P_GLUE_INFO_T prGlueInfo;
P_CMD_INFO_T prCmdInfo;
P_WIFI_CMD_T prWifiCmd;
P_PARAM_DEFAULT_KEY_T prDefaultKey;
P_CMD_DEFAULT_KEY prCmdDefaultKey;
UINT_8 ucCmdSeqNum;
P_BSS_INFO_T prBssInfo;
BOOL fgSetWepKey = FALSE;
UINT_8 ucWlanIndex = WTBL_RESERVED_ENTRY;
DEBUGFUNC("wlanoidSetDefaultKey");
DBGLOG(REQ, LOUD, "\n");
ASSERT(prAdapter);
ASSERT(pvSetBuffer);
ASSERT(pu4SetInfoLen);
if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
prDefaultKey = (P_PARAM_DEFAULT_KEY_T) pvSetBuffer;
*pu4SetInfoLen = u4SetBufferLen;
/* Dump PARAM_DEFAULT_KEY_T content. */
DBGLOG(RSN, INFO, "Key Index : %d\n", prDefaultKey->ucKeyID);
DBGLOG(RSN, INFO, "Unicast Key : %d\n", prDefaultKey->ucUnicast);
DBGLOG(RSN, INFO, "Multicast Key : %d\n", prDefaultKey->ucMulticast);
/* prWlanTable = prAdapter->rWifiVar.arWtbl; */
prGlueInfo = prAdapter->prGlueInfo;
prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prDefaultKey->ucBssIdx);
DBGLOG(RSN, INFO, "WlanIdx = %d\n", prBssInfo->wepkeyWlanIdx);
if (prDefaultKey->ucMulticast) {
if (!prBssInfo)
ASSERT(FALSE);
if (prBssInfo->prStaRecOfAP) { /* Actually GC not have wep */
if (prBssInfo->wepkeyUsed[prDefaultKey->ucKeyID]) {
prBssInfo->ucBcDefaultKeyIdx = prDefaultKey->ucKeyID;
prBssInfo->fgBcDefaultKeyExist = TRUE;
ucWlanIndex = prBssInfo->wepkeyWlanIdx;
} else {
DBGLOG(RSN, ERROR, "WPA encryption should retrun");
return WLAN_STATUS_SUCCESS;
}
} else { /* For AP mode only */
if (prBssInfo->wepkeyUsed[prDefaultKey->ucKeyID] == TRUE)
fgSetWepKey = TRUE;
if (fgSetWepKey) {
ucWlanIndex = prBssInfo->wepkeyWlanIdx;
} else {
if (!prBssInfo->ucBMCWlanIndexSUsed[prDefaultKey->ucKeyID]) {
DBGLOG(RSN, ERROR, "Set AP wep default but key not exist!");
return WLAN_STATUS_SUCCESS;
}
ucWlanIndex = prBssInfo->ucBMCWlanIndexS[prDefaultKey->ucKeyID];
}
prBssInfo->ucBcDefaultKeyIdx = prDefaultKey->ucKeyID;
prBssInfo->fgBcDefaultKeyExist = TRUE;
}
if (ucWlanIndex > WTBL_SIZE)
ASSERT(FALSE);
} else {
DBGLOG(RSN, ERROR, "Check the case set unicast default key!");
ASSERT(FALSE);
}
prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_DEFAULT_KEY)));
if (!prCmdInfo) {
DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n");
return WLAN_STATUS_FAILURE;
}
/* increase command sequence number */
ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
DBGLOG(REQ, INFO, "ucCmdSeqNum = %d\n", ucCmdSeqNum);
/* compose CMD_802_11_KEY cmd pkt */
prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL;
prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_DEFAULT_KEY);
prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon;
prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon;
prCmdInfo->fgIsOid = TRUE;
prCmdInfo->ucCID = CMD_ID_DEFAULT_KEY_ID;
prCmdInfo->fgSetQuery = TRUE;
prCmdInfo->fgNeedResp = FALSE;
prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
prCmdInfo->u4SetInfoLen = u4SetBufferLen;
prCmdInfo->pvInformationBuffer = pvSetBuffer;
prCmdInfo->u4InformationBufferLength = u4SetBufferLen;
/* Setup WIFI_CMD_T */
prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer);
prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen;
prWifiCmd->u2PQ_ID = CMD_PQ_ID;
prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID;
prWifiCmd->ucCID = prCmdInfo->ucCID;
prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
prCmdDefaultKey = (P_CMD_DEFAULT_KEY) (prWifiCmd->aucBuffer);
kalMemZero(prCmdDefaultKey, sizeof(CMD_DEFAULT_KEY));
prCmdDefaultKey->ucBssIdx = prDefaultKey->ucBssIdx;
prCmdDefaultKey->ucKeyId = prDefaultKey->ucKeyID;
prCmdDefaultKey->ucWlanIndex = ucWlanIndex;
prCmdDefaultKey->ucMulticast = prDefaultKey->ucMulticast;
DBGLOG(RSN, INFO, "CMD_ID_DEFAULT_KEY_ID (%d) with wlan idx = %d\n", prDefaultKey->ucKeyID, ucWlanIndex);
/* insert into prCmdQueue */
kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
/* wakeup txServiceThread later */
GLUE_SET_EVENT(prGlueInfo);
return WLAN_STATUS_PENDING;
} /* wlanoidSetDefaultKey */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to query the current encryption status.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of
* the query.
* \param[in] u4QueryBufferLen The length of the query buffer.
* \param[out] pu4QueryInfoLen If the call is successful, returns the number of
* bytes written into the query buffer. If the call
* failed due to invalid length of the query buffer,
* returns the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidQueryEncryptionStatus(IN P_ADAPTER_T prAdapter,
IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
{
BOOLEAN fgTransmitKeyAvailable = TRUE;
ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus = 0;
DEBUGFUNC("wlanoidQueryEncryptionStatus");
ASSERT(prAdapter);
ASSERT(pu4QueryInfoLen);
if (u4QueryBufferLen)
ASSERT(pvQueryBuffer);
*pu4QueryInfoLen = sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T);
fgTransmitKeyAvailable = prAdapter->prAisBssInfo->fgBcDefaultKeyExist;
switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) {
case ENUM_ENCRYPTION3_ENABLED:
if (fgTransmitKeyAvailable)
eEncStatus = ENUM_ENCRYPTION3_ENABLED;
else
eEncStatus = ENUM_ENCRYPTION3_KEY_ABSENT;
break;
case ENUM_ENCRYPTION2_ENABLED:
if (fgTransmitKeyAvailable) {
eEncStatus = ENUM_ENCRYPTION2_ENABLED;
break;
}
eEncStatus = ENUM_ENCRYPTION2_KEY_ABSENT;
break;
case ENUM_ENCRYPTION1_ENABLED:
if (fgTransmitKeyAvailable)
eEncStatus = ENUM_ENCRYPTION1_ENABLED;
else
eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT;
break;
case ENUM_ENCRYPTION_DISABLED:
eEncStatus = ENUM_ENCRYPTION_DISABLED;
break;
default:
DBGLOG(REQ, ERROR, "Unknown Encryption Status Setting:%d\n",
prAdapter->rWifiVar.rConnSettings.eEncStatus);
}
#if DBG
DBGLOG(REQ, INFO,
"Encryption status: %d Return:%d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus, eEncStatus);
#endif
*(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvQueryBuffer = eEncStatus;
return WLAN_STATUS_SUCCESS;
} /* wlanoidQueryEncryptionStatus */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to set the encryption status to the driver.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_ADAPTER_NOT_READY
* \retval WLAN_STATUS_NOT_SUPPORTED
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetEncryptionStatus(IN P_ADAPTER_T prAdapter,
IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
P_GLUE_INFO_T prGlueInfo;
WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
ENUM_PARAM_ENCRYPTION_STATUS_T eEewEncrypt;
DEBUGFUNC("wlanoidSetEncryptionStatus");
ASSERT(prAdapter);
ASSERT(pvSetBuffer);
ASSERT(pu4SetInfoLen);
prGlueInfo = prAdapter->prGlueInfo;
*pu4SetInfoLen = sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T);
/* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */
/* return WLAN_STATUS_SUCCESS; */
/* } */
if (prAdapter->rAcpiState == ACPI_STATE_D3) {
DBGLOG(REQ, WARN,
"Fail in set encryption status! (Adapter not ready). ACPI=D%d, Radio=%d\n",
prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
return WLAN_STATUS_ADAPTER_NOT_READY;
}
eEewEncrypt = *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer;
DBGLOG(REQ, INFO, "ENCRYPTION_STATUS %d\n", eEewEncrypt);
switch (eEewEncrypt) {
case ENUM_ENCRYPTION_DISABLED: /* Disable WEP, TKIP, AES */
DBGLOG(RSN, INFO, "Disable Encryption\n");
secSetCipherSuite(prAdapter, CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128);
break;
case ENUM_ENCRYPTION1_ENABLED: /* Enable WEP. Disable TKIP, AES */
DBGLOG(RSN, INFO, "Enable Encryption1\n");
secSetCipherSuite(prAdapter, CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128);
break;
case ENUM_ENCRYPTION2_ENABLED: /* Enable WEP, TKIP. Disable AES */
secSetCipherSuite(prAdapter,
CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP);
DBGLOG(RSN, INFO, "Enable Encryption2\n");
break;
case ENUM_ENCRYPTION3_ENABLED: /* Enable WEP, TKIP, AES */
secSetCipherSuite(prAdapter,
CIPHER_FLAG_WEP40 |
CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP | CIPHER_FLAG_CCMP);
DBGLOG(RSN, INFO, "Enable Encryption3\n");
break;
default:
DBGLOG(RSN, INFO, "Unacceptible encryption status: %d\n",
*(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer);
rStatus = WLAN_STATUS_NOT_SUPPORTED;
}
if (rStatus == WLAN_STATUS_SUCCESS) {
/* Save the new encryption status. */
prAdapter->rWifiVar.rConnSettings.eEncStatus = *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer;
}
return rStatus;
} /* wlanoidSetEncryptionStatus */
/*----------------------------------------------------------------------------*/
/*!
* \brief This routine is called to test the driver.
*
* \param[in] prAdapter Pointer to the Adapter structure.
* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
* \param[in] u4SetBufferLen The length of the set buffer.
* \param[out] pu4SetInfoLen If the call is successful, returns the number of
* bytes read from the set buffer. If the call failed
* due to invalid length of the set buffer, returns
* the amount of storage needed.
*
* \retval WLAN_STATUS_SUCCESS
* \retval WLAN_STATUS_INVALID_LENGTH
* \retval WLAN_STATUS_INVALID_DATA
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
wlanoidSetTest(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
{
P_PARAM_802_11_TEST_T prTest;
PVOID pvTestData;
PVOID pvStatusBuffer;
UINT_32 u4StatusBufferSize;
DEBUGFUNC("wlanoidSetTest");
ASSERT(prAdapter);
ASSERT(pu4SetInfoLen);
ASSERT(pvSetBuffer);
*pu4SetInfoLen = u4SetBufferLen;
prTest = (P_PARAM_802_11_TEST_T) pvSetBuffer;
DBGLOG(REQ, TRACE, "Test - Type %ld\n", prTest->u4Type);
switch (prTest->u4Type) {
case 1: /* Type 1: generate an authentication event */
pvTestData = (PVOID) &prTest->u.AuthenticationEvent;
pvStatusBuffer = (PVOID) prAdapter->aucIndicationEventBuffer;
u4StatusBufferSize = prTest->u4Length - 8;
if (u4StatusBufferSize > sizeof(prTest->u.AuthenticationEvent))