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