Linux Audio

Check our new training course

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