rtl8188eu: update driver to v4.3.0.8_13968.20150417
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8188eu / os_dep / linux / ioctl_linux.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _IOCTL_LINUX_C_
21
22 #include <drv_types.h>
23
24 //#ifdef CONFIG_MP_INCLUDED
25 #include <rtw_mp_ioctl.h>
26 #include "../../hal/OUTSRC/odm_precomp.h"
27 //#endif
28
29 #if defined(CONFIG_RTL8723A)
30 #include "rtl8723a_hal.h"
31 #include <rtw_bt_mp.h>
32 #endif
33
34 #if defined(CONFIG_RTL8723B)
35 #include <rtw_bt_mp.h>
36 #endif
37
38 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
39 #define  iwe_stream_add_event(a, b, c, d, e)  iwe_stream_add_event(b, c, d, e)
40 #define  iwe_stream_add_point(a, b, c, d, e)  iwe_stream_add_point(b, c, d, e)
41 #endif
42
43
44 #define RTL_IOCTL_WPA_SUPPLICANT        SIOCIWFIRSTPRIV+30
45
46 #define SCAN_ITEM_SIZE 768
47 #define MAX_CUSTOM_LEN 64
48 #define RATE_COUNT 4
49
50 #ifdef CONFIG_GLOBAL_UI_PID
51 extern int ui_pid[3];
52 #endif
53
54 // combo scan
55 #define WEXT_CSCAN_AMOUNT 9
56 #define WEXT_CSCAN_BUF_LEN              360
57 #define WEXT_CSCAN_HEADER               "CSCAN S\x01\x00\x00S\x00"
58 #define WEXT_CSCAN_HEADER_SIZE          12
59 #define WEXT_CSCAN_SSID_SECTION         'S'
60 #define WEXT_CSCAN_CHANNEL_SECTION      'C'
61 #define WEXT_CSCAN_NPROBE_SECTION       'N'
62 #define WEXT_CSCAN_ACTV_DWELL_SECTION   'A'
63 #define WEXT_CSCAN_PASV_DWELL_SECTION   'P'
64 #define WEXT_CSCAN_HOME_DWELL_SECTION   'H'
65 #define WEXT_CSCAN_TYPE_SECTION         'T'
66
67
68 extern u8 key_2char2num(u8 hch, u8 lch);
69 extern u8 str_2char2num(u8 hch, u8 lch);
70 extern void macstr2num(u8 *dst, u8 *src);
71 extern u8 convert_ip_addr(u8 hch, u8 mch, u8 lch);
72
73 u32 rtw_rates[] = {1000000,2000000,5500000,11000000,
74         6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
75
76 static const char * const iw_operation_mode[] = 
77
78         "Auto", "Ad-Hoc", "Managed",  "Master", "Repeater", "Secondary", "Monitor" 
79 };
80
81 static int hex2num_i(char c)
82 {
83         if (c >= '0' && c <= '9')
84                 return c - '0';
85         if (c >= 'a' && c <= 'f')
86                 return c - 'a' + 10;
87         if (c >= 'A' && c <= 'F')
88                 return c - 'A' + 10;
89         return -1;
90 }
91
92 static int hex2byte_i(const char *hex)
93 {
94         int a, b;
95         a = hex2num_i(*hex++);
96         if (a < 0)
97                 return -1;
98         b = hex2num_i(*hex++);
99         if (b < 0)
100                 return -1;
101         return (a << 4) | b;
102 }
103
104 /**
105  * hwaddr_aton - Convert ASCII string to MAC address
106  * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
107  * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
108  * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
109  */
110 static int hwaddr_aton_i(const char *txt, u8 *addr)
111 {
112         int i;
113
114         for (i = 0; i < 6; i++) {
115                 int a, b;
116
117                 a = hex2num_i(*txt++);
118                 if (a < 0)
119                         return -1;
120                 b = hex2num_i(*txt++);
121                 if (b < 0)
122                         return -1;
123                 *addr++ = (a << 4) | b;
124                 if (i < 5 && *txt++ != ':')
125                         return -1;
126         }
127
128         return 0;
129 }
130
131 static void indicate_wx_custom_event(_adapter *padapter, char *msg)
132 {
133         u8 *buff, *p;
134         union iwreq_data wrqu;
135
136         if (strlen(msg) > IW_CUSTOM_MAX) {
137                 DBG_871X("%s strlen(msg):%zu > IW_CUSTOM_MAX:%u\n", __FUNCTION__ , strlen(msg), IW_CUSTOM_MAX);
138                 return;
139         }
140
141         buff = rtw_zmalloc(IW_CUSTOM_MAX+1);
142         if(!buff)
143                 return;
144
145         _rtw_memcpy(buff, msg, strlen(msg));
146                 
147         _rtw_memset(&wrqu,0,sizeof(wrqu));
148         wrqu.data.length = strlen(msg);
149
150         DBG_871X("%s %s\n", __FUNCTION__, buff);        
151 #ifndef CONFIG_IOCTL_CFG80211
152         wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
153 #endif
154
155         rtw_mfree(buff, IW_CUSTOM_MAX+1);
156
157 }
158
159
160 static void request_wps_pbc_event(_adapter *padapter)
161 {
162         u8 *buff, *p;
163         union iwreq_data wrqu;
164
165
166         buff = rtw_malloc(IW_CUSTOM_MAX);
167         if(!buff)
168                 return;
169                 
170         _rtw_memset(buff, 0, IW_CUSTOM_MAX);
171                 
172         p=buff;
173                 
174         p+=sprintf(p, "WPS_PBC_START.request=TRUE");
175                 
176         _rtw_memset(&wrqu,0,sizeof(wrqu));
177                 
178         wrqu.data.length = p-buff;
179                 
180         wrqu.data.length = (wrqu.data.length<IW_CUSTOM_MAX) ? wrqu.data.length:IW_CUSTOM_MAX;
181
182         DBG_871X("%s\n", __FUNCTION__);
183                 
184 #ifndef CONFIG_IOCTL_CFG80211
185         wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
186 #endif
187
188         if(buff)
189         {
190                 rtw_mfree(buff, IW_CUSTOM_MAX);
191         }
192
193 }
194
195 #ifdef CONFIG_SUPPORT_HW_WPS_PBC
196 void rtw_request_wps_pbc_event(_adapter *padapter)
197 {
198 #ifdef RTK_DMP_PLATFORM
199 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12))
200         kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_NET_PBC);
201 #else
202         kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_NET_PBC);
203 #endif
204 #else
205
206         if ( padapter->pid[0] == 0 )
207         {       //      0 is the default value and it means the application monitors the HW PBC doesn't privde its pid to driver.
208                 return;
209         }
210
211         rtw_signal_process(padapter->pid[0], SIGUSR1);
212
213 #endif
214
215         rtw_led_control(padapter, LED_CTL_START_WPS_BOTTON);
216 }
217 #endif//#ifdef CONFIG_SUPPORT_HW_WPS_PBC
218
219 void indicate_wx_scan_complete_event(_adapter *padapter)
220 {       
221         union iwreq_data wrqu;
222         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;     
223
224         _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
225
226         //DBG_871X("+rtw_indicate_wx_scan_complete_event\n");
227 #ifndef CONFIG_IOCTL_CFG80211
228         wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
229 #endif
230 }
231
232
233 void rtw_indicate_wx_assoc_event(_adapter *padapter)
234 {       
235         union iwreq_data wrqu;
236         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
237         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
238         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
239         WLAN_BSSID_EX           *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
240
241         _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
242         
243         wrqu.ap_addr.sa_family = ARPHRD_ETHER;  
244         
245         if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE )
246                 _rtw_memcpy(wrqu.ap_addr.sa_data, pnetwork->MacAddress, ETH_ALEN);
247         else
248                 _rtw_memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
249
250         DBG_871X_LEVEL(_drv_always_, "assoc success\n");
251 #ifndef CONFIG_IOCTL_CFG80211
252         wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
253 #endif
254 }
255
256 void rtw_indicate_wx_disassoc_event(_adapter *padapter)
257 {       
258         union iwreq_data wrqu;
259
260         _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
261
262         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
263         _rtw_memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
264
265 #ifndef CONFIG_IOCTL_CFG80211
266         DBG_871X_LEVEL(_drv_always_, "indicate disassoc\n");
267         wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
268 #endif
269 }
270
271 /*
272 uint    rtw_is_cckrates_included(u8 *rate)
273 {       
274                 u32     i = 0;                  
275
276                 while(rate[i]!=0)
277                 {               
278                         if  (  (((rate[i]) & 0x7f) == 2)        || (((rate[i]) & 0x7f) == 4) ||         
279                         (((rate[i]) & 0x7f) == 11)  || (((rate[i]) & 0x7f) == 22) )             
280                         return _TRUE;   
281                         i++;
282                 }
283                 
284                 return _FALSE;
285 }
286
287 uint    rtw_is_cckratesonly_included(u8 *rate)
288 {
289         u32 i = 0;
290
291         while(rate[i]!=0)
292         {
293                         if  (  (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
294                                 (((rate[i]) & 0x7f) != 11)  && (((rate[i]) & 0x7f) != 22) )
295                         return _FALSE;          
296                         i++;
297         }
298         
299         return _TRUE;
300 }
301 */
302
303 static int search_p2p_wfd_ie(_adapter *padapter,
304                                 struct iw_request_info* info, struct wlan_network *pnetwork,
305                                 char *start, char *stop)
306 {
307 #ifdef CONFIG_P2P
308         struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
309 #ifdef CONFIG_WFD
310         if ( SCAN_RESULT_ALL == pwdinfo->wfd_info->scan_result_type )
311         {
312
313         }
314         else if ( ( SCAN_RESULT_P2P_ONLY == pwdinfo->wfd_info->scan_result_type ) || 
315                       ( SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type ) )
316 #endif // CONFIG_WFD
317         {
318                 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
319                 {
320                         u32     blnGotP2PIE = _FALSE;
321                         
322                         //      User is doing the P2P device discovery
323                         //      The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE.
324                         //      If not, the driver should ignore this AP and go to the next AP.
325
326                         //      Verifying the SSID
327                         if ( _rtw_memcmp( pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN ) )
328                         {
329                                 u32     p2pielen = 0;
330
331                                 //      Verifying the P2P IE
332                                 if (rtw_get_p2p_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0]))
333                                 {
334                                         blnGotP2PIE = _TRUE;
335                                 }
336                         }
337
338                         if ( blnGotP2PIE == _FALSE )
339                         {
340                                 return _FALSE;
341                         }
342                         
343                 }
344         }
345
346 #ifdef CONFIG_WFD
347         if ( SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type )
348         {
349                 u32     blnGotWFD = _FALSE;
350                 u8      wfd_ie[ 128 ] = { 0x00 };
351                 uint    wfd_ielen = 0;
352                 
353                 if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength,  wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) )
354                 {
355                         u8      wfd_devinfo[ 6 ] = { 0x00 };
356                         uint    wfd_devlen = 6;
357                         
358                         if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen) )
359                         {
360                                 if ( pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_PSINK )
361                                 {
362                                         //      the first two bits will indicate the WFD device type
363                                         if ( ( wfd_devinfo[ 1 ] & 0x03 ) == WFD_DEVINFO_SOURCE )
364                                         {
365                                                 //      If this device is Miracast PSink device, the scan reuslt should just provide the Miracast source.
366                                                 blnGotWFD = _TRUE;
367                                         }
368                                 }
369                                 else if ( pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_SOURCE )
370                                 {
371                                         //      the first two bits will indicate the WFD device type
372                                         if ( ( wfd_devinfo[ 1 ] & 0x03 ) == WFD_DEVINFO_PSINK )
373                                         {
374                                                 //      If this device is Miracast source device, the scan reuslt should just provide the Miracast PSink.
375                                                 //      Todo: How about the SSink?!
376                                                 blnGotWFD = _TRUE;
377                                         }
378                                 }
379                         }
380                 }
381                 
382                 if ( blnGotWFD == _FALSE )
383                 {
384                         return _FALSE;
385                 }
386         }
387 #endif // CONFIG_WFD
388
389 #endif //CONFIG_P2P
390         return _TRUE;
391 }
392
393 static inline char *iwe_stream_mac_addr_proess(_adapter *padapter,
394                                 struct iw_request_info* info, struct wlan_network *pnetwork,
395                                 char *start, char *stop,struct iw_event *iwe)
396 {
397         /*  AP MAC address  */
398         iwe->cmd = SIOCGIWAP;
399         iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
400
401         _rtw_memcpy(iwe->u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
402         start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_ADDR_LEN);
403         return start;
404 }
405
406 static inline char * iwe_stream_essid_proess(_adapter *padapter,
407                                 struct iw_request_info* info, struct wlan_network *pnetwork,
408                                 char *start, char *stop,struct iw_event *iwe)
409 {
410         /* Add the ESSID */
411         iwe->cmd = SIOCGIWESSID;
412         iwe->u.data.flags = 1;
413         iwe->u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32);
414         start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid);
415         return start;
416 }
417
418 static inline char * iwe_stream_chan_process(_adapter *padapter,
419                                 struct iw_request_info* info, struct wlan_network *pnetwork,
420                                 char *start, char *stop,struct iw_event *iwe)
421 {
422         if(pnetwork->network.Configuration.DSConfig<1 /*|| pnetwork->network.Configuration.DSConfig>14*/)
423                 pnetwork->network.Configuration.DSConfig = 1;
424
425         /* Add frequency/channel */
426         iwe->cmd = SIOCGIWFREQ;
427         iwe->u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
428         iwe->u.freq.e = 1;
429         iwe->u.freq.i = pnetwork->network.Configuration.DSConfig;
430         start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_FREQ_LEN);
431         return start;
432 }
433
434 static inline char * iwe_stream_mode_process(_adapter *padapter,
435                                 struct iw_request_info* info, struct wlan_network *pnetwork,
436                                 char *start, char *stop,struct iw_event *iwe,u16 cap)
437 {
438         /* Add mode */
439         if(cap & (WLAN_CAPABILITY_IBSS |WLAN_CAPABILITY_BSS)){
440                 iwe->cmd = SIOCGIWMODE;
441                 if (cap & WLAN_CAPABILITY_BSS)
442                         iwe->u.mode = IW_MODE_MASTER;
443                 else
444                         iwe->u.mode = IW_MODE_ADHOC;
445
446                 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_UINT_LEN);
447         }
448         return start;
449 }
450
451 static inline char * iwe_stream_encryption_process(_adapter *padapter,
452                                 struct iw_request_info* info, struct wlan_network *pnetwork,
453                                 char *start, char *stop,struct iw_event *iwe,u16 cap)
454 {
455         /* Add encryption capability */
456         iwe->cmd = SIOCGIWENCODE;
457         if (cap & WLAN_CAPABILITY_PRIVACY)
458                 iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
459         else
460                 iwe->u.data.flags = IW_ENCODE_DISABLED;
461         iwe->u.data.length = 0;
462         start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid);
463         return start;
464 }
465
466 static inline char * iwe_stream_protocol_process(_adapter *padapter,
467                                 struct iw_request_info* info, struct wlan_network *pnetwork,
468                                 char *start, char *stop,struct iw_event *iwe)
469 {
470         u16 ht_cap=_FALSE,vht_cap = _FALSE;
471         u32 ht_ielen = 0, vht_ielen = 0;
472         char *p;
473         u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);// Probe Request
474
475         //parsing HT_CAP_IE
476         p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-ie_offset);
477         if(p && ht_ielen>0)
478                 ht_cap = _TRUE;
479
480         #ifdef CONFIG_80211AC_VHT
481         //parsing VHT_CAP_IE
482         p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength-ie_offset);
483         if(p && vht_ielen>0)
484                 vht_cap = _TRUE;
485         #endif
486         /* Add the protocol name */
487         iwe->cmd = SIOCGIWNAME;
488         if ((rtw_is_cckratesonly_included((u8*)&pnetwork->network.SupportedRates)) == _TRUE)
489         {
490                 if(ht_cap == _TRUE)
491                         snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bn");
492                 else
493                         snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11b");
494         }
495         else if ((rtw_is_cckrates_included((u8*)&pnetwork->network.SupportedRates)) == _TRUE)
496         {
497                 if(ht_cap == _TRUE)
498                         snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bgn");
499                 else
500                         snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bg");
501         }
502         else
503         {
504                 if(pnetwork->network.Configuration.DSConfig > 14)
505                 {
506                         #ifdef CONFIG_80211AC_VHT
507                         if(vht_cap == _TRUE){
508                                 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11AC");
509                         }
510                         else
511                         #endif
512                         {
513                                 if(ht_cap == _TRUE)
514                                         snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11an");
515                                 else
516                                         snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11a");
517                         }
518                 }
519                 else
520                 {
521                         if(ht_cap == _TRUE)
522                                 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11gn");
523                         else
524                                 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11g");
525                 }
526         }
527         start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_CHAR_LEN);
528         return start;
529 }
530
531 static inline char * iwe_stream_rate_process(_adapter *padapter,
532                                 struct iw_request_info* info, struct wlan_network *pnetwork,
533                                 char *start, char *stop,struct iw_event *iwe)
534 {
535         u32 ht_ielen = 0, vht_ielen = 0;
536         char *p;
537         u16 max_rate=0, rate, ht_cap=_FALSE, vht_cap = _FALSE;
538         u32 i = 0;
539         u8 bw_40MHz=0, short_GI=0, bw_160MHz=0, vht_highest_rate = 0;
540         u16 mcs_rate=0, vht_data_rate=0;
541         char custom[MAX_CUSTOM_LEN]={0};
542         u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);// Probe Request
543
544         //parsing HT_CAP_IE
545         p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-ie_offset);
546         if(p && ht_ielen>0)
547         {
548                 struct rtw_ieee80211_ht_cap *pht_capie;
549                 ht_cap = _TRUE;
550                 pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
551                 _rtw_memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
552                 bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH) ? 1:0;
553                 short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1:0;
554         }
555
556 #ifdef CONFIG_80211AC_VHT
557         //parsing VHT_CAP_IE
558         p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength-ie_offset);
559         if(p && vht_ielen>0)
560         {
561                 u8      mcs_map[2];
562
563                 vht_cap = _TRUE;
564                 bw_160MHz = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p+2);
565                 if(bw_160MHz)
566                         short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI160M(p+2);
567                 else
568                         short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI80M(p+2);
569
570                 _rtw_memcpy(mcs_map, GET_VHT_CAPABILITY_ELE_TX_MCS(p+2), 2);
571
572                 vht_highest_rate = rtw_get_vht_highest_rate(mcs_map);
573                 vht_data_rate = rtw_vht_mcs_to_data_rate(CHANNEL_WIDTH_80, short_GI, vht_highest_rate);
574         }
575 #endif
576
577         /*Add basic and extended rates */
578         p = custom;
579         p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
580         while(pnetwork->network.SupportedRates[i]!=0)
581         {
582                 rate = pnetwork->network.SupportedRates[i]&0x7F;
583                 if (rate > max_rate)
584                         max_rate = rate;
585                 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
586                               "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
587                 i++;
588         }
589
590 #ifdef CONFIG_80211AC_VHT
591         if(vht_cap == _TRUE) {
592                 max_rate = vht_data_rate;
593         }
594         else
595 #endif
596         if(ht_cap == _TRUE)
597         {
598                 if(mcs_rate&0x8000)//MCS15
599                 {
600                         max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130);
601                 }
602                 else if(mcs_rate&0x0080)//MCS7
603                 {
604                         max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
605                 }
606                 else//default MCS7
607                 {
608                         //DBG_871X("wx_get_scan, mcs_rate_bitmap=0x%x\n", mcs_rate);
609                         max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
610                 }
611
612                 max_rate = max_rate*2;//Mbps/2;
613         }
614
615         iwe->cmd = SIOCGIWRATE;
616         iwe->u.bitrate.fixed = iwe->u.bitrate.disabled = 0;
617         iwe->u.bitrate.value = max_rate * 500000;
618         start =iwe_stream_add_event(info, start, stop, iwe, IW_EV_PARAM_LEN);
619         return start ;
620 }
621
622 static inline char * iwe_stream_wpa_wpa2_process(_adapter *padapter,
623                                 struct iw_request_info* info, struct wlan_network *pnetwork,
624                                 char *start, char *stop,struct iw_event *iwe)
625 {
626         int buf_size = MAX_WPA_IE_LEN*2;
627         //u8 pbuf[buf_size]={0};
628         u8 *pbuf = rtw_zmalloc(buf_size);
629
630         u8 wpa_ie[255]={0},rsn_ie[255]={0};
631         u16 i, wpa_len=0,rsn_len=0;
632         u8 *p;
633         sint out_len=0;
634
635         if(pbuf){
636                 p=pbuf;
637
638                 //parsing WPA/WPA2 IE
639                 if (pnetwork->network.Reserved[0] != 2) // Probe Request
640                 {
641                         out_len=rtw_get_sec_ie(pnetwork->network.IEs ,pnetwork->network.IELength,rsn_ie,&rsn_len,wpa_ie,&wpa_len);
642                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: ssid=%s\n",pnetwork->network.Ssid.Ssid));
643                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: wpa_len=%d rsn_len=%d\n",wpa_len,rsn_len));
644
645                         if (wpa_len > 0){
646                                 _rtw_memset(pbuf, 0, buf_size);
647                                 p += sprintf(p, "wpa_ie=");
648                                 for (i = 0; i < wpa_len; i++) {
649                                         p += sprintf(p, "%02x", wpa_ie[i]);
650                                 }
651
652                                 if (wpa_len > 100) {
653                                         printk("-----------------Len %d----------------\n", wpa_len);
654                                         for (i = 0; i < wpa_len; i++) {
655                                                 printk("%02x ", wpa_ie[i]);
656                                         }
657                                         printk("\n");
658                                         printk("-----------------Len %d----------------\n", wpa_len);
659                                 }
660
661                                 _rtw_memset(iwe, 0, sizeof(*iwe));
662                                 iwe->cmd = IWEVCUSTOM;
663                                 iwe->u.data.length = strlen(pbuf);
664                                 start = iwe_stream_add_point(info, start, stop, iwe,pbuf);
665
666                                 _rtw_memset(iwe, 0, sizeof(*iwe));
667                                 iwe->cmd =IWEVGENIE;
668                                 iwe->u.data.length = wpa_len;
669                                 start = iwe_stream_add_point(info, start, stop, iwe, wpa_ie);
670                         }
671
672                         if (rsn_len > 0){
673                                 _rtw_memset(pbuf, 0, buf_size);
674                                 p += sprintf(p, "rsn_ie=");
675                                 for (i = 0; i < rsn_len; i++) {
676                                         p += sprintf(p, "%02x", rsn_ie[i]);
677                                 }
678                                 _rtw_memset(iwe, 0, sizeof(*iwe));
679                                 iwe->cmd = IWEVCUSTOM;
680                                 iwe->u.data.length = strlen(pbuf);
681                                 start = iwe_stream_add_point(info, start, stop, iwe,pbuf);
682
683                                 _rtw_memset(iwe, 0, sizeof(*iwe));
684                                 iwe->cmd =IWEVGENIE;
685                                 iwe->u.data.length = rsn_len;
686                                 start = iwe_stream_add_point(info, start, stop, iwe, rsn_ie);
687                         }
688                 }
689
690                 rtw_mfree(pbuf, buf_size);
691         }
692         return start;
693 }
694
695 static inline char * iwe_stream_wps_process(_adapter *padapter,
696                                 struct iw_request_info* info, struct wlan_network *pnetwork,
697                                 char *start, char *stop,struct iw_event *iwe)
698 {
699         //parsing WPS IE
700         uint cnt = 0,total_ielen;
701         u8 *wpsie_ptr=NULL;
702         uint wps_ielen = 0;
703         u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);
704
705         u8 *ie_ptr = pnetwork->network.IEs + ie_offset;
706         total_ielen= pnetwork->network.IELength - ie_offset;
707
708         if (pnetwork->network.Reserved[0] == 2) // Probe Request
709         {
710                 ie_ptr = pnetwork->network.IEs;
711                 total_ielen = pnetwork->network.IELength;
712         }
713         else // Beacon or Probe Respones
714         {
715                 ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
716                 total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
717         }
718
719         while(cnt < total_ielen)
720         {
721                 if(rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen>2))
722                 {
723                         wpsie_ptr = &ie_ptr[cnt];
724                         iwe->cmd =IWEVGENIE;
725                         iwe->u.data.length = (u16)wps_ielen;
726                         start = iwe_stream_add_point(info, start, stop,iwe, wpsie_ptr);
727                 }
728                 cnt+=ie_ptr[cnt+1]+2; //goto next
729         }
730         return start;
731 }
732
733 static inline char * iwe_stream_wapi_process(_adapter *padapter,
734                                 struct iw_request_info* info, struct wlan_network *pnetwork,
735                                 char *start, char *stop,struct iw_event *iwe)
736 {
737 #ifdef CONFIG_WAPI_SUPPORT
738         char *p;
739
740         if (pnetwork->network.Reserved[0] != 2) // Probe Request
741         {
742                 sint out_len_wapi=0;
743                 /* here use static for stack size */
744                 static u8 buf_wapi[MAX_WAPI_IE_LEN*2]={0};
745                 static u8 wapi_ie[MAX_WAPI_IE_LEN]={0};
746                 u16 wapi_len=0;
747                 u16  i;
748
749                 out_len_wapi=rtw_get_wapi_ie(pnetwork->network.IEs ,pnetwork->network.IELength,wapi_ie,&wapi_len);
750                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: ssid=%s\n",pnetwork->network.Ssid.Ssid));
751                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: wapi_len=%d \n",wapi_len));
752
753                 DBG_871X("rtw_wx_get_scan: %s ",pnetwork->network.Ssid.Ssid);
754                 DBG_871X("rtw_wx_get_scan: ssid = %d ",wapi_len);
755
756                 if (wapi_len > 0)
757                 {
758                         p=buf_wapi;
759                         //_rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN*2);
760                         p += sprintf(p, "wapi_ie=");
761                         for (i = 0; i < wapi_len; i++) {
762                                 p += sprintf(p, "%02x", wapi_ie[i]);
763                         }
764
765                         _rtw_memset(iwe, 0, sizeof(*iwe));
766                         iwe->cmd = IWEVCUSTOM;
767                         iwe->u.data.length = strlen(buf_wapi);
768                         start = iwe_stream_add_point(info, start, stop, iwe,buf_wapi);
769
770                         _rtw_memset(iwe, 0, sizeof(*iwe));
771                         iwe->cmd =IWEVGENIE;
772                         iwe->u.data.length = wapi_len;
773                         start = iwe_stream_add_point(info, start, stop, iwe, wapi_ie);
774                 }
775         }
776 #endif//#ifdef CONFIG_WAPI_SUPPORT
777         return start;
778 }
779
780 static inline char *  iwe_stream_rssi_process(_adapter *padapter,
781                                 struct iw_request_info* info, struct wlan_network *pnetwork,
782                                 char *start, char *stop,struct iw_event *iwe)
783 {
784         u8 ss, sq;
785         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
786
787         /* Add quality statistics */
788         iwe->cmd = IWEVQUAL;
789         iwe->u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
790         #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
791                 | IW_QUAL_NOISE_UPDATED
792         #else
793                 | IW_QUAL_NOISE_INVALID
794         #endif
795         #ifdef CONFIG_SIGNAL_DISPLAY_DBM
796                 | IW_QUAL_DBM
797         #endif
798         ;
799
800         if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE &&
801                 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)){
802                 ss = padapter->recvpriv.signal_strength;
803                 sq = padapter->recvpriv.signal_qual;
804         } else {
805                 ss = pnetwork->network.PhyInfo.SignalStrength;
806                 sq = pnetwork->network.PhyInfo.SignalQuality;
807         }
808
809         #ifdef CONFIG_SIGNAL_DISPLAY_DBM
810         iwe->u.qual.level = (u8) translate_percentage_to_dbm(ss);//dbm
811         #else
812         #ifdef CONFIG_SKIP_SIGNAL_SCALE_MAPPING
813         {
814                 /* Do signal scale mapping when using percentage as the unit of signal strength, since the scale mapping is skipped in odm */
815                 HAL_DATA_TYPE *pHal = GET_HAL_DATA(padapter);
816                 iwe->u.qual.level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, ss);
817         }
818         #else
819         iwe->u.qual.level = (u8)ss;//%
820         #endif
821         #endif
822
823         iwe->u.qual.qual = (u8)sq;   // signal quality
824
825         #ifdef CONFIG_PLATFORM_ROCKCHIPS
826         iwe->u.qual.noise = -100; // noise level suggest by zhf@rockchips
827         #else
828         #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
829         {
830                 s16 tmp_noise=0;
831                 rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&(pnetwork->network.Configuration.DSConfig), &(tmp_noise));
832                 iwe->u.qual.noise = tmp_noise;
833         }
834         #else
835         iwe->u.qual.noise = 0; // noise level
836         #endif
837         #endif //CONFIG_PLATFORM_ROCKCHIPS
838
839         //DBG_871X("iqual=%d, ilevel=%d, inoise=%d, iupdated=%d\n", iwe.u.qual.qual, iwe.u.qual.level , iwe.u.qual.noise, iwe.u.qual.updated);
840
841         start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_QUAL_LEN);
842         return start;
843 }
844
845 static inline char *  iwe_stream_net_rsv_process(_adapter *padapter,
846                                 struct iw_request_info* info, struct wlan_network *pnetwork,
847                                 char *start, char *stop,struct iw_event *iwe)
848 {
849         u8 buf[32] = {0};
850         u8 * p,*pos;
851         int len;
852         p = buf;
853         pos = pnetwork->network.Reserved;
854
855         p += sprintf(p, "fm=%02X%02X", pos[1], pos[0]);
856         _rtw_memset(iwe, 0, sizeof(*iwe));
857         iwe->cmd = IWEVCUSTOM;
858         iwe->u.data.length = strlen(buf);
859         start = iwe_stream_add_point(info, start, stop,iwe, buf);
860         return start;
861 }
862
863 static char *translate_scan(_adapter *padapter,
864                                 struct iw_request_info* info, struct wlan_network *pnetwork,
865                                 char *start, char *stop)
866 {
867         struct iw_event iwe;
868         u16 cap = 0;
869         _rtw_memset(&iwe, 0, sizeof(iwe));
870
871         if(_FALSE == search_p2p_wfd_ie(padapter,info,pnetwork,start,stop))
872                 return start;
873
874         start = iwe_stream_mac_addr_proess(padapter,info,pnetwork,start,stop,&iwe);
875         start = iwe_stream_essid_proess(padapter,info,pnetwork,start,stop,&iwe);
876         start = iwe_stream_protocol_process(padapter,info,pnetwork,start,stop,&iwe);
877         if (pnetwork->network.Reserved[0] == 2) // Probe Request
878         {
879                 cap = 0;
880         }
881         else
882         {
883                 _rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
884                 cap = le16_to_cpu(cap);
885         }
886
887         start = iwe_stream_mode_process(padapter,info,pnetwork,start,stop,&iwe,cap);
888         start = iwe_stream_chan_process(padapter,info,pnetwork,start,stop,&iwe);
889         start = iwe_stream_encryption_process(padapter,info,pnetwork,start,stop,&iwe,cap);
890         start = iwe_stream_rate_process(padapter,info,pnetwork,start,stop,&iwe);
891         start = iwe_stream_wpa_wpa2_process(padapter,info,pnetwork,start,stop,&iwe);
892         start = iwe_stream_wps_process(padapter,info,pnetwork,start,stop,&iwe);
893         start = iwe_stream_wapi_process(padapter,info,pnetwork,start,stop,&iwe);
894         start = iwe_stream_rssi_process(padapter,info,pnetwork,start,stop,&iwe);
895         start = iwe_stream_net_rsv_process(padapter,info,pnetwork,start,stop,&iwe);
896
897         return start;
898 }
899
900 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
901 {       
902         _adapter *padapter = (_adapter *) rtw_netdev_priv(dev);
903         int ret = 0;
904
905         if ((value & AUTH_ALG_SHARED_KEY)&&(value & AUTH_ALG_OPEN_SYSTEM))
906         {
907                 DBG_871X("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and  AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n",value);
908                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
909                 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
910                 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
911         } 
912         else if (value & AUTH_ALG_SHARED_KEY)
913         {
914                 DBG_871X("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY  [value:0x%x]\n",value);
915                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
916
917 #ifdef CONFIG_PLATFORM_MT53XX
918                 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
919                 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
920 #else
921                 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
922                 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
923 #endif
924         } 
925         else if(value & AUTH_ALG_OPEN_SYSTEM)
926         {
927                 DBG_871X("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
928                 //padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
929                 if(padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK)
930                 {
931 #ifdef CONFIG_PLATFORM_MT53XX
932                         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
933                         padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
934 #else
935                         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
936                         padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
937 #endif
938                 }
939                 
940         }
941         else if(value & AUTH_ALG_LEAP)
942         {
943                 DBG_871X("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
944         }
945         else
946         {
947                 DBG_871X("wpa_set_auth_algs, error!\n");
948                 ret = -EINVAL;
949         }
950
951         return ret;
952         
953 }
954
955 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
956 {
957         int ret = 0;
958         u32 wep_key_idx, wep_key_len,wep_total_len;
959         NDIS_802_11_WEP  *pwep = NULL;  
960         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
961         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;               
962         struct security_priv *psecuritypriv = &padapter->securitypriv;
963 #ifdef CONFIG_P2P
964         struct wifidirect_info* pwdinfo = &padapter->wdinfo;
965 #endif //CONFIG_P2P
966
967 _func_enter_;
968
969         param->u.crypt.err = 0;
970         param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
971
972         if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
973         {
974                 ret =  -EINVAL;
975                 goto exit;
976         }
977
978         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
979             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
980             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
981         {
982
983                 if (param->u.crypt.idx >= WEP_KEYS
984 #ifdef CONFIG_IEEE80211W
985                         && param->u.crypt.idx > BIP_MAX_KEYID
986 #endif //CONFIG_IEEE80211W
987                         )
988                 {
989                         ret = -EINVAL;
990                         goto exit;
991                 }
992         } 
993         else 
994         {
995 #ifdef CONFIG_WAPI_SUPPORT
996                 if (strcmp(param->u.crypt.alg, "SMS4"))
997 #endif
998                 {
999                         ret = -EINVAL;
1000                         goto exit;
1001                 }
1002         }
1003
1004         if (strcmp(param->u.crypt.alg, "WEP") == 0)
1005         {
1006                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n"));
1007                 DBG_871X("wpa_set_encryption, crypt.alg = WEP\n");
1008
1009                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1010                 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
1011                 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
1012
1013                 wep_key_idx = param->u.crypt.idx;
1014                 wep_key_len = param->u.crypt.key_len;
1015
1016                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("(1)wep_key_idx=%d\n", wep_key_idx));
1017                 DBG_871X("(1)wep_key_idx=%d\n", wep_key_idx);
1018
1019                 if (wep_key_idx > WEP_KEYS)
1020                         return -EINVAL;
1021
1022                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("(2)wep_key_idx=%d\n", wep_key_idx));
1023
1024                 if (wep_key_len > 0) 
1025                 {
1026                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
1027                         wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
1028                         pwep =(NDIS_802_11_WEP   *) rtw_malloc(wep_total_len);
1029                         if(pwep == NULL){
1030                                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,(" wpa_set_encryption: pwep allocate fail !!!\n"));
1031                                 goto exit;
1032                         }
1033
1034                         _rtw_memset(pwep, 0, wep_total_len);
1035
1036                         pwep->KeyLength = wep_key_len;
1037                         pwep->Length = wep_total_len;
1038
1039                         if(wep_key_len==13)
1040                         {
1041                                 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
1042                                 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
1043                         }
1044                 }
1045                 else {          
1046                         ret = -EINVAL;
1047                         goto exit;
1048                 }
1049
1050                 pwep->KeyIndex = wep_key_idx;
1051                 pwep->KeyIndex |= 0x80000000;
1052
1053                 _rtw_memcpy(pwep->KeyMaterial,  param->u.crypt.key, pwep->KeyLength);
1054
1055                 if(param->u.crypt.set_tx)
1056                 {
1057                         DBG_871X("wep, set_tx=1\n");
1058
1059                         if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
1060                         {
1061                                 ret = -EOPNOTSUPP ;
1062                         }
1063                 }
1064                 else
1065                 {
1066                         DBG_871X("wep, set_tx=0\n");
1067                         
1068                         //don't update "psecuritypriv->dot11PrivacyAlgrthm" and 
1069                         //"psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to fw/cam
1070                         
1071                         if (wep_key_idx >= WEP_KEYS) {
1072                                 ret = -EOPNOTSUPP ;
1073                                 goto exit;
1074                         }                               
1075                         
1076                       _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
1077                         psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength;     
1078                         rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, _TRUE);
1079                 }
1080
1081                 goto exit;              
1082         }
1083
1084         if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x
1085         {
1086                 struct sta_info * psta,*pbcmc_sta;
1087                 struct sta_priv * pstapriv = &padapter->stapriv;
1088
1089                 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode
1090                 {
1091                         psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));                         
1092                         if (psta == NULL) {
1093                                 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
1094                         }
1095                         else
1096                         {
1097                                 //Jeff: don't disable ieee8021x_blocked while clearing key
1098                                 if (strcmp(param->u.crypt.alg, "none") != 0) 
1099                                         psta->ieee8021x_blocked = _FALSE;
1100                                 
1101                                 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1102                                                 (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
1103                                 {
1104                                         psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1105                                 }               
1106
1107                                 if(param->u.crypt.set_tx ==1)//pairwise key
1108                                 { 
1109                                         _rtw_memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1110                                         
1111                                         if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key
1112                                         {                                               
1113                                                 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1114                                                 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1115                                                 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1116
1117                                                 padapter->securitypriv.busetkipkey=_FALSE;
1118                                                 //_set_timer(&padapter->securitypriv.tkip_timer, 50);                                           
1119                                         }
1120
1121                                         //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
1122                                         DBG_871X(" ~~~~set sta key:unicastkey\n");
1123                                         
1124                                         rtw_setstakey_cmd(padapter, psta, _TRUE, _TRUE);
1125                                 }
1126                                 else//group key
1127                                 {                                       
1128                                         if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
1129                                         {
1130                                                 _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1131                                                 //only TKIP group key need to install this
1132                                                 if(param->u.crypt.key_len > 16)
1133                                                 {
1134                                                         _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8);
1135                                                         _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8);
1136                                                 }
1137                                                 padapter->securitypriv.binstallGrpkey = _TRUE;  
1138                                                 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1139                                                 DBG_871X(" ~~~~set sta key:groupkey\n");
1140         
1141                                                 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
1142         
1143                                                 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1, _TRUE);
1144                                         }
1145 #ifdef CONFIG_IEEE80211W
1146                                         else if(strcmp(param->u.crypt.alg, "BIP") == 0)
1147                                         {
1148                                                 int no;
1149                                                 //printk("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx);
1150                                                 //save the IGTK key, length 16 bytes
1151                                                 _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey,  param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1152                                                 /*printk("IGTK key below:\n");
1153                                                 for(no=0;no<16;no++)
1154                                                         printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
1155                                                 printk("\n");*/
1156                                                 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
1157                                                 padapter->securitypriv.binstallBIPkey = _TRUE;
1158                                                 DBG_871X(" ~~~~set sta key:IGKT\n");
1159                                         }
1160 #endif //CONFIG_IEEE80211W
1161                                         
1162 #ifdef CONFIG_P2P
1163                                         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
1164                                         {
1165                                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
1166                                         }
1167 #endif //CONFIG_P2P
1168                                         
1169                                 }                                               
1170                         }
1171
1172                         pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
1173                         if(pbcmc_sta==NULL)
1174                         {
1175                                 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
1176                         }
1177                         else
1178                         {
1179                                 //Jeff: don't disable ieee8021x_blocked while clearing key
1180                                 if (strcmp(param->u.crypt.alg, "none") != 0) 
1181                                         pbcmc_sta->ieee8021x_blocked = _FALSE;
1182                                 
1183                                 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1184                                                 (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
1185                                 {                                                       
1186                                         pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1187                                 }                                       
1188                         }                               
1189                 }
1190                 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode
1191                 {               
1192                 }                       
1193         }
1194
1195 #ifdef CONFIG_WAPI_SUPPORT
1196         if (strcmp(param->u.crypt.alg, "SMS4") == 0)
1197         {
1198                 PRT_WAPI_T                      pWapiInfo = &padapter->wapiInfo;
1199                 PRT_WAPI_STA_INFO       pWapiSta;
1200                 u8                                      WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
1201                 u8                                      WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
1202                 u8                                      WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
1203
1204                 if(param->u.crypt.set_tx == 1)
1205                 {
1206                         list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1207                                 if(_rtw_memcmp(pWapiSta->PeerMacAddr,param->sta_addr,6))
1208                                 {
1209                                         _rtw_memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16);
1210
1211                                         pWapiSta->wapiUsk.bSet = true;
1212                                         _rtw_memcpy(pWapiSta->wapiUsk.dataKey,param->u.crypt.key,16);
1213                                         _rtw_memcpy(pWapiSta->wapiUsk.micKey,param->u.crypt.key+16,16);
1214                                         pWapiSta->wapiUsk.keyId = param->u.crypt.idx ;
1215                                         pWapiSta->wapiUsk.bTxEnable = true;
1216
1217                                         _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16);
1218                                         _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16);
1219                                         _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16);
1220                                         _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16);
1221                                         _rtw_memcpy(pWapiSta->lastRxUnicastPN,WapiAEPNInitialValueSrc,16);
1222                                         pWapiSta->wapiUskUpdate.bTxEnable = false;
1223                                         pWapiSta->wapiUskUpdate.bSet = false;
1224
1225                                         if (psecuritypriv->sw_encrypt== false || psecuritypriv->sw_decrypt == false)
1226                                         {
1227                                                 //set unicast key for ASUE
1228                                                 rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false);
1229                                         }
1230                                 }
1231                         }
1232                 }
1233                 else
1234                 {
1235                         list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1236                                 if(_rtw_memcmp(pWapiSta->PeerMacAddr,get_bssid(pmlmepriv),6))
1237                                 {
1238                                         pWapiSta->wapiMsk.bSet = true;
1239                                         _rtw_memcpy(pWapiSta->wapiMsk.dataKey,param->u.crypt.key,16);
1240                                         _rtw_memcpy(pWapiSta->wapiMsk.micKey,param->u.crypt.key+16,16);
1241                                         pWapiSta->wapiMsk.keyId = param->u.crypt.idx ;
1242                                         pWapiSta->wapiMsk.bTxEnable = false;
1243                                         if(!pWapiSta->bSetkeyOk)
1244                                                 pWapiSta->bSetkeyOk = true;
1245                                         pWapiSta->bAuthenticateInProgress = false;
1246
1247                                         _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
1248
1249                                         if (psecuritypriv->sw_decrypt == false)
1250                                         {
1251                                                 //set rx broadcast key for ASUE
1252                                                 rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false);
1253                                         }
1254                                 }
1255
1256                         }
1257                 }
1258         }
1259 #endif
1260
1261 exit:
1262         
1263         if (pwep) {
1264                 rtw_mfree((u8 *)pwep, wep_total_len);           
1265         }       
1266         
1267 _func_exit_;
1268
1269         return ret;     
1270 }
1271
1272 static int rtw_set_wpa_ie(_adapter *padapter, char *pie, unsigned short ielen)
1273 {
1274         u8 *buf=NULL, *pos=NULL;        
1275         u32 left;       
1276         int group_cipher = 0, pairwise_cipher = 0;
1277         int ret = 0;
1278         u8 null_addr[]= {0,0,0,0,0,0};
1279 #ifdef CONFIG_P2P
1280         struct wifidirect_info* pwdinfo = &padapter->wdinfo;
1281 #endif //CONFIG_P2P
1282
1283         if((ielen > MAX_WPA_IE_LEN) || (pie == NULL)){
1284                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1285                 if(pie == NULL) 
1286                         return ret;
1287                 else
1288                         return -EINVAL;
1289         }
1290
1291         if(ielen)
1292         {               
1293                 buf = rtw_zmalloc(ielen);
1294                 if (buf == NULL){
1295                         ret =  -ENOMEM;
1296                         goto exit;
1297                 }
1298         
1299                 _rtw_memcpy(buf, pie , ielen);
1300
1301                 //dump
1302                 {
1303                         int i;
1304                         DBG_871X("\n wpa_ie(length:%d):\n", ielen);
1305                         for(i=0;i<ielen;i=i+8)
1306                                 DBG_871X("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n",buf[i],buf[i+1],buf[i+2],buf[i+3],buf[i+4],buf[i+5],buf[i+6],buf[i+7]);
1307                 }
1308         
1309                 pos = buf;
1310                 if(ielen < RSN_HEADER_LEN){
1311                         RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
1312                         ret  = -1;
1313                         goto exit;
1314                 }
1315
1316 #if 0
1317                 pos += RSN_HEADER_LEN;
1318                 left  = ielen - RSN_HEADER_LEN;
1319                 
1320                 if (left >= RSN_SELECTOR_LEN){
1321                         pos += RSN_SELECTOR_LEN;
1322                         left -= RSN_SELECTOR_LEN;
1323                 }               
1324                 else if (left > 0){
1325                         RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie length mismatch, %u too much \n", left));
1326                         ret =-1;
1327                         goto exit;
1328                 }
1329 #endif          
1330                 
1331                 if(rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
1332                 {
1333                         padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
1334                         padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
1335                         _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);      
1336                 }
1337         
1338                 if(rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
1339                 {
1340                         padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
1341                         padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;  
1342                         _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);      
1343                 }
1344                         
1345                 if (group_cipher == 0)
1346                 {
1347                         group_cipher = WPA_CIPHER_NONE;
1348                 }
1349                 if (pairwise_cipher == 0)
1350                 {
1351                         pairwise_cipher = WPA_CIPHER_NONE;
1352                 }
1353                         
1354                 switch(group_cipher)
1355                 {
1356                         case WPA_CIPHER_NONE:
1357                                 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
1358                                 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
1359                                 break;
1360                         case WPA_CIPHER_WEP40:
1361                                 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
1362                                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1363                                 break;
1364                         case WPA_CIPHER_TKIP:
1365                                 padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
1366                                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1367                                 break;
1368                         case WPA_CIPHER_CCMP:
1369                                 padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
1370                                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1371                                 break;
1372                         case WPA_CIPHER_WEP104: 
1373                                 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
1374                                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1375                                 break;
1376                 }
1377
1378                 switch(pairwise_cipher)
1379                 {
1380                         case WPA_CIPHER_NONE:
1381                                 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
1382                                 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
1383                                 break;
1384                         case WPA_CIPHER_WEP40:
1385                                 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
1386                                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1387                                 break;
1388                         case WPA_CIPHER_TKIP:
1389                                 padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
1390                                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1391                                 break;
1392                         case WPA_CIPHER_CCMP:
1393                                 padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
1394                                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1395                                 break;
1396                         case WPA_CIPHER_WEP104: 
1397                                 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
1398                                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1399                                 break;
1400                 }
1401                 
1402                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1403                 {//set wps_ie   
1404                         u16 cnt = 0;    
1405                         u8 eid, wps_oui[4]={0x0,0x50,0xf2,0x04};
1406                          
1407                         while( cnt < ielen )
1408                         {
1409                                 eid = buf[cnt];
1410                 
1411                                 if((eid==_VENDOR_SPECIFIC_IE_)&&(_rtw_memcmp(&buf[cnt+2], wps_oui, 4)==_TRUE))
1412                                 {
1413                                         DBG_871X("SET WPS_IE\n");
1414
1415                                         padapter->securitypriv.wps_ie_len = ((buf[cnt+1]+2) < MAX_WPS_IE_LEN) ? (buf[cnt+1]+2):MAX_WPS_IE_LEN;
1416
1417                                         _rtw_memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
1418                                         
1419                                         set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
1420                                         
1421 #ifdef CONFIG_P2P
1422                                         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
1423                                         {
1424                                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING);
1425                                         }
1426 #endif //CONFIG_P2P
1427                                         cnt += buf[cnt+1]+2;
1428                                         
1429                                         break;
1430                                 } else {
1431                                         cnt += buf[cnt+1]+2; //goto next        
1432                                 }                               
1433                         }                       
1434                 }               
1435         }
1436         
1437         //TKIP and AES disallow multicast packets until installing group key
1438         if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
1439                 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
1440                 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
1441                 //WPS open need to enable multicast
1442                 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
1443                 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
1444         
1445         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1446                  ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
1447                   pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
1448         
1449 exit:
1450
1451         if (buf) rtw_mfree(buf, ielen);
1452
1453         return ret;
1454 }
1455
1456 static int rtw_wx_get_name(struct net_device *dev, 
1457                              struct iw_request_info *info, 
1458                              union iwreq_data *wrqu, char *extra)
1459 {
1460         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1461         u16 cap;
1462         u32 ht_ielen = 0;
1463         char *p;
1464         u8 ht_cap=_FALSE, vht_cap=_FALSE;
1465         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
1466         WLAN_BSSID_EX  *pcur_bss = &pmlmepriv->cur_network.network;
1467         NDIS_802_11_RATES_EX* prates = NULL;
1468
1469         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("cmd_code=%x\n", info->cmd));
1470
1471         _func_enter_;   
1472
1473         if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE)
1474         {
1475                 //parsing HT_CAP_IE
1476                 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12);
1477                 if(p && ht_ielen>0)
1478                 {
1479                         ht_cap = _TRUE;
1480                 }
1481
1482 #ifdef CONFIG_80211AC_VHT
1483                 if(pmlmepriv->vhtpriv.vht_option == _TRUE)
1484                         vht_cap = _TRUE;
1485 #endif
1486
1487                 prates = &pcur_bss->SupportedRates;
1488
1489                 if (rtw_is_cckratesonly_included((u8*)prates) == _TRUE)
1490                 {
1491                         if(ht_cap == _TRUE)
1492                                 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
1493                         else
1494                                 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
1495                 }
1496                 else if ((rtw_is_cckrates_included((u8*)prates)) == _TRUE)
1497                 {
1498                         if(ht_cap == _TRUE)
1499                                 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
1500                         else
1501                                 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
1502                 }
1503                 else
1504                 {
1505                         if(pcur_bss->Configuration.DSConfig > 14)
1506                         {
1507                                 if(vht_cap == _TRUE)
1508                                         snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC");
1509                                 else if(ht_cap == _TRUE)
1510                                         snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
1511                                 else
1512                                         snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
1513                         }
1514                         else
1515                         {
1516                                 if(ht_cap == _TRUE)
1517                                         snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
1518                                 else
1519                                         snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
1520                         }
1521                 }
1522         }
1523         else
1524         {
1525                 //prates = &padapter->registrypriv.dev_network.SupportedRates;
1526                 //snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
1527                 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
1528         }
1529
1530         _func_exit_;
1531
1532         return 0;
1533 }
1534
1535 static int rtw_wx_set_freq(struct net_device *dev, 
1536                              struct iw_request_info *info, 
1537                              union iwreq_data *wrqu, char *extra)
1538 {       
1539
1540         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1541         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
1542         struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
1543         int exp = 1, freq = 0, div = 0;
1544
1545         _func_enter_;
1546
1547         RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n"));
1548
1549         if (wrqu->freq.m <= 1000) {
1550                 if (wrqu->freq.flags == IW_FREQ_AUTO) {
1551                         padapter->mlmeextpriv.cur_channel = 1;
1552                         DBG_871X("%s: channel is auto, set to channel 1\n", __func__);
1553                 } else {
1554                         padapter->mlmeextpriv.cur_channel = wrqu->freq.m;
1555                         DBG_871X("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel);
1556                 }
1557         } else {
1558                 while (wrqu->freq.e) {
1559                         exp *= 10;
1560                         wrqu->freq.e--;
1561                 }
1562
1563                 freq = wrqu->freq.m;
1564                 while (!(freq%10)) {
1565                         freq /= 10;
1566                         exp *= 10;
1567                 }
1568
1569                 /* freq unit is MHz here */
1570                 div = 1000000/exp;
1571
1572                 if (div)
1573                         freq /= div;
1574                 else {
1575                         div = exp/1000000;
1576                         freq *= div;
1577                 }
1578
1579                 /* If freq is invalid, rtw_freq2ch() will return channel 1 */
1580                 padapter->mlmeextpriv.cur_channel = rtw_freq2ch(freq);
1581                 DBG_871X("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel);
1582         }
1583
1584         _func_exit_;
1585         
1586         return 0;
1587 }
1588
1589 static int rtw_wx_get_freq(struct net_device *dev, 
1590                              struct iw_request_info *info, 
1591                              union iwreq_data *wrqu, char *extra)
1592 {
1593         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1594         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
1595         WLAN_BSSID_EX  *pcur_bss = &pmlmepriv->cur_network.network;
1596         
1597         if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
1598         {
1599                 //wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000;
1600                 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
1601                 wrqu->freq.e = 1;
1602                 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
1603
1604         }
1605         else{
1606                 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
1607                 wrqu->freq.e = 1;
1608                 wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
1609         }
1610
1611         return 0;
1612 }
1613
1614 static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
1615                              union iwreq_data *wrqu, char *b)
1616 {
1617         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1618         NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
1619         int ret = 0;
1620         
1621         _func_enter_;
1622         
1623         if(_FAIL == rtw_pwr_wakeup(padapter)) {
1624                 ret= -EPERM;
1625                 goto exit;
1626         }
1627
1628         if (padapter->hw_init_completed==_FALSE){
1629                 ret = -EPERM;
1630                 goto exit;
1631         }
1632
1633         /* initial default type */
1634         dev->type = ARPHRD_ETHER;
1635
1636         switch(wrqu->mode)
1637         {
1638                 case IW_MODE_MONITOR:
1639                         networkType = Ndis802_11Monitor;
1640 #if 0
1641                         dev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */
1642 #endif
1643                         dev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */
1644                         DBG_871X("set_mode = IW_MODE_MONITOR\n");
1645                         break;
1646
1647                 case IW_MODE_AUTO:
1648                         networkType = Ndis802_11AutoUnknown;
1649                         DBG_871X("set_mode = IW_MODE_AUTO\n");  
1650                         break;                          
1651                 case IW_MODE_ADHOC:             
1652                         networkType = Ndis802_11IBSS;
1653                         DBG_871X("set_mode = IW_MODE_ADHOC\n");                 
1654                         break;
1655                 case IW_MODE_MASTER:            
1656                         networkType = Ndis802_11APMode;
1657                         DBG_871X("set_mode = IW_MODE_MASTER\n");
1658                         //rtw_setopmode_cmd(padapter, networkType,_TRUE);       
1659                         break;                          
1660                 case IW_MODE_INFRA:
1661                         networkType = Ndis802_11Infrastructure;
1662                         DBG_871X("set_mode = IW_MODE_INFRA\n");                 
1663                         break;
1664         
1665                 default :
1666                         ret = -EINVAL;;
1667                         RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("\n Mode: %s is not supported  \n", iw_operation_mode[wrqu->mode]));
1668                         goto exit;
1669         }
1670         
1671 /*      
1672         if(Ndis802_11APMode == networkType)
1673         {
1674                 rtw_setopmode_cmd(padapter, networkType,_TRUE);
1675         }       
1676         else
1677         {
1678                 rtw_setopmode_cmd(padapter, Ndis802_11AutoUnknown,_TRUE);       
1679         }
1680 */
1681         
1682         if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE){
1683
1684                 ret = -EPERM;
1685                 goto exit;
1686
1687         }
1688
1689         rtw_setopmode_cmd(padapter, networkType,_TRUE);
1690
1691 exit:
1692         
1693         _func_exit_;
1694         
1695         return ret;
1696         
1697 }
1698
1699 static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
1700                              union iwreq_data *wrqu, char *b)
1701 {
1702         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1703         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
1704         
1705         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,(" rtw_wx_get_mode \n"));
1706
1707         _func_enter_;
1708         
1709         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1710         {
1711                 wrqu->mode = IW_MODE_INFRA;
1712         }
1713         else if  ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
1714                        (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
1715                 
1716         {
1717                 wrqu->mode = IW_MODE_ADHOC;
1718         }
1719         else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1720         {
1721                 wrqu->mode = IW_MODE_MASTER;
1722         }
1723         else
1724         {
1725                 wrqu->mode = IW_MODE_AUTO;
1726         }
1727
1728         _func_exit_;
1729         
1730         return 0;
1731         
1732 }
1733
1734
1735 static int rtw_wx_set_pmkid(struct net_device *dev,
1736                              struct iw_request_info *a,
1737                              union iwreq_data *wrqu, char *extra)
1738 {
1739         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1740         u8          j,blInserted = _FALSE;
1741         int         intReturn = _FALSE;
1742         struct mlme_priv  *pmlmepriv = &padapter->mlmepriv;
1743         struct security_priv *psecuritypriv = &padapter->securitypriv;
1744         struct iw_pmksa*  pPMK = ( struct iw_pmksa* ) extra;
1745         u8     strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
1746         u8     strIssueBssid[ ETH_ALEN ] = { 0x00 };
1747         
1748 /*
1749         struct iw_pmksa
1750         {
1751             __u32   cmd;
1752             struct sockaddr bssid;
1753             __u8    pmkid[IW_PMKID_LEN];   //IW_PMKID_LEN=16
1754         }
1755         There are the BSSID information in the bssid.sa_data array.
1756         If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear all the PMKID information.
1757         If cmd is IW_PMKSA_ADD, it means the wpa_supplicant wants to add a PMKID/BSSID to driver.
1758         If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to remove a PMKID/BSSID from driver.
1759         */
1760
1761         _rtw_memcpy( strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
1762         if ( pPMK->cmd == IW_PMKSA_ADD )
1763         {
1764                 DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n" );
1765                 if ( _rtw_memcmp( strIssueBssid, strZeroMacAddress, ETH_ALEN ) == _TRUE )
1766                 {
1767                     return( intReturn );
1768                 }
1769                 else
1770                 {
1771                     intReturn = _TRUE;
1772                 }
1773                 blInserted = _FALSE;
1774                 
1775                 //overwrite PMKID
1776                 for(j=0 ; j<NUM_PMKID_CACHE; j++)
1777                 {
1778                         if( _rtw_memcmp( psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) ==_TRUE )
1779                         { // BSSID is matched, the same AP => rewrite with new PMKID.
1780                                 
1781                                 DBG_871X( "[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n" );
1782
1783                                 _rtw_memcpy( psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1784                                 psecuritypriv->PMKIDList[ j ].bUsed = _TRUE;
1785                                 psecuritypriv->PMKIDIndex = j+1;
1786                                 blInserted = _TRUE;
1787                                 break;
1788                         }       
1789                 }
1790
1791                 if(!blInserted)
1792                 {
1793                     // Find a new entry
1794                     DBG_871X( "[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
1795                             psecuritypriv->PMKIDIndex );
1796
1797                     _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
1798                     _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1799
1800                     psecuritypriv->PMKIDList[ psecuritypriv->PMKIDIndex ].bUsed = _TRUE;
1801                     psecuritypriv->PMKIDIndex++ ;
1802                     if(psecuritypriv->PMKIDIndex==16)
1803                     {
1804                         psecuritypriv->PMKIDIndex =0;
1805                     }
1806                 }
1807         }
1808         else if ( pPMK->cmd == IW_PMKSA_REMOVE )
1809         {
1810                 DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n" );
1811                 intReturn = _TRUE;
1812                 for(j=0 ; j<NUM_PMKID_CACHE; j++)
1813                 {
1814                         if( _rtw_memcmp( psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) ==_TRUE )
1815                         { // BSSID is matched, the same AP => Remove this PMKID information and reset it. 
1816                                 _rtw_memset( psecuritypriv->PMKIDList[ j ].Bssid, 0x00, ETH_ALEN );
1817                                 psecuritypriv->PMKIDList[ j ].bUsed = _FALSE;
1818                                 break;
1819                         }       
1820                 }
1821         }
1822         else if ( pPMK->cmd == IW_PMKSA_FLUSH ) 
1823         {
1824             DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n" );
1825             _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
1826             psecuritypriv->PMKIDIndex = 0;
1827             intReturn = _TRUE;
1828         }
1829     return( intReturn );
1830 }
1831
1832 static int rtw_wx_get_sens(struct net_device *dev, 
1833                              struct iw_request_info *info, 
1834                              union iwreq_data *wrqu, char *extra)
1835 {
1836         #ifdef CONFIG_PLATFORM_ROCKCHIPS
1837         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1838         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 
1839         
1840         /*
1841         *  20110311 Commented by Jeff
1842         *  For rockchip platform's wpa_driver_wext_get_rssi
1843         */
1844         if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
1845                 //wrqu->sens.value=-padapter->recvpriv.signal_strength;
1846                 wrqu->sens.value=-padapter->recvpriv.rssi;
1847                 //DBG_871X("%s: %d\n", __FUNCTION__, wrqu->sens.value);
1848                 wrqu->sens.fixed = 0; /* no auto select */ 
1849         } else 
1850         #endif
1851         {
1852                 wrqu->sens.value = 0;
1853                 wrqu->sens.fixed = 0;   /* no auto select */
1854                 wrqu->sens.disabled = 1;
1855         }
1856         return 0;
1857 }
1858
1859 static int rtw_wx_get_range(struct net_device *dev, 
1860                                 struct iw_request_info *info, 
1861                                 union iwreq_data *wrqu, char *extra)
1862 {
1863         struct iw_range *range = (struct iw_range *)extra;
1864         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1865         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1866
1867         u16 val;
1868         int i;
1869         
1870         _func_enter_;
1871         
1872         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_range. cmd_code=%x\n", info->cmd));
1873
1874         wrqu->data.length = sizeof(*range);
1875         _rtw_memset(range, 0, sizeof(*range));
1876
1877         /* Let's try to keep this struct in the same order as in
1878          * linux/include/wireless.h
1879          */
1880
1881         /* TODO: See what values we can set, and remove the ones we can't
1882          * set, or fill them with some default data.
1883          */
1884
1885         /* ~5 Mb/s real (802.11b) */
1886         range->throughput = 5 * 1000 * 1000;     
1887
1888         // TODO: Not used in 802.11b?
1889 //      range->min_nwid;        /* Minimal NWID we are able to set */
1890         // TODO: Not used in 802.11b?
1891 //      range->max_nwid;        /* Maximal NWID we are able to set */
1892
1893         /* Old Frequency (backward compat - moved lower ) */
1894 //      range->old_num_channels; 
1895 //      range->old_num_frequency;
1896 //      range->old_freq[6]; /* Filler to keep "version" at the same offset */
1897
1898         /* signal level threshold range */
1899
1900         //percent values between 0 and 100.
1901         range->max_qual.qual = 100;     
1902         range->max_qual.level = 100;
1903         range->max_qual.noise = 100;
1904         range->max_qual.updated = 7; /* Updated all three */
1905
1906
1907         range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
1908         /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
1909         range->avg_qual.level = 20 + -98;
1910         range->avg_qual.noise = 0;
1911         range->avg_qual.updated = 7; /* Updated all three */
1912
1913         range->num_bitrates = RATE_COUNT;
1914
1915         for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
1916                 range->bitrate[i] = rtw_rates[i];
1917         }
1918
1919         range->min_frag = MIN_FRAG_THRESHOLD;
1920         range->max_frag = MAX_FRAG_THRESHOLD;
1921
1922         range->pm_capa = 0;
1923
1924         range->we_version_compiled = WIRELESS_EXT;
1925         range->we_version_source = 16;
1926
1927 //      range->retry_capa;      /* What retry options are supported */
1928 //      range->retry_flags;     /* How to decode max/min retry limit */
1929 //      range->r_time_flags;    /* How to decode max/min retry life */
1930 //      range->min_retry;       /* Minimal number of retries */
1931 //      range->max_retry;       /* Maximal number of retries */
1932 //      range->min_r_time;      /* Minimal retry lifetime */
1933 //      range->max_r_time;      /* Maximal retry lifetime */
1934
1935         for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
1936
1937                 // Include only legal frequencies for some countries
1938                 if(pmlmeext->channel_set[i].ChannelNum != 0)
1939                 {
1940                         range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
1941                         range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
1942                         range->freq[val].e = 1;
1943                         val++;
1944                 }
1945
1946                 if (val == IW_MAX_FREQUENCIES)
1947                         break;
1948         }
1949
1950         range->num_channels = val;
1951         range->num_frequency = val;
1952
1953 // Commented by Albert 2009/10/13
1954 // The following code will proivde the security capability to network manager.
1955 // If the driver doesn't provide this capability to network manager,
1956 // the WPA/WPA2 routers can't be choosen in the network manager.
1957
1958 /*
1959 #define IW_SCAN_CAPA_NONE               0x00
1960 #define IW_SCAN_CAPA_ESSID              0x01
1961 #define IW_SCAN_CAPA_BSSID              0x02
1962 #define IW_SCAN_CAPA_CHANNEL    0x04
1963 #define IW_SCAN_CAPA_MODE               0x08
1964 #define IW_SCAN_CAPA_RATE               0x10
1965 #define IW_SCAN_CAPA_TYPE               0x20
1966 #define IW_SCAN_CAPA_TIME               0x40
1967 */
1968
1969 #if WIRELESS_EXT > 17
1970         range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
1971                           IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
1972 #endif
1973
1974 #ifdef IW_SCAN_CAPA_ESSID //WIRELESS_EXT > 21
1975         range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |IW_SCAN_CAPA_BSSID|
1976                                         IW_SCAN_CAPA_CHANNEL|IW_SCAN_CAPA_MODE|IW_SCAN_CAPA_RATE;
1977 #endif
1978
1979
1980         _func_exit_;
1981
1982         return 0;
1983
1984 }
1985
1986 //set bssid flow
1987 //s1. rtw_set_802_11_infrastructure_mode()
1988 //s2. rtw_set_802_11_authentication_mode()
1989 //s3. set_802_11_encryption_mode()
1990 //s4. rtw_set_802_11_bssid()
1991 static int rtw_wx_set_wap(struct net_device *dev,
1992                          struct iw_request_info *info,
1993                          union iwreq_data *awrq,
1994                          char *extra)
1995 {
1996         _irqL   irqL;
1997         uint ret = 0;
1998         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1999         struct sockaddr *temp = (struct sockaddr *)awrq;
2000         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
2001         _list   *phead;
2002         u8 *dst_bssid, *src_bssid;
2003         _queue  *queue  = &(pmlmepriv->scanned_queue);
2004         struct  wlan_network    *pnetwork = NULL;
2005         NDIS_802_11_AUTHENTICATION_MODE authmode;
2006
2007         _func_enter_;
2008 /*
2009 #ifdef CONFIG_CONCURRENT_MODE
2010         if(padapter->iface_type > PRIMARY_IFACE)
2011         {
2012                 ret = -EINVAL;
2013                 goto exit;
2014         }
2015 #endif  
2016 */      
2017
2018 #ifdef CONFIG_CONCURRENT_MODE
2019         if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2020         {
2021                 DBG_871X("set bssid, but buddy_intf is under scanning or linking\n");
2022
2023                 ret = -EINVAL;
2024
2025                 goto exit;
2026         }
2027 #endif
2028
2029 #ifdef CONFIG_DUALMAC_CONCURRENT
2030         if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE)
2031         {
2032                 DBG_871X("set bssid, but buddy_intf is under scanning or linking\n");
2033                 ret = -EINVAL;
2034                 goto exit;
2035         }
2036 #endif
2037
2038         rtw_ps_deny(padapter, PS_DENY_JOIN);
2039         if(_FAIL == rtw_pwr_wakeup(padapter))
2040         {
2041                 ret= -1;
2042                 goto exit;
2043         }
2044         
2045         if(!padapter->bup){
2046                 ret = -1;
2047                 goto exit;
2048         }
2049
2050         
2051         if (temp->sa_family != ARPHRD_ETHER){
2052                 ret = -EINVAL;
2053                 goto exit;
2054         }
2055
2056         authmode = padapter->securitypriv.ndisauthtype;
2057         _enter_critical_bh(&queue->lock, &irqL);
2058        phead = get_list_head(queue);
2059        pmlmepriv->pscanned = get_next(phead);
2060
2061         while (1)
2062          {
2063                         
2064                 if ((rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) == _TRUE)
2065                 {
2066 #if 0           
2067                         ret = -EINVAL;
2068                         goto exit;
2069
2070                         if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
2071                         {
2072                                 rtw_set_802_11_bssid(padapter, temp->sa_data);
2073                                 goto exit;                    
2074                         }
2075                         else
2076                         {
2077                                 ret = -EINVAL;
2078                                 goto exit;
2079                         }
2080 #endif
2081
2082                         break;
2083                 }
2084         
2085                 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
2086
2087                 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
2088
2089                 dst_bssid = pnetwork->network.MacAddress;
2090
2091                 src_bssid = temp->sa_data;
2092
2093                 if ((_rtw_memcmp(dst_bssid, src_bssid, ETH_ALEN)) == _TRUE)
2094                 {                       
2095                         if(!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode))
2096                         {
2097                                 ret = -1;
2098                                 _exit_critical_bh(&queue->lock, &irqL);
2099                                 goto exit;
2100                         }
2101
2102                                 break;                  
2103                 }
2104
2105         }               
2106         _exit_critical_bh(&queue->lock, &irqL);
2107         
2108         rtw_set_802_11_authentication_mode(padapter, authmode);
2109         //set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
2110         if (rtw_set_802_11_bssid(padapter, temp->sa_data) == _FALSE) {
2111                 ret = -1;
2112                 goto exit;              
2113         }       
2114         
2115 exit:
2116         
2117         rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
2118
2119         _func_exit_;
2120         
2121         return ret;     
2122 }
2123
2124 static int rtw_wx_get_wap(struct net_device *dev, 
2125                             struct iw_request_info *info, 
2126                             union iwreq_data *wrqu, char *extra)
2127 {
2128
2129         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
2130         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
2131         WLAN_BSSID_EX  *pcur_bss = &pmlmepriv->cur_network.network;     
2132         
2133         wrqu->ap_addr.sa_family = ARPHRD_ETHER;
2134         
2135         _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
2136         
2137         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_wap\n"));
2138
2139         _func_enter_;
2140
2141         if  ( ((check_fwstate(pmlmepriv, _FW_LINKED)) == _TRUE) || 
2142                         ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) ||
2143                         ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == _TRUE) )
2144         {
2145
2146                 _rtw_memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
2147         }
2148         else
2149         {
2150                 _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
2151         }               
2152
2153         _func_exit_;
2154         
2155         return 0;
2156         
2157 }
2158
2159 static int rtw_wx_set_mlme(struct net_device *dev, 
2160                              struct iw_request_info *info, 
2161                              union iwreq_data *wrqu, char *extra)
2162 {
2163 #if 0
2164 /* SIOCSIWMLME data */
2165 struct  iw_mlme
2166 {
2167         __u16           cmd; /* IW_MLME_* */
2168         __u16           reason_code;
2169         struct sockaddr addr;
2170 };
2171 #endif
2172
2173         int ret=0;
2174         u16 reason;
2175         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2176         struct iw_mlme *mlme = (struct iw_mlme *) extra;
2177
2178
2179         if(mlme==NULL)
2180                 return -1;
2181
2182         DBG_871X("%s\n", __FUNCTION__);
2183
2184         reason = cpu_to_le16(mlme->reason_code);
2185
2186
2187         DBG_871X("%s, cmd=%d, reason=%d\n", __FUNCTION__, mlme->cmd, reason);
2188         
2189
2190         switch (mlme->cmd) 
2191         {
2192                 case IW_MLME_DEAUTH:
2193                                 if(!rtw_set_802_11_disassociate(padapter))
2194                                 ret = -1;
2195                                 break;
2196
2197                 case IW_MLME_DISASSOC:
2198                                 if(!rtw_set_802_11_disassociate(padapter))
2199                                                 ret = -1;
2200
2201                                 break;
2202
2203                 default:
2204                         return -EOPNOTSUPP;
2205         }
2206
2207         return ret;
2208 }
2209
2210 static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
2211                              union iwreq_data *wrqu, char *extra)
2212 {
2213         u8 _status = _FALSE;
2214         int ret = 0;    
2215         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2216         struct mlme_priv *pmlmepriv= &padapter->mlmepriv;
2217         NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
2218         _irqL   irqL;
2219 #ifdef CONFIG_P2P
2220         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);   
2221 #endif //CONFIG_P2P
2222         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_set_scan\n"));
2223
2224 _func_enter_;
2225
2226         #ifdef DBG_IOCTL
2227         DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__);
2228         #endif
2229 /*
2230 #ifdef CONFIG_CONCURRENT_MODE
2231         if(padapter->iface_type > PRIMARY_IFACE)
2232         {
2233                 ret = -1;
2234                 goto exit;
2235         }
2236 #endif
2237 */
2238 #ifdef CONFIG_MP_INCLUDED
2239                 if (padapter->registrypriv.mp_mode == 1)
2240                 {
2241                                 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter));      
2242                                 ret = -1;
2243                                 goto exit;
2244                 }
2245 #ifdef CONFIG_CONCURRENT_MODE
2246                         if (padapter->pbuddy_adapter) {
2247                                 if (padapter->pbuddy_adapter->registrypriv.mp_mode == 1)
2248                                 {
2249                                         DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter->pbuddy_adapter));
2250                                         ret = -1;
2251                                         goto exit;
2252                                 }
2253                         }
2254 #endif //CONFIG_CONCURRENT_MODE
2255 #endif
2256
2257         rtw_ps_deny(padapter, PS_DENY_SCAN);
2258         if(_FAIL == rtw_pwr_wakeup(padapter))
2259         {
2260                 ret= -1;
2261                 goto exit;
2262         }
2263
2264         if(padapter->bDriverStopped){
2265            DBG_871X("bDriverStopped=%d\n", padapter->bDriverStopped);
2266                 ret= -1;
2267                 goto exit;
2268         }
2269         
2270         if(!padapter->bup){
2271                 ret = -1;
2272                 goto exit;
2273         }
2274         
2275         if (padapter->hw_init_completed==_FALSE){
2276                 ret = -1;
2277                 goto exit;
2278         }
2279
2280         // When Busy Traffic, driver do not site survey. So driver return success.
2281         // wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout.
2282         // modify by thomas 2011-02-22.
2283         if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE
2284 #ifdef CONFIG_CONCURRENT_MODE
2285         || rtw_get_buddy_bBusyTraffic(padapter) == _TRUE
2286 #endif //CONFIG_CONCURRENT_MODE
2287         )
2288         {
2289                 indicate_wx_scan_complete_event(padapter);
2290                 goto exit;
2291         }
2292
2293         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2294         {
2295                 indicate_wx_scan_complete_event(padapter);
2296                 goto exit;
2297         } 
2298
2299 #ifdef CONFIG_CONCURRENT_MODE
2300         if (check_buddy_fwstate(padapter,
2301                 _FW_UNDER_SURVEY|_FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
2302         {
2303                 indicate_wx_scan_complete_event(padapter);
2304                 goto exit;
2305         }
2306 #endif
2307
2308 #ifdef CONFIG_DUALMAC_CONCURRENT
2309         if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE)
2310         {
2311                 indicate_wx_scan_complete_event(padapter);
2312                 goto exit;
2313         }
2314 #endif
2315
2316 #ifdef CONFIG_P2P
2317         if ( pwdinfo->p2p_state != P2P_STATE_NONE )
2318         {
2319                 rtw_p2p_set_pre_state( pwdinfo, rtw_p2p_state( pwdinfo ) );
2320                 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
2321                 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL);
2322                 rtw_free_network_queue(padapter, _TRUE);
2323         }
2324 #endif //CONFIG_P2P
2325
2326         _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
2327
2328 #if WIRELESS_EXT >= 17
2329         if (wrqu->data.length == sizeof(struct iw_scan_req)) 
2330         {
2331                 struct iw_scan_req *req = (struct iw_scan_req *)extra;
2332         
2333                 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
2334                 {
2335                         int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
2336
2337                         _rtw_memcpy(ssid[0].Ssid, req->essid, len);
2338                         ssid[0].SsidLength = len;       
2339
2340                         DBG_871X("IW_SCAN_THIS_ESSID, ssid=%s, len=%d\n", req->essid, req->essid_len);
2341                 
2342                         _enter_critical_bh(&pmlmepriv->lock, &irqL);                            
2343                 
2344                         _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0);
2345                 
2346                         _exit_critical_bh(&pmlmepriv->lock, &irqL);
2347                         
2348                 }
2349                 else if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
2350                 {
2351                         DBG_871X("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
2352                 }
2353                 
2354         }
2355         else
2356 #endif
2357
2358         if(     wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE
2359                 && _rtw_memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
2360         )
2361         {
2362                 int len = wrqu->data.length -WEXT_CSCAN_HEADER_SIZE;
2363                 char *pos = extra+WEXT_CSCAN_HEADER_SIZE;
2364                 char section;
2365                 char sec_len;
2366                 int ssid_index = 0;
2367
2368                 //DBG_871X("%s COMBO_SCAN header is recognized\n", __FUNCTION__);
2369                 
2370                 while(len >= 1) {
2371                         section = *(pos++); len-=1;
2372
2373                         switch(section) {
2374                                 case WEXT_CSCAN_SSID_SECTION:
2375                                         //DBG_871X("WEXT_CSCAN_SSID_SECTION\n");
2376                                         if(len < 1) {
2377                                                 len = 0;
2378                                                 break;
2379                                         }
2380                                         
2381                                         sec_len = *(pos++); len-=1;
2382
2383                                         if(sec_len>0 && sec_len<=len) {
2384                                                 ssid[ssid_index].SsidLength = sec_len;
2385                                                 _rtw_memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength);
2386                                                 //DBG_871X("%s COMBO_SCAN with specific ssid:%s, %d\n", __FUNCTION__
2387                                                 //      , ssid[ssid_index].Ssid, ssid[ssid_index].SsidLength);
2388                                                 ssid_index++;
2389                                         }
2390                                         
2391                                         pos+=sec_len; len-=sec_len;
2392                                         break;
2393                                         
2394                                 
2395                                 case WEXT_CSCAN_CHANNEL_SECTION:
2396                                         //DBG_871X("WEXT_CSCAN_CHANNEL_SECTION\n");
2397                                         pos+=1; len-=1;
2398                                         break;
2399                                 case WEXT_CSCAN_ACTV_DWELL_SECTION:
2400                                         //DBG_871X("WEXT_CSCAN_ACTV_DWELL_SECTION\n");
2401                                         pos+=2; len-=2;
2402                                         break;
2403                                 case WEXT_CSCAN_PASV_DWELL_SECTION:
2404                                         //DBG_871X("WEXT_CSCAN_PASV_DWELL_SECTION\n");
2405                                         pos+=2; len-=2;                                 
2406                                         break;
2407                                 case WEXT_CSCAN_HOME_DWELL_SECTION:
2408                                         //DBG_871X("WEXT_CSCAN_HOME_DWELL_SECTION\n");
2409                                         pos+=2; len-=2;
2410                                         break;
2411                                 case WEXT_CSCAN_TYPE_SECTION:
2412                                         //DBG_871X("WEXT_CSCAN_TYPE_SECTION\n");
2413                                         pos+=1; len-=1;
2414                                         break;
2415                                 #if 0
2416                                 case WEXT_CSCAN_NPROBE_SECTION:
2417                                         DBG_871X("WEXT_CSCAN_NPROBE_SECTION\n");
2418                                         break;
2419                                 #endif
2420                                 
2421                                 default:
2422                                         //DBG_871X("Unknown CSCAN section %c\n", section);
2423                                         len = 0; // stop parsing
2424                         }
2425                         //DBG_871X("len:%d\n", len);
2426                         
2427                 }
2428                 
2429                 //jeff: it has still some scan paramater to parse, we only do this now...
2430                 _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
2431                 
2432         } else
2433         
2434         {
2435                 _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
2436         }
2437
2438         if(_status == _FALSE)
2439                 ret = -1;
2440
2441 exit:
2442
2443         rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
2444
2445         #ifdef DBG_IOCTL
2446         DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret);
2447         #endif
2448
2449 _func_exit_;
2450
2451         return ret;     
2452 }
2453
2454 static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
2455                              union iwreq_data *wrqu, char *extra)
2456 {
2457         _irqL   irqL;
2458         _list                                   *plist, *phead;
2459         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2460         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
2461         _queue                          *queue  = &(pmlmepriv->scanned_queue);
2462         struct  wlan_network    *pnetwork = NULL;
2463         char *ev = extra;
2464         char *stop = ev + wrqu->data.length;
2465         u32 ret = 0;
2466         u32 cnt=0;
2467         u32 wait_for_surveydone;
2468         sint wait_status;
2469 #ifdef CONFIG_CONCURRENT_MODE
2470         //PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
2471         //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);      
2472 #endif
2473 #ifdef CONFIG_P2P
2474         struct  wifidirect_info*        pwdinfo = &padapter->wdinfo;
2475 #endif //CONFIG_P2P
2476         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan\n"));
2477         RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_, (" Start of Query SIOCGIWSCAN .\n"));
2478
2479         _func_enter_;
2480
2481         #ifdef DBG_IOCTL
2482         DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__);
2483         #endif
2484 /*
2485 #ifdef CONFIG_CONCURRENT_MODE
2486         if(padapter->iface_type > PRIMARY_IFACE)
2487         {
2488                 ret = -EINVAL;
2489                 goto exit;
2490         }
2491 #endif
2492 */      
2493         if(adapter_to_pwrctl(padapter)->brfoffbyhw && padapter->bDriverStopped)
2494         {
2495                 ret = -EINVAL;
2496                 goto exit;
2497         }
2498   
2499 #ifdef CONFIG_P2P
2500         if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2501         {
2502                 //      P2P is enabled
2503                 if ( padapter->chip_type == RTL8192D )
2504                         wait_for_surveydone = 300;      //      Because the 8192du supports more channels.
2505                 else
2506                         wait_for_surveydone = 200;
2507         }
2508         else
2509         {
2510                 //      P2P is disabled
2511                 wait_for_surveydone = 100;
2512         }
2513 #else
2514         {
2515                 wait_for_surveydone = 100;
2516         }
2517 #endif //CONFIG_P2P
2518
2519 #if 1 // Wireless Extension use EAGAIN to try
2520         wait_status = _FW_UNDER_SURVEY
2521 #ifndef CONFIG_ANDROID
2522                 | _FW_UNDER_LINKING
2523 #endif
2524         ;
2525
2526         while (check_fwstate(pmlmepriv, wait_status) == _TRUE)
2527         {
2528                 return -EAGAIN;
2529         }
2530 #else
2531         wait_status = _FW_UNDER_SURVEY
2532                 #ifndef CONFIG_ANDROID
2533                 |_FW_UNDER_LINKING
2534                 #endif
2535         ;
2536
2537 #ifdef CONFIG_DUALMAC_CONCURRENT
2538         while(dc_check_fwstate(padapter, wait_status)== _TRUE)
2539         {
2540                 rtw_msleep_os(30);
2541                 cnt++;
2542                 if(cnt > wait_for_surveydone )
2543                         break;
2544         }
2545 #endif // CONFIG_DUALMAC_CONCURRENT
2546
2547         while(check_fwstate(pmlmepriv, wait_status) == _TRUE)
2548         {       
2549                 rtw_msleep_os(30);
2550                 cnt++;
2551                 if(cnt > wait_for_surveydone )
2552                         break;
2553         }
2554 #endif
2555         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2556
2557         phead = get_list_head(queue);
2558         plist = get_next(phead);
2559        
2560         while(1)
2561         {
2562                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
2563                         break;
2564
2565                 if((stop - ev) < SCAN_ITEM_SIZE) {
2566                         ret = -E2BIG;
2567                         break;
2568                 }
2569
2570                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2571
2572                 //report network only if the current channel set contains the channel to which this network belongs
2573                 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
2574                         && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE
2575                         && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
2576                 )
2577                 {
2578                         ev=translate_scan(padapter, a, pnetwork, ev, stop);
2579                 }
2580
2581                 plist = get_next(plist);
2582         
2583         }        
2584
2585         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2586
2587        wrqu->data.length = ev-extra;
2588         wrqu->data.flags = 0;
2589         
2590 exit:           
2591         
2592         _func_exit_;    
2593         
2594         #ifdef DBG_IOCTL
2595         DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret);
2596         #endif
2597         
2598         return ret ;
2599         
2600 }
2601
2602 //set ssid flow
2603 //s1. rtw_set_802_11_infrastructure_mode()
2604 //s2. set_802_11_authenticaion_mode()
2605 //s3. set_802_11_encryption_mode()
2606 //s4. rtw_set_802_11_ssid()
2607 static int rtw_wx_set_essid(struct net_device *dev, 
2608                               struct iw_request_info *a,
2609                               union iwreq_data *wrqu, char *extra)
2610 {
2611         _irqL irqL;
2612         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2613         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2614         _queue *queue = &pmlmepriv->scanned_queue;
2615         _list *phead;
2616         s8 status = _TRUE;
2617         struct wlan_network *pnetwork = NULL;
2618         NDIS_802_11_AUTHENTICATION_MODE authmode;       
2619         NDIS_802_11_SSID ndis_ssid;     
2620         u8 *dst_ssid, *src_ssid;
2621
2622         uint ret = 0, len;
2623
2624         _func_enter_;
2625         
2626         #ifdef DBG_IOCTL
2627         DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__);
2628         #endif
2629         #ifdef CONFIG_WEXT_DONT_JOIN_BYSSID
2630         DBG_871X("%s: CONFIG_WEXT_DONT_JOIN_BYSSID be defined!! only allow bssid joining\n", __func__);
2631         return -EPERM;
2632         #endif
2633 /*
2634 #ifdef CONFIG_CONCURRENT_MODE
2635         if(padapter->iface_type > PRIMARY_IFACE)
2636         {
2637                 ret = -EINVAL;
2638                 goto exit;
2639         }
2640 #endif
2641 */
2642
2643 #ifdef CONFIG_CONCURRENT_MODE
2644         if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2645         {               
2646                 DBG_871X("set ssid, but buddy_intf is under scanning or linking\n");
2647                 
2648                 ret = -EINVAL;
2649                 
2650                 goto exit;
2651         }
2652 #endif
2653
2654 #ifdef CONFIG_DUALMAC_CONCURRENT
2655         if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE)
2656         {
2657                 DBG_871X("set bssid, but buddy_intf is under scanning or linking\n");
2658                 ret = -EINVAL;
2659                 goto exit;
2660         }
2661 #endif
2662
2663         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2664                  ("+rtw_wx_set_essid: fw_state=0x%08x\n", get_fwstate(pmlmepriv)));
2665
2666         rtw_ps_deny(padapter, PS_DENY_JOIN);
2667         if(_FAIL == rtw_pwr_wakeup(padapter))
2668         {               
2669                 ret = -1;
2670                 goto exit;
2671         }
2672
2673         if(!padapter->bup){
2674                 ret = -1;
2675                 goto exit;
2676         }
2677
2678 #if WIRELESS_EXT <= 20
2679         if ((wrqu->essid.length-1) > IW_ESSID_MAX_SIZE){
2680 #else
2681         if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
2682 #endif
2683                 ret= -E2BIG;
2684                 goto exit;
2685         }
2686         
2687         if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2688                 ret = -1;
2689                 goto exit;
2690         }               
2691         
2692         authmode = padapter->securitypriv.ndisauthtype;
2693         DBG_871X("=>%s\n",__FUNCTION__);
2694         if (wrqu->essid.flags && wrqu->essid.length)
2695         {
2696                 // Commented by Albert 20100519
2697                 // We got the codes in "set_info" function of iwconfig source code.
2698                 //      =========================================
2699                 //      wrq.u.essid.length = strlen(essid) + 1;
2700                 //      if(we_kernel_version > 20)
2701                 //              wrq.u.essid.length--;
2702                 //      =========================================
2703                 //      That means, if the WIRELESS_EXT less than or equal to 20, the correct ssid len should subtract 1.
2704 #if WIRELESS_EXT <= 20
2705                 len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
2706 #else
2707                 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
2708 #endif
2709
2710                 if( wrqu->essid.length != 33 )
2711                         DBG_871X("ssid=%s, len=%d\n", extra, wrqu->essid.length);
2712
2713                 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
2714                 ndis_ssid.SsidLength = len;
2715                 _rtw_memcpy(ndis_ssid.Ssid, extra, len);                
2716                 src_ssid = ndis_ssid.Ssid;
2717                 
2718                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid=[%s]\n", src_ssid));
2719                 _enter_critical_bh(&queue->lock, &irqL);
2720                phead = get_list_head(queue);
2721               pmlmepriv->pscanned = get_next(phead);
2722
2723                 while (1)
2724                 {                       
2725                         if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == _TRUE)
2726                         {
2727 #if 0                   
2728                                 if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
2729                                 {
2730                                         rtw_set_802_11_ssid(padapter, &ndis_ssid);
2731
2732                                         goto exit;                    
2733                                 }
2734                                 else
2735                                 {
2736                                         RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("rtw_wx_set_ssid(): scanned_queue is empty\n"));
2737                                         ret = -EINVAL;
2738                                         goto exit;
2739                                 }
2740 #endif                  
2741                                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_warning_,
2742                                          ("rtw_wx_set_essid: scan_q is empty, set ssid to check if scanning again!\n"));
2743
2744                                 break;
2745                         }
2746         
2747                         pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
2748
2749                         pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
2750
2751                         dst_ssid = pnetwork->network.Ssid.Ssid;
2752
2753                         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2754                                  ("rtw_wx_set_essid: dst_ssid=%s\n",
2755                                   pnetwork->network.Ssid.Ssid));
2756
2757                         if ((_rtw_memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength) == _TRUE) &&
2758                                 (pnetwork->network.Ssid.SsidLength==ndis_ssid.SsidLength))
2759                         {
2760                                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2761                                          ("rtw_wx_set_essid: find match, set infra mode\n"));
2762                                 
2763                                 if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
2764                                 {
2765                                         if(pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
2766                                                 continue;
2767                                 }       
2768                                         
2769                                 if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == _FALSE)
2770                                 {
2771                                         ret = -1;
2772                                         _exit_critical_bh(&queue->lock, &irqL);
2773                                         goto exit;
2774                                 }
2775
2776                                 break;                  
2777                         }
2778                 }
2779                 _exit_critical_bh(&queue->lock, &irqL);
2780                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2781                          ("set ssid: set_802_11_auth. mode=%d\n", authmode));
2782                 rtw_set_802_11_authentication_mode(padapter, authmode);
2783                 //set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
2784                 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {
2785                         ret = -1;
2786                         goto exit;
2787                 }       
2788         }                       
2789         
2790 exit:
2791
2792         rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
2793
2794         DBG_871X("<=%s, ret %d\n",__FUNCTION__, ret);
2795         
2796         #ifdef DBG_IOCTL
2797         DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret);
2798         #endif
2799         
2800         _func_exit_;
2801         
2802         return ret;     
2803 }
2804
2805 static int rtw_wx_get_essid(struct net_device *dev, 
2806                               struct iw_request_info *a,
2807                               union iwreq_data *wrqu, char *extra)
2808 {
2809         u32 len,ret = 0;
2810         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2811         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
2812         WLAN_BSSID_EX  *pcur_bss = &pmlmepriv->cur_network.network;
2813
2814         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_essid\n"));
2815
2816         _func_enter_;
2817
2818         if ( (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ||
2819               (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE))
2820         {
2821                 len = pcur_bss->Ssid.SsidLength;
2822
2823                 wrqu->essid.length = len;
2824                         
2825                 _rtw_memcpy(extra, pcur_bss->Ssid.Ssid, len);
2826
2827                 wrqu->essid.flags = 1;
2828         }
2829         else
2830         {
2831                 ret = -1;
2832                 goto exit;
2833         }
2834
2835 exit:
2836
2837         _func_exit_;
2838         
2839         return ret;
2840         
2841 }
2842
2843 static int rtw_wx_set_rate(struct net_device *dev, 
2844                               struct iw_request_info *a,
2845                               union iwreq_data *wrqu, char *extra)
2846 {
2847         int     i, ret = 0;
2848         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2849         u8      datarates[NumRates];
2850         u32     target_rate = wrqu->bitrate.value;
2851         u32     fixed = wrqu->bitrate.fixed;
2852         u32     ratevalue = 0;
2853          u8 mpdatarate[NumRates]={11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
2854
2855 _func_enter_;
2856
2857         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,(" rtw_wx_set_rate \n"));
2858         RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("target_rate = %d, fixed = %d\n",target_rate,fixed));
2859         
2860         if(target_rate == -1){
2861                 ratevalue = 11;
2862                 goto set_rate;
2863         }
2864         target_rate = target_rate/100000;
2865
2866         switch(target_rate){
2867                 case 10:
2868                         ratevalue = 0;
2869                         break;
2870                 case 20:
2871                         ratevalue = 1;
2872                         break;
2873                 case 55:
2874                         ratevalue = 2;
2875                         break;
2876                 case 60:
2877                         ratevalue = 3;
2878                         break;
2879                 case 90:
2880                         ratevalue = 4;
2881                         break;
2882                 case 110:
2883                         ratevalue = 5;
2884                         break;
2885                 case 120:
2886                         ratevalue = 6;
2887                         break;
2888                 case 180:
2889                         ratevalue = 7;
2890                         break;
2891                 case 240:
2892                         ratevalue = 8;
2893                         break;
2894                 case 360:
2895                         ratevalue = 9;
2896                         break;
2897                 case 480:
2898                         ratevalue = 10;
2899                         break;
2900                 case 540:
2901                         ratevalue = 11;
2902                         break;
2903                 default:
2904                         ratevalue = 11;
2905                         break;
2906         }
2907
2908 set_rate:
2909
2910         for(i=0; i<NumRates; i++)
2911         {
2912                 if(ratevalue==mpdatarate[i])
2913                 {
2914                         datarates[i] = mpdatarate[i];
2915                         if(fixed == 0)
2916                                 break;
2917                 }
2918                 else{
2919                         datarates[i] = 0xff;
2920                 }
2921
2922                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("datarate_inx=%d\n",datarates[i]));
2923         }
2924
2925         if( rtw_setdatarate_cmd(padapter, datarates) !=_SUCCESS){
2926                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("rtw_wx_set_rate Fail!!!\n"));
2927                 ret = -1;
2928         }
2929
2930 _func_exit_;
2931
2932         return ret;
2933 }
2934
2935 static int rtw_wx_get_rate(struct net_device *dev, 
2936                              struct iw_request_info *info, 
2937                              union iwreq_data *wrqu, char *extra)
2938 {       
2939         u16 max_rate = 0;
2940
2941         max_rate = rtw_get_cur_max_rate((_adapter *)rtw_netdev_priv(dev));
2942
2943         if(max_rate == 0)
2944                 return -EPERM;
2945         
2946         wrqu->bitrate.fixed = 0;        /* no auto select */
2947         wrqu->bitrate.value = max_rate * 100000;
2948
2949         return 0;
2950 }
2951
2952 static int rtw_wx_set_rts(struct net_device *dev, 
2953                              struct iw_request_info *info, 
2954                              union iwreq_data *wrqu, char *extra)
2955 {
2956         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2957
2958         _func_enter_;
2959         
2960         if (wrqu->rts.disabled)
2961                 padapter->registrypriv.rts_thresh = 2347;
2962         else {
2963                 if (wrqu->rts.value < 0 ||
2964                     wrqu->rts.value > 2347)
2965                         return -EINVAL;
2966                 
2967                 padapter->registrypriv.rts_thresh = wrqu->rts.value;
2968         }
2969
2970         DBG_871X("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
2971         
2972         _func_exit_;
2973         
2974         return 0;
2975
2976 }
2977
2978 static int rtw_wx_get_rts(struct net_device *dev, 
2979                              struct iw_request_info *info, 
2980                              union iwreq_data *wrqu, char *extra)
2981 {
2982         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2983         
2984         _func_enter_;
2985
2986         DBG_871X("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);   
2987         
2988         wrqu->rts.value = padapter->registrypriv.rts_thresh;
2989         wrqu->rts.fixed = 0;    /* no auto select */
2990         //wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
2991         
2992         _func_exit_;
2993         
2994         return 0;
2995 }
2996
2997 static int rtw_wx_set_frag(struct net_device *dev, 
2998                              struct iw_request_info *info, 
2999                              union iwreq_data *wrqu, char *extra)
3000 {
3001         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3002
3003         _func_enter_;
3004         
3005         if (wrqu->frag.disabled)
3006                 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
3007         else {
3008                 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
3009                     wrqu->frag.value > MAX_FRAG_THRESHOLD)
3010                         return -EINVAL;
3011                 
3012                 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
3013         }
3014
3015         DBG_871X("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
3016         
3017         _func_exit_;
3018         
3019         return 0;
3020         
3021 }
3022
3023 static int rtw_wx_get_frag(struct net_device *dev, 
3024                              struct iw_request_info *info, 
3025                              union iwreq_data *wrqu, char *extra)
3026 {
3027         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3028         
3029         _func_enter_;
3030
3031         DBG_871X("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
3032         
3033         wrqu->frag.value = padapter->xmitpriv.frag_len;
3034         wrqu->frag.fixed = 0;   /* no auto select */
3035         //wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
3036         
3037         _func_exit_;
3038         
3039         return 0;
3040 }
3041
3042 static int rtw_wx_get_retry(struct net_device *dev, 
3043                              struct iw_request_info *info, 
3044                              union iwreq_data *wrqu, char *extra)
3045 {
3046         //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3047
3048         
3049         wrqu->retry.value = 7;
3050         wrqu->retry.fixed = 0;  /* no auto select */
3051         wrqu->retry.disabled = 1;
3052         
3053         return 0;
3054
3055 }       
3056
3057 #if 0
3058 #define IW_ENCODE_INDEX         0x00FF  /* Token index (if needed) */
3059 #define IW_ENCODE_FLAGS         0xFF00  /* Flags defined below */
3060 #define IW_ENCODE_MODE          0xF000  /* Modes defined below */
3061 #define IW_ENCODE_DISABLED      0x8000  /* Encoding disabled */
3062 #define IW_ENCODE_ENABLED       0x0000  /* Encoding enabled */
3063 #define IW_ENCODE_RESTRICTED    0x4000  /* Refuse non-encoded packets */
3064 #define IW_ENCODE_OPEN          0x2000  /* Accept non-encoded packets */
3065 #define IW_ENCODE_NOKEY         0x0800  /* Key is write only, so not present */
3066 #define IW_ENCODE_TEMP          0x0400  /* Temporary key */
3067 /*
3068 iwconfig wlan0 key on -> flags = 0x6001 -> maybe it means auto
3069 iwconfig wlan0 key off -> flags = 0x8800
3070 iwconfig wlan0 key open -> flags = 0x2800
3071 iwconfig wlan0 key open 1234567890 -> flags = 0x2000
3072 iwconfig wlan0 key restricted -> flags = 0x4800
3073 iwconfig wlan0 key open [3] 1234567890 -> flags = 0x2003
3074 iwconfig wlan0 key restricted [2] 1234567890 -> flags = 0x4002
3075 iwconfig wlan0 key open [3] -> flags = 0x2803
3076 iwconfig wlan0 key restricted [2] -> flags = 0x4802
3077 */
3078 #endif
3079
3080 static int rtw_wx_set_enc(struct net_device *dev, 
3081                             struct iw_request_info *info, 
3082                             union iwreq_data *wrqu, char *keybuf)
3083 {       
3084         u32 key, ret = 0;
3085         u32 keyindex_provided;
3086         NDIS_802_11_WEP  wep;   
3087         NDIS_802_11_AUTHENTICATION_MODE authmode;
3088
3089         struct iw_point *erq = &(wrqu->encoding);
3090         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3091         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
3092         DBG_871X("+rtw_wx_set_enc, flags=0x%x\n", erq->flags);
3093
3094         _rtw_memset(&wep, 0, sizeof(NDIS_802_11_WEP));
3095         
3096         key = erq->flags & IW_ENCODE_INDEX;
3097         
3098         _func_enter_;   
3099
3100         if (erq->flags & IW_ENCODE_DISABLED)
3101         {
3102                 DBG_871X("EncryptionDisabled\n");
3103                 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
3104                 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3105                 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
3106                 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
3107                 authmode = Ndis802_11AuthModeOpen;
3108                 padapter->securitypriv.ndisauthtype=authmode;
3109                 
3110                 goto exit;
3111         }
3112
3113         if (key) {
3114                 if (key > WEP_KEYS)
3115                         return -EINVAL;
3116                 key--;
3117                 keyindex_provided = 1;
3118         } 
3119         else
3120         {
3121                 keyindex_provided = 0;
3122                 key = padapter->securitypriv.dot11PrivacyKeyIndex;
3123                 DBG_871X("rtw_wx_set_enc, key=%d\n", key);
3124         }
3125         
3126         //set authentication mode       
3127         if(erq->flags & IW_ENCODE_OPEN)
3128         {
3129                 DBG_871X("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
3130                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;//Ndis802_11EncryptionDisabled;
3131
3132 #ifdef CONFIG_PLATFORM_MT53XX
3133                 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
3134 #else
3135                 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open;
3136 #endif
3137
3138                 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3139                 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
3140                 authmode = Ndis802_11AuthModeOpen;
3141                 padapter->securitypriv.ndisauthtype=authmode;
3142         }       
3143         else if(erq->flags & IW_ENCODE_RESTRICTED)
3144         {               
3145                 DBG_871X("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
3146                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
3147
3148 #ifdef CONFIG_PLATFORM_MT53XX
3149                 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
3150 #else
3151                 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Shared;
3152 #endif
3153
3154                 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
3155                 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;                    
3156                 authmode = Ndis802_11AuthModeShared;
3157                 padapter->securitypriv.ndisauthtype=authmode;
3158         }
3159         else
3160         {
3161                 DBG_871X("rtw_wx_set_enc():erq->flags=0x%x\n", erq->flags);
3162
3163                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;//Ndis802_11EncryptionDisabled;
3164                 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
3165                 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3166                 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
3167                 authmode = Ndis802_11AuthModeOpen;
3168                 padapter->securitypriv.ndisauthtype=authmode;
3169         }
3170         
3171         wep.KeyIndex = key;
3172         if (erq->length > 0)
3173         {
3174                 wep.KeyLength = erq->length <= 5 ? 5 : 13;
3175
3176                 wep.Length = wep.KeyLength + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
3177         }
3178         else
3179         {
3180                 wep.KeyLength = 0 ;
3181                 
3182                 if(keyindex_provided == 1)// set key_id only, no given KeyMaterial(erq->length==0).
3183                 {
3184                         padapter->securitypriv.dot11PrivacyKeyIndex = key;
3185
3186                         DBG_871X("(keyindex_provided == 1), keyid=%d, key_len=%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
3187
3188                         switch(padapter->securitypriv.dot11DefKeylen[key])
3189                         {
3190                                 case 5:
3191                                         padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;                                     
3192                                         break;
3193                                 case 13:
3194                                         padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;                                    
3195                                         break;
3196                                 default:
3197                                         padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;                                        
3198                                         break;
3199                         }
3200                                 
3201                         goto exit;
3202                         
3203                 }
3204                 
3205         }
3206
3207         wep.KeyIndex |= 0x80000000;
3208
3209         _rtw_memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
3210         
3211         if (rtw_set_802_11_add_wep(padapter, &wep) == _FALSE) {
3212                 if(rf_on == pwrpriv->rf_pwrstate )
3213                         ret = -EOPNOTSUPP;
3214                 goto exit;
3215         }       
3216
3217 exit:
3218         
3219         _func_exit_;
3220         
3221         return ret;
3222         
3223 }
3224
3225 static int rtw_wx_get_enc(struct net_device *dev, 
3226                             struct iw_request_info *info, 
3227                             union iwreq_data *wrqu, char *keybuf)
3228 {
3229         uint key, ret =0;
3230         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3231         struct iw_point *erq = &(wrqu->encoding);
3232         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
3233
3234         _func_enter_;
3235         
3236         if(check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE)
3237         {
3238                  if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE)
3239                  {
3240                 erq->length = 0;
3241                 erq->flags |= IW_ENCODE_DISABLED;
3242                 return 0;
3243         }       
3244         }       
3245
3246         
3247         key = erq->flags & IW_ENCODE_INDEX;
3248
3249         if (key) {
3250                 if (key > WEP_KEYS)
3251                         return -EINVAL;
3252                 key--;
3253         } else
3254         {
3255                 key = padapter->securitypriv.dot11PrivacyKeyIndex;
3256         }       
3257
3258         erq->flags = key + 1;
3259
3260         //if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
3261         //{
3262         //      erq->flags |= IW_ENCODE_OPEN;
3263         //}       
3264         
3265         switch(padapter->securitypriv.ndisencryptstatus)
3266         {
3267                 case Ndis802_11EncryptionNotSupported:
3268                 case Ndis802_11EncryptionDisabled:
3269
3270                 erq->length = 0;
3271                 erq->flags |= IW_ENCODE_DISABLED;
3272         
3273                 break;
3274                 
3275                 case Ndis802_11Encryption1Enabled:                                      
3276                 
3277                 erq->length = padapter->securitypriv.dot11DefKeylen[key];               
3278
3279                 if(erq->length)
3280                 {
3281                         _rtw_memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
3282                 
3283                 erq->flags |= IW_ENCODE_ENABLED;
3284
3285                         if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
3286                         {
3287                                 erq->flags |= IW_ENCODE_OPEN;
3288                         }
3289                         else if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
3290                         {
3291                 erq->flags |= IW_ENCODE_RESTRICTED;
3292                         }       
3293                 }       
3294                 else
3295                 {
3296                         erq->length = 0;
3297                         erq->flags |= IW_ENCODE_DISABLED;
3298                 }
3299
3300                 break;
3301
3302                 case Ndis802_11Encryption2Enabled:
3303                 case Ndis802_11Encryption3Enabled:
3304
3305                 erq->length = 16;
3306                 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
3307
3308                 break;
3309         
3310                 default:
3311                 erq->length = 0;
3312                 erq->flags |= IW_ENCODE_DISABLED;
3313
3314                 break;
3315                 
3316         }
3317         
3318         _func_exit_;
3319         
3320         return ret;
3321         
3322 }                                    
3323
3324 static int rtw_wx_get_power(struct net_device *dev, 
3325                              struct iw_request_info *info, 
3326                              union iwreq_data *wrqu, char *extra)
3327 {
3328         //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3329         
3330         wrqu->power.value = 0;
3331         wrqu->power.fixed = 0;  /* no auto select */
3332         wrqu->power.disabled = 1;
3333         
3334         return 0;
3335
3336 }
3337
3338 static int rtw_wx_set_gen_ie(struct net_device *dev, 
3339                              struct iw_request_info *info, 
3340                              union iwreq_data *wrqu, char *extra)
3341 {
3342         int ret;
3343         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3344         
3345        ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
3346            
3347         return ret;
3348 }       
3349
3350 static int rtw_wx_set_auth(struct net_device *dev, 
3351                              struct iw_request_info *info, 
3352                              union iwreq_data *wrqu, char *extra)
3353 {
3354         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3355         struct iw_param *param = (struct iw_param*)&(wrqu->param);
3356         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
3357         struct security_priv *psecuritypriv = &padapter->securitypriv;
3358         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3359         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3360         u32 value = param->value;
3361         int ret = 0;
3362         
3363         switch (param->flags & IW_AUTH_INDEX) {
3364
3365         case IW_AUTH_WPA_VERSION:
3366 #ifdef CONFIG_WAPI_SUPPORT
3367 #ifndef CONFIG_IOCTL_CFG80211
3368                  padapter->wapiInfo.bWapiEnable = false;
3369                  if(value == IW_AUTH_WAPI_VERSION_1)
3370                  {
3371                         padapter->wapiInfo.bWapiEnable = true;
3372                         psecuritypriv->dot11PrivacyAlgrthm = _SMS4_;
3373                         psecuritypriv->dot118021XGrpPrivacy = _SMS4_;
3374                         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
3375                         pmlmeinfo->auth_algo = psecuritypriv->dot11AuthAlgrthm;
3376                         padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
3377                         padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
3378                 }
3379 #endif
3380 #endif
3381                 break;
3382         case IW_AUTH_CIPHER_PAIRWISE:
3383                 
3384                 break;
3385         case IW_AUTH_CIPHER_GROUP:
3386                 
3387                 break;
3388         case IW_AUTH_KEY_MGMT:
3389 #ifdef CONFIG_WAPI_SUPPORT
3390 #ifndef CONFIG_IOCTL_CFG80211
3391                 DBG_871X("rtw_wx_set_auth: IW_AUTH_KEY_MGMT case \n");
3392                 if(value == IW_AUTH_KEY_MGMT_WAPI_PSK)
3393                         padapter->wapiInfo.bWapiPSK = true;
3394                 else
3395                         padapter->wapiInfo.bWapiPSK = false;
3396                 DBG_871X("rtw_wx_set_auth: IW_AUTH_KEY_MGMT bwapipsk %d \n",padapter->wapiInfo.bWapiPSK);
3397 #endif
3398 #endif
3399                 /*
3400                  *  ??? does not use these parameters
3401                  */
3402                 break;
3403
3404         case IW_AUTH_TKIP_COUNTERMEASURES:
3405         {
3406             if ( param->value )
3407             {  // wpa_supplicant is enabling the tkip countermeasure.
3408                padapter->securitypriv.btkip_countermeasure = _TRUE; 
3409             }
3410             else
3411             {  // wpa_supplicant is disabling the tkip countermeasure.
3412                padapter->securitypriv.btkip_countermeasure = _FALSE; 
3413             }
3414                 break;
3415         }
3416         case IW_AUTH_DROP_UNENCRYPTED:
3417                 {
3418                         /* HACK:
3419                          *
3420                          * wpa_supplicant calls set_wpa_enabled when the driver
3421                          * is loaded and unloaded, regardless of if WPA is being
3422                          * used.  No other calls are made which can be used to
3423                          * determine if encryption will be used or not prior to
3424                          * association being expected.  If encryption is not being
3425                          * used, drop_unencrypted is set to false, else true -- we
3426                          * can use this to determine if the CAP_PRIVACY_ON bit should
3427                          * be set.
3428                          */
3429
3430                         if(padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
3431                         {
3432                                 break;//it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, 
3433                                                 // then it needn't reset it;
3434                         }
3435                         
3436                         if(param->value){
3437                                 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
3438                                 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3439                                 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
3440                                 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
3441                                 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeOpen;
3442                         }
3443                         
3444                         break;
3445                 }
3446
3447         case IW_AUTH_80211_AUTH_ALG:
3448
3449                 #if defined(CONFIG_ANDROID) || 1
3450                 /*
3451                  *  It's the starting point of a link layer connection using wpa_supplicant
3452                 */
3453                 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
3454                         LeaveAllPowerSaveMode(padapter);
3455                         rtw_disassoc_cmd(padapter, 500, _FALSE);
3456                         DBG_871X("%s...call rtw_indicate_disconnect\n ",__FUNCTION__);
3457                         rtw_indicate_disconnect(padapter);
3458                         rtw_free_assoc_resources(padapter, 1);
3459                 }
3460                 #endif
3461
3462
3463                 ret = wpa_set_auth_algs(dev, (u32)param->value);                
3464         
3465                 break;
3466
3467         case IW_AUTH_WPA_ENABLED:
3468
3469                 //if(param->value)
3470                 //      padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; //802.1x
3471                 //else
3472                 //      padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;//open system
3473                 
3474                 //_disassociate(priv);
3475                 
3476                 break;
3477
3478         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3479                 //ieee->ieee802_1x = param->value;
3480                 break;
3481
3482         case IW_AUTH_PRIVACY_INVOKED:
3483                 //ieee->privacy_invoked = param->value;
3484                 break;
3485
3486 #ifdef CONFIG_WAPI_SUPPORT
3487 #ifndef CONFIG_IOCTL_CFG80211
3488         case IW_AUTH_WAPI_ENABLED:
3489                 break;
3490 #endif
3491 #endif
3492
3493         default:
3494                 return -EOPNOTSUPP;
3495                 
3496         }
3497         
3498         return ret;
3499         
3500 }
3501
3502 static int rtw_wx_set_enc_ext(struct net_device *dev, 
3503                              struct iw_request_info *info, 
3504                              union iwreq_data *wrqu, char *extra)
3505 {
3506         char *alg_name;
3507         u32 param_len;
3508         struct ieee_param *param = NULL;
3509         struct iw_point *pencoding = &wrqu->encoding;
3510         struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
3511         int ret=0;
3512
3513         param_len = sizeof(struct ieee_param) + pext->key_len;
3514         param = (struct ieee_param *)rtw_malloc(param_len);
3515         if (param == NULL)
3516                 return -1;
3517         
3518         _rtw_memset(param, 0, param_len);
3519
3520         param->cmd = IEEE_CMD_SET_ENCRYPTION;
3521         _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
3522
3523
3524         switch (pext->alg) {
3525         case IW_ENCODE_ALG_NONE:
3526                 //todo: remove key 
3527                 //remove = 1;   
3528                 alg_name = "none";
3529                 break;
3530         case IW_ENCODE_ALG_WEP:
3531                 alg_name = "WEP";
3532                 break;
3533         case IW_ENCODE_ALG_TKIP:
3534                 alg_name = "TKIP";
3535                 break;
3536         case IW_ENCODE_ALG_CCMP:
3537                 alg_name = "CCMP";
3538                 break;
3539 #ifdef CONFIG_IEEE80211W
3540         case IW_ENCODE_ALG_AES_CMAC:
3541                 alg_name = "BIP";
3542                 break;
3543 #endif //CONFIG_IEEE80211W
3544 #ifdef CONFIG_WAPI_SUPPORT
3545 #ifndef CONFIG_IOCTL_CFG80211
3546         case IW_ENCODE_ALG_SM4:
3547                 alg_name= "SMS4";
3548                 _rtw_memcpy(param->sta_addr, pext->addr.sa_data, ETH_ALEN);
3549                 DBG_871X("rtw_wx_set_enc_ext: SMS4 case \n");
3550                 break;
3551 #endif
3552 #endif
3553         default:
3554                 ret = -1;
3555                 goto exit;
3556         }
3557
3558         strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
3559
3560         if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
3561         {
3562                 param->u.crypt.set_tx = 1;
3563         }
3564
3565         /* cliW: WEP does not have group key
3566          * just not checking GROUP key setting 
3567          */
3568         if ((pext->alg != IW_ENCODE_ALG_WEP) &&
3569                 ((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
3570 #ifdef CONFIG_IEEE80211W
3571                 || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC)
3572 #endif //CONFIG_IEEE80211W
3573         ))
3574         {
3575                 param->u.crypt.set_tx = 0;
3576         }
3577
3578         param->u.crypt.idx = (pencoding->flags&0x00FF) -1 ;
3579
3580         if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
3581         {
3582 #ifdef CONFIG_WAPI_SUPPORT
3583 #ifndef CONFIG_IOCTL_CFG80211
3584                 if(pext->alg == IW_ENCODE_ALG_SM4)
3585                         _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 16);
3586                 else
3587 #endif //CONFIG_IOCTL_CFG80211
3588 #endif //CONFIG_WAPI_SUPPORT
3589                 _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 8);
3590         }
3591
3592         if(pext->key_len)
3593         {
3594                 param->u.crypt.key_len = pext->key_len;
3595                 //_rtw_memcpy(param + 1, pext + 1, pext->key_len);
3596                 _rtw_memcpy(param->u.crypt.key, pext + 1, pext->key_len);
3597         }
3598
3599         if (pencoding->flags & IW_ENCODE_DISABLED)
3600         {
3601                 //todo: remove key 
3602                 //remove = 1;
3603         }
3604
3605         ret =  wpa_set_encryption(dev, param, param_len);
3606
3607 exit:
3608         if(param)
3609         {
3610                 rtw_mfree((u8*)param, param_len);
3611         }
3612
3613         return ret;
3614 }
3615
3616
3617 static int rtw_wx_get_nick(struct net_device *dev, 
3618                              struct iw_request_info *info, 
3619                              union iwreq_data *wrqu, char *extra)
3620 {       
3621         //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3622          //struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3623          //struct security_priv *psecuritypriv = &padapter->securitypriv;
3624
3625         if(extra)
3626         {
3627                 wrqu->data.length = 14;
3628                 wrqu->data.flags = 1;
3629                 _rtw_memcpy(extra, "<WIFI@REALTEK>", 14);
3630         }
3631
3632         //rtw_signal_process(pid, SIGUSR1); //for test
3633
3634         //dump debug info here  
3635 /*
3636         u32 dot11AuthAlgrthm;           // 802.11 auth, could be open, shared, and 8021x
3637         u32 dot11PrivacyAlgrthm;        // This specify the privacy for shared auth. algorithm.
3638         u32 dot118021XGrpPrivacy;       // This specify the privacy algthm. used for Grp key 
3639         u32 ndisauthtype;
3640         u32 ndisencryptstatus;
3641 */
3642
3643         //DBG_871X("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", 
3644         //              psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
3645         //              psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
3646         
3647         //DBG_871X("enc_alg=0x%x\n", psecuritypriv->dot11PrivacyAlgrthm);
3648         //DBG_871X("auth_type=0x%x\n", psecuritypriv->ndisauthtype);
3649         //DBG_871X("enc_type=0x%x\n", psecuritypriv->ndisencryptstatus);
3650
3651 #if 0
3652         DBG_871X("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
3653         DBG_871X("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
3654         DBG_871X("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
3655         DBG_871X("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
3656         DBG_871X("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
3657         
3658         DBG_871X("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
3659
3660
3661         DBG_871X("\n");
3662
3663         DBG_871X("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
3664         DBG_871X("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
3665
3666         DBG_871X("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
3667         
3668         DBG_871X("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
3669         
3670         DBG_871X("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
3671         DBG_871X("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
3672         
3673         DBG_871X("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
3674         DBG_871X("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
3675         DBG_871X("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
3676         DBG_871X("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
3677 #endif
3678         
3679         return 0;
3680
3681 }
3682
3683 static int rtw_wx_read32(struct net_device *dev,
3684                             struct iw_request_info *info,
3685                             union iwreq_data *wrqu, char *extra)
3686 {
3687         PADAPTER padapter;
3688         struct iw_point *p;
3689         u16 len;
3690         u32 addr;
3691         u32 data32;
3692         u32 bytes;
3693         u8 *ptmp;
3694         int ret;
3695
3696
3697         ret = 0;
3698         padapter = (PADAPTER)rtw_netdev_priv(dev);
3699         p = &wrqu->data;
3700         len = p->length;
3701         if (0 == len)
3702                 return -EINVAL;
3703
3704         ptmp = (u8*)rtw_malloc(len);
3705         if (NULL == ptmp)
3706                 return -ENOMEM;
3707
3708         if (copy_from_user(ptmp, p->pointer, len)) {
3709                 ret = -EFAULT;
3710                 goto exit;
3711         }
3712
3713         bytes = 0;
3714         addr = 0;
3715         sscanf(ptmp, "%d,%x", &bytes, &addr);
3716
3717         switch (bytes) {
3718                 case 1:
3719                         data32 = rtw_read8(padapter, addr);
3720                         sprintf(extra, "0x%02X", data32);
3721                         break;
3722                 case 2:
3723                         data32 = rtw_read16(padapter, addr);
3724                         sprintf(extra, "0x%04X", data32);
3725                         break;
3726                 case 4:
3727                         data32 = rtw_read32(padapter, addr);
3728                         sprintf(extra, "0x%08X", data32);
3729                         break;
3730                 default:
3731                         DBG_871X(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__);
3732                         ret = -EINVAL;
3733                         goto exit;
3734         }
3735         DBG_871X(KERN_INFO "%s: addr=0x%08X data=%s\n", __func__, addr, extra);
3736
3737 exit:
3738         rtw_mfree(ptmp, len);
3739
3740         return 0;
3741 }
3742
3743 static int rtw_wx_write32(struct net_device *dev,
3744                             struct iw_request_info *info,
3745                             union iwreq_data *wrqu, char *extra)
3746 {
3747         PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
3748
3749         u32 addr;
3750         u32 data32;
3751         u32 bytes;
3752
3753
3754         bytes = 0;
3755         addr = 0;
3756         data32 = 0;
3757         sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
3758
3759         switch (bytes) {
3760                 case 1:
3761                         rtw_write8(padapter, addr, (u8)data32);
3762                         DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%02X\n", __func__, addr, (u8)data32);
3763                         break;
3764                 case 2:
3765                         rtw_write16(padapter, addr, (u16)data32);
3766                         DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%04X\n", __func__, addr, (u16)data32);
3767                         break;
3768                 case 4:
3769                         rtw_write32(padapter, addr, data32);
3770                         DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%08X\n", __func__, addr, data32);
3771                         break;
3772                 default:
3773                         DBG_871X(KERN_INFO "%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);
3774                         return -EINVAL;
3775         }
3776
3777         return 0;
3778 }
3779
3780 static int rtw_wx_read_rf(struct net_device *dev,
3781                             struct iw_request_info *info,
3782                             union iwreq_data *wrqu, char *extra)
3783 {
3784         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3785         u32 path, addr, data32;
3786
3787
3788         path = *(u32*)extra;
3789         addr = *((u32*)extra + 1);
3790         data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);
3791 //      DBG_871X("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32);
3792         /*
3793          * IMPORTANT!!
3794          * Only when wireless private ioctl is at odd order,
3795          * "extra" would be copied to user space.
3796          */
3797         sprintf(extra, "0x%05x", data32);
3798
3799         return 0;
3800 }
3801
3802 static int rtw_wx_write_rf(struct net_device *dev,
3803                             struct iw_request_info *info,
3804                             union iwreq_data *wrqu, char *extra)
3805 {
3806         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3807         u32 path, addr, data32;
3808
3809
3810         path = *(u32*)extra;
3811         addr = *((u32*)extra + 1);
3812         data32 = *((u32*)extra + 2);
3813 //      DBG_871X("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32);
3814         rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);
3815
3816         return 0;
3817 }
3818
3819 static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
3820                  union iwreq_data *wrqu, char *b)
3821 {
3822         return -1;
3823 }
3824
3825 static int dummy(struct net_device *dev, struct iw_request_info *a,
3826                  union iwreq_data *wrqu, char *b)
3827 {
3828         //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);        
3829         //struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3830
3831         //DBG_871X("cmd_code=%x, fwstate=0x%x\n", a->cmd, get_fwstate(pmlmepriv));
3832         
3833         return -1;
3834         
3835 }
3836
3837 static int rtw_wx_set_channel_plan(struct net_device *dev,
3838                                struct iw_request_info *info,
3839                                union iwreq_data *wrqu, char *extra)
3840 {
3841         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3842         struct registry_priv *pregistrypriv = &padapter->registrypriv;
3843         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3844         extern int rtw_channel_plan;
3845         u8 channel_plan_req = (u8) (*((int *)wrqu));
3846
3847         #if 0
3848         rtw_channel_plan = (int)wrqu->data.pointer;
3849         pregistrypriv->channel_plan = rtw_channel_plan;
3850         pmlmepriv->ChannelPlan = pregistrypriv->channel_plan;
3851         #endif
3852
3853         if (_SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1, 1)) {
3854                 DBG_871X("%s set channel_plan = 0x%02X\n", __func__, pmlmepriv->ChannelPlan);
3855         } else 
3856                 return -EPERM;
3857
3858         return 0;
3859 }
3860
3861 static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
3862                 struct iw_request_info *a,
3863                 union iwreq_data *wrqu, char *b)
3864 {
3865 #ifdef CONFIG_PLATFORM_MT53XX
3866         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3867         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3868
3869         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_,
3870                  ("WLAN IOCTL: cmd_code=%x, fwstate=0x%x\n",
3871                   a->cmd, get_fwstate(pmlmepriv)));
3872 #endif
3873         return 0;
3874 }
3875
3876 static int rtw_wx_get_sensitivity(struct net_device *dev,
3877                                 struct iw_request_info *info,
3878                                 union iwreq_data *wrqu, char *buf)
3879 {
3880 #ifdef CONFIG_PLATFORM_MT53XX
3881         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3882
3883         //      Modified by Albert 20110914
3884         //      This is in dbm format for MTK platform.
3885         wrqu->qual.level = padapter->recvpriv.rssi;
3886         DBG_871X(" level = %u\n",  wrqu->qual.level );
3887 #endif
3888         return 0;
3889 }
3890
3891 static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
3892                                 struct iw_request_info *info,
3893                                 union iwreq_data *wrqu, char *extra)
3894 {
3895 #ifdef CONFIG_PLATFORM_MT53XX
3896         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3897
3898         return rtw_set_wpa_ie(padapter, wrqu->data.pointer, wrqu->data.length);
3899 #else
3900         return 0;
3901 #endif
3902 }
3903
3904 /*
3905 typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
3906                           union iwreq_data *wrqu, char *extra);
3907 */
3908 /*
3909  *      For all data larger than 16 octets, we need to use a
3910  *      pointer to memory allocated in user space.
3911  */
3912 static  int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info,
3913                                                 union iwreq_data *wrqu, char *extra)
3914 {
3915
3916  #if 0
3917 struct  iw_point
3918 {
3919   void __user   *pointer;       /* Pointer to the data  (in user space) */
3920   __u16         length;         /* number of fields or size in bytes */
3921   __u16         flags;          /* Optional params */
3922 };
3923  #endif
3924
3925 #ifdef CONFIG_DRVEXT_MODULE
3926         u8 res;
3927         struct drvext_handler *phandler;        
3928         struct drvext_oidparam *poidparam;              
3929         int ret;
3930         u16 len;
3931         u8 *pparmbuf, bset;
3932         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3933         struct iw_point *p = &wrqu->data;
3934
3935         if( (!p->length) || (!p->pointer)){
3936                 ret = -EINVAL;
3937                 goto _rtw_drvext_hdl_exit;
3938         }
3939         
3940         
3941         bset = (u8)(p->flags&0xFFFF);
3942         len = p->length;
3943         pparmbuf = (u8*)rtw_malloc(len);
3944         if (pparmbuf == NULL){
3945                 ret = -ENOMEM;
3946                 goto _rtw_drvext_hdl_exit;
3947         }
3948         
3949         if(bset)//set info
3950         {
3951                 if (copy_from_user(pparmbuf, p->pointer,len)) {
3952                         rtw_mfree(pparmbuf, len);
3953                         ret = -EFAULT;
3954                         goto _rtw_drvext_hdl_exit;
3955                 }               
3956         }
3957         else//query info
3958         {
3959         
3960         }
3961
3962         
3963         //
3964         poidparam = (struct drvext_oidparam *)pparmbuf; 
3965         
3966         RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("drvext set oid subcode [%d], len[%d], InformationBufferLength[%d]\r\n",
3967                                                  poidparam->subcode, poidparam->len, len));
3968
3969
3970         //check subcode 
3971         if ( poidparam->subcode >= MAX_DRVEXT_HANDLERS)
3972         {
3973                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext handlers\r\n"));             
3974                 ret = -EINVAL;
3975                 goto _rtw_drvext_hdl_exit;
3976         }
3977
3978
3979         if ( poidparam->subcode >= MAX_DRVEXT_OID_SUBCODES)
3980         {
3981                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext subcodes\r\n"));             
3982                 ret = -EINVAL;
3983                 goto _rtw_drvext_hdl_exit;
3984         }
3985
3986
3987         phandler = drvextoidhandlers + poidparam->subcode;
3988
3989         if (poidparam->len != phandler->parmsize)
3990         {
3991                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext param size %d vs %d\r\n",                    
3992                                                 poidparam->len , phandler->parmsize));          
3993                 ret = -EINVAL;          
3994                 goto _rtw_drvext_hdl_exit;
3995         }
3996
3997
3998         res = phandler->handler(&padapter->drvextpriv, bset, poidparam->data);
3999
4000         if(res==0)
4001         {
4002                 ret = 0;
4003                         
4004                 if (bset == 0x00) {//query info
4005                         //_rtw_memcpy(p->pointer, pparmbuf, len);
4006                         if (copy_to_user(p->pointer, pparmbuf, len))
4007                                 ret = -EFAULT;
4008                 }               
4009         }               
4010         else
4011                 ret = -EFAULT;
4012
4013         
4014 _rtw_drvext_hdl_exit:   
4015         
4016         return ret;     
4017         
4018 #endif
4019
4020         return 0;
4021
4022 }
4023
4024 static void rtw_dbg_mode_hdl(_adapter *padapter, u32 id, u8 *pdata, u32 len)
4025 {
4026         pRW_Reg         RegRWStruct;
4027         struct rf_reg_param *prfreg;
4028         u8 path;
4029         u8 offset;
4030         u32 value;
4031
4032         DBG_871X("%s\n", __FUNCTION__);
4033
4034         switch(id)
4035         {
4036                 case GEN_MP_IOCTL_SUBCODE(MP_START):
4037                         DBG_871X("871x_driver is only for normal mode, can't enter mp mode\n");
4038                         break;
4039                 case GEN_MP_IOCTL_SUBCODE(READ_REG):
4040                         RegRWStruct = (pRW_Reg)pdata;
4041                         switch (RegRWStruct->width)
4042                         {
4043                                 case 1:
4044                                         RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
4045                                         break;
4046                                 case 2:
4047                                         RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
4048                                         break;
4049                                 case 4:
4050                                         RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
4051                                         break;
4052                                 default:
4053                                         break;
4054                         }
4055                 
4056                         break;
4057                 case GEN_MP_IOCTL_SUBCODE(WRITE_REG):
4058                         RegRWStruct = (pRW_Reg)pdata;
4059                         switch (RegRWStruct->width)
4060                         {
4061                                 case 1:
4062                                         rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value);
4063                                         break;
4064                                 case 2:
4065                                         rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value);
4066                                         break;
4067                                 case 4:
4068                                         rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value);
4069                                         break;
4070                                 default:                                        
4071                                 break;
4072                         }
4073                                 
4074                         break;
4075                 case GEN_MP_IOCTL_SUBCODE(READ_RF_REG):
4076
4077                         prfreg = (struct rf_reg_param *)pdata;
4078
4079                         path = (u8)prfreg->path;                
4080                         offset = (u8)prfreg->offset;    
4081
4082                         value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff);
4083
4084                         prfreg->value = value;
4085
4086                         break;                  
4087                 case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG):
4088
4089                         prfreg = (struct rf_reg_param *)pdata;
4090
4091                         path = (u8)prfreg->path;
4092                         offset = (u8)prfreg->offset;    
4093                         value = prfreg->value;
4094
4095                         rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value);
4096                         
4097                         break;                  
4098                 case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO):
4099                         DBG_871X("==> trigger gpio 0\n");
4100                         rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, 0);
4101                         break;  
4102 #ifdef CONFIG_BT_COEXIST
4103                 case GEN_MP_IOCTL_SUBCODE(SET_DM_BT):                   
4104                         DBG_871X("==> set dm_bt_coexist:%x\n",*(u8 *)pdata);
4105                         rtw_hal_set_hwreg(padapter, HW_VAR_BT_SET_COEXIST, pdata);
4106                         break;
4107                 case GEN_MP_IOCTL_SUBCODE(DEL_BA):
4108                         DBG_871X("==> delete ba:%x\n",*(u8 *)pdata);
4109                         rtw_hal_set_hwreg(padapter, HW_VAR_BT_ISSUE_DELBA, pdata);
4110                         break;
4111 #endif
4112 #ifdef DBG_CONFIG_ERROR_DETECT
4113                 case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS):                                                     
4114                         *pdata = rtw_hal_sreset_get_wifi_status(padapter);                   
4115                         break;
4116 #endif
4117         
4118                 default:
4119                         break;
4120         }
4121         
4122 }
4123
4124 static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info,
4125                                                 union iwreq_data *wrqu, char *extra)
4126 {
4127         int ret = 0;
4128         u32 BytesRead, BytesWritten, BytesNeeded;
4129         struct oid_par_priv     oid_par;
4130         struct mp_ioctl_handler *phandler;
4131         struct mp_ioctl_param   *poidparam;
4132         uint status=0;
4133         u16 len;
4134         u8 *pparmbuf = NULL, bset;
4135         PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
4136         struct iw_point *p = &wrqu->data;
4137
4138         //DBG_871X("+rtw_mp_ioctl_hdl\n");
4139
4140         //mutex_lock(&ioctl_mutex);
4141
4142         if ((!p->length) || (!p->pointer)) {
4143                 ret = -EINVAL;
4144                 goto _rtw_mp_ioctl_hdl_exit;
4145         }
4146
4147         pparmbuf = NULL;
4148         bset = (u8)(p->flags & 0xFFFF);
4149         len = p->length;
4150         pparmbuf = (u8*)rtw_malloc(len);
4151         if (pparmbuf == NULL){
4152                 ret = -ENOMEM;
4153                 goto _rtw_mp_ioctl_hdl_exit;
4154         }
4155
4156         if (copy_from_user(pparmbuf, p->pointer, len)) {
4157                 ret = -EFAULT;
4158                 goto _rtw_mp_ioctl_hdl_exit;
4159         }
4160
4161         poidparam = (struct mp_ioctl_param *)pparmbuf;
4162         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
4163                  ("rtw_mp_ioctl_hdl: subcode [%d], len[%d], buffer_len[%d]\r\n",
4164                   poidparam->subcode, poidparam->len, len));
4165
4166         if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
4167                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("no matching drvext subcodes\r\n"));
4168                 ret = -EINVAL;
4169                 goto _rtw_mp_ioctl_hdl_exit;
4170         }
4171
4172         //DBG_871X("%s: %d\n", __func__, poidparam->subcode);
4173 #ifdef CONFIG_MP_INCLUDED 
4174 if (padapter->registrypriv.mp_mode == 1)
4175 {       
4176         phandler = mp_ioctl_hdl + poidparam->subcode;
4177
4178         if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize))
4179         {
4180                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
4181                          ("no matching drvext param size %d vs %d\r\n",
4182                           poidparam->len, phandler->paramsize));
4183                 ret = -EINVAL;
4184                 goto _rtw_mp_ioctl_hdl_exit;
4185         }
4186
4187         if (phandler->handler)
4188         {
4189                 oid_par.adapter_context = padapter;
4190                 oid_par.oid = phandler->oid;
4191                 oid_par.information_buf = poidparam->data;
4192                 oid_par.information_buf_len = poidparam->len;
4193                 oid_par.dbg = 0;
4194
4195                 BytesWritten = 0;
4196                 BytesNeeded = 0;
4197
4198                 if (bset) {
4199                         oid_par.bytes_rw = &BytesRead;
4200                         oid_par.bytes_needed = &BytesNeeded;
4201                         oid_par.type_of_oid = SET_OID;
4202                 } else {
4203                         oid_par.bytes_rw = &BytesWritten;
4204                         oid_par.bytes_needed = &BytesNeeded;
4205                         oid_par.type_of_oid = QUERY_OID;
4206                 }
4207
4208                 status = phandler->handler(&oid_par);
4209
4210                 //todo:check status, BytesNeeded, etc.
4211         }
4212         else {
4213                 DBG_871X("rtw_mp_ioctl_hdl(): err!, subcode=%d, oid=%d, handler=%p\n", 
4214                         poidparam->subcode, phandler->oid, phandler->handler);
4215                 ret = -EFAULT;
4216                 goto _rtw_mp_ioctl_hdl_exit;
4217         }
4218 }
4219 else
4220 #endif
4221 {
4222         rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len);
4223 }
4224
4225         if (bset == 0x00) {//query info
4226                 if (copy_to_user(p->pointer, pparmbuf, len))
4227                         ret = -EFAULT;
4228         }
4229
4230         if (status) {
4231                 ret = -EFAULT;
4232                 goto _rtw_mp_ioctl_hdl_exit;
4233         }
4234
4235 _rtw_mp_ioctl_hdl_exit:
4236
4237         if (pparmbuf)
4238                 rtw_mfree(pparmbuf, len);
4239
4240         //mutex_unlock(&ioctl_mutex);
4241
4242         return ret;
4243 }
4244
4245 static int rtw_get_ap_info(struct net_device *dev,
4246                                struct iw_request_info *info,
4247                                union iwreq_data *wrqu, char *extra)
4248 {
4249         int bssid_match, ret = 0;
4250         u32 cnt=0, wpa_ielen;
4251         _irqL   irqL;
4252         _list   *plist, *phead;
4253         unsigned char *pbuf;
4254         u8 bssid[ETH_ALEN];
4255         char data[32];
4256         struct wlan_network *pnetwork = NULL;
4257         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4258         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
4259         _queue *queue = &(pmlmepriv->scanned_queue);
4260         struct iw_point *pdata = &wrqu->data;   
4261
4262         DBG_871X("+rtw_get_aplist_info\n");
4263
4264         if((padapter->bDriverStopped) || (pdata==NULL))
4265         {                
4266                 ret= -EINVAL;
4267                 goto exit;
4268         }               
4269   
4270         while((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) == _TRUE)
4271         {       
4272                 rtw_msleep_os(30);
4273                 cnt++;
4274                 if(cnt > 100)
4275                         break;
4276         }
4277         
4278
4279         //pdata->length = 0;//? 
4280         pdata->flags = 0;
4281         if(pdata->length>=32)
4282         {
4283                 if(copy_from_user(data, pdata->pointer, 32))
4284                 {
4285                         ret= -EINVAL;
4286                         goto exit;
4287                 }
4288         }       
4289         else
4290         {
4291                 ret= -EINVAL;
4292                 goto exit;
4293         }       
4294
4295         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4296         
4297         phead = get_list_head(queue);
4298         plist = get_next(phead);
4299        
4300         while(1)
4301         {
4302                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
4303                         break;
4304
4305
4306                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4307
4308                 //if(hwaddr_aton_i(pdata->pointer, bssid)) 
4309                 if(hwaddr_aton_i(data, bssid)) 
4310                 {                       
4311                         DBG_871X("Invalid BSSID '%s'.\n", (u8*)data);
4312                         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4313                         return -EINVAL;
4314                 }               
4315                 
4316         
4317                 if(_rtw_memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE)//BSSID match, then check if supporting wpa/wpa2
4318                 {
4319                         DBG_871X("BSSID:" MAC_FMT "\n", MAC_ARG(bssid));
4320                         
4321                         pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);                           
4322                         if(pbuf && (wpa_ielen>0))
4323                         {
4324                                 pdata->flags = 1;
4325                                 break;
4326                         }
4327
4328                         pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
4329                         if(pbuf && (wpa_ielen>0))
4330                         {
4331                                 pdata->flags = 2;
4332                                 break;
4333                         }
4334                         
4335                 }
4336
4337                 plist = get_next(plist);                
4338         
4339         }        
4340
4341         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4342
4343         if(pdata->length>=34)
4344         {
4345                 if(copy_to_user((u8*)pdata->pointer+32, (u8*)&pdata->flags, 1))
4346                 {
4347                         ret= -EINVAL;
4348                         goto exit;
4349                 }
4350         }       
4351         
4352 exit:
4353         
4354         return ret;
4355                 
4356 }
4357
4358 static int rtw_set_pid(struct net_device *dev,
4359                                struct iw_request_info *info,
4360                                union iwreq_data *wrqu, char *extra)
4361 {
4362         
4363         int ret = 0;    
4364         _adapter *padapter = rtw_netdev_priv(dev);      
4365         int *pdata = (int *)wrqu;
4366         int selector;
4367
4368         if((padapter->bDriverStopped) || (pdata==NULL))
4369         {                
4370                 ret= -EINVAL;
4371                 goto exit;
4372         }               
4373   
4374         selector = *pdata;
4375         if(selector < 3 && selector >=0) {
4376                 padapter->pid[selector] = *(pdata+1);
4377                 #ifdef CONFIG_GLOBAL_UI_PID
4378                 ui_pid[selector] = *(pdata+1);
4379                 #endif
4380                 DBG_871X("%s set pid[%d]=%d\n", __FUNCTION__, selector ,padapter->pid[selector]);
4381         }
4382         else
4383                 DBG_871X("%s selector %d error\n", __FUNCTION__, selector);
4384
4385 exit:
4386         
4387         return ret;
4388                 
4389 }
4390
4391 static int rtw_wps_start(struct net_device *dev,
4392                                struct iw_request_info *info,
4393                                union iwreq_data *wrqu, char *extra)
4394 {
4395         
4396         int ret = 0;    
4397         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4398         struct iw_point *pdata = &wrqu->data;
4399         u32   u32wps_start = 0;
4400         unsigned int uintRet = 0;
4401
4402         if((_TRUE == padapter->bDriverStopped) ||(_TRUE==padapter->bSurpriseRemoved) || (NULL== pdata))
4403         {                
4404                 ret= -EINVAL;
4405                 goto exit;
4406         }               
4407
4408         uintRet = copy_from_user( ( void* ) &u32wps_start, pdata->pointer, 4 );
4409         if ( u32wps_start == 0 )
4410         {
4411                 u32wps_start = *extra;
4412         }
4413
4414         DBG_871X( "[%s] wps_start = %d\n", __FUNCTION__, u32wps_start );
4415
4416         if ( u32wps_start == 1 ) // WPS Start
4417         {
4418                 rtw_led_control(padapter, LED_CTL_START_WPS);
4419         }
4420         else if ( u32wps_start == 2 ) // WPS Stop because of wps success
4421         {
4422                 rtw_led_control(padapter, LED_CTL_STOP_WPS);
4423         }
4424         else if ( u32wps_start == 3 ) // WPS Stop because of wps fail
4425         {
4426                 rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);
4427         }
4428
4429 #ifdef CONFIG_INTEL_WIDI
4430         process_intel_widi_wps_status(padapter, u32wps_start);
4431 #endif //CONFIG_INTEL_WIDI
4432         
4433 exit:
4434         
4435         return ret;
4436                 
4437 }
4438
4439 #ifdef CONFIG_P2P
4440 static int rtw_wext_p2p_enable(struct net_device *dev,
4441                                struct iw_request_info *info,
4442                                union iwreq_data *wrqu, char *extra)
4443 {
4444         
4445         int ret = 0;    
4446         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4447         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
4448         struct iw_point *pdata = &wrqu->data;
4449         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4450         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
4451         enum P2P_ROLE init_role = P2P_ROLE_DISABLE;
4452
4453         if(*extra == '0' )
4454                 init_role = P2P_ROLE_DISABLE;
4455         else if(*extra == '1')
4456                 init_role = P2P_ROLE_DEVICE;
4457         else if(*extra == '2')
4458                 init_role = P2P_ROLE_CLIENT;
4459         else if(*extra == '3')
4460                 init_role = P2P_ROLE_GO;
4461
4462         if(_FAIL == rtw_p2p_enable(padapter, init_role))
4463         {
4464                 ret = -EFAULT;
4465                 goto exit;
4466         }
4467
4468         //set channel/bandwidth
4469         if(init_role != P2P_ROLE_DISABLE) 
4470         {       
4471                 u8 channel, ch_offset;
4472                 u16 bwmode;
4473
4474                 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN))
4475                 {
4476                         //      Stay at the listen state and wait for discovery.
4477                         channel = pwdinfo->listen_channel;
4478                         pwdinfo->operating_channel = pwdinfo->listen_channel;
4479                         ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4480                         bwmode = CHANNEL_WIDTH_20;
4481                 }
4482 #ifdef CONFIG_CONCURRENT_MODE
4483                 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
4484                 {
4485                         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
4486                         //struct wifidirect_info        *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4487                         struct mlme_priv                *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4488                         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4489                         
4490                         _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval );
4491                         if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
4492                         {
4493                                 pwdinfo->operating_channel = pbuddy_mlmeext->cur_channel;
4494                                 //      How about the ch_offset and bwmode ??
4495                         }
4496                         else
4497                         {
4498                                 pwdinfo->operating_channel = pwdinfo->listen_channel;
4499                         }
4500
4501                         channel = pbuddy_mlmeext->cur_channel;
4502                         ch_offset = pbuddy_mlmeext->cur_ch_offset;
4503                         bwmode = pbuddy_mlmeext->cur_bwmode;
4504                 }
4505 #endif
4506                 else
4507                 {
4508                         pwdinfo->operating_channel = pmlmeext->cur_channel;
4509                 
4510                         channel = pwdinfo->operating_channel;
4511                         ch_offset = pmlmeext->cur_ch_offset;
4512                         bwmode = pmlmeext->cur_bwmode;                                          
4513                 }
4514
4515                 set_channel_bwmode(padapter, channel, ch_offset, bwmode);
4516         }
4517
4518 exit:
4519         return ret;
4520                 
4521 }
4522
4523 static int rtw_p2p_set_go_nego_ssid(struct net_device *dev,
4524                                struct iw_request_info *info,
4525                                union iwreq_data *wrqu, char *extra)
4526 {
4527         
4528         int ret = 0;    
4529         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4530         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
4531         struct iw_point *pdata = &wrqu->data;
4532         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4533
4534         DBG_871X( "[%s] ssid = %s, len = %zu\n", __FUNCTION__, extra, strlen( extra ) );
4535         _rtw_memcpy( pwdinfo->nego_ssid, extra, strlen( extra ) );
4536         pwdinfo->nego_ssidlen = strlen( extra );
4537         
4538         return ret;
4539                 
4540 }
4541
4542
4543 static int rtw_p2p_set_intent(struct net_device *dev,
4544                                struct iw_request_info *info,
4545                                union iwreq_data *wrqu, char *extra)
4546 {
4547         int                                                     ret = 0;
4548         _adapter                                                *padapter = (_adapter *)rtw_netdev_priv(dev);
4549         struct wifidirect_info                  *pwdinfo= &(padapter->wdinfo);
4550         u8                                                      intent = pwdinfo->intent;
4551
4552         extra[ wrqu->data.length ] = 0x00;
4553
4554         intent = rtw_atoi( extra );
4555
4556         if ( intent <= 15 )
4557         {
4558                 pwdinfo->intent= intent;
4559         }
4560         else
4561         {
4562                 ret = -1;
4563         }
4564         
4565         DBG_871X( "[%s] intent = %d\n", __FUNCTION__, intent);
4566
4567         return ret;
4568                 
4569 }
4570
4571 static int rtw_p2p_set_listen_ch(struct net_device *dev,
4572                                struct iw_request_info *info,
4573                                union iwreq_data *wrqu, char *extra)
4574 {
4575         
4576         int ret = 0;    
4577         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4578         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4579         u8      listen_ch = pwdinfo->listen_channel;    //      Listen channel number
4580
4581         extra[ wrqu->data.length ] = 0x00;
4582         listen_ch = rtw_atoi( extra );
4583
4584         if ( ( listen_ch == 1 ) || ( listen_ch == 6 ) || ( listen_ch == 11 ) )
4585         {
4586                 pwdinfo->listen_channel = listen_ch;
4587                 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
4588         }
4589         else
4590         {
4591                 ret = -1;
4592         }
4593         
4594         DBG_871X( "[%s] listen_ch = %d\n", __FUNCTION__, pwdinfo->listen_channel );
4595         
4596         return ret;
4597                 
4598 }
4599
4600 static int rtw_p2p_set_op_ch(struct net_device *dev,
4601                                struct iw_request_info *info,
4602                                union iwreq_data *wrqu, char *extra)
4603 {
4604 //      Commented by Albert 20110524
4605 //      This function is used to set the operating channel if the driver will become the group owner
4606
4607         int ret = 0;    
4608         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4609         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4610         u8      op_ch = pwdinfo->operating_channel;     //      Operating channel number
4611
4612         extra[ wrqu->data.length ] = 0x00;
4613
4614         op_ch = ( u8 ) rtw_atoi( extra );
4615         if ( op_ch > 0 )
4616         {
4617                 pwdinfo->operating_channel = op_ch;
4618         }
4619         else
4620         {
4621                 ret = -1;
4622         }
4623         
4624         DBG_871X( "[%s] op_ch = %d\n", __FUNCTION__, pwdinfo->operating_channel );
4625         
4626         return ret;
4627
4628 }
4629
4630
4631 static int rtw_p2p_profilefound(struct net_device *dev,
4632                                struct iw_request_info *info,
4633                                union iwreq_data *wrqu, char *extra)
4634 {
4635         
4636         int ret = 0;    
4637         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4638         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4639
4640         //      Comment by Albert 2010/10/13
4641         //      Input data format:
4642         //      Ex:  0
4643         //      Ex:  1XX:XX:XX:XX:XX:XXYYSSID
4644         //      0 => Reflush the profile record list.
4645         //      1 => Add the profile list
4646         //      XX:XX:XX:XX:XX:XX => peer's MAC Address ( ex: 00:E0:4C:00:00:01 )
4647         //      YY => SSID Length
4648         //      SSID => SSID for persistence group
4649
4650         DBG_871X( "[%s] In value = %s, len = %d \n", __FUNCTION__, extra, wrqu->data.length -1);
4651
4652         
4653         //      The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function.
4654         if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4655         {
4656                 if ( extra[ 0 ] == '0' )
4657                 {
4658                         //      Remove all the profile information of wifidirect_info structure.
4659                         _rtw_memset( &pwdinfo->profileinfo[ 0 ], 0x00, sizeof( struct profile_info ) * P2P_MAX_PERSISTENT_GROUP_NUM );
4660                         pwdinfo->profileindex = 0;
4661                 }
4662                 else
4663                 {
4664                         if ( pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM )
4665                 {
4666                                 ret = -1;
4667                 }
4668                 else
4669                 {
4670                                 int jj, kk;
4671                                 
4672                                 //      Add this profile information into pwdinfo->profileinfo
4673                                 //      Ex:  1XX:XX:XX:XX:XX:XXYYSSID
4674                                 for( jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3 )
4675                                 {
4676                                         pwdinfo->profileinfo[ pwdinfo->profileindex ].peermac[ jj ] = key_2char2num(extra[ kk ], extra[ kk+ 1 ]);
4677                                 }
4678
4679                                 //pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen = ( extra[18] - '0' ) * 10 + ( extra[ 19 ] - '0' );
4680                                 //_rtw_memcpy( pwdinfo->profileinfo[ pwdinfo->profileindex ].ssid, &extra[ 20 ], pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen );
4681                                 pwdinfo->profileindex++;
4682                         }
4683                 }
4684         }       
4685         
4686         return ret;
4687                 
4688 }
4689
4690 static int rtw_p2p_setDN(struct net_device *dev,
4691                                struct iw_request_info *info,
4692                                union iwreq_data *wrqu, char *extra)
4693 {
4694         
4695         int ret = 0;    
4696         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4697         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4698
4699
4700         DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
4701         _rtw_memset( pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN );
4702         _rtw_memcpy( pwdinfo->device_name, extra, wrqu->data.length - 1 );
4703         pwdinfo->device_name_len = wrqu->data.length - 1;
4704
4705         return ret;
4706                 
4707 }
4708
4709
4710 static int rtw_p2p_get_status(struct net_device *dev,
4711                                struct iw_request_info *info,
4712                                union iwreq_data *wrqu, char *extra)
4713 {
4714         
4715         int ret = 0;    
4716         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4717         struct iw_point *pdata = &wrqu->data;
4718         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4719 #ifdef CONFIG_CONCURRENT_MODE
4720         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
4721         struct wifidirect_info  *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4722         struct mlme_priv                *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4723         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; 
4724 #endif
4725         
4726         if ( padapter->bShowGetP2PState )
4727         {
4728                 DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4729                                 pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
4730                                 pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
4731         }
4732
4733         //      Commented by Albert 2010/10/12
4734         //      Because of the output size limitation, I had removed the "Role" information.
4735         //      About the "Role" information, we will use the new private IOCTL to get the "Role" information.
4736         sprintf( extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo) );
4737         wrqu->data.length = strlen( extra );
4738
4739         return ret;
4740                 
4741 }
4742
4743 //      Commented by Albert 20110520
4744 //      This function will return the config method description 
4745 //      This config method description will show us which config method the remote P2P device is intented to use
4746 //      by sending the provisioning discovery request frame.
4747
4748 static int rtw_p2p_get_req_cm(struct net_device *dev,
4749                                struct iw_request_info *info,
4750                                union iwreq_data *wrqu, char *extra)
4751 {
4752         
4753         int ret = 0;    
4754         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4755         struct iw_point *pdata = &wrqu->data;
4756         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4757
4758         sprintf( extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req );
4759         wrqu->data.length = strlen( extra );
4760         return ret;
4761                 
4762 }
4763
4764
4765 static int rtw_p2p_get_role(struct net_device *dev,
4766                                struct iw_request_info *info,
4767                                union iwreq_data *wrqu, char *extra)
4768 {
4769         
4770         int ret = 0;    
4771         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4772         struct iw_point *pdata = &wrqu->data;
4773         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4774
4775         
4776         DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4777                         pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
4778                         pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
4779
4780         sprintf( extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo) );
4781         wrqu->data.length = strlen( extra );
4782         return ret;
4783                 
4784 }
4785
4786
4787 static int rtw_p2p_get_peer_ifaddr(struct net_device *dev,
4788                                struct iw_request_info *info,
4789                                union iwreq_data *wrqu, char *extra)
4790 {
4791         
4792         int ret = 0;    
4793         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4794         struct iw_point *pdata = &wrqu->data;
4795         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4796
4797
4798         DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4799                         pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
4800                         pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
4801
4802         sprintf( extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4803                         pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
4804                         pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
4805         wrqu->data.length = strlen( extra );
4806         return ret;
4807                 
4808 }
4809
4810 static int rtw_p2p_get_peer_devaddr(struct net_device *dev,
4811                                struct iw_request_info *info,
4812                                union iwreq_data *wrqu, char *extra)
4813
4814 {
4815         
4816         int ret = 0;    
4817         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4818         struct iw_point *pdata = &wrqu->data;
4819         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4820
4821         DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4822                         pwdinfo->rx_prov_disc_info.peerDevAddr[ 0 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 1 ], 
4823                         pwdinfo->rx_prov_disc_info.peerDevAddr[ 2 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 3 ],
4824                         pwdinfo->rx_prov_disc_info.peerDevAddr[ 4 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 5 ]);
4825         sprintf( extra, "\n%.2X%.2X%.2X%.2X%.2X%.2X",
4826                         pwdinfo->rx_prov_disc_info.peerDevAddr[ 0 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 1 ], 
4827                         pwdinfo->rx_prov_disc_info.peerDevAddr[ 2 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 3 ],
4828                         pwdinfo->rx_prov_disc_info.peerDevAddr[ 4 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 5 ]);
4829         wrqu->data.length = strlen( extra );    
4830         return ret;
4831                 
4832 }
4833
4834 static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev,
4835                                struct iw_request_info *info,
4836                                union iwreq_data *wrqu, char *extra)
4837
4838 {
4839         
4840         int ret = 0;    
4841         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4842         struct iw_point *pdata = &wrqu->data;
4843         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4844
4845         DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4846                         pwdinfo->p2p_peer_device_addr[ 0 ], pwdinfo->p2p_peer_device_addr[ 1 ], 
4847                         pwdinfo->p2p_peer_device_addr[ 2 ], pwdinfo->p2p_peer_device_addr[ 3 ],
4848                         pwdinfo->p2p_peer_device_addr[ 4 ], pwdinfo->p2p_peer_device_addr[ 5 ]);
4849         sprintf( extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4850                         pwdinfo->p2p_peer_device_addr[ 0 ], pwdinfo->p2p_peer_device_addr[ 1 ], 
4851                         pwdinfo->p2p_peer_device_addr[ 2 ], pwdinfo->p2p_peer_device_addr[ 3 ],
4852                         pwdinfo->p2p_peer_device_addr[ 4 ], pwdinfo->p2p_peer_device_addr[ 5 ]);
4853         wrqu->data.length = strlen( extra );    
4854         return ret;
4855                 
4856 }
4857
4858 static int rtw_p2p_get_groupid(struct net_device *dev,
4859                                struct iw_request_info *info,
4860                                union iwreq_data *wrqu, char *extra)
4861
4862 {
4863         
4864         int ret = 0;    
4865         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4866         struct iw_point *pdata = &wrqu->data;
4867         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4868
4869         sprintf( extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s",
4870                         pwdinfo->groupid_info.go_device_addr[ 0 ], pwdinfo->groupid_info.go_device_addr[ 1 ], 
4871                         pwdinfo->groupid_info.go_device_addr[ 2 ], pwdinfo->groupid_info.go_device_addr[ 3 ],
4872                         pwdinfo->groupid_info.go_device_addr[ 4 ], pwdinfo->groupid_info.go_device_addr[ 5 ],
4873                         pwdinfo->groupid_info.ssid);
4874         wrqu->data.length = strlen( extra );    
4875         return ret;
4876                 
4877 }
4878
4879 static int rtw_p2p_get_op_ch(struct net_device *dev,
4880                                struct iw_request_info *info,
4881                                union iwreq_data *wrqu, char *extra)
4882
4883 {
4884         
4885         int ret = 0;    
4886         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4887         struct iw_point *pdata = &wrqu->data;
4888         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4889
4890         
4891         DBG_871X( "[%s] Op_ch = %02x\n", __FUNCTION__, pwdinfo->operating_channel);
4892         
4893         sprintf( extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel );
4894         wrqu->data.length = strlen( extra );
4895         return ret;
4896                 
4897 }
4898
4899 static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
4900                                                                                 struct iw_request_info *info,
4901                                                                                 union iwreq_data *wrqu, char *extra, char *subcmd)
4902
4903         
4904         int ret = 0;
4905         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4906         u8 peerMAC[ETH_ALEN] = { 0x00 };
4907         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4908         _irqL irqL;
4909         _list * plist,*phead;
4910         _queue *queue = &(pmlmepriv->scanned_queue);
4911         struct wlan_network *pnetwork = NULL;
4912         u8 blnMatch = 0;
4913         u16     attr_content = 0;
4914         uint attr_contentlen = 0;
4915         u8      attr_content_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4916
4917         //      Commented by Albert 20110727
4918         //      The input data is the MAC address which the application wants to know its WPS config method.
4919         //      After knowing its WPS config method, the application can decide the config method for provisioning discovery.
4920         //      Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05
4921
4922         DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
4923
4924         macstr2num(peerMAC, subcmd);
4925
4926         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4927
4928         phead = get_list_head(queue);
4929         plist = get_next(phead);
4930
4931         while (1)
4932         {
4933                 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
4934
4935                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4936                 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
4937                 {
4938                         u8 *wpsie;
4939                         uint    wpsie_len = 0;
4940
4941                         //      The mac address is matched.
4942
4943                         if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) )
4944                         {
4945                                 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&attr_content, &attr_contentlen);
4946                                 if (attr_contentlen)
4947                                 {
4948                                         attr_content = be16_to_cpu(attr_content);
4949                                         sprintf(attr_content_str, "\n\nM=%.4d", attr_content);
4950                                         blnMatch = 1;
4951                                 }
4952                         }
4953
4954                         break;
4955                 }
4956
4957                 plist = get_next(plist);
4958
4959         }
4960
4961         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4962
4963         if (!blnMatch)
4964         {
4965                 sprintf(attr_content_str, "\n\nM=0000");
4966         }
4967
4968         wrqu->data.length = strlen(attr_content_str);
4969         _rtw_memcpy(extra, attr_content_str, wrqu->data.length);
4970
4971         return ret; 
4972                 
4973 }
4974
4975 #ifdef CONFIG_WFD
4976 static int rtw_p2p_get_peer_wfd_port(struct net_device *dev,
4977                                struct iw_request_info *info,
4978                                union iwreq_data *wrqu, char *extra)
4979 {
4980         
4981         int ret = 0;    
4982         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4983         struct iw_point *pdata = &wrqu->data;
4984         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4985
4986         DBG_871X( "[%s] p2p_state = %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
4987
4988         sprintf( extra, "\n\nPort=%d\n", pwdinfo->wfd_info->peer_rtsp_ctrlport );
4989         DBG_871X( "[%s] remote port = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
4990         
4991         wrqu->data.length = strlen( extra );
4992         return ret;
4993                 
4994 }
4995
4996 static int rtw_p2p_get_peer_wfd_preferred_connection(struct net_device *dev,
4997                                struct iw_request_info *info,
4998                                union iwreq_data *wrqu, char *extra)
4999 {
5000         
5001         int ret = 0;    
5002         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
5003         struct iw_point *pdata = &wrqu->data;
5004         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
5005
5006         sprintf( extra, "\n\nwfd_pc=%d\n", pwdinfo->wfd_info->wfd_pc );
5007         DBG_871X( "[%s] wfd_pc = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_pc );
5008
5009         wrqu->data.length = strlen( extra );
5010         pwdinfo->wfd_info->wfd_pc = _FALSE;     //      Reset the WFD preferred connection to P2P
5011         return ret;
5012                 
5013 }
5014
5015 static int rtw_p2p_get_peer_wfd_session_available(struct net_device *dev,
5016                                struct iw_request_info *info,
5017                                union iwreq_data *wrqu, char *extra)
5018 {
5019         
5020         int ret = 0;    
5021         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
5022         struct iw_point *pdata = &wrqu->data;
5023         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
5024
5025         sprintf( extra, "\n\nwfd_sa=%d\n", pwdinfo->wfd_info->peer_session_avail );
5026         DBG_871X( "[%s] wfd_sa = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_session_avail );
5027
5028         wrqu->data.length = strlen( extra );
5029         pwdinfo->wfd_info->peer_session_avail = _TRUE;  //      Reset the WFD session available
5030         return ret;
5031                 
5032 }
5033
5034 #endif // CONFIG_WFD
5035
5036 static int rtw_p2p_get_go_device_address(struct net_device *dev,
5037                                                                                  struct iw_request_info *info,
5038                                                                                  union iwreq_data *wrqu, char *extra, char *subcmd)
5039 {
5040
5041         int ret = 0;    
5042         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5043         u8 peerMAC[ETH_ALEN] = { 0x00 };
5044         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5045         _irqL irqL;
5046         _list *plist, *phead;
5047         _queue *queue   = &(pmlmepriv->scanned_queue);
5048         struct wlan_network *pnetwork = NULL;
5049         u8 blnMatch = 0;
5050         u8 *p2pie;
5051         uint p2pielen = 0, attr_contentlen = 0;
5052         u8 attr_content[100] = { 0x00 };
5053         u8 go_devadd_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
5054
5055         //      Commented by Albert 20121209
5056         //      The input data is the GO's interface address which the application wants to know its device address.
5057         //      Format: iwpriv wlanx p2p_get2 go_devadd=00:E0:4C:00:00:05
5058
5059         DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5060
5061         macstr2num(peerMAC, subcmd);
5062
5063         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5064
5065         phead = get_list_head(queue);
5066         plist = get_next(phead);
5067
5068         while (1)
5069         {
5070                 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5071
5072                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5073                 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5074                 {
5075                         //      Commented by Albert 2011/05/18
5076                         //      Match the device address located in the P2P IE
5077                         //      This is for the case that the P2P device address is not the same as the P2P interface address.
5078
5079                         if ((p2pie = rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
5080                         {
5081                                 while (p2pie)
5082                                 {
5083                                         //      The P2P Device ID attribute is included in the Beacon frame.
5084                                         //      The P2P Device Info attribute is included in the probe response frame.
5085
5086                                         _rtw_memset(attr_content, 0x00, 100);
5087                                         if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen))
5088                                         {
5089                                                 //      Handle the P2P Device ID attribute of Beacon first
5090                                                 blnMatch = 1;
5091                                                 break;
5092
5093                                         } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen))
5094                                         {
5095                                                 //      Handle the P2P Device Info attribute of probe response
5096                                                 blnMatch = 1;
5097                                                 break;
5098                                         }
5099
5100                                         //Get the next P2P IE
5101                                         p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
5102                                 }
5103                         }
5104                 }
5105
5106                 plist = get_next(plist);
5107
5108         }
5109
5110         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5111
5112         if (!blnMatch)
5113         {
5114                 sprintf(go_devadd_str, "\n\ndev_add=NULL");
5115         } else
5116         {
5117                 sprintf(go_devadd_str, "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
5118                                 attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
5119         }
5120
5121         wrqu->data.length = strlen(go_devadd_str);
5122         _rtw_memcpy(extra, go_devadd_str, wrqu->data.length);
5123
5124         return ret; 
5125                 
5126 }
5127
5128 static int rtw_p2p_get_device_type(struct net_device *dev,
5129                                                                    struct iw_request_info *info,
5130                                                                    union iwreq_data *wrqu, char *extra, char *subcmd)
5131
5132         
5133         int ret = 0;
5134         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5135         u8 peerMAC[ETH_ALEN] = { 0x00 };
5136         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5137         _irqL irqL;
5138         _list *plist, *phead;
5139         _queue *queue = &(pmlmepriv->scanned_queue);
5140         struct wlan_network *pnetwork = NULL;
5141         u8 blnMatch = 0;
5142         u8 dev_type[8] = { 0x00 };
5143         uint dev_type_len = 0;
5144         u8 dev_type_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };    // +9 is for the str "dev_type=", we have to clear it at wrqu->data.pointer
5145
5146         //      Commented by Albert 20121209
5147         //      The input data is the MAC address which the application wants to know its device type.
5148         //      Such user interface could know the device type.
5149         //      Format: iwpriv wlanx p2p_get2 dev_type=00:E0:4C:00:00:05
5150
5151         DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5152
5153         macstr2num(peerMAC, subcmd);
5154
5155         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5156
5157         phead = get_list_head(queue);
5158         plist = get_next(phead);
5159
5160         while (1)
5161         {
5162                 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5163
5164                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5165                 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5166                 {
5167                         u8 *wpsie;
5168                         uint    wpsie_len = 0;
5169
5170                         //      The mac address is matched.
5171
5172                         if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) )
5173                         {
5174                                 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len);
5175                                 if (dev_type_len)
5176                                 {
5177                                         u16     type = 0;
5178
5179                                         _rtw_memcpy(&type, dev_type, 2);
5180                                         type = be16_to_cpu(type);
5181                                         sprintf(dev_type_str, "\n\nN=%.2d", type);
5182                                         blnMatch = 1;
5183                                 }
5184                         }
5185                         break;
5186                 }
5187
5188                 plist = get_next(plist);
5189
5190         }
5191
5192         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5193
5194         if (!blnMatch)
5195         {
5196                 sprintf(dev_type_str, "\n\nN=00");
5197         }
5198
5199         wrqu->data.length = strlen(dev_type_str);
5200         _rtw_memcpy(extra, dev_type_str, wrqu->data.length);
5201
5202         return ret; 
5203                 
5204 }
5205
5206 static int rtw_p2p_get_device_name(struct net_device *dev,
5207                                                                    struct iw_request_info *info,
5208                                                                    union iwreq_data *wrqu, char *extra, char *subcmd)
5209
5210         
5211         int ret = 0;
5212         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5213         u8 peerMAC[ETH_ALEN] = { 0x00 };
5214         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5215         _irqL irqL;
5216         _list *plist, *phead;
5217         _queue *queue = &(pmlmepriv->scanned_queue);
5218         struct wlan_network *pnetwork = NULL;
5219         u8 blnMatch = 0;
5220         u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = { 0x00 };
5221         uint dev_len = 0;
5222         u8 dev_name_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
5223
5224         //      Commented by Albert 20121225
5225         //      The input data is the MAC address which the application wants to know its device name.
5226         //      Such user interface could show peer device's device name instead of ssid.
5227         //      Format: iwpriv wlanx p2p_get2 devN=00:E0:4C:00:00:05
5228
5229         DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5230
5231         macstr2num(peerMAC, subcmd);
5232
5233         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5234
5235         phead = get_list_head(queue);
5236         plist = get_next(phead);
5237
5238         while (1)
5239         {
5240                 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5241
5242                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5243                 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5244                 {
5245                         u8 *wpsie;
5246                         uint    wpsie_len = 0;
5247
5248                         //      The mac address is matched.
5249
5250                         if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) )
5251                         {
5252                                 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
5253                                 if (dev_len)
5254                                 {
5255                                         sprintf(dev_name_str, "\n\nN=%s", dev_name);
5256                                         blnMatch = 1;
5257                                 }
5258                         }
5259                         break;
5260                 }
5261
5262                 plist = get_next(plist);
5263
5264         }
5265
5266         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5267
5268         if (!blnMatch)
5269         {
5270                 sprintf(dev_name_str, "\n\nN=0000");
5271         }
5272
5273         wrqu->data.length = strlen(dev_name_str);
5274         _rtw_memcpy(extra, dev_name_str, wrqu->data.length);
5275
5276         return ret; 
5277                 
5278 }
5279
5280 static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
5281                                                                                         struct iw_request_info *info,
5282                                                                                         union iwreq_data *wrqu, char *extra, char *subcmd)
5283 {
5284
5285         int ret = 0;    
5286         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5287         u8 peerMAC[ETH_ALEN] = { 0x00 };
5288         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5289         _irqL irqL;
5290         _list *plist, *phead;
5291         _queue *queue   = &(pmlmepriv->scanned_queue);
5292         struct wlan_network *pnetwork = NULL;
5293         u8 blnMatch = 0;
5294         u8 *p2pie;
5295         uint p2pielen = 0, attr_contentlen = 0;
5296         u8 attr_content[2] = { 0x00 };
5297         u8 inv_proc_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
5298
5299         //      Commented by Ouden 20121226
5300         //      The application wants to know P2P initation procedure is support or not.
5301         //      Format: iwpriv wlanx p2p_get2 InvProc=00:E0:4C:00:00:05
5302
5303         DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5304
5305         macstr2num(peerMAC, subcmd);
5306
5307         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5308
5309         phead = get_list_head(queue);
5310         plist = get_next(phead);
5311
5312         while (1)
5313         {
5314                 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5315
5316                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5317                 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5318                 {
5319                         //      Commented by Albert 20121226
5320                         //      Match the device address located in the P2P IE
5321                         //      This is for the case that the P2P device address is not the same as the P2P interface address.
5322
5323                         if ((p2pie = rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
5324                         {
5325                                 while (p2pie)
5326                                 {
5327                                         //_rtw_memset( attr_content, 0x00, 2);
5328                                         if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen))
5329                                         {
5330                                                 //      Handle the P2P capability attribute
5331                                                 blnMatch = 1;
5332                                                 break;
5333
5334                                         }
5335
5336                                         //Get the next P2P IE
5337                                         p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
5338                                 }
5339                         }
5340                 }
5341
5342                 plist = get_next(plist);
5343
5344         }
5345
5346         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5347
5348         if (!blnMatch)
5349         {
5350                 sprintf(inv_proc_str, "\nIP=-1");
5351         } else
5352         {
5353                 if (attr_content[0] && 0x20)
5354                 {
5355                         sprintf(inv_proc_str, "\nIP=1");
5356                 } else
5357                 {
5358                         sprintf(inv_proc_str, "\nIP=0");
5359                 }
5360         }
5361
5362         wrqu->data.length = strlen(inv_proc_str);
5363         _rtw_memcpy(extra, inv_proc_str, wrqu->data.length);
5364
5365         return ret; 
5366                 
5367 }
5368
5369 static int rtw_p2p_connect(struct net_device *dev,
5370                                struct iw_request_info *info,
5371                                union iwreq_data *wrqu, char *extra)
5372 {
5373         
5374         int ret = 0;    
5375         _adapter                                *padapter = (_adapter *)rtw_netdev_priv(dev);   
5376         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
5377         u8                                      peerMAC[ ETH_ALEN ] = { 0x00 };
5378         int                                     jj,kk;
5379         u8                                      peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5380         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
5381         _irqL                           irqL;
5382         _list                                   *plist, *phead;
5383         _queue                          *queue  = &(pmlmepriv->scanned_queue);
5384         struct  wlan_network    *pnetwork = NULL;
5385         uint                                    uintPeerChannel = 0;
5386 #ifdef CONFIG_CONCURRENT_MODE
5387         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
5388         struct mlme_priv                *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5389         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5390 #endif // CONFIG_CONCURRENT_MODE        
5391
5392         //      Commented by Albert 20110304
5393         //      The input data contains two informations.
5394         //      1. First information is the MAC address which wants to formate with
5395         //      2. Second information is the WPS PINCode or "pbc" string for push button method
5396         //      Format: 00:E0:4C:00:00:05
5397         //      Format: 00:E0:4C:00:00:05
5398
5399         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5400
5401         if ( pwdinfo->p2p_state == P2P_STATE_NONE )
5402         {
5403                 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5404                 return ret;
5405         }
5406         
5407         if ( pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO )
5408         {
5409                 return -1;
5410         }
5411         
5412         for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
5413         {
5414                 peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
5415         }
5416
5417         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5418
5419         phead = get_list_head(queue);
5420         plist = get_next(phead);
5421        
5422         while(1)
5423         {
5424                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
5425                         break;
5426
5427                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5428                 if ( _rtw_memcmp( pnetwork->network.MacAddress, peerMAC, ETH_ALEN ) )
5429                 {
5430                         uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5431                         break;
5432                 }
5433
5434                 plist = get_next(plist);
5435         
5436         }
5437
5438         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5439
5440         if ( uintPeerChannel )
5441         {
5442 #ifdef CONFIG_CONCURRENT_MODE
5443                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5444                 {
5445                         _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
5446                 }
5447 #endif // CONFIG_CONCURRENT_MODE
5448
5449                 _rtw_memset( &pwdinfo->nego_req_info, 0x00, sizeof( struct tx_nego_req_info ) );
5450                 _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
5451                 
5452                 pwdinfo->nego_req_info.peer_channel_num[ 0 ] = uintPeerChannel;
5453                 _rtw_memcpy( pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN );
5454                 pwdinfo->nego_req_info.benable = _TRUE;
5455
5456                 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5457                 if ( rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK )
5458                 {
5459                         //      Restore to the listen state if the current p2p state is not nego OK
5460                         rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN );
5461                 }
5462
5463                 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5464                 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
5465
5466 #ifdef CONFIG_CONCURRENT_MODE
5467                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5468                 {
5469                         //      Have to enter the power saving with the AP
5470                         set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
5471                         
5472                         issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
5473                 }
5474 #endif // CONFIG_CONCURRENT_MODE
5475
5476                 DBG_871X( "[%s] Start PreTx Procedure!\n", __FUNCTION__ );
5477                 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
5478 #ifdef CONFIG_CONCURRENT_MODE
5479                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5480                 {
5481                         _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_GO_NEGO_TIMEOUT );
5482                 }
5483                 else
5484                 {
5485                         _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT );
5486                 }
5487 #else
5488                 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT );
5489 #endif // CONFIG_CONCURRENT_MODE                
5490
5491         }
5492         else
5493         {
5494                 DBG_871X( "[%s] Not Found in Scanning Queue~\n", __FUNCTION__ );
5495                 ret = -1;
5496         }
5497 exit:   
5498         return ret;
5499 }
5500
5501 static int rtw_p2p_invite_req(struct net_device *dev,
5502                                struct iw_request_info *info,
5503                                union iwreq_data *wrqu, char *extra)
5504 {
5505         
5506         int ret = 0;    
5507         _adapter                                        *padapter = (_adapter *)rtw_netdev_priv(dev);   
5508         struct iw_point                         *pdata = &wrqu->data;
5509         struct wifidirect_info          *pwdinfo = &( padapter->wdinfo );
5510         int                                             jj,kk;
5511         u8                                              peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5512         struct mlme_priv                        *pmlmepriv = &padapter->mlmepriv;
5513         _list                                           *plist, *phead;
5514         _queue                                  *queue  = &(pmlmepriv->scanned_queue);
5515         struct  wlan_network            *pnetwork = NULL;
5516         uint                                            uintPeerChannel = 0;
5517         u8                                              attr_content[50] = { 0x00 }, _status = 0;
5518         u8                                              *p2pie;
5519         uint                                            p2pielen = 0, attr_contentlen = 0;
5520         _irqL                                   irqL;
5521         struct tx_invite_req_info*      pinvite_req_info = &pwdinfo->invitereq_info;
5522         u8 ie_offset = 12;
5523 #ifdef CONFIG_CONCURRENT_MODE
5524         _adapter                                        *pbuddy_adapter = padapter->pbuddy_adapter;
5525         struct mlme_priv                        *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5526         struct mlme_ext_priv            *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5527 #endif // CONFIG_CONCURRENT_MODE
5528
5529 #ifdef CONFIG_WFD
5530         struct wifi_display_info*       pwfd_info = pwdinfo->wfd_info;
5531 #endif // CONFIG_WFD
5532         
5533         //      Commented by Albert 20120321
5534         //      The input data contains two informations.
5535         //      1. First information is the P2P device address which you want to send to.       
5536         //      2. Second information is the group id which combines with GO's mac address, space and GO's ssid.
5537         //      Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy"
5538         //      Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy
5539
5540         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5541
5542         if ( wrqu->data.length <=  37 )
5543         {
5544                 DBG_871X( "[%s] Wrong format!\n", __FUNCTION__ );
5545                 return ret;
5546         }
5547
5548         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
5549         {
5550                 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5551                 return ret;
5552         }
5553         else
5554         {
5555                 //      Reset the content of struct tx_invite_req_info
5556                 pinvite_req_info->benable = _FALSE;
5557                 _rtw_memset( pinvite_req_info->go_bssid, 0x00, ETH_ALEN );
5558                 _rtw_memset( pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN );
5559                 pinvite_req_info->ssidlen = 0x00;
5560                 pinvite_req_info->operating_ch = pwdinfo->operating_channel;
5561                 _rtw_memset( pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN );
5562                 pinvite_req_info->token = 3;
5563         }
5564         
5565         for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
5566         {
5567                 pinvite_req_info->peer_macaddr[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
5568         }
5569
5570         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5571
5572         phead = get_list_head(queue);
5573         plist = get_next(phead);
5574        
5575         while(1)
5576         {
5577                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
5578                         break;
5579
5580                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5581
5582                 //      Commented by Albert 2011/05/18
5583                 //      Match the device address located in the P2P IE
5584                 //      This is for the case that the P2P device address is not the same as the P2P interface address.
5585
5586                 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);
5587                 if ( (p2pie=rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
5588                 {
5589                         //      The P2P Device ID attribute is included in the Beacon frame.
5590                         //      The P2P Device Info attribute is included in the probe response frame.
5591
5592                         if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
5593                         {
5594                                 //      Handle the P2P Device ID attribute of Beacon first
5595                                 if ( _rtw_memcmp( attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN ) )
5596                                 {
5597                                         uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5598                                         break;
5599                                 }
5600                         }
5601                         else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
5602                         {
5603                                 //      Handle the P2P Device Info attribute of probe response
5604                                 if ( _rtw_memcmp( attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN ) )
5605                                 {
5606                                         uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5607                                         break;
5608                                 }                                       
5609                         }
5610
5611                 }
5612
5613                 plist = get_next(plist);
5614         
5615         }
5616
5617         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5618
5619 #ifdef CONFIG_WFD
5620         if ( uintPeerChannel )
5621         {
5622                 u8      wfd_ie[ 128 ] = { 0x00 };
5623                 uint    wfd_ielen = 0;
5624                 
5625                 if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength,  wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) )
5626                 {
5627                         u8      wfd_devinfo[ 6 ] = { 0x00 };
5628                         uint    wfd_devlen = 6;
5629
5630                         DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ );
5631                         if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) )
5632                         {
5633                                 u16     wfd_devinfo_field = 0;
5634                                 
5635                                 //      Commented by Albert 20120319
5636                                 //      The first two bytes are the WFD device information field of WFD device information subelement.
5637                                 //      In big endian format.
5638                                 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5639                                 if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL )
5640                                 {
5641                                         pwfd_info->peer_session_avail = _TRUE;
5642                                 }
5643                                 else
5644                                 {
5645                                         pwfd_info->peer_session_avail = _FALSE;
5646                                 }
5647                         }
5648                 }
5649                 
5650                 if ( _FALSE == pwfd_info->peer_session_avail )
5651                 {
5652                         DBG_871X( "[%s] WFD Session not avaiable!\n", __FUNCTION__ );
5653                         goto exit;
5654                 }
5655         }
5656 #endif // CONFIG_WFD
5657
5658         if ( uintPeerChannel )
5659         {
5660 #ifdef CONFIG_CONCURRENT_MODE
5661                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5662                 {
5663                         _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
5664                 }
5665 #endif // CONFIG_CONCURRENT_MODE
5666
5667                 //      Store the GO's bssid
5668                 for( jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3 )
5669                 {
5670                         pinvite_req_info->go_bssid[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
5671                 }
5672
5673                 //      Store the GO's ssid
5674                 pinvite_req_info->ssidlen = wrqu->data.length - 36;
5675                 _rtw_memcpy( pinvite_req_info->go_ssid, &extra[ 36 ], (u32) pinvite_req_info->ssidlen );
5676                 pinvite_req_info->benable = _TRUE;
5677                 pinvite_req_info->peer_ch = uintPeerChannel;
5678
5679                 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5680                 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ);
5681
5682 #ifdef CONFIG_CONCURRENT_MODE
5683                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5684                 {
5685                         //      Have to enter the power saving with the AP
5686                         set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
5687                         
5688                         issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
5689                 }
5690                 else
5691                 {
5692                         set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5693                 }
5694 #else
5695                 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5696 #endif
5697
5698                 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
5699                 
5700 #ifdef CONFIG_CONCURRENT_MODE
5701                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5702                 {
5703                         _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_INVITE_TIMEOUT );
5704                 }
5705                 else
5706                 {
5707                         _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT );
5708                 }
5709 #else
5710                 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT );
5711 #endif // CONFIG_CONCURRENT_MODE                
5712
5713                 
5714         }
5715         else
5716         {
5717                 DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ );
5718         }
5719 exit:
5720         
5721         return ret;
5722                 
5723 }
5724
5725 static int rtw_p2p_set_persistent(struct net_device *dev,
5726                                struct iw_request_info *info,
5727                                union iwreq_data *wrqu, char *extra)
5728 {
5729         
5730         int ret = 0;    
5731         _adapter                                        *padapter = (_adapter *)rtw_netdev_priv(dev);   
5732         struct iw_point                         *pdata = &wrqu->data;
5733         struct wifidirect_info          *pwdinfo = &( padapter->wdinfo );
5734         int                                             jj,kk;
5735         u8                                              peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5736         struct mlme_priv                        *pmlmepriv = &padapter->mlmepriv;
5737         _list                                           *plist, *phead;
5738         _queue                                  *queue  = &(pmlmepriv->scanned_queue);
5739         struct  wlan_network            *pnetwork = NULL;
5740         uint                                            uintPeerChannel = 0;
5741         u8                                              attr_content[50] = { 0x00 }, _status = 0;
5742         u8                                              *p2pie;
5743         uint                                            p2pielen = 0, attr_contentlen = 0;
5744         _irqL                                   irqL;
5745         struct tx_invite_req_info*      pinvite_req_info = &pwdinfo->invitereq_info;
5746 #ifdef CONFIG_CONCURRENT_MODE
5747         _adapter                                        *pbuddy_adapter = padapter->pbuddy_adapter;
5748         struct mlme_priv                        *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5749         struct mlme_ext_priv            *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5750 #endif // CONFIG_CONCURRENT_MODE
5751
5752 #ifdef CONFIG_WFD
5753         struct wifi_display_info*       pwfd_info = pwdinfo->wfd_info;
5754 #endif // CONFIG_WFD
5755         
5756         //      Commented by Albert 20120328
5757         //      The input data is 0 or 1
5758         //      0: disable persistent group functionality
5759         //      1: enable persistent group founctionality
5760         
5761         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5762
5763         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
5764         {
5765                 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5766                 return ret;
5767         }
5768         else
5769         {
5770                 if ( extra[ 0 ] == '0' )        //      Disable the persistent group function.
5771                 {
5772                         pwdinfo->persistent_supported = _FALSE;
5773                 }
5774                 else if ( extra[ 0 ] == '1' )   //      Enable the persistent group function.
5775                 {
5776                         pwdinfo->persistent_supported = _TRUE;
5777                 }
5778                 else
5779                 {
5780                         pwdinfo->persistent_supported = _FALSE;
5781                 }
5782         }
5783         printk( "[%s] persistent_supported = %d\n", __FUNCTION__, pwdinfo->persistent_supported );
5784         
5785 exit:
5786         
5787         return ret;
5788                 
5789 }
5790
5791 static int hexstr2bin(const char *hex, u8 *buf, size_t len)
5792 {
5793         size_t i;
5794         int a;
5795         const char *ipos = hex;
5796         u8 *opos = buf;
5797
5798         for (i = 0; i < len; i++) {
5799                 a = hex2byte_i(ipos);
5800                 if (a < 0)
5801                         return -1;
5802                 *opos++ = a;
5803                 ipos += 2;
5804         }
5805         return 0;
5806 }
5807
5808 static int uuid_str2bin(const char *str, u8 *bin)
5809 {
5810         const char *pos;
5811         u8 *opos;
5812
5813         pos = str;
5814         opos = bin;
5815
5816         if (hexstr2bin(pos, opos, 4))
5817                 return -1;
5818         pos += 8;
5819         opos += 4;
5820
5821         if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5822                 return -1;
5823         pos += 4;
5824         opos += 2;
5825
5826         if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5827                 return -1;
5828         pos += 4;
5829         opos += 2;
5830
5831         if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5832                 return -1;
5833         pos += 4;
5834         opos += 2;
5835
5836         if (*pos++ != '-' || hexstr2bin(pos, opos, 6))
5837                 return -1;
5838
5839         return 0;
5840 }
5841
5842 static int rtw_p2p_set_wps_uuid(struct net_device *dev,
5843         struct iw_request_info *info,
5844         union iwreq_data *wrqu, char *extra)
5845 {
5846
5847         int ret = 0;
5848         _adapter                                *padapter = (_adapter *)rtw_netdev_priv(dev);
5849         struct wifidirect_info                  *pwdinfo = &(padapter->wdinfo);
5850
5851         DBG_871X("[%s] data = %s\n", __FUNCTION__, extra);
5852
5853         if ((36 == strlen(extra)) && (uuid_str2bin(extra, pwdinfo->uuid) == 0)) 
5854         {
5855                 pwdinfo->external_uuid = 1;
5856         } else {
5857                 pwdinfo->external_uuid = 0;
5858                 ret = -EINVAL;
5859         }
5860
5861         return ret;
5862
5863 }
5864 #ifdef CONFIG_WFD
5865 static int rtw_p2p_set_pc(struct net_device *dev,
5866                                struct iw_request_info *info,
5867                                union iwreq_data *wrqu, char *extra)
5868 {
5869         
5870         int ret = 0;    
5871         _adapter                                *padapter = (_adapter *)rtw_netdev_priv(dev);   
5872         struct iw_point                 *pdata = &wrqu->data;
5873         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
5874         u8                                      peerMAC[ ETH_ALEN ] = { 0x00 };
5875         int                                     jj,kk;
5876         u8                                      peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5877         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
5878         _list                                   *plist, *phead;
5879         _queue                          *queue  = &(pmlmepriv->scanned_queue);
5880         struct  wlan_network    *pnetwork = NULL;
5881         u8                                      attr_content[50] = { 0x00 }, _status = 0;
5882         u8 *p2pie;
5883         uint                                    p2pielen = 0, attr_contentlen = 0;
5884         _irqL                           irqL;
5885         uint                                    uintPeerChannel = 0;
5886 #ifdef CONFIG_CONCURRENT_MODE
5887         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
5888         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5889 #endif // CONFIG_CONCURRENT_MODE        
5890         
5891         struct wifi_display_info*       pwfd_info = pwdinfo->wfd_info;
5892         
5893         //      Commented by Albert 20120512
5894         //      1. Input information is the MAC address which wants to know the Preferred Connection bit (PC bit)
5895         //      Format: 00:E0:4C:00:00:05
5896
5897         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5898
5899         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
5900         {
5901                 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5902                 return ret;
5903         }
5904         
5905         for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
5906         {
5907                 peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
5908         }
5909
5910         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5911
5912         phead = get_list_head(queue);
5913         plist = get_next(phead);
5914        
5915         while(1)
5916         {
5917                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
5918                         break;
5919
5920                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5921
5922                 //      Commented by Albert 2011/05/18
5923                 //      Match the device address located in the P2P IE
5924                 //      This is for the case that the P2P device address is not the same as the P2P interface address.
5925
5926                 if ( (p2pie=rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
5927                 {
5928                         //      The P2P Device ID attribute is included in the Beacon frame.
5929                         //      The P2P Device Info attribute is included in the probe response frame.
5930                         printk( "[%s] Got P2P IE\n", __FUNCTION__ );
5931                         if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
5932                         {
5933                                 //      Handle the P2P Device ID attribute of Beacon first
5934                                 printk( "[%s] P2P_ATTR_DEVICE_ID \n", __FUNCTION__ );
5935                                 if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
5936                                 {
5937                                         uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5938                                         break;
5939                                 }
5940                         }
5941                         else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
5942                         {
5943                                 //      Handle the P2P Device Info attribute of probe response
5944                                 printk( "[%s] P2P_ATTR_DEVICE_INFO \n", __FUNCTION__ );
5945                                 if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
5946                                 {
5947                                         uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5948                                         break;
5949                                 }                                       
5950                         }
5951
5952                 }
5953
5954                 plist = get_next(plist);
5955         
5956         }
5957
5958         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5959         printk( "[%s] channel = %d\n", __FUNCTION__, uintPeerChannel );
5960
5961         if ( uintPeerChannel )
5962         {
5963                 u8      wfd_ie[ 128 ] = { 0x00 };
5964                 uint    wfd_ielen = 0;
5965                 u8 ie_offset = (pnetwork->network.Reserved[0] == 2 ? 0:12);
5966
5967                 if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength,  wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) )
5968                 {
5969                         u8      wfd_devinfo[ 6 ] = { 0x00 };
5970                         uint    wfd_devlen = 6;
5971
5972                         DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ );
5973                         if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) )
5974                         {
5975                                 u16     wfd_devinfo_field = 0;
5976                                 
5977                                 //      Commented by Albert 20120319
5978                                 //      The first two bytes are the WFD device information field of WFD device information subelement.
5979                                 //      In big endian format.
5980                                 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5981                                 if ( wfd_devinfo_field & WFD_DEVINFO_PC_TDLS )
5982                                 {
5983                                         pwfd_info->wfd_pc = _TRUE;
5984                                 }
5985                                 else
5986                                 {
5987                                         pwfd_info->wfd_pc = _FALSE;
5988                                 }
5989                         }
5990                 }
5991         }       
5992         else
5993         {
5994                 DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ );
5995         }
5996
5997 exit:
5998         
5999         return ret;
6000                 
6001 }
6002
6003 static int rtw_p2p_set_wfd_device_type(struct net_device *dev,
6004                                struct iw_request_info *info,
6005                                union iwreq_data *wrqu, char *extra)
6006 {
6007         
6008         int ret = 0;    
6009         _adapter                                        *padapter = (_adapter *)rtw_netdev_priv(dev);   
6010         struct iw_point                         *pdata = &wrqu->data;
6011         struct wifidirect_info          *pwdinfo = &( padapter->wdinfo );
6012         struct wifi_display_info                *pwfd_info = pwdinfo->wfd_info;
6013         
6014         //      Commented by Albert 20120328
6015         //      The input data is 0 or 1
6016         //      0: specify to Miracast source device
6017         //      1 or others: specify to Miracast sink device (display device)
6018         
6019         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6020
6021         if ( extra[ 0 ] == '0' )        //      Set to Miracast source device.
6022         {
6023                 pwfd_info->wfd_device_type = WFD_DEVINFO_SOURCE;
6024         }
6025         else                                    //      Set to Miracast sink device.
6026         {
6027                 pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK;
6028         }
6029
6030 exit:
6031         
6032         return ret;
6033                 
6034 }
6035
6036 static int rtw_p2p_set_wfd_enable(struct net_device *dev,
6037                                struct iw_request_info *info,
6038                                union iwreq_data *wrqu, char *extra)
6039 {
6040 //      Commented by Kurt 20121206
6041 //      This function is used to set wfd enabled
6042
6043         int ret = 0;    
6044         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6045         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
6046
6047         if(*extra == '0' )
6048                 pwdinfo->wfd_info->wfd_enable = _FALSE;
6049         else if(*extra == '1')
6050                 pwdinfo->wfd_info->wfd_enable = _TRUE;
6051
6052         DBG_871X( "[%s] wfd_enable = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_enable );
6053         
6054         return ret;
6055                 
6056 }
6057
6058 static int rtw_p2p_set_driver_iface(struct net_device *dev,
6059                                struct iw_request_info *info,
6060                                union iwreq_data *wrqu, char *extra)
6061 {
6062 //      Commented by Kurt 20121206
6063 //      This function is used to set driver iface is WEXT or CFG80211
6064         int ret = 0;    
6065         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6066         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
6067
6068         if(*extra == '1' )
6069         {
6070                 pwdinfo->driver_interface = DRIVER_WEXT;
6071                 DBG_871X( "[%s] driver_interface = WEXT\n", __FUNCTION__);
6072         }
6073         else if(*extra == '2')
6074         {
6075                 pwdinfo->driver_interface = DRIVER_CFG80211;
6076                 DBG_871X( "[%s] driver_interface = CFG80211\n", __FUNCTION__);
6077         }
6078         
6079         return ret;
6080                 
6081 }
6082
6083 //      To set the WFD session available to enable or disable
6084 static int rtw_p2p_set_sa(struct net_device *dev,
6085                                struct iw_request_info *info,
6086                                union iwreq_data *wrqu, char *extra)
6087 {
6088         
6089         int ret = 0;    
6090         _adapter                                        *padapter = (_adapter *)rtw_netdev_priv(dev);   
6091         struct iw_point                         *pdata = &wrqu->data;
6092         struct wifidirect_info          *pwdinfo = &( padapter->wdinfo );
6093         struct wifi_display_info                *pwfd_info = pwdinfo->wfd_info;
6094         
6095         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6096
6097         if( 0 )
6098         {
6099                 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
6100                 return ret;
6101         }
6102         else
6103         {
6104                 if ( extra[ 0 ] == '0' )        //      Disable the session available.
6105                 {
6106                         pwdinfo->session_available = _FALSE;
6107                 }
6108                 else if ( extra[ 0 ] == '1' )   //      Enable the session available.
6109                 {
6110                         pwdinfo->session_available = _TRUE;
6111                 }
6112                 else
6113                 {
6114                         pwdinfo->session_available = _FALSE;
6115                 }
6116         }
6117         printk( "[%s] session available = %d\n", __FUNCTION__, pwdinfo->session_available );
6118         
6119 exit:
6120         
6121         return ret;
6122                 
6123 }
6124 #endif // CONFIG_WFD
6125
6126 static int rtw_p2p_prov_disc(struct net_device *dev,
6127                                struct iw_request_info *info,
6128                                union iwreq_data *wrqu, char *extra)
6129 {
6130         int ret = 0;    
6131         _adapter                                *padapter = (_adapter *)rtw_netdev_priv(dev);   
6132         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
6133         u8                                      peerMAC[ ETH_ALEN ] = { 0x00 };
6134         int                                     jj,kk;
6135         u8                                      peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
6136         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
6137         _list                                   *plist, *phead;
6138         _queue                          *queue  = &(pmlmepriv->scanned_queue);
6139         struct  wlan_network    *pnetwork = NULL;
6140         uint                                    uintPeerChannel = 0;
6141         u8                                      attr_content[100] = { 0x00 }, _status = 0;
6142         u8 *p2pie;
6143         uint                                    p2pielen = 0, attr_contentlen = 0;
6144         _irqL                           irqL;
6145         u8                                      ie_offset = 12;
6146 #ifdef CONFIG_CONCURRENT_MODE
6147         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
6148         struct mlme_priv                *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
6149         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
6150 #endif // CONFIG_CONCURRENT_MODE        
6151 #ifdef CONFIG_WFD
6152         struct wifi_display_info*       pwfd_info = pwdinfo->wfd_info;
6153 #endif // CONFIG_WFD
6154
6155         //      Commented by Albert 20110301
6156         //      The input data contains two informations.
6157         //      1. First information is the MAC address which wants to issue the provisioning discovery request frame.
6158         //      2. Second information is the WPS configuration method which wants to discovery
6159         //      Format: 00:E0:4C:00:00:05_display
6160         //      Format: 00:E0:4C:00:00:05_keypad
6161         //      Format: 00:E0:4C:00:00:05_pbc
6162         //      Format: 00:E0:4C:00:00:05_label
6163
6164         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6165
6166         if ( pwdinfo->p2p_state == P2P_STATE_NONE )
6167         {
6168                 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
6169                 return ret;
6170         }
6171         else
6172         {
6173 #ifdef CONFIG_INTEL_WIDI
6174                 if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE){
6175                         DBG_871X( "[%s] WiFi is under survey!\n", __FUNCTION__ );
6176                         return ret;
6177                 }
6178 #endif //CONFIG_INTEL_WIDI
6179
6180                 //      Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request.
6181                 _rtw_memset( pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN );
6182                 _rtw_memset( pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN );
6183                 _rtw_memset( &pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof( NDIS_802_11_SSID ) );              
6184                 pwdinfo->tx_prov_disc_info.peer_channel_num[ 0 ] = 0;
6185                 pwdinfo->tx_prov_disc_info.peer_channel_num[ 1 ] = 0;
6186                 pwdinfo->tx_prov_disc_info.benable = _FALSE;
6187         }
6188         
6189         for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
6190         {
6191                 peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
6192         }
6193
6194         if ( _rtw_memcmp( &extra[ 18 ], "display", 7 ) )
6195         {
6196                 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
6197         }
6198         else if ( _rtw_memcmp( &extra[ 18 ], "keypad", 7 ) )
6199         {
6200                 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
6201         }
6202         else if ( _rtw_memcmp( &extra[ 18 ], "pbc", 3 ) )
6203         {
6204                 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
6205         }
6206         else if ( _rtw_memcmp( &extra[ 18 ], "label", 5 ) )
6207         {
6208                 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
6209         }
6210         else
6211         {
6212                 DBG_871X( "[%s] Unknown WPS config methodn", __FUNCTION__ );
6213                 return( ret );
6214         }
6215
6216         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
6217
6218         phead = get_list_head(queue);
6219         plist = get_next(phead);
6220        
6221         while(1)
6222         {
6223                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
6224                         break;
6225
6226                 if( uintPeerChannel != 0 )
6227                         break;
6228
6229                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
6230
6231                 //      Commented by Albert 2011/05/18
6232                 //      Match the device address located in the P2P IE
6233                 //      This is for the case that the P2P device address is not the same as the P2P interface address.
6234
6235                 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);
6236                 if ( (p2pie=rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
6237                 {
6238                         while ( p2pie )
6239                         {
6240                                 //      The P2P Device ID attribute is included in the Beacon frame.
6241                                 //      The P2P Device Info attribute is included in the probe response frame.
6242
6243                                 if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
6244                                 {
6245                                         //      Handle the P2P Device ID attribute of Beacon first
6246                                         if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
6247                                         {
6248                                                 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6249                                                 break;
6250                                         }
6251                                 }
6252                                 else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
6253                                 {
6254                                         //      Handle the P2P Device Info attribute of probe response
6255                                         if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
6256                                         {
6257                                                 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6258                                                 break;
6259                                         }                                       
6260                                 }
6261
6262                                 //Get the next P2P IE
6263                                 p2pie = rtw_get_p2p_ie(p2pie+p2pielen, pnetwork->network.IELength - ie_offset -(p2pie -&pnetwork->network.IEs[ie_offset] + p2pielen), NULL, &p2pielen);
6264                         }
6265
6266                 }
6267
6268 #ifdef CONFIG_INTEL_WIDI
6269                 // Some Intel WiDi source may not provide P2P IE, 
6270                 // so we could only compare mac addr by 802.11 Source Address
6271                 if( pmlmepriv->widi_state == INTEL_WIDI_STATE_WFD_CONNECTION 
6272                         && uintPeerChannel == 0 )
6273                 {
6274                         if ( _rtw_memcmp( pnetwork->network.MacAddress, peerMAC, ETH_ALEN ) )
6275                         {
6276                                 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6277                                 break;
6278                         }
6279                 }
6280 #endif //CONFIG_INTEL_WIDI
6281
6282                 plist = get_next(plist);
6283         
6284         }
6285
6286         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
6287
6288         if ( uintPeerChannel )
6289         {
6290 #ifdef CONFIG_WFD
6291                 {
6292                         u8      wfd_ie[ 128 ] = { 0x00 };
6293                         uint    wfd_ielen = 0;
6294                         
6295                         if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength,  wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) )
6296                         {
6297                                 u8      wfd_devinfo[ 6 ] = { 0x00 };
6298                                 uint    wfd_devlen = 6;
6299
6300                                 DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ );
6301                                 if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) )
6302                                 {
6303                                         u16     wfd_devinfo_field = 0;
6304                                         
6305                                         //      Commented by Albert 20120319
6306                                         //      The first two bytes are the WFD device information field of WFD device information subelement.
6307                                         //      In big endian format.
6308                                         wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
6309                                         if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL )
6310                                         {
6311                                                 pwfd_info->peer_session_avail = _TRUE;
6312                                         }
6313                                         else
6314                                         {
6315                                                 pwfd_info->peer_session_avail = _FALSE;
6316                                         }
6317                                 }
6318                         }
6319                         
6320                         if ( _FALSE == pwfd_info->peer_session_avail )
6321                         {
6322                                 DBG_871X( "[%s] WFD Session not avaiable!\n", __FUNCTION__ );
6323                                 goto exit;
6324                         }
6325                 }
6326 #endif // CONFIG_WFD
6327                 
6328                 DBG_871X( "[%s] peer channel: %d!\n", __FUNCTION__, uintPeerChannel );
6329 #ifdef CONFIG_CONCURRENT_MODE
6330                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6331                 {
6332                         _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
6333                 }
6334 #endif // CONFIG_CONCURRENT_MODE
6335                 _rtw_memcpy( pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN );
6336                 _rtw_memcpy( pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN );
6337                 pwdinfo->tx_prov_disc_info.peer_channel_num[0] = ( u16 ) uintPeerChannel;
6338                 pwdinfo->tx_prov_disc_info.benable = _TRUE;
6339                 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6340                 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ);
6341
6342                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
6343                 {
6344                         _rtw_memcpy( &pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof( NDIS_802_11_SSID ) );
6345                 }
6346                 else if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
6347                 {
6348                         _rtw_memcpy( pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN );
6349                         pwdinfo->tx_prov_disc_info.ssid.SsidLength= P2P_WILDCARD_SSID_LEN;
6350                 }
6351
6352 #ifdef CONFIG_CONCURRENT_MODE
6353                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6354                 {
6355                         //      Have to enter the power saving with the AP
6356                         set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
6357                         
6358                         issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
6359                 }
6360                 else
6361                 {
6362                         set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
6363                 }
6364 #else
6365                 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
6366 #endif
6367
6368                 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
6369                 
6370 #ifdef CONFIG_CONCURRENT_MODE
6371                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6372                 {
6373                         _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_PROVISION_TIMEOUT );
6374                 }
6375                 else
6376                 {
6377                         _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6378                 }
6379 #else
6380                 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6381 #endif // CONFIG_CONCURRENT_MODE                
6382                 
6383         }
6384         else
6385         {
6386                 DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ );
6387 #ifdef CONFIG_INTEL_WIDI
6388                 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
6389                 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
6390                 rtw_free_network_queue(padapter, _TRUE);                
6391                 _enter_critical_bh(&pmlmepriv->lock, &irqL);                            
6392                 rtw_sitesurvey_cmd(padapter, NULL, 0, NULL, 0);
6393                 _exit_critical_bh(&pmlmepriv->lock, &irqL);
6394 #endif //CONFIG_INTEL_WIDI
6395         }
6396 exit:
6397         
6398         return ret;
6399                 
6400 }
6401
6402 //      Added by Albert 20110328
6403 //      This function is used to inform the driver the user had specified the pin code value or pbc
6404 //      to application.
6405
6406 static int rtw_p2p_got_wpsinfo(struct net_device *dev,
6407                                struct iw_request_info *info,
6408                                union iwreq_data *wrqu, char *extra)
6409 {
6410         
6411         int ret = 0;    
6412         _adapter                                *padapter = (_adapter *)rtw_netdev_priv(dev);   
6413         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
6414         
6415
6416         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6417         //      Added by Albert 20110328
6418         //      if the input data is P2P_NO_WPSINFO -> reset the wpsinfo
6419         //      if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device.
6420         //      if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself.
6421         //      if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC
6422         
6423         if ( *extra == '0' )
6424         {
6425                 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
6426         }
6427         else if ( *extra == '1' )
6428         {
6429                 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN;
6430         }
6431         else if ( *extra == '2' )
6432         {
6433                 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN;
6434         }
6435         else if ( *extra == '3' )
6436         {
6437                 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC;
6438         }
6439         else
6440         {
6441                 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
6442         }
6443         
6444         return ret;
6445                 
6446 }
6447
6448 #endif //CONFIG_P2P
6449
6450 static int rtw_p2p_set(struct net_device *dev,
6451                                struct iw_request_info *info,
6452                                union iwreq_data *wrqu, char *extra)
6453 {
6454         
6455         int ret = 0;
6456 #ifdef CONFIG_P2P
6457
6458         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6459         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
6460         struct iw_point *pdata = &wrqu->data;
6461         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
6462         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
6463
6464         DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra );
6465
6466         if ( _rtw_memcmp( extra, "enable=", 7 ) )
6467         {
6468                 rtw_wext_p2p_enable( dev, info, wrqu, &extra[7] );
6469         }
6470         else if ( _rtw_memcmp( extra, "setDN=", 6 ) )
6471         {
6472                 wrqu->data.length -= 6;
6473                 rtw_p2p_setDN( dev, info, wrqu, &extra[6] );
6474         }
6475         else if ( _rtw_memcmp( extra, "profilefound=", 13 ) )
6476         {
6477                 wrqu->data.length -= 13;
6478                 rtw_p2p_profilefound( dev, info, wrqu, &extra[13] );
6479         }
6480         else if ( _rtw_memcmp( extra, "prov_disc=", 10 ) )
6481         {
6482                 wrqu->data.length -= 10;
6483                 rtw_p2p_prov_disc( dev, info, wrqu, &extra[10] );
6484         }
6485         else if ( _rtw_memcmp( extra, "nego=", 5 ) )
6486         {
6487                 wrqu->data.length -= 5;
6488                 rtw_p2p_connect( dev, info, wrqu, &extra[5] );
6489         }
6490         else if ( _rtw_memcmp( extra, "intent=", 7 ) )
6491         {
6492                 //      Commented by Albert 2011/03/23
6493                 //      The wrqu->data.length will include the null character
6494                 //      So, we will decrease 7 + 1
6495                 wrqu->data.length -= 8;
6496                 rtw_p2p_set_intent( dev, info, wrqu, &extra[7] );
6497         }
6498         else if ( _rtw_memcmp( extra, "ssid=", 5 ) )
6499         {
6500                 wrqu->data.length -= 5;
6501                 rtw_p2p_set_go_nego_ssid( dev, info, wrqu, &extra[5] );
6502         }
6503         else if ( _rtw_memcmp( extra, "got_wpsinfo=", 12 ) )
6504         {
6505                 wrqu->data.length -= 12;
6506                 rtw_p2p_got_wpsinfo( dev, info, wrqu, &extra[12] );
6507         }
6508         else if ( _rtw_memcmp( extra, "listen_ch=", 10 ) )
6509         {
6510                 //      Commented by Albert 2011/05/24
6511                 //      The wrqu->data.length will include the null character
6512                 //      So, we will decrease (10 + 1)   
6513                 wrqu->data.length -= 11;
6514                 rtw_p2p_set_listen_ch( dev, info, wrqu, &extra[10] );
6515         }
6516         else if ( _rtw_memcmp( extra, "op_ch=", 6 ) )
6517         {
6518                 //      Commented by Albert 2011/05/24
6519                 //      The wrqu->data.length will include the null character
6520                 //      So, we will decrease (6 + 1)    
6521                 wrqu->data.length -= 7;
6522                 rtw_p2p_set_op_ch( dev, info, wrqu, &extra[6] );
6523         }
6524         else if ( _rtw_memcmp( extra, "invite=", 7 ) )
6525         {
6526                 wrqu->data.length -= 8;
6527                 rtw_p2p_invite_req( dev, info, wrqu, &extra[7] );
6528         }
6529         else if ( _rtw_memcmp( extra, "persistent=", 11 ) )
6530         {
6531                 wrqu->data.length -= 11;
6532                 rtw_p2p_set_persistent( dev, info, wrqu, &extra[11] );
6533         }
6534         else if ( _rtw_memcmp ( extra, "uuid=", 5) )
6535         {
6536                 wrqu->data.length -= 5;
6537                 ret = rtw_p2p_set_wps_uuid( dev, info, wrqu, &extra[5] );
6538         }
6539 #ifdef CONFIG_WFD
6540         else if ( _rtw_memcmp( extra, "sa=", 3 ) )
6541         {
6542                 //      sa: WFD Session Available information
6543                 wrqu->data.length -= 3;
6544                 rtw_p2p_set_sa( dev, info, wrqu, &extra[3] );
6545         }
6546         else if ( _rtw_memcmp( extra, "pc=", 3 ) )
6547         {
6548                 //      pc: WFD Preferred Connection
6549                 wrqu->data.length -= 3;
6550                 rtw_p2p_set_pc( dev, info, wrqu, &extra[3] );
6551         }
6552         else if ( _rtw_memcmp( extra, "wfd_type=", 9 ) )
6553         {
6554                 //      pc: WFD Preferred Connection
6555                 wrqu->data.length -= 9;
6556                 rtw_p2p_set_wfd_device_type( dev, info, wrqu, &extra[9] );
6557         }
6558         else if ( _rtw_memcmp( extra, "wfd_enable=", 11 ) )
6559         {
6560                 wrqu->data.length -= 11;
6561                 rtw_p2p_set_wfd_enable( dev, info, wrqu, &extra[11] );
6562         }
6563         else if ( _rtw_memcmp( extra, "driver_iface=", 13 ) )
6564         {
6565                 wrqu->data.length -= 13;
6566                 rtw_p2p_set_driver_iface( dev, info, wrqu, &extra[13] );
6567         }
6568 #endif //CONFIG_WFD
6569
6570 #endif //CONFIG_P2P
6571
6572         return ret;
6573                 
6574 }
6575
6576 static int rtw_p2p_get(struct net_device *dev,
6577                                struct iw_request_info *info,
6578                                union iwreq_data *wrqu, char *extra)
6579 {
6580         
6581         int ret = 0;    
6582         
6583 #ifdef CONFIG_P2P
6584
6585         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6586         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
6587         struct iw_point *pdata = &wrqu->data;
6588         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
6589         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
6590
6591         if ( padapter->bShowGetP2PState )
6592         {
6593                 DBG_871X( "[%s] extra = %s\n", __FUNCTION__, (char*) wrqu->data.pointer );
6594         }
6595
6596         if ( _rtw_memcmp( wrqu->data.pointer, "status", 6 ) )
6597         {
6598                 rtw_p2p_get_status( dev, info, wrqu, extra );
6599         }
6600         else if ( _rtw_memcmp( wrqu->data.pointer, "role", 4 ) )
6601         {
6602                 rtw_p2p_get_role( dev, info, wrqu, extra);
6603         }
6604         else if ( _rtw_memcmp( wrqu->data.pointer, "peer_ifa", 8 ) )
6605         {
6606                 rtw_p2p_get_peer_ifaddr( dev, info, wrqu, extra);
6607         }
6608         else if ( _rtw_memcmp( wrqu->data.pointer, "req_cm", 6 ) )
6609         {
6610                 rtw_p2p_get_req_cm( dev, info, wrqu, extra);
6611         }
6612         else if ( _rtw_memcmp( wrqu->data.pointer, "peer_deva", 9 ) )
6613         {
6614                 //      Get the P2P device address when receiving the provision discovery request frame.
6615                 rtw_p2p_get_peer_devaddr( dev, info, wrqu, extra);
6616         }
6617         else if ( _rtw_memcmp( wrqu->data.pointer, "group_id", 8 ) )
6618         {
6619                 rtw_p2p_get_groupid( dev, info, wrqu, extra);
6620         }
6621         else if ( _rtw_memcmp( wrqu->data.pointer, "inv_peer_deva", 13 ) )
6622         {
6623                 //      Get the P2P device address when receiving the P2P Invitation request frame.
6624                 rtw_p2p_get_peer_devaddr_by_invitation( dev, info, wrqu, extra);
6625         }
6626         else if ( _rtw_memcmp( wrqu->data.pointer, "op_ch", 5 ) )
6627         {
6628                 rtw_p2p_get_op_ch( dev, info, wrqu, extra);
6629         }
6630 #ifdef CONFIG_WFD
6631         else if ( _rtw_memcmp( wrqu->data.pointer, "peer_port", 9 ) )
6632         {
6633                 rtw_p2p_get_peer_wfd_port( dev, info, wrqu, extra );
6634         }
6635         else if ( _rtw_memcmp( wrqu->data.pointer, "wfd_sa", 6 ) )
6636         {
6637                 rtw_p2p_get_peer_wfd_session_available( dev, info, wrqu, extra );
6638         }
6639         else if ( _rtw_memcmp( wrqu->data.pointer, "wfd_pc", 6 ) )
6640         {
6641                 rtw_p2p_get_peer_wfd_preferred_connection( dev, info, wrqu, extra );
6642         }
6643 #endif // CONFIG_WFD    
6644         
6645 #endif //CONFIG_P2P
6646
6647         return ret;
6648                 
6649 }
6650
6651 static int rtw_p2p_get2(struct net_device *dev,
6652                                                 struct iw_request_info *info,
6653                                                 union iwreq_data *wrqu, char *extra)
6654 {
6655
6656         int ret = 0;
6657
6658 #ifdef CONFIG_P2P
6659
6660         int length = wrqu->data.length;
6661         char *buffer = (u8 *)rtw_malloc(length);
6662
6663         if (buffer == NULL)
6664         {
6665                 ret = -ENOMEM;
6666                 goto bad;
6667         }
6668
6669         if (copy_from_user(buffer, wrqu->data.pointer, wrqu->data.length))
6670         {
6671                 ret - EFAULT;
6672                 goto bad;
6673         }
6674
6675         DBG_871X("[%s] buffer = %s\n", __FUNCTION__, buffer);
6676
6677         if (_rtw_memcmp(buffer, "wpsCM=", 6))
6678         {
6679                 ret = rtw_p2p_get_wps_configmethod(dev, info, wrqu, extra, &buffer[6]);
6680         } else if (_rtw_memcmp(buffer, "devN=", 5))
6681         {
6682                 ret = rtw_p2p_get_device_name(dev, info, wrqu, extra, &buffer[5]);
6683         } else if (_rtw_memcmp(buffer, "dev_type=", 9))
6684         {
6685                 ret = rtw_p2p_get_device_type(dev, info, wrqu, extra, &buffer[9]);
6686         } else if (_rtw_memcmp(buffer, "go_devadd=", 10))
6687         {
6688                 ret = rtw_p2p_get_go_device_address(dev, info, wrqu, extra, &buffer[10]);
6689         } else if (_rtw_memcmp(buffer, "InvProc=", 8))
6690         {
6691                 ret = rtw_p2p_get_invitation_procedure(dev, info, wrqu, extra, &buffer[8]);
6692         } else
6693         {
6694                 snprintf(extra, sizeof("Command not found."), "Command not found.");
6695                 wrqu->data.length = strlen(extra);
6696         }
6697
6698 bad:
6699         if (buffer)
6700         {
6701                 rtw_mfree(buffer, length);
6702         }
6703
6704 #endif //CONFIG_P2P
6705
6706         return ret;
6707
6708 }
6709
6710 static int rtw_cta_test_start(struct net_device *dev,
6711                                                            struct iw_request_info *info,
6712                                                            union iwreq_data *wrqu, char *extra)
6713 {
6714         int ret = 0;
6715         _adapter        *padapter = (_adapter *)rtw_netdev_priv(dev);
6716         DBG_871X("%s %s\n", __func__, extra);
6717         if (!strcmp(extra, "1"))
6718                 padapter->in_cta_test = 1;
6719         else
6720                 padapter->in_cta_test = 0;
6721
6722         if(padapter->in_cta_test)
6723         {
6724                 u32 v = rtw_read32(padapter, REG_RCR);
6725                 v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN );//| RCR_ADF
6726                 rtw_write32(padapter, REG_RCR, v);
6727                 DBG_871X("enable RCR_ADF\n");
6728         }
6729         else
6730         {
6731                 u32 v = rtw_read32(padapter, REG_RCR);
6732                 v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN ;//| RCR_ADF
6733                 rtw_write32(padapter, REG_RCR, v);
6734                 DBG_871X("disable RCR_ADF\n");
6735         }
6736         return ret;
6737 }
6738
6739
6740 extern int rtw_change_ifname(_adapter *padapter, const char *ifname);
6741 static int rtw_rereg_nd_name(struct net_device *dev,
6742                                struct iw_request_info *info,
6743                                union iwreq_data *wrqu, char *extra)
6744 {
6745         int ret = 0;    
6746         _adapter *padapter = rtw_netdev_priv(dev);
6747         struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;
6748         char new_ifname[IFNAMSIZ];
6749
6750         if(rereg_priv->old_ifname[0] == 0) {
6751                 char *reg_ifname;
6752 #ifdef CONFIG_CONCURRENT_MODE 
6753                 if (padapter->isprimary)
6754                         reg_ifname = padapter->registrypriv.ifname;
6755                 else
6756 #endif
6757                 reg_ifname = padapter->registrypriv.if2name;
6758
6759                 strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);
6760                 rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
6761         }
6762
6763         //DBG_871X("%s wrqu->data.length:%d\n", __FUNCTION__, wrqu->data.length);
6764         if(wrqu->data.length > IFNAMSIZ)
6765                 return -EFAULT;
6766
6767         if ( copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ) ) {
6768                 return -EFAULT;
6769         }
6770
6771         if( 0 == strcmp(rereg_priv->old_ifname, new_ifname) ) {
6772                 return ret;
6773         }
6774
6775         DBG_871X("%s new_ifname:%s\n", __FUNCTION__, new_ifname);
6776         if( 0 != (ret = rtw_change_ifname(padapter, new_ifname)) ) {
6777                 goto exit;
6778         }
6779
6780         if(_rtw_memcmp(rereg_priv->old_ifname, "disable%d", 9) == _TRUE) {
6781                 padapter->ledpriv.bRegUseLed= rereg_priv->old_bRegUseLed;
6782                 rtw_hal_sw_led_init(padapter);
6783                 //rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode);
6784         }
6785
6786         strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
6787         rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
6788         
6789         if(_rtw_memcmp(new_ifname, "disable%d", 9) == _TRUE) {
6790
6791                 DBG_871X("%s disable\n", __FUNCTION__);
6792                 // free network queue for Android's timming issue
6793                 rtw_free_network_queue(padapter, _TRUE);
6794                 
6795                 // close led
6796                 rtw_led_control(padapter, LED_CTL_POWER_OFF);
6797                 rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed;
6798                 padapter->ledpriv.bRegUseLed= _FALSE;
6799                 rtw_hal_sw_led_deinit(padapter);
6800                 
6801                 // the interface is being "disabled", we can do deeper IPS
6802                 //rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv);
6803                 //rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL);
6804         }
6805 exit:
6806         return ret;
6807
6808 }
6809
6810 #ifdef CONFIG_IOL
6811 #include <rtw_iol.h>
6812 #endif
6813 static int rtw_dbg_port(struct net_device *dev,
6814                                struct iw_request_info *info,
6815                                union iwreq_data *wrqu, char *extra)
6816 {       
6817         _irqL irqL;
6818         int ret = 0;
6819         u8 major_cmd, minor_cmd;
6820         u16 arg;
6821         u32 extra_arg, *pdata, val32;
6822         struct sta_info *psta;                                          
6823         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6824         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6825         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
6826         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
6827         struct security_priv *psecuritypriv = &padapter->securitypriv;
6828         struct wlan_network *cur_network = &(pmlmepriv->cur_network);
6829         struct sta_priv *pstapriv = &padapter->stapriv;
6830         
6831
6832         pdata = (u32*)&wrqu->data;      
6833
6834         val32 = *pdata;
6835         arg = (u16)(val32&0x0000ffff);
6836         major_cmd = (u8)(val32>>24);
6837         minor_cmd = (u8)((val32>>16)&0x00ff);
6838
6839         extra_arg = *(pdata+1);
6840         
6841         switch(major_cmd)
6842         {
6843                 case 0x70://read_reg
6844                         switch(minor_cmd)
6845                         {
6846                                 case 1:
6847                                         DBG_871X("rtw_read8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
6848                                         break;
6849                                 case 2:
6850                                         DBG_871X("rtw_read16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
6851                                         break;
6852                                 case 4:
6853                                         DBG_871X("rtw_read32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
6854                                         break;
6855                         }                       
6856                         break;
6857                 case 0x71://write_reg
6858                         switch(minor_cmd)
6859                         {
6860                                 case 1:
6861                                         rtw_write8(padapter, arg, extra_arg);
6862                                         DBG_871X("rtw_write8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
6863                                         break;
6864                                 case 2:
6865                                         rtw_write16(padapter, arg, extra_arg);
6866                                         DBG_871X("rtw_write16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
6867                                         break;
6868                                 case 4:
6869                                         rtw_write32(padapter, arg, extra_arg);
6870                                         DBG_871X("rtw_write32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
6871                                         break;
6872                         }                       
6873                         break;
6874                 case 0x72://read_bb
6875                         DBG_871X("read_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
6876                         break;
6877                 case 0x73://write_bb
6878                         rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);
6879                         DBG_871X("write_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
6880                         break;
6881                 case 0x74://read_rf
6882                         DBG_871X("read RF_reg path(0x%02x),offset(0x%x),value(0x%08x)\n",minor_cmd,arg,rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff));       
6883                         break;
6884                 case 0x75://write_rf
6885                         rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
6886                         DBG_871X("write RF_reg path(0x%02x),offset(0x%x),value(0x%08x)\n",minor_cmd,arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff));
6887                         break;  
6888
6889                 case 0x76:
6890                         switch(minor_cmd)
6891                         {
6892                                 case 0x00: //normal mode, 
6893                                         padapter->recvpriv.is_signal_dbg = 0;
6894                                         break;
6895                                 case 0x01: //dbg mode
6896                                         padapter->recvpriv.is_signal_dbg = 1;
6897                                         extra_arg = extra_arg>100?100:extra_arg;
6898                                         extra_arg = extra_arg<0?0:extra_arg;
6899                                         padapter->recvpriv.signal_strength_dbg=extra_arg;
6900                                         break;
6901                         }
6902                         break;
6903                 case 0x78: //IOL test
6904                         switch(minor_cmd)
6905                         {
6906                                 #ifdef CONFIG_IOL
6907                                 case 0x04: //LLT table initialization test
6908                                 {
6909                                         u8 page_boundary = 0xf9;
6910                                         {
6911                                                 struct xmit_frame       *xmit_frame;
6912
6913                                                 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6914                                                         ret = -ENOMEM;  
6915                                                         break;
6916                                                 }
6917                                                 
6918                                                 rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary);
6919
6920
6921                                                 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500,0) )
6922                                                         ret = -EPERM;
6923                                         }
6924                                 }
6925                                         break;
6926                                 case 0x05: //blink LED test
6927                                 {
6928                                         u16 reg = 0x4c;
6929                                         u32 blink_num = 50;
6930                                         u32 blink_delay_ms = 200;
6931                                         int i;
6932                                         
6933                                         {
6934                                                 struct xmit_frame       *xmit_frame;
6935
6936                                                 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6937                                                         ret = -ENOMEM;  
6938                                                         break;
6939                                                 }
6940
6941                                                 for(i=0;i<blink_num;i++){
6942                                                         #ifdef CONFIG_IOL_NEW_GENERATION
6943                                                         rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00,0xff);
6944                                                         rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6945                                                         rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08,0xff);
6946                                                         rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6947                                                         #else
6948                                                         rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00);
6949                                                         rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6950                                                         rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08);
6951                                                         rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6952                                                         #endif
6953                                                 }
6954                                                 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms*blink_num*2)+200,0) )
6955                                                         ret = -EPERM;
6956                                         }
6957                                 }
6958                                         break;
6959                                         
6960                                 case 0x06: //continuous wirte byte test
6961                                 {
6962                                         u16 reg = arg;
6963                                         u16 start_value = 0;
6964                                         u32 write_num = extra_arg;
6965                                         int i;
6966                                         u8 final;
6967                                         
6968                                         {
6969                                                 struct xmit_frame       *xmit_frame;
6970
6971                                                 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6972                                                         ret = -ENOMEM;  
6973                                                         break;
6974                                                 }
6975
6976                                                 for(i=0;i<write_num;i++){
6977                                                         #ifdef CONFIG_IOL_NEW_GENERATION
6978                                                         rtw_IOL_append_WB_cmd(xmit_frame, reg, i+start_value,0xFF);
6979                                                         #else
6980                                                         rtw_IOL_append_WB_cmd(xmit_frame, reg, i+start_value);
6981                                                         #endif
6982                                                 }
6983                                                 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
6984                                                         ret = -EPERM;
6985                                         }
6986
6987                                         if(start_value+write_num-1 == (final=rtw_read8(padapter, reg)) ) {
6988                                                 DBG_871X("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6989                                         } else {
6990                                                 DBG_871X("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6991                                         }
6992                                 }
6993                                         break;
6994                                         
6995                                 case 0x07: //continuous wirte word test
6996                                 {
6997                                         u16 reg = arg;
6998                                         u16 start_value = 200;
6999                                         u32 write_num = extra_arg;
7000                                 
7001                                         int i;
7002                                         u16 final;
7003
7004                                         {
7005                                                 struct xmit_frame       *xmit_frame;
7006
7007                                                 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
7008                                                         ret = -ENOMEM;  
7009                                                         break;
7010                                                 }
7011
7012                                                 for(i=0;i<write_num;i++){
7013                                                         #ifdef CONFIG_IOL_NEW_GENERATION
7014                                                         rtw_IOL_append_WW_cmd(xmit_frame, reg, i+start_value,0xFFFF);
7015                                                         #else
7016                                                         rtw_IOL_append_WW_cmd(xmit_frame, reg, i+start_value);
7017                                                         #endif
7018                                                 }
7019                                                 if(_SUCCESS !=rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
7020                                                         ret = -EPERM;
7021                                         }
7022
7023                                         if(start_value+write_num-1 == (final=rtw_read16(padapter, reg)) ) {
7024                                                 DBG_871X("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
7025                                         } else {
7026                                                 DBG_871X("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
7027                                         }
7028                                 }
7029                                         break;
7030                                         
7031                                 case 0x08: //continuous wirte dword test
7032                                 {
7033                                         u16 reg = arg;
7034                                         u32 start_value = 0x110000c7;
7035                                         u32 write_num = extra_arg;
7036                                 
7037                                         int i;
7038                                         u32 final;
7039
7040                                         {
7041                                                 struct xmit_frame       *xmit_frame;
7042
7043                                                 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
7044                                                         ret = -ENOMEM;  
7045                                                         break;
7046                                                 }
7047
7048                                                 for(i=0;i<write_num;i++){
7049                                                         #ifdef CONFIG_IOL_NEW_GENERATION
7050                                                         rtw_IOL_append_WD_cmd(xmit_frame, reg, i+start_value,0xFFFFFFFF);
7051                                                         #else
7052                                                         rtw_IOL_append_WD_cmd(xmit_frame, reg, i+start_value);
7053                                                         #endif
7054                                                 }
7055                                                 if(_SUCCESS !=rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
7056                                                         ret = -EPERM;
7057                                                         
7058                                         }
7059
7060                                         if(start_value+write_num-1 == (final=rtw_read32(padapter, reg)) ) {
7061                                                 DBG_871X("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
7062                                         } else {
7063                                                 DBG_871X("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
7064                                         }
7065                                 }
7066                                         break;
7067                                 #endif //CONFIG_IOL
7068                         }
7069                         break;
7070                 case 0x79:
7071                         {
7072                                 /*
7073                                 * dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15
7074                                 * dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15
7075                                 */
7076                                 u8 value =  extra_arg & 0x0f;
7077                                 u8 sign = minor_cmd;
7078                                 u16 write_value = 0;
7079
7080                                 DBG_871X("%s set RESP_TXAGC to %s %u\n", __func__, sign?"minus":"plus", value);
7081
7082                                 if (sign)
7083                                         value = value | 0x10;
7084
7085                                 write_value = value | (value << 5);
7086                                 rtw_write16(padapter, 0x6d9, write_value);
7087                         }
7088                         break;
7089                 case 0x7a:
7090                         receive_disconnect(padapter, pmlmeinfo->network.MacAddress
7091                                 , WLAN_REASON_EXPIRATION_CHK);
7092                         break;
7093                 case 0x7F:
7094                         switch(minor_cmd)
7095                         {
7096                                 case 0x0:
7097                                         DBG_871X("fwstate=0x%x\n", get_fwstate(pmlmepriv));
7098                                         break;
7099                                 case 0x01:
7100                                         DBG_871X("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", 
7101                                                 psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
7102                                                 psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
7103                                         break;
7104                                 case 0x02:
7105                                         DBG_871X("pmlmeinfo->state=0x%x\n", pmlmeinfo->state);
7106                                         DBG_871X("DrvBcnEarly=%d\n", pmlmeext->DrvBcnEarly);
7107                                         DBG_871X("DrvBcnTimeOut=%d\n", pmlmeext->DrvBcnTimeOut);
7108                                         break;
7109                                 case 0x03:
7110                                         DBG_871X("qos_option=%d\n", pmlmepriv->qospriv.qos_option);
7111 #ifdef CONFIG_80211N_HT
7112                                         DBG_871X("ht_option=%d\n", pmlmepriv->htpriv.ht_option);
7113 #endif //CONFIG_80211N_HT
7114                                         break;
7115                                 case 0x04:
7116                                         DBG_871X("cur_ch=%d\n", pmlmeext->cur_channel);
7117                                         DBG_871X("cur_bw=%d\n", pmlmeext->cur_bwmode);
7118                                         DBG_871X("cur_ch_off=%d\n", pmlmeext->cur_ch_offset);
7119
7120                                         DBG_871X("oper_ch=%d\n", rtw_get_oper_ch(padapter));
7121                                         DBG_871X("oper_bw=%d\n", rtw_get_oper_bw(padapter));
7122                                         DBG_871X("oper_ch_offet=%d\n", rtw_get_oper_choffset(padapter));
7123                                 
7124                                         break;
7125                                 case 0x05:
7126                                         psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
7127                                         if(psta)
7128                                         {
7129                                                 int i;
7130                                                 struct recv_reorder_ctrl *preorder_ctrl;
7131                                         
7132                                                 DBG_871X("SSID=%s\n", cur_network->network.Ssid.Ssid);
7133                                                 DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
7134                                                 DBG_871X("cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
7135                                                 DBG_871X("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
7136                                                 DBG_871X("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
7137 #ifdef CONFIG_80211N_HT
7138                                                 DBG_871X("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
7139                                                 DBG_871X("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m);
7140                                                 DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);     
7141                                                 DBG_871X("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
7142 #endif //CONFIG_80211N_HT
7143                                                 
7144                                                 for(i=0;i<16;i++)
7145                                                 {                                                       
7146                                                         preorder_ctrl = &psta->recvreorder_ctrl[i];
7147                                                         if(preorder_ctrl->enable)
7148                                                         {
7149                                                                 DBG_871X("tid=%d, indicate_seq=%d\n", i, preorder_ctrl->indicate_seq);
7150                                                         }
7151                                                 }       
7152                                                         
7153                                         }
7154                                         else
7155                                         {                                                       
7156                                                 DBG_871X("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));
7157                                         }                                       
7158                                         break;
7159                                 case 0x06:
7160                                         {
7161                                                 u32     ODMFlag;
7162                                                 rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8*)(&ODMFlag));
7163                                                 DBG_871X("(B)DMFlag=0x%x, arg=0x%x\n", ODMFlag, arg);
7164                                                 ODMFlag = (u32)(0x0f&arg);
7165                                                 DBG_871X("(A)DMFlag=0x%x\n", ODMFlag);
7166                                                 rtw_hal_set_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
7167                                         }
7168                                         break;
7169                                 case 0x07:
7170                                         DBG_871X("bSurpriseRemoved=%d, bDriverStopped=%d\n", 
7171                                                 padapter->bSurpriseRemoved, padapter->bDriverStopped);
7172                                         break;
7173                                 case 0x08:
7174                                         {
7175                                                 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7176                                                 struct recv_priv  *precvpriv = &padapter->recvpriv;
7177                                                 
7178                                                 DBG_871X("free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d"
7179                                                         ", free_xmit_extbuf_cnt=%d, free_xframe_ext_cnt=%d"
7180                                                         ", free_recvframe_cnt=%d\n",
7181                                                         pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt,
7182                                                         pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt,
7183                                                         precvpriv->free_recvframe_cnt);
7184                                                 #ifdef CONFIG_USB_HCI
7185                                                 DBG_871X("rx_urb_pending_cn=%d\n", precvpriv->rx_pending_cnt);
7186                                                 #endif
7187                                         }
7188                                         break;  
7189                                 case 0x09:
7190                                         {
7191                                                 int i, j;
7192                                                 _list   *plist, *phead;
7193                                                 struct recv_reorder_ctrl *preorder_ctrl;
7194                                                 
7195 #ifdef CONFIG_AP_MODE
7196                                                 DBG_871X("sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
7197 #endif                                          
7198                                                 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
7199
7200                                                 for(i=0; i< NUM_STA; i++)
7201                                                 {
7202                                                         phead = &(pstapriv->sta_hash[i]);
7203                                                         plist = get_next(phead);
7204                 
7205                                                         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
7206                                                         {
7207                                                                 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
7208
7209                                                                 plist = get_next(plist);
7210
7211                                                                 if(extra_arg == psta->aid)
7212                                                                 {
7213                                                                         DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
7214                                                                         DBG_871X("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
7215                                                                         DBG_871X("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
7216 #ifdef CONFIG_80211N_HT
7217                                                                         DBG_871X("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);     
7218                                                                         DBG_871X("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m);
7219                                                                         DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);                                                                     
7220                                                                         DBG_871X("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
7221 #endif //CONFIG_80211N_HT
7222                                                                         
7223 #ifdef CONFIG_AP_MODE
7224                                                                         DBG_871X("capability=0x%x\n", psta->capability);
7225                                                                         DBG_871X("flags=0x%x\n", psta->flags);
7226                                                                         DBG_871X("wpa_psk=0x%x\n", psta->wpa_psk);
7227                                                                         DBG_871X("wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher);
7228                                                                         DBG_871X("wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher);
7229                                                                         DBG_871X("qos_info=0x%x\n", psta->qos_info);
7230 #endif
7231                                                                         DBG_871X("dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy);
7232                                                                         
7233                                                                         
7234                                                 
7235                                                                         for(j=0;j<16;j++)
7236                                                                         {                                                       
7237                                                                                 preorder_ctrl = &psta->recvreorder_ctrl[j];
7238                                                                                 if(preorder_ctrl->enable)
7239                                                                                 {
7240                                                                                         DBG_871X("tid=%d, indicate_seq=%d\n", j, preorder_ctrl->indicate_seq);
7241                                                                                 }
7242                                                                         }               
7243                                                                         
7244                                                                 }                                                       
7245                         
7246                                                         }
7247                                                 }
7248         
7249                                                 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
7250
7251                                         }
7252                                         break;
7253                                 case 0x0a:
7254                                         {
7255                                                 int max_mac_id = 0;
7256                                                 max_mac_id = rtw_search_max_mac_id( padapter);
7257                                                 printk("%s ==> max_mac_id = %d \n",__FUNCTION__,max_mac_id);
7258                                         }       
7259                                         break;
7260                                 case 0x0c://dump rx/tx packet
7261                                         {
7262                                                 if(arg == 0){
7263                                                         DBG_871X("dump rx packet (%d)\n",extra_arg);                                            
7264                                                         //pHalData->bDumpRxPkt =extra_arg;                                              
7265                                                         rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
7266                                                 }
7267                                                 else if(arg==1){
7268                                                         DBG_871X("dump tx packet (%d)\n",extra_arg);                                            
7269                                                         rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
7270                                                 }
7271                                         }
7272                                         break;
7273 #if 0                           
7274                                 case 0x0d://dump cam
7275                                         {
7276                                                 //u8 entry = (u8) extra_arg;
7277                                                 u8 entry=0;
7278                                                 //dump cam
7279                                                 for(entry=0;entry<32;entry++)
7280                                                         read_cam(padapter,entry);
7281                                         }                               
7282                                         break;
7283 #endif
7284                 #ifdef DBG_CONFIG_ERROR_DETECT
7285                                 case 0x0f:
7286                                                 {
7287                                                         if(extra_arg == 0){     
7288                                                                 DBG_871X("###### silent reset test.......#####\n");
7289                                                                 rtw_hal_sreset_reset(padapter);                                         
7290                                                         } else {
7291                                                                 HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
7292                                                                 struct sreset_priv *psrtpriv = &pHalData->srestpriv;
7293                                                                 psrtpriv->dbg_trigger_point = extra_arg;
7294                                                         }
7295                                                         
7296                                                 }
7297                                         break;
7298                                 case 0x15:
7299                                         {
7300                                                 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
7301                                                 DBG_871X("==>silent resete cnts:%d\n",pwrpriv->ips_enter_cnts);
7302                                         }
7303                                         break;  
7304                                         
7305                 #endif  
7306
7307                                 case 0x10:// driver version display
7308                                         dump_drv_version(RTW_DBGDUMP);
7309                                         break;
7310                                 case 0x11://dump linked status
7311                                         {
7312                                                  linked_info_dump(padapter,extra_arg);
7313                                         }                                       
7314                                         break;
7315 #ifdef CONFIG_80211N_HT
7316                                 case 0x12: //set rx_stbc
7317                                 {
7318                                         struct registry_priv    *pregpriv = &padapter->registrypriv;
7319                                         // 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g
7320                                         //default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ
7321                                         if( pregpriv && (extra_arg == 0 || extra_arg == 1|| extra_arg == 2 || extra_arg == 3))
7322                                         {
7323                                                 pregpriv->rx_stbc= extra_arg;
7324                                                 DBG_871X("set rx_stbc=%d\n",pregpriv->rx_stbc);
7325                                         }
7326                                         else
7327                                                 DBG_871X("get rx_stbc=%d\n",pregpriv->rx_stbc);
7328                                         
7329                                 }
7330                                 break;
7331                                 case 0x13: //set ampdu_enable
7332                                 {
7333                                         struct registry_priv    *pregpriv = &padapter->registrypriv;
7334                                         // 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec)
7335                                         if( pregpriv && extra_arg < 3 )
7336                                         {
7337                                                 pregpriv->ampdu_enable= extra_arg;
7338                                                 DBG_871X("set ampdu_enable=%d\n",pregpriv->ampdu_enable);
7339                                         }
7340                                         else
7341                                                 DBG_871X("get ampdu_enable=%d\n",pregpriv->ampdu_enable);
7342                                         
7343                                 }
7344                                 break;
7345 #endif
7346                                 case 0x14: //get wifi_spec
7347                                 {
7348                                         struct registry_priv    *pregpriv = &padapter->registrypriv;
7349                                         DBG_871X("get wifi_spec=%d\n",pregpriv->wifi_spec);
7350                                         
7351                                 }
7352                                 break;
7353                                 case 0x16:
7354                                 {
7355                                         if(arg == 0xff){
7356                                                 rtw_odm_dbg_comp_msg(RTW_DBGDUMP,padapter);
7357                                         }
7358                                         else{
7359                                                 u64 dbg_comp = (u64)extra_arg;
7360                                                 rtw_odm_dbg_comp_set(padapter, dbg_comp);
7361                                         }
7362                                 }
7363                                         break;
7364 #ifdef DBG_FIXED_CHAN
7365                                 case 0x17:
7366                                         {
7367                                                 struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);                                           
7368                                                 printk("===>  Fixed channel to %d \n",extra_arg);
7369                                                 pmlmeext->fixed_chan = extra_arg;       
7370                                                 
7371                                         }
7372                                         break;
7373 #endif
7374                                 case 0x18:
7375                                         {
7376                                                 printk("===>  Switch USB Mode %d \n",extra_arg);
7377                                                 rtw_hal_set_hwreg(padapter, HW_VAR_USB_MODE, (u8 *)&extra_arg);
7378                                         }
7379                                         break;
7380                                 case 0x23:
7381                                         {
7382                                                 DBG_871X("turn %s the bNotifyChannelChange Variable\n",(extra_arg==1)?"on":"off");
7383                                                 padapter->bNotifyChannelChange = extra_arg;
7384                                                 break;
7385                                         }
7386                                 case 0x24:
7387                                         {
7388 #ifdef CONFIG_P2P
7389                                                 DBG_871X("turn %s the bShowGetP2PState Variable\n",(extra_arg==1)?"on":"off");
7390                                                 padapter->bShowGetP2PState = extra_arg;
7391 #endif // CONFIG_P2P
7392                                                 break;                                          
7393                                         }
7394                                 case 0xaa:
7395                                         {
7396                                                 if((extra_arg & 0x7F)> 0x3F) extra_arg = 0xFF;
7397                                                 DBG_871X("chang data rate to :0x%02x\n",extra_arg);
7398                                                 padapter->fix_rate = extra_arg;
7399                                         }
7400                                         break;  
7401                                 case 0xdd://registers dump , 0 for mac reg,1 for bb reg, 2 for rf reg
7402                                         {
7403                                                 if(extra_arg==0){
7404                                                         mac_reg_dump(RTW_DBGDUMP, padapter);
7405                                                 }
7406                                                 else if(extra_arg==1){
7407                                                         bb_reg_dump(RTW_DBGDUMP, padapter);
7408                                                 }
7409                                                 else if(extra_arg==2){
7410                                                         rf_reg_dump(RTW_DBGDUMP, padapter);
7411                                                 }
7412                                         }
7413                                         break;          
7414
7415                                 case 0xee://turn on/off dynamic funcs
7416                                         {
7417                                                 u32 odm_flag;
7418
7419                                                 if(0xf==extra_arg){
7420                                                         rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&odm_flag);                                                   
7421                                                         DBG_871X(" === DMFlag(0x%08x) === \n",odm_flag);
7422                                                         DBG_871X("extra_arg = 0  - disable all dynamic func \n");
7423                                                         DBG_871X("extra_arg = 1  - disable DIG- BIT(0)\n");
7424                                                         DBG_871X("extra_arg = 2  - disable High power - BIT(1)\n");
7425                                                         DBG_871X("extra_arg = 3  - disable tx power tracking - BIT(2)\n");
7426                                                         DBG_871X("extra_arg = 4  - disable BT coexistence - BIT(3)\n");
7427                                                         DBG_871X("extra_arg = 5  - disable antenna diversity - BIT(4)\n");
7428                                                         DBG_871X("extra_arg = 6  - enable all dynamic func \n");                                                        
7429                                                 }
7430                                                 else{
7431                                                         /*      extra_arg = 0  - disable all dynamic func
7432                                                                 extra_arg = 1  - disable DIG
7433                                                                 extra_arg = 2  - disable tx power tracking
7434                                                                 extra_arg = 3  - turn on all dynamic func
7435                                                         */                      
7436                                                         rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &(extra_arg));
7437                                                         rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&odm_flag);                                                   
7438                                                         DBG_871X(" === DMFlag(0x%08x) === \n",odm_flag);
7439                                                 }
7440                                         }
7441                                         break;
7442
7443                                 case 0xfd:
7444                                         rtw_write8(padapter, 0xc50, arg);
7445                                         DBG_871X("wr(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
7446                                         rtw_write8(padapter, 0xc58, arg);
7447                                         DBG_871X("wr(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
7448                                         break;
7449                                 case 0xfe:
7450                                         DBG_871X("rd(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
7451                                         DBG_871X("rd(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
7452                                         break;
7453                                 case 0xff:
7454                                         {
7455                                                 DBG_871X("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
7456                                                 DBG_871X("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
7457                                                 DBG_871X("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
7458                                                 DBG_871X("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
7459                                                 DBG_871X("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
7460         
7461                                                 DBG_871X("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
7462
7463
7464                                                 DBG_871X("\n");
7465                 
7466                                                 DBG_871X("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
7467                                                 DBG_871X("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
7468
7469                                                 DBG_871X("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
7470         
7471                                                 DBG_871X("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
7472         
7473                                                 DBG_871X("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
7474                                                 DBG_871X("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
7475         
7476                                                 DBG_871X("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
7477                                                 DBG_871X("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
7478                                                 DBG_871X("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
7479                                                 DBG_871X("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
7480                                         }
7481                                         break;
7482                         }                       
7483                         break;
7484                 default:
7485                         DBG_871X("error dbg cmd!\n");
7486                         break;  
7487         }
7488         
7489
7490         return ret;
7491
7492 }
7493
7494 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
7495 {
7496         uint ret=0;
7497         u32 flags;
7498         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7499         
7500         switch (name){
7501         case IEEE_PARAM_WPA_ENABLED:
7502
7503                 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; //802.1x
7504                 
7505                 //ret = ieee80211_wpa_enable(ieee, value);
7506                 
7507                 switch((value)&0xff)
7508                 {
7509                         case 1 : //WPA
7510                         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; //WPA_PSK
7511                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
7512                                 break;
7513                         case 2: //WPA2
7514                         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; //WPA2_PSK
7515                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
7516                                 break;
7517                 }
7518                 
7519                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("wpa_set_param:padapter->securitypriv.ndisauthtype=%d\n", padapter->securitypriv.ndisauthtype));
7520                 
7521                 break;
7522
7523         case IEEE_PARAM_TKIP_COUNTERMEASURES:
7524                 //ieee->tkip_countermeasures=value;
7525                 break;
7526
7527         case IEEE_PARAM_DROP_UNENCRYPTED: 
7528         {
7529                 /* HACK:
7530                  *
7531                  * wpa_supplicant calls set_wpa_enabled when the driver
7532                  * is loaded and unloaded, regardless of if WPA is being
7533                  * used.  No other calls are made which can be used to
7534                  * determine if encryption will be used or not prior to
7535                  * association being expected.  If encryption is not being
7536                  * used, drop_unencrypted is set to false, else true -- we
7537                  * can use this to determine if the CAP_PRIVACY_ON bit should
7538                  * be set.
7539                  */
7540                  
7541 #if 0    
7542                 struct ieee80211_security sec = {
7543                         .flags = SEC_ENABLED,
7544                         .enabled = value,
7545                 };
7546                 ieee->drop_unencrypted = value;
7547                 /* We only change SEC_LEVEL for open mode. Others
7548                  * are set by ipw_wpa_set_encryption.
7549                  */
7550                 if (!value) {
7551                         sec.flags |= SEC_LEVEL;
7552                         sec.level = SEC_LEVEL_0;
7553                 }
7554                 else {
7555                         sec.flags |= SEC_LEVEL;
7556                         sec.level = SEC_LEVEL_1;
7557                 }
7558                 if (ieee->set_security)
7559                         ieee->set_security(ieee->dev, &sec);
7560 #endif          
7561                 break;
7562
7563         }
7564         case IEEE_PARAM_PRIVACY_INVOKED:        
7565                 
7566                 //ieee->privacy_invoked=value;
7567                 
7568                 break;
7569
7570         case IEEE_PARAM_AUTH_ALGS:
7571                 
7572                 ret = wpa_set_auth_algs(dev, value);
7573                 
7574                 break;
7575
7576         case IEEE_PARAM_IEEE_802_1X:
7577                 
7578                 //ieee->ieee802_1x=value;               
7579                 
7580                 break;
7581                 
7582         case IEEE_PARAM_WPAX_SELECT:
7583                 
7584                 // added for WPA2 mixed mode
7585                 //DBG_871X(KERN_WARNING "------------------------>wpax value = %x\n", value);
7586                 /*
7587                 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
7588                 ieee->wpax_type_set = 1;
7589                 ieee->wpax_type_notify = value;
7590                 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
7591                 */
7592                 
7593                 break;
7594
7595         default:                
7596
7597
7598                 
7599                 ret = -EOPNOTSUPP;
7600
7601                 
7602                 break;
7603         
7604         }
7605
7606         return ret;
7607         
7608 }
7609
7610 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
7611 {       
7612         int ret = 0;
7613         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7614
7615         switch (command)
7616         {
7617                 case IEEE_MLME_STA_DEAUTH:
7618
7619                         if(!rtw_set_802_11_disassociate(padapter))
7620                                 ret = -1;               
7621                         
7622                         break;
7623
7624                 case IEEE_MLME_STA_DISASSOC:
7625                 
7626                         if(!rtw_set_802_11_disassociate(padapter))
7627                                 ret = -1;               
7628         
7629                         break;
7630
7631                 default:
7632                         ret = -EOPNOTSUPP;
7633                         break;
7634         }
7635
7636         return ret;
7637         
7638 }
7639
7640 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
7641 {
7642         struct ieee_param *param;
7643         uint ret=0;
7644
7645         //down(&ieee->wx_sem);  
7646
7647         if (p->length < sizeof(struct ieee_param) || !p->pointer){
7648                 ret = -EINVAL;
7649                 goto out;
7650         }
7651         
7652         param = (struct ieee_param *)rtw_malloc(p->length);
7653         if (param == NULL)
7654         {
7655                 ret = -ENOMEM;
7656                 goto out;
7657         }
7658         
7659         if (copy_from_user(param, p->pointer, p->length))
7660         {
7661                 rtw_mfree((u8*)param, p->length);
7662                 ret = -EFAULT;
7663                 goto out;
7664         }
7665
7666         switch (param->cmd) {
7667
7668         case IEEE_CMD_SET_WPA_PARAM:
7669                 ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
7670                 break;
7671
7672         case IEEE_CMD_SET_WPA_IE:
7673                 //ret = wpa_set_wpa_ie(dev, param, p->length);
7674                 ret =  rtw_set_wpa_ie((_adapter *)rtw_netdev_priv(dev), (char*)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
7675                 break;
7676
7677         case IEEE_CMD_SET_ENCRYPTION:
7678                 ret = wpa_set_encryption(dev, param, p->length);
7679                 break;
7680
7681         case IEEE_CMD_MLME:
7682                 ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
7683                 break;
7684
7685         default:
7686                 DBG_871X("Unknown WPA supplicant request: %d\n", param->cmd);
7687                 ret = -EOPNOTSUPP;
7688                 break;
7689                 
7690         }
7691
7692         if (ret == 0 && copy_to_user(p->pointer, param, p->length))
7693                 ret = -EFAULT;
7694
7695         rtw_mfree((u8 *)param, p->length);
7696         
7697 out:
7698         
7699         //up(&ieee->wx_sem);
7700         
7701         return ret;
7702         
7703 }
7704
7705 #ifdef CONFIG_AP_MODE
7706 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
7707 {
7708         int ret = 0;
7709         u32 wep_key_idx, wep_key_len,wep_total_len;
7710         NDIS_802_11_WEP  *pwep = NULL;
7711         struct sta_info *psta = NULL, *pbcmc_sta = NULL;        
7712         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7713         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
7714         struct security_priv* psecuritypriv=&(padapter->securitypriv);
7715         struct sta_priv *pstapriv = &padapter->stapriv;
7716
7717         DBG_871X("%s\n", __FUNCTION__);
7718
7719         param->u.crypt.err = 0;
7720         param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
7721
7722         //sizeof(struct ieee_param) = 64 bytes;
7723         //if (param_len !=  (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
7724         if (param_len !=  sizeof(struct ieee_param) + param->u.crypt.key_len)
7725         {
7726                 ret =  -EINVAL;
7727                 goto exit;
7728         }
7729
7730         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7731             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7732             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
7733         {
7734                 if (param->u.crypt.idx >= WEP_KEYS)
7735                 {
7736                         ret = -EINVAL;
7737                         goto exit;
7738                 }       
7739         }
7740         else 
7741         {               
7742                 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7743                 if(!psta)
7744                 {
7745                         //ret = -EINVAL;
7746                         DBG_871X("rtw_set_encryption(), sta has already been removed or never been added\n");
7747                         goto exit;
7748                 }                       
7749         }
7750
7751         if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
7752         {
7753                 //todo:clear default encryption keys
7754
7755                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
7756                 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
7757                 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
7758                 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
7759
7760                 DBG_871X("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
7761                 
7762                 goto exit;
7763         }
7764
7765
7766         if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
7767         {               
7768                 DBG_871X("r871x_set_encryption, crypt.alg = WEP\n");
7769                 
7770                 wep_key_idx = param->u.crypt.idx;
7771                 wep_key_len = param->u.crypt.key_len;
7772                                         
7773                 DBG_871X("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
7774
7775                 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
7776                 {
7777                         ret = -EINVAL;
7778                         goto exit;
7779                 }
7780                         
7781
7782                 if (wep_key_len > 0) 
7783                 {                       
7784                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
7785                         wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
7786                         pwep =(NDIS_802_11_WEP *)rtw_malloc(wep_total_len);
7787                         if(pwep == NULL){
7788                                 DBG_871X(" r871x_set_encryption: pwep allocate fail !!!\n");
7789                                 goto exit;
7790                         }
7791                         
7792                         _rtw_memset(pwep, 0, wep_total_len);
7793                 
7794                         pwep->KeyLength = wep_key_len;
7795                         pwep->Length = wep_total_len;
7796                         
7797                 }
7798                 
7799                 pwep->KeyIndex = wep_key_idx;
7800
7801                 _rtw_memcpy(pwep->KeyMaterial,  param->u.crypt.key, pwep->KeyLength);
7802
7803                 if(param->u.crypt.set_tx)
7804                 {
7805                         DBG_871X("wep, set_tx=1\n");
7806
7807                         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
7808                         psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
7809                         psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
7810                         psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
7811                         
7812                         if(pwep->KeyLength==13)
7813                         {
7814                                 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
7815                                 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
7816                         }
7817
7818                 
7819                         psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
7820                         
7821                         _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
7822
7823                         psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength;
7824
7825                         rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1);
7826                 }
7827                 else
7828                 {
7829                         DBG_871X("wep, set_tx=0\n");
7830                         
7831                         //don't update "psecuritypriv->dot11PrivacyAlgrthm" and 
7832                         //"psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to cam
7833                                         
7834                       _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
7835
7836                         psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;                   
7837
7838                         rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0);
7839                 }
7840
7841                 goto exit;
7842                 
7843         }
7844
7845         
7846         if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
7847         {
7848                 if(param->u.crypt.set_tx ==1)
7849                 {
7850                         if(strcmp(param->u.crypt.alg, "WEP") == 0)
7851                         {
7852                                 DBG_871X("%s, set group_key, WEP\n", __FUNCTION__);
7853                                 
7854                                 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
7855                                         
7856                                 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
7857                                 if(param->u.crypt.key_len==13)
7858                                 {                                               
7859                                                 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
7860                                 }
7861                                 
7862                         }
7863                         else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
7864                         {                                               
7865                                 DBG_871X("%s, set group_key, TKIP\n", __FUNCTION__);
7866                                 
7867                                 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
7868
7869                                 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
7870                                 
7871                                 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
7872                                 //set mic key
7873                                 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
7874                                 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
7875
7876                                 psecuritypriv->busetkipkey = _TRUE;
7877                                                                                         
7878                         }
7879                         else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
7880                         {
7881                                 DBG_871X("%s, set group_key, CCMP\n", __FUNCTION__);
7882                         
7883                                 psecuritypriv->dot118021XGrpPrivacy = _AES_;
7884
7885                                 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
7886                         }
7887                         else
7888                         {
7889                                 DBG_871X("%s, set group_key, none\n", __FUNCTION__);
7890                                 
7891                                 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
7892                         }
7893
7894                         psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
7895
7896                         psecuritypriv->binstallGrpkey = _TRUE;
7897
7898                         psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
7899                                                                 
7900                         rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
7901                         
7902                         pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
7903                         if(pbcmc_sta)
7904                         {
7905                                 pbcmc_sta->ieee8021x_blocked = _FALSE;
7906                                 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy                     
7907                         }       
7908                                                 
7909                 }
7910
7911                 goto exit;
7912                 
7913         }       
7914
7915         if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
7916         {
7917                 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
7918                 {
7919                         if(param->u.crypt.set_tx ==1)
7920                         { 
7921                                 _rtw_memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
7922                                 
7923                                 if(strcmp(param->u.crypt.alg, "WEP") == 0)
7924                                 {
7925                                         DBG_871X("%s, set pairwise key, WEP\n", __FUNCTION__);
7926                                         
7927                                         psta->dot118021XPrivacy = _WEP40_;
7928                                         if(param->u.crypt.key_len==13)
7929                                         {                                               
7930                                                 psta->dot118021XPrivacy = _WEP104_;
7931                                         }
7932                                 }
7933                                 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
7934                                 {                                               
7935                                         DBG_871X("%s, set pairwise key, TKIP\n", __FUNCTION__);
7936                                         
7937                                         psta->dot118021XPrivacy = _TKIP_;
7938                                 
7939                                         //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
7940                                         //set mic key
7941                                         _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
7942                                         _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
7943
7944                                         psecuritypriv->busetkipkey = _TRUE;
7945                                                                                         
7946                                 }
7947                                 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
7948                                 {
7949
7950                                         DBG_871X("%s, set pairwise key, CCMP\n", __FUNCTION__);
7951                                         
7952                                         psta->dot118021XPrivacy = _AES_;
7953                                 }
7954                                 else
7955                                 {
7956                                         DBG_871X("%s, set pairwise key, none\n", __FUNCTION__);
7957                                         
7958                                         psta->dot118021XPrivacy = _NO_PRIVACY_;
7959                                 }
7960                                                 
7961                                 rtw_ap_set_pairwise_key(padapter, psta);
7962                                         
7963                                 psta->ieee8021x_blocked = _FALSE;
7964                                         
7965                         }                       
7966                         else//group key???
7967                         { 
7968                                 if(strcmp(param->u.crypt.alg, "WEP") == 0)
7969                                 {
7970                                         _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
7971                                         
7972                                         psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
7973                                         if(param->u.crypt.key_len==13)
7974                                         {                                               
7975                                                 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
7976                                         }
7977                                 }
7978                                 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
7979                                 {                                               
7980                                         psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
7981
7982                                         _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
7983                                 
7984                                         //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
7985                                         //set mic key
7986                                         _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
7987                                         _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
7988
7989                                         psecuritypriv->busetkipkey = _TRUE;
7990                                                                                         
7991                                 }
7992                                 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
7993                                 {
7994                                         psecuritypriv->dot118021XGrpPrivacy = _AES_;
7995
7996                                         _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
7997                                 }
7998                                 else
7999                                 {
8000                                         psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
8001                                 }
8002
8003                                 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
8004
8005                                 psecuritypriv->binstallGrpkey = _TRUE;  
8006                                                                 
8007                                 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
8008                                                                 
8009                                 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
8010                         
8011                                 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
8012                                 if(pbcmc_sta)
8013                                 {
8014                                         pbcmc_sta->ieee8021x_blocked = _FALSE;
8015                                         pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy                     
8016                                 }                                       
8017
8018                         }
8019                         
8020                 }
8021                                 
8022         }
8023
8024 exit:
8025
8026         if(pwep)
8027         {
8028                 rtw_mfree((u8 *)pwep, wep_total_len);           
8029         }       
8030         
8031         return ret;
8032         
8033 }
8034
8035 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
8036 {
8037         int ret=0;      
8038         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8039         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8040         struct sta_priv *pstapriv = &padapter->stapriv;
8041         unsigned char *pbuf = param->u.bcn_ie.buf;
8042
8043
8044         DBG_871X("%s, len=%d\n", __FUNCTION__, len);
8045
8046         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8047                 return -EINVAL;
8048
8049         _rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
8050
8051         if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
8052                 pstapriv->max_num_sta = NUM_STA;
8053
8054
8055         if(rtw_check_beacon_data(padapter, pbuf,  (len-12-2)) == _SUCCESS)// 12 = param header, 2:no packed
8056                 ret = 0;
8057         else
8058                 ret = -EINVAL;
8059         
8060
8061         return ret;
8062         
8063 }
8064
8065 static int rtw_hostapd_sta_flush(struct net_device *dev)
8066 {
8067         //_irqL irqL;
8068         //_list *phead, *plist;
8069         int ret=0;      
8070         //struct sta_info *psta = NULL;
8071         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
8072         //struct sta_priv *pstapriv = &padapter->stapriv;
8073
8074         DBG_871X("%s\n", __FUNCTION__);
8075
8076         flush_all_cam_entry(padapter);  //clear CAM
8077
8078         ret = rtw_sta_flush(padapter);  
8079
8080         return ret;
8081
8082 }
8083
8084 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
8085 {
8086         _irqL irqL;
8087         int ret=0;      
8088         struct sta_info *psta = NULL;
8089         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8090         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8091         struct sta_priv *pstapriv = &padapter->stapriv;
8092
8093         DBG_871X("rtw_add_sta(aid=%d)=" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr));
8094         
8095         if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)       
8096         {
8097                 return -EINVAL;         
8098         }
8099
8100         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8101             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8102             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
8103         {
8104                 return -EINVAL; 
8105         }
8106
8107 /*
8108         psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8109         if(psta)
8110         {
8111                 DBG_871X("rtw_add_sta(), free has been added psta=%p\n", psta);
8112                 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
8113                 rtw_free_stainfo(padapter,  psta);              
8114                 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
8115
8116                 psta = NULL;
8117         }       
8118 */
8119         //psta = rtw_alloc_stainfo(pstapriv, param->sta_addr);
8120         psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8121         if(psta)
8122         {
8123                 int flags = param->u.add_sta.flags;                     
8124                 
8125                 //DBG_871X("rtw_add_sta(), init sta's variables, psta=%p\n", psta);
8126                 
8127                 psta->aid = param->u.add_sta.aid;//aid=1~2007
8128
8129                 _rtw_memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
8130                 
8131                 
8132                 //check wmm cap.
8133                 if(WLAN_STA_WME&flags)
8134                         psta->qos_option = 1;
8135                 else
8136                         psta->qos_option = 0;
8137
8138                 if(pmlmepriv->qospriv.qos_option == 0)  
8139                         psta->qos_option = 0;
8140
8141                 
8142 #ifdef CONFIG_80211N_HT         
8143                 //chec 802.11n ht cap.
8144                 if(WLAN_STA_HT&flags)
8145                 {
8146                         psta->htpriv.ht_option = _TRUE;
8147                         psta->qos_option = 1;
8148                         _rtw_memcpy((void*)&psta->htpriv.ht_cap, (void*)&param->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
8149                 }
8150                 else            
8151                 {
8152                         psta->htpriv.ht_option = _FALSE;
8153                 }
8154                 
8155                 if(pmlmepriv->htpriv.ht_option == _FALSE)       
8156                         psta->htpriv.ht_option = _FALSE;
8157 #endif          
8158
8159
8160                 update_sta_info_apmode(padapter, psta);
8161                 
8162                 
8163         }
8164         else
8165         {
8166                 ret = -ENOMEM;
8167         }       
8168         
8169         return ret;
8170         
8171 }
8172
8173 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
8174 {
8175         _irqL irqL;
8176         int ret=0;      
8177         struct sta_info *psta = NULL;
8178         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8179         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8180         struct sta_priv *pstapriv = &padapter->stapriv;
8181
8182         DBG_871X("rtw_del_sta=" MAC_FMT "\n", MAC_ARG(param->sta_addr));
8183                 
8184         if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)               
8185         {
8186                 return -EINVAL;         
8187         }
8188
8189         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8190             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8191             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
8192         {
8193                 return -EINVAL; 
8194         }
8195
8196         psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8197         if(psta)
8198         {
8199                 u8 updated=_FALSE;
8200         
8201                 //DBG_871X("free psta=%p, aid=%d\n", psta, psta->aid);
8202
8203                 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
8204                 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
8205                 {                       
8206                         rtw_list_delete(&psta->asoc_list);
8207                         pstapriv->asoc_list_cnt--;
8208                         updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
8209
8210                 }
8211                 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
8212                 
8213                 associated_clients_update(padapter, updated);
8214         
8215                 psta = NULL;
8216                 
8217         }
8218         else
8219         {
8220                 DBG_871X("rtw_del_sta(), sta has already been removed or never been added\n");
8221                 
8222                 //ret = -1;
8223         }
8224         
8225         
8226         return ret;
8227         
8228 }
8229
8230 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
8231 {
8232         int ret=0;      
8233         struct sta_info *psta = NULL;
8234         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8235         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8236         struct sta_priv *pstapriv = &padapter->stapriv;
8237         struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
8238         struct sta_data *psta_data = (struct sta_data *)param_ex->data;
8239
8240         DBG_871X("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr));
8241
8242         if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)               
8243         {
8244                 return -EINVAL;         
8245         }
8246
8247         if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
8248             param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
8249             param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) 
8250         {
8251                 return -EINVAL; 
8252         }
8253
8254         psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
8255         if(psta)
8256         {
8257 #if 0
8258                 struct {
8259                         u16 aid;
8260                         u16 capability;
8261                         int flags;
8262                         u32 sta_set;
8263                         u8 tx_supp_rates[16];   
8264                         u32 tx_supp_rates_len;
8265                         struct rtw_ieee80211_ht_cap ht_cap;
8266                         u64     rx_pkts;
8267                         u64     rx_bytes;
8268                         u64     rx_drops;
8269                         u64     tx_pkts;
8270                         u64     tx_bytes;
8271                         u64     tx_drops;
8272                 } get_sta;              
8273 #endif
8274                 psta_data->aid = (u16)psta->aid;
8275                 psta_data->capability = psta->capability;
8276                 psta_data->flags = psta->flags;
8277
8278 /*
8279                 nonerp_set : BIT(0)
8280                 no_short_slot_time_set : BIT(1)
8281                 no_short_preamble_set : BIT(2)
8282                 no_ht_gf_set : BIT(3)
8283                 no_ht_set : BIT(4)
8284                 ht_20mhz_set : BIT(5)
8285 */
8286
8287                 psta_data->sta_set =((psta->nonerp_set) |
8288                                                         (psta->no_short_slot_time_set <<1) |
8289                                                         (psta->no_short_preamble_set <<2) |
8290                                                         (psta->no_ht_gf_set <<3) |
8291                                                         (psta->no_ht_set <<4) |
8292                                                         (psta->ht_20mhz_set <<5));
8293
8294                 psta_data->tx_supp_rates_len =  psta->bssratelen;
8295                 _rtw_memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
8296 #ifdef CONFIG_80211N_HT
8297                 _rtw_memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
8298 #endif //CONFIG_80211N_HT
8299                 psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
8300                 psta_data->rx_bytes = psta->sta_stats.rx_bytes;
8301                 psta_data->rx_drops = psta->sta_stats.rx_drops;
8302
8303                 psta_data->tx_pkts = psta->sta_stats.tx_pkts;
8304                 psta_data->tx_bytes = psta->sta_stats.tx_bytes;
8305                 psta_data->tx_drops = psta->sta_stats.tx_drops;
8306                 
8307
8308         }
8309         else
8310         {
8311                 ret = -1;
8312         }
8313
8314         return ret;
8315
8316 }
8317
8318 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
8319 {
8320         int ret=0;      
8321         struct sta_info *psta = NULL;
8322         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8323         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8324         struct sta_priv *pstapriv = &padapter->stapriv;
8325
8326         DBG_871X("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr));
8327
8328         if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)               
8329         {
8330                 return -EINVAL;         
8331         }
8332
8333         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8334             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8335             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
8336         {
8337                 return -EINVAL; 
8338         }
8339
8340         psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8341         if(psta)
8342         {
8343                 if((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC))
8344                 {
8345                         int wpa_ie_len;
8346                         int copy_len;
8347
8348                         wpa_ie_len = psta->wpa_ie[1];
8349                         
8350                         copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)):(wpa_ie_len+2);
8351                                 
8352                         param->u.wpa_ie.len = copy_len;
8353
8354                         _rtw_memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
8355                 }
8356                 else
8357                 {
8358                         //ret = -1;
8359                         DBG_871X("sta's wpa_ie is NONE\n");
8360                 }               
8361         }
8362         else
8363         {
8364                 ret = -1;
8365         }
8366
8367         return ret;
8368
8369 }
8370
8371 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
8372 {
8373         int ret=0;
8374         unsigned char wps_oui[4]={0x0,0x50,0xf2,0x04};
8375         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
8376         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8377         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
8378         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
8379         int ie_len;
8380
8381         DBG_871X("%s, len=%d\n", __FUNCTION__, len);
8382
8383         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8384                 return -EINVAL;
8385
8386         ie_len = len-12-2;// 12 = param header, 2:no packed
8387
8388
8389         if(pmlmepriv->wps_beacon_ie)
8390         {
8391                 rtw_mfree(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
8392                 pmlmepriv->wps_beacon_ie = NULL;                        
8393         }       
8394
8395         if(ie_len>0)
8396         {
8397                 pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
8398                 pmlmepriv->wps_beacon_ie_len = ie_len;
8399                 if ( pmlmepriv->wps_beacon_ie == NULL) {
8400                         DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8401                         return -EINVAL;
8402                 }
8403
8404                 _rtw_memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
8405
8406                 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
8407                 
8408                 pmlmeext->bstart_bss = _TRUE;
8409                 
8410         }
8411         
8412         
8413         return ret;             
8414
8415 }
8416
8417 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
8418 {
8419         int ret=0;
8420         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
8421         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8422         int ie_len;
8423
8424         DBG_871X("%s, len=%d\n", __FUNCTION__, len);
8425
8426         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8427                 return -EINVAL;
8428
8429         ie_len = len-12-2;// 12 = param header, 2:no packed
8430
8431
8432         if(pmlmepriv->wps_probe_resp_ie)
8433         {
8434                 rtw_mfree(pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
8435                 pmlmepriv->wps_probe_resp_ie = NULL;                    
8436         }       
8437
8438         if(ie_len>0)
8439         {
8440                 pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
8441                 pmlmepriv->wps_probe_resp_ie_len = ie_len;
8442                 if ( pmlmepriv->wps_probe_resp_ie == NULL) {
8443                         DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8444                         return -EINVAL;
8445                 }
8446                 _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);         
8447         }
8448         
8449         
8450         return ret;
8451
8452 }
8453
8454 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
8455 {
8456         int ret=0;
8457         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
8458         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8459         int ie_len;
8460
8461         DBG_871X("%s, len=%d\n", __FUNCTION__, len);
8462
8463         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8464                 return -EINVAL;
8465
8466         ie_len = len-12-2;// 12 = param header, 2:no packed
8467
8468
8469         if(pmlmepriv->wps_assoc_resp_ie)
8470         {
8471                 rtw_mfree(pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
8472                 pmlmepriv->wps_assoc_resp_ie = NULL;                    
8473         }       
8474
8475         if(ie_len>0)
8476         {
8477                 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
8478                 pmlmepriv->wps_assoc_resp_ie_len = ie_len;
8479                 if ( pmlmepriv->wps_assoc_resp_ie == NULL) {
8480                         DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8481                         return -EINVAL;
8482                 }
8483                 
8484                 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);         
8485         }
8486         
8487         
8488         return ret;
8489
8490 }
8491
8492 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
8493 {
8494         int ret=0;
8495         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8496         struct mlme_priv *mlmepriv = &(adapter->mlmepriv);
8497         struct mlme_ext_priv    *mlmeext = &(adapter->mlmeextpriv);
8498         struct mlme_ext_info    *mlmeinfo = &(mlmeext->mlmext_info);
8499         int ie_len;
8500         u8 *ssid_ie;
8501         char ssid[NDIS_802_11_LENGTH_SSID + 1];
8502         sint ssid_len;
8503         u8 ignore_broadcast_ssid;
8504
8505         if(check_fwstate(mlmepriv, WIFI_AP_STATE) != _TRUE)
8506                 return -EPERM;
8507
8508         if (param->u.bcn_ie.reserved[0] != 0xea)
8509                 return -EINVAL;
8510
8511         mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];
8512
8513         ie_len = len-12-2;// 12 = param header, 2:no packed
8514         ssid_ie = rtw_get_ie(param->u.bcn_ie.buf,  WLAN_EID_SSID, &ssid_len, ie_len);
8515
8516         if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) {
8517                 WLAN_BSSID_EX *pbss_network = &mlmepriv->cur_network.network;
8518                 WLAN_BSSID_EX *pbss_network_ext = &mlmeinfo->network;
8519
8520                 _rtw_memcpy(ssid, ssid_ie+2, ssid_len);
8521                 ssid[ssid_len] = 0x0;
8522
8523                 if(0)
8524                 DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
8525                         ssid, ssid_len,
8526                         pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
8527                         pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
8528
8529                 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len);
8530                 pbss_network->Ssid.SsidLength = ssid_len;
8531                 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len);
8532                 pbss_network_ext->Ssid.SsidLength = ssid_len;
8533
8534                 if(0)
8535                 DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
8536                         pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
8537                         pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
8538         }
8539
8540         DBG_871X(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter),
8541                 ignore_broadcast_ssid, ssid, ssid_len);
8542
8543         return ret;
8544 }
8545
8546 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
8547 {
8548         int ret=0;
8549         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
8550         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
8551
8552         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8553                 return -EINVAL;
8554
8555         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8556             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8557             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
8558         {
8559                 return -EINVAL; 
8560         }
8561
8562         ret = rtw_acl_remove_sta(padapter, param->sta_addr);    
8563
8564         return ret;             
8565
8566 }
8567
8568 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
8569 {
8570         int ret=0;
8571         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
8572         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8573         
8574         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8575                 return -EINVAL;
8576
8577         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8578             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8579             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
8580         {
8581                 return -EINVAL; 
8582         }
8583
8584         ret = rtw_acl_add_sta(padapter, param->sta_addr);       
8585
8586         return ret;             
8587
8588 }
8589
8590 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
8591 {
8592         int ret=0;
8593         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
8594         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8595         
8596         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8597                 return -EINVAL; 
8598         
8599         rtw_set_macaddr_acl(padapter, param->u.mlme.command);   
8600
8601         return ret;
8602 }
8603
8604 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
8605 {
8606         struct ieee_param *param;
8607         int ret=0;
8608         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8609
8610         //DBG_871X("%s\n", __FUNCTION__);
8611
8612         /*
8613         * this function is expect to call in master mode, which allows no power saving
8614         * so, we just check hw_init_completed
8615         */
8616
8617         if (padapter->hw_init_completed==_FALSE){
8618                 ret = -EPERM;
8619                 goto out;
8620         }
8621
8622
8623         //if (p->length < sizeof(struct ieee_param) || !p->pointer){
8624         if(!p->pointer){
8625                 ret = -EINVAL;
8626                 goto out;
8627         }
8628         
8629         param = (struct ieee_param *)rtw_malloc(p->length);
8630         if (param == NULL)
8631         {
8632                 ret = -ENOMEM;
8633                 goto out;
8634         }
8635         
8636         if (copy_from_user(param, p->pointer, p->length))
8637         {
8638                 rtw_mfree((u8*)param, p->length);
8639                 ret = -EFAULT;
8640                 goto out;
8641         }
8642
8643         //DBG_871X("%s, cmd=%d\n", __FUNCTION__, param->cmd);
8644
8645         switch (param->cmd) 
8646         {       
8647                 case RTL871X_HOSTAPD_FLUSH:
8648
8649                         ret = rtw_hostapd_sta_flush(dev);
8650
8651                         break;
8652         
8653                 case RTL871X_HOSTAPD_ADD_STA:   
8654                         
8655                         ret = rtw_add_sta(dev, param);                                  
8656                         
8657                         break;
8658
8659                 case RTL871X_HOSTAPD_REMOVE_STA:
8660
8661                         ret = rtw_del_sta(dev, param);
8662
8663                         break;
8664         
8665                 case RTL871X_HOSTAPD_SET_BEACON:
8666
8667                         ret = rtw_set_beacon(dev, param, p->length);
8668
8669                         break;
8670                         
8671                 case RTL871X_SET_ENCRYPTION:
8672
8673                         ret = rtw_set_encryption(dev, param, p->length);
8674                         
8675                         break;
8676                         
8677                 case RTL871X_HOSTAPD_GET_WPAIE_STA:
8678
8679                         ret = rtw_get_sta_wpaie(dev, param);
8680         
8681                         break;
8682                         
8683                 case RTL871X_HOSTAPD_SET_WPS_BEACON:
8684
8685                         ret = rtw_set_wps_beacon(dev, param, p->length);
8686
8687                         break;
8688
8689                 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
8690
8691                         ret = rtw_set_wps_probe_resp(dev, param, p->length);
8692                         
8693                         break;
8694                         
8695                 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
8696
8697                         ret = rtw_set_wps_assoc_resp(dev, param, p->length);
8698                         
8699                         break;
8700
8701                 case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
8702
8703                         ret = rtw_set_hidden_ssid(dev, param, p->length);
8704
8705                         break;
8706
8707                 case RTL871X_HOSTAPD_GET_INFO_STA:
8708
8709                         ret = rtw_ioctl_get_sta_data(dev, param, p->length);
8710
8711                         break;
8712                         
8713                 case RTL871X_HOSTAPD_SET_MACADDR_ACL:
8714
8715                         ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
8716
8717                         break;
8718
8719                 case RTL871X_HOSTAPD_ACL_ADD_STA:
8720
8721                         ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
8722
8723                         break;
8724
8725                 case RTL871X_HOSTAPD_ACL_REMOVE_STA:
8726
8727                         ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
8728
8729                         break;
8730                         
8731                 default:
8732                         DBG_871X("Unknown hostapd request: %d\n", param->cmd);
8733                         ret = -EOPNOTSUPP;
8734                         break;
8735                 
8736         }
8737
8738         if (ret == 0 && copy_to_user(p->pointer, param, p->length))
8739                 ret = -EFAULT;
8740
8741
8742         rtw_mfree((u8 *)param, p->length);
8743         
8744 out:
8745                 
8746         return ret;
8747         
8748 }
8749 #endif
8750
8751 static int rtw_wx_set_priv(struct net_device *dev,
8752                                 struct iw_request_info *info,
8753                                 union iwreq_data *awrq,
8754                                 char *extra)
8755 {
8756
8757 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8758         char *ext_dbg;
8759 #endif
8760
8761         int ret = 0;
8762         int len = 0;
8763         char *ext;
8764         int i;
8765
8766         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8767         struct iw_point *dwrq = (struct iw_point*)awrq;
8768
8769         //RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, ("+rtw_wx_set_priv\n"));
8770         if(dwrq->length == 0)
8771                 return -EFAULT;
8772         
8773         len = dwrq->length;
8774         if (!(ext = rtw_vmalloc(len)))
8775                 return -ENOMEM;
8776
8777         if (copy_from_user(ext, dwrq->pointer, len)) {
8778                 rtw_vmfree(ext, len);
8779                 return -EFAULT;
8780         }
8781
8782
8783         //RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_,
8784         //       ("rtw_wx_set_priv: %s req=%s\n",
8785         //        dev->name, ext));
8786
8787         #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV     
8788         if (!(ext_dbg = rtw_vmalloc(len)))
8789         {
8790                 rtw_vmfree(ext, len);
8791                 return -ENOMEM;
8792         }       
8793         
8794         _rtw_memcpy(ext_dbg, ext, len);
8795         #endif
8796
8797         //added for wps2.0 @20110524
8798         if(dwrq->flags == 0x8766 && len > 8)
8799         {
8800                 u32 cp_sz;              
8801                 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8802                 u8 *probereq_wpsie = ext;
8803                 int probereq_wpsie_len = len;
8804                 u8 wps_oui[4]={0x0,0x50,0xf2,0x04};             
8805         
8806                 if((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
8807                         (_rtw_memcmp(&probereq_wpsie[2], wps_oui, 4) ==_TRUE))
8808                 {
8809                         cp_sz = probereq_wpsie_len>MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN:probereq_wpsie_len;
8810
8811                         if(pmlmepriv->wps_probe_req_ie)
8812                         {
8813                                 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
8814                                 pmlmepriv->wps_probe_req_ie_len = 0;
8815                                 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
8816                                 pmlmepriv->wps_probe_req_ie = NULL;                     
8817                         }       
8818
8819                         pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
8820                         if ( pmlmepriv->wps_probe_req_ie == NULL) {
8821                                 printk("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8822                                 ret =  -EINVAL;
8823                                 goto FREE_EXT;
8824                         
8825                         }
8826                         
8827                         _rtw_memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
8828                         pmlmepriv->wps_probe_req_ie_len = cp_sz;                                        
8829                         
8830                 }       
8831                 
8832                 goto FREE_EXT;
8833                 
8834         }
8835
8836         if(     len >= WEXT_CSCAN_HEADER_SIZE
8837                 && _rtw_memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
8838         ){
8839                 ret = rtw_wx_set_scan(dev, info, awrq, ext);
8840                 goto FREE_EXT;
8841         }
8842         
8843 #ifdef CONFIG_ANDROID
8844         //DBG_871X("rtw_wx_set_priv: %s req=%s\n", dev->name, ext);
8845
8846         i = rtw_android_cmdstr_to_num(ext);
8847
8848         switch(i) {
8849                 case ANDROID_WIFI_CMD_START :
8850                         indicate_wx_custom_event(padapter, "START");
8851                         break;
8852                 case ANDROID_WIFI_CMD_STOP :
8853                         indicate_wx_custom_event(padapter, "STOP");
8854                         break;
8855                 case ANDROID_WIFI_CMD_RSSI :
8856                         {
8857                                 struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);     
8858                                 struct  wlan_network    *pcur_network = &pmlmepriv->cur_network;
8859
8860                                 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
8861                                         sprintf(ext, "%s rssi %d", pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi);
8862                                 } else {
8863                                         sprintf(ext, "OK");
8864                                 }
8865                         }
8866                         break;
8867                 case ANDROID_WIFI_CMD_LINKSPEED :
8868                         {
8869                                 u16 mbps = rtw_get_cur_max_rate(padapter)/10;
8870                                 sprintf(ext, "LINKSPEED %d", mbps);
8871                         }
8872                         break;
8873                 case ANDROID_WIFI_CMD_MACADDR :
8874                         sprintf(ext, "MACADDR = " MAC_FMT, MAC_ARG(dev->dev_addr));
8875                         break;
8876                 case ANDROID_WIFI_CMD_SCAN_ACTIVE :
8877                         {
8878                                 //rtw_set_scan_mode(padapter, SCAN_ACTIVE);
8879                                 sprintf(ext, "OK");
8880                         }
8881                         break;
8882                 case ANDROID_WIFI_CMD_SCAN_PASSIVE :
8883                         {
8884                                 //rtw_set_scan_mode(padapter, SCAN_PASSIVE);
8885                                 sprintf(ext, "OK");
8886                         }
8887                         break;
8888
8889                 case ANDROID_WIFI_CMD_COUNTRY :
8890                         {
8891                                 char country_code[10];
8892                                 sscanf(ext, "%*s %s", country_code);
8893                                 rtw_set_country(padapter, country_code);
8894                                 sprintf(ext, "OK");
8895                         }
8896                         break;
8897                 default :
8898                         #ifdef  CONFIG_DEBUG_RTW_WX_SET_PRIV
8899                         DBG_871X("%s: %s unknowned req=%s\n", __FUNCTION__,
8900                                 dev->name, ext_dbg);
8901                         #endif
8902
8903                         sprintf(ext, "OK");
8904                 
8905         }
8906
8907         if (copy_to_user(dwrq->pointer, ext, min(dwrq->length, (u16)(strlen(ext)+1)) ) )
8908                 ret = -EFAULT;
8909
8910         #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8911         DBG_871X("%s: %s req=%s rep=%s dwrq->length=%d, strlen(ext)+1=%d\n", __FUNCTION__,
8912                 dev->name, ext_dbg ,ext, dwrq->length, (u16)(strlen(ext)+1));
8913         #endif
8914 #endif //end of CONFIG_ANDROID
8915
8916
8917 FREE_EXT:
8918
8919         rtw_vmfree(ext, len);
8920         #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8921         rtw_vmfree(ext_dbg, len);
8922         #endif
8923
8924         //DBG_871X("rtw_wx_set_priv: (SIOCSIWPRIV) %s ret=%d\n", 
8925         //              dev->name, ret);
8926
8927         return ret;
8928         
8929 }
8930
8931 #ifdef CONFIG_AP_WOWLAN
8932 static int rtw_ap_wowlan_ctrl(struct net_device *dev,
8933                                                 struct iw_request_info *info,
8934                                                 union iwreq_data *wrqu, char *extra)
8935 {
8936         _adapter *padapter =  (_adapter *)rtw_netdev_priv(dev);
8937         struct wowlan_ioctl_param poidparam;
8938         struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
8939         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8940         struct sta_info *psta = NULL;
8941         int ret = 0;
8942         u32 start_time = rtw_get_current_time();
8943         poidparam.subcode = 0;
8944
8945         DBG_871X("+rtw_ap_wowlan_ctrl: %s\n", extra);
8946
8947         if(pwrctrlpriv->bSupportRemoteWakeup==_FALSE){
8948                 ret = -EPERM;
8949                 DBG_871X("+rtw_wowlan_ctrl: Device didn't support the remote wakeup!!\n");
8950                 goto _rtw_ap_wowlan_ctrl_exit_free;
8951         }
8952
8953         if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
8954                 DBG_871X("[%s] It is not AP mode!!\n", __func__);
8955                 goto _rtw_ap_wowlan_ctrl_exit_free;
8956         }
8957
8958         if (_rtw_memcmp( extra, "enable", 6 )) {
8959                 pwrctrlpriv->wowlan_ap_mode = _TRUE;
8960                 while (pwrctrlpriv->bips_processing == _TRUE)
8961                         rtw_msleep_os(1);
8962
8963                 rtw_cancel_all_timer(padapter);
8964
8965                 padapter->bDriverStopped = _TRUE;       //for stop thread
8966                 rtw_stop_drv_threads(padapter);
8967                 padapter->bDriverStopped = _FALSE;      //for 32k command
8968
8969 #ifdef CONFIG_LPS
8970                 LeaveAllPowerSaveModeDirect(padapter);
8971 #endif
8972                 rtw_hal_disable_interrupt(padapter); // It need wait for leaving 32K.
8973
8974                 // 2.1 clean interupt
8975                 if (padapter->HalFunc.clear_interrupt)
8976                         padapter->HalFunc.clear_interrupt(padapter);
8977
8978                 poidparam.subcode = WOWLAN_AP_ENABLE;
8979
8980                 rtw_hal_set_hwreg(padapter, HW_VAR_AP_WOWLAN,(u8 *)&poidparam);
8981         } else if (_rtw_memcmp( extra, "disable", 6 )) {
8982 #ifdef CONFIG_LPS
8983                 LeaveAllPowerSaveModeDirect(padapter);
8984 #endif //CONFIG_LPS
8985                 pwrctrlpriv->bFwCurrentInPSMode = _FALSE;
8986
8987                 rtw_hal_disable_interrupt(padapter);
8988
8989                 if (padapter->HalFunc.clear_interrupt)
8990                         padapter->HalFunc.clear_interrupt(padapter);
8991
8992                 poidparam.subcode = WOWLAN_AP_ENABLE;
8993
8994                 rtw_hal_set_hwreg(padapter, HW_VAR_AP_WOWLAN,(u8 *)&poidparam);
8995
8996                 pwrctrlpriv->wowlan_ap_mode = _FALSE;
8997
8998                 psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
8999                 if (psta) {
9000                         set_sta_rate(padapter, psta);
9001                 }
9002
9003                 padapter->bDriverStopped = _FALSE;
9004                 DBG_871X("%s: wowmode resuming, DriverStopped:%d\n", __func__, padapter->bDriverStopped);
9005                 rtw_start_drv_threads(padapter);
9006
9007                 rtw_hal_enable_interrupt(padapter);
9008
9009                 _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000);
9010                 pwrctrlpriv->bips_processing = _FALSE;
9011                 rtw_set_pwr_state_check_timer(pwrctrlpriv);
9012
9013         } else {
9014                 DBG_871X("[%s] Invalid Parameter.\n", __func__);
9015                 goto _rtw_ap_wowlan_ctrl_exit_free;
9016         }
9017         //mutex_lock(&ioctl_mutex);
9018 _rtw_ap_wowlan_ctrl_exit_free:
9019         DBG_871X("-rtw_ap_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);
9020         DBG_871X_LEVEL(_drv_always_, "%s in %d ms\n", __func__,
9021                         rtw_get_passing_time_ms(start_time));
9022 _rtw_ap_wowlan_ctrl_exit:
9023         return ret;
9024 }
9025 #endif //CONFIG_AP_WOWLAN
9026
9027 static int rtw_pm_set(struct net_device *dev,
9028                                struct iw_request_info *info,
9029                                union iwreq_data *wrqu, char *extra)
9030 {
9031         int ret = 0;
9032         unsigned        mode = 0;
9033         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
9034
9035         DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra );
9036
9037         if ( _rtw_memcmp( extra, "lps=", 4 ) )
9038         {
9039                 sscanf(extra+4, "%u", &mode);   
9040                 ret = rtw_pm_set_lps(padapter,mode);
9041         }
9042         else if ( _rtw_memcmp( extra, "ips=", 4 ) )
9043         {
9044                 sscanf(extra+4, "%u", &mode);
9045                 ret = rtw_pm_set_ips(padapter,mode);
9046         }
9047         else{
9048                 ret = -EINVAL;
9049         }
9050
9051         return ret;
9052 }
9053
9054 static int rtw_mp_efuse_get(struct net_device *dev,
9055                         struct iw_request_info *info,
9056                         union iwreq_data *wdata, char *extra)
9057 {
9058         PADAPTER padapter = rtw_netdev_priv(dev);
9059         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
9060         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
9061         PEFUSE_HAL pEfuseHal;
9062         struct iw_point *wrqu;
9063         
9064         u8      *PROMContent = pEEPROM->efuse_eeprom_data;
9065         u8 ips_mode = IPS_NUM; // init invalid value
9066         u8 lps_mode = PS_MODE_NUM; // init invalid value
9067         struct pwrctrl_priv *pwrctrlpriv ;
9068         u8 *data = NULL;
9069         u8 *rawdata = NULL;
9070         char *pch, *ptmp, *token, *tmp[3]={0x00,0x00,0x00};
9071         u16 i=0, j=0, mapLen=0, addr=0, cnts=0;
9072         u16 max_available_size=0, raw_cursize=0, raw_maxsize=0;
9073         int err;
9074         #ifdef CONFIG_IOL
9075         u8 org_fw_iol = padapter->registrypriv.fw_iol;// 0:Disable, 1:enable, 2:by usb speed
9076         #endif
9077         
9078         wrqu = (struct iw_point*)wdata;
9079         pwrctrlpriv = adapter_to_pwrctl(padapter);
9080         pEfuseHal = &pHalData->EfuseHal;
9081
9082         err = 0;
9083         data = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
9084         if (data == NULL)
9085         {
9086                 err = -ENOMEM;
9087                 goto exit;
9088         }
9089         rawdata = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
9090         if (rawdata == NULL)
9091         {
9092                 err = -ENOMEM;
9093                 goto exit;
9094         }
9095
9096         if (copy_from_user(extra, wrqu->pointer, wrqu->length))
9097         {
9098                 err = -EFAULT;
9099                 goto exit;
9100         }
9101         #ifdef CONFIG_LPS
9102         lps_mode = pwrctrlpriv->power_mgnt;//keep org value
9103         rtw_pm_set_lps(padapter,PS_MODE_ACTIVE);
9104         #endif  
9105         
9106         #ifdef CONFIG_IPS       
9107         ips_mode = pwrctrlpriv->ips_mode;//keep org value
9108         rtw_pm_set_ips(padapter,IPS_NONE);
9109         #endif  
9110         
9111         pch = extra;
9112         DBG_871X("%s: in=%s\n", __FUNCTION__, extra);
9113
9114         i = 0;
9115         //mac 16 "00e04c871200" rmap,00,2
9116         while ((token = strsep(&pch, ",")) != NULL)
9117         {
9118                 if (i > 2) break;
9119                 tmp[i] = token;
9120                 i++;
9121         }
9122         #ifdef CONFIG_IOL
9123         padapter->registrypriv.fw_iol = 0;// 0:Disable, 1:enable, 2:by usb speed
9124         #endif
9125         
9126         if(strcmp(tmp[0], "status") == 0){
9127                 sprintf(extra, "Load File efuse=%s,Load File MAC=%s",(pEEPROM->bloadfile_fail_flag? "FAIL" : "OK"),(pEEPROM->bloadmac_fail_flag? "FAIL" : "OK"));
9128
9129                   goto exit;
9130         }
9131         else if (strcmp(tmp[0], "drvmap") == 0)
9132         {
9133                 mapLen = EFUSE_MAP_SIZE;
9134                 
9135                 sprintf(extra, "\n");
9136                 for (i = 0; i < EFUSE_MAP_SIZE; i += 16)
9137                 {
9138 //                      DBG_871X("0x%02x\t", i);
9139                         sprintf(extra, "%s0x%02x\t", extra, i);
9140                         for (j=0; j<8; j++) {
9141 //                              DBG_871X("%02X ", data[i+j]);
9142                                 sprintf(extra, "%s%02X ", extra, PROMContent[i+j]);
9143                         }
9144 //                      DBG_871X("\t");
9145                         sprintf(extra, "%s\t", extra);
9146                         for (; j<16; j++) {
9147 //                              DBG_871X("%02X ", data[i+j]);
9148                                 sprintf(extra, "%s%02X ", extra, PROMContent[i+j]);
9149                         }
9150 //                      DBG_871X("\n");
9151                         sprintf(extra,"%s\n",extra);
9152                 }
9153 //              DBG_871X("\n");
9154         }
9155         else if (strcmp(tmp[0], "realmap") == 0)
9156         {
9157                 mapLen = EFUSE_MAP_SIZE;
9158                 if (rtw_efuse_map_read(padapter, EFUSE_WIFI , mapLen, pEfuseHal->fakeEfuseInitMap) == _FAIL)
9159                 {
9160                         DBG_871X("%s: read realmap Fail!!\n", __FUNCTION__);
9161                         err = -EFAULT;
9162                         goto exit;
9163                 }
9164
9165 //              DBG_871X("OFFSET\tVALUE(hex)\n");
9166                 sprintf(extra, "\n");
9167                 for (i = 0; i < EFUSE_MAP_SIZE; i += 16)
9168                 {
9169 //                      DBG_871X("0x%02x\t", i);
9170                         sprintf(extra, "%s0x%02x\t", extra, i);
9171                         for (j=0; j<8; j++) {
9172 //                              DBG_871X("%02X ", data[i+j]);
9173                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseInitMap[i+j]);
9174                         }
9175 //                      DBG_871X("\t");
9176                         sprintf(extra, "%s\t", extra);
9177                         for (; j<16; j++) {
9178 //                              DBG_871X("%02X ", data[i+j]);
9179                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseInitMap[i+j]);
9180                         }
9181 //                      DBG_871X("\n");
9182                         sprintf(extra,"%s\n",extra);
9183                 }
9184 //              DBG_871X("\n");
9185         }
9186         else if (strcmp(tmp[0], "rmap") == 0)
9187         {
9188                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9189                 {
9190                         DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9191                         err = -EINVAL;
9192                         goto exit;
9193                 }
9194
9195                 // rmap addr cnts
9196                 addr = simple_strtoul(tmp[1], &ptmp, 16);
9197                 DBG_871X("%s: addr=%x\n", __FUNCTION__, addr);
9198
9199                 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9200                 if (cnts == 0)
9201                 {
9202                         DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9203                         err = -EINVAL;
9204                         goto exit;
9205                 }
9206                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9207
9208                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (PVOID)&max_available_size, _FALSE);
9209                 if ((addr+ cnts) > max_available_size)
9210                 {
9211                         DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9212                         err = -EINVAL;
9213                         goto exit;
9214                 }
9215
9216                 if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL)
9217                 {
9218                         DBG_871X("%s: rtw_efuse_map_read error!\n", __FUNCTION__);
9219                         err = -EFAULT;
9220                         goto exit;
9221                 }
9222
9223 //              DBG_871X("%s: data={", __FUNCTION__);
9224                 *extra = 0;
9225                 for (i=0; i<cnts; i++) {
9226 //                      DBG_871X("0x%02x ", data[i]);
9227                         sprintf(extra, "%s0x%02X ", extra, data[i]);
9228                 }
9229 //              DBG_871X("}\n");
9230         }
9231         else if (strcmp(tmp[0], "realraw") == 0)
9232         {
9233                 addr = 0;
9234                 mapLen = EFUSE_MAX_SIZE;
9235                 if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL)
9236                 {
9237                         DBG_871X("%s: rtw_efuse_access Fail!!\n", __FUNCTION__);
9238                         err = -EFAULT;
9239                         goto exit;
9240                 }
9241                 _rtw_memset(extra,'\0',strlen(extra));
9242                 //              DBG_871X("%s: realraw={\n", __FUNCTION__);
9243                                 sprintf(extra, "\n0x00\t");
9244                                 for (i=0; i< mapLen; i++)
9245                                 {
9246                 //                      DBG_871X("%02X", rawdata[i]);
9247                                         sprintf(extra, "%s%02X", extra, rawdata[i]);
9248                                         if ((i & 0xF) == 0xF) {
9249                 //                              DBG_871X("\n");
9250                                                 sprintf(extra, "%s\n", extra);
9251                                                 sprintf(extra, "%s0x%02x\t", extra, i+1);
9252                                         }
9253                                         else if ((i & 0x7) == 0x7){
9254                 //                              DBG_871X("\t");
9255                                                 sprintf(extra, "%s \t", extra);
9256                                         } else {
9257                 //                              DBG_871X(" ");
9258                                                 sprintf(extra, "%s ", extra);
9259                                         }
9260                                 }
9261                 //              DBG_871X("}\n");
9262         }
9263         else if (strcmp(tmp[0], "mac") == 0)
9264         {
9265                 #ifdef CONFIG_RTL8192C
9266                 addr = EEPROM_MAC_ADDR_92C;
9267                 #endif // CONFIG_RTL8192C
9268                 #ifdef CONFIG_RTL8192D
9269                         #ifdef CONFIG_USB_HCI
9270                         if (pHalData->interfaceIndex == 0)
9271                                 addr = EEPROM_MAC_ADDR_MAC0_92DU;
9272                         else
9273                                 addr = EEPROM_MAC_ADDR_MAC1_92DU;
9274                         #else
9275                         if (pHalData->interfaceIndex == 0)
9276                                 addr = EEPROM_MAC_ADDR_MAC0_92DE;
9277                         else
9278                                 addr = EEPROM_MAC_ADDR_MAC1_92DE;
9279                         #endif
9280                 #endif // CONFIG_RTL8192D
9281                 #ifdef CONFIG_RTL8723A
9282                         #ifdef CONFIG_SDIO_HCI
9283                         addr = EEPROM_MAC_ADDR_8723AS;
9284                         #endif
9285                         #ifdef CONFIG_GSPI_HCI
9286                         addr = EEPROM_MAC_ADDR_8723AS;
9287                         #endif
9288                         #ifdef CONFIG_USB_HCI
9289                         addr = EEPROM_MAC_ADDR_8723AU;
9290                         #endif
9291                 #endif // CONFIG_RTL8723A
9292                 #ifdef CONFIG_RTL8188E
9293                         #ifdef CONFIG_USB_HCI
9294                         addr = EEPROM_MAC_ADDR_88EU;
9295                         #endif
9296                         #ifdef CONFIG_SDIO_HCI
9297                         addr = EEPROM_MAC_ADDR_88ES;
9298                         #endif
9299                         #ifdef CONFIG_PCI_HCI
9300                         addr = EEPROM_MAC_ADDR_88EE;
9301                         #endif
9302                 #endif // CONFIG_RTL8188E
9303
9304                 #ifdef CONFIG_RTL8192E
9305                         #ifdef CONFIG_USB_HCI
9306                         addr = EEPROM_MAC_ADDR_8192EU;
9307                         #endif
9308                         #ifdef CONFIG_SDIO_HCI
9309                         addr = EEPROM_MAC_ADDR_8192ES;
9310                         #endif
9311                         #ifdef CONFIG_PCI_HCI
9312                         addr = EEPROM_MAC_ADDR_8192EE;
9313                         #endif
9314                 #endif
9315                 #ifdef CONFIG_RTL8723B
9316                 #ifdef CONFIG_SDIO_HCI
9317                 addr = EEPROM_MAC_ADDR_8723BS;
9318                 #endif
9319                 #ifdef CONFIG_GSPI_HCI
9320                 addr = EEPROM_MAC_ADDR_8723BS;
9321                 #endif
9322                 #ifdef CONFIG_USB_HCI
9323                 addr = EEPROM_MAC_ADDR_8723BU;
9324                 #endif
9325                 #endif // CONFIG_RTL8723B
9326                 cnts = 6;
9327
9328                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
9329                 if ((addr + cnts) > max_available_size) {
9330                         DBG_871X("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9331                         err = -EFAULT;
9332                         goto exit;
9333                 }
9334
9335                 if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL)
9336                 {
9337                         DBG_871X("%s: rtw_efuse_map_read error!\n", __FUNCTION__);
9338                         err = -EFAULT;
9339                         goto exit;
9340                 }
9341
9342 //              DBG_871X("%s: MAC address={", __FUNCTION__);
9343                 *extra = 0;
9344                 for (i=0; i<cnts; i++)
9345                 {
9346 //                      DBG_871X("%02X", data[i]);
9347                         sprintf(extra, "%s%02X", extra, data[i]);
9348                         if (i != (cnts-1))
9349                         {
9350 //                              DBG_871X(":");
9351                                 sprintf(extra,"%s:",extra);
9352                         }
9353                 }
9354 //              DBG_871X("}\n");
9355         }
9356         else if (strcmp(tmp[0], "vidpid") == 0)
9357         {
9358                 #ifdef CONFIG_RTL8192C
9359                 addr = EEPROM_VID_92C;
9360                 #endif // CONFIG_RTL8192C
9361                 #ifdef CONFIG_RTL8192D
9362                         #ifdef CONFIG_USB_HCI
9363                         addr = EEPROM_VID_92DU;
9364                         #else
9365                         addr = EEPROM_VID_92DE;
9366                         #endif
9367                 #endif // CONFIG_RTL8192D
9368                 #ifdef CONFIG_RTL8723A
9369                         #ifdef CONFIG_USB_HCI
9370                         addr = EEPROM_VID_8723AU;
9371                         #endif
9372                 #endif // CONFIG_RTL8723A
9373                 #ifdef CONFIG_RTL8188E
9374                         #ifdef CONFIG_USB_HCI
9375                         addr = EEPROM_VID_88EU;
9376                         #endif
9377                         #ifdef CONFIG_PCI_HCI
9378                         addr = EEPROM_VID_88EE;
9379                         #endif
9380                 #endif // CONFIG_RTL8188E
9381
9382                 #ifdef CONFIG_RTL8192E
9383                         #ifdef CONFIG_USB_HCI
9384                         addr = EEPROM_VID_8192EU;
9385                         #endif
9386                         #ifdef CONFIG_PCI_HCI
9387                         addr = EEPROM_VID_8192EE;
9388                         #endif
9389                 #endif // CONFIG_RTL8192E
9390                 #ifdef CONFIG_RTL8723B
9391                 addr = EEPROM_VID_8723BU;
9392                 #endif // CONFIG_RTL8192E
9393                 cnts = 4;
9394
9395                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
9396                 if ((addr + cnts) > max_available_size)
9397                 {
9398                         DBG_871X("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9399                         err = -EFAULT;
9400                         goto exit;
9401                 }
9402                 if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL)
9403                 {
9404                         DBG_871X("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9405                         err = -EFAULT;
9406                         goto exit;
9407                 }
9408
9409 //              DBG_871X("%s: {VID,PID}={", __FUNCTION__);
9410                 *extra = 0;
9411                 for (i=0; i<cnts; i++)
9412                 {
9413 //                      DBG_871X("0x%02x", data[i]);
9414                         sprintf(extra, "%s0x%02X", extra, data[i]);
9415                         if (i != (cnts-1))
9416                         {
9417 //                              DBG_871X(",");
9418                                 sprintf(extra,"%s,",extra);
9419                         }
9420                 }
9421 //              DBG_871X("}\n");
9422         }
9423         else if (strcmp(tmp[0], "ableraw") == 0)
9424         {
9425                 efuse_GetCurrentSize(padapter,&raw_cursize);
9426                 raw_maxsize = efuse_GetMaxSize(padapter);
9427                 sprintf(extra, "[available raw size]= %d bytes", raw_maxsize-raw_cursize);
9428         }
9429         else if (strcmp(tmp[0], "btfmap") == 0)
9430         {
9431                 BTEfuse_PowerSwitch(padapter,1,_TRUE);
9432                                 
9433                 mapLen = EFUSE_BT_MAX_MAP_LEN;
9434                 if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL)
9435                 {
9436                         DBG_871X("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
9437                         err = -EFAULT;
9438                         goto exit;
9439                 }
9440
9441 //              DBG_871X("OFFSET\tVALUE(hex)\n");
9442                 sprintf(extra, "\n");
9443                 for (i=0; i<512; i+=16) // set 512 because the iwpriv's extra size have limit 0x7FF
9444                 {
9445 //                      DBG_871X("0x%03x\t", i);
9446                         sprintf(extra, "%s0x%03x\t", extra, i);
9447                         for (j=0; j<8; j++) {
9448 //                              DBG_871X("%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
9449                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
9450                         }
9451 //                      DBG_871X("\t");
9452                         sprintf(extra,"%s\t",extra);
9453                         for (; j<16; j++) {
9454 //                              DBG_871X("%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
9455                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
9456                         }
9457 //                      DBG_871X("\n");
9458                         sprintf(extra, "%s\n", extra);
9459                 }
9460 //              DBG_871X("\n");
9461         }
9462         else if (strcmp(tmp[0],"btbmap") == 0)
9463         {
9464                 BTEfuse_PowerSwitch(padapter,1,_TRUE);
9465                 
9466                 mapLen = EFUSE_BT_MAX_MAP_LEN;
9467                 if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL)
9468                 {
9469                         DBG_871X("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
9470                         err = -EFAULT;
9471                         goto exit;
9472                 }
9473
9474 //              DBG_871X("OFFSET\tVALUE(hex)\n");
9475                 sprintf(extra, "\n");
9476                 for (i=512; i<1024 ; i+=16)
9477                 {
9478 //                      DBG_871X("0x%03x\t", i);
9479                         sprintf(extra, "%s0x%03x\t", extra, i);
9480                         for (j=0; j<8; j++)
9481                         {
9482 //                              DBG_871X("%02X ", data[i+j]);
9483                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
9484                         }
9485 //                      DBG_871X("\t");
9486                         sprintf(extra,"%s\t",extra);
9487                         for (; j<16; j++) {
9488 //                              DBG_871X("%02X ", data[i+j]);
9489                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
9490                         }
9491 //                      DBG_871X("\n");
9492                         sprintf(extra, "%s\n", extra);
9493                 }
9494 //              DBG_871X("\n");
9495         }
9496         else if (strcmp(tmp[0],"btrmap") == 0)
9497         {
9498                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9499                 {
9500                         err = -EINVAL;
9501                         goto exit;
9502                 }
9503
9504                 BTEfuse_PowerSwitch(padapter,1,_TRUE);
9505                 
9506                 // rmap addr cnts
9507                 addr = simple_strtoul(tmp[1], &ptmp, 16);
9508                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
9509
9510                 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9511                 if (cnts == 0)
9512                 {
9513                         DBG_871X("%s: btrmap Fail!! cnts error!\n", __FUNCTION__);
9514                         err = -EINVAL;
9515                         goto exit;
9516                 }
9517                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9518
9519                 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
9520                 if ((addr + cnts) > max_available_size)
9521                 {
9522                         DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9523                         err = -EFAULT;
9524                         goto exit;
9525                 }
9526
9527                 if (rtw_BT_efuse_map_read(padapter, addr, cnts, data) == _FAIL) 
9528                 {
9529                         DBG_871X("%s: rtw_BT_efuse_map_read error!!\n", __FUNCTION__);
9530                         err = -EFAULT;
9531                         goto exit;
9532                 }
9533
9534                 *extra = 0;
9535 //              DBG_871X("%s: bt efuse data={", __FUNCTION__);
9536                 for (i=0; i<cnts; i++)
9537                 {
9538 //                      DBG_871X("0x%02x ", data[i]);
9539                         sprintf(extra, "%s 0x%02X ", extra, data[i]);
9540                 }
9541 //              DBG_871X("}\n");
9542                 DBG_871X(FUNC_ADPT_FMT ": BT MAC=[%s]\n", FUNC_ADPT_ARG(padapter), extra);
9543         }
9544         else if (strcmp(tmp[0], "btffake") == 0)
9545         {
9546 //              DBG_871X("OFFSET\tVALUE(hex)\n");
9547                 sprintf(extra, "\n");
9548                 for (i=0; i<512; i+=16)
9549                 {
9550 //                      DBG_871X("0x%03x\t", i);
9551                         sprintf(extra, "%s0x%03x\t", extra, i);
9552                         for (j=0; j<8; j++) {
9553 //                              DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9554                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9555                         }
9556 //                      DBG_871X("\t");
9557                         sprintf(extra, "%s\t", extra);
9558                         for (; j<16; j++) {
9559 //                              DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9560                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9561                         }
9562 //                      DBG_871X("\n");
9563                         sprintf(extra, "%s\n", extra);
9564                 }
9565 //              DBG_871X("\n");
9566         }
9567         else if (strcmp(tmp[0],"btbfake") == 0)
9568         {
9569 //              DBG_871X("OFFSET\tVALUE(hex)\n");
9570                 sprintf(extra, "\n");
9571                 for (i=512; i<1024; i+=16)
9572                 {
9573 //                      DBG_871X("0x%03x\t", i);
9574                         sprintf(extra, "%s0x%03x\t", extra, i);
9575                         for (j=0; j<8; j++) {
9576 //                              DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9577                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9578                         }
9579 //                      DBG_871X("\t");
9580                         sprintf(extra, "%s\t", extra);
9581                         for (; j<16; j++) {
9582 //                              DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9583                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9584                         }
9585 //                      DBG_871X("\n");
9586                         sprintf(extra, "%s\n", extra);
9587                 }
9588 //              DBG_871X("\n");
9589         }
9590         else if (strcmp(tmp[0],"wlrfkmap")== 0)
9591         {
9592 //              DBG_871X("OFFSET\tVALUE(hex)\n");
9593                 sprintf(extra, "\n");
9594                 for (i=0; i<EFUSE_MAP_SIZE; i+=16)
9595                 {
9596 //                      DBG_871X("\t0x%02x\t", i);
9597                         sprintf(extra, "%s0x%02x\t", extra, i);
9598                         for (j=0; j<8; j++) {
9599 //                              DBG_871X("%02X ", pEfuseHal->fakeEfuseModifiedMap[i+j]);
9600                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseModifiedMap[i+j]);
9601                         }
9602 //                      DBG_871X("\t");
9603                         sprintf(extra, "%s\t", extra);
9604                         for (; j<16; j++) {
9605 //                              DBG_871X("%02X ", pEfuseHal->fakeEfuseModifiedMap[i+j]);
9606                                 sprintf(extra, "%s %02X", extra, pEfuseHal->fakeEfuseModifiedMap[i+j]);
9607                         }
9608 //                      DBG_871X("\n");
9609                         sprintf(extra, "%s\n", extra);
9610                 }
9611 //              DBG_871X("\n");
9612
9613         }
9614         else if (strcmp(tmp[0],"wlrfkrmap")== 0)
9615         {
9616                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9617                                 {
9618                                         DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9619                                         err = -EINVAL;
9620                                         goto exit;
9621                                 }
9622                                 // rmap addr cnts
9623                                 addr = simple_strtoul(tmp[1], &ptmp, 16);
9624                                 DBG_871X("%s: addr=%x\n", __FUNCTION__, addr);
9625                 
9626                                 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9627                                 if (cnts == 0)
9628                                 {
9629                                         DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9630                                         err = -EINVAL;
9631                                         goto exit;
9632                                 }
9633                                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9634                 
9635                 //              DBG_871X("%s: data={", __FUNCTION__);
9636                         *extra = 0;
9637                         for (i=0; i<cnts; i++) {
9638                                         DBG_871X("wlrfkrmap = 0x%02x \n", pEfuseHal->fakeEfuseModifiedMap[addr+i]);
9639                                         sprintf(extra, "%s0x%02X ", extra, pEfuseHal->fakeEfuseModifiedMap[addr+i]);
9640                         }
9641         }
9642         else if (strcmp(tmp[0],"btrfkrmap")== 0)
9643         {
9644                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9645                                 {
9646                                         DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9647                                         err = -EINVAL;
9648                                         goto exit;
9649                                 }
9650                                 // rmap addr cnts
9651                                 addr = simple_strtoul(tmp[1], &ptmp, 16);
9652                                 DBG_871X("%s: addr=%x\n", __FUNCTION__, addr);
9653                 
9654                                 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9655                                 if (cnts == 0)
9656                                 {
9657                                         DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9658                                         err = -EINVAL;
9659                                         goto exit;
9660                                 }
9661                                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9662                 
9663                 //              DBG_871X("%s: data={", __FUNCTION__);
9664                         *extra = 0;
9665                         for (i=0; i<cnts; i++) {
9666                                         DBG_871X("wlrfkrmap = 0x%02x \n", pEfuseHal->fakeBTEfuseModifiedMap[addr+i]);
9667                                         sprintf(extra, "%s0x%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[addr+i]);
9668                         }
9669         }
9670         else
9671         {
9672                  sprintf(extra, "Command not found!");
9673         }
9674
9675 exit:
9676         if (data)
9677                 rtw_mfree(data, EFUSE_BT_MAX_MAP_LEN);
9678         if (rawdata)
9679                 rtw_mfree(rawdata, EFUSE_BT_MAX_MAP_LEN);
9680         if (!err)
9681                 wrqu->length = strlen(extra);
9682         
9683         if (padapter->registrypriv.mp_mode == 0)
9684         {
9685         #ifdef CONFIG_IPS               
9686         rtw_pm_set_ips(padapter, ips_mode);
9687 #endif // CONFIG_IPS
9688
9689         #ifdef CONFIG_LPS       
9690         rtw_pm_set_lps(padapter, lps_mode);
9691 #endif // CONFIG_LPS
9692         }
9693
9694         #ifdef CONFIG_IOL
9695         padapter->registrypriv.fw_iol = org_fw_iol;// 0:Disable, 1:enable, 2:by usb speed
9696         #endif
9697         return err;
9698 }
9699
9700 static int rtw_mp_efuse_set(struct net_device *dev,
9701                         struct iw_request_info *info,
9702                         union iwreq_data *wdata, char *extra)
9703 {
9704         struct iw_point *wrqu;
9705         PADAPTER padapter;
9706         struct pwrctrl_priv *pwrctrlpriv ;
9707         PHAL_DATA_TYPE pHalData;
9708         PEFUSE_HAL pEfuseHal;
9709         struct mp_priv *pmppriv;
9710         
9711         u8 ips_mode = IPS_NUM; // init invalid value
9712         u8 lps_mode = PS_MODE_NUM; // init invalid value
9713         u32 i=0,j=0, jj, kk;
9714         u8 *setdata = NULL;
9715         u8 *ShadowMapBT = NULL;
9716         u8 *ShadowMapWiFi = NULL;
9717         u8 *setrawdata = NULL;
9718         char *pch, *ptmp, *token, *tmp[3]={0x00,0x00,0x00};
9719         u16 addr=0, cnts=0, BTStatus=0 , max_available_size=0;
9720         int err;
9721
9722         wrqu = (struct iw_point*)wdata;
9723         padapter = rtw_netdev_priv(dev);
9724         pwrctrlpriv = adapter_to_pwrctl(padapter);
9725         pHalData = GET_HAL_DATA(padapter);
9726         pEfuseHal = &pHalData->EfuseHal;
9727         pmppriv = &padapter->mppriv;
9728         
9729         err = 0;
9730         
9731         if (copy_from_user(extra, wrqu->pointer, wrqu->length))
9732                         return -EFAULT;
9733                         
9734         setdata = rtw_zmalloc(1024);
9735         if (setdata == NULL)
9736         {
9737                 err = -ENOMEM;
9738                 goto exit;
9739         }
9740         ShadowMapBT = rtw_malloc(EFUSE_BT_MAX_MAP_LEN);
9741         if (ShadowMapBT == NULL)
9742         {
9743                 err = -ENOMEM;
9744                 goto exit;
9745         }
9746         ShadowMapWiFi = rtw_malloc(EFUSE_MAP_SIZE);
9747         if (ShadowMapWiFi == NULL)
9748         {
9749                 err = -ENOMEM;
9750                 goto exit;
9751         }
9752         setrawdata = rtw_malloc(EFUSE_MAX_SIZE);
9753         if (setrawdata == NULL)
9754         {
9755                 err = -ENOMEM;
9756                 goto exit;
9757         }
9758
9759         #ifdef CONFIG_LPS
9760         lps_mode = pwrctrlpriv->power_mgnt;//keep org value
9761         rtw_pm_set_lps(padapter,PS_MODE_ACTIVE);
9762         #endif  
9763         
9764         #ifdef CONFIG_IPS       
9765         ips_mode = pwrctrlpriv->ips_mode;//keep org value
9766         rtw_pm_set_ips(padapter,IPS_NONE);
9767         #endif  
9768                         
9769         pch = extra;
9770         DBG_871X("%s: in=%s\n", __FUNCTION__, extra);
9771         
9772         i = 0;
9773         while ((token = strsep(&pch, ",")) != NULL)
9774         {
9775                 if (i > 2) break;
9776                 tmp[i] = token;
9777                 i++;
9778         }
9779
9780         // tmp[0],[1],[2]
9781         // wmap,addr,00e04c871200
9782         if (strcmp(tmp[0], "wmap") == 0)
9783         {
9784 #if defined(CONFIG_RTL8188E) || defined(CONFIG_USB_HCI)
9785                 if(pmppriv->bPreBrunEfuse==_FALSE)
9786                         Rtw_EfuseChkPreBurn8188ESerial(padapter);
9787 #endif          
9788                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9789                 {
9790                         err = -EINVAL;
9791                         goto exit;
9792                 }
9793 #if 1
9794                 // unknown bug workaround, need to fix later
9795                 addr=0x1ff;
9796                 rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff));
9797                 rtw_msleep_os(10);
9798                 rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03));
9799                 rtw_msleep_os(10);
9800                 rtw_write8(padapter, EFUSE_CTRL+3, 0x72);
9801                 rtw_msleep_os(10);
9802                 rtw_read8(padapter, EFUSE_CTRL);
9803 #endif
9804
9805                 addr = simple_strtoul(tmp[1], &ptmp, 16);
9806                 addr &= 0xFFF;
9807
9808                 cnts = strlen(tmp[2]);
9809                 if (cnts%2)
9810                 {
9811                         err = -EINVAL;
9812                         goto exit;
9813                 }
9814                 cnts /= 2;
9815                 if (cnts == 0)
9816                 {
9817                         err = -EINVAL;
9818                         goto exit;
9819                 }
9820                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
9821                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9822                 DBG_871X("%s: map data=%s\n", __FUNCTION__, tmp[2]);
9823                                 
9824                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
9825                 {
9826                         setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
9827                 }
9828 #ifndef CONFIG_RTL8188E
9829                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
9830 #else
9831                 //Change to check TYPE_EFUSE_MAP_LEN ,beacuse 8188E raw 256,logic map over 256.
9832                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_size, _FALSE);
9833 #endif
9834                 if ((addr+cnts) > max_available_size)
9835                 {
9836                         DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9837                         err = -EFAULT;
9838                         goto exit;
9839                 }
9840
9841                 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
9842                 {
9843                         DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9844                         err = -EFAULT;
9845                         goto exit;
9846                 }
9847                 *extra = 0;
9848                 DBG_871X("%s: after rtw_BT_efuse_map_write to _rtw_memcmp \n", __FUNCTION__);
9849                 if ( (rtw_efuse_map_read(padapter, addr, cnts, ShadowMapWiFi) == _SUCCESS ) )
9850                 {
9851                         if (_rtw_memcmp((void*)ShadowMapWiFi ,(void*)setdata,cnts))
9852                         { 
9853                                 DBG_871X("%s: WiFi write map afterf compare success\n", __FUNCTION__);
9854                                 sprintf(extra, "WiFi write map compare OK\n");
9855                                 err = 0;
9856                                 goto exit;
9857                         }
9858                         else
9859                         {
9860                                 sprintf(extra, "WiFi write map compare FAIL\n");
9861                                 DBG_871X("%s: WiFi write map compare Fail\n", __FUNCTION__);
9862                                 err = 0;
9863                                 goto exit;
9864                         }
9865                 }
9866         }
9867         else if (strcmp(tmp[0], "wraw") == 0)
9868         {
9869                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9870                 {
9871                         err = -EINVAL;
9872                         goto exit;
9873                 }
9874
9875                 addr = simple_strtoul( tmp[1], &ptmp, 16 );
9876                 addr &= 0xFFF;
9877
9878                 cnts = strlen(tmp[2]);
9879                 if (cnts%2)
9880                 {
9881                         err = -EINVAL;
9882                         goto exit;
9883                 }
9884                 cnts /= 2;
9885                 if (cnts == 0)
9886                 {
9887                         err = -EINVAL;
9888                         goto exit;
9889                 }
9890
9891                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
9892                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9893                 DBG_871X("%s: raw data=%s\n", __FUNCTION__, tmp[2]);
9894
9895                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
9896                 {
9897                         setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
9898                 }
9899
9900                 if (rtw_efuse_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL)
9901                 {
9902                         DBG_871X("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9903                         err = -EFAULT;
9904                         goto exit;
9905                 }
9906         }
9907         else if (strcmp(tmp[0], "mac") == 0)
9908         {
9909                 if (tmp[1]==NULL)
9910                 {
9911                         err = -EINVAL;
9912                         goto exit;
9913                 }
9914
9915                 //mac,00e04c871200
9916                 #ifdef CONFIG_RTL8192C
9917                 addr = EEPROM_MAC_ADDR_92C;
9918                 #endif
9919                 #ifdef CONFIG_RTL8192D
9920                         #ifdef CONFIG_USB_HCI
9921                         if (pHalData->interfaceIndex == 0)
9922                                 addr = EEPROM_MAC_ADDR_MAC0_92DU;
9923                         else
9924                                 addr = EEPROM_MAC_ADDR_MAC1_92DU;
9925                         #else
9926                         if (pHalData->interfaceIndex == 0)
9927                                 addr = EEPROM_MAC_ADDR_MAC0_92DE;
9928                         else
9929                                 addr = EEPROM_MAC_ADDR_MAC1_92DE;
9930                         #endif
9931                 #endif
9932                 #ifdef CONFIG_RTL8723A
9933                 #ifdef CONFIG_SDIO_HCI
9934                 addr = EEPROM_MAC_ADDR_8723AS;
9935                 #endif
9936                 #ifdef CONFIG_GSPI_HCI
9937                 addr = EEPROM_MAC_ADDR_8723AS;
9938                 #endif
9939                 #ifdef CONFIG_USB_HCI
9940                 addr = EEPROM_MAC_ADDR_8723AU;
9941                 #endif
9942                 #endif // CONFIG_RTL8723A
9943                 #ifdef CONFIG_RTL8188E
9944                         #ifdef CONFIG_USB_HCI
9945                         addr = EEPROM_MAC_ADDR_88EU;
9946                         #endif
9947                         #ifdef CONFIG_SDIO_HCI
9948                         addr = EEPROM_MAC_ADDR_88ES;
9949                         #endif
9950                         #ifdef CONFIG_PCI_HCI
9951                         addr = EEPROM_MAC_ADDR_88EE;
9952                         #endif
9953                 #endif //#ifdef CONFIG_RTL8188E
9954
9955                 #ifdef CONFIG_RTL8192E
9956                         #ifdef CONFIG_USB_HCI
9957                         addr = EEPROM_MAC_ADDR_8192EU;
9958                         #endif
9959                         #ifdef CONFIG_SDIO_HCI
9960                         addr = EEPROM_MAC_ADDR_8192ES;
9961                         #endif
9962                         #ifdef CONFIG_PCI_HCI
9963                         addr = EEPROM_MAC_ADDR_8192EE;
9964                         #endif
9965                 #endif //#ifdef CONFIG_RTL8192E
9966                 
9967                 #ifdef CONFIG_RTL8723B
9968                 #ifdef CONFIG_SDIO_HCI
9969                 addr = EEPROM_MAC_ADDR_8723BS;
9970                 #endif
9971                 #ifdef CONFIG_GSPI_HCI
9972                 addr = EEPROM_MAC_ADDR_8723BS;
9973                 #endif
9974                 #ifdef CONFIG_USB_HCI
9975                 addr = EEPROM_MAC_ADDR_8723BU;
9976                 #endif
9977                 #endif // CONFIG_RTL8723B
9978
9979                 cnts = strlen(tmp[1]);
9980                 if (cnts%2)
9981                 {
9982                         err = -EINVAL;
9983                         goto exit;
9984                 }
9985                 cnts /= 2;
9986                 if (cnts == 0)
9987                 {
9988                         err = -EINVAL;
9989                         goto exit;
9990                 }
9991                 if (cnts > 6)
9992                 {
9993                         DBG_871X("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]);
9994                         err = -EFAULT;
9995                         goto exit;
9996                 }
9997
9998                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
9999                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10000                 DBG_871X("%s: MAC address=%s\n", __FUNCTION__, tmp[1]);
10001
10002                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10003                 {
10004                         setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
10005                 }
10006 #ifndef CONFIG_RTL8188E
10007                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
10008 #else
10009                 //Change to check TYPE_EFUSE_MAP_LEN ,beacuse 8188E raw 256,logic map over 256.
10010                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_size, _FALSE);
10011 #endif
10012                 if ((addr+cnts) > max_available_size)
10013                 {
10014                         DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10015                         err = -EFAULT;
10016                         goto exit;
10017                 }
10018
10019                 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
10020                 {
10021                         DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
10022                         err = -EFAULT;
10023                         goto exit;
10024                 }
10025         }
10026         else if (strcmp(tmp[0], "vidpid") == 0)
10027         {
10028                 if (tmp[1]==NULL)
10029                 {
10030                         err = -EINVAL;
10031                         goto exit;
10032                 }
10033
10034                 // pidvid,da0b7881
10035                 #ifdef CONFIG_RTL8192C
10036                 addr = EEPROM_VID_92C;
10037                 #endif // CONFIG_RTL8192C
10038                 #ifdef CONFIG_RTL8192D
10039                         #ifdef CONFIG_USB_HCI
10040                         addr = EEPROM_VID_92DU;
10041                         #else
10042                         addr = EEPROM_VID_92DE;
10043                         #endif
10044                 #endif // CONFIG_RTL8192D
10045                 #ifdef CONFIG_RTL8723A
10046                         #ifdef CONFIG_USB_HCI
10047                         addr = EEPROM_VID_8723AU;
10048                         #endif
10049                 #endif // CONFIG_RTL8723A
10050                 #ifdef CONFIG_RTL8188E
10051                         #ifdef CONFIG_USB_HCI
10052                         addr = EEPROM_VID_88EU;
10053                         #endif
10054                         #ifdef CONFIG_PCI_HCI
10055                         addr = EEPROM_VID_88EE;
10056                         #endif
10057                 #endif // CONFIG_RTL8188E
10058
10059                 #ifdef CONFIG_RTL8192E
10060                         #ifdef CONFIG_USB_HCI
10061                         addr = EEPROM_VID_8192EU;
10062                         #endif
10063                         #ifdef CONFIG_PCI_HCI
10064                         addr = EEPROM_VID_8192EE;
10065                         #endif
10066                 #endif // CONFIG_RTL8188E
10067
10068                 #ifdef CONFIG_RTL8723B
10069                 addr = EEPROM_VID_8723BU;
10070                 #endif
10071                 
10072                 cnts = strlen(tmp[1]);
10073                 if (cnts%2)
10074                 {
10075                         err = -EINVAL;
10076                         goto exit;
10077                 }
10078                 cnts /= 2;
10079                 if (cnts == 0)
10080                 {
10081                         err = -EINVAL;
10082                         goto exit;
10083                 }
10084
10085                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10086                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10087                 DBG_871X("%s: VID/PID=%s\n", __FUNCTION__, tmp[1]);
10088
10089                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10090                 {
10091                         setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
10092                 }
10093
10094                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
10095                 if ((addr+cnts) > max_available_size)
10096                 {
10097                         DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10098                         err = -EFAULT;
10099                         goto exit;
10100                 }
10101
10102                 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
10103                 {
10104                         DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
10105                         err = -EFAULT;
10106                         goto exit;
10107                 }
10108         }
10109         else if (strcmp(tmp[0], "wldumpfake") == 0)
10110         {
10111                 if (rtw_efuse_map_read(padapter, 0, EFUSE_MAP_SIZE,  pEfuseHal->fakeEfuseModifiedMap) == _SUCCESS) {
10112                         DBG_871X("%s: WiFi hw efuse dump to Fake map success \n", __FUNCTION__); 
10113                 } else {
10114                         DBG_871X("%s: WiFi hw efuse dump to Fake map Fail \n", __FUNCTION__);
10115                         err = -EFAULT;
10116                 }
10117         }
10118         else if (strcmp(tmp[0], "btwmap") == 0)
10119         {
10120                 rtw_write8(padapter, 0xa3, 0x05); //For 8723AB ,8821S ?
10121                 BTStatus=rtw_read8(padapter, 0xa0);
10122                 DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus);
10123                 if (BTStatus != 0x04)
10124                 {
10125                         sprintf(extra, "BT Status not Active Write FAIL\n");
10126                         goto exit;
10127                 }
10128
10129                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10130                 {
10131                         err = -EINVAL;
10132                         goto exit;
10133                 }
10134                 BTEfuse_PowerSwitch(padapter,1,_TRUE);
10135                 
10136                 addr=0x1ff;
10137                 rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff));
10138                 rtw_msleep_os(10);
10139                 rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03));
10140                 rtw_msleep_os(10);
10141                 rtw_write8(padapter, EFUSE_CTRL+3, 0x72);
10142                 rtw_msleep_os(10);
10143                 rtw_read8(padapter, EFUSE_CTRL);
10144
10145                 addr = simple_strtoul(tmp[1], &ptmp, 16);
10146                 addr &= 0xFFF;
10147
10148                 cnts = strlen(tmp[2]);
10149                 if (cnts%2)
10150                 {
10151                         err = -EINVAL;
10152                         goto exit;
10153                 }
10154                 cnts /= 2;
10155                 if (cnts == 0)
10156                 {
10157                         err = -EINVAL;
10158                         goto exit;
10159                 }
10160
10161                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10162                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10163                 DBG_871X("%s: BT data=%s\n", __FUNCTION__, tmp[2]);
10164
10165                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10166                 {
10167                         setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
10168                 }
10169
10170                 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
10171                 if ((addr+cnts) > max_available_size)
10172                 {
10173                         DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10174                         err = -EFAULT;
10175                         goto exit;
10176                 }
10177
10178                 if (rtw_BT_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
10179                 {
10180                         DBG_871X("%s: rtw_BT_efuse_map_write error!!\n", __FUNCTION__);
10181                         err = -EFAULT;
10182                         goto exit;
10183                 }
10184                 *extra = 0;
10185                 DBG_871X("%s: after rtw_BT_efuse_map_write to _rtw_memcmp \n", __FUNCTION__);
10186                 if ( (rtw_BT_efuse_map_read(padapter, addr, cnts, ShadowMapBT ) == _SUCCESS ) )
10187                 {
10188                         if (_rtw_memcmp((void*)ShadowMapBT ,(void*)setdata,cnts))
10189                         { 
10190                                 DBG_871X("%s: BT write map compare OK BTStatus=0x%x\n", __FUNCTION__,BTStatus);
10191                                 sprintf(extra, "BT write map compare OK");
10192                                 err = 0;
10193                                 goto exit;
10194                         }
10195                         else
10196                         {
10197                                 sprintf(extra, "BT write map compare FAIL");
10198                                 DBG_871X("%s: BT write map compare FAIL BTStatus=0x%x\n", __FUNCTION__,BTStatus);
10199                                 err = 0;
10200                                 goto exit;
10201                         }
10202                 }
10203         }
10204         else if (strcmp(tmp[0], "btwfake") == 0)
10205         {
10206                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10207                 {
10208                         err = -EINVAL;
10209                         goto exit;
10210                 }
10211
10212                 addr = simple_strtoul(tmp[1], &ptmp, 16);
10213                 addr &= 0xFFF;
10214
10215                 cnts = strlen(tmp[2]);
10216                 if (cnts%2)
10217                 {
10218                         err = -EINVAL;
10219                         goto exit;
10220                 }
10221                 cnts /= 2;
10222                 if (cnts == 0)
10223                 {
10224                         err = -EINVAL;
10225                         goto exit;
10226                 }
10227
10228                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10229                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10230                 DBG_871X("%s: BT tmp data=%s\n", __FUNCTION__, tmp[2]);
10231                                 
10232                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10233                 {
10234                         pEfuseHal->fakeBTEfuseModifiedMap[addr+jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
10235                 }
10236         }
10237         else if (strcmp(tmp[0], "btdumpfake") == 0)
10238         {
10239                 if (rtw_BT_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _SUCCESS) {
10240                         DBG_871X("%s: BT read all map success\n", __FUNCTION__);
10241                 } else {
10242                         DBG_871X("%s: BT read all map Fail!\n", __FUNCTION__);
10243                         err = -EFAULT;
10244                 }
10245         }
10246         else if (strcmp(tmp[0], "btfk2map") == 0)
10247         {
10248                 rtw_write8(padapter, 0xa3, 0x05);
10249                 BTStatus=rtw_read8(padapter, 0xa0);
10250                 DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus);
10251                 if (BTStatus != 0x04)
10252                 {
10253                         sprintf(extra, "BT Status not Active Write FAIL\n");
10254                         goto exit;
10255                 }
10256                 
10257                 BTEfuse_PowerSwitch(padapter,1,_TRUE);
10258
10259                 addr=0x1ff;
10260                 rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff));
10261                 rtw_msleep_os(10);
10262                 rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03));
10263                 rtw_msleep_os(10);
10264                 rtw_write8(padapter, EFUSE_CTRL+3, 0x72);
10265                 rtw_msleep_os(10);
10266                 rtw_read8(padapter, EFUSE_CTRL);
10267
10268                 _rtw_memcpy(pEfuseHal->BTEfuseModifiedMap, pEfuseHal->fakeBTEfuseModifiedMap, EFUSE_BT_MAX_MAP_LEN);
10269                         
10270                 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);     
10271                 if (max_available_size < 1)
10272                 {
10273                         err = -EFAULT;
10274                         goto exit;
10275                 }
10276
10277                 if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL)
10278                 {
10279                         DBG_871X("%s: rtw_BT_efuse_map_write error!\n", __FUNCTION__);
10280                         err = -EFAULT;
10281                         goto exit;
10282                 }
10283                 
10284                 DBG_871X("pEfuseHal->fakeBTEfuseModifiedMap OFFSET\tVALUE(hex)\n");
10285                 for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16)
10286                 {
10287                         printk("0x%02x\t", i);
10288                         for (j=0; j<8; j++) {
10289                                 printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10290                         }
10291                         printk("\t");
10292
10293                         for (; j<16; j++) {
10294                                 printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10295                         }
10296                         printk("\n");
10297                 }
10298                 printk("\n");
10299 #if 1           
10300                 err = -EFAULT;
10301                 DBG_871X("%s: rtw_BT_efuse_map_read _rtw_memcmp \n", __FUNCTION__);
10302                 if ( (rtw_BT_efuse_map_read(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS ) )
10303                 { 
10304                         if (_rtw_memcmp((void*)pEfuseHal->fakeBTEfuseModifiedMap,(void*)pEfuseHal->fakeBTEfuseInitMap,EFUSE_BT_MAX_MAP_LEN))
10305                         { 
10306                                 sprintf(extra, "BT write map compare OK");
10307                                 DBG_871X("%s: BT write map afterf compare success BTStatus=0x%x \n", __FUNCTION__,BTStatus);
10308                                 err = 0;
10309                                 goto exit;
10310                         }
10311                         else
10312                         {
10313                                 sprintf(extra, "BT write map compare FAIL");
10314                                 if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL)
10315                                 {
10316                                         DBG_871X("%s: rtw_BT_efuse_map_write compare error,retry = %d!\n", __FUNCTION__,i);
10317                                 }
10318
10319                                 if (rtw_BT_efuse_map_read(padapter, EFUSE_BT, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS)
10320                                 {
10321                                         DBG_871X("pEfuseHal->fakeBTEfuseInitMap OFFSET\tVALUE(hex)\n");
10322
10323                                         for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16)
10324                                         {
10325                                                 printk("0x%02x\t", i);
10326                                                 for (j=0; j<8; j++) {
10327                                                         printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i+j]);
10328                                                 }
10329                                                 printk("\t");
10330                                                 for (; j<16; j++) {
10331                                                         printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i+j]);
10332                                                 }
10333                                                 printk("\n");
10334                                         }
10335                                         printk("\n"); 
10336                                 }
10337                                 DBG_871X("%s: BT write map afterf compare not match to write efuse try write Map again , BTStatus=0x%x\n", __FUNCTION__,BTStatus);      
10338                                 goto exit;
10339                         }
10340                 }
10341 #endif
10342
10343         }
10344         else if (strcmp(tmp[0], "wlfk2map") == 0)
10345         {
10346                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);                                   
10347                 if (max_available_size < 1)
10348                 {
10349                         err = -EFAULT;
10350                         goto exit;
10351                 }
10352                 if (rtw_efuse_map_write(padapter, 0x00, EFUSE_MAP_SIZE, pEfuseHal->fakeEfuseModifiedMap) == _FAIL)
10353                 {
10354                         DBG_871X("%s: rtw_efuse_map_write fakeEfuseModifiedMap error!\n", __FUNCTION__);
10355                         err = -EFAULT;
10356                         goto exit;
10357                 }
10358                 *extra = 0;
10359                 DBG_871X("%s: after rtw_BT_efuse_map_write to _rtw_memcmp \n", __FUNCTION__);
10360                 if ( (rtw_efuse_map_read(padapter, 0x00, EFUSE_MAP_SIZE, ShadowMapWiFi) == _SUCCESS ) )
10361                 {
10362                         if (_rtw_memcmp((void*)ShadowMapWiFi ,(void*)setdata,cnts))
10363                         {
10364                                 DBG_871X("%s: WiFi write map afterf compare OK\n", __FUNCTION__);
10365                                 sprintf(extra, "WiFi write map compare OK\n");
10366                                 err = 0;
10367                                 goto exit;
10368                         }
10369                         else
10370                         {
10371                                 sprintf(extra, "WiFi write map compare FAIL\n");
10372                                 DBG_871X("%s: WiFi write map compare Fail\n", __FUNCTION__);
10373                                 err = 0;
10374                                 goto exit;
10375                         }
10376                 }
10377         }
10378         else if (strcmp(tmp[0], "wlwfake") == 0)
10379         {
10380                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10381                 {
10382                         err = -EINVAL;
10383                         goto exit;
10384                 }
10385
10386                 addr = simple_strtoul(tmp[1], &ptmp, 16);
10387                 addr &= 0xFFF;
10388
10389                 cnts = strlen(tmp[2]);
10390                 if (cnts%2)
10391                 {
10392                         err = -EINVAL;
10393                         goto exit;
10394                 }
10395                 cnts /= 2;
10396                 if (cnts == 0)
10397                 {
10398                         err = -EINVAL;
10399                         goto exit;
10400                 }
10401
10402                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10403                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10404                 DBG_871X("%s: map tmp data=%s\n", __FUNCTION__, tmp[2]);
10405
10406                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10407                 {
10408                         pEfuseHal->fakeEfuseModifiedMap[addr+jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
10409                 }
10410         }
10411
10412 exit:
10413         if (setdata)
10414                 rtw_mfree(setdata, 1024);
10415         if (ShadowMapBT)
10416                 rtw_mfree(ShadowMapBT, EFUSE_BT_MAX_MAP_LEN);
10417         if (ShadowMapWiFi)
10418                 rtw_mfree(ShadowMapWiFi, EFUSE_MAP_SIZE);
10419         if (setrawdata)
10420                 rtw_mfree(setrawdata, EFUSE_MAX_SIZE);
10421         
10422         wrqu->length = strlen(extra);
10423
10424         if (padapter->registrypriv.mp_mode == 0)
10425         {
10426         #ifdef CONFIG_IPS               
10427         rtw_pm_set_ips(padapter, ips_mode);
10428         #endif // CONFIG_IPS
10429
10430         #ifdef CONFIG_LPS       
10431         rtw_pm_set_lps(padapter, lps_mode);
10432         #endif // CONFIG_LPS
10433         }
10434
10435         return err;
10436 }
10437
10438 #if defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT)
10439 /*
10440  * Input Format: %s,%d,%d
10441  *      %s is width, could be
10442  *              "b" for 1 byte
10443  *              "w" for WORD (2 bytes)
10444  *              "dw" for DWORD (4 bytes)
10445  *      1st %d is address(offset)
10446  *      2st %d is data to write
10447  */
10448 static int rtw_mp_write_reg(struct net_device *dev,
10449                         struct iw_request_info *info,
10450                         struct iw_point *wrqu, char *extra)
10451 {
10452         char *pch, *pnext, *ptmp;
10453         char *width_str;
10454         char width;
10455         u32 addr, data;
10456         int ret;
10457         PADAPTER padapter = rtw_netdev_priv(dev);
10458         char input[wrqu->length];
10459
10460         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10461                                  return -EFAULT;
10462                                  
10463         _rtw_memset(extra, 0, wrqu->length);    
10464           
10465         pch = input;
10466
10467         pnext = strpbrk(pch, " ,.-");
10468         if (pnext == NULL) return -EINVAL;
10469         *pnext = 0;
10470         width_str = pch;
10471
10472         pch = pnext + 1;
10473         pnext = strpbrk(pch, " ,.-");
10474         if (pnext == NULL) return -EINVAL;
10475         *pnext = 0;
10476         addr = simple_strtoul(pch, &ptmp, 16);
10477         if (addr > 0x3FFF) return -EINVAL;
10478
10479         pch = pnext + 1;
10480         if ((pch - extra) >= wrqu->length) return -EINVAL;
10481         data = simple_strtoul(pch, &ptmp, 16);
10482
10483         ret = 0;
10484         width = width_str[0];
10485         switch (width) {
10486                 case 'b':
10487                         // 1 byte
10488                         if (data > 0xFF) {
10489                                 ret = -EINVAL;
10490                                 break;
10491                         }
10492                         rtw_write8(padapter, addr, data);
10493                         break;
10494                 case 'w':
10495                         // 2 bytes
10496                         if (data > 0xFFFF) {
10497                                 ret = -EINVAL;
10498                                 break;
10499                         }
10500                         rtw_write16(padapter, addr, data);
10501                         break;
10502                 case 'd':
10503                         // 4 bytes
10504                         rtw_write32(padapter, addr, data);
10505                         break;
10506                 default:
10507                         ret = -EINVAL;
10508                         break;
10509         }
10510
10511         return ret;
10512 }
10513
10514 /*
10515  * Input Format: %s,%d
10516  *      %s is width, could be
10517  *              "b" for 1 byte
10518  *              "w" for WORD (2 bytes)
10519  *              "dw" for DWORD (4 bytes)
10520  *      %d is address(offset)
10521  *
10522  * Return:
10523  *      %d for data readed
10524  */
10525 static int rtw_mp_read_reg(struct net_device *dev,
10526                         struct iw_request_info *info,
10527                         struct iw_point *wrqu, char *extra)
10528 {
10529         char input[wrqu->length];
10530         char *pch, *pnext, *ptmp;
10531         char *width_str;
10532         char width;
10533         char data[20],tmp[20];
10534         u32 addr;
10535         //u32 *data = (u32*)extra;
10536         u32 ret, i=0, j=0, strtout=0;
10537         PADAPTER padapter = rtw_netdev_priv(dev);
10538
10539
10540         if (wrqu->length > 128) 
10541                 return -EFAULT;
10542
10543         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10544                 return -EFAULT;
10545
10546         _rtw_memset(data, 0, 20);
10547         _rtw_memset(tmp, 0, 20);
10548         _rtw_memset(extra, 0, wrqu->length);
10549
10550         pch = input;
10551         pnext = strpbrk(pch, " ,.-");
10552         if (pnext == NULL) return -EINVAL;
10553         *pnext = 0;
10554         width_str = pch;
10555
10556         pch = pnext + 1;
10557         if ((pch - input) >= wrqu->length) return -EINVAL;
10558         
10559         addr = simple_strtoul(pch, &ptmp, 16);
10560         if (addr > 0x3FFF) return -EINVAL;
10561
10562         ret = 0;
10563         width = width_str[0];
10564         switch (width)
10565         {
10566                 case 'b':
10567                         // 1 byte
10568                         // *(u8*)data = rtw_read8(padapter, addr);
10569                         sprintf(extra, "%d\n",  rtw_read8(padapter, addr));
10570                         wrqu->length = strlen(extra);
10571                         break;
10572                 case 'w':
10573                         // 2 bytes
10574                         //*(u16*)data = rtw_read16(padapter, addr);
10575                         sprintf(data, "%04x\n", rtw_read16(padapter, addr));
10576                         for( i=0 ; i <= strlen(data) ; i++)
10577                                 {
10578                                           if( i%2==0 )
10579                                           {
10580                                                    tmp[j]=' ';
10581                                                    j++;
10582                                           }
10583                                           if ( data[i] != '\0' )
10584                                                  tmp[j] = data[i];
10585                                                 
10586                                                  j++;
10587                                 }
10588                                 pch = tmp;              
10589                                 DBG_871X("pch=%s",pch);
10590                                 
10591                                 while( *pch != '\0' )
10592                                 {
10593                                         pnext = strpbrk(pch, " ");
10594                                         if (!pnext)
10595                                                 break;
10596                                         
10597                                         pnext++;
10598                                         if ( *pnext != '\0' )
10599                                         {
10600                                                   strtout = simple_strtoul (pnext , &ptmp, 16);
10601                                                   sprintf( extra, "%s %d" ,extra ,strtout );
10602                                         }
10603                                         else{
10604                                                   break;
10605                                         }
10606                                         pch = pnext;
10607                                 }
10608                         wrqu->length = 7;
10609                         break;
10610                 case 'd':
10611                         // 4 bytes
10612                         //*data = rtw_read32(padapter, addr);
10613                         sprintf(data, "%08x", rtw_read32(padapter, addr));
10614                                 //add read data format blank
10615                                 for( i=0 ; i <= strlen(data) ; i++)
10616                                 {
10617                                           if( i%2==0 )
10618                                           {
10619                                                    tmp[j]=' ';
10620                                                    j++;
10621                                           }
10622                                           if ( data[i] != '\0' )
10623                                           tmp[j] = data[i];
10624                                           
10625                                           j++;
10626                                 }
10627                                 pch = tmp;              
10628                                 DBG_871X("pch=%s",pch);
10629                                 
10630                                 while( *pch != '\0' )
10631                                 {
10632                                         pnext = strpbrk(pch, " ");
10633                                         if (!pnext)
10634                                                 break;
10635                                         
10636                                         pnext++;
10637                                         if ( *pnext != '\0' )
10638                                         {
10639                                                   strtout = simple_strtoul (pnext , &ptmp, 16);
10640                                                   sprintf( extra, "%s %d" ,extra ,strtout );
10641                                         }
10642                                         else{
10643                         break;
10644                                         }
10645                                         pch = pnext;
10646                                 }
10647                         wrqu->length = strlen(extra);
10648                         break;
10649                         
10650                 default:
10651                         wrqu->length = 0;
10652                         ret = -EINVAL;
10653                         break;
10654                         
10655         }
10656
10657         return ret;
10658 }
10659
10660 /*
10661  * Input Format: %d,%x,%x
10662  *      %d is RF path, should be smaller than MAX_RF_PATH_NUMS
10663  *      1st %x is address(offset)
10664  *      2st %x is data to write
10665  */
10666  static int rtw_mp_write_rf(struct net_device *dev,
10667                         struct iw_request_info *info,
10668                         struct iw_point *wrqu, char *extra)
10669 {                       
10670 /*static int rtw_mp_write_rf(struct net_device *dev,
10671                         struct iw_request_info *info,
10672                         union iwreq_data *wrqu, char *extra)
10673 */
10674         u32 path, addr, data;
10675         int ret;
10676         PADAPTER padapter = rtw_netdev_priv(dev);
10677         char input[wrqu->length];
10678
10679         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10680                          return -EFAULT;
10681
10682
10683         ret = sscanf(input, "%d,%x,%x", &path, &addr, &data);
10684         if (ret < 3) return -EINVAL;
10685
10686         if (path >= GET_HAL_RFPATH_NUM(padapter)) return -EINVAL;
10687         if (addr > 0xFF) return -EINVAL;
10688         if (data > 0xFFFFF) return -EINVAL;
10689         
10690         _rtw_memset(extra, 0, wrqu->length);
10691         
10692         write_rfreg(padapter, path, addr, data);
10693         
10694         sprintf(extra, "write_rf completed \n");
10695         wrqu->length = strlen(extra);
10696         
10697         return 0;
10698 }
10699
10700 /*
10701  * Input Format: %d,%x
10702  *      %d is RF path, should be smaller than MAX_RF_PATH_NUMS
10703  *      %x is address(offset)
10704  *
10705  * Return:
10706  *      %d for data readed
10707  */
10708 static int rtw_mp_read_rf(struct net_device *dev,
10709                         struct iw_request_info *info,
10710                         struct iw_point *wrqu, char *extra)
10711 {
10712         char input[wrqu->length];
10713         char *pch, *pnext, *ptmp;
10714         char data[20],tmp[20];
10715         //u32 *data = (u32*)extra;
10716         u32 path, addr;
10717         u32 ret,i=0 ,j=0,strtou=0;
10718         PADAPTER padapter = rtw_netdev_priv(dev);
10719
10720
10721         if (wrqu->length > 128) return -EFAULT;
10722         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10723                 return -EFAULT;
10724
10725         ret = sscanf(input, "%d,%x", &path, &addr);
10726         if (ret < 2) return -EINVAL;
10727
10728         if (path >= GET_HAL_RFPATH_NUM(padapter)) return -EINVAL;
10729         if (addr > 0xFF) return -EINVAL;
10730         
10731         _rtw_memset(extra, 0, wrqu->length);
10732         
10733         //*data = read_rfreg(padapter, path, addr);
10734         sprintf(data, "%08x", read_rfreg(padapter, path, addr));
10735                                 //add read data format blank
10736                                 for( i=0 ; i <= strlen(data) ; i++)
10737                                 {
10738                                           if( i%2==0 )
10739                                           {
10740                                                    tmp[j]=' ';
10741                                                    j++;
10742                                           }
10743                                           tmp[j] = data[i];
10744                                           j++;
10745                                 }
10746                                 pch = tmp;              
10747                                 DBG_871X("pch=%s",pch);
10748                                 
10749                                 while( *pch != '\0' )
10750                                 {
10751                                         pnext = strpbrk(pch, " ");
10752                                         pnext++;
10753                                         if ( *pnext != '\0' )
10754                                         {
10755                                                   strtou = simple_strtoul (pnext , &ptmp, 16);
10756                                                   sprintf( extra, "%s %d" ,extra ,strtou );
10757                                         }
10758                                         else{
10759                                                   break;
10760                                         }
10761                                         pch = pnext;
10762                                 }
10763                         wrqu->length = strlen(extra);   
10764
10765         return 0;
10766 }
10767
10768 static int rtw_mp_start(struct net_device *dev,
10769                         struct iw_request_info *info,
10770                         struct iw_point *wrqu, char *extra)
10771 {
10772         u8 val8;
10773         PADAPTER padapter = rtw_netdev_priv(dev);
10774         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
10775         struct dm_priv  *pdmpriv = &pHalData->dmpriv;
10776         struct hal_ops *pHalFunc = &padapter->HalFunc;
10777
10778         if(padapter->registrypriv.mp_mode ==0)
10779         {
10780                 #if (defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B))
10781                 DBG_871X("_rtw_mp_xmit_priv for Download BT patch FW\n");
10782                 _rtw_mp_xmit_priv(&padapter->xmitpriv);
10783                 #endif
10784                 pHalFunc->hal_deinit(padapter);
10785                 padapter->registrypriv.mp_mode =1;
10786                 pHalFunc->hal_init(padapter);
10787                 rtw_pm_set_ips(padapter,IPS_NONE);
10788                 LeaveAllPowerSaveMode(padapter);
10789
10790                 MPT_InitializeAdapter(padapter, 1);
10791 #ifdef CONFIG_BT_COEXIST
10792                 rtw_btcoex_HaltNotify(padapter);
10793                 rtw_btcoex_SetManualControl(padapter, _TRUE);
10794                 pdmpriv->DMFlag &= ~DYNAMIC_FUNC_BT;
10795                 // Force to switch Antenna to WiFi
10796                 padapter->registrypriv.mp_mode=0;
10797                 pHalFunc->hal_init(padapter);
10798                 padapter->registrypriv.mp_mode=1;
10799                 //rtw_btcoex_HaltNotify(padapter);
10800 #endif
10801         }
10802
10803         if (padapter->registrypriv.mp_mode == 0)
10804                 return -EPERM;
10805
10806         if (padapter->mppriv.mode == MP_OFF) {
10807                 if (mp_start_test(padapter) == _FAIL)
10808                         return -EPERM;
10809                 padapter->mppriv.mode = MP_ON;
10810                 MPT_PwrCtlDM(padapter,0);
10811         }
10812         padapter->mppriv.bmac_filter = _FALSE;
10813 #ifdef CONFIG_RTL8723B
10814         rtw_write8(padapter, 0x66, 0x27); //Open BT uart Log
10815         rtw_write8(padapter, 0xc50, 0x20); //for RX init Gain
10816 #endif  
10817         ODM_Write_DIG(&pHalData->odmpriv,0x20);
10818
10819         return 0;
10820 }
10821
10822 static int rtw_mp_stop(struct net_device *dev,
10823                         struct iw_request_info *info,
10824                         struct iw_point *wrqu, char *extra)
10825 {
10826         PADAPTER padapter = rtw_netdev_priv(dev);
10827         struct hal_ops *pHalFunc = &padapter->HalFunc;
10828
10829         if(padapter->registrypriv.mp_mode ==1)
10830         {
10831                 #if (defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B))
10832                 DBG_871X("_rtw_mp_xmit_priv reinit for normal mode\n");
10833                 _rtw_mp_xmit_priv(&padapter->xmitpriv);
10834                 #endif
10835                 
10836                 MPT_DeInitAdapter(padapter);
10837                 pHalFunc->hal_deinit(padapter);
10838                 padapter->registrypriv.mp_mode=0;
10839                 pHalFunc->hal_init(padapter);
10840         }
10841         
10842         if (padapter->mppriv.mode != MP_OFF) {
10843                 mp_stop_test(padapter);
10844                 padapter->mppriv.mode = MP_OFF;
10845         }
10846
10847         return 0;
10848 }
10849
10850 extern int wifirate2_ratetbl_inx(unsigned char rate);
10851
10852 static int rtw_mp_rate(struct net_device *dev,
10853                         struct iw_request_info *info,
10854                         struct iw_point *wrqu, char *extra)
10855 {
10856         u32 rate = MPT_RATE_1M;
10857         u8              input[wrqu->length];
10858         PADAPTER padapter = rtw_netdev_priv(dev);
10859
10860         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10861                         return -EFAULT;
10862                         
10863         rate = rtw_atoi(input);
10864         sprintf( extra, "Set data rate to %d" , rate );
10865                 
10866         if(rate <= 0x7f)
10867                 rate = wifirate2_ratetbl_inx( (u8)rate);        
10868         else if (rate < 0x90)
10869         //HT  rate 0x80(MCS0)        ~ 0x8F(MCS15)       128~143
10870                 rate =(rate - 0x80 + MPT_RATE_MCS0);
10871         else 
10872                 //VHT rate 0x90(VHT1SS_MCS0) ~ 0x99(VHT1SS_MCS9) 144~153
10873                 rate =(rate - MPT_RATE_VHT1SS_MCS0); 
10874
10875         //DBG_871X("%s: rate=%d\n", __func__, rate);
10876         
10877         if (rate >= MPT_RATE_LAST )     
10878         return -EINVAL;
10879
10880         padapter->mppriv.rateidx = rate;
10881         Hal_SetDataRate(padapter);
10882         
10883         wrqu->length = strlen(extra) + 1;
10884         return 0;
10885 }
10886
10887 static int rtw_mp_channel(struct net_device *dev,
10888                         struct iw_request_info *info,
10889                         struct iw_point *wrqu, char *extra)
10890 {
10891
10892         PADAPTER padapter = rtw_netdev_priv(dev);
10893         HAL_DATA_TYPE   *pHalData       = GET_HAL_DATA(padapter);
10894         u8              input[wrqu->length];
10895         u32     channel = 1;
10896         int cur_ch_offset;
10897
10898         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10899                         return -EFAULT;
10900         
10901         channel = rtw_atoi(input);
10902         //DBG_871X("%s: channel=%d\n", __func__, channel);
10903         sprintf( extra, "Change channel %d to channel %d", padapter->mppriv.channel , channel );
10904         padapter->mppriv.channel = channel;
10905         pHalData->CurrentChannel = channel;
10906         Hal_SetChannel(padapter);
10907
10908         //cur_ch_offset =  rtw_get_offset_by_ch(padapter->mppriv.channel);
10909         //set_channel_bwmode(padapter, padapter->mppriv.channel, cur_ch_offset, padapter->mppriv.bandwidth);
10910         wrqu->length = strlen(extra) + 1;
10911         return 0;
10912 }
10913
10914 static int rtw_mp_bandwidth(struct net_device *dev,
10915                         struct iw_request_info *info,
10916                         struct iw_point *wrqu, char *extra)
10917 {
10918         u32 bandwidth=0, sg=0;
10919         int cur_ch_offset;
10920         //u8 buffer[40];
10921         PADAPTER padapter = rtw_netdev_priv(dev);
10922         HAL_DATA_TYPE   *pHalData       = GET_HAL_DATA(padapter);
10923         //if (copy_from_user(buffer, (void*)wrqu->data.pointer, wrqu->data.length))
10924     //            return -EFAULT;
10925                 
10926         //DBG_871X("%s:iwpriv in=%s\n", __func__, extra);
10927         
10928         sscanf(extra, "40M=%d,shortGI=%d", &bandwidth, &sg);
10929         
10930         if (bandwidth == 1)
10931                 bandwidth=CHANNEL_WIDTH_40;
10932         else if (bandwidth == 2)
10933                 bandwidth=CHANNEL_WIDTH_80;
10934         DBG_871X("%s: bw=%d sg=%d \n", __func__, bandwidth , sg);
10935         
10936         padapter->mppriv.bandwidth = (u8)bandwidth;
10937         pHalData->CurrentChannelBW = bandwidth;
10938         padapter->mppriv.preamble = sg;
10939         
10940         SetBandwidth(padapter);
10941         //cur_ch_offset =  rtw_get_offset_by_ch(padapter->mppriv.channel);
10942         //set_channel_bwmode(padapter, padapter->mppriv.channel, cur_ch_offset, bandwidth);
10943
10944         return 0;
10945 }
10946
10947
10948 static int rtw_mp_txpower_index(struct net_device *dev,
10949                         struct iw_request_info *info,
10950                         struct iw_point *wrqu, char *extra)
10951 {
10952         PADAPTER padapter = rtw_netdev_priv(dev);
10953         char input[wrqu->length];
10954         u32 rfpath;
10955         u32 txpower_inx;
10956
10957         if (wrqu->length > 128)
10958                 return -EFAULT;
10959
10960         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10961                 return -EFAULT;
10962
10963         rfpath = rtw_atoi(input);
10964         txpower_inx = mpt_ProQueryCalTxPower(padapter, rfpath);
10965         sprintf(extra, " %d", txpower_inx);
10966         wrqu->length = strlen(extra) + 1;
10967
10968         return 0;
10969 }
10970
10971
10972 static int rtw_mp_txpower(struct net_device *dev,
10973                         struct iw_request_info *info,
10974                         struct iw_point *wrqu, char *extra)
10975 {
10976         u32             idx_a=0,idx_b=0,MsetPower=1;
10977         u8              input[wrqu->length];
10978
10979         PADAPTER padapter = rtw_netdev_priv(dev);
10980
10981         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10982                         return -EFAULT;
10983
10984         MsetPower = strncmp(input, "off", 3); 
10985         sscanf(input,"patha=%d,pathb=%d",&idx_a,&idx_b);
10986         //DBG_871X("%s: tx_pwr_idx_a=%x b=%x\n", __func__, idx_a, idx_b);
10987         if(MsetPower==0)
10988         {
10989                 padapter->mppriv.bSetTxPower = 0;
10990                 sprintf( extra, "MP Set power off");
10991         }
10992         else
10993         {
10994         sprintf( extra, "Set power level path_A:%d path_B:%d", idx_a , idx_b );
10995         padapter->mppriv.txpoweridx = (u8)idx_a;
10996         padapter->mppriv.txpoweridx_b = (u8)idx_b;
10997         padapter->mppriv.bSetTxPower = 1;
10998                 Hal_SetAntennaPathPower(padapter);
10999         }
11000         wrqu->length = strlen(extra) + 1;
11001         return 0;
11002 }
11003
11004 static int rtw_mp_ant_tx(struct net_device *dev,
11005                         struct iw_request_info *info,
11006                         struct iw_point *wrqu, char *extra)
11007 {
11008         u8 i;
11009         u8              input[wrqu->length];
11010         u16 antenna = 0;
11011         PADAPTER padapter = rtw_netdev_priv(dev);
11012
11013         if (copy_from_user(input, wrqu->pointer, wrqu->length))
11014                         return -EFAULT;
11015                         
11016         //DBG_871X("%s: input=%s\n", __func__, input);  
11017         
11018         sprintf( extra, "switch Tx antenna to %s", input );
11019         
11020         for (i=0; i < strlen(input); i++)
11021         {
11022                 switch(input[i])
11023                         {
11024                                 case 'a' :
11025                                                                 antenna|=ANTENNA_A;
11026                                                                 break;
11027                                 case 'b':
11028                                                                 antenna|=ANTENNA_B;
11029                                                                 break;
11030                         }
11031         }
11032         //antenna |= BIT(extra[i]-'a');
11033         //DBG_871X("%s: antenna=0x%x\n", __func__, antenna);            
11034         padapter->mppriv.antenna_tx = antenna;
11035         //DBG_871X("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_tx);
11036         
11037         Hal_SetAntenna(padapter);
11038
11039         wrqu->length = strlen(extra) + 1;
11040         return 0;
11041 }
11042
11043 static int rtw_mp_ant_rx(struct net_device *dev,
11044                         struct iw_request_info *info,
11045                         struct iw_point *wrqu, char *extra)
11046 {
11047         u8 i;
11048         u16 antenna = 0;
11049         u8              input[wrqu->length];
11050         PADAPTER padapter = rtw_netdev_priv(dev);
11051
11052         if (copy_from_user(input, wrqu->pointer, wrqu->length))
11053                         return -EFAULT;
11054         //DBG_871X("%s: input=%s\n", __func__, input);
11055         _rtw_memset(extra, 0, wrqu->length);
11056         
11057         sprintf( extra, "switch Rx antenna to %s", input );
11058         
11059         for (i=0; i < strlen(input); i++) {
11060         switch( input[i] )
11061                         {
11062                                 case 'a' :
11063                                                                 antenna|=ANTENNA_A;
11064                                                                 break;
11065                                 case 'b':
11066                                                                 antenna|=ANTENNA_B;
11067                                                                 break;
11068                                 case 'c' :
11069                                                                 antenna|=ANTENNA_C;
11070                                                                 break;
11071                         }
11072         }
11073         
11074         //DBG_871X("%s: antenna=0x%x\n", __func__, antenna);            
11075         padapter->mppriv.antenna_rx = antenna;
11076         //DBG_871X("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_rx);
11077         Hal_SetAntenna(padapter);
11078         wrqu->length = strlen(extra);
11079         
11080         return 0;
11081 }
11082
11083 static int rtw_mp_ctx(struct net_device *dev,
11084                         struct iw_request_info *info,
11085                         struct iw_point *wrqu, char *extra)
11086 {
11087         u32 pkTx = 1, countPkTx = 1, cotuTx = 1, CarrSprTx = 1, scTx = 1, sgleTx = 1, stop = 1;
11088         u32 bStartTest = 1;
11089         u32 count = 0,pktinterval=0;
11090         struct mp_priv *pmp_priv;
11091         struct pkt_attrib *pattrib;
11092
11093         PADAPTER padapter = rtw_netdev_priv(dev);
11094
11095
11096         pmp_priv = &padapter->mppriv;
11097
11098         if (copy_from_user(extra, wrqu->pointer, wrqu->length))
11099                         return -EFAULT;
11100                         
11101         DBG_871X("%s: in=%s\n", __func__, extra);
11102
11103         countPkTx = strncmp(extra, "count=", 5); // strncmp TRUE is 0
11104         cotuTx = strncmp(extra, "background", 20);
11105         CarrSprTx = strncmp(extra, "background,cs", 20);
11106         scTx = strncmp(extra, "background,sc", 20);
11107         sgleTx = strncmp(extra, "background,stone", 20);
11108         pkTx = strncmp(extra, "background,pkt", 20);
11109         stop = strncmp(extra, "stop", 4);
11110         sscanf(extra, "count=%d,pkt", &count);
11111         sscanf(extra, "pktinterval=%d", &pktinterval);
11112         
11113         //DBG_871X("%s: count=%d countPkTx=%d cotuTx=%d CarrSprTx=%d scTx=%d sgleTx=%d pkTx=%d stop=%d\n", __func__, count, countPkTx, cotuTx, CarrSprTx, pkTx, sgleTx, scTx, stop);
11114         _rtw_memset(extra, '\0', sizeof(extra));
11115
11116         if( pktinterval !=0 )
11117         {
11118                 sprintf( extra, "Pkt Interval = %d",pktinterval);
11119                 padapter->mppriv.pktInterval = pktinterval;
11120                 
11121                 wrqu->length = strlen(extra);
11122                 return 0;
11123         }
11124         
11125         if (stop == 0) {
11126                 bStartTest = 0; // To set Stop
11127                 pmp_priv->tx.stop = 1;
11128                 sprintf( extra, "Stop continuous Tx");
11129         } else {
11130                 bStartTest = 1;
11131                 if (pmp_priv->mode != MP_ON) {
11132                         if (pmp_priv->tx.stop != 1) {
11133                                 DBG_871X("%s: MP_MODE != ON %d\n", __func__, pmp_priv->mode);
11134                                 return  -EFAULT;
11135                         }
11136                 }
11137         }
11138
11139         if (pkTx == 0 || countPkTx == 0)
11140                 pmp_priv->mode = MP_PACKET_TX;
11141         if (sgleTx == 0)
11142                 pmp_priv->mode = MP_SINGLE_TONE_TX;
11143         if (cotuTx == 0)
11144                 pmp_priv->mode = MP_CONTINUOUS_TX;
11145         if (CarrSprTx == 0)
11146                 pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX;
11147         if (scTx == 0)
11148                 pmp_priv->mode = MP_SINGLE_CARRIER_TX;
11149
11150         switch (pmp_priv->mode)
11151         {
11152                 case MP_PACKET_TX:
11153                 
11154                         //DBG_871X("%s:pkTx %d\n", __func__,bStartTest);
11155                         if (bStartTest == 0)
11156                         {
11157                                 pmp_priv->tx.stop = 1;
11158                                 pmp_priv->mode = MP_ON;
11159                                 sprintf( extra, "Stop continuous Tx");
11160                         }
11161                         else if (pmp_priv->tx.stop == 1)
11162                         {
11163                                 sprintf( extra, "Start continuous DA=ffffffffffff len=1500 count=%u,\n",count);
11164                                 //DBG_871X("%s:countPkTx %d\n", __func__,count);
11165                                 pmp_priv->tx.stop = 0;
11166                                 pmp_priv->tx.count = count;
11167                                 pmp_priv->tx.payload = 2;
11168 #ifdef CONFIG_80211N_HT
11169                                 pmp_priv->tx.attrib.ht_en = 1;
11170 #endif
11171 #ifdef CONFIG_80211AC_VHT
11172                                 pmp_priv->tx.attrib.raid = RATEID_IDX_VHT_1SS; //10
11173 #endif
11174                                 pattrib = &pmp_priv->tx.attrib;
11175                                 pattrib->pktlen = 1000;
11176                                 _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);
11177                                 SetPacketTx(padapter);
11178                         } 
11179                         else {
11180                                 //DBG_871X("%s: pkTx not stop\n", __func__);
11181                                 return -EFAULT;
11182                         }
11183                                 wrqu->length = strlen(extra);
11184                                 return 0;
11185
11186                 case MP_SINGLE_TONE_TX:
11187                         //DBG_871X("%s: sgleTx %d \n", __func__, bStartTest);
11188                         if (bStartTest != 0){
11189                                 sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes.");
11190             }
11191                         Hal_SetSingleToneTx(padapter, (u8)bStartTest);
11192                         break;
11193
11194                 case MP_CONTINUOUS_TX:
11195                         //DBG_871X("%s: cotuTx %d\n", __func__, bStartTest);
11196                         if (bStartTest != 0){
11197                                 sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes.");
11198                          }
11199                 Hal_SetContinuousTx(padapter, (u8)bStartTest);
11200                         break;
11201
11202                 case MP_CARRIER_SUPPRISSION_TX:
11203                         //DBG_871X("%s: CarrSprTx %d\n", __func__, bStartTest);
11204                         if (bStartTest != 0){
11205                                 if( pmp_priv->rateidx <= MPT_RATE_11M ) 
11206                                 {
11207                                         sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes.");
11208                                         
11209                                 }else
11210                                         sprintf( extra, "Specify carrier suppression but not CCK rate");
11211                         }
11212                         Hal_SetCarrierSuppressionTx(padapter, (u8)bStartTest);
11213                         break;
11214
11215                 case MP_SINGLE_CARRIER_TX:
11216                         //DBG_871X("%s: scTx %d\n", __func__, bStartTest);
11217                         if (bStartTest != 0){
11218                                 sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes.");
11219                         }
11220                         Hal_SetSingleCarrierTx(padapter, (u8)bStartTest);
11221                         break;
11222
11223                 default:
11224                         //DBG_871X("%s:No Match MP_MODE\n", __func__);
11225                         sprintf( extra, "Error! Continuous-Tx is not on-going.");
11226                         return -EFAULT;
11227         }
11228
11229         if ( bStartTest==1 && pmp_priv->mode != MP_ON) {
11230                 struct mp_priv *pmp_priv = &padapter->mppriv;
11231                 if (pmp_priv->tx.stop == 0) {
11232                         pmp_priv->tx.stop = 1;
11233                         //DBG_871X("%s: pkt tx is running...\n", __func__);
11234                         rtw_msleep_os(5);
11235                 }
11236 #ifdef CONFIG_80211N_HT
11237                 pmp_priv->tx.attrib.ht_en = 1;
11238 #endif
11239 #ifdef CONFIG_80211AC_VHT
11240                 pmp_priv->tx.attrib.raid = RATEID_IDX_VHT_1SS; //10
11241 #endif
11242                 pmp_priv->tx.stop = 0;
11243                 pmp_priv->tx.count = 1;
11244                 SetPacketTx(padapter);
11245         } else {
11246                 pmp_priv->mode = MP_ON;
11247         }
11248
11249         wrqu->length = strlen(extra);
11250         return 0;
11251 }
11252
11253
11254 static int rtw_mp_disable_bt_coexist(struct net_device *dev,
11255                         struct iw_request_info *info,
11256                         union iwreq_data *wrqu, char *extra)
11257 {
11258         PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
11259         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
11260         struct dm_priv  *pdmpriv = &pHalData->dmpriv;
11261         struct hal_ops *pHalFunc = &padapter->HalFunc;
11262         
11263         u8 input[wrqu->data.length];
11264         u32 bt_coexist;
11265
11266         if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
11267                 return -EFAULT;
11268         
11269         bt_coexist = rtw_atoi(input);
11270         
11271         if( bt_coexist == 0 )
11272         {
11273                 RT_TRACE(_module_mp_, _drv_info_,
11274                         ("Set OID_RT_SET_DISABLE_BT_COEXIST: disable BT_COEXIST\n"));
11275                 DBG_871X("Set OID_RT_SET_DISABLE_BT_COEXIST: disable BT_COEXIST\n");
11276 #ifdef CONFIG_BT_COEXIST
11277                 rtw_btcoex_HaltNotify(padapter);
11278                 rtw_btcoex_SetManualControl(padapter, _TRUE);
11279                 pdmpriv->DMFlag &= ~DYNAMIC_FUNC_BT;
11280                 // Force to switch Antenna to WiFi
11281                 rtw_write16(padapter, 0x870, 0x300);
11282                 rtw_write16(padapter, 0x860, 0x110); 
11283 #endif // CONFIG_BT_COEXIST
11284         }
11285         else
11286         {
11287                 RT_TRACE(_module_mp_, _drv_info_,
11288                         ("Set OID_RT_SET_DISABLE_BT_COEXIST: enable BT_COEXIST\n"));
11289 #ifdef CONFIG_BT_COEXIST                
11290                 pdmpriv->DMFlag |= DYNAMIC_FUNC_BT;
11291                 rtw_btcoex_SetManualControl(padapter, _FALSE);
11292 #endif
11293         }
11294
11295         return 0;       
11296 }
11297
11298
11299 static int rtw_mp_arx(struct net_device *dev,
11300                         struct iw_request_info *info,
11301                         struct iw_point *wrqu, char *extra)
11302 {
11303         u8 bStartRx=0,bStopRx=0,bQueryPhy=0,bQueryMac=0,bSetBssid=0;
11304         u8 bmac_filter = 0,bfilter_init=0;
11305         u32 cckok=0,cckcrc=0,ofdmok=0,ofdmcrc=0,htok=0,htcrc=0,OFDM_FA=0,CCK_FA=0,DropPacket=0,vht_ok=0,vht_err=0;
11306         u32             mac_cck_ok=0, mac_ofdm_ok=0, mac_ht_ok=0, mac_vht_ok=0;
11307         u32             mac_cck_err=0, mac_ofdm_err=0, mac_ht_err=0, mac_vht_err=0;
11308         u8              input[wrqu->length];
11309         char *pch, *ptmp, *token, *tmp[2]={0x00,0x00};
11310         u32 i=0,ii=0,jj=0,kk=0,cnts=0,bmon=0;
11311         PADAPTER padapter = rtw_netdev_priv(dev);
11312         struct mp_priv *pmppriv = &padapter->mppriv;
11313
11314
11315         if (copy_from_user(input, wrqu->pointer, wrqu->length))
11316                         return -EFAULT;
11317
11318         DBG_871X("%s: %s\n", __func__, input);
11319
11320         bStartRx = (strncmp(input, "start", 5)==0)?1:0; // strncmp TRUE is 0
11321         bStopRx = (strncmp(input, "stop", 5)==0)?1:0; // strncmp TRUE is 0
11322         bQueryPhy = (strncmp(input, "phy", 3)==0)?1:0; // strncmp TRUE is 0
11323         bQueryMac = (strncmp(input, "mac", 3)==0)?1:0; // strncmp TRUE is 0
11324         bSetBssid = (strncmp(input, "setbssid=", 8)==0)?1:0; // strncmp TRUE is 0
11325         //bfilter_init = (strncmp(input, "filter_init",11)==0)?1:0;
11326         bmac_filter = (strncmp(input, "accept_mac",10)==0)?1:0;
11327         bmon = (strncmp(input, "mon=",4)==0)?1:0;
11328
11329
11330         if(bSetBssid==1){
11331                 pch = input;
11332                 while ((token = strsep(&pch, "=")) != NULL)
11333                 {
11334                         if (i > 1) break;
11335                         tmp[i] = token;
11336                         i++;
11337                 }
11338                 if ((tmp[0]==NULL) && (tmp[1]==NULL)){
11339                         return -EFAULT;
11340                 }
11341                 else{
11342                         cnts = strlen(tmp[1])/2;
11343                         if (cnts<1) return -EFAULT;
11344                         DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
11345                         DBG_871X("%s: data=%s\n", __FUNCTION__, tmp[1]);
11346                         for (jj=0, kk=0; jj < cnts ; jj++, kk+=2){
11347                                          pmppriv->network_macaddr[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
11348                                         DBG_871X("network_macaddr[%d]=%x \n",jj, pmppriv->network_macaddr[jj]);
11349                         }
11350                 }
11351                 pmppriv->bSetRxBssid = _TRUE;
11352         }
11353
11354         if(bmac_filter)
11355         {
11356                 pmppriv->bmac_filter = bmac_filter;
11357                 pch = input;
11358                 while ((token = strsep(&pch, "=")) != NULL)
11359                 {
11360                         if (i > 1) break;
11361                         tmp[i] = token;
11362                         i++;
11363                 }
11364                 if ((tmp[0]==NULL) && (tmp[1]==NULL)){
11365                         return -EFAULT;
11366                 }
11367                 else{
11368                         cnts = strlen(tmp[1])/2;
11369                         if (cnts<1) return -EFAULT;
11370                         DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
11371                         DBG_871X("%s: data=%s\n", __FUNCTION__, tmp[1]);
11372                         for (jj=0, kk=0; jj < cnts ; jj++, kk+=2){
11373                                         pmppriv->mac_filter[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
11374                                         DBG_871X("%s mac_filter[%d]=%x \n",__FUNCTION__,jj, pmppriv->mac_filter[jj]);
11375                         }
11376                 }
11377         }
11378         
11379         if(bStartRx)
11380         {
11381                 sprintf( extra, "start");
11382                 SetPacketRx(padapter, bStartRx);
11383         }
11384         else if(bStopRx)
11385         {
11386                 SetPacketRx(padapter, 0);
11387                 pmppriv->bmac_filter = _FALSE;
11388                 sprintf( extra, "Received packet OK:%d CRC error:%d ,Filter out:%d",padapter->mppriv.rx_pktcount,padapter->mppriv.rx_crcerrpktcount,padapter->mppriv.rx_pktcount_filter_out);
11389         }
11390         else if(bQueryPhy)
11391         {          
11392
11393                 if (IS_HARDWARE_TYPE_JAGUAR(padapter)) 
11394                 {
11395                         cckok      = PHY_QueryBBReg(padapter, 0xF04, 0x3FFF);        // [13:0]  
11396                         ofdmok     = PHY_QueryBBReg(padapter, 0xF14, 0x3FFF);        // [13:0]  
11397                         htok       = PHY_QueryBBReg(padapter, 0xF10, 0x3FFF);     // [13:0]
11398                         vht_ok      = PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF);     // [13:0]
11399                                                                   
11400                         cckcrc     = PHY_QueryBBReg(padapter, 0xF04, 0x3FFF0000); // [29:16]                                            
11401                         ofdmcrc    = PHY_QueryBBReg(padapter, 0xF14, 0x3FFF0000); // [29:16]
11402                         htcrc      = PHY_QueryBBReg(padapter, 0xF10, 0x3FFF0000); // [29:16]            
11403                         vht_err     = PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF0000); // [29:16]           
11404                         
11405                         CCK_FA = PHY_QueryBBReg(padapter, 0xa5c, bMaskLWord);
11406                         OFDM_FA = PHY_QueryBBReg(padapter, 0xF48, bMaskLWord);
11407                 } 
11408                 else
11409                 {
11410                         cckok      = PHY_QueryBBReg(padapter, 0xF88, bMaskDWord);               
11411                         ofdmok     = PHY_QueryBBReg(padapter, 0xF94, bMaskLWord);               
11412                         htok       = PHY_QueryBBReg(padapter, 0xF90, bMaskLWord);
11413                         vht_ok      = 0;
11414                     
11415                         cckcrc     = PHY_QueryBBReg(padapter, 0xF84, bMaskDWord);                                               
11416                         ofdmcrc    = PHY_QueryBBReg(padapter, 0xF94, bMaskHWord);
11417                         htcrc      = PHY_QueryBBReg(padapter, 0xF90, bMaskHWord);               
11418                         vht_err     = 0;
11419                 
11420                 OFDM_FA = PHY_QueryBBReg(padapter, 0xCF0, bMaskLWord) + PHY_QueryBBReg(padapter, 0xCF2, bMaskLWord) + 
11421                                         PHY_QueryBBReg(padapter, 0xDA2, bMaskLWord)+ PHY_QueryBBReg(padapter, 0xDA4, bMaskLWord) + 
11422                                         PHY_QueryBBReg(padapter, 0xDA6, bMaskLWord) + PHY_QueryBBReg(padapter, 0xDA8, bMaskLWord);
11423                 
11424                 CCK_FA=(rtw_read8(padapter, 0xa5b )<<8 ) | (rtw_read8(padapter, 0xa5c));
11425                 }
11426                 DBG_871X("%s: OFDM_FA =%d\n", __FUNCTION__, OFDM_FA);
11427                 DBG_871X("%s: CCK_FA =%d\n", __FUNCTION__, CCK_FA);
11428                 sprintf( extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d",cckok+ofdmok+htok+vht_ok,cckcrc+ofdmcrc+htcrc+vht_err,OFDM_FA+CCK_FA);
11429         }
11430         else if(bQueryMac)
11431         {
11432                 // for 8723A
11433                 {
11434                         PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x3);
11435                         mac_cck_ok      = PHY_QueryMacReg(padapter, 0x664, bMaskLWord);      // [15:0]    
11436                         PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x0);
11437                         mac_ofdm_ok     = PHY_QueryMacReg(padapter, 0x664, bMaskLWord);      // [15:0]   
11438                         PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x6);
11439                         mac_ht_ok       = PHY_QueryMacReg(padapter, 0x664, bMaskLWord);     // [15:0]   
11440                         mac_vht_ok      = 0;
11441                         
11442                         PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x4);
11443                         mac_cck_err     = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0]       
11444                         PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x1);
11445                         mac_ofdm_err    = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0]       
11446                         PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x7);
11447                         mac_ht_err      = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0]               
11448                         mac_vht_err     = 0;
11449                         //Mac_DropPacket
11450                         rtw_write32(padapter, 0x664, (rtw_read32(padapter, 0x0664)& 0x0FFFFFFF)| Mac_DropPacket);
11451                         DropPacket = rtw_read32(padapter, 0x664)& 0x0000FFFF;
11452                 } 
11453                 
11454                 sprintf( extra, "Mac Received packet OK: %d , CRC error: %d , Drop Packets: %d\n",
11455                                 mac_cck_ok+mac_ofdm_ok+mac_ht_ok+mac_vht_ok,mac_cck_err+mac_ofdm_err+mac_ht_err+mac_vht_err,DropPacket);                        
11456         }
11457
11458
11459
11460         if( bmon==1 ) {
11461                 sscanf(input, "mon=%d", &bmon);
11462                 if(bmon==1)             {
11463                 pmppriv->rx_bindicatePkt= _TRUE;        
11464                 sprintf( extra, "Indicating Receive Packet to network start\n");
11465                 }else {                 
11466                         pmppriv->rx_bindicatePkt= _FALSE;                       
11467                         sprintf( extra, "Indicating Receive Packet to network Stop\n");
11468                 }
11469         }
11470         wrqu->length = strlen(extra) + 1;
11471
11472         
11473         return 0;
11474 }
11475
11476 static int rtw_mp_trx_query(struct net_device *dev,
11477                         struct iw_request_info *info,
11478                         struct iw_point *wrqu, char *extra)
11479 {
11480         u32 txok,txfail,rxok,rxfail,rxfilterout;
11481         PADAPTER padapter = rtw_netdev_priv(dev);
11482         //if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
11483         //      return -EFAULT;
11484
11485         txok=padapter->mppriv.tx.sended;
11486         txfail=0;
11487         rxok = padapter->mppriv.rx_pktcount;
11488         rxfail = padapter->mppriv.rx_crcerrpktcount;
11489         rxfilterout = padapter->mppriv.rx_pktcount_filter_out;
11490
11491         _rtw_memset(extra, '\0', 128);
11492
11493         sprintf(extra, "Tx OK:%d, Tx Fail:%d, Rx OK:%d, CRC error:%d ,Rx Filter out:%d \n", txok, txfail,rxok,rxfail,rxfilterout);
11494
11495         wrqu->length=strlen(extra)+1;
11496
11497         return 0;
11498 }
11499
11500 static int rtw_mp_pwrtrk(struct net_device *dev,
11501                         struct iw_request_info *info,
11502                         struct iw_point *wrqu, char *extra)
11503 {
11504         u8 enable;
11505         u32 thermal;
11506         s32 ret;
11507         PADAPTER padapter = rtw_netdev_priv(dev);
11508         HAL_DATA_TYPE                   *pHalData = GET_HAL_DATA(padapter);
11509         u8              input[wrqu->length];
11510
11511         if (copy_from_user(input, wrqu->pointer, wrqu->length))
11512                         return -EFAULT;
11513
11514         _rtw_memset(extra, 0, wrqu->length);
11515
11516         enable = 1;
11517         if (wrqu->length > 1) { // not empty string
11518                 if (strncmp(input, "stop", 4) == 0)
11519                 {       
11520                         enable = 0;
11521                         sprintf(extra, "mp tx power tracking stop");
11522                         pHalData->TxPowerTrackControl = _FALSE;
11523                 }
11524                 else if (sscanf(input, "ther=%d", &thermal)) {
11525                         pHalData->TxPowerTrackControl = _TRUE;
11526                                 ret = Hal_SetThermalMeter(padapter, (u8)thermal);
11527                                 if (ret == _FAIL) return -EPERM;
11528                                 sprintf(extra, "mp tx power tracking start,target value=%d ok ",thermal);
11529                 }else   {
11530                                 return -EINVAL;
11531                 }
11532         }
11533
11534         ret = Hal_SetPowerTracking(padapter, enable);
11535         if (ret == _FAIL) return -EPERM;
11536
11537         wrqu->length = strlen(extra);
11538
11539         return 0;
11540 }
11541
11542 static int rtw_mp_psd(struct net_device *dev,
11543                         struct iw_request_info *info,
11544                         struct iw_point *wrqu, char *extra)
11545 {
11546         PADAPTER padapter = rtw_netdev_priv(dev);
11547         u8              input[wrqu->length];
11548         
11549         if (copy_from_user(input, wrqu->pointer, wrqu->length))
11550                 return -EFAULT;
11551         
11552         strcpy(extra,input);
11553         
11554         wrqu->length = mp_query_psd(padapter, extra);
11555         
11556         return 0;
11557 }
11558
11559 static int rtw_mp_thermal(struct net_device *dev,
11560                         struct iw_request_info *info,
11561                         struct iw_point *wrqu, char *extra)
11562 {
11563         u8 val;
11564         u16 bwrite=1;
11565         
11566         #ifdef CONFIG_RTL8192C
11567                         u16 addr=EEPROM_THERMAL_METER_92C;
11568         #endif
11569         #ifdef CONFIG_RTL8192D
11570                         u16 addr=EEPROM_THERMAL_METER_92D;
11571         #endif
11572         #ifdef CONFIG_RTL8723A
11573                         u16 addr=EEPROM_THERMAL_METER_8723A;
11574         #endif
11575         #ifdef CONFIG_RTL8188E
11576                         u16 addr=EEPROM_THERMAL_METER_88E;
11577         #endif
11578         #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11579                         u16 addr=EEPROM_THERMAL_METER_8812;
11580         #endif
11581         #ifdef CONFIG_RTL8192E
11582                         u16 addr=EEPROM_THERMAL_METER_8192E;
11583         #endif
11584         #ifdef CONFIG_RTL8723B
11585                         u16 addr=EEPROM_THERMAL_METER_8723B;
11586         #endif
11587         u16 cnt=1;
11588         u16 max_available_size=0;
11589         PADAPTER padapter = rtw_netdev_priv(dev);       
11590
11591         if (copy_from_user(extra, wrqu->pointer, wrqu->length))
11592                 return -EFAULT;
11593
11594         //DBG_871X("print extra %s \n",extra); 
11595          
11596          bwrite = strncmp(extra, "write", 6); // strncmp TRUE is 0
11597          
11598          Hal_GetThermalMeter(padapter, &val);
11599          
11600          if( bwrite == 0 )      
11601          {
11602                  //DBG_871X("to write val:%d",val);
11603                         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
11604                         if( 2 > max_available_size )
11605                         {                       
11606                                 DBG_871X("no available efuse!\n");
11607                                 return -EFAULT;
11608                         }       
11609                         if ( rtw_efuse_map_write(padapter, addr, cnt, &val) == _FAIL )
11610                         {
11611                                 DBG_871X("rtw_efuse_map_write error \n");                       
11612                                 return -EFAULT;
11613                         } 
11614                         else
11615                         {
11616                                  sprintf(extra, " efuse write ok :%d", val);    
11617                         }
11618           }
11619           else
11620           {
11621                          sprintf(extra, "%d", val);
11622           }
11623         wrqu->length = strlen(extra);
11624         
11625         return 0;
11626 }
11627
11628 static int rtw_mp_reset_stats(struct net_device *dev,
11629                         struct iw_request_info *info,
11630                         struct iw_point *wrqu, char *extra)
11631 {
11632         struct mp_priv *pmp_priv;
11633         struct pkt_attrib *pattrib;
11634         PADAPTER padapter = rtw_netdev_priv(dev);
11635         
11636         pmp_priv = &padapter->mppriv;
11637         
11638         pmp_priv->tx.sended = 0;
11639         pmp_priv->tx_pktcount = 0;
11640         pmp_priv->rx_pktcount = 0;
11641         pmp_priv->rx_pktcount_filter_out=0;
11642         pmp_priv->rx_crcerrpktcount = 0;
11643
11644         //reset phy counter
11645         if (IS_HARDWARE_TYPE_JAGUAR(padapter))
11646         {
11647                 write_bbreg(padapter, 0xB58, BIT0, 0x1);
11648                 write_bbreg(padapter, 0xB58, BIT0, 0x0);
11649
11650                 write_bbreg(padapter, 0x9A4, BIT17, 0x1);//reset  OFDA FA counter
11651                 write_bbreg(padapter, 0x9A4, BIT17, 0x0);
11652                 
11653                 write_bbreg(padapter, 0xA5C, BIT15, 0x0);//reset  CCK FA counter
11654                 write_bbreg(padapter, 0xA5C, BIT15, 0x1);
11655         }
11656         else
11657         {
11658                 write_bbreg(padapter, 0xF14, BIT16, 0x1);
11659                 rtw_msleep_os(10);
11660                 write_bbreg(padapter, 0xF14, BIT16, 0x0);
11661                 
11662                 write_bbreg(padapter, 0xD00, BIT27, 0x1);//reset  OFDA FA counter
11663                 write_bbreg(padapter, 0xC0C, BIT31, 0x1);//reset  OFDA FA counter
11664                 write_bbreg(padapter, 0xD00, BIT27, 0x0);
11665                 write_bbreg(padapter, 0xC0C, BIT31, 0x0);
11666                 
11667                 write_bbreg(padapter, 0xA2C, BIT15, 0x0);//reset  CCK FA counter
11668                 write_bbreg(padapter, 0xA2C, BIT15, 0x1);
11669         }
11670         //reset mac counter
11671         PHY_SetMacReg(padapter, 0x664, BIT27, 0x1); 
11672         PHY_SetMacReg(padapter, 0x664, BIT27, 0x0);
11673         return 0;
11674 }
11675
11676 static int rtw_mp_dump(struct net_device *dev,
11677                         struct iw_request_info *info,
11678                         struct iw_point *wrqu, char *extra)
11679 {
11680         struct mp_priv *pmp_priv;
11681         struct pkt_attrib *pattrib;
11682         u32 value;
11683     u8          input[wrqu->length];
11684         u8 rf_type,path_nums = 0;
11685         u32 i,j=1,path;
11686         PADAPTER padapter = rtw_netdev_priv(dev);
11687         
11688         pmp_priv = &padapter->mppriv;
11689
11690         if (copy_from_user(input, wrqu->pointer, wrqu->length))
11691                 return -EFAULT;
11692         
11693         if ( strncmp(input, "all", 4)==0 )
11694         {
11695                 mac_reg_dump(RTW_DBGDUMP, padapter);
11696                 bb_reg_dump(RTW_DBGDUMP, padapter);
11697                 rf_reg_dump(RTW_DBGDUMP, padapter);
11698         }
11699         return 0;
11700 }
11701
11702 static int rtw_mp_phypara(struct net_device *dev,
11703                         struct iw_request_info *info,
11704                         struct iw_point *wrqu, char *extra)
11705 {
11706
11707         PADAPTER padapter = rtw_netdev_priv(dev);
11708         HAL_DATA_TYPE   *pHalData       = GET_HAL_DATA(padapter);
11709         char    input[wrqu->length];
11710         u32             valxcap;
11711         
11712         if (copy_from_user(input, wrqu->pointer, wrqu->length))
11713                         return -EFAULT;
11714         
11715         DBG_871X("%s:iwpriv in=%s\n", __func__, input);
11716         
11717         sscanf(input, "xcap=%d", &valxcap);
11718
11719         pHalData->CrystalCap = (u8)valxcap;
11720         Hal_ProSetCrystalCap( padapter , valxcap );
11721
11722         sprintf( extra, "Set xcap=%d",valxcap );
11723         wrqu->length = strlen(extra) + 1;
11724         
11725 return 0;
11726
11727 }
11728
11729 static int rtw_mp_SetRFPath(struct net_device *dev,
11730                         struct iw_request_info *info,
11731                         union iwreq_data *wrqu, char *extra)
11732 {
11733         PADAPTER padapter = rtw_netdev_priv(dev);
11734         char    input[wrqu->data.length];
11735         s32             bMain=1,bTurnoff=1;
11736         
11737         if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
11738                         return -EFAULT;
11739         DBG_871X("%s:iwpriv in=%s\n", __func__, input); 
11740         
11741         bMain = strncmp(input, "1", 2); // strncmp TRUE is 0
11742         bTurnoff = strncmp(input, "0", 3); // strncmp TRUE is 0
11743
11744         if(bMain==0)
11745         {
11746                 MP_PHY_SetRFPathSwitch(padapter,_TRUE);
11747                 DBG_871X("%s:PHY_SetRFPathSwitch=TRUE\n", __func__);    
11748         }
11749         else if(bTurnoff==0)
11750         {
11751                 MP_PHY_SetRFPathSwitch(padapter,_FALSE);
11752                 DBG_871X("%s:PHY_SetRFPathSwitch=FALSE\n", __func__);   
11753         }
11754         
11755         return 0;
11756 }
11757
11758 static int rtw_mp_QueryDrv(struct net_device *dev,
11759                         struct iw_request_info *info,
11760                         union iwreq_data *wrqu, char *extra)
11761 {
11762         PADAPTER padapter = rtw_netdev_priv(dev);
11763         char    input[wrqu->data.length];
11764         s32     qAutoLoad=1;
11765
11766         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
11767         
11768         if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
11769                         return -EFAULT;
11770         DBG_871X("%s:iwpriv in=%s\n", __func__, input); 
11771         
11772         qAutoLoad = strncmp(input, "autoload", 8); // strncmp TRUE is 0
11773
11774         if(qAutoLoad==0)
11775         {
11776                 DBG_871X("%s:qAutoLoad\n", __func__);
11777                 
11778                 if(pEEPROM->bautoload_fail_flag)
11779                         sprintf(extra, "fail");
11780                 else
11781                 sprintf(extra, "ok");      
11782         }
11783                 wrqu->data.length = strlen(extra) + 1;
11784         return 0;
11785 }
11786
11787 /* update Tx AGC offset */
11788 static int rtw_mp_antBdiff(struct net_device *dev,
11789                         struct iw_request_info *info,
11790                         struct iw_point *wrqu, char *extra)
11791 {
11792
11793
11794         // MPT_ProSetTxAGCOffset
11795         return 0;
11796 }
11797
11798
11799 static int rtw_mp_PwrCtlDM(struct net_device *dev,
11800                         struct iw_request_info *info,
11801                         struct iw_point *wrqu, char *extra)
11802 {
11803         PADAPTER padapter = rtw_netdev_priv(dev);
11804         u8              input[wrqu->length];
11805         u8              bstart=1;
11806         
11807         if (copy_from_user(input, wrqu->pointer, wrqu->length))
11808                         return -EFAULT;
11809
11810         bstart = strncmp(input, "start", 5); // strncmp TRUE is 0
11811         if(bstart==0){
11812                 sprintf(extra, "PwrCtlDM start \n");
11813                 MPT_PwrCtlDM(padapter,1);
11814         }else{
11815                 sprintf(extra, "PwrCtlDM stop \n");
11816                 MPT_PwrCtlDM(padapter,0);
11817         }
11818         wrqu->length = strlen(extra);
11819
11820         return 0;
11821 }
11822
11823 #if (defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B))
11824 /* update Tx AGC offset */
11825 static int rtw_mp_SetBT(struct net_device *dev,
11826                         struct iw_request_info *info,
11827                         union iwreq_data *wrqu, char *extra)
11828 {
11829         PADAPTER padapter = rtw_netdev_priv(dev);
11830         struct hal_ops *pHalFunc = &padapter->HalFunc;
11831         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
11832         
11833         BT_REQ_CMD      BtReq;
11834         PMPT_CONTEXT    pMptCtx=&(padapter->mppriv.MptCtx);
11835         PBT_RSP_CMD     pBtRsp=(PBT_RSP_CMD)&pMptCtx->mptOutBuf[0];
11836         char    input[128];
11837         char *pch, *ptmp, *token, *tmp[2]={0x00,0x00};
11838         u8 setdata[100];
11839         u8 resetbt=0x00;
11840         u8 tempval,BTStatus;
11841         u8 H2cSetbtmac[6];
11842         u8 u1H2CBtMpOperParm[4]={0x01};
11843         u16 testmode=1,ready=1,trxparam=1,setgen=1,getgen=1,testctrl=1,testbt=1,readtherm=1,setbtmac=1;
11844         u32 i=0,ii=0,jj=0,kk=0,cnts=0,status=0;
11845         PRT_MP_FIRMWARE pBTFirmware = NULL;
11846         
11847         if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
11848                         return -EFAULT;
11849         if(strlen(extra)<1) return -EFAULT;
11850         
11851         DBG_871X("%s:iwpriv in=%s\n", __FUNCTION__, extra); 
11852         ready = strncmp(extra, "ready", 5); 
11853         testmode = strncmp(extra, "testmode", 8); // strncmp TRUE is 0
11854         trxparam = strncmp(extra, "trxparam", 8); 
11855         setgen = strncmp(extra, "setgen", 6);
11856         getgen = strncmp(extra, "getgen", 6); 
11857         testctrl = strncmp(extra, "testctrl", 8);
11858         testbt = strncmp(extra, "testbt", 6);
11859         readtherm = strncmp(extra, "readtherm", 9);
11860         setbtmac = strncmp(extra, "setbtmac", 8);
11861
11862         if ( strncmp(extra, "dlbt", 4) == 0)
11863         {
11864                 pHalData->LastHMEBoxNum=0;
11865                 padapter->bBTFWReady = _FALSE;
11866                 rtw_write8(padapter, 0xa3, 0x05);
11867                 BTStatus=rtw_read8(padapter, 0xa0);
11868                 DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus);
11869                 if (BTStatus != 0x04)
11870                 {
11871                         sprintf(extra, "BT Status not Active DLFW FAIL\n");
11872                         goto exit;
11873                 }
11874
11875                 tempval = rtw_read8(padapter, 0x6B);
11876                 tempval |= BIT7;
11877                 rtw_write8(padapter, 0x6B, tempval);
11878
11879                 // Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay
11880                 // So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together!
11881                 rtw_usleep_os(100);
11882                 // disable BT power cut
11883                 // 0x6A[14] = 0
11884                 tempval = rtw_read8(padapter, 0x6B);
11885                 tempval &= ~BIT6;
11886                 rtw_write8(padapter, 0x6B, tempval);
11887                 rtw_usleep_os(100);
11888                 MPT_PwrCtlDM(padapter,0);
11889                 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)| 0x00000004));
11890                 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)& 0xFFFFFFEF));
11891                 rtw_msleep_os(600);
11892                 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)| 0x00000010));
11893                 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)& 0xFFFFFFFB));
11894                 rtw_msleep_os(1200);            
11895                 pBTFirmware = (PRT_MP_FIRMWARE)rtw_zmalloc(sizeof(RT_MP_FIRMWARE));
11896                 if(pBTFirmware==NULL)
11897                         goto exit;
11898                 padapter->bBTFWReady = _FALSE;
11899                 FirmwareDownloadBT(padapter, pBTFirmware);
11900                 if (pBTFirmware)
11901                         rtw_mfree((u8*)pBTFirmware, sizeof(RT_MP_FIRMWARE));
11902                         
11903                 DBG_871X("Wait for FirmwareDownloadBT fw boot!\n");
11904                 rtw_msleep_os(2000);
11905                 _rtw_memset(extra,'\0', wrqu->data.length);
11906                 BtReq.opCodeVer = 1;
11907                 BtReq.OpCode = 0;
11908                 BtReq.paraLength = 0;
11909                 mptbt_BtControlProcess(padapter, &BtReq);
11910                 rtw_msleep_os(100);
11911
11912                 DBG_8192C("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4],pMptCtx->mptOutBuf[5]);
11913                 if( (pMptCtx->mptOutBuf[4]==0x00) && (pMptCtx->mptOutBuf[5]==0x00))
11914                         {
11915                                 if(padapter->mppriv.bTxBufCkFail==_TRUE)
11916                                         sprintf(extra, "check TxBuf Fail.\n");
11917                                 else
11918                                         sprintf(extra, "download FW Fail.\n");
11919                         }
11920                         else
11921                         {
11922                                 sprintf(extra, "download FW OK.\n");
11923                                 goto exit;
11924                         }
11925                 goto exit;
11926                 goto exit;      
11927         }
11928         if ( strncmp(extra, "dlfw", 4) == 0)
11929         {
11930                 #ifdef CONFIG_BT_COEXIST
11931                 rtw_btcoex_HaltNotify(padapter);
11932                 //DBG_871X("SetBT bt1ant !\n");
11933                 //hal_btcoex1ant_SetAntPath(padapter);
11934                 rtw_btcoex_SetManualControl(padapter, _TRUE);
11935                 #endif
11936                 pHalData->LastHMEBoxNum=0;
11937                 padapter->bBTFWReady = _FALSE;
11938                 rtw_write8(padapter, 0xa3, 0x05);
11939                 BTStatus=rtw_read8(padapter, 0xa0);
11940                 DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus);
11941                 if (BTStatus != 0x04)
11942                 {
11943                         sprintf(extra, "BT Status not Active DLFW FAIL\n");
11944                         goto exit;
11945                 }
11946
11947                 tempval = rtw_read8(padapter, 0x6B);
11948                 tempval |= BIT7;
11949                 rtw_write8(padapter, 0x6B, tempval);
11950
11951                 // Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay
11952                 // So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together!
11953                 rtw_usleep_os(100);
11954                 // disable BT power cut
11955                 // 0x6A[14] = 0
11956                 tempval = rtw_read8(padapter, 0x6B);
11957                 tempval &= ~BIT6;
11958                 rtw_write8(padapter, 0x6B, tempval);
11959                 rtw_usleep_os(100);
11960         
11961                 MPT_PwrCtlDM(padapter,0);
11962                 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)| 0x00000004));
11963                 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)& 0xFFFFFFEF));
11964                 rtw_msleep_os(600);
11965                 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)| 0x00000010));
11966                 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)& 0xFFFFFFFB));
11967                 rtw_msleep_os(1200);
11968
11969 #if defined(CONFIG_PLATFORM_SPRD) && (MP_DRIVER == 1)
11970                 // Pull up BT reset pin.
11971                 DBG_871X("%s: pull up BT reset pin when bt start mp test\n", __FUNCTION__);
11972                 rtw_wifi_gpio_wlan_ctrl(WLAN_BT_PWDN_ON);
11973 #endif
11974                 DBG_871X(" rtl8723a_FirmwareDownload!\n");
11975
11976 #ifdef CONFIG_RTL8723A
11977                 status = rtl8723a_FirmwareDownload(padapter);
11978 #elif defined(CONFIG_RTL8723B)
11979                 status = rtl8723b_FirmwareDownload(padapter, _FALSE);
11980 #endif
11981                 DBG_871X("Wait for FirmwareDownloadBT fw boot!\n");
11982                 rtw_msleep_os(1000);
11983                 _rtw_memset(extra,'\0', wrqu->data.length);
11984                 BtReq.opCodeVer = 1;
11985                 BtReq.OpCode = 0;
11986                 BtReq.paraLength = 0;
11987                 mptbt_BtControlProcess(padapter, &BtReq);
11988                 rtw_msleep_os(200);
11989
11990                 DBG_8192C("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4],pMptCtx->mptOutBuf[5]);
11991                 if( (pMptCtx->mptOutBuf[4]==0x00) && (pMptCtx->mptOutBuf[5]==0x00))
11992                         {
11993                                 if(padapter->mppriv.bTxBufCkFail==_TRUE)
11994                                         sprintf(extra, "check TxBuf Fail.\n");
11995                                 else
11996                                         sprintf(extra, "download FW Fail.\n");
11997                         }
11998                         else
11999                         {
12000                                 #ifdef CONFIG_BT_COEXIST
12001                                 rtw_btcoex_SwitchGntBt(padapter);
12002                                 #endif
12003                                 rtw_msleep_os(200);
12004                                 sprintf(extra, "download FW OK.\n");
12005                                 goto exit;
12006                         }
12007                 goto exit;
12008         }
12009
12010         if ( strncmp(extra, "down", 4) == 0){
12011                 DBG_871X("SetBT down for to hal_init !\n");
12012                 mp_stop_test(padapter);
12013                 pHalFunc->hal_init(padapter);
12014                 mp_start_test(padapter);
12015                 MPT_PwrCtlDM(padapter,0);
12016                 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)| 0x00000004));
12017                 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)& 0xFFFFFFEF));
12018                 rtw_msleep_os(600);
12019                         //rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFE));
12020                 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)| 0x00000010));
12021                 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)& 0xFFFFFFFB));
12022                 rtw_msleep_os(1200);
12023                 goto exit;
12024         }
12025         if ( strncmp(extra, "disable", 7) == 0){
12026                 DBG_871X("SetBT disable !\n");
12027                 rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFB));
12028                 rtw_msleep_os(500);
12029                 goto exit;
12030                 }
12031         if ( strncmp(extra, "enable", 6) == 0){
12032                 DBG_871X("SetBT enable !\n");
12033                 rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)| 0x00000004));
12034                 rtw_msleep_os(500);
12035                 goto exit;
12036         }
12037         if ( strncmp(extra, "h2c", 3) == 0){
12038                         DBG_871X("SetBT h2c !\n");
12039                         padapter->bBTFWReady = _TRUE;
12040                         FillH2CCmd(padapter, 0x63, 1, u1H2CBtMpOperParm);
12041                         goto exit;
12042                 }
12043         if ( strncmp(extra, "2ant", 4) == 0){
12044                 DBG_871X("Set BT 2ant use!\n");
12045                 PHY_SetMacReg(padapter,0x67,BIT5,0x1);
12046                 rtw_write32(padapter, 0x948, 0000);
12047                 
12048                 goto exit;
12049         }
12050                 
12051         if( ready!=0 && testmode!=0 && trxparam!=0 && setgen!=0 && getgen!=0 && testctrl!=0 && testbt!=0 && readtherm!=0 &&setbtmac!=0)
12052                 return -EFAULT;
12053                 
12054         if( testbt==0 )
12055         {
12056                         BtReq.opCodeVer=1;
12057                         BtReq.OpCode=6;
12058                         BtReq.paraLength=cnts/2;
12059                         goto todo;
12060         }
12061         if( ready==0 )
12062         {
12063                 BtReq.opCodeVer=1;
12064                 BtReq.OpCode=0;
12065                 BtReq.paraLength=0; 
12066                 goto todo;
12067         }
12068
12069         pch = extra;    
12070         i = 0;
12071         while ((token = strsep(&pch, ",")) != NULL)
12072         {
12073                 if (i > 1) break;
12074                 tmp[i] = token;
12075                 i++;
12076         }
12077
12078         if ((tmp[0]==NULL) && (tmp[1]==NULL))
12079         {
12080                 return -EFAULT;
12081         }
12082         else
12083         {
12084                 cnts = strlen(tmp[1]);
12085                 if (cnts<1) return -EFAULT;
12086         
12087                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
12088                 DBG_871X("%s: data=%s\n", __FUNCTION__, tmp[1]);
12089                                 
12090                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
12091                 {
12092                         BtReq.pParamStart[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
12093 //                      DBG_871X("BtReq.pParamStart[%d]=0x%02x\n", jj, BtReq.pParamStart[jj]);
12094                 }
12095         }
12096         
12097         if( testmode==0 )       
12098         {
12099                 BtReq.opCodeVer=1;
12100                 BtReq.OpCode=1;
12101                 BtReq.paraLength=1; 
12102         }
12103         if( trxparam==0 )
12104         {
12105                 BtReq.opCodeVer=1;
12106                 BtReq.OpCode=2;
12107                 BtReq.paraLength=cnts/2; 
12108         }
12109         if( setgen==0 )
12110         {       
12111                 DBG_871X("%s: BT_SET_GENERAL \n", __func__); 
12112                 BtReq.opCodeVer=1;
12113                 BtReq.OpCode=3; //BT_SET_GENERAL        3
12114                 BtReq.paraLength=cnts/2;        
12115         }
12116         if( getgen==0 )
12117         {       
12118                 DBG_871X("%s: BT_GET_GENERAL \n", __func__); 
12119                 BtReq.opCodeVer=1;
12120                 BtReq.OpCode=4;         //BT_GET_GENERAL        4
12121                 BtReq.paraLength=cnts/2;        
12122         }
12123         if( readtherm==0 )
12124         {       
12125                 DBG_871X("%s: BT_GET_GENERAL \n", __func__); 
12126                 BtReq.opCodeVer=1;
12127                 BtReq.OpCode=4;         //BT_GET_GENERAL        4
12128                 BtReq.paraLength=cnts/2;        
12129         }
12130         
12131         if( testctrl==0 )
12132         {       
12133                 DBG_871X("%s: BT_TEST_CTRL \n", __func__);
12134                 BtReq.opCodeVer=1;
12135                 BtReq.OpCode=5;         //BT_TEST_CTRL  5
12136                 BtReq.paraLength=cnts/2;        
12137         }
12138
12139         DBG_871X("%s: Req opCodeVer=%d OpCode=%d paraLength=%d\n",
12140                 __FUNCTION__, BtReq.opCodeVer, BtReq.OpCode, BtReq.paraLength);
12141
12142         if(BtReq.paraLength<1)
12143                 goto todo;
12144         for (i=0; i<BtReq.paraLength; i++)
12145         {
12146                 DBG_871X("%s: BtReq.pParamStart[%d] = 0x%02x \n",
12147                         __FUNCTION__, i, BtReq.pParamStart[i]);
12148         }
12149         
12150 todo:
12151         _rtw_memset(extra,'\0', wrqu->data.length);
12152
12153         if (padapter->bBTFWReady == _FALSE)
12154         {
12155                 sprintf(extra, "BTFWReady = FALSE.\n");
12156                 goto exit;
12157         }
12158
12159         mptbt_BtControlProcess(padapter, &BtReq);
12160
12161         if (readtherm == 0)
12162         {
12163                 sprintf(extra, "BT thermal=");
12164                 for (i=4; i<pMptCtx->mptOutLen; i++)
12165                 {
12166                         if ((pMptCtx->mptOutBuf[i]==0x00) && (pMptCtx->mptOutBuf[i+1]==0x00))
12167                                 goto exit;
12168
12169 #ifdef CONFIG_RTL8723A
12170                         sprintf(extra, "%s %d ", extra, (pMptCtx->mptOutBuf[i]& 0x3f));
12171 #else
12172                         sprintf(extra, "%s %d ", extra, (pMptCtx->mptOutBuf[i]& 0x1f));
12173 #endif
12174                 }
12175         }
12176         else
12177         {
12178                 for (i=4; i<pMptCtx->mptOutLen; i++)
12179                 {
12180                         sprintf(extra, "%s 0x%x ", extra, pMptCtx->mptOutBuf[i]);
12181                 }
12182         }
12183         
12184 exit:
12185         wrqu->data.length = strlen(extra) + 1;
12186         DBG_871X("-%s: output len=%d data=%s\n", __FUNCTION__, wrqu->data.length, extra);
12187
12188         return status;
12189 }
12190
12191 #endif //#ifdef CONFIG_RTL8723A
12192
12193 static int rtw_mp_set(struct net_device *dev,
12194                         struct iw_request_info *info,
12195                         union iwreq_data *wdata, char *extra)
12196 {
12197         struct iw_point *wrqu = (struct iw_point *)wdata;
12198         u32 subcmd = wrqu->flags;
12199         PADAPTER padapter = rtw_netdev_priv(dev);
12200
12201         if (padapter == NULL)
12202         {
12203                 return -ENETDOWN;
12204         }
12205
12206         if((padapter->bup == _FALSE ))
12207         {
12208                 DBG_871X(" %s fail =>(padapter->bup == _FALSE )\n",__FUNCTION__);
12209                 return -ENETDOWN;
12210         }
12211
12212         if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE))
12213        {        
12214         DBG_871X("%s fail =>(padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE) \n",__FUNCTION__);
12215              return -ENETDOWN;
12216        }
12217
12218         
12219         //_rtw_memset(extra, 0x00, IW_PRIV_SIZE_MASK);
12220
12221         if (extra == NULL)
12222         {
12223                 wrqu->length = 0;
12224                 return -EIO;
12225         }
12226
12227         switch(subcmd)
12228         {
12229         case MP_START:
12230                         DBG_871X("set case mp_start \n");
12231                         rtw_mp_start (dev,info,wrqu,extra);
12232                          break; 
12233                          
12234         case MP_STOP:
12235                         DBG_871X("set case mp_stop \n");
12236                         rtw_mp_stop (dev,info,wrqu,extra);
12237                          break; 
12238                          
12239         case MP_BANDWIDTH:
12240                         DBG_871X("set case mp_bandwidth \n");
12241                         rtw_mp_bandwidth (dev,info,wrqu,extra);
12242                         break;
12243                                 
12244         case MP_RESET_STATS:
12245                         DBG_871X("set case MP_RESET_STATS \n");
12246                         rtw_mp_reset_stats      (dev,info,wrqu,extra);
12247                         break;
12248         case MP_SetRFPathSwh:           
12249                         DBG_871X("set MP_SetRFPathSwitch \n");
12250                         rtw_mp_SetRFPath  (dev,info,wdata,extra);
12251                         break;
12252         case CTA_TEST:
12253                         DBG_871X("set CTA_TEST\n");
12254                         rtw_cta_test_start (dev, info, wdata, extra);
12255                         break;
12256         case MP_DISABLE_BT_COEXIST:
12257                         DBG_871X("set case MP_DISABLE_BT_COEXIST \n");
12258                         rtw_mp_disable_bt_coexist(dev, info, wdata, extra);
12259                 break;
12260 #ifdef CONFIG_AP_WOWLAN
12261         case MP_AP_WOW_ENABLE:
12262                         DBG_871X("set case MP_AP_WOW_ENABLE: %s \n", extra);
12263                         rtw_ap_wowlan_ctrl(dev, info, wdata, extra);
12264         break;
12265 #endif
12266         }
12267
12268           
12269         return 0;               
12270 }
12271
12272
12273 static int rtw_mp_get(struct net_device *dev,
12274                         struct iw_request_info *info,
12275                         union iwreq_data *wdata, char *extra)
12276 {
12277         struct iw_point *wrqu = (struct iw_point *)wdata;
12278         u32 subcmd = wrqu->flags;
12279         PADAPTER padapter = rtw_netdev_priv(dev);
12280
12281         //DBG_871X("in mp_get extra= %s \n",extra);
12282
12283         if (padapter == NULL)
12284         {
12285                 return -ENETDOWN;
12286         }
12287         if((padapter->bup == _FALSE ))
12288         {
12289                 DBG_871X(" %s fail =>(padapter->bup == _FALSE )\n",__FUNCTION__);
12290                 return -ENETDOWN;
12291         }
12292
12293         if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE))
12294        {        
12295         DBG_871X("%s fail =>(padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE) \n",__FUNCTION__);
12296              return -ENETDOWN;
12297        }
12298         
12299         if (extra == NULL)
12300         {
12301                 wrqu->length = 0;
12302                 return -EIO;
12303         }
12304         
12305         switch(subcmd)
12306         {
12307         case WRITE_REG :
12308                         rtw_mp_write_reg (dev,info,wrqu,extra);
12309                          break;
12310                          
12311         case WRITE_RF:
12312                         rtw_mp_write_rf (dev,info,wrqu,extra);
12313                          break; 
12314                          
12315         case MP_PHYPARA:
12316                         DBG_871X("mp_get  MP_PHYPARA \n");
12317                         rtw_mp_phypara(dev,info,wrqu,extra);    
12318                         break;
12319
12320         case MP_CHANNEL:
12321                         DBG_871X("set case mp_channel \n");
12322                         rtw_mp_channel (dev,info,wrqu,extra);
12323                         break;
12324                         
12325         case READ_REG:
12326                         DBG_871X("mp_get  READ_REG \n");
12327                         rtw_mp_read_reg (dev,info,wrqu,extra);
12328                          break; 
12329         case READ_RF:
12330                         DBG_871X("mp_get  READ_RF \n");
12331                         rtw_mp_read_rf (dev,info,wrqu,extra);
12332                         break; 
12333                         
12334         case MP_RATE:
12335                         DBG_871X("set case mp_rate \n");
12336                         rtw_mp_rate (dev,info,wrqu,extra);
12337                         break;
12338                         
12339         case MP_TXPOWER:
12340                         DBG_871X("set case MP_TXPOWER \n");
12341                         rtw_mp_txpower (dev,info,wrqu,extra);
12342                         break;
12343                         
12344         case MP_ANT_TX:
12345                         DBG_871X("set case MP_ANT_TX \n");
12346                         rtw_mp_ant_tx (dev,info,wrqu,extra);
12347                         break;
12348                         
12349         case MP_ANT_RX:
12350                         DBG_871X("set case MP_ANT_RX \n");
12351                         rtw_mp_ant_rx (dev,info,wrqu,extra);
12352                         break;
12353                         
12354         case MP_QUERY:
12355                         //DBG_871X("mp_get mp_query MP_QUERY \n");
12356                         rtw_mp_trx_query(dev,info,wrqu,extra);
12357                         break;
12358                                         
12359         case MP_CTX:
12360                         DBG_871X("set case MP_CTX \n");
12361                         rtw_mp_ctx (dev,info,wrqu,extra);
12362                         break;
12363                         
12364         case MP_ARX:
12365                         DBG_871X("set case MP_ARX \n");
12366                         rtw_mp_arx (dev,info,wrqu,extra);
12367                         break;
12368                         
12369         case EFUSE_GET:
12370                         DBG_871X("efuse get EFUSE_GET \n");
12371                         rtw_mp_efuse_get(dev,info,wdata,extra);
12372                  break; 
12373                  
12374         case MP_DUMP:
12375                         DBG_871X("set case MP_DUMP \n");
12376                         rtw_mp_dump (dev,info,wrqu,extra);
12377                  break; 
12378         case MP_PSD:
12379                         DBG_871X("set case MP_PSD \n");
12380                         rtw_mp_psd (dev,info,wrqu,extra);
12381                  break;
12382         case MP_THER:
12383                         DBG_871X("set case MP_THER \n");
12384                         rtw_mp_thermal (dev,info,wrqu,extra);
12385                 break;
12386         case MP_PwrCtlDM:
12387                         DBG_871X("set MP_PwrCtlDM\n");
12388                         rtw_mp_PwrCtlDM (dev,info,wrqu,extra);
12389                 break;
12390         case MP_QueryDrvStats:          
12391                         DBG_871X("mp_get MP_QueryDrvStats \n");
12392                         rtw_mp_QueryDrv(dev,info,wdata,extra);
12393                         break;
12394                 case MP_PWRTRK:
12395                         DBG_871X("set case MP_PWRTRK \n");
12396                         rtw_mp_pwrtrk(dev,info,wrqu,extra);
12397                         break;                   
12398         case EFUSE_SET:
12399                         DBG_871X("set case efuse set \n");
12400                         rtw_mp_efuse_set(dev,info,wdata,extra);
12401                         break;                   
12402         case MP_GET_TXPOWER_INX:
12403                         DBG_871X("mp_get MP_GET_TXPOWER_INX \n");
12404                         rtw_mp_txpower_index(dev,info,wrqu,extra);
12405                 break;
12406
12407 #if defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B)
12408         case MP_SetBT:          
12409                         DBG_871X("set MP_SetBT \n");
12410                         rtw_mp_SetBT(dev,info,wdata,extra);
12411                         break;           
12412 #endif
12413
12414         }
12415
12416         rtw_msleep_os(10); //delay 5ms for sending pkt before exit adb shell operation
12417 return 0;       
12418 }
12419
12420 #endif //#if defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT)
12421
12422 static int rtw_wfd_tdls_enable(struct net_device *dev,
12423                                 struct iw_request_info *info,
12424                                 union iwreq_data *wrqu, char *extra)
12425 {
12426         int ret = 0;
12427
12428 #ifdef CONFIG_TDLS
12429 #ifdef CONFIG_WFD
12430
12431         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12432
12433         printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12434
12435         if ( extra[ 0 ] == '0' )
12436         {
12437                 padapter->wdinfo.wfd_tdls_enable = 0;
12438         }
12439         else
12440         {
12441                 padapter->wdinfo.wfd_tdls_enable = 1;
12442         }
12443
12444 #endif //CONFIG_WFD
12445 #endif //CONFIG_TDLS
12446         
12447         return ret;
12448 }
12449
12450 static int rtw_tdls_weaksec(struct net_device *dev,
12451                                 struct iw_request_info *info,
12452                                 union iwreq_data *wrqu, char *extra)
12453 {
12454         int ret = 0;
12455
12456 #ifdef CONFIG_TDLS
12457
12458         u8 i, j;
12459         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12460
12461         DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12462
12463         if ( extra[ 0 ] == '0' )
12464         {
12465                 padapter->wdinfo.wfd_tdls_weaksec = 0;
12466         }
12467         else
12468         {
12469                 padapter->wdinfo.wfd_tdls_weaksec = 1;
12470         }
12471 #endif
12472         
12473         return ret;
12474 }
12475
12476
12477 static int rtw_tdls_enable(struct net_device *dev,
12478                                 struct iw_request_info *info,
12479                                 union iwreq_data *wrqu, char *extra)
12480 {
12481         int ret = 0;
12482
12483 #ifdef CONFIG_TDLS
12484
12485         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12486         struct tdls_info        *ptdlsinfo = &padapter->tdlsinfo;
12487         _irqL    irqL;
12488         _list   *plist, *phead;
12489         s32     index;
12490         struct sta_info *psta = NULL;
12491         struct  sta_priv *pstapriv = &padapter->stapriv;
12492         u8 tdls_sta[NUM_STA][ETH_ALEN];
12493         u8 empty_hwaddr[ETH_ALEN] = { 0x00 };
12494         struct tdls_txmgmt txmgmt;
12495
12496         printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12497
12498         _rtw_memset(tdls_sta, 0x00, sizeof(tdls_sta));
12499         _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12500
12501         if ( extra[ 0 ] == '0' )
12502         {
12503                 ptdlsinfo->tdls_enable = 0;
12504
12505                 if(pstapriv->asoc_sta_count==1)
12506                         return ret;
12507
12508                 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12509                 for(index=0; index< NUM_STA; index++)
12510                 {
12511                         phead = &(pstapriv->sta_hash[index]);
12512                         plist = get_next(phead);
12513                         
12514                         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12515                         {
12516                                 psta = LIST_CONTAINOR(plist, struct sta_info ,hash_list);
12517
12518                                 plist = get_next(plist);
12519
12520                                 if(psta->tdls_sta_state != TDLS_STATE_NONE)
12521                                 {
12522                                         _rtw_memcpy(tdls_sta[index], psta->hwaddr, ETH_ALEN);
12523                                 }
12524                         }
12525                 }
12526                 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12527
12528                 for(index=0; index< NUM_STA; index++)
12529                 {
12530                         if( !_rtw_memcmp(tdls_sta[index], empty_hwaddr, ETH_ALEN) )
12531                         {
12532                                 printk("issue tear down to "MAC_FMT"\n", MAC_ARG(tdls_sta[index]));
12533                                 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
12534                                 _rtw_memcpy(txmgmt.peer, tdls_sta[index], ETH_ALEN);
12535                                 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12536                         }
12537                 }
12538                 rtw_tdls_cmd(padapter, myid(&(padapter->eeprompriv)), TDLS_RS_RCR);
12539                 rtw_reset_tdls_info(padapter);
12540         }
12541         else if ( extra[ 0 ] == '1' )
12542         {
12543                 ptdlsinfo->tdls_enable = 1;
12544         }
12545 #endif //CONFIG_TDLS
12546         
12547         return ret;
12548 }
12549
12550 static int rtw_tdls_setup(struct net_device *dev,
12551                                 struct iw_request_info *info,
12552                                 union iwreq_data *wrqu, char *extra)
12553 {
12554         int ret = 0;
12555 #ifdef CONFIG_TDLS
12556         u8 i, j;
12557         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12558         struct tdls_txmgmt txmgmt;
12559 #ifdef CONFIG_WFD
12560         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
12561 #endif // CONFIG_WFD
12562
12563         printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12564
12565         if(wrqu->data.length - 1 != 17 )
12566         {
12567                 printk( "[%s] length:%d != 17\n", __FUNCTION__, (wrqu->data.length -1)  );
12568                 return ret;
12569         }
12570
12571         _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12572         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12573                 txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1));
12574         }
12575
12576 #ifdef CONFIG_WFD
12577         if ( _AES_ != padapter->securitypriv.dot11PrivacyAlgrthm )
12578         {
12579                 //      Weak Security situation with AP.
12580                 if ( 0 == pwdinfo->wfd_tdls_weaksec )
12581                 {
12582                         //      Can't send the tdls setup request out!!
12583                         DBG_871X( "[%s] Current link is not AES, SKIP sending the tdls setup request!!\n", __FUNCTION__ );
12584                 }
12585                 else
12586                 {
12587                         issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
12588                 }
12589         }
12590         else
12591 #endif // CONFIG_WFD
12592         {
12593                 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
12594         }
12595 #endif
12596         
12597         return ret;
12598 }
12599
12600 static int rtw_tdls_teardown(struct net_device *dev,
12601                                 struct iw_request_info *info,
12602                                 union iwreq_data *wrqu, char *extra)
12603 {
12604         int ret = 0;
12605
12606 #ifdef CONFIG_TDLS
12607
12608         u8 i,j;
12609         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12610         struct sta_info *ptdls_sta = NULL;
12611         struct tdls_txmgmt txmgmt;
12612
12613         DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12614
12615         if(wrqu->data.length - 1 != 17 && wrqu->data.length - 1 != 19)
12616         {
12617                 printk( "[%s] length:%d != 17 or 19\n", __FUNCTION__, (wrqu->data.length -1)  );
12618                 return ret;
12619         }
12620
12621         _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12622         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12623                 txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1));
12624         }
12625
12626         ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), txmgmt.peer);
12627         
12628         if(ptdls_sta != NULL)
12629         {
12630                 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
12631                 if(wrqu->data.length - 1 == 17)
12632                         issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12633                 else if(wrqu->data.length - 1 == 19)
12634                         issue_tdls_teardown(padapter, &txmgmt, _TRUE);
12635         }
12636         else
12637                 DBG_871X( "TDLS peer not found\n");
12638 #endif //CONFIG_TDLS
12639         
12640         return ret;
12641 }
12642
12643 static int rtw_tdls_discovery(struct net_device *dev,
12644                                 struct iw_request_info *info,
12645                                 union iwreq_data *wrqu, char *extra)
12646 {
12647         int ret = 0;
12648
12649 #ifdef CONFIG_TDLS
12650         
12651         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12652         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
12653         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12654         struct tdls_txmgmt      txmgmt;
12655         int i = 0, j=0;
12656
12657         DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12658
12659         _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12660         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12661                 txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1));
12662         }
12663
12664         issue_tdls_dis_req(padapter, &txmgmt);
12665
12666 #endif //CONFIG_TDLS
12667
12668         return ret;
12669 }
12670
12671 static int rtw_tdls_ch_switch(struct net_device *dev,
12672                                 struct iw_request_info *info,
12673                                 union iwreq_data *wrqu, char *extra)
12674 {
12675         int ret = 0;
12676
12677 #ifdef CONFIG_TDLS
12678         
12679         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12680         struct tdls_info        *ptdlsinfo = &padapter->tdlsinfo;
12681         u8 i, j, mac_addr[ETH_ALEN];
12682         struct sta_info *ptdls_sta = NULL;
12683
12684         DBG_8192C( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12685
12686         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12687                 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
12688         }
12689
12690         ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
12691         if( ptdls_sta == NULL )
12692                 return ret;
12693
12694 //      ptdlsinfo->ch_sensing=1;
12695
12696 //      rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_INIT_CH_SEN);
12697
12698 #endif //CONFIG_TDLS
12699
12700                 return ret;
12701 }
12702         
12703 static int rtw_tdls_pson(struct net_device *dev,
12704                                 struct iw_request_info *info,
12705                                 union iwreq_data *wrqu, char *extra)
12706 {
12707         int ret = 0;
12708
12709 #ifdef CONFIG_TDLS
12710         
12711         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12712         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
12713         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12714         u8 i, j, mac_addr[ETH_ALEN];
12715         struct sta_info *ptdls_sta = NULL;
12716
12717         DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12718
12719         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12720                 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
12721         }
12722
12723         ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
12724
12725         issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 1, 3, 500);
12726
12727 #endif //CONFIG_TDLS
12728
12729                 return ret;
12730 }
12731         
12732 static int rtw_tdls_psoff(struct net_device *dev,
12733                                 struct iw_request_info *info,
12734                                 union iwreq_data *wrqu, char *extra)
12735 {
12736         int ret = 0;
12737
12738 #ifdef CONFIG_TDLS
12739         
12740         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12741         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
12742         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12743         u8 i, j, mac_addr[ETH_ALEN];
12744         struct sta_info *ptdls_sta = NULL;
12745         
12746         DBG_8192C( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12747
12748         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12749                 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
12750         }
12751
12752         ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
12753
12754         if(ptdls_sta)
12755         {
12756                 //issue_tdls_peer_traffic_rsp(padapter, ptdls_sta);
12757                 issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 0, 3, 500);
12758         }
12759 #endif //CONFIG_TDLS
12760
12761         return ret;
12762 }
12763
12764 static int rtw_tdls_setip(struct net_device *dev,
12765                                 struct iw_request_info *info,
12766                                 union iwreq_data *wrqu, char *extra)
12767 {
12768         int ret = 0;
12769
12770 #ifdef CONFIG_TDLS
12771 #ifdef CONFIG_WFD
12772         
12773         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12774         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12775         struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
12776         u8 i=0, j=0, k=0, tag=0, ip[3] = { 0xff }, *ptr = extra;
12777         
12778         printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1  );
12779
12780
12781         while( i < 4 )
12782         {
12783                 for( j=0; j < 4; j++)
12784                 {
12785                         if( *( extra + j + tag ) == '.' || *( extra + j + tag ) == '\0' )
12786                         {
12787                                 if( j == 1 )
12788                                         pwfd_info->ip_address[i]=convert_ip_addr( '0', '0', *(extra+(j-1)+tag));
12789                                 if( j == 2 )
12790                                         pwfd_info->ip_address[i]=convert_ip_addr( '0', *(extra+(j-2)+tag), *(extra+(j-1)+tag));
12791                                 if( j == 3 )
12792                                         pwfd_info->ip_address[i]=convert_ip_addr( *(extra+(j-3)+tag), *(extra+(j-2)+tag), *(extra+(j-1)+tag));  
12793
12794                                 tag += j + 1;
12795                                 break;
12796                         }
12797                 }
12798                 i++;
12799         }
12800
12801         printk( "[%s] Set IP = %u.%u.%u.%u \n", __FUNCTION__, 
12802                 ptdlsinfo->wfd_info->ip_address[0], ptdlsinfo->wfd_info->ip_address[1],
12803                 ptdlsinfo->wfd_info->ip_address[2], ptdlsinfo->wfd_info->ip_address[3]
12804         );
12805
12806 #endif //CONFIG_WFD     
12807 #endif //CONFIG_TDLS
12808
12809         return ret;
12810 }
12811
12812 static int rtw_tdls_getip(struct net_device *dev,
12813                                 struct iw_request_info *info,
12814                                 union iwreq_data *wrqu, char *extra)
12815 {
12816         int ret = 0;
12817
12818 #ifdef CONFIG_TDLS
12819 #ifdef CONFIG_WFD
12820         
12821         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12822         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12823         struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
12824         
12825         printk( "[%s]\n", __FUNCTION__);
12826
12827         sprintf( extra, "\n\n%u.%u.%u.%u\n", 
12828                 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1], 
12829                 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]
12830                 );
12831
12832         printk( "[%s] IP=%u.%u.%u.%u\n", __FUNCTION__,
12833                 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1], 
12834                 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]
12835                 );
12836         
12837         wrqu->data.length = strlen( extra );
12838
12839 #endif //CONFIG_WFD     
12840 #endif //CONFIG_TDLS
12841
12842         return ret;
12843 }
12844
12845 static int rtw_tdls_getport(struct net_device *dev,
12846                                struct iw_request_info *info,
12847                                union iwreq_data *wrqu, char *extra)
12848 {
12849         
12850         int ret = 0;    
12851
12852 #ifdef CONFIG_TDLS
12853 #ifdef CONFIG_WFD
12854
12855         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12856         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12857         struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
12858
12859         printk( "[%s]\n", __FUNCTION__);
12860
12861         sprintf( extra, "\n\n%d\n", pwfd_info->peer_rtsp_ctrlport );
12862         printk( "[%s] remote port = %d\n", __FUNCTION__, pwfd_info->peer_rtsp_ctrlport );
12863         
12864         wrqu->data.length = strlen( extra );
12865
12866 #endif //CONFIG_WFD
12867 #endif //CONFIG_TDLS
12868
12869         return ret;
12870                 
12871 }
12872
12873 //WFDTDLS, for sigma test
12874 static int rtw_tdls_dis_result(struct net_device *dev,
12875                                struct iw_request_info *info,
12876                                union iwreq_data *wrqu, char *extra)
12877 {
12878         
12879         int ret = 0;    
12880
12881 #ifdef CONFIG_TDLS
12882 #ifdef CONFIG_WFD
12883
12884         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12885         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12886         struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
12887
12888         printk( "[%s]\n", __FUNCTION__);
12889
12890         if(ptdlsinfo->dev_discovered == 1 )
12891         {
12892                 sprintf( extra, "\n\nDis=1\n" );
12893                 ptdlsinfo->dev_discovered = 0;
12894         }
12895         
12896         wrqu->data.length = strlen( extra );
12897
12898 #endif //CONFIG_WFD
12899 #endif //CONFIG_TDLS
12900
12901         return ret;
12902                 
12903 }
12904
12905 //WFDTDLS, for sigma test
12906 static int rtw_wfd_tdls_status(struct net_device *dev,
12907                                struct iw_request_info *info,
12908                                union iwreq_data *wrqu, char *extra)
12909 {
12910         
12911         int ret = 0;    
12912
12913 #ifdef CONFIG_TDLS
12914
12915         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12916         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12917
12918         printk( "[%s]\n", __FUNCTION__);
12919
12920         sprintf( extra, "\nlink_established:0x%08x \n"
12921                 "sta_cnt:%d \n"
12922                 "sta_maximum:%d \n"
12923                 "cur_channel:%d \n"
12924                 "tdls_enable:%d",
12925                 ptdlsinfo->link_established, ptdlsinfo->sta_cnt, ptdlsinfo->sta_maximum,
12926                 ptdlsinfo->cur_channel, ptdlsinfo->tdls_enable
12927                 );
12928
12929         wrqu->data.length = strlen( extra );
12930
12931 #endif //CONFIG_TDLS
12932
12933         return ret;
12934                 
12935         }
12936
12937 static int rtw_tdls_getsta(struct net_device *dev,
12938                                struct iw_request_info *info,
12939                                union iwreq_data *wrqu, char *extra)
12940         {
12941         
12942         int ret = 0;
12943 #ifdef CONFIG_TDLS
12944         u8 i, j;
12945         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12946         u8 addr[ETH_ALEN] = {0};
12947         char charmac[17];
12948         struct sta_info *ptdls_sta = NULL;
12949
12950         printk( "[%s] %s %d\n", __FUNCTION__, (char *)wrqu->data.pointer, wrqu->data.length -1  );
12951
12952         if(copy_from_user(charmac, wrqu->data.pointer+9, 17)){
12953                 ret = -EFAULT;
12954                 goto exit;
12955         }
12956         
12957         printk("[%s] %d, charmac:%s\n", __FUNCTION__, __LINE__, charmac);
12958         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12959                 addr[i]=key_2char2num(*(charmac+j), *(charmac+j+1));
12960         }
12961
12962         printk("[%s] %d, charmac:%s, addr:"MAC_FMT"\n", __FUNCTION__, __LINE__, charmac, MAC_ARG(addr));
12963         ptdls_sta = rtw_get_stainfo(&padapter->stapriv, addr);  
12964         if(ptdls_sta) {
12965                 sprintf(extra, "\n\ntdls_sta_state=%d\n", ptdls_sta->tdls_sta_state);
12966                 printk("\n\ntdls_sta_state=%d\n", ptdls_sta->tdls_sta_state);
12967         }
12968         else {
12969                 sprintf(extra, "\n\nNot found this sta\n");
12970                 printk("\n\nNot found this sta\n");
12971         }
12972         wrqu->data.length = strlen( extra );
12973
12974 #endif //CONFIG_TDLS
12975 exit:
12976         return ret;
12977                 
12978 }
12979
12980 static int rtw_tdls_ch_switch_off(struct net_device *dev,
12981                                 struct iw_request_info *info,
12982                                 union iwreq_data *wrqu, char *extra)
12983 {
12984         int ret = 0;
12985
12986 #ifdef CONFIG_TDLS
12987         
12988         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12989         u8 i, j, mac_addr[ETH_ALEN];
12990         struct sta_info *ptdls_sta = NULL;
12991         
12992         DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12993
12994         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12995                 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
12996         }
12997
12998         ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
12999
13000         ptdls_sta->tdls_sta_state |= TDLS_SW_OFF_STATE;
13001 /*
13002         if((ptdls_sta->tdls_sta_state & TDLS_AT_OFF_CH_STATE) && (ptdls_sta->tdls_sta_state & TDLS_PEER_AT_OFF_STATE)){
13003                 pmlmeinfo->tdls_candidate_ch= pmlmeext->cur_channel;
13004                 issue_tdls_ch_switch_req(padapter, mac_addr);
13005                 DBG_871X("issue tdls ch switch req back to base channel\n");
13006         }
13007 */
13008         
13009 #endif //CONFIG_TDLS
13010
13011         return ret;
13012 }
13013
13014 static int rtw_tdls(struct net_device *dev,
13015                                 struct iw_request_info *info,
13016                                 union iwreq_data *wrqu, char *extra)
13017 {
13018         int ret = 0;
13019
13020 #ifdef CONFIG_TDLS
13021         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
13022
13023
13024
13025         DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra );
13026         //      WFD Sigma will use the tdls enable command to let the driver know we want to test the tdls now!
13027         if ( _rtw_memcmp( extra, "wfdenable=", 10 ) )
13028         {
13029                 wrqu->data.length -=10;
13030                 rtw_wfd_tdls_enable( dev, info, wrqu, &extra[10] );
13031                 return ret;
13032         }
13033         else if ( _rtw_memcmp( extra, "weaksec=", 8 ) )
13034         {
13035                 wrqu->data.length -=8;
13036                 rtw_tdls_weaksec( dev, info, wrqu, &extra[8] );
13037                 return ret;
13038         }
13039         else if ( _rtw_memcmp( extra, "tdlsenable=", 11 ) )
13040         {
13041                 wrqu->data.length -=11;
13042                 rtw_tdls_enable( dev, info, wrqu, &extra[11] );
13043                 return ret;
13044         }
13045
13046         if( padapter->tdlsinfo.tdls_enable == 0 )
13047         {
13048                 printk("tdls haven't enabled\n");
13049                 return 0;
13050         }
13051
13052         if ( _rtw_memcmp( extra, "setup=", 6 ) )
13053         {
13054                 wrqu->data.length -=6;
13055                 rtw_tdls_setup( dev, info, wrqu, &extra[6] );
13056         }
13057         else if (_rtw_memcmp( extra, "tear=", 5 ) )
13058         {
13059                 wrqu->data.length -= 5;
13060                 rtw_tdls_teardown( dev, info, wrqu, &extra[5] );
13061         }
13062         else if (_rtw_memcmp( extra, "dis=", 4 ) )
13063         {
13064                 wrqu->data.length -= 4;
13065                 rtw_tdls_discovery( dev, info, wrqu, &extra[4] );
13066         }
13067         else if (_rtw_memcmp( extra, "sw=", 3 ) )
13068         {
13069                 wrqu->data.length -= 3;
13070                 rtw_tdls_ch_switch( dev, info, wrqu, &extra[3] );
13071         }
13072         else if (_rtw_memcmp( extra, "swoff=", 6 ) )
13073         {
13074                 wrqu->data.length -= 6;
13075                 rtw_tdls_ch_switch_off( dev, info, wrqu, &extra[6] );
13076         }       
13077         else if (_rtw_memcmp( extra, "pson=", 5 ) )
13078         {
13079                 wrqu->data.length -= 5;
13080                 rtw_tdls_pson( dev, info, wrqu, &extra[5] );
13081         }
13082         else if (_rtw_memcmp( extra, "psoff=", 6 ) )
13083         {
13084                 wrqu->data.length -= 6;
13085                 rtw_tdls_psoff( dev, info, wrqu, &extra[6] );
13086         }
13087 #ifdef CONFIG_WFD
13088         else if (_rtw_memcmp( extra, "setip=", 6 ) )
13089         {
13090                 wrqu->data.length -= 6;
13091                 rtw_tdls_setip( dev, info, wrqu, &extra[6] );
13092         }
13093         else if (_rtw_memcmp( extra, "tprobe=", 6 ) )
13094         {
13095                 issue_tunneled_probe_req((_adapter *)rtw_netdev_priv(dev));
13096         }
13097 #endif //CONFIG_WFD
13098
13099 #endif //CONFIG_TDLS
13100         
13101         return ret;
13102 }
13103
13104
13105 static int rtw_tdls_get(struct net_device *dev,
13106                                 struct iw_request_info *info,
13107                                 union iwreq_data *wrqu, char *extra)
13108 {
13109         int ret = 0;
13110
13111 #ifdef CONFIG_WFD
13112
13113         DBG_871X( "[%s] extra = %s\n", __FUNCTION__, (char*) wrqu->data.pointer );
13114
13115         if ( _rtw_memcmp( wrqu->data.pointer, "ip", 2 ) )
13116         {
13117                 rtw_tdls_getip( dev, info, wrqu, extra );
13118         }
13119         if ( _rtw_memcmp( wrqu->data.pointer, "port", 4 ) )
13120         {
13121                 rtw_tdls_getport( dev, info, wrqu, extra );
13122         }
13123         //WFDTDLS, for sigma test
13124         if ( _rtw_memcmp( wrqu->data.pointer, "dis", 3 ) )
13125         {
13126                 rtw_tdls_dis_result( dev, info, wrqu, extra );
13127         }
13128         if ( _rtw_memcmp( wrqu->data.pointer, "status", 6 ) )
13129         {
13130                 rtw_wfd_tdls_status( dev, info, wrqu, extra );
13131         }
13132         if ( _rtw_memcmp( wrqu->data.pointer, "tdls_sta=", 9 ) )
13133         {
13134                 rtw_tdls_getsta( dev, info, wrqu, extra );
13135         }
13136
13137 #endif //CONFIG_WFD
13138
13139         return ret;
13140 }
13141
13142
13143
13144
13145
13146 #ifdef CONFIG_INTEL_WIDI
13147 static int rtw_widi_set(struct net_device *dev,
13148                                struct iw_request_info *info,
13149                                union iwreq_data *wrqu, char *extra)
13150 {
13151         int ret = 0;
13152         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
13153
13154         process_intel_widi_cmd(padapter, extra);
13155
13156         return ret;
13157 }
13158
13159 static int rtw_widi_set_probe_request(struct net_device *dev,
13160                                struct iw_request_info *info,
13161                                union iwreq_data *wrqu, char *extra)
13162 {
13163         int     ret = 0;
13164         u8      *pbuf = NULL;
13165         _adapter        *padapter = (_adapter *)rtw_netdev_priv(dev);
13166
13167         pbuf = rtw_malloc(sizeof(l2_msg_t));
13168         if(pbuf)
13169         {
13170                 if ( copy_from_user(pbuf, wrqu->data.pointer, wrqu->data.length) )
13171                         ret = -EFAULT;
13172                 //_rtw_memcpy(pbuf, wrqu->data.pointer, wrqu->data.length);
13173
13174                 if( wrqu->data.flags == 0 )
13175                         intel_widi_wk_cmd(padapter, INTEL_WIDI_ISSUE_PROB_WK, pbuf, sizeof(l2_msg_t));
13176                 else if( wrqu->data.flags == 1 )
13177                         rtw_set_wfd_rds_sink_info( padapter, (l2_msg_t *)pbuf );
13178         }
13179         return ret;
13180 }
13181 #endif // CONFIG_INTEL_WIDI
13182
13183 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
13184
13185 #ifdef CONFIG_RTL8723A
13186 extern void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc);
13187 #define cal_txdesc_chksum rtl8723a_cal_txdesc_chksum
13188 extern void rtl8723a_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
13189 #define fill_default_txdesc rtl8723a_fill_default_txdesc
13190 #endif
13191 #if defined(CONFIG_RTL8188E)
13192 #include <rtl8188e_hal.h>
13193 extern void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc);
13194 #define cal_txdesc_chksum rtl8188e_cal_txdesc_chksum
13195 #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)
13196 extern void rtl8188es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
13197 #define fill_default_txdesc rtl8188es_fill_default_txdesc
13198 #endif // CONFIG_SDIO_HCI
13199 #endif // CONFIG_RTL8188E
13200 #if defined(CONFIG_RTL8723B)
13201 extern void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc);
13202 #define cal_txdesc_chksum rtl8723b_cal_txdesc_chksum
13203 extern void rtl8723b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
13204 #define fill_default_txdesc rtl8723b_fill_default_txdesc
13205 #endif // CONFIG_RTL8723B
13206
13207 static s32 initLoopback(PADAPTER padapter)
13208 {
13209         PLOOPBACKDATA ploopback;
13210
13211
13212         if (padapter->ploopback == NULL) {
13213                 ploopback = (PLOOPBACKDATA)rtw_zmalloc(sizeof(LOOPBACKDATA));
13214                 if (ploopback == NULL) return -ENOMEM;
13215
13216                 _rtw_init_sema(&ploopback->sema, 0);
13217                 ploopback->bstop = _TRUE;
13218                 ploopback->cnt = 0;
13219                 ploopback->size = 300;
13220                 _rtw_memset(ploopback->msg, 0, sizeof(ploopback->msg));
13221
13222                 padapter->ploopback = ploopback;
13223         }
13224
13225         return 0;
13226 }
13227
13228 static void freeLoopback(PADAPTER padapter)
13229 {
13230         PLOOPBACKDATA ploopback;
13231
13232
13233         ploopback = padapter->ploopback;
13234         if (ploopback) {
13235                 rtw_mfree((u8*)ploopback, sizeof(LOOPBACKDATA));
13236                 padapter->ploopback = NULL;
13237         }
13238 }
13239
13240 static s32 initpseudoadhoc(PADAPTER padapter)
13241 {
13242         NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
13243         s32 err;
13244
13245         networkType = Ndis802_11IBSS;
13246         err = rtw_set_802_11_infrastructure_mode(padapter, networkType);
13247         if (err == _FALSE) return _FAIL;
13248
13249         err = rtw_setopmode_cmd(padapter, networkType,_TRUE);
13250         if (err == _FAIL) return _FAIL;
13251
13252         return _SUCCESS;
13253 }
13254
13255 static s32 createpseudoadhoc(PADAPTER padapter)
13256 {
13257         NDIS_802_11_AUTHENTICATION_MODE authmode;
13258         struct mlme_priv *pmlmepriv;
13259         NDIS_802_11_SSID *passoc_ssid;
13260         WLAN_BSSID_EX *pdev_network;
13261         u8 *pibss;
13262         u8 ssid[] = "pseduo_ad-hoc";
13263         s32 err;
13264         _irqL irqL;
13265
13266
13267         pmlmepriv = &padapter->mlmepriv;
13268
13269         authmode = Ndis802_11AuthModeOpen;
13270         err = rtw_set_802_11_authentication_mode(padapter, authmode);
13271         if (err == _FALSE) return _FAIL;
13272
13273         passoc_ssid = &pmlmepriv->assoc_ssid;
13274         _rtw_memset(passoc_ssid, 0, sizeof(NDIS_802_11_SSID));
13275         passoc_ssid->SsidLength = sizeof(ssid) - 1;
13276         _rtw_memcpy(passoc_ssid->Ssid, ssid, passoc_ssid->SsidLength);
13277
13278         pdev_network = &padapter->registrypriv.dev_network;
13279         pibss = padapter->registrypriv.dev_network.MacAddress;
13280         _rtw_memcpy(&pdev_network->Ssid, passoc_ssid, sizeof(NDIS_802_11_SSID));
13281
13282         rtw_update_registrypriv_dev_network(padapter);
13283         rtw_generate_random_ibss(pibss);
13284
13285         _enter_critical_bh(&pmlmepriv->lock, &irqL);
13286         pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
13287         _exit_critical_bh(&pmlmepriv->lock, &irqL);
13288
13289 #if 0
13290         err = rtw_createbss_cmd(padapter);
13291         if (err == _FAIL) return _FAIL;
13292 #else
13293 {
13294         struct wlan_network *pcur_network;
13295         struct sta_info *psta;
13296
13297         //3  create a new psta
13298         pcur_network = &pmlmepriv->cur_network;
13299
13300         //clear psta in the cur_network, if any
13301         psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress);
13302         if (psta) rtw_free_stainfo(padapter, psta);
13303
13304         psta = rtw_alloc_stainfo(&padapter->stapriv, pibss);
13305         if (psta == NULL) return _FAIL;
13306
13307         //3  join psudo AdHoc
13308         pcur_network->join_res = 1;
13309         pcur_network->aid = psta->aid = 1;
13310         _rtw_memcpy(&pcur_network->network, pdev_network, get_WLAN_BSSID_EX_sz(pdev_network));
13311
13312         // set msr to WIFI_FW_ADHOC_STATE
13313 #if 0
13314         Set_NETYPE0_MSR(padapter, WIFI_FW_ADHOC_STATE);
13315 #else
13316         {
13317                 u8 val8;
13318
13319                 val8 = rtw_read8(padapter, MSR);
13320                 val8 &= 0xFC; // clear NETYPE0
13321                 val8 |= WIFI_FW_ADHOC_STATE & 0x3;
13322                 rtw_write8(padapter, MSR, val8);
13323         }
13324 #endif
13325 }
13326 #endif
13327
13328         return _SUCCESS;
13329 }
13330
13331 static struct xmit_frame* createloopbackpkt(PADAPTER padapter, u32 size)
13332 {
13333         struct xmit_priv *pxmitpriv;
13334         struct xmit_frame *pframe;
13335         struct xmit_buf *pxmitbuf;
13336         struct pkt_attrib *pattrib;
13337         struct tx_desc *desc;
13338         u8 *pkt_start, *pkt_end, *ptr;
13339         struct rtw_ieee80211_hdr *hdr;
13340         s32 bmcast;
13341         _irqL irqL;
13342
13343
13344         if ((TXDESC_SIZE + WLANHDR_OFFSET + size) > MAX_XMITBUF_SZ) return NULL;
13345
13346         pxmitpriv = &padapter->xmitpriv;
13347         pframe = NULL;
13348
13349         //2 1. allocate xmit frame
13350         pframe = rtw_alloc_xmitframe(pxmitpriv);
13351         if (pframe == NULL) return NULL;
13352         pframe->padapter = padapter;
13353
13354         //2 2. allocate xmit buffer
13355         _enter_critical_bh(&pxmitpriv->lock, &irqL);
13356         pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
13357         _exit_critical_bh(&pxmitpriv->lock, &irqL);
13358         if (pxmitbuf == NULL) {
13359                 rtw_free_xmitframe(pxmitpriv, pframe);
13360                 return NULL;
13361         }
13362
13363         pframe->pxmitbuf = pxmitbuf;
13364         pframe->buf_addr = pxmitbuf->pbuf;
13365         pxmitbuf->priv_data = pframe;
13366
13367         //2 3. update_attrib()
13368         pattrib = &pframe->attrib;
13369
13370         // init xmitframe attribute
13371         _rtw_memset(pattrib, 0, sizeof(struct pkt_attrib));
13372
13373         pattrib->ether_type = 0x8723;
13374         _rtw_memcpy(pattrib->src, padapter->eeprompriv.mac_addr, ETH_ALEN);
13375         _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
13376         _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);
13377         _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
13378
13379 //      pattrib->dhcp_pkt = 0;
13380 //      pattrib->pktlen = 0;
13381         pattrib->ack_policy = 0;
13382 //      pattrib->pkt_hdrlen = ETH_HLEN;
13383         pattrib->hdrlen = WLAN_HDR_A3_LEN;
13384         pattrib->subtype = WIFI_DATA;
13385         pattrib->priority = 0;
13386         pattrib->qsel = pattrib->priority;
13387 //      do_queue_select(padapter, pattrib);
13388         pattrib->nr_frags = 1;
13389         pattrib->encrypt = 0;
13390         pattrib->bswenc = _FALSE;
13391         pattrib->qos_en = _FALSE;
13392
13393         bmcast = IS_MCAST(pattrib->ra);
13394         if (bmcast) {
13395                 pattrib->mac_id = 1;
13396                 pattrib->psta = rtw_get_bcmc_stainfo(padapter);
13397         } else {
13398                 pattrib->mac_id = 0;
13399                 pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
13400         }
13401
13402         pattrib->pktlen = size;
13403         pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen;
13404
13405         //2 4. fill TX descriptor
13406         desc = (struct tx_desc*)pframe->buf_addr;
13407         _rtw_memset(desc, 0, TXDESC_SIZE);
13408
13409         fill_default_txdesc(pframe, (u8*)desc);
13410
13411         // Hw set sequence number
13412         ((PTXDESC)desc)->hwseq_en = 0; // HWSEQ_EN, 0:disable, 1:enable
13413 //      ((PTXDESC)desc)->hwseq_sel = 0; // HWSEQ_SEL
13414
13415         ((PTXDESC)desc)->disdatafb = 1;
13416
13417         // convert to little endian
13418         desc->txdw0 = cpu_to_le32(desc->txdw0);
13419         desc->txdw1 = cpu_to_le32(desc->txdw1);
13420         desc->txdw2 = cpu_to_le32(desc->txdw2);
13421         desc->txdw3 = cpu_to_le32(desc->txdw3);
13422         desc->txdw4 = cpu_to_le32(desc->txdw4);
13423         desc->txdw5 = cpu_to_le32(desc->txdw5);
13424         desc->txdw6 = cpu_to_le32(desc->txdw6);
13425         desc->txdw7 = cpu_to_le32(desc->txdw7);
13426 #ifdef CONFIG_PCI_HCI
13427         desc->txdw8 = cpu_to_le32(desc->txdw8);
13428         desc->txdw9 = cpu_to_le32(desc->txdw9);
13429         desc->txdw10 = cpu_to_le32(desc->txdw10);
13430         desc->txdw11 = cpu_to_le32(desc->txdw11);
13431         desc->txdw12 = cpu_to_le32(desc->txdw12);
13432         desc->txdw13 = cpu_to_le32(desc->txdw13);
13433         desc->txdw14 = cpu_to_le32(desc->txdw14);
13434         desc->txdw15 = cpu_to_le32(desc->txdw15);
13435 #endif
13436
13437         cal_txdesc_chksum(desc);
13438
13439         //2 5. coalesce
13440         pkt_start = pframe->buf_addr + TXDESC_SIZE;
13441         pkt_end = pkt_start + pattrib->last_txcmdsz;
13442
13443         //3 5.1. make wlan header, make_wlanhdr()
13444         hdr = (struct rtw_ieee80211_hdr *)pkt_start;
13445         SetFrameSubType(&hdr->frame_ctl, pattrib->subtype);
13446         _rtw_memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); // DA
13447         _rtw_memcpy(hdr->addr2, pattrib->src, ETH_ALEN); // SA
13448         _rtw_memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); // RA, BSSID
13449
13450         //3 5.2. make payload
13451         ptr = pkt_start + pattrib->hdrlen;
13452         get_random_bytes(ptr, pkt_end - ptr);
13453
13454         pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz;
13455         pxmitbuf->ptail += pxmitbuf->len;
13456
13457         return pframe;
13458 }
13459
13460 static void freeloopbackpkt(PADAPTER padapter, struct xmit_frame *pframe)
13461 {
13462         struct xmit_priv *pxmitpriv;
13463         struct xmit_buf *pxmitbuf;
13464
13465
13466         pxmitpriv = &padapter->xmitpriv;
13467         pxmitbuf = pframe->pxmitbuf;
13468
13469         rtw_free_xmitframe(pxmitpriv, pframe);
13470         rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
13471 }
13472
13473 static void printdata(u8 *pbuf, u32 len)
13474 {
13475         u32 i, val;
13476
13477
13478         for (i = 0; (i+4) <= len; i+=4) {
13479                 printk("%08X", *(u32*)(pbuf + i));
13480                 if ((i+4) & 0x1F) printk(" ");
13481                 else printk("\n");
13482         }
13483
13484         if (i < len)
13485         {
13486 #ifdef CONFIG_BIG_ENDIAN
13487                 for (; i < len, i++)
13488                         printk("%02X", pbuf+i);
13489 #else // CONFIG_LITTLE_ENDIAN
13490 #if 0
13491                 val = 0;
13492                 _rtw_memcpy(&val, pbuf + i, len - i);
13493                 printk("%8X", val);
13494 #else
13495                 u8 str[9];
13496                 u8 n;
13497                 val = 0;
13498                 n = len - i;
13499                 _rtw_memcpy(&val, pbuf+i, n);
13500                 sprintf(str, "%08X", val);
13501                 n = (4 - n) * 2;
13502                 printk("%8s", str+n);
13503 #endif
13504 #endif // CONFIG_LITTLE_ENDIAN
13505         }
13506         printk("\n");
13507 }
13508
13509 static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz)
13510 {
13511         PHAL_DATA_TYPE phal;
13512         struct recv_stat *prxstat;
13513         struct recv_stat report;
13514         PRXREPORT prxreport;
13515         u32 drvinfosize;
13516         u32 rxpktsize;
13517         u8 fcssize;
13518         u8 ret = _FALSE;
13519
13520         prxstat = (struct recv_stat*)rxbuf;
13521         report.rxdw0 = le32_to_cpu(prxstat->rxdw0);
13522         report.rxdw1 = le32_to_cpu(prxstat->rxdw1);
13523         report.rxdw2 = le32_to_cpu(prxstat->rxdw2);
13524         report.rxdw3 = le32_to_cpu(prxstat->rxdw3);
13525         report.rxdw4 = le32_to_cpu(prxstat->rxdw4);
13526         report.rxdw5 = le32_to_cpu(prxstat->rxdw5);
13527
13528         prxreport = (PRXREPORT)&report;
13529         drvinfosize = prxreport->drvinfosize << 3;
13530         rxpktsize = prxreport->pktlen;
13531
13532         phal = GET_HAL_DATA(padapter);
13533         if (phal->ReceiveConfig & RCR_APPFCS) fcssize = IEEE80211_FCS_LEN;
13534         else fcssize = 0;
13535
13536         if ((txsz - TXDESC_SIZE) != (rxpktsize - fcssize)) {
13537                 DBG_8192C("%s: ERROR! size not match tx/rx=%d/%d !\n",
13538                         __func__, txsz - TXDESC_SIZE, rxpktsize - fcssize);
13539                 ret = _FALSE;
13540         } else {
13541                 ret = _rtw_memcmp(txbuf + TXDESC_SIZE,\
13542                                                   rxbuf + RXDESC_SIZE + drvinfosize,\
13543                                                   txsz - TXDESC_SIZE);
13544                 if (ret == _FALSE) {
13545                         DBG_8192C("%s: ERROR! pkt content mismatch!\n", __func__);
13546                 }
13547         }
13548
13549         if (ret == _FALSE)
13550         {
13551                 DBG_8192C("\n%s: TX PKT total=%d, desc=%d, content=%d\n",
13552                         __func__, txsz, TXDESC_SIZE, txsz - TXDESC_SIZE);
13553                 DBG_8192C("%s: TX DESC size=%d\n", __func__, TXDESC_SIZE);
13554                 printdata(txbuf, TXDESC_SIZE);
13555                 DBG_8192C("%s: TX content size=%d\n", __func__, txsz - TXDESC_SIZE);
13556                 printdata(txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE);
13557
13558                 DBG_8192C("\n%s: RX PKT read=%d offset=%d(%d,%d) content=%d\n",
13559                         __func__, rxsz, RXDESC_SIZE + drvinfosize, RXDESC_SIZE, drvinfosize, rxpktsize);
13560                 if (rxpktsize != 0)
13561                 {
13562                         DBG_8192C("%s: RX DESC size=%d\n", __func__, RXDESC_SIZE);
13563                         printdata(rxbuf, RXDESC_SIZE);
13564                         DBG_8192C("%s: RX drvinfo size=%d\n", __func__, drvinfosize);
13565                         printdata(rxbuf + RXDESC_SIZE, drvinfosize);
13566                         DBG_8192C("%s: RX content size=%d\n", __func__, rxpktsize);
13567                         printdata(rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize);
13568                 } else {
13569                         DBG_8192C("%s: RX data size=%d\n", __func__, rxsz);
13570                         printdata(rxbuf, rxsz);
13571                 }
13572         }
13573
13574         return ret;
13575 }
13576
13577 thread_return lbk_thread(thread_context context)
13578 {
13579         s32 err;
13580         PADAPTER padapter;
13581         PLOOPBACKDATA ploopback;
13582         struct xmit_frame *pxmitframe;
13583         u32 cnt, ok, fail, headerlen;
13584         u32 pktsize;
13585         u32 ff_hwaddr;
13586
13587
13588         padapter = (PADAPTER)context;
13589         ploopback = padapter->ploopback;
13590         if (ploopback == NULL) return -1;
13591         cnt = 0;
13592         ok = 0;
13593         fail = 0;
13594
13595         daemonize("%s", "RTW_LBK_THREAD");
13596         allow_signal(SIGTERM);
13597
13598         do {
13599                 if (ploopback->size == 0) {
13600                         get_random_bytes(&pktsize, 4);
13601                         pktsize = (pktsize % 1535) + 1; // 1~1535
13602                 } else
13603                         pktsize = ploopback->size;
13604                 
13605                 pxmitframe = createloopbackpkt(padapter, pktsize);
13606                 if (pxmitframe == NULL) {
13607                         sprintf(ploopback->msg, "loopback FAIL! 3. create Packet FAIL!");
13608                         break;
13609                 }
13610
13611                 ploopback->txsize = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz;
13612                 _rtw_memcpy(ploopback->txbuf, pxmitframe->buf_addr, ploopback->txsize);
13613                 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
13614                 cnt++;
13615                 DBG_8192C("%s: wirte port cnt=%d size=%d\n", __func__, cnt, ploopback->txsize);
13616                 pxmitframe->pxmitbuf->pdata = ploopback->txbuf;
13617                 rtw_write_port(padapter, ff_hwaddr, ploopback->txsize, (u8 *)pxmitframe->pxmitbuf);
13618
13619                 // wait for rx pkt
13620                 _rtw_down_sema(&ploopback->sema);
13621
13622                 err = pktcmp(padapter, ploopback->txbuf, ploopback->txsize, ploopback->rxbuf, ploopback->rxsize);
13623                 if (err == _TRUE)
13624                         ok++;
13625                 else
13626                         fail++;
13627
13628                 ploopback->txsize = 0;
13629                 _rtw_memset(ploopback->txbuf, 0, 0x8000);
13630                 ploopback->rxsize = 0;
13631                 _rtw_memset(ploopback->rxbuf, 0, 0x8000);
13632
13633                 freeloopbackpkt(padapter, pxmitframe);
13634                 pxmitframe = NULL;
13635
13636                 if (signal_pending(current)) {
13637                         flush_signals(current);
13638                 }
13639
13640                 if ((ploopback->bstop == _TRUE) ||
13641                         ((ploopback->cnt != 0) && (ploopback->cnt == cnt)))
13642                 {
13643                         u32 ok_rate, fail_rate, all;
13644                         all = cnt;
13645                         ok_rate = (ok*100)/all;
13646                         fail_rate = (fail*100)/all;
13647                         sprintf(ploopback->msg,\
13648                                         "loopback result: ok=%d%%(%d/%d),error=%d%%(%d/%d)",\
13649                                         ok_rate, ok, all, fail_rate, fail, all);
13650                         break;
13651                 }
13652         } while (1);
13653
13654         ploopback->bstop = _TRUE;
13655
13656         thread_exit();
13657 }
13658
13659 static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8* pmsg)
13660 {
13661         PLOOPBACKDATA ploopback;
13662         u32 len;
13663         s32 err;
13664
13665
13666         ploopback = padapter->ploopback;
13667
13668         if (ploopback)
13669         {
13670                 if (ploopback->bstop == _FALSE) {
13671                         ploopback->bstop = _TRUE;
13672                         _rtw_up_sema(&ploopback->sema);
13673                 }
13674                 len = 0;
13675                 do {
13676                         len = strlen(ploopback->msg);
13677                         if (len) break;
13678                         rtw_msleep_os(1);
13679                 } while (1);
13680                 _rtw_memcpy(pmsg, ploopback->msg, len+1);
13681                 freeLoopback(padapter);
13682
13683                 return;
13684         }
13685
13686         // disable dynamic algorithm
13687         {
13688         u32 DMFlag = DYNAMIC_FUNC_DISABLE;
13689         rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8*)&DMFlag);
13690         }
13691
13692         // create pseudo ad-hoc connection
13693         err = initpseudoadhoc(padapter);
13694         if (err == _FAIL) {
13695                 sprintf(pmsg, "loopback FAIL! 1.1 init ad-hoc FAIL!");
13696                 return;
13697         }
13698
13699         err = createpseudoadhoc(padapter);
13700         if (err == _FAIL) {
13701                 sprintf(pmsg, "loopback FAIL! 1.2 create ad-hoc master FAIL!");
13702                 return;
13703         }
13704
13705         err = initLoopback(padapter);
13706         if (err) {
13707                 sprintf(pmsg, "loopback FAIL! 2. init FAIL! error code=%d", err);
13708                 return;
13709         }
13710
13711         ploopback = padapter->ploopback;
13712
13713         ploopback->bstop = _FALSE;
13714         ploopback->cnt = cnt;
13715         ploopback->size = size;
13716         ploopback->lbkthread = kthread_run(lbk_thread, padapter, "RTW_LBK_THREAD");
13717         if (IS_ERR(padapter->lbkthread))
13718         {
13719                 freeLoopback(padapter);
13720                 sprintf(pmsg, "loopback start FAIL! cnt=%d", cnt);
13721                 return;
13722         }
13723
13724         sprintf(pmsg, "loopback start! cnt=%d", cnt);
13725 }
13726 #endif // CONFIG_MAC_LOOPBACK_DRIVER
13727
13728 static int rtw_test(
13729         struct net_device *dev,
13730         struct iw_request_info *info,
13731         union iwreq_data *wrqu, char *extra)
13732 {
13733         u32 len;
13734         u8 *pbuf, *pch;
13735         char *ptmp;
13736         u8 *delim = ",";
13737         PADAPTER padapter = rtw_netdev_priv(dev);
13738
13739
13740         DBG_871X("+%s\n", __func__);
13741         len = wrqu->data.length;
13742
13743         pbuf = (u8*)rtw_zmalloc(len);
13744         if (pbuf == NULL) {
13745                 DBG_871X("%s: no memory!\n", __func__);
13746                 return -ENOMEM;
13747         }
13748
13749         if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
13750                 rtw_mfree(pbuf, len);
13751                 DBG_871X("%s: copy from user fail!\n", __func__);
13752                 return -EFAULT;
13753         }
13754         DBG_871X("%s: string=\"%s\"\n", __func__, pbuf);
13755
13756         ptmp = (char*)pbuf;
13757         pch = strsep(&ptmp, delim);
13758         if ((pch == NULL) || (strlen(pch) == 0)) {
13759                 rtw_mfree(pbuf, len);
13760                 DBG_871X("%s: parameter error(level 1)!\n", __func__);
13761                 return -EFAULT;
13762         }
13763
13764 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
13765         if (strcmp(pch, "loopback") == 0)
13766         {
13767                 s32 cnt = 0;
13768                 u32 size = 64;
13769
13770                 pch = strsep(&ptmp, delim);
13771                 if ((pch == NULL) || (strlen(pch) == 0)) {
13772                         rtw_mfree(pbuf, len);
13773                         DBG_871X("%s: parameter error(level 2)!\n", __func__);
13774                         return -EFAULT;
13775                 }
13776
13777                 sscanf(pch, "%d", &cnt);
13778                 DBG_871X("%s: loopback cnt=%d\n", __func__, cnt);
13779
13780                 pch = strsep(&ptmp, delim);
13781                 if ((pch == NULL) || (strlen(pch) == 0)) {
13782                         rtw_mfree(pbuf, len);
13783                         DBG_871X("%s: parameter error(level 2)!\n", __func__);
13784                         return -EFAULT;
13785                 }
13786
13787                 sscanf(pch, "%d", &size);
13788                 DBG_871X("%s: loopback size=%d\n", __func__, size);
13789
13790                 loopbackTest(padapter, cnt, size, extra);
13791                 wrqu->data.length = strlen(extra) + 1;
13792
13793                 rtw_mfree(pbuf, len);
13794                 return 0;
13795         }
13796 #endif
13797
13798 #if 0
13799 //#ifdef CONFIG_RTL8723A
13800         if (strcmp(pch, "poweron") == 0)
13801         {
13802                 s32 ret;
13803
13804                 ret = _InitPowerOn(padapter);
13805                 DBG_871X("%s: power on %s\n", __func__, (_FAIL==ret) ? "FAIL!":"OK.");
13806                 sprintf(extra, "Power ON %s", (_FAIL==ret) ? "FAIL!":"OK.");
13807                 wrqu->data.length = strlen(extra) + 1;
13808
13809                 rtw_mfree(pbuf, len);
13810                 return 0;
13811         }
13812
13813         if (strcmp(pch, "dlfw") == 0)
13814         {
13815                 s32 ret;
13816
13817                 ret = rtl8723a_FirmwareDownload(padapter);
13818                 DBG_871X("%s: download FW %s\n", __func__, (_FAIL==ret) ? "FAIL!":"OK.");
13819                 sprintf(extra, "download FW %s", (_FAIL==ret) ? "FAIL!":"OK.");
13820                 wrqu->data.length = strlen(extra) + 1;
13821
13822                 rtw_mfree(pbuf, len);
13823                 return 0;
13824         }
13825 #endif
13826
13827 #ifdef CONFIG_BT_COEXIST
13828         if (strcmp(pch, "bton") == 0)
13829         {
13830                 rtw_btcoex_SetManualControl(padapter, _FALSE);
13831         }
13832
13833         if (strcmp(pch, "btoff") == 0)
13834         {
13835                 rtw_btcoex_SetManualControl(padapter, _TRUE);
13836         }
13837
13838         if (strcmp(pch, "h2c") == 0)
13839         {
13840                 u8 param[8];
13841                 u8 count = 0;
13842                 u32 tmp;
13843                 u8 i;
13844                 u32 pos;
13845                 s32 ret;
13846
13847
13848                 do {
13849                         pch = strsep(&ptmp, delim);
13850                         if ((pch == NULL) || (strlen(pch) == 0))
13851                                 break;
13852
13853                         sscanf(pch, "%x", &tmp);
13854                         param[count++] = (u8)tmp;
13855                 } while (count < 8);
13856
13857                 if (count == 0) {
13858                         rtw_mfree(pbuf, len);
13859                         DBG_871X("%s: parameter error(level 2)!\n", __func__);
13860                         return -EFAULT;
13861                 }
13862
13863                 ret = rtw_hal_fill_h2c_cmd(padapter, param[0], count-1, &param[1]);
13864
13865                 pos = sprintf(extra, "H2C ID=0x%02x content=", param[0]);
13866                 for (i=1; i<count; i++) {
13867                         pos += sprintf(extra+pos, "%02x,", param[i]);
13868                 }
13869                 extra[pos] = 0;
13870                 pos--;
13871                 pos += sprintf(extra+pos, " %s", ret==_FAIL?"FAIL":"OK");
13872
13873                 wrqu->data.length = strlen(extra) + 1;
13874         }
13875 #endif // CONFIG_BT_COEXIST
13876
13877         rtw_mfree(pbuf, len);
13878         return 0;
13879 }
13880
13881 static iw_handler rtw_handlers[] =
13882 {
13883         NULL,                                   /* SIOCSIWCOMMIT */
13884         rtw_wx_get_name,                /* SIOCGIWNAME */
13885         dummy,                                  /* SIOCSIWNWID */
13886         dummy,                                  /* SIOCGIWNWID */
13887         rtw_wx_set_freq,                /* SIOCSIWFREQ */
13888         rtw_wx_get_freq,                /* SIOCGIWFREQ */
13889         rtw_wx_set_mode,                /* SIOCSIWMODE */
13890         rtw_wx_get_mode,                /* SIOCGIWMODE */
13891         dummy,                                  /* SIOCSIWSENS */
13892         rtw_wx_get_sens,                /* SIOCGIWSENS */
13893         NULL,                                   /* SIOCSIWRANGE */
13894         rtw_wx_get_range,               /* SIOCGIWRANGE */
13895         rtw_wx_set_priv,                /* SIOCSIWPRIV */
13896         NULL,                                   /* SIOCGIWPRIV */
13897         NULL,                                   /* SIOCSIWSTATS */
13898         NULL,                                   /* SIOCGIWSTATS */
13899         dummy,                                  /* SIOCSIWSPY */
13900         dummy,                                  /* SIOCGIWSPY */
13901         NULL,                                   /* SIOCGIWTHRSPY */
13902         NULL,                                   /* SIOCWIWTHRSPY */
13903         rtw_wx_set_wap,         /* SIOCSIWAP */
13904         rtw_wx_get_wap,         /* SIOCGIWAP */
13905         rtw_wx_set_mlme,                /* request MLME operation; uses struct iw_mlme */
13906         dummy,                                  /* SIOCGIWAPLIST -- depricated */
13907         rtw_wx_set_scan,                /* SIOCSIWSCAN */
13908         rtw_wx_get_scan,                /* SIOCGIWSCAN */
13909         rtw_wx_set_essid,               /* SIOCSIWESSID */
13910         rtw_wx_get_essid,               /* SIOCGIWESSID */
13911         dummy,                                  /* SIOCSIWNICKN */
13912         rtw_wx_get_nick,                /* SIOCGIWNICKN */
13913         NULL,                                   /* -- hole -- */
13914         NULL,                                   /* -- hole -- */
13915         rtw_wx_set_rate,                /* SIOCSIWRATE */
13916         rtw_wx_get_rate,                /* SIOCGIWRATE */
13917         rtw_wx_set_rts,                 /* SIOCSIWRTS */
13918         rtw_wx_get_rts,                 /* SIOCGIWRTS */
13919         rtw_wx_set_frag,                /* SIOCSIWFRAG */
13920         rtw_wx_get_frag,                /* SIOCGIWFRAG */
13921         dummy,                                  /* SIOCSIWTXPOW */
13922         dummy,                                  /* SIOCGIWTXPOW */
13923         dummy,                                  /* SIOCSIWRETRY */
13924         rtw_wx_get_retry,               /* SIOCGIWRETRY */
13925         rtw_wx_set_enc,                 /* SIOCSIWENCODE */
13926         rtw_wx_get_enc,                 /* SIOCGIWENCODE */
13927         dummy,                                  /* SIOCSIWPOWER */
13928         rtw_wx_get_power,               /* SIOCGIWPOWER */
13929         NULL,                                   /*---hole---*/
13930         NULL,                                   /*---hole---*/
13931         rtw_wx_set_gen_ie,              /* SIOCSIWGENIE */
13932         NULL,                                   /* SIOCGWGENIE */
13933         rtw_wx_set_auth,                /* SIOCSIWAUTH */
13934         NULL,                                   /* SIOCGIWAUTH */
13935         rtw_wx_set_enc_ext,             /* SIOCSIWENCODEEXT */
13936         NULL,                                   /* SIOCGIWENCODEEXT */
13937         rtw_wx_set_pmkid,               /* SIOCSIWPMKSA */
13938         NULL,                                   /*---hole---*/
13939 }; 
13940
13941 #if 0
13942 //defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT)
13943 static const struct iw_priv_args rtw_private_args[] =
13944 {       
13945         { SIOCIWFIRSTPRIV + 0x00, IW_PRIV_TYPE_CHAR | 1024, 0 , ""},  //set 
13946         { SIOCIWFIRSTPRIV + 0x01, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , ""},//get
13947 /* --- sub-ioctls definitions --- */   
13948                 { MP_START , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_start" }, //set
13949                 { MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara" },//get
13950                 { MP_STOP , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_stop" }, //set
13951                 { MP_CHANNEL , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel" },//get
13952                 { MP_BANDWIDTH , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_bandwidth"}, //set
13953                 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },//get
13954                 { MP_RESET_STATS , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_reset_stats"},
13955                 { MP_QUERY , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "mp_query"}, //get
13956                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13957                 { READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" },
13958                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13959                 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
13960                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13961                 { READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" },
13962                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13963                 { MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"}, 
13964                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13965                 { MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" },
13966                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13967                 { MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},
13968                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13969                 { MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024,  IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},
13970                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13971                 { MP_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},
13972                 { WRITE_REG, IW_PRIV_TYPE_CHAR | 1024, 0,"write_reg"},//set
13973                 { MP_NULL, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL" },
13974                 { WRITE_RF, IW_PRIV_TYPE_CHAR | 1024, 0,"write_rf"},//set
13975                 { MP_NULL, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL" },
13976                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13977                 { MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},
13978                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13979                 { MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},
13980                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13981                 { MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},
13982                 { EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set" },
13983                 { EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get" },
13984                 { MP_PWRTRK , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_pwrtrk"},
13985                 { MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery" },
13986                 { MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"}, // mp_ioctl       
13987                 { MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_setrfpath" },
13988 #ifdef CONFIG_RTL8723A
13989                 { MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" },
13990 #endif
13991         { SIOCIWFIRSTPRIV + 0x02, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "test"},//set
13992 };
13993 static iw_handler rtw_private_handler[] = 
13994 {
13995         rtw_mp_set,
13996         rtw_mp_get,
13997 };
13998 #else // not inlucde MP
13999
14000 static const struct iw_priv_args rtw_private_args[] = {
14001         {
14002                 SIOCIWFIRSTPRIV + 0x0,
14003                 IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
14004         },
14005         {
14006                 SIOCIWFIRSTPRIV + 0x1,
14007                 IW_PRIV_TYPE_CHAR | 0x7FF,
14008                 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
14009         },
14010         {
14011                 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
14012         },
14013         {
14014                 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
14015         },
14016         {
14017                 SIOCIWFIRSTPRIV + 0x4,
14018                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
14019         },
14020         {
14021                 SIOCIWFIRSTPRIV + 0x5,
14022                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
14023         },
14024         {
14025                 SIOCIWFIRSTPRIV + 0x6,
14026                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
14027         },
14028 //for PLATFORM_MT53XX   
14029         {
14030                 SIOCIWFIRSTPRIV + 0x7,
14031                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
14032         },
14033         {
14034                 SIOCIWFIRSTPRIV + 0x8,
14035                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
14036         },
14037         {
14038                 SIOCIWFIRSTPRIV + 0x9,
14039                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
14040         },
14041
14042 //for RTK_DMP_PLATFORM  
14043         {
14044                 SIOCIWFIRSTPRIV + 0xA,
14045                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
14046         },
14047
14048         {
14049                 SIOCIWFIRSTPRIV + 0xB,
14050                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
14051         },      
14052         {
14053                 SIOCIWFIRSTPRIV + 0xC,
14054                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
14055         },
14056         {
14057                 SIOCIWFIRSTPRIV + 0xD,
14058                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
14059         },
14060 #if 0
14061         {
14062                 SIOCIWFIRSTPRIV + 0xE,0,0, "wowlan_ctrl"
14063         },
14064 #endif
14065         {
14066                 SIOCIWFIRSTPRIV + 0x10,
14067                 IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set"
14068         },
14069         {
14070                 SIOCIWFIRSTPRIV + 0x11,
14071                 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get"
14072         },
14073         {
14074                 SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL"
14075         },
14076         {
14077                 SIOCIWFIRSTPRIV + 0x13,
14078                 IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2"
14079         },      
14080         {
14081                 SIOCIWFIRSTPRIV + 0x14,
14082                 IW_PRIV_TYPE_CHAR  | 64, 0, "tdls"
14083         },
14084         {
14085                 SIOCIWFIRSTPRIV + 0x15,
14086                 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "tdls_get"
14087         },      
14088         {
14089                 SIOCIWFIRSTPRIV + 0x16,
14090                 IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
14091         },
14092
14093         {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"},
14094 #ifdef CONFIG_MP_INCLUDED
14095         {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0,  "NULL"},
14096         {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL"},
14097 #else
14098         {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"},
14099         {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
14100 #endif
14101         {
14102                 SIOCIWFIRSTPRIV + 0x1D,
14103                 IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
14104         },
14105
14106 #ifdef CONFIG_INTEL_WIDI
14107         {
14108                 SIOCIWFIRSTPRIV + 0x1E,
14109                 IW_PRIV_TYPE_CHAR | 1024, 0, "widi_set"
14110         },
14111         {
14112                 SIOCIWFIRSTPRIV + 0x1F,
14113                 IW_PRIV_TYPE_CHAR | 128, 0, "widi_prob_req"
14114         },
14115 #endif // CONFIG_INTEL_WIDI
14116
14117 #ifdef CONFIG_MP_INCLUDED
14118         { SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0 , ""},  //set 
14119         { SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , ""},//get
14120 /* --- sub-ioctls definitions --- */   
14121                 { MP_START , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_start" }, //set
14122                 { MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara" },//get
14123                 { MP_STOP , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_stop" }, //set
14124                 { MP_CHANNEL , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel" },//get
14125                 { MP_BANDWIDTH , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_bandwidth"}, //set
14126                 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },//get
14127                 { MP_RESET_STATS , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_reset_stats"},
14128                 { MP_QUERY , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "mp_query"}, //get
14129                 { READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" },
14130                 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
14131                 { READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" },
14132                 { MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"}, 
14133                 { MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" },
14134                 { MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},
14135                 { MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024,  IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},
14136                 { MP_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},
14137                 { WRITE_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg" },
14138                 { WRITE_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf" },
14139                 { MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},
14140                 { MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},
14141                 { MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},
14142                 { EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_set" },
14143                 { EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get" },
14144                 { MP_PWRTRK , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_pwrtrk"},
14145                 { MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery" },
14146                 { MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"}, // mp_ioctl       
14147                 { MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_setrfpath" },               
14148                 { MP_PwrCtlDM, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrctldm" },                
14149                 { MP_GET_TXPOWER_INX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_get_txpower" },
14150                 
14151 #if defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B)
14152                 { MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" },
14153         { MP_DISABLE_BT_COEXIST, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_disa_btcoex"},
14154 #endif
14155                 { CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"},
14156 #endif
14157 #ifdef CONFIG_AP_WOWLAN
14158                 { MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_enable" }, //set 
14159 #endif
14160 };
14161
14162 static iw_handler rtw_private_handler[] = 
14163 {
14164         rtw_wx_write32,                                 //0x00
14165         rtw_wx_read32,                                  //0x01
14166         rtw_drvext_hdl,                                 //0x02
14167         rtw_mp_ioctl_hdl,                               //0x03
14168
14169 // for MM DTV platform
14170         rtw_get_ap_info,                                        //0x04
14171
14172         rtw_set_pid,                                            //0x05
14173         rtw_wps_start,                                  //0x06
14174
14175 // for PLATFORM_MT53XX
14176         rtw_wx_get_sensitivity,                 //0x07
14177         rtw_wx_set_mtk_wps_probe_ie,    //0x08
14178         rtw_wx_set_mtk_wps_ie,                  //0x09
14179
14180 // for RTK_DMP_PLATFORM
14181 // Set Channel depend on the country code
14182         rtw_wx_set_channel_plan,                //0x0A
14183
14184         rtw_dbg_port,                                   //0x0B
14185         rtw_wx_write_rf,                                        //0x0C
14186         rtw_wx_read_rf,                                 //0x0D
14187 #ifdef CONFIG_MP_INCLUDED
14188         rtw_mp_set,                                     //0x0E
14189         rtw_mp_get,                                     //0x0F
14190 #else
14191         rtw_wx_priv_null,                               //0x0E
14192         rtw_wx_priv_null,                               //0x0F
14193 #endif
14194         rtw_p2p_set,                                    //0x10
14195         rtw_p2p_get,                                    //0x11
14196         NULL,                                                   //0x12
14197         rtw_p2p_get2,                                   //0x13
14198
14199         rtw_tdls,                                               //0x14
14200         rtw_tdls_get,                                   //0x15
14201
14202         rtw_pm_set,                                             //0x16
14203         rtw_wx_priv_null,                               //0x17
14204         rtw_rereg_nd_name,                              //0x18
14205         rtw_wx_priv_null,                               //0x19
14206 #ifdef CONFIG_MP_INCLUDED
14207         rtw_wx_priv_null,                               //0x1A
14208         rtw_wx_priv_null,                               //0x1B
14209 #else
14210         rtw_mp_efuse_set,                               //0x1A
14211         rtw_mp_efuse_get,                               //0x1B
14212 #endif
14213         NULL,                                                   // 0x1C is reserved for hostapd
14214         rtw_test,                                               // 0x1D
14215 #ifdef CONFIG_INTEL_WIDI
14216         rtw_widi_set,                                   //0x1E
14217         rtw_widi_set_probe_request,             //0x1F
14218 #endif // CONFIG_INTEL_WIDI
14219 };
14220
14221 #endif // #if defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT)
14222
14223 #if WIRELESS_EXT >= 17  
14224 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
14225 {
14226        _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
14227            struct iw_statistics *piwstats=&padapter->iwstats;
14228         int tmp_level = 0;
14229         int tmp_qual = 0;
14230         int tmp_noise = 0;
14231
14232         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != _TRUE)
14233         {
14234                 piwstats->qual.qual = 0;
14235                 piwstats->qual.level = 0;
14236                 piwstats->qual.noise = 0;
14237                 //DBG_871X("No link  level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
14238         }
14239         else{
14240                 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
14241                 tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength); 
14242                 #else
14243                 #ifdef CONFIG_SKIP_SIGNAL_SCALE_MAPPING
14244                 {
14245                         /* Do signal scale mapping when using percentage as the unit of signal strength, since the scale mapping is skipped in odm */
14246                         HAL_DATA_TYPE *pHal = GET_HAL_DATA(padapter);
14247                         tmp_level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, padapter->recvpriv.signal_strength);
14248                 }
14249                 #else
14250                 tmp_level = padapter->recvpriv.signal_strength;
14251                 #endif
14252                 #endif
14253                 
14254                 tmp_qual = padapter->recvpriv.signal_qual;
14255                 tmp_noise =padapter->recvpriv.noise;            
14256                 //DBG_871X("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise,padapter->recvpriv.rssi);
14257
14258                 piwstats->qual.level = tmp_level;
14259                 piwstats->qual.qual = tmp_qual;
14260                 piwstats->qual.noise = tmp_noise;
14261         }
14262 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
14263         piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;//|IW_QUAL_DBM;
14264 #else
14265 #ifdef RTK_DMP_PLATFORM
14266         //IW_QUAL_DBM= 0x8, if driver use this flag, wireless extension will show value of dbm.
14267         //remove this flag for show percentage 0~100
14268         piwstats->qual.updated = 0x07;
14269 #else
14270         piwstats->qual.updated = 0x0f;
14271 #endif
14272 #endif
14273
14274         #ifdef CONFIG_SIGNAL_DISPLAY_DBM
14275         piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM;
14276         #endif
14277
14278         return &padapter->iwstats;
14279 }
14280 #endif
14281
14282 #ifdef CONFIG_WIRELESS_EXT
14283 struct iw_handler_def rtw_handlers_def =
14284 {
14285         .standard = rtw_handlers,
14286         .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
14287 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) || defined(CONFIG_WEXT_PRIV)
14288         .private = rtw_private_handler,
14289         .private_args = (struct iw_priv_args *)rtw_private_args,
14290         .num_private = sizeof(rtw_private_handler) / sizeof(iw_handler),
14291         .num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args),
14292 #endif
14293 #if WIRELESS_EXT >= 17
14294         .get_wireless_stats = rtw_get_wireless_stats,
14295 #endif
14296 };
14297 #endif
14298
14299 // copy from net/wireless/wext.c start
14300 /* ---------------------------------------------------------------- */
14301 /*
14302  * Calculate size of private arguments
14303  */
14304 static const char iw_priv_type_size[] = {
14305         0,                              /* IW_PRIV_TYPE_NONE */
14306         1,                              /* IW_PRIV_TYPE_BYTE */
14307         1,                              /* IW_PRIV_TYPE_CHAR */
14308         0,                              /* Not defined */
14309         sizeof(__u32),                  /* IW_PRIV_TYPE_INT */
14310         sizeof(struct iw_freq),         /* IW_PRIV_TYPE_FLOAT */
14311         sizeof(struct sockaddr),        /* IW_PRIV_TYPE_ADDR */
14312         0,                              /* Not defined */
14313 };
14314
14315 static int get_priv_size(__u16 args)
14316 {
14317         int num = args & IW_PRIV_SIZE_MASK;
14318         int type = (args & IW_PRIV_TYPE_MASK) >> 12;
14319
14320         return num * iw_priv_type_size[type];
14321 }
14322 // copy from net/wireless/wext.c end
14323
14324 static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)
14325 {
14326         int err = 0;
14327         u8 *input = NULL;
14328         u32 input_len = 0;
14329         const char delim[] = " ";
14330         u8 *output = NULL;
14331         u32 output_len = 0;
14332         u32 count = 0;
14333         u8 *buffer= NULL;
14334         u32 buffer_len = 0;
14335         char *ptr = NULL;
14336         u8 cmdname[17] = {0}; // IFNAMSIZ+1
14337         u32 cmdlen;
14338         s32 len;
14339         u8 *extra = NULL;
14340         u32 extra_size = 0;
14341
14342         s32 k;
14343         const iw_handler *priv;         /* Private ioctl */
14344         const struct iw_priv_args *priv_args;   /* Private ioctl description */
14345         u32 num_priv;                           /* Number of ioctl */
14346         u32 num_priv_args;                      /* Number of descriptions */
14347         iw_handler handler;
14348         int temp;
14349         int subcmd = 0;                         /* sub-ioctl index */
14350         int offset = 0;                         /* Space for sub-ioctl index */
14351
14352         union iwreq_data wdata;
14353
14354
14355         _rtw_memcpy(&wdata, wrq_data, sizeof(wdata));
14356
14357         input_len = wdata.data.length;
14358         input = rtw_zmalloc(input_len);
14359         if (NULL == input)
14360                 return -ENOMEM;
14361         if (copy_from_user(input, wdata.data.pointer, input_len)) {
14362                 err = -EFAULT;
14363                 goto exit;
14364         }
14365         ptr = input;
14366         len = input_len;
14367
14368         sscanf(ptr, "%16s", cmdname);
14369         cmdlen = strlen(cmdname);
14370         DBG_8192C("%s: cmd=%s\n", __func__, cmdname);
14371
14372         // skip command string
14373         if (cmdlen > 0)
14374                 cmdlen += 1; // skip one space
14375         ptr += cmdlen;
14376         len -= cmdlen;
14377         DBG_8192C("%s: parameters=%s\n", __func__, ptr);
14378
14379         priv = rtw_private_handler;
14380         priv_args = rtw_private_args;
14381         num_priv = sizeof(rtw_private_handler) / sizeof(iw_handler);
14382         num_priv_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args);
14383
14384         if (num_priv_args == 0) {
14385                 err = -EOPNOTSUPP;
14386                 goto exit;
14387         }
14388
14389         /* Search the correct ioctl */
14390         k = -1;
14391         while((++k < num_priv_args) && strcmp(priv_args[k].name, cmdname));
14392
14393         /* If not found... */
14394         if (k == num_priv_args) {
14395                 err = -EOPNOTSUPP;
14396                 goto exit;
14397         }
14398
14399         /* Watch out for sub-ioctls ! */
14400         if (priv_args[k].cmd < SIOCDEVPRIVATE)
14401         {
14402                 int j = -1;
14403
14404                 /* Find the matching *real* ioctl */
14405                 while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||
14406                         (priv_args[j].set_args != priv_args[k].set_args) ||
14407                         (priv_args[j].get_args != priv_args[k].get_args)));
14408
14409                 /* If not found... */
14410                 if (j == num_priv_args) {
14411                         err = -EINVAL;
14412                         goto exit;
14413                 }
14414
14415                 /* Save sub-ioctl number */
14416                 subcmd = priv_args[k].cmd;
14417                 /* Reserve one int (simplify alignment issues) */
14418                 offset = sizeof(__u32);
14419                 /* Use real ioctl definition from now on */
14420                 k = j;
14421         }
14422
14423         buffer = rtw_zmalloc(4096);
14424         if (NULL == buffer) {
14425                 err = -ENOMEM;
14426                 goto exit;
14427         }
14428
14429         /* If we have to set some data */
14430         if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&
14431                 (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
14432         {
14433                 u8 *str;
14434
14435                 switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK)
14436                 {
14437                         case IW_PRIV_TYPE_BYTE:
14438                                 /* Fetch args */
14439                                 count = 0;
14440                                 do {
14441                                         str = strsep(&ptr, delim);
14442                                         if (NULL == str) break;
14443                                         sscanf(str, "%i", &temp);
14444                                         buffer[count++] = (u8)temp;
14445                                 } while (1);
14446                                 buffer_len = count;
14447
14448                                 /* Number of args to fetch */
14449                                 wdata.data.length = count;
14450                                 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
14451                                         wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
14452
14453                                 break;
14454
14455                         case IW_PRIV_TYPE_INT:
14456                                 /* Fetch args */
14457                                 count = 0;
14458                                 do {
14459                                         str = strsep(&ptr, delim);
14460                                         if (NULL == str) break;
14461                                         sscanf(str, "%i", &temp);
14462                                         ((s32*)buffer)[count++] = (s32)temp;
14463                                 } while (1);
14464                                 buffer_len = count * sizeof(s32);
14465
14466                                 /* Number of args to fetch */
14467                                 wdata.data.length = count;
14468                                 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
14469                                         wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
14470
14471                                 break;
14472
14473                         case IW_PRIV_TYPE_CHAR:
14474                                 if (len > 0)
14475                                 {
14476                                         /* Size of the string to fetch */
14477                                         wdata.data.length = len;
14478                                         if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
14479                                                 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
14480
14481                                         /* Fetch string */
14482                                         _rtw_memcpy(buffer, ptr, wdata.data.length);
14483                                 }
14484                                 else
14485                                 {
14486                                         wdata.data.length = 1;
14487                                         buffer[0] = '\0';
14488                                 }
14489                                 buffer_len = wdata.data.length;
14490                                 break;
14491
14492                         default:
14493                                 DBG_8192C("%s: Not yet implemented...\n", __func__);
14494                                 err = -1;
14495                                 goto exit;
14496                 }
14497
14498                 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
14499                         (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK)))
14500                 {
14501                         DBG_8192C("%s: The command %s needs exactly %d argument(s)...\n",
14502                                         __func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK);
14503                         err = -EINVAL;
14504                         goto exit;
14505                 }
14506         }   /* if args to set */
14507         else
14508         {
14509                 wdata.data.length = 0L;
14510         }
14511
14512         /* Those two tests are important. They define how the driver
14513         * will have to handle the data */
14514         if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
14515                 ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ))
14516         {
14517                 /* First case : all SET args fit within wrq */
14518                 if (offset)
14519                         wdata.mode = subcmd;
14520                 _rtw_memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
14521         }
14522         else
14523         {
14524                 if ((priv_args[k].set_args == 0) &&
14525                         (priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
14526                         (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
14527                 {
14528                         /* Second case : no SET args, GET args fit within wrq */
14529                         if (offset)
14530                                 wdata.mode = subcmd;
14531                 }
14532                 else
14533                 {
14534                         /* Third case : args won't fit in wrq, or variable number of args */
14535                         if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {
14536                                 err = -EFAULT;
14537                                 goto exit;
14538                         }
14539                         wdata.data.flags = subcmd;
14540                 }
14541         }
14542
14543         rtw_mfree(input, input_len);
14544         input = NULL;
14545
14546         extra_size = 0;
14547         if (IW_IS_SET(priv_args[k].cmd))
14548         {
14549                 /* Size of set arguments */
14550                 extra_size = get_priv_size(priv_args[k].set_args);
14551
14552                 /* Does it fits in iwr ? */
14553                 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
14554                         ((extra_size + offset) <= IFNAMSIZ))
14555                         extra_size = 0;
14556         } else {
14557                 /* Size of get arguments */
14558                 extra_size = get_priv_size(priv_args[k].get_args);
14559
14560                 /* Does it fits in iwr ? */
14561                 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
14562                         (extra_size <= IFNAMSIZ))
14563                         extra_size = 0;
14564         }
14565
14566         if (extra_size == 0) {
14567                 extra = (u8*)&wdata;
14568                 rtw_mfree(buffer, 4096);
14569                 buffer = NULL;
14570         } else
14571                 extra = buffer;
14572
14573         handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];
14574         err = handler(dev, NULL, &wdata, extra);
14575
14576         /* If we have to get some data */
14577         if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&
14578                 (priv_args[k].get_args & IW_PRIV_SIZE_MASK))
14579         {
14580                 int j;
14581                 int n = 0;      /* number of args */
14582                 u8 str[20] = {0};
14583
14584                 /* Check where is the returned data */
14585                 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
14586                         (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
14587                         n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;
14588                 else
14589                         n = wdata.data.length;
14590
14591                 output = rtw_zmalloc(4096);
14592                 if (NULL == output) {
14593                         err =  -ENOMEM;
14594                         goto exit;
14595                 }
14596
14597                 switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK)
14598                 {
14599                         case IW_PRIV_TYPE_BYTE:
14600                                 /* Display args */
14601                                 for (j = 0; j < n; j++)
14602                                 {
14603                                         sprintf(str, "%d  ", extra[j]);
14604                                         len = strlen(str);
14605                                         output_len = strlen(output);
14606                                         if ((output_len + len + 1) > 4096) {
14607                                                 err = -E2BIG;
14608                                                 goto exit;
14609                                         }
14610                                         _rtw_memcpy(output+output_len, str, len);
14611                                 }
14612                                 break;
14613
14614                         case IW_PRIV_TYPE_INT:
14615                                 /* Display args */
14616                                 for (j = 0; j < n; j++)
14617                                 {
14618                                         sprintf(str, "%d  ", ((__s32*)extra)[j]);
14619                                         len = strlen(str);
14620                                         output_len = strlen(output);
14621                                         if ((output_len + len + 1) > 4096) {
14622                                                 err = -E2BIG;
14623                                                 goto exit;
14624                                         }
14625                                         _rtw_memcpy(output+output_len, str, len);
14626                                 }
14627                                 break;
14628
14629                         case IW_PRIV_TYPE_CHAR:
14630                                 /* Display args */
14631                                 _rtw_memcpy(output, extra, n);
14632                                 break;
14633
14634                         default:
14635                                 DBG_8192C("%s: Not yet implemented...\n", __func__);
14636                                 err = -1;
14637                                 goto exit;
14638                 }
14639
14640                 output_len = strlen(output) + 1;
14641                 wrq_data->data.length = output_len;
14642                 if (copy_to_user(wrq_data->data.pointer, output, output_len)) {
14643                         err = -EFAULT;
14644                         goto exit;
14645                 }
14646         }   /* if args to set */
14647         else
14648         {
14649                 wrq_data->data.length = 0;
14650         }
14651
14652 exit:
14653         if (input)
14654                 rtw_mfree(input, input_len);
14655         if (buffer)
14656                 rtw_mfree(buffer, 4096);
14657         if (output)
14658                 rtw_mfree(output, 4096);
14659
14660         return err;
14661 }
14662
14663 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
14664 {
14665         struct iwreq *wrq = (struct iwreq *)rq;
14666         int ret=0;
14667
14668         switch (cmd)
14669         {
14670                 case RTL_IOCTL_WPA_SUPPLICANT:
14671                         ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
14672                         break;
14673 #ifdef CONFIG_AP_MODE
14674                 case RTL_IOCTL_HOSTAPD:
14675                         ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
14676                         break;
14677 #ifdef CONFIG_NO_WIRELESS_HANDLERS
14678                 case SIOCSIWMODE:
14679                         ret = rtw_wx_set_mode(dev, NULL, &wrq->u, NULL);
14680                         break;
14681 #endif
14682 #endif // CONFIG_AP_MODE
14683                 case SIOCDEVPRIVATE:
14684                         ret = rtw_ioctl_wext_private(dev, &wrq->u);
14685                         break;
14686                 case (SIOCDEVPRIVATE+1):
14687                         ret = rtw_android_priv_cmd(dev, rq, cmd);
14688                         break;
14689                 default:
14690                         ret = -EOPNOTSUPP;
14691                         break;
14692         }
14693
14694         return ret;
14695 }
14696
14697