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