Archived
14
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
linux-2.6/drivers/staging/rt3070/sta_ioctl.c
Greg Kroah-Hartman e642f09951 Staging: add rt3070 wireless driver
This is the Ralink RT3070 driver from the company that does horrible
things like reading a config file from /etc.  However, the driver that
is currently under development from the wireless development community
is not working at all yet, so distros and users are using this version
instead (quite common hardware on a lot of netbook machines).

So here is this driver, for now, until the wireless developers get a
"clean" version into the main tree, or until this version is cleaned up
sufficiently to move out of the staging tree.

Ported to the Linux build system, fixed lots of build issues, forward
ported to the current kernel version, and other minor cleanups were all
done by me.

Cc: Linux wireless <linux-wireless@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-04-03 14:54:24 -07:00

7204 lines
246 KiB
C

/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
sta_ioctl.c
Abstract:
IOCTL related subroutines
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Rory Chen 01-03-2003 created
Rory Chen 02-14-2005 modify to support RT61
*/
#include "rt_config.h"
#ifdef DBG
extern ULONG RTDebugLevel;
#endif
#define NR_WEP_KEYS 4
#define WEP_SMALL_KEY_LEN (40/8)
#define WEP_LARGE_KEY_LEN (104/8)
#define GROUP_KEY_NO 4
extern UCHAR CipherWpa2Template[];
extern UCHAR CipherWpaPskTkip[];
extern UCHAR CipherWpaPskTkipLen;
typedef struct PACKED _RT_VERSION_INFO{
UCHAR DriverVersionW;
UCHAR DriverVersionX;
UCHAR DriverVersionY;
UCHAR DriverVersionZ;
UINT DriverBuildYear;
UINT DriverBuildMonth;
UINT DriverBuildDay;
} RT_VERSION_INFO, *PRT_VERSION_INFO;
struct iw_priv_args privtab[] = {
{ RTPRIV_IOCTL_SET,
IW_PRIV_TYPE_CHAR | 1024, 0,
"set"},
{ RTPRIV_IOCTL_SHOW, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
""},
{ RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
""},
/* --- sub-ioctls definitions --- */
{ SHOW_CONN_STATUS,
0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" },
{ SHOW_DRVIER_VERION,
0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" },
{ SHOW_BA_INFO,
0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" },
{ SHOW_DESC_INFO,
0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" },
{ RAIO_OFF,
0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" },
{ RAIO_ON,
0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
#ifdef QOS_DLS_SUPPORT
{ SHOW_DLS_ENTRY_INFO,
0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "dlsentryinfo" },
#endif // QOS_DLS_SUPPORT //
{ SHOW_CFG_VALUE,
IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" },
/* --- sub-ioctls relations --- */
#ifdef DBG
{ RTPRIV_IOCTL_BBP,
IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
"bbp"},
{ RTPRIV_IOCTL_MAC,
IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
"mac"},
#ifdef RT30xx
{ RTPRIV_IOCTL_RF,
IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
"rf"},
#endif // RT30xx //
{ RTPRIV_IOCTL_E2P,
IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
"e2p"},
#endif /* DBG */
{ RTPRIV_IOCTL_STATISTICS,
0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
"stat"},
{ RTPRIV_IOCTL_GSITESURVEY,
0, IW_PRIV_TYPE_CHAR | 1024,
"get_site_survey"},
};
INT Set_SSID_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
#ifdef WMM_SUPPORT
INT Set_WmmCapable_Proc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg);
#endif
INT Set_NetworkType_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
INT Set_AuthMode_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
INT Set_EncrypType_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
INT Set_DefaultKeyID_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
INT Set_Key1_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
INT Set_Key2_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
INT Set_Key3_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
INT Set_Key4_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
INT Set_WPAPSK_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
INT Set_PSMode_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
#ifdef WPA_SUPPLICANT_SUPPORT
INT Set_Wpa_Support(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg);
#endif // WPA_SUPPLICANT_SUPPORT //
#ifdef DBG
VOID RTMPIoctlMAC(
IN PRTMP_ADAPTER pAdapter,
IN struct iwreq *wrq);
VOID RTMPIoctlE2PROM(
IN PRTMP_ADAPTER pAdapter,
IN struct iwreq *wrq);
#ifdef RT30xx
VOID RTMPIoctlRF(
IN PRTMP_ADAPTER pAdapter,
IN struct iwreq *wrq);
#endif // RT30xx //
#endif // DBG //
NDIS_STATUS RTMPWPANoneAddKeyProc(
IN PRTMP_ADAPTER pAd,
IN PVOID pBuf);
INT Set_FragTest_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
#ifdef DOT11_N_SUPPORT
INT Set_TGnWifiTest_Proc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg);
#endif // DOT11_N_SUPPORT //
INT Set_LongRetryLimit_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
INT Set_ShortRetryLimit_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
#ifdef EXT_BUILD_CHANNEL_LIST
INT Set_Ieee80211dClientMode_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg);
#endif // EXT_BUILD_CHANNEL_LIST //
#ifdef CARRIER_DETECTION_SUPPORT
INT Set_CarrierDetect_Proc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg);
#endif // CARRIER_DETECTION_SUPPORT //
static struct {
CHAR *name;
INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
} *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = {
{"DriverVersion", Set_DriverVersion_Proc},
{"CountryRegion", Set_CountryRegion_Proc},
{"CountryRegionABand", Set_CountryRegionABand_Proc},
{"SSID", Set_SSID_Proc},
{"WirelessMode", Set_WirelessMode_Proc},
{"TxBurst", Set_TxBurst_Proc},
{"TxPreamble", Set_TxPreamble_Proc},
{"TxPower", Set_TxPower_Proc},
{"Channel", Set_Channel_Proc},
{"BGProtection", Set_BGProtection_Proc},
{"RTSThreshold", Set_RTSThreshold_Proc},
{"FragThreshold", Set_FragThreshold_Proc},
#ifdef DOT11_N_SUPPORT
{"HtBw", Set_HtBw_Proc},
{"HtMcs", Set_HtMcs_Proc},
{"HtGi", Set_HtGi_Proc},
{"HtOpMode", Set_HtOpMode_Proc},
{"HtExtcha", Set_HtExtcha_Proc},
{"HtMpduDensity", Set_HtMpduDensity_Proc},
{"HtBaWinSize", Set_HtBaWinSize_Proc},
{"HtRdg", Set_HtRdg_Proc},
{"HtAmsdu", Set_HtAmsdu_Proc},
{"HtAutoBa", Set_HtAutoBa_Proc},
{"HtBaDecline", Set_BADecline_Proc},
{"HtProtect", Set_HtProtect_Proc},
{"HtMimoPs", Set_HtMimoPs_Proc},
#endif // DOT11_N_SUPPORT //
#ifdef AGGREGATION_SUPPORT
{"PktAggregate", Set_PktAggregate_Proc},
#endif
#ifdef WMM_SUPPORT
{"WmmCapable", Set_WmmCapable_Proc},
#endif
{"IEEE80211H", Set_IEEE80211H_Proc},
{"NetworkType", Set_NetworkType_Proc},
{"AuthMode", Set_AuthMode_Proc},
{"EncrypType", Set_EncrypType_Proc},
{"DefaultKeyID", Set_DefaultKeyID_Proc},
{"Key1", Set_Key1_Proc},
{"Key2", Set_Key2_Proc},
{"Key3", Set_Key3_Proc},
{"Key4", Set_Key4_Proc},
{"WPAPSK", Set_WPAPSK_Proc},
{"ResetCounter", Set_ResetStatCounter_Proc},
{"PSMode", Set_PSMode_Proc},
#ifdef DBG
{"Debug", Set_Debug_Proc},
#endif
#ifdef RALINK_ATE
{"ATE", Set_ATE_Proc},
{"ATEDA", Set_ATE_DA_Proc},
{"ATESA", Set_ATE_SA_Proc},
{"ATEBSSID", Set_ATE_BSSID_Proc},
{"ATECHANNEL", Set_ATE_CHANNEL_Proc},
{"ATETXPOW0", Set_ATE_TX_POWER0_Proc},
{"ATETXPOW1", Set_ATE_TX_POWER1_Proc},
{"ATETXANT", Set_ATE_TX_Antenna_Proc},
{"ATERXANT", Set_ATE_RX_Antenna_Proc},
{"ATETXFREQOFFSET", Set_ATE_TX_FREQOFFSET_Proc},
{"ATETXBW", Set_ATE_TX_BW_Proc},
{"ATETXLEN", Set_ATE_TX_LENGTH_Proc},
{"ATETXCNT", Set_ATE_TX_COUNT_Proc},
{"ATETXMCS", Set_ATE_TX_MCS_Proc},
{"ATETXMODE", Set_ATE_TX_MODE_Proc},
{"ATETXGI", Set_ATE_TX_GI_Proc},
{"ATERXFER", Set_ATE_RX_FER_Proc},
{"ATERRF", Set_ATE_Read_RF_Proc},
{"ATEWRF1", Set_ATE_Write_RF1_Proc},
{"ATEWRF2", Set_ATE_Write_RF2_Proc},
{"ATEWRF3", Set_ATE_Write_RF3_Proc},
{"ATEWRF4", Set_ATE_Write_RF4_Proc},
{"ATELDE2P", Set_ATE_Load_E2P_Proc},
{"ATERE2P", Set_ATE_Read_E2P_Proc},
{"ATESHOW", Set_ATE_Show_Proc},
{"ATEHELP", Set_ATE_Help_Proc},
#ifdef RALINK_28xx_QA
{"TxStop", Set_TxStop_Proc},
{"RxStop", Set_RxStop_Proc},
#endif // RALINK_28xx_QA //
#endif // RALINK_ATE //
#ifdef WPA_SUPPLICANT_SUPPORT
{"WpaSupport", Set_Wpa_Support},
#endif // WPA_SUPPLICANT_SUPPORT //
{"FixedTxMode", Set_FixedTxMode_Proc},
#ifdef CONFIG_APSTA_MIXED_SUPPORT
{"OpMode", Set_OpMode_Proc},
#endif // CONFIG_APSTA_MIXED_SUPPORT //
#ifdef DOT11_N_SUPPORT
{"TGnWifiTest", Set_TGnWifiTest_Proc},
{"ForceGF", Set_ForceGF_Proc},
#endif // DOT11_N_SUPPORT //
#ifdef QOS_DLS_SUPPORT
{"DlsAddEntry", Set_DlsAddEntry_Proc},
{"DlsTearDownEntry", Set_DlsTearDownEntry_Proc},
#endif // QOS_DLS_SUPPORT //
{"LongRetry", Set_LongRetryLimit_Proc},
{"ShortRetry", Set_ShortRetryLimit_Proc},
#ifdef EXT_BUILD_CHANNEL_LIST
{"11dClientMode", Set_Ieee80211dClientMode_Proc},
#endif // EXT_BUILD_CHANNEL_LIST //
#ifdef CARRIER_DETECTION_SUPPORT
{"CarrierDetect", Set_CarrierDetect_Proc},
#endif // CARRIER_DETECTION_SUPPORT //
//2008/09/11:KH add to support efuse<--
#ifdef RT30xx
{"efuseFreeNumber", set_eFuseGetFreeBlockCount_Proc},
{"efuseDump", set_eFusedump_Proc},
{"efuseLoadFromBin", set_eFuseLoadFromBin_Proc},
#endif // RT30xx //
//2008/09/11:KH add to support efuse-->
{NULL,}
};
VOID RTMPAddKey(
IN PRTMP_ADAPTER pAd,
IN PNDIS_802_11_KEY pKey)
{
ULONG KeyIdx;
MAC_TABLE_ENTRY *pEntry;
DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
{
if (pKey->KeyIndex & 0x80000000)
{
if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
{
NdisZeroMemory(pAd->StaCfg.PMK, 32);
NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength);
goto end;
}
// Update PTK
NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TKIP_EK);
#ifdef WPA_SUPPLICANT_SUPPORT
if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
{
NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
}
else
#endif // WPA_SUPPLICANT_SUPPORT //
{
NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
}
// Decide its ChiperAlg
if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
else
pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
// Update these related information to MAC_TABLE_ENTRY
pEntry = &pAd->MacTab.Content[BSSID_WCID];
NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TKIP_EK);
NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_RXMICK);
NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_TXMICK);
pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
// Update pairwise key information to ASIC Shared Key Table
AsicAddSharedKeyEntry(pAd,
BSS0,
0,
pAd->SharedKey[BSS0][0].CipherAlg,
pAd->SharedKey[BSS0][0].Key,
pAd->SharedKey[BSS0][0].TxMic,
pAd->SharedKey[BSS0][0].RxMic);
// Update ASIC WCID attribute table and IVEIV table
RTMPAddWcidAttributeEntry(pAd,
BSS0,
0,
pAd->SharedKey[BSS0][0].CipherAlg,
pEntry);
if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
{
// set 802.1x port control
//pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
STA_PORT_SECURED(pAd);
// Indicate Connected for GUI
pAd->IndicateMediaState = NdisMediaStateConnected;
}
}
else
{
// Update GTK
pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TKIP_EK);
#ifdef WPA_SUPPLICANT_SUPPORT
if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
{
NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
}
else
#endif // WPA_SUPPLICANT_SUPPORT //
{
NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
}
// Update Shared Key CipherAlg
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
// Update group key information to ASIC Shared Key Table
AsicAddSharedKeyEntry(pAd,
BSS0,
pAd->StaCfg.DefaultKeyId,
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
// Update ASIC WCID attribute table and IVEIV table
RTMPAddWcidAttributeEntry(pAd,
BSS0,
pAd->StaCfg.DefaultKeyId,
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
NULL);
// set 802.1x port control
//pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
STA_PORT_SECURED(pAd);
// Indicate Connected for GUI
pAd->IndicateMediaState = NdisMediaStateConnected;
}
}
else // dynamic WEP from wpa_supplicant
{
UCHAR CipherAlg;
PUCHAR Key;
if(pKey->KeyLength == 32)
goto end;
KeyIdx = pKey->KeyIndex & 0x0fffffff;
if (KeyIdx < 4)
{
// it is a default shared key, for Pairwise key setting
if (pKey->KeyIndex & 0x80000000)
{
pEntry = MacTableLookup(pAd, pKey->BSSID);
if (pEntry)
{
DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n"));
// set key material and key length
pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
// set Cipher type
if (pKey->KeyLength == 5)
pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
else
pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
// Add Pair-wise key to Asic
AsicAddPairwiseKeyEntry(
pAd,
pEntry->Addr,
(UCHAR)pEntry->Aid,
&pEntry->PairwiseKey);
// update WCID attribute table and IVEIV table for this entry
RTMPAddWcidAttributeEntry(
pAd,
BSS0,
KeyIdx, // The value may be not zero
pEntry->PairwiseKey.CipherAlg,
pEntry);
}
}
else
{
// Default key for tx (shared key)
pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
// set key material and key length
pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
// Set Ciper type
if (pKey->KeyLength == 5)
pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64;
else
pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128;
CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
Key = pAd->SharedKey[BSS0][KeyIdx].Key;
// Set Group key material to Asic
AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
// Update WCID attribute table and IVEIV table for this group key table
RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
}
}
}
end:
return;
}
char * rtstrchr(const char * s, int c)
{
for(; *s != (char) c; ++s)
if (*s == '\0')
return NULL;
return (char *) s;
}
/*
This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
*/
int
rt_ioctl_giwname(struct net_device *dev,
struct iw_request_info *info,
char *name, char *extra)
{
// PRTMP_ADAPTER pAdapter = dev->ml_priv;
#ifdef RT2870
strncpy(name, "RT2870 Wireless", IFNAMSIZ);
#endif // RT2870 //
return 0;
}
int rt_ioctl_siwfreq(struct net_device *dev,
struct iw_request_info *info,
struct iw_freq *freq, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
int chan = -1;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
if (freq->e > 1)
return -EINVAL;
if((freq->e == 0) && (freq->m <= 1000))
chan = freq->m; // Setting by channel number
else
MAP_KHZ_TO_CHANNEL_ID( (freq->m /100) , chan); // Setting by frequency - search the table , like 2.412G, 2.422G,
if (ChannelSanity(pAdapter, chan) == TRUE)
{
pAdapter->CommonCfg.Channel = chan;
DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
}
else
return -EINVAL;
return 0;
}
int rt_ioctl_giwfreq(struct net_device *dev,
struct iw_request_info *info,
struct iw_freq *freq, char *extra)
{
VIRTUAL_ADAPTER *pVirtualAd = NULL;
PRTMP_ADAPTER pAdapter;
UCHAR ch;
ULONG m;
if (dev->priv_flags == INT_MAIN)
{
pAdapter = dev->ml_priv;
}
else
{
pVirtualAd = dev->ml_priv;
pAdapter = pVirtualAd->RtmpDev->ml_priv;
}
if (pAdapter == NULL)
{
/* if 1st open fail, pAd will be free;
So the net_dev->ml_priv will be NULL in 2rd open */
return -ENETDOWN;
}
ch = pAdapter->CommonCfg.Channel;
DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq %d\n", ch));
MAP_CHANNEL_ID_TO_KHZ(ch, m);
freq->m = m * 100;
freq->e = 1;
return 0;
}
int rt_ioctl_siwmode(struct net_device *dev,
struct iw_request_info *info,
__u32 *mode, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
switch (*mode)
{
case IW_MODE_ADHOC:
Set_NetworkType_Proc(pAdapter, "Adhoc");
break;
case IW_MODE_INFRA:
Set_NetworkType_Proc(pAdapter, "Infra");
break;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
case IW_MODE_MONITOR:
Set_NetworkType_Proc(pAdapter, "Monitor");
break;
#endif
default:
DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
return -EINVAL;
}
// Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
pAdapter->StaCfg.WpaState = SS_NOTUSE;
return 0;
}
int rt_ioctl_giwmode(struct net_device *dev,
struct iw_request_info *info,
__u32 *mode, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
if (ADHOC_ON(pAdapter))
*mode = IW_MODE_ADHOC;
else if (INFRA_ON(pAdapter))
*mode = IW_MODE_INFRA;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
else if (MONITOR_ON(pAdapter))
{
*mode = IW_MODE_MONITOR;
}
#endif
else
*mode = IW_MODE_AUTO;
DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
return 0;
}
int rt_ioctl_siwsens(struct net_device *dev,
struct iw_request_info *info,
char *name, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
return 0;
}
int rt_ioctl_giwsens(struct net_device *dev,
struct iw_request_info *info,
char *name, char *extra)
{
return 0;
}
int rt_ioctl_giwrange(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
struct iw_range *range = (struct iw_range *) extra;
u16 val;
int i;
DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
data->length = sizeof(struct iw_range);
memset(range, 0, sizeof(struct iw_range));
range->txpower_capa = IW_TXPOW_DBM;
if (INFRA_ON(pAdapter)||ADHOC_ON(pAdapter))
{
range->min_pmp = 1 * 1024;
range->max_pmp = 65535 * 1024;
range->min_pmt = 1 * 1024;
range->max_pmt = 1000 * 1024;
range->pmp_flags = IW_POWER_PERIOD;
range->pmt_flags = IW_POWER_TIMEOUT;
range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
IW_POWER_UNICAST_R | IW_POWER_ALL_R;
}
range->we_version_compiled = WIRELESS_EXT;
range->we_version_source = 14;
range->retry_capa = IW_RETRY_LIMIT;
range->retry_flags = IW_RETRY_LIMIT;
range->min_retry = 0;
range->max_retry = 255;
range->num_channels = pAdapter->ChannelListNum;
val = 0;
for (i = 1; i <= range->num_channels; i++)
{
u32 m;
range->freq[val].i = pAdapter->ChannelList[i-1].Channel;
MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m);
range->freq[val].m = m * 100; /* HZ */
range->freq[val].e = 1;
val++;
if (val == IW_MAX_FREQUENCIES)
break;
}
range->num_frequency = val;
range->max_qual.qual = 100; /* what is correct max? This was not
* documented exactly. At least
* 69 has been observed. */
range->max_qual.level = 0; /* dB */
range->max_qual.noise = 0; /* dB */
/* What would be suitable values for "average/typical" qual? */
range->avg_qual.qual = 20;
range->avg_qual.level = -60;
range->avg_qual.noise = -95;
range->sensitivity = 3;
range->max_encoding_tokens = NR_WEP_KEYS;
range->num_encoding_sizes = 2;
range->encoding_size[0] = 5;
range->encoding_size[1] = 13;
range->min_rts = 0;
range->max_rts = 2347;
range->min_frag = 256;
range->max_frag = 2346;
#if WIRELESS_EXT > 17
/* IW_ENC_CAPA_* bit field */
range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
#endif
return 0;
}
int rt_ioctl_siwap(struct net_device *dev,
struct iw_request_info *info,
struct sockaddr *ap_addr, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
NDIS_802_11_MAC_ADDRESS Bssid;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
{
RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
}
// tell CNTL state machine to call NdisMSetInformationComplete() after completing
// this request, because this request is initiated by NDIS.
pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
// Prevent to connect AP again in STAMlmePeriodicExec
pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
memset(Bssid, 0, MAC_ADDR_LEN);
memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
MlmeEnqueue(pAdapter,
MLME_CNTL_STATE_MACHINE,
OID_802_11_BSSID,
sizeof(NDIS_802_11_MAC_ADDRESS),
(VOID *)&Bssid);
DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n",
Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
return 0;
}
int rt_ioctl_giwap(struct net_device *dev,
struct iw_request_info *info,
struct sockaddr *ap_addr, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
{
ap_addr->sa_family = ARPHRD_ETHER;
memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
}
#ifdef WPA_SUPPLICANT_SUPPORT
// Add for RT2870
else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
{
ap_addr->sa_family = ARPHRD_ETHER;
memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
}
#endif // WPA_SUPPLICANT_SUPPORT //
else
{
DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
return -ENOTCONN;
}
return 0;
}
/*
* Units are in db above the noise floor. That means the
* rssi values reported in the tx/rx descriptors in the
* driver are the SNR expressed in db.
*
* If you assume that the noise floor is -95, which is an
* excellent assumption 99.5 % of the time, then you can
* derive the absolute signal level (i.e. -95 + rssi).
* There are some other slight factors to take into account
* depending on whether the rssi measurement is from 11b,
* 11g, or 11a. These differences are at most 2db and
* can be documented.
*
* NB: various calculations are based on the orinoco/wavelan
* drivers for compatibility
*/
static void set_quality(PRTMP_ADAPTER pAdapter,
struct iw_quality *iq,
signed char rssi)
{
__u8 ChannelQuality;
// Normalize Rssi
if (rssi >= -50)
ChannelQuality = 100;
else if (rssi >= -80) // between -50 ~ -80dbm
ChannelQuality = (__u8)(24 + ((rssi + 80) * 26)/10);
else if (rssi >= -90) // between -80 ~ -90dbm
ChannelQuality = (__u8)((rssi + 90) * 26)/10;
else
ChannelQuality = 0;
iq->qual = (__u8)ChannelQuality;
iq->level = (__u8)(rssi);
iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8)pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]); // noise level (dBm)
iq->noise += 256 - 143;
iq->updated = pAdapter->iw_stats.qual.updated;
}
int rt_ioctl_iwaplist(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
struct sockaddr addr[IW_MAX_AP];
struct iw_quality qual[IW_MAX_AP];
int i;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
data->length = 0;
return 0;
//return -ENETDOWN;
}
for (i = 0; i <IW_MAX_AP ; i++)
{
if (i >= pAdapter->ScanTab.BssNr)
break;
addr[i].sa_family = ARPHRD_ETHER;
memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
set_quality(pAdapter, &qual[i], pAdapter->ScanTab.BssEntry[i].Rssi);
}
data->length = i;
memcpy(extra, &addr, i*sizeof(addr[0]));
data->flags = 1; /* signal quality present (sort of) */
memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i]));
return 0;
}
#ifdef SIOCGIWSCAN
int rt_ioctl_siwscan(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
ULONG Now;
int Status = NDIS_STATUS_SUCCESS;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
if (MONITOR_ON(pAdapter))
{
DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
return -EINVAL;
}
#ifdef WPA_SUPPLICANT_SUPPORT
if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
{
pAdapter->StaCfg.WpaSupplicantScanCount++;
}
#endif // WPA_SUPPLICANT_SUPPORT //
pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
return 0;
do{
Now = jiffies;
#ifdef WPA_SUPPLICANT_SUPPORT
if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
(pAdapter->StaCfg.WpaSupplicantScanCount > 3))
{
DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n"));
Status = NDIS_STATUS_SUCCESS;
break;
}
#endif // WPA_SUPPLICANT_SUPPORT //
if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
(pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
{
DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
Status = NDIS_STATUS_SUCCESS;
break;
}
if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
{
RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
}
// tell CNTL state machine to call NdisMSetInformationComplete() after completing
// this request, because this request is initiated by NDIS.
pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
// Reset allowed scan retries
pAdapter->StaCfg.ScanCnt = 0;
pAdapter->StaCfg.LastScanTime = Now;
MlmeEnqueue(pAdapter,
MLME_CNTL_STATE_MACHINE,
OID_802_11_BSSID_LIST_SCAN,
0,
NULL);
Status = NDIS_STATUS_SUCCESS;
RT28XX_MLME_HANDLER(pAdapter);
}while(0);
return 0;
}
int rt_ioctl_giwscan(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
int i=0;
char *current_ev = extra, *previous_ev = extra;
char *end_buf;
char *current_val, custom[MAX_CUSTOM_LEN] = {0};
#ifndef IWEVGENIE
char idx;
#endif // IWEVGENIE //
struct iw_event iwe;
if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
{
/*
* Still scanning, indicate the caller should try again.
*/
return -EAGAIN;
}
#ifdef WPA_SUPPLICANT_SUPPORT
if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
{
pAdapter->StaCfg.WpaSupplicantScanCount = 0;
}
#endif // WPA_SUPPLICANT_SUPPORT //
if (pAdapter->ScanTab.BssNr == 0)
{
data->length = 0;
return 0;
}
#if WIRELESS_EXT >= 17
if (data->length > 0)
end_buf = extra + data->length;
else
end_buf = extra + IW_SCAN_MAX_DATA;
#else
end_buf = extra + IW_SCAN_MAX_DATA;
#endif
for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
{
if (current_ev >= end_buf)
{
#if WIRELESS_EXT >= 17
return -E2BIG;
#else
break;
#endif
}
//MAC address
//================================
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
previous_ev = current_ev;
current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
if (current_ev == previous_ev)
#if WIRELESS_EXT >= 17
return -E2BIG;
#else
break;
#endif
/*
Protocol:
it will show scanned AP's WirelessMode .
it might be
802.11a
802.11a/n
802.11g/n
802.11b/g/n
802.11g
802.11b/g
*/
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWNAME;
{
PBSS_ENTRY pBssEntry=&pAdapter->ScanTab.BssEntry[i];
BOOLEAN isGonly=FALSE;
int rateCnt=0;
if (pBssEntry->Channel>14)
{
if (pBssEntry->HtCapabilityLen!=0)
strcpy(iwe.u.name,"802.11a/n");
else
strcpy(iwe.u.name,"802.11a");
}
else
{
/*
if one of non B mode rate is set supported rate . it mean G only.
*/
for (rateCnt=0;rateCnt<pBssEntry->SupRateLen;rateCnt++)
{
/*
6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only.
*/
if (pBssEntry->SupRate[rateCnt]==140 || pBssEntry->SupRate[rateCnt]==146 || pBssEntry->SupRate[rateCnt]>=152)
isGonly=TRUE;
}
for (rateCnt=0;rateCnt<pBssEntry->ExtRateLen;rateCnt++)
{
if (pBssEntry->ExtRate[rateCnt]==140 || pBssEntry->ExtRate[rateCnt]==146 || pBssEntry->ExtRate[rateCnt]>=152)
isGonly=TRUE;
}
if (pBssEntry->HtCapabilityLen!=0)
{
if (isGonly==TRUE)
strcpy(iwe.u.name,"802.11g/n");
else
strcpy(iwe.u.name,"802.11b/g/n");
}
else
{
if (isGonly==TRUE)
strcpy(iwe.u.name,"802.11g");
else
{
if (pBssEntry->SupRateLen==4 && pBssEntry->ExtRateLen==0)
strcpy(iwe.u.name,"802.11b");
else
strcpy(iwe.u.name,"802.11b/g");
}
}
}
}
previous_ev = current_ev;
current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
if (current_ev == previous_ev)
#if WIRELESS_EXT >= 17
return -E2BIG;
#else
break;
#endif
//ESSID
//================================
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
iwe.u.data.flags = 1;
previous_ev = current_ev;
current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid);
if (current_ev == previous_ev)
#if WIRELESS_EXT >= 17
return -E2BIG;
#else
break;
#endif
//Network Type
//================================
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWMODE;
if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
{
iwe.u.mode = IW_MODE_ADHOC;
}
else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
{
iwe.u.mode = IW_MODE_INFRA;
}
else
{
iwe.u.mode = IW_MODE_AUTO;
}
iwe.len = IW_EV_UINT_LEN;
previous_ev = current_ev;
current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
if (current_ev == previous_ev)
#if WIRELESS_EXT >= 17
return -E2BIG;
#else
break;
#endif
//Channel and Frequency
//================================
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWFREQ;
if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
else
iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
iwe.u.freq.e = 0;
iwe.u.freq.i = 0;
previous_ev = current_ev;
current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
if (current_ev == previous_ev)
#if WIRELESS_EXT >= 17
return -E2BIG;
#else
break;
#endif
//Add quality statistics
//================================
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVQUAL;
iwe.u.qual.level = 0;
iwe.u.qual.noise = 0;
set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
if (current_ev == previous_ev)
#if WIRELESS_EXT >= 17
return -E2BIG;
#else
break;
#endif
//Encyption key
//================================
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWENCODE;
if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
previous_ev = current_ev;
current_ev = iwe_stream_add_point(info, current_ev, end_buf,&iwe, (char *)pAdapter->SharedKey[BSS0][(iwe.u.data.flags & IW_ENCODE_INDEX)-1].Key);
if (current_ev == previous_ev)
#if WIRELESS_EXT >= 17
return -E2BIG;
#else
break;
#endif
//Bit Rate
//================================
if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
{
UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWRATE;
current_val = current_ev + IW_EV_LCP_LEN;
if (tmpRate == 0x82)
iwe.u.bitrate.value = 1 * 1000000;
else if (tmpRate == 0x84)
iwe.u.bitrate.value = 2 * 1000000;
else if (tmpRate == 0x8B)
iwe.u.bitrate.value = 5.5 * 1000000;
else if (tmpRate == 0x96)
iwe.u.bitrate.value = 11 * 1000000;
else
iwe.u.bitrate.value = (tmpRate/2) * 1000000;
iwe.u.bitrate.disabled = 0;
current_val = iwe_stream_add_value(info, current_ev,
current_val, end_buf, &iwe,
IW_EV_PARAM_LEN);
if((current_val-current_ev)>IW_EV_LCP_LEN)
current_ev = current_val;
else
#if WIRELESS_EXT >= 17
return -E2BIG;
#else
break;
#endif
}
#ifdef IWEVGENIE
//WPA IE
if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
{
memset(&iwe, 0, sizeof(iwe));
memset(&custom[0], 0, MAX_CUSTOM_LEN);
memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
if (current_ev == previous_ev)
#if WIRELESS_EXT >= 17
return -E2BIG;
#else
break;
#endif
}
//WPA2 IE
if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
{
memset(&iwe, 0, sizeof(iwe));
memset(&custom[0], 0, MAX_CUSTOM_LEN);
memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
if (current_ev == previous_ev)
#if WIRELESS_EXT >= 17
return -E2BIG;
#else
break;
#endif
}
#else
//WPA IE
//================================
if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
{
NdisZeroMemory(&iwe, sizeof(iwe));
memset(&custom[0], 0, MAX_CUSTOM_LEN);
iwe.cmd = IWEVCUSTOM;
iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen * 2) + 7;
NdisMoveMemory(custom, "wpa_ie=", 7);
for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].WpaIE.IELen; idx++)
sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].WpaIE.IE[idx]);
previous_ev = current_ev;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom);
if (current_ev == previous_ev)
#if WIRELESS_EXT >= 17
return -E2BIG;
#else
break;
#endif
}
//WPA2 IE
if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
{
NdisZeroMemory(&iwe, sizeof(iwe));
memset(&custom[0], 0, MAX_CUSTOM_LEN);
iwe.cmd = IWEVCUSTOM;
iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen * 2) + 7;
NdisMoveMemory(custom, "rsn_ie=", 7);
for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].RsnIE.IELen; idx++)
sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].RsnIE.IE[idx]);
previous_ev = current_ev;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom);
if (current_ev == previous_ev)
#if WIRELESS_EXT >= 17
return -E2BIG;
#else
break;
#endif
}
#endif // IWEVGENIE //
}
data->length = current_ev - extra;
pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
return 0;
}
#endif
int rt_ioctl_siwessid(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *essid)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
if (data->flags)
{
PCHAR pSsidString = NULL;
// Includes null character.
if (data->length > (IW_ESSID_MAX_SIZE + 1))
return -E2BIG;
pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
if (pSsidString)
{
NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
NdisMoveMemory(pSsidString, essid, data->length);
if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
return -EINVAL;
}
else
return -ENOMEM;
}
else
{
// ANY ssid
if (Set_SSID_Proc(pAdapter, "") == FALSE)
return -EINVAL;
}
return 0;
}
int rt_ioctl_giwessid(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *essid)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
data->flags = 1;
if (MONITOR_ON(pAdapter))
{
data->length = 0;
return 0;
}
if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
{
DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
data->length = pAdapter->CommonCfg.SsidLen;
memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
}
#ifdef RT2870
#ifdef WPA_SUPPLICANT_SUPPORT
// Add for RT2870
else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
{
data->length = pAdapter->CommonCfg.SsidLen;
memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
}
#endif // WPA_SUPPLICANT_SUPPORT //
#endif // RT2870 //
else
{//the ANY ssid was specified
data->length = 0;
DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
}
return 0;
}
int rt_ioctl_siwnickn(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *nickname)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
return -ENETDOWN;
}
if (data->length > IW_ESSID_MAX_SIZE)
return -EINVAL;
memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
memcpy(pAdapter->nickname, nickname, data->length);
return 0;
}
int rt_ioctl_giwnickn(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *nickname)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
if (data->length > strlen(pAdapter->nickname) + 1)
data->length = strlen(pAdapter->nickname) + 1;
if (data->length > 0) {
memcpy(nickname, pAdapter->nickname, data->length-1);
nickname[data->length-1] = '\0';
}
return 0;
}
int rt_ioctl_siwrts(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *rts, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
u16 val;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
if (rts->disabled)
val = MAX_RTS_THRESHOLD;
else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
return -EINVAL;
else if (rts->value == 0)
val = MAX_RTS_THRESHOLD;
else
val = rts->value;
if (val != pAdapter->CommonCfg.RtsThreshold)
pAdapter->CommonCfg.RtsThreshold = val;
return 0;
}
int rt_ioctl_giwrts(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *rts, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
rts->value = pAdapter->CommonCfg.RtsThreshold;
rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
rts->fixed = 1;
return 0;
}
int rt_ioctl_siwfrag(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *frag, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
u16 val;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
if (frag->disabled)
val = MAX_FRAG_THRESHOLD;
else if (frag->value >= MIN_FRAG_THRESHOLD || frag->value <= MAX_FRAG_THRESHOLD)
val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
else if (frag->value == 0)
val = MAX_FRAG_THRESHOLD;
else
return -EINVAL;
pAdapter->CommonCfg.FragmentThreshold = val;
return 0;
}
int rt_ioctl_giwfrag(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *frag, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
frag->value = pAdapter->CommonCfg.FragmentThreshold;
frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
frag->fixed = 1;
return 0;
}
#define MAX_WEP_KEY_SIZE 13
#define MIN_WEP_KEY_SIZE 5
int rt_ioctl_siwencode(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *erq, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
if ((erq->length == 0) &&
(erq->flags & IW_ENCODE_DISABLED))
{
pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
goto done;
}
else if (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN)
{
//pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
STA_PORT_SECURED(pAdapter);
pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
if (erq->flags & IW_ENCODE_RESTRICTED)
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
else
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
}
if (erq->length > 0)
{
int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
/* Check the size of the key */
if (erq->length > MAX_WEP_KEY_SIZE)
{
return -EINVAL;
}
/* Check key index */
if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
{
DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
keyIdx, pAdapter->StaCfg.DefaultKeyId));
//Using default key
keyIdx = pAdapter->StaCfg.DefaultKeyId;
}
else
{
pAdapter->StaCfg.DefaultKeyId=keyIdx;
}
NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
if (erq->length == MAX_WEP_KEY_SIZE)
{
pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
}
else if (erq->length == MIN_WEP_KEY_SIZE)
{
pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
}
else
/* Disable the key */
pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
/* Check if the key is not marked as invalid */
if(!(erq->flags & IW_ENCODE_NOKEY))
{
/* Copy the key in the driver */
NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
}
}
else
{
/* Do we want to just set the transmit key index ? */
int index = (erq->flags & IW_ENCODE_INDEX) - 1;
if ((index >= 0) && (index < 4))
{
pAdapter->StaCfg.DefaultKeyId = index;
}
else
/* Don't complain if only change the mode */
if(!erq->flags & IW_ENCODE_MODE)
{
return -EINVAL;
}
}
done:
DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
return 0;
}
int
rt_ioctl_giwencode(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *erq, char *key)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
int kid;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
kid = erq->flags & IW_ENCODE_INDEX;
DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
{
erq->length = 0;
erq->flags = IW_ENCODE_DISABLED;
}
else if ((kid > 0) && (kid <=4))
{
// copy wep key
erq->flags = kid ; /* NB: base 1 */
if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
//if ((kid == pAdapter->PortCfg.DefaultKeyId))
//erq->flags |= IW_ENCODE_ENABLED; /* XXX */
if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
else
erq->flags |= IW_ENCODE_OPEN; /* XXX */
}
else if (kid == 0)
{
if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
else
erq->flags |= IW_ENCODE_OPEN; /* XXX */
erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
// copy default key ID
if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
else
erq->flags |= IW_ENCODE_OPEN; /* XXX */
erq->flags = pAdapter->StaCfg.DefaultKeyId + 1; /* NB: base 1 */
erq->flags |= IW_ENCODE_ENABLED; /* XXX */
}
return 0;
}
static int
rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
void *w, char *extra)
{
VIRTUAL_ADAPTER *pVirtualAd = NULL;
PRTMP_ADAPTER pAdapter;
POS_COOKIE pObj;
char *this_char = extra;
char *value;
int Status=0;
if (dev->priv_flags == INT_MAIN)
{
pAdapter = dev->ml_priv;
}
else
{
pVirtualAd = dev->ml_priv;
pAdapter = pVirtualAd->RtmpDev->ml_priv;
}
pObj = (POS_COOKIE) pAdapter->OS_Cookie;
if (pAdapter == NULL)
{
/* if 1st open fail, pAd will be free;
So the net_dev->ml_priv will be NULL in 2rd open */
return -ENETDOWN;
}
{
pObj->ioctl_if_type = INT_MAIN;
pObj->ioctl_if = MAIN_MBSSID;
}
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
if (!*this_char)
return -EINVAL;
if ((value = rtstrchr(this_char, '=')) != NULL)
*value++ = 0;
if (!value)
return -EINVAL;
// reject setting nothing besides ANY ssid(ssidLen=0)
if (!*value && (strcmp(this_char, "SSID") != 0))
return -EINVAL;
for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
{
if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
{
if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
{ //FALSE:Set private failed then return Invalid argument
Status = -EINVAL;
}
break; //Exit for loop.
}
}
if(PRTMP_PRIVATE_SET_PROC->name == NULL)
{ //Not found argument
Status = -EINVAL;
DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
}
return Status;
}
static int
rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
struct iw_point *wrq, char *extra)
{
INT Status = 0;
PRTMP_ADAPTER pAd = dev->ml_priv;
if (extra == NULL)
{
wrq->length = 0;
return -EIO;
}
memset(extra, 0x00, IW_PRIV_SIZE_MASK);
sprintf(extra, "\n\n");
#ifdef RALINK_ATE
if (ATE_ON(pAd))
{
sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->ate.TxDoneCount);
//sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->ate.TxDoneCount);
}
else
#endif // RALINK_ATE //
{
sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
}
sprintf(extra+strlen(extra), "Tx success after retry = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
sprintf(extra+strlen(extra), "RTS Success Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
sprintf(extra+strlen(extra), "RTS Fail Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
sprintf(extra+strlen(extra), "Rx success = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
sprintf(extra+strlen(extra), "Rx with CRC = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
sprintf(extra+strlen(extra), "Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
sprintf(extra+strlen(extra), "Rx duplicate frame = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
sprintf(extra+strlen(extra), "False CCA (one second) = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
#ifdef RALINK_ATE
if (ATE_ON(pAd))
{
if (pAd->ate.RxAntennaSel == 0)
{
sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->ate.LastRssi1 - pAd->BbpRssiToDbmDelta));
sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->ate.LastRssi2 - pAd->BbpRssiToDbmDelta));
}
else
{
sprintf(extra+strlen(extra), "RSSI = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
}
}
else
#endif // RALINK_ATE //
{
sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
}
#ifdef WPA_SUPPLICANT_SUPPORT
sprintf(extra+strlen(extra), "WpaSupplicantUP = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
#endif // WPA_SUPPLICANT_SUPPORT //
wrq->length = strlen(extra) + 1; // 1: size of '\0'
DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
return Status;
}
#ifdef DOT11_N_SUPPORT
void getBaInfo(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pOutBuf)
{
INT i, j;
BA_ORI_ENTRY *pOriBAEntry;
BA_REC_ENTRY *pRecBAEntry;
for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
{
PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
|| (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
{
sprintf(pOutBuf, "%s\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
pOutBuf,
pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
for (j=0; j < NUM_OF_TID; j++)
{
if (pEntry->BARecWcidArray[j] != 0)
{
pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", pOutBuf, j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
}
}
sprintf(pOutBuf, "%s\n", pOutBuf);
sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
for (j=0; j < NUM_OF_TID; j++)
{
if (pEntry->BAOriWcidArray[j] != 0)
{
pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", pOutBuf, j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
}
}
sprintf(pOutBuf, "%s\n\n", pOutBuf);
}
if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
break;
}
return;
}
#endif // DOT11_N_SUPPORT //
static int
rt_private_show(struct net_device *dev, struct iw_request_info *info,
struct iw_point *wrq, char *extra)
{
INT Status = 0;
VIRTUAL_ADAPTER *pVirtualAd = NULL;
PRTMP_ADAPTER pAd;
POS_COOKIE pObj;
u32 subcmd = wrq->flags;
if (dev->priv_flags == INT_MAIN)
pAd = dev->ml_priv;
else
{
pVirtualAd = dev->ml_priv;
pAd = pVirtualAd->RtmpDev->ml_priv;
}
pObj = (POS_COOKIE) pAd->OS_Cookie;
if (pAd == NULL)
{
/* if 1st open fail, pAd will be free;
So the net_dev->ml_priv will be NULL in 2rd open */
return -ENETDOWN;
}
if (extra == NULL)
{
wrq->length = 0;
return -EIO;
}
memset(extra, 0x00, IW_PRIV_SIZE_MASK);
{
pObj->ioctl_if_type = INT_MAIN;
pObj->ioctl_if = MAIN_MBSSID;
}
switch(subcmd)
{
case SHOW_CONN_STATUS:
if (MONITOR_ON(pAd))
{
#ifdef DOT11_N_SUPPORT
if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
pAd->CommonCfg.RegTransmitSetting.field.BW)
sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
else
#endif // DOT11_N_SUPPORT //
sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
}
else
{
if (pAd->IndicateMediaState == NdisMediaStateConnected)
{
if (INFRA_ON(pAd))
{
sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
pAd->CommonCfg.Ssid,
pAd->CommonCfg.Bssid[0],
pAd->CommonCfg.Bssid[1],
pAd->CommonCfg.Bssid[2],
pAd->CommonCfg.Bssid[3],
pAd->CommonCfg.Bssid[4],
pAd->CommonCfg.Bssid[5]);
DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
}
else if (ADHOC_ON(pAd))
sprintf(extra, "Connected\n");
}
else
{
sprintf(extra, "Disconnected\n");
DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
}
}
wrq->length = strlen(extra) + 1; // 1: size of '\0'
break;
case SHOW_DRVIER_VERION:
sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
wrq->length = strlen(extra) + 1; // 1: size of '\0'
break;
#ifdef DOT11_N_SUPPORT
case SHOW_BA_INFO:
getBaInfo(pAd, extra);
wrq->length = strlen(extra) + 1; // 1: size of '\0'
break;
#endif // DOT11_N_SUPPORT //
case SHOW_DESC_INFO:
{
Show_DescInfo_Proc(pAd, NULL);
wrq->length = 0; // 1: size of '\0'
}
break;
case RAIO_OFF:
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
{
sprintf(extra, "Scanning\n");
wrq->length = strlen(extra) + 1; // 1: size of '\0'
break;
}
pAd->StaCfg.bSwRadio = FALSE;
if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
{
pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
if (pAd->StaCfg.bRadio == FALSE)
{
MlmeRadioOff(pAd);
// Update extra information
pAd->ExtraInfo = SW_RADIO_OFF;
}
}
sprintf(extra, "Radio Off\n");
wrq->length = strlen(extra) + 1; // 1: size of '\0'
break;
case RAIO_ON:
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
{
sprintf(extra, "Scanning\n");
wrq->length = strlen(extra) + 1; // 1: size of '\0'
break;
}
pAd->StaCfg.bSwRadio = TRUE;
//if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
{
pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
if (pAd->StaCfg.bRadio == TRUE)
{
MlmeRadioOn(pAd);
// Update extra information
pAd->ExtraInfo = EXTRA_INFO_CLEAR;
}
}
sprintf(extra, "Radio On\n");
wrq->length = strlen(extra) + 1; // 1: size of '\0'
break;
#ifdef QOS_DLS_SUPPORT
case SHOW_DLS_ENTRY_INFO:
{
Set_DlsEntryInfo_Display_Proc(pAd, NULL);
wrq->length = 0; // 1: size of '\0'
}
break;
#endif // QOS_DLS_SUPPORT //
case SHOW_CFG_VALUE:
{
Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
if (Status == 0)
wrq->length = strlen(extra) + 1; // 1: size of '\0'
}
break;
default:
DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __FUNCTION__, subcmd));
break;
}
return Status;
}
#ifdef SIOCSIWMLME
int rt_ioctl_siwmlme(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu,
char *extra)
{
PRTMP_ADAPTER pAd = dev->ml_priv;
struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
MLME_QUEUE_ELEM MsgElem;
MLME_DISASSOC_REQ_STRUCT DisAssocReq;
MLME_DEAUTH_REQ_STRUCT DeAuthReq;
DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));
if (pMlme == NULL)
return -EINVAL;
switch(pMlme->cmd)
{
#ifdef IW_MLME_DEAUTH
case IW_MLME_DEAUTH:
DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __FUNCTION__));
COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
DeAuthReq.Reason = pMlme->reason_code;
MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
MlmeDeauthReqAction(pAd, &MsgElem);
if (INFRA_ON(pAd))
{
LinkDown(pAd, FALSE);
pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
}
break;
#endif // IW_MLME_DEAUTH //
#ifdef IW_MLME_DISASSOC
case IW_MLME_DISASSOC:
DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __FUNCTION__));
COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
DisAssocReq.Reason = pMlme->reason_code;
MsgElem.Machine = ASSOC_STATE_MACHINE;
MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
MlmeDisassocReqAction(pAd, &MsgElem);
break;
#endif // IW_MLME_DISASSOC //
default:
DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __FUNCTION__));
break;
}
return 0;
}
#endif // SIOCSIWMLME //
#if WIRELESS_EXT > 17
int rt_ioctl_siwauth(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
struct iw_param *param = &wrqu->param;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
switch (param->flags & IW_AUTH_INDEX) {
case IW_AUTH_WPA_VERSION:
if (param->value == IW_AUTH_WPA_VERSION_WPA)
{
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
if (pAdapter->StaCfg.BssType == BSS_ADHOC)
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
}
else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
break;
case IW_AUTH_CIPHER_PAIRWISE:
if (param->value == IW_AUTH_CIPHER_NONE)
{
pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
}
else if (param->value == IW_AUTH_CIPHER_WEP40 ||
param->value == IW_AUTH_CIPHER_WEP104)
{
pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
#ifdef WPA_SUPPLICANT_SUPPORT
pAdapter->StaCfg.IEEE8021X = FALSE;
#endif // WPA_SUPPLICANT_SUPPORT //
}
else if (param->value == IW_AUTH_CIPHER_TKIP)
{
pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
}
else if (param->value == IW_AUTH_CIPHER_CCMP)
{
pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
}
DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __FUNCTION__, param->value));
break;
case IW_AUTH_CIPHER_GROUP:
if (param->value == IW_AUTH_CIPHER_NONE)
{
pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
}
else if (param->value == IW_AUTH_CIPHER_WEP40 ||
param->value == IW_AUTH_CIPHER_WEP104)
{
pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
}
else if (param->value == IW_AUTH_CIPHER_TKIP)
{
pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
}
else if (param->value == IW_AUTH_CIPHER_CCMP)
{
pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
}
DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __FUNCTION__, param->value));
break;
case IW_AUTH_KEY_MGMT:
if (param->value == IW_AUTH_KEY_MGMT_802_1X)
{
if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
{
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
#ifdef WPA_SUPPLICANT_SUPPORT
pAdapter->StaCfg.IEEE8021X = FALSE;
#endif // WPA_SUPPLICANT_SUPPORT //
}
else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
{
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
#ifdef WPA_SUPPLICANT_SUPPORT
pAdapter->StaCfg.IEEE8021X = FALSE;
#endif // WPA_SUPPLICANT_SUPPORT //
}
#ifdef WPA_SUPPLICANT_SUPPORT
else
// WEP 1x
pAdapter->StaCfg.IEEE8021X = TRUE;
#endif // WPA_SUPPLICANT_SUPPORT //
}
else if (param->value == 0)
{
//pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
STA_PORT_SECURED(pAdapter);
}
DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __FUNCTION__, param->value));
break;
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
break;
case IW_AUTH_PRIVACY_INVOKED:
/*if (param->value == 0)
{
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
}*/
DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __FUNCTION__, param->value));
break;
case IW_AUTH_DROP_UNENCRYPTED:
if (param->value != 0)
pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
else
{
//pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
STA_PORT_SECURED(pAdapter);
}
DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
break;
case IW_AUTH_80211_AUTH_ALG:
if (param->value & IW_AUTH_ALG_SHARED_KEY)
{
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
}
else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
{
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
}
else
return -EINVAL;
DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __FUNCTION__, param->value));
break;
case IW_AUTH_WPA_ENABLED:
DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __FUNCTION__, param->value));
break;
default:
return -EOPNOTSUPP;
}
return 0;
}
int rt_ioctl_giwauth(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
struct iw_param *param = &wrqu->param;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
switch (param->flags & IW_AUTH_INDEX) {
case IW_AUTH_DROP_UNENCRYPTED:
param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
break;
case IW_AUTH_80211_AUTH_ALG:
param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
break;
case IW_AUTH_WPA_ENABLED:
param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
break;
default:
return -EOPNOTSUPP;
}
DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
return 0;
}
void fnSetCipherKey(
IN PRTMP_ADAPTER pAdapter,
IN INT keyIdx,
IN UCHAR CipherAlg,
IN BOOLEAN bGTK,
IN struct iw_encode_ext *ext)
{
NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
// Update group key information to ASIC Shared Key Table
AsicAddSharedKeyEntry(pAdapter,
BSS0,
keyIdx,
pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
pAdapter->SharedKey[BSS0][keyIdx].Key,
pAdapter->SharedKey[BSS0][keyIdx].TxMic,
pAdapter->SharedKey[BSS0][keyIdx].RxMic);
if (bGTK)
// Update ASIC WCID attribute table and IVEIV table
RTMPAddWcidAttributeEntry(pAdapter,
BSS0,
keyIdx,
pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
NULL);
else
// Update ASIC WCID attribute table and IVEIV table
RTMPAddWcidAttributeEntry(pAdapter,
BSS0,
keyIdx,
pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
&pAdapter->MacTab.Content[BSSID_WCID]);
}
int rt_ioctl_siwencodeext(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu,
char *extra)
{
PRTMP_ADAPTER pAdapter = dev->ml_priv;
struct iw_point *encoding = &wrqu->encoding;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
int keyIdx, alg = ext->alg;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
if (encoding->flags & IW_ENCODE_DISABLED)
{
keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
// set BSSID wcid entry of the Pair-wise Key table as no-security mode
AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __FUNCTION__, encoding->flags));
}
else
{
// Get Key Index and convet to our own defined key index
keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
return -EINVAL;
if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
{
pAdapter->StaCfg.DefaultKeyId = keyIdx;
DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __FUNCTION__, pAdapter->StaCfg.DefaultKeyId));
}
switch (alg) {
case IW_ENCODE_ALG_NONE:
DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __FUNCTION__));
break;
case IW_ENCODE_ALG_WEP:
DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __FUNCTION__, ext->key_len, keyIdx));
if (ext->key_len == MAX_WEP_KEY_SIZE)
{
pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
}
else if (ext->key_len == MIN_WEP_KEY_SIZE)
{
pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
}
else
return -EINVAL;
NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
break;
case IW_ENCODE_ALG_TKIP:
DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __FUNCTION__, keyIdx, ext->key_len));
if (ext->key_len == 32)
{
if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
{
fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
{
//pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
STA_PORT_SECURED(pAdapter);
}
}
else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
{
fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
// set 802.1x port control
//pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
STA_PORT_SECURED(pAdapter);
}
}
else
return -EINVAL;
break;
case IW_ENCODE_ALG_CCMP:
if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
{
fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
//pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
STA_PORT_SECURED(pAdapter);
}
else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
{
fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
// set 802.1x port control
//pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
STA_PORT_SECURED(pAdapter);
}
break;
default:
return -EINVAL;
}
}
return 0;
}
int
rt_ioctl_giwencodeext(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
PRTMP_ADAPTER pAd = dev->ml_priv;
PCHAR pKey = NULL;
struct iw_point *encoding = &wrqu->encoding;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
int idx, max_key_len;
DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
max_key_len = encoding->length - sizeof(*ext);
if (max_key_len < 0)
return -EINVAL;
idx = encoding->flags & IW_ENCODE_INDEX;
if (idx)
{
if (idx < 1 || idx > 4)
return -EINVAL;
idx--;
if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
{
if (idx != pAd->StaCfg.DefaultKeyId)
{
ext->key_len = 0;
return 0;
}
}
}
else
idx = pAd->StaCfg.DefaultKeyId;
encoding->flags = idx + 1;
memset(ext, 0, sizeof(*ext));
ext->key_len = 0;
switch(pAd->StaCfg.WepStatus) {
case Ndis802_11WEPDisabled:
ext->alg = IW_ENCODE_ALG_NONE;
encoding->flags |= IW_ENCODE_DISABLED;
break;
case Ndis802_11WEPEnabled:
ext->alg = IW_ENCODE_ALG_WEP;
if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
return -E2BIG;
else
{
ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
}
break;
case Ndis802_11Encryption2Enabled:
case Ndis802_11Encryption3Enabled:
if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
ext->alg = IW_ENCODE_ALG_TKIP;
else
ext->alg = IW_ENCODE_ALG_CCMP;
if (max_key_len < 32)
return -E2BIG;
else
{
ext->key_len = 32;
pKey = &pAd->StaCfg.PMK[0];
}
break;
default:
return -EINVAL;
}
if (ext->key_len && pKey)
{
encoding->flags |= IW_ENCODE_ENABLED;
memcpy(ext->key, pKey, ext->key_len);
}
return 0;
}
#ifdef SIOCSIWGENIE
int rt_ioctl_siwgenie(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
PRTMP_ADAPTER pAd = dev->ml_priv;
if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
(wrqu->data.length && extra == NULL))
return -EINVAL;
if (wrqu->data.length)
{
pAd->StaCfg.RSNIE_Len = wrqu->data.length;
NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
}
else
{
pAd->StaCfg.RSNIE_Len = 0;
NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
}
return 0;
}
#endif // SIOCSIWGENIE //
int rt_ioctl_giwgenie(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
PRTMP_ADAPTER pAd = dev->ml_priv;
if ((pAd->StaCfg.RSNIE_Len == 0) ||
(pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
{
wrqu->data.length = 0;
return 0;
}
#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
#ifdef SIOCSIWGENIE
if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
{
if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
return -E2BIG;
wrqu->data.length = pAd->StaCfg.RSNIE_Len;
memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
}
else
#endif // SIOCSIWGENIE //
#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
{
UCHAR RSNIe = IE_WPA;
if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
return -E2BIG;
wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
RSNIe = IE_RSN;
extra[0] = (char)RSNIe;
extra[1] = pAd->StaCfg.RSNIE_Len;
memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
}
return 0;
}
int rt_ioctl_siwpmksa(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu,
char *extra)
{
PRTMP_ADAPTER pAd = dev->ml_priv;
struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
INT CachedIdx = 0, idx = 0;
if (pPmksa == NULL)
return -EINVAL;
DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
switch(pPmksa->cmd)
{
case IW_PMKSA_FLUSH:
NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
break;
case IW_PMKSA_REMOVE:
for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
{
// compare the BSSID
if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
{
NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
{
NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
}
pAd->StaCfg.SavedPMKNum--;
break;
}
}
DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
break;
case IW_PMKSA_ADD:
for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
{
// compare the BSSID
if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
break;
}
// Found, replace it
if (CachedIdx < PMKID_NO)
{
DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
pAd->StaCfg.SavedPMKNum++;
}
// Not found, replace the last one
else
{
// Randomly replace one
CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
}
DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
break;
default:
DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
break;
}
return 0;
}
#endif // #if WIRELESS_EXT > 17
#ifdef DBG
static int
rt_private_ioctl_bbp(struct net_device *dev, struct iw_request_info *info,
struct iw_point *wrq, char *extra)
{
CHAR *this_char;
CHAR *value = NULL;
UCHAR regBBP = 0;
// CHAR arg[255]={0};
UINT32 bbpId;
UINT32 bbpValue;
BOOLEAN bIsPrintAllBBP = FALSE;
INT Status = 0;
PRTMP_ADAPTER pAdapter = dev->ml_priv;
memset(extra, 0x00, IW_PRIV_SIZE_MASK);
if (wrq->length > 1) //No parameters.
{
sprintf(extra, "\n");
//Parsing Read or Write
this_char = wrq->pointer;
DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s\n", this_char));
if (!*this_char)
goto next;
if ((value = rtstrchr(this_char, '=')) != NULL)
*value++ = 0;
if (!value || !*value)
{ //Read
DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s, value=%s\n", this_char, value));
if (sscanf(this_char, "%d", &(bbpId)) == 1)
{
#ifndef RT30xx
if (bbpId <= 136)
#endif // RT30xx //
#ifdef RT30xx
if (bbpId <= 138) // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
#endif // RT30xx //
{
#ifdef RALINK_ATE
if (ATE_ON(pAdapter))
{
ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
}
else
#endif // RALINK_ATE //
{
RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
}
sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
wrq->length = strlen(extra) + 1; // 1: size of '\0'
DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
}
else
{//Invalid parametes, so default printk all bbp
bIsPrintAllBBP = TRUE;
goto next;
}
}
else
{ //Invalid parametes, so default printk all bbp
bIsPrintAllBBP = TRUE;
goto next;
}
}
else
{ //Write
if ((sscanf(this_char, "%d", &(bbpId)) == 1) && (sscanf(value, "%x", &(bbpValue)) == 1))
{
#ifndef RT30xx
if (bbpId <= 136)
#endif // RT30xx //
#ifdef RT30xx
if (bbpId <= 138) // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
#endif // RT30xx //
{
#ifdef RALINK_ATE
if (ATE_ON(pAdapter))
{
ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
//Read it back for showing
ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
}
else
#endif // RALINK_ATE //
{
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
//Read it back for showing
RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
}
sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
wrq->length = strlen(extra) + 1; // 1: size of '\0'
DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
}
else
{//Invalid parametes, so default printk all bbp
bIsPrintAllBBP = TRUE;
goto next;
}
}
else
{ //Invalid parametes, so default printk all bbp
bIsPrintAllBBP = TRUE;
goto next;
}
}
}
else
bIsPrintAllBBP = TRUE;
next:
if (bIsPrintAllBBP)
{
memset(extra, 0x00, IW_PRIV_SIZE_MASK);
sprintf(extra, "\n");
#ifndef RT30xx
for (bbpId = 0; bbpId <= 136; bbpId++)
#endif // RT30xx //
#ifdef RT30xx
for (bbpId = 0; bbpId <= 138; bbpId++) // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
#endif // RT30xx //
{
if (strlen(extra) >= (IW_PRIV_SIZE_MASK - 10))
break;
#ifdef RALINK_ATE
if (ATE_ON(pAdapter))
{
ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
}
else
#endif // RALINK_ATE //
RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
/*
sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X ", bbpId, bbpId*2, regBBP);
if (bbpId%5 == 4)
sprintf(extra+strlen(extra), "\n");
*/
sprintf(extra+strlen(extra), "%03d = %02X\n", bbpId, regBBP); // edit by johnli, change display format
}
wrq->length = strlen(extra) + 1; // 1: size of '\0'
DBGPRINT(RT_DEBUG_TRACE, ("wrq->length = %d\n", wrq->length));
}
DBGPRINT(RT_DEBUG_TRACE, ("<==rt_private_ioctl_bbp\n\n"));
return Status;
}
#endif // DBG //
int rt_ioctl_siwrate(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
PRTMP_ADAPTER pAd = dev->ml_priv;
UINT32 rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
//check if the interface is down
if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
return -ENETDOWN;
}
DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
/* rate = -1 => auto rate
rate = X, fixed = 1 => (fixed rate X)
*/
if (rate == -1)
{
//Auto Rate
pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
pAd->StaCfg.bAutoTxRateSwitch = TRUE;
if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
(pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
RTMPSetDesiredRates(pAd, -1);
#ifdef DOT11_N_SUPPORT
SetCommonHT(pAd);
#endif // DOT11_N_SUPPORT //
}
else
{
if (fixed)
{
pAd->StaCfg.bAutoTxRateSwitch = FALSE;
if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
(pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
RTMPSetDesiredRates(pAd, rate);
else
{
pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
#ifdef DOT11_N_SUPPORT
SetCommonHT(pAd);
#endif // DOT11_N_SUPPORT //
}
DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
}
else
{
// TODO: rate = X, fixed = 0 => (rates <= X)
return -EOPNOTSUPP;
}
}
return 0;
}
int rt_ioctl_giwrate(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
PRTMP_ADAPTER pAd = dev->ml_priv;
int rate_index = 0, rate_count = 0;
HTTRANSMIT_SETTING ht_setting;
__s32 ralinkrate[] =
{2, 4, 11, 22, // CCK
12, 18, 24, 36, 48, 72, 96, 108, // OFDM
13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
39, 78, 117, 156, 234, 312, 351, 390, // 20MHz, 800ns GI, MCS: 16 ~ 23
27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
81, 162, 243, 324, 486, 648, 729, 810, // 40MHz, 800ns GI, MCS: 16 ~ 23
14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
43, 87, 130, 173, 260, 317, 390, 433, // 20MHz, 400ns GI, MCS: 16 ~ 23
30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
90, 180, 270, 360, 540, 720, 810, 900}; // 40MHz, 400ns GI, MCS: 16 ~ 23
rate_count = sizeof(ralinkrate)/sizeof(__s32);
//check if the interface is down
if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
(INFRA_ON(pAd)) &&
((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
ht_setting.word = pAd->StaCfg.HTPhyMode.word;
else
ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
#ifdef DOT11_N_SUPPORT
if (ht_setting.field.MODE >= MODE_HTMIX)
{
// rate_index = 12 + ((UCHAR)ht_setting.field.BW *16) + ((UCHAR)ht_setting.field.ShortGI *32) + ((UCHAR)ht_setting.field.MCS);
rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
}
else
#endif // DOT11_N_SUPPORT //
if (ht_setting.field.MODE == MODE_OFDM)
rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
else if (ht_setting.field.MODE == MODE_CCK)
rate_index = (UCHAR)(ht_setting.field.MCS);
if (rate_index < 0)
rate_index = 0;
if (rate_index > rate_count)
rate_index = rate_count;
wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
wrqu->bitrate.disabled = 0;
return 0;
}
static const iw_handler rt_handler[] =
{
(iw_handler) NULL, /* SIOCSIWCOMMIT */
(iw_handler) rt_ioctl_giwname, /* SIOCGIWNAME */
(iw_handler) NULL, /* SIOCSIWNWID */
(iw_handler) NULL, /* SIOCGIWNWID */
(iw_handler) rt_ioctl_siwfreq, /* SIOCSIWFREQ */
(iw_handler) rt_ioctl_giwfreq, /* SIOCGIWFREQ */
(iw_handler) rt_ioctl_siwmode, /* SIOCSIWMODE */
(iw_handler) rt_ioctl_giwmode, /* SIOCGIWMODE */
(iw_handler) NULL, /* SIOCSIWSENS */
(iw_handler) NULL, /* SIOCGIWSENS */
(iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
(iw_handler) rt_ioctl_giwrange, /* SIOCGIWRANGE */
(iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
(iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
(iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
(iw_handler) rt28xx_get_wireless_stats /* kernel code */, /* SIOCGIWSTATS */
(iw_handler) NULL, /* SIOCSIWSPY */
(iw_handler) NULL, /* SIOCGIWSPY */
(iw_handler) NULL, /* SIOCSIWTHRSPY */
(iw_handler) NULL, /* SIOCGIWTHRSPY */
(iw_handler) rt_ioctl_siwap, /* SIOCSIWAP */
(iw_handler) rt_ioctl_giwap, /* SIOCGIWAP */
#ifdef SIOCSIWMLME
(iw_handler) rt_ioctl_siwmlme, /* SIOCSIWMLME */
#else
(iw_handler) NULL, /* SIOCSIWMLME */
#endif // SIOCSIWMLME //
(iw_handler) rt_ioctl_iwaplist, /* SIOCGIWAPLIST */
#ifdef SIOCGIWSCAN
(iw_handler) rt_ioctl_siwscan, /* SIOCSIWSCAN */
(iw_handler) rt_ioctl_giwscan, /* SIOCGIWSCAN */
#else
(iw_handler) NULL, /* SIOCSIWSCAN */
(iw_handler) NULL, /* SIOCGIWSCAN */
#endif /* SIOCGIWSCAN */
(iw_handler) rt_ioctl_siwessid, /* SIOCSIWESSID */
(iw_handler) rt_ioctl_giwessid, /* SIOCGIWESSID */
(iw_handler) rt_ioctl_siwnickn, /* SIOCSIWNICKN */
(iw_handler) rt_ioctl_giwnickn, /* SIOCGIWNICKN */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) rt_ioctl_siwrate, /* SIOCSIWRATE */
(iw_handler) rt_ioctl_giwrate, /* SIOCGIWRATE */
(iw_handler) rt_ioctl_siwrts, /* SIOCSIWRTS */
(iw_handler) rt_ioctl_giwrts, /* SIOCGIWRTS */
(iw_handler) rt_ioctl_siwfrag, /* SIOCSIWFRAG */
(iw_handler) rt_ioctl_giwfrag, /* SIOCGIWFRAG */
(iw_handler) NULL, /* SIOCSIWTXPOW */
(iw_handler) NULL, /* SIOCGIWTXPOW */
(iw_handler) NULL, /* SIOCSIWRETRY */
(iw_handler) NULL, /* SIOCGIWRETRY */
(iw_handler) rt_ioctl_siwencode, /* SIOCSIWENCODE */
(iw_handler) rt_ioctl_giwencode, /* SIOCGIWENCODE */
(iw_handler) NULL, /* SIOCSIWPOWER */
(iw_handler) NULL, /* SIOCGIWPOWER */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
#if WIRELESS_EXT > 17
(iw_handler) rt_ioctl_siwgenie, /* SIOCSIWGENIE */
(iw_handler) rt_ioctl_giwgenie, /* SIOCGIWGENIE */
(iw_handler) rt_ioctl_siwauth, /* SIOCSIWAUTH */
(iw_handler) rt_ioctl_giwauth, /* SIOCGIWAUTH */
(iw_handler) rt_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
(iw_handler) rt_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */
(iw_handler) rt_ioctl_siwpmksa, /* SIOCSIWPMKSA */
#endif
};
static const iw_handler rt_priv_handlers[] = {
(iw_handler) NULL, /* + 0x00 */
(iw_handler) NULL, /* + 0x01 */
#ifndef CONFIG_AP_SUPPORT
(iw_handler) rt_ioctl_setparam, /* + 0x02 */
#else
(iw_handler) NULL, /* + 0x02 */
#endif // CONFIG_AP_SUPPORT //
#ifdef DBG
(iw_handler) rt_private_ioctl_bbp, /* + 0x03 */
#else
(iw_handler) NULL, /* + 0x03 */
#endif
(iw_handler) NULL, /* + 0x04 */
(iw_handler) NULL, /* + 0x05 */
(iw_handler) NULL, /* + 0x06 */
(iw_handler) NULL, /* + 0x07 */
(iw_handler) NULL, /* + 0x08 */
(iw_handler) rt_private_get_statistics, /* + 0x09 */
(iw_handler) NULL, /* + 0x0A */
(iw_handler) NULL, /* + 0x0B */
(iw_handler) NULL, /* + 0x0C */
(iw_handler) NULL, /* + 0x0D */
(iw_handler) NULL, /* + 0x0E */
(iw_handler) NULL, /* + 0x0F */
(iw_handler) NULL, /* + 0x10 */
(iw_handler) rt_private_show, /* + 0x11 */
(iw_handler) NULL, /* + 0x12 */
(iw_handler) NULL, /* + 0x13 */
(iw_handler) NULL, /* + 0x15 */
(iw_handler) NULL, /* + 0x17 */
(iw_handler) NULL, /* + 0x18 */
};
const struct iw_handler_def rt28xx_iw_handler_def =
{
#define N(a) (sizeof (a) / sizeof (a[0]))
.standard = (iw_handler *) rt_handler,
.num_standard = sizeof(rt_handler) / sizeof(iw_handler),
.private = (iw_handler *) rt_priv_handlers,
.num_private = N(rt_priv_handlers),
.private_args = (struct iw_priv_args *) privtab,
.num_private_args = N(privtab),
#if IW_HANDLER_VERSION >= 7
.get_wireless_stats = rt28xx_get_wireless_stats,
#endif
};
INT RTMPSetInformation(
IN PRTMP_ADAPTER pAdapter,
IN OUT struct ifreq *rq,
IN INT cmd)
{
struct iwreq *wrq = (struct iwreq *) rq;
NDIS_802_11_SSID Ssid;
NDIS_802_11_MAC_ADDRESS Bssid;
RT_802_11_PHY_MODE PhyMode;
RT_802_11_STA_CONFIG StaConfig;
NDIS_802_11_RATES aryRates;
RT_802_11_PREAMBLE Preamble;
NDIS_802_11_WEP_STATUS WepStatus;
NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeMax;
NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
NDIS_802_11_RTS_THRESHOLD RtsThresh;
NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
NDIS_802_11_POWER_MODE PowerMode;
PNDIS_802_11_KEY pKey = NULL;
PNDIS_802_11_WEP pWepKey =NULL;
PNDIS_802_11_REMOVE_KEY pRemoveKey = NULL;
NDIS_802_11_CONFIGURATION Config, *pConfig = NULL;
NDIS_802_11_NETWORK_TYPE NetType;
ULONG Now;
UINT KeyIdx = 0;
INT Status = NDIS_STATUS_SUCCESS, MaxPhyMode = PHY_11G;
ULONG PowerTemp;
BOOLEAN RadioState;
BOOLEAN StateMachineTouched = FALSE;
#ifdef DOT11_N_SUPPORT
OID_SET_HT_PHYMODE HT_PhyMode; //11n ,kathy
#endif // DOT11_N_SUPPORT //
#ifdef WPA_SUPPLICANT_SUPPORT
PNDIS_802_11_PMKID pPmkId = NULL;
BOOLEAN IEEE8021xState = FALSE;
BOOLEAN IEEE8021x_required_keys = FALSE;
UCHAR wpa_supplicant_enable = 0;
#endif // WPA_SUPPLICANT_SUPPORT //
#ifdef SNMP_SUPPORT
TX_RTY_CFG_STRUC tx_rty_cfg;
ULONG ShortRetryLimit, LongRetryLimit;
UCHAR ctmp;
#endif // SNMP_SUPPORT //
#ifdef DOT11_N_SUPPORT
MaxPhyMode = PHY_11N_5G;
#endif // DOT11_N_SUPPORT //
DBGPRINT(RT_DEBUG_TRACE, ("-->RTMPSetInformation(), 0x%08x\n", cmd&0x7FFF));
switch(cmd & 0x7FFF) {
case RT_OID_802_11_COUNTRY_REGION:
if (wrq->u.data.length < sizeof(UCHAR))
Status = -EINVAL;
// Only avaliable when EEPROM not programming
else if (!(pAdapter->CommonCfg.CountryRegion & 0x80) && !(pAdapter->CommonCfg.CountryRegionForABand & 0x80))
{
ULONG Country;
UCHAR TmpPhy;
Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length);
pAdapter->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF);
pAdapter->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF);
TmpPhy = pAdapter->CommonCfg.PhyMode;
pAdapter->CommonCfg.PhyMode = 0xff;
// Build all corresponding channel information
RTMPSetPhyMode(pAdapter, TmpPhy);
#ifdef DOT11_N_SUPPORT
SetCommonHT(pAdapter);
#endif // DOT11_N_SUPPORT //
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d B/G:%d)\n", pAdapter->CommonCfg.CountryRegionForABand,
pAdapter->CommonCfg.CountryRegion));
}
break;
case OID_802_11_BSSID_LIST_SCAN:
#ifdef RALINK_ATE
if (ATE_ON(pAdapter))
{
DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
break;
}
#endif // RALINK_ATE //
Now = jiffies;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAdapter->RalinkCounters.LastOneSecTotalTxCount));
if (MONITOR_ON(pAdapter))
{
DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
break;
}
//Benson add 20080527, when radio off, sta don't need to scan
if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
break;
if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
{
DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is scanning now !!!\n"));
pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
Status = NDIS_STATUS_SUCCESS;
break;
}
if (pAdapter->RalinkCounters.LastOneSecTotalTxCount > 100)
{
DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
Status = NDIS_STATUS_SUCCESS;
pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
break;
}
if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
(pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
{
DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
Status = NDIS_STATUS_SUCCESS;
pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
break;
}
if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
{
RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
}
// tell CNTL state machine to call NdisMSetInformationComplete() after completing
// this request, because this request is initiated by NDIS.
pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
// Reset allowed scan retries
pAdapter->StaCfg.ScanCnt = 0;
pAdapter->StaCfg.LastScanTime = Now;
pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
MlmeEnqueue(pAdapter,
MLME_CNTL_STATE_MACHINE,
OID_802_11_BSSID_LIST_SCAN,
0,
NULL);
Status = NDIS_STATUS_SUCCESS;
StateMachineTouched = TRUE;
break;
case OID_802_11_SSID:
if (wrq->u.data.length != sizeof(NDIS_802_11_SSID))
Status = -EINVAL;
else
{
PCHAR pSsidString = NULL;
Status = copy_from_user(&Ssid, wrq->u.data.pointer, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SSID (Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
if (Ssid.SsidLength > MAX_LEN_OF_SSID)
Status = -EINVAL;
else
{
if (Ssid.SsidLength == 0)
{
Set_SSID_Proc(pAdapter, "");
}
else
{
pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
if (pSsidString)
{
NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength);
Set_SSID_Proc(pAdapter, pSsidString);
kfree(pSsidString);
}
else
Status = -ENOMEM;
}
}
}
break;
case OID_802_11_BSSID:
#ifdef RALINK_ATE
if (ATE_ON(pAdapter))
{
DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
break;
}
#endif // RALINK_ATE //
if (wrq->u.data.length != sizeof(NDIS_802_11_MAC_ADDRESS))
Status = -EINVAL;
else
{
Status = copy_from_user(&Bssid, wrq->u.data.pointer, wrq->u.data.length);
// tell CNTL state machine to call NdisMSetInformationComplete() after completing
// this request, because this request is initiated by NDIS.
pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
// Prevent to connect AP again in STAMlmePeriodicExec
pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
// Reset allowed scan retries
pAdapter->StaCfg.ScanCnt = 0;
if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
{
RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
}
MlmeEnqueue(pAdapter,
MLME_CNTL_STATE_MACHINE,
OID_802_11_BSSID,
sizeof(NDIS_802_11_MAC_ADDRESS),
(VOID *)&Bssid);
Status = NDIS_STATUS_SUCCESS;
StateMachineTouched = TRUE;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
}
break;
case RT_OID_802_11_RADIO:
if (wrq->u.data.length != sizeof(BOOLEAN))
Status = -EINVAL;
else
{
Status = copy_from_user(&RadioState, wrq->u.data.pointer, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RADIO (=%d)\n", RadioState));
if (pAdapter->StaCfg.bSwRadio != RadioState)
{
pAdapter->StaCfg.bSwRadio = RadioState;
if (pAdapter->StaCfg.bRadio != (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio))
{
pAdapter->StaCfg.bRadio = (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio);
if (pAdapter->StaCfg.bRadio == TRUE)
{
MlmeRadioOn(pAdapter);
// Update extra information
pAdapter->ExtraInfo = EXTRA_INFO_CLEAR;
}
else
{
MlmeRadioOff(pAdapter);
// Update extra information
pAdapter->ExtraInfo = SW_RADIO_OFF;
}
}
}
}
break;
case RT_OID_802_11_PHY_MODE:
if (wrq->u.data.length != sizeof(RT_802_11_PHY_MODE))
Status = -EINVAL;
else
{
Status = copy_from_user(&PhyMode, wrq->u.data.pointer, wrq->u.data.length);
if (PhyMode <= MaxPhyMode)
{
RTMPSetPhyMode(pAdapter, PhyMode);
#ifdef DOT11_N_SUPPORT
SetCommonHT(pAdapter);
#endif // DOT11_N_SUPPORT //
}
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PHY_MODE (=%d)\n", PhyMode));
}
break;
case RT_OID_802_11_STA_CONFIG:
if (wrq->u.data.length != sizeof(RT_802_11_STA_CONFIG))
Status = -EINVAL;
else
{
Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length);
pAdapter->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst;
pAdapter->CommonCfg.UseBGProtection = StaConfig.UseBGProtection;
pAdapter->CommonCfg.bUseShortSlotTime = 1; // 2003-10-30 always SHORT SLOT capable
if ((pAdapter->CommonCfg.PhyMode != StaConfig.AdhocMode) &&
(StaConfig.AdhocMode <= MaxPhyMode))
{
// allow dynamic change of "USE OFDM rate or not" in ADHOC mode
// if setting changed, need to reset current TX rate as well as BEACON frame format
pAdapter->CommonCfg.PhyMode = StaConfig.AdhocMode;
if (pAdapter->StaCfg.BssType == BSS_ADHOC)
{
RTMPSetPhyMode(pAdapter, PhyMode);
MlmeUpdateTxRates(pAdapter, FALSE, 0);
MakeIbssBeacon(pAdapter); // re-build BEACON frame
AsicEnableIbssSync(pAdapter); // copy to on-chip memory
}
}
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n",
pAdapter->CommonCfg.bEnableTxBurst,
pAdapter->CommonCfg.UseBGProtection,
pAdapter->CommonCfg.bUseShortSlotTime));
}
break;
case OID_802_11_DESIRED_RATES:
if (wrq->u.data.length != sizeof(NDIS_802_11_RATES))
Status = -EINVAL;
else
{
Status = copy_from_user(&aryRates, wrq->u.data.pointer, wrq->u.data.length);
NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DESIRED_RATES (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
// Changing DesiredRate may affect the MAX TX rate we used to TX frames out
MlmeUpdateTxRates(pAdapter, FALSE, 0);
}
break;
case RT_OID_802_11_PREAMBLE:
if (wrq->u.data.length != sizeof(RT_802_11_PREAMBLE))
Status = -EINVAL;
else
{
Status = copy_from_user(&Preamble, wrq->u.data.pointer, wrq->u.data.length);
if (Preamble == Rt802_11PreambleShort)
{
pAdapter->CommonCfg.TxPreamble = Preamble;
MlmeSetTxPreamble(pAdapter, Rt802_11PreambleShort);
}
else if ((Preamble == Rt802_11PreambleLong) || (Preamble == Rt802_11PreambleAuto))
{
// if user wants AUTO, initialize to LONG here, then change according to AP's
// capability upon association.
pAdapter->CommonCfg.TxPreamble = Preamble;
MlmeSetTxPreamble(pAdapter, Rt802_11PreambleLong);
}
else
{
Status = -EINVAL;
break;
}
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PREAMBLE (=%d)\n", Preamble));
}
break;
case OID_802_11_WEP_STATUS:
if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS))
Status = -EINVAL;
else
{
Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length);
// Since TKIP, AES, WEP are all supported. It should not have any invalid setting
if (WepStatus <= Ndis802_11Encryption3KeyAbsent)
{
if (pAdapter->StaCfg.WepStatus != WepStatus)
{
// Config has changed
pAdapter->bConfigChanged = TRUE;
}
pAdapter->StaCfg.WepStatus = WepStatus;
pAdapter->StaCfg.OrigWepStatus = WepStatus;
pAdapter->StaCfg.PairCipher = WepStatus;
pAdapter->StaCfg.GroupCipher = WepStatus;
}
else
{
Status = -EINVAL;
break;
}
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus));
}
break;
case OID_802_11_AUTHENTICATION_MODE:
if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE))
Status = -EINVAL;
else
{
Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length);
if (AuthMode > Ndis802_11AuthModeMax)
{
Status = -EINVAL;
break;
}
else
{
if (pAdapter->StaCfg.AuthMode != AuthMode)
{
// Config has changed
pAdapter->bConfigChanged = TRUE;
}
pAdapter->StaCfg.AuthMode = AuthMode;
}
pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAdapter->StaCfg.AuthMode));
}
break;
case OID_802_11_INFRASTRUCTURE_MODE:
if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE))
Status = -EINVAL;
else
{
Status = copy_from_user(&BssType, wrq->u.data.pointer, wrq->u.data.length);
if (BssType == Ndis802_11IBSS)
Set_NetworkType_Proc(pAdapter, "Adhoc");
else if (BssType == Ndis802_11Infrastructure)
Set_NetworkType_Proc(pAdapter, "Infra");
else if (BssType == Ndis802_11Monitor)
Set_NetworkType_Proc(pAdapter, "Monitor");
else
{
Status = -EINVAL;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_INFRASTRUCTURE_MODE (unknown)\n"));
}
}
break;
case OID_802_11_REMOVE_WEP:
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_WEP\n"));
if (wrq->u.data.length != sizeof(NDIS_802_11_KEY_INDEX))
{
Status = -EINVAL;
}
else
{
KeyIdx = *(NDIS_802_11_KEY_INDEX *) wrq->u.data.pointer;
if (KeyIdx & 0x80000000)
{
// Should never set default bit when remove key
Status = -EINVAL;
}
else
{
KeyIdx = KeyIdx & 0x0fffffff;
if (KeyIdx >= 4){
Status = -EINVAL;
}
else
{
pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
}
}
}
break;
case RT_OID_802_11_RESET_COUNTERS:
NdisZeroMemory(&pAdapter->WlanCounters, sizeof(COUNTER_802_11));
NdisZeroMemory(&pAdapter->Counters8023, sizeof(COUNTER_802_3));
NdisZeroMemory(&pAdapter->RalinkCounters, sizeof(COUNTER_RALINK));
pAdapter->Counters8023.RxNoBuffer = 0;
pAdapter->Counters8023.GoodReceives = 0;
pAdapter->Counters8023.RxNoBuffer = 0;
#ifdef RT2870
pAdapter->BulkOutComplete = 0;
pAdapter->BulkOutCompleteOther= 0;
pAdapter->BulkOutCompleteCancel = 0;
pAdapter->BulkOutReq = 0;
pAdapter->BulkInReq= 0;
pAdapter->BulkInComplete = 0;
pAdapter->BulkInCompleteFail = 0;
#endif // RT2870 //
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RESET_COUNTERS \n"));
break;
case OID_802_11_RTS_THRESHOLD:
if (wrq->u.data.length != sizeof(NDIS_802_11_RTS_THRESHOLD))
Status = -EINVAL;
else
{
Status = copy_from_user(&RtsThresh, wrq->u.data.pointer, wrq->u.data.length);
if (RtsThresh > MAX_RTS_THRESHOLD)
Status = -EINVAL;
else
pAdapter->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
}
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_RTS_THRESHOLD (=%ld)\n",RtsThresh));
break;
case OID_802_11_FRAGMENTATION_THRESHOLD:
if (wrq->u.data.length != sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD))
Status = -EINVAL;
else
{
Status = copy_from_user(&FragThresh, wrq->u.data.pointer, wrq->u.data.length);
pAdapter->CommonCfg.bUseZeroToDisableFragment = FALSE;
if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
{
if (FragThresh == 0)
{
pAdapter->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
pAdapter->CommonCfg.bUseZeroToDisableFragment = TRUE;
}
else
Status = -EINVAL;
}
else
pAdapter->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
}
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_FRAGMENTATION_THRESHOLD (=%ld) \n",FragThresh));
break;
case OID_802_11_POWER_MODE:
if (wrq->u.data.length != sizeof(NDIS_802_11_POWER_MODE))
Status = -EINVAL;
else
{
Status = copy_from_user(&PowerMode, wrq->u.data.pointer, wrq->u.data.length);
if (PowerMode == Ndis802_11PowerModeCAM)
Set_PSMode_Proc(pAdapter, "CAM");
else if (PowerMode == Ndis802_11PowerModeMAX_PSP)
Set_PSMode_Proc(pAdapter, "Max_PSP");
else if (PowerMode == Ndis802_11PowerModeFast_PSP)
Set_PSMode_Proc(pAdapter, "Fast_PSP");
else if (PowerMode == Ndis802_11PowerModeLegacy_PSP)
Set_PSMode_Proc(pAdapter, "Legacy_PSP");
else
Status = -EINVAL;
}
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_POWER_MODE (=%d)\n",PowerMode));
break;
case RT_OID_802_11_TX_POWER_LEVEL_1:
if (wrq->u.data.length < sizeof(ULONG))
Status = -EINVAL;
else
{
Status = copy_from_user(&PowerTemp, wrq->u.data.pointer, wrq->u.data.length);
if (PowerTemp > 100)
PowerTemp = 0xffffffff; // AUTO
pAdapter->CommonCfg.TxPowerDefault = PowerTemp; //keep current setting.
pAdapter->CommonCfg.TxPowerPercentage = pAdapter->CommonCfg.TxPowerDefault;
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
}
break;
case OID_802_11_NETWORK_TYPE_IN_USE:
if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_TYPE))
Status = -EINVAL;
else
{
Status = copy_from_user(&NetType, wrq->u.data.pointer, wrq->u.data.length);
if (NetType == Ndis802_11DS)
RTMPSetPhyMode(pAdapter, PHY_11B);
else if (NetType == Ndis802_11OFDM24)
RTMPSetPhyMode(pAdapter, PHY_11BG_MIXED);
else if (NetType == Ndis802_11OFDM5)
RTMPSetPhyMode(pAdapter, PHY_11A);
else
Status = -EINVAL;
#ifdef DOT11_N_SUPPORT
if (Status == NDIS_STATUS_SUCCESS)
SetCommonHT(pAdapter);
#endif // DOT11_N_SUPPORT //
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_NETWORK_TYPE_IN_USE (=%d)\n",NetType));
}
break;
// For WPA PSK PMK key
case RT_OID_802_11_ADD_WPA:
pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
if(pKey == NULL)
{
Status = -ENOMEM;
break;
}
Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
if (pKey->Length != wrq->u.data.length)
{
Status = -EINVAL;
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!!\n"));
}
else
{
if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
(pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
(pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) )
{
Status = -EOPNOTSUPP;
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!! [AuthMode != WPAPSK/WPA2PSK/WPANONE]\n"));
}
else if ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) ) // Only for WPA PSK mode
{
NdisMoveMemory(pAdapter->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength);
// Use RaConfig as PSK agent.
// Start STA supplicant state machine
if (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
pAdapter->StaCfg.WpaState = SS_START;
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
}
else
{
pAdapter->StaCfg.WpaState = SS_NOTUSE;
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
}
}
kfree(pKey);
break;
case OID_802_11_REMOVE_KEY:
pRemoveKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
if(pRemoveKey == NULL)
{
Status = -ENOMEM;
break;
}
Status = copy_from_user(pRemoveKey, wrq->u.data.pointer, wrq->u.data.length);
if (pRemoveKey->Length != wrq->u.data.length)
{
Status = -EINVAL;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!\n"));
}
else
{
if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
{
RTMPWPARemoveKeyProc(pAdapter, pRemoveKey);
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n"));
}
else
{
KeyIdx = pRemoveKey->KeyIndex;
if (KeyIdx & 0x80000000)
{
// Should never set default bit when remove key
Status = -EINVAL;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(Should never set default bit when remove key)\n"));
}
else
{
KeyIdx = KeyIdx & 0x0fffffff;
if (KeyIdx > 3)
{
Status = -EINVAL;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(KeyId[%d] out of range)\n", KeyIdx));
}
else
{
pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length));
}
}
}
}
kfree(pRemoveKey);
break;
// New for WPA
case OID_802_11_ADD_KEY:
pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
if(pKey == NULL)
{
Status = -ENOMEM;
break;
}
Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
if (pKey->Length != wrq->u.data.length)
{
Status = -EINVAL;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n"));
}
else
{
RTMPAddKey(pAdapter, pKey);
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
}
kfree(pKey);
break;
case OID_802_11_CONFIGURATION:
if (wrq->u.data.length != sizeof(NDIS_802_11_CONFIGURATION))
Status = -EINVAL;
else
{
Status = copy_from_user(&Config, wrq->u.data.pointer, wrq->u.data.length);
pConfig = &Config;
if ((pConfig->BeaconPeriod >= 20) && (pConfig->BeaconPeriod <=400))
pAdapter->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod;
pAdapter->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow;
MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAdapter->CommonCfg.Channel);
//
// Save the channel on MlmeAux for CntlOidRTBssidProc used.
//
pAdapter->MlmeAux.Channel = pAdapter->CommonCfg.Channel;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n",
pConfig->BeaconPeriod, pConfig->ATIMWindow, pAdapter->CommonCfg.Channel));
// Config has changed
pAdapter->bConfigChanged = TRUE;
}
break;
#ifdef DOT11_N_SUPPORT
case RT_OID_802_11_SET_HT_PHYMODE:
if (wrq->u.data.length != sizeof(OID_SET_HT_PHYMODE))
Status = -EINVAL;
else
{
POID_SET_HT_PHYMODE pHTPhyMode = &HT_PhyMode;
Status = copy_from_user(&HT_PhyMode, wrq->u.data.pointer, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Set::pHTPhyMode (PhyMode = %d,TransmitNo = %d, HtMode = %d, ExtOffset = %d , MCS = %d, BW = %d, STBC = %d, SHORTGI = %d) \n",
pHTPhyMode->PhyMode, pHTPhyMode->TransmitNo,pHTPhyMode->HtMode,pHTPhyMode->ExtOffset,
pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
RTMPSetHT(pAdapter, pHTPhyMode);
}
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n",
pAdapter->StaCfg.HTPhyMode.field.MCS, pAdapter->StaCfg.HTPhyMode.field.BW, pAdapter->StaCfg.HTPhyMode.field.ShortGI,
pAdapter->StaCfg.HTPhyMode.field.STBC));
break;
#endif // DOT11_N_SUPPORT //
case RT_OID_802_11_SET_APSD_SETTING:
if (wrq->u.data.length != sizeof(ULONG))
Status = -EINVAL;
else
{
ULONG apsd ;
Status = copy_from_user(&apsd, wrq->u.data.pointer, wrq->u.data.length);
/*-------------------------------------------------------------------
|B31~B7 | B6~B5 | B4 | B3 | B2 | B1 | B0 |
---------------------------------------------------------------------
| Rsvd | Max SP Len | AC_VO | AC_VI | AC_BK | AC_BE | APSD Capable |
---------------------------------------------------------------------*/
pAdapter->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE : FALSE;
pAdapter->CommonCfg.bAPSDAC_BE = ((apsd & 0x00000002) >> 1) ? TRUE : FALSE;
pAdapter->CommonCfg.bAPSDAC_BK = ((apsd & 0x00000004) >> 2) ? TRUE : FALSE;
pAdapter->CommonCfg.bAPSDAC_VI = ((apsd & 0x00000008) >> 3) ? TRUE : FALSE;
pAdapter->CommonCfg.bAPSDAC_VO = ((apsd & 0x00000010) >> 4) ? TRUE : FALSE;
pAdapter->CommonCfg.MaxSPLength = (UCHAR)((apsd & 0x00000060) >> 5);
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_SETTING (apsd=0x%lx, APSDCap=%d, [BE,BK,VI,VO]=[%d/%d/%d/%d], MaxSPLen=%d)\n", apsd, pAdapter->CommonCfg.bAPSDCapable,
pAdapter->CommonCfg.bAPSDAC_BE, pAdapter->CommonCfg.bAPSDAC_BK, pAdapter->CommonCfg.bAPSDAC_VI, pAdapter->CommonCfg.bAPSDAC_VO, pAdapter->CommonCfg.MaxSPLength));
}
break;
case RT_OID_802_11_SET_APSD_PSM:
if (wrq->u.data.length != sizeof(ULONG))
Status = -EINVAL;
else
{
// Driver needs to notify AP when PSM changes
Status = copy_from_user(&pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length);
if (pAdapter->CommonCfg.bAPSDForcePowerSave != pAdapter->StaCfg.Psm)
{
MlmeSetPsmBit(pAdapter, pAdapter->CommonCfg.bAPSDForcePowerSave);
RTMPSendNullFrame(pAdapter, pAdapter->CommonCfg.TxRate, TRUE);
}
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
}
break;
#ifdef QOS_DLS_SUPPORT
case RT_OID_802_11_SET_DLS:
if (wrq->u.data.length != sizeof(ULONG))
Status = -EINVAL;
else
{
BOOLEAN oldvalue = pAdapter->CommonCfg.bDLSCapable;
Status = copy_from_user(&pAdapter->CommonCfg.bDLSCapable, wrq->u.data.pointer, wrq->u.data.length);
if (oldvalue && !pAdapter->CommonCfg.bDLSCapable)
{
int i;
// tear down local dls table entry
for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
{
if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
{
pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
}
}
// tear down peer dls table entry
for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
{
if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
{
pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
}
}
}
DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS (=%d)\n", pAdapter->CommonCfg.bDLSCapable));
}
break;
case RT_OID_802_11_SET_DLS_PARAM:
if (wrq->u.data.length != sizeof(RT_802_11_DLS_UI))
Status = -EINVAL;
else
{
RT_802_11_DLS Dls;
NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
RTMPMoveMemory(&Dls, wrq->u.data.pointer, sizeof(RT_802_11_DLS_UI));
MlmeEnqueue(pAdapter,
MLME_CNTL_STATE_MACHINE,
RT_OID_802_11_SET_DLS_PARAM,
sizeof(RT_802_11_DLS),
&Dls);
DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS_PARAM \n"));
}
break;
#endif // QOS_DLS_SUPPORT //
case RT_OID_802_11_SET_WMM:
if (wrq->u.data.length != sizeof(BOOLEAN))
Status = -EINVAL;
else
{
Status = copy_from_user(&pAdapter->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d) \n", pAdapter->CommonCfg.bWmmCapable));
}
break;
case OID_802_11_DISASSOCIATE:
#ifdef RALINK_ATE
if (ATE_ON(pAdapter))
{
DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
break;
}
#endif // RALINK_ATE //
//
// Set NdisRadioStateOff to TRUE, instead of called MlmeRadioOff.
// Later on, NDIS_802_11_BSSID_LIST_EX->NumberOfItems should be 0
// when query OID_802_11_BSSID_LIST.
//
// TRUE: NumberOfItems will set to 0.
// FALSE: NumberOfItems no change.
//
pAdapter->CommonCfg.NdisRadioStateOff = TRUE;
// Set to immediately send the media disconnect event
pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE \n"));
if (INFRA_ON(pAdapter))
{
if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
{
RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
}
MlmeEnqueue(pAdapter,
MLME_CNTL_STATE_MACHINE,
OID_802_11_DISASSOCIATE,
0,
NULL);
StateMachineTouched = TRUE;
}
break;
#ifdef DOT11_N_SUPPORT
case RT_OID_802_11_SET_IMME_BA_CAP:
if (wrq->u.data.length != sizeof(OID_BACAP_STRUC))
Status = -EINVAL;
else
{
OID_BACAP_STRUC Orde ;
Status = copy_from_user(&Orde, wrq->u.data.pointer, wrq->u.data.length);
if (Orde.Policy > BA_NOTUSE)
{
Status = NDIS_STATUS_INVALID_DATA;
}
else if (Orde.Policy == BA_NOTUSE)
{
pAdapter->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
pAdapter->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode;
pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
// UPdata to HT IE
pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
}
else
{
pAdapter->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA;
pAdapter->CommonCfg.BACapability.field.Policy = IMMED_BA; // we only support immediate BA.
pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
pAdapter->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode;
pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
// UPdata to HT IE
pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
if (pAdapter->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF)
pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF;
}
pAdapter->CommonCfg.REGBACapability.word = pAdapter->CommonCfg.BACapability.word;
DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAdapter->CommonCfg.BACapability.field.Policy,
pAdapter->CommonCfg.BACapability.field.RxBAWinLimit,pAdapter->CommonCfg.BACapability.field.TxBAWinLimit, pAdapter->CommonCfg.BACapability.field.AutoBA));
DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAdapter->CommonCfg.DesiredHtPhy.MimoPs, pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable,
pAdapter->CommonCfg.DesiredHtPhy.AmsduSize, pAdapter->CommonCfg.DesiredHtPhy.MpduDensity));
}
break;
case RT_OID_802_11_ADD_IMME_BA:
DBGPRINT(RT_DEBUG_TRACE, (" Set :: RT_OID_802_11_ADD_IMME_BA \n"));
if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
Status = -EINVAL;
else
{
UCHAR index;
OID_ADD_BA_ENTRY BA;
MAC_TABLE_ENTRY *pEntry;
Status = copy_from_user(&BA, wrq->u.data.pointer, wrq->u.data.length);
if (BA.TID > 15)
{
Status = NDIS_STATUS_INVALID_DATA;
break;
}
else
{
//BATableInsertEntry
//As ad-hoc mode, BA pair is not limited to only BSSID. so add via OID.
index = BA.TID;
// in ad hoc mode, when adding BA pair, we should insert this entry into MACEntry too
pEntry = MacTableLookup(pAdapter, BA.MACAddr);
if (!pEntry)
{
DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_ADD_IMME_BA. break on no connection.----:%x:%x\n", BA.MACAddr[4], BA.MACAddr[5]));
break;
}
if (BA.IsRecipient == FALSE)
{
if (pEntry->bIAmBadAtheros == TRUE)
pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = 0x10;
BAOriSessionSetUp(pAdapter, pEntry, index, 0, 100, TRUE);
}
else
{
//BATableInsertEntry(pAdapter, pEntry->Aid, BA.MACAddr, 0, 0xffff, BA.TID, BA.nMSDU, BA.IsRecipient);
}
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_IMME_BA. Rec = %d. Mac = %x:%x:%x:%x:%x:%x . \n",
BA.IsRecipient, BA.MACAddr[0], BA.MACAddr[1], BA.MACAddr[2], BA.MACAddr[2]
, BA.MACAddr[4], BA.MACAddr[5]));
}
}
break;
case RT_OID_802_11_TEAR_IMME_BA:
DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA \n"));
if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
Status = -EINVAL;
else
{
POID_ADD_BA_ENTRY pBA;
MAC_TABLE_ENTRY *pEntry;
pBA = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
if (pBA == NULL)
{
DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA kmalloc() can't allocate enough memory\n"));
Status = NDIS_STATUS_FAILURE;
}
else
{
Status = copy_from_user(pBA, wrq->u.data.pointer, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA(TID=%d, bAllTid=%d)\n", pBA->TID, pBA->bAllTid));
if (!pBA->bAllTid && (pBA->TID > NUM_OF_TID))
{
Status = NDIS_STATUS_INVALID_DATA;
break;
}
if (pBA->IsRecipient == FALSE)
{
pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n"));
if (pEntry)
{
DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n"));
BAOriSessionTearDown(pAdapter, pEntry->Aid, pBA->TID, FALSE, TRUE);
}
else
DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
}
else
{
pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
if (pEntry)
{
BARecSessionTearDown( pAdapter, (UCHAR)pEntry->Aid, pBA->TID, TRUE);
}
else
DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
}
kfree(pBA);
}
}
break;
#endif // DOT11_N_SUPPORT //
// For WPA_SUPPLICANT to set static wep key
case OID_802_11_ADD_WEP:
pWepKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
if(pWepKey == NULL)
{
Status = -ENOMEM;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed!!\n"));
break;
}
Status = copy_from_user(pWepKey, wrq->u.data.pointer, wrq->u.data.length);
if (Status)
{
Status = -EINVAL;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (length mismatch)!!\n"));
}
else
{
KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
// KeyIdx must be 0 ~ 3
if (KeyIdx > 4)
{
Status = -EINVAL;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (KeyIdx must be smaller than 4)!!\n"));
}
else
{
UCHAR CipherAlg = 0;
PUCHAR Key;
// set key material and key length
NdisZeroMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, 16);
pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
NdisMoveMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
switch(pWepKey->KeyLength)
{
case 5:
CipherAlg = CIPHER_WEP64;
break;
case 13:
CipherAlg = CIPHER_WEP128;
break;
default:
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, only support CIPHER_WEP64(len:5) & CIPHER_WEP128(len:13)!!\n"));
Status = -EINVAL;
break;
}
pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
// Default key for tx (shared key)
if (pWepKey->KeyIndex & 0x80000000)
{
#ifdef WPA_SUPPLICANT_SUPPORT
// set key material and key length
NdisZeroMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, 16);
pAdapter->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
NdisMoveMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
pAdapter->StaCfg.DesireSharedKeyId = KeyIdx;
pAdapter->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
#endif // WPA_SUPPLICANT_SUPPORT //
pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
}
#ifdef WPA_SUPPLICANT_SUPPORT
if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
#endif // WPA_SUPPLICANT_SUPPORT
{
Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
// Set key material and cipherAlg to Asic
AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
if (pWepKey->KeyIndex & 0x80000000)
{
PMAC_TABLE_ENTRY pEntry = &pAdapter->MacTab.Content[BSSID_WCID];
// Assign group key info
RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
// Assign pairwise key info
RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, pEntry);
}
}
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP (id=0x%x, Len=%d-byte), %s\n", pWepKey->KeyIndex, pWepKey->KeyLength, (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED) ? "Port Secured":"Port NOT Secured"));
}
}
kfree(pWepKey);
break;
#ifdef WPA_SUPPLICANT_SUPPORT
case OID_SET_COUNTERMEASURES:
if (wrq->u.data.length != sizeof(int))
Status = -EINVAL;
else
{
int enabled = 0;
Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
if (enabled == 1)
pAdapter->StaCfg.bBlockAssoc = TRUE;
else
// WPA MIC error should block association attempt for 60 seconds
pAdapter->StaCfg.bBlockAssoc = FALSE;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAdapter->StaCfg.bBlockAssoc ? "TRUE":"FALSE"));
}
break;
case RT_OID_WPA_SUPPLICANT_SUPPORT:
if (wrq->u.data.length != sizeof(UCHAR))
Status = -EINVAL;
else
{
Status = copy_from_user(&wpa_supplicant_enable, wrq->u.data.pointer, wrq->u.data.length);
pAdapter->StaCfg.WpaSupplicantUP = wpa_supplicant_enable;
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
}
break;
case OID_802_11_DEAUTHENTICATION:
if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT))
Status = -EINVAL;
else
{
MLME_DEAUTH_REQ_STRUCT *pInfo;
MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg;
Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
MlmeDeauthReqAction(pAdapter, MsgElem);
kfree(MsgElem);
if (INFRA_ON(pAdapter))
{
LinkDown(pAdapter, FALSE);
pAdapter->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
}
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason));
}
break;
case OID_802_11_DROP_UNENCRYPTED:
if (wrq->u.data.length != sizeof(int))
Status = -EINVAL;
else
{
int enabled = 0;
Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
if (enabled == 1)
pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
else
pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
NdisAcquireSpinLock(&pAdapter->MacTabLock);
pAdapter->MacTab.Content[BSSID_WCID].PortSecured = pAdapter->StaCfg.PortSecured;
NdisReleaseSpinLock(&pAdapter->MacTabLock);
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled));
}
break;
case OID_802_11_SET_IEEE8021X:
if (wrq->u.data.length != sizeof(BOOLEAN))
Status = -EINVAL;
else
{
Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length);
pAdapter->StaCfg.IEEE8021X = IEEE8021xState;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X (=%d)\n", IEEE8021xState));
}
break;
case OID_802_11_SET_IEEE8021X_REQUIRE_KEY:
if (wrq->u.data.length != sizeof(BOOLEAN))
Status = -EINVAL;
else
{
Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length);
pAdapter->StaCfg.IEEE8021x_required_keys = IEEE8021x_required_keys;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n", IEEE8021x_required_keys));
}
break;
case OID_802_11_PMKID:
pPmkId = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
if(pPmkId == NULL) {
Status = -ENOMEM;
break;
}
Status = copy_from_user(pPmkId, wrq->u.data.pointer, wrq->u.data.length);
// check the PMKID information
if (pPmkId->BSSIDInfoCount == 0)
NdisZeroMemory(pAdapter->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
else
{
PBSSID_INFO pBssIdInfo;
UINT BssIdx;
UINT CachedIdx;
for (BssIdx = 0; BssIdx < pPmkId->BSSIDInfoCount; BssIdx++)
{
// point to the indexed BSSID_INFO structure
pBssIdInfo = (PBSSID_INFO) ((PUCHAR) pPmkId + 2 * sizeof(UINT) + BssIdx * sizeof(BSSID_INFO));
// Find the entry in the saved data base.
for (CachedIdx = 0; CachedIdx < pAdapter->StaCfg.SavedPMKNum; CachedIdx++)
{
// compare the BSSID
if (NdisEqualMemory(pBssIdInfo->BSSID, pAdapter->StaCfg.SavedPMK[CachedIdx].BSSID, sizeof(NDIS_802_11_MAC_ADDRESS)))
break;
}
// Found, replace it
if (CachedIdx < PMKID_NO)
{
DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
pAdapter->StaCfg.SavedPMKNum++;
}
// Not found, replace the last one
else
{
// Randomly replace one
CachedIdx = (pBssIdInfo->BSSID[5] % PMKID_NO);
DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
}
}
}
if(pPmkId)
kfree(pPmkId);
break;
#endif // WPA_SUPPLICANT_SUPPORT //
#ifdef SNMP_SUPPORT
case OID_802_11_SHORTRETRYLIMIT:
if (wrq->u.data.length != sizeof(ULONG))
Status = -EINVAL;
else
{
Status = copy_from_user(&ShortRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SHORTRETRYLIMIT (tx_rty_cfg.field.ShortRetryLimit=%d, ShortRetryLimit=%ld)\n", tx_rty_cfg.field.ShortRtyLimit, ShortRetryLimit));
}
break;
case OID_802_11_LONGRETRYLIMIT:
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT \n"));
if (wrq->u.data.length != sizeof(ULONG))
Status = -EINVAL;
else
{
Status = copy_from_user(&LongRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT (tx_rty_cfg.field.LongRetryLimit= %d,LongRetryLimit=%ld)\n", tx_rty_cfg.field.LongRtyLimit, LongRetryLimit));
}
break;
case OID_802_11_WEPDEFAULTKEYVALUE:
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE\n"));
pKey = kmalloc(wrq->u.data.length, GFP_KERNEL);
Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
//pKey = &WepKey;
if ( pKey->Length != wrq->u.data.length)
{
Status = -EINVAL;
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n"));
}
KeyIdx = pKey->KeyIndex & 0x0fffffff;
DBGPRINT(RT_DEBUG_TRACE,("pKey->KeyIndex =%d, pKey->KeyLength=%d\n", pKey->KeyIndex, pKey->KeyLength));
// it is a shared key
if (KeyIdx > 4)
Status = -EINVAL;
else
{
pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength;
NdisMoveMemory(&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength);
if (pKey->KeyIndex & 0x80000000)
{
// Default key for tx (shared key)
pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
}
//RestartAPIsRequired = TRUE;
}
break;
case OID_802_11_WEPDEFAULTKEYID:
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYID \n"));
if (wrq->u.data.length != sizeof(UCHAR))
Status = -EINVAL;
else
Status = copy_from_user(&pAdapter->StaCfg.DefaultKeyId, wrq->u.data.pointer, wrq->u.data.length);
break;
case OID_802_11_CURRENTCHANNEL:
DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CURRENTCHANNEL \n"));
if (wrq->u.data.length != sizeof(UCHAR))
Status = -EINVAL;
else
{
Status = copy_from_user(&ctmp, wrq->u.data.pointer, wrq->u.data.length);
sprintf(&ctmp,"%d", ctmp);
Set_Channel_Proc(pAdapter, &ctmp);
}
break;
#endif
default:
DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
Status = -EOPNOTSUPP;
break;
}
return Status;
}
INT RTMPQueryInformation(
IN PRTMP_ADAPTER pAdapter,
IN OUT struct ifreq *rq,
IN INT cmd)
{
struct iwreq *wrq = (struct iwreq *) rq;
NDIS_802_11_BSSID_LIST_EX *pBssidList = NULL;
PNDIS_WLAN_BSSID_EX pBss;
NDIS_802_11_SSID Ssid;
NDIS_802_11_CONFIGURATION *pConfiguration = NULL;
RT_802_11_LINK_STATUS *pLinkStatus = NULL;
RT_802_11_STA_CONFIG *pStaConfig = NULL;
NDIS_802_11_STATISTICS *pStatistics = NULL;
NDIS_802_11_RTS_THRESHOLD RtsThresh;
NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
NDIS_802_11_POWER_MODE PowerMode;
NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
RT_802_11_PREAMBLE PreamType;
NDIS_802_11_AUTHENTICATION_MODE AuthMode;
NDIS_802_11_WEP_STATUS WepStatus;
NDIS_MEDIA_STATE MediaState;
ULONG BssBufSize, ulInfo=0, NetworkTypeList[4], apsd = 0;
USHORT BssLen = 0;
PUCHAR pBuf = NULL, pPtr;
INT Status = NDIS_STATUS_SUCCESS;
UINT we_version_compiled;
UCHAR i, Padding = 0;
BOOLEAN RadioState;
UCHAR driverVersion[8];
OID_SET_HT_PHYMODE *pHTPhyMode = NULL;
#ifdef SNMP_SUPPORT
//for snmp, kathy
DefaultKeyIdxValue *pKeyIdxValue;
INT valueLen;
TX_RTY_CFG_STRUC tx_rty_cfg;
ULONG ShortRetryLimit, LongRetryLimit;
UCHAR tmp[64];
#endif //SNMP
switch(cmd)
{
case RT_OID_DEVICE_NAME:
wrq->u.data.length = sizeof(STA_NIC_DEVICE_NAME);
Status = copy_to_user(wrq->u.data.pointer, STA_NIC_DEVICE_NAME, wrq->u.data.length);
break;
case RT_OID_VERSION_INFO:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_VERSION_INFO \n"));
wrq->u.data.length = 8*sizeof(UCHAR);
sprintf(&driverVersion[0], "%s", STA_DRIVER_VERSION);
driverVersion[7] = '\0';
if (copy_to_user(wrq->u.data.pointer, &driverVersion, wrq->u.data.length))
{
Status = -EFAULT;
}
break;
#ifdef RALINK_ATE
case RT_QUERY_ATE_TXDONE_COUNT:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_QUERY_ATE_TXDONE_COUNT \n"));
wrq->u.data.length = sizeof(UINT32);
if (copy_to_user(wrq->u.data.pointer, &pAdapter->ate.TxDoneCount, wrq->u.data.length))
{
Status = -EFAULT;
}
break;
#endif // RALINK_ATE //
case OID_802_11_BSSID_LIST:
if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
{
/*
* Still scanning, indicate the caller should try again.
*/
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (Still scanning)\n"));
return -EAGAIN;
}
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAdapter->ScanTab.BssNr));
pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
// Claculate total buffer size required
BssBufSize = sizeof(ULONG);
for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
{
// Align pointer to 4 bytes boundary.
//Padding = 4 - (pAdapter->ScanTab.BssEntry[i].VarIELen & 0x0003);
//if (Padding == 4)
// Padding = 0;
BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
}
// For safety issue, we add 256 bytes just in case
BssBufSize += 256;
// Allocate the same size as passed from higher layer
pBuf = kmalloc(BssBufSize, MEM_ALLOC_FLAG);
if(pBuf == NULL)
{
Status = -ENOMEM;
break;
}
// Init 802_11_BSSID_LIST_EX structure
NdisZeroMemory(pBuf, BssBufSize);
pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf;
pBssidList->NumberOfItems = pAdapter->ScanTab.BssNr;
// Calculate total buffer length
BssLen = 4; // Consist of NumberOfItems
// Point to start of NDIS_WLAN_BSSID_EX
// pPtr = pBuf + sizeof(ULONG);
pPtr = (PUCHAR) &pBssidList->Bssid[0];
for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
{
pBss = (PNDIS_WLAN_BSSID_EX) pPtr;
NdisMoveMemory(&pBss->MacAddress, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
if ((pAdapter->ScanTab.BssEntry[i].Hidden == 1) && (pAdapter->StaCfg.bShowHiddenSSID == FALSE))
{
//
// We must return this SSID during 4way handshaking, otherwise Aegis will failed to parse WPA infomation
// and then failed to send EAPOl farame.
//
if ((pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAdapter->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
{
pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
}
else
pBss->Ssid.SsidLength = 0;
}
else
{
pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
}
pBss->Privacy = pAdapter->ScanTab.BssEntry[i].Privacy;
pBss->Rssi = pAdapter->ScanTab.BssEntry[i].Rssi - pAdapter->BbpRssiToDbmDelta;
pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
pBss->Configuration.BeaconPeriod = pAdapter->ScanTab.BssEntry[i].BeaconPeriod;
pBss->Configuration.ATIMWindow = pAdapter->ScanTab.BssEntry[i].AtimWin;
MAP_CHANNEL_ID_TO_KHZ(pAdapter->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig);
if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_INFRA)
pBss->InfrastructureMode = Ndis802_11Infrastructure;
else
pBss->InfrastructureMode = Ndis802_11IBSS;
NdisMoveMemory(pBss->SupportedRates, pAdapter->ScanTab.BssEntry[i].SupRate, pAdapter->ScanTab.BssEntry[i].SupRateLen);
NdisMoveMemory(pBss->SupportedRates + pAdapter->ScanTab.BssEntry[i].SupRateLen,
pAdapter->ScanTab.BssEntry[i].ExtRate,
pAdapter->ScanTab.BssEntry[i].ExtRateLen);
if (pAdapter->ScanTab.BssEntry[i].VarIELen == 0)
{
pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs);
NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
}
else
{
pBss->IELength = (ULONG)(sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen);
pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAdapter->ScanTab.BssEntry[i].VarIEs, pAdapter->ScanTab.BssEntry[i].VarIELen);
pPtr += pAdapter->ScanTab.BssEntry[i].VarIELen;
}
pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
#if WIRELESS_EXT < 17
if ((BssLen + pBss->Length) < wrq->u.data.length)
BssLen += pBss->Length;
else
{
pBssidList->NumberOfItems = i;
break;
}
#else
BssLen += pBss->Length;
#endif
}
#if WIRELESS_EXT < 17
wrq->u.data.length = BssLen;
#else
if (BssLen > wrq->u.data.length)
{
kfree(pBssidList);
return -E2BIG;
}
else
wrq->u.data.length = BssLen;
#endif
Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen);
kfree(pBssidList);
break;
case OID_802_3_CURRENT_ADDRESS:
wrq->u.data.length = MAC_ADDR_LEN;
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
break;
case OID_GEN_MEDIA_CONNECT_STATUS:
if (pAdapter->IndicateMediaState == NdisMediaStateConnected)
MediaState = NdisMediaStateConnected;
else
MediaState = NdisMediaStateDisconnected;
wrq->u.data.length = sizeof(NDIS_MEDIA_STATE);
Status = copy_to_user(wrq->u.data.pointer, &MediaState, wrq->u.data.length);
break;
case OID_802_11_BSSID:
#ifdef RALINK_ATE
if (ATE_ON(pAdapter))
{
DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
Status = NDIS_STATUS_RESOURCES;
break;
}
#endif // RALINK_ATE //
if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
{
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS));
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n"));
Status = -ENOTCONN;
}
break;
case OID_802_11_SSID:
NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID);
Ssid.SsidLength = pAdapter->CommonCfg.SsidLen;
memcpy(Ssid.Ssid, pAdapter->CommonCfg.Ssid, Ssid.SsidLength);
wrq->u.data.length = sizeof(NDIS_802_11_SSID);
Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid));
break;
case RT_OID_802_11_QUERY_LINK_STATUS:
pLinkStatus = (RT_802_11_LINK_STATUS *) kmalloc(sizeof(RT_802_11_LINK_STATUS), MEM_ALLOC_FLAG);
if (pLinkStatus)
{
pLinkStatus->CurrTxRate = RateIdTo500Kbps[pAdapter->CommonCfg.TxRate]; // unit : 500 kbps
pLinkStatus->ChannelQuality = pAdapter->Mlme.ChannelQuality;
pLinkStatus->RxByteCount = pAdapter->RalinkCounters.ReceivedByteCount;
pLinkStatus->TxByteCount = pAdapter->RalinkCounters.TransmittedByteCount;
pLinkStatus->CentralChannel = pAdapter->CommonCfg.CentralChannel;
wrq->u.data.length = sizeof(RT_802_11_LINK_STATUS);
Status = copy_to_user(wrq->u.data.pointer, pLinkStatus, wrq->u.data.length);
kfree(pLinkStatus);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS\n"));
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS(kmalloc failed)\n"));
Status = -EFAULT;
}
break;
case OID_802_11_CONFIGURATION:
pConfiguration = (NDIS_802_11_CONFIGURATION *) kmalloc(sizeof(NDIS_802_11_CONFIGURATION), MEM_ALLOC_FLAG);
if (pConfiguration)
{
pConfiguration->Length = sizeof(NDIS_802_11_CONFIGURATION);
pConfiguration->BeaconPeriod = pAdapter->CommonCfg.BeaconPeriod;
pConfiguration->ATIMWindow = pAdapter->StaActive.AtimWin;
MAP_CHANNEL_ID_TO_KHZ(pAdapter->CommonCfg.Channel, pConfiguration->DSConfig);
wrq->u.data.length = sizeof(NDIS_802_11_CONFIGURATION);
Status = copy_to_user(wrq->u.data.pointer, pConfiguration, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(BeaconPeriod=%ld,AtimW=%ld,Channel=%d) \n",
pConfiguration->BeaconPeriod, pConfiguration->ATIMWindow, pAdapter->CommonCfg.Channel));
kfree(pConfiguration);
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(kmalloc failed)\n"));
Status = -EFAULT;
}
break;
case RT_OID_802_11_SNR_0:
if ((pAdapter->StaCfg.LastSNR0 > 0))
{
ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR0) * 3) / 16 ;
wrq->u.data.length = sizeof(ulInfo);
Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo));
}
else
Status = -EFAULT;
break;
case RT_OID_802_11_SNR_1:
if ((pAdapter->Antenna.field.RxPath > 1) &&
(pAdapter->StaCfg.LastSNR1 > 0))
{
ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR1) * 3) / 16 ;
wrq->u.data.length = sizeof(ulInfo);
Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(0x=%lx)\n",ulInfo));
}
else
Status = -EFAULT;
DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(pAdapter->StaCfg.LastSNR1=%d)\n",pAdapter->StaCfg.LastSNR1));
break;
case OID_802_11_RSSI_TRIGGER:
ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0 - pAdapter->BbpRssiToDbmDelta;
wrq->u.data.length = sizeof(ulInfo);
Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RSSI_TRIGGER(=%ld)\n", ulInfo));
break;
case OID_802_11_RSSI:
case RT_OID_802_11_RSSI:
ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0;
wrq->u.data.length = sizeof(ulInfo);
Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
break;
case RT_OID_802_11_RSSI_1:
ulInfo = pAdapter->StaCfg.RssiSample.LastRssi1;
wrq->u.data.length = sizeof(ulInfo);
Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
break;
case RT_OID_802_11_RSSI_2:
ulInfo = pAdapter->StaCfg.RssiSample.LastRssi2;
wrq->u.data.length = sizeof(ulInfo);
Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
break;
case OID_802_11_STATISTICS:
pStatistics = (NDIS_802_11_STATISTICS *) kmalloc(sizeof(NDIS_802_11_STATISTICS), MEM_ALLOC_FLAG);
if (pStatistics)
{
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS \n"));
// add the most up-to-date h/w raw counters into software counters
NICUpdateRawCounters(pAdapter);
// Sanity check for calculation of sucessful count
if (pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart < pAdapter->WlanCounters.RetryCount.QuadPart)
pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
pStatistics->TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart;
pStatistics->MulticastTransmittedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastTransmittedFrameCount.QuadPart;
pStatistics->FailedCount.QuadPart = pAdapter->WlanCounters.FailedCount.QuadPart;
pStatistics->RetryCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
pStatistics->MultipleRetryCount.QuadPart = pAdapter->WlanCounters.MultipleRetryCount.QuadPart;
pStatistics->RTSSuccessCount.QuadPart = pAdapter->WlanCounters.RTSSuccessCount.QuadPart;
pStatistics->RTSFailureCount.QuadPart = pAdapter->WlanCounters.RTSFailureCount.QuadPart;
pStatistics->ACKFailureCount.QuadPart = pAdapter->WlanCounters.ACKFailureCount.QuadPart;
pStatistics->FrameDuplicateCount.QuadPart = pAdapter->WlanCounters.FrameDuplicateCount.QuadPart;
pStatistics->ReceivedFragmentCount.QuadPart = pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart;
pStatistics->MulticastReceivedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastReceivedFrameCount.QuadPart;
#ifdef DBG
pStatistics->FCSErrorCount = pAdapter->RalinkCounters.RealFcsErrCount;
#else
pStatistics->FCSErrorCount.QuadPart = pAdapter->WlanCounters.FCSErrorCount.QuadPart;
pStatistics->FrameDuplicateCount.u.LowPart = pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart / 100;
#endif
wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS);
Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length);
kfree(pStatistics);
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS(kmalloc failed)\n"));
Status = -EFAULT;
}
break;
case OID_GEN_RCV_OK:
ulInfo = pAdapter->Counters8023.GoodReceives;
wrq->u.data.length = sizeof(ulInfo);
Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
break;
case OID_GEN_RCV_NO_BUFFER:
ulInfo = pAdapter->Counters8023.RxNoBuffer;
wrq->u.data.length = sizeof(ulInfo);
Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
break;
case RT_OID_802_11_PHY_MODE:
ulInfo = (ULONG)pAdapter->CommonCfg.PhyMode;
wrq->u.data.length = sizeof(ulInfo);
Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%ld)\n", ulInfo));
break;
case RT_OID_802_11_STA_CONFIG:
pStaConfig = (RT_802_11_STA_CONFIG *) kmalloc(sizeof(RT_802_11_STA_CONFIG), MEM_ALLOC_FLAG);
if (pStaConfig)
{
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG\n"));
pStaConfig->EnableTxBurst = pAdapter->CommonCfg.bEnableTxBurst;
pStaConfig->EnableTurboRate = 0;
pStaConfig->UseBGProtection = pAdapter->CommonCfg.UseBGProtection;
pStaConfig->UseShortSlotTime = pAdapter->CommonCfg.bUseShortSlotTime;
//pStaConfig->AdhocMode = pAdapter->StaCfg.AdhocMode;
pStaConfig->HwRadioStatus = (pAdapter->StaCfg.bHwRadio == TRUE) ? 1 : 0;
pStaConfig->Rsv1 = 0;
pStaConfig->SystemErrorBitmap = pAdapter->SystemErrorBitmap;
wrq->u.data.length = sizeof(RT_802_11_STA_CONFIG);
Status = copy_to_user(wrq->u.data.pointer, pStaConfig, wrq->u.data.length);
kfree(pStaConfig);
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
Status = -EFAULT;
}
break;
case OID_802_11_RTS_THRESHOLD:
RtsThresh = pAdapter->CommonCfg.RtsThreshold;
wrq->u.data.length = sizeof(RtsThresh);
Status = copy_to_user(wrq->u.data.pointer, &RtsThresh, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RTS_THRESHOLD(=%ld)\n", RtsThresh));
break;
case OID_802_11_FRAGMENTATION_THRESHOLD:
FragThresh = pAdapter->CommonCfg.FragmentThreshold;
if (pAdapter->CommonCfg.bUseZeroToDisableFragment == TRUE)
FragThresh = 0;
wrq->u.data.length = sizeof(FragThresh);
Status = copy_to_user(wrq->u.data.pointer, &FragThresh, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_FRAGMENTATION_THRESHOLD(=%ld)\n", FragThresh));
break;
case OID_802_11_POWER_MODE:
PowerMode = pAdapter->StaCfg.WindowsPowerMode;
wrq->u.data.length = sizeof(PowerMode);
Status = copy_to_user(wrq->u.data.pointer, &PowerMode, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_POWER_MODE(=%d)\n", PowerMode));
break;
case RT_OID_802_11_RADIO:
RadioState = (BOOLEAN) pAdapter->StaCfg.bSwRadio;
wrq->u.data.length = sizeof(RadioState);
Status = copy_to_user(wrq->u.data.pointer, &RadioState, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_RADIO (=%d)\n", RadioState));
break;
case OID_802_11_INFRASTRUCTURE_MODE:
if (pAdapter->StaCfg.BssType == BSS_ADHOC)
BssType = Ndis802_11IBSS;
else if (pAdapter->StaCfg.BssType == BSS_INFRA)
BssType = Ndis802_11Infrastructure;
else if (pAdapter->StaCfg.BssType == BSS_MONITOR)
BssType = Ndis802_11Monitor;
else
BssType = Ndis802_11AutoUnknown;
wrq->u.data.length = sizeof(BssType);
Status = copy_to_user(wrq->u.data.pointer, &BssType, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_INFRASTRUCTURE_MODE(=%d)\n", BssType));
break;
case RT_OID_802_11_PREAMBLE:
PreamType = pAdapter->CommonCfg.TxPreamble;
wrq->u.data.length = sizeof(PreamType);
Status = copy_to_user(wrq->u.data.pointer, &PreamType, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%d)\n", PreamType));
break;
case OID_802_11_AUTHENTICATION_MODE:
AuthMode = pAdapter->StaCfg.AuthMode;
wrq->u.data.length = sizeof(AuthMode);
Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE(=%d)\n", AuthMode));
break;
case OID_802_11_WEP_STATUS:
WepStatus = pAdapter->StaCfg.WepStatus;
wrq->u.data.length = sizeof(WepStatus);
Status = copy_to_user(wrq->u.data.pointer, &WepStatus, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEP_STATUS(=%d)\n", WepStatus));
break;
case OID_802_11_TX_POWER_LEVEL:
wrq->u.data.length = sizeof(ULONG);
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPower, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAdapter->CommonCfg.TxPower));
break;
case RT_OID_802_11_TX_POWER_LEVEL_1:
wrq->u.data.length = sizeof(ULONG);
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPowerPercentage, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
break;
case OID_802_11_NETWORK_TYPES_SUPPORTED:
if ((pAdapter->RfIcType == RFIC_2850) || (pAdapter->RfIcType == RFIC_2750))
{
NetworkTypeList[0] = 3; // NumberOfItems = 3
NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
NetworkTypeList[3] = Ndis802_11OFDM5; // NetworkType[3] = 11a
wrq->u.data.length = 16;
Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
}
else
{
NetworkTypeList[0] = 2; // NumberOfItems = 2
NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
wrq->u.data.length = 12;
Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
}
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED\n"));
break;
case OID_802_11_NETWORK_TYPE_IN_USE:
wrq->u.data.length = sizeof(ULONG);
if (pAdapter->CommonCfg.PhyMode == PHY_11A)
ulInfo = Ndis802_11OFDM5;
else if ((pAdapter->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAdapter->CommonCfg.PhyMode == PHY_11G))
ulInfo = Ndis802_11OFDM24;
else
ulInfo = Ndis802_11DS;
Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
break;
case RT_OID_802_11_QUERY_LAST_RX_RATE:
ulInfo = (ULONG)pAdapter->LastRxRate;
wrq->u.data.length = sizeof(ulInfo);
Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", ulInfo));
break;
case RT_OID_802_11_QUERY_LAST_TX_RATE:
//ulInfo = (ULONG)pAdapter->LastTxRate;
ulInfo = (ULONG)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word;
wrq->u.data.length = sizeof(ulInfo);
Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%lx)\n", ulInfo));
break;
case RT_OID_802_11_QUERY_EEPROM_VERSION:
wrq->u.data.length = sizeof(ULONG);
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->EepromVersion, wrq->u.data.length);
break;
case RT_OID_802_11_QUERY_FIRMWARE_VERSION:
wrq->u.data.length = sizeof(ULONG);
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->FirmwareVersion, wrq->u.data.length);
break;
case RT_OID_802_11_QUERY_NOISE_LEVEL:
wrq->u.data.length = sizeof(UCHAR);
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->BbpWriteLatch[66], wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAdapter->BbpWriteLatch[66]));
break;
case RT_OID_802_11_EXTRA_INFO:
wrq->u.data.length = sizeof(ULONG);
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->ExtraInfo, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAdapter->ExtraInfo));
break;
case RT_OID_WE_VERSION_COMPILED:
wrq->u.data.length = sizeof(UINT);
we_version_compiled = WIRELESS_EXT;
Status = copy_to_user(wrq->u.data.pointer, &we_version_compiled, wrq->u.data.length);
break;
case RT_OID_802_11_QUERY_APSD_SETTING:
apsd = (pAdapter->CommonCfg.bAPSDCapable | (pAdapter->CommonCfg.bAPSDAC_BE << 1) | (pAdapter->CommonCfg.bAPSDAC_BK << 2)
| (pAdapter->CommonCfg.bAPSDAC_VI << 3) | (pAdapter->CommonCfg.bAPSDAC_VO << 4) | (pAdapter->CommonCfg.MaxSPLength << 5));
wrq->u.data.length = sizeof(ULONG);
Status = copy_to_user(wrq->u.data.pointer, &apsd, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_SETTING (=0x%lx,APSDCap=%d,AC_BE=%d,AC_BK=%d,AC_VI=%d,AC_VO=%d,MAXSPLen=%d)\n",
apsd,pAdapter->CommonCfg.bAPSDCapable,pAdapter->CommonCfg.bAPSDAC_BE,pAdapter->CommonCfg.bAPSDAC_BK,pAdapter->CommonCfg.bAPSDAC_VI,pAdapter->CommonCfg.bAPSDAC_VO,pAdapter->CommonCfg.MaxSPLength));
break;
case RT_OID_802_11_QUERY_APSD_PSM:
wrq->u.data.length = sizeof(ULONG);
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
break;
case RT_OID_802_11_QUERY_WMM:
wrq->u.data.length = sizeof(BOOLEAN);
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bWmmCapable, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n", pAdapter->CommonCfg.bWmmCapable));
break;
#ifdef WPA_SUPPLICANT_SUPPORT
case RT_OID_NEW_DRIVER:
{
UCHAR enabled = 1;
wrq->u.data.length = sizeof(UCHAR);
Status = copy_to_user(wrq->u.data.pointer, &enabled, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_NEW_DRIVER (=%d)\n", enabled));
}
break;
case RT_OID_WPA_SUPPLICANT_SUPPORT:
wrq->u.data.length = sizeof(UCHAR);
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.WpaSupplicantUP, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
break;
#endif // WPA_SUPPLICANT_SUPPORT //
case RT_OID_DRIVER_DEVICE_NAME:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_DRIVER_DEVICE_NAME \n"));
wrq->u.data.length = 16;
if (copy_to_user(wrq->u.data.pointer, pAdapter->StaCfg.dev_name, wrq->u.data.length))
{
Status = -EFAULT;
}
break;
case RT_OID_802_11_QUERY_HT_PHYMODE:
pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
if (pHTPhyMode)
{
pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
pHTPhyMode->HtMode = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE;
pHTPhyMode->BW = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW;
pHTPhyMode->MCS= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS;
pHTPhyMode->SHORTGI= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI;
pHTPhyMode->STBC= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC;
pHTPhyMode->ExtOffset = ((pAdapter->CommonCfg.CentralChannel < pAdapter->CommonCfg.Channel) ? (EXTCHA_BELOW) : (EXTCHA_ABOVE));
wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
{
Status = -EFAULT;
}
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
Status = -EFAULT;
}
break;
case RT_OID_802_11_COUNTRY_REGION:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION \n"));
wrq->u.data.length = sizeof(ulInfo);
ulInfo = pAdapter->CommonCfg.CountryRegionForABand;
ulInfo = (ulInfo << 8)|(pAdapter->CommonCfg.CountryRegion);
if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length))
{
Status = -EFAULT;
}
break;
case RT_OID_802_11_QUERY_DAT_HT_PHYMODE:
pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
if (pHTPhyMode)
{
pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
pHTPhyMode->HtMode = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.HTMODE;
pHTPhyMode->BW = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.BW;
pHTPhyMode->MCS= (UCHAR)pAdapter->StaCfg.DesiredTransmitSetting.field.MCS;
pHTPhyMode->SHORTGI= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.ShortGI;
pHTPhyMode->STBC= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.STBC;
wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
{
Status = -EFAULT;
}
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
Status = -EFAULT;
}
break;
case RT_OID_QUERY_MULTIPLE_CARD_SUPPORT:
wrq->u.data.length = sizeof(UCHAR);
i = 0;
#ifdef MULTIPLE_CARD_SUPPORT
i = 1;
#endif // MULTIPLE_CARD_SUPPORT //
if (copy_to_user(wrq->u.data.pointer, &i, wrq->u.data.length))
{
Status = -EFAULT;
}
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_QUERY_MULTIPLE_CARD_SUPPORT(=%d) \n", i));
break;
#ifdef SNMP_SUPPORT
case RT_OID_802_11_MAC_ADDRESS:
wrq->u.data.length = MAC_ADDR_LEN;
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
break;
case RT_OID_802_11_MANUFACTUREROUI:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREROUI \n"));
wrq->u.data.length = ManufacturerOUI_LEN;
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
break;
case RT_OID_802_11_MANUFACTURERNAME:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTURERNAME \n"));
wrq->u.data.length = strlen(ManufacturerNAME);
Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
break;
case RT_OID_802_11_RESOURCETYPEIDNAME:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_RESOURCETYPEIDNAME \n"));
wrq->u.data.length = strlen(ResourceTypeIdName);
Status = copy_to_user(wrq->u.data.pointer, ResourceTypeIdName, wrq->u.data.length);
break;
case RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED \n"));
ulInfo = 1; // 1 is support wep else 2 is not support.
wrq->u.data.length = sizeof(ulInfo);
Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
break;
case RT_OID_802_11_POWERMANAGEMENTMODE:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_POWERMANAGEMENTMODE \n"));
if (pAdapter->StaCfg.Psm == PSMP_ACTION)
ulInfo = 1; // 1 is power active else 2 is power save.
else
ulInfo = 2;
wrq->u.data.length = sizeof(ulInfo);
Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
break;
case OID_802_11_WEPDEFAULTKEYVALUE:
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEPDEFAULTKEYVALUE \n"));
//KeyIdxValue.KeyIdx = pAd->PortCfg.MBSSID[pAd->IoctlIF].DefaultKeyId;
pKeyIdxValue = wrq->u.data.pointer;
DBGPRINT(RT_DEBUG_TRACE,("KeyIdxValue.KeyIdx = %d, \n",pKeyIdxValue->KeyIdx));
valueLen = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
NdisMoveMemory(pKeyIdxValue->Value,
&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key,
valueLen);
pKeyIdxValue->Value[valueLen]='\0';
wrq->u.data.length = sizeof(DefaultKeyIdxValue);
Status = copy_to_user(wrq->u.data.pointer, pKeyIdxValue, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE,("DefaultKeyId = %d, total len = %d, str len=%d, KeyValue= %02x %02x %02x %02x \n", pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
pAdapter->SharedKey[BSS0][0].Key[0],
pAdapter->SharedKey[BSS0][1].Key[0],
pAdapter->SharedKey[BSS0][2].Key[0],
pAdapter->SharedKey[BSS0][3].Key[0]));
break;
case OID_802_11_WEPDEFAULTKEYID:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPDEFAULTKEYID \n"));
wrq->u.data.length = sizeof(UCHAR);
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAdapter->StaCfg.DefaultKeyId));
break;
case RT_OID_802_11_WEPKEYMAPPINGLENGTH:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPKEYMAPPINGLENGTH \n"));
wrq->u.data.length = sizeof(UCHAR);
Status = copy_to_user(wrq->u.data.pointer,
&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
wrq->u.data.length);
break;
case OID_802_11_SHORTRETRYLIMIT:
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SHORTRETRYLIMIT \n"));
wrq->u.data.length = sizeof(ULONG);
RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
ShortRetryLimit = tx_rty_cfg.field.ShortRtyLimit;
DBGPRINT(RT_DEBUG_TRACE, ("ShortRetryLimit =%ld, tx_rty_cfg.field.ShortRetryLimit=%d\n", ShortRetryLimit, tx_rty_cfg.field.ShortRtyLimit));
Status = copy_to_user(wrq->u.data.pointer, &ShortRetryLimit, wrq->u.data.length);
break;
case OID_802_11_LONGRETRYLIMIT:
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_LONGRETRYLIMIT \n"));
wrq->u.data.length = sizeof(ULONG);
RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
LongRetryLimit = tx_rty_cfg.field.LongRtyLimit;
DBGPRINT(RT_DEBUG_TRACE, ("LongRetryLimit =%ld, tx_rty_cfg.field.LongRtyLimit=%d\n", LongRetryLimit, tx_rty_cfg.field.LongRtyLimit));
Status = copy_to_user(wrq->u.data.pointer, &LongRetryLimit, wrq->u.data.length);
break;
case RT_OID_802_11_PRODUCTID:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
#ifdef RT2870
sprintf(tmp, "%04x %04x\n", ((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idVendor ,((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idProduct);
#endif // RT2870 //
wrq->u.data.length = strlen(tmp);
Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
break;
case RT_OID_802_11_MANUFACTUREID:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREID \n"));
wrq->u.data.length = strlen(ManufacturerNAME);
Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
break;
case OID_802_11_CURRENTCHANNEL:
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CURRENTCHANNEL \n"));
wrq->u.data.length = sizeof(UCHAR);
DBGPRINT(RT_DEBUG_TRACE, ("sizeof UCHAR=%d, channel=%d \n", sizeof(UCHAR), pAdapter->CommonCfg.Channel));
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Channel, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
break;
#endif //SNMP_SUPPORT
case OID_802_11_BUILD_CHANNEL_EX:
{
UCHAR value;
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BUILD_CHANNEL_EX \n"));
wrq->u.data.length = sizeof(UCHAR);
#ifdef EXT_BUILD_CHANNEL_LIST
DBGPRINT(RT_DEBUG_TRACE, ("Support EXT_BUILD_CHANNEL_LIST.\n"));
value = 1;
#else
DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n"));
value = 0;
#endif // EXT_BUILD_CHANNEL_LIST //
Status = copy_to_user(wrq->u.data.pointer, &value, 1);
DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
}
break;
case OID_802_11_GET_CH_LIST:
{
PRT_CHANNEL_LIST_INFO pChListBuf;
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CH_LIST \n"));
if (pAdapter->ChannelListNum == 0)
{
wrq->u.data.length = 0;
break;
}
pChListBuf = (RT_CHANNEL_LIST_INFO *) kmalloc(sizeof(RT_CHANNEL_LIST_INFO), MEM_ALLOC_FLAG);
if (pChListBuf == NULL)
{
wrq->u.data.length = 0;
break;
}
pChListBuf->ChannelListNum = pAdapter->ChannelListNum;
for (i = 0; i < pChListBuf->ChannelListNum; i++)
pChListBuf->ChannelList[i] = pAdapter->ChannelList[i].Channel;
wrq->u.data.length = sizeof(RT_CHANNEL_LIST_INFO);
Status = copy_to_user(wrq->u.data.pointer, pChListBuf, sizeof(RT_CHANNEL_LIST_INFO));
DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
if (pChListBuf)
kfree(pChListBuf);
}
break;
case OID_802_11_GET_COUNTRY_CODE:
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_COUNTRY_CODE \n"));
wrq->u.data.length = 2;
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.CountryCode, 2);
DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
break;
case OID_802_11_GET_CHANNEL_GEOGRAPHY:
DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CHANNEL_GEOGRAPHY \n"));
wrq->u.data.length = 1;
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Geography, 1);
DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
break;
#ifdef QOS_DLS_SUPPORT
case RT_OID_802_11_QUERY_DLS:
wrq->u.data.length = sizeof(BOOLEAN);
Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bDLSCapable, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS(=%d)\n", pAdapter->CommonCfg.bDLSCapable));
break;
case RT_OID_802_11_QUERY_DLS_PARAM:
{
PRT_802_11_DLS_INFO pDlsInfo = kmalloc(sizeof(RT_802_11_DLS_INFO), GFP_ATOMIC);
if (pDlsInfo == NULL)
break;
for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
{
RTMPMoveMemory(&pDlsInfo->Entry[i], &pAdapter->StaCfg.DLSEntry[i], sizeof(RT_802_11_DLS_UI));
}
pDlsInfo->num = MAX_NUM_OF_DLS_ENTRY;
wrq->u.data.length = sizeof(RT_802_11_DLS_INFO);
Status = copy_to_user(wrq->u.data.pointer, pDlsInfo, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS_PARAM\n"));
if (pDlsInfo)
kfree(pDlsInfo);
}
break;
#endif // QOS_DLS_SUPPORT //
default:
DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x\n", cmd));
Status = -EOPNOTSUPP;
break;
}
return Status;
}
INT rt28xx_sta_ioctl(
IN struct net_device *net_dev,
IN OUT struct ifreq *rq,
IN INT cmd)
{
POS_COOKIE pObj;
VIRTUAL_ADAPTER *pVirtualAd = NULL;
RTMP_ADAPTER *pAd = NULL;
struct iwreq *wrq = (struct iwreq *) rq;
BOOLEAN StateMachineTouched = FALSE;
INT Status = NDIS_STATUS_SUCCESS;
USHORT subcmd;
if (net_dev->priv_flags == INT_MAIN)
{
pAd = net_dev->ml_priv;
}
else
{
pVirtualAd = net_dev->ml_priv;
pAd = pVirtualAd->RtmpDev->ml_priv;
}
pObj = (POS_COOKIE) pAd->OS_Cookie;
if (pAd == NULL)
{
/* if 1st open fail, pAd will be free;
So the net_dev->ml_priv will be NULL in 2rd open */
return -ENETDOWN;
}
//check if the interface is down
if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
#ifdef CONFIG_APSTA_MIXED_SUPPORT
if (wrq->u.data.pointer == NULL)
{
return Status;
}
if (strstr(wrq->u.data.pointer, "OpMode") == NULL)
#endif // CONFIG_APSTA_MIXED_SUPPORT //
{
DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
return -ENETDOWN;
}
}
{ // determine this ioctl command is comming from which interface.
pObj->ioctl_if_type = INT_MAIN;
pObj->ioctl_if = MAIN_MBSSID;
}
switch(cmd)
{
#ifdef RALINK_ATE
#ifdef RALINK_28xx_QA
case RTPRIV_IOCTL_ATE:
{
RtmpDoAte(pAd, wrq);
}
break;
#endif // RALINK_28xx_QA //
#endif // RALINK_ATE //
case SIOCGIFHWADDR:
DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
break;
case SIOCGIWNAME:
{
char *name=&wrq->u.name[0];
rt_ioctl_giwname(net_dev, NULL, name, NULL);
break;
}
case SIOCGIWESSID: //Get ESSID
{
struct iw_point *essid=&wrq->u.essid;
rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
break;
}
case SIOCSIWESSID: //Set ESSID
{
struct iw_point *essid=&wrq->u.essid;
rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
break;
}
case SIOCSIWNWID: // set network id (the cell)
case SIOCGIWNWID: // get network id
Status = -EOPNOTSUPP;
break;
case SIOCSIWFREQ: //set channel/frequency (Hz)
{
struct iw_freq *freq=&wrq->u.freq;
rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
break;
}
case SIOCGIWFREQ: // get channel/frequency (Hz)
{
struct iw_freq *freq=&wrq->u.freq;
rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
break;
}
case SIOCSIWNICKN: //set node name/nickname
{
struct iw_point *data=&wrq->u.data;
rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
break;
}
case SIOCGIWNICKN: //get node name/nickname
{
struct iw_point *data=&wrq->u.data;
rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
break;
}
case SIOCGIWRATE: //get default bit rate (bps)
rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
break;
case SIOCSIWRATE: //set default bit rate (bps)
rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
break;
case SIOCGIWRTS: // get RTS/CTS threshold (bytes)
{
struct iw_param *rts=&wrq->u.rts;
rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
break;
}
case SIOCSIWRTS: //set RTS/CTS threshold (bytes)
{
struct iw_param *rts=&wrq->u.rts;
rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
break;
}
case SIOCGIWFRAG: //get fragmentation thr (bytes)
{
struct iw_param *frag=&wrq->u.frag;
rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
break;
}
case SIOCSIWFRAG: //set fragmentation thr (bytes)
{
struct iw_param *frag=&wrq->u.frag;
rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
break;
}
case SIOCGIWENCODE: //get encoding token & mode
{
struct iw_point *erq=&wrq->u.encoding;
if(erq->pointer)
rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
break;
}
case SIOCSIWENCODE: //set encoding token & mode
{
struct iw_point *erq=&wrq->u.encoding;
if(erq->pointer)
rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
break;
}
case SIOCGIWAP: //get access point MAC addresses
{
struct sockaddr *ap_addr=&wrq->u.ap_addr;
rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
break;
}
case SIOCSIWAP: //set access point MAC addresses
{
struct sockaddr *ap_addr=&wrq->u.ap_addr;
rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
break;
}
case SIOCGIWMODE: //get operation mode
{
__u32 *mode=&wrq->u.mode;
rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
break;
}
case SIOCSIWMODE: //set operation mode
{
__u32 *mode=&wrq->u.mode;
rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
break;
}
case SIOCGIWSENS: //get sensitivity (dBm)
case SIOCSIWSENS: //set sensitivity (dBm)
case SIOCGIWPOWER: //get Power Management settings
case SIOCSIWPOWER: //set Power Management settings
case SIOCGIWTXPOW: //get transmit power (dBm)
case SIOCSIWTXPOW: //set transmit power (dBm)
case SIOCGIWRANGE: //Get range of parameters
case SIOCGIWRETRY: //get retry limits and lifetime
case SIOCSIWRETRY: //set retry limits and lifetime
Status = -EOPNOTSUPP;
break;
case RT_PRIV_IOCTL:
case RT_PRIV_IOCTL_EXT:
subcmd = wrq->u.data.flags;
if( subcmd & OID_GET_SET_TOGGLE)
Status = RTMPSetInformation(pAd, rq, subcmd);
else
Status = RTMPQueryInformation(pAd, rq, subcmd);
break;
case SIOCGIWPRIV:
if (wrq->u.data.pointer)
{
if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
break;
wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
Status = -EFAULT;
}
break;
case RTPRIV_IOCTL_SET:
if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
break;
rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
break;
case RTPRIV_IOCTL_GSITESURVEY:
RTMPIoctlGetSiteSurvey(pAd, wrq);
break;
#ifdef DBG
case RTPRIV_IOCTL_MAC:
RTMPIoctlMAC(pAd, wrq);
break;
case RTPRIV_IOCTL_E2P:
RTMPIoctlE2PROM(pAd, wrq);
break;
#ifdef RT30xx
case RTPRIV_IOCTL_RF:
RTMPIoctlRF(pAd, wrq);
break;
#endif // RT30xx //
#endif // DBG //
case SIOCETHTOOL:
break;
default:
DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
Status = -EOPNOTSUPP;
break;
}
if(StateMachineTouched) // Upper layer sent a MLME-related operations
RT28XX_MLME_HANDLER(pAd);
return Status;
}
/*
==========================================================================
Description:
Set SSID
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT Set_SSID_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg)
{
NDIS_802_11_SSID Ssid, *pSsid=NULL;
BOOLEAN StateMachineTouched = FALSE;
int success = TRUE;
if( strlen(arg) <= MAX_LEN_OF_SSID)
{
NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
if (strlen(arg) != 0)
{
NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
Ssid.SsidLength = strlen(arg);
}
else //ANY ssid
{
Ssid.SsidLength = 0;
memcpy(Ssid.Ssid, "", 0);
pAdapter->StaCfg.BssType = BSS_INFRA;
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
pAdapter->StaCfg.WepStatus = Ndis802_11EncryptionDisabled;
}
pSsid = &Ssid;
if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
{
RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
}
pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
pAdapter->bConfigChanged = TRUE;
MlmeEnqueue(pAdapter,
MLME_CNTL_STATE_MACHINE,
OID_802_11_SSID,
sizeof(NDIS_802_11_SSID),
(VOID *)pSsid);
StateMachineTouched = TRUE;
DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
}
else
success = FALSE;
if (StateMachineTouched) // Upper layer sent a MLME-related operations
RT28XX_MLME_HANDLER(pAdapter);
return success;
}
#ifdef WMM_SUPPORT
/*
==========================================================================
Description:
Set WmmCapable Enable or Disable
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT Set_WmmCapable_Proc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg)
{
BOOLEAN bWmmCapable;
bWmmCapable = simple_strtol(arg, 0, 10);
if ((bWmmCapable == 1)
#ifdef RT2870
&& (pAd->NumberOfPipes >= 5)
#endif // RT2870 //
)
pAd->CommonCfg.bWmmCapable = TRUE;
else if (bWmmCapable == 0)
pAd->CommonCfg.bWmmCapable = FALSE;
else
return FALSE; //Invalid argument
DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
pAd->CommonCfg.bWmmCapable));
return TRUE;
}
#endif // WMM_SUPPORT //
/*
==========================================================================
Description:
Set Network Type(Infrastructure/Adhoc mode)
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT Set_NetworkType_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg)
{
UINT32 Value = 0;
if (strcmp(arg, "Adhoc") == 0)
{
if (pAdapter->StaCfg.BssType != BSS_ADHOC)
{
// Config has changed
pAdapter->bConfigChanged = TRUE;
if (MONITOR_ON(pAdapter))
{
RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
Value &= (~0x80);
RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
pAdapter->StaCfg.bAutoReconnect = TRUE;
LinkDown(pAdapter, FALSE);
}
if (INFRA_ON(pAdapter))
{
//BOOLEAN Cancelled;
// Set the AutoReconnectSsid to prevent it reconnect to old SSID
// Since calling this indicate user don't want to connect to that SSID anymore.
pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
LinkDown(pAdapter, FALSE);
DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
}
}
pAdapter->StaCfg.BssType = BSS_ADHOC;
pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
}
else if (strcmp(arg, "Infra") == 0)
{
if (pAdapter->StaCfg.BssType != BSS_INFRA)
{
// Config has changed
pAdapter->bConfigChanged = TRUE;
if (MONITOR_ON(pAdapter))
{
RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
Value &= (~0x80);
RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
pAdapter->StaCfg.bAutoReconnect = TRUE;
LinkDown(pAdapter, FALSE);
}
if (ADHOC_ON(pAdapter))
{
// Set the AutoReconnectSsid to prevent it reconnect to old SSID
// Since calling this indicate user don't want to connect to that SSID anymore.
pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
LinkDown(pAdapter, FALSE);
}
}
pAdapter->StaCfg.BssType = BSS_INFRA;
pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
pAdapter->StaCfg.BssType = BSS_INFRA;
}
else if (strcmp(arg, "Monitor") == 0)
{
UCHAR bbpValue = 0;
BCN_TIME_CFG_STRUC csr;
OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
// disable all periodic state machine
pAdapter->StaCfg.bAutoReconnect = FALSE;
// reset all mlme state machine
RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
if (pAdapter->CommonCfg.CentralChannel == 0)
{
#ifdef DOT11_N_SUPPORT
if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
pAdapter->CommonCfg.CentralChannel = 36;
else
#endif // DOT11_N_SUPPORT //
pAdapter->CommonCfg.CentralChannel = 6;
}
#ifdef DOT11_N_SUPPORT
else
N_ChannelCheck(pAdapter);
#endif // DOT11_N_SUPPORT //
#ifdef DOT11_N_SUPPORT
if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
{
// 40MHz ,control channel at lower
RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
bbpValue &= (~0x18);
bbpValue |= 0x10;
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
pAdapter->CommonCfg.BBPCurrentBW = BW_40;
// RX : control channel at lower
RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
bbpValue &= (~0x20);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
Value &= 0xfffffffe;
RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
pAdapter->CommonCfg.Channel,
pAdapter->CommonCfg.CentralChannel));
}
else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
{
// 40MHz ,control channel at upper
RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
bbpValue &= (~0x18);
bbpValue |= 0x10;
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
pAdapter->CommonCfg.BBPCurrentBW = BW_40;
RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
Value |= 0x1;
RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
bbpValue |= (0x20);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
pAdapter->CommonCfg.Channel,
pAdapter->CommonCfg.CentralChannel));
}
else
#endif // DOT11_N_SUPPORT //
{
// 20MHz
RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
bbpValue &= (~0x18);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
pAdapter->CommonCfg.BBPCurrentBW = BW_20;
AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
}
// Enable Rx with promiscuous reception
RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
// ASIC supporsts sniffer function with replacing RSSI with timestamp.
//RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
//Value |= (0x80);
//RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
// disable sync
RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
csr.field.bBeaconGen = 0;
csr.field.bTBTTEnable = 0;
csr.field.TsfSyncMode = 0;
RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
pAdapter->StaCfg.BssType = BSS_MONITOR;
pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
}
// Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
pAdapter->StaCfg.WpaState = SS_NOTUSE;
DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
return TRUE;
}
/*
==========================================================================
Description:
Set Authentication mode
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT Set_AuthMode_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg)
{
if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
#ifdef WPA_SUPPLICANT_SUPPORT
else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
#endif // WPA_SUPPLICANT_SUPPORT //
else
return FALSE;
pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
return TRUE;
}
/*
==========================================================================
Description:
Set Encryption Type
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT Set_EncrypType_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg)
{
if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
{
if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
return TRUE; // do nothing
pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
}
else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
{
if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
return TRUE; // do nothing
pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
}
else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
{
if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
return TRUE; // do nothing
pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
}
else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
{
if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
return TRUE; // do nothing
pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
}
else
return FALSE;
pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
return TRUE;
}
/*
==========================================================================
Description:
Set Default Key ID
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT Set_DefaultKeyID_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg)
{
ULONG KeyIdx;
KeyIdx = simple_strtol(arg, 0, 10);
if((KeyIdx >= 1 ) && (KeyIdx <= 4))
pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
else
return FALSE; //Invalid argument
DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
return TRUE;
}
/*
==========================================================================
Description:
Set WEP KEY1
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT Set_Key1_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg)
{
int KeyLen;
int i;
UCHAR CipherAlg=CIPHER_WEP64;
if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
return TRUE; // do nothing
KeyLen = strlen(arg);
switch (KeyLen)
{
case 5: //wep 40 Ascii type
pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
CipherAlg = CIPHER_WEP64;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
break;
case 10: //wep 40 Hex type
for(i=0; i < KeyLen; i++)
{
if( !isxdigit(*(arg+i)) )
return FALSE; //Not Hex value;
}
pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
CipherAlg = CIPHER_WEP64;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
break;
case 13: //wep 104 Ascii type
pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
CipherAlg = CIPHER_WEP128;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
break;
case 26: //wep 104 Hex type
for(i=0; i < KeyLen; i++)
{
if( !isxdigit(*(arg+i)) )
return FALSE; //Not Hex value;
}
pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
CipherAlg = CIPHER_WEP128;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
break;
default: //Invalid argument
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
return FALSE;
}
pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
// Set keys (into ASIC)
if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
; // not support
else // Old WEP stuff
{
AsicAddSharedKeyEntry(pAdapter,
0,
0,
pAdapter->SharedKey[BSS0][0].CipherAlg,
pAdapter->SharedKey[BSS0][0].Key,
NULL,
NULL);
}
return TRUE;
}
/*
==========================================================================
Description:
Set WEP KEY2
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT Set_Key2_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg)
{
int KeyLen;
int i;
UCHAR CipherAlg=CIPHER_WEP64;
if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
return TRUE; // do nothing
KeyLen = strlen(arg);
switch (KeyLen)
{
case 5: //wep 40 Ascii type
pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
CipherAlg = CIPHER_WEP64;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
break;
case 10: //wep 40 Hex type
for(i=0; i < KeyLen; i++)
{
if( !isxdigit(*(arg+i)) )
return FALSE; //Not Hex value;
}
pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
CipherAlg = CIPHER_WEP64;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
break;
case 13: //wep 104 Ascii type
pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
CipherAlg = CIPHER_WEP128;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
break;
case 26: //wep 104 Hex type
for(i=0; i < KeyLen; i++)
{
if( !isxdigit(*(arg+i)) )
return FALSE; //Not Hex value;
}
pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
CipherAlg = CIPHER_WEP128;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
break;
default: //Invalid argument
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
return FALSE;
}
pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
// Set keys (into ASIC)
if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
; // not support
else // Old WEP stuff
{
AsicAddSharedKeyEntry(pAdapter,
0,
1,
pAdapter->SharedKey[BSS0][1].CipherAlg,
pAdapter->SharedKey[BSS0][1].Key,
NULL,
NULL);
}
return TRUE;
}
/*
==========================================================================
Description:
Set WEP KEY3
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT Set_Key3_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg)
{
int KeyLen;
int i;
UCHAR CipherAlg=CIPHER_WEP64;
if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
return TRUE; // do nothing
KeyLen = strlen(arg);
switch (KeyLen)
{
case 5: //wep 40 Ascii type
pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
CipherAlg = CIPHER_WEP64;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
break;
case 10: //wep 40 Hex type
for(i=0; i < KeyLen; i++)
{
if( !isxdigit(*(arg+i)) )
return FALSE; //Not Hex value;
}
pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
CipherAlg = CIPHER_WEP64;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
break;
case 13: //wep 104 Ascii type
pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
CipherAlg = CIPHER_WEP128;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
break;
case 26: //wep 104 Hex type
for(i=0; i < KeyLen; i++)
{
if( !isxdigit(*(arg+i)) )
return FALSE; //Not Hex value;
}
pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
CipherAlg = CIPHER_WEP128;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
break;
default: //Invalid argument
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
return FALSE;
}
pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
// Set keys (into ASIC)
if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
; // not support
else // Old WEP stuff
{
AsicAddSharedKeyEntry(pAdapter,
0,
2,
pAdapter->SharedKey[BSS0][2].CipherAlg,
pAdapter->SharedKey[BSS0][2].Key,
NULL,
NULL);
}
return TRUE;
}
/*
==========================================================================
Description:
Set WEP KEY4
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT Set_Key4_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg)
{
int KeyLen;
int i;
UCHAR CipherAlg=CIPHER_WEP64;
if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
return TRUE; // do nothing
KeyLen = strlen(arg);
switch (KeyLen)
{
case 5: //wep 40 Ascii type
pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
CipherAlg = CIPHER_WEP64;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
break;
case 10: //wep 40 Hex type
for(i=0; i < KeyLen; i++)
{
if( !isxdigit(*(arg+i)) )
return FALSE; //Not Hex value;
}
pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
CipherAlg = CIPHER_WEP64;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
break;
case 13: //wep 104 Ascii type
pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
CipherAlg = CIPHER_WEP128;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
break;
case 26: //wep 104 Hex type
for(i=0; i < KeyLen; i++)
{
if( !isxdigit(*(arg+i)) )
return FALSE; //Not Hex value;
}
pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
CipherAlg = CIPHER_WEP128;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
break;
default: //Invalid argument
DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
return FALSE;
}
pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
// Set keys (into ASIC)
if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
; // not support
else // Old WEP stuff
{
AsicAddSharedKeyEntry(pAdapter,
0,
3,
pAdapter->SharedKey[BSS0][3].CipherAlg,
pAdapter->SharedKey[BSS0][3].Key,
NULL,
NULL);
}
return TRUE;
}
/*
==========================================================================
Description:
Set WPA PSK key
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT Set_WPAPSK_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg)
{
UCHAR keyMaterial[40];
if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
(pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
(pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
)
return TRUE; // do nothing
DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
NdisZeroMemory(keyMaterial, 40);
if ((strlen(arg) < 8) || (strlen(arg) > 64))
{
DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
return FALSE;
}
if (strlen(arg) == 64)
{
AtoH(arg, keyMaterial, 32);
NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
}
else
{
PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
}
if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
{
pAdapter->StaCfg.WpaState = SS_NOTUSE;
}
else
{
// Start STA supplicant state machine
pAdapter->StaCfg.WpaState = SS_START;
}
return TRUE;
}
/*
==========================================================================
Description:
Set Power Saving mode
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT Set_PSMode_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg)
{
if (pAdapter->StaCfg.BssType == BSS_INFRA)
{
if ((strcmp(arg, "Max_PSP") == 0) ||
(strcmp(arg, "max_psp") == 0) ||
(strcmp(arg, "MAX_PSP") == 0))
{
// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
// to exclude certain situations.
if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
pAdapter->StaCfg.DefaultListenCount = 5;
}
else if ((strcmp(arg, "Fast_PSP") == 0) ||
(strcmp(arg, "fast_psp") == 0) ||
(strcmp(arg, "FAST_PSP") == 0))
{
// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
// to exclude certain situations.
OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
pAdapter->StaCfg.DefaultListenCount = 3;
}
else if ((strcmp(arg, "Legacy_PSP") == 0) ||
(strcmp(arg, "legacy_psp") == 0) ||
(strcmp(arg, "LEGACY_PSP") == 0))
{
// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
// to exclude certain situations.
OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
pAdapter->StaCfg.DefaultListenCount = 3;
}
else
{
//Default Ndis802_11PowerModeCAM
// clear PSM bit immediately
MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
}
DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
}
else
return FALSE;
return TRUE;
}
#ifdef WPA_SUPPLICANT_SUPPORT
/*
==========================================================================
Description:
Set WpaSupport flag.
Value:
0: Driver ignore wpa_supplicant.
1: wpa_supplicant initiates scanning and AP selection.
2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT Set_Wpa_Support(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg)
{
if ( simple_strtol(arg, 0, 10) == 0)
pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
else if ( simple_strtol(arg, 0, 10) == 1)
pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
else if ( simple_strtol(arg, 0, 10) == 2)
pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
else
pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
return TRUE;
}
#endif // WPA_SUPPLICANT_SUPPORT //
#ifdef DBG
/*
==========================================================================
Description:
Read / Write MAC
Arguments:
pAdapter Pointer to our adapter
wrq Pointer to the ioctl argument
Return Value:
None
Note:
Usage:
1.) iwpriv ra0 mac 0 ==> read MAC where Addr=0x0
2.) iwpriv ra0 mac 0=12 ==> write MAC where Addr=0x0, value=12
==========================================================================
*/
VOID RTMPIoctlMAC(
IN PRTMP_ADAPTER pAdapter,
IN struct iwreq *wrq)
{
CHAR *this_char;
CHAR *value;
INT j = 0, k = 0;
CHAR msg[1024];
CHAR arg[255];
ULONG macAddr = 0;
UCHAR temp[16], temp2[16];
UINT32 macValue = 0;
INT Status;
BOOLEAN bIsPrintAllMAC = FALSE;
memset(msg, 0x00, 1024);
if (wrq->u.data.length > 1) //No parameters.
{
Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
sprintf(msg, "\n");
//Parsing Read or Write
this_char = arg;
if (!*this_char)
goto next;
if ((value = rtstrchr(this_char, '=')) != NULL)
*value++ = 0;
if (!value || !*value)
{ //Read
// Sanity check
if(strlen(this_char) > 4)
goto next;
j = strlen(this_char);
while(j-- > 0)
{
if(this_char[j] > 'f' || this_char[j] < '0')
return;
}
// Mac Addr
k = j = strlen(this_char);
while(j-- > 0)
{
this_char[4-k+j] = this_char[j];
}
while(k < 4)
this_char[3-k++]='0';
this_char[4]='\0';
if(strlen(this_char) == 4)
{
AtoH(this_char, temp, 2);
macAddr = *temp*256 + temp[1];
if (macAddr < 0xFFFF)
{
RTMP_IO_READ32(pAdapter, macAddr, &macValue);
DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%lx, MacValue=%x\n", macAddr, macValue));
sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr , macValue);
}
else
{//Invalid parametes, so default printk all mac
bIsPrintAllMAC = TRUE;
goto next;
}
}
}
else
{ //Write
memcpy(&temp2, value, strlen(value));
temp2[strlen(value)] = '\0';
// Sanity check
if((strlen(this_char) > 4) || strlen(temp2) > 8)
goto next;
j = strlen(this_char);
while(j-- > 0)
{
if(this_char[j] > 'f' || this_char[j] < '0')
return;
}
j = strlen(temp2);
while(j-- > 0)
{
if(temp2[j] > 'f' || temp2[j] < '0')
return;
}
//MAC Addr
k = j = strlen(this_char);
while(j-- > 0)
{
this_char[4-k+j] = this_char[j];
}
while(k < 4)
this_char[3-k++]='0';
this_char[4]='\0';
//MAC value
k = j = strlen(temp2);
while(j-- > 0)
{
temp2[8-k+j] = temp2[j];
}
while(k < 8)
temp2[7-k++]='0';
temp2[8]='\0';
{
AtoH(this_char, temp, 2);
macAddr = *temp*256 + temp[1];
AtoH(temp2, temp, 4);
macValue = *temp*256*256*256 + temp[1]*256*256 + temp[2]*256 + temp[3];
// debug mode
if (macAddr == (HW_DEBUG_SETTING_BASE + 4))
{
// 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
if (macValue & 0x000000ff)
{
pAdapter->BbpTuning.bEnable = TRUE;
DBGPRINT(RT_DEBUG_TRACE,("turn on R17 tuning\n"));
}
else
{
UCHAR R66;
pAdapter->BbpTuning.bEnable = FALSE;
R66 = 0x26 + GET_LNA_GAIN(pAdapter);
#ifdef RALINK_ATE
if (ATE_ON(pAdapter))
{
ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
}
else
#endif // RALINK_ATE //
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66));
}
return;
}
DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%02lx, MacValue=0x%x\n", macAddr, macValue));
RTMP_IO_WRITE32(pAdapter, macAddr, macValue);
sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr, macValue);
}
}
}
else
bIsPrintAllMAC = TRUE;
next:
if (bIsPrintAllMAC)
{
struct file *file_w;
PCHAR fileName = "MacDump.txt";
mm_segment_t orig_fs;
orig_fs = get_fs();
set_fs(KERNEL_DS);
// open file
file_w = filp_open(fileName, O_WRONLY|O_CREAT, 0);
if (IS_ERR(file_w))
{
DBGPRINT(RT_DEBUG_TRACE, ("-->2) %s: Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(file_w), fileName));
}
else
{
if (file_w->f_op && file_w->f_op->write)
{
file_w->f_pos = 0;
macAddr = 0x1000;
while (macAddr <= 0x1800)
{
RTMP_IO_READ32(pAdapter, macAddr, &macValue);
sprintf(msg, "%08lx = %08X\n", macAddr, macValue);
// write data to file
file_w->f_op->write(file_w, msg, strlen(msg), &file_w->f_pos);
printk("%s", msg);
macAddr += 4;
}
sprintf(msg, "\nDump all MAC values to %s\n", fileName);
}
filp_close(file_w, NULL);
}
set_fs(orig_fs);
}
if(strlen(msg) == 1)
sprintf(msg+strlen(msg), "===>Error command format!");
// Copy the information into the user buffer
wrq->u.data.length = strlen(msg);
Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlMAC\n\n"));
}
/*
==========================================================================
Description:
Read / Write E2PROM
Arguments:
pAdapter Pointer to our adapter
wrq Pointer to the ioctl argument
Return Value:
None
Note:
Usage:
1.) iwpriv ra0 e2p 0 ==> read E2PROM where Addr=0x0
2.) iwpriv ra0 e2p 0=1234 ==> write E2PROM where Addr=0x0, value=1234
==========================================================================
*/
VOID RTMPIoctlE2PROM(
IN PRTMP_ADAPTER pAdapter,
IN struct iwreq *wrq)
{
CHAR *this_char;
CHAR *value;
INT j = 0, k = 0;
CHAR msg[1024];
CHAR arg[255];
USHORT eepAddr = 0;
UCHAR temp[16], temp2[16];
USHORT eepValue;
int Status;
BOOLEAN bIsPrintAllE2P = FALSE;
memset(msg, 0x00, 1024);
if (wrq->u.data.length > 1) //No parameters.
{
Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
sprintf(msg, "\n");
//Parsing Read or Write
this_char = arg;
if (!*this_char)
goto next;
if ((value = rtstrchr(this_char, '=')) != NULL)
*value++ = 0;
if (!value || !*value)
{ //Read
// Sanity check
if(strlen(this_char) > 4)
goto next;
j = strlen(this_char);
while(j-- > 0)
{
if(this_char[j] > 'f' || this_char[j] < '0')
return;
}
// E2PROM addr
k = j = strlen(this_char);
while(j-- > 0)
{
this_char[4-k+j] = this_char[j];
}
while(k < 4)
this_char[3-k++]='0';
this_char[4]='\0';
if(strlen(this_char) == 4)
{
AtoH(this_char, temp, 2);
eepAddr = *temp*256 + temp[1];
if (eepAddr < 0xFFFF)
{
RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
sprintf(msg+strlen(msg), "[0x%04X]:0x%04X ", eepAddr , eepValue);
}
else
{//Invalid parametes, so default printk all bbp
bIsPrintAllE2P = TRUE;
goto next;
}
}
}
else
{ //Write
memcpy(&temp2, value, strlen(value));
temp2[strlen(value)] = '\0';
// Sanity check
if((strlen(this_char) > 4) || strlen(temp2) > 8)
goto next;
j = strlen(this_char);
while(j-- > 0)
{
if(this_char[j] > 'f' || this_char[j] < '0')
return;
}
j = strlen(temp2);
while(j-- > 0)
{
if(temp2[j] > 'f' || temp2[j] < '0')
return;
}
//MAC Addr
k = j = strlen(this_char);
while(j-- > 0)
{
this_char[4-k+j] = this_char[j];
}
while(k < 4)
this_char[3-k++]='0';
this_char[4]='\0';
//MAC value
k = j = strlen(temp2);
while(j-- > 0)
{
temp2[4-k+j] = temp2[j];
}
while(k < 4)
temp2[3-k++]='0';
temp2[4]='\0';
AtoH(this_char, temp, 2);
eepAddr = *temp*256 + temp[1];
AtoH(temp2, temp, 2);
eepValue = *temp*256 + temp[1];
RT28xx_EEPROM_WRITE16(pAdapter, eepAddr, eepValue);
sprintf(msg+strlen(msg), "[0x%02X]:%02X ", eepAddr, eepValue);
}
}
else
bIsPrintAllE2P = TRUE;
next:
if (bIsPrintAllE2P)
{
struct file *file_w;
PCHAR fileName = "EEPROMDump.txt";
mm_segment_t orig_fs;
orig_fs = get_fs();
set_fs(KERNEL_DS);
// open file
file_w = filp_open(fileName, O_WRONLY|O_CREAT, 0);
if (IS_ERR(file_w))
{
DBGPRINT(RT_DEBUG_TRACE, ("-->2) %s: Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(file_w), fileName));
}
else
{
if (file_w->f_op && file_w->f_op->write)
{
file_w->f_pos = 0;
eepAddr = 0x00;
while (eepAddr <= 0xFE)
{
RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
sprintf(msg, "%08x = %04x\n", eepAddr , eepValue);
// write data to file
file_w->f_op->write(file_w, msg, strlen(msg), &file_w->f_pos);
printk("%s", msg);
eepAddr += 2;
}
sprintf(msg, "\nDump all EEPROM values to %s\n", fileName);
}
filp_close(file_w, NULL);
}
set_fs(orig_fs);
}
if(strlen(msg) == 1)
sprintf(msg+strlen(msg), "===>Error command format!");
// Copy the information into the user buffer
wrq->u.data.length = strlen(msg);
Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n"));
}
#ifdef RT30xx
/*
==========================================================================
Description:
Read / Write RF register
Arguments:
pAdapter Pointer to our adapter
wrq Pointer to the ioctl argument
Return Value:
None
Note:
Usage:
1.) iwpriv ra0 rf ==> read all RF registers
2.) iwpriv ra0 rf 1 ==> read RF where RegID=1
3.) iwpriv ra0 rf 1=10 ==> write RF R1=0x10
==========================================================================
*/
VOID RTMPIoctlRF(
IN PRTMP_ADAPTER pAdapter,
IN struct iwreq *wrq)
{
CHAR *this_char;
CHAR *value;
UCHAR regRF = 0;
CHAR msg[2048];
CHAR arg[255];
INT rfId;
LONG rfValue;
int Status;
BOOLEAN bIsPrintAllRF = FALSE;
memset(msg, 0x00, 2048);
if (wrq->u.data.length > 1) //No parameters.
{
Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
sprintf(msg, "\n");
//Parsing Read or Write
this_char = arg;
if (!*this_char)
goto next;
if ((value = strchr(this_char, '=')) != NULL)
*value++ = 0;
if (!value || !*value)
{ //Read
if (sscanf(this_char, "%d", &(rfId)) == 1)
{
if (rfId <= 31)
{
// In RT2860 ATE mode, we do not load 8051 firmware.
//We must access RF directly.
// For RT2870 ATE mode, ATE_RF_IO_WRITE8(/READ8)_BY_REG_ID are redefined.
#ifdef RALINK_ATE
if (ATE_ON(pAdapter))
{
ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
}
else
#endif // RALINK_ATE //
// according to Andy, Gary, David require.
// the command rf shall read rf register directly for dubug.
// BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
RT30xxReadRFRegister(pAdapter, rfId, &regRF);
sprintf(msg+strlen(msg), "R%02d[0x%02x]:%02X ", rfId, rfId*2, regRF);
}
else
{//Invalid parametes, so default printk all RF
bIsPrintAllRF = TRUE;
goto next;
}
}
else
{ //Invalid parametes, so default printk all RF
bIsPrintAllRF = TRUE;
goto next;
}
}
else
{ //Write
if ((sscanf(this_char, "%d", &(rfId)) == 1) && (sscanf(value, "%lx", &(rfValue)) == 1))
{
if (rfId <= 31)
{
// In RT2860 ATE mode, we do not load 8051 firmware.
// We should access RF registers directly.
// For RT2870 ATE mode, ATE_RF_IO_WRITE8/READ8_BY_REG_ID are redefined.
#ifdef RALINK_ATE
if (ATE_ON(pAdapter))
{
ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
ATE_RF_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)rfId,(UCHAR) rfValue);
//Read it back for showing
ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
sprintf(msg+strlen(msg), "R%02d[0x%02X]:%02X\n", rfId, rfId*2, regRF);
}
else
#endif // RALINK_ATE //
{
// according to Andy, Gary, David require.
// the command RF shall read/write RF register directly for dubug.
//BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
//BBP_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)bbpId,(UCHAR) bbpValue);
RT30xxReadRFRegister(pAdapter, rfId, &regRF);
RT30xxWriteRFRegister(pAdapter, (UCHAR)rfId,(UCHAR) rfValue);
//Read it back for showing
//BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
RT30xxReadRFRegister(pAdapter, rfId, &regRF);
sprintf(msg+strlen(msg), "R%02d[0x%02X]:%02X\n", rfId, rfId*2, regRF);
}
}
else
{//Invalid parametes, so default printk all RF
bIsPrintAllRF = TRUE;
}
}
else
{ //Invalid parametes, so default printk all RF
bIsPrintAllRF = TRUE;
}
}
}
else
bIsPrintAllRF = TRUE;
next:
if (bIsPrintAllRF)
{
memset(msg, 0x00, 2048);
sprintf(msg, "\n");
for (rfId = 0; rfId <= 31; rfId++)
{
// In RT2860 ATE mode, we do not load 8051 firmware.
// We should access RF registers directly.
// For RT2870 ATE mode, ATE_RF_IO_WRITE8/READ8_BY_REG_ID are redefined.
#ifdef RALINK_ATE
if (ATE_ON(pAdapter))
{
ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
}
else
#endif // RALINK_ATE //
// according to Andy, Gary, David require.
// the command RF shall read/write RF register directly for dubug.
RT30xxReadRFRegister(pAdapter, rfId, &regRF);
sprintf(msg+strlen(msg), "%03d = %02X\n", rfId, regRF);
}
// Copy the information into the user buffer
DBGPRINT(RT_DEBUG_TRACE, ("strlen(msg)=%d\n", (UINT32)strlen(msg)));
wrq->u.data.length = strlen(msg);
if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
{
DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
}
}
else
{
if(strlen(msg) == 1)
sprintf(msg+strlen(msg), "===>Error command format!");
DBGPRINT(RT_DEBUG_TRACE, ("copy to user [msg=%s]\n", msg));
// Copy the information into the user buffer
DBGPRINT(RT_DEBUG_TRACE, ("strlen(msg) =%d\n", (UINT32)strlen(msg)));
// Copy the information into the user buffer
wrq->u.data.length = strlen(msg);
Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
}
DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlRF\n\n"));
}
#endif // RT30xx //
#endif // DBG //
INT Set_TGnWifiTest_Proc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg)
{
if (simple_strtol(arg, 0, 10) == 0)
pAd->StaCfg.bTGnWifiTest = FALSE;
else
pAd->StaCfg.bTGnWifiTest = TRUE;
DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
return TRUE;
}
INT Set_LongRetryLimit_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg)
{
TX_RTY_CFG_STRUC tx_rty_cfg;
UCHAR LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
return TRUE;
}
INT Set_ShortRetryLimit_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg)
{
TX_RTY_CFG_STRUC tx_rty_cfg;
UCHAR ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
return TRUE;
}
#ifdef EXT_BUILD_CHANNEL_LIST
INT Set_Ieee80211dClientMode_Proc(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR arg)
{
if (simple_strtol(arg, 0, 10) == 0)
pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
else if (simple_strtol(arg, 0, 10) == 1)
pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Flexible;
else if (simple_strtol(arg, 0, 10) == 2)
pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Strict;
else
return FALSE;
DBGPRINT(RT_DEBUG_TRACE, ("Set_Ieee802dMode_Proc::(IEEEE0211dMode=%d)\n", pAdapter->StaCfg.IEEE80211dClientMode));
return TRUE;
}
#endif // EXT_BUILD_CHANNEL_LIST //
#ifdef CARRIER_DETECTION_SUPPORT
INT Set_CarrierDetect_Proc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg)
{
if (simple_strtol(arg, 0, 10) == 0)
pAd->CommonCfg.CarrierDetect.Enable = FALSE;
else
pAd->CommonCfg.CarrierDetect.Enable = TRUE;
DBGPRINT(RT_DEBUG_TRACE, ("IF Set_CarrierDetect_Proc::(CarrierDetect.Enable=%d)\n", pAd->CommonCfg.CarrierDetect.Enable));
return TRUE;
}
#endif // CARRIER_DETECTION_SUPPORT //