linux/drivers/staging/vt6656/iwctl.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
   3 * All rights reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License as published by
   7 * the Free Software Foundation; either version 2 of the License, or
   8 * (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License along
  16 * with this program; if not, write to the Free Software Foundation, Inc.,
  17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18 *
  19 * File: iwctl.c
  20 *
  21 * Purpose:  wireless ext & ioctl functions
  22 *
  23 * Author: Lyndon Chen
  24 *
  25 * Date: July 5, 2006
  26 *
  27 * Functions:
  28 *
  29 * Revision History:
  30 *
  31 */
  32
  33#include "device.h"
  34#include "ioctl.h"
  35#include "iocmd.h"
  36#include "mac.h"
  37#include "card.h"
  38#include "hostap.h"
  39#include "power.h"
  40#include "rf.h"
  41
  42#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
  43#include "iowpa.h"
  44#include "wpactl.h"
  45#endif
  46
  47#include <net/iw_handler.h>
  48
  49
  50/*---------------------  Static Definitions -------------------------*/
  51
  52//2008-0409-07, <Add> by Einsn Liu
  53#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
  54#define SUPPORTED_WIRELESS_EXT                  18
  55#else
  56#define SUPPORTED_WIRELESS_EXT                  17
  57#endif
  58
  59static const long frequency_list[] = {
  60    2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
  61    4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
  62    5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240,
  63    5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
  64    5700, 5745, 5765, 5785, 5805, 5825
  65        };
  66
  67
  68/*---------------------  Static Classes  ----------------------------*/
  69
  70
  71//static int          msglevel                =MSG_LEVEL_DEBUG;
  72static int          msglevel                =MSG_LEVEL_INFO;
  73
  74
  75/*---------------------  Static Variables  --------------------------*/
  76/*---------------------  Static Functions  --------------------------*/
  77
  78/*---------------------  Export Variables  --------------------------*/
  79
  80struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
  81{
  82        PSDevice pDevice = netdev_priv(dev);
  83        long ldBm;
  84
  85        pDevice->wstats.status = pDevice->eOPMode;
  86        #ifdef Calcu_LinkQual
  87         #if 0
  88          if(pDevice->byBBType == BB_TYPE_11B) {
  89             if(pDevice->byCurrSQ > 120)
  90                  pDevice->scStatistic.LinkQuality = 100;
  91             else
  92                 pDevice->scStatistic.LinkQuality = pDevice->byCurrSQ*100/120;
  93            }
  94          else if(pDevice->byBBType == BB_TYPE_11G) {
  95                if(pDevice->byCurrSQ < 20)
  96                   pDevice->scStatistic.LinkQuality = 100;
  97               else if(pDevice->byCurrSQ >96)
  98                   pDevice->scStatistic.LinkQuality  = 0;
  99               else
 100                   pDevice->scStatistic.LinkQuality = (96-pDevice->byCurrSQ)*100/76;
 101           }
 102           if(pDevice->bLinkPass !=TRUE)
 103               pDevice->scStatistic.LinkQuality = 0;
 104          #endif
 105           if(pDevice->scStatistic.LinkQuality > 100)
 106               pDevice->scStatistic.LinkQuality = 100;
 107               pDevice->wstats.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality;
 108        #else
 109        pDevice->wstats.qual.qual = pDevice->byCurrSQ;
 110        #endif
 111        RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
 112        pDevice->wstats.qual.level = ldBm;
 113        //pDevice->wstats.qual.level = 0x100 - pDevice->uCurrRSSI;
 114        pDevice->wstats.qual.noise = 0;
 115        pDevice->wstats.qual.updated = 1;
 116        pDevice->wstats.discard.nwid = 0;
 117        pDevice->wstats.discard.code = 0;
 118        pDevice->wstats.discard.fragment = 0;
 119        pDevice->wstats.discard.retries = pDevice->scStatistic.dwTsrErr;
 120        pDevice->wstats.discard.misc = 0;
 121        pDevice->wstats.miss.beacon = 0;
 122
 123        return &pDevice->wstats;
 124}
 125
 126
 127
 128/*------------------------------------------------------------------*/
 129
 130
 131static int iwctl_commit(struct net_device *dev,
 132                              struct iw_request_info *info,
 133                              void *wrq,
 134                              char *extra)
 135{
 136//2008-0409-02, <Mark> by Einsn Liu
 137/*
 138#ifdef Safe_Close
 139  PSDevice              pDevice = (PSDevice)netdev_priv(dev);
 140  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
 141        return -EINVAL;
 142#endif
 143*/
 144    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT \n");
 145
 146        return 0;
 147
 148}
 149
 150/*
 151 * Wireless Handler : get protocol name
 152 */
 153
 154int iwctl_giwname(struct net_device *dev,
 155                         struct iw_request_info *info,
 156                         char *wrq,
 157                         char *extra)
 158{
 159        strcpy(wrq, "802.11-a/b/g");
 160        return 0;
 161}
 162
 163int iwctl_giwnwid(struct net_device *dev,
 164             struct iw_request_info *info,
 165                         struct iw_param *wrq,
 166                   char *extra)
 167{
 168        //wrq->value = 0x100;
 169        //wrq->disabled = 0;
 170        //wrq->fixed = 1;
 171        //return 0;
 172  return -EOPNOTSUPP;
 173}
 174/*
 175 * Wireless Handler : set scan
 176 */
 177
 178int iwctl_siwscan(struct net_device *dev,
 179             struct iw_request_info *info,
 180                         struct iw_point *wrq,
 181             char *extra)
 182{
 183        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
 184         PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 185        struct iw_scan_req  *req = (struct iw_scan_req *)extra;
 186        BYTE                abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
 187        PWLAN_IE_SSID       pItemSSID=NULL;
 188
 189//2008-0920-01<Add>by MikeLiu
 190  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
 191        return -EINVAL;
 192
 193    PRINT_K(" SIOCSIWSCAN \n");
 194
 195if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
 196        // In scanning..
 197     PRINT_K("SIOCSIWSCAN(overlap??)-->In scanning...\n");
 198     return -EAGAIN;
 199  }
 200
 201if(pDevice->byReAssocCount > 0) {   //reject scan when re-associating!
 202//send scan event to wpa_Supplicant
 203  union iwreq_data wrqu;
 204 PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
 205 memset(&wrqu, 0, sizeof(wrqu));
 206 wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
 207  return 0;
 208}
 209
 210        spin_lock_irq(&pDevice->lock);
 211
 212   #ifdef update_BssList
 213        BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
 214   #endif
 215
 216//mike add: active scan OR passive scan OR desire_ssid scan
 217 if(wrq->length == sizeof(struct iw_scan_req)) {
 218   if (wrq->flags & IW_SCAN_THIS_ESSID)  {                               //desire_ssid scan
 219       memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
 220       pItemSSID = (PWLAN_IE_SSID)abyScanSSID;
 221       pItemSSID->byElementID = WLAN_EID_SSID;
 222       memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len);
 223         if (pItemSSID->abySSID[req->essid_len - 1] == '\0') {
 224           if(req->essid_len>0)
 225                pItemSSID->len = req->essid_len - 1;
 226         }
 227        else
 228          pItemSSID->len = req->essid_len;
 229          pMgmt->eScanType = WMAC_SCAN_PASSIVE;
 230         PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID,
 231                                                                                                        ((PWLAN_IE_SSID)abyScanSSID)->len);
 232        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID);
 233        spin_unlock_irq(&pDevice->lock);
 234
 235        return 0;
 236   }
 237   else if(req->scan_type == IW_SCAN_TYPE_PASSIVE) {          //passive scan
 238       pMgmt->eScanType = WMAC_SCAN_PASSIVE;
 239   }
 240 }
 241 else {           //active scan
 242     pMgmt->eScanType = WMAC_SCAN_ACTIVE;
 243 }
 244
 245         pMgmt->eScanType = WMAC_SCAN_PASSIVE;
 246         //printk("SIOCSIWSCAN:WLAN_CMD_BSSID_SCAN\n");
 247        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
 248        spin_unlock_irq(&pDevice->lock);
 249
 250        return 0;
 251}
 252
 253
 254/*
 255 * Wireless Handler : get scan results
 256 */
 257
 258int iwctl_giwscan(struct net_device *dev,
 259             struct iw_request_info *info,
 260                         struct iw_point *wrq,
 261             char *extra)
 262{
 263    int ii, jj, kk;
 264        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
 265    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 266    PKnownBSS           pBSS;
 267    PWLAN_IE_SSID       pItemSSID;
 268    PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates;
 269        char *current_ev = extra;
 270        char *end_buf = extra + IW_SCAN_MAX_DATA;
 271        char *current_val = NULL;
 272        struct iw_event iwe;
 273        long ldBm;
 274        char buf[MAX_WPA_IE_LEN * 2 + 30];
 275
 276//2008-0409-02, <Mark> by Einsn Liu
 277/*
 278#ifdef Safe_Close
 279  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
 280        return -EINVAL;
 281#endif
 282*/
 283    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN \n");
 284
 285    if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
 286        // In scanning..
 287                return -EAGAIN;
 288        }
 289        pBSS = &(pMgmt->sBSSList[0]);
 290    for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) {
 291                if (current_ev >= end_buf)
 292                        break;
 293        pBSS = &(pMgmt->sBSSList[jj]);
 294        if (pBSS->bActive) {
 295                //ADD mac address
 296                    memset(&iwe, 0, sizeof(iwe));
 297                    iwe.cmd = SIOCGIWAP;
 298                    iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
 299                        memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN);
 300                           current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
 301                 //ADD ssid
 302                     memset(&iwe, 0, sizeof(iwe));
 303                      iwe.cmd = SIOCGIWESSID;
 304                      pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
 305                       iwe.u.data.length = pItemSSID->len;
 306                       iwe.u.data.flags = 1;
 307                      current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID);
 308                //ADD mode
 309                    memset(&iwe, 0, sizeof(iwe));
 310                    iwe.cmd = SIOCGIWMODE;
 311            if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) {
 312                        iwe.u.mode = IW_MODE_INFRA;
 313            }
 314            else {
 315                iwe.u.mode = IW_MODE_ADHOC;
 316                    }
 317                iwe.len = IW_EV_UINT_LEN;
 318                      current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe,  IW_EV_UINT_LEN);
 319           //ADD frequency
 320            pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates;
 321            pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates;
 322            memset(&iwe, 0, sizeof(iwe));
 323                iwe.cmd = SIOCGIWFREQ;
 324                iwe.u.freq.m = pBSS->uChannel;
 325                iwe.u.freq.e = 0;
 326                iwe.u.freq.i = 0;
 327                  current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
 328            //2008-0409-04, <Add> by Einsn Liu
 329                        {
 330                        int f = (int)pBSS->uChannel - 1;
 331                        if(f < 0)f = 0;
 332                        iwe.u.freq.m = frequency_list[f] * 100000;
 333                        iwe.u.freq.e = 1;
 334                        }
 335                  current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
 336                //ADD quality
 337            memset(&iwe, 0, sizeof(iwe));
 338                iwe.cmd = IWEVQUAL;
 339                RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
 340                    iwe.u.qual.level = ldBm;
 341                iwe.u.qual.noise = 0;
 342//2008-0409-01, <Add> by Einsn Liu
 343                        if(-ldBm<50){
 344                                iwe.u.qual.qual = 100;
 345                        }else  if(-ldBm > 90) {
 346                                 iwe.u.qual.qual = 0;
 347                        }else {
 348                                iwe.u.qual.qual=(40-(-ldBm-50))*100/40;
 349                        }
 350                        iwe.u.qual.updated=7;
 351
 352//2008-0409-01, <Mark> by Einsn Liu
 353/*
 354//2008-0220-03, <Modify>  by Einsn Liu
 355        if(pDevice->bLinkPass== TRUE && IS_ETH_ADDRESS_EQUAL(pBSS->abyBSSID, pMgmt->abyCurrBSSID)){
 356        #ifdef Calcu_LinkQual
 357         #if 0
 358          if(pDevice->byBBType == BB_TYPE_11B) {
 359             if(pDevice->byCurrSQ > 120)
 360                  pDevice->scStatistic.LinkQuality = 100;
 361             else
 362                 pDevice->scStatistic.LinkQuality = pDevice->byCurrSQ*100/120;
 363            }
 364          else if(pDevice->byBBType == BB_TYPE_11G) {
 365                if(pDevice->byCurrSQ < 20)
 366                   pDevice->scStatistic.LinkQuality = 100;
 367               else if(pDevice->byCurrSQ >96)
 368                   pDevice->scStatistic.LinkQuality  = 0;
 369               else
 370                   pDevice->scStatistic.LinkQuality = (96-pDevice->byCurrSQ)*100/76;
 371           }
 372           if(pDevice->bLinkPass !=TRUE)
 373               pDevice->scStatistic.LinkQuality = 0;
 374          #endif
 375           if(pDevice->scStatistic.LinkQuality > 100)
 376               pDevice->scStatistic.LinkQuality = 100;
 377              iwe.u.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality;
 378        #else
 379        iwe.u.qual.qual = pDevice->byCurrSQ;
 380        #endif
 381                }else {
 382                iwe.u.qual.qual = 0;
 383                }
 384*/
 385                 current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
 386        //ADD encryption
 387            memset(&iwe, 0, sizeof(iwe));
 388            iwe.cmd = SIOCGIWENCODE;
 389            iwe.u.data.length = 0;
 390            if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) {
 391                iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
 392            }else {
 393                iwe.u.data.flags = IW_ENCODE_DISABLED;
 394            }
 395            current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID);
 396
 397            memset(&iwe, 0, sizeof(iwe));
 398            iwe.cmd = SIOCGIWRATE;
 399                iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
 400                current_val = current_ev + IW_EV_LCP_LEN;
 401
 402                for (kk = 0 ; kk < 12 ; kk++) {
 403                        if (pSuppRates->abyRates[kk] == 0)
 404                                break;
 405                        // Bit rate given in 500 kb/s units (+ 0x80)
 406                        iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000);
 407                          current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
 408                }
 409                for (kk = 0 ; kk < 8 ; kk++) {
 410                        if (pExtSuppRates->abyRates[kk] == 0)
 411                                break;
 412                        // Bit rate given in 500 kb/s units (+ 0x80)
 413                        iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000);
 414                         current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
 415                }
 416
 417                if((current_val - current_ev) > IW_EV_LCP_LEN)
 418                        current_ev = current_val;
 419
 420            memset(&iwe, 0, sizeof(iwe));
 421            iwe.cmd = IWEVCUSTOM;
 422            sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval);
 423            iwe.u.data.length = strlen(buf);
 424             current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf);
 425
 426            if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) {
 427                memset(&iwe, 0, sizeof(iwe));
 428                iwe.cmd = IWEVGENIE;
 429                iwe.u.data.length = pBSS->wWPALen;
 430                current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byWPAIE);
 431            }
 432
 433            if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) {
 434                memset(&iwe, 0, sizeof(iwe));
 435                iwe.cmd = IWEVGENIE;
 436                iwe.u.data.length = pBSS->wRSNLen;
 437                current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byRSNIE);
 438            }
 439
 440        }
 441    }// for
 442
 443        wrq->length = current_ev - extra;
 444        return 0;
 445
 446}
 447
 448
 449/*
 450 * Wireless Handler : set frequence or channel
 451 */
 452
 453int iwctl_siwfreq(struct net_device *dev,
 454             struct iw_request_info *info,
 455             struct iw_freq *wrq,
 456             char *extra)
 457{
 458        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
 459        int rc = 0;
 460
 461    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n");
 462
 463        // If setting by frequency, convert to a channel
 464        if((wrq->e == 1) &&
 465           (wrq->m >= (int) 2.412e8) &&
 466           (wrq->m <= (int) 2.487e8)) {
 467                int f = wrq->m / 100000;
 468                int c = 0;
 469                while((c < 14) && (f != frequency_list[c]))
 470                        c++;
 471                wrq->e = 0;
 472                wrq->m = c + 1;
 473        }
 474        // Setting by channel number
 475        if((wrq->m > 14) || (wrq->e > 0))
 476                rc = -EOPNOTSUPP;
 477        else {
 478                int channel = wrq->m;
 479                if((channel < 1) || (channel > 14)) {
 480                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m);
 481                        rc = -EINVAL;
 482                } else {
 483                          // Yes ! We can set it !!!
 484              DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel);
 485                          pDevice->uChannel = channel;
 486                }
 487        }
 488
 489        return rc;
 490}
 491
 492/*
 493 * Wireless Handler : get frequence or channel
 494 */
 495
 496int iwctl_giwfreq(struct net_device *dev,
 497             struct iw_request_info *info,
 498             struct iw_freq *wrq,
 499             char *extra)
 500{
 501        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
 502    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 503
 504    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n");
 505
 506#ifdef WEXT_USECHANNELS
 507        wrq->m = (int)pMgmt->uCurrChannel;
 508        wrq->e = 0;
 509#else
 510        {
 511                int f = (int)pMgmt->uCurrChannel - 1;
 512                if(f < 0)
 513                   f = 0;
 514                wrq->m = frequency_list[f] * 100000;
 515                wrq->e = 1;
 516        }
 517#endif
 518
 519        return 0;
 520}
 521
 522/*
 523 * Wireless Handler : set operation mode
 524 */
 525
 526int iwctl_siwmode(struct net_device *dev,
 527             struct iw_request_info *info,
 528             __u32 *wmode,
 529             char *extra)
 530{
 531        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
 532    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 533    int rc = 0;
 534
 535    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n");
 536
 537    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) {
 538        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Can't set operation mode, hostapd is running \n");
 539        return rc;
 540    }
 541
 542        switch(*wmode) {
 543
 544        case IW_MODE_ADHOC:
 545            if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) {
 546            pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
 547            if (pDevice->flags & DEVICE_FLAGS_OPENED) {
 548                        pDevice->bCommit = TRUE;
 549                    }
 550                }
 551        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n");
 552                break;
 553        case IW_MODE_AUTO:
 554        case IW_MODE_INFRA:
 555            if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) {
 556            pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
 557            if (pDevice->flags & DEVICE_FLAGS_OPENED) {
 558                        pDevice->bCommit = TRUE;
 559                    }
 560                }
 561        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n");
 562                break;
 563        case IW_MODE_MASTER:
 564
 565        pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
 566                rc = -EOPNOTSUPP;
 567                break;
 568
 569            if (pMgmt->eConfigMode != WMAC_CONFIG_AP) {
 570            pMgmt->eConfigMode = WMAC_CONFIG_AP;
 571            if (pDevice->flags & DEVICE_FLAGS_OPENED) {
 572                        pDevice->bCommit = TRUE;
 573                    }
 574                }
 575        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n");
 576                break;
 577
 578        case IW_MODE_REPEAT:
 579        pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
 580                rc = -EOPNOTSUPP;
 581                break;
 582        default:
 583                rc = -EINVAL;
 584        }
 585
 586        return rc;
 587}
 588
 589/*
 590 * Wireless Handler : get operation mode
 591 */
 592
 593int iwctl_giwmode(struct net_device *dev,
 594             struct iw_request_info *info,
 595             __u32 *wmode,
 596             char *extra)
 597{
 598        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
 599    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 600
 601
 602    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n");
 603        // If not managed, assume it's ad-hoc
 604        switch (pMgmt->eConfigMode) {
 605        case WMAC_CONFIG_ESS_STA:
 606                *wmode = IW_MODE_INFRA;
 607                break;
 608        case WMAC_CONFIG_IBSS_STA:
 609        *wmode = IW_MODE_ADHOC;
 610                break;
 611        case WMAC_CONFIG_AUTO:
 612                *wmode = IW_MODE_INFRA;
 613                break;
 614        case WMAC_CONFIG_AP:
 615                *wmode = IW_MODE_MASTER;
 616                break;
 617        default:
 618                *wmode = IW_MODE_ADHOC;
 619        }
 620
 621        return 0;
 622}
 623
 624
 625/*
 626 * Wireless Handler : get capability range
 627 */
 628
 629int iwctl_giwrange(struct net_device *dev,
 630             struct iw_request_info *info,
 631             struct iw_point *wrq,
 632             char *extra)
 633{
 634        struct iw_range *range = (struct iw_range *) extra;
 635        int             i,k;
 636    BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
 637//2008-0409-02, <Mark> by Einsn Liu
 638/*
 639 #ifdef Safe_Close
 640  PSDevice              pDevice = (PSDevice)netdev_priv(dev);
 641  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
 642        return -EINVAL;
 643#endif
 644 */
 645
 646    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE \n");
 647        if (wrq->pointer) {
 648                wrq->length = sizeof(struct iw_range);
 649                memset(range, 0, sizeof(struct iw_range));
 650                range->min_nwid = 0x0000;
 651                range->max_nwid = 0x0000;
 652                range->num_channels = 14;
 653                // Should be based on cap_rid.country to give only
 654                //  what the current card support
 655                k = 0;
 656                for(i = 0; i < 14; i++) {
 657                        range->freq[k].i = i + 1; // List index
 658                        range->freq[k].m = frequency_list[i] * 100000;
 659                        range->freq[k++].e = 1; // Values in table in MHz -> * 10^5 * 10
 660                }
 661                range->num_frequency = k;
 662                // Hum... Should put the right values there
 663             #ifdef Calcu_LinkQual
 664                 range->max_qual.qual = 100;
 665             #else
 666                range->max_qual.qual = 255;
 667             #endif
 668                range->max_qual.level = 0;
 669                range->max_qual.noise = 0;
 670                range->sensitivity = 255;
 671
 672                for(i = 0 ; i < 13 ; i++) {
 673                        range->bitrate[i] = abySupportedRates[i] * 500000;
 674                        if(range->bitrate[i] == 0)
 675                                break;
 676                }
 677                range->num_bitrates = i;
 678
 679                // Set an indication of the max TCP throughput
 680                // in bit/s that we can expect using this interface.
 681                //  May be use for QoS stuff... Jean II
 682                if(i > 2)
 683                        range->throughput = 5 * 1000 * 1000;
 684                else
 685                        range->throughput = 1.5 * 1000 * 1000;
 686
 687                range->min_rts = 0;
 688                range->max_rts = 2312;
 689                range->min_frag = 256;
 690                range->max_frag = 2312;
 691
 692
 693            // the encoding capabilities
 694            range->num_encoding_sizes = 3;
 695            // 64(40) bits WEP
 696            range->encoding_size[0] = 5;
 697            // 128(104) bits WEP
 698            range->encoding_size[1] = 13;
 699            // 256 bits for WPA-PSK
 700            range->encoding_size[2] = 32;
 701            // 4 keys are allowed
 702            range->max_encoding_tokens = 4;
 703
 704            range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
 705                    IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
 706
 707                range->min_pmp = 0;
 708                range->max_pmp = 1000000;// 1 secs
 709                range->min_pmt = 0;
 710                range->max_pmt = 1000000;// 1 secs
 711                range->pmp_flags = IW_POWER_PERIOD;
 712                range->pmt_flags = IW_POWER_TIMEOUT;
 713                range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
 714
 715                // Transmit Power - values are in mW
 716
 717        range->txpower[0] = 100;
 718                range->num_txpower = 1;
 719                range->txpower_capa = IW_TXPOW_MWATT;
 720                range->we_version_source = SUPPORTED_WIRELESS_EXT;
 721                range->we_version_compiled = WIRELESS_EXT;
 722                range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
 723                range->retry_flags = IW_RETRY_LIMIT;
 724                range->r_time_flags = IW_RETRY_LIFETIME;
 725                range->min_retry = 1;
 726                range->max_retry = 65535;
 727                range->min_r_time = 1024;
 728                range->max_r_time = 65535 * 1024;
 729                // Experimental measurements - boundary 11/5.5 Mb/s
 730                // Note : with or without the (local->rssi), results
 731                //  are somewhat different. - Jean II
 732                range->avg_qual.qual = 6;
 733                range->avg_qual.level = 176;    // -80 dBm
 734                range->avg_qual.noise = 0;
 735        }
 736
 737
 738        return 0;
 739}
 740
 741
 742/*
 743 * Wireless Handler : set ap mac address
 744 */
 745
 746int iwctl_siwap(struct net_device *dev,
 747             struct iw_request_info *info,
 748                         struct sockaddr *wrq,
 749             char *extra)
 750{
 751        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
 752    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 753    int rc = 0;
 754    BYTE                 ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
 755
 756   PRINT_K(" SIOCSIWAP \n");
 757
 758        if (wrq->sa_family != ARPHRD_ETHER)
 759                rc = -EINVAL;
 760        else {
 761                memset(pMgmt->abyDesireBSSID, 0xFF, 6);
 762                memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6);
 763
 764        //mike :add
 765         if ((IS_BROADCAST_ADDRESS(pMgmt->abyDesireBSSID)) ||
 766             (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){
 767              PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n");
 768               return rc;
 769         }
 770       //mike add: if desired AP is hidden ssid(there are two same BSSID in list),
 771       //                  then ignore,because you don't known which one to be connect with??
 772        {
 773           UINT            ii , uSameBssidNum=0;
 774                  for (ii = 0; ii < MAX_BSS_NUM; ii++) {
 775                     if (pMgmt->sBSSList[ii].bActive &&
 776                        IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID,pMgmt->abyDesireBSSID)) {
 777                        uSameBssidNum++;
 778                     }
 779                  }
 780             if(uSameBssidNum >= 2) {  //hit: desired AP is in hidden ssid mode!!!
 781                 PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n");
 782                return rc;
 783             }
 784        }
 785
 786        if (pDevice->flags & DEVICE_FLAGS_OPENED) {
 787                    pDevice->bCommit = TRUE;
 788                }
 789        }
 790        return rc;
 791}
 792
 793/*
 794 * Wireless Handler : get ap mac address
 795 */
 796
 797int iwctl_giwap(struct net_device *dev,
 798             struct iw_request_info *info,
 799                         struct sockaddr *wrq,
 800             char *extra)
 801{
 802        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
 803    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 804
 805
 806    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n");
 807
 808    memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
 809
 810//20080123-02,<Modify> by Einsn Liu
 811 if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP))
 812 //   if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode == WMAC_MODE_ESS_STA))
 813        memset(wrq->sa_data, 0, 6);
 814
 815    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
 816        memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
 817    }
 818
 819        wrq->sa_family = ARPHRD_ETHER;
 820
 821        return 0;
 822
 823}
 824
 825
 826/*
 827 * Wireless Handler : get ap list
 828 */
 829
 830int iwctl_giwaplist(struct net_device *dev,
 831             struct iw_request_info *info,
 832             struct iw_point *wrq,
 833             char *extra)
 834{
 835        int ii,jj, rc = 0;
 836        struct sockaddr sock[IW_MAX_AP];
 837        struct iw_quality qual[IW_MAX_AP];
 838        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
 839    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 840
 841
 842    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n");
 843        // Only super-user can see AP list
 844
 845        if (!capable(CAP_NET_ADMIN)) {
 846                rc = -EPERM;
 847                return rc;
 848        }
 849
 850        if (wrq->pointer) {
 851
 852                PKnownBSS pBSS = &(pMgmt->sBSSList[0]);
 853
 854                for (ii = 0, jj= 0; ii < MAX_BSS_NUM; ii++) {
 855                    pBSS = &(pMgmt->sBSSList[ii]);
 856            if (!pBSS->bActive)
 857                continue;
 858            if ( jj >= IW_MAX_AP)
 859                break;
 860                        memcpy(sock[jj].sa_data, pBSS->abyBSSID, 6);
 861                        sock[jj].sa_family = ARPHRD_ETHER;
 862                        qual[jj].level = pBSS->uRSSI;
 863                        qual[jj].qual = qual[jj].noise = 0;
 864                        qual[jj].updated = 2;
 865                        jj++;
 866                }
 867
 868                wrq->flags = 1; // Should be define'd
 869                wrq->length = jj;
 870                memcpy(extra, sock, sizeof(struct sockaddr)*jj);
 871                memcpy(extra + sizeof(struct sockaddr)*jj, qual, sizeof(struct iw_quality)*jj);
 872        }
 873
 874        return rc;
 875}
 876
 877
 878/*
 879 * Wireless Handler : set essid
 880 */
 881
 882int iwctl_siwessid(struct net_device *dev,
 883             struct iw_request_info *info,
 884             struct iw_point *wrq,
 885             char *extra)
 886{
 887        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
 888    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 889    PWLAN_IE_SSID       pItemSSID;
 890
 891//2008-0920-01<Add>by MikeLiu
 892  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
 893        return -EINVAL;
 894
 895    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID :\n");
 896
 897         pDevice->fWPA_Authened = FALSE;
 898        // Check if we asked for `any'
 899        if(wrq->flags == 0) {
 900                // Just send an empty SSID list
 901                memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
 902                  memset(pMgmt->abyDesireBSSID, 0xFF,6);
 903            PRINT_K("set essid to 'any' \n");
 904           #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
 905             //Unknown desired AP,so here need not associate??
 906                  return 0;
 907            #endif
 908        } else {
 909                // Set the SSID
 910                memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
 911        pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
 912        pItemSSID->byElementID = WLAN_EID_SSID;
 913
 914                memcpy(pItemSSID->abySSID, extra, wrq->length);
 915         if (pItemSSID->abySSID[wrq->length - 1] == '\0') {
 916           if(wrq->length>0)
 917                pItemSSID->len = wrq->length - 1;
 918         }
 919        else
 920          pItemSSID->len = wrq->length;
 921        PRINT_K("set essid to %s \n",pItemSSID->abySSID);
 922
 923     //mike:need clear desiredBSSID
 924     if(pItemSSID->len==0) {
 925        memset(pMgmt->abyDesireBSSID, 0xFF,6);
 926        return 0;
 927     }
 928
 929#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
 930 //Wext wil order another command of siwap to link with desired AP,
 931 //so here need not associate??
 932  if(pDevice->bWPASuppWextEnabled == TRUE)  {
 933        /*******search if  in hidden ssid mode ****/
 934        {
 935           PKnownBSS       pCurr = NULL;
 936           BYTE                   abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
 937          UINT            ii , uSameBssidNum=0;
 938
 939          memset(abyTmpDesireSSID,0,sizeof(abyTmpDesireSSID));
 940          memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID));
 941            pCurr = BSSpSearchBSSList(pDevice,
 942                                      NULL,
 943                                      abyTmpDesireSSID,
 944                                      pDevice->eConfigPHYMode
 945                                      );
 946
 947            if (pCurr == NULL){
 948               PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n");
 949              vResetCommandTimer((HANDLE) pDevice);
 950              pMgmt->eScanType = WMAC_SCAN_ACTIVE;
 951               bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
 952              bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID);
 953          }
 954         else {  //mike:to find out if that desired SSID is a hidden-ssid AP ,
 955                     //         by means of judging if there are two same BSSID exist in list ?
 956                  for (ii = 0; ii < MAX_BSS_NUM; ii++) {
 957                     if (pMgmt->sBSSList[ii].bActive &&
 958                        IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) {
 959                        uSameBssidNum++;
 960                     }
 961                  }
 962             if(uSameBssidNum >= 2) {  //hit: desired AP is in hidden ssid mode!!!
 963                 PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n");
 964                vResetCommandTimer((HANDLE) pDevice);
 965                pMgmt->eScanType = WMAC_SCAN_PASSIVE;          //this scan type,you'll submit scan result!
 966                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
 967                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID);
 968             }
 969         }
 970        }
 971     return 0;
 972  }
 973             #endif
 974
 975            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
 976        }
 977
 978    if (pDevice->flags & DEVICE_FLAGS_OPENED) {
 979            pDevice->bCommit = TRUE;
 980        }
 981
 982
 983        return 0;
 984}
 985
 986
 987/*
 988 * Wireless Handler : get essid
 989 */
 990
 991int iwctl_giwessid(struct net_device *dev,
 992             struct iw_request_info *info,
 993             struct iw_point *wrq,
 994             char *extra)
 995{
 996
 997        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
 998    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 999        PWLAN_IE_SSID       pItemSSID;
1000
1001    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n");
1002
1003        // Note : if wrq->u.data.flags != 0, we should
1004        // get the relevant SSID from the SSID list...
1005
1006        // Get the current SSID
1007    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
1008        //pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
1009        memcpy(extra, pItemSSID->abySSID , pItemSSID->len);
1010        extra[pItemSSID->len] = '\0';
1011        //2008-0409-03, <Add> by Einsn Liu
1012        wrq->length = pItemSSID->len;
1013        wrq->flags = 1; // active
1014
1015
1016        return 0;
1017}
1018
1019/*
1020 * Wireless Handler : set data rate
1021 */
1022
1023int iwctl_siwrate(struct net_device *dev,
1024             struct iw_request_info *info,
1025                         struct iw_param *wrq,
1026             char *extra)
1027{
1028        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
1029    int rc = 0;
1030        u8      brate = 0;
1031        int     i;
1032        BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
1033
1034
1035    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n");
1036    if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1037        rc = -EINVAL;
1038        return rc;
1039    }
1040
1041        // First : get a valid bit rate value
1042
1043        // Which type of value
1044        if((wrq->value < 13) &&
1045           (wrq->value >= 0)) {
1046                // Setting by rate index
1047                // Find value in the magic rate table
1048                brate = wrq->value;
1049        } else {
1050                // Setting by frequency value
1051                u8      normvalue = (u8) (wrq->value/500000);
1052
1053                // Check if rate is valid
1054                for(i = 0 ; i < 13 ; i++) {
1055                        if(normvalue == abySupportedRates[i]) {
1056                                brate = i;
1057                                break;
1058                        }
1059                }
1060        }
1061        // -1 designed the max rate (mostly auto mode)
1062        if(wrq->value == -1) {
1063                // Get the highest available rate
1064                for(i = 0 ; i < 13 ; i++) {
1065                        if(abySupportedRates[i] == 0)
1066                                break;
1067                }
1068                if(i != 0)
1069                        brate = i - 1;
1070
1071        }
1072        // Check that it is valid
1073        // brate is index of abySupportedRates[]
1074        if(brate > 13 ) {
1075                rc = -EINVAL;
1076                return rc;
1077        }
1078
1079        // Now, check if we want a fixed or auto value
1080        if(wrq->fixed != 0) {
1081                // Fixed mode
1082                // One rate, fixed
1083                pDevice->bFixRate = TRUE;
1084        if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) {
1085            pDevice->uConnectionRate = 3;
1086        }
1087        else {
1088            pDevice->uConnectionRate = brate;
1089            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate);
1090        }
1091
1092        }
1093        else {
1094        pDevice->bFixRate = FALSE;
1095        pDevice->uConnectionRate = 13;
1096    }
1097
1098        return rc;
1099}
1100
1101/*
1102 * Wireless Handler : get data rate
1103 */
1104
1105int iwctl_giwrate(struct net_device *dev,
1106             struct iw_request_info *info,
1107             struct iw_param *wrq,
1108             char *extra)
1109{
1110        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
1111    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1112
1113    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n");
1114    {
1115        BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
1116            int brate = 0;
1117                if (pDevice->uConnectionRate < 13) {
1118                brate = abySupportedRates[pDevice->uConnectionRate];
1119            }else {
1120            if (pDevice->byBBType == BB_TYPE_11B)
1121                    brate = 0x16;
1122            if (pDevice->byBBType == BB_TYPE_11G)
1123                    brate = 0x6C;
1124            if (pDevice->byBBType == BB_TYPE_11A)
1125                    brate = 0x6C;
1126            }
1127
1128            if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1129            if (pDevice->byBBType == BB_TYPE_11B)
1130                    brate = 0x16;
1131            if (pDevice->byBBType == BB_TYPE_11G)
1132                    brate = 0x6C;
1133            if (pDevice->byBBType == BB_TYPE_11A)
1134                    brate = 0x6C;
1135            }
1136                if (pDevice->uConnectionRate == 13)
1137                brate = abySupportedRates[pDevice->wCurrentRate];
1138            wrq->value = brate * 500000;
1139            // If more than one rate, set auto
1140            if (pDevice->bFixRate == TRUE)
1141                wrq->fixed = TRUE;
1142    }
1143
1144
1145        return 0;
1146}
1147
1148
1149
1150/*
1151 * Wireless Handler : set rts threshold
1152 */
1153
1154int iwctl_siwrts(struct net_device *dev,
1155             struct iw_request_info *info,
1156                         struct iw_param *wrq,
1157             char *extra)
1158{
1159        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
1160        int rc = 0;
1161
1162    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS \n");
1163
1164        {
1165            int rthr = wrq->value;
1166            if(wrq->disabled)
1167                        rthr = 2312;
1168            if((rthr < 0) || (rthr > 2312)) {
1169                        rc = -EINVAL;
1170        }else {
1171                    pDevice->wRTSThreshold = rthr;
1172            }
1173    }
1174
1175        return 0;
1176}
1177
1178/*
1179 * Wireless Handler : get rts
1180 */
1181
1182int iwctl_giwrts(struct net_device *dev,
1183             struct iw_request_info *info,
1184                         struct iw_param *wrq,
1185             char *extra)
1186{
1187        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
1188
1189    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n");
1190        wrq->value = pDevice->wRTSThreshold;
1191        wrq->disabled = (wrq->value >= 2312);
1192        wrq->fixed = 1;
1193
1194        return 0;
1195}
1196
1197/*
1198 * Wireless Handler : set fragment threshold
1199 */
1200
1201int iwctl_siwfrag(struct net_device *dev,
1202             struct iw_request_info *info,
1203                         struct iw_param *wrq,
1204             char *extra)
1205{
1206    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1207    int rc = 0;
1208    int fthr = wrq->value;
1209
1210
1211    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n");
1212
1213
1214    if (wrq->disabled)
1215                fthr = 2312;
1216    if((fthr < 256) || (fthr > 2312)) {
1217                rc = -EINVAL;
1218    }else {
1219                 fthr &= ~0x1;  // Get an even value
1220             pDevice->wFragmentationThreshold = (u16)fthr;
1221    }
1222
1223        return rc;
1224}
1225
1226/*
1227 * Wireless Handler : get fragment threshold
1228 */
1229
1230int iwctl_giwfrag(struct net_device *dev,
1231             struct iw_request_info *info,
1232                         struct iw_param *wrq,
1233             char *extra)
1234{
1235    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1236
1237    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n");
1238        wrq->value = pDevice->wFragmentationThreshold;
1239        wrq->disabled = (wrq->value >= 2312);
1240        wrq->fixed = 1;
1241
1242        return 0;
1243}
1244
1245
1246
1247/*
1248 * Wireless Handler : set retry threshold
1249 */
1250int iwctl_siwretry(struct net_device *dev,
1251             struct iw_request_info *info,
1252                         struct iw_param *wrq,
1253             char *extra)
1254{
1255    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1256    int rc = 0;
1257
1258
1259    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n");
1260
1261        if (wrq->disabled) {
1262                rc = -EINVAL;
1263                return rc;
1264        }
1265
1266        if (wrq->flags & IW_RETRY_LIMIT) {
1267                if(wrq->flags & IW_RETRY_MAX)
1268                        pDevice->byLongRetryLimit = wrq->value;
1269                else if (wrq->flags & IW_RETRY_MIN)
1270                        pDevice->byShortRetryLimit = wrq->value;
1271                else {
1272                        // No modifier : set both
1273                        pDevice->byShortRetryLimit = wrq->value;
1274                        pDevice->byLongRetryLimit = wrq->value;
1275                }
1276        }
1277        if (wrq->flags & IW_RETRY_LIFETIME) {
1278                pDevice->wMaxTransmitMSDULifetime = wrq->value;
1279        }
1280
1281
1282        return rc;
1283}
1284
1285/*
1286 * Wireless Handler : get retry threshold
1287 */
1288int iwctl_giwretry(struct net_device *dev,
1289             struct iw_request_info *info,
1290                         struct iw_param *wrq,
1291             char *extra)
1292{
1293    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1294    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n");
1295        wrq->disabled = 0;      // Can't be disabled
1296
1297        // Note : by default, display the min retry number
1298        if((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1299                wrq->flags = IW_RETRY_LIFETIME;
1300                wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; //ms
1301        } else if((wrq->flags & IW_RETRY_MAX)) {
1302                wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
1303                wrq->value = (int)pDevice->byLongRetryLimit;
1304        } else {
1305                wrq->flags = IW_RETRY_LIMIT;
1306                wrq->value = (int)pDevice->byShortRetryLimit;
1307                if((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit)
1308                        wrq->flags |= IW_RETRY_MIN;
1309        }
1310
1311
1312        return 0;
1313}
1314
1315
1316/*
1317 * Wireless Handler : set encode mode
1318 */
1319int iwctl_siwencode(struct net_device *dev,
1320             struct iw_request_info *info,
1321             struct iw_point *wrq,
1322             char *extra)
1323{
1324    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1325    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1326        DWORD dwKeyIndex = (DWORD)(wrq->flags & IW_ENCODE_INDEX);
1327        int ii,uu, rc = 0;
1328        int index = (wrq->flags & IW_ENCODE_INDEX);
1329
1330
1331    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n");
1332
1333        // Check the size of the key
1334        if (wrq->length > WLAN_WEP232_KEYLEN) {
1335                rc = -EINVAL;
1336        return rc;
1337        }
1338
1339        if (dwKeyIndex > WLAN_WEP_NKEYS) {
1340                rc = -EINVAL;
1341        return rc;
1342    }
1343
1344    if (dwKeyIndex > 0)
1345                dwKeyIndex--;
1346
1347        // Send the key to the card
1348        if (wrq->length > 0) {
1349
1350        if (wrq->length ==  WLAN_WEP232_KEYLEN) {
1351            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
1352        }
1353        else if (wrq->length ==  WLAN_WEP104_KEYLEN) {
1354            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
1355        }
1356        else if (wrq->length == WLAN_WEP40_KEYLEN) {
1357            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
1358        }
1359        memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN);
1360        memcpy(pDevice->abyKey, extra, wrq->length);
1361
1362        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
1363        for (ii = 0; ii < wrq->length; ii++) {
1364            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
1365        }
1366
1367        if (pDevice->flags & DEVICE_FLAGS_OPENED) {
1368            spin_lock_irq(&pDevice->lock);
1369            KeybSetDefaultKey(  pDevice,
1370                                &(pDevice->sKey),
1371                                dwKeyIndex | (1 << 31),
1372                                wrq->length,
1373                                NULL,
1374                                pDevice->abyKey,
1375                                KEY_CTL_WEP
1376                              );
1377            spin_unlock_irq(&pDevice->lock);
1378        }
1379        pDevice->byKeyIndex = (BYTE)dwKeyIndex;
1380        pDevice->uKeyLength = wrq->length;
1381        pDevice->bTransmitKey = TRUE;
1382        pDevice->bEncryptionEnable = TRUE;
1383        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1384
1385                // Do we want to just set the transmit key index ?
1386                if ( index < 4 ) {
1387                    pDevice->byKeyIndex = index;
1388                } else if (!(wrq->flags & IW_ENCODE_MODE)) {
1389                                rc = -EINVAL;
1390                                return rc;
1391            }
1392        }
1393        // Read the flags
1394        if(wrq->flags & IW_ENCODE_DISABLED){
1395
1396        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
1397                pMgmt->bShareKeyAlgorithm = FALSE;
1398        pDevice->bEncryptionEnable = FALSE;
1399        pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1400        if (pDevice->flags & DEVICE_FLAGS_OPENED) {
1401            spin_lock_irq(&pDevice->lock);
1402            for(uu=0;uu<MAX_KEY_TABLE;uu++)
1403                MACvDisableKeyEntry(pDevice,uu);
1404            spin_unlock_irq(&pDevice->lock);
1405        }
1406        }
1407        if(wrq->flags & IW_ENCODE_RESTRICTED) {
1408        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
1409                pMgmt->bShareKeyAlgorithm = TRUE;
1410        }
1411        if(wrq->flags & IW_ENCODE_OPEN) {
1412            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
1413                pMgmt->bShareKeyAlgorithm = FALSE;
1414        }
1415
1416#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1417           memset(pMgmt->abyDesireBSSID, 0xFF,6);
1418#endif
1419
1420        return rc;
1421}
1422
1423/*
1424 * Wireless Handler : get encode mode
1425 */
1426//2008-0409-06, <Mark> by Einsn Liu
1427 /*
1428int iwctl_giwencode(struct net_device *dev,
1429             struct iw_request_info *info,
1430             struct iw_point *wrq,
1431             char *extra)
1432{
1433    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1434    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1435    int rc = 0;
1436    char abyKey[WLAN_WEP232_KEYLEN];
1437        UINT index = (UINT)(wrq->flags & IW_ENCODE_INDEX);
1438        PSKeyItem   pKey = NULL;
1439
1440    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
1441
1442
1443        memset(abyKey, 0, sizeof(abyKey));
1444        // Check encryption mode
1445        wrq->flags = IW_ENCODE_NOKEY;
1446        // Is WEP enabled ???
1447        if (pDevice->bEncryptionEnable)
1448                wrq->flags |=  IW_ENCODE_ENABLED;
1449    else
1450                wrq->flags |=  IW_ENCODE_DISABLED;
1451
1452    if (pMgmt->bShareKeyAlgorithm)
1453                wrq->flags |=  IW_ENCODE_RESTRICTED;
1454        else
1455                wrq->flags |=  IW_ENCODE_OPEN;
1456
1457        if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
1458        wrq->length = pKey->uKeyLength;
1459        memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
1460    }
1461    else {
1462        rc = -EINVAL;
1463        return rc;
1464    }
1465        wrq->flags |= index;
1466        // Copy the key to the user buffer
1467        memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
1468        return 0;
1469}
1470*/
1471
1472//2008-0409-06, <Add> by Einsn Liu
1473
1474int iwctl_giwencode(struct net_device *dev,
1475                        struct iw_request_info *info,
1476                        struct iw_point *wrq,
1477                        char *extra)
1478{
1479        PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1480        PSMgmtObject            pMgmt = &(pDevice->sMgmtObj);
1481        char abyKey[WLAN_WEP232_KEYLEN];
1482
1483        UINT index = (UINT)(wrq->flags & IW_ENCODE_INDEX);
1484        PSKeyItem       pKey = NULL;
1485
1486        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
1487
1488        if (index > WLAN_WEP_NKEYS) {
1489                return  -EINVAL;
1490        }
1491        if(index<1){//get default key
1492                if(pDevice->byKeyIndex<WLAN_WEP_NKEYS){
1493                        index=pDevice->byKeyIndex;
1494                } else
1495                      index=0;
1496        }else
1497             index--;
1498
1499        memset(abyKey, 0, WLAN_WEP232_KEYLEN);
1500        // Check encryption mode
1501        wrq->flags = IW_ENCODE_NOKEY;
1502        // Is WEP enabled ???
1503        if (pDevice->bEncryptionEnable)
1504                wrq->flags |=  IW_ENCODE_ENABLED;
1505        else
1506                wrq->flags |=  IW_ENCODE_DISABLED;
1507
1508        if (pMgmt->bShareKeyAlgorithm)
1509                wrq->flags |=  IW_ENCODE_RESTRICTED;
1510        else
1511                wrq->flags |=  IW_ENCODE_OPEN;
1512                wrq->length=0;
1513
1514        if((index==0)&&(pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled||
1515                pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){//get wpa pairwise  key
1516                        if (KeybGetKey(&(pDevice->sKey),pMgmt->abyCurrBSSID, 0xffffffff, &pKey)){
1517                           wrq->length = pKey->uKeyLength;
1518                                  memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
1519                                  memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
1520                           }
1521        }else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
1522                        wrq->length = pKey->uKeyLength;
1523                        memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
1524                memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
1525        }
1526
1527        wrq->flags |= index+1;
1528
1529        return 0;
1530}
1531
1532
1533/*
1534 * Wireless Handler : set power mode
1535 */
1536int iwctl_siwpower(struct net_device *dev,
1537             struct iw_request_info *info,
1538                         struct iw_param *wrq,
1539             char *extra)
1540{
1541    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1542    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1543    int rc = 0;
1544
1545    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n");
1546
1547    if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1548                 rc = -EINVAL;
1549                 return rc;
1550        }
1551
1552        if (wrq->disabled) {
1553                pDevice->ePSMode = WMAC_POWER_CAM;
1554                PSvDisablePowerSaving(pDevice);
1555                return rc;
1556        }
1557        if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1558         pDevice->ePSMode = WMAC_POWER_FAST;
1559         PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval);
1560
1561        } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
1562             pDevice->ePSMode = WMAC_POWER_FAST;
1563         PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval);
1564        }
1565        switch (wrq->flags & IW_POWER_MODE) {
1566        case IW_POWER_UNICAST_R:
1567        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
1568                rc = -EINVAL;
1569                break;
1570        case IW_POWER_ALL_R:
1571        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
1572                rc = -EINVAL;
1573        case IW_POWER_ON:
1574        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n");
1575                break;
1576        default:
1577                rc = -EINVAL;
1578        }
1579
1580        return rc;
1581}
1582
1583/*
1584 * Wireless Handler : get power mode
1585 */
1586int iwctl_giwpower(struct net_device *dev,
1587             struct iw_request_info *info,
1588                         struct iw_param *wrq,
1589             char *extra)
1590{
1591    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1592    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1593    int mode = pDevice->ePSMode;
1594
1595
1596    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n");
1597
1598
1599        if ((wrq->disabled = (mode == WMAC_POWER_CAM)))
1600            return 0;
1601
1602        if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1603                wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
1604                wrq->flags = IW_POWER_TIMEOUT;
1605        } else {
1606                wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
1607                wrq->flags = IW_POWER_PERIOD;
1608        }
1609        wrq->flags |= IW_POWER_ALL_R;
1610
1611        return 0;
1612}
1613
1614
1615/*
1616 * Wireless Handler : get Sensitivity
1617 */
1618int iwctl_giwsens(struct net_device *dev,
1619                         struct iw_request_info *info,
1620                         struct iw_param *wrq,
1621                         char *extra)
1622{
1623    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1624    long ldBm;
1625
1626    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n");
1627    if (pDevice->bLinkPass == TRUE) {
1628        RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
1629            wrq->value = ldBm;
1630        }
1631        else {
1632            wrq->value = 0;
1633    };
1634        wrq->disabled = (wrq->value == 0);
1635        wrq->fixed = 1;
1636
1637
1638        return 0;
1639}
1640
1641//2008-0409-07, <Add> by Einsn Liu
1642#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1643
1644int iwctl_siwauth(struct net_device *dev,
1645                          struct iw_request_info *info,
1646                          struct iw_param *wrq,
1647                          char *extra)
1648{
1649        PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1650        PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1651        int ret=0;
1652        static int wpa_version=0;  //must be static to save the last value,einsn liu
1653        static int pairwise=0;
1654
1655    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
1656        switch (wrq->flags & IW_AUTH_INDEX) {
1657        case IW_AUTH_WPA_VERSION:
1658                wpa_version = wrq->value;
1659                if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
1660                       PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
1661                        //pDevice->bWPADEVUp = FALSE;
1662                }
1663                else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) {
1664                          PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
1665                }
1666                else {
1667                          PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
1668                }
1669                //pDevice->bWPASuppWextEnabled =TRUE;
1670                break;
1671        case IW_AUTH_CIPHER_PAIRWISE:
1672                pairwise = wrq->value;
1673                   PRINT_K("iwctl_siwauth:set pairwise=%d\n",pairwise);
1674                if(pairwise == IW_AUTH_CIPHER_CCMP){
1675                        pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
1676                }else if(pairwise == IW_AUTH_CIPHER_TKIP){
1677                        pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
1678                }else if(pairwise == IW_AUTH_CIPHER_WEP40||pairwise == IW_AUTH_CIPHER_WEP104){
1679                        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1680                }else if(pairwise == IW_AUTH_CIPHER_NONE){
1681                        //do nothing,einsn liu
1682                }else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1683
1684                break;
1685        case IW_AUTH_CIPHER_GROUP:
1686                 PRINT_K("iwctl_siwauth:set GROUP=%d\n",wrq->value);
1687                if(wpa_version == IW_AUTH_WPA_VERSION_DISABLED)
1688                        break;
1689                if(pairwise == IW_AUTH_CIPHER_NONE){
1690                        if(wrq->value == IW_AUTH_CIPHER_CCMP){
1691                                pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
1692                        }else {
1693                                pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
1694                        }
1695                }
1696                break;
1697        case IW_AUTH_KEY_MGMT:
1698                    PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n",wpa_version,wrq->value);
1699                if(wpa_version == IW_AUTH_WPA_VERSION_WPA2){
1700                        if(wrq->value == IW_AUTH_KEY_MGMT_PSK)
1701                                pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
1702                        else pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
1703                }else if(wpa_version == IW_AUTH_WPA_VERSION_WPA){
1704                        if(wrq->value == 0){
1705                                pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
1706                        }else if(wrq->value == IW_AUTH_KEY_MGMT_PSK)
1707                                pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
1708                        else pMgmt->eAuthenMode = WMAC_AUTH_WPA;
1709                }
1710
1711                break;
1712        case IW_AUTH_TKIP_COUNTERMEASURES:
1713                break;          /* FIXME */
1714        case IW_AUTH_DROP_UNENCRYPTED:
1715                break;
1716        case IW_AUTH_80211_AUTH_ALG:
1717                 PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n",wrq->value);
1718                if(wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){
1719                        pMgmt->bShareKeyAlgorithm=FALSE;
1720                }else if(wrq->value==IW_AUTH_ALG_SHARED_KEY){
1721                        pMgmt->bShareKeyAlgorithm=TRUE;
1722                }
1723                break;
1724        case IW_AUTH_WPA_ENABLED:
1725                //pDevice->bWPADEVUp = !! wrq->value;
1726                //if(pDevice->bWPADEVUp==TRUE)
1727                  // printk("iwctl_siwauth:set WPADEV to enable sucessful*******\n");
1728                //else
1729                 //  printk("iwctl_siwauth:set WPADEV to enable fail?????\n");
1730                break;
1731        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1732                break;
1733        case IW_AUTH_ROAMING_CONTROL:
1734                ret = -EOPNOTSUPP;
1735                break;
1736        case IW_AUTH_PRIVACY_INVOKED:
1737                pDevice->bEncryptionEnable = !!wrq->value;
1738                if(pDevice->bEncryptionEnable == FALSE){
1739                        wpa_version = 0;
1740                        pairwise = 0;
1741                        pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1742                        pMgmt->bShareKeyAlgorithm = FALSE;
1743                        pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
1744                        //pDevice->bWPADEVUp = FALSE;
1745                         PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n");
1746                }
1747
1748                break;
1749        default:
1750                ret = -EOPNOTSUPP;
1751                break;
1752        }
1753/*
1754        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_version = %d\n",wpa_version);
1755        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise = %d\n",pairwise);
1756        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->eEncryptionStatus = %d\n",pDevice->eEncryptionStatus);
1757        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->eAuthenMode  = %d\n",pMgmt->eAuthenMode);
1758        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->bShareKeyAlgorithm = %s\n",pMgmt->bShareKeyAlgorithm?"TRUE":"FALSE");
1759        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bEncryptionEnable = %s\n",pDevice->bEncryptionEnable?"TRUE":"FALSE");
1760        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bWPADEVUp = %s\n",pDevice->bWPADEVUp?"TRUE":"FALSE");
1761*/
1762   return ret;
1763}
1764
1765
1766int iwctl_giwauth(struct net_device *dev,
1767                          struct iw_request_info *info,
1768                          struct iw_param *wrq,
1769                          char *extra)
1770{
1771        return -EOPNOTSUPP;
1772}
1773
1774
1775
1776int iwctl_siwgenie(struct net_device *dev,
1777                          struct iw_request_info *info,
1778                          struct iw_point *wrq,
1779                          char *extra)
1780{
1781        PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1782        PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1783        int ret=0;
1784
1785        if(wrq->length){
1786                if ((wrq->length < 2) || (extra[1]+2 != wrq->length)) {
1787                        ret = -EINVAL;
1788                        goto out;
1789                }
1790                if(wrq->length > MAX_WPA_IE_LEN){
1791                        ret = -ENOMEM;
1792                        goto out;
1793                }
1794                memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
1795                if(copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)){
1796                        ret = -EFAULT;
1797                        goto out;
1798                }
1799                pMgmt->wWPAIELen = wrq->length;
1800        }else {
1801                memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
1802                pMgmt->wWPAIELen = 0;
1803        }
1804
1805        out://not completely ...not necessary in wpa_supplicant 0.5.8
1806        return 0;
1807}
1808
1809int iwctl_giwgenie(struct net_device *dev,
1810                          struct iw_request_info *info,
1811                          struct iw_point *wrq,
1812                          char *extra)
1813{
1814        PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1815        PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1816        int ret=0;
1817        int space = wrq->length;
1818
1819        wrq->length = 0;
1820        if(pMgmt->wWPAIELen > 0){
1821                wrq->length = pMgmt->wWPAIELen;
1822                if(pMgmt->wWPAIELen <= space){
1823                        if(copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)){
1824                                ret = -EFAULT;
1825                        }
1826                }else
1827                        ret = -E2BIG;
1828        }
1829
1830        return ret;
1831}
1832
1833
1834int iwctl_siwencodeext(struct net_device *dev,
1835             struct iw_request_info *info,
1836             struct iw_point *wrq,
1837             char *extra)
1838{
1839    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1840    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1841        struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
1842    struct viawget_wpa_param *param=NULL;
1843//original member
1844    wpa_alg alg_name;
1845    u8  addr[6];
1846    int key_idx, set_tx=0;
1847    u8  seq[IW_ENCODE_SEQ_MAX_SIZE];
1848    u8 key[64];
1849    size_t seq_len=0,key_len=0;
1850//
1851   // int ii;
1852    u8 *buf;
1853    size_t blen;
1854    u8 key_array[64];
1855    int ret=0;
1856
1857PRINT_K("SIOCSIWENCODEEXT...... \n");
1858
1859blen = sizeof(*param);
1860buf = kmalloc((int)blen, (int)GFP_KERNEL);
1861if (buf == NULL)
1862    return -ENOMEM;
1863memset(buf, 0, blen);
1864param = (struct viawget_wpa_param *) buf;
1865
1866//recover alg_name
1867switch (ext->alg) {
1868    case IW_ENCODE_ALG_NONE:
1869                  alg_name = WPA_ALG_NONE;
1870                break;
1871    case IW_ENCODE_ALG_WEP:
1872                  alg_name = WPA_ALG_WEP;
1873                break;
1874    case IW_ENCODE_ALG_TKIP:
1875                  alg_name = WPA_ALG_TKIP;
1876                break;
1877    case IW_ENCODE_ALG_CCMP:
1878                  alg_name = WPA_ALG_CCMP;
1879                break;
1880    default:
1881                PRINT_K("Unknown alg = %d\n",ext->alg);
1882                ret= -ENOMEM;
1883                goto error;
1884                }
1885//recover addr
1886 memcpy(addr, ext->addr.sa_data, ETH_ALEN);
1887//recover key_idx
1888  key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1;
1889//recover set_tx
1890if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1891   set_tx = 1;
1892//recover seq,seq_len
1893        if(ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
1894   seq_len=IW_ENCODE_SEQ_MAX_SIZE;
1895   memcpy(seq, ext->rx_seq, seq_len);
1896                }
1897//recover key,key_len
1898if(ext->key_len) {
1899  key_len=ext->key_len;
1900  memcpy(key, &ext->key[0], key_len);
1901        }
1902
1903memset(key_array, 0, 64);
1904if ( key_len > 0) {
1905     memcpy(key_array, key, key_len);
1906    if (key_len == 32) {
1907          // notice ! the oder
1908          memcpy(&key_array[16], &key[24], 8);
1909          memcpy(&key_array[24], &key[16], 8);
1910        }
1911        }
1912
1913/**************Translate iw_encode_ext to viawget_wpa_param****************/
1914memcpy(param->addr, addr, ETH_ALEN);
1915param->u.wpa_key.alg_name = (int)alg_name;
1916param->u.wpa_key.set_tx = set_tx;
1917param->u.wpa_key.key_index = key_idx;
1918param->u.wpa_key.key_len = key_len;
1919param->u.wpa_key.key = (u8 *)key_array;
1920param->u.wpa_key.seq = (u8 *)seq;
1921param->u.wpa_key.seq_len = seq_len;
1922
1923#if 0
1924printk("param->u.wpa_key.alg_name =%d\n",param->u.wpa_key.alg_name);
1925printk("param->addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
1926              param->addr[0],param->addr[1],param->addr[2],
1927              param->addr[3],param->addr[4],param->addr[5]);
1928printk("param->u.wpa_key.set_tx =%d\n",param->u.wpa_key.set_tx);
1929printk("param->u.wpa_key.key_index =%d\n",param->u.wpa_key.key_index);
1930printk("param->u.wpa_key.key_len =%d\n",param->u.wpa_key.key_len);
1931printk("param->u.wpa_key.key =");
1932for(ii=0;ii<param->u.wpa_key.key_len;ii++)
1933        printk("%02x:",param->u.wpa_key.key[ii]);
1934         printk("\n");
1935printk("param->u.wpa_key.seq_len =%d\n",param->u.wpa_key.seq_len);
1936printk("param->u.wpa_key.seq =");
1937for(ii=0;ii<param->u.wpa_key.seq_len;ii++)
1938        printk("%02x:",param->u.wpa_key.seq[ii]);
1939         printk("\n");
1940
1941printk("...........\n");
1942#endif
1943//****set if current action is Network Manager count??
1944//****this method is so foolish,but there is no other way???
1945if(param->u.wpa_key.alg_name == WPA_ALG_NONE) {
1946   if(param->u.wpa_key.key_index ==0) {
1947     pDevice->bwextstep0 = TRUE;
1948    }
1949   if((pDevice->bwextstep0 = TRUE)&&(param->u.wpa_key.key_index ==1)) {
1950     pDevice->bwextstep0 = FALSE;
1951     pDevice->bwextstep1 = TRUE;
1952    }
1953   if((pDevice->bwextstep1 = TRUE)&&(param->u.wpa_key.key_index ==2)) {
1954     pDevice->bwextstep1 = FALSE;
1955     pDevice->bwextstep2 = TRUE;
1956        }
1957   if((pDevice->bwextstep2 = TRUE)&&(param->u.wpa_key.key_index ==3)) {
1958     pDevice->bwextstep2 = FALSE;
1959     pDevice->bwextstep3 = TRUE;
1960        }
1961                 }
1962if(pDevice->bwextstep3 == TRUE) {
1963    PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
1964     pDevice->bwextstep0 = FALSE;
1965     pDevice->bwextstep1 = FALSE;
1966     pDevice->bwextstep2 = FALSE;
1967     pDevice->bwextstep3 = FALSE;
1968     pDevice->bWPASuppWextEnabled = TRUE;
1969     memset(pMgmt->abyDesireBSSID, 0xFF,6);
1970     KeyvInitTable(pDevice,&pDevice->sKey);
1971                 }
1972//******
1973
1974                spin_lock_irq(&pDevice->lock);
1975 ret = wpa_set_keys(pDevice, param, TRUE);
1976                spin_unlock_irq(&pDevice->lock);
1977
1978error:
1979kfree(param);
1980        return ret;
1981}
1982
1983
1984
1985int iwctl_giwencodeext(struct net_device *dev,
1986             struct iw_request_info *info,
1987             struct iw_point *wrq,
1988             char *extra)
1989{
1990                return -EOPNOTSUPP;;
1991}
1992
1993int iwctl_siwmlme(struct net_device *dev,
1994                                struct iw_request_info * info,
1995                                struct iw_point *wrq,
1996                                char *extra)
1997{
1998        PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1999        PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
2000        struct iw_mlme *mlme = (struct iw_mlme *)extra;
2001        //u16 reason = cpu_to_le16(mlme->reason_code);
2002        int ret = 0;
2003
2004        if(memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)){
2005                ret = -EINVAL;
2006                return ret;
2007        }
2008        switch(mlme->cmd){
2009        case IW_MLME_DEAUTH:
2010                //this command seems to be not complete,please test it --einsnliu
2011                //printk("iwctl_siwmlme--->send DEAUTH\n");
2012                //bScheduleCommand((HANDLE) pDevice, WLAN_CMD_DEAUTH, (PBYTE)&reason);
2013                //break;
2014        case IW_MLME_DISASSOC:
2015                if(pDevice->bLinkPass == TRUE){
2016                  PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n");
2017                  bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
2018                }
2019                break;
2020        default:
2021                ret = -EOPNOTSUPP;
2022        }
2023
2024        return ret;
2025
2026}
2027
2028#endif
2029//End Add --//2008-0409-07, <Add> by Einsn Liu
2030
2031
2032
2033/*------------------------------------------------------------------*/
2034/*
2035 * Structures to export the Wireless Handlers
2036 */
2037
2038
2039/*
2040static const iw_handler         iwctl_handler[] =
2041{
2042        (iw_handler) iwctl_commit,      // SIOCSIWCOMMIT
2043        (iw_handler) iwctl_giwname,     // SIOCGIWNAME
2044        (iw_handler) NULL,                              // SIOCSIWNWID
2045        (iw_handler) NULL,                              // SIOCGIWNWID
2046        (iw_handler) iwctl_siwfreq,             // SIOCSIWFREQ
2047        (iw_handler) iwctl_giwfreq,             // SIOCGIWFREQ
2048        (iw_handler) iwctl_siwmode,             // SIOCSIWMODE
2049        (iw_handler) iwctl_giwmode,             // SIOCGIWMODE
2050        (iw_handler) NULL,                      // SIOCSIWSENS
2051        (iw_handler) iwctl_giwsens,                     // SIOCGIWSENS
2052        (iw_handler) NULL,                      // SIOCSIWRANGE
2053        (iw_handler) iwctl_giwrange,            // SIOCGIWRANGE
2054        (iw_handler) NULL,                          // SIOCSIWPRIV
2055        (iw_handler) NULL,                      // SIOCGIWPRIV
2056        (iw_handler) NULL,                      // SIOCSIWSTATS
2057        (iw_handler) NULL,                  // SIOCGIWSTATS
2058    (iw_handler) NULL,                  // SIOCSIWSPY
2059        (iw_handler) NULL,                          // SIOCGIWSPY
2060        (iw_handler) NULL,                                  // -- hole --
2061        (iw_handler) NULL,                                  // -- hole --
2062        (iw_handler) iwctl_siwap,                   // SIOCSIWAP
2063        (iw_handler) iwctl_giwap,                   // SIOCGIWAP
2064        (iw_handler) NULL,                                  // -- hole -- 0x16
2065        (iw_handler) iwctl_giwaplist,       // SIOCGIWAPLIST
2066        (iw_handler) iwctl_siwscan,         // SIOCSIWSCAN
2067        (iw_handler) iwctl_giwscan,         // SIOCGIWSCAN
2068        (iw_handler) iwctl_siwessid,            // SIOCSIWESSID
2069        (iw_handler) iwctl_giwessid,            // SIOCGIWESSID
2070        (iw_handler) NULL,              // SIOCSIWNICKN
2071        (iw_handler) NULL,              // SIOCGIWNICKN
2072        (iw_handler) NULL,                                  // -- hole --
2073        (iw_handler) NULL,                                  // -- hole --
2074        (iw_handler) iwctl_siwrate,             // SIOCSIWRATE 0x20
2075        (iw_handler) iwctl_giwrate,             // SIOCGIWRATE
2076        (iw_handler) iwctl_siwrts,              // SIOCSIWRTS
2077        (iw_handler) iwctl_giwrts,              // SIOCGIWRTS
2078        (iw_handler) iwctl_siwfrag,             // SIOCSIWFRAG
2079        (iw_handler) iwctl_giwfrag,             // SIOCGIWFRAG
2080        (iw_handler) NULL,              // SIOCSIWTXPOW
2081        (iw_handler) NULL,              // SIOCGIWTXPOW
2082        (iw_handler) iwctl_siwretry,            // SIOCSIWRETRY
2083        (iw_handler) iwctl_giwretry,            // SIOCGIWRETRY
2084        (iw_handler) iwctl_siwencode,           // SIOCSIWENCODE
2085        (iw_handler) iwctl_giwencode,           // SIOCGIWENCODE
2086        (iw_handler) iwctl_siwpower,            // SIOCSIWPOWER
2087        (iw_handler) iwctl_giwpower,            // SIOCGIWPOWER
2088        (iw_handler) NULL,                      // -- hole --
2089        (iw_handler) NULL,                      // -- hole --
2090        (iw_handler) iwctl_siwgenie,    // SIOCSIWGENIE
2091        (iw_handler) iwctl_giwgenie,    // SIOCGIWGENIE
2092        (iw_handler) iwctl_siwauth,             // SIOCSIWAUTH
2093        (iw_handler) iwctl_giwauth,             // SIOCGIWAUTH
2094        (iw_handler) iwctl_siwencodeext,                // SIOCSIWENCODEEXT
2095        (iw_handler) iwctl_giwencodeext,                // SIOCGIWENCODEEXT
2096        (iw_handler) NULL,                              // SIOCSIWPMKSA
2097        (iw_handler) NULL,                              // -- hole --
2098
2099};
2100*/
2101
2102static const iw_handler         iwctl_handler[] =
2103{
2104        (iw_handler) iwctl_commit,      // SIOCSIWCOMMIT
2105        (iw_handler) NULL,      // SIOCGIWNAME
2106        (iw_handler) NULL,                              // SIOCSIWNWID
2107        (iw_handler) NULL,                              // SIOCGIWNWID
2108        (iw_handler) NULL,              // SIOCSIWFREQ
2109        (iw_handler) NULL,              // SIOCGIWFREQ
2110        (iw_handler) NULL,              // SIOCSIWMODE
2111        (iw_handler) NULL,              // SIOCGIWMODE
2112        (iw_handler) NULL,                      // SIOCSIWSENS
2113        (iw_handler) NULL,                      // SIOCGIWSENS
2114        (iw_handler) NULL,                      // SIOCSIWRANGE
2115        (iw_handler) iwctl_giwrange,            // SIOCGIWRANGE
2116        (iw_handler) NULL,                          // SIOCSIWPRIV
2117        (iw_handler) NULL,                      // SIOCGIWPRIV
2118        (iw_handler) NULL,                      // SIOCSIWSTATS
2119        (iw_handler) NULL,                  // SIOCGIWSTATS
2120    (iw_handler) NULL,                  // SIOCSIWSPY
2121        (iw_handler) NULL,                          // SIOCGIWSPY
2122        (iw_handler) NULL,                                  // -- hole --
2123        (iw_handler) NULL,                                  // -- hole --
2124        (iw_handler) NULL,                  // SIOCSIWAP
2125        (iw_handler) NULL,                  // SIOCGIWAP
2126        (iw_handler) NULL,                                  // -- hole -- 0x16
2127        (iw_handler) NULL,       // SIOCGIWAPLIST
2128        (iw_handler) iwctl_siwscan,         // SIOCSIWSCAN
2129        (iw_handler) iwctl_giwscan,         // SIOCGIWSCAN
2130        (iw_handler) NULL,              // SIOCSIWESSID
2131        (iw_handler) NULL,              // SIOCGIWESSID
2132        (iw_handler) NULL,              // SIOCSIWNICKN
2133        (iw_handler) NULL,              // SIOCGIWNICKN
2134        (iw_handler) NULL,              // -- hole --
2135        (iw_handler) NULL,              // -- hole --
2136        (iw_handler) NULL,              // SIOCSIWRATE 0x20
2137        (iw_handler) NULL,              // SIOCGIWRATE
2138        (iw_handler) NULL,              // SIOCSIWRTS
2139        (iw_handler) NULL,              // SIOCGIWRTS
2140        (iw_handler) NULL,              // SIOCSIWFRAG
2141        (iw_handler) NULL,              // SIOCGIWFRAG
2142        (iw_handler) NULL,              // SIOCSIWTXPOW
2143        (iw_handler) NULL,              // SIOCGIWTXPOW
2144        (iw_handler) NULL,              // SIOCSIWRETRY
2145        (iw_handler) NULL,              // SIOCGIWRETRY
2146        (iw_handler) NULL,              // SIOCSIWENCODE
2147        (iw_handler) NULL,              // SIOCGIWENCODE
2148        (iw_handler) NULL,              // SIOCSIWPOWER
2149        (iw_handler) NULL,              // SIOCGIWPOWER
2150        (iw_handler) NULL,                      // -- hole --
2151        (iw_handler) NULL,                      // -- hole --
2152        (iw_handler) NULL,    // SIOCSIWGENIE
2153        (iw_handler) NULL,    // SIOCGIWGENIE
2154        (iw_handler) NULL,              // SIOCSIWAUTH
2155        (iw_handler) NULL,              // SIOCGIWAUTH
2156        (iw_handler) NULL,              // SIOCSIWENCODEEXT
2157        (iw_handler) NULL,              // SIOCGIWENCODEEXT
2158        (iw_handler) NULL,                              // SIOCSIWPMKSA
2159        (iw_handler) NULL,                              // -- hole --
2160};
2161
2162
2163static const iw_handler         iwctl_private_handler[] =
2164{
2165        NULL,                           // SIOCIWFIRSTPRIV
2166};
2167
2168
2169struct iw_priv_args iwctl_private_args[] = {
2170{ IOCTL_CMD_SET,
2171  IW_PRIV_TYPE_CHAR | 1024, 0,
2172  "set"},
2173};
2174
2175
2176
2177const struct iw_handler_def     iwctl_handler_def =
2178{
2179        .get_wireless_stats = &iwctl_get_wireless_stats,
2180        .num_standard   = sizeof(iwctl_handler)/sizeof(iw_handler),
2181//      .num_private    = sizeof(iwctl_private_handler)/sizeof(iw_handler),
2182//      .num_private_args = sizeof(iwctl_private_args)/sizeof(struct iw_priv_args),
2183        .num_private    = 0,
2184        .num_private_args = 0,
2185        .standard       = (iw_handler *) iwctl_handler,
2186//      .private        = (iw_handler *) iwctl_private_handler,
2187//      .private_args   = (struct iw_priv_args *)iwctl_private_args,
2188        .private        = NULL,
2189        .private_args   = NULL,
2190};
2191