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((void *) 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((void *) 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((void *) 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                memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6);
 762
 763        //mike :add
 764         if ((IS_BROADCAST_ADDRESS(pMgmt->abyDesireBSSID)) ||
 765             (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){
 766              PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n");
 767               return rc;
 768         }
 769       //mike add: if desired AP is hidden ssid(there are two same BSSID in list),
 770       //                  then ignore,because you don't known which one to be connect with??
 771        {
 772                unsigned int ii, uSameBssidNum = 0;
 773                  for (ii = 0; ii < MAX_BSS_NUM; ii++) {
 774                     if (pMgmt->sBSSList[ii].bActive &&
 775                        IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID,pMgmt->abyDesireBSSID)) {
 776                        uSameBssidNum++;
 777                     }
 778                  }
 779             if(uSameBssidNum >= 2) {  //hit: desired AP is in hidden ssid mode!!!
 780                 PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n");
 781                return rc;
 782             }
 783        }
 784
 785        if (pDevice->flags & DEVICE_FLAGS_OPENED) {
 786                    pDevice->bCommit = TRUE;
 787                }
 788        }
 789        return rc;
 790}
 791
 792/*
 793 * Wireless Handler : get ap mac address
 794 */
 795
 796int iwctl_giwap(struct net_device *dev,
 797             struct iw_request_info *info,
 798                         struct sockaddr *wrq,
 799             char *extra)
 800{
 801        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
 802    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 803
 804
 805    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n");
 806
 807    memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
 808
 809//20080123-02,<Modify> by Einsn Liu
 810 if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP))
 811 //   if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode == WMAC_MODE_ESS_STA))
 812        memset(wrq->sa_data, 0, 6);
 813
 814    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
 815        memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
 816    }
 817
 818        wrq->sa_family = ARPHRD_ETHER;
 819
 820        return 0;
 821
 822}
 823
 824
 825/*
 826 * Wireless Handler : get ap list
 827 */
 828
 829int iwctl_giwaplist(struct net_device *dev,
 830             struct iw_request_info *info,
 831             struct iw_point *wrq,
 832             char *extra)
 833{
 834        int ii,jj, rc = 0;
 835        struct sockaddr sock[IW_MAX_AP];
 836        struct iw_quality qual[IW_MAX_AP];
 837        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
 838    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 839
 840
 841    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n");
 842        // Only super-user can see AP list
 843
 844        if (!capable(CAP_NET_ADMIN)) {
 845                rc = -EPERM;
 846                return rc;
 847        }
 848
 849        if (wrq->pointer) {
 850
 851                PKnownBSS pBSS = &(pMgmt->sBSSList[0]);
 852
 853                for (ii = 0, jj= 0; ii < MAX_BSS_NUM; ii++) {
 854                    pBSS = &(pMgmt->sBSSList[ii]);
 855            if (!pBSS->bActive)
 856                continue;
 857            if ( jj >= IW_MAX_AP)
 858                break;
 859                        memcpy(sock[jj].sa_data, pBSS->abyBSSID, 6);
 860                        sock[jj].sa_family = ARPHRD_ETHER;
 861                        qual[jj].level = pBSS->uRSSI;
 862                        qual[jj].qual = qual[jj].noise = 0;
 863                        qual[jj].updated = 2;
 864                        jj++;
 865                }
 866
 867                wrq->flags = 1; // Should be define'd
 868                wrq->length = jj;
 869                memcpy(extra, sock, sizeof(struct sockaddr)*jj);
 870                memcpy(extra + sizeof(struct sockaddr)*jj, qual, sizeof(struct iw_quality)*jj);
 871        }
 872
 873        return rc;
 874}
 875
 876
 877/*
 878 * Wireless Handler : set essid
 879 */
 880
 881int iwctl_siwessid(struct net_device *dev,
 882             struct iw_request_info *info,
 883             struct iw_point *wrq,
 884             char *extra)
 885{
 886        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
 887    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 888    PWLAN_IE_SSID       pItemSSID;
 889
 890//2008-0920-01<Add>by MikeLiu
 891  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
 892        return -EINVAL;
 893
 894    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID :\n");
 895
 896         pDevice->fWPA_Authened = FALSE;
 897        // Check if we asked for `any'
 898        if(wrq->flags == 0) {
 899                // Just send an empty SSID list
 900                memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
 901                  memset(pMgmt->abyDesireBSSID, 0xFF,6);
 902            PRINT_K("set essid to 'any' \n");
 903           #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
 904             //Unknown desired AP,so here need not associate??
 905                  return 0;
 906            #endif
 907        } else {
 908                // Set the SSID
 909                memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
 910        pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
 911        pItemSSID->byElementID = WLAN_EID_SSID;
 912
 913                memcpy(pItemSSID->abySSID, extra, wrq->length);
 914         if (pItemSSID->abySSID[wrq->length - 1] == '\0') {
 915           if(wrq->length>0)
 916                pItemSSID->len = wrq->length - 1;
 917         }
 918        else
 919          pItemSSID->len = wrq->length;
 920        PRINT_K("set essid to %s \n",pItemSSID->abySSID);
 921
 922     //mike:need clear desiredBSSID
 923     if(pItemSSID->len==0) {
 924        memset(pMgmt->abyDesireBSSID, 0xFF,6);
 925        return 0;
 926     }
 927
 928#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
 929 //Wext wil order another command of siwap to link with desired AP,
 930 //so here need not associate??
 931  if(pDevice->bWPASuppWextEnabled == TRUE)  {
 932        /*******search if  in hidden ssid mode ****/
 933        {
 934           PKnownBSS       pCurr = NULL;
 935           BYTE                   abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
 936          unsigned int ii, uSameBssidNum = 0;
 937
 938          memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID));
 939            pCurr = BSSpSearchBSSList(pDevice,
 940                                      NULL,
 941                                      abyTmpDesireSSID,
 942                                      pDevice->eConfigPHYMode
 943                                      );
 944
 945            if (pCurr == NULL){
 946               PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n");
 947              vResetCommandTimer((void *) pDevice);
 948              pMgmt->eScanType = WMAC_SCAN_ACTIVE;
 949              bScheduleCommand((void *) pDevice,
 950                               WLAN_CMD_BSSID_SCAN,
 951                               pMgmt->abyDesireSSID);
 952              bScheduleCommand((void *) pDevice,
 953                               WLAN_CMD_SSID,
 954                               pMgmt->abyDesireSSID);
 955          }
 956         else {  //mike:to find out if that desired SSID is a hidden-ssid AP ,
 957                     //         by means of judging if there are two same BSSID exist in list ?
 958                  for (ii = 0; ii < MAX_BSS_NUM; ii++) {
 959                     if (pMgmt->sBSSList[ii].bActive &&
 960                        IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) {
 961                        uSameBssidNum++;
 962                     }
 963                  }
 964             if(uSameBssidNum >= 2) {  //hit: desired AP is in hidden ssid mode!!!
 965                 PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n");
 966                 vResetCommandTimer((void *) pDevice);
 967                pMgmt->eScanType = WMAC_SCAN_PASSIVE;          //this scan type,you'll submit scan result!
 968                bScheduleCommand((void *) pDevice,
 969                                 WLAN_CMD_BSSID_SCAN,
 970                                 pMgmt->abyDesireSSID);
 971                bScheduleCommand((void *) pDevice,
 972                                 WLAN_CMD_SSID,
 973                                 pMgmt->abyDesireSSID);
 974             }
 975         }
 976        }
 977     return 0;
 978  }
 979             #endif
 980
 981            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
 982        }
 983
 984    if (pDevice->flags & DEVICE_FLAGS_OPENED) {
 985            pDevice->bCommit = TRUE;
 986        }
 987
 988
 989        return 0;
 990}
 991
 992
 993/*
 994 * Wireless Handler : get essid
 995 */
 996
 997int iwctl_giwessid(struct net_device *dev,
 998             struct iw_request_info *info,
 999             struct iw_point *wrq,
1000             char *extra)
1001{
1002
1003        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
1004    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1005        PWLAN_IE_SSID       pItemSSID;
1006
1007    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n");
1008
1009        // Note : if wrq->u.data.flags != 0, we should
1010        // get the relevant SSID from the SSID list...
1011
1012        // Get the current SSID
1013    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
1014        //pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
1015        memcpy(extra, pItemSSID->abySSID , pItemSSID->len);
1016        extra[pItemSSID->len] = '\0';
1017        //2008-0409-03, <Add> by Einsn Liu
1018        wrq->length = pItemSSID->len;
1019        wrq->flags = 1; // active
1020
1021
1022        return 0;
1023}
1024
1025/*
1026 * Wireless Handler : set data rate
1027 */
1028
1029int iwctl_siwrate(struct net_device *dev,
1030             struct iw_request_info *info,
1031                         struct iw_param *wrq,
1032             char *extra)
1033{
1034        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
1035    int rc = 0;
1036        u8      brate = 0;
1037        int     i;
1038        BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
1039
1040
1041    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n");
1042    if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1043        rc = -EINVAL;
1044        return rc;
1045    }
1046
1047        // First : get a valid bit rate value
1048
1049        // Which type of value
1050        if((wrq->value < 13) &&
1051           (wrq->value >= 0)) {
1052                // Setting by rate index
1053                // Find value in the magic rate table
1054                brate = wrq->value;
1055        } else {
1056                // Setting by frequency value
1057                u8      normvalue = (u8) (wrq->value/500000);
1058
1059                // Check if rate is valid
1060                for(i = 0 ; i < 13 ; i++) {
1061                        if(normvalue == abySupportedRates[i]) {
1062                                brate = i;
1063                                break;
1064                        }
1065                }
1066        }
1067        // -1 designed the max rate (mostly auto mode)
1068        if(wrq->value == -1) {
1069                // Get the highest available rate
1070                for(i = 0 ; i < 13 ; i++) {
1071                        if(abySupportedRates[i] == 0)
1072                                break;
1073                }
1074                if(i != 0)
1075                        brate = i - 1;
1076
1077        }
1078        // Check that it is valid
1079        // brate is index of abySupportedRates[]
1080        if(brate > 13 ) {
1081                rc = -EINVAL;
1082                return rc;
1083        }
1084
1085        // Now, check if we want a fixed or auto value
1086        if(wrq->fixed != 0) {
1087                // Fixed mode
1088                // One rate, fixed
1089                pDevice->bFixRate = TRUE;
1090        if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) {
1091            pDevice->uConnectionRate = 3;
1092        }
1093        else {
1094            pDevice->uConnectionRate = brate;
1095            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate);
1096        }
1097
1098        }
1099        else {
1100        pDevice->bFixRate = FALSE;
1101        pDevice->uConnectionRate = 13;
1102    }
1103
1104        return rc;
1105}
1106
1107/*
1108 * Wireless Handler : get data rate
1109 */
1110
1111int iwctl_giwrate(struct net_device *dev,
1112             struct iw_request_info *info,
1113             struct iw_param *wrq,
1114             char *extra)
1115{
1116        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
1117    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1118
1119    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n");
1120    {
1121        BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
1122            int brate = 0;
1123                if (pDevice->uConnectionRate < 13) {
1124                brate = abySupportedRates[pDevice->uConnectionRate];
1125            }else {
1126            if (pDevice->byBBType == BB_TYPE_11B)
1127                    brate = 0x16;
1128            if (pDevice->byBBType == BB_TYPE_11G)
1129                    brate = 0x6C;
1130            if (pDevice->byBBType == BB_TYPE_11A)
1131                    brate = 0x6C;
1132            }
1133
1134            if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1135            if (pDevice->byBBType == BB_TYPE_11B)
1136                    brate = 0x16;
1137            if (pDevice->byBBType == BB_TYPE_11G)
1138                    brate = 0x6C;
1139            if (pDevice->byBBType == BB_TYPE_11A)
1140                    brate = 0x6C;
1141            }
1142                if (pDevice->uConnectionRate == 13)
1143                brate = abySupportedRates[pDevice->wCurrentRate];
1144            wrq->value = brate * 500000;
1145            // If more than one rate, set auto
1146            if (pDevice->bFixRate == TRUE)
1147                wrq->fixed = TRUE;
1148    }
1149
1150
1151        return 0;
1152}
1153
1154
1155
1156/*
1157 * Wireless Handler : set rts threshold
1158 */
1159
1160int iwctl_siwrts(struct net_device *dev,
1161             struct iw_request_info *info,
1162                         struct iw_param *wrq,
1163             char *extra)
1164{
1165        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
1166        int rc = 0;
1167
1168    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS \n");
1169
1170        {
1171            int rthr = wrq->value;
1172            if(wrq->disabled)
1173                        rthr = 2312;
1174            if((rthr < 0) || (rthr > 2312)) {
1175                        rc = -EINVAL;
1176        }else {
1177                    pDevice->wRTSThreshold = rthr;
1178            }
1179    }
1180
1181        return 0;
1182}
1183
1184/*
1185 * Wireless Handler : get rts
1186 */
1187
1188int iwctl_giwrts(struct net_device *dev,
1189             struct iw_request_info *info,
1190                         struct iw_param *wrq,
1191             char *extra)
1192{
1193        PSDevice                pDevice = (PSDevice)netdev_priv(dev);
1194
1195    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n");
1196        wrq->value = pDevice->wRTSThreshold;
1197        wrq->disabled = (wrq->value >= 2312);
1198        wrq->fixed = 1;
1199
1200        return 0;
1201}
1202
1203/*
1204 * Wireless Handler : set fragment threshold
1205 */
1206
1207int iwctl_siwfrag(struct net_device *dev,
1208             struct iw_request_info *info,
1209                         struct iw_param *wrq,
1210             char *extra)
1211{
1212    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1213    int rc = 0;
1214    int fthr = wrq->value;
1215
1216
1217    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n");
1218
1219
1220    if (wrq->disabled)
1221                fthr = 2312;
1222    if((fthr < 256) || (fthr > 2312)) {
1223                rc = -EINVAL;
1224    }else {
1225                 fthr &= ~0x1;  // Get an even value
1226             pDevice->wFragmentationThreshold = (u16)fthr;
1227    }
1228
1229        return rc;
1230}
1231
1232/*
1233 * Wireless Handler : get fragment threshold
1234 */
1235
1236int iwctl_giwfrag(struct net_device *dev,
1237             struct iw_request_info *info,
1238                         struct iw_param *wrq,
1239             char *extra)
1240{
1241    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1242
1243    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n");
1244        wrq->value = pDevice->wFragmentationThreshold;
1245        wrq->disabled = (wrq->value >= 2312);
1246        wrq->fixed = 1;
1247
1248        return 0;
1249}
1250
1251
1252
1253/*
1254 * Wireless Handler : set retry threshold
1255 */
1256int iwctl_siwretry(struct net_device *dev,
1257             struct iw_request_info *info,
1258                         struct iw_param *wrq,
1259             char *extra)
1260{
1261    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1262    int rc = 0;
1263
1264
1265    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n");
1266
1267        if (wrq->disabled) {
1268                rc = -EINVAL;
1269                return rc;
1270        }
1271
1272        if (wrq->flags & IW_RETRY_LIMIT) {
1273                if(wrq->flags & IW_RETRY_MAX)
1274                        pDevice->byLongRetryLimit = wrq->value;
1275                else if (wrq->flags & IW_RETRY_MIN)
1276                        pDevice->byShortRetryLimit = wrq->value;
1277                else {
1278                        // No modifier : set both
1279                        pDevice->byShortRetryLimit = wrq->value;
1280                        pDevice->byLongRetryLimit = wrq->value;
1281                }
1282        }
1283        if (wrq->flags & IW_RETRY_LIFETIME) {
1284                pDevice->wMaxTransmitMSDULifetime = wrq->value;
1285        }
1286
1287
1288        return rc;
1289}
1290
1291/*
1292 * Wireless Handler : get retry threshold
1293 */
1294int iwctl_giwretry(struct net_device *dev,
1295             struct iw_request_info *info,
1296                         struct iw_param *wrq,
1297             char *extra)
1298{
1299    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1300    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n");
1301        wrq->disabled = 0;      // Can't be disabled
1302
1303        // Note : by default, display the min retry number
1304        if((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1305                wrq->flags = IW_RETRY_LIFETIME;
1306                wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; //ms
1307        } else if((wrq->flags & IW_RETRY_MAX)) {
1308                wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
1309                wrq->value = (int)pDevice->byLongRetryLimit;
1310        } else {
1311                wrq->flags = IW_RETRY_LIMIT;
1312                wrq->value = (int)pDevice->byShortRetryLimit;
1313                if((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit)
1314                        wrq->flags |= IW_RETRY_MIN;
1315        }
1316
1317
1318        return 0;
1319}
1320
1321
1322/*
1323 * Wireless Handler : set encode mode
1324 */
1325int iwctl_siwencode(struct net_device *dev,
1326             struct iw_request_info *info,
1327             struct iw_point *wrq,
1328             char *extra)
1329{
1330    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1331    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1332        DWORD dwKeyIndex = (DWORD)(wrq->flags & IW_ENCODE_INDEX);
1333        int ii,uu, rc = 0;
1334        int index = (wrq->flags & IW_ENCODE_INDEX);
1335
1336
1337    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n");
1338
1339        // Check the size of the key
1340        if (wrq->length > WLAN_WEP232_KEYLEN) {
1341                rc = -EINVAL;
1342        return rc;
1343        }
1344
1345        if (dwKeyIndex > WLAN_WEP_NKEYS) {
1346                rc = -EINVAL;
1347        return rc;
1348    }
1349
1350    if (dwKeyIndex > 0)
1351                dwKeyIndex--;
1352
1353        // Send the key to the card
1354        if (wrq->length > 0) {
1355
1356        if (wrq->length ==  WLAN_WEP232_KEYLEN) {
1357            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
1358        }
1359        else if (wrq->length ==  WLAN_WEP104_KEYLEN) {
1360            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
1361        }
1362        else if (wrq->length == WLAN_WEP40_KEYLEN) {
1363            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
1364        }
1365        memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN);
1366        memcpy(pDevice->abyKey, extra, wrq->length);
1367
1368        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
1369        for (ii = 0; ii < wrq->length; ii++) {
1370            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
1371        }
1372
1373        if (pDevice->flags & DEVICE_FLAGS_OPENED) {
1374            spin_lock_irq(&pDevice->lock);
1375            KeybSetDefaultKey(  pDevice,
1376                                &(pDevice->sKey),
1377                                dwKeyIndex | (1 << 31),
1378                                wrq->length,
1379                                NULL,
1380                                pDevice->abyKey,
1381                                KEY_CTL_WEP
1382                              );
1383            spin_unlock_irq(&pDevice->lock);
1384        }
1385        pDevice->byKeyIndex = (BYTE)dwKeyIndex;
1386        pDevice->uKeyLength = wrq->length;
1387        pDevice->bTransmitKey = TRUE;
1388        pDevice->bEncryptionEnable = TRUE;
1389        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1390
1391                // Do we want to just set the transmit key index ?
1392                if ( index < 4 ) {
1393                    pDevice->byKeyIndex = index;
1394                } else if (!(wrq->flags & IW_ENCODE_MODE)) {
1395                                rc = -EINVAL;
1396                                return rc;
1397            }
1398        }
1399        // Read the flags
1400        if(wrq->flags & IW_ENCODE_DISABLED){
1401
1402        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
1403                pMgmt->bShareKeyAlgorithm = FALSE;
1404        pDevice->bEncryptionEnable = FALSE;
1405        pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1406        if (pDevice->flags & DEVICE_FLAGS_OPENED) {
1407            spin_lock_irq(&pDevice->lock);
1408            for(uu=0;uu<MAX_KEY_TABLE;uu++)
1409                MACvDisableKeyEntry(pDevice,uu);
1410            spin_unlock_irq(&pDevice->lock);
1411        }
1412        }
1413        if(wrq->flags & IW_ENCODE_RESTRICTED) {
1414        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
1415                pMgmt->bShareKeyAlgorithm = TRUE;
1416        }
1417        if(wrq->flags & IW_ENCODE_OPEN) {
1418            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
1419                pMgmt->bShareKeyAlgorithm = FALSE;
1420        }
1421
1422#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1423           memset(pMgmt->abyDesireBSSID, 0xFF,6);
1424#endif
1425
1426        return rc;
1427}
1428
1429/*
1430 * Wireless Handler : get encode mode
1431 */
1432//2008-0409-06, <Mark> by Einsn Liu
1433 /*
1434int iwctl_giwencode(struct net_device *dev,
1435             struct iw_request_info *info,
1436             struct iw_point *wrq,
1437             char *extra)
1438{
1439    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1440    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1441    int rc = 0;
1442    char abyKey[WLAN_WEP232_KEYLEN];
1443        unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX);
1444        PSKeyItem   pKey = NULL;
1445
1446    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
1447
1448
1449        memset(abyKey, 0, sizeof(abyKey));
1450        // Check encryption mode
1451        wrq->flags = IW_ENCODE_NOKEY;
1452        // Is WEP enabled ???
1453        if (pDevice->bEncryptionEnable)
1454                wrq->flags |=  IW_ENCODE_ENABLED;
1455    else
1456                wrq->flags |=  IW_ENCODE_DISABLED;
1457
1458    if (pMgmt->bShareKeyAlgorithm)
1459                wrq->flags |=  IW_ENCODE_RESTRICTED;
1460        else
1461                wrq->flags |=  IW_ENCODE_OPEN;
1462
1463        if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
1464        wrq->length = pKey->uKeyLength;
1465        memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
1466    }
1467    else {
1468        rc = -EINVAL;
1469        return rc;
1470    }
1471        wrq->flags |= index;
1472        // Copy the key to the user buffer
1473        memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
1474        return 0;
1475}
1476*/
1477
1478//2008-0409-06, <Add> by Einsn Liu
1479
1480int iwctl_giwencode(struct net_device *dev,
1481                        struct iw_request_info *info,
1482                        struct iw_point *wrq,
1483                        char *extra)
1484{
1485        PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1486        PSMgmtObject            pMgmt = &(pDevice->sMgmtObj);
1487        char abyKey[WLAN_WEP232_KEYLEN];
1488
1489        unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX);
1490        PSKeyItem       pKey = NULL;
1491
1492        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
1493
1494        if (index > WLAN_WEP_NKEYS) {
1495                return  -EINVAL;
1496        }
1497        if(index<1){//get default key
1498                if(pDevice->byKeyIndex<WLAN_WEP_NKEYS){
1499                        index=pDevice->byKeyIndex;
1500                } else
1501                      index=0;
1502        }else
1503             index--;
1504
1505        memset(abyKey, 0, WLAN_WEP232_KEYLEN);
1506        // Check encryption mode
1507        wrq->flags = IW_ENCODE_NOKEY;
1508        // Is WEP enabled ???
1509        if (pDevice->bEncryptionEnable)
1510                wrq->flags |=  IW_ENCODE_ENABLED;
1511        else
1512                wrq->flags |=  IW_ENCODE_DISABLED;
1513
1514        if (pMgmt->bShareKeyAlgorithm)
1515                wrq->flags |=  IW_ENCODE_RESTRICTED;
1516        else
1517                wrq->flags |=  IW_ENCODE_OPEN;
1518                wrq->length=0;
1519
1520        if((index==0)&&(pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled||
1521                pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){//get wpa pairwise  key
1522                        if (KeybGetKey(&(pDevice->sKey),pMgmt->abyCurrBSSID, 0xffffffff, &pKey)){
1523                           wrq->length = pKey->uKeyLength;
1524                                  memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
1525                                  memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
1526                           }
1527        }else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
1528                        wrq->length = pKey->uKeyLength;
1529                        memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
1530                memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
1531        }
1532
1533        wrq->flags |= index+1;
1534
1535        return 0;
1536}
1537
1538
1539/*
1540 * Wireless Handler : set power mode
1541 */
1542int iwctl_siwpower(struct net_device *dev,
1543             struct iw_request_info *info,
1544                         struct iw_param *wrq,
1545             char *extra)
1546{
1547    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1548    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1549    int rc = 0;
1550
1551    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n");
1552
1553    if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1554                 rc = -EINVAL;
1555                 return rc;
1556        }
1557
1558        if (wrq->disabled) {
1559                pDevice->ePSMode = WMAC_POWER_CAM;
1560                PSvDisablePowerSaving(pDevice);
1561                return rc;
1562        }
1563        if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1564         pDevice->ePSMode = WMAC_POWER_FAST;
1565         PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval);
1566
1567        } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
1568             pDevice->ePSMode = WMAC_POWER_FAST;
1569             PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval);
1570        }
1571        switch (wrq->flags & IW_POWER_MODE) {
1572        case IW_POWER_UNICAST_R:
1573        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
1574                rc = -EINVAL;
1575                break;
1576        case IW_POWER_ALL_R:
1577        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
1578                rc = -EINVAL;
1579        case IW_POWER_ON:
1580        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n");
1581                break;
1582        default:
1583                rc = -EINVAL;
1584        }
1585
1586        return rc;
1587}
1588
1589/*
1590 * Wireless Handler : get power mode
1591 */
1592int iwctl_giwpower(struct net_device *dev,
1593             struct iw_request_info *info,
1594                         struct iw_param *wrq,
1595             char *extra)
1596{
1597    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1598    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1599    int mode = pDevice->ePSMode;
1600
1601
1602    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n");
1603
1604
1605        if ((wrq->disabled = (mode == WMAC_POWER_CAM)))
1606            return 0;
1607
1608        if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1609                wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
1610                wrq->flags = IW_POWER_TIMEOUT;
1611        } else {
1612                wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
1613                wrq->flags = IW_POWER_PERIOD;
1614        }
1615        wrq->flags |= IW_POWER_ALL_R;
1616
1617        return 0;
1618}
1619
1620
1621/*
1622 * Wireless Handler : get Sensitivity
1623 */
1624int iwctl_giwsens(struct net_device *dev,
1625                         struct iw_request_info *info,
1626                         struct iw_param *wrq,
1627                         char *extra)
1628{
1629    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1630    long ldBm;
1631
1632    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n");
1633    if (pDevice->bLinkPass == TRUE) {
1634        RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
1635            wrq->value = ldBm;
1636        }
1637        else {
1638            wrq->value = 0;
1639    };
1640        wrq->disabled = (wrq->value == 0);
1641        wrq->fixed = 1;
1642
1643
1644        return 0;
1645}
1646
1647//2008-0409-07, <Add> by Einsn Liu
1648#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1649
1650int iwctl_siwauth(struct net_device *dev,
1651                          struct iw_request_info *info,
1652                          struct iw_param *wrq,
1653                          char *extra)
1654{
1655        PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1656        PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1657        int ret=0;
1658        static int wpa_version=0;  //must be static to save the last value,einsn liu
1659        static int pairwise=0;
1660
1661    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
1662        switch (wrq->flags & IW_AUTH_INDEX) {
1663        case IW_AUTH_WPA_VERSION:
1664                wpa_version = wrq->value;
1665                if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
1666                       PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
1667                        //pDevice->bWPADEVUp = FALSE;
1668                }
1669                else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) {
1670                          PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
1671                }
1672                else {
1673                          PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
1674                }
1675                //pDevice->bWPASuppWextEnabled =TRUE;
1676                break;
1677        case IW_AUTH_CIPHER_PAIRWISE:
1678                pairwise = wrq->value;
1679                   PRINT_K("iwctl_siwauth:set pairwise=%d\n",pairwise);
1680                if(pairwise == IW_AUTH_CIPHER_CCMP){
1681                        pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
1682                }else if(pairwise == IW_AUTH_CIPHER_TKIP){
1683                        pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
1684                }else if(pairwise == IW_AUTH_CIPHER_WEP40||pairwise == IW_AUTH_CIPHER_WEP104){
1685                        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1686                }else if(pairwise == IW_AUTH_CIPHER_NONE){
1687                        //do nothing,einsn liu
1688                }else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1689
1690                break;
1691        case IW_AUTH_CIPHER_GROUP:
1692                 PRINT_K("iwctl_siwauth:set GROUP=%d\n",wrq->value);
1693                if(wpa_version == IW_AUTH_WPA_VERSION_DISABLED)
1694                        break;
1695                if(pairwise == IW_AUTH_CIPHER_NONE){
1696                        if(wrq->value == IW_AUTH_CIPHER_CCMP){
1697                                pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
1698                        }else {
1699                                pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
1700                        }
1701                }
1702                break;
1703        case IW_AUTH_KEY_MGMT:
1704                    PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n",wpa_version,wrq->value);
1705                if(wpa_version == IW_AUTH_WPA_VERSION_WPA2){
1706                        if(wrq->value == IW_AUTH_KEY_MGMT_PSK)
1707                                pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
1708                        else pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
1709                }else if(wpa_version == IW_AUTH_WPA_VERSION_WPA){
1710                        if(wrq->value == 0){
1711                                pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
1712                        }else if(wrq->value == IW_AUTH_KEY_MGMT_PSK)
1713                                pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
1714                        else pMgmt->eAuthenMode = WMAC_AUTH_WPA;
1715                }
1716
1717                break;
1718        case IW_AUTH_TKIP_COUNTERMEASURES:
1719                break;          /* FIXME */
1720        case IW_AUTH_DROP_UNENCRYPTED:
1721                break;
1722        case IW_AUTH_80211_AUTH_ALG:
1723                 PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n",wrq->value);
1724                if(wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){
1725                        pMgmt->bShareKeyAlgorithm=FALSE;
1726                }else if(wrq->value==IW_AUTH_ALG_SHARED_KEY){
1727                        pMgmt->bShareKeyAlgorithm=TRUE;
1728                }
1729                break;
1730        case IW_AUTH_WPA_ENABLED:
1731                //pDevice->bWPADEVUp = !! wrq->value;
1732                //if(pDevice->bWPADEVUp==TRUE)
1733                  // printk("iwctl_siwauth:set WPADEV to enable successful*******\n");
1734                //else
1735                 //  printk("iwctl_siwauth:set WPADEV to enable fail?????\n");
1736                break;
1737        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1738                break;
1739        case IW_AUTH_ROAMING_CONTROL:
1740                ret = -EOPNOTSUPP;
1741                break;
1742        case IW_AUTH_PRIVACY_INVOKED:
1743                pDevice->bEncryptionEnable = !!wrq->value;
1744                if(pDevice->bEncryptionEnable == FALSE){
1745                        wpa_version = 0;
1746                        pairwise = 0;
1747                        pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1748                        pMgmt->bShareKeyAlgorithm = FALSE;
1749                        pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
1750                        //pDevice->bWPADEVUp = FALSE;
1751                         PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n");
1752                }
1753
1754                break;
1755        default:
1756                ret = -EOPNOTSUPP;
1757                break;
1758        }
1759/*
1760        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_version = %d\n",wpa_version);
1761        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise = %d\n",pairwise);
1762        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->eEncryptionStatus = %d\n",pDevice->eEncryptionStatus);
1763        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->eAuthenMode  = %d\n",pMgmt->eAuthenMode);
1764        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->bShareKeyAlgorithm = %s\n",pMgmt->bShareKeyAlgorithm?"TRUE":"FALSE");
1765        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bEncryptionEnable = %s\n",pDevice->bEncryptionEnable?"TRUE":"FALSE");
1766        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bWPADEVUp = %s\n",pDevice->bWPADEVUp?"TRUE":"FALSE");
1767*/
1768   return ret;
1769}
1770
1771
1772int iwctl_giwauth(struct net_device *dev,
1773                          struct iw_request_info *info,
1774                          struct iw_param *wrq,
1775                          char *extra)
1776{
1777        return -EOPNOTSUPP;
1778}
1779
1780
1781
1782int iwctl_siwgenie(struct net_device *dev,
1783                          struct iw_request_info *info,
1784                          struct iw_point *wrq,
1785                          char *extra)
1786{
1787        PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1788        PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1789        int ret=0;
1790
1791        if(wrq->length){
1792                if ((wrq->length < 2) || (extra[1]+2 != wrq->length)) {
1793                        ret = -EINVAL;
1794                        goto out;
1795                }
1796                if(wrq->length > MAX_WPA_IE_LEN){
1797                        ret = -ENOMEM;
1798                        goto out;
1799                }
1800                memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
1801                if(copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)){
1802                        ret = -EFAULT;
1803                        goto out;
1804                }
1805                pMgmt->wWPAIELen = wrq->length;
1806        }else {
1807                memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
1808                pMgmt->wWPAIELen = 0;
1809        }
1810
1811        out://not completely ...not necessary in wpa_supplicant 0.5.8
1812        return 0;
1813}
1814
1815int iwctl_giwgenie(struct net_device *dev,
1816                          struct iw_request_info *info,
1817                          struct iw_point *wrq,
1818                          char *extra)
1819{
1820        PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1821        PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1822        int ret=0;
1823        int space = wrq->length;
1824
1825        wrq->length = 0;
1826        if(pMgmt->wWPAIELen > 0){
1827                wrq->length = pMgmt->wWPAIELen;
1828                if(pMgmt->wWPAIELen <= space){
1829                        if(copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)){
1830                                ret = -EFAULT;
1831                        }
1832                }else
1833                        ret = -E2BIG;
1834        }
1835
1836        return ret;
1837}
1838
1839
1840int iwctl_siwencodeext(struct net_device *dev,
1841             struct iw_request_info *info,
1842             struct iw_point *wrq,
1843             char *extra)
1844{
1845    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1846    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1847        struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
1848    struct viawget_wpa_param *param=NULL;
1849//original member
1850    wpa_alg alg_name;
1851    u8  addr[6];
1852    int key_idx, set_tx=0;
1853    u8  seq[IW_ENCODE_SEQ_MAX_SIZE];
1854    u8 key[64];
1855    size_t seq_len=0,key_len=0;
1856//
1857   // int ii;
1858    u8 *buf;
1859    size_t blen;
1860    u8 key_array[64];
1861    int ret=0;
1862
1863PRINT_K("SIOCSIWENCODEEXT...... \n");
1864
1865blen = sizeof(*param);
1866buf = kmalloc((int)blen, (int)GFP_KERNEL);
1867if (buf == NULL)
1868    return -ENOMEM;
1869memset(buf, 0, blen);
1870param = (struct viawget_wpa_param *) buf;
1871
1872//recover alg_name
1873switch (ext->alg) {
1874    case IW_ENCODE_ALG_NONE:
1875                  alg_name = WPA_ALG_NONE;
1876                break;
1877    case IW_ENCODE_ALG_WEP:
1878                  alg_name = WPA_ALG_WEP;
1879                break;
1880    case IW_ENCODE_ALG_TKIP:
1881                  alg_name = WPA_ALG_TKIP;
1882                break;
1883    case IW_ENCODE_ALG_CCMP:
1884                  alg_name = WPA_ALG_CCMP;
1885                break;
1886    default:
1887                PRINT_K("Unknown alg = %d\n",ext->alg);
1888                ret= -ENOMEM;
1889                goto error;
1890                }
1891//recover addr
1892 memcpy(addr, ext->addr.sa_data, ETH_ALEN);
1893//recover key_idx
1894  key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1;
1895//recover set_tx
1896if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1897   set_tx = 1;
1898//recover seq,seq_len
1899        if(ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
1900   seq_len=IW_ENCODE_SEQ_MAX_SIZE;
1901   memcpy(seq, ext->rx_seq, seq_len);
1902                }
1903//recover key,key_len
1904if(ext->key_len) {
1905  key_len=ext->key_len;
1906  memcpy(key, &ext->key[0], key_len);
1907        }
1908
1909memset(key_array, 0, 64);
1910if ( key_len > 0) {
1911     memcpy(key_array, key, key_len);
1912    if (key_len == 32) {
1913          // notice ! the oder
1914          memcpy(&key_array[16], &key[24], 8);
1915          memcpy(&key_array[24], &key[16], 8);
1916        }
1917        }
1918
1919/**************Translate iw_encode_ext to viawget_wpa_param****************/
1920memcpy(param->addr, addr, ETH_ALEN);
1921param->u.wpa_key.alg_name = (int)alg_name;
1922param->u.wpa_key.set_tx = set_tx;
1923param->u.wpa_key.key_index = key_idx;
1924param->u.wpa_key.key_len = key_len;
1925param->u.wpa_key.key = (u8 *)key_array;
1926param->u.wpa_key.seq = (u8 *)seq;
1927param->u.wpa_key.seq_len = seq_len;
1928
1929#if 0
1930printk("param->u.wpa_key.alg_name =%d\n",param->u.wpa_key.alg_name);
1931printk("param->addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
1932              param->addr[0],param->addr[1],param->addr[2],
1933              param->addr[3],param->addr[4],param->addr[5]);
1934printk("param->u.wpa_key.set_tx =%d\n",param->u.wpa_key.set_tx);
1935printk("param->u.wpa_key.key_index =%d\n",param->u.wpa_key.key_index);
1936printk("param->u.wpa_key.key_len =%d\n",param->u.wpa_key.key_len);
1937printk("param->u.wpa_key.key =");
1938for(ii=0;ii<param->u.wpa_key.key_len;ii++)
1939        printk("%02x:",param->u.wpa_key.key[ii]);
1940         printk("\n");
1941printk("param->u.wpa_key.seq_len =%d\n",param->u.wpa_key.seq_len);
1942printk("param->u.wpa_key.seq =");
1943for(ii=0;ii<param->u.wpa_key.seq_len;ii++)
1944        printk("%02x:",param->u.wpa_key.seq[ii]);
1945         printk("\n");
1946
1947printk("...........\n");
1948#endif
1949//****set if current action is Network Manager count??
1950//****this method is so foolish,but there is no other way???
1951if(param->u.wpa_key.alg_name == WPA_ALG_NONE) {
1952   if(param->u.wpa_key.key_index ==0) {
1953     pDevice->bwextstep0 = TRUE;
1954    }
1955   if((pDevice->bwextstep0 = TRUE)&&(param->u.wpa_key.key_index ==1)) {
1956     pDevice->bwextstep0 = FALSE;
1957     pDevice->bwextstep1 = TRUE;
1958    }
1959   if((pDevice->bwextstep1 = TRUE)&&(param->u.wpa_key.key_index ==2)) {
1960     pDevice->bwextstep1 = FALSE;
1961     pDevice->bwextstep2 = TRUE;
1962        }
1963   if((pDevice->bwextstep2 = TRUE)&&(param->u.wpa_key.key_index ==3)) {
1964     pDevice->bwextstep2 = FALSE;
1965     pDevice->bwextstep3 = TRUE;
1966        }
1967                 }
1968if(pDevice->bwextstep3 == TRUE) {
1969    PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
1970     pDevice->bwextstep0 = FALSE;
1971     pDevice->bwextstep1 = FALSE;
1972     pDevice->bwextstep2 = FALSE;
1973     pDevice->bwextstep3 = FALSE;
1974     pDevice->bWPASuppWextEnabled = TRUE;
1975     memset(pMgmt->abyDesireBSSID, 0xFF,6);
1976     KeyvInitTable(pDevice,&pDevice->sKey);
1977                 }
1978//******
1979
1980                spin_lock_irq(&pDevice->lock);
1981 ret = wpa_set_keys(pDevice, param, TRUE);
1982                spin_unlock_irq(&pDevice->lock);
1983
1984error:
1985kfree(param);
1986        return ret;
1987}
1988
1989
1990
1991int iwctl_giwencodeext(struct net_device *dev,
1992             struct iw_request_info *info,
1993             struct iw_point *wrq,
1994             char *extra)
1995{
1996                return -EOPNOTSUPP;;
1997}
1998
1999int iwctl_siwmlme(struct net_device *dev,
2000                                struct iw_request_info * info,
2001                                struct iw_point *wrq,
2002                                char *extra)
2003{
2004        PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
2005        PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
2006        struct iw_mlme *mlme = (struct iw_mlme *)extra;
2007        //u16 reason = cpu_to_le16(mlme->reason_code);
2008        int ret = 0;
2009
2010        if(memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)){
2011                ret = -EINVAL;
2012                return ret;
2013        }
2014        switch(mlme->cmd){
2015        case IW_MLME_DEAUTH:
2016                //this command seems to be not complete,please test it --einsnliu
2017                //printk("iwctl_siwmlme--->send DEAUTH\n");
2018                /* bScheduleCommand((void *) pDevice,
2019                   WLAN_CMD_DEAUTH,
2020                   (PBYTE)&reason); */
2021                //break;
2022        case IW_MLME_DISASSOC:
2023                if(pDevice->bLinkPass == TRUE){
2024                  PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n");
2025                  bScheduleCommand((void *) pDevice,
2026                                   WLAN_CMD_DISASSOCIATE,
2027                                   NULL);
2028                }
2029                break;
2030        default:
2031                ret = -EOPNOTSUPP;
2032        }
2033
2034        return ret;
2035
2036}
2037
2038#endif
2039//End Add --//2008-0409-07, <Add> by Einsn Liu
2040
2041
2042
2043/*------------------------------------------------------------------*/
2044/*
2045 * Structures to export the Wireless Handlers
2046 */
2047
2048
2049/*
2050static const iw_handler         iwctl_handler[] =
2051{
2052        (iw_handler) iwctl_commit,      // SIOCSIWCOMMIT
2053        (iw_handler) iwctl_giwname,     // SIOCGIWNAME
2054        (iw_handler) NULL,                              // SIOCSIWNWID
2055        (iw_handler) NULL,                              // SIOCGIWNWID
2056        (iw_handler) iwctl_siwfreq,             // SIOCSIWFREQ
2057        (iw_handler) iwctl_giwfreq,             // SIOCGIWFREQ
2058        (iw_handler) iwctl_siwmode,             // SIOCSIWMODE
2059        (iw_handler) iwctl_giwmode,             // SIOCGIWMODE
2060        (iw_handler) NULL,                      // SIOCSIWSENS
2061        (iw_handler) iwctl_giwsens,                     // SIOCGIWSENS
2062        (iw_handler) NULL,                      // SIOCSIWRANGE
2063        (iw_handler) iwctl_giwrange,            // SIOCGIWRANGE
2064        (iw_handler) NULL,                          // SIOCSIWPRIV
2065        (iw_handler) NULL,                      // SIOCGIWPRIV
2066        (iw_handler) NULL,                      // SIOCSIWSTATS
2067        (iw_handler) NULL,                  // SIOCGIWSTATS
2068    (iw_handler) NULL,                  // SIOCSIWSPY
2069        (iw_handler) NULL,                          // SIOCGIWSPY
2070        (iw_handler) NULL,                                  // -- hole --
2071        (iw_handler) NULL,                                  // -- hole --
2072        (iw_handler) iwctl_siwap,                   // SIOCSIWAP
2073        (iw_handler) iwctl_giwap,                   // SIOCGIWAP
2074        (iw_handler) NULL,                                  // -- hole -- 0x16
2075        (iw_handler) iwctl_giwaplist,       // SIOCGIWAPLIST
2076        (iw_handler) iwctl_siwscan,         // SIOCSIWSCAN
2077        (iw_handler) iwctl_giwscan,         // SIOCGIWSCAN
2078        (iw_handler) iwctl_siwessid,            // SIOCSIWESSID
2079        (iw_handler) iwctl_giwessid,            // SIOCGIWESSID
2080        (iw_handler) NULL,              // SIOCSIWNICKN
2081        (iw_handler) NULL,              // SIOCGIWNICKN
2082        (iw_handler) NULL,                                  // -- hole --
2083        (iw_handler) NULL,                                  // -- hole --
2084        (iw_handler) iwctl_siwrate,             // SIOCSIWRATE 0x20
2085        (iw_handler) iwctl_giwrate,             // SIOCGIWRATE
2086        (iw_handler) iwctl_siwrts,              // SIOCSIWRTS
2087        (iw_handler) iwctl_giwrts,              // SIOCGIWRTS
2088        (iw_handler) iwctl_siwfrag,             // SIOCSIWFRAG
2089        (iw_handler) iwctl_giwfrag,             // SIOCGIWFRAG
2090        (iw_handler) NULL,              // SIOCSIWTXPOW
2091        (iw_handler) NULL,              // SIOCGIWTXPOW
2092        (iw_handler) iwctl_siwretry,            // SIOCSIWRETRY
2093        (iw_handler) iwctl_giwretry,            // SIOCGIWRETRY
2094        (iw_handler) iwctl_siwencode,           // SIOCSIWENCODE
2095        (iw_handler) iwctl_giwencode,           // SIOCGIWENCODE
2096        (iw_handler) iwctl_siwpower,            // SIOCSIWPOWER
2097        (iw_handler) iwctl_giwpower,            // SIOCGIWPOWER
2098        (iw_handler) NULL,                      // -- hole --
2099        (iw_handler) NULL,                      // -- hole --
2100        (iw_handler) iwctl_siwgenie,    // SIOCSIWGENIE
2101        (iw_handler) iwctl_giwgenie,    // SIOCGIWGENIE
2102        (iw_handler) iwctl_siwauth,             // SIOCSIWAUTH
2103        (iw_handler) iwctl_giwauth,             // SIOCGIWAUTH
2104        (iw_handler) iwctl_siwencodeext,                // SIOCSIWENCODEEXT
2105        (iw_handler) iwctl_giwencodeext,                // SIOCGIWENCODEEXT
2106        (iw_handler) NULL,                              // SIOCSIWPMKSA
2107        (iw_handler) NULL,                              // -- hole --
2108
2109};
2110*/
2111
2112static const iw_handler         iwctl_handler[] =
2113{
2114        (iw_handler) iwctl_commit,      // SIOCSIWCOMMIT
2115        (iw_handler) NULL,      // SIOCGIWNAME
2116        (iw_handler) NULL,                              // SIOCSIWNWID
2117        (iw_handler) NULL,                              // SIOCGIWNWID
2118        (iw_handler) NULL,              // SIOCSIWFREQ
2119        (iw_handler) NULL,              // SIOCGIWFREQ
2120        (iw_handler) NULL,              // SIOCSIWMODE
2121        (iw_handler) NULL,              // SIOCGIWMODE
2122        (iw_handler) NULL,                      // SIOCSIWSENS
2123        (iw_handler) NULL,                      // SIOCGIWSENS
2124        (iw_handler) NULL,                      // SIOCSIWRANGE
2125        (iw_handler) iwctl_giwrange,            // SIOCGIWRANGE
2126        (iw_handler) NULL,                          // SIOCSIWPRIV
2127        (iw_handler) NULL,                      // SIOCGIWPRIV
2128        (iw_handler) NULL,                      // SIOCSIWSTATS
2129        (iw_handler) NULL,                  // SIOCGIWSTATS
2130    (iw_handler) NULL,                  // SIOCSIWSPY
2131        (iw_handler) NULL,                          // SIOCGIWSPY
2132        (iw_handler) NULL,                                  // -- hole --
2133        (iw_handler) NULL,                                  // -- hole --
2134        (iw_handler) NULL,                  // SIOCSIWAP
2135        (iw_handler) NULL,                  // SIOCGIWAP
2136        (iw_handler) NULL,                                  // -- hole -- 0x16
2137        (iw_handler) NULL,       // SIOCGIWAPLIST
2138        (iw_handler) iwctl_siwscan,         // SIOCSIWSCAN
2139        (iw_handler) iwctl_giwscan,         // SIOCGIWSCAN
2140        (iw_handler) NULL,              // SIOCSIWESSID
2141        (iw_handler) NULL,              // SIOCGIWESSID
2142        (iw_handler) NULL,              // SIOCSIWNICKN
2143        (iw_handler) NULL,              // SIOCGIWNICKN
2144        (iw_handler) NULL,              // -- hole --
2145        (iw_handler) NULL,              // -- hole --
2146        (iw_handler) NULL,              // SIOCSIWRATE 0x20
2147        (iw_handler) NULL,              // SIOCGIWRATE
2148        (iw_handler) NULL,              // SIOCSIWRTS
2149        (iw_handler) NULL,              // SIOCGIWRTS
2150        (iw_handler) NULL,              // SIOCSIWFRAG
2151        (iw_handler) NULL,              // SIOCGIWFRAG
2152        (iw_handler) NULL,              // SIOCSIWTXPOW
2153        (iw_handler) NULL,              // SIOCGIWTXPOW
2154        (iw_handler) NULL,              // SIOCSIWRETRY
2155        (iw_handler) NULL,              // SIOCGIWRETRY
2156        (iw_handler) NULL,              // SIOCSIWENCODE
2157        (iw_handler) NULL,              // SIOCGIWENCODE
2158        (iw_handler) NULL,              // SIOCSIWPOWER
2159        (iw_handler) NULL,              // SIOCGIWPOWER
2160        (iw_handler) NULL,                      // -- hole --
2161        (iw_handler) NULL,                      // -- hole --
2162        (iw_handler) NULL,    // SIOCSIWGENIE
2163        (iw_handler) NULL,    // SIOCGIWGENIE
2164        (iw_handler) NULL,              // SIOCSIWAUTH
2165        (iw_handler) NULL,              // SIOCGIWAUTH
2166        (iw_handler) NULL,              // SIOCSIWENCODEEXT
2167        (iw_handler) NULL,              // SIOCGIWENCODEEXT
2168        (iw_handler) NULL,                              // SIOCSIWPMKSA
2169        (iw_handler) NULL,                              // -- hole --
2170};
2171
2172
2173static const iw_handler         iwctl_private_handler[] =
2174{
2175        NULL,                           // SIOCIWFIRSTPRIV
2176};
2177
2178
2179struct iw_priv_args iwctl_private_args[] = {
2180{ IOCTL_CMD_SET,
2181  IW_PRIV_TYPE_CHAR | 1024, 0,
2182  "set"},
2183};
2184
2185
2186
2187const struct iw_handler_def     iwctl_handler_def =
2188{
2189        .get_wireless_stats = &iwctl_get_wireless_stats,
2190        .num_standard   = sizeof(iwctl_handler)/sizeof(iw_handler),
2191//      .num_private    = sizeof(iwctl_private_handler)/sizeof(iw_handler),
2192//      .num_private_args = sizeof(iwctl_private_args)/sizeof(struct iw_priv_args),
2193        .num_private    = 0,
2194        .num_private_args = 0,
2195        .standard       = (iw_handler *) iwctl_handler,
2196//      .private        = (iw_handler *) iwctl_private_handler,
2197//      .private_args   = (struct iw_priv_args *)iwctl_private_args,
2198        .private        = NULL,
2199        .private_args   = NULL,
2200};
2201
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.