linux/drivers/staging/rt2860/sta_ioctl.c
<<
>>
Prefs
   1/*
   2 *************************************************************************
   3 * Ralink Tech Inc.
   4 * 5F., No.36, Taiyuan St., Jhubei City,
   5 * Hsinchu County 302,
   6 * Taiwan, R.O.C.
   7 *
   8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
   9 *
  10 * This program is free software; you can redistribute it and/or modify  *
  11 * it under the terms of the GNU General Public License as published by  *
  12 * the Free Software Foundation; either version 2 of the License, or     *
  13 * (at your option) any later version.                                   *
  14 *                                                                       *
  15 * This program is distributed in the hope that it will be useful,       *
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  18 * GNU General Public License for more details.                          *
  19 *                                                                       *
  20 * You should have received a copy of the GNU General Public License     *
  21 * along with this program; if not, write to the                         *
  22 * Free Software Foundation, Inc.,                                       *
  23 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  24 *                                                                       *
  25 *************************************************************************
  26
  27    Module Name:
  28    sta_ioctl.c
  29
  30    Abstract:
  31    IOCTL related subroutines
  32
  33    Revision History:
  34    Who         When          What
  35    --------    ----------    ----------------------------------------------
  36    Rory Chen   01-03-2003    created
  37        Rory Chen   02-14-2005    modify to support RT61
  38*/
  39
  40#include        "rt_config.h"
  41
  42#ifdef DBG
  43extern ULONG    RTDebugLevel;
  44#endif
  45
  46#define NR_WEP_KEYS                             4
  47#define WEP_SMALL_KEY_LEN                       (40/8)
  48#define WEP_LARGE_KEY_LEN                       (104/8)
  49
  50#define GROUP_KEY_NO                4
  51
  52extern UCHAR    CipherWpa2Template[];
  53extern UCHAR    CipherWpaPskTkip[];
  54extern UCHAR    CipherWpaPskTkipLen;
  55
  56typedef struct PACKED _RT_VERSION_INFO{
  57    UCHAR       DriverVersionW;
  58    UCHAR       DriverVersionX;
  59    UCHAR       DriverVersionY;
  60    UCHAR       DriverVersionZ;
  61    UINT        DriverBuildYear;
  62    UINT        DriverBuildMonth;
  63    UINT        DriverBuildDay;
  64} RT_VERSION_INFO, *PRT_VERSION_INFO;
  65
  66struct iw_priv_args privtab[] = {
  67{ RTPRIV_IOCTL_SET,
  68  IW_PRIV_TYPE_CHAR | 1024, 0,
  69  "set"},
  70
  71{ RTPRIV_IOCTL_SHOW, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
  72  ""},
  73{ RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
  74  ""},
  75/* --- sub-ioctls definitions --- */
  76    { SHOW_CONN_STATUS,
  77          0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" },
  78        { SHOW_DRVIER_VERION,
  79          0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" },
  80    { SHOW_BA_INFO,
  81          0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" },
  82        { SHOW_DESC_INFO,
  83          0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" },
  84    { RAIO_OFF,
  85          0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" },
  86        { RAIO_ON,
  87          0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
  88        { SHOW_CFG_VALUE,
  89          IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" },
  90/* --- sub-ioctls relations --- */
  91
  92{ RTPRIV_IOCTL_STATISTICS,
  93  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
  94  "stat"},
  95{ RTPRIV_IOCTL_GSITESURVEY,
  96  0, IW_PRIV_TYPE_CHAR | 1024,
  97  "get_site_survey"},
  98};
  99
 100INT Set_SSID_Proc(
 101    IN  PRTMP_ADAPTER   pAdapter,
 102    IN  PUCHAR          arg);
 103
 104#ifdef WMM_SUPPORT
 105INT     Set_WmmCapable_Proc(
 106        IN      PRTMP_ADAPTER   pAd,
 107        IN      PUCHAR                  arg);
 108#endif
 109
 110INT Set_NetworkType_Proc(
 111    IN  PRTMP_ADAPTER   pAdapter,
 112    IN  PUCHAR          arg);
 113
 114INT Set_AuthMode_Proc(
 115    IN  PRTMP_ADAPTER   pAdapter,
 116    IN  PUCHAR          arg);
 117
 118INT Set_EncrypType_Proc(
 119    IN  PRTMP_ADAPTER   pAdapter,
 120    IN  PUCHAR          arg);
 121
 122INT Set_DefaultKeyID_Proc(
 123    IN  PRTMP_ADAPTER   pAdapter,
 124    IN  PUCHAR          arg);
 125
 126INT Set_Key1_Proc(
 127    IN  PRTMP_ADAPTER   pAdapter,
 128    IN  PUCHAR          arg);
 129
 130INT Set_Key2_Proc(
 131    IN  PRTMP_ADAPTER   pAdapter,
 132    IN  PUCHAR          arg);
 133
 134INT Set_Key3_Proc(
 135    IN  PRTMP_ADAPTER   pAdapter,
 136    IN  PUCHAR          arg);
 137
 138INT Set_Key4_Proc(
 139    IN  PRTMP_ADAPTER   pAdapter,
 140    IN  PUCHAR          arg);
 141
 142INT Set_WPAPSK_Proc(
 143    IN  PRTMP_ADAPTER   pAdapter,
 144    IN  PUCHAR          arg);
 145
 146
 147INT Set_PSMode_Proc(
 148    IN  PRTMP_ADAPTER   pAdapter,
 149    IN  PUCHAR          arg);
 150
 151INT Set_Wpa_Support(
 152    IN  PRTMP_ADAPTER   pAd,
 153        IN      PUCHAR                  arg);
 154
 155NDIS_STATUS RTMPWPANoneAddKeyProc(
 156    IN  PRTMP_ADAPTER   pAd,
 157    IN  PVOID                   pBuf);
 158
 159INT Set_FragTest_Proc(
 160    IN  PRTMP_ADAPTER   pAdapter,
 161    IN  PUCHAR          arg);
 162
 163INT Set_TGnWifiTest_Proc(
 164    IN  PRTMP_ADAPTER   pAd,
 165    IN  PUCHAR          arg);
 166
 167INT Set_LongRetryLimit_Proc(
 168        IN      PRTMP_ADAPTER   pAdapter,
 169        IN      PUCHAR                  arg);
 170
 171INT Set_ShortRetryLimit_Proc(
 172        IN      PRTMP_ADAPTER   pAdapter,
 173        IN      PUCHAR                  arg);
 174
 175static struct {
 176        CHAR *name;
 177        INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
 178} *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = {
 179        {"DriverVersion",                               Set_DriverVersion_Proc},
 180        {"CountryRegion",                               Set_CountryRegion_Proc},
 181        {"CountryRegionABand",                  Set_CountryRegionABand_Proc},
 182        {"SSID",                                                Set_SSID_Proc},
 183        {"WirelessMode",                                Set_WirelessMode_Proc},
 184        {"TxBurst",                                     Set_TxBurst_Proc},
 185        {"TxPreamble",                          Set_TxPreamble_Proc},
 186        {"TxPower",                                     Set_TxPower_Proc},
 187        {"Channel",                                     Set_Channel_Proc},
 188        {"BGProtection",                                Set_BGProtection_Proc},
 189        {"RTSThreshold",                                Set_RTSThreshold_Proc},
 190        {"FragThreshold",                               Set_FragThreshold_Proc},
 191        {"HtBw",                                Set_HtBw_Proc},
 192        {"HtMcs",                               Set_HtMcs_Proc},
 193        {"HtGi",                                Set_HtGi_Proc},
 194        {"HtOpMode",                        Set_HtOpMode_Proc},
 195        {"HtExtcha",                        Set_HtExtcha_Proc},
 196        {"HtMpduDensity",                       Set_HtMpduDensity_Proc},
 197        {"HtBaWinSize",                         Set_HtBaWinSize_Proc},
 198        {"HtRdg",                                       Set_HtRdg_Proc},
 199        {"HtAmsdu",                                     Set_HtAmsdu_Proc},
 200        {"HtAutoBa",                            Set_HtAutoBa_Proc},
 201        {"HtBaDecline",                                 Set_BADecline_Proc},
 202        {"HtProtect",                           Set_HtProtect_Proc},
 203        {"HtMimoPs",                            Set_HtMimoPs_Proc},
 204#ifdef AGGREGATION_SUPPORT
 205        {"PktAggregate",                                Set_PktAggregate_Proc},
 206#endif
 207
 208#ifdef WMM_SUPPORT
 209        {"WmmCapable",                                  Set_WmmCapable_Proc},
 210#endif
 211        {"IEEE80211H",                                  Set_IEEE80211H_Proc},
 212    {"NetworkType",                 Set_NetworkType_Proc},
 213        {"AuthMode",                                    Set_AuthMode_Proc},
 214        {"EncrypType",                                  Set_EncrypType_Proc},
 215        {"DefaultKeyID",                                Set_DefaultKeyID_Proc},
 216        {"Key1",                                                Set_Key1_Proc},
 217        {"Key2",                                                Set_Key2_Proc},
 218        {"Key3",                                                Set_Key3_Proc},
 219        {"Key4",                                                Set_Key4_Proc},
 220        {"WPAPSK",                                              Set_WPAPSK_Proc},
 221        {"ResetCounter",                                Set_ResetStatCounter_Proc},
 222        {"PSMode",                      Set_PSMode_Proc},
 223#ifdef DBG
 224        {"Debug",                                               Set_Debug_Proc},
 225#endif
 226    {"WpaSupport",                  Set_Wpa_Support},
 227        {"FixedTxMode",                 Set_FixedTxMode_Proc},
 228    {"TGnWifiTest",                 Set_TGnWifiTest_Proc},
 229    {"ForceGF",                                 Set_ForceGF_Proc},
 230        {"LongRetry",                           Set_LongRetryLimit_Proc},
 231        {"ShortRetry",                          Set_ShortRetryLimit_Proc},
 232#ifdef RT2870
 233        {"efuseFreeNumber",                             set_eFuseGetFreeBlockCount_Proc},
 234        {"efuseDump",                                   set_eFusedump_Proc},
 235        {"efuseLoadFromBin",                            set_eFuseLoadFromBin_Proc},
 236#endif
 237        {NULL,}
 238};
 239
 240
 241VOID RTMPAddKey(
 242        IN      PRTMP_ADAPTER       pAd,
 243        IN      PNDIS_802_11_KEY    pKey)
 244{
 245        ULONG                           KeyIdx;
 246        MAC_TABLE_ENTRY         *pEntry;
 247
 248    DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
 249
 250#ifdef RT2860
 251        RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
 252        if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
 253        {
 254                if (pAd->StaCfg.bRadio == FALSE)
 255                {
 256                        RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
 257                        return;
 258                }
 259                DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n"));
 260                RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
 261                RTMPusecDelay(6000);
 262                pAd->bPCIclkOff = FALSE;
 263        }
 264#endif
 265
 266        if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
 267        {
 268                if (pKey->KeyIndex & 0x80000000)
 269                {
 270                    if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
 271            {
 272                NdisZeroMemory(pAd->StaCfg.PMK, 32);
 273                NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength);
 274                goto end;
 275            }
 276                    // Update PTK
 277                    NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
 278            pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
 279            NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TKIP_EK);
 280
 281            if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
 282            {
 283                NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
 284                NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
 285            }
 286            else
 287            {
 288                NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
 289                NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
 290            }
 291
 292            // Decide its ChiperAlg
 293                if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
 294                        pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
 295                else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
 296                        pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
 297                else
 298                        pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
 299
 300            // Update these related information to MAC_TABLE_ENTRY
 301                pEntry = &pAd->MacTab.Content[BSSID_WCID];
 302            NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TKIP_EK);
 303                NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_RXMICK);
 304                NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_TXMICK);
 305                pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
 306
 307                // Update pairwise key information to ASIC Shared Key Table
 308                AsicAddSharedKeyEntry(pAd,
 309                                                          BSS0,
 310                                                          0,
 311                                                          pAd->SharedKey[BSS0][0].CipherAlg,
 312                                                          pAd->SharedKey[BSS0][0].Key,
 313                                                          pAd->SharedKey[BSS0][0].TxMic,
 314                                                          pAd->SharedKey[BSS0][0].RxMic);
 315
 316                // Update ASIC WCID attribute table and IVEIV table
 317                RTMPAddWcidAttributeEntry(pAd,
 318                                                                  BSS0,
 319                                                                  0,
 320                                                                  pAd->SharedKey[BSS0][0].CipherAlg,
 321                                                                  pEntry);
 322
 323            if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
 324            {
 325                // set 802.1x port control
 326                                STA_PORT_SECURED(pAd);
 327
 328                // Indicate Connected for GUI
 329                pAd->IndicateMediaState = NdisMediaStateConnected;
 330            }
 331                }
 332        else
 333        {
 334            // Update GTK
 335            pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
 336            NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
 337            pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
 338            NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TKIP_EK);
 339
 340            if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
 341            {
 342                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
 343                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
 344            }
 345            else
 346            {
 347                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
 348                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
 349            }
 350
 351            // Update Shared Key CipherAlg
 352                pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
 353                if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
 354                        pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
 355                else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
 356                        pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
 357
 358            // Update group key information to ASIC Shared Key Table
 359                AsicAddSharedKeyEntry(pAd,
 360                                                          BSS0,
 361                                                          pAd->StaCfg.DefaultKeyId,
 362                                                          pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
 363                                                          pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
 364                                                          pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
 365                                                          pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
 366
 367                // Update ASIC WCID attribute table and IVEIV table
 368                RTMPAddWcidAttributeEntry(pAd,
 369                                                                  BSS0,
 370                                                                  pAd->StaCfg.DefaultKeyId,
 371                                                                  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
 372                                                                  NULL);
 373
 374            // set 802.1x port control
 375                        STA_PORT_SECURED(pAd);
 376
 377            // Indicate Connected for GUI
 378            pAd->IndicateMediaState = NdisMediaStateConnected;
 379        }
 380        }
 381        else    // dynamic WEP from wpa_supplicant
 382        {
 383                UCHAR   CipherAlg;
 384        PUCHAR  Key;
 385
 386                if(pKey->KeyLength == 32)
 387                        goto end;
 388
 389                KeyIdx = pKey->KeyIndex & 0x0fffffff;
 390
 391                if (KeyIdx < 4)
 392                {
 393                        // it is a default shared key, for Pairwise key setting
 394                        if (pKey->KeyIndex & 0x80000000)
 395                        {
 396                                pEntry = MacTableLookup(pAd, pKey->BSSID);
 397
 398                                if (pEntry)
 399                                {
 400                                        DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n"));
 401
 402                                        // set key material and key length
 403                                        pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
 404                                        NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
 405
 406                                        // set Cipher type
 407                                        if (pKey->KeyLength == 5)
 408                                                pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
 409                                        else
 410                                                pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
 411
 412                                        // Add Pair-wise key to Asic
 413                                        AsicAddPairwiseKeyEntry(
 414                                                pAd,
 415                                                pEntry->Addr,
 416                                                (UCHAR)pEntry->Aid,
 417                                &pEntry->PairwiseKey);
 418
 419                                        // update WCID attribute table and IVEIV table for this entry
 420                                        RTMPAddWcidAttributeEntry(
 421                                                pAd,
 422                                                BSS0,
 423                                                KeyIdx, // The value may be not zero
 424                                                pEntry->PairwiseKey.CipherAlg,
 425                                                pEntry);
 426
 427                                }
 428                        }
 429                        else
 430            {
 431                                // Default key for tx (shared key)
 432                                pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
 433
 434                                // set key material and key length
 435                                pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
 436                                NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
 437
 438                                // Set Ciper type
 439                                if (pKey->KeyLength == 5)
 440                                        pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64;
 441                                else
 442                                        pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128;
 443
 444                        CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
 445                        Key = pAd->SharedKey[BSS0][KeyIdx].Key;
 446
 447                                // Set Group key material to Asic
 448                        AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
 449
 450                                // Update WCID attribute table and IVEIV table for this group key table
 451                                RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
 452
 453                        }
 454                }
 455        }
 456end:
 457#ifdef RT2860
 458        RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
 459    DBGPRINT(RT_DEBUG_INFO, ("<------ RTMPAddKey\n"));
 460#endif
 461        return;
 462}
 463
 464char * rtstrchr(const char * s, int c)
 465{
 466    for(; *s != (char) c; ++s)
 467        if (*s == '\0')
 468            return NULL;
 469    return (char *) s;
 470}
 471
 472/*
 473This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
 474*/
 475
 476int
 477rt_ioctl_giwname(struct net_device *dev,
 478                   struct iw_request_info *info,
 479                   char *name, char *extra)
 480{
 481//      PRTMP_ADAPTER pAdapter = dev->ml_priv;
 482        strncpy(name, RT28xx_CHIP_NAME " Wireless", IFNAMSIZ);
 483        return 0;
 484}
 485
 486int rt_ioctl_siwfreq(struct net_device *dev,
 487                        struct iw_request_info *info,
 488                        struct iw_freq *freq, char *extra)
 489{
 490        PRTMP_ADAPTER pAdapter = dev->ml_priv;
 491        int     chan = -1;
 492
 493    //check if the interface is down
 494    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
 495    {
 496        DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
 497        return -ENETDOWN;
 498    }
 499
 500
 501        if (freq->e > 1)
 502                return -EINVAL;
 503
 504        if((freq->e == 0) && (freq->m <= 1000))
 505                chan = freq->m; // Setting by channel number
 506        else
 507                MAP_KHZ_TO_CHANNEL_ID( (freq->m /100) , chan); // Setting by frequency - search the table , like 2.412G, 2.422G,
 508
 509    if (ChannelSanity(pAdapter, chan) == TRUE)
 510    {
 511        pAdapter->CommonCfg.Channel = chan;
 512        DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
 513    }
 514    else
 515        return -EINVAL;
 516
 517        return 0;
 518}
 519int rt_ioctl_giwfreq(struct net_device *dev,
 520                   struct iw_request_info *info,
 521                   struct iw_freq *freq, char *extra)
 522{
 523        PRTMP_ADAPTER pAdapter = dev->ml_priv;
 524        UCHAR ch = pAdapter->CommonCfg.Channel;
 525        ULONG   m;
 526
 527        DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq  %d\n", ch));
 528
 529    MAP_CHANNEL_ID_TO_KHZ(ch, m);
 530        freq->m = m * 100;
 531        freq->e = 1;
 532        return 0;
 533}
 534
 535int rt_ioctl_siwmode(struct net_device *dev,
 536                   struct iw_request_info *info,
 537                   __u32 *mode, char *extra)
 538{
 539        PRTMP_ADAPTER pAdapter = dev->ml_priv;
 540
 541        //check if the interface is down
 542    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
 543    {
 544        DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
 545        return -ENETDOWN;
 546    }
 547
 548        switch (*mode)
 549        {
 550                case IW_MODE_ADHOC:
 551                        Set_NetworkType_Proc(pAdapter, "Adhoc");
 552                        break;
 553                case IW_MODE_INFRA:
 554                        Set_NetworkType_Proc(pAdapter, "Infra");
 555                        break;
 556        case IW_MODE_MONITOR:
 557                        Set_NetworkType_Proc(pAdapter, "Monitor");
 558                        break;
 559                default:
 560                        DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
 561                        return -EINVAL;
 562        }
 563
 564        // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
 565        pAdapter->StaCfg.WpaState = SS_NOTUSE;
 566
 567        return 0;
 568}
 569
 570int rt_ioctl_giwmode(struct net_device *dev,
 571                   struct iw_request_info *info,
 572                   __u32 *mode, char *extra)
 573{
 574        PRTMP_ADAPTER pAdapter = dev->ml_priv;
 575
 576        if (ADHOC_ON(pAdapter))
 577                *mode = IW_MODE_ADHOC;
 578    else if (INFRA_ON(pAdapter))
 579                *mode = IW_MODE_INFRA;
 580    else if (MONITOR_ON(pAdapter))
 581    {
 582        *mode = IW_MODE_MONITOR;
 583    }
 584    else
 585        *mode = IW_MODE_AUTO;
 586
 587        DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
 588        return 0;
 589}
 590
 591int rt_ioctl_siwsens(struct net_device *dev,
 592                   struct iw_request_info *info,
 593                   char *name, char *extra)
 594{
 595        PRTMP_ADAPTER pAdapter = dev->ml_priv;
 596
 597        //check if the interface is down
 598        if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
 599        {
 600                DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
 601                return -ENETDOWN;
 602        }
 603
 604        return 0;
 605}
 606
 607int rt_ioctl_giwsens(struct net_device *dev,
 608                   struct iw_request_info *info,
 609                   char *name, char *extra)
 610{
 611        return 0;
 612}
 613
 614int rt_ioctl_giwrange(struct net_device *dev,
 615                   struct iw_request_info *info,
 616                   struct iw_point *data, char *extra)
 617{
 618        PRTMP_ADAPTER pAdapter = dev->ml_priv;
 619        struct iw_range *range = (struct iw_range *) extra;
 620        u16 val;
 621        int i;
 622
 623        DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
 624        data->length = sizeof(struct iw_range);
 625        memset(range, 0, sizeof(struct iw_range));
 626
 627        range->txpower_capa = IW_TXPOW_DBM;
 628
 629        if (INFRA_ON(pAdapter)||ADHOC_ON(pAdapter))
 630        {
 631                range->min_pmp = 1 * 1024;
 632                range->max_pmp = 65535 * 1024;
 633                range->min_pmt = 1 * 1024;
 634                range->max_pmt = 1000 * 1024;
 635                range->pmp_flags = IW_POWER_PERIOD;
 636                range->pmt_flags = IW_POWER_TIMEOUT;
 637                range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
 638                        IW_POWER_UNICAST_R | IW_POWER_ALL_R;
 639        }
 640
 641        range->we_version_compiled = WIRELESS_EXT;
 642        range->we_version_source = 14;
 643
 644        range->retry_capa = IW_RETRY_LIMIT;
 645        range->retry_flags = IW_RETRY_LIMIT;
 646        range->min_retry = 0;
 647        range->max_retry = 255;
 648
 649        range->num_channels =  pAdapter->ChannelListNum;
 650
 651        val = 0;
 652        for (i = 1; i <= range->num_channels; i++)
 653        {
 654                u32 m;
 655                range->freq[val].i = pAdapter->ChannelList[i-1].Channel;
 656                MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m);
 657                range->freq[val].m = m * 100; /* HZ */
 658
 659                range->freq[val].e = 1;
 660                val++;
 661                if (val == IW_MAX_FREQUENCIES)
 662                        break;
 663        }
 664        range->num_frequency = val;
 665
 666        range->max_qual.qual = 100; /* what is correct max? This was not
 667                                        * documented exactly. At least
 668                                        * 69 has been observed. */
 669        range->max_qual.level = 0; /* dB */
 670        range->max_qual.noise = 0; /* dB */
 671
 672        /* What would be suitable values for "average/typical" qual? */
 673        range->avg_qual.qual = 20;
 674        range->avg_qual.level = -60;
 675        range->avg_qual.noise = -95;
 676        range->sensitivity = 3;
 677
 678        range->max_encoding_tokens = NR_WEP_KEYS;
 679        range->num_encoding_sizes = 2;
 680        range->encoding_size[0] = 5;
 681        range->encoding_size[1] = 13;
 682
 683        range->min_rts = 0;
 684        range->max_rts = 2347;
 685        range->min_frag = 256;
 686        range->max_frag = 2346;
 687
 688        /* IW_ENC_CAPA_* bit field */
 689        range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
 690                                        IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
 691
 692        return 0;
 693}
 694
 695int rt_ioctl_siwap(struct net_device *dev,
 696                      struct iw_request_info *info,
 697                      struct sockaddr *ap_addr, char *extra)
 698{
 699        PRTMP_ADAPTER pAdapter = dev->ml_priv;
 700    NDIS_802_11_MAC_ADDRESS Bssid;
 701
 702        //check if the interface is down
 703        if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
 704        {
 705        DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
 706        return -ENETDOWN;
 707    }
 708
 709        if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
 710    {
 711        RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
 712        DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
 713    }
 714
 715    // tell CNTL state machine to call NdisMSetInformationComplete() after completing
 716    // this request, because this request is initiated by NDIS.
 717    pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
 718        // Prevent to connect AP again in STAMlmePeriodicExec
 719        pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
 720
 721    memset(Bssid, 0, MAC_ADDR_LEN);
 722    memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
 723    MlmeEnqueue(pAdapter,
 724                MLME_CNTL_STATE_MACHINE,
 725                OID_802_11_BSSID,
 726                sizeof(NDIS_802_11_MAC_ADDRESS),
 727                (VOID *)&Bssid);
 728
 729    DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n",
 730        Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
 731
 732        return 0;
 733}
 734
 735int rt_ioctl_giwap(struct net_device *dev,
 736                      struct iw_request_info *info,
 737                      struct sockaddr *ap_addr, char *extra)
 738{
 739        PRTMP_ADAPTER pAdapter = dev->ml_priv;
 740
 741        if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
 742        {
 743                ap_addr->sa_family = ARPHRD_ETHER;
 744                memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
 745        }
 746    // Add for RT2870
 747    else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
 748    {
 749        ap_addr->sa_family = ARPHRD_ETHER;
 750        memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
 751    }
 752        else
 753        {
 754                DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
 755                return -ENOTCONN;
 756        }
 757
 758        return 0;
 759}
 760
 761/*
 762 * Units are in db above the noise floor. That means the
 763 * rssi values reported in the tx/rx descriptors in the
 764 * driver are the SNR expressed in db.
 765 *
 766 * If you assume that the noise floor is -95, which is an
 767 * excellent assumption 99.5 % of the time, then you can
 768 * derive the absolute signal level (i.e. -95 + rssi).
 769 * There are some other slight factors to take into account
 770 * depending on whether the rssi measurement is from 11b,
 771 * 11g, or 11a.   These differences are at most 2db and
 772 * can be documented.
 773 *
 774 * NB: various calculations are based on the orinoco/wavelan
 775 *     drivers for compatibility
 776 */
 777static void set_quality(PRTMP_ADAPTER pAdapter,
 778                        struct iw_quality *iq,
 779                        signed char rssi)
 780{
 781        __u8 ChannelQuality;
 782
 783        // Normalize Rssi
 784        if (rssi >= -50)
 785                ChannelQuality = 100;
 786        else if (rssi >= -80) // between -50 ~ -80dbm
 787                ChannelQuality = (__u8)(24 + ((rssi + 80) * 26)/10);
 788        else if (rssi >= -90)   // between -80 ~ -90dbm
 789        ChannelQuality = (__u8)((rssi + 90) * 26)/10;
 790        else
 791                ChannelQuality = 0;
 792
 793    iq->qual = (__u8)ChannelQuality;
 794
 795    iq->level = (__u8)(rssi);
 796    iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8)pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]);         // noise level (dBm)
 797    iq->noise += 256 - 143;
 798    iq->updated = pAdapter->iw_stats.qual.updated;
 799}
 800
 801int rt_ioctl_iwaplist(struct net_device *dev,
 802                        struct iw_request_info *info,
 803                        struct iw_point *data, char *extra)
 804{
 805        PRTMP_ADAPTER pAdapter = dev->ml_priv;
 806
 807        struct sockaddr addr[IW_MAX_AP];
 808        struct iw_quality qual[IW_MAX_AP];
 809        int i;
 810
 811        //check if the interface is down
 812    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
 813    {
 814        DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
 815                data->length = 0;
 816                return 0;
 817        //return -ENETDOWN;
 818        }
 819
 820        for (i = 0; i <IW_MAX_AP ; i++)
 821        {
 822                if (i >=  pAdapter->ScanTab.BssNr)
 823                        break;
 824                addr[i].sa_family = ARPHRD_ETHER;
 825                        memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
 826                set_quality(pAdapter, &qual[i], pAdapter->ScanTab.BssEntry[i].Rssi);
 827        }
 828        data->length = i;
 829        memcpy(extra, &addr, i*sizeof(addr[0]));
 830        data->flags = 1;                /* signal quality present (sort of) */
 831        memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i]));
 832
 833        return 0;
 834}
 835
 836int rt_ioctl_siwscan(struct net_device *dev,
 837                        struct iw_request_info *info,
 838                        struct iw_point *data, char *extra)
 839{
 840        PRTMP_ADAPTER pAdapter = dev->ml_priv;
 841
 842        ULONG                                                           Now;
 843        int Status = NDIS_STATUS_SUCCESS;
 844
 845        //check if the interface is down
 846        if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
 847        {
 848                DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
 849                return -ENETDOWN;
 850        }
 851
 852        if (MONITOR_ON(pAdapter))
 853    {
 854        DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
 855        return -EINVAL;
 856    }
 857#ifdef RT2860
 858        if ((pAdapter->OpMode == OPMODE_STA) && (IDLE_ON(pAdapter))
 859                && (pAdapter->StaCfg.bRadio == TRUE)
 860                && (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
 861        {
 862                RT28xxPciAsicRadioOn(pAdapter, GUI_IDLE_POWER_SAVE);
 863        }
 864        // Check if still radio off.
 865        else if (pAdapter->bPCIclkOff == TRUE)
 866                return 0;
 867#endif
 868        if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
 869        {
 870                pAdapter->StaCfg.WpaSupplicantScanCount++;
 871        }
 872
 873    pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
 874        if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
 875                return 0;
 876        do{
 877                Now = jiffies;
 878
 879                if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
 880                        (pAdapter->StaCfg.WpaSupplicantScanCount > 3))
 881                {
 882                        DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n"));
 883                        Status = NDIS_STATUS_SUCCESS;
 884                        break;
 885                }
 886
 887                if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
 888                        ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
 889                        (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
 890                        (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
 891                {
 892                        DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
 893                        Status = NDIS_STATUS_SUCCESS;
 894                        break;
 895                }
 896
 897                if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
 898                {
 899                        RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
 900                        DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
 901                }
 902
 903                // tell CNTL state machine to call NdisMSetInformationComplete() after completing
 904                // this request, because this request is initiated by NDIS.
 905                pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
 906                // Reset allowed scan retries
 907                pAdapter->StaCfg.ScanCnt = 0;
 908                pAdapter->StaCfg.LastScanTime = Now;
 909
 910                MlmeEnqueue(pAdapter,
 911                        MLME_CNTL_STATE_MACHINE,
 912                        OID_802_11_BSSID_LIST_SCAN,
 913                        0,
 914                        NULL);
 915
 916                Status = NDIS_STATUS_SUCCESS;
 917                RT28XX_MLME_HANDLER(pAdapter);
 918        }while(0);
 919        return 0;
 920}
 921
 922int rt_ioctl_giwscan(struct net_device *dev,
 923                        struct iw_request_info *info,
 924                        struct iw_point *data, char *extra)
 925{
 926
 927        PRTMP_ADAPTER pAdapter = dev->ml_priv;
 928        int i=0;
 929        char *current_ev = extra, *previous_ev = extra;
 930        char *end_buf;
 931        char *current_val, custom[MAX_CUSTOM_LEN] = {0};
 932        struct iw_event iwe;
 933
 934        if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
 935    {
 936                /*
 937                 * Still scanning, indicate the caller should try again.
 938                 */
 939                return -EAGAIN;
 940        }
 941
 942        if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
 943        {
 944                pAdapter->StaCfg.WpaSupplicantScanCount = 0;
 945        }
 946
 947        if (pAdapter->ScanTab.BssNr == 0)
 948        {
 949                data->length = 0;
 950                return 0;
 951        }
 952
 953    if (data->length > 0)
 954        end_buf = extra + data->length;
 955    else
 956        end_buf = extra + IW_SCAN_MAX_DATA;
 957
 958        for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
 959        {
 960                if (current_ev >= end_buf)
 961                        return -E2BIG;
 962
 963                //MAC address
 964                //================================
 965                memset(&iwe, 0, sizeof(iwe));
 966                iwe.cmd = SIOCGIWAP;
 967                iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
 968                memcpy(iwe.u.ap_addr.sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
 969
 970        previous_ev = current_ev;
 971                current_ev = iwe_stream_add_event(info, current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
 972        if (current_ev == previous_ev)
 973                return -E2BIG;
 974
 975                /*
 976                Protocol:
 977                        it will show scanned AP's WirelessMode .
 978                        it might be
 979                                        802.11a
 980                                        802.11a/n
 981                                        802.11g/n
 982                                        802.11b/g/n
 983                                        802.11g
 984                                        802.11b/g
 985                */
 986                memset(&iwe, 0, sizeof(iwe));
 987                iwe.cmd = SIOCGIWNAME;
 988
 989
 990        {
 991                PBSS_ENTRY pBssEntry=&pAdapter->ScanTab.BssEntry[i];
 992                BOOLEAN isGonly=FALSE;
 993                int rateCnt=0;
 994
 995                if (pBssEntry->Channel>14)
 996                {
 997                        if (pBssEntry->HtCapabilityLen!=0)
 998                                strcpy(iwe.u.name,"802.11a/n");
 999                        else
1000                                strcpy(iwe.u.name,"802.11a");
1001                }
1002                else
1003                {
1004                        /*
1005                                if one of non B mode rate is set supported rate . it mean G only.
1006                        */
1007                        for (rateCnt=0;rateCnt<pBssEntry->SupRateLen;rateCnt++)
1008                        {
1009                                /*
1010                                        6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only.
1011                                */
1012                                if (pBssEntry->SupRate[rateCnt]==140 || pBssEntry->SupRate[rateCnt]==146 || pBssEntry->SupRate[rateCnt]>=152)
1013                                        isGonly=TRUE;
1014                        }
1015
1016                        for (rateCnt=0;rateCnt<pBssEntry->ExtRateLen;rateCnt++)
1017                        {
1018                                if (pBssEntry->ExtRate[rateCnt]==140 || pBssEntry->ExtRate[rateCnt]==146 || pBssEntry->ExtRate[rateCnt]>=152)
1019                                        isGonly=TRUE;
1020                        }
1021
1022
1023                        if (pBssEntry->HtCapabilityLen!=0)
1024                        {
1025                                if (isGonly==TRUE)
1026                                        strcpy(iwe.u.name,"802.11g/n");
1027                                else
1028                                        strcpy(iwe.u.name,"802.11b/g/n");
1029                        }
1030                        else
1031                        {
1032                                if (isGonly==TRUE)
1033                                        strcpy(iwe.u.name,"802.11g");
1034                                else
1035                                {
1036                                        if (pBssEntry->SupRateLen==4 && pBssEntry->ExtRateLen==0)
1037                                                strcpy(iwe.u.name,"802.11b");
1038                                        else
1039                                                strcpy(iwe.u.name,"802.11b/g");
1040                                }
1041                        }
1042                }
1043        }
1044
1045                previous_ev = current_ev;
1046                current_ev       = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
1047        if (current_ev == previous_ev)
1048                return -E2BIG;
1049
1050                //ESSID
1051                //================================
1052                memset(&iwe, 0, sizeof(iwe));
1053                iwe.cmd = SIOCGIWESSID;
1054                iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
1055                iwe.u.data.flags = 1;
1056
1057        previous_ev = current_ev;
1058                current_ev = iwe_stream_add_point(info, current_ev,end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid);
1059        if (current_ev == previous_ev)
1060                return -E2BIG;
1061
1062                //Network Type
1063                //================================
1064                memset(&iwe, 0, sizeof(iwe));
1065                iwe.cmd = SIOCGIWMODE;
1066                if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
1067                {
1068                        iwe.u.mode = IW_MODE_ADHOC;
1069                }
1070                else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
1071                {
1072                        iwe.u.mode = IW_MODE_INFRA;
1073                }
1074                else
1075                {
1076                        iwe.u.mode = IW_MODE_AUTO;
1077                }
1078                iwe.len = IW_EV_UINT_LEN;
1079
1080        previous_ev = current_ev;
1081                current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,  IW_EV_UINT_LEN);
1082        if (current_ev == previous_ev)
1083                return -E2BIG;
1084
1085                //Channel and Frequency
1086                //================================
1087                memset(&iwe, 0, sizeof(iwe));
1088                iwe.cmd = SIOCGIWFREQ;
1089                if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
1090                        iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1091                else
1092                        iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1093                iwe.u.freq.e = 0;
1094                iwe.u.freq.i = 0;
1095
1096                previous_ev = current_ev;
1097                current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
1098        if (current_ev == previous_ev)
1099                return -E2BIG;
1100
1101        //Add quality statistics
1102        //================================
1103        memset(&iwe, 0, sizeof(iwe));
1104        iwe.cmd = IWEVQUAL;
1105        iwe.u.qual.level = 0;
1106        iwe.u.qual.noise = 0;
1107        set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
1108        current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
1109        if (current_ev == previous_ev)
1110                return -E2BIG;
1111
1112                //Encyption key
1113                //================================
1114                memset(&iwe, 0, sizeof(iwe));
1115                iwe.cmd = SIOCGIWENCODE;
1116                if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
1117                        iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1118                else
1119                        iwe.u.data.flags = IW_ENCODE_DISABLED;
1120
1121        previous_ev = current_ev;
1122        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);
1123        if (current_ev == previous_ev)
1124                return -E2BIG;
1125
1126                //Bit Rate
1127                //================================
1128                if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
1129        {
1130            UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
1131                        memset(&iwe, 0, sizeof(iwe));
1132                        iwe.cmd = SIOCGIWRATE;
1133                current_val = current_ev + IW_EV_LCP_LEN;
1134            if (tmpRate == 0x82)
1135                iwe.u.bitrate.value =  1 * 1000000;
1136            else if (tmpRate == 0x84)
1137                iwe.u.bitrate.value =  2 * 1000000;
1138            else if (tmpRate == 0x8B)
1139                iwe.u.bitrate.value =  5.5 * 1000000;
1140            else if (tmpRate == 0x96)
1141                iwe.u.bitrate.value =  11 * 1000000;
1142            else
1143                    iwe.u.bitrate.value =  (tmpRate/2) * 1000000;
1144
1145                        iwe.u.bitrate.disabled = 0;
1146                        current_val = iwe_stream_add_value(info, current_ev,
1147                                current_val, end_buf, &iwe,
1148                        IW_EV_PARAM_LEN);
1149
1150                if((current_val-current_ev)>IW_EV_LCP_LEN)
1151                current_ev = current_val;
1152                else
1153                        return -E2BIG;
1154        }
1155
1156                //WPA IE
1157                if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1158                {
1159                        memset(&iwe, 0, sizeof(iwe));
1160                        memset(&custom[0], 0, MAX_CUSTOM_LEN);
1161                        memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
1162                                                   pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
1163                        iwe.cmd = IWEVGENIE;
1164                        iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
1165                        current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
1166                        if (current_ev == previous_ev)
1167                                return -E2BIG;
1168                }
1169
1170                //WPA2 IE
1171        if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1172        {
1173                memset(&iwe, 0, sizeof(iwe));
1174                        memset(&custom[0], 0, MAX_CUSTOM_LEN);
1175                        memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
1176                                                   pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
1177                        iwe.cmd = IWEVGENIE;
1178                        iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
1179                        current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
1180                        if (current_ev == previous_ev)
1181                                return -E2BIG;
1182        }
1183        }
1184
1185        data->length = current_ev - extra;
1186    pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
1187        DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
1188        return 0;
1189}
1190
1191int rt_ioctl_siwessid(struct net_device *dev,
1192                         struct iw_request_info *info,
1193                         struct iw_point *data, char *essid)
1194{
1195        PRTMP_ADAPTER pAdapter = dev->ml_priv;
1196
1197        //check if the interface is down
1198    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1199    {
1200        DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1201        return -ENETDOWN;
1202    }
1203
1204        if (data->flags)
1205        {
1206                PCHAR   pSsidString = NULL;
1207
1208                // Includes null character.
1209                if (data->length > (IW_ESSID_MAX_SIZE + 1))
1210                        return -E2BIG;
1211
1212                pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
1213                if (pSsidString)
1214                {
1215                        NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
1216                        NdisMoveMemory(pSsidString, essid, data->length);
1217                        if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
1218                                return -EINVAL;
1219                }
1220                else
1221                        return -ENOMEM;
1222        }
1223        else
1224        {
1225                // ANY ssid
1226                if (Set_SSID_Proc(pAdapter, "") == FALSE)
1227                        return -EINVAL;
1228    }
1229        return 0;
1230}
1231
1232int rt_ioctl_giwessid(struct net_device *dev,
1233                         struct iw_request_info *info,
1234                         struct iw_point *data, char *essid)
1235{
1236        PRTMP_ADAPTER pAdapter = dev->ml_priv;
1237
1238        data->flags = 1;
1239    if (MONITOR_ON(pAdapter))
1240    {
1241        data->length  = 0;
1242        return 0;
1243    }
1244
1245        if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
1246        {
1247                DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
1248                data->length = pAdapter->CommonCfg.SsidLen;
1249                memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1250        }
1251#ifdef RT2870
1252    // Add for RT2870
1253    else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1254    {
1255        data->length = pAdapter->CommonCfg.SsidLen;
1256                memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1257        }
1258#endif // RT2870 //
1259        else
1260        {//the ANY ssid was specified
1261                data->length  = 0;
1262                DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
1263        }
1264
1265        return 0;
1266
1267}
1268
1269int rt_ioctl_siwnickn(struct net_device *dev,
1270                         struct iw_request_info *info,
1271                         struct iw_point *data, char *nickname)
1272{
1273        PRTMP_ADAPTER pAdapter = dev->ml_priv;
1274
1275    //check if the interface is down
1276    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1277    {
1278        DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
1279        return -ENETDOWN;
1280    }
1281
1282        if (data->length > IW_ESSID_MAX_SIZE)
1283                return -EINVAL;
1284
1285        memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
1286        memcpy(pAdapter->nickname, nickname, data->length);
1287
1288
1289        return 0;
1290}
1291
1292int rt_ioctl_giwnickn(struct net_device *dev,
1293                         struct iw_request_info *info,
1294                         struct iw_point *data, char *nickname)
1295{
1296        PRTMP_ADAPTER pAdapter = dev->ml_priv;
1297
1298        if (data->length > strlen(pAdapter->nickname) + 1)
1299                data->length = strlen(pAdapter->nickname) + 1;
1300        if (data->length > 0) {
1301                memcpy(nickname, pAdapter->nickname, data->length-1);
1302                nickname[data->length-1] = '\0';
1303        }
1304        return 0;
1305}
1306
1307int rt_ioctl_siwrts(struct net_device *dev,
1308                       struct iw_request_info *info,
1309                       struct iw_param *rts, char *extra)
1310{
1311        PRTMP_ADAPTER pAdapter = dev->ml_priv;
1312        u16 val;
1313
1314    //check if the interface is down
1315    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1316    {
1317        DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1318        return -ENETDOWN;
1319    }
1320
1321        if (rts->disabled)
1322                val = MAX_RTS_THRESHOLD;
1323        else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
1324                return -EINVAL;
1325        else if (rts->value == 0)
1326            val = MAX_RTS_THRESHOLD;
1327        else
1328                val = rts->value;
1329
1330        if (val != pAdapter->CommonCfg.RtsThreshold)
1331                pAdapter->CommonCfg.RtsThreshold = val;
1332
1333        return 0;
1334}
1335
1336int rt_ioctl_giwrts(struct net_device *dev,
1337                       struct iw_request_info *info,
1338                       struct iw_param *rts, char *extra)
1339{
1340        PRTMP_ADAPTER pAdapter = dev->ml_priv;
1341
1342        //check if the interface is down
1343        if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1344        {
1345                DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1346                return -ENETDOWN;
1347        }
1348
1349        rts->value = pAdapter->CommonCfg.RtsThreshold;
1350        rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
1351        rts->fixed = 1;
1352
1353        return 0;
1354}
1355
1356int rt_ioctl_siwfrag(struct net_device *dev,
1357                        struct iw_request_info *info,
1358                        struct iw_param *frag, char *extra)
1359{
1360        PRTMP_ADAPTER pAdapter = dev->ml_priv;
1361        u16 val;
1362
1363        //check if the interface is down
1364        if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1365        {
1366                DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1367                return -ENETDOWN;
1368        }
1369
1370        if (frag->disabled)
1371                val = MAX_FRAG_THRESHOLD;
1372        else if (frag->value >= MIN_FRAG_THRESHOLD && frag->value <= MAX_FRAG_THRESHOLD)
1373                val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
1374        else if (frag->value == 0)
1375            val = MAX_FRAG_THRESHOLD;
1376        else
1377                return -EINVAL;
1378
1379        pAdapter->CommonCfg.FragmentThreshold = val;
1380        return 0;
1381}
1382
1383int rt_ioctl_giwfrag(struct net_device *dev,
1384                        struct iw_request_info *info,
1385                        struct iw_param *frag, char *extra)
1386{
1387        PRTMP_ADAPTER pAdapter = dev->ml_priv;
1388
1389        //check if the interface is down
1390        if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1391        {
1392                DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1393                return -ENETDOWN;
1394        }
1395
1396        frag->value = pAdapter->CommonCfg.FragmentThreshold;
1397        frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
1398        frag->fixed = 1;
1399
1400        return 0;
1401}
1402
1403#define MAX_WEP_KEY_SIZE 13
1404#define MIN_WEP_KEY_SIZE 5
1405int rt_ioctl_siwencode(struct net_device *dev,
1406                          struct iw_request_info *info,
1407                          struct iw_point *erq, char *extra)
1408{
1409        PRTMP_ADAPTER pAdapter = dev->ml_priv;
1410
1411        //check if the interface is down
1412        if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1413        {
1414                DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1415                return -ENETDOWN;
1416        }
1417
1418        if ((erq->length == 0) &&
1419        (erq->flags & IW_ENCODE_DISABLED))
1420        {
1421                pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1422                pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1423                pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1424        pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1425        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1426        goto done;
1427        } else if (
1428                 (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN)) {
1429                STA_PORT_SECURED(pAdapter);
1430                pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
1431                pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
1432                pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1433        pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1434                if (erq->flags & IW_ENCODE_RESTRICTED)
1435                        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1436        else
1437                        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1438        }
1439
1440    if (erq->length > 0)
1441        {
1442                int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
1443                /* Check the size of the key */
1444                if (erq->length > MAX_WEP_KEY_SIZE) {
1445                        return -EINVAL;
1446                }
1447                /* Check key index */
1448                if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
1449        {
1450            DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
1451                                        keyIdx, pAdapter->StaCfg.DefaultKeyId));
1452
1453            //Using default key
1454                        keyIdx = pAdapter->StaCfg.DefaultKeyId;
1455        }
1456                else
1457                        pAdapter->StaCfg.DefaultKeyId=keyIdx;
1458
1459        NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
1460
1461                if (erq->length == MAX_WEP_KEY_SIZE)
1462        {
1463                        pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
1464            pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
1465                }
1466                else if (erq->length == MIN_WEP_KEY_SIZE)
1467        {
1468            pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
1469            pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
1470                }
1471                else
1472                        /* Disable the key */
1473                        pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
1474
1475                /* Check if the key is not marked as invalid */
1476                if(!(erq->flags & IW_ENCODE_NOKEY)) {
1477                        /* Copy the key in the driver */
1478                        NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
1479        }
1480        }
1481    else
1482                        {
1483                /* Do we want to just set the transmit key index ? */
1484                int index = (erq->flags & IW_ENCODE_INDEX) - 1;
1485                if ((index >= 0) && (index < 4))
1486        {
1487                        pAdapter->StaCfg.DefaultKeyId = index;
1488            }
1489        else
1490                        /* Don't complain if only change the mode */
1491                        if (!(erq->flags & IW_ENCODE_MODE)) {
1492                                return -EINVAL;
1493                }
1494        }
1495
1496done:
1497    DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
1498        DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
1499        DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
1500        DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
1501        return 0;
1502}
1503
1504int
1505rt_ioctl_giwencode(struct net_device *dev,
1506                          struct iw_request_info *info,
1507                          struct iw_point *erq, char *key)
1508{
1509        PRTMP_ADAPTER pAdapter = dev->ml_priv;
1510        int kid;
1511
1512        //check if the interface is down
1513        if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1514        {
1515                DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1516        return -ENETDOWN;
1517        }
1518
1519        kid = erq->flags & IW_ENCODE_INDEX;
1520        DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
1521
1522        if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
1523        {
1524                erq->length = 0;
1525                erq->flags = IW_ENCODE_DISABLED;
1526        }
1527        else if ((kid > 0) && (kid <=4))
1528        {
1529                // copy wep key
1530                erq->flags = kid ;                      /* NB: base 1 */
1531                if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
1532                        erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
1533                memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
1534                //if ((kid == pAdapter->PortCfg.DefaultKeyId))
1535                //erq->flags |= IW_ENCODE_ENABLED;      /* XXX */
1536                if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1537                        erq->flags |= IW_ENCODE_RESTRICTED;             /* XXX */
1538                else
1539                        erq->flags |= IW_ENCODE_OPEN;           /* XXX */
1540
1541        }
1542        else if (kid == 0)
1543        {
1544                if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1545                        erq->flags |= IW_ENCODE_RESTRICTED;             /* XXX */
1546                else
1547                        erq->flags |= IW_ENCODE_OPEN;           /* XXX */
1548                erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
1549                memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
1550                // copy default key ID
1551                if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1552                        erq->flags |= IW_ENCODE_RESTRICTED;             /* XXX */
1553                else
1554                        erq->flags |= IW_ENCODE_OPEN;           /* XXX */
1555                erq->flags = pAdapter->StaCfg.DefaultKeyId + 1;                 /* NB: base 1 */
1556                erq->flags |= IW_ENCODE_ENABLED;        /* XXX */
1557        }
1558
1559        return 0;
1560
1561}
1562
1563static int
1564rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
1565                         void *w, char *extra)
1566{
1567        PRTMP_ADAPTER pAdapter = dev->ml_priv;
1568        POS_COOKIE pObj = (POS_COOKIE)pAdapter->OS_Cookie;
1569        char *this_char = extra;
1570        char *value;
1571        int  Status=0;
1572
1573        {
1574                pObj->ioctl_if_type = INT_MAIN;
1575        pObj->ioctl_if = MAIN_MBSSID;
1576        }
1577
1578        //check if the interface is down
1579        if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1580        {
1581                DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1582                        return -ENETDOWN;
1583        }
1584
1585        if (!*this_char)
1586                return -EINVAL;
1587
1588        if ((value = rtstrchr(this_char, '=')) != NULL)
1589            *value++ = 0;
1590
1591        if (!value)
1592            return -EINVAL;
1593
1594        // reject setting nothing besides ANY ssid(ssidLen=0)
1595    if (!*value && (strcmp(this_char, "SSID") != 0))
1596        return -EINVAL;
1597
1598        for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
1599        {
1600            if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
1601            {
1602                if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
1603                {       //FALSE:Set private failed then return Invalid argument
1604                            Status = -EINVAL;
1605                }
1606                    break;      //Exit for loop.
1607            }
1608        }
1609
1610        if(PRTMP_PRIVATE_SET_PROC->name == NULL)
1611        {  //Not found argument
1612            Status = -EINVAL;
1613            DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
1614        }
1615
1616    return Status;
1617}
1618
1619
1620static int
1621rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
1622                struct iw_point *wrq, char *extra)
1623{
1624        INT                             Status = 0;
1625    PRTMP_ADAPTER   pAd = dev->ml_priv;
1626
1627    if (extra == NULL)
1628    {
1629        wrq->length = 0;
1630        return -EIO;
1631    }
1632
1633    memset(extra, 0x00, IW_PRIV_SIZE_MASK);
1634    sprintf(extra, "\n\n");
1635
1636        {
1637    sprintf(extra+strlen(extra), "Tx success                      = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
1638    sprintf(extra+strlen(extra), "Tx success without retry        = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1639        }
1640    sprintf(extra+strlen(extra), "Tx success after retry          = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1641    sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry  = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
1642    sprintf(extra+strlen(extra), "RTS Success Rcv CTS             = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
1643    sprintf(extra+strlen(extra), "RTS Fail Rcv CTS                = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
1644
1645    sprintf(extra+strlen(extra), "Rx success                      = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
1646    sprintf(extra+strlen(extra), "Rx with CRC                     = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
1647    sprintf(extra+strlen(extra), "Rx drop due to out of resource  = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
1648    sprintf(extra+strlen(extra), "Rx duplicate frame              = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
1649
1650    sprintf(extra+strlen(extra), "False CCA (one second)          = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
1651        {
1652        sprintf(extra+strlen(extra), "RSSI-A                          = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
1653        sprintf(extra+strlen(extra), "RSSI-B (if available)           = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
1654        sprintf(extra+strlen(extra), "RSSI-C (if available)           = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
1655        }
1656    sprintf(extra+strlen(extra), "WpaSupplicantUP                 = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
1657
1658    wrq->length = strlen(extra) + 1; // 1: size of '\0'
1659    DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
1660
1661    return Status;
1662}
1663
1664void    getBaInfo(
1665        IN      PRTMP_ADAPTER   pAd,
1666        IN      PUCHAR                  pOutBuf)
1667{
1668        INT i, j;
1669        BA_ORI_ENTRY *pOriBAEntry;
1670        BA_REC_ENTRY *pRecBAEntry;
1671
1672        for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
1673        {
1674                PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
1675                if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
1676                        || (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
1677                {
1678                        sprintf(pOutBuf + strlen(pOutBuf), "\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
1679                                pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
1680                                pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
1681
1682                        sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
1683                        for (j=0; j < NUM_OF_TID; j++)
1684                        {
1685                                if (pEntry->BARecWcidArray[j] != 0)
1686                                {
1687                                        pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
1688                                        sprintf(pOutBuf + strlen(pOutBuf), "TID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
1689                                }
1690                        }
1691                        sprintf(pOutBuf, "%s\n", pOutBuf);
1692
1693                        sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
1694                        for (j=0; j < NUM_OF_TID; j++)
1695                        {
1696                                if (pEntry->BAOriWcidArray[j] != 0)
1697                                {
1698                                        pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
1699                                        sprintf(pOutBuf + strlen(pOutBuf), "TID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
1700                                }
1701                        }
1702                        sprintf(pOutBuf, "%s\n\n", pOutBuf);
1703                }
1704        if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
1705                break;
1706        }
1707
1708        return;
1709}
1710
1711static int
1712rt_private_show(struct net_device *dev, struct iw_request_info *info,
1713                struct iw_point *wrq, char *extra)
1714{
1715    INT                         Status = 0;
1716    PRTMP_ADAPTER pAd = dev->ml_priv;
1717    POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
1718    u32             subcmd = wrq->flags;
1719
1720    if (extra == NULL)
1721    {
1722        wrq->length = 0;
1723        return -EIO;
1724    }
1725    memset(extra, 0x00, IW_PRIV_SIZE_MASK);
1726
1727        {
1728                pObj->ioctl_if_type = INT_MAIN;
1729        pObj->ioctl_if = MAIN_MBSSID;
1730        }
1731
1732    switch(subcmd)
1733    {
1734
1735        case SHOW_CONN_STATUS:
1736            if (MONITOR_ON(pAd))
1737            {
1738                if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
1739                    pAd->CommonCfg.RegTransmitSetting.field.BW)
1740                    sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
1741                else
1742                    sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
1743            }
1744            else
1745            {
1746                if (pAd->IndicateMediaState == NdisMediaStateConnected)
1747                {
1748                    if (INFRA_ON(pAd))
1749                    {
1750                    sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
1751                                    pAd->CommonCfg.Ssid,
1752                                    pAd->CommonCfg.Bssid[0],
1753                                    pAd->CommonCfg.Bssid[1],
1754                                    pAd->CommonCfg.Bssid[2],
1755                                    pAd->CommonCfg.Bssid[3],
1756                                    pAd->CommonCfg.Bssid[4],
1757                                    pAd->CommonCfg.Bssid[5]);
1758                        DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
1759                }
1760                    else if (ADHOC_ON(pAd))
1761                        sprintf(extra, "Connected\n");
1762                }
1763                else
1764                {
1765                    sprintf(extra, "Disconnected\n");
1766                        DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
1767                }
1768            }
1769            wrq->length = strlen(extra) + 1; // 1: size of '\0'
1770            break;
1771        case SHOW_DRVIER_VERION:
1772            sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
1773            wrq->length = strlen(extra) + 1; // 1: size of '\0'
1774            break;
1775        case SHOW_BA_INFO:
1776            getBaInfo(pAd, extra);
1777            wrq->length = strlen(extra) + 1; // 1: size of '\0'
1778            break;
1779                case SHOW_DESC_INFO:
1780                        {
1781                                Show_DescInfo_Proc(pAd, NULL);
1782                                wrq->length = 0; // 1: size of '\0'
1783                        }
1784                        break;
1785        case RAIO_OFF:
1786            if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1787            {
1788                sprintf(extra, "Scanning\n");
1789                wrq->length = strlen(extra) + 1; // 1: size of '\0'
1790                break;
1791            }
1792            pAd->StaCfg.bSwRadio = FALSE;
1793            if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
1794            {
1795                pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
1796                if (pAd->StaCfg.bRadio == FALSE)
1797                {
1798                    MlmeRadioOff(pAd);
1799                    // Update extra information
1800                                        pAd->ExtraInfo = SW_RADIO_OFF;
1801                }
1802            }
1803            sprintf(extra, "Radio Off\n");
1804            wrq->length = strlen(extra) + 1; // 1: size of '\0'
1805            break;
1806        case RAIO_ON:
1807#ifdef RT2870
1808            if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1809            {
1810                sprintf(extra, "Scanning\n");
1811                wrq->length = strlen(extra) + 1; // 1: size of '\0'
1812                break;
1813            }
1814#endif
1815            pAd->StaCfg.bSwRadio = TRUE;
1816            //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
1817            {
1818                pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
1819                if (pAd->StaCfg.bRadio == TRUE)
1820                {
1821                    MlmeRadioOn(pAd);
1822                    // Update extra information
1823                                        pAd->ExtraInfo = EXTRA_INFO_CLEAR;
1824                }
1825            }
1826            sprintf(extra, "Radio On\n");
1827            wrq->length = strlen(extra) + 1; // 1: size of '\0'
1828            break;
1829
1830                case SHOW_CFG_VALUE:
1831                        {
1832                                Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
1833                                if (Status == 0)
1834                                        wrq->length = strlen(extra) + 1; // 1: size of '\0'
1835                        }
1836                        break;
1837        default:
1838            DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __func__, subcmd));
1839            break;
1840    }
1841
1842    return Status;
1843}
1844
1845int rt_ioctl_siwmlme(struct net_device *dev,
1846                           struct iw_request_info *info,
1847                           union iwreq_data *wrqu,
1848                           char *extra)
1849{
1850        PRTMP_ADAPTER   pAd = dev->ml_priv;
1851        struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
1852        MLME_QUEUE_ELEM                         MsgElem;
1853        MLME_DISASSOC_REQ_STRUCT        DisAssocReq;
1854        MLME_DEAUTH_REQ_STRUCT      DeAuthReq;
1855
1856        DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __func__));
1857
1858        if (pMlme == NULL)
1859                return -EINVAL;
1860
1861        switch(pMlme->cmd)
1862        {
1863#ifdef IW_MLME_DEAUTH
1864                case IW_MLME_DEAUTH:
1865                        DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __func__));
1866                        COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
1867                        DeAuthReq.Reason = pMlme->reason_code;
1868                        MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
1869                        NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
1870                        MlmeDeauthReqAction(pAd, &MsgElem);
1871                        if (INFRA_ON(pAd))
1872                        {
1873                            LinkDown(pAd, FALSE);
1874                            pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1875                        }
1876                        break;
1877#endif // IW_MLME_DEAUTH //
1878#ifdef IW_MLME_DISASSOC
1879                case IW_MLME_DISASSOC:
1880                        DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __func__));
1881                        COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
1882                        DisAssocReq.Reason =  pMlme->reason_code;
1883
1884                        MsgElem.Machine = ASSOC_STATE_MACHINE;
1885                        MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
1886                        MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
1887                        NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
1888
1889                        pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
1890                        MlmeDisassocReqAction(pAd, &MsgElem);
1891                        break;
1892#endif // IW_MLME_DISASSOC //
1893                default:
1894                        DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __func__));
1895                        break;
1896        }
1897
1898        return 0;
1899}
1900
1901int rt_ioctl_siwauth(struct net_device *dev,
1902                          struct iw_request_info *info,
1903                          union iwreq_data *wrqu, char *extra)
1904{
1905        PRTMP_ADAPTER   pAdapter = dev->ml_priv;
1906        struct iw_param *param = &wrqu->param;
1907
1908    //check if the interface is down
1909        if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1910        {
1911                DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1912        return -ENETDOWN;
1913        }
1914        switch (param->flags & IW_AUTH_INDEX) {
1915        case IW_AUTH_WPA_VERSION:
1916            if (param->value == IW_AUTH_WPA_VERSION_WPA)
1917            {
1918                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
1919                                if (pAdapter->StaCfg.BssType == BSS_ADHOC)
1920                                        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
1921            }
1922            else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
1923                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
1924
1925            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __func__, param->value));
1926            break;
1927        case IW_AUTH_CIPHER_PAIRWISE:
1928            if (param->value == IW_AUTH_CIPHER_NONE)
1929            {
1930                pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1931                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1932                pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1933            }
1934            else if (param->value == IW_AUTH_CIPHER_WEP40 ||
1935                     param->value == IW_AUTH_CIPHER_WEP104)
1936            {
1937                pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1938                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1939                pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
1940                pAdapter->StaCfg.IEEE8021X = FALSE;
1941            }
1942            else if (param->value == IW_AUTH_CIPHER_TKIP)
1943            {
1944                pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
1945                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1946                pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
1947            }
1948            else if (param->value == IW_AUTH_CIPHER_CCMP)
1949            {
1950                pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
1951                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1952                pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
1953            }
1954            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __func__, param->value));
1955            break;
1956        case IW_AUTH_CIPHER_GROUP:
1957            if (param->value == IW_AUTH_CIPHER_NONE)
1958            {
1959                pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1960            }
1961            else if (param->value == IW_AUTH_CIPHER_WEP40 ||
1962                     param->value == IW_AUTH_CIPHER_WEP104)
1963            {
1964                pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
1965            }
1966            else if (param->value == IW_AUTH_CIPHER_TKIP)
1967            {
1968                pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
1969            }
1970            else if (param->value == IW_AUTH_CIPHER_CCMP)
1971            {
1972                pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
1973            }
1974            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __func__, param->value));
1975            break;
1976        case IW_AUTH_KEY_MGMT:
1977            if (param->value == IW_AUTH_KEY_MGMT_802_1X)
1978            {
1979                if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
1980                {
1981                    pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
1982                    pAdapter->StaCfg.IEEE8021X = FALSE;
1983                }
1984                else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1985                {
1986                    pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
1987                    pAdapter->StaCfg.IEEE8021X = FALSE;
1988                }
1989                else
1990                    // WEP 1x
1991                    pAdapter->StaCfg.IEEE8021X = TRUE;
1992            }
1993            else if (param->value == 0)
1994            {
1995                                STA_PORT_SECURED(pAdapter);
1996            }
1997            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __func__, param->value));
1998            break;
1999        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2000            break;
2001        case IW_AUTH_PRIVACY_INVOKED:
2002            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __func__, param->value));
2003                break;
2004        case IW_AUTH_DROP_UNENCRYPTED:
2005            if (param->value != 0)
2006                pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2007                        else
2008                        {
2009                                STA_PORT_SECURED(pAdapter);
2010                        }
2011            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __func__, param->value));
2012                break;
2013        case IW_AUTH_80211_AUTH_ALG:
2014                        if (param->value & IW_AUTH_ALG_SHARED_KEY)
2015            {
2016                                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
2017                        }
2018            else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
2019            {
2020                                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2021                        }
2022            else
2023                                return -EINVAL;
2024            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __func__, param->value));
2025                        break;
2026        case IW_AUTH_WPA_ENABLED:
2027                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __func__, param->value));
2028                break;
2029        default:
2030                return -EOPNOTSUPP;
2031}
2032
2033        return 0;
2034}
2035
2036int rt_ioctl_giwauth(struct net_device *dev,
2037                               struct iw_request_info *info,
2038                               union iwreq_data *wrqu, char *extra)
2039{
2040        PRTMP_ADAPTER   pAdapter = dev->ml_priv;
2041        struct iw_param *param = &wrqu->param;
2042
2043    //check if the interface is down
2044        if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2045    {
2046                DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2047        return -ENETDOWN;
2048    }
2049
2050        switch (param->flags & IW_AUTH_INDEX) {
2051        case IW_AUTH_DROP_UNENCRYPTED:
2052        param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
2053                break;
2054
2055        case IW_AUTH_80211_AUTH_ALG:
2056        param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
2057                break;
2058
2059        case IW_AUTH_WPA_ENABLED:
2060                param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
2061                break;
2062
2063        default:
2064                return -EOPNOTSUPP;
2065        }
2066    DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
2067        return 0;
2068}
2069
2070void fnSetCipherKey(
2071    IN  PRTMP_ADAPTER   pAdapter,
2072    IN  INT             keyIdx,
2073    IN  UCHAR           CipherAlg,
2074    IN  BOOLEAN         bGTK,
2075    IN  struct iw_encode_ext *ext)
2076{
2077#ifdef RT2860
2078        RTMP_CLEAR_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
2079        if (RTMP_TEST_PSFLAG(pAdapter, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
2080        {
2081                if (pAdapter->StaCfg.bRadio == FALSE)
2082                {
2083                        RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
2084                        return;
2085                }
2086                DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n"));
2087                RTMPPCIeLinkCtrlValueRestore(pAdapter, RESTORE_HALT);
2088                RTMPusecDelay(6000);
2089                pAdapter->bPCIclkOff = FALSE;
2090        }
2091#endif
2092    NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2093    pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
2094    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
2095    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
2096    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
2097    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
2098
2099    // Update group key information to ASIC Shared Key Table
2100        AsicAddSharedKeyEntry(pAdapter,
2101                                                  BSS0,
2102                                                  keyIdx,
2103                                                  pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2104                                                  pAdapter->SharedKey[BSS0][keyIdx].Key,
2105                                                  pAdapter->SharedKey[BSS0][keyIdx].TxMic,
2106                                                  pAdapter->SharedKey[BSS0][keyIdx].RxMic);
2107
2108    if (bGTK)
2109        // Update ASIC WCID attribute table and IVEIV table
2110        RTMPAddWcidAttributeEntry(pAdapter,
2111                                                          BSS0,
2112                                                          keyIdx,
2113                                                          pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2114                                                          NULL);
2115    else
2116        // Update ASIC WCID attribute table and IVEIV table
2117        RTMPAddWcidAttributeEntry(pAdapter,
2118                                                          BSS0,
2119                                                          keyIdx,
2120                                                          pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2121                                                          &pAdapter->MacTab.Content[BSSID_WCID]);
2122#ifdef RT2860
2123        RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
2124#endif
2125}
2126
2127int rt_ioctl_siwencodeext(struct net_device *dev,
2128                           struct iw_request_info *info,
2129                           union iwreq_data *wrqu,
2130                           char *extra)
2131                        {
2132    PRTMP_ADAPTER   pAdapter = dev->ml_priv;
2133        struct iw_point *encoding = &wrqu->encoding;
2134        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2135    int keyIdx, alg = ext->alg;
2136
2137    //check if the interface is down
2138        if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2139        {
2140                DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2141        return -ENETDOWN;
2142        }
2143
2144    if (encoding->flags & IW_ENCODE_DISABLED)
2145        {
2146        keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2147        // set BSSID wcid entry of the Pair-wise Key table as no-security mode
2148            AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
2149        pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
2150                pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
2151                AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
2152        NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2153        DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __func__, encoding->flags));
2154    }
2155                                        else
2156    {
2157        // Get Key Index and convet to our own defined key index
2158        keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2159        if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
2160                return -EINVAL;
2161
2162        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2163        {
2164            pAdapter->StaCfg.DefaultKeyId = keyIdx;
2165            DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __func__, pAdapter->StaCfg.DefaultKeyId));
2166        }
2167
2168        switch (alg) {
2169                case IW_ENCODE_ALG_NONE:
2170                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __func__));
2171                        break;
2172                case IW_ENCODE_ALG_WEP:
2173                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __func__, ext->key_len, keyIdx));
2174                        if (ext->key_len == MAX_WEP_KEY_SIZE)
2175                {
2176                                pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
2177                    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
2178                                }
2179                        else if (ext->key_len == MIN_WEP_KEY_SIZE)
2180                {
2181                    pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
2182                    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
2183                        }
2184                        else
2185                    return -EINVAL;
2186
2187                NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
2188                            NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
2189                                if (pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled ||
2190                                        pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
2191                                {
2192                                        // Set Group key material to Asic
2193                                        AsicAddSharedKeyEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, pAdapter->SharedKey[BSS0][keyIdx].Key, NULL, NULL);
2194
2195                                        // Update WCID attribute table and IVEIV table for this group key table
2196                                        RTMPAddWcidAttributeEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, NULL);
2197
2198                                        STA_PORT_SECURED(pAdapter);
2199
2200                                // Indicate Connected for GUI
2201                                pAdapter->IndicateMediaState = NdisMediaStateConnected;
2202                                }
2203                        break;
2204            case IW_ENCODE_ALG_TKIP:
2205                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __func__, keyIdx, ext->key_len));
2206                if (ext->key_len == 32)
2207                {
2208                    if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2209                    {
2210                        fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
2211                        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2212                        {
2213                            STA_PORT_SECURED(pAdapter);
2214                        }
2215                }
2216                    else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2217                    {
2218                        fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
2219
2220                        // set 802.1x port control
2221                        STA_PORT_SECURED(pAdapter);
2222                    }
2223                }
2224                else
2225                    return -EINVAL;
2226                break;
2227            case IW_ENCODE_ALG_CCMP:
2228                if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2229                {
2230                    fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
2231                    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2232                        STA_PORT_SECURED(pAdapter);
2233                }
2234                else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2235                {
2236                    fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
2237
2238                    // set 802.1x port control
2239                        STA_PORT_SECURED(pAdapter);
2240                }
2241                break;
2242                default:
2243                        return -EINVAL;
2244                }
2245    }
2246
2247    return 0;
2248}
2249
2250int
2251rt_ioctl_giwencodeext(struct net_device *dev,
2252                          struct iw_request_info *info,
2253                          union iwreq_data *wrqu, char *extra)
2254{
2255        PRTMP_ADAPTER pAd = dev->ml_priv;
2256        PCHAR pKey = NULL;
2257        struct iw_point *encoding = &wrqu->encoding;
2258        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2259        int idx, max_key_len;
2260
2261        DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
2262
2263        max_key_len = encoding->length - sizeof(*ext);
2264        if (max_key_len < 0)
2265                return -EINVAL;
2266
2267        idx = encoding->flags & IW_ENCODE_INDEX;
2268        if (idx)
2269        {
2270                if (idx < 1 || idx > 4)
2271                        return -EINVAL;
2272                idx--;
2273
2274                if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2275                        (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
2276                {
2277                        if (idx != pAd->StaCfg.DefaultKeyId)
2278                        {
2279                                ext->key_len = 0;
2280                                return 0;
2281                        }
2282                }
2283        }
2284        else
2285                idx = pAd->StaCfg.DefaultKeyId;
2286
2287        encoding->flags = idx + 1;
2288        memset(ext, 0, sizeof(*ext));
2289
2290        ext->key_len = 0;
2291        switch(pAd->StaCfg.WepStatus) {
2292                case Ndis802_11WEPDisabled:
2293                        ext->alg = IW_ENCODE_ALG_NONE;
2294                        encoding->flags |= IW_ENCODE_DISABLED;
2295                        break;
2296                case Ndis802_11WEPEnabled:
2297                        ext->alg = IW_ENCODE_ALG_WEP;
2298                        if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
2299                                return -E2BIG;
2300                        else
2301                        {
2302                                ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
2303                                pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
2304                        }
2305                        break;
2306                case Ndis802_11Encryption2Enabled:
2307                case Ndis802_11Encryption3Enabled:
2308                        if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
2309                                ext->alg = IW_ENCODE_ALG_TKIP;
2310                        else
2311                                ext->alg = IW_ENCODE_ALG_CCMP;
2312
2313                        if (max_key_len < 32)
2314                                return -E2BIG;
2315                        else
2316                        {
2317                                ext->key_len = 32;
2318                                pKey = &pAd->StaCfg.PMK[0];
2319                        }
2320                        break;
2321                default:
2322                        return -EINVAL;
2323        }
2324
2325        if (ext->key_len && pKey)
2326        {
2327                encoding->flags |= IW_ENCODE_ENABLED;
2328                memcpy(ext->key, pKey, ext->key_len);
2329        }
2330
2331        return 0;
2332}
2333
2334int rt_ioctl_siwgenie(struct net_device *dev,
2335                          struct iw_request_info *info,
2336                          union iwreq_data *wrqu, char *extra)
2337{
2338        PRTMP_ADAPTER   pAd = dev->ml_priv;
2339
2340        if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
2341            (wrqu->data.length && extra == NULL))
2342                return -EINVAL;
2343
2344        if (wrqu->data.length)
2345        {
2346                pAd->StaCfg.RSNIE_Len = wrqu->data.length;
2347                NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
2348        }
2349        else
2350        {
2351                pAd->StaCfg.RSNIE_Len = 0;
2352                NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
2353        }
2354
2355        return 0;
2356}
2357
2358int rt_ioctl_giwgenie(struct net_device *dev,
2359                               struct iw_request_info *info,
2360                               union iwreq_data *wrqu, char *extra)
2361{
2362        PRTMP_ADAPTER   pAd = dev->ml_priv;
2363
2364        if ((pAd->StaCfg.RSNIE_Len == 0) ||
2365                (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
2366        {
2367                wrqu->data.length = 0;
2368                return 0;
2369        }
2370
2371        if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
2372        {
2373        if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
2374                return -E2BIG;
2375
2376        wrqu->data.length = pAd->StaCfg.RSNIE_Len;
2377        memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2378        }
2379        else
2380        {
2381                UCHAR RSNIe = IE_WPA;
2382
2383                if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
2384                        return -E2BIG;
2385                wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
2386
2387                if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
2388            (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
2389                        RSNIe = IE_RSN;
2390
2391                extra[0] = (char)RSNIe;
2392                extra[1] = pAd->StaCfg.RSNIE_Len;
2393                memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2394        }
2395
2396        return 0;
2397}
2398
2399int rt_ioctl_siwpmksa(struct net_device *dev,
2400                           struct iw_request_info *info,
2401                           union iwreq_data *wrqu,
2402                           char *extra)
2403{
2404        PRTMP_ADAPTER   pAd = dev->ml_priv;
2405        struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
2406        INT     CachedIdx = 0, idx = 0;
2407
2408        if (pPmksa == NULL)
2409                return -EINVAL;
2410
2411        DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
2412        switch(pPmksa->cmd)
2413        {
2414                case IW_PMKSA_FLUSH:
2415                        NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
2416                        DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
2417                        break;
2418                case IW_PMKSA_REMOVE:
2419                        for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2420                        {
2421                        // compare the BSSID
2422                        if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2423                        {
2424                                NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
2425                                        NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
2426                                        for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
2427                                        {
2428                                                NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
2429                                                NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
2430                                        }
2431                                        pAd->StaCfg.SavedPMKNum--;
2432                                break;
2433                        }
2434                }
2435
2436                        DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
2437                        break;
2438                case IW_PMKSA_ADD:
2439                        for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2440                        {
2441                        // compare the BSSID
2442                        if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2443                                break;
2444                }
2445
2446                // Found, replace it
2447                if (CachedIdx < PMKID_NO)
2448                {
2449                        DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2450                        NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2451                                NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2452                        pAd->StaCfg.SavedPMKNum++;
2453                }
2454                // Not found, replace the last one
2455                else
2456                {
2457                        // Randomly replace one
2458                        CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
2459                        DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2460                        NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2461                                NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2462                }
2463
2464                        DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
2465                        break;
2466                default:
2467                        DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
2468                        break;
2469        }
2470
2471        return 0;
2472}
2473
2474int rt_ioctl_siwrate(struct net_device *dev,
2475                        struct iw_request_info *info,
2476                        union iwreq_data *wrqu, char *extra)
2477{
2478    PRTMP_ADAPTER   pAd = dev->ml_priv;
2479    UINT32          rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
2480
2481    //check if the interface is down
2482        if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2483        {
2484                DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
2485        return -ENETDOWN;
2486        }
2487
2488    DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
2489    /* rate = -1 => auto rate
2490       rate = X, fixed = 1 => (fixed rate X)
2491    */
2492    if (rate == -1)
2493    {
2494                //Auto Rate
2495                pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
2496                pAd->StaCfg.bAutoTxRateSwitch = TRUE;
2497                if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
2498                    (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
2499                        RTMPSetDesiredRates(pAd, -1);
2500
2501                SetCommonHT(pAd);
2502    }
2503    else
2504    {
2505        if (fixed)
2506        {
2507                pAd->StaCfg.bAutoTxRateSwitch = FALSE;
2508            if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
2509                (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
2510                RTMPSetDesiredRates(pAd, rate);
2511            else
2512            {
2513                pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
2514                SetCommonHT(pAd);
2515            }
2516            DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
2517        }
2518        else
2519        {
2520            // TODO: rate = X, fixed = 0 => (rates <= X)
2521            return -EOPNOTSUPP;
2522        }
2523    }
2524
2525    return 0;
2526}
2527
2528int rt_ioctl_giwrate(struct net_device *dev,
2529                               struct iw_request_info *info,
2530                               union iwreq_data *wrqu, char *extra)
2531{
2532    PRTMP_ADAPTER   pAd = dev->ml_priv;
2533    int rate_index = 0, rate_count = 0;
2534    HTTRANSMIT_SETTING ht_setting;
2535    __s32 ralinkrate[] =
2536        {2,  4,   11,  22, // CCK
2537        12, 18,   24,  36, 48, 72, 96, 108, // OFDM
2538        13, 26,   39,  52,  78, 104, 117, 130, 26,  52,  78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
2539        39, 78,  117, 156, 234, 312, 351, 390,                                                                            // 20MHz, 800ns GI, MCS: 16 ~ 23
2540        27, 54,   81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
2541        81, 162, 243, 324, 486, 648, 729, 810,                                                                            // 40MHz, 800ns GI, MCS: 16 ~ 23
2542        14, 29,   43,  57,  87, 115, 130, 144, 29, 59,   87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
2543        43, 87,  130, 173, 260, 317, 390, 433,                                                                            // 20MHz, 400ns GI, MCS: 16 ~ 23
2544        30, 60,   90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
2545        90, 180, 270, 360, 540, 720, 810, 900};                                                                           // 40MHz, 400ns GI, MCS: 16 ~ 23
2546
2547    rate_count = sizeof(ralinkrate)/sizeof(__s32);
2548    //check if the interface is down
2549        if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2550        {
2551                DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2552        return -ENETDOWN;
2553        }
2554
2555    if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
2556        (INFRA_ON(pAd)) &&
2557        ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
2558        ht_setting.word = pAd->StaCfg.HTPhyMode.word;
2559    else
2560        ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
2561
2562    if (ht_setting.field.MODE >= MODE_HTMIX)
2563    {
2564        rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
2565    }
2566    else
2567    if (ht_setting.field.MODE == MODE_OFDM)
2568        rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
2569    else if (ht_setting.field.MODE == MODE_CCK)
2570        rate_index = (UCHAR)(ht_setting.field.MCS);
2571
2572    if (rate_index < 0)
2573        rate_index = 0;
2574
2575    if (rate_index > rate_count)
2576        rate_index = rate_count;
2577
2578    wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
2579    wrqu->bitrate.disabled = 0;
2580
2581    return 0;
2582}
2583
2584static const iw_handler rt_handler[] =
2585{
2586        (iw_handler) NULL,                                  /* SIOCSIWCOMMIT */
2587        (iw_handler) rt_ioctl_giwname,                  /* SIOCGIWNAME   */
2588        (iw_handler) NULL,                                  /* SIOCSIWNWID   */
2589        (iw_handler) NULL,                                  /* SIOCGIWNWID   */
2590        (iw_handler) rt_ioctl_siwfreq,              /* SIOCSIWFREQ   */
2591        (iw_handler) rt_ioctl_giwfreq,              /* SIOCGIWFREQ   */
2592        (iw_handler) rt_ioctl_siwmode,              /* SIOCSIWMODE   */
2593        (iw_handler) rt_ioctl_giwmode,              /* SIOCGIWMODE   */
2594        (iw_handler) NULL,                              /* SIOCSIWSENS   */
2595        (iw_handler) NULL,                              /* SIOCGIWSENS   */
2596        (iw_handler) NULL /* not used */,               /* SIOCSIWRANGE  */
2597        (iw_handler) rt_ioctl_giwrange,             /* SIOCGIWRANGE  */
2598        (iw_handler) NULL /* not used */,               /* SIOCSIWPRIV   */
2599        (iw_handler) NULL /* kernel code */,    /* SIOCGIWPRIV   */
2600        (iw_handler) NULL /* not used */,               /* SIOCSIWSTATS  */
2601        (iw_handler) rt28xx_get_wireless_stats /* kernel code */,    /* SIOCGIWSTATS  */
2602        (iw_handler) NULL,                              /* SIOCSIWSPY    */
2603        (iw_handler) NULL,                              /* SIOCGIWSPY    */
2604        (iw_handler) NULL,                                      /* SIOCSIWTHRSPY */
2605        (iw_handler) NULL,                                      /* SIOCGIWTHRSPY */
2606        (iw_handler) rt_ioctl_siwap,            /* SIOCSIWAP     */
2607        (iw_handler) rt_ioctl_giwap,                /* SIOCGIWAP     */
2608        (iw_handler) rt_ioctl_siwmlme,          /* SIOCSIWMLME   */
2609        (iw_handler) rt_ioctl_iwaplist,             /* SIOCGIWAPLIST */
2610        (iw_handler) rt_ioctl_siwscan,              /* SIOCSIWSCAN   */
2611        (iw_handler) rt_ioctl_giwscan,              /* SIOCGIWSCAN   */
2612        (iw_handler) rt_ioctl_siwessid,             /* SIOCSIWESSID  */
2613        (iw_handler) rt_ioctl_giwessid,             /* SIOCGIWESSID  */
2614        (iw_handler) rt_ioctl_siwnickn,             /* SIOCSIWNICKN  */
2615        (iw_handler) rt_ioctl_giwnickn,             /* SIOCGIWNICKN  */
2616        (iw_handler) NULL,                                      /* -- hole --    */
2617        (iw_handler) NULL,                                      /* -- hole --    */
2618        (iw_handler) rt_ioctl_siwrate,          /* SIOCSIWRATE   */
2619        (iw_handler) rt_ioctl_giwrate,          /* SIOCGIWRATE   */
2620        (iw_handler) rt_ioctl_siwrts,               /* SIOCSIWRTS    */
2621        (iw_handler) rt_ioctl_giwrts,               /* SIOCGIWRTS    */
2622        (iw_handler) rt_ioctl_siwfrag,              /* SIOCSIWFRAG   */
2623        (iw_handler) rt_ioctl_giwfrag,              /* SIOCGIWFRAG   */
2624        (iw_handler) NULL,                              /* SIOCSIWTXPOW  */
2625        (iw_handler) NULL,                              /* SIOCGIWTXPOW  */
2626        (iw_handler) NULL,                              /* SIOCSIWRETRY  */
2627        (iw_handler) NULL,                              /* SIOCGIWRETRY  */
2628        (iw_handler) rt_ioctl_siwencode,                /* SIOCSIWENCODE */
2629        (iw_handler) rt_ioctl_giwencode,                /* SIOCGIWENCODE */
2630        (iw_handler) NULL,                              /* SIOCSIWPOWER  */
2631        (iw_handler) NULL,                              /* SIOCGIWPOWER  */
2632        (iw_handler) NULL,                                              /* -- hole -- */
2633        (iw_handler) NULL,                                              /* -- hole -- */
2634    (iw_handler) rt_ioctl_siwgenie,         /* SIOCSIWGENIE  */
2635        (iw_handler) rt_ioctl_giwgenie,         /* SIOCGIWGENIE  */
2636        (iw_handler) rt_ioctl_siwauth,              /* SIOCSIWAUTH   */
2637        (iw_handler) rt_ioctl_giwauth,              /* SIOCGIWAUTH   */
2638        (iw_handler) rt_ioctl_siwencodeext,         /* SIOCSIWENCODEEXT */
2639        (iw_handler) rt_ioctl_giwencodeext,             /* SIOCGIWENCODEEXT */
2640        (iw_handler) rt_ioctl_siwpmksa,         /* SIOCSIWPMKSA  */
2641};
2642
2643static const iw_handler rt_priv_handlers[] = {
2644        (iw_handler) NULL, /* + 0x00 */
2645        (iw_handler) NULL, /* + 0x01 */
2646        (iw_handler) rt_ioctl_setparam, /* + 0x02 */
2647        (iw_handler) NULL, /* + 0x03 */
2648        (iw_handler) NULL, /* + 0x04 */
2649        (iw_handler) NULL, /* + 0x05 */
2650        (iw_handler) NULL, /* + 0x06 */
2651        (iw_handler) NULL, /* + 0x07 */
2652        (iw_handler) NULL, /* + 0x08 */
2653        (iw_handler) rt_private_get_statistics, /* + 0x09 */
2654        (iw_handler) NULL, /* + 0x0A */
2655        (iw_handler) NULL, /* + 0x0B */
2656        (iw_handler) NULL, /* + 0x0C */
2657        (iw_handler) NULL, /* + 0x0D */
2658        (iw_handler) NULL, /* + 0x0E */
2659        (iw_handler) NULL, /* + 0x0F */
2660        (iw_handler) NULL, /* + 0x10 */
2661        (iw_handler) rt_private_show, /* + 0x11 */
2662    (iw_handler) NULL, /* + 0x12 */
2663        (iw_handler) NULL, /* + 0x13 */
2664        (iw_handler) NULL, /* + 0x15 */
2665        (iw_handler) NULL, /* + 0x17 */
2666        (iw_handler) NULL, /* + 0x18 */
2667};
2668
2669const struct iw_handler_def rt28xx_iw_handler_def =
2670{
2671#define N(a)    (sizeof (a) / sizeof (a[0]))
2672        .standard       = (iw_handler *) rt_handler,
2673        .num_standard   = sizeof(rt_handler) / sizeof(iw_handler),
2674        .private        = (iw_handler *) rt_priv_handlers,
2675        .num_private            = N(rt_priv_handlers),
2676        .private_args   = (struct iw_priv_args *) privtab,
2677        .num_private_args       = N(privtab),
2678#if IW_HANDLER_VERSION >= 7
2679    .get_wireless_stats = rt28xx_get_wireless_stats,
2680#endif
2681};
2682
2683INT rt28xx_sta_ioctl(
2684        IN      struct net_device       *net_dev,
2685        IN      OUT     struct ifreq    *rq,
2686        IN      INT                                     cmd)
2687{
2688        RTMP_ADAPTER *pAd = net_dev->ml_priv;
2689        POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
2690        struct iwreq        *wrq = (struct iwreq *) rq;
2691        BOOLEAN                         StateMachineTouched = FALSE;
2692        INT                                     Status = NDIS_STATUS_SUCCESS;
2693
2694    //check if the interface is down
2695    if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2696    {
2697        {
2698            DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2699                    return -ENETDOWN;
2700        }
2701    }
2702
2703        {       // determine this ioctl command is comming from which interface.
2704                pObj->ioctl_if_type = INT_MAIN;
2705                pObj->ioctl_if = MAIN_MBSSID;
2706        }
2707
2708        switch(cmd)
2709        {
2710        case SIOCGIFHWADDR:
2711                        DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
2712                        memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
2713                        break;
2714                case SIOCGIWNAME:
2715        {
2716                char *name=&wrq->u.name[0];
2717                rt_ioctl_giwname(net_dev, NULL, name, NULL);
2718                        break;
2719                }
2720                case SIOCGIWESSID:  //Get ESSID
2721        {
2722                struct iw_point *essid=&wrq->u.essid;
2723                rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
2724                        break;
2725                }
2726                case SIOCSIWESSID:  //Set ESSID
2727        {
2728                struct iw_point *essid=&wrq->u.essid;
2729                rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
2730                        break;
2731                }
2732                case SIOCSIWNWID:   // set network id (the cell)
2733                case SIOCGIWNWID:   // get network id
2734                        Status = -EOPNOTSUPP;
2735                        break;
2736                case SIOCSIWFREQ:   //set channel/frequency (Hz)
2737        {
2738                struct iw_freq *freq=&wrq->u.freq;
2739                rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
2740                        break;
2741                }
2742                case SIOCGIWFREQ:   // get channel/frequency (Hz)
2743        {
2744                struct iw_freq *freq=&wrq->u.freq;
2745                rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
2746                        break;
2747                }
2748                case SIOCSIWNICKN: //set node name/nickname
2749        {
2750                struct iw_point *data=&wrq->u.data;
2751                rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
2752                        break;
2753                }
2754                case SIOCGIWNICKN: //get node name/nickname
2755        {
2756                struct iw_point *data=&wrq->u.data;
2757                rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
2758                        break;
2759                }
2760                case SIOCGIWRATE:   //get default bit rate (bps)
2761                    rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
2762            break;
2763            case SIOCSIWRATE:  //set default bit rate (bps)
2764                rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
2765            break;
2766        case SIOCGIWRTS:  // get RTS/CTS threshold (bytes)
2767        {
2768                struct iw_param *rts=&wrq->u.rts;
2769                rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
2770                        break;
2771                }
2772        case SIOCSIWRTS:  //set RTS/CTS threshold (bytes)
2773        {
2774                struct iw_param *rts=&wrq->u.rts;
2775                rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
2776                        break;
2777                }
2778        case SIOCGIWFRAG:  //get fragmentation thr (bytes)
2779        {
2780                struct iw_param *frag=&wrq->u.frag;
2781                rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
2782                        break;
2783                }
2784        case SIOCSIWFRAG:  //set fragmentation thr (bytes)
2785        {
2786                struct iw_param *frag=&wrq->u.frag;
2787                rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
2788                        break;
2789                }
2790        case SIOCGIWENCODE:  //get encoding token & mode
2791        {
2792                struct iw_point *erq=&wrq->u.encoding;
2793                if(erq->pointer)
2794                        rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
2795                        break;
2796                }
2797        case SIOCSIWENCODE:  //set encoding token & mode
2798        {
2799                struct iw_point *erq=&wrq->u.encoding;
2800                if(erq->pointer)
2801                        rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
2802                        break;
2803                }
2804                case SIOCGIWAP:     //get access point MAC addresses
2805        {
2806                struct sockaddr *ap_addr=&wrq->u.ap_addr;
2807                rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
2808                        break;
2809                }
2810            case SIOCSIWAP:  //set access point MAC addresses
2811        {
2812                struct sockaddr *ap_addr=&wrq->u.ap_addr;
2813                rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
2814                        break;
2815                }
2816                case SIOCGIWMODE:   //get operation mode
2817        {
2818                __u32 *mode=&wrq->u.mode;
2819                rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
2820                        break;
2821                }
2822                case SIOCSIWMODE:   //set operation mode
2823        {
2824                __u32 *mode=&wrq->u.mode;
2825                rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
2826                        break;
2827                }
2828                case SIOCGIWSENS:   //get sensitivity (dBm)
2829                case SIOCSIWSENS:       //set sensitivity (dBm)
2830                case SIOCGIWPOWER:  //get Power Management settings
2831                case SIOCSIWPOWER:  //set Power Management settings
2832                case SIOCGIWTXPOW:  //get transmit power (dBm)
2833                case SIOCSIWTXPOW:  //set transmit power (dBm)
2834                case SIOCGIWRANGE:      //Get range of parameters
2835                case SIOCGIWRETRY:      //get retry limits and lifetime
2836                case SIOCSIWRETRY:      //set retry limits and lifetime
2837                case RT_PRIV_IOCTL:
2838                case RT_PRIV_IOCTL_EXT:
2839                        Status = -EOPNOTSUPP;
2840                        break;
2841                case SIOCGIWPRIV:
2842                        if (wrq->u.data.pointer)
2843                        {
2844                                if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
2845                                        break;
2846                                wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
2847                                if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
2848                                        Status = -EFAULT;
2849                        }
2850                        break;
2851                case RTPRIV_IOCTL_SET:
2852                        if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
2853                                break;
2854                        rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
2855                        break;
2856                case RTPRIV_IOCTL_GSITESURVEY:
2857                        RTMPIoctlGetSiteSurvey(pAd, wrq);
2858                    break;
2859        case SIOCETHTOOL:
2860                break;
2861                default:
2862                        DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
2863                        Status = -EOPNOTSUPP;
2864                        break;
2865        }
2866
2867    if(StateMachineTouched) // Upper layer sent a MLME-related operations
2868        RT28XX_MLME_HANDLER(pAd);
2869
2870        return Status;
2871}
2872
2873/*
2874    ==========================================================================
2875    Description:
2876        Set SSID
2877    Return:
2878        TRUE if all parameters are OK, FALSE otherwise
2879    ==========================================================================
2880*/
2881INT Set_SSID_Proc(
2882    IN  PRTMP_ADAPTER   pAdapter,
2883    IN  PUCHAR          arg)
2884{
2885    NDIS_802_11_SSID                    Ssid, *pSsid=NULL;
2886    BOOLEAN                             StateMachineTouched = FALSE;
2887    int                                 success = TRUE;
2888
2889    if( strlen(arg) <= MAX_LEN_OF_SSID)
2890    {
2891        NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
2892        if (strlen(arg) != 0)
2893        {
2894            NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
2895            Ssid.SsidLength = strlen(arg);
2896        }
2897        else   //ANY ssid
2898        {
2899            Ssid.SsidLength = 0;
2900                    memcpy(Ssid.Ssid, "", 0);
2901                        pAdapter->StaCfg.BssType = BSS_INFRA;
2902                        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2903                pAdapter->StaCfg.WepStatus  = Ndis802_11EncryptionDisabled;
2904                }
2905        pSsid = &Ssid;
2906
2907        if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
2908        {
2909            RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
2910            DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
2911        }
2912
2913        pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
2914        pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
2915                pAdapter->bConfigChanged = TRUE;
2916
2917        MlmeEnqueue(pAdapter,
2918                    MLME_CNTL_STATE_MACHINE,
2919                    OID_802_11_SSID,
2920                    sizeof(NDIS_802_11_SSID),
2921                    (VOID *)pSsid);
2922
2923        StateMachineTouched = TRUE;
2924        DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
2925    }
2926    else
2927        success = FALSE;
2928
2929    if (StateMachineTouched) // Upper layer sent a MLME-related operations
2930        RT28XX_MLME_HANDLER(pAdapter);
2931
2932    return success;
2933}
2934
2935#ifdef WMM_SUPPORT
2936/*
2937    ==========================================================================
2938    Description:
2939        Set WmmCapable Enable or Disable
2940    Return:
2941        TRUE if all parameters are OK, FALSE otherwise
2942    ==========================================================================
2943*/
2944INT     Set_WmmCapable_Proc(
2945        IN      PRTMP_ADAPTER   pAd,
2946        IN      PUCHAR                  arg)
2947{
2948        BOOLEAN bWmmCapable;
2949
2950        bWmmCapable = simple_strtol(arg, 0, 10);
2951
2952        if ((bWmmCapable == 1)
2953#ifdef RT2870
2954                && (pAd->NumberOfPipes >= 5)
2955#endif // RT2870 //
2956                )
2957                pAd->CommonCfg.bWmmCapable = TRUE;
2958        else if (bWmmCapable == 0)
2959                pAd->CommonCfg.bWmmCapable = FALSE;
2960        else
2961                return FALSE;  //Invalid argument
2962
2963        DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
2964                pAd->CommonCfg.bWmmCapable));
2965
2966        return TRUE;
2967}
2968#endif // WMM_SUPPORT //
2969
2970/*
2971    ==========================================================================
2972    Description:
2973        Set Network Type(Infrastructure/Adhoc mode)
2974    Return:
2975        TRUE if all parameters are OK, FALSE otherwise
2976    ==========================================================================
2977*/
2978INT Set_NetworkType_Proc(
2979    IN  PRTMP_ADAPTER   pAdapter,
2980    IN  PUCHAR          arg)
2981{
2982    UINT32      Value = 0;
2983
2984    if (strcmp(arg, "Adhoc") == 0)
2985        {
2986                if (pAdapter->StaCfg.BssType != BSS_ADHOC)
2987                {
2988                        // Config has changed
2989                        pAdapter->bConfigChanged = TRUE;
2990            if (MONITOR_ON(pAdapter))
2991            {
2992                RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
2993                RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
2994                                Value &= (~0x80);
2995                                RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
2996                OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
2997                pAdapter->StaCfg.bAutoReconnect = TRUE;
2998                LinkDown(pAdapter, FALSE);
2999            }
3000                        if (INFRA_ON(pAdapter))
3001                        {
3002                                //BOOLEAN Cancelled;
3003                                // Set the AutoReconnectSsid to prevent it reconnect to old SSID
3004                                // Since calling this indicate user don't want to connect to that SSID anymore.
3005                                pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
3006                                NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
3007
3008                                LinkDown(pAdapter, FALSE);
3009
3010                                DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
3011                        }
3012                }
3013                pAdapter->StaCfg.BssType = BSS_ADHOC;
3014        pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
3015                DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
3016        }
3017    else if (strcmp(arg, "Infra") == 0)
3018        {
3019                if (pAdapter->StaCfg.BssType != BSS_INFRA)
3020                {
3021                        // Config has changed
3022                        pAdapter->bConfigChanged = TRUE;
3023            if (MONITOR_ON(pAdapter))
3024            {
3025                RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
3026                RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
3027                                Value &= (~0x80);
3028                                RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
3029                OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
3030                pAdapter->StaCfg.bAutoReconnect = TRUE;
3031                LinkDown(pAdapter, FALSE);
3032            }
3033                        if (ADHOC_ON(pAdapter))
3034                        {
3035                                // Set the AutoReconnectSsid to prevent it reconnect to old SSID
3036                                // Since calling this indicate user don't want to connect to that SSID anymore.
3037                                pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
3038                                NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
3039
3040                                LinkDown(pAdapter, FALSE);
3041                        }
3042                }
3043                pAdapter->StaCfg.BssType = BSS_INFRA;
3044        pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
3045                DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
3046
3047        pAdapter->StaCfg.BssType = BSS_INFRA;
3048        }
3049    else if (strcmp(arg, "Monitor") == 0)
3050    {
3051                UCHAR   bbpValue = 0;
3052                BCN_TIME_CFG_STRUC csr;
3053                OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
3054        OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
3055                OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
3056                // disable all periodic state machine
3057                pAdapter->StaCfg.bAutoReconnect = FALSE;
3058                // reset all mlme state machine
3059                RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3060                DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
3061        if (pAdapter->CommonCfg.CentralChannel == 0)
3062        {
3063            if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
3064                pAdapter->CommonCfg.CentralChannel = 36;
3065            else
3066                pAdapter->CommonCfg.CentralChannel = 6;
3067        }
3068        else
3069            N_ChannelCheck(pAdapter);
3070
3071        if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
3072            pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
3073            pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
3074                {
3075                        // 40MHz ,control channel at lower
3076                        RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
3077                        bbpValue &= (~0x18);
3078                        bbpValue |= 0x10;
3079                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
3080                        pAdapter->CommonCfg.BBPCurrentBW = BW_40;
3081                        //  RX : control channel at lower
3082                        RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
3083                        bbpValue &= (~0x20);
3084                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
3085
3086                        RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
3087                        Value &= 0xfffffffe;
3088                        RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
3089                        pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
3090            AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
3091                    AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
3092            DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
3093                                       pAdapter->CommonCfg.Channel,
3094                                       pAdapter->CommonCfg.CentralChannel));
3095                }
3096                else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
3097                 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
3098                 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
3099                {
3100                        // 40MHz ,control channel at upper
3101                        RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
3102                        bbpValue &= (~0x18);
3103                        bbpValue |= 0x10;
3104                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
3105                        pAdapter->CommonCfg.BBPCurrentBW = BW_40;
3106                        RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
3107                        Value |= 0x1;
3108                        RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
3109
3110                        RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
3111                        bbpValue |= (0x20);
3112                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
3113                        pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
3114            AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
3115                    AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
3116            DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
3117                                       pAdapter->CommonCfg.Channel,
3118                                       pAdapter->CommonCfg.CentralChannel));
3119                }
3120                else
3121                {
3122                        // 20MHz
3123                        RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
3124                        bbpValue &= (~0x18);
3125                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
3126                        pAdapter->CommonCfg.BBPCurrentBW = BW_20;
3127                        AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
3128                        AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
3129                        DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
3130                }
3131                // Enable Rx with promiscuous reception
3132                RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
3133                // ASIC supporsts sniffer function with replacing RSSI with timestamp.
3134                //RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
3135                //Value |= (0x80);
3136                //RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
3137                // disable sync
3138                RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
3139                csr.field.bBeaconGen = 0;
3140                csr.field.bTBTTEnable = 0;
3141                csr.field.TsfSyncMode = 0;
3142                RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
3143
3144                pAdapter->StaCfg.BssType = BSS_MONITOR;
3145        pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
3146                DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
3147    }
3148
3149    // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
3150    pAdapter->StaCfg.WpaState = SS_NOTUSE;
3151
3152    DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
3153
3154    return TRUE;
3155}
3156
3157/*
3158    ==========================================================================
3159    Description:
3160        Set Authentication mode
3161    Return:
3162        TRUE if all parameters are OK, FALSE otherwise
3163    ==========================================================================
3164*/
3165INT Set_AuthMode_Proc(
3166    IN  PRTMP_ADAPTER   pAdapter,
3167    IN  PUCHAR          arg)
3168{
3169    if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
3170        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
3171    else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
3172        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
3173    else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
3174        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
3175    else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
3176        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
3177    else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
3178        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
3179    else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
3180        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
3181    else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
3182        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
3183    else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
3184        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
3185    else
3186        return FALSE;
3187
3188    pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
3189
3190    DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
3191
3192    return TRUE;
3193}
3194
3195/*
3196    ==========================================================================
3197    Description:
3198        Set Encryption Type
3199    Return:
3200        TRUE if all parameters are OK, FALSE otherwise
3201    ==========================================================================
3202*/
3203INT Set_EncrypType_Proc(
3204    IN  PRTMP_ADAPTER   pAdapter,
3205    IN  PUCHAR          arg)
3206{
3207    if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
3208    {
3209        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3210            return TRUE;    // do nothing
3211
3212        pAdapter->StaCfg.WepStatus     = Ndis802_11WEPDisabled;
3213        pAdapter->StaCfg.PairCipher    = Ndis802_11WEPDisabled;
3214            pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPDisabled;
3215    }
3216    else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
3217    {
3218        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3219            return TRUE;    // do nothing
3220
3221        pAdapter->StaCfg.WepStatus     = Ndis802_11WEPEnabled;
3222        pAdapter->StaCfg.PairCipher    = Ndis802_11WEPEnabled;
3223            pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPEnabled;
3224    }
3225    else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
3226    {
3227        if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
3228            return TRUE;    // do nothing
3229
3230        pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption2Enabled;
3231        pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption2Enabled;
3232            pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption2Enabled;
3233    }
3234    else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
3235    {
3236        if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
3237            return TRUE;    // do nothing
3238
3239        pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption3Enabled;
3240        pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption3Enabled;
3241            pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption3Enabled;
3242    }
3243    else
3244        return FALSE;
3245
3246    pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
3247
3248    DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
3249
3250    return TRUE;
3251}
3252
3253/*
3254    ==========================================================================
3255    Description:
3256        Set Default Key ID
3257    Return:
3258        TRUE if all parameters are OK, FALSE otherwise
3259    ==========================================================================
3260*/
3261INT Set_DefaultKeyID_Proc(
3262    IN  PRTMP_ADAPTER   pAdapter,
3263    IN  PUCHAR          arg)
3264{
3265    ULONG                               KeyIdx;
3266
3267    KeyIdx = simple_strtol(arg, 0, 10);
3268    if((KeyIdx >= 1 ) && (KeyIdx <= 4))
3269        pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
3270    else
3271        return FALSE;  //Invalid argument
3272
3273    DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
3274
3275    return TRUE;
3276}
3277
3278/*
3279    ==========================================================================
3280    Description:
3281        Set WEP KEY1
3282    Return:
3283        TRUE if all parameters are OK, FALSE otherwise
3284    ==========================================================================
3285*/
3286INT Set_Key1_Proc(
3287    IN  PRTMP_ADAPTER   pAdapter,
3288    IN  PUCHAR          arg)
3289{
3290    int                                 KeyLen;
3291    int                                 i;
3292    UCHAR                               CipherAlg=CIPHER_WEP64;
3293
3294    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3295        return TRUE;    // do nothing
3296
3297    KeyLen = strlen(arg);
3298
3299    switch (KeyLen)
3300    {
3301        case 5: //wep 40 Ascii type
3302            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
3303            memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
3304            CipherAlg = CIPHER_WEP64;
3305            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
3306            break;
3307        case 10: //wep 40 Hex type
3308            for(i=0; i < KeyLen; i++)
3309            {
3310                if( !isxdigit(*(arg+i)) )
3311                    return FALSE;  //Not Hex value;
3312            }
3313            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
3314            AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
3315            CipherAlg = CIPHER_WEP64;
3316            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
3317            break;
3318        case 13: //wep 104 Ascii type
3319            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
3320            memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
3321            CipherAlg = CIPHER_WEP128;
3322            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
3323            break;
3324        case 26: //wep 104 Hex type
3325            for(i=0; i < KeyLen; i++)
3326            {
3327                if( !isxdigit(*(arg+i)) )
3328                    return FALSE;  //Not Hex value;
3329            }
3330            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
3331            AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
3332            CipherAlg = CIPHER_WEP128;
3333            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
3334            break;
3335        default: //Invalid argument
3336            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
3337            return FALSE;
3338    }
3339
3340    pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
3341
3342    // Set keys (into ASIC)
3343    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3344        ;   // not support
3345    else    // Old WEP stuff
3346    {
3347        AsicAddSharedKeyEntry(pAdapter,
3348                              0,
3349                              0,
3350                              pAdapter->SharedKey[BSS0][0].CipherAlg,
3351                              pAdapter->SharedKey[BSS0][0].Key,
3352                              NULL,
3353                              NULL);
3354    }
3355
3356    return TRUE;
3357}
3358/*
3359    ==========================================================================
3360
3361    Description:
3362        Set WEP KEY2
3363    Return:
3364        TRUE if all parameters are OK, FALSE otherwise
3365    ==========================================================================
3366*/
3367INT Set_Key2_Proc(
3368    IN  PRTMP_ADAPTER   pAdapter,
3369    IN  PUCHAR          arg)
3370{
3371    int                                 KeyLen;
3372    int                                 i;
3373    UCHAR                               CipherAlg=CIPHER_WEP64;
3374
3375    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3376        return TRUE;    // do nothing
3377
3378    KeyLen = strlen(arg);
3379
3380    switch (KeyLen)
3381    {
3382        case 5: //wep 40 Ascii type
3383            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
3384            memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
3385            CipherAlg = CIPHER_WEP64;
3386            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
3387            break;
3388        case 10: //wep 40 Hex type
3389            for(i=0; i < KeyLen; i++)
3390            {
3391                if( !isxdigit(*(arg+i)) )
3392                    return FALSE;  //Not Hex value;
3393            }
3394            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
3395            AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
3396            CipherAlg = CIPHER_WEP64;
3397            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
3398            break;
3399        case 13: //wep 104 Ascii type
3400            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
3401            memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
3402            CipherAlg = CIPHER_WEP128;
3403            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
3404            break;
3405        case 26: //wep 104 Hex type
3406            for(i=0; i < KeyLen; i++)
3407            {
3408                if( !isxdigit(*(arg+i)) )
3409                    return FALSE;  //Not Hex value;
3410            }
3411            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
3412            AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
3413            CipherAlg = CIPHER_WEP128;
3414            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
3415            break;
3416        default: //Invalid argument
3417            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
3418            return FALSE;
3419    }
3420    pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
3421
3422    // Set keys (into ASIC)
3423    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3424        ;   // not support
3425    else    // Old WEP stuff
3426    {
3427        AsicAddSharedKeyEntry(pAdapter,
3428                              0,
3429                              1,
3430                              pAdapter->SharedKey[BSS0][1].CipherAlg,
3431                              pAdapter->SharedKey[BSS0][1].Key,
3432                              NULL,
3433                              NULL);
3434    }
3435
3436    return TRUE;
3437}
3438/*
3439    ==========================================================================
3440    Description:
3441        Set WEP KEY3
3442    Return:
3443        TRUE if all parameters are OK, FALSE otherwise
3444    ==========================================================================
3445*/
3446INT Set_Key3_Proc(
3447    IN  PRTMP_ADAPTER   pAdapter,
3448    IN  PUCHAR          arg)
3449{
3450    int                                 KeyLen;
3451    int                                 i;
3452    UCHAR                               CipherAlg=CIPHER_WEP64;
3453
3454    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3455        return TRUE;    // do nothing
3456
3457    KeyLen = strlen(arg);
3458
3459    switch (KeyLen)
3460    {
3461        case 5: //wep 40 Ascii type
3462            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
3463            memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
3464            CipherAlg = CIPHER_WEP64;
3465            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
3466            break;
3467        case 10: //wep 40 Hex type
3468            for(i=0; i < KeyLen; i++)
3469            {
3470                if( !isxdigit(*(arg+i)) )
3471                    return FALSE;  //Not Hex value;
3472            }
3473            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
3474            AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
3475            CipherAlg = CIPHER_WEP64;
3476            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
3477            break;
3478        case 13: //wep 104 Ascii type
3479            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
3480            memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
3481            CipherAlg = CIPHER_WEP128;
3482            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
3483            break;
3484        case 26: //wep 104 Hex type
3485            for(i=0; i < KeyLen; i++)
3486            {
3487                if( !isxdigit(*(arg+i)) )
3488                    return FALSE;  //Not Hex value;
3489            }
3490            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
3491            AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
3492            CipherAlg = CIPHER_WEP128;
3493            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
3494            break;
3495        default: //Invalid argument
3496            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
3497            return FALSE;
3498    }
3499    pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
3500
3501    // Set keys (into ASIC)
3502    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3503        ;   // not support
3504    else    // Old WEP stuff
3505    {
3506        AsicAddSharedKeyEntry(pAdapter,
3507                              0,
3508                              2,
3509                              pAdapter->SharedKey[BSS0][2].CipherAlg,
3510                              pAdapter->SharedKey[BSS0][2].Key,
3511                              NULL,
3512                              NULL);
3513    }
3514
3515    return TRUE;
3516}
3517/*
3518    ==========================================================================
3519    Description:
3520        Set WEP KEY4
3521    Return:
3522        TRUE if all parameters are OK, FALSE otherwise
3523    ==========================================================================
3524*/
3525INT Set_Key4_Proc(
3526    IN  PRTMP_ADAPTER   pAdapter,
3527    IN  PUCHAR          arg)
3528{
3529    int                                 KeyLen;
3530    int                                 i;
3531    UCHAR                               CipherAlg=CIPHER_WEP64;
3532
3533    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3534        return TRUE;    // do nothing
3535
3536    KeyLen = strlen(arg);
3537
3538    switch (KeyLen)
3539    {
3540        case 5: //wep 40 Ascii type
3541            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
3542            memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
3543            CipherAlg = CIPHER_WEP64;
3544            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
3545            break;
3546        case 10: //wep 40 Hex type
3547            for(i=0; i < KeyLen; i++)
3548            {
3549                if( !isxdigit(*(arg+i)) )
3550                    return FALSE;  //Not Hex value;
3551            }
3552            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
3553            AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
3554            CipherAlg = CIPHER_WEP64;
3555            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
3556            break;
3557        case 13: //wep 104 Ascii type
3558            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
3559            memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
3560            CipherAlg = CIPHER_WEP128;
3561            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
3562            break;
3563        case 26: //wep 104 Hex type
3564            for(i=0; i < KeyLen; i++)
3565            {
3566                if( !isxdigit(*(arg+i)) )
3567                    return FALSE;  //Not Hex value;
3568            }
3569            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
3570            AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
3571            CipherAlg = CIPHER_WEP128;
3572            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
3573            break;
3574        default: //Invalid argument
3575            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
3576            return FALSE;
3577    }
3578    pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
3579
3580    // Set keys (into ASIC)
3581    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3582        ;   // not support
3583    else    // Old WEP stuff
3584    {
3585        AsicAddSharedKeyEntry(pAdapter,
3586                              0,
3587                              3,
3588                              pAdapter->SharedKey[BSS0][3].CipherAlg,
3589                              pAdapter->SharedKey[BSS0][3].Key,
3590                              NULL,
3591                              NULL);
3592    }
3593
3594    return TRUE;
3595}
3596
3597/*
3598    ==========================================================================
3599    Description:
3600        Set WPA PSK key
3601    Return:
3602        TRUE if all parameters are OK, FALSE otherwise
3603    ==========================================================================
3604*/
3605INT Set_WPAPSK_Proc(
3606    IN  PRTMP_ADAPTER   pAdapter,
3607    IN  PUCHAR          arg)
3608{
3609    UCHAR                   keyMaterial[40];
3610
3611    if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
3612        (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
3613            (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
3614                )
3615        return TRUE;    // do nothing
3616
3617    DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
3618
3619    NdisZeroMemory(keyMaterial, 40);
3620
3621    if ((strlen(arg) < 8) || (strlen(arg) > 64))
3622    {
3623        DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
3624        return FALSE;
3625    }
3626
3627    if (strlen(arg) == 64)
3628    {
3629        AtoH(arg, keyMaterial, 32);
3630        NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
3631
3632    }
3633    else
3634    {
3635        PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
3636        NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
3637    }
3638
3639
3640
3641    if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
3642       pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
3643    {
3644         pAdapter->StaCfg.WpaState = SS_NOTUSE;
3645    }
3646    else
3647    {
3648        // Start STA supplicant state machine
3649        pAdapter->StaCfg.WpaState = SS_START;
3650    }
3651
3652    return TRUE;
3653}
3654
3655/*
3656    ==========================================================================
3657    Description:
3658        Set Power Saving mode
3659    Return:
3660        TRUE if all parameters are OK, FALSE otherwise
3661    ==========================================================================
3662*/
3663INT Set_PSMode_Proc(
3664    IN  PRTMP_ADAPTER   pAdapter,
3665    IN  PUCHAR          arg)
3666{
3667    if (pAdapter->StaCfg.BssType == BSS_INFRA)
3668    {
3669        if ((strcmp(arg, "Max_PSP") == 0) ||
3670                        (strcmp(arg, "max_psp") == 0) ||
3671                        (strcmp(arg, "MAX_PSP") == 0))
3672        {
3673            // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
3674            // to exclude certain situations.
3675            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
3676                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
3677            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
3678            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
3679            pAdapter->StaCfg.DefaultListenCount = 5;
3680
3681        }
3682        else if ((strcmp(arg, "Fast_PSP") == 0) ||
3683                                 (strcmp(arg, "fast_psp") == 0) ||
3684                 (strcmp(arg, "FAST_PSP") == 0))
3685        {
3686            // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
3687            // to exclude certain situations.
3688            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
3689            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
3690                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
3691            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
3692            pAdapter->StaCfg.DefaultListenCount = 3;
3693        }
3694        else if ((strcmp(arg, "Legacy_PSP") == 0) ||
3695                 (strcmp(arg, "legacy_psp") == 0) ||
3696                 (strcmp(arg, "LEGACY_PSP") == 0))
3697        {
3698            // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
3699            // to exclude certain situations.
3700            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
3701            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
3702                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
3703            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
3704            pAdapter->StaCfg.DefaultListenCount = 3;
3705        }
3706        else
3707        {
3708            //Default Ndis802_11PowerModeCAM
3709            // clear PSM bit immediately
3710            MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
3711            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
3712            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
3713                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
3714            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
3715        }
3716
3717        DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
3718    }
3719    else
3720        return FALSE;
3721
3722
3723    return TRUE;
3724}
3725
3726/*
3727    ==========================================================================
3728    Description:
3729        Set WpaSupport flag.
3730    Value:
3731        0: Driver ignore wpa_supplicant.
3732        1: wpa_supplicant initiates scanning and AP selection.
3733        2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
3734    Return:
3735        TRUE if all parameters are OK, FALSE otherwise
3736    ==========================================================================
3737*/
3738INT Set_Wpa_Support(
3739    IN  PRTMP_ADAPTER   pAd,
3740        IN      PUCHAR                  arg)
3741{
3742
3743    if ( simple_strtol(arg, 0, 10) == 0)
3744        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
3745    else if ( simple_strtol(arg, 0, 10) == 1)
3746        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
3747    else if ( simple_strtol(arg, 0, 10) == 2)
3748        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
3749    else
3750        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
3751
3752    DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
3753
3754    return TRUE;
3755}
3756
3757INT Set_TGnWifiTest_Proc(
3758    IN  PRTMP_ADAPTER   pAd,
3759    IN  PUCHAR          arg)
3760{
3761    if (simple_strtol(arg, 0, 10) == 0)
3762        pAd->StaCfg.bTGnWifiTest = FALSE;
3763    else
3764        pAd->StaCfg.bTGnWifiTest = TRUE;
3765
3766    DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
3767        return TRUE;
3768}
3769
3770INT Set_LongRetryLimit_Proc(
3771        IN      PRTMP_ADAPTER   pAdapter,
3772        IN      PUCHAR                  arg)
3773{
3774        TX_RTY_CFG_STRUC        tx_rty_cfg;
3775        UCHAR                           LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
3776
3777        RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
3778        tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
3779        RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
3780        DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
3781        return TRUE;
3782}
3783
3784INT Set_ShortRetryLimit_Proc(
3785        IN      PRTMP_ADAPTER   pAdapter,
3786        IN      PUCHAR                  arg)
3787{
3788        TX_RTY_CFG_STRUC        tx_rty_cfg;
3789        UCHAR                           ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
3790
3791        RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
3792        tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
3793        RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
3794        DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
3795        return TRUE;
3796}
3797