bb005df69465ccb0b3c3dbf23a80a4657920d69a
[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         _func_enter_;
1540
1541         RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n"));
1542
1543         _func_exit_;
1544         
1545         return 0;
1546 }
1547
1548 static int rtw_wx_get_freq(struct net_device *dev, 
1549                              struct iw_request_info *info, 
1550                              union iwreq_data *wrqu, char *extra)
1551 {
1552         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1553         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
1554         WLAN_BSSID_EX  *pcur_bss = &pmlmepriv->cur_network.network;
1555         
1556         if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
1557         {
1558                 //wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000;
1559                 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
1560                 wrqu->freq.e = 1;
1561                 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
1562
1563         }
1564         else{
1565                 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
1566                 wrqu->freq.e = 1;
1567                 wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
1568         }
1569
1570         return 0;
1571 }
1572
1573 static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
1574                              union iwreq_data *wrqu, char *b)
1575 {
1576         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1577         NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
1578         int ret = 0;
1579         
1580         _func_enter_;
1581         
1582         if(_FAIL == rtw_pwr_wakeup(padapter)) {
1583                 ret= -EPERM;
1584                 goto exit;
1585         }
1586
1587         if (padapter->hw_init_completed==_FALSE){
1588                 ret = -EPERM;
1589                 goto exit;
1590         }
1591         
1592         switch(wrqu->mode)
1593         {
1594                 case IW_MODE_AUTO:
1595                         networkType = Ndis802_11AutoUnknown;
1596                         DBG_871X("set_mode = IW_MODE_AUTO\n");  
1597                         break;                          
1598                 case IW_MODE_ADHOC:             
1599                         networkType = Ndis802_11IBSS;
1600                         DBG_871X("set_mode = IW_MODE_ADHOC\n");                 
1601                         break;
1602                 case IW_MODE_MASTER:            
1603                         networkType = Ndis802_11APMode;
1604                         DBG_871X("set_mode = IW_MODE_MASTER\n");
1605                         //rtw_setopmode_cmd(padapter, networkType,_TRUE);       
1606                         break;                          
1607                 case IW_MODE_INFRA:
1608                         networkType = Ndis802_11Infrastructure;
1609                         DBG_871X("set_mode = IW_MODE_INFRA\n");                 
1610                         break;
1611         
1612                 default :
1613                         ret = -EINVAL;;
1614                         RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("\n Mode: %s is not supported  \n", iw_operation_mode[wrqu->mode]));
1615                         goto exit;
1616         }
1617         
1618 /*      
1619         if(Ndis802_11APMode == networkType)
1620         {
1621                 rtw_setopmode_cmd(padapter, networkType,_TRUE);
1622         }       
1623         else
1624         {
1625                 rtw_setopmode_cmd(padapter, Ndis802_11AutoUnknown,_TRUE);       
1626         }
1627 */
1628         
1629         if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE){
1630
1631                 ret = -EPERM;
1632                 goto exit;
1633
1634         }
1635
1636         rtw_setopmode_cmd(padapter, networkType,_TRUE);
1637
1638 exit:
1639         
1640         _func_exit_;
1641         
1642         return ret;
1643         
1644 }
1645
1646 static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
1647                              union iwreq_data *wrqu, char *b)
1648 {
1649         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1650         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
1651         
1652         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,(" rtw_wx_get_mode \n"));
1653
1654         _func_enter_;
1655         
1656         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1657         {
1658                 wrqu->mode = IW_MODE_INFRA;
1659         }
1660         else if  ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
1661                        (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
1662                 
1663         {
1664                 wrqu->mode = IW_MODE_ADHOC;
1665         }
1666         else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1667         {
1668                 wrqu->mode = IW_MODE_MASTER;
1669         }
1670         else
1671         {
1672                 wrqu->mode = IW_MODE_AUTO;
1673         }
1674
1675         _func_exit_;
1676         
1677         return 0;
1678         
1679 }
1680
1681
1682 static int rtw_wx_set_pmkid(struct net_device *dev,
1683                              struct iw_request_info *a,
1684                              union iwreq_data *wrqu, char *extra)
1685 {
1686         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1687         u8          j,blInserted = _FALSE;
1688         int         intReturn = _FALSE;
1689         struct mlme_priv  *pmlmepriv = &padapter->mlmepriv;
1690         struct security_priv *psecuritypriv = &padapter->securitypriv;
1691         struct iw_pmksa*  pPMK = ( struct iw_pmksa* ) extra;
1692         u8     strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
1693         u8     strIssueBssid[ ETH_ALEN ] = { 0x00 };
1694         
1695 /*
1696         struct iw_pmksa
1697         {
1698             __u32   cmd;
1699             struct sockaddr bssid;
1700             __u8    pmkid[IW_PMKID_LEN];   //IW_PMKID_LEN=16
1701         }
1702         There are the BSSID information in the bssid.sa_data array.
1703         If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear all the PMKID information.
1704         If cmd is IW_PMKSA_ADD, it means the wpa_supplicant wants to add a PMKID/BSSID to driver.
1705         If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to remove a PMKID/BSSID from driver.
1706         */
1707
1708         _rtw_memcpy( strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
1709         if ( pPMK->cmd == IW_PMKSA_ADD )
1710         {
1711                 DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n" );
1712                 if ( _rtw_memcmp( strIssueBssid, strZeroMacAddress, ETH_ALEN ) == _TRUE )
1713                 {
1714                     return( intReturn );
1715                 }
1716                 else
1717                 {
1718                     intReturn = _TRUE;
1719                 }
1720                 blInserted = _FALSE;
1721                 
1722                 //overwrite PMKID
1723                 for(j=0 ; j<NUM_PMKID_CACHE; j++)
1724                 {
1725                         if( _rtw_memcmp( psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) ==_TRUE )
1726                         { // BSSID is matched, the same AP => rewrite with new PMKID.
1727                                 
1728                                 DBG_871X( "[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n" );
1729
1730                                 _rtw_memcpy( psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1731                                 psecuritypriv->PMKIDList[ j ].bUsed = _TRUE;
1732                                 psecuritypriv->PMKIDIndex = j+1;
1733                                 blInserted = _TRUE;
1734                                 break;
1735                         }       
1736                 }
1737
1738                 if(!blInserted)
1739                 {
1740                     // Find a new entry
1741                     DBG_871X( "[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
1742                             psecuritypriv->PMKIDIndex );
1743
1744                     _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
1745                     _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1746
1747                     psecuritypriv->PMKIDList[ psecuritypriv->PMKIDIndex ].bUsed = _TRUE;
1748                     psecuritypriv->PMKIDIndex++ ;
1749                     if(psecuritypriv->PMKIDIndex==16)
1750                     {
1751                         psecuritypriv->PMKIDIndex =0;
1752                     }
1753                 }
1754         }
1755         else if ( pPMK->cmd == IW_PMKSA_REMOVE )
1756         {
1757                 DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n" );
1758                 intReturn = _TRUE;
1759                 for(j=0 ; j<NUM_PMKID_CACHE; j++)
1760                 {
1761                         if( _rtw_memcmp( psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) ==_TRUE )
1762                         { // BSSID is matched, the same AP => Remove this PMKID information and reset it. 
1763                                 _rtw_memset( psecuritypriv->PMKIDList[ j ].Bssid, 0x00, ETH_ALEN );
1764                                 psecuritypriv->PMKIDList[ j ].bUsed = _FALSE;
1765                                 break;
1766                         }       
1767                 }
1768         }
1769         else if ( pPMK->cmd == IW_PMKSA_FLUSH ) 
1770         {
1771             DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n" );
1772             _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
1773             psecuritypriv->PMKIDIndex = 0;
1774             intReturn = _TRUE;
1775         }
1776     return( intReturn );
1777 }
1778
1779 static int rtw_wx_get_sens(struct net_device *dev, 
1780                              struct iw_request_info *info, 
1781                              union iwreq_data *wrqu, char *extra)
1782 {
1783         #ifdef CONFIG_PLATFORM_ROCKCHIPS
1784         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1785         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 
1786         
1787         /*
1788         *  20110311 Commented by Jeff
1789         *  For rockchip platform's wpa_driver_wext_get_rssi
1790         */
1791         if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
1792                 //wrqu->sens.value=-padapter->recvpriv.signal_strength;
1793                 wrqu->sens.value=-padapter->recvpriv.rssi;
1794                 //DBG_871X("%s: %d\n", __FUNCTION__, wrqu->sens.value);
1795                 wrqu->sens.fixed = 0; /* no auto select */ 
1796         } else 
1797         #endif
1798         {
1799                 wrqu->sens.value = 0;
1800                 wrqu->sens.fixed = 0;   /* no auto select */
1801                 wrqu->sens.disabled = 1;
1802         }
1803         return 0;
1804 }
1805
1806 static int rtw_wx_get_range(struct net_device *dev, 
1807                                 struct iw_request_info *info, 
1808                                 union iwreq_data *wrqu, char *extra)
1809 {
1810         struct iw_range *range = (struct iw_range *)extra;
1811         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1812         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1813
1814         u16 val;
1815         int i;
1816         
1817         _func_enter_;
1818         
1819         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_range. cmd_code=%x\n", info->cmd));
1820
1821         wrqu->data.length = sizeof(*range);
1822         _rtw_memset(range, 0, sizeof(*range));
1823
1824         /* Let's try to keep this struct in the same order as in
1825          * linux/include/wireless.h
1826          */
1827
1828         /* TODO: See what values we can set, and remove the ones we can't
1829          * set, or fill them with some default data.
1830          */
1831
1832         /* ~5 Mb/s real (802.11b) */
1833         range->throughput = 5 * 1000 * 1000;     
1834
1835         // TODO: Not used in 802.11b?
1836 //      range->min_nwid;        /* Minimal NWID we are able to set */
1837         // TODO: Not used in 802.11b?
1838 //      range->max_nwid;        /* Maximal NWID we are able to set */
1839
1840         /* Old Frequency (backward compat - moved lower ) */
1841 //      range->old_num_channels; 
1842 //      range->old_num_frequency;
1843 //      range->old_freq[6]; /* Filler to keep "version" at the same offset */
1844
1845         /* signal level threshold range */
1846
1847         //percent values between 0 and 100.
1848         range->max_qual.qual = 100;     
1849         range->max_qual.level = 100;
1850         range->max_qual.noise = 100;
1851         range->max_qual.updated = 7; /* Updated all three */
1852
1853
1854         range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
1855         /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
1856         range->avg_qual.level = 20 + -98;
1857         range->avg_qual.noise = 0;
1858         range->avg_qual.updated = 7; /* Updated all three */
1859
1860         range->num_bitrates = RATE_COUNT;
1861
1862         for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
1863                 range->bitrate[i] = rtw_rates[i];
1864         }
1865
1866         range->min_frag = MIN_FRAG_THRESHOLD;
1867         range->max_frag = MAX_FRAG_THRESHOLD;
1868
1869         range->pm_capa = 0;
1870
1871         range->we_version_compiled = WIRELESS_EXT;
1872         range->we_version_source = 16;
1873
1874 //      range->retry_capa;      /* What retry options are supported */
1875 //      range->retry_flags;     /* How to decode max/min retry limit */
1876 //      range->r_time_flags;    /* How to decode max/min retry life */
1877 //      range->min_retry;       /* Minimal number of retries */
1878 //      range->max_retry;       /* Maximal number of retries */
1879 //      range->min_r_time;      /* Minimal retry lifetime */
1880 //      range->max_r_time;      /* Maximal retry lifetime */
1881
1882         for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
1883
1884                 // Include only legal frequencies for some countries
1885                 if(pmlmeext->channel_set[i].ChannelNum != 0)
1886                 {
1887                         range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
1888                         range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
1889                         range->freq[val].e = 1;
1890                         val++;
1891                 }
1892
1893                 if (val == IW_MAX_FREQUENCIES)
1894                         break;
1895         }
1896
1897         range->num_channels = val;
1898         range->num_frequency = val;
1899
1900 // Commented by Albert 2009/10/13
1901 // The following code will proivde the security capability to network manager.
1902 // If the driver doesn't provide this capability to network manager,
1903 // the WPA/WPA2 routers can't be choosen in the network manager.
1904
1905 /*
1906 #define IW_SCAN_CAPA_NONE               0x00
1907 #define IW_SCAN_CAPA_ESSID              0x01
1908 #define IW_SCAN_CAPA_BSSID              0x02
1909 #define IW_SCAN_CAPA_CHANNEL    0x04
1910 #define IW_SCAN_CAPA_MODE               0x08
1911 #define IW_SCAN_CAPA_RATE               0x10
1912 #define IW_SCAN_CAPA_TYPE               0x20
1913 #define IW_SCAN_CAPA_TIME               0x40
1914 */
1915
1916 #if WIRELESS_EXT > 17
1917         range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
1918                           IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
1919 #endif
1920
1921 #ifdef IW_SCAN_CAPA_ESSID //WIRELESS_EXT > 21
1922         range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |IW_SCAN_CAPA_BSSID|
1923                                         IW_SCAN_CAPA_CHANNEL|IW_SCAN_CAPA_MODE|IW_SCAN_CAPA_RATE;
1924 #endif
1925
1926
1927         _func_exit_;
1928
1929         return 0;
1930
1931 }
1932
1933 //set bssid flow
1934 //s1. rtw_set_802_11_infrastructure_mode()
1935 //s2. rtw_set_802_11_authentication_mode()
1936 //s3. set_802_11_encryption_mode()
1937 //s4. rtw_set_802_11_bssid()
1938 static int rtw_wx_set_wap(struct net_device *dev,
1939                          struct iw_request_info *info,
1940                          union iwreq_data *awrq,
1941                          char *extra)
1942 {
1943         _irqL   irqL;
1944         uint ret = 0;
1945         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1946         struct sockaddr *temp = (struct sockaddr *)awrq;
1947         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
1948         _list   *phead;
1949         u8 *dst_bssid, *src_bssid;
1950         _queue  *queue  = &(pmlmepriv->scanned_queue);
1951         struct  wlan_network    *pnetwork = NULL;
1952         NDIS_802_11_AUTHENTICATION_MODE authmode;
1953
1954         _func_enter_;
1955 /*
1956 #ifdef CONFIG_CONCURRENT_MODE
1957         if(padapter->iface_type > PRIMARY_IFACE)
1958         {
1959                 ret = -EINVAL;
1960                 goto exit;
1961         }
1962 #endif  
1963 */      
1964
1965 #ifdef CONFIG_CONCURRENT_MODE
1966         if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
1967         {
1968                 DBG_871X("set bssid, but buddy_intf is under scanning or linking\n");
1969
1970                 ret = -EINVAL;
1971
1972                 goto exit;
1973         }
1974 #endif
1975
1976 #ifdef CONFIG_DUALMAC_CONCURRENT
1977         if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE)
1978         {
1979                 DBG_871X("set bssid, but buddy_intf is under scanning or linking\n");
1980                 ret = -EINVAL;
1981                 goto exit;
1982         }
1983 #endif
1984
1985         rtw_ps_deny(padapter, PS_DENY_JOIN);
1986         if(_FAIL == rtw_pwr_wakeup(padapter))
1987         {
1988                 ret= -1;
1989                 goto exit;
1990         }
1991         
1992         if(!padapter->bup){
1993                 ret = -1;
1994                 goto exit;
1995         }
1996
1997         
1998         if (temp->sa_family != ARPHRD_ETHER){
1999                 ret = -EINVAL;
2000                 goto exit;
2001         }
2002
2003         authmode = padapter->securitypriv.ndisauthtype;
2004         _enter_critical_bh(&queue->lock, &irqL);
2005        phead = get_list_head(queue);
2006        pmlmepriv->pscanned = get_next(phead);
2007
2008         while (1)
2009          {
2010                         
2011                 if ((rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) == _TRUE)
2012                 {
2013 #if 0           
2014                         ret = -EINVAL;
2015                         goto exit;
2016
2017                         if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
2018                         {
2019                                 rtw_set_802_11_bssid(padapter, temp->sa_data);
2020                                 goto exit;                    
2021                         }
2022                         else
2023                         {
2024                                 ret = -EINVAL;
2025                                 goto exit;
2026                         }
2027 #endif
2028
2029                         break;
2030                 }
2031         
2032                 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
2033
2034                 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
2035
2036                 dst_bssid = pnetwork->network.MacAddress;
2037
2038                 src_bssid = temp->sa_data;
2039
2040                 if ((_rtw_memcmp(dst_bssid, src_bssid, ETH_ALEN)) == _TRUE)
2041                 {                       
2042                         if(!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode))
2043                         {
2044                                 ret = -1;
2045                                 _exit_critical_bh(&queue->lock, &irqL);
2046                                 goto exit;
2047                         }
2048
2049                                 break;                  
2050                 }
2051
2052         }               
2053         _exit_critical_bh(&queue->lock, &irqL);
2054         
2055         rtw_set_802_11_authentication_mode(padapter, authmode);
2056         //set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
2057         if (rtw_set_802_11_bssid(padapter, temp->sa_data) == _FALSE) {
2058                 ret = -1;
2059                 goto exit;              
2060         }       
2061         
2062 exit:
2063         
2064         rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
2065
2066         _func_exit_;
2067         
2068         return ret;     
2069 }
2070
2071 static int rtw_wx_get_wap(struct net_device *dev, 
2072                             struct iw_request_info *info, 
2073                             union iwreq_data *wrqu, char *extra)
2074 {
2075
2076         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
2077         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
2078         WLAN_BSSID_EX  *pcur_bss = &pmlmepriv->cur_network.network;     
2079         
2080         wrqu->ap_addr.sa_family = ARPHRD_ETHER;
2081         
2082         _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
2083         
2084         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_wap\n"));
2085
2086         _func_enter_;
2087
2088         if  ( ((check_fwstate(pmlmepriv, _FW_LINKED)) == _TRUE) || 
2089                         ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) ||
2090                         ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == _TRUE) )
2091         {
2092
2093                 _rtw_memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
2094         }
2095         else
2096         {
2097                 _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
2098         }               
2099
2100         _func_exit_;
2101         
2102         return 0;
2103         
2104 }
2105
2106 static int rtw_wx_set_mlme(struct net_device *dev, 
2107                              struct iw_request_info *info, 
2108                              union iwreq_data *wrqu, char *extra)
2109 {
2110 #if 0
2111 /* SIOCSIWMLME data */
2112 struct  iw_mlme
2113 {
2114         __u16           cmd; /* IW_MLME_* */
2115         __u16           reason_code;
2116         struct sockaddr addr;
2117 };
2118 #endif
2119
2120         int ret=0;
2121         u16 reason;
2122         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2123         struct iw_mlme *mlme = (struct iw_mlme *) extra;
2124
2125
2126         if(mlme==NULL)
2127                 return -1;
2128
2129         DBG_871X("%s\n", __FUNCTION__);
2130
2131         reason = cpu_to_le16(mlme->reason_code);
2132
2133
2134         DBG_871X("%s, cmd=%d, reason=%d\n", __FUNCTION__, mlme->cmd, reason);
2135         
2136
2137         switch (mlme->cmd) 
2138         {
2139                 case IW_MLME_DEAUTH:
2140                                 if(!rtw_set_802_11_disassociate(padapter))
2141                                 ret = -1;
2142                                 break;
2143
2144                 case IW_MLME_DISASSOC:
2145                                 if(!rtw_set_802_11_disassociate(padapter))
2146                                                 ret = -1;
2147
2148                                 break;
2149
2150                 default:
2151                         return -EOPNOTSUPP;
2152         }
2153
2154         return ret;
2155 }
2156
2157 static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
2158                              union iwreq_data *wrqu, char *extra)
2159 {
2160         u8 _status = _FALSE;
2161         int ret = 0;    
2162         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2163         struct mlme_priv *pmlmepriv= &padapter->mlmepriv;
2164         NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
2165         _irqL   irqL;
2166 #ifdef CONFIG_P2P
2167         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);   
2168 #endif //CONFIG_P2P
2169         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_set_scan\n"));
2170
2171 _func_enter_;
2172
2173         #ifdef DBG_IOCTL
2174         DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__);
2175         #endif
2176 /*
2177 #ifdef CONFIG_CONCURRENT_MODE
2178         if(padapter->iface_type > PRIMARY_IFACE)
2179         {
2180                 ret = -1;
2181                 goto exit;
2182         }
2183 #endif
2184 */
2185 #ifdef CONFIG_MP_INCLUDED
2186                 if (padapter->registrypriv.mp_mode == 1)
2187                 {
2188                                 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter));      
2189                                 ret = -1;
2190                                 goto exit;
2191                 }
2192 #ifdef CONFIG_CONCURRENT_MODE
2193                         if (padapter->pbuddy_adapter) {
2194                                 if (padapter->pbuddy_adapter->registrypriv.mp_mode == 1)
2195                                 {
2196                                         DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter->pbuddy_adapter));
2197                                         ret = -1;
2198                                         goto exit;
2199                                 }
2200                         }
2201 #endif //CONFIG_CONCURRENT_MODE
2202 #endif
2203
2204         rtw_ps_deny(padapter, PS_DENY_SCAN);
2205         if(_FAIL == rtw_pwr_wakeup(padapter))
2206         {
2207                 ret= -1;
2208                 goto exit;
2209         }
2210
2211         if(padapter->bDriverStopped){
2212            DBG_871X("bDriverStopped=%d\n", padapter->bDriverStopped);
2213                 ret= -1;
2214                 goto exit;
2215         }
2216         
2217         if(!padapter->bup){
2218                 ret = -1;
2219                 goto exit;
2220         }
2221         
2222         if (padapter->hw_init_completed==_FALSE){
2223                 ret = -1;
2224                 goto exit;
2225         }
2226
2227         // When Busy Traffic, driver do not site survey. So driver return success.
2228         // wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout.
2229         // modify by thomas 2011-02-22.
2230         if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE
2231 #ifdef CONFIG_CONCURRENT_MODE
2232         || rtw_get_buddy_bBusyTraffic(padapter) == _TRUE
2233 #endif //CONFIG_CONCURRENT_MODE
2234         )
2235         {
2236                 indicate_wx_scan_complete_event(padapter);
2237                 goto exit;
2238         }
2239
2240         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2241         {
2242                 indicate_wx_scan_complete_event(padapter);
2243                 goto exit;
2244         } 
2245
2246 #ifdef CONFIG_CONCURRENT_MODE
2247         if (check_buddy_fwstate(padapter,
2248                 _FW_UNDER_SURVEY|_FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
2249         {
2250                 indicate_wx_scan_complete_event(padapter);
2251                 goto exit;
2252         }
2253 #endif
2254
2255 #ifdef CONFIG_DUALMAC_CONCURRENT
2256         if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE)
2257         {
2258                 indicate_wx_scan_complete_event(padapter);
2259                 goto exit;
2260         }
2261 #endif
2262
2263 #ifdef CONFIG_P2P
2264         if ( pwdinfo->p2p_state != P2P_STATE_NONE )
2265         {
2266                 rtw_p2p_set_pre_state( pwdinfo, rtw_p2p_state( pwdinfo ) );
2267                 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
2268                 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL);
2269                 rtw_free_network_queue(padapter, _TRUE);
2270         }
2271 #endif //CONFIG_P2P
2272
2273         _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
2274
2275 #if WIRELESS_EXT >= 17
2276         if (wrqu->data.length == sizeof(struct iw_scan_req)) 
2277         {
2278                 struct iw_scan_req *req = (struct iw_scan_req *)extra;
2279         
2280                 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
2281                 {
2282                         int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
2283
2284                         _rtw_memcpy(ssid[0].Ssid, req->essid, len);
2285                         ssid[0].SsidLength = len;       
2286
2287                         DBG_871X("IW_SCAN_THIS_ESSID, ssid=%s, len=%d\n", req->essid, req->essid_len);
2288                 
2289                         _enter_critical_bh(&pmlmepriv->lock, &irqL);                            
2290                 
2291                         _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0);
2292                 
2293                         _exit_critical_bh(&pmlmepriv->lock, &irqL);
2294                         
2295                 }
2296                 else if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
2297                 {
2298                         DBG_871X("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
2299                 }
2300                 
2301         }
2302         else
2303 #endif
2304
2305         if(     wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE
2306                 && _rtw_memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
2307         )
2308         {
2309                 int len = wrqu->data.length -WEXT_CSCAN_HEADER_SIZE;
2310                 char *pos = extra+WEXT_CSCAN_HEADER_SIZE;
2311                 char section;
2312                 char sec_len;
2313                 int ssid_index = 0;
2314
2315                 //DBG_871X("%s COMBO_SCAN header is recognized\n", __FUNCTION__);
2316                 
2317                 while(len >= 1) {
2318                         section = *(pos++); len-=1;
2319
2320                         switch(section) {
2321                                 case WEXT_CSCAN_SSID_SECTION:
2322                                         //DBG_871X("WEXT_CSCAN_SSID_SECTION\n");
2323                                         if(len < 1) {
2324                                                 len = 0;
2325                                                 break;
2326                                         }
2327                                         
2328                                         sec_len = *(pos++); len-=1;
2329
2330                                         if(sec_len>0 && sec_len<=len) {
2331                                                 ssid[ssid_index].SsidLength = sec_len;
2332                                                 _rtw_memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength);
2333                                                 //DBG_871X("%s COMBO_SCAN with specific ssid:%s, %d\n", __FUNCTION__
2334                                                 //      , ssid[ssid_index].Ssid, ssid[ssid_index].SsidLength);
2335                                                 ssid_index++;
2336                                         }
2337                                         
2338                                         pos+=sec_len; len-=sec_len;
2339                                         break;
2340                                         
2341                                 
2342                                 case WEXT_CSCAN_CHANNEL_SECTION:
2343                                         //DBG_871X("WEXT_CSCAN_CHANNEL_SECTION\n");
2344                                         pos+=1; len-=1;
2345                                         break;
2346                                 case WEXT_CSCAN_ACTV_DWELL_SECTION:
2347                                         //DBG_871X("WEXT_CSCAN_ACTV_DWELL_SECTION\n");
2348                                         pos+=2; len-=2;
2349                                         break;
2350                                 case WEXT_CSCAN_PASV_DWELL_SECTION:
2351                                         //DBG_871X("WEXT_CSCAN_PASV_DWELL_SECTION\n");
2352                                         pos+=2; len-=2;                                 
2353                                         break;
2354                                 case WEXT_CSCAN_HOME_DWELL_SECTION:
2355                                         //DBG_871X("WEXT_CSCAN_HOME_DWELL_SECTION\n");
2356                                         pos+=2; len-=2;
2357                                         break;
2358                                 case WEXT_CSCAN_TYPE_SECTION:
2359                                         //DBG_871X("WEXT_CSCAN_TYPE_SECTION\n");
2360                                         pos+=1; len-=1;
2361                                         break;
2362                                 #if 0
2363                                 case WEXT_CSCAN_NPROBE_SECTION:
2364                                         DBG_871X("WEXT_CSCAN_NPROBE_SECTION\n");
2365                                         break;
2366                                 #endif
2367                                 
2368                                 default:
2369                                         //DBG_871X("Unknown CSCAN section %c\n", section);
2370                                         len = 0; // stop parsing
2371                         }
2372                         //DBG_871X("len:%d\n", len);
2373                         
2374                 }
2375                 
2376                 //jeff: it has still some scan paramater to parse, we only do this now...
2377                 _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
2378                 
2379         } else
2380         
2381         {
2382                 _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
2383         }
2384
2385         if(_status == _FALSE)
2386                 ret = -1;
2387
2388 exit:
2389
2390         rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
2391
2392         #ifdef DBG_IOCTL
2393         DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret);
2394         #endif
2395
2396 _func_exit_;
2397
2398         return ret;     
2399 }
2400
2401 static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
2402                              union iwreq_data *wrqu, char *extra)
2403 {
2404         _irqL   irqL;
2405         _list                                   *plist, *phead;
2406         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2407         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
2408         _queue                          *queue  = &(pmlmepriv->scanned_queue);
2409         struct  wlan_network    *pnetwork = NULL;
2410         char *ev = extra;
2411         char *stop = ev + wrqu->data.length;
2412         u32 ret = 0;
2413         u32 cnt=0;
2414         u32 wait_for_surveydone;
2415         sint wait_status;
2416 #ifdef CONFIG_CONCURRENT_MODE
2417         //PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
2418         //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);      
2419 #endif
2420 #ifdef CONFIG_P2P
2421         struct  wifidirect_info*        pwdinfo = &padapter->wdinfo;
2422 #endif //CONFIG_P2P
2423         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan\n"));
2424         RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_, (" Start of Query SIOCGIWSCAN .\n"));
2425
2426         _func_enter_;
2427
2428         #ifdef DBG_IOCTL
2429         DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__);
2430         #endif
2431 /*
2432 #ifdef CONFIG_CONCURRENT_MODE
2433         if(padapter->iface_type > PRIMARY_IFACE)
2434         {
2435                 ret = -EINVAL;
2436                 goto exit;
2437         }
2438 #endif
2439 */      
2440         if(adapter_to_pwrctl(padapter)->brfoffbyhw && padapter->bDriverStopped)
2441         {
2442                 ret = -EINVAL;
2443                 goto exit;
2444         }
2445   
2446 #ifdef CONFIG_P2P
2447         if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2448         {
2449                 //      P2P is enabled
2450                 if ( padapter->chip_type == RTL8192D )
2451                         wait_for_surveydone = 300;      //      Because the 8192du supports more channels.
2452                 else
2453                         wait_for_surveydone = 200;
2454         }
2455         else
2456         {
2457                 //      P2P is disabled
2458                 wait_for_surveydone = 100;
2459         }
2460 #else
2461         {
2462                 wait_for_surveydone = 100;
2463         }
2464 #endif //CONFIG_P2P
2465
2466 #if 1 // Wireless Extension use EAGAIN to try
2467         wait_status = _FW_UNDER_SURVEY
2468 #ifndef CONFIG_ANDROID
2469                 | _FW_UNDER_LINKING
2470 #endif
2471         ;
2472
2473         while (check_fwstate(pmlmepriv, wait_status) == _TRUE)
2474         {
2475                 return -EAGAIN;
2476         }
2477 #else
2478         wait_status = _FW_UNDER_SURVEY
2479                 #ifndef CONFIG_ANDROID
2480                 |_FW_UNDER_LINKING
2481                 #endif
2482         ;
2483
2484 #ifdef CONFIG_DUALMAC_CONCURRENT
2485         while(dc_check_fwstate(padapter, wait_status)== _TRUE)
2486         {
2487                 rtw_msleep_os(30);
2488                 cnt++;
2489                 if(cnt > wait_for_surveydone )
2490                         break;
2491         }
2492 #endif // CONFIG_DUALMAC_CONCURRENT
2493
2494         while(check_fwstate(pmlmepriv, wait_status) == _TRUE)
2495         {       
2496                 rtw_msleep_os(30);
2497                 cnt++;
2498                 if(cnt > wait_for_surveydone )
2499                         break;
2500         }
2501 #endif
2502         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2503
2504         phead = get_list_head(queue);
2505         plist = get_next(phead);
2506        
2507         while(1)
2508         {
2509                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
2510                         break;
2511
2512                 if((stop - ev) < SCAN_ITEM_SIZE) {
2513                         ret = -E2BIG;
2514                         break;
2515                 }
2516
2517                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2518
2519                 //report network only if the current channel set contains the channel to which this network belongs
2520                 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
2521                         && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE
2522                         && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
2523                 )
2524                 {
2525                         ev=translate_scan(padapter, a, pnetwork, ev, stop);
2526                 }
2527
2528                 plist = get_next(plist);
2529         
2530         }        
2531
2532         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2533
2534        wrqu->data.length = ev-extra;
2535         wrqu->data.flags = 0;
2536         
2537 exit:           
2538         
2539         _func_exit_;    
2540         
2541         #ifdef DBG_IOCTL
2542         DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret);
2543         #endif
2544         
2545         return ret ;
2546         
2547 }
2548
2549 //set ssid flow
2550 //s1. rtw_set_802_11_infrastructure_mode()
2551 //s2. set_802_11_authenticaion_mode()
2552 //s3. set_802_11_encryption_mode()
2553 //s4. rtw_set_802_11_ssid()
2554 static int rtw_wx_set_essid(struct net_device *dev, 
2555                               struct iw_request_info *a,
2556                               union iwreq_data *wrqu, char *extra)
2557 {
2558         _irqL irqL;
2559         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2560         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2561         _queue *queue = &pmlmepriv->scanned_queue;
2562         _list *phead;
2563         s8 status = _TRUE;
2564         struct wlan_network *pnetwork = NULL;
2565         NDIS_802_11_AUTHENTICATION_MODE authmode;       
2566         NDIS_802_11_SSID ndis_ssid;     
2567         u8 *dst_ssid, *src_ssid;
2568
2569         uint ret = 0, len;
2570
2571         _func_enter_;
2572         
2573         #ifdef DBG_IOCTL
2574         DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__);
2575         #endif
2576         
2577 /*
2578 #ifdef CONFIG_CONCURRENT_MODE
2579         if(padapter->iface_type > PRIMARY_IFACE)
2580         {
2581                 ret = -EINVAL;
2582                 goto exit;
2583         }
2584 #endif
2585 */
2586
2587 #ifdef CONFIG_CONCURRENT_MODE
2588         if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2589         {               
2590                 DBG_871X("set ssid, but buddy_intf is under scanning or linking\n");
2591                 
2592                 ret = -EINVAL;
2593                 
2594                 goto exit;
2595         }
2596 #endif
2597
2598 #ifdef CONFIG_DUALMAC_CONCURRENT
2599         if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE)
2600         {
2601                 DBG_871X("set bssid, but buddy_intf is under scanning or linking\n");
2602                 ret = -EINVAL;
2603                 goto exit;
2604         }
2605 #endif
2606
2607         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2608                  ("+rtw_wx_set_essid: fw_state=0x%08x\n", get_fwstate(pmlmepriv)));
2609
2610         rtw_ps_deny(padapter, PS_DENY_JOIN);
2611         if(_FAIL == rtw_pwr_wakeup(padapter))
2612         {               
2613                 ret = -1;
2614                 goto exit;
2615         }
2616
2617         if(!padapter->bup){
2618                 ret = -1;
2619                 goto exit;
2620         }
2621
2622 #if WIRELESS_EXT <= 20
2623         if ((wrqu->essid.length-1) > IW_ESSID_MAX_SIZE){
2624 #else
2625         if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
2626 #endif
2627                 ret= -E2BIG;
2628                 goto exit;
2629         }
2630         
2631         if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2632                 ret = -1;
2633                 goto exit;
2634         }               
2635         
2636         authmode = padapter->securitypriv.ndisauthtype;
2637         DBG_871X("=>%s\n",__FUNCTION__);
2638         if (wrqu->essid.flags && wrqu->essid.length)
2639         {
2640                 // Commented by Albert 20100519
2641                 // We got the codes in "set_info" function of iwconfig source code.
2642                 //      =========================================
2643                 //      wrq.u.essid.length = strlen(essid) + 1;
2644                 //      if(we_kernel_version > 20)
2645                 //              wrq.u.essid.length--;
2646                 //      =========================================
2647                 //      That means, if the WIRELESS_EXT less than or equal to 20, the correct ssid len should subtract 1.
2648 #if WIRELESS_EXT <= 20
2649                 len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
2650 #else
2651                 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
2652 #endif
2653
2654                 if( wrqu->essid.length != 33 )
2655                         DBG_871X("ssid=%s, len=%d\n", extra, wrqu->essid.length);
2656
2657                 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
2658                 ndis_ssid.SsidLength = len;
2659                 _rtw_memcpy(ndis_ssid.Ssid, extra, len);                
2660                 src_ssid = ndis_ssid.Ssid;
2661                 
2662                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid=[%s]\n", src_ssid));
2663                 _enter_critical_bh(&queue->lock, &irqL);
2664                phead = get_list_head(queue);
2665               pmlmepriv->pscanned = get_next(phead);
2666
2667                 while (1)
2668                 {                       
2669                         if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == _TRUE)
2670                         {
2671 #if 0                   
2672                                 if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
2673                                 {
2674                                         rtw_set_802_11_ssid(padapter, &ndis_ssid);
2675
2676                                         goto exit;                    
2677                                 }
2678                                 else
2679                                 {
2680                                         RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("rtw_wx_set_ssid(): scanned_queue is empty\n"));
2681                                         ret = -EINVAL;
2682                                         goto exit;
2683                                 }
2684 #endif                  
2685                                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_warning_,
2686                                          ("rtw_wx_set_essid: scan_q is empty, set ssid to check if scanning again!\n"));
2687
2688                                 break;
2689                         }
2690         
2691                         pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
2692
2693                         pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
2694
2695                         dst_ssid = pnetwork->network.Ssid.Ssid;
2696
2697                         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2698                                  ("rtw_wx_set_essid: dst_ssid=%s\n",
2699                                   pnetwork->network.Ssid.Ssid));
2700
2701                         if ((_rtw_memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength) == _TRUE) &&
2702                                 (pnetwork->network.Ssid.SsidLength==ndis_ssid.SsidLength))
2703                         {
2704                                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2705                                          ("rtw_wx_set_essid: find match, set infra mode\n"));
2706                                 
2707                                 if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
2708                                 {
2709                                         if(pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
2710                                                 continue;
2711                                 }       
2712                                         
2713                                 if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == _FALSE)
2714                                 {
2715                                         ret = -1;
2716                                         _exit_critical_bh(&queue->lock, &irqL);
2717                                         goto exit;
2718                                 }
2719
2720                                 break;                  
2721                         }
2722                 }
2723                 _exit_critical_bh(&queue->lock, &irqL);
2724                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2725                          ("set ssid: set_802_11_auth. mode=%d\n", authmode));
2726                 rtw_set_802_11_authentication_mode(padapter, authmode);
2727                 //set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
2728                 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {
2729                         ret = -1;
2730                         goto exit;
2731                 }       
2732         }                       
2733         
2734 exit:
2735
2736         rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
2737
2738         DBG_871X("<=%s, ret %d\n",__FUNCTION__, ret);
2739         
2740         #ifdef DBG_IOCTL
2741         DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret);
2742         #endif
2743         
2744         _func_exit_;
2745         
2746         return ret;     
2747 }
2748
2749 static int rtw_wx_get_essid(struct net_device *dev, 
2750                               struct iw_request_info *a,
2751                               union iwreq_data *wrqu, char *extra)
2752 {
2753         u32 len,ret = 0;
2754         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2755         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
2756         WLAN_BSSID_EX  *pcur_bss = &pmlmepriv->cur_network.network;
2757
2758         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_essid\n"));
2759
2760         _func_enter_;
2761
2762         if ( (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ||
2763               (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE))
2764         {
2765                 len = pcur_bss->Ssid.SsidLength;
2766
2767                 wrqu->essid.length = len;
2768                         
2769                 _rtw_memcpy(extra, pcur_bss->Ssid.Ssid, len);
2770
2771                 wrqu->essid.flags = 1;
2772         }
2773         else
2774         {
2775                 ret = -1;
2776                 goto exit;
2777         }
2778
2779 exit:
2780
2781         _func_exit_;
2782         
2783         return ret;
2784         
2785 }
2786
2787 static int rtw_wx_set_rate(struct net_device *dev, 
2788                               struct iw_request_info *a,
2789                               union iwreq_data *wrqu, char *extra)
2790 {
2791         int     i, ret = 0;
2792         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2793         u8      datarates[NumRates];
2794         u32     target_rate = wrqu->bitrate.value;
2795         u32     fixed = wrqu->bitrate.fixed;
2796         u32     ratevalue = 0;
2797          u8 mpdatarate[NumRates]={11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
2798
2799 _func_enter_;
2800
2801         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,(" rtw_wx_set_rate \n"));
2802         RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("target_rate = %d, fixed = %d\n",target_rate,fixed));
2803         
2804         if(target_rate == -1){
2805                 ratevalue = 11;
2806                 goto set_rate;
2807         }
2808         target_rate = target_rate/100000;
2809
2810         switch(target_rate){
2811                 case 10:
2812                         ratevalue = 0;
2813                         break;
2814                 case 20:
2815                         ratevalue = 1;
2816                         break;
2817                 case 55:
2818                         ratevalue = 2;
2819                         break;
2820                 case 60:
2821                         ratevalue = 3;
2822                         break;
2823                 case 90:
2824                         ratevalue = 4;
2825                         break;
2826                 case 110:
2827                         ratevalue = 5;
2828                         break;
2829                 case 120:
2830                         ratevalue = 6;
2831                         break;
2832                 case 180:
2833                         ratevalue = 7;
2834                         break;
2835                 case 240:
2836                         ratevalue = 8;
2837                         break;
2838                 case 360:
2839                         ratevalue = 9;
2840                         break;
2841                 case 480:
2842                         ratevalue = 10;
2843                         break;
2844                 case 540:
2845                         ratevalue = 11;
2846                         break;
2847                 default:
2848                         ratevalue = 11;
2849                         break;
2850         }
2851
2852 set_rate:
2853
2854         for(i=0; i<NumRates; i++)
2855         {
2856                 if(ratevalue==mpdatarate[i])
2857                 {
2858                         datarates[i] = mpdatarate[i];
2859                         if(fixed == 0)
2860                                 break;
2861                 }
2862                 else{
2863                         datarates[i] = 0xff;
2864                 }
2865
2866                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("datarate_inx=%d\n",datarates[i]));
2867         }
2868
2869         if( rtw_setdatarate_cmd(padapter, datarates) !=_SUCCESS){
2870                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("rtw_wx_set_rate Fail!!!\n"));
2871                 ret = -1;
2872         }
2873
2874 _func_exit_;
2875
2876         return ret;
2877 }
2878
2879 static int rtw_wx_get_rate(struct net_device *dev, 
2880                              struct iw_request_info *info, 
2881                              union iwreq_data *wrqu, char *extra)
2882 {       
2883         u16 max_rate = 0;
2884
2885         max_rate = rtw_get_cur_max_rate((_adapter *)rtw_netdev_priv(dev));
2886
2887         if(max_rate == 0)
2888                 return -EPERM;
2889         
2890         wrqu->bitrate.fixed = 0;        /* no auto select */
2891         wrqu->bitrate.value = max_rate * 100000;
2892
2893         return 0;
2894 }
2895
2896 static int rtw_wx_set_rts(struct net_device *dev, 
2897                              struct iw_request_info *info, 
2898                              union iwreq_data *wrqu, char *extra)
2899 {
2900         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2901
2902         _func_enter_;
2903         
2904         if (wrqu->rts.disabled)
2905                 padapter->registrypriv.rts_thresh = 2347;
2906         else {
2907                 if (wrqu->rts.value < 0 ||
2908                     wrqu->rts.value > 2347)
2909                         return -EINVAL;
2910                 
2911                 padapter->registrypriv.rts_thresh = wrqu->rts.value;
2912         }
2913
2914         DBG_871X("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
2915         
2916         _func_exit_;
2917         
2918         return 0;
2919
2920 }
2921
2922 static int rtw_wx_get_rts(struct net_device *dev, 
2923                              struct iw_request_info *info, 
2924                              union iwreq_data *wrqu, char *extra)
2925 {
2926         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2927         
2928         _func_enter_;
2929
2930         DBG_871X("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);   
2931         
2932         wrqu->rts.value = padapter->registrypriv.rts_thresh;
2933         wrqu->rts.fixed = 0;    /* no auto select */
2934         //wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
2935         
2936         _func_exit_;
2937         
2938         return 0;
2939 }
2940
2941 static int rtw_wx_set_frag(struct net_device *dev, 
2942                              struct iw_request_info *info, 
2943                              union iwreq_data *wrqu, char *extra)
2944 {
2945         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2946
2947         _func_enter_;
2948         
2949         if (wrqu->frag.disabled)
2950                 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
2951         else {
2952                 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
2953                     wrqu->frag.value > MAX_FRAG_THRESHOLD)
2954                         return -EINVAL;
2955                 
2956                 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
2957         }
2958
2959         DBG_871X("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
2960         
2961         _func_exit_;
2962         
2963         return 0;
2964         
2965 }
2966
2967 static int rtw_wx_get_frag(struct net_device *dev, 
2968                              struct iw_request_info *info, 
2969                              union iwreq_data *wrqu, char *extra)
2970 {
2971         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2972         
2973         _func_enter_;
2974
2975         DBG_871X("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
2976         
2977         wrqu->frag.value = padapter->xmitpriv.frag_len;
2978         wrqu->frag.fixed = 0;   /* no auto select */
2979         //wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
2980         
2981         _func_exit_;
2982         
2983         return 0;
2984 }
2985
2986 static int rtw_wx_get_retry(struct net_device *dev, 
2987                              struct iw_request_info *info, 
2988                              union iwreq_data *wrqu, char *extra)
2989 {
2990         //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2991
2992         
2993         wrqu->retry.value = 7;
2994         wrqu->retry.fixed = 0;  /* no auto select */
2995         wrqu->retry.disabled = 1;
2996         
2997         return 0;
2998
2999 }       
3000
3001 #if 0
3002 #define IW_ENCODE_INDEX         0x00FF  /* Token index (if needed) */
3003 #define IW_ENCODE_FLAGS         0xFF00  /* Flags defined below */
3004 #define IW_ENCODE_MODE          0xF000  /* Modes defined below */
3005 #define IW_ENCODE_DISABLED      0x8000  /* Encoding disabled */
3006 #define IW_ENCODE_ENABLED       0x0000  /* Encoding enabled */
3007 #define IW_ENCODE_RESTRICTED    0x4000  /* Refuse non-encoded packets */
3008 #define IW_ENCODE_OPEN          0x2000  /* Accept non-encoded packets */
3009 #define IW_ENCODE_NOKEY         0x0800  /* Key is write only, so not present */
3010 #define IW_ENCODE_TEMP          0x0400  /* Temporary key */
3011 /*
3012 iwconfig wlan0 key on -> flags = 0x6001 -> maybe it means auto
3013 iwconfig wlan0 key off -> flags = 0x8800
3014 iwconfig wlan0 key open -> flags = 0x2800
3015 iwconfig wlan0 key open 1234567890 -> flags = 0x2000
3016 iwconfig wlan0 key restricted -> flags = 0x4800
3017 iwconfig wlan0 key open [3] 1234567890 -> flags = 0x2003
3018 iwconfig wlan0 key restricted [2] 1234567890 -> flags = 0x4002
3019 iwconfig wlan0 key open [3] -> flags = 0x2803
3020 iwconfig wlan0 key restricted [2] -> flags = 0x4802
3021 */
3022 #endif
3023
3024 static int rtw_wx_set_enc(struct net_device *dev, 
3025                             struct iw_request_info *info, 
3026                             union iwreq_data *wrqu, char *keybuf)
3027 {       
3028         u32 key, ret = 0;
3029         u32 keyindex_provided;
3030         NDIS_802_11_WEP  wep;   
3031         NDIS_802_11_AUTHENTICATION_MODE authmode;
3032
3033         struct iw_point *erq = &(wrqu->encoding);
3034         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3035         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
3036         DBG_871X("+rtw_wx_set_enc, flags=0x%x\n", erq->flags);
3037
3038         _rtw_memset(&wep, 0, sizeof(NDIS_802_11_WEP));
3039         
3040         key = erq->flags & IW_ENCODE_INDEX;
3041         
3042         _func_enter_;   
3043
3044         if (erq->flags & IW_ENCODE_DISABLED)
3045         {
3046                 DBG_871X("EncryptionDisabled\n");
3047                 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
3048                 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3049                 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
3050                 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
3051                 authmode = Ndis802_11AuthModeOpen;
3052                 padapter->securitypriv.ndisauthtype=authmode;
3053                 
3054                 goto exit;
3055         }
3056
3057         if (key) {
3058                 if (key > WEP_KEYS)
3059                         return -EINVAL;
3060                 key--;
3061                 keyindex_provided = 1;
3062         } 
3063         else
3064         {
3065                 keyindex_provided = 0;
3066                 key = padapter->securitypriv.dot11PrivacyKeyIndex;
3067                 DBG_871X("rtw_wx_set_enc, key=%d\n", key);
3068         }
3069         
3070         //set authentication mode       
3071         if(erq->flags & IW_ENCODE_OPEN)
3072         {
3073                 DBG_871X("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
3074                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;//Ndis802_11EncryptionDisabled;
3075
3076 #ifdef CONFIG_PLATFORM_MT53XX
3077                 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
3078 #else
3079                 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open;
3080 #endif
3081
3082                 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3083                 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
3084                 authmode = Ndis802_11AuthModeOpen;
3085                 padapter->securitypriv.ndisauthtype=authmode;
3086         }       
3087         else if(erq->flags & IW_ENCODE_RESTRICTED)
3088         {               
3089                 DBG_871X("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
3090                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
3091
3092 #ifdef CONFIG_PLATFORM_MT53XX
3093                 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
3094 #else
3095                 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Shared;
3096 #endif
3097
3098                 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
3099                 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;                    
3100                 authmode = Ndis802_11AuthModeShared;
3101                 padapter->securitypriv.ndisauthtype=authmode;
3102         }
3103         else
3104         {
3105                 DBG_871X("rtw_wx_set_enc():erq->flags=0x%x\n", erq->flags);
3106
3107                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;//Ndis802_11EncryptionDisabled;
3108                 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
3109                 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3110                 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
3111                 authmode = Ndis802_11AuthModeOpen;
3112                 padapter->securitypriv.ndisauthtype=authmode;
3113         }
3114         
3115         wep.KeyIndex = key;
3116         if (erq->length > 0)
3117         {
3118                 wep.KeyLength = erq->length <= 5 ? 5 : 13;
3119
3120                 wep.Length = wep.KeyLength + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
3121         }
3122         else
3123         {
3124                 wep.KeyLength = 0 ;
3125                 
3126                 if(keyindex_provided == 1)// set key_id only, no given KeyMaterial(erq->length==0).
3127                 {
3128                         padapter->securitypriv.dot11PrivacyKeyIndex = key;
3129
3130                         DBG_871X("(keyindex_provided == 1), keyid=%d, key_len=%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
3131
3132                         switch(padapter->securitypriv.dot11DefKeylen[key])
3133                         {
3134                                 case 5:
3135                                         padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;                                     
3136                                         break;
3137                                 case 13:
3138                                         padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;                                    
3139                                         break;
3140                                 default:
3141                                         padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;                                        
3142                                         break;
3143                         }
3144                                 
3145                         goto exit;
3146                         
3147                 }
3148                 
3149         }
3150
3151         wep.KeyIndex |= 0x80000000;
3152
3153         _rtw_memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
3154         
3155         if (rtw_set_802_11_add_wep(padapter, &wep) == _FALSE) {
3156                 if(rf_on == pwrpriv->rf_pwrstate )
3157                         ret = -EOPNOTSUPP;
3158                 goto exit;
3159         }       
3160
3161 exit:
3162         
3163         _func_exit_;
3164         
3165         return ret;
3166         
3167 }
3168
3169 static int rtw_wx_get_enc(struct net_device *dev, 
3170                             struct iw_request_info *info, 
3171                             union iwreq_data *wrqu, char *keybuf)
3172 {
3173         uint key, ret =0;
3174         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3175         struct iw_point *erq = &(wrqu->encoding);
3176         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
3177
3178         _func_enter_;
3179         
3180         if(check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE)
3181         {
3182                  if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE)
3183                  {
3184                 erq->length = 0;
3185                 erq->flags |= IW_ENCODE_DISABLED;
3186                 return 0;
3187         }       
3188         }       
3189
3190         
3191         key = erq->flags & IW_ENCODE_INDEX;
3192
3193         if (key) {
3194                 if (key > WEP_KEYS)
3195                         return -EINVAL;
3196                 key--;
3197         } else
3198         {
3199                 key = padapter->securitypriv.dot11PrivacyKeyIndex;
3200         }       
3201
3202         erq->flags = key + 1;
3203
3204         //if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
3205         //{
3206         //      erq->flags |= IW_ENCODE_OPEN;
3207         //}       
3208         
3209         switch(padapter->securitypriv.ndisencryptstatus)
3210         {
3211                 case Ndis802_11EncryptionNotSupported:
3212                 case Ndis802_11EncryptionDisabled:
3213
3214                 erq->length = 0;
3215                 erq->flags |= IW_ENCODE_DISABLED;
3216         
3217                 break;
3218                 
3219                 case Ndis802_11Encryption1Enabled:                                      
3220                 
3221                 erq->length = padapter->securitypriv.dot11DefKeylen[key];               
3222
3223                 if(erq->length)
3224                 {
3225                         _rtw_memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
3226                 
3227                 erq->flags |= IW_ENCODE_ENABLED;
3228
3229                         if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
3230                         {
3231                                 erq->flags |= IW_ENCODE_OPEN;
3232                         }
3233                         else if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
3234                         {
3235                 erq->flags |= IW_ENCODE_RESTRICTED;
3236                         }       
3237                 }       
3238                 else
3239                 {
3240                         erq->length = 0;
3241                         erq->flags |= IW_ENCODE_DISABLED;
3242                 }
3243
3244                 break;
3245
3246                 case Ndis802_11Encryption2Enabled:
3247                 case Ndis802_11Encryption3Enabled:
3248
3249                 erq->length = 16;
3250                 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
3251
3252                 break;
3253         
3254                 default:
3255                 erq->length = 0;
3256                 erq->flags |= IW_ENCODE_DISABLED;
3257
3258                 break;
3259                 
3260         }
3261         
3262         _func_exit_;
3263         
3264         return ret;
3265         
3266 }                                    
3267
3268 static int rtw_wx_get_power(struct net_device *dev, 
3269                              struct iw_request_info *info, 
3270                              union iwreq_data *wrqu, char *extra)
3271 {
3272         //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3273         
3274         wrqu->power.value = 0;
3275         wrqu->power.fixed = 0;  /* no auto select */
3276         wrqu->power.disabled = 1;
3277         
3278         return 0;
3279
3280 }
3281
3282 static int rtw_wx_set_gen_ie(struct net_device *dev, 
3283                              struct iw_request_info *info, 
3284                              union iwreq_data *wrqu, char *extra)
3285 {
3286         int ret;
3287         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3288         
3289        ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
3290            
3291         return ret;
3292 }       
3293
3294 static int rtw_wx_set_auth(struct net_device *dev, 
3295                              struct iw_request_info *info, 
3296                              union iwreq_data *wrqu, char *extra)
3297 {
3298         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3299         struct iw_param *param = (struct iw_param*)&(wrqu->param);
3300         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
3301         struct security_priv *psecuritypriv = &padapter->securitypriv;
3302         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3303         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3304         u32 value = param->value;
3305         int ret = 0;
3306         
3307         switch (param->flags & IW_AUTH_INDEX) {
3308
3309         case IW_AUTH_WPA_VERSION:
3310 #ifdef CONFIG_WAPI_SUPPORT
3311 #ifndef CONFIG_IOCTL_CFG80211
3312                  padapter->wapiInfo.bWapiEnable = false;
3313                  if(value == IW_AUTH_WAPI_VERSION_1)
3314                  {
3315                         padapter->wapiInfo.bWapiEnable = true;
3316                         psecuritypriv->dot11PrivacyAlgrthm = _SMS4_;
3317                         psecuritypriv->dot118021XGrpPrivacy = _SMS4_;
3318                         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
3319                         pmlmeinfo->auth_algo = psecuritypriv->dot11AuthAlgrthm;
3320                         padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
3321                         padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
3322                 }
3323 #endif
3324 #endif
3325                 break;
3326         case IW_AUTH_CIPHER_PAIRWISE:
3327                 
3328                 break;
3329         case IW_AUTH_CIPHER_GROUP:
3330                 
3331                 break;
3332         case IW_AUTH_KEY_MGMT:
3333 #ifdef CONFIG_WAPI_SUPPORT
3334 #ifndef CONFIG_IOCTL_CFG80211
3335                 DBG_871X("rtw_wx_set_auth: IW_AUTH_KEY_MGMT case \n");
3336                 if(value == IW_AUTH_KEY_MGMT_WAPI_PSK)
3337                         padapter->wapiInfo.bWapiPSK = true;
3338                 else
3339                         padapter->wapiInfo.bWapiPSK = false;
3340                 DBG_871X("rtw_wx_set_auth: IW_AUTH_KEY_MGMT bwapipsk %d \n",padapter->wapiInfo.bWapiPSK);
3341 #endif
3342 #endif
3343                 /*
3344                  *  ??? does not use these parameters
3345                  */
3346                 break;
3347
3348         case IW_AUTH_TKIP_COUNTERMEASURES:
3349         {
3350             if ( param->value )
3351             {  // wpa_supplicant is enabling the tkip countermeasure.
3352                padapter->securitypriv.btkip_countermeasure = _TRUE; 
3353             }
3354             else
3355             {  // wpa_supplicant is disabling the tkip countermeasure.
3356                padapter->securitypriv.btkip_countermeasure = _FALSE; 
3357             }
3358                 break;
3359         }
3360         case IW_AUTH_DROP_UNENCRYPTED:
3361                 {
3362                         /* HACK:
3363                          *
3364                          * wpa_supplicant calls set_wpa_enabled when the driver
3365                          * is loaded and unloaded, regardless of if WPA is being
3366                          * used.  No other calls are made which can be used to
3367                          * determine if encryption will be used or not prior to
3368                          * association being expected.  If encryption is not being
3369                          * used, drop_unencrypted is set to false, else true -- we
3370                          * can use this to determine if the CAP_PRIVACY_ON bit should
3371                          * be set.
3372                          */
3373
3374                         if(padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
3375                         {
3376                                 break;//it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, 
3377                                                 // then it needn't reset it;
3378                         }
3379                         
3380                         if(param->value){
3381                                 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
3382                                 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3383                                 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
3384                                 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
3385                                 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeOpen;
3386                         }
3387                         
3388                         break;
3389                 }
3390
3391         case IW_AUTH_80211_AUTH_ALG:
3392
3393                 #if defined(CONFIG_ANDROID) || 1
3394                 /*
3395                  *  It's the starting point of a link layer connection using wpa_supplicant
3396                 */
3397                 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
3398                         LeaveAllPowerSaveMode(padapter);
3399                         rtw_disassoc_cmd(padapter, 500, _FALSE);
3400                         DBG_871X("%s...call rtw_indicate_disconnect\n ",__FUNCTION__);
3401                         rtw_indicate_disconnect(padapter);
3402                         rtw_free_assoc_resources(padapter, 1);
3403                 }
3404                 #endif
3405
3406
3407                 ret = wpa_set_auth_algs(dev, (u32)param->value);                
3408         
3409                 break;
3410
3411         case IW_AUTH_WPA_ENABLED:
3412
3413                 //if(param->value)
3414                 //      padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; //802.1x
3415                 //else
3416                 //      padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;//open system
3417                 
3418                 //_disassociate(priv);
3419                 
3420                 break;
3421
3422         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3423                 //ieee->ieee802_1x = param->value;
3424                 break;
3425
3426         case IW_AUTH_PRIVACY_INVOKED:
3427                 //ieee->privacy_invoked = param->value;
3428                 break;
3429
3430 #ifdef CONFIG_WAPI_SUPPORT
3431 #ifndef CONFIG_IOCTL_CFG80211
3432         case IW_AUTH_WAPI_ENABLED:
3433                 break;
3434 #endif
3435 #endif
3436
3437         default:
3438                 return -EOPNOTSUPP;
3439                 
3440         }
3441         
3442         return ret;
3443         
3444 }
3445
3446 static int rtw_wx_set_enc_ext(struct net_device *dev, 
3447                              struct iw_request_info *info, 
3448                              union iwreq_data *wrqu, char *extra)
3449 {
3450         char *alg_name;
3451         u32 param_len;
3452         struct ieee_param *param = NULL;
3453         struct iw_point *pencoding = &wrqu->encoding;
3454         struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
3455         int ret=0;
3456
3457         param_len = sizeof(struct ieee_param) + pext->key_len;
3458         param = (struct ieee_param *)rtw_malloc(param_len);
3459         if (param == NULL)
3460                 return -1;
3461         
3462         _rtw_memset(param, 0, param_len);
3463
3464         param->cmd = IEEE_CMD_SET_ENCRYPTION;
3465         _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
3466
3467
3468         switch (pext->alg) {
3469         case IW_ENCODE_ALG_NONE:
3470                 //todo: remove key 
3471                 //remove = 1;   
3472                 alg_name = "none";
3473                 break;
3474         case IW_ENCODE_ALG_WEP:
3475                 alg_name = "WEP";
3476                 break;
3477         case IW_ENCODE_ALG_TKIP:
3478                 alg_name = "TKIP";
3479                 break;
3480         case IW_ENCODE_ALG_CCMP:
3481                 alg_name = "CCMP";
3482                 break;
3483 #ifdef CONFIG_IEEE80211W
3484         case IW_ENCODE_ALG_AES_CMAC:
3485                 alg_name = "BIP";
3486                 break;
3487 #endif //CONFIG_IEEE80211W
3488 #ifdef CONFIG_WAPI_SUPPORT
3489 #ifndef CONFIG_IOCTL_CFG80211
3490         case IW_ENCODE_ALG_SM4:
3491                 alg_name= "SMS4";
3492                 _rtw_memcpy(param->sta_addr, pext->addr.sa_data, ETH_ALEN);
3493                 DBG_871X("rtw_wx_set_enc_ext: SMS4 case \n");
3494                 break;
3495 #endif
3496 #endif
3497         default:
3498                 ret = -1;
3499                 goto exit;
3500         }
3501
3502         strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
3503
3504         if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
3505         {
3506                 param->u.crypt.set_tx = 1;
3507         }
3508
3509         /* cliW: WEP does not have group key
3510          * just not checking GROUP key setting 
3511          */
3512         if ((pext->alg != IW_ENCODE_ALG_WEP) &&
3513                 ((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
3514 #ifdef CONFIG_IEEE80211W
3515                 || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC)
3516 #endif //CONFIG_IEEE80211W
3517         ))
3518         {
3519                 param->u.crypt.set_tx = 0;
3520         }
3521
3522         param->u.crypt.idx = (pencoding->flags&0x00FF) -1 ;
3523
3524         if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
3525         {
3526 #ifdef CONFIG_WAPI_SUPPORT
3527 #ifndef CONFIG_IOCTL_CFG80211
3528                 if(pext->alg == IW_ENCODE_ALG_SM4)
3529                         _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 16);
3530                 else
3531 #endif //CONFIG_IOCTL_CFG80211
3532 #endif //CONFIG_WAPI_SUPPORT
3533                 _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 8);
3534         }
3535
3536         if(pext->key_len)
3537         {
3538                 param->u.crypt.key_len = pext->key_len;
3539                 //_rtw_memcpy(param + 1, pext + 1, pext->key_len);
3540                 _rtw_memcpy(param->u.crypt.key, pext + 1, pext->key_len);
3541         }
3542
3543         if (pencoding->flags & IW_ENCODE_DISABLED)
3544         {
3545                 //todo: remove key 
3546                 //remove = 1;
3547         }
3548
3549         ret =  wpa_set_encryption(dev, param, param_len);
3550
3551 exit:
3552         if(param)
3553         {
3554                 rtw_mfree((u8*)param, param_len);
3555         }
3556
3557         return ret;
3558 }
3559
3560
3561 static int rtw_wx_get_nick(struct net_device *dev, 
3562                              struct iw_request_info *info, 
3563                              union iwreq_data *wrqu, char *extra)
3564 {       
3565         //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3566          //struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3567          //struct security_priv *psecuritypriv = &padapter->securitypriv;
3568
3569         if(extra)
3570         {
3571                 wrqu->data.length = 14;
3572                 wrqu->data.flags = 1;
3573                 _rtw_memcpy(extra, "<WIFI@REALTEK>", 14);
3574         }
3575
3576         //rtw_signal_process(pid, SIGUSR1); //for test
3577
3578         //dump debug info here  
3579 /*
3580         u32 dot11AuthAlgrthm;           // 802.11 auth, could be open, shared, and 8021x
3581         u32 dot11PrivacyAlgrthm;        // This specify the privacy for shared auth. algorithm.
3582         u32 dot118021XGrpPrivacy;       // This specify the privacy algthm. used for Grp key 
3583         u32 ndisauthtype;
3584         u32 ndisencryptstatus;
3585 */
3586
3587         //DBG_871X("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", 
3588         //              psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
3589         //              psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
3590         
3591         //DBG_871X("enc_alg=0x%x\n", psecuritypriv->dot11PrivacyAlgrthm);
3592         //DBG_871X("auth_type=0x%x\n", psecuritypriv->ndisauthtype);
3593         //DBG_871X("enc_type=0x%x\n", psecuritypriv->ndisencryptstatus);
3594
3595 #if 0
3596         DBG_871X("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
3597         DBG_871X("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
3598         DBG_871X("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
3599         DBG_871X("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
3600         DBG_871X("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
3601         
3602         DBG_871X("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
3603
3604
3605         DBG_871X("\n");
3606
3607         DBG_871X("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
3608         DBG_871X("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
3609
3610         DBG_871X("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
3611         
3612         DBG_871X("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
3613         
3614         DBG_871X("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
3615         DBG_871X("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
3616         
3617         DBG_871X("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
3618         DBG_871X("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
3619         DBG_871X("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
3620         DBG_871X("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
3621 #endif
3622         
3623         return 0;
3624
3625 }
3626
3627 static int rtw_wx_read32(struct net_device *dev,
3628                             struct iw_request_info *info,
3629                             union iwreq_data *wrqu, char *extra)
3630 {
3631         PADAPTER padapter;
3632         struct iw_point *p;
3633         u16 len;
3634         u32 addr;
3635         u32 data32;
3636         u32 bytes;
3637         u8 *ptmp;
3638         int ret;
3639
3640
3641         ret = 0;
3642         padapter = (PADAPTER)rtw_netdev_priv(dev);
3643         p = &wrqu->data;
3644         len = p->length;
3645         if (0 == len)
3646                 return -EINVAL;
3647
3648         ptmp = (u8*)rtw_malloc(len);
3649         if (NULL == ptmp)
3650                 return -ENOMEM;
3651
3652         if (copy_from_user(ptmp, p->pointer, len)) {
3653                 ret = -EFAULT;
3654                 goto exit;
3655         }
3656
3657         bytes = 0;
3658         addr = 0;
3659         sscanf(ptmp, "%d,%x", &bytes, &addr);
3660
3661         switch (bytes) {
3662                 case 1:
3663                         data32 = rtw_read8(padapter, addr);
3664                         sprintf(extra, "0x%02X", data32);
3665                         break;
3666                 case 2:
3667                         data32 = rtw_read16(padapter, addr);
3668                         sprintf(extra, "0x%04X", data32);
3669                         break;
3670                 case 4:
3671                         data32 = rtw_read32(padapter, addr);
3672                         sprintf(extra, "0x%08X", data32);
3673                         break;
3674                 default:
3675                         DBG_871X(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__);
3676                         ret = -EINVAL;
3677                         goto exit;
3678         }
3679         DBG_871X(KERN_INFO "%s: addr=0x%08X data=%s\n", __func__, addr, extra);
3680
3681 exit:
3682         rtw_mfree(ptmp, len);
3683
3684         return 0;
3685 }
3686
3687 static int rtw_wx_write32(struct net_device *dev,
3688                             struct iw_request_info *info,
3689                             union iwreq_data *wrqu, char *extra)
3690 {
3691         PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
3692
3693         u32 addr;
3694         u32 data32;
3695         u32 bytes;
3696
3697
3698         bytes = 0;
3699         addr = 0;
3700         data32 = 0;
3701         sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
3702
3703         switch (bytes) {
3704                 case 1:
3705                         rtw_write8(padapter, addr, (u8)data32);
3706                         DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%02X\n", __func__, addr, (u8)data32);
3707                         break;
3708                 case 2:
3709                         rtw_write16(padapter, addr, (u16)data32);
3710                         DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%04X\n", __func__, addr, (u16)data32);
3711                         break;
3712                 case 4:
3713                         rtw_write32(padapter, addr, data32);
3714                         DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%08X\n", __func__, addr, data32);
3715                         break;
3716                 default:
3717                         DBG_871X(KERN_INFO "%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);
3718                         return -EINVAL;
3719         }
3720
3721         return 0;
3722 }
3723
3724 static int rtw_wx_read_rf(struct net_device *dev,
3725                             struct iw_request_info *info,
3726                             union iwreq_data *wrqu, char *extra)
3727 {
3728         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3729         u32 path, addr, data32;
3730
3731
3732         path = *(u32*)extra;
3733         addr = *((u32*)extra + 1);
3734         data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);
3735 //      DBG_871X("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32);
3736         /*
3737          * IMPORTANT!!
3738          * Only when wireless private ioctl is at odd order,
3739          * "extra" would be copied to user space.
3740          */
3741         sprintf(extra, "0x%05x", data32);
3742
3743         return 0;
3744 }
3745
3746 static int rtw_wx_write_rf(struct net_device *dev,
3747                             struct iw_request_info *info,
3748                             union iwreq_data *wrqu, char *extra)
3749 {
3750         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3751         u32 path, addr, data32;
3752
3753
3754         path = *(u32*)extra;
3755         addr = *((u32*)extra + 1);
3756         data32 = *((u32*)extra + 2);
3757 //      DBG_871X("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32);
3758         rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);
3759
3760         return 0;
3761 }
3762
3763 static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
3764                  union iwreq_data *wrqu, char *b)
3765 {
3766         return -1;
3767 }
3768
3769 static int dummy(struct net_device *dev, struct iw_request_info *a,
3770                  union iwreq_data *wrqu, char *b)
3771 {
3772         //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);        
3773         //struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3774
3775         //DBG_871X("cmd_code=%x, fwstate=0x%x\n", a->cmd, get_fwstate(pmlmepriv));
3776         
3777         return -1;
3778         
3779 }
3780
3781 static int rtw_wx_set_channel_plan(struct net_device *dev,
3782                                struct iw_request_info *info,
3783                                union iwreq_data *wrqu, char *extra)
3784 {
3785         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3786         struct registry_priv *pregistrypriv = &padapter->registrypriv;
3787         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3788         extern int rtw_channel_plan;
3789         u8 channel_plan_req = (u8) (*((int *)wrqu));
3790
3791         #if 0
3792         rtw_channel_plan = (int)wrqu->data.pointer;
3793         pregistrypriv->channel_plan = rtw_channel_plan;
3794         pmlmepriv->ChannelPlan = pregistrypriv->channel_plan;
3795         #endif
3796
3797         if (_SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1, 1)) {
3798                 DBG_871X("%s set channel_plan = 0x%02X\n", __func__, pmlmepriv->ChannelPlan);
3799         } else 
3800                 return -EPERM;
3801
3802         return 0;
3803 }
3804
3805 static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
3806                 struct iw_request_info *a,
3807                 union iwreq_data *wrqu, char *b)
3808 {
3809 #ifdef CONFIG_PLATFORM_MT53XX
3810         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3811         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3812
3813         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_,
3814                  ("WLAN IOCTL: cmd_code=%x, fwstate=0x%x\n",
3815                   a->cmd, get_fwstate(pmlmepriv)));
3816 #endif
3817         return 0;
3818 }
3819
3820 static int rtw_wx_get_sensitivity(struct net_device *dev,
3821                                 struct iw_request_info *info,
3822                                 union iwreq_data *wrqu, char *buf)
3823 {
3824 #ifdef CONFIG_PLATFORM_MT53XX
3825         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3826
3827         //      Modified by Albert 20110914
3828         //      This is in dbm format for MTK platform.
3829         wrqu->qual.level = padapter->recvpriv.rssi;
3830         DBG_871X(" level = %u\n",  wrqu->qual.level );
3831 #endif
3832         return 0;
3833 }
3834
3835 static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
3836                                 struct iw_request_info *info,
3837                                 union iwreq_data *wrqu, char *extra)
3838 {
3839 #ifdef CONFIG_PLATFORM_MT53XX
3840         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3841
3842         return rtw_set_wpa_ie(padapter, wrqu->data.pointer, wrqu->data.length);
3843 #else
3844         return 0;
3845 #endif
3846 }
3847
3848 /*
3849 typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
3850                           union iwreq_data *wrqu, char *extra);
3851 */
3852 /*
3853  *      For all data larger than 16 octets, we need to use a
3854  *      pointer to memory allocated in user space.
3855  */
3856 static  int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info,
3857                                                 union iwreq_data *wrqu, char *extra)
3858 {
3859
3860  #if 0
3861 struct  iw_point
3862 {
3863   void __user   *pointer;       /* Pointer to the data  (in user space) */
3864   __u16         length;         /* number of fields or size in bytes */
3865   __u16         flags;          /* Optional params */
3866 };
3867  #endif
3868
3869 #ifdef CONFIG_DRVEXT_MODULE
3870         u8 res;
3871         struct drvext_handler *phandler;        
3872         struct drvext_oidparam *poidparam;              
3873         int ret;
3874         u16 len;
3875         u8 *pparmbuf, bset;
3876         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3877         struct iw_point *p = &wrqu->data;
3878
3879         if( (!p->length) || (!p->pointer)){
3880                 ret = -EINVAL;
3881                 goto _rtw_drvext_hdl_exit;
3882         }
3883         
3884         
3885         bset = (u8)(p->flags&0xFFFF);
3886         len = p->length;
3887         pparmbuf = (u8*)rtw_malloc(len);
3888         if (pparmbuf == NULL){
3889                 ret = -ENOMEM;
3890                 goto _rtw_drvext_hdl_exit;
3891         }
3892         
3893         if(bset)//set info
3894         {
3895                 if (copy_from_user(pparmbuf, p->pointer,len)) {
3896                         rtw_mfree(pparmbuf, len);
3897                         ret = -EFAULT;
3898                         goto _rtw_drvext_hdl_exit;
3899                 }               
3900         }
3901         else//query info
3902         {
3903         
3904         }
3905
3906         
3907         //
3908         poidparam = (struct drvext_oidparam *)pparmbuf; 
3909         
3910         RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("drvext set oid subcode [%d], len[%d], InformationBufferLength[%d]\r\n",
3911                                                  poidparam->subcode, poidparam->len, len));
3912
3913
3914         //check subcode 
3915         if ( poidparam->subcode >= MAX_DRVEXT_HANDLERS)
3916         {
3917                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext handlers\r\n"));             
3918                 ret = -EINVAL;
3919                 goto _rtw_drvext_hdl_exit;
3920         }
3921
3922
3923         if ( poidparam->subcode >= MAX_DRVEXT_OID_SUBCODES)
3924         {
3925                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext subcodes\r\n"));             
3926                 ret = -EINVAL;
3927                 goto _rtw_drvext_hdl_exit;
3928         }
3929
3930
3931         phandler = drvextoidhandlers + poidparam->subcode;
3932
3933         if (poidparam->len != phandler->parmsize)
3934         {
3935                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext param size %d vs %d\r\n",                    
3936                                                 poidparam->len , phandler->parmsize));          
3937                 ret = -EINVAL;          
3938                 goto _rtw_drvext_hdl_exit;
3939         }
3940
3941
3942         res = phandler->handler(&padapter->drvextpriv, bset, poidparam->data);
3943
3944         if(res==0)
3945         {
3946                 ret = 0;
3947                         
3948                 if (bset == 0x00) {//query info
3949                         //_rtw_memcpy(p->pointer, pparmbuf, len);
3950                         if (copy_to_user(p->pointer, pparmbuf, len))
3951                                 ret = -EFAULT;
3952                 }               
3953         }               
3954         else
3955                 ret = -EFAULT;
3956
3957         
3958 _rtw_drvext_hdl_exit:   
3959         
3960         return ret;     
3961         
3962 #endif
3963
3964         return 0;
3965
3966 }
3967
3968 static void rtw_dbg_mode_hdl(_adapter *padapter, u32 id, u8 *pdata, u32 len)
3969 {
3970         pRW_Reg         RegRWStruct;
3971         struct rf_reg_param *prfreg;
3972         u8 path;
3973         u8 offset;
3974         u32 value;
3975
3976         DBG_871X("%s\n", __FUNCTION__);
3977
3978         switch(id)
3979         {
3980                 case GEN_MP_IOCTL_SUBCODE(MP_START):
3981                         DBG_871X("871x_driver is only for normal mode, can't enter mp mode\n");
3982                         break;
3983                 case GEN_MP_IOCTL_SUBCODE(READ_REG):
3984                         RegRWStruct = (pRW_Reg)pdata;
3985                         switch (RegRWStruct->width)
3986                         {
3987                                 case 1:
3988                                         RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
3989                                         break;
3990                                 case 2:
3991                                         RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
3992                                         break;
3993                                 case 4:
3994                                         RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
3995                                         break;
3996                                 default:
3997                                         break;
3998                         }
3999                 
4000                         break;
4001                 case GEN_MP_IOCTL_SUBCODE(WRITE_REG):
4002                         RegRWStruct = (pRW_Reg)pdata;
4003                         switch (RegRWStruct->width)
4004                         {
4005                                 case 1:
4006                                         rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value);
4007                                         break;
4008                                 case 2:
4009                                         rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value);
4010                                         break;
4011                                 case 4:
4012                                         rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value);
4013                                         break;
4014                                 default:                                        
4015                                 break;
4016                         }
4017                                 
4018                         break;
4019                 case GEN_MP_IOCTL_SUBCODE(READ_RF_REG):
4020
4021                         prfreg = (struct rf_reg_param *)pdata;
4022
4023                         path = (u8)prfreg->path;                
4024                         offset = (u8)prfreg->offset;    
4025
4026                         value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff);
4027
4028                         prfreg->value = value;
4029
4030                         break;                  
4031                 case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG):
4032
4033                         prfreg = (struct rf_reg_param *)pdata;
4034
4035                         path = (u8)prfreg->path;
4036                         offset = (u8)prfreg->offset;    
4037                         value = prfreg->value;
4038
4039                         rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value);
4040                         
4041                         break;                  
4042                 case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO):
4043                         DBG_871X("==> trigger gpio 0\n");
4044                         rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, 0);
4045                         break;  
4046 #ifdef CONFIG_BT_COEXIST
4047                 case GEN_MP_IOCTL_SUBCODE(SET_DM_BT):                   
4048                         DBG_871X("==> set dm_bt_coexist:%x\n",*(u8 *)pdata);
4049                         rtw_hal_set_hwreg(padapter, HW_VAR_BT_SET_COEXIST, pdata);
4050                         break;
4051                 case GEN_MP_IOCTL_SUBCODE(DEL_BA):
4052                         DBG_871X("==> delete ba:%x\n",*(u8 *)pdata);
4053                         rtw_hal_set_hwreg(padapter, HW_VAR_BT_ISSUE_DELBA, pdata);
4054                         break;
4055 #endif
4056 #ifdef DBG_CONFIG_ERROR_DETECT
4057                 case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS):                                                     
4058                         *pdata = rtw_hal_sreset_get_wifi_status(padapter);                   
4059                         break;
4060 #endif
4061         
4062                 default:
4063                         break;
4064         }
4065         
4066 }
4067
4068 static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info,
4069                                                 union iwreq_data *wrqu, char *extra)
4070 {
4071         int ret = 0;
4072         u32 BytesRead, BytesWritten, BytesNeeded;
4073         struct oid_par_priv     oid_par;
4074         struct mp_ioctl_handler *phandler;
4075         struct mp_ioctl_param   *poidparam;
4076         uint status=0;
4077         u16 len;
4078         u8 *pparmbuf = NULL, bset;
4079         PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
4080         struct iw_point *p = &wrqu->data;
4081
4082         //DBG_871X("+rtw_mp_ioctl_hdl\n");
4083
4084         //mutex_lock(&ioctl_mutex);
4085
4086         if ((!p->length) || (!p->pointer)) {
4087                 ret = -EINVAL;
4088                 goto _rtw_mp_ioctl_hdl_exit;
4089         }
4090
4091         pparmbuf = NULL;
4092         bset = (u8)(p->flags & 0xFFFF);
4093         len = p->length;
4094         pparmbuf = (u8*)rtw_malloc(len);
4095         if (pparmbuf == NULL){
4096                 ret = -ENOMEM;
4097                 goto _rtw_mp_ioctl_hdl_exit;
4098         }
4099
4100         if (copy_from_user(pparmbuf, p->pointer, len)) {
4101                 ret = -EFAULT;
4102                 goto _rtw_mp_ioctl_hdl_exit;
4103         }
4104
4105         poidparam = (struct mp_ioctl_param *)pparmbuf;
4106         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
4107                  ("rtw_mp_ioctl_hdl: subcode [%d], len[%d], buffer_len[%d]\r\n",
4108                   poidparam->subcode, poidparam->len, len));
4109
4110         if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
4111                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("no matching drvext subcodes\r\n"));
4112                 ret = -EINVAL;
4113                 goto _rtw_mp_ioctl_hdl_exit;
4114         }
4115
4116         //DBG_871X("%s: %d\n", __func__, poidparam->subcode);
4117 #ifdef CONFIG_MP_INCLUDED 
4118 if (padapter->registrypriv.mp_mode == 1)
4119 {       
4120         phandler = mp_ioctl_hdl + poidparam->subcode;
4121
4122         if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize))
4123         {
4124                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
4125                          ("no matching drvext param size %d vs %d\r\n",
4126                           poidparam->len, phandler->paramsize));
4127                 ret = -EINVAL;
4128                 goto _rtw_mp_ioctl_hdl_exit;
4129         }
4130
4131         if (phandler->handler)
4132         {
4133                 oid_par.adapter_context = padapter;
4134                 oid_par.oid = phandler->oid;
4135                 oid_par.information_buf = poidparam->data;
4136                 oid_par.information_buf_len = poidparam->len;
4137                 oid_par.dbg = 0;
4138
4139                 BytesWritten = 0;
4140                 BytesNeeded = 0;
4141
4142                 if (bset) {
4143                         oid_par.bytes_rw = &BytesRead;
4144                         oid_par.bytes_needed = &BytesNeeded;
4145                         oid_par.type_of_oid = SET_OID;
4146                 } else {
4147                         oid_par.bytes_rw = &BytesWritten;
4148                         oid_par.bytes_needed = &BytesNeeded;
4149                         oid_par.type_of_oid = QUERY_OID;
4150                 }
4151
4152                 status = phandler->handler(&oid_par);
4153
4154                 //todo:check status, BytesNeeded, etc.
4155         }
4156         else {
4157                 DBG_871X("rtw_mp_ioctl_hdl(): err!, subcode=%d, oid=%d, handler=%p\n", 
4158                         poidparam->subcode, phandler->oid, phandler->handler);
4159                 ret = -EFAULT;
4160                 goto _rtw_mp_ioctl_hdl_exit;
4161         }
4162 }
4163 else
4164 #endif
4165 {
4166         rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len);
4167 }
4168
4169         if (bset == 0x00) {//query info
4170                 if (copy_to_user(p->pointer, pparmbuf, len))
4171                         ret = -EFAULT;
4172         }
4173
4174         if (status) {
4175                 ret = -EFAULT;
4176                 goto _rtw_mp_ioctl_hdl_exit;
4177         }
4178
4179 _rtw_mp_ioctl_hdl_exit:
4180
4181         if (pparmbuf)
4182                 rtw_mfree(pparmbuf, len);
4183
4184         //mutex_unlock(&ioctl_mutex);
4185
4186         return ret;
4187 }
4188
4189 static int rtw_get_ap_info(struct net_device *dev,
4190                                struct iw_request_info *info,
4191                                union iwreq_data *wrqu, char *extra)
4192 {
4193         int bssid_match, ret = 0;
4194         u32 cnt=0, wpa_ielen;
4195         _irqL   irqL;
4196         _list   *plist, *phead;
4197         unsigned char *pbuf;
4198         u8 bssid[ETH_ALEN];
4199         char data[32];
4200         struct wlan_network *pnetwork = NULL;
4201         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4202         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
4203         _queue *queue = &(pmlmepriv->scanned_queue);
4204         struct iw_point *pdata = &wrqu->data;   
4205
4206         DBG_871X("+rtw_get_aplist_info\n");
4207
4208         if((padapter->bDriverStopped) || (pdata==NULL))
4209         {                
4210                 ret= -EINVAL;
4211                 goto exit;
4212         }               
4213   
4214         while((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) == _TRUE)
4215         {       
4216                 rtw_msleep_os(30);
4217                 cnt++;
4218                 if(cnt > 100)
4219                         break;
4220         }
4221         
4222
4223         //pdata->length = 0;//? 
4224         pdata->flags = 0;
4225         if(pdata->length>=32)
4226         {
4227                 if(copy_from_user(data, pdata->pointer, 32))
4228                 {
4229                         ret= -EINVAL;
4230                         goto exit;
4231                 }
4232         }       
4233         else
4234         {
4235                 ret= -EINVAL;
4236                 goto exit;
4237         }       
4238
4239         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4240         
4241         phead = get_list_head(queue);
4242         plist = get_next(phead);
4243        
4244         while(1)
4245         {
4246                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
4247                         break;
4248
4249
4250                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4251
4252                 //if(hwaddr_aton_i(pdata->pointer, bssid)) 
4253                 if(hwaddr_aton_i(data, bssid)) 
4254                 {                       
4255                         DBG_871X("Invalid BSSID '%s'.\n", (u8*)data);
4256                         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4257                         return -EINVAL;
4258                 }               
4259                 
4260         
4261                 if(_rtw_memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE)//BSSID match, then check if supporting wpa/wpa2
4262                 {
4263                         DBG_871X("BSSID:" MAC_FMT "\n", MAC_ARG(bssid));
4264                         
4265                         pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);                           
4266                         if(pbuf && (wpa_ielen>0))
4267                         {
4268                                 pdata->flags = 1;
4269                                 break;
4270                         }
4271
4272                         pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
4273                         if(pbuf && (wpa_ielen>0))
4274                         {
4275                                 pdata->flags = 2;
4276                                 break;
4277                         }
4278                         
4279                 }
4280
4281                 plist = get_next(plist);                
4282         
4283         }        
4284
4285         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4286
4287         if(pdata->length>=34)
4288         {
4289                 if(copy_to_user((u8*)pdata->pointer+32, (u8*)&pdata->flags, 1))
4290                 {
4291                         ret= -EINVAL;
4292                         goto exit;
4293                 }
4294         }       
4295         
4296 exit:
4297         
4298         return ret;
4299                 
4300 }
4301
4302 static int rtw_set_pid(struct net_device *dev,
4303                                struct iw_request_info *info,
4304                                union iwreq_data *wrqu, char *extra)
4305 {
4306         
4307         int ret = 0;    
4308         _adapter *padapter = rtw_netdev_priv(dev);      
4309         int *pdata = (int *)wrqu;
4310         int selector;
4311
4312         if((padapter->bDriverStopped) || (pdata==NULL))
4313         {                
4314                 ret= -EINVAL;
4315                 goto exit;
4316         }               
4317   
4318         selector = *pdata;
4319         if(selector < 3 && selector >=0) {
4320                 padapter->pid[selector] = *(pdata+1);
4321                 #ifdef CONFIG_GLOBAL_UI_PID
4322                 ui_pid[selector] = *(pdata+1);
4323                 #endif
4324                 DBG_871X("%s set pid[%d]=%d\n", __FUNCTION__, selector ,padapter->pid[selector]);
4325         }
4326         else
4327                 DBG_871X("%s selector %d error\n", __FUNCTION__, selector);
4328
4329 exit:
4330         
4331         return ret;
4332                 
4333 }
4334
4335 static int rtw_wps_start(struct net_device *dev,
4336                                struct iw_request_info *info,
4337                                union iwreq_data *wrqu, char *extra)
4338 {
4339         
4340         int ret = 0;    
4341         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4342         struct iw_point *pdata = &wrqu->data;
4343         u32   u32wps_start = 0;
4344         unsigned int uintRet = 0;
4345
4346         if((_TRUE == padapter->bDriverStopped) ||(_TRUE==padapter->bSurpriseRemoved) || (NULL== pdata))
4347         {                
4348                 ret= -EINVAL;
4349                 goto exit;
4350         }               
4351
4352         uintRet = copy_from_user( ( void* ) &u32wps_start, pdata->pointer, 4 );
4353         if ( u32wps_start == 0 )
4354         {
4355                 u32wps_start = *extra;
4356         }
4357
4358         DBG_871X( "[%s] wps_start = %d\n", __FUNCTION__, u32wps_start );
4359
4360         if ( u32wps_start == 1 ) // WPS Start
4361         {
4362                 rtw_led_control(padapter, LED_CTL_START_WPS);
4363         }
4364         else if ( u32wps_start == 2 ) // WPS Stop because of wps success
4365         {
4366                 rtw_led_control(padapter, LED_CTL_STOP_WPS);
4367         }
4368         else if ( u32wps_start == 3 ) // WPS Stop because of wps fail
4369         {
4370                 rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);
4371         }
4372
4373 #ifdef CONFIG_INTEL_WIDI
4374         process_intel_widi_wps_status(padapter, u32wps_start);
4375 #endif //CONFIG_INTEL_WIDI
4376         
4377 exit:
4378         
4379         return ret;
4380                 
4381 }
4382
4383 #ifdef CONFIG_P2P
4384 static int rtw_wext_p2p_enable(struct net_device *dev,
4385                                struct iw_request_info *info,
4386                                union iwreq_data *wrqu, char *extra)
4387 {
4388         
4389         int ret = 0;    
4390         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4391         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
4392         struct iw_point *pdata = &wrqu->data;
4393         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4394         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
4395         enum P2P_ROLE init_role = P2P_ROLE_DISABLE;
4396
4397         if(*extra == '0' )
4398                 init_role = P2P_ROLE_DISABLE;
4399         else if(*extra == '1')
4400                 init_role = P2P_ROLE_DEVICE;
4401         else if(*extra == '2')
4402                 init_role = P2P_ROLE_CLIENT;
4403         else if(*extra == '3')
4404                 init_role = P2P_ROLE_GO;
4405
4406         if(_FAIL == rtw_p2p_enable(padapter, init_role))
4407         {
4408                 ret = -EFAULT;
4409                 goto exit;
4410         }
4411
4412         //set channel/bandwidth
4413         if(init_role != P2P_ROLE_DISABLE) 
4414         {       
4415                 u8 channel, ch_offset;
4416                 u16 bwmode;
4417
4418                 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN))
4419                 {
4420                         //      Stay at the listen state and wait for discovery.
4421                         channel = pwdinfo->listen_channel;
4422                         pwdinfo->operating_channel = pwdinfo->listen_channel;
4423                         ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4424                         bwmode = CHANNEL_WIDTH_20;
4425                 }
4426 #ifdef CONFIG_CONCURRENT_MODE
4427                 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
4428                 {
4429                         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
4430                         //struct wifidirect_info        *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4431                         struct mlme_priv                *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4432                         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4433                         
4434                         _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval );
4435                         if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
4436                         {
4437                                 pwdinfo->operating_channel = pbuddy_mlmeext->cur_channel;
4438                                 //      How about the ch_offset and bwmode ??
4439                         }
4440                         else
4441                         {
4442                                 pwdinfo->operating_channel = pwdinfo->listen_channel;
4443                         }
4444
4445                         channel = pbuddy_mlmeext->cur_channel;
4446                         ch_offset = pbuddy_mlmeext->cur_ch_offset;
4447                         bwmode = pbuddy_mlmeext->cur_bwmode;
4448                 }
4449 #endif
4450                 else
4451                 {
4452                         pwdinfo->operating_channel = pmlmeext->cur_channel;
4453                 
4454                         channel = pwdinfo->operating_channel;
4455                         ch_offset = pmlmeext->cur_ch_offset;
4456                         bwmode = pmlmeext->cur_bwmode;                                          
4457                 }
4458
4459                 set_channel_bwmode(padapter, channel, ch_offset, bwmode);
4460         }
4461
4462 exit:
4463         return ret;
4464                 
4465 }
4466
4467 static int rtw_p2p_set_go_nego_ssid(struct net_device *dev,
4468                                struct iw_request_info *info,
4469                                union iwreq_data *wrqu, char *extra)
4470 {
4471         
4472         int ret = 0;    
4473         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4474         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
4475         struct iw_point *pdata = &wrqu->data;
4476         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4477
4478         DBG_871X( "[%s] ssid = %s, len = %zu\n", __FUNCTION__, extra, strlen( extra ) );
4479         _rtw_memcpy( pwdinfo->nego_ssid, extra, strlen( extra ) );
4480         pwdinfo->nego_ssidlen = strlen( extra );
4481         
4482         return ret;
4483                 
4484 }
4485
4486
4487 static int rtw_p2p_set_intent(struct net_device *dev,
4488                                struct iw_request_info *info,
4489                                union iwreq_data *wrqu, char *extra)
4490 {
4491         int                                                     ret = 0;
4492         _adapter                                                *padapter = (_adapter *)rtw_netdev_priv(dev);
4493         struct wifidirect_info                  *pwdinfo= &(padapter->wdinfo);
4494         u8                                                      intent = pwdinfo->intent;
4495
4496         extra[ wrqu->data.length ] = 0x00;
4497
4498         intent = rtw_atoi( extra );
4499
4500         if ( intent <= 15 )
4501         {
4502                 pwdinfo->intent= intent;
4503         }
4504         else
4505         {
4506                 ret = -1;
4507         }
4508         
4509         DBG_871X( "[%s] intent = %d\n", __FUNCTION__, intent);
4510
4511         return ret;
4512                 
4513 }
4514
4515 static int rtw_p2p_set_listen_ch(struct net_device *dev,
4516                                struct iw_request_info *info,
4517                                union iwreq_data *wrqu, char *extra)
4518 {
4519         
4520         int ret = 0;    
4521         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4522         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4523         u8      listen_ch = pwdinfo->listen_channel;    //      Listen channel number
4524
4525         extra[ wrqu->data.length ] = 0x00;
4526         listen_ch = rtw_atoi( extra );
4527
4528         if ( ( listen_ch == 1 ) || ( listen_ch == 6 ) || ( listen_ch == 11 ) )
4529         {
4530                 pwdinfo->listen_channel = listen_ch;
4531                 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
4532         }
4533         else
4534         {
4535                 ret = -1;
4536         }
4537         
4538         DBG_871X( "[%s] listen_ch = %d\n", __FUNCTION__, pwdinfo->listen_channel );
4539         
4540         return ret;
4541                 
4542 }
4543
4544 static int rtw_p2p_set_op_ch(struct net_device *dev,
4545                                struct iw_request_info *info,
4546                                union iwreq_data *wrqu, char *extra)
4547 {
4548 //      Commented by Albert 20110524
4549 //      This function is used to set the operating channel if the driver will become the group owner
4550
4551         int ret = 0;    
4552         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4553         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4554         u8      op_ch = pwdinfo->operating_channel;     //      Operating channel number
4555
4556         extra[ wrqu->data.length ] = 0x00;
4557
4558         op_ch = ( u8 ) rtw_atoi( extra );
4559         if ( op_ch > 0 )
4560         {
4561                 pwdinfo->operating_channel = op_ch;
4562         }
4563         else
4564         {
4565                 ret = -1;
4566         }
4567         
4568         DBG_871X( "[%s] op_ch = %d\n", __FUNCTION__, pwdinfo->operating_channel );
4569         
4570         return ret;
4571
4572 }
4573
4574
4575 static int rtw_p2p_profilefound(struct net_device *dev,
4576                                struct iw_request_info *info,
4577                                union iwreq_data *wrqu, char *extra)
4578 {
4579         
4580         int ret = 0;    
4581         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4582         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4583
4584         //      Comment by Albert 2010/10/13
4585         //      Input data format:
4586         //      Ex:  0
4587         //      Ex:  1XX:XX:XX:XX:XX:XXYYSSID
4588         //      0 => Reflush the profile record list.
4589         //      1 => Add the profile list
4590         //      XX:XX:XX:XX:XX:XX => peer's MAC Address ( ex: 00:E0:4C:00:00:01 )
4591         //      YY => SSID Length
4592         //      SSID => SSID for persistence group
4593
4594         DBG_871X( "[%s] In value = %s, len = %d \n", __FUNCTION__, extra, wrqu->data.length -1);
4595
4596         
4597         //      The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function.
4598         if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4599         {
4600                 if ( extra[ 0 ] == '0' )
4601                 {
4602                         //      Remove all the profile information of wifidirect_info structure.
4603                         _rtw_memset( &pwdinfo->profileinfo[ 0 ], 0x00, sizeof( struct profile_info ) * P2P_MAX_PERSISTENT_GROUP_NUM );
4604                         pwdinfo->profileindex = 0;
4605                 }
4606                 else
4607                 {
4608                         if ( pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM )
4609                 {
4610                                 ret = -1;
4611                 }
4612                 else
4613                 {
4614                                 int jj, kk;
4615                                 
4616                                 //      Add this profile information into pwdinfo->profileinfo
4617                                 //      Ex:  1XX:XX:XX:XX:XX:XXYYSSID
4618                                 for( jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3 )
4619                                 {
4620                                         pwdinfo->profileinfo[ pwdinfo->profileindex ].peermac[ jj ] = key_2char2num(extra[ kk ], extra[ kk+ 1 ]);
4621                                 }
4622
4623                                 //pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen = ( extra[18] - '0' ) * 10 + ( extra[ 19 ] - '0' );
4624                                 //_rtw_memcpy( pwdinfo->profileinfo[ pwdinfo->profileindex ].ssid, &extra[ 20 ], pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen );
4625                                 pwdinfo->profileindex++;
4626                         }
4627                 }
4628         }       
4629         
4630         return ret;
4631                 
4632 }
4633
4634 static int rtw_p2p_setDN(struct net_device *dev,
4635                                struct iw_request_info *info,
4636                                union iwreq_data *wrqu, char *extra)
4637 {
4638         
4639         int ret = 0;    
4640         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4641         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4642
4643
4644         DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
4645         _rtw_memset( pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN );
4646         _rtw_memcpy( pwdinfo->device_name, extra, wrqu->data.length - 1 );
4647         pwdinfo->device_name_len = wrqu->data.length - 1;
4648
4649         return ret;
4650                 
4651 }
4652
4653
4654 static int rtw_p2p_get_status(struct net_device *dev,
4655                                struct iw_request_info *info,
4656                                union iwreq_data *wrqu, char *extra)
4657 {
4658         
4659         int ret = 0;    
4660         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4661         struct iw_point *pdata = &wrqu->data;
4662         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4663 #ifdef CONFIG_CONCURRENT_MODE
4664         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
4665         struct wifidirect_info  *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4666         struct mlme_priv                *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4667         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; 
4668 #endif
4669         
4670         if ( padapter->bShowGetP2PState )
4671         {
4672                 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),
4673                                 pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
4674                                 pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
4675         }
4676
4677         //      Commented by Albert 2010/10/12
4678         //      Because of the output size limitation, I had removed the "Role" information.
4679         //      About the "Role" information, we will use the new private IOCTL to get the "Role" information.
4680         sprintf( extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo) );
4681         wrqu->data.length = strlen( extra );
4682
4683         return ret;
4684                 
4685 }
4686
4687 //      Commented by Albert 20110520
4688 //      This function will return the config method description 
4689 //      This config method description will show us which config method the remote P2P device is intented to use
4690 //      by sending the provisioning discovery request frame.
4691
4692 static int rtw_p2p_get_req_cm(struct net_device *dev,
4693                                struct iw_request_info *info,
4694                                union iwreq_data *wrqu, char *extra)
4695 {
4696         
4697         int ret = 0;    
4698         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4699         struct iw_point *pdata = &wrqu->data;
4700         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4701
4702         sprintf( extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req );
4703         wrqu->data.length = strlen( extra );
4704         return ret;
4705                 
4706 }
4707
4708
4709 static int rtw_p2p_get_role(struct net_device *dev,
4710                                struct iw_request_info *info,
4711                                union iwreq_data *wrqu, char *extra)
4712 {
4713         
4714         int ret = 0;    
4715         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4716         struct iw_point *pdata = &wrqu->data;
4717         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4718
4719         
4720         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),
4721                         pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
4722                         pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
4723
4724         sprintf( extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo) );
4725         wrqu->data.length = strlen( extra );
4726         return ret;
4727                 
4728 }
4729
4730
4731 static int rtw_p2p_get_peer_ifaddr(struct net_device *dev,
4732                                struct iw_request_info *info,
4733                                union iwreq_data *wrqu, char *extra)
4734 {
4735         
4736         int ret = 0;    
4737         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4738         struct iw_point *pdata = &wrqu->data;
4739         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4740
4741
4742         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),
4743                         pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
4744                         pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
4745
4746         sprintf( extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4747                         pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
4748                         pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
4749         wrqu->data.length = strlen( extra );
4750         return ret;
4751                 
4752 }
4753
4754 static int rtw_p2p_get_peer_devaddr(struct net_device *dev,
4755                                struct iw_request_info *info,
4756                                union iwreq_data *wrqu, char *extra)
4757
4758 {
4759         
4760         int ret = 0;    
4761         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4762         struct iw_point *pdata = &wrqu->data;
4763         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4764
4765         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),
4766                         pwdinfo->rx_prov_disc_info.peerDevAddr[ 0 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 1 ], 
4767                         pwdinfo->rx_prov_disc_info.peerDevAddr[ 2 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 3 ],
4768                         pwdinfo->rx_prov_disc_info.peerDevAddr[ 4 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 5 ]);
4769         sprintf( extra, "\n%.2X%.2X%.2X%.2X%.2X%.2X",
4770                         pwdinfo->rx_prov_disc_info.peerDevAddr[ 0 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 1 ], 
4771                         pwdinfo->rx_prov_disc_info.peerDevAddr[ 2 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 3 ],
4772                         pwdinfo->rx_prov_disc_info.peerDevAddr[ 4 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 5 ]);
4773         wrqu->data.length = strlen( extra );    
4774         return ret;
4775                 
4776 }
4777
4778 static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev,
4779                                struct iw_request_info *info,
4780                                union iwreq_data *wrqu, char *extra)
4781
4782 {
4783         
4784         int ret = 0;    
4785         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4786         struct iw_point *pdata = &wrqu->data;
4787         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4788
4789         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),
4790                         pwdinfo->p2p_peer_device_addr[ 0 ], pwdinfo->p2p_peer_device_addr[ 1 ], 
4791                         pwdinfo->p2p_peer_device_addr[ 2 ], pwdinfo->p2p_peer_device_addr[ 3 ],
4792                         pwdinfo->p2p_peer_device_addr[ 4 ], pwdinfo->p2p_peer_device_addr[ 5 ]);
4793         sprintf( extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4794                         pwdinfo->p2p_peer_device_addr[ 0 ], pwdinfo->p2p_peer_device_addr[ 1 ], 
4795                         pwdinfo->p2p_peer_device_addr[ 2 ], pwdinfo->p2p_peer_device_addr[ 3 ],
4796                         pwdinfo->p2p_peer_device_addr[ 4 ], pwdinfo->p2p_peer_device_addr[ 5 ]);
4797         wrqu->data.length = strlen( extra );    
4798         return ret;
4799                 
4800 }
4801
4802 static int rtw_p2p_get_groupid(struct net_device *dev,
4803                                struct iw_request_info *info,
4804                                union iwreq_data *wrqu, char *extra)
4805
4806 {
4807         
4808         int ret = 0;    
4809         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4810         struct iw_point *pdata = &wrqu->data;
4811         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4812
4813         sprintf( extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s",
4814                         pwdinfo->groupid_info.go_device_addr[ 0 ], pwdinfo->groupid_info.go_device_addr[ 1 ], 
4815                         pwdinfo->groupid_info.go_device_addr[ 2 ], pwdinfo->groupid_info.go_device_addr[ 3 ],
4816                         pwdinfo->groupid_info.go_device_addr[ 4 ], pwdinfo->groupid_info.go_device_addr[ 5 ],
4817                         pwdinfo->groupid_info.ssid);
4818         wrqu->data.length = strlen( extra );    
4819         return ret;
4820                 
4821 }
4822
4823 static int rtw_p2p_get_op_ch(struct net_device *dev,
4824                                struct iw_request_info *info,
4825                                union iwreq_data *wrqu, char *extra)
4826
4827 {
4828         
4829         int ret = 0;    
4830         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4831         struct iw_point *pdata = &wrqu->data;
4832         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4833
4834         
4835         DBG_871X( "[%s] Op_ch = %02x\n", __FUNCTION__, pwdinfo->operating_channel);
4836         
4837         sprintf( extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel );
4838         wrqu->data.length = strlen( extra );
4839         return ret;
4840                 
4841 }
4842
4843 static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
4844                                                                                 struct iw_request_info *info,
4845                                                                                 union iwreq_data *wrqu, char *extra, char *subcmd)
4846
4847         
4848         int ret = 0;
4849         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4850         u8 peerMAC[ETH_ALEN] = { 0x00 };
4851         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4852         _irqL irqL;
4853         _list * plist,*phead;
4854         _queue *queue = &(pmlmepriv->scanned_queue);
4855         struct wlan_network *pnetwork = NULL;
4856         u8 blnMatch = 0;
4857         u16     attr_content = 0;
4858         uint attr_contentlen = 0;
4859         u8      attr_content_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4860
4861         //      Commented by Albert 20110727
4862         //      The input data is the MAC address which the application wants to know its WPS config method.
4863         //      After knowing its WPS config method, the application can decide the config method for provisioning discovery.
4864         //      Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05
4865
4866         DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
4867
4868         macstr2num(peerMAC, subcmd);
4869
4870         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4871
4872         phead = get_list_head(queue);
4873         plist = get_next(phead);
4874
4875         while (1)
4876         {
4877                 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
4878
4879                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4880                 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
4881                 {
4882                         u8 *wpsie;
4883                         uint    wpsie_len = 0;
4884
4885                         //      The mac address is matched.
4886
4887                         if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) )
4888                         {
4889                                 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&attr_content, &attr_contentlen);
4890                                 if (attr_contentlen)
4891                                 {
4892                                         attr_content = be16_to_cpu(attr_content);
4893                                         sprintf(attr_content_str, "\n\nM=%.4d", attr_content);
4894                                         blnMatch = 1;
4895                                 }
4896                         }
4897
4898                         break;
4899                 }
4900
4901                 plist = get_next(plist);
4902
4903         }
4904
4905         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4906
4907         if (!blnMatch)
4908         {
4909                 sprintf(attr_content_str, "\n\nM=0000");
4910         }
4911
4912         wrqu->data.length = strlen(attr_content_str);
4913         _rtw_memcpy(extra, attr_content_str, wrqu->data.length);
4914
4915         return ret; 
4916                 
4917 }
4918
4919 #ifdef CONFIG_WFD
4920 static int rtw_p2p_get_peer_wfd_port(struct net_device *dev,
4921                                struct iw_request_info *info,
4922                                union iwreq_data *wrqu, char *extra)
4923 {
4924         
4925         int ret = 0;    
4926         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4927         struct iw_point *pdata = &wrqu->data;
4928         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4929
4930         DBG_871X( "[%s] p2p_state = %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
4931
4932         sprintf( extra, "\n\nPort=%d\n", pwdinfo->wfd_info->peer_rtsp_ctrlport );
4933         DBG_871X( "[%s] remote port = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
4934         
4935         wrqu->data.length = strlen( extra );
4936         return ret;
4937                 
4938 }
4939
4940 static int rtw_p2p_get_peer_wfd_preferred_connection(struct net_device *dev,
4941                                struct iw_request_info *info,
4942                                union iwreq_data *wrqu, char *extra)
4943 {
4944         
4945         int ret = 0;    
4946         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4947         struct iw_point *pdata = &wrqu->data;
4948         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4949
4950         sprintf( extra, "\n\nwfd_pc=%d\n", pwdinfo->wfd_info->wfd_pc );
4951         DBG_871X( "[%s] wfd_pc = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_pc );
4952
4953         wrqu->data.length = strlen( extra );
4954         pwdinfo->wfd_info->wfd_pc = _FALSE;     //      Reset the WFD preferred connection to P2P
4955         return ret;
4956                 
4957 }
4958
4959 static int rtw_p2p_get_peer_wfd_session_available(struct net_device *dev,
4960                                struct iw_request_info *info,
4961                                union iwreq_data *wrqu, char *extra)
4962 {
4963         
4964         int ret = 0;    
4965         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
4966         struct iw_point *pdata = &wrqu->data;
4967         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
4968
4969         sprintf( extra, "\n\nwfd_sa=%d\n", pwdinfo->wfd_info->peer_session_avail );
4970         DBG_871X( "[%s] wfd_sa = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_session_avail );
4971
4972         wrqu->data.length = strlen( extra );
4973         pwdinfo->wfd_info->peer_session_avail = _TRUE;  //      Reset the WFD session available
4974         return ret;
4975                 
4976 }
4977
4978 #endif // CONFIG_WFD
4979
4980 static int rtw_p2p_get_go_device_address(struct net_device *dev,
4981                                                                                  struct iw_request_info *info,
4982                                                                                  union iwreq_data *wrqu, char *extra, char *subcmd)
4983 {
4984
4985         int ret = 0;    
4986         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4987         u8 peerMAC[ETH_ALEN] = { 0x00 };
4988         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4989         _irqL irqL;
4990         _list *plist, *phead;
4991         _queue *queue   = &(pmlmepriv->scanned_queue);
4992         struct wlan_network *pnetwork = NULL;
4993         u8 blnMatch = 0;
4994         u8 *p2pie;
4995         uint p2pielen = 0, attr_contentlen = 0;
4996         u8 attr_content[100] = { 0x00 };
4997         u8 go_devadd_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4998
4999         //      Commented by Albert 20121209
5000         //      The input data is the GO's interface address which the application wants to know its device address.
5001         //      Format: iwpriv wlanx p2p_get2 go_devadd=00:E0:4C:00:00:05
5002
5003         DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5004
5005         macstr2num(peerMAC, subcmd);
5006
5007         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5008
5009         phead = get_list_head(queue);
5010         plist = get_next(phead);
5011
5012         while (1)
5013         {
5014                 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5015
5016                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5017                 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5018                 {
5019                         //      Commented by Albert 2011/05/18
5020                         //      Match the device address located in the P2P IE
5021                         //      This is for the case that the P2P device address is not the same as the P2P interface address.
5022
5023                         if ((p2pie = rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
5024                         {
5025                                 while (p2pie)
5026                                 {
5027                                         //      The P2P Device ID attribute is included in the Beacon frame.
5028                                         //      The P2P Device Info attribute is included in the probe response frame.
5029
5030                                         _rtw_memset(attr_content, 0x00, 100);
5031                                         if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen))
5032                                         {
5033                                                 //      Handle the P2P Device ID attribute of Beacon first
5034                                                 blnMatch = 1;
5035                                                 break;
5036
5037                                         } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen))
5038                                         {
5039                                                 //      Handle the P2P Device Info attribute of probe response
5040                                                 blnMatch = 1;
5041                                                 break;
5042                                         }
5043
5044                                         //Get the next P2P IE
5045                                         p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
5046                                 }
5047                         }
5048                 }
5049
5050                 plist = get_next(plist);
5051
5052         }
5053
5054         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5055
5056         if (!blnMatch)
5057         {
5058                 sprintf(go_devadd_str, "\n\ndev_add=NULL");
5059         } else
5060         {
5061                 sprintf(go_devadd_str, "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
5062                                 attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
5063         }
5064
5065         wrqu->data.length = strlen(go_devadd_str);
5066         _rtw_memcpy(extra, go_devadd_str, wrqu->data.length);
5067
5068         return ret; 
5069                 
5070 }
5071
5072 static int rtw_p2p_get_device_type(struct net_device *dev,
5073                                                                    struct iw_request_info *info,
5074                                                                    union iwreq_data *wrqu, char *extra, char *subcmd)
5075
5076         
5077         int ret = 0;
5078         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5079         u8 peerMAC[ETH_ALEN] = { 0x00 };
5080         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5081         _irqL irqL;
5082         _list *plist, *phead;
5083         _queue *queue = &(pmlmepriv->scanned_queue);
5084         struct wlan_network *pnetwork = NULL;
5085         u8 blnMatch = 0;
5086         u8 dev_type[8] = { 0x00 };
5087         uint dev_type_len = 0;
5088         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
5089
5090         //      Commented by Albert 20121209
5091         //      The input data is the MAC address which the application wants to know its device type.
5092         //      Such user interface could know the device type.
5093         //      Format: iwpriv wlanx p2p_get2 dev_type=00:E0:4C:00:00:05
5094
5095         DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5096
5097         macstr2num(peerMAC, subcmd);
5098
5099         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5100
5101         phead = get_list_head(queue);
5102         plist = get_next(phead);
5103
5104         while (1)
5105         {
5106                 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5107
5108                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5109                 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5110                 {
5111                         u8 *wpsie;
5112                         uint    wpsie_len = 0;
5113
5114                         //      The mac address is matched.
5115
5116                         if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) )
5117                         {
5118                                 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len);
5119                                 if (dev_type_len)
5120                                 {
5121                                         u16     type = 0;
5122
5123                                         _rtw_memcpy(&type, dev_type, 2);
5124                                         type = be16_to_cpu(type);
5125                                         sprintf(dev_type_str, "\n\nN=%.2d", type);
5126                                         blnMatch = 1;
5127                                 }
5128                         }
5129                         break;
5130                 }
5131
5132                 plist = get_next(plist);
5133
5134         }
5135
5136         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5137
5138         if (!blnMatch)
5139         {
5140                 sprintf(dev_type_str, "\n\nN=00");
5141         }
5142
5143         wrqu->data.length = strlen(dev_type_str);
5144         _rtw_memcpy(extra, dev_type_str, wrqu->data.length);
5145
5146         return ret; 
5147                 
5148 }
5149
5150 static int rtw_p2p_get_device_name(struct net_device *dev,
5151                                                                    struct iw_request_info *info,
5152                                                                    union iwreq_data *wrqu, char *extra, char *subcmd)
5153
5154         
5155         int ret = 0;
5156         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5157         u8 peerMAC[ETH_ALEN] = { 0x00 };
5158         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5159         _irqL irqL;
5160         _list *plist, *phead;
5161         _queue *queue = &(pmlmepriv->scanned_queue);
5162         struct wlan_network *pnetwork = NULL;
5163         u8 blnMatch = 0;
5164         u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = { 0x00 };
5165         uint dev_len = 0;
5166         u8 dev_name_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
5167
5168         //      Commented by Albert 20121225
5169         //      The input data is the MAC address which the application wants to know its device name.
5170         //      Such user interface could show peer device's device name instead of ssid.
5171         //      Format: iwpriv wlanx p2p_get2 devN=00:E0:4C:00:00:05
5172
5173         DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5174
5175         macstr2num(peerMAC, subcmd);
5176
5177         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5178
5179         phead = get_list_head(queue);
5180         plist = get_next(phead);
5181
5182         while (1)
5183         {
5184                 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5185
5186                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5187                 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5188                 {
5189                         u8 *wpsie;
5190                         uint    wpsie_len = 0;
5191
5192                         //      The mac address is matched.
5193
5194                         if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) )
5195                         {
5196                                 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
5197                                 if (dev_len)
5198                                 {
5199                                         sprintf(dev_name_str, "\n\nN=%s", dev_name);
5200                                         blnMatch = 1;
5201                                 }
5202                         }
5203                         break;
5204                 }
5205
5206                 plist = get_next(plist);
5207
5208         }
5209
5210         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5211
5212         if (!blnMatch)
5213         {
5214                 sprintf(dev_name_str, "\n\nN=0000");
5215         }
5216
5217         wrqu->data.length = strlen(dev_name_str);
5218         _rtw_memcpy(extra, dev_name_str, wrqu->data.length);
5219
5220         return ret; 
5221                 
5222 }
5223
5224 static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
5225                                                                                         struct iw_request_info *info,
5226                                                                                         union iwreq_data *wrqu, char *extra, char *subcmd)
5227 {
5228
5229         int ret = 0;    
5230         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5231         u8 peerMAC[ETH_ALEN] = { 0x00 };
5232         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5233         _irqL irqL;
5234         _list *plist, *phead;
5235         _queue *queue   = &(pmlmepriv->scanned_queue);
5236         struct wlan_network *pnetwork = NULL;
5237         u8 blnMatch = 0;
5238         u8 *p2pie;
5239         uint p2pielen = 0, attr_contentlen = 0;
5240         u8 attr_content[2] = { 0x00 };
5241         u8 inv_proc_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
5242
5243         //      Commented by Ouden 20121226
5244         //      The application wants to know P2P initation procedure is support or not.
5245         //      Format: iwpriv wlanx p2p_get2 InvProc=00:E0:4C:00:00:05
5246
5247         DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5248
5249         macstr2num(peerMAC, subcmd);
5250
5251         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5252
5253         phead = get_list_head(queue);
5254         plist = get_next(phead);
5255
5256         while (1)
5257         {
5258                 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5259
5260                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5261                 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5262                 {
5263                         //      Commented by Albert 20121226
5264                         //      Match the device address located in the P2P IE
5265                         //      This is for the case that the P2P device address is not the same as the P2P interface address.
5266
5267                         if ((p2pie = rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
5268                         {
5269                                 while (p2pie)
5270                                 {
5271                                         //_rtw_memset( attr_content, 0x00, 2);
5272                                         if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen))
5273                                         {
5274                                                 //      Handle the P2P capability attribute
5275                                                 blnMatch = 1;
5276                                                 break;
5277
5278                                         }
5279
5280                                         //Get the next P2P IE
5281                                         p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
5282                                 }
5283                         }
5284                 }
5285
5286                 plist = get_next(plist);
5287
5288         }
5289
5290         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5291
5292         if (!blnMatch)
5293         {
5294                 sprintf(inv_proc_str, "\nIP=-1");
5295         } else
5296         {
5297                 if (attr_content[0] && 0x20)
5298                 {
5299                         sprintf(inv_proc_str, "\nIP=1");
5300                 } else
5301                 {
5302                         sprintf(inv_proc_str, "\nIP=0");
5303                 }
5304         }
5305
5306         wrqu->data.length = strlen(inv_proc_str);
5307         _rtw_memcpy(extra, inv_proc_str, wrqu->data.length);
5308
5309         return ret; 
5310                 
5311 }
5312
5313 static int rtw_p2p_connect(struct net_device *dev,
5314                                struct iw_request_info *info,
5315                                union iwreq_data *wrqu, char *extra)
5316 {
5317         
5318         int ret = 0;    
5319         _adapter                                *padapter = (_adapter *)rtw_netdev_priv(dev);   
5320         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
5321         u8                                      peerMAC[ ETH_ALEN ] = { 0x00 };
5322         int                                     jj,kk;
5323         u8                                      peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5324         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
5325         _irqL                           irqL;
5326         _list                                   *plist, *phead;
5327         _queue                          *queue  = &(pmlmepriv->scanned_queue);
5328         struct  wlan_network    *pnetwork = NULL;
5329         uint                                    uintPeerChannel = 0;
5330 #ifdef CONFIG_CONCURRENT_MODE
5331         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
5332         struct mlme_priv                *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5333         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5334 #endif // CONFIG_CONCURRENT_MODE        
5335
5336         //      Commented by Albert 20110304
5337         //      The input data contains two informations.
5338         //      1. First information is the MAC address which wants to formate with
5339         //      2. Second information is the WPS PINCode or "pbc" string for push button method
5340         //      Format: 00:E0:4C:00:00:05
5341         //      Format: 00:E0:4C:00:00:05
5342
5343         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5344
5345         if ( pwdinfo->p2p_state == P2P_STATE_NONE )
5346         {
5347                 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5348                 return ret;
5349         }
5350         
5351         if ( pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO )
5352         {
5353                 return -1;
5354         }
5355         
5356         for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
5357         {
5358                 peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
5359         }
5360
5361         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5362
5363         phead = get_list_head(queue);
5364         plist = get_next(phead);
5365        
5366         while(1)
5367         {
5368                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
5369                         break;
5370
5371                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5372                 if ( _rtw_memcmp( pnetwork->network.MacAddress, peerMAC, ETH_ALEN ) )
5373                 {
5374                         uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5375                         break;
5376                 }
5377
5378                 plist = get_next(plist);
5379         
5380         }
5381
5382         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5383
5384         if ( uintPeerChannel )
5385         {
5386 #ifdef CONFIG_CONCURRENT_MODE
5387                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5388                 {
5389                         _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
5390                 }
5391 #endif // CONFIG_CONCURRENT_MODE
5392
5393                 _rtw_memset( &pwdinfo->nego_req_info, 0x00, sizeof( struct tx_nego_req_info ) );
5394                 _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
5395                 
5396                 pwdinfo->nego_req_info.peer_channel_num[ 0 ] = uintPeerChannel;
5397                 _rtw_memcpy( pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN );
5398                 pwdinfo->nego_req_info.benable = _TRUE;
5399
5400                 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5401                 if ( rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK )
5402                 {
5403                         //      Restore to the listen state if the current p2p state is not nego OK
5404                         rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN );
5405                 }
5406
5407                 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5408                 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
5409
5410 #ifdef CONFIG_CONCURRENT_MODE
5411                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5412                 {
5413                         //      Have to enter the power saving with the AP
5414                         set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
5415                         
5416                         issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
5417                 }
5418 #endif // CONFIG_CONCURRENT_MODE
5419
5420                 DBG_871X( "[%s] Start PreTx Procedure!\n", __FUNCTION__ );
5421                 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
5422 #ifdef CONFIG_CONCURRENT_MODE
5423                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5424                 {
5425                         _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_GO_NEGO_TIMEOUT );
5426                 }
5427                 else
5428                 {
5429                         _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT );
5430                 }
5431 #else
5432                 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT );
5433 #endif // CONFIG_CONCURRENT_MODE                
5434
5435         }
5436         else
5437         {
5438                 DBG_871X( "[%s] Not Found in Scanning Queue~\n", __FUNCTION__ );
5439                 ret = -1;
5440         }
5441 exit:   
5442         return ret;
5443 }
5444
5445 static int rtw_p2p_invite_req(struct net_device *dev,
5446                                struct iw_request_info *info,
5447                                union iwreq_data *wrqu, char *extra)
5448 {
5449         
5450         int ret = 0;    
5451         _adapter                                        *padapter = (_adapter *)rtw_netdev_priv(dev);   
5452         struct iw_point                         *pdata = &wrqu->data;
5453         struct wifidirect_info          *pwdinfo = &( padapter->wdinfo );
5454         int                                             jj,kk;
5455         u8                                              peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5456         struct mlme_priv                        *pmlmepriv = &padapter->mlmepriv;
5457         _list                                           *plist, *phead;
5458         _queue                                  *queue  = &(pmlmepriv->scanned_queue);
5459         struct  wlan_network            *pnetwork = NULL;
5460         uint                                            uintPeerChannel = 0;
5461         u8                                              attr_content[50] = { 0x00 }, _status = 0;
5462         u8                                              *p2pie;
5463         uint                                            p2pielen = 0, attr_contentlen = 0;
5464         _irqL                                   irqL;
5465         struct tx_invite_req_info*      pinvite_req_info = &pwdinfo->invitereq_info;
5466         u8 ie_offset = 12;
5467 #ifdef CONFIG_CONCURRENT_MODE
5468         _adapter                                        *pbuddy_adapter = padapter->pbuddy_adapter;
5469         struct mlme_priv                        *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5470         struct mlme_ext_priv            *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5471 #endif // CONFIG_CONCURRENT_MODE
5472
5473 #ifdef CONFIG_WFD
5474         struct wifi_display_info*       pwfd_info = pwdinfo->wfd_info;
5475 #endif // CONFIG_WFD
5476         
5477         //      Commented by Albert 20120321
5478         //      The input data contains two informations.
5479         //      1. First information is the P2P device address which you want to send to.       
5480         //      2. Second information is the group id which combines with GO's mac address, space and GO's ssid.
5481         //      Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy"
5482         //      Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy
5483
5484         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5485
5486         if ( wrqu->data.length <=  37 )
5487         {
5488                 DBG_871X( "[%s] Wrong format!\n", __FUNCTION__ );
5489                 return ret;
5490         }
5491
5492         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
5493         {
5494                 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5495                 return ret;
5496         }
5497         else
5498         {
5499                 //      Reset the content of struct tx_invite_req_info
5500                 pinvite_req_info->benable = _FALSE;
5501                 _rtw_memset( pinvite_req_info->go_bssid, 0x00, ETH_ALEN );
5502                 _rtw_memset( pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN );
5503                 pinvite_req_info->ssidlen = 0x00;
5504                 pinvite_req_info->operating_ch = pwdinfo->operating_channel;
5505                 _rtw_memset( pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN );
5506                 pinvite_req_info->token = 3;
5507         }
5508         
5509         for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
5510         {
5511                 pinvite_req_info->peer_macaddr[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
5512         }
5513
5514         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5515
5516         phead = get_list_head(queue);
5517         plist = get_next(phead);
5518        
5519         while(1)
5520         {
5521                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
5522                         break;
5523
5524                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5525
5526                 //      Commented by Albert 2011/05/18
5527                 //      Match the device address located in the P2P IE
5528                 //      This is for the case that the P2P device address is not the same as the P2P interface address.
5529
5530                 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);
5531                 if ( (p2pie=rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
5532                 {
5533                         //      The P2P Device ID attribute is included in the Beacon frame.
5534                         //      The P2P Device Info attribute is included in the probe response frame.
5535
5536                         if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
5537                         {
5538                                 //      Handle the P2P Device ID attribute of Beacon first
5539                                 if ( _rtw_memcmp( attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN ) )
5540                                 {
5541                                         uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5542                                         break;
5543                                 }
5544                         }
5545                         else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
5546                         {
5547                                 //      Handle the P2P Device Info attribute of probe response
5548                                 if ( _rtw_memcmp( attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN ) )
5549                                 {
5550                                         uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5551                                         break;
5552                                 }                                       
5553                         }
5554
5555                 }
5556
5557                 plist = get_next(plist);
5558         
5559         }
5560
5561         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5562
5563 #ifdef CONFIG_WFD
5564         if ( uintPeerChannel )
5565         {
5566                 u8      wfd_ie[ 128 ] = { 0x00 };
5567                 uint    wfd_ielen = 0;
5568                 
5569                 if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength,  wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) )
5570                 {
5571                         u8      wfd_devinfo[ 6 ] = { 0x00 };
5572                         uint    wfd_devlen = 6;
5573
5574                         DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ );
5575                         if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) )
5576                         {
5577                                 u16     wfd_devinfo_field = 0;
5578                                 
5579                                 //      Commented by Albert 20120319
5580                                 //      The first two bytes are the WFD device information field of WFD device information subelement.
5581                                 //      In big endian format.
5582                                 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5583                                 if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL )
5584                                 {
5585                                         pwfd_info->peer_session_avail = _TRUE;
5586                                 }
5587                                 else
5588                                 {
5589                                         pwfd_info->peer_session_avail = _FALSE;
5590                                 }
5591                         }
5592                 }
5593                 
5594                 if ( _FALSE == pwfd_info->peer_session_avail )
5595                 {
5596                         DBG_871X( "[%s] WFD Session not avaiable!\n", __FUNCTION__ );
5597                         goto exit;
5598                 }
5599         }
5600 #endif // CONFIG_WFD
5601
5602         if ( uintPeerChannel )
5603         {
5604 #ifdef CONFIG_CONCURRENT_MODE
5605                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5606                 {
5607                         _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
5608                 }
5609 #endif // CONFIG_CONCURRENT_MODE
5610
5611                 //      Store the GO's bssid
5612                 for( jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3 )
5613                 {
5614                         pinvite_req_info->go_bssid[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
5615                 }
5616
5617                 //      Store the GO's ssid
5618                 pinvite_req_info->ssidlen = wrqu->data.length - 36;
5619                 _rtw_memcpy( pinvite_req_info->go_ssid, &extra[ 36 ], (u32) pinvite_req_info->ssidlen );
5620                 pinvite_req_info->benable = _TRUE;
5621                 pinvite_req_info->peer_ch = uintPeerChannel;
5622
5623                 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5624                 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ);
5625
5626 #ifdef CONFIG_CONCURRENT_MODE
5627                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5628                 {
5629                         //      Have to enter the power saving with the AP
5630                         set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
5631                         
5632                         issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
5633                 }
5634                 else
5635                 {
5636                         set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5637                 }
5638 #else
5639                 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5640 #endif
5641
5642                 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
5643                 
5644 #ifdef CONFIG_CONCURRENT_MODE
5645                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5646                 {
5647                         _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_INVITE_TIMEOUT );
5648                 }
5649                 else
5650                 {
5651                         _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT );
5652                 }
5653 #else
5654                 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT );
5655 #endif // CONFIG_CONCURRENT_MODE                
5656
5657                 
5658         }
5659         else
5660         {
5661                 DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ );
5662         }
5663 exit:
5664         
5665         return ret;
5666                 
5667 }
5668
5669 static int rtw_p2p_set_persistent(struct net_device *dev,
5670                                struct iw_request_info *info,
5671                                union iwreq_data *wrqu, char *extra)
5672 {
5673         
5674         int ret = 0;    
5675         _adapter                                        *padapter = (_adapter *)rtw_netdev_priv(dev);   
5676         struct iw_point                         *pdata = &wrqu->data;
5677         struct wifidirect_info          *pwdinfo = &( padapter->wdinfo );
5678         int                                             jj,kk;
5679         u8                                              peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5680         struct mlme_priv                        *pmlmepriv = &padapter->mlmepriv;
5681         _list                                           *plist, *phead;
5682         _queue                                  *queue  = &(pmlmepriv->scanned_queue);
5683         struct  wlan_network            *pnetwork = NULL;
5684         uint                                            uintPeerChannel = 0;
5685         u8                                              attr_content[50] = { 0x00 }, _status = 0;
5686         u8                                              *p2pie;
5687         uint                                            p2pielen = 0, attr_contentlen = 0;
5688         _irqL                                   irqL;
5689         struct tx_invite_req_info*      pinvite_req_info = &pwdinfo->invitereq_info;
5690 #ifdef CONFIG_CONCURRENT_MODE
5691         _adapter                                        *pbuddy_adapter = padapter->pbuddy_adapter;
5692         struct mlme_priv                        *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5693         struct mlme_ext_priv            *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5694 #endif // CONFIG_CONCURRENT_MODE
5695
5696 #ifdef CONFIG_WFD
5697         struct wifi_display_info*       pwfd_info = pwdinfo->wfd_info;
5698 #endif // CONFIG_WFD
5699         
5700         //      Commented by Albert 20120328
5701         //      The input data is 0 or 1
5702         //      0: disable persistent group functionality
5703         //      1: enable persistent group founctionality
5704         
5705         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5706
5707         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
5708         {
5709                 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5710                 return ret;
5711         }
5712         else
5713         {
5714                 if ( extra[ 0 ] == '0' )        //      Disable the persistent group function.
5715                 {
5716                         pwdinfo->persistent_supported = _FALSE;
5717                 }
5718                 else if ( extra[ 0 ] == '1' )   //      Enable the persistent group function.
5719                 {
5720                         pwdinfo->persistent_supported = _TRUE;
5721                 }
5722                 else
5723                 {
5724                         pwdinfo->persistent_supported = _FALSE;
5725                 }
5726         }
5727         printk( "[%s] persistent_supported = %d\n", __FUNCTION__, pwdinfo->persistent_supported );
5728         
5729 exit:
5730         
5731         return ret;
5732                 
5733 }
5734
5735 static int hexstr2bin(const char *hex, u8 *buf, size_t len)
5736 {
5737         size_t i;
5738         int a;
5739         const char *ipos = hex;
5740         u8 *opos = buf;
5741
5742         for (i = 0; i < len; i++) {
5743                 a = hex2byte_i(ipos);
5744                 if (a < 0)
5745                         return -1;
5746                 *opos++ = a;
5747                 ipos += 2;
5748         }
5749         return 0;
5750 }
5751
5752 static int uuid_str2bin(const char *str, u8 *bin)
5753 {
5754         const char *pos;
5755         u8 *opos;
5756
5757         pos = str;
5758         opos = bin;
5759
5760         if (hexstr2bin(pos, opos, 4))
5761                 return -1;
5762         pos += 8;
5763         opos += 4;
5764
5765         if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5766                 return -1;
5767         pos += 4;
5768         opos += 2;
5769
5770         if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5771                 return -1;
5772         pos += 4;
5773         opos += 2;
5774
5775         if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5776                 return -1;
5777         pos += 4;
5778         opos += 2;
5779
5780         if (*pos++ != '-' || hexstr2bin(pos, opos, 6))
5781                 return -1;
5782
5783         return 0;
5784 }
5785
5786 static int rtw_p2p_set_wps_uuid(struct net_device *dev,
5787         struct iw_request_info *info,
5788         union iwreq_data *wrqu, char *extra)
5789 {
5790
5791         int ret = 0;
5792         _adapter                                *padapter = (_adapter *)rtw_netdev_priv(dev);
5793         struct wifidirect_info                  *pwdinfo = &(padapter->wdinfo);
5794
5795         DBG_871X("[%s] data = %s\n", __FUNCTION__, extra);
5796
5797         if ((36 == strlen(extra)) && (uuid_str2bin(extra, pwdinfo->uuid) == 0)) 
5798         {
5799                 pwdinfo->external_uuid = 1;
5800         } else {
5801                 pwdinfo->external_uuid = 0;
5802                 ret = -EINVAL;
5803         }
5804
5805         return ret;
5806
5807 }
5808 #ifdef CONFIG_WFD
5809 static int rtw_p2p_set_pc(struct net_device *dev,
5810                                struct iw_request_info *info,
5811                                union iwreq_data *wrqu, char *extra)
5812 {
5813         
5814         int ret = 0;    
5815         _adapter                                *padapter = (_adapter *)rtw_netdev_priv(dev);   
5816         struct iw_point                 *pdata = &wrqu->data;
5817         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
5818         u8                                      peerMAC[ ETH_ALEN ] = { 0x00 };
5819         int                                     jj,kk;
5820         u8                                      peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5821         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
5822         _list                                   *plist, *phead;
5823         _queue                          *queue  = &(pmlmepriv->scanned_queue);
5824         struct  wlan_network    *pnetwork = NULL;
5825         u8                                      attr_content[50] = { 0x00 }, _status = 0;
5826         u8 *p2pie;
5827         uint                                    p2pielen = 0, attr_contentlen = 0;
5828         _irqL                           irqL;
5829         uint                                    uintPeerChannel = 0;
5830 #ifdef CONFIG_CONCURRENT_MODE
5831         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
5832         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5833 #endif // CONFIG_CONCURRENT_MODE        
5834         
5835         struct wifi_display_info*       pwfd_info = pwdinfo->wfd_info;
5836         
5837         //      Commented by Albert 20120512
5838         //      1. Input information is the MAC address which wants to know the Preferred Connection bit (PC bit)
5839         //      Format: 00:E0:4C:00:00:05
5840
5841         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5842
5843         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
5844         {
5845                 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5846                 return ret;
5847         }
5848         
5849         for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
5850         {
5851                 peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
5852         }
5853
5854         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5855
5856         phead = get_list_head(queue);
5857         plist = get_next(phead);
5858        
5859         while(1)
5860         {
5861                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
5862                         break;
5863
5864                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5865
5866                 //      Commented by Albert 2011/05/18
5867                 //      Match the device address located in the P2P IE
5868                 //      This is for the case that the P2P device address is not the same as the P2P interface address.
5869
5870                 if ( (p2pie=rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
5871                 {
5872                         //      The P2P Device ID attribute is included in the Beacon frame.
5873                         //      The P2P Device Info attribute is included in the probe response frame.
5874                         printk( "[%s] Got P2P IE\n", __FUNCTION__ );
5875                         if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
5876                         {
5877                                 //      Handle the P2P Device ID attribute of Beacon first
5878                                 printk( "[%s] P2P_ATTR_DEVICE_ID \n", __FUNCTION__ );
5879                                 if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
5880                                 {
5881                                         uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5882                                         break;
5883                                 }
5884                         }
5885                         else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
5886                         {
5887                                 //      Handle the P2P Device Info attribute of probe response
5888                                 printk( "[%s] P2P_ATTR_DEVICE_INFO \n", __FUNCTION__ );
5889                                 if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
5890                                 {
5891                                         uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5892                                         break;
5893                                 }                                       
5894                         }
5895
5896                 }
5897
5898                 plist = get_next(plist);
5899         
5900         }
5901
5902         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5903         printk( "[%s] channel = %d\n", __FUNCTION__, uintPeerChannel );
5904
5905         if ( uintPeerChannel )
5906         {
5907                 u8      wfd_ie[ 128 ] = { 0x00 };
5908                 uint    wfd_ielen = 0;
5909                 u8 ie_offset = (pnetwork->network.Reserved[0] == 2 ? 0:12);
5910
5911                 if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength,  wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) )
5912                 {
5913                         u8      wfd_devinfo[ 6 ] = { 0x00 };
5914                         uint    wfd_devlen = 6;
5915
5916                         DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ );
5917                         if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) )
5918                         {
5919                                 u16     wfd_devinfo_field = 0;
5920                                 
5921                                 //      Commented by Albert 20120319
5922                                 //      The first two bytes are the WFD device information field of WFD device information subelement.
5923                                 //      In big endian format.
5924                                 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5925                                 if ( wfd_devinfo_field & WFD_DEVINFO_PC_TDLS )
5926                                 {
5927                                         pwfd_info->wfd_pc = _TRUE;
5928                                 }
5929                                 else
5930                                 {
5931                                         pwfd_info->wfd_pc = _FALSE;
5932                                 }
5933                         }
5934                 }
5935         }       
5936         else
5937         {
5938                 DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ );
5939         }
5940
5941 exit:
5942         
5943         return ret;
5944                 
5945 }
5946
5947 static int rtw_p2p_set_wfd_device_type(struct net_device *dev,
5948                                struct iw_request_info *info,
5949                                union iwreq_data *wrqu, char *extra)
5950 {
5951         
5952         int ret = 0;    
5953         _adapter                                        *padapter = (_adapter *)rtw_netdev_priv(dev);   
5954         struct iw_point                         *pdata = &wrqu->data;
5955         struct wifidirect_info          *pwdinfo = &( padapter->wdinfo );
5956         struct wifi_display_info                *pwfd_info = pwdinfo->wfd_info;
5957         
5958         //      Commented by Albert 20120328
5959         //      The input data is 0 or 1
5960         //      0: specify to Miracast source device
5961         //      1 or others: specify to Miracast sink device (display device)
5962         
5963         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5964
5965         if ( extra[ 0 ] == '0' )        //      Set to Miracast source device.
5966         {
5967                 pwfd_info->wfd_device_type = WFD_DEVINFO_SOURCE;
5968         }
5969         else                                    //      Set to Miracast sink device.
5970         {
5971                 pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK;
5972         }
5973
5974 exit:
5975         
5976         return ret;
5977                 
5978 }
5979
5980 static int rtw_p2p_set_wfd_enable(struct net_device *dev,
5981                                struct iw_request_info *info,
5982                                union iwreq_data *wrqu, char *extra)
5983 {
5984 //      Commented by Kurt 20121206
5985 //      This function is used to set wfd enabled
5986
5987         int ret = 0;    
5988         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5989         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
5990
5991         if(*extra == '0' )
5992                 pwdinfo->wfd_info->wfd_enable = _FALSE;
5993         else if(*extra == '1')
5994                 pwdinfo->wfd_info->wfd_enable = _TRUE;
5995
5996         DBG_871X( "[%s] wfd_enable = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_enable );
5997         
5998         return ret;
5999                 
6000 }
6001
6002 static int rtw_p2p_set_driver_iface(struct net_device *dev,
6003                                struct iw_request_info *info,
6004                                union iwreq_data *wrqu, char *extra)
6005 {
6006 //      Commented by Kurt 20121206
6007 //      This function is used to set driver iface is WEXT or CFG80211
6008         int ret = 0;    
6009         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6010         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
6011
6012         if(*extra == '1' )
6013         {
6014                 pwdinfo->driver_interface = DRIVER_WEXT;
6015                 DBG_871X( "[%s] driver_interface = WEXT\n", __FUNCTION__);
6016         }
6017         else if(*extra == '2')
6018         {
6019                 pwdinfo->driver_interface = DRIVER_CFG80211;
6020                 DBG_871X( "[%s] driver_interface = CFG80211\n", __FUNCTION__);
6021         }
6022         
6023         return ret;
6024                 
6025 }
6026
6027 //      To set the WFD session available to enable or disable
6028 static int rtw_p2p_set_sa(struct net_device *dev,
6029                                struct iw_request_info *info,
6030                                union iwreq_data *wrqu, char *extra)
6031 {
6032         
6033         int ret = 0;    
6034         _adapter                                        *padapter = (_adapter *)rtw_netdev_priv(dev);   
6035         struct iw_point                         *pdata = &wrqu->data;
6036         struct wifidirect_info          *pwdinfo = &( padapter->wdinfo );
6037         struct wifi_display_info                *pwfd_info = pwdinfo->wfd_info;
6038         
6039         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6040
6041         if( 0 )
6042         {
6043                 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
6044                 return ret;
6045         }
6046         else
6047         {
6048                 if ( extra[ 0 ] == '0' )        //      Disable the session available.
6049                 {
6050                         pwdinfo->session_available = _FALSE;
6051                 }
6052                 else if ( extra[ 0 ] == '1' )   //      Enable the session available.
6053                 {
6054                         pwdinfo->session_available = _TRUE;
6055                 }
6056                 else
6057                 {
6058                         pwdinfo->session_available = _FALSE;
6059                 }
6060         }
6061         printk( "[%s] session available = %d\n", __FUNCTION__, pwdinfo->session_available );
6062         
6063 exit:
6064         
6065         return ret;
6066                 
6067 }
6068 #endif // CONFIG_WFD
6069
6070 static int rtw_p2p_prov_disc(struct net_device *dev,
6071                                struct iw_request_info *info,
6072                                union iwreq_data *wrqu, char *extra)
6073 {
6074         int ret = 0;    
6075         _adapter                                *padapter = (_adapter *)rtw_netdev_priv(dev);   
6076         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
6077         u8                                      peerMAC[ ETH_ALEN ] = { 0x00 };
6078         int                                     jj,kk;
6079         u8                                      peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
6080         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
6081         _list                                   *plist, *phead;
6082         _queue                          *queue  = &(pmlmepriv->scanned_queue);
6083         struct  wlan_network    *pnetwork = NULL;
6084         uint                                    uintPeerChannel = 0;
6085         u8                                      attr_content[100] = { 0x00 }, _status = 0;
6086         u8 *p2pie;
6087         uint                                    p2pielen = 0, attr_contentlen = 0;
6088         _irqL                           irqL;
6089         u8                                      ie_offset = 12;
6090 #ifdef CONFIG_CONCURRENT_MODE
6091         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
6092         struct mlme_priv                *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
6093         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
6094 #endif // CONFIG_CONCURRENT_MODE        
6095 #ifdef CONFIG_WFD
6096         struct wifi_display_info*       pwfd_info = pwdinfo->wfd_info;
6097 #endif // CONFIG_WFD
6098
6099         //      Commented by Albert 20110301
6100         //      The input data contains two informations.
6101         //      1. First information is the MAC address which wants to issue the provisioning discovery request frame.
6102         //      2. Second information is the WPS configuration method which wants to discovery
6103         //      Format: 00:E0:4C:00:00:05_display
6104         //      Format: 00:E0:4C:00:00:05_keypad
6105         //      Format: 00:E0:4C:00:00:05_pbc
6106         //      Format: 00:E0:4C:00:00:05_label
6107
6108         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6109
6110         if ( pwdinfo->p2p_state == P2P_STATE_NONE )
6111         {
6112                 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
6113                 return ret;
6114         }
6115         else
6116         {
6117 #ifdef CONFIG_INTEL_WIDI
6118                 if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE){
6119                         DBG_871X( "[%s] WiFi is under survey!\n", __FUNCTION__ );
6120                         return ret;
6121                 }
6122 #endif //CONFIG_INTEL_WIDI
6123
6124                 //      Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request.
6125                 _rtw_memset( pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN );
6126                 _rtw_memset( pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN );
6127                 _rtw_memset( &pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof( NDIS_802_11_SSID ) );              
6128                 pwdinfo->tx_prov_disc_info.peer_channel_num[ 0 ] = 0;
6129                 pwdinfo->tx_prov_disc_info.peer_channel_num[ 1 ] = 0;
6130                 pwdinfo->tx_prov_disc_info.benable = _FALSE;
6131         }
6132         
6133         for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
6134         {
6135                 peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
6136         }
6137
6138         if ( _rtw_memcmp( &extra[ 18 ], "display", 7 ) )
6139         {
6140                 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
6141         }
6142         else if ( _rtw_memcmp( &extra[ 18 ], "keypad", 7 ) )
6143         {
6144                 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
6145         }
6146         else if ( _rtw_memcmp( &extra[ 18 ], "pbc", 3 ) )
6147         {
6148                 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
6149         }
6150         else if ( _rtw_memcmp( &extra[ 18 ], "label", 5 ) )
6151         {
6152                 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
6153         }
6154         else
6155         {
6156                 DBG_871X( "[%s] Unknown WPS config methodn", __FUNCTION__ );
6157                 return( ret );
6158         }
6159
6160         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
6161
6162         phead = get_list_head(queue);
6163         plist = get_next(phead);
6164        
6165         while(1)
6166         {
6167                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
6168                         break;
6169
6170                 if( uintPeerChannel != 0 )
6171                         break;
6172
6173                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
6174
6175                 //      Commented by Albert 2011/05/18
6176                 //      Match the device address located in the P2P IE
6177                 //      This is for the case that the P2P device address is not the same as the P2P interface address.
6178
6179                 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);
6180                 if ( (p2pie=rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
6181                 {
6182                         while ( p2pie )
6183                         {
6184                                 //      The P2P Device ID attribute is included in the Beacon frame.
6185                                 //      The P2P Device Info attribute is included in the probe response frame.
6186
6187                                 if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
6188                                 {
6189                                         //      Handle the P2P Device ID attribute of Beacon first
6190                                         if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
6191                                         {
6192                                                 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6193                                                 break;
6194                                         }
6195                                 }
6196                                 else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
6197                                 {
6198                                         //      Handle the P2P Device Info attribute of probe response
6199                                         if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
6200                                         {
6201                                                 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6202                                                 break;
6203                                         }                                       
6204                                 }
6205
6206                                 //Get the next P2P IE
6207                                 p2pie = rtw_get_p2p_ie(p2pie+p2pielen, pnetwork->network.IELength - ie_offset -(p2pie -&pnetwork->network.IEs[ie_offset] + p2pielen), NULL, &p2pielen);
6208                         }
6209
6210                 }
6211
6212 #ifdef CONFIG_INTEL_WIDI
6213                 // Some Intel WiDi source may not provide P2P IE, 
6214                 // so we could only compare mac addr by 802.11 Source Address
6215                 if( pmlmepriv->widi_state == INTEL_WIDI_STATE_WFD_CONNECTION 
6216                         && uintPeerChannel == 0 )
6217                 {
6218                         if ( _rtw_memcmp( pnetwork->network.MacAddress, peerMAC, ETH_ALEN ) )
6219                         {
6220                                 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6221                                 break;
6222                         }
6223                 }
6224 #endif //CONFIG_INTEL_WIDI
6225
6226                 plist = get_next(plist);
6227         
6228         }
6229
6230         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
6231
6232         if ( uintPeerChannel )
6233         {
6234 #ifdef CONFIG_WFD
6235                 {
6236                         u8      wfd_ie[ 128 ] = { 0x00 };
6237                         uint    wfd_ielen = 0;
6238                         
6239                         if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength,  wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) )
6240                         {
6241                                 u8      wfd_devinfo[ 6 ] = { 0x00 };
6242                                 uint    wfd_devlen = 6;
6243
6244                                 DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ );
6245                                 if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) )
6246                                 {
6247                                         u16     wfd_devinfo_field = 0;
6248                                         
6249                                         //      Commented by Albert 20120319
6250                                         //      The first two bytes are the WFD device information field of WFD device information subelement.
6251                                         //      In big endian format.
6252                                         wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
6253                                         if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL )
6254                                         {
6255                                                 pwfd_info->peer_session_avail = _TRUE;
6256                                         }
6257                                         else
6258                                         {
6259                                                 pwfd_info->peer_session_avail = _FALSE;
6260                                         }
6261                                 }
6262                         }
6263                         
6264                         if ( _FALSE == pwfd_info->peer_session_avail )
6265                         {
6266                                 DBG_871X( "[%s] WFD Session not avaiable!\n", __FUNCTION__ );
6267                                 goto exit;
6268                         }
6269                 }
6270 #endif // CONFIG_WFD
6271                 
6272                 DBG_871X( "[%s] peer channel: %d!\n", __FUNCTION__, uintPeerChannel );
6273 #ifdef CONFIG_CONCURRENT_MODE
6274                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6275                 {
6276                         _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
6277                 }
6278 #endif // CONFIG_CONCURRENT_MODE
6279                 _rtw_memcpy( pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN );
6280                 _rtw_memcpy( pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN );
6281                 pwdinfo->tx_prov_disc_info.peer_channel_num[0] = ( u16 ) uintPeerChannel;
6282                 pwdinfo->tx_prov_disc_info.benable = _TRUE;
6283                 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6284                 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ);
6285
6286                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
6287                 {
6288                         _rtw_memcpy( &pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof( NDIS_802_11_SSID ) );
6289                 }
6290                 else if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
6291                 {
6292                         _rtw_memcpy( pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN );
6293                         pwdinfo->tx_prov_disc_info.ssid.SsidLength= P2P_WILDCARD_SSID_LEN;
6294                 }
6295
6296 #ifdef CONFIG_CONCURRENT_MODE
6297                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6298                 {
6299                         //      Have to enter the power saving with the AP
6300                         set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
6301                         
6302                         issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
6303                 }
6304                 else
6305                 {
6306                         set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
6307                 }
6308 #else
6309                 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
6310 #endif
6311
6312                 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
6313                 
6314 #ifdef CONFIG_CONCURRENT_MODE
6315                 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6316                 {
6317                         _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_PROVISION_TIMEOUT );
6318                 }
6319                 else
6320                 {
6321                         _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6322                 }
6323 #else
6324                 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6325 #endif // CONFIG_CONCURRENT_MODE                
6326                 
6327         }
6328         else
6329         {
6330                 DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ );
6331 #ifdef CONFIG_INTEL_WIDI
6332                 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
6333                 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
6334                 rtw_free_network_queue(padapter, _TRUE);                
6335                 _enter_critical_bh(&pmlmepriv->lock, &irqL);                            
6336                 rtw_sitesurvey_cmd(padapter, NULL, 0, NULL, 0);
6337                 _exit_critical_bh(&pmlmepriv->lock, &irqL);
6338 #endif //CONFIG_INTEL_WIDI
6339         }
6340 exit:
6341         
6342         return ret;
6343                 
6344 }
6345
6346 //      Added by Albert 20110328
6347 //      This function is used to inform the driver the user had specified the pin code value or pbc
6348 //      to application.
6349
6350 static int rtw_p2p_got_wpsinfo(struct net_device *dev,
6351                                struct iw_request_info *info,
6352                                union iwreq_data *wrqu, char *extra)
6353 {
6354         
6355         int ret = 0;    
6356         _adapter                                *padapter = (_adapter *)rtw_netdev_priv(dev);   
6357         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
6358         
6359
6360         DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6361         //      Added by Albert 20110328
6362         //      if the input data is P2P_NO_WPSINFO -> reset the wpsinfo
6363         //      if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device.
6364         //      if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself.
6365         //      if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC
6366         
6367         if ( *extra == '0' )
6368         {
6369                 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
6370         }
6371         else if ( *extra == '1' )
6372         {
6373                 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN;
6374         }
6375         else if ( *extra == '2' )
6376         {
6377                 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN;
6378         }
6379         else if ( *extra == '3' )
6380         {
6381                 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC;
6382         }
6383         else
6384         {
6385                 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
6386         }
6387         
6388         return ret;
6389                 
6390 }
6391
6392 #endif //CONFIG_P2P
6393
6394 static int rtw_p2p_set(struct net_device *dev,
6395                                struct iw_request_info *info,
6396                                union iwreq_data *wrqu, char *extra)
6397 {
6398         
6399         int ret = 0;
6400 #ifdef CONFIG_P2P
6401
6402         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6403         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
6404         struct iw_point *pdata = &wrqu->data;
6405         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
6406         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
6407
6408         DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra );
6409
6410         if ( _rtw_memcmp( extra, "enable=", 7 ) )
6411         {
6412                 rtw_wext_p2p_enable( dev, info, wrqu, &extra[7] );
6413         }
6414         else if ( _rtw_memcmp( extra, "setDN=", 6 ) )
6415         {
6416                 wrqu->data.length -= 6;
6417                 rtw_p2p_setDN( dev, info, wrqu, &extra[6] );
6418         }
6419         else if ( _rtw_memcmp( extra, "profilefound=", 13 ) )
6420         {
6421                 wrqu->data.length -= 13;
6422                 rtw_p2p_profilefound( dev, info, wrqu, &extra[13] );
6423         }
6424         else if ( _rtw_memcmp( extra, "prov_disc=", 10 ) )
6425         {
6426                 wrqu->data.length -= 10;
6427                 rtw_p2p_prov_disc( dev, info, wrqu, &extra[10] );
6428         }
6429         else if ( _rtw_memcmp( extra, "nego=", 5 ) )
6430         {
6431                 wrqu->data.length -= 5;
6432                 rtw_p2p_connect( dev, info, wrqu, &extra[5] );
6433         }
6434         else if ( _rtw_memcmp( extra, "intent=", 7 ) )
6435         {
6436                 //      Commented by Albert 2011/03/23
6437                 //      The wrqu->data.length will include the null character
6438                 //      So, we will decrease 7 + 1
6439                 wrqu->data.length -= 8;
6440                 rtw_p2p_set_intent( dev, info, wrqu, &extra[7] );
6441         }
6442         else if ( _rtw_memcmp( extra, "ssid=", 5 ) )
6443         {
6444                 wrqu->data.length -= 5;
6445                 rtw_p2p_set_go_nego_ssid( dev, info, wrqu, &extra[5] );
6446         }
6447         else if ( _rtw_memcmp( extra, "got_wpsinfo=", 12 ) )
6448         {
6449                 wrqu->data.length -= 12;
6450                 rtw_p2p_got_wpsinfo( dev, info, wrqu, &extra[12] );
6451         }
6452         else if ( _rtw_memcmp( extra, "listen_ch=", 10 ) )
6453         {
6454                 //      Commented by Albert 2011/05/24
6455                 //      The wrqu->data.length will include the null character
6456                 //      So, we will decrease (10 + 1)   
6457                 wrqu->data.length -= 11;
6458                 rtw_p2p_set_listen_ch( dev, info, wrqu, &extra[10] );
6459         }
6460         else if ( _rtw_memcmp( extra, "op_ch=", 6 ) )
6461         {
6462                 //      Commented by Albert 2011/05/24
6463                 //      The wrqu->data.length will include the null character
6464                 //      So, we will decrease (6 + 1)    
6465                 wrqu->data.length -= 7;
6466                 rtw_p2p_set_op_ch( dev, info, wrqu, &extra[6] );
6467         }
6468         else if ( _rtw_memcmp( extra, "invite=", 7 ) )
6469         {
6470                 wrqu->data.length -= 8;
6471                 rtw_p2p_invite_req( dev, info, wrqu, &extra[7] );
6472         }
6473         else if ( _rtw_memcmp( extra, "persistent=", 11 ) )
6474         {
6475                 wrqu->data.length -= 11;
6476                 rtw_p2p_set_persistent( dev, info, wrqu, &extra[11] );
6477         }
6478         else if ( _rtw_memcmp ( extra, "uuid=", 5) )
6479         {
6480                 wrqu->data.length -= 5;
6481                 ret = rtw_p2p_set_wps_uuid( dev, info, wrqu, &extra[5] );
6482         }
6483 #ifdef CONFIG_WFD
6484         else if ( _rtw_memcmp( extra, "sa=", 3 ) )
6485         {
6486                 //      sa: WFD Session Available information
6487                 wrqu->data.length -= 3;
6488                 rtw_p2p_set_sa( dev, info, wrqu, &extra[3] );
6489         }
6490         else if ( _rtw_memcmp( extra, "pc=", 3 ) )
6491         {
6492                 //      pc: WFD Preferred Connection
6493                 wrqu->data.length -= 3;
6494                 rtw_p2p_set_pc( dev, info, wrqu, &extra[3] );
6495         }
6496         else if ( _rtw_memcmp( extra, "wfd_type=", 9 ) )
6497         {
6498                 //      pc: WFD Preferred Connection
6499                 wrqu->data.length -= 9;
6500                 rtw_p2p_set_wfd_device_type( dev, info, wrqu, &extra[9] );
6501         }
6502         else if ( _rtw_memcmp( extra, "wfd_enable=", 11 ) )
6503         {
6504                 wrqu->data.length -= 11;
6505                 rtw_p2p_set_wfd_enable( dev, info, wrqu, &extra[11] );
6506         }
6507         else if ( _rtw_memcmp( extra, "driver_iface=", 13 ) )
6508         {
6509                 wrqu->data.length -= 13;
6510                 rtw_p2p_set_driver_iface( dev, info, wrqu, &extra[13] );
6511         }
6512 #endif //CONFIG_WFD
6513
6514 #endif //CONFIG_P2P
6515
6516         return ret;
6517                 
6518 }
6519
6520 static int rtw_p2p_get(struct net_device *dev,
6521                                struct iw_request_info *info,
6522                                union iwreq_data *wrqu, char *extra)
6523 {
6524         
6525         int ret = 0;    
6526         
6527 #ifdef CONFIG_P2P
6528
6529         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6530         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
6531         struct iw_point *pdata = &wrqu->data;
6532         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
6533         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
6534
6535         if ( padapter->bShowGetP2PState )
6536         {
6537                 DBG_871X( "[%s] extra = %s\n", __FUNCTION__, (char*) wrqu->data.pointer );
6538         }
6539
6540         if ( _rtw_memcmp( wrqu->data.pointer, "status", 6 ) )
6541         {
6542                 rtw_p2p_get_status( dev, info, wrqu, extra );
6543         }
6544         else if ( _rtw_memcmp( wrqu->data.pointer, "role", 4 ) )
6545         {
6546                 rtw_p2p_get_role( dev, info, wrqu, extra);
6547         }
6548         else if ( _rtw_memcmp( wrqu->data.pointer, "peer_ifa", 8 ) )
6549         {
6550                 rtw_p2p_get_peer_ifaddr( dev, info, wrqu, extra);
6551         }
6552         else if ( _rtw_memcmp( wrqu->data.pointer, "req_cm", 6 ) )
6553         {
6554                 rtw_p2p_get_req_cm( dev, info, wrqu, extra);
6555         }
6556         else if ( _rtw_memcmp( wrqu->data.pointer, "peer_deva", 9 ) )
6557         {
6558                 //      Get the P2P device address when receiving the provision discovery request frame.
6559                 rtw_p2p_get_peer_devaddr( dev, info, wrqu, extra);
6560         }
6561         else if ( _rtw_memcmp( wrqu->data.pointer, "group_id", 8 ) )
6562         {
6563                 rtw_p2p_get_groupid( dev, info, wrqu, extra);
6564         }
6565         else if ( _rtw_memcmp( wrqu->data.pointer, "inv_peer_deva", 13 ) )
6566         {
6567                 //      Get the P2P device address when receiving the P2P Invitation request frame.
6568                 rtw_p2p_get_peer_devaddr_by_invitation( dev, info, wrqu, extra);
6569         }
6570         else if ( _rtw_memcmp( wrqu->data.pointer, "op_ch", 5 ) )
6571         {
6572                 rtw_p2p_get_op_ch( dev, info, wrqu, extra);
6573         }
6574 #ifdef CONFIG_WFD
6575         else if ( _rtw_memcmp( wrqu->data.pointer, "peer_port", 9 ) )
6576         {
6577                 rtw_p2p_get_peer_wfd_port( dev, info, wrqu, extra );
6578         }
6579         else if ( _rtw_memcmp( wrqu->data.pointer, "wfd_sa", 6 ) )
6580         {
6581                 rtw_p2p_get_peer_wfd_session_available( dev, info, wrqu, extra );
6582         }
6583         else if ( _rtw_memcmp( wrqu->data.pointer, "wfd_pc", 6 ) )
6584         {
6585                 rtw_p2p_get_peer_wfd_preferred_connection( dev, info, wrqu, extra );
6586         }
6587 #endif // CONFIG_WFD    
6588         
6589 #endif //CONFIG_P2P
6590
6591         return ret;
6592                 
6593 }
6594
6595 static int rtw_p2p_get2(struct net_device *dev,
6596                                                 struct iw_request_info *info,
6597                                                 union iwreq_data *wrqu, char *extra)
6598 {
6599
6600         int ret = 0;
6601
6602 #ifdef CONFIG_P2P
6603
6604         int length = wrqu->data.length;
6605         char *buffer = (u8 *)rtw_malloc(length);
6606
6607         if (buffer == NULL)
6608         {
6609                 ret = -ENOMEM;
6610                 goto bad;
6611         }
6612
6613         if (copy_from_user(buffer, wrqu->data.pointer, wrqu->data.length))
6614         {
6615                 ret - EFAULT;
6616                 goto bad;
6617         }
6618
6619         DBG_871X("[%s] buffer = %s\n", __FUNCTION__, buffer);
6620
6621         if (_rtw_memcmp(buffer, "wpsCM=", 6))
6622         {
6623                 ret = rtw_p2p_get_wps_configmethod(dev, info, wrqu, extra, &buffer[6]);
6624         } else if (_rtw_memcmp(buffer, "devN=", 5))
6625         {
6626                 ret = rtw_p2p_get_device_name(dev, info, wrqu, extra, &buffer[5]);
6627         } else if (_rtw_memcmp(buffer, "dev_type=", 9))
6628         {
6629                 ret = rtw_p2p_get_device_type(dev, info, wrqu, extra, &buffer[9]);
6630         } else if (_rtw_memcmp(buffer, "go_devadd=", 10))
6631         {
6632                 ret = rtw_p2p_get_go_device_address(dev, info, wrqu, extra, &buffer[10]);
6633         } else if (_rtw_memcmp(buffer, "InvProc=", 8))
6634         {
6635                 ret = rtw_p2p_get_invitation_procedure(dev, info, wrqu, extra, &buffer[8]);
6636         } else
6637         {
6638                 snprintf(extra, sizeof("Command not found."), "Command not found.");
6639                 wrqu->data.length = strlen(extra);
6640         }
6641
6642 bad:
6643         if (buffer)
6644         {
6645                 rtw_mfree(buffer, length);
6646         }
6647
6648 #endif //CONFIG_P2P
6649
6650         return ret;
6651
6652 }
6653
6654 static int rtw_cta_test_start(struct net_device *dev,
6655                                                            struct iw_request_info *info,
6656                                                            union iwreq_data *wrqu, char *extra)
6657 {
6658         int ret = 0;
6659         _adapter        *padapter = (_adapter *)rtw_netdev_priv(dev);
6660         DBG_871X("%s %s\n", __func__, extra);
6661         if (!strcmp(extra, "1"))
6662                 padapter->in_cta_test = 1;
6663         else
6664                 padapter->in_cta_test = 0;
6665
6666         if(padapter->in_cta_test)
6667         {
6668                 u32 v = rtw_read32(padapter, REG_RCR);
6669                 v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN );//| RCR_ADF
6670                 rtw_write32(padapter, REG_RCR, v);
6671                 DBG_871X("enable RCR_ADF\n");
6672         }
6673         else
6674         {
6675                 u32 v = rtw_read32(padapter, REG_RCR);
6676                 v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN ;//| RCR_ADF
6677                 rtw_write32(padapter, REG_RCR, v);
6678                 DBG_871X("disable RCR_ADF\n");
6679         }
6680         return ret;
6681 }
6682
6683
6684 extern int rtw_change_ifname(_adapter *padapter, const char *ifname);
6685 static int rtw_rereg_nd_name(struct net_device *dev,
6686                                struct iw_request_info *info,
6687                                union iwreq_data *wrqu, char *extra)
6688 {
6689         int ret = 0;    
6690         _adapter *padapter = rtw_netdev_priv(dev);
6691         struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;
6692         char new_ifname[IFNAMSIZ];
6693
6694         if(rereg_priv->old_ifname[0] == 0) {
6695                 char *reg_ifname;
6696 #ifdef CONFIG_CONCURRENT_MODE 
6697                 if (padapter->isprimary)
6698                         reg_ifname = padapter->registrypriv.ifname;
6699                 else
6700 #endif
6701                 reg_ifname = padapter->registrypriv.if2name;
6702
6703                 strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);
6704                 rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
6705         }
6706
6707         //DBG_871X("%s wrqu->data.length:%d\n", __FUNCTION__, wrqu->data.length);
6708         if(wrqu->data.length > IFNAMSIZ)
6709                 return -EFAULT;
6710
6711         if ( copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ) ) {
6712                 return -EFAULT;
6713         }
6714
6715         if( 0 == strcmp(rereg_priv->old_ifname, new_ifname) ) {
6716                 return ret;
6717         }
6718
6719         DBG_871X("%s new_ifname:%s\n", __FUNCTION__, new_ifname);
6720         if( 0 != (ret = rtw_change_ifname(padapter, new_ifname)) ) {
6721                 goto exit;
6722         }
6723
6724         if(_rtw_memcmp(rereg_priv->old_ifname, "disable%d", 9) == _TRUE) {
6725                 padapter->ledpriv.bRegUseLed= rereg_priv->old_bRegUseLed;
6726                 rtw_hal_sw_led_init(padapter);
6727                 //rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode);
6728         }
6729
6730         strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
6731         rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
6732         
6733         if(_rtw_memcmp(new_ifname, "disable%d", 9) == _TRUE) {
6734
6735                 DBG_871X("%s disable\n", __FUNCTION__);
6736                 // free network queue for Android's timming issue
6737                 rtw_free_network_queue(padapter, _TRUE);
6738                 
6739                 // close led
6740                 rtw_led_control(padapter, LED_CTL_POWER_OFF);
6741                 rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed;
6742                 padapter->ledpriv.bRegUseLed= _FALSE;
6743                 rtw_hal_sw_led_deinit(padapter);
6744                 
6745                 // the interface is being "disabled", we can do deeper IPS
6746                 //rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv);
6747                 //rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL);
6748         }
6749 exit:
6750         return ret;
6751
6752 }
6753
6754 #ifdef CONFIG_IOL
6755 #include <rtw_iol.h>
6756 #endif
6757 static int rtw_dbg_port(struct net_device *dev,
6758                                struct iw_request_info *info,
6759                                union iwreq_data *wrqu, char *extra)
6760 {       
6761         _irqL irqL;
6762         int ret = 0;
6763         u8 major_cmd, minor_cmd;
6764         u16 arg;
6765         u32 extra_arg, *pdata, val32;
6766         struct sta_info *psta;                                          
6767         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6768         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6769         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
6770         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
6771         struct security_priv *psecuritypriv = &padapter->securitypriv;
6772         struct wlan_network *cur_network = &(pmlmepriv->cur_network);
6773         struct sta_priv *pstapriv = &padapter->stapriv;
6774         
6775
6776         pdata = (u32*)&wrqu->data;      
6777
6778         val32 = *pdata;
6779         arg = (u16)(val32&0x0000ffff);
6780         major_cmd = (u8)(val32>>24);
6781         minor_cmd = (u8)((val32>>16)&0x00ff);
6782
6783         extra_arg = *(pdata+1);
6784         
6785         switch(major_cmd)
6786         {
6787                 case 0x70://read_reg
6788                         switch(minor_cmd)
6789                         {
6790                                 case 1:
6791                                         DBG_871X("rtw_read8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
6792                                         break;
6793                                 case 2:
6794                                         DBG_871X("rtw_read16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
6795                                         break;
6796                                 case 4:
6797                                         DBG_871X("rtw_read32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
6798                                         break;
6799                         }                       
6800                         break;
6801                 case 0x71://write_reg
6802                         switch(minor_cmd)
6803                         {
6804                                 case 1:
6805                                         rtw_write8(padapter, arg, extra_arg);
6806                                         DBG_871X("rtw_write8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
6807                                         break;
6808                                 case 2:
6809                                         rtw_write16(padapter, arg, extra_arg);
6810                                         DBG_871X("rtw_write16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
6811                                         break;
6812                                 case 4:
6813                                         rtw_write32(padapter, arg, extra_arg);
6814                                         DBG_871X("rtw_write32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
6815                                         break;
6816                         }                       
6817                         break;
6818                 case 0x72://read_bb
6819                         DBG_871X("read_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
6820                         break;
6821                 case 0x73://write_bb
6822                         rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);
6823                         DBG_871X("write_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
6824                         break;
6825                 case 0x74://read_rf
6826                         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));       
6827                         break;
6828                 case 0x75://write_rf
6829                         rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
6830                         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));
6831                         break;  
6832
6833                 case 0x76:
6834                         switch(minor_cmd)
6835                         {
6836                                 case 0x00: //normal mode, 
6837                                         padapter->recvpriv.is_signal_dbg = 0;
6838                                         break;
6839                                 case 0x01: //dbg mode
6840                                         padapter->recvpriv.is_signal_dbg = 1;
6841                                         extra_arg = extra_arg>100?100:extra_arg;
6842                                         extra_arg = extra_arg<0?0:extra_arg;
6843                                         padapter->recvpriv.signal_strength_dbg=extra_arg;
6844                                         break;
6845                         }
6846                         break;
6847                 case 0x78: //IOL test
6848                         switch(minor_cmd)
6849                         {
6850                                 #ifdef CONFIG_IOL
6851                                 case 0x04: //LLT table initialization test
6852                                 {
6853                                         u8 page_boundary = 0xf9;
6854                                         {
6855                                                 struct xmit_frame       *xmit_frame;
6856
6857                                                 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6858                                                         ret = -ENOMEM;  
6859                                                         break;
6860                                                 }
6861                                                 
6862                                                 rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary);
6863
6864
6865                                                 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500,0) )
6866                                                         ret = -EPERM;
6867                                         }
6868                                 }
6869                                         break;
6870                                 case 0x05: //blink LED test
6871                                 {
6872                                         u16 reg = 0x4c;
6873                                         u32 blink_num = 50;
6874                                         u32 blink_delay_ms = 200;
6875                                         int i;
6876                                         
6877                                         {
6878                                                 struct xmit_frame       *xmit_frame;
6879
6880                                                 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6881                                                         ret = -ENOMEM;  
6882                                                         break;
6883                                                 }
6884
6885                                                 for(i=0;i<blink_num;i++){
6886                                                         #ifdef CONFIG_IOL_NEW_GENERATION
6887                                                         rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00,0xff);
6888                                                         rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6889                                                         rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08,0xff);
6890                                                         rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6891                                                         #else
6892                                                         rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00);
6893                                                         rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6894                                                         rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08);
6895                                                         rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6896                                                         #endif
6897                                                 }
6898                                                 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms*blink_num*2)+200,0) )
6899                                                         ret = -EPERM;
6900                                         }
6901                                 }
6902                                         break;
6903                                         
6904                                 case 0x06: //continuous wirte byte test
6905                                 {
6906                                         u16 reg = arg;
6907                                         u16 start_value = 0;
6908                                         u32 write_num = extra_arg;
6909                                         int i;
6910                                         u8 final;
6911                                         
6912                                         {
6913                                                 struct xmit_frame       *xmit_frame;
6914
6915                                                 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6916                                                         ret = -ENOMEM;  
6917                                                         break;
6918                                                 }
6919
6920                                                 for(i=0;i<write_num;i++){
6921                                                         #ifdef CONFIG_IOL_NEW_GENERATION
6922                                                         rtw_IOL_append_WB_cmd(xmit_frame, reg, i+start_value,0xFF);
6923                                                         #else
6924                                                         rtw_IOL_append_WB_cmd(xmit_frame, reg, i+start_value);
6925                                                         #endif
6926                                                 }
6927                                                 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
6928                                                         ret = -EPERM;
6929                                         }
6930
6931                                         if(start_value+write_num-1 == (final=rtw_read8(padapter, reg)) ) {
6932                                                 DBG_871X("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6933                                         } else {
6934                                                 DBG_871X("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6935                                         }
6936                                 }
6937                                         break;
6938                                         
6939                                 case 0x07: //continuous wirte word test
6940                                 {
6941                                         u16 reg = arg;
6942                                         u16 start_value = 200;
6943                                         u32 write_num = extra_arg;
6944                                 
6945                                         int i;
6946                                         u16 final;
6947
6948                                         {
6949                                                 struct xmit_frame       *xmit_frame;
6950
6951                                                 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6952                                                         ret = -ENOMEM;  
6953                                                         break;
6954                                                 }
6955
6956                                                 for(i=0;i<write_num;i++){
6957                                                         #ifdef CONFIG_IOL_NEW_GENERATION
6958                                                         rtw_IOL_append_WW_cmd(xmit_frame, reg, i+start_value,0xFFFF);
6959                                                         #else
6960                                                         rtw_IOL_append_WW_cmd(xmit_frame, reg, i+start_value);
6961                                                         #endif
6962                                                 }
6963                                                 if(_SUCCESS !=rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
6964                                                         ret = -EPERM;
6965                                         }
6966
6967                                         if(start_value+write_num-1 == (final=rtw_read16(padapter, reg)) ) {
6968                                                 DBG_871X("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6969                                         } else {
6970                                                 DBG_871X("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6971                                         }
6972                                 }
6973                                         break;
6974                                         
6975                                 case 0x08: //continuous wirte dword test
6976                                 {
6977                                         u16 reg = arg;
6978                                         u32 start_value = 0x110000c7;
6979                                         u32 write_num = extra_arg;
6980                                 
6981                                         int i;
6982                                         u32 final;
6983
6984                                         {
6985                                                 struct xmit_frame       *xmit_frame;
6986
6987                                                 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6988                                                         ret = -ENOMEM;  
6989                                                         break;
6990                                                 }
6991
6992                                                 for(i=0;i<write_num;i++){
6993                                                         #ifdef CONFIG_IOL_NEW_GENERATION
6994                                                         rtw_IOL_append_WD_cmd(xmit_frame, reg, i+start_value,0xFFFFFFFF);
6995                                                         #else
6996                                                         rtw_IOL_append_WD_cmd(xmit_frame, reg, i+start_value);
6997                                                         #endif
6998                                                 }
6999                                                 if(_SUCCESS !=rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
7000                                                         ret = -EPERM;
7001                                                         
7002                                         }
7003
7004                                         if(start_value+write_num-1 == (final=rtw_read32(padapter, reg)) ) {
7005                                                 DBG_871X("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
7006                                         } else {
7007                                                 DBG_871X("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
7008                                         }
7009                                 }
7010                                         break;
7011                                 #endif //CONFIG_IOL
7012                         }
7013                         break;
7014                 case 0x79:
7015                         {
7016                                 /*
7017                                 * dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15
7018                                 * dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15
7019                                 */
7020                                 u8 value =  extra_arg & 0x0f;
7021                                 u8 sign = minor_cmd;
7022                                 u16 write_value = 0;
7023
7024                                 DBG_871X("%s set RESP_TXAGC to %s %u\n", __func__, sign?"minus":"plus", value);
7025
7026                                 if (sign)
7027                                         value = value | 0x10;
7028
7029                                 write_value = value | (value << 5);
7030                                 rtw_write16(padapter, 0x6d9, write_value);
7031                         }
7032                         break;
7033                 case 0x7a:
7034                         receive_disconnect(padapter, pmlmeinfo->network.MacAddress
7035                                 , WLAN_REASON_EXPIRATION_CHK);
7036                         break;
7037                 case 0x7F:
7038                         switch(minor_cmd)
7039                         {
7040                                 case 0x0:
7041                                         DBG_871X("fwstate=0x%x\n", get_fwstate(pmlmepriv));
7042                                         break;
7043                                 case 0x01:
7044                                         DBG_871X("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", 
7045                                                 psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
7046                                                 psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
7047                                         break;
7048                                 case 0x02:
7049                                         DBG_871X("pmlmeinfo->state=0x%x\n", pmlmeinfo->state);
7050                                         DBG_871X("DrvBcnEarly=%d\n", pmlmeext->DrvBcnEarly);
7051                                         DBG_871X("DrvBcnTimeOut=%d\n", pmlmeext->DrvBcnTimeOut);
7052                                         break;
7053                                 case 0x03:
7054                                         DBG_871X("qos_option=%d\n", pmlmepriv->qospriv.qos_option);
7055 #ifdef CONFIG_80211N_HT
7056                                         DBG_871X("ht_option=%d\n", pmlmepriv->htpriv.ht_option);
7057 #endif //CONFIG_80211N_HT
7058                                         break;
7059                                 case 0x04:
7060                                         DBG_871X("cur_ch=%d\n", pmlmeext->cur_channel);
7061                                         DBG_871X("cur_bw=%d\n", pmlmeext->cur_bwmode);
7062                                         DBG_871X("cur_ch_off=%d\n", pmlmeext->cur_ch_offset);
7063
7064                                         DBG_871X("oper_ch=%d\n", rtw_get_oper_ch(padapter));
7065                                         DBG_871X("oper_bw=%d\n", rtw_get_oper_bw(padapter));
7066                                         DBG_871X("oper_ch_offet=%d\n", rtw_get_oper_choffset(padapter));
7067                                 
7068                                         break;
7069                                 case 0x05:
7070                                         psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
7071                                         if(psta)
7072                                         {
7073                                                 int i;
7074                                                 struct recv_reorder_ctrl *preorder_ctrl;
7075                                         
7076                                                 DBG_871X("SSID=%s\n", cur_network->network.Ssid.Ssid);
7077                                                 DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
7078                                                 DBG_871X("cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
7079                                                 DBG_871X("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
7080                                                 DBG_871X("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
7081 #ifdef CONFIG_80211N_HT
7082                                                 DBG_871X("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
7083                                                 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);
7084                                                 DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);     
7085                                                 DBG_871X("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
7086 #endif //CONFIG_80211N_HT
7087                                                 
7088                                                 for(i=0;i<16;i++)
7089                                                 {                                                       
7090                                                         preorder_ctrl = &psta->recvreorder_ctrl[i];
7091                                                         if(preorder_ctrl->enable)
7092                                                         {
7093                                                                 DBG_871X("tid=%d, indicate_seq=%d\n", i, preorder_ctrl->indicate_seq);
7094                                                         }
7095                                                 }       
7096                                                         
7097                                         }
7098                                         else
7099                                         {                                                       
7100                                                 DBG_871X("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));
7101                                         }                                       
7102                                         break;
7103                                 case 0x06:
7104                                         {
7105                                                 u32     ODMFlag;
7106                                                 rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8*)(&ODMFlag));
7107                                                 DBG_871X("(B)DMFlag=0x%x, arg=0x%x\n", ODMFlag, arg);
7108                                                 ODMFlag = (u32)(0x0f&arg);
7109                                                 DBG_871X("(A)DMFlag=0x%x\n", ODMFlag);
7110                                                 rtw_hal_set_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
7111                                         }
7112                                         break;
7113                                 case 0x07:
7114                                         DBG_871X("bSurpriseRemoved=%d, bDriverStopped=%d\n", 
7115                                                 padapter->bSurpriseRemoved, padapter->bDriverStopped);
7116                                         break;
7117                                 case 0x08:
7118                                         {
7119                                                 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7120                                                 struct recv_priv  *precvpriv = &padapter->recvpriv;
7121                                                 
7122                                                 DBG_871X("free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d"
7123                                                         ", free_xmit_extbuf_cnt=%d, free_xframe_ext_cnt=%d"
7124                                                         ", free_recvframe_cnt=%d\n",
7125                                                         pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt,
7126                                                         pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt,
7127                                                         precvpriv->free_recvframe_cnt);
7128                                                 #ifdef CONFIG_USB_HCI
7129                                                 DBG_871X("rx_urb_pending_cn=%d\n", precvpriv->rx_pending_cnt);
7130                                                 #endif
7131                                         }
7132                                         break;  
7133                                 case 0x09:
7134                                         {
7135                                                 int i, j;
7136                                                 _list   *plist, *phead;
7137                                                 struct recv_reorder_ctrl *preorder_ctrl;
7138                                                 
7139 #ifdef CONFIG_AP_MODE
7140                                                 DBG_871X("sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
7141 #endif                                          
7142                                                 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
7143
7144                                                 for(i=0; i< NUM_STA; i++)
7145                                                 {
7146                                                         phead = &(pstapriv->sta_hash[i]);
7147                                                         plist = get_next(phead);
7148                 
7149                                                         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
7150                                                         {
7151                                                                 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
7152
7153                                                                 plist = get_next(plist);
7154
7155                                                                 if(extra_arg == psta->aid)
7156                                                                 {
7157                                                                         DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
7158                                                                         DBG_871X("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
7159                                                                         DBG_871X("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
7160 #ifdef CONFIG_80211N_HT
7161                                                                         DBG_871X("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);     
7162                                                                         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);
7163                                                                         DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);                                                                     
7164                                                                         DBG_871X("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
7165 #endif //CONFIG_80211N_HT
7166                                                                         
7167 #ifdef CONFIG_AP_MODE
7168                                                                         DBG_871X("capability=0x%x\n", psta->capability);
7169                                                                         DBG_871X("flags=0x%x\n", psta->flags);
7170                                                                         DBG_871X("wpa_psk=0x%x\n", psta->wpa_psk);
7171                                                                         DBG_871X("wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher);
7172                                                                         DBG_871X("wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher);
7173                                                                         DBG_871X("qos_info=0x%x\n", psta->qos_info);
7174 #endif
7175                                                                         DBG_871X("dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy);
7176                                                                         
7177                                                                         
7178                                                 
7179                                                                         for(j=0;j<16;j++)
7180                                                                         {                                                       
7181                                                                                 preorder_ctrl = &psta->recvreorder_ctrl[j];
7182                                                                                 if(preorder_ctrl->enable)
7183                                                                                 {
7184                                                                                         DBG_871X("tid=%d, indicate_seq=%d\n", j, preorder_ctrl->indicate_seq);
7185                                                                                 }
7186                                                                         }               
7187                                                                         
7188                                                                 }                                                       
7189                         
7190                                                         }
7191                                                 }
7192         
7193                                                 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
7194
7195                                         }
7196                                         break;
7197                                 case 0x0a:
7198                                         {
7199                                                 int max_mac_id = 0;
7200                                                 max_mac_id = rtw_search_max_mac_id( padapter);
7201                                                 printk("%s ==> max_mac_id = %d \n",__FUNCTION__,max_mac_id);
7202                                         }       
7203                                         break;
7204                                 case 0x0c://dump rx/tx packet
7205                                         {
7206                                                 if(arg == 0){
7207                                                         DBG_871X("dump rx packet (%d)\n",extra_arg);                                            
7208                                                         //pHalData->bDumpRxPkt =extra_arg;                                              
7209                                                         rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
7210                                                 }
7211                                                 else if(arg==1){
7212                                                         DBG_871X("dump tx packet (%d)\n",extra_arg);                                            
7213                                                         rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
7214                                                 }
7215                                         }
7216                                         break;
7217 #if 0                           
7218                                 case 0x0d://dump cam
7219                                         {
7220                                                 //u8 entry = (u8) extra_arg;
7221                                                 u8 entry=0;
7222                                                 //dump cam
7223                                                 for(entry=0;entry<32;entry++)
7224                                                         read_cam(padapter,entry);
7225                                         }                               
7226                                         break;
7227 #endif
7228                 #ifdef DBG_CONFIG_ERROR_DETECT
7229                                 case 0x0f:
7230                                                 {
7231                                                         if(extra_arg == 0){     
7232                                                                 DBG_871X("###### silent reset test.......#####\n");
7233                                                                 rtw_hal_sreset_reset(padapter);                                         
7234                                                         } else {
7235                                                                 HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
7236                                                                 struct sreset_priv *psrtpriv = &pHalData->srestpriv;
7237                                                                 psrtpriv->dbg_trigger_point = extra_arg;
7238                                                         }
7239                                                         
7240                                                 }
7241                                         break;
7242                                 case 0x15:
7243                                         {
7244                                                 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
7245                                                 DBG_871X("==>silent resete cnts:%d\n",pwrpriv->ips_enter_cnts);
7246                                         }
7247                                         break;  
7248                                         
7249                 #endif  
7250
7251                                 case 0x10:// driver version display
7252                                         dump_drv_version(RTW_DBGDUMP);
7253                                         break;
7254                                 case 0x11://dump linked status
7255                                         {
7256                                                  linked_info_dump(padapter,extra_arg);
7257                                         }                                       
7258                                         break;
7259 #ifdef CONFIG_80211N_HT
7260                                 case 0x12: //set rx_stbc
7261                                 {
7262                                         struct registry_priv    *pregpriv = &padapter->registrypriv;
7263                                         // 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g
7264                                         //default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ
7265                                         if( pregpriv && (extra_arg == 0 || extra_arg == 1|| extra_arg == 2 || extra_arg == 3))
7266                                         {
7267                                                 pregpriv->rx_stbc= extra_arg;
7268                                                 DBG_871X("set rx_stbc=%d\n",pregpriv->rx_stbc);
7269                                         }
7270                                         else
7271                                                 DBG_871X("get rx_stbc=%d\n",pregpriv->rx_stbc);
7272                                         
7273                                 }
7274                                 break;
7275                                 case 0x13: //set ampdu_enable
7276                                 {
7277                                         struct registry_priv    *pregpriv = &padapter->registrypriv;
7278                                         // 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec)
7279                                         if( pregpriv && extra_arg < 3 )
7280                                         {
7281                                                 pregpriv->ampdu_enable= extra_arg;
7282                                                 DBG_871X("set ampdu_enable=%d\n",pregpriv->ampdu_enable);
7283                                         }
7284                                         else
7285                                                 DBG_871X("get ampdu_enable=%d\n",pregpriv->ampdu_enable);
7286                                         
7287                                 }
7288                                 break;
7289 #endif
7290                                 case 0x14: //get wifi_spec
7291                                 {
7292                                         struct registry_priv    *pregpriv = &padapter->registrypriv;
7293                                         DBG_871X("get wifi_spec=%d\n",pregpriv->wifi_spec);
7294                                         
7295                                 }
7296                                 break;
7297                                 case 0x16:
7298                                 {
7299                                         if(arg == 0xff){
7300                                                 rtw_odm_dbg_comp_msg(RTW_DBGDUMP,padapter);
7301                                         }
7302                                         else{
7303                                                 u64 dbg_comp = (u64)extra_arg;
7304                                                 rtw_odm_dbg_comp_set(padapter, dbg_comp);
7305                                         }
7306                                 }
7307                                         break;
7308 #ifdef DBG_FIXED_CHAN
7309                                 case 0x17:
7310                                         {
7311                                                 struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);                                           
7312                                                 printk("===>  Fixed channel to %d \n",extra_arg);
7313                                                 pmlmeext->fixed_chan = extra_arg;       
7314                                                 
7315                                         }
7316                                         break;
7317 #endif
7318                                 case 0x18:
7319                                         {
7320                                                 printk("===>  Switch USB Mode %d \n",extra_arg);
7321                                                 rtw_hal_set_hwreg(padapter, HW_VAR_USB_MODE, (u8 *)&extra_arg);
7322                                         }
7323                                         break;
7324                                 case 0x23:
7325                                         {
7326                                                 DBG_871X("turn %s the bNotifyChannelChange Variable\n",(extra_arg==1)?"on":"off");
7327                                                 padapter->bNotifyChannelChange = extra_arg;
7328                                                 break;
7329                                         }
7330                                 case 0x24:
7331                                         {
7332 #ifdef CONFIG_P2P
7333                                                 DBG_871X("turn %s the bShowGetP2PState Variable\n",(extra_arg==1)?"on":"off");
7334                                                 padapter->bShowGetP2PState = extra_arg;
7335 #endif // CONFIG_P2P
7336                                                 break;                                          
7337                                         }
7338                                 case 0xaa:
7339                                         {
7340                                                 if((extra_arg & 0x7F)> 0x3F) extra_arg = 0xFF;
7341                                                 DBG_871X("chang data rate to :0x%02x\n",extra_arg);
7342                                                 padapter->fix_rate = extra_arg;
7343                                         }
7344                                         break;  
7345                                 case 0xdd://registers dump , 0 for mac reg,1 for bb reg, 2 for rf reg
7346                                         {
7347                                                 if(extra_arg==0){
7348                                                         mac_reg_dump(RTW_DBGDUMP, padapter);
7349                                                 }
7350                                                 else if(extra_arg==1){
7351                                                         bb_reg_dump(RTW_DBGDUMP, padapter);
7352                                                 }
7353                                                 else if(extra_arg==2){
7354                                                         rf_reg_dump(RTW_DBGDUMP, padapter);
7355                                                 }
7356                                         }
7357                                         break;          
7358
7359                                 case 0xee://turn on/off dynamic funcs
7360                                         {
7361                                                 u32 odm_flag;
7362
7363                                                 if(0xf==extra_arg){
7364                                                         rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&odm_flag);                                                   
7365                                                         DBG_871X(" === DMFlag(0x%08x) === \n",odm_flag);
7366                                                         DBG_871X("extra_arg = 0  - disable all dynamic func \n");
7367                                                         DBG_871X("extra_arg = 1  - disable DIG- BIT(0)\n");
7368                                                         DBG_871X("extra_arg = 2  - disable High power - BIT(1)\n");
7369                                                         DBG_871X("extra_arg = 3  - disable tx power tracking - BIT(2)\n");
7370                                                         DBG_871X("extra_arg = 4  - disable BT coexistence - BIT(3)\n");
7371                                                         DBG_871X("extra_arg = 5  - disable antenna diversity - BIT(4)\n");
7372                                                         DBG_871X("extra_arg = 6  - enable all dynamic func \n");                                                        
7373                                                 }
7374                                                 else{
7375                                                         /*      extra_arg = 0  - disable all dynamic func
7376                                                                 extra_arg = 1  - disable DIG
7377                                                                 extra_arg = 2  - disable tx power tracking
7378                                                                 extra_arg = 3  - turn on all dynamic func
7379                                                         */                      
7380                                                         rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &(extra_arg));
7381                                                         rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&odm_flag);                                                   
7382                                                         DBG_871X(" === DMFlag(0x%08x) === \n",odm_flag);
7383                                                 }
7384                                         }
7385                                         break;
7386
7387                                 case 0xfd:
7388                                         rtw_write8(padapter, 0xc50, arg);
7389                                         DBG_871X("wr(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
7390                                         rtw_write8(padapter, 0xc58, arg);
7391                                         DBG_871X("wr(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
7392                                         break;
7393                                 case 0xfe:
7394                                         DBG_871X("rd(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
7395                                         DBG_871X("rd(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
7396                                         break;
7397                                 case 0xff:
7398                                         {
7399                                                 DBG_871X("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
7400                                                 DBG_871X("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
7401                                                 DBG_871X("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
7402                                                 DBG_871X("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
7403                                                 DBG_871X("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
7404         
7405                                                 DBG_871X("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
7406
7407
7408                                                 DBG_871X("\n");
7409                 
7410                                                 DBG_871X("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
7411                                                 DBG_871X("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
7412
7413                                                 DBG_871X("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
7414         
7415                                                 DBG_871X("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
7416         
7417                                                 DBG_871X("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
7418                                                 DBG_871X("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
7419         
7420                                                 DBG_871X("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
7421                                                 DBG_871X("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
7422                                                 DBG_871X("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
7423                                                 DBG_871X("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
7424                                         }
7425                                         break;
7426                         }                       
7427                         break;
7428                 default:
7429                         DBG_871X("error dbg cmd!\n");
7430                         break;  
7431         }
7432         
7433
7434         return ret;
7435
7436 }
7437
7438 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
7439 {
7440         uint ret=0;
7441         u32 flags;
7442         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7443         
7444         switch (name){
7445         case IEEE_PARAM_WPA_ENABLED:
7446
7447                 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; //802.1x
7448                 
7449                 //ret = ieee80211_wpa_enable(ieee, value);
7450                 
7451                 switch((value)&0xff)
7452                 {
7453                         case 1 : //WPA
7454                         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; //WPA_PSK
7455                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
7456                                 break;
7457                         case 2: //WPA2
7458                         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; //WPA2_PSK
7459                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
7460                                 break;
7461                 }
7462                 
7463                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("wpa_set_param:padapter->securitypriv.ndisauthtype=%d\n", padapter->securitypriv.ndisauthtype));
7464                 
7465                 break;
7466
7467         case IEEE_PARAM_TKIP_COUNTERMEASURES:
7468                 //ieee->tkip_countermeasures=value;
7469                 break;
7470
7471         case IEEE_PARAM_DROP_UNENCRYPTED: 
7472         {
7473                 /* HACK:
7474                  *
7475                  * wpa_supplicant calls set_wpa_enabled when the driver
7476                  * is loaded and unloaded, regardless of if WPA is being
7477                  * used.  No other calls are made which can be used to
7478                  * determine if encryption will be used or not prior to
7479                  * association being expected.  If encryption is not being
7480                  * used, drop_unencrypted is set to false, else true -- we
7481                  * can use this to determine if the CAP_PRIVACY_ON bit should
7482                  * be set.
7483                  */
7484                  
7485 #if 0    
7486                 struct ieee80211_security sec = {
7487                         .flags = SEC_ENABLED,
7488                         .enabled = value,
7489                 };
7490                 ieee->drop_unencrypted = value;
7491                 /* We only change SEC_LEVEL for open mode. Others
7492                  * are set by ipw_wpa_set_encryption.
7493                  */
7494                 if (!value) {
7495                         sec.flags |= SEC_LEVEL;
7496                         sec.level = SEC_LEVEL_0;
7497                 }
7498                 else {
7499                         sec.flags |= SEC_LEVEL;
7500                         sec.level = SEC_LEVEL_1;
7501                 }
7502                 if (ieee->set_security)
7503                         ieee->set_security(ieee->dev, &sec);
7504 #endif          
7505                 break;
7506
7507         }
7508         case IEEE_PARAM_PRIVACY_INVOKED:        
7509                 
7510                 //ieee->privacy_invoked=value;
7511                 
7512                 break;
7513
7514         case IEEE_PARAM_AUTH_ALGS:
7515                 
7516                 ret = wpa_set_auth_algs(dev, value);
7517                 
7518                 break;
7519
7520         case IEEE_PARAM_IEEE_802_1X:
7521                 
7522                 //ieee->ieee802_1x=value;               
7523                 
7524                 break;
7525                 
7526         case IEEE_PARAM_WPAX_SELECT:
7527                 
7528                 // added for WPA2 mixed mode
7529                 //DBG_871X(KERN_WARNING "------------------------>wpax value = %x\n", value);
7530                 /*
7531                 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
7532                 ieee->wpax_type_set = 1;
7533                 ieee->wpax_type_notify = value;
7534                 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
7535                 */
7536                 
7537                 break;
7538
7539         default:                
7540
7541
7542                 
7543                 ret = -EOPNOTSUPP;
7544
7545                 
7546                 break;
7547         
7548         }
7549
7550         return ret;
7551         
7552 }
7553
7554 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
7555 {       
7556         int ret = 0;
7557         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7558
7559         switch (command)
7560         {
7561                 case IEEE_MLME_STA_DEAUTH:
7562
7563                         if(!rtw_set_802_11_disassociate(padapter))
7564                                 ret = -1;               
7565                         
7566                         break;
7567
7568                 case IEEE_MLME_STA_DISASSOC:
7569                 
7570                         if(!rtw_set_802_11_disassociate(padapter))
7571                                 ret = -1;               
7572         
7573                         break;
7574
7575                 default:
7576                         ret = -EOPNOTSUPP;
7577                         break;
7578         }
7579
7580         return ret;
7581         
7582 }
7583
7584 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
7585 {
7586         struct ieee_param *param;
7587         uint ret=0;
7588
7589         //down(&ieee->wx_sem);  
7590
7591         if (p->length < sizeof(struct ieee_param) || !p->pointer){
7592                 ret = -EINVAL;
7593                 goto out;
7594         }
7595         
7596         param = (struct ieee_param *)rtw_malloc(p->length);
7597         if (param == NULL)
7598         {
7599                 ret = -ENOMEM;
7600                 goto out;
7601         }
7602         
7603         if (copy_from_user(param, p->pointer, p->length))
7604         {
7605                 rtw_mfree((u8*)param, p->length);
7606                 ret = -EFAULT;
7607                 goto out;
7608         }
7609
7610         switch (param->cmd) {
7611
7612         case IEEE_CMD_SET_WPA_PARAM:
7613                 ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
7614                 break;
7615
7616         case IEEE_CMD_SET_WPA_IE:
7617                 //ret = wpa_set_wpa_ie(dev, param, p->length);
7618                 ret =  rtw_set_wpa_ie((_adapter *)rtw_netdev_priv(dev), (char*)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
7619                 break;
7620
7621         case IEEE_CMD_SET_ENCRYPTION:
7622                 ret = wpa_set_encryption(dev, param, p->length);
7623                 break;
7624
7625         case IEEE_CMD_MLME:
7626                 ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
7627                 break;
7628
7629         default:
7630                 DBG_871X("Unknown WPA supplicant request: %d\n", param->cmd);
7631                 ret = -EOPNOTSUPP;
7632                 break;
7633                 
7634         }
7635
7636         if (ret == 0 && copy_to_user(p->pointer, param, p->length))
7637                 ret = -EFAULT;
7638
7639         rtw_mfree((u8 *)param, p->length);
7640         
7641 out:
7642         
7643         //up(&ieee->wx_sem);
7644         
7645         return ret;
7646         
7647 }
7648
7649 #ifdef CONFIG_AP_MODE
7650 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
7651 {
7652         int ret = 0;
7653         u32 wep_key_idx, wep_key_len,wep_total_len;
7654         NDIS_802_11_WEP  *pwep = NULL;
7655         struct sta_info *psta = NULL, *pbcmc_sta = NULL;        
7656         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7657         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
7658         struct security_priv* psecuritypriv=&(padapter->securitypriv);
7659         struct sta_priv *pstapriv = &padapter->stapriv;
7660
7661         DBG_871X("%s\n", __FUNCTION__);
7662
7663         param->u.crypt.err = 0;
7664         param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
7665
7666         //sizeof(struct ieee_param) = 64 bytes;
7667         //if (param_len !=  (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
7668         if (param_len !=  sizeof(struct ieee_param) + param->u.crypt.key_len)
7669         {
7670                 ret =  -EINVAL;
7671                 goto exit;
7672         }
7673
7674         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7675             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7676             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
7677         {
7678                 if (param->u.crypt.idx >= WEP_KEYS)
7679                 {
7680                         ret = -EINVAL;
7681                         goto exit;
7682                 }       
7683         }
7684         else 
7685         {               
7686                 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7687                 if(!psta)
7688                 {
7689                         //ret = -EINVAL;
7690                         DBG_871X("rtw_set_encryption(), sta has already been removed or never been added\n");
7691                         goto exit;
7692                 }                       
7693         }
7694
7695         if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
7696         {
7697                 //todo:clear default encryption keys
7698
7699                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
7700                 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
7701                 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
7702                 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
7703
7704                 DBG_871X("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
7705                 
7706                 goto exit;
7707         }
7708
7709
7710         if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
7711         {               
7712                 DBG_871X("r871x_set_encryption, crypt.alg = WEP\n");
7713                 
7714                 wep_key_idx = param->u.crypt.idx;
7715                 wep_key_len = param->u.crypt.key_len;
7716                                         
7717                 DBG_871X("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
7718
7719                 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
7720                 {
7721                         ret = -EINVAL;
7722                         goto exit;
7723                 }
7724                         
7725
7726                 if (wep_key_len > 0) 
7727                 {                       
7728                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
7729                         wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
7730                         pwep =(NDIS_802_11_WEP *)rtw_malloc(wep_total_len);
7731                         if(pwep == NULL){
7732                                 DBG_871X(" r871x_set_encryption: pwep allocate fail !!!\n");
7733                                 goto exit;
7734                         }
7735                         
7736                         _rtw_memset(pwep, 0, wep_total_len);
7737                 
7738                         pwep->KeyLength = wep_key_len;
7739                         pwep->Length = wep_total_len;
7740                         
7741                 }
7742                 
7743                 pwep->KeyIndex = wep_key_idx;
7744
7745                 _rtw_memcpy(pwep->KeyMaterial,  param->u.crypt.key, pwep->KeyLength);
7746
7747                 if(param->u.crypt.set_tx)
7748                 {
7749                         DBG_871X("wep, set_tx=1\n");
7750
7751                         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
7752                         psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
7753                         psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
7754                         psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
7755                         
7756                         if(pwep->KeyLength==13)
7757                         {
7758                                 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
7759                                 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
7760                         }
7761
7762                 
7763                         psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
7764                         
7765                         _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
7766
7767                         psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength;
7768
7769                         rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1);
7770                 }
7771                 else
7772                 {
7773                         DBG_871X("wep, set_tx=0\n");
7774                         
7775                         //don't update "psecuritypriv->dot11PrivacyAlgrthm" and 
7776                         //"psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to cam
7777                                         
7778                       _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
7779
7780                         psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;                   
7781
7782                         rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0);
7783                 }
7784
7785                 goto exit;
7786                 
7787         }
7788
7789         
7790         if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
7791         {
7792                 if(param->u.crypt.set_tx ==1)
7793                 {
7794                         if(strcmp(param->u.crypt.alg, "WEP") == 0)
7795                         {
7796                                 DBG_871X("%s, set group_key, WEP\n", __FUNCTION__);
7797                                 
7798                                 _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));
7799                                         
7800                                 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
7801                                 if(param->u.crypt.key_len==13)
7802                                 {                                               
7803                                                 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
7804                                 }
7805                                 
7806                         }
7807                         else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
7808                         {                                               
7809                                 DBG_871X("%s, set group_key, TKIP\n", __FUNCTION__);
7810                                 
7811                                 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
7812
7813                                 _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));
7814                                 
7815                                 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
7816                                 //set mic key
7817                                 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
7818                                 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
7819
7820                                 psecuritypriv->busetkipkey = _TRUE;
7821                                                                                         
7822                         }
7823                         else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
7824                         {
7825                                 DBG_871X("%s, set group_key, CCMP\n", __FUNCTION__);
7826                         
7827                                 psecuritypriv->dot118021XGrpPrivacy = _AES_;
7828
7829                                 _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));
7830                         }
7831                         else
7832                         {
7833                                 DBG_871X("%s, set group_key, none\n", __FUNCTION__);
7834                                 
7835                                 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
7836                         }
7837
7838                         psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
7839
7840                         psecuritypriv->binstallGrpkey = _TRUE;
7841
7842                         psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
7843                                                                 
7844                         rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
7845                         
7846                         pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
7847                         if(pbcmc_sta)
7848                         {
7849                                 pbcmc_sta->ieee8021x_blocked = _FALSE;
7850                                 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy                     
7851                         }       
7852                                                 
7853                 }
7854
7855                 goto exit;
7856                 
7857         }       
7858
7859         if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
7860         {
7861                 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
7862                 {
7863                         if(param->u.crypt.set_tx ==1)
7864                         { 
7865                                 _rtw_memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
7866                                 
7867                                 if(strcmp(param->u.crypt.alg, "WEP") == 0)
7868                                 {
7869                                         DBG_871X("%s, set pairwise key, WEP\n", __FUNCTION__);
7870                                         
7871                                         psta->dot118021XPrivacy = _WEP40_;
7872                                         if(param->u.crypt.key_len==13)
7873                                         {                                               
7874                                                 psta->dot118021XPrivacy = _WEP104_;
7875                                         }
7876                                 }
7877                                 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
7878                                 {                                               
7879                                         DBG_871X("%s, set pairwise key, TKIP\n", __FUNCTION__);
7880                                         
7881                                         psta->dot118021XPrivacy = _TKIP_;
7882                                 
7883                                         //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
7884                                         //set mic key
7885                                         _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
7886                                         _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
7887
7888                                         psecuritypriv->busetkipkey = _TRUE;
7889                                                                                         
7890                                 }
7891                                 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
7892                                 {
7893
7894                                         DBG_871X("%s, set pairwise key, CCMP\n", __FUNCTION__);
7895                                         
7896                                         psta->dot118021XPrivacy = _AES_;
7897                                 }
7898                                 else
7899                                 {
7900                                         DBG_871X("%s, set pairwise key, none\n", __FUNCTION__);
7901                                         
7902                                         psta->dot118021XPrivacy = _NO_PRIVACY_;
7903                                 }
7904                                                 
7905                                 rtw_ap_set_pairwise_key(padapter, psta);
7906                                         
7907                                 psta->ieee8021x_blocked = _FALSE;
7908                                         
7909                         }                       
7910                         else//group key???
7911                         { 
7912                                 if(strcmp(param->u.crypt.alg, "WEP") == 0)
7913                                 {
7914                                         _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));
7915                                         
7916                                         psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
7917                                         if(param->u.crypt.key_len==13)
7918                                         {                                               
7919                                                 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
7920                                         }
7921                                 }
7922                                 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
7923                                 {                                               
7924                                         psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
7925
7926                                         _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));
7927                                 
7928                                         //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
7929                                         //set mic key
7930                                         _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
7931                                         _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
7932
7933                                         psecuritypriv->busetkipkey = _TRUE;
7934                                                                                         
7935                                 }
7936                                 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
7937                                 {
7938                                         psecuritypriv->dot118021XGrpPrivacy = _AES_;
7939
7940                                         _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));
7941                                 }
7942                                 else
7943                                 {
7944                                         psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
7945                                 }
7946
7947                                 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
7948
7949                                 psecuritypriv->binstallGrpkey = _TRUE;  
7950                                                                 
7951                                 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
7952                                                                 
7953                                 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
7954                         
7955                                 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
7956                                 if(pbcmc_sta)
7957                                 {
7958                                         pbcmc_sta->ieee8021x_blocked = _FALSE;
7959                                         pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy                     
7960                                 }                                       
7961
7962                         }
7963                         
7964                 }
7965                                 
7966         }
7967
7968 exit:
7969
7970         if(pwep)
7971         {
7972                 rtw_mfree((u8 *)pwep, wep_total_len);           
7973         }       
7974         
7975         return ret;
7976         
7977 }
7978
7979 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
7980 {
7981         int ret=0;      
7982         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7983         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7984         struct sta_priv *pstapriv = &padapter->stapriv;
7985         unsigned char *pbuf = param->u.bcn_ie.buf;
7986
7987
7988         DBG_871X("%s, len=%d\n", __FUNCTION__, len);
7989
7990         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7991                 return -EINVAL;
7992
7993         _rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
7994
7995         if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
7996                 pstapriv->max_num_sta = NUM_STA;
7997
7998
7999         if(rtw_check_beacon_data(padapter, pbuf,  (len-12-2)) == _SUCCESS)// 12 = param header, 2:no packed
8000                 ret = 0;
8001         else
8002                 ret = -EINVAL;
8003         
8004
8005         return ret;
8006         
8007 }
8008
8009 static int rtw_hostapd_sta_flush(struct net_device *dev)
8010 {
8011         //_irqL irqL;
8012         //_list *phead, *plist;
8013         int ret=0;      
8014         //struct sta_info *psta = NULL;
8015         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
8016         //struct sta_priv *pstapriv = &padapter->stapriv;
8017
8018         DBG_871X("%s\n", __FUNCTION__);
8019
8020         flush_all_cam_entry(padapter);  //clear CAM
8021
8022         ret = rtw_sta_flush(padapter);  
8023
8024         return ret;
8025
8026 }
8027
8028 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
8029 {
8030         _irqL irqL;
8031         int ret=0;      
8032         struct sta_info *psta = NULL;
8033         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8034         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8035         struct sta_priv *pstapriv = &padapter->stapriv;
8036
8037         DBG_871X("rtw_add_sta(aid=%d)=" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr));
8038         
8039         if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)       
8040         {
8041                 return -EINVAL;         
8042         }
8043
8044         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8045             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8046             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
8047         {
8048                 return -EINVAL; 
8049         }
8050
8051 /*
8052         psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8053         if(psta)
8054         {
8055                 DBG_871X("rtw_add_sta(), free has been added psta=%p\n", psta);
8056                 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
8057                 rtw_free_stainfo(padapter,  psta);              
8058                 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
8059
8060                 psta = NULL;
8061         }       
8062 */
8063         //psta = rtw_alloc_stainfo(pstapriv, param->sta_addr);
8064         psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8065         if(psta)
8066         {
8067                 int flags = param->u.add_sta.flags;                     
8068                 
8069                 //DBG_871X("rtw_add_sta(), init sta's variables, psta=%p\n", psta);
8070                 
8071                 psta->aid = param->u.add_sta.aid;//aid=1~2007
8072
8073                 _rtw_memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
8074                 
8075                 
8076                 //check wmm cap.
8077                 if(WLAN_STA_WME&flags)
8078                         psta->qos_option = 1;
8079                 else
8080                         psta->qos_option = 0;
8081
8082                 if(pmlmepriv->qospriv.qos_option == 0)  
8083                         psta->qos_option = 0;
8084
8085                 
8086 #ifdef CONFIG_80211N_HT         
8087                 //chec 802.11n ht cap.
8088                 if(WLAN_STA_HT&flags)
8089                 {
8090                         psta->htpriv.ht_option = _TRUE;
8091                         psta->qos_option = 1;
8092                         _rtw_memcpy((void*)&psta->htpriv.ht_cap, (void*)&param->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
8093                 }
8094                 else            
8095                 {
8096                         psta->htpriv.ht_option = _FALSE;
8097                 }
8098                 
8099                 if(pmlmepriv->htpriv.ht_option == _FALSE)       
8100                         psta->htpriv.ht_option = _FALSE;
8101 #endif          
8102
8103
8104                 update_sta_info_apmode(padapter, psta);
8105                 
8106                 
8107         }
8108         else
8109         {
8110                 ret = -ENOMEM;
8111         }       
8112         
8113         return ret;
8114         
8115 }
8116
8117 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
8118 {
8119         _irqL irqL;
8120         int ret=0;      
8121         struct sta_info *psta = NULL;
8122         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8123         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8124         struct sta_priv *pstapriv = &padapter->stapriv;
8125
8126         DBG_871X("rtw_del_sta=" MAC_FMT "\n", MAC_ARG(param->sta_addr));
8127                 
8128         if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)               
8129         {
8130                 return -EINVAL;         
8131         }
8132
8133         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8134             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8135             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
8136         {
8137                 return -EINVAL; 
8138         }
8139
8140         psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8141         if(psta)
8142         {
8143                 u8 updated=_FALSE;
8144         
8145                 //DBG_871X("free psta=%p, aid=%d\n", psta, psta->aid);
8146
8147                 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
8148                 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
8149                 {                       
8150                         rtw_list_delete(&psta->asoc_list);
8151                         pstapriv->asoc_list_cnt--;
8152                         updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
8153
8154                 }
8155                 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
8156                 
8157                 associated_clients_update(padapter, updated);
8158         
8159                 psta = NULL;
8160                 
8161         }
8162         else
8163         {
8164                 DBG_871X("rtw_del_sta(), sta has already been removed or never been added\n");
8165                 
8166                 //ret = -1;
8167         }
8168         
8169         
8170         return ret;
8171         
8172 }
8173
8174 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
8175 {
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         struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
8182         struct sta_data *psta_data = (struct sta_data *)param_ex->data;
8183
8184         DBG_871X("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr));
8185
8186         if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)               
8187         {
8188                 return -EINVAL;         
8189         }
8190
8191         if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
8192             param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
8193             param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) 
8194         {
8195                 return -EINVAL; 
8196         }
8197
8198         psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
8199         if(psta)
8200         {
8201 #if 0
8202                 struct {
8203                         u16 aid;
8204                         u16 capability;
8205                         int flags;
8206                         u32 sta_set;
8207                         u8 tx_supp_rates[16];   
8208                         u32 tx_supp_rates_len;
8209                         struct rtw_ieee80211_ht_cap ht_cap;
8210                         u64     rx_pkts;
8211                         u64     rx_bytes;
8212                         u64     rx_drops;
8213                         u64     tx_pkts;
8214                         u64     tx_bytes;
8215                         u64     tx_drops;
8216                 } get_sta;              
8217 #endif
8218                 psta_data->aid = (u16)psta->aid;
8219                 psta_data->capability = psta->capability;
8220                 psta_data->flags = psta->flags;
8221
8222 /*
8223                 nonerp_set : BIT(0)
8224                 no_short_slot_time_set : BIT(1)
8225                 no_short_preamble_set : BIT(2)
8226                 no_ht_gf_set : BIT(3)
8227                 no_ht_set : BIT(4)
8228                 ht_20mhz_set : BIT(5)
8229 */
8230
8231                 psta_data->sta_set =((psta->nonerp_set) |
8232                                                         (psta->no_short_slot_time_set <<1) |
8233                                                         (psta->no_short_preamble_set <<2) |
8234                                                         (psta->no_ht_gf_set <<3) |
8235                                                         (psta->no_ht_set <<4) |
8236                                                         (psta->ht_20mhz_set <<5));
8237
8238                 psta_data->tx_supp_rates_len =  psta->bssratelen;
8239                 _rtw_memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
8240 #ifdef CONFIG_80211N_HT
8241                 _rtw_memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
8242 #endif //CONFIG_80211N_HT
8243                 psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
8244                 psta_data->rx_bytes = psta->sta_stats.rx_bytes;
8245                 psta_data->rx_drops = psta->sta_stats.rx_drops;
8246
8247                 psta_data->tx_pkts = psta->sta_stats.tx_pkts;
8248                 psta_data->tx_bytes = psta->sta_stats.tx_bytes;
8249                 psta_data->tx_drops = psta->sta_stats.tx_drops;
8250                 
8251
8252         }
8253         else
8254         {
8255                 ret = -1;
8256         }
8257
8258         return ret;
8259
8260 }
8261
8262 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
8263 {
8264         int ret=0;      
8265         struct sta_info *psta = NULL;
8266         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8267         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8268         struct sta_priv *pstapriv = &padapter->stapriv;
8269
8270         DBG_871X("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr));
8271
8272         if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)               
8273         {
8274                 return -EINVAL;         
8275         }
8276
8277         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8278             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8279             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
8280         {
8281                 return -EINVAL; 
8282         }
8283
8284         psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8285         if(psta)
8286         {
8287                 if((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC))
8288                 {
8289                         int wpa_ie_len;
8290                         int copy_len;
8291
8292                         wpa_ie_len = psta->wpa_ie[1];
8293                         
8294                         copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)):(wpa_ie_len+2);
8295                                 
8296                         param->u.wpa_ie.len = copy_len;
8297
8298                         _rtw_memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
8299                 }
8300                 else
8301                 {
8302                         //ret = -1;
8303                         DBG_871X("sta's wpa_ie is NONE\n");
8304                 }               
8305         }
8306         else
8307         {
8308                 ret = -1;
8309         }
8310
8311         return ret;
8312
8313 }
8314
8315 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
8316 {
8317         int ret=0;
8318         unsigned char wps_oui[4]={0x0,0x50,0xf2,0x04};
8319         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
8320         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8321         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
8322         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
8323         int ie_len;
8324
8325         DBG_871X("%s, len=%d\n", __FUNCTION__, len);
8326
8327         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8328                 return -EINVAL;
8329
8330         ie_len = len-12-2;// 12 = param header, 2:no packed
8331
8332
8333         if(pmlmepriv->wps_beacon_ie)
8334         {
8335                 rtw_mfree(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
8336                 pmlmepriv->wps_beacon_ie = NULL;                        
8337         }       
8338
8339         if(ie_len>0)
8340         {
8341                 pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
8342                 pmlmepriv->wps_beacon_ie_len = ie_len;
8343                 if ( pmlmepriv->wps_beacon_ie == NULL) {
8344                         DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8345                         return -EINVAL;
8346                 }
8347
8348                 _rtw_memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
8349
8350                 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
8351                 
8352                 pmlmeext->bstart_bss = _TRUE;
8353                 
8354         }
8355         
8356         
8357         return ret;             
8358
8359 }
8360
8361 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
8362 {
8363         int ret=0;
8364         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
8365         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8366         int ie_len;
8367
8368         DBG_871X("%s, len=%d\n", __FUNCTION__, len);
8369
8370         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8371                 return -EINVAL;
8372
8373         ie_len = len-12-2;// 12 = param header, 2:no packed
8374
8375
8376         if(pmlmepriv->wps_probe_resp_ie)
8377         {
8378                 rtw_mfree(pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
8379                 pmlmepriv->wps_probe_resp_ie = NULL;                    
8380         }       
8381
8382         if(ie_len>0)
8383         {
8384                 pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
8385                 pmlmepriv->wps_probe_resp_ie_len = ie_len;
8386                 if ( pmlmepriv->wps_probe_resp_ie == NULL) {
8387                         DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8388                         return -EINVAL;
8389                 }
8390                 _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);         
8391         }
8392         
8393         
8394         return ret;
8395
8396 }
8397
8398 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
8399 {
8400         int ret=0;
8401         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
8402         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8403         int ie_len;
8404
8405         DBG_871X("%s, len=%d\n", __FUNCTION__, len);
8406
8407         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8408                 return -EINVAL;
8409
8410         ie_len = len-12-2;// 12 = param header, 2:no packed
8411
8412
8413         if(pmlmepriv->wps_assoc_resp_ie)
8414         {
8415                 rtw_mfree(pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
8416                 pmlmepriv->wps_assoc_resp_ie = NULL;                    
8417         }       
8418
8419         if(ie_len>0)
8420         {
8421                 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
8422                 pmlmepriv->wps_assoc_resp_ie_len = ie_len;
8423                 if ( pmlmepriv->wps_assoc_resp_ie == NULL) {
8424                         DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8425                         return -EINVAL;
8426                 }
8427                 
8428                 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);         
8429         }
8430         
8431         
8432         return ret;
8433
8434 }
8435
8436 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
8437 {
8438         int ret=0;
8439         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8440         struct mlme_priv *mlmepriv = &(adapter->mlmepriv);
8441         struct mlme_ext_priv    *mlmeext = &(adapter->mlmeextpriv);
8442         struct mlme_ext_info    *mlmeinfo = &(mlmeext->mlmext_info);
8443         int ie_len;
8444         u8 *ssid_ie;
8445         char ssid[NDIS_802_11_LENGTH_SSID + 1];
8446         sint ssid_len;
8447         u8 ignore_broadcast_ssid;
8448
8449         if(check_fwstate(mlmepriv, WIFI_AP_STATE) != _TRUE)
8450                 return -EPERM;
8451
8452         if (param->u.bcn_ie.reserved[0] != 0xea)
8453                 return -EINVAL;
8454
8455         mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];
8456
8457         ie_len = len-12-2;// 12 = param header, 2:no packed
8458         ssid_ie = rtw_get_ie(param->u.bcn_ie.buf,  WLAN_EID_SSID, &ssid_len, ie_len);
8459
8460         if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) {
8461                 WLAN_BSSID_EX *pbss_network = &mlmepriv->cur_network.network;
8462                 WLAN_BSSID_EX *pbss_network_ext = &mlmeinfo->network;
8463
8464                 _rtw_memcpy(ssid, ssid_ie+2, ssid_len);
8465                 ssid[ssid_len] = 0x0;
8466
8467                 if(0)
8468                 DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
8469                         ssid, ssid_len,
8470                         pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
8471                         pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
8472
8473                 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len);
8474                 pbss_network->Ssid.SsidLength = ssid_len;
8475                 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len);
8476                 pbss_network_ext->Ssid.SsidLength = ssid_len;
8477
8478                 if(0)
8479                 DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
8480                         pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
8481                         pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
8482         }
8483
8484         DBG_871X(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter),
8485                 ignore_broadcast_ssid, ssid, ssid_len);
8486
8487         return ret;
8488 }
8489
8490 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
8491 {
8492         int ret=0;
8493         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
8494         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
8495
8496         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8497                 return -EINVAL;
8498
8499         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8500             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8501             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
8502         {
8503                 return -EINVAL; 
8504         }
8505
8506         ret = rtw_acl_remove_sta(padapter, param->sta_addr);    
8507
8508         return ret;             
8509
8510 }
8511
8512 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
8513 {
8514         int ret=0;
8515         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
8516         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8517         
8518         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8519                 return -EINVAL;
8520
8521         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8522             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8523             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
8524         {
8525                 return -EINVAL; 
8526         }
8527
8528         ret = rtw_acl_add_sta(padapter, param->sta_addr);       
8529
8530         return ret;             
8531
8532 }
8533
8534 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
8535 {
8536         int ret=0;
8537         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);  
8538         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8539         
8540         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8541                 return -EINVAL; 
8542         
8543         rtw_set_macaddr_acl(padapter, param->u.mlme.command);   
8544
8545         return ret;
8546 }
8547
8548 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
8549 {
8550         struct ieee_param *param;
8551         int ret=0;
8552         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8553
8554         //DBG_871X("%s\n", __FUNCTION__);
8555
8556         /*
8557         * this function is expect to call in master mode, which allows no power saving
8558         * so, we just check hw_init_completed
8559         */
8560
8561         if (padapter->hw_init_completed==_FALSE){
8562                 ret = -EPERM;
8563                 goto out;
8564         }
8565
8566
8567         //if (p->length < sizeof(struct ieee_param) || !p->pointer){
8568         if(!p->pointer){
8569                 ret = -EINVAL;
8570                 goto out;
8571         }
8572         
8573         param = (struct ieee_param *)rtw_malloc(p->length);
8574         if (param == NULL)
8575         {
8576                 ret = -ENOMEM;
8577                 goto out;
8578         }
8579         
8580         if (copy_from_user(param, p->pointer, p->length))
8581         {
8582                 rtw_mfree((u8*)param, p->length);
8583                 ret = -EFAULT;
8584                 goto out;
8585         }
8586
8587         //DBG_871X("%s, cmd=%d\n", __FUNCTION__, param->cmd);
8588
8589         switch (param->cmd) 
8590         {       
8591                 case RTL871X_HOSTAPD_FLUSH:
8592
8593                         ret = rtw_hostapd_sta_flush(dev);
8594
8595                         break;
8596         
8597                 case RTL871X_HOSTAPD_ADD_STA:   
8598                         
8599                         ret = rtw_add_sta(dev, param);                                  
8600                         
8601                         break;
8602
8603                 case RTL871X_HOSTAPD_REMOVE_STA:
8604
8605                         ret = rtw_del_sta(dev, param);
8606
8607                         break;
8608         
8609                 case RTL871X_HOSTAPD_SET_BEACON:
8610
8611                         ret = rtw_set_beacon(dev, param, p->length);
8612
8613                         break;
8614                         
8615                 case RTL871X_SET_ENCRYPTION:
8616
8617                         ret = rtw_set_encryption(dev, param, p->length);
8618                         
8619                         break;
8620                         
8621                 case RTL871X_HOSTAPD_GET_WPAIE_STA:
8622
8623                         ret = rtw_get_sta_wpaie(dev, param);
8624         
8625                         break;
8626                         
8627                 case RTL871X_HOSTAPD_SET_WPS_BEACON:
8628
8629                         ret = rtw_set_wps_beacon(dev, param, p->length);
8630
8631                         break;
8632
8633                 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
8634
8635                         ret = rtw_set_wps_probe_resp(dev, param, p->length);
8636                         
8637                         break;
8638                         
8639                 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
8640
8641                         ret = rtw_set_wps_assoc_resp(dev, param, p->length);
8642                         
8643                         break;
8644
8645                 case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
8646
8647                         ret = rtw_set_hidden_ssid(dev, param, p->length);
8648
8649                         break;
8650
8651                 case RTL871X_HOSTAPD_GET_INFO_STA:
8652
8653                         ret = rtw_ioctl_get_sta_data(dev, param, p->length);
8654
8655                         break;
8656                         
8657                 case RTL871X_HOSTAPD_SET_MACADDR_ACL:
8658
8659                         ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
8660
8661                         break;
8662
8663                 case RTL871X_HOSTAPD_ACL_ADD_STA:
8664
8665                         ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
8666
8667                         break;
8668
8669                 case RTL871X_HOSTAPD_ACL_REMOVE_STA:
8670
8671                         ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
8672
8673                         break;
8674                         
8675                 default:
8676                         DBG_871X("Unknown hostapd request: %d\n", param->cmd);
8677                         ret = -EOPNOTSUPP;
8678                         break;
8679                 
8680         }
8681
8682         if (ret == 0 && copy_to_user(p->pointer, param, p->length))
8683                 ret = -EFAULT;
8684
8685
8686         rtw_mfree((u8 *)param, p->length);
8687         
8688 out:
8689                 
8690         return ret;
8691         
8692 }
8693 #endif
8694
8695 static int rtw_wx_set_priv(struct net_device *dev,
8696                                 struct iw_request_info *info,
8697                                 union iwreq_data *awrq,
8698                                 char *extra)
8699 {
8700
8701 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8702         char *ext_dbg;
8703 #endif
8704
8705         int ret = 0;
8706         int len = 0;
8707         char *ext;
8708         int i;
8709
8710         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8711         struct iw_point *dwrq = (struct iw_point*)awrq;
8712
8713         //RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, ("+rtw_wx_set_priv\n"));
8714         if(dwrq->length == 0)
8715                 return -EFAULT;
8716         
8717         len = dwrq->length;
8718         if (!(ext = rtw_vmalloc(len)))
8719                 return -ENOMEM;
8720
8721         if (copy_from_user(ext, dwrq->pointer, len)) {
8722                 rtw_vmfree(ext, len);
8723                 return -EFAULT;
8724         }
8725
8726
8727         //RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_,
8728         //       ("rtw_wx_set_priv: %s req=%s\n",
8729         //        dev->name, ext));
8730
8731         #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV     
8732         if (!(ext_dbg = rtw_vmalloc(len)))
8733         {
8734                 rtw_vmfree(ext, len);
8735                 return -ENOMEM;
8736         }       
8737         
8738         _rtw_memcpy(ext_dbg, ext, len);
8739         #endif
8740
8741         //added for wps2.0 @20110524
8742         if(dwrq->flags == 0x8766 && len > 8)
8743         {
8744                 u32 cp_sz;              
8745                 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8746                 u8 *probereq_wpsie = ext;
8747                 int probereq_wpsie_len = len;
8748                 u8 wps_oui[4]={0x0,0x50,0xf2,0x04};             
8749         
8750                 if((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
8751                         (_rtw_memcmp(&probereq_wpsie[2], wps_oui, 4) ==_TRUE))
8752                 {
8753                         cp_sz = probereq_wpsie_len>MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN:probereq_wpsie_len;
8754
8755                         if(pmlmepriv->wps_probe_req_ie)
8756                         {
8757                                 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
8758                                 pmlmepriv->wps_probe_req_ie_len = 0;
8759                                 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
8760                                 pmlmepriv->wps_probe_req_ie = NULL;                     
8761                         }       
8762
8763                         pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
8764                         if ( pmlmepriv->wps_probe_req_ie == NULL) {
8765                                 printk("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8766                                 ret =  -EINVAL;
8767                                 goto FREE_EXT;
8768                         
8769                         }
8770                         
8771                         _rtw_memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
8772                         pmlmepriv->wps_probe_req_ie_len = cp_sz;                                        
8773                         
8774                 }       
8775                 
8776                 goto FREE_EXT;
8777                 
8778         }
8779
8780         if(     len >= WEXT_CSCAN_HEADER_SIZE
8781                 && _rtw_memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
8782         ){
8783                 ret = rtw_wx_set_scan(dev, info, awrq, ext);
8784                 goto FREE_EXT;
8785         }
8786         
8787 #ifdef CONFIG_ANDROID
8788         //DBG_871X("rtw_wx_set_priv: %s req=%s\n", dev->name, ext);
8789
8790         i = rtw_android_cmdstr_to_num(ext);
8791
8792         switch(i) {
8793                 case ANDROID_WIFI_CMD_START :
8794                         indicate_wx_custom_event(padapter, "START");
8795                         break;
8796                 case ANDROID_WIFI_CMD_STOP :
8797                         indicate_wx_custom_event(padapter, "STOP");
8798                         break;
8799                 case ANDROID_WIFI_CMD_RSSI :
8800                         {
8801                                 struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);     
8802                                 struct  wlan_network    *pcur_network = &pmlmepriv->cur_network;
8803
8804                                 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
8805                                         sprintf(ext, "%s rssi %d", pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi);
8806                                 } else {
8807                                         sprintf(ext, "OK");
8808                                 }
8809                         }
8810                         break;
8811                 case ANDROID_WIFI_CMD_LINKSPEED :
8812                         {
8813                                 u16 mbps = rtw_get_cur_max_rate(padapter)/10;
8814                                 sprintf(ext, "LINKSPEED %d", mbps);
8815                         }
8816                         break;
8817                 case ANDROID_WIFI_CMD_MACADDR :
8818                         sprintf(ext, "MACADDR = " MAC_FMT, MAC_ARG(dev->dev_addr));
8819                         break;
8820                 case ANDROID_WIFI_CMD_SCAN_ACTIVE :
8821                         {
8822                                 //rtw_set_scan_mode(padapter, SCAN_ACTIVE);
8823                                 sprintf(ext, "OK");
8824                         }
8825                         break;
8826                 case ANDROID_WIFI_CMD_SCAN_PASSIVE :
8827                         {
8828                                 //rtw_set_scan_mode(padapter, SCAN_PASSIVE);
8829                                 sprintf(ext, "OK");
8830                         }
8831                         break;
8832
8833                 case ANDROID_WIFI_CMD_COUNTRY :
8834                         {
8835                                 char country_code[10];
8836                                 sscanf(ext, "%*s %s", country_code);
8837                                 rtw_set_country(padapter, country_code);
8838                                 sprintf(ext, "OK");
8839                         }
8840                         break;
8841                 default :
8842                         #ifdef  CONFIG_DEBUG_RTW_WX_SET_PRIV
8843                         DBG_871X("%s: %s unknowned req=%s\n", __FUNCTION__,
8844                                 dev->name, ext_dbg);
8845                         #endif
8846
8847                         sprintf(ext, "OK");
8848                 
8849         }
8850
8851         if (copy_to_user(dwrq->pointer, ext, min(dwrq->length, (u16)(strlen(ext)+1)) ) )
8852                 ret = -EFAULT;
8853
8854         #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8855         DBG_871X("%s: %s req=%s rep=%s dwrq->length=%d, strlen(ext)+1=%d\n", __FUNCTION__,
8856                 dev->name, ext_dbg ,ext, dwrq->length, (u16)(strlen(ext)+1));
8857         #endif
8858 #endif //end of CONFIG_ANDROID
8859
8860
8861 FREE_EXT:
8862
8863         rtw_vmfree(ext, len);
8864         #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8865         rtw_vmfree(ext_dbg, len);
8866         #endif
8867
8868         //DBG_871X("rtw_wx_set_priv: (SIOCSIWPRIV) %s ret=%d\n", 
8869         //              dev->name, ret);
8870
8871         return ret;
8872         
8873 }
8874
8875 #ifdef CONFIG_AP_WOWLAN
8876 static int rtw_ap_wowlan_ctrl(struct net_device *dev,
8877                                                 struct iw_request_info *info,
8878                                                 union iwreq_data *wrqu, char *extra)
8879 {
8880         _adapter *padapter =  (_adapter *)rtw_netdev_priv(dev);
8881         struct wowlan_ioctl_param poidparam;
8882         struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
8883         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8884         struct sta_info *psta = NULL;
8885         int ret = 0;
8886         u32 start_time = rtw_get_current_time();
8887         poidparam.subcode = 0;
8888
8889         DBG_871X("+rtw_ap_wowlan_ctrl: %s\n", extra);
8890
8891         if(pwrctrlpriv->bSupportRemoteWakeup==_FALSE){
8892                 ret = -EPERM;
8893                 DBG_871X("+rtw_wowlan_ctrl: Device didn't support the remote wakeup!!\n");
8894                 goto _rtw_ap_wowlan_ctrl_exit_free;
8895         }
8896
8897         if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
8898                 DBG_871X("[%s] It is not AP mode!!\n", __func__);
8899                 goto _rtw_ap_wowlan_ctrl_exit_free;
8900         }
8901
8902         if (_rtw_memcmp( extra, "enable", 6 )) {
8903                 pwrctrlpriv->wowlan_ap_mode = _TRUE;
8904                 while (pwrctrlpriv->bips_processing == _TRUE)
8905                         rtw_msleep_os(1);
8906
8907                 rtw_cancel_all_timer(padapter);
8908
8909                 padapter->bDriverStopped = _TRUE;       //for stop thread
8910                 rtw_stop_drv_threads(padapter);
8911                 padapter->bDriverStopped = _FALSE;      //for 32k command
8912
8913 #ifdef CONFIG_LPS
8914                 LeaveAllPowerSaveModeDirect(padapter);
8915 #endif
8916                 rtw_hal_disable_interrupt(padapter); // It need wait for leaving 32K.
8917
8918                 // 2.1 clean interupt
8919                 if (padapter->HalFunc.clear_interrupt)
8920                         padapter->HalFunc.clear_interrupt(padapter);
8921
8922                 poidparam.subcode = WOWLAN_AP_ENABLE;
8923
8924                 rtw_hal_set_hwreg(padapter, HW_VAR_AP_WOWLAN,(u8 *)&poidparam);
8925         } else if (_rtw_memcmp( extra, "disable", 6 )) {
8926 #ifdef CONFIG_LPS
8927                 LeaveAllPowerSaveModeDirect(padapter);
8928 #endif //CONFIG_LPS
8929                 pwrctrlpriv->bFwCurrentInPSMode = _FALSE;
8930
8931                 rtw_hal_disable_interrupt(padapter);
8932
8933                 if (padapter->HalFunc.clear_interrupt)
8934                         padapter->HalFunc.clear_interrupt(padapter);
8935
8936                 poidparam.subcode = WOWLAN_AP_ENABLE;
8937
8938                 rtw_hal_set_hwreg(padapter, HW_VAR_AP_WOWLAN,(u8 *)&poidparam);
8939
8940                 pwrctrlpriv->wowlan_ap_mode = _FALSE;
8941
8942                 psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
8943                 if (psta) {
8944                         set_sta_rate(padapter, psta);
8945                 }
8946
8947                 padapter->bDriverStopped = _FALSE;
8948                 DBG_871X("%s: wowmode resuming, DriverStopped:%d\n", __func__, padapter->bDriverStopped);
8949                 rtw_start_drv_threads(padapter);
8950
8951                 rtw_hal_enable_interrupt(padapter);
8952
8953                 _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000);
8954                 pwrctrlpriv->bips_processing = _FALSE;
8955                 rtw_set_pwr_state_check_timer(pwrctrlpriv);
8956
8957         } else {
8958                 DBG_871X("[%s] Invalid Parameter.\n", __func__);
8959                 goto _rtw_ap_wowlan_ctrl_exit_free;
8960         }
8961         //mutex_lock(&ioctl_mutex);
8962 _rtw_ap_wowlan_ctrl_exit_free:
8963         DBG_871X("-rtw_ap_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);
8964         DBG_871X_LEVEL(_drv_always_, "%s in %d ms\n", __func__,
8965                         rtw_get_passing_time_ms(start_time));
8966 _rtw_ap_wowlan_ctrl_exit:
8967         return ret;
8968 }
8969 #endif //CONFIG_AP_WOWLAN
8970
8971 static int rtw_pm_set(struct net_device *dev,
8972                                struct iw_request_info *info,
8973                                union iwreq_data *wrqu, char *extra)
8974 {
8975         int ret = 0;
8976         unsigned        mode = 0;
8977         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8978
8979         DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra );
8980
8981         if ( _rtw_memcmp( extra, "lps=", 4 ) )
8982         {
8983                 sscanf(extra+4, "%u", &mode);   
8984                 ret = rtw_pm_set_lps(padapter,mode);
8985         }
8986         else if ( _rtw_memcmp( extra, "ips=", 4 ) )
8987         {
8988                 sscanf(extra+4, "%u", &mode);
8989                 ret = rtw_pm_set_ips(padapter,mode);
8990         }
8991         else{
8992                 ret = -EINVAL;
8993         }
8994
8995         return ret;
8996 }
8997
8998 static int rtw_mp_efuse_get(struct net_device *dev,
8999                         struct iw_request_info *info,
9000                         union iwreq_data *wdata, char *extra)
9001 {
9002         PADAPTER padapter = rtw_netdev_priv(dev);
9003         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
9004         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
9005         PEFUSE_HAL pEfuseHal;
9006         struct iw_point *wrqu;
9007         
9008         u8      *PROMContent = pEEPROM->efuse_eeprom_data;
9009         u8 ips_mode = IPS_NUM; // init invalid value
9010         u8 lps_mode = PS_MODE_NUM; // init invalid value
9011         struct pwrctrl_priv *pwrctrlpriv ;
9012         u8 *data = NULL;
9013         u8 *rawdata = NULL;
9014         char *pch, *ptmp, *token, *tmp[3]={0x00,0x00,0x00};
9015         u16 i=0, j=0, mapLen=0, addr=0, cnts=0;
9016         u16 max_available_size=0, raw_cursize=0, raw_maxsize=0;
9017         int err;
9018         #ifdef CONFIG_IOL
9019         u8 org_fw_iol = padapter->registrypriv.fw_iol;// 0:Disable, 1:enable, 2:by usb speed
9020         #endif
9021         
9022         wrqu = (struct iw_point*)wdata;
9023         pwrctrlpriv = adapter_to_pwrctl(padapter);
9024         pEfuseHal = &pHalData->EfuseHal;
9025
9026         err = 0;
9027         data = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
9028         if (data == NULL)
9029         {
9030                 err = -ENOMEM;
9031                 goto exit;
9032         }
9033         rawdata = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
9034         if (rawdata == NULL)
9035         {
9036                 err = -ENOMEM;
9037                 goto exit;
9038         }
9039
9040         if (copy_from_user(extra, wrqu->pointer, wrqu->length))
9041         {
9042                 err = -EFAULT;
9043                 goto exit;
9044         }
9045         #ifdef CONFIG_LPS
9046         lps_mode = pwrctrlpriv->power_mgnt;//keep org value
9047         rtw_pm_set_lps(padapter,PS_MODE_ACTIVE);
9048         #endif  
9049         
9050         #ifdef CONFIG_IPS       
9051         ips_mode = pwrctrlpriv->ips_mode;//keep org value
9052         rtw_pm_set_ips(padapter,IPS_NONE);
9053         #endif  
9054         
9055         pch = extra;
9056         DBG_871X("%s: in=%s\n", __FUNCTION__, extra);
9057
9058         i = 0;
9059         //mac 16 "00e04c871200" rmap,00,2
9060         while ((token = strsep(&pch, ",")) != NULL)
9061         {
9062                 if (i > 2) break;
9063                 tmp[i] = token;
9064                 i++;
9065         }
9066         #ifdef CONFIG_IOL
9067         padapter->registrypriv.fw_iol = 0;// 0:Disable, 1:enable, 2:by usb speed
9068         #endif
9069         
9070         if(strcmp(tmp[0], "status") == 0){
9071                 sprintf(extra, "Load File efuse=%s,Load File MAC=%s",(pEEPROM->bloadfile_fail_flag? "FAIL" : "OK"),(pEEPROM->bloadmac_fail_flag? "FAIL" : "OK"));
9072
9073                   goto exit;
9074         }
9075         else if (strcmp(tmp[0], "drvmap") == 0)
9076         {
9077                 mapLen = EFUSE_MAP_SIZE;
9078                 
9079                 sprintf(extra, "\n");
9080                 for (i = 0; i < EFUSE_MAP_SIZE; i += 16)
9081                 {
9082 //                      DBG_871X("0x%02x\t", i);
9083                         sprintf(extra, "%s0x%02x\t", extra, i);
9084                         for (j=0; j<8; j++) {
9085 //                              DBG_871X("%02X ", data[i+j]);
9086                                 sprintf(extra, "%s%02X ", extra, PROMContent[i+j]);
9087                         }
9088 //                      DBG_871X("\t");
9089                         sprintf(extra, "%s\t", extra);
9090                         for (; j<16; j++) {
9091 //                              DBG_871X("%02X ", data[i+j]);
9092                                 sprintf(extra, "%s%02X ", extra, PROMContent[i+j]);
9093                         }
9094 //                      DBG_871X("\n");
9095                         sprintf(extra,"%s\n",extra);
9096                 }
9097 //              DBG_871X("\n");
9098         }
9099         else if (strcmp(tmp[0], "realmap") == 0)
9100         {
9101                 mapLen = EFUSE_MAP_SIZE;
9102                 if (rtw_efuse_map_read(padapter, EFUSE_WIFI , mapLen, pEfuseHal->fakeEfuseInitMap) == _FAIL)
9103                 {
9104                         DBG_871X("%s: read realmap Fail!!\n", __FUNCTION__);
9105                         err = -EFAULT;
9106                         goto exit;
9107                 }
9108
9109 //              DBG_871X("OFFSET\tVALUE(hex)\n");
9110                 sprintf(extra, "\n");
9111                 for (i = 0; i < EFUSE_MAP_SIZE; i += 16)
9112                 {
9113 //                      DBG_871X("0x%02x\t", i);
9114                         sprintf(extra, "%s0x%02x\t", extra, i);
9115                         for (j=0; j<8; j++) {
9116 //                              DBG_871X("%02X ", data[i+j]);
9117                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseInitMap[i+j]);
9118                         }
9119 //                      DBG_871X("\t");
9120                         sprintf(extra, "%s\t", extra);
9121                         for (; j<16; j++) {
9122 //                              DBG_871X("%02X ", data[i+j]);
9123                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseInitMap[i+j]);
9124                         }
9125 //                      DBG_871X("\n");
9126                         sprintf(extra,"%s\n",extra);
9127                 }
9128 //              DBG_871X("\n");
9129         }
9130         else if (strcmp(tmp[0], "rmap") == 0)
9131         {
9132                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9133                 {
9134                         DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9135                         err = -EINVAL;
9136                         goto exit;
9137                 }
9138
9139                 // rmap addr cnts
9140                 addr = simple_strtoul(tmp[1], &ptmp, 16);
9141                 DBG_871X("%s: addr=%x\n", __FUNCTION__, addr);
9142
9143                 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9144                 if (cnts == 0)
9145                 {
9146                         DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9147                         err = -EINVAL;
9148                         goto exit;
9149                 }
9150                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9151
9152                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (PVOID)&max_available_size, _FALSE);
9153                 if ((addr+ cnts) > max_available_size)
9154                 {
9155                         DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9156                         err = -EINVAL;
9157                         goto exit;
9158                 }
9159
9160                 if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL)
9161                 {
9162                         DBG_871X("%s: rtw_efuse_map_read error!\n", __FUNCTION__);
9163                         err = -EFAULT;
9164                         goto exit;
9165                 }
9166
9167 //              DBG_871X("%s: data={", __FUNCTION__);
9168                 *extra = 0;
9169                 for (i=0; i<cnts; i++) {
9170 //                      DBG_871X("0x%02x ", data[i]);
9171                         sprintf(extra, "%s0x%02X ", extra, data[i]);
9172                 }
9173 //              DBG_871X("}\n");
9174         }
9175         else if (strcmp(tmp[0], "realraw") == 0)
9176         {
9177                 addr = 0;
9178                 mapLen = EFUSE_MAX_SIZE;
9179                 if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL)
9180                 {
9181                         DBG_871X("%s: rtw_efuse_access Fail!!\n", __FUNCTION__);
9182                         err = -EFAULT;
9183                         goto exit;
9184                 }
9185                 _rtw_memset(extra,'\0',strlen(extra));
9186                 //              DBG_871X("%s: realraw={\n", __FUNCTION__);
9187                                 sprintf(extra, "\n0x00\t");
9188                                 for (i=0; i< mapLen; i++)
9189                                 {
9190                 //                      DBG_871X("%02X", rawdata[i]);
9191                                         sprintf(extra, "%s%02X", extra, rawdata[i]);
9192                                         if ((i & 0xF) == 0xF) {
9193                 //                              DBG_871X("\n");
9194                                                 sprintf(extra, "%s\n", extra);
9195                                                 sprintf(extra, "%s0x%02x\t", extra, i+1);
9196                                         }
9197                                         else if ((i & 0x7) == 0x7){
9198                 //                              DBG_871X("\t");
9199                                                 sprintf(extra, "%s \t", extra);
9200                                         } else {
9201                 //                              DBG_871X(" ");
9202                                                 sprintf(extra, "%s ", extra);
9203                                         }
9204                                 }
9205                 //              DBG_871X("}\n");
9206         }
9207         else if (strcmp(tmp[0], "mac") == 0)
9208         {
9209                 #ifdef CONFIG_RTL8192C
9210                 addr = EEPROM_MAC_ADDR_92C;
9211                 #endif // CONFIG_RTL8192C
9212                 #ifdef CONFIG_RTL8192D
9213                         #ifdef CONFIG_USB_HCI
9214                         if (pHalData->interfaceIndex == 0)
9215                                 addr = EEPROM_MAC_ADDR_MAC0_92DU;
9216                         else
9217                                 addr = EEPROM_MAC_ADDR_MAC1_92DU;
9218                         #else
9219                         if (pHalData->interfaceIndex == 0)
9220                                 addr = EEPROM_MAC_ADDR_MAC0_92DE;
9221                         else
9222                                 addr = EEPROM_MAC_ADDR_MAC1_92DE;
9223                         #endif
9224                 #endif // CONFIG_RTL8192D
9225                 #ifdef CONFIG_RTL8723A
9226                         #ifdef CONFIG_SDIO_HCI
9227                         addr = EEPROM_MAC_ADDR_8723AS;
9228                         #endif
9229                         #ifdef CONFIG_GSPI_HCI
9230                         addr = EEPROM_MAC_ADDR_8723AS;
9231                         #endif
9232                         #ifdef CONFIG_USB_HCI
9233                         addr = EEPROM_MAC_ADDR_8723AU;
9234                         #endif
9235                 #endif // CONFIG_RTL8723A
9236                 #ifdef CONFIG_RTL8188E
9237                         #ifdef CONFIG_USB_HCI
9238                         addr = EEPROM_MAC_ADDR_88EU;
9239                         #endif
9240                         #ifdef CONFIG_SDIO_HCI
9241                         addr = EEPROM_MAC_ADDR_88ES;
9242                         #endif
9243                         #ifdef CONFIG_PCI_HCI
9244                         addr = EEPROM_MAC_ADDR_88EE;
9245                         #endif
9246                 #endif // CONFIG_RTL8188E
9247
9248                 #ifdef CONFIG_RTL8192E
9249                         #ifdef CONFIG_USB_HCI
9250                         addr = EEPROM_MAC_ADDR_8192EU;
9251                         #endif
9252                         #ifdef CONFIG_SDIO_HCI
9253                         addr = EEPROM_MAC_ADDR_8192ES;
9254                         #endif
9255                         #ifdef CONFIG_PCI_HCI
9256                         addr = EEPROM_MAC_ADDR_8192EE;
9257                         #endif
9258                 #endif
9259                 #ifdef CONFIG_RTL8723B
9260                 #ifdef CONFIG_SDIO_HCI
9261                 addr = EEPROM_MAC_ADDR_8723BS;
9262                 #endif
9263                 #ifdef CONFIG_GSPI_HCI
9264                 addr = EEPROM_MAC_ADDR_8723BS;
9265                 #endif
9266                 #ifdef CONFIG_USB_HCI
9267                 addr = EEPROM_MAC_ADDR_8723BU;
9268                 #endif
9269                 #endif // CONFIG_RTL8723B
9270                 cnts = 6;
9271
9272                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
9273                 if ((addr + cnts) > max_available_size) {
9274                         DBG_871X("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9275                         err = -EFAULT;
9276                         goto exit;
9277                 }
9278
9279                 if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL)
9280                 {
9281                         DBG_871X("%s: rtw_efuse_map_read error!\n", __FUNCTION__);
9282                         err = -EFAULT;
9283                         goto exit;
9284                 }
9285
9286 //              DBG_871X("%s: MAC address={", __FUNCTION__);
9287                 *extra = 0;
9288                 for (i=0; i<cnts; i++)
9289                 {
9290 //                      DBG_871X("%02X", data[i]);
9291                         sprintf(extra, "%s%02X", extra, data[i]);
9292                         if (i != (cnts-1))
9293                         {
9294 //                              DBG_871X(":");
9295                                 sprintf(extra,"%s:",extra);
9296                         }
9297                 }
9298 //              DBG_871X("}\n");
9299         }
9300         else if (strcmp(tmp[0], "vidpid") == 0)
9301         {
9302                 #ifdef CONFIG_RTL8192C
9303                 addr = EEPROM_VID_92C;
9304                 #endif // CONFIG_RTL8192C
9305                 #ifdef CONFIG_RTL8192D
9306                         #ifdef CONFIG_USB_HCI
9307                         addr = EEPROM_VID_92DU;
9308                         #else
9309                         addr = EEPROM_VID_92DE;
9310                         #endif
9311                 #endif // CONFIG_RTL8192D
9312                 #ifdef CONFIG_RTL8723A
9313                         #ifdef CONFIG_USB_HCI
9314                         addr = EEPROM_VID_8723AU;
9315                         #endif
9316                 #endif // CONFIG_RTL8723A
9317                 #ifdef CONFIG_RTL8188E
9318                         #ifdef CONFIG_USB_HCI
9319                         addr = EEPROM_VID_88EU;
9320                         #endif
9321                         #ifdef CONFIG_PCI_HCI
9322                         addr = EEPROM_VID_88EE;
9323                         #endif
9324                 #endif // CONFIG_RTL8188E
9325
9326                 #ifdef CONFIG_RTL8192E
9327                         #ifdef CONFIG_USB_HCI
9328                         addr = EEPROM_VID_8192EU;
9329                         #endif
9330                         #ifdef CONFIG_PCI_HCI
9331                         addr = EEPROM_VID_8192EE;
9332                         #endif
9333                 #endif // CONFIG_RTL8192E
9334                 #ifdef CONFIG_RTL8723B
9335                 addr = EEPROM_VID_8723BU;
9336                 #endif // CONFIG_RTL8192E
9337                 cnts = 4;
9338
9339                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
9340                 if ((addr + cnts) > max_available_size)
9341                 {
9342                         DBG_871X("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9343                         err = -EFAULT;
9344                         goto exit;
9345                 }
9346                 if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL)
9347                 {
9348                         DBG_871X("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9349                         err = -EFAULT;
9350                         goto exit;
9351                 }
9352
9353 //              DBG_871X("%s: {VID,PID}={", __FUNCTION__);
9354                 *extra = 0;
9355                 for (i=0; i<cnts; i++)
9356                 {
9357 //                      DBG_871X("0x%02x", data[i]);
9358                         sprintf(extra, "%s0x%02X", extra, data[i]);
9359                         if (i != (cnts-1))
9360                         {
9361 //                              DBG_871X(",");
9362                                 sprintf(extra,"%s,",extra);
9363                         }
9364                 }
9365 //              DBG_871X("}\n");
9366         }
9367         else if (strcmp(tmp[0], "ableraw") == 0)
9368         {
9369                 efuse_GetCurrentSize(padapter,&raw_cursize);
9370                 raw_maxsize = efuse_GetMaxSize(padapter);
9371                 sprintf(extra, "[available raw size]= %d bytes", raw_maxsize-raw_cursize);
9372         }
9373         else if (strcmp(tmp[0], "btfmap") == 0)
9374         {
9375                 BTEfuse_PowerSwitch(padapter,1,_TRUE);
9376                                 
9377                 mapLen = EFUSE_BT_MAX_MAP_LEN;
9378                 if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL)
9379                 {
9380                         DBG_871X("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
9381                         err = -EFAULT;
9382                         goto exit;
9383                 }
9384
9385 //              DBG_871X("OFFSET\tVALUE(hex)\n");
9386                 sprintf(extra, "\n");
9387                 for (i=0; i<512; i+=16) // set 512 because the iwpriv's extra size have limit 0x7FF
9388                 {
9389 //                      DBG_871X("0x%03x\t", i);
9390                         sprintf(extra, "%s0x%03x\t", extra, i);
9391                         for (j=0; j<8; j++) {
9392 //                              DBG_871X("%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
9393                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
9394                         }
9395 //                      DBG_871X("\t");
9396                         sprintf(extra,"%s\t",extra);
9397                         for (; j<16; j++) {
9398 //                              DBG_871X("%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
9399                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
9400                         }
9401 //                      DBG_871X("\n");
9402                         sprintf(extra, "%s\n", extra);
9403                 }
9404 //              DBG_871X("\n");
9405         }
9406         else if (strcmp(tmp[0],"btbmap") == 0)
9407         {
9408                 BTEfuse_PowerSwitch(padapter,1,_TRUE);
9409                 
9410                 mapLen = EFUSE_BT_MAX_MAP_LEN;
9411                 if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL)
9412                 {
9413                         DBG_871X("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
9414                         err = -EFAULT;
9415                         goto exit;
9416                 }
9417
9418 //              DBG_871X("OFFSET\tVALUE(hex)\n");
9419                 sprintf(extra, "\n");
9420                 for (i=512; i<1024 ; i+=16)
9421                 {
9422 //                      DBG_871X("0x%03x\t", i);
9423                         sprintf(extra, "%s0x%03x\t", extra, i);
9424                         for (j=0; j<8; j++)
9425                         {
9426 //                              DBG_871X("%02X ", data[i+j]);
9427                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
9428                         }
9429 //                      DBG_871X("\t");
9430                         sprintf(extra,"%s\t",extra);
9431                         for (; j<16; j++) {
9432 //                              DBG_871X("%02X ", data[i+j]);
9433                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
9434                         }
9435 //                      DBG_871X("\n");
9436                         sprintf(extra, "%s\n", extra);
9437                 }
9438 //              DBG_871X("\n");
9439         }
9440         else if (strcmp(tmp[0],"btrmap") == 0)
9441         {
9442                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9443                 {
9444                         err = -EINVAL;
9445                         goto exit;
9446                 }
9447
9448                 BTEfuse_PowerSwitch(padapter,1,_TRUE);
9449                 
9450                 // rmap addr cnts
9451                 addr = simple_strtoul(tmp[1], &ptmp, 16);
9452                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
9453
9454                 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9455                 if (cnts == 0)
9456                 {
9457                         DBG_871X("%s: btrmap Fail!! cnts error!\n", __FUNCTION__);
9458                         err = -EINVAL;
9459                         goto exit;
9460                 }
9461                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9462
9463                 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
9464                 if ((addr + cnts) > max_available_size)
9465                 {
9466                         DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9467                         err = -EFAULT;
9468                         goto exit;
9469                 }
9470
9471                 if (rtw_BT_efuse_map_read(padapter, addr, cnts, data) == _FAIL) 
9472                 {
9473                         DBG_871X("%s: rtw_BT_efuse_map_read error!!\n", __FUNCTION__);
9474                         err = -EFAULT;
9475                         goto exit;
9476                 }
9477
9478                 *extra = 0;
9479 //              DBG_871X("%s: bt efuse data={", __FUNCTION__);
9480                 for (i=0; i<cnts; i++)
9481                 {
9482 //                      DBG_871X("0x%02x ", data[i]);
9483                         sprintf(extra, "%s 0x%02X ", extra, data[i]);
9484                 }
9485 //              DBG_871X("}\n");
9486                 DBG_871X(FUNC_ADPT_FMT ": BT MAC=[%s]\n", FUNC_ADPT_ARG(padapter), extra);
9487         }
9488         else if (strcmp(tmp[0], "btffake") == 0)
9489         {
9490 //              DBG_871X("OFFSET\tVALUE(hex)\n");
9491                 sprintf(extra, "\n");
9492                 for (i=0; i<512; i+=16)
9493                 {
9494 //                      DBG_871X("0x%03x\t", i);
9495                         sprintf(extra, "%s0x%03x\t", extra, i);
9496                         for (j=0; j<8; j++) {
9497 //                              DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9498                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9499                         }
9500 //                      DBG_871X("\t");
9501                         sprintf(extra, "%s\t", extra);
9502                         for (; j<16; j++) {
9503 //                              DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9504                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9505                         }
9506 //                      DBG_871X("\n");
9507                         sprintf(extra, "%s\n", extra);
9508                 }
9509 //              DBG_871X("\n");
9510         }
9511         else if (strcmp(tmp[0],"btbfake") == 0)
9512         {
9513 //              DBG_871X("OFFSET\tVALUE(hex)\n");
9514                 sprintf(extra, "\n");
9515                 for (i=512; i<1024; i+=16)
9516                 {
9517 //                      DBG_871X("0x%03x\t", i);
9518                         sprintf(extra, "%s0x%03x\t", extra, i);
9519                         for (j=0; j<8; j++) {
9520 //                              DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9521                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9522                         }
9523 //                      DBG_871X("\t");
9524                         sprintf(extra, "%s\t", extra);
9525                         for (; j<16; j++) {
9526 //                              DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9527                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9528                         }
9529 //                      DBG_871X("\n");
9530                         sprintf(extra, "%s\n", extra);
9531                 }
9532 //              DBG_871X("\n");
9533         }
9534         else if (strcmp(tmp[0],"wlrfkmap")== 0)
9535         {
9536 //              DBG_871X("OFFSET\tVALUE(hex)\n");
9537                 sprintf(extra, "\n");
9538                 for (i=0; i<EFUSE_MAP_SIZE; i+=16)
9539                 {
9540 //                      DBG_871X("\t0x%02x\t", i);
9541                         sprintf(extra, "%s0x%02x\t", extra, i);
9542                         for (j=0; j<8; j++) {
9543 //                              DBG_871X("%02X ", pEfuseHal->fakeEfuseModifiedMap[i+j]);
9544                                 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseModifiedMap[i+j]);
9545                         }
9546 //                      DBG_871X("\t");
9547                         sprintf(extra, "%s\t", extra);
9548                         for (; j<16; j++) {
9549 //                              DBG_871X("%02X ", pEfuseHal->fakeEfuseModifiedMap[i+j]);
9550                                 sprintf(extra, "%s %02X", extra, pEfuseHal->fakeEfuseModifiedMap[i+j]);
9551                         }
9552 //                      DBG_871X("\n");
9553                         sprintf(extra, "%s\n", extra);
9554                 }
9555 //              DBG_871X("\n");
9556
9557         }
9558         else if (strcmp(tmp[0],"wlrfkrmap")== 0)
9559         {
9560                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9561                                 {
9562                                         DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9563                                         err = -EINVAL;
9564                                         goto exit;
9565                                 }
9566                                 // rmap addr cnts
9567                                 addr = simple_strtoul(tmp[1], &ptmp, 16);
9568                                 DBG_871X("%s: addr=%x\n", __FUNCTION__, addr);
9569                 
9570                                 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9571                                 if (cnts == 0)
9572                                 {
9573                                         DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9574                                         err = -EINVAL;
9575                                         goto exit;
9576                                 }
9577                                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9578                 
9579                 //              DBG_871X("%s: data={", __FUNCTION__);
9580                         *extra = 0;
9581                         for (i=0; i<cnts; i++) {
9582                                         DBG_871X("wlrfkrmap = 0x%02x \n", pEfuseHal->fakeEfuseModifiedMap[addr+i]);
9583                                         sprintf(extra, "%s0x%02X ", extra, pEfuseHal->fakeEfuseModifiedMap[addr+i]);
9584                         }
9585         }
9586         else if (strcmp(tmp[0],"btrfkrmap")== 0)
9587         {
9588                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9589                                 {
9590                                         DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9591                                         err = -EINVAL;
9592                                         goto exit;
9593                                 }
9594                                 // rmap addr cnts
9595                                 addr = simple_strtoul(tmp[1], &ptmp, 16);
9596                                 DBG_871X("%s: addr=%x\n", __FUNCTION__, addr);
9597                 
9598                                 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9599                                 if (cnts == 0)
9600                                 {
9601                                         DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9602                                         err = -EINVAL;
9603                                         goto exit;
9604                                 }
9605                                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9606                 
9607                 //              DBG_871X("%s: data={", __FUNCTION__);
9608                         *extra = 0;
9609                         for (i=0; i<cnts; i++) {
9610                                         DBG_871X("wlrfkrmap = 0x%02x \n", pEfuseHal->fakeBTEfuseModifiedMap[addr+i]);
9611                                         sprintf(extra, "%s0x%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[addr+i]);
9612                         }
9613         }
9614         else
9615         {
9616                  sprintf(extra, "Command not found!");
9617         }
9618
9619 exit:
9620         if (data)
9621                 rtw_mfree(data, EFUSE_BT_MAX_MAP_LEN);
9622         if (rawdata)
9623                 rtw_mfree(rawdata, EFUSE_BT_MAX_MAP_LEN);
9624         if (!err)
9625                 wrqu->length = strlen(extra);
9626         
9627         if (padapter->registrypriv.mp_mode == 0)
9628         {
9629         #ifdef CONFIG_IPS               
9630         rtw_pm_set_ips(padapter, ips_mode);
9631 #endif // CONFIG_IPS
9632
9633         #ifdef CONFIG_LPS       
9634         rtw_pm_set_lps(padapter, lps_mode);
9635 #endif // CONFIG_LPS
9636         }
9637
9638         #ifdef CONFIG_IOL
9639         padapter->registrypriv.fw_iol = org_fw_iol;// 0:Disable, 1:enable, 2:by usb speed
9640         #endif
9641         return err;
9642 }
9643
9644 static int rtw_mp_efuse_set(struct net_device *dev,
9645                         struct iw_request_info *info,
9646                         union iwreq_data *wdata, char *extra)
9647 {
9648         struct iw_point *wrqu;
9649         PADAPTER padapter;
9650         struct pwrctrl_priv *pwrctrlpriv ;
9651         PHAL_DATA_TYPE pHalData;
9652         PEFUSE_HAL pEfuseHal;
9653         struct mp_priv *pmppriv;
9654         
9655         u8 ips_mode = IPS_NUM; // init invalid value
9656         u8 lps_mode = PS_MODE_NUM; // init invalid value
9657         u32 i=0,j=0, jj, kk;
9658         u8 *setdata = NULL;
9659         u8 *ShadowMapBT = NULL;
9660         u8 *ShadowMapWiFi = NULL;
9661         u8 *setrawdata = NULL;
9662         char *pch, *ptmp, *token, *tmp[3]={0x00,0x00,0x00};
9663         u16 addr=0, cnts=0, BTStatus=0 , max_available_size=0;
9664         int err;
9665
9666         wrqu = (struct iw_point*)wdata;
9667         padapter = rtw_netdev_priv(dev);
9668         pwrctrlpriv = adapter_to_pwrctl(padapter);
9669         pHalData = GET_HAL_DATA(padapter);
9670         pEfuseHal = &pHalData->EfuseHal;
9671         pmppriv = &padapter->mppriv;
9672         
9673         err = 0;
9674         
9675         if (copy_from_user(extra, wrqu->pointer, wrqu->length))
9676                         return -EFAULT;
9677                         
9678         setdata = rtw_zmalloc(1024);
9679         if (setdata == NULL)
9680         {
9681                 err = -ENOMEM;
9682                 goto exit;
9683         }
9684         ShadowMapBT = rtw_malloc(EFUSE_BT_MAX_MAP_LEN);
9685         if (ShadowMapBT == NULL)
9686         {
9687                 err = -ENOMEM;
9688                 goto exit;
9689         }
9690         ShadowMapWiFi = rtw_malloc(EFUSE_MAP_SIZE);
9691         if (ShadowMapWiFi == NULL)
9692         {
9693                 err = -ENOMEM;
9694                 goto exit;
9695         }
9696         setrawdata = rtw_malloc(EFUSE_MAX_SIZE);
9697         if (setrawdata == NULL)
9698         {
9699                 err = -ENOMEM;
9700                 goto exit;
9701         }
9702
9703         #ifdef CONFIG_LPS
9704         lps_mode = pwrctrlpriv->power_mgnt;//keep org value
9705         rtw_pm_set_lps(padapter,PS_MODE_ACTIVE);
9706         #endif  
9707         
9708         #ifdef CONFIG_IPS       
9709         ips_mode = pwrctrlpriv->ips_mode;//keep org value
9710         rtw_pm_set_ips(padapter,IPS_NONE);
9711         #endif  
9712                         
9713         pch = extra;
9714         DBG_871X("%s: in=%s\n", __FUNCTION__, extra);
9715         
9716         i = 0;
9717         while ((token = strsep(&pch, ",")) != NULL)
9718         {
9719                 if (i > 2) break;
9720                 tmp[i] = token;
9721                 i++;
9722         }
9723
9724         // tmp[0],[1],[2]
9725         // wmap,addr,00e04c871200
9726         if (strcmp(tmp[0], "wmap") == 0)
9727         {
9728 #if defined(CONFIG_RTL8188E) || defined(CONFIG_USB_HCI)
9729                 if(pmppriv->bPreBrunEfuse==_FALSE)
9730                         Rtw_EfuseChkPreBurn8188ESerial(padapter);
9731 #endif          
9732                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9733                 {
9734                         err = -EINVAL;
9735                         goto exit;
9736                 }
9737 #if 1
9738                 // unknown bug workaround, need to fix later
9739                 addr=0x1ff;
9740                 rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff));
9741                 rtw_msleep_os(10);
9742                 rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03));
9743                 rtw_msleep_os(10);
9744                 rtw_write8(padapter, EFUSE_CTRL+3, 0x72);
9745                 rtw_msleep_os(10);
9746                 rtw_read8(padapter, EFUSE_CTRL);
9747 #endif
9748
9749                 addr = simple_strtoul(tmp[1], &ptmp, 16);
9750                 addr &= 0xFFF;
9751
9752                 cnts = strlen(tmp[2]);
9753                 if (cnts%2)
9754                 {
9755                         err = -EINVAL;
9756                         goto exit;
9757                 }
9758                 cnts /= 2;
9759                 if (cnts == 0)
9760                 {
9761                         err = -EINVAL;
9762                         goto exit;
9763                 }
9764                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
9765                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9766                 DBG_871X("%s: map data=%s\n", __FUNCTION__, tmp[2]);
9767                                 
9768                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
9769                 {
9770                         setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
9771                 }
9772 #ifndef CONFIG_RTL8188E
9773                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
9774 #else
9775                 //Change to check TYPE_EFUSE_MAP_LEN ,beacuse 8188E raw 256,logic map over 256.
9776                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_size, _FALSE);
9777 #endif
9778                 if ((addr+cnts) > max_available_size)
9779                 {
9780                         DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9781                         err = -EFAULT;
9782                         goto exit;
9783                 }
9784
9785                 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
9786                 {
9787                         DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9788                         err = -EFAULT;
9789                         goto exit;
9790                 }
9791                 *extra = 0;
9792                 DBG_871X("%s: after rtw_BT_efuse_map_write to _rtw_memcmp \n", __FUNCTION__);
9793                 if ( (rtw_efuse_map_read(padapter, addr, cnts, ShadowMapWiFi) == _SUCCESS ) )
9794                 {
9795                         if (_rtw_memcmp((void*)ShadowMapWiFi ,(void*)setdata,cnts))
9796                         { 
9797                                 DBG_871X("%s: WiFi write map afterf compare success\n", __FUNCTION__);
9798                                 sprintf(extra, "WiFi write map compare OK\n");
9799                                 err = 0;
9800                                 goto exit;
9801                         }
9802                         else
9803                         {
9804                                 sprintf(extra, "WiFi write map compare FAIL\n");
9805                                 DBG_871X("%s: WiFi write map compare Fail\n", __FUNCTION__);
9806                                 err = 0;
9807                                 goto exit;
9808                         }
9809                 }
9810         }
9811         else if (strcmp(tmp[0], "wraw") == 0)
9812         {
9813                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9814                 {
9815                         err = -EINVAL;
9816                         goto exit;
9817                 }
9818
9819                 addr = simple_strtoul( tmp[1], &ptmp, 16 );
9820                 addr &= 0xFFF;
9821
9822                 cnts = strlen(tmp[2]);
9823                 if (cnts%2)
9824                 {
9825                         err = -EINVAL;
9826                         goto exit;
9827                 }
9828                 cnts /= 2;
9829                 if (cnts == 0)
9830                 {
9831                         err = -EINVAL;
9832                         goto exit;
9833                 }
9834
9835                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
9836                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9837                 DBG_871X("%s: raw data=%s\n", __FUNCTION__, tmp[2]);
9838
9839                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
9840                 {
9841                         setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
9842                 }
9843
9844                 if (rtw_efuse_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL)
9845                 {
9846                         DBG_871X("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9847                         err = -EFAULT;
9848                         goto exit;
9849                 }
9850         }
9851         else if (strcmp(tmp[0], "mac") == 0)
9852         {
9853                 if (tmp[1]==NULL)
9854                 {
9855                         err = -EINVAL;
9856                         goto exit;
9857                 }
9858
9859                 //mac,00e04c871200
9860                 #ifdef CONFIG_RTL8192C
9861                 addr = EEPROM_MAC_ADDR_92C;
9862                 #endif
9863                 #ifdef CONFIG_RTL8192D
9864                         #ifdef CONFIG_USB_HCI
9865                         if (pHalData->interfaceIndex == 0)
9866                                 addr = EEPROM_MAC_ADDR_MAC0_92DU;
9867                         else
9868                                 addr = EEPROM_MAC_ADDR_MAC1_92DU;
9869                         #else
9870                         if (pHalData->interfaceIndex == 0)
9871                                 addr = EEPROM_MAC_ADDR_MAC0_92DE;
9872                         else
9873                                 addr = EEPROM_MAC_ADDR_MAC1_92DE;
9874                         #endif
9875                 #endif
9876                 #ifdef CONFIG_RTL8723A
9877                 #ifdef CONFIG_SDIO_HCI
9878                 addr = EEPROM_MAC_ADDR_8723AS;
9879                 #endif
9880                 #ifdef CONFIG_GSPI_HCI
9881                 addr = EEPROM_MAC_ADDR_8723AS;
9882                 #endif
9883                 #ifdef CONFIG_USB_HCI
9884                 addr = EEPROM_MAC_ADDR_8723AU;
9885                 #endif
9886                 #endif // CONFIG_RTL8723A
9887                 #ifdef CONFIG_RTL8188E
9888                         #ifdef CONFIG_USB_HCI
9889                         addr = EEPROM_MAC_ADDR_88EU;
9890                         #endif
9891                         #ifdef CONFIG_SDIO_HCI
9892                         addr = EEPROM_MAC_ADDR_88ES;
9893                         #endif
9894                         #ifdef CONFIG_PCI_HCI
9895                         addr = EEPROM_MAC_ADDR_88EE;
9896                         #endif
9897                 #endif //#ifdef CONFIG_RTL8188E
9898
9899                 #ifdef CONFIG_RTL8192E
9900                         #ifdef CONFIG_USB_HCI
9901                         addr = EEPROM_MAC_ADDR_8192EU;
9902                         #endif
9903                         #ifdef CONFIG_SDIO_HCI
9904                         addr = EEPROM_MAC_ADDR_8192ES;
9905                         #endif
9906                         #ifdef CONFIG_PCI_HCI
9907                         addr = EEPROM_MAC_ADDR_8192EE;
9908                         #endif
9909                 #endif //#ifdef CONFIG_RTL8192E
9910                 
9911                 #ifdef CONFIG_RTL8723B
9912                 #ifdef CONFIG_SDIO_HCI
9913                 addr = EEPROM_MAC_ADDR_8723BS;
9914                 #endif
9915                 #ifdef CONFIG_GSPI_HCI
9916                 addr = EEPROM_MAC_ADDR_8723BS;
9917                 #endif
9918                 #ifdef CONFIG_USB_HCI
9919                 addr = EEPROM_MAC_ADDR_8723BU;
9920                 #endif
9921                 #endif // CONFIG_RTL8723B
9922
9923                 cnts = strlen(tmp[1]);
9924                 if (cnts%2)
9925                 {
9926                         err = -EINVAL;
9927                         goto exit;
9928                 }
9929                 cnts /= 2;
9930                 if (cnts == 0)
9931                 {
9932                         err = -EINVAL;
9933                         goto exit;
9934                 }
9935                 if (cnts > 6)
9936                 {
9937                         DBG_871X("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]);
9938                         err = -EFAULT;
9939                         goto exit;
9940                 }
9941
9942                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
9943                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9944                 DBG_871X("%s: MAC address=%s\n", __FUNCTION__, tmp[1]);
9945
9946                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
9947                 {
9948                         setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
9949                 }
9950 #ifndef CONFIG_RTL8188E
9951                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
9952 #else
9953                 //Change to check TYPE_EFUSE_MAP_LEN ,beacuse 8188E raw 256,logic map over 256.
9954                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_size, _FALSE);
9955 #endif
9956                 if ((addr+cnts) > max_available_size)
9957                 {
9958                         DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9959                         err = -EFAULT;
9960                         goto exit;
9961                 }
9962
9963                 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
9964                 {
9965                         DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9966                         err = -EFAULT;
9967                         goto exit;
9968                 }
9969         }
9970         else if (strcmp(tmp[0], "vidpid") == 0)
9971         {
9972                 if (tmp[1]==NULL)
9973                 {
9974                         err = -EINVAL;
9975                         goto exit;
9976                 }
9977
9978                 // pidvid,da0b7881
9979                 #ifdef CONFIG_RTL8192C
9980                 addr = EEPROM_VID_92C;
9981                 #endif // CONFIG_RTL8192C
9982                 #ifdef CONFIG_RTL8192D
9983                         #ifdef CONFIG_USB_HCI
9984                         addr = EEPROM_VID_92DU;
9985                         #else
9986                         addr = EEPROM_VID_92DE;
9987                         #endif
9988                 #endif // CONFIG_RTL8192D
9989                 #ifdef CONFIG_RTL8723A
9990                         #ifdef CONFIG_USB_HCI
9991                         addr = EEPROM_VID_8723AU;
9992                         #endif
9993                 #endif // CONFIG_RTL8723A
9994                 #ifdef CONFIG_RTL8188E
9995                         #ifdef CONFIG_USB_HCI
9996                         addr = EEPROM_VID_88EU;
9997                         #endif
9998                         #ifdef CONFIG_PCI_HCI
9999                         addr = EEPROM_VID_88EE;
10000                         #endif
10001                 #endif // CONFIG_RTL8188E
10002
10003                 #ifdef CONFIG_RTL8192E
10004                         #ifdef CONFIG_USB_HCI
10005                         addr = EEPROM_VID_8192EU;
10006                         #endif
10007                         #ifdef CONFIG_PCI_HCI
10008                         addr = EEPROM_VID_8192EE;
10009                         #endif
10010                 #endif // CONFIG_RTL8188E
10011
10012                 #ifdef CONFIG_RTL8723B
10013                 addr = EEPROM_VID_8723BU;
10014                 #endif
10015                 
10016                 cnts = strlen(tmp[1]);
10017                 if (cnts%2)
10018                 {
10019                         err = -EINVAL;
10020                         goto exit;
10021                 }
10022                 cnts /= 2;
10023                 if (cnts == 0)
10024                 {
10025                         err = -EINVAL;
10026                         goto exit;
10027                 }
10028
10029                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10030                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10031                 DBG_871X("%s: VID/PID=%s\n", __FUNCTION__, tmp[1]);
10032
10033                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10034                 {
10035                         setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
10036                 }
10037
10038                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
10039                 if ((addr+cnts) > max_available_size)
10040                 {
10041                         DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10042                         err = -EFAULT;
10043                         goto exit;
10044                 }
10045
10046                 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
10047                 {
10048                         DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
10049                         err = -EFAULT;
10050                         goto exit;
10051                 }
10052         }
10053         else if (strcmp(tmp[0], "wldumpfake") == 0)
10054         {
10055                 if (rtw_efuse_map_read(padapter, 0, EFUSE_MAP_SIZE,  pEfuseHal->fakeEfuseModifiedMap) == _SUCCESS) {
10056                         DBG_871X("%s: WiFi hw efuse dump to Fake map success \n", __FUNCTION__); 
10057                 } else {
10058                         DBG_871X("%s: WiFi hw efuse dump to Fake map Fail \n", __FUNCTION__);
10059                         err = -EFAULT;
10060                 }
10061         }
10062         else if (strcmp(tmp[0], "btwmap") == 0)
10063         {
10064                 rtw_write8(padapter, 0xa3, 0x05); //For 8723AB ,8821S ?
10065                 BTStatus=rtw_read8(padapter, 0xa0);
10066                 DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus);
10067                 if (BTStatus != 0x04)
10068                 {
10069                         sprintf(extra, "BT Status not Active Write FAIL\n");
10070                         goto exit;
10071                 }
10072
10073                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10074                 {
10075                         err = -EINVAL;
10076                         goto exit;
10077                 }
10078                 BTEfuse_PowerSwitch(padapter,1,_TRUE);
10079                 
10080                 addr=0x1ff;
10081                 rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff));
10082                 rtw_msleep_os(10);
10083                 rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03));
10084                 rtw_msleep_os(10);
10085                 rtw_write8(padapter, EFUSE_CTRL+3, 0x72);
10086                 rtw_msleep_os(10);
10087                 rtw_read8(padapter, EFUSE_CTRL);
10088
10089                 addr = simple_strtoul(tmp[1], &ptmp, 16);
10090                 addr &= 0xFFF;
10091
10092                 cnts = strlen(tmp[2]);
10093                 if (cnts%2)
10094                 {
10095                         err = -EINVAL;
10096                         goto exit;
10097                 }
10098                 cnts /= 2;
10099                 if (cnts == 0)
10100                 {
10101                         err = -EINVAL;
10102                         goto exit;
10103                 }
10104
10105                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10106                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10107                 DBG_871X("%s: BT data=%s\n", __FUNCTION__, tmp[2]);
10108
10109                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10110                 {
10111                         setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
10112                 }
10113
10114                 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
10115                 if ((addr+cnts) > max_available_size)
10116                 {
10117                         DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10118                         err = -EFAULT;
10119                         goto exit;
10120                 }
10121
10122                 if (rtw_BT_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
10123                 {
10124                         DBG_871X("%s: rtw_BT_efuse_map_write error!!\n", __FUNCTION__);
10125                         err = -EFAULT;
10126                         goto exit;
10127                 }
10128                 *extra = 0;
10129                 DBG_871X("%s: after rtw_BT_efuse_map_write to _rtw_memcmp \n", __FUNCTION__);
10130                 if ( (rtw_BT_efuse_map_read(padapter, addr, cnts, ShadowMapBT ) == _SUCCESS ) )
10131                 {
10132                         if (_rtw_memcmp((void*)ShadowMapBT ,(void*)setdata,cnts))
10133                         { 
10134                                 DBG_871X("%s: BT write map compare OK BTStatus=0x%x\n", __FUNCTION__,BTStatus);
10135                                 sprintf(extra, "BT write map compare OK");
10136                                 err = 0;
10137                                 goto exit;
10138                         }
10139                         else
10140                         {
10141                                 sprintf(extra, "BT write map compare FAIL");
10142                                 DBG_871X("%s: BT write map compare FAIL BTStatus=0x%x\n", __FUNCTION__,BTStatus);
10143                                 err = 0;
10144                                 goto exit;
10145                         }
10146                 }
10147         }
10148         else if (strcmp(tmp[0], "btwfake") == 0)
10149         {
10150                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10151                 {
10152                         err = -EINVAL;
10153                         goto exit;
10154                 }
10155
10156                 addr = simple_strtoul(tmp[1], &ptmp, 16);
10157                 addr &= 0xFFF;
10158
10159                 cnts = strlen(tmp[2]);
10160                 if (cnts%2)
10161                 {
10162                         err = -EINVAL;
10163                         goto exit;
10164                 }
10165                 cnts /= 2;
10166                 if (cnts == 0)
10167                 {
10168                         err = -EINVAL;
10169                         goto exit;
10170                 }
10171
10172                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10173                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10174                 DBG_871X("%s: BT tmp data=%s\n", __FUNCTION__, tmp[2]);
10175                                 
10176                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10177                 {
10178                         pEfuseHal->fakeBTEfuseModifiedMap[addr+jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
10179                 }
10180         }
10181         else if (strcmp(tmp[0], "btdumpfake") == 0)
10182         {
10183                 if (rtw_BT_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _SUCCESS) {
10184                         DBG_871X("%s: BT read all map success\n", __FUNCTION__);
10185                 } else {
10186                         DBG_871X("%s: BT read all map Fail!\n", __FUNCTION__);
10187                         err = -EFAULT;
10188                 }
10189         }
10190         else if (strcmp(tmp[0], "btfk2map") == 0)
10191         {
10192                 rtw_write8(padapter, 0xa3, 0x05);
10193                 BTStatus=rtw_read8(padapter, 0xa0);
10194                 DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus);
10195                 if (BTStatus != 0x04)
10196                 {
10197                         sprintf(extra, "BT Status not Active Write FAIL\n");
10198                         goto exit;
10199                 }
10200                 
10201                 BTEfuse_PowerSwitch(padapter,1,_TRUE);
10202
10203                 addr=0x1ff;
10204                 rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff));
10205                 rtw_msleep_os(10);
10206                 rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03));
10207                 rtw_msleep_os(10);
10208                 rtw_write8(padapter, EFUSE_CTRL+3, 0x72);
10209                 rtw_msleep_os(10);
10210                 rtw_read8(padapter, EFUSE_CTRL);
10211
10212                 _rtw_memcpy(pEfuseHal->BTEfuseModifiedMap, pEfuseHal->fakeBTEfuseModifiedMap, EFUSE_BT_MAX_MAP_LEN);
10213                         
10214                 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);     
10215                 if (max_available_size < 1)
10216                 {
10217                         err = -EFAULT;
10218                         goto exit;
10219                 }
10220
10221                 if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL)
10222                 {
10223                         DBG_871X("%s: rtw_BT_efuse_map_write error!\n", __FUNCTION__);
10224                         err = -EFAULT;
10225                         goto exit;
10226                 }
10227                 
10228                 DBG_871X("pEfuseHal->fakeBTEfuseModifiedMap OFFSET\tVALUE(hex)\n");
10229                 for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16)
10230                 {
10231                         printk("0x%02x\t", i);
10232                         for (j=0; j<8; j++) {
10233                                 printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10234                         }
10235                         printk("\t");
10236
10237                         for (; j<16; j++) {
10238                                 printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10239                         }
10240                         printk("\n");
10241                 }
10242                 printk("\n");
10243 #if 1           
10244                 err = -EFAULT;
10245                 DBG_871X("%s: rtw_BT_efuse_map_read _rtw_memcmp \n", __FUNCTION__);
10246                 if ( (rtw_BT_efuse_map_read(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS ) )
10247                 { 
10248                         if (_rtw_memcmp((void*)pEfuseHal->fakeBTEfuseModifiedMap,(void*)pEfuseHal->fakeBTEfuseInitMap,EFUSE_BT_MAX_MAP_LEN))
10249                         { 
10250                                 sprintf(extra, "BT write map compare OK");
10251                                 DBG_871X("%s: BT write map afterf compare success BTStatus=0x%x \n", __FUNCTION__,BTStatus);
10252                                 err = 0;
10253                                 goto exit;
10254                         }
10255                         else
10256                         {
10257                                 sprintf(extra, "BT write map compare FAIL");
10258                                 if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL)
10259                                 {
10260                                         DBG_871X("%s: rtw_BT_efuse_map_write compare error,retry = %d!\n", __FUNCTION__,i);
10261                                 }
10262
10263                                 if (rtw_BT_efuse_map_read(padapter, EFUSE_BT, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS)
10264                                 {
10265                                         DBG_871X("pEfuseHal->fakeBTEfuseInitMap OFFSET\tVALUE(hex)\n");
10266
10267                                         for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16)
10268                                         {
10269                                                 printk("0x%02x\t", i);
10270                                                 for (j=0; j<8; j++) {
10271                                                         printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i+j]);
10272                                                 }
10273                                                 printk("\t");
10274                                                 for (; j<16; j++) {
10275                                                         printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i+j]);
10276                                                 }
10277                                                 printk("\n");
10278                                         }
10279                                         printk("\n"); 
10280                                 }
10281                                 DBG_871X("%s: BT write map afterf compare not match to write efuse try write Map again , BTStatus=0x%x\n", __FUNCTION__,BTStatus);      
10282                                 goto exit;
10283                         }
10284                 }
10285 #endif
10286
10287         }
10288         else if (strcmp(tmp[0], "wlfk2map") == 0)
10289         {
10290                 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);                                   
10291                 if (max_available_size < 1)
10292                 {
10293                         err = -EFAULT;
10294                         goto exit;
10295                 }
10296                 if (rtw_efuse_map_write(padapter, 0x00, EFUSE_MAP_SIZE, pEfuseHal->fakeEfuseModifiedMap) == _FAIL)
10297                 {
10298                         DBG_871X("%s: rtw_efuse_map_write fakeEfuseModifiedMap error!\n", __FUNCTION__);
10299                         err = -EFAULT;
10300                         goto exit;
10301                 }
10302                 *extra = 0;
10303                 DBG_871X("%s: after rtw_BT_efuse_map_write to _rtw_memcmp \n", __FUNCTION__);
10304                 if ( (rtw_efuse_map_read(padapter, 0x00, EFUSE_MAP_SIZE, ShadowMapWiFi) == _SUCCESS ) )
10305                 {
10306                         if (_rtw_memcmp((void*)ShadowMapWiFi ,(void*)setdata,cnts))
10307                         {
10308                                 DBG_871X("%s: WiFi write map afterf compare OK\n", __FUNCTION__);
10309                                 sprintf(extra, "WiFi write map compare OK\n");
10310                                 err = 0;
10311                                 goto exit;
10312                         }
10313                         else
10314                         {
10315                                 sprintf(extra, "WiFi write map compare FAIL\n");
10316                                 DBG_871X("%s: WiFi write map compare Fail\n", __FUNCTION__);
10317                                 err = 0;
10318                                 goto exit;
10319                         }
10320                 }
10321         }
10322         else if (strcmp(tmp[0], "wlwfake") == 0)
10323         {
10324                 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10325                 {
10326                         err = -EINVAL;
10327                         goto exit;
10328                 }
10329
10330                 addr = simple_strtoul(tmp[1], &ptmp, 16);
10331                 addr &= 0xFFF;
10332
10333                 cnts = strlen(tmp[2]);
10334                 if (cnts%2)
10335                 {
10336                         err = -EINVAL;
10337                         goto exit;
10338                 }
10339                 cnts /= 2;
10340                 if (cnts == 0)
10341                 {
10342                         err = -EINVAL;
10343                         goto exit;
10344                 }
10345
10346                 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10347                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10348                 DBG_871X("%s: map tmp data=%s\n", __FUNCTION__, tmp[2]);
10349
10350                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10351                 {
10352                         pEfuseHal->fakeEfuseModifiedMap[addr+jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
10353                 }
10354         }
10355
10356 exit:
10357         if (setdata)
10358                 rtw_mfree(setdata, 1024);
10359         if (ShadowMapBT)
10360                 rtw_mfree(ShadowMapBT, EFUSE_BT_MAX_MAP_LEN);
10361         if (ShadowMapWiFi)
10362                 rtw_mfree(ShadowMapWiFi, EFUSE_MAP_SIZE);
10363         if (setrawdata)
10364                 rtw_mfree(setrawdata, EFUSE_MAX_SIZE);
10365         
10366         wrqu->length = strlen(extra);
10367
10368         if (padapter->registrypriv.mp_mode == 0)
10369         {
10370         #ifdef CONFIG_IPS               
10371         rtw_pm_set_ips(padapter, ips_mode);
10372         #endif // CONFIG_IPS
10373
10374         #ifdef CONFIG_LPS       
10375         rtw_pm_set_lps(padapter, lps_mode);
10376         #endif // CONFIG_LPS
10377         }
10378
10379         return err;
10380 }
10381
10382 #if defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT)
10383 /*
10384  * Input Format: %s,%d,%d
10385  *      %s is width, could be
10386  *              "b" for 1 byte
10387  *              "w" for WORD (2 bytes)
10388  *              "dw" for DWORD (4 bytes)
10389  *      1st %d is address(offset)
10390  *      2st %d is data to write
10391  */
10392 static int rtw_mp_write_reg(struct net_device *dev,
10393                         struct iw_request_info *info,
10394                         struct iw_point *wrqu, char *extra)
10395 {
10396         char *pch, *pnext, *ptmp;
10397         char *width_str;
10398         char width;
10399         u32 addr, data;
10400         int ret;
10401         PADAPTER padapter = rtw_netdev_priv(dev);
10402         char input[wrqu->length];
10403
10404         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10405                                  return -EFAULT;
10406                                  
10407         _rtw_memset(extra, 0, wrqu->length);    
10408           
10409         pch = input;
10410
10411         pnext = strpbrk(pch, " ,.-");
10412         if (pnext == NULL) return -EINVAL;
10413         *pnext = 0;
10414         width_str = pch;
10415
10416         pch = pnext + 1;
10417         pnext = strpbrk(pch, " ,.-");
10418         if (pnext == NULL) return -EINVAL;
10419         *pnext = 0;
10420         addr = simple_strtoul(pch, &ptmp, 16);
10421         if (addr > 0x3FFF) return -EINVAL;
10422
10423         pch = pnext + 1;
10424         if ((pch - extra) >= wrqu->length) return -EINVAL;
10425         data = simple_strtoul(pch, &ptmp, 16);
10426
10427         ret = 0;
10428         width = width_str[0];
10429         switch (width) {
10430                 case 'b':
10431                         // 1 byte
10432                         if (data > 0xFF) {
10433                                 ret = -EINVAL;
10434                                 break;
10435                         }
10436                         rtw_write8(padapter, addr, data);
10437                         break;
10438                 case 'w':
10439                         // 2 bytes
10440                         if (data > 0xFFFF) {
10441                                 ret = -EINVAL;
10442                                 break;
10443                         }
10444                         rtw_write16(padapter, addr, data);
10445                         break;
10446                 case 'd':
10447                         // 4 bytes
10448                         rtw_write32(padapter, addr, data);
10449                         break;
10450                 default:
10451                         ret = -EINVAL;
10452                         break;
10453         }
10454
10455         return ret;
10456 }
10457
10458 /*
10459  * Input Format: %s,%d
10460  *      %s is width, could be
10461  *              "b" for 1 byte
10462  *              "w" for WORD (2 bytes)
10463  *              "dw" for DWORD (4 bytes)
10464  *      %d is address(offset)
10465  *
10466  * Return:
10467  *      %d for data readed
10468  */
10469 static int rtw_mp_read_reg(struct net_device *dev,
10470                         struct iw_request_info *info,
10471                         struct iw_point *wrqu, char *extra)
10472 {
10473         char input[wrqu->length];
10474         char *pch, *pnext, *ptmp;
10475         char *width_str;
10476         char width;
10477         char data[20],tmp[20];
10478         u32 addr;
10479         //u32 *data = (u32*)extra;
10480         u32 ret, i=0, j=0, strtout=0;
10481         PADAPTER padapter = rtw_netdev_priv(dev);
10482
10483
10484         if (wrqu->length > 128) 
10485                 return -EFAULT;
10486
10487         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10488                 return -EFAULT;
10489
10490         _rtw_memset(data, 0, 20);
10491         _rtw_memset(tmp, 0, 20);
10492         _rtw_memset(extra, 0, wrqu->length);
10493
10494         pch = input;
10495         pnext = strpbrk(pch, " ,.-");
10496         if (pnext == NULL) return -EINVAL;
10497         *pnext = 0;
10498         width_str = pch;
10499
10500         pch = pnext + 1;
10501         if ((pch - input) >= wrqu->length) return -EINVAL;
10502         
10503         addr = simple_strtoul(pch, &ptmp, 16);
10504         if (addr > 0x3FFF) return -EINVAL;
10505
10506         ret = 0;
10507         width = width_str[0];
10508         switch (width)
10509         {
10510                 case 'b':
10511                         // 1 byte
10512                         // *(u8*)data = rtw_read8(padapter, addr);
10513                         sprintf(extra, "%d\n",  rtw_read8(padapter, addr));
10514                         wrqu->length = strlen(extra);
10515                         break;
10516                 case 'w':
10517                         // 2 bytes
10518                         //*(u16*)data = rtw_read16(padapter, addr);
10519                         sprintf(data, "%04x\n", rtw_read16(padapter, addr));
10520                         for( i=0 ; i <= strlen(data) ; i++)
10521                                 {
10522                                           if( i%2==0 )
10523                                           {
10524                                                    tmp[j]=' ';
10525                                                    j++;
10526                                           }
10527                                           if ( data[i] != '\0' )
10528                                                  tmp[j] = data[i];
10529                                                 
10530                                                  j++;
10531                                 }
10532                                 pch = tmp;              
10533                                 DBG_871X("pch=%s",pch);
10534                                 
10535                                 while( *pch != '\0' )
10536                                 {
10537                                         pnext = strpbrk(pch, " ");
10538                                         if (!pnext)
10539                                                 break;
10540                                         
10541                                         pnext++;
10542                                         if ( *pnext != '\0' )
10543                                         {
10544                                                   strtout = simple_strtoul (pnext , &ptmp, 16);
10545                                                   sprintf( extra, "%s %d" ,extra ,strtout );
10546                                         }
10547                                         else{
10548                                                   break;
10549                                         }
10550                                         pch = pnext;
10551                                 }
10552                         wrqu->length = 7;
10553                         break;
10554                 case 'd':
10555                         // 4 bytes
10556                         //*data = rtw_read32(padapter, addr);
10557                         sprintf(data, "%08x", rtw_read32(padapter, addr));
10558                                 //add read data format blank
10559                                 for( i=0 ; i <= strlen(data) ; i++)
10560                                 {
10561                                           if( i%2==0 )
10562                                           {
10563                                                    tmp[j]=' ';
10564                                                    j++;
10565                                           }
10566                                           if ( data[i] != '\0' )
10567                                           tmp[j] = data[i];
10568                                           
10569                                           j++;
10570                                 }
10571                                 pch = tmp;              
10572                                 DBG_871X("pch=%s",pch);
10573                                 
10574                                 while( *pch != '\0' )
10575                                 {
10576                                         pnext = strpbrk(pch, " ");
10577                                         if (!pnext)
10578                                                 break;
10579                                         
10580                                         pnext++;
10581                                         if ( *pnext != '\0' )
10582                                         {
10583                                                   strtout = simple_strtoul (pnext , &ptmp, 16);
10584                                                   sprintf( extra, "%s %d" ,extra ,strtout );
10585                                         }
10586                                         else{
10587                         break;
10588                                         }
10589                                         pch = pnext;
10590                                 }
10591                         wrqu->length = strlen(extra);
10592                         break;
10593                         
10594                 default:
10595                         wrqu->length = 0;
10596                         ret = -EINVAL;
10597                         break;
10598                         
10599         }
10600
10601         return ret;
10602 }
10603
10604 /*
10605  * Input Format: %d,%x,%x
10606  *      %d is RF path, should be smaller than MAX_RF_PATH_NUMS
10607  *      1st %x is address(offset)
10608  *      2st %x is data to write
10609  */
10610  static int rtw_mp_write_rf(struct net_device *dev,
10611                         struct iw_request_info *info,
10612                         struct iw_point *wrqu, char *extra)
10613 {                       
10614 /*static int rtw_mp_write_rf(struct net_device *dev,
10615                         struct iw_request_info *info,
10616                         union iwreq_data *wrqu, char *extra)
10617 */
10618         u32 path, addr, data;
10619         int ret;
10620         PADAPTER padapter = rtw_netdev_priv(dev);
10621         char input[wrqu->length];
10622
10623         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10624                          return -EFAULT;
10625
10626
10627         ret = sscanf(input, "%d,%x,%x", &path, &addr, &data);
10628         if (ret < 3) return -EINVAL;
10629
10630         if (path >= GET_HAL_RFPATH_NUM(padapter)) return -EINVAL;
10631         if (addr > 0xFF) return -EINVAL;
10632         if (data > 0xFFFFF) return -EINVAL;
10633         
10634         _rtw_memset(extra, 0, wrqu->length);
10635         
10636         write_rfreg(padapter, path, addr, data);
10637         
10638         sprintf(extra, "write_rf completed \n");
10639         wrqu->length = strlen(extra);
10640         
10641         return 0;
10642 }
10643
10644 /*
10645  * Input Format: %d,%x
10646  *      %d is RF path, should be smaller than MAX_RF_PATH_NUMS
10647  *      %x is address(offset)
10648  *
10649  * Return:
10650  *      %d for data readed
10651  */
10652 static int rtw_mp_read_rf(struct net_device *dev,
10653                         struct iw_request_info *info,
10654                         struct iw_point *wrqu, char *extra)
10655 {
10656         char input[wrqu->length];
10657         char *pch, *pnext, *ptmp;
10658         char data[20],tmp[20];
10659         //u32 *data = (u32*)extra;
10660         u32 path, addr;
10661         u32 ret,i=0 ,j=0,strtou=0;
10662         PADAPTER padapter = rtw_netdev_priv(dev);
10663
10664
10665         if (wrqu->length > 128) return -EFAULT;
10666         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10667                 return -EFAULT;
10668
10669         ret = sscanf(input, "%d,%x", &path, &addr);
10670         if (ret < 2) return -EINVAL;
10671
10672         if (path >= GET_HAL_RFPATH_NUM(padapter)) return -EINVAL;
10673         if (addr > 0xFF) return -EINVAL;
10674         
10675         _rtw_memset(extra, 0, wrqu->length);
10676         
10677         //*data = read_rfreg(padapter, path, addr);
10678         sprintf(data, "%08x", read_rfreg(padapter, path, addr));
10679                                 //add read data format blank
10680                                 for( i=0 ; i <= strlen(data) ; i++)
10681                                 {
10682                                           if( i%2==0 )
10683                                           {
10684                                                    tmp[j]=' ';
10685                                                    j++;
10686                                           }
10687                                           tmp[j] = data[i];
10688                                           j++;
10689                                 }
10690                                 pch = tmp;              
10691                                 DBG_871X("pch=%s",pch);
10692                                 
10693                                 while( *pch != '\0' )
10694                                 {
10695                                         pnext = strpbrk(pch, " ");
10696                                         pnext++;
10697                                         if ( *pnext != '\0' )
10698                                         {
10699                                                   strtou = simple_strtoul (pnext , &ptmp, 16);
10700                                                   sprintf( extra, "%s %d" ,extra ,strtou );
10701                                         }
10702                                         else{
10703                                                   break;
10704                                         }
10705                                         pch = pnext;
10706                                 }
10707                         wrqu->length = strlen(extra);   
10708
10709         return 0;
10710 }
10711
10712 static int rtw_mp_start(struct net_device *dev,
10713                         struct iw_request_info *info,
10714                         struct iw_point *wrqu, char *extra)
10715 {
10716         u8 val8;
10717         PADAPTER padapter = rtw_netdev_priv(dev);
10718         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
10719         struct dm_priv  *pdmpriv = &pHalData->dmpriv;
10720         struct hal_ops *pHalFunc = &padapter->HalFunc;
10721
10722         if(padapter->registrypriv.mp_mode ==0)
10723         {
10724                 #if (defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B))
10725                 DBG_871X("_rtw_mp_xmit_priv for Download BT patch FW\n");
10726                 _rtw_mp_xmit_priv(&padapter->xmitpriv);
10727                 #endif
10728                 pHalFunc->hal_deinit(padapter);
10729                 padapter->registrypriv.mp_mode =1;
10730                 pHalFunc->hal_init(padapter);
10731                 rtw_pm_set_ips(padapter,IPS_NONE);
10732                 LeaveAllPowerSaveMode(padapter);
10733
10734                 MPT_InitializeAdapter(padapter, 1);
10735 #ifdef CONFIG_BT_COEXIST
10736                 rtw_btcoex_HaltNotify(padapter);
10737                 rtw_btcoex_SetManualControl(padapter, _TRUE);
10738                 pdmpriv->DMFlag &= ~DYNAMIC_FUNC_BT;
10739                 // Force to switch Antenna to WiFi
10740                 padapter->registrypriv.mp_mode=0;
10741                 pHalFunc->hal_init(padapter);
10742                 padapter->registrypriv.mp_mode=1;
10743                 //rtw_btcoex_HaltNotify(padapter);
10744 #endif
10745         }
10746
10747         if (padapter->registrypriv.mp_mode == 0)
10748                 return -EPERM;
10749
10750         if (padapter->mppriv.mode == MP_OFF) {
10751                 if (mp_start_test(padapter) == _FAIL)
10752                         return -EPERM;
10753                 padapter->mppriv.mode = MP_ON;
10754                 MPT_PwrCtlDM(padapter,0);
10755         }
10756         padapter->mppriv.bmac_filter = _FALSE;
10757 #ifdef CONFIG_RTL8723B
10758         rtw_write8(padapter, 0x66, 0x27); //Open BT uart Log
10759         rtw_write8(padapter, 0xc50, 0x20); //for RX init Gain
10760 #endif  
10761         ODM_Write_DIG(&pHalData->odmpriv,0x20);
10762
10763         return 0;
10764 }
10765
10766 static int rtw_mp_stop(struct net_device *dev,
10767                         struct iw_request_info *info,
10768                         struct iw_point *wrqu, char *extra)
10769 {
10770         PADAPTER padapter = rtw_netdev_priv(dev);
10771         struct hal_ops *pHalFunc = &padapter->HalFunc;
10772
10773         if(padapter->registrypriv.mp_mode ==1)
10774         {
10775                 #if (defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B))
10776                 DBG_871X("_rtw_mp_xmit_priv reinit for normal mode\n");
10777                 _rtw_mp_xmit_priv(&padapter->xmitpriv);
10778                 #endif
10779                 
10780                 MPT_DeInitAdapter(padapter);
10781                 pHalFunc->hal_deinit(padapter);
10782                 padapter->registrypriv.mp_mode=0;
10783                 pHalFunc->hal_init(padapter);
10784         }
10785         
10786         if (padapter->mppriv.mode != MP_OFF) {
10787                 mp_stop_test(padapter);
10788                 padapter->mppriv.mode = MP_OFF;
10789         }
10790
10791         return 0;
10792 }
10793
10794 extern int wifirate2_ratetbl_inx(unsigned char rate);
10795
10796 static int rtw_mp_rate(struct net_device *dev,
10797                         struct iw_request_info *info,
10798                         struct iw_point *wrqu, char *extra)
10799 {
10800         u32 rate = MPT_RATE_1M;
10801         u8              input[wrqu->length];
10802         PADAPTER padapter = rtw_netdev_priv(dev);
10803
10804         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10805                         return -EFAULT;
10806                         
10807         rate = rtw_atoi(input);
10808         sprintf( extra, "Set data rate to %d" , rate );
10809                 
10810         if(rate <= 0x7f)
10811                 rate = wifirate2_ratetbl_inx( (u8)rate);        
10812         else if (rate < 0x90)
10813         //HT  rate 0x80(MCS0)        ~ 0x8F(MCS15)       128~143
10814                 rate =(rate - 0x80 + MPT_RATE_MCS0);
10815         else 
10816                 //VHT rate 0x90(VHT1SS_MCS0) ~ 0x99(VHT1SS_MCS9) 144~153
10817                 rate =(rate - MPT_RATE_VHT1SS_MCS0); 
10818
10819         //DBG_871X("%s: rate=%d\n", __func__, rate);
10820         
10821         if (rate >= MPT_RATE_LAST )     
10822         return -EINVAL;
10823
10824         padapter->mppriv.rateidx = rate;
10825         Hal_SetDataRate(padapter);
10826         
10827         wrqu->length = strlen(extra) + 1;
10828         return 0;
10829 }
10830
10831 static int rtw_mp_channel(struct net_device *dev,
10832                         struct iw_request_info *info,
10833                         struct iw_point *wrqu, char *extra)
10834 {
10835
10836         PADAPTER padapter = rtw_netdev_priv(dev);
10837         HAL_DATA_TYPE   *pHalData       = GET_HAL_DATA(padapter);
10838         u8              input[wrqu->length];
10839         u32     channel = 1;
10840         int cur_ch_offset;
10841
10842         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10843                         return -EFAULT;
10844         
10845         channel = rtw_atoi(input);
10846         //DBG_871X("%s: channel=%d\n", __func__, channel);
10847         sprintf( extra, "Change channel %d to channel %d", padapter->mppriv.channel , channel );
10848         padapter->mppriv.channel = channel;
10849         pHalData->CurrentChannel = channel;
10850         Hal_SetChannel(padapter);
10851
10852         //cur_ch_offset =  rtw_get_offset_by_ch(padapter->mppriv.channel);
10853         //set_channel_bwmode(padapter, padapter->mppriv.channel, cur_ch_offset, padapter->mppriv.bandwidth);
10854         wrqu->length = strlen(extra) + 1;
10855         return 0;
10856 }
10857
10858 static int rtw_mp_bandwidth(struct net_device *dev,
10859                         struct iw_request_info *info,
10860                         struct iw_point *wrqu, char *extra)
10861 {
10862         u32 bandwidth=0, sg=0;
10863         int cur_ch_offset;
10864         //u8 buffer[40];
10865         PADAPTER padapter = rtw_netdev_priv(dev);
10866         HAL_DATA_TYPE   *pHalData       = GET_HAL_DATA(padapter);
10867         //if (copy_from_user(buffer, (void*)wrqu->data.pointer, wrqu->data.length))
10868     //            return -EFAULT;
10869                 
10870         //DBG_871X("%s:iwpriv in=%s\n", __func__, extra);
10871         
10872         sscanf(extra, "40M=%d,shortGI=%d", &bandwidth, &sg);
10873         
10874         if (bandwidth == 1)
10875                 bandwidth=CHANNEL_WIDTH_40;
10876         else if (bandwidth == 2)
10877                 bandwidth=CHANNEL_WIDTH_80;
10878         DBG_871X("%s: bw=%d sg=%d \n", __func__, bandwidth , sg);
10879         
10880         padapter->mppriv.bandwidth = (u8)bandwidth;
10881         pHalData->CurrentChannelBW = bandwidth;
10882         padapter->mppriv.preamble = sg;
10883         
10884         SetBandwidth(padapter);
10885         //cur_ch_offset =  rtw_get_offset_by_ch(padapter->mppriv.channel);
10886         //set_channel_bwmode(padapter, padapter->mppriv.channel, cur_ch_offset, bandwidth);
10887
10888         return 0;
10889 }
10890
10891
10892 static int rtw_mp_txpower_index(struct net_device *dev,
10893                         struct iw_request_info *info,
10894                         struct iw_point *wrqu, char *extra)
10895 {
10896         PADAPTER padapter = rtw_netdev_priv(dev);
10897         char input[wrqu->length];
10898         u32 rfpath;
10899         u32 txpower_inx;
10900
10901         if (wrqu->length > 128)
10902                 return -EFAULT;
10903
10904         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10905                 return -EFAULT;
10906
10907         rfpath = rtw_atoi(input);
10908         txpower_inx = mpt_ProQueryCalTxPower(padapter, rfpath);
10909         sprintf(extra, " %d", txpower_inx);
10910         wrqu->length = strlen(extra) + 1;
10911
10912         return 0;
10913 }
10914
10915
10916 static int rtw_mp_txpower(struct net_device *dev,
10917                         struct iw_request_info *info,
10918                         struct iw_point *wrqu, char *extra)
10919 {
10920         u32             idx_a=0,idx_b=0,MsetPower=1;
10921         u8              input[wrqu->length];
10922
10923         PADAPTER padapter = rtw_netdev_priv(dev);
10924
10925         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10926                         return -EFAULT;
10927
10928         MsetPower = strncmp(input, "off", 3); 
10929         sscanf(input,"patha=%d,pathb=%d",&idx_a,&idx_b);
10930         //DBG_871X("%s: tx_pwr_idx_a=%x b=%x\n", __func__, idx_a, idx_b);
10931         if(MsetPower==0)
10932         {
10933                 padapter->mppriv.bSetTxPower = 0;
10934                 sprintf( extra, "MP Set power off");
10935         }
10936         else
10937         {
10938         sprintf( extra, "Set power level path_A:%d path_B:%d", idx_a , idx_b );
10939         padapter->mppriv.txpoweridx = (u8)idx_a;
10940         padapter->mppriv.txpoweridx_b = (u8)idx_b;
10941         padapter->mppriv.bSetTxPower = 1;
10942                 Hal_SetAntennaPathPower(padapter);
10943         }
10944         wrqu->length = strlen(extra) + 1;
10945         return 0;
10946 }
10947
10948 static int rtw_mp_ant_tx(struct net_device *dev,
10949                         struct iw_request_info *info,
10950                         struct iw_point *wrqu, char *extra)
10951 {
10952         u8 i;
10953         u8              input[wrqu->length];
10954         u16 antenna = 0;
10955         PADAPTER padapter = rtw_netdev_priv(dev);
10956
10957         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10958                         return -EFAULT;
10959                         
10960         //DBG_871X("%s: input=%s\n", __func__, input);  
10961         
10962         sprintf( extra, "switch Tx antenna to %s", input );
10963         
10964         for (i=0; i < strlen(input); i++)
10965         {
10966                 switch(input[i])
10967                         {
10968                                 case 'a' :
10969                                                                 antenna|=ANTENNA_A;
10970                                                                 break;
10971                                 case 'b':
10972                                                                 antenna|=ANTENNA_B;
10973                                                                 break;
10974                         }
10975         }
10976         //antenna |= BIT(extra[i]-'a');
10977         //DBG_871X("%s: antenna=0x%x\n", __func__, antenna);            
10978         padapter->mppriv.antenna_tx = antenna;
10979         //DBG_871X("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_tx);
10980         
10981         Hal_SetAntenna(padapter);
10982
10983         wrqu->length = strlen(extra) + 1;
10984         return 0;
10985 }
10986
10987 static int rtw_mp_ant_rx(struct net_device *dev,
10988                         struct iw_request_info *info,
10989                         struct iw_point *wrqu, char *extra)
10990 {
10991         u8 i;
10992         u16 antenna = 0;
10993         u8              input[wrqu->length];
10994         PADAPTER padapter = rtw_netdev_priv(dev);
10995
10996         if (copy_from_user(input, wrqu->pointer, wrqu->length))
10997                         return -EFAULT;
10998         //DBG_871X("%s: input=%s\n", __func__, input);
10999         _rtw_memset(extra, 0, wrqu->length);
11000         
11001         sprintf( extra, "switch Rx antenna to %s", input );
11002         
11003         for (i=0; i < strlen(input); i++) {
11004         switch( input[i] )
11005                         {
11006                                 case 'a' :
11007                                                                 antenna|=ANTENNA_A;
11008                                                                 break;
11009                                 case 'b':
11010                                                                 antenna|=ANTENNA_B;
11011                                                                 break;
11012                                 case 'c' :
11013                                                                 antenna|=ANTENNA_C;
11014                                                                 break;
11015                         }
11016         }
11017         
11018         //DBG_871X("%s: antenna=0x%x\n", __func__, antenna);            
11019         padapter->mppriv.antenna_rx = antenna;
11020         //DBG_871X("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_rx);
11021         Hal_SetAntenna(padapter);
11022         wrqu->length = strlen(extra);
11023         
11024         return 0;
11025 }
11026
11027 static int rtw_mp_ctx(struct net_device *dev,
11028                         struct iw_request_info *info,
11029                         struct iw_point *wrqu, char *extra)
11030 {
11031         u32 pkTx = 1, countPkTx = 1, cotuTx = 1, CarrSprTx = 1, scTx = 1, sgleTx = 1, stop = 1;
11032         u32 bStartTest = 1;
11033         u32 count = 0,pktinterval=0;
11034         struct mp_priv *pmp_priv;
11035         struct pkt_attrib *pattrib;
11036
11037         PADAPTER padapter = rtw_netdev_priv(dev);
11038
11039
11040         pmp_priv = &padapter->mppriv;
11041
11042         if (copy_from_user(extra, wrqu->pointer, wrqu->length))
11043                         return -EFAULT;
11044                         
11045         DBG_871X("%s: in=%s\n", __func__, extra);
11046
11047         countPkTx = strncmp(extra, "count=", 5); // strncmp TRUE is 0
11048         cotuTx = strncmp(extra, "background", 20);
11049         CarrSprTx = strncmp(extra, "background,cs", 20);
11050         scTx = strncmp(extra, "background,sc", 20);
11051         sgleTx = strncmp(extra, "background,stone", 20);
11052         pkTx = strncmp(extra, "background,pkt", 20);
11053         stop = strncmp(extra, "stop", 4);
11054         sscanf(extra, "count=%d,pkt", &count);
11055         sscanf(extra, "pktinterval=%d", &pktinterval);
11056         
11057         //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);
11058         _rtw_memset(extra, '\0', sizeof(extra));
11059
11060         if( pktinterval !=0 )
11061         {
11062                 sprintf( extra, "Pkt Interval = %d",pktinterval);
11063                 padapter->mppriv.pktInterval = pktinterval;
11064                 
11065                 wrqu->length = strlen(extra);
11066                 return 0;
11067         }
11068         
11069         if (stop == 0) {
11070                 bStartTest = 0; // To set Stop
11071                 pmp_priv->tx.stop = 1;
11072                 sprintf( extra, "Stop continuous Tx");
11073         } else {
11074                 bStartTest = 1;
11075                 if (pmp_priv->mode != MP_ON) {
11076                         if (pmp_priv->tx.stop != 1) {
11077                                 DBG_871X("%s: MP_MODE != ON %d\n", __func__, pmp_priv->mode);
11078                                 return  -EFAULT;
11079                         }
11080                 }
11081         }
11082
11083         if (pkTx == 0 || countPkTx == 0)
11084                 pmp_priv->mode = MP_PACKET_TX;
11085         if (sgleTx == 0)
11086                 pmp_priv->mode = MP_SINGLE_TONE_TX;
11087         if (cotuTx == 0)
11088                 pmp_priv->mode = MP_CONTINUOUS_TX;
11089         if (CarrSprTx == 0)
11090                 pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX;
11091         if (scTx == 0)
11092                 pmp_priv->mode = MP_SINGLE_CARRIER_TX;
11093
11094         switch (pmp_priv->mode)
11095         {
11096                 case MP_PACKET_TX:
11097                 
11098                         //DBG_871X("%s:pkTx %d\n", __func__,bStartTest);
11099                         if (bStartTest == 0)
11100                         {
11101                                 pmp_priv->tx.stop = 1;
11102                                 pmp_priv->mode = MP_ON;
11103                                 sprintf( extra, "Stop continuous Tx");
11104                         }
11105                         else if (pmp_priv->tx.stop == 1)
11106                         {
11107                                 sprintf( extra, "Start continuous DA=ffffffffffff len=1500 count=%u,\n",count);
11108                                 //DBG_871X("%s:countPkTx %d\n", __func__,count);
11109                                 pmp_priv->tx.stop = 0;
11110                                 pmp_priv->tx.count = count;
11111                                 pmp_priv->tx.payload = 2;
11112 #ifdef CONFIG_80211N_HT
11113                                 pmp_priv->tx.attrib.ht_en = 1;
11114 #endif
11115 #ifdef CONFIG_80211AC_VHT
11116                                 pmp_priv->tx.attrib.raid = RATEID_IDX_VHT_1SS; //10
11117 #endif
11118                                 pattrib = &pmp_priv->tx.attrib;
11119                                 pattrib->pktlen = 1000;
11120                                 _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);
11121                                 SetPacketTx(padapter);
11122                         } 
11123                         else {
11124                                 //DBG_871X("%s: pkTx not stop\n", __func__);
11125                                 return -EFAULT;
11126                         }
11127                                 wrqu->length = strlen(extra);
11128                                 return 0;
11129
11130                 case MP_SINGLE_TONE_TX:
11131                         //DBG_871X("%s: sgleTx %d \n", __func__, bStartTest);
11132                         if (bStartTest != 0){
11133                                 sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes.");
11134             }
11135                         Hal_SetSingleToneTx(padapter, (u8)bStartTest);
11136                         break;
11137
11138                 case MP_CONTINUOUS_TX:
11139                         //DBG_871X("%s: cotuTx %d\n", __func__, bStartTest);
11140                         if (bStartTest != 0){
11141                                 sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes.");
11142                          }
11143                 Hal_SetContinuousTx(padapter, (u8)bStartTest);
11144                         break;
11145
11146                 case MP_CARRIER_SUPPRISSION_TX:
11147                         //DBG_871X("%s: CarrSprTx %d\n", __func__, bStartTest);
11148                         if (bStartTest != 0){
11149                                 if( pmp_priv->rateidx <= MPT_RATE_11M ) 
11150                                 {
11151                                         sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes.");
11152                                         
11153                                 }else
11154                                         sprintf( extra, "Specify carrier suppression but not CCK rate");
11155                         }
11156                         Hal_SetCarrierSuppressionTx(padapter, (u8)bStartTest);
11157                         break;
11158
11159                 case MP_SINGLE_CARRIER_TX:
11160                         //DBG_871X("%s: scTx %d\n", __func__, bStartTest);
11161                         if (bStartTest != 0){
11162                                 sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes.");
11163                         }
11164                         Hal_SetSingleCarrierTx(padapter, (u8)bStartTest);
11165                         break;
11166
11167                 default:
11168                         //DBG_871X("%s:No Match MP_MODE\n", __func__);
11169                         sprintf( extra, "Error! Continuous-Tx is not on-going.");
11170                         return -EFAULT;
11171         }
11172
11173         if ( bStartTest==1 && pmp_priv->mode != MP_ON) {
11174                 struct mp_priv *pmp_priv = &padapter->mppriv;
11175                 if (pmp_priv->tx.stop == 0) {
11176                         pmp_priv->tx.stop = 1;
11177                         //DBG_871X("%s: pkt tx is running...\n", __func__);
11178                         rtw_msleep_os(5);
11179                 }
11180 #ifdef CONFIG_80211N_HT
11181                 pmp_priv->tx.attrib.ht_en = 1;
11182 #endif
11183 #ifdef CONFIG_80211AC_VHT
11184                 pmp_priv->tx.attrib.raid = RATEID_IDX_VHT_1SS; //10
11185 #endif
11186                 pmp_priv->tx.stop = 0;
11187                 pmp_priv->tx.count = 1;
11188                 SetPacketTx(padapter);
11189         } else {
11190                 pmp_priv->mode = MP_ON;
11191         }
11192
11193         wrqu->length = strlen(extra);
11194         return 0;
11195 }
11196
11197
11198 static int rtw_mp_disable_bt_coexist(struct net_device *dev,
11199                         struct iw_request_info *info,
11200                         union iwreq_data *wrqu, char *extra)
11201 {
11202         PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
11203         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
11204         struct dm_priv  *pdmpriv = &pHalData->dmpriv;
11205         struct hal_ops *pHalFunc = &padapter->HalFunc;
11206         
11207         u8 input[wrqu->data.length];
11208         u32 bt_coexist;
11209
11210         if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
11211                 return -EFAULT;
11212         
11213         bt_coexist = rtw_atoi(input);
11214         
11215         if( bt_coexist == 0 )
11216         {
11217                 RT_TRACE(_module_mp_, _drv_info_,
11218                         ("Set OID_RT_SET_DISABLE_BT_COEXIST: disable BT_COEXIST\n"));
11219                 DBG_871X("Set OID_RT_SET_DISABLE_BT_COEXIST: disable BT_COEXIST\n");
11220 #ifdef CONFIG_BT_COEXIST
11221                 rtw_btcoex_HaltNotify(padapter);
11222                 rtw_btcoex_SetManualControl(padapter, _TRUE);
11223                 pdmpriv->DMFlag &= ~DYNAMIC_FUNC_BT;
11224                 // Force to switch Antenna to WiFi
11225                 rtw_write16(padapter, 0x870, 0x300);
11226                 rtw_write16(padapter, 0x860, 0x110); 
11227 #endif // CONFIG_BT_COEXIST
11228         }
11229         else
11230         {
11231                 RT_TRACE(_module_mp_, _drv_info_,
11232                         ("Set OID_RT_SET_DISABLE_BT_COEXIST: enable BT_COEXIST\n"));
11233 #ifdef CONFIG_BT_COEXIST                
11234                 pdmpriv->DMFlag |= DYNAMIC_FUNC_BT;
11235                 rtw_btcoex_SetManualControl(padapter, _FALSE);
11236 #endif
11237         }
11238
11239         return 0;       
11240 }
11241
11242
11243 static int rtw_mp_arx(struct net_device *dev,
11244                         struct iw_request_info *info,
11245                         struct iw_point *wrqu, char *extra)
11246 {
11247         u8 bStartRx=0,bStopRx=0,bQueryPhy=0,bQueryMac=0,bSetBssid=0;
11248         u8 bmac_filter = 0,bfilter_init=0;
11249         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;
11250         u32             mac_cck_ok=0, mac_ofdm_ok=0, mac_ht_ok=0, mac_vht_ok=0;
11251         u32             mac_cck_err=0, mac_ofdm_err=0, mac_ht_err=0, mac_vht_err=0;
11252         u8              input[wrqu->length];
11253         char *pch, *ptmp, *token, *tmp[2]={0x00,0x00};
11254         u32 i=0,ii=0,jj=0,kk=0,cnts=0,bmon=0;
11255         PADAPTER padapter = rtw_netdev_priv(dev);
11256         struct mp_priv *pmppriv = &padapter->mppriv;
11257
11258
11259         if (copy_from_user(input, wrqu->pointer, wrqu->length))
11260                         return -EFAULT;
11261
11262         DBG_871X("%s: %s\n", __func__, input);
11263
11264         bStartRx = (strncmp(input, "start", 5)==0)?1:0; // strncmp TRUE is 0
11265         bStopRx = (strncmp(input, "stop", 5)==0)?1:0; // strncmp TRUE is 0
11266         bQueryPhy = (strncmp(input, "phy", 3)==0)?1:0; // strncmp TRUE is 0
11267         bQueryMac = (strncmp(input, "mac", 3)==0)?1:0; // strncmp TRUE is 0
11268         bSetBssid = (strncmp(input, "setbssid=", 8)==0)?1:0; // strncmp TRUE is 0
11269         //bfilter_init = (strncmp(input, "filter_init",11)==0)?1:0;
11270         bmac_filter = (strncmp(input, "accept_mac",10)==0)?1:0;
11271         bmon = (strncmp(input, "mon=",4)==0)?1:0;
11272
11273
11274         if(bSetBssid==1){
11275                 pch = input;
11276                 while ((token = strsep(&pch, "=")) != NULL)
11277                 {
11278                         if (i > 1) break;
11279                         tmp[i] = token;
11280                         i++;
11281                 }
11282                 if ((tmp[0]==NULL) && (tmp[1]==NULL)){
11283                         return -EFAULT;
11284                 }
11285                 else{
11286                         cnts = strlen(tmp[1])/2;
11287                         if (cnts<1) return -EFAULT;
11288                         DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
11289                         DBG_871X("%s: data=%s\n", __FUNCTION__, tmp[1]);
11290                         for (jj=0, kk=0; jj < cnts ; jj++, kk+=2){
11291                                          pmppriv->network_macaddr[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
11292                                         DBG_871X("network_macaddr[%d]=%x \n",jj, pmppriv->network_macaddr[jj]);
11293                         }
11294                 }
11295                 pmppriv->bSetRxBssid = _TRUE;
11296         }
11297
11298         if(bmac_filter)
11299         {
11300                 pmppriv->bmac_filter = bmac_filter;
11301                 pch = input;
11302                 while ((token = strsep(&pch, "=")) != NULL)
11303                 {
11304                         if (i > 1) break;
11305                         tmp[i] = token;
11306                         i++;
11307                 }
11308                 if ((tmp[0]==NULL) && (tmp[1]==NULL)){
11309                         return -EFAULT;
11310                 }
11311                 else{
11312                         cnts = strlen(tmp[1])/2;
11313                         if (cnts<1) return -EFAULT;
11314                         DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
11315                         DBG_871X("%s: data=%s\n", __FUNCTION__, tmp[1]);
11316                         for (jj=0, kk=0; jj < cnts ; jj++, kk+=2){
11317                                         pmppriv->mac_filter[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
11318                                         DBG_871X("%s mac_filter[%d]=%x \n",__FUNCTION__,jj, pmppriv->mac_filter[jj]);
11319                         }
11320                 }
11321         }
11322         
11323         if(bStartRx)
11324         {
11325                 sprintf( extra, "start");
11326                 SetPacketRx(padapter, bStartRx);
11327         }
11328         else if(bStopRx)
11329         {
11330                 SetPacketRx(padapter, 0);
11331                 pmppriv->bmac_filter = _FALSE;
11332                 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);
11333         }
11334         else if(bQueryPhy)
11335         {          
11336
11337                 if (IS_HARDWARE_TYPE_JAGUAR(padapter)) 
11338                 {
11339                         cckok      = PHY_QueryBBReg(padapter, 0xF04, 0x3FFF);        // [13:0]  
11340                         ofdmok     = PHY_QueryBBReg(padapter, 0xF14, 0x3FFF);        // [13:0]  
11341                         htok       = PHY_QueryBBReg(padapter, 0xF10, 0x3FFF);     // [13:0]
11342                         vht_ok      = PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF);     // [13:0]
11343                                                                   
11344                         cckcrc     = PHY_QueryBBReg(padapter, 0xF04, 0x3FFF0000); // [29:16]                                            
11345                         ofdmcrc    = PHY_QueryBBReg(padapter, 0xF14, 0x3FFF0000); // [29:16]
11346                         htcrc      = PHY_QueryBBReg(padapter, 0xF10, 0x3FFF0000); // [29:16]            
11347                         vht_err     = PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF0000); // [29:16]           
11348                         
11349                         CCK_FA = PHY_QueryBBReg(padapter, 0xa5c, bMaskLWord);
11350                         OFDM_FA = PHY_QueryBBReg(padapter, 0xF48, bMaskLWord);
11351                 } 
11352                 else
11353                 {
11354                         cckok      = PHY_QueryBBReg(padapter, 0xF88, bMaskDWord);               
11355                         ofdmok     = PHY_QueryBBReg(padapter, 0xF94, bMaskLWord);               
11356                         htok       = PHY_QueryBBReg(padapter, 0xF90, bMaskLWord);
11357                         vht_ok      = 0;
11358                     
11359                         cckcrc     = PHY_QueryBBReg(padapter, 0xF84, bMaskDWord);                                               
11360                         ofdmcrc    = PHY_QueryBBReg(padapter, 0xF94, bMaskHWord);
11361                         htcrc      = PHY_QueryBBReg(padapter, 0xF90, bMaskHWord);               
11362                         vht_err     = 0;
11363                 
11364                 OFDM_FA = PHY_QueryBBReg(padapter, 0xCF0, bMaskLWord) + PHY_QueryBBReg(padapter, 0xCF2, bMaskLWord) + 
11365                                         PHY_QueryBBReg(padapter, 0xDA2, bMaskLWord)+ PHY_QueryBBReg(padapter, 0xDA4, bMaskLWord) + 
11366                                         PHY_QueryBBReg(padapter, 0xDA6, bMaskLWord) + PHY_QueryBBReg(padapter, 0xDA8, bMaskLWord);
11367                 
11368                 CCK_FA=(rtw_read8(padapter, 0xa5b )<<8 ) | (rtw_read8(padapter, 0xa5c));
11369                 }
11370                 DBG_871X("%s: OFDM_FA =%d\n", __FUNCTION__, OFDM_FA);
11371                 DBG_871X("%s: CCK_FA =%d\n", __FUNCTION__, CCK_FA);
11372                 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);
11373         }
11374         else if(bQueryMac)
11375         {
11376                 // for 8723A
11377                 {
11378                         PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x3);
11379                         mac_cck_ok      = PHY_QueryMacReg(padapter, 0x664, bMaskLWord);      // [15:0]    
11380                         PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x0);
11381                         mac_ofdm_ok     = PHY_QueryMacReg(padapter, 0x664, bMaskLWord);      // [15:0]   
11382                         PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x6);
11383                         mac_ht_ok       = PHY_QueryMacReg(padapter, 0x664, bMaskLWord);     // [15:0]   
11384                         mac_vht_ok      = 0;
11385                         
11386                         PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x4);
11387                         mac_cck_err     = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0]       
11388                         PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x1);
11389                         mac_ofdm_err    = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0]       
11390                         PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x7);
11391                         mac_ht_err      = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0]               
11392                         mac_vht_err     = 0;
11393                         //Mac_DropPacket
11394                         rtw_write32(padapter, 0x664, (rtw_read32(padapter, 0x0664)& 0x0FFFFFFF)| Mac_DropPacket);
11395                         DropPacket = rtw_read32(padapter, 0x664)& 0x0000FFFF;
11396                 } 
11397                 
11398                 sprintf( extra, "Mac Received packet OK: %d , CRC error: %d , Drop Packets: %d\n",
11399                                 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);                        
11400         }
11401
11402
11403
11404         if( bmon==1 ) {
11405                 sscanf(input, "mon=%d", &bmon);
11406                 if(bmon==1)             {
11407                 pmppriv->rx_bindicatePkt= _TRUE;        
11408                 sprintf( extra, "Indicating Receive Packet to network start\n");
11409                 }else {                 
11410                         pmppriv->rx_bindicatePkt= _FALSE;                       
11411                         sprintf( extra, "Indicating Receive Packet to network Stop\n");
11412                 }
11413         }
11414         wrqu->length = strlen(extra) + 1;
11415
11416         
11417         return 0;
11418 }
11419
11420 static int rtw_mp_trx_query(struct net_device *dev,
11421                         struct iw_request_info *info,
11422                         struct iw_point *wrqu, char *extra)
11423 {
11424         u32 txok,txfail,rxok,rxfail,rxfilterout;
11425         PADAPTER padapter = rtw_netdev_priv(dev);
11426         //if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
11427         //      return -EFAULT;
11428
11429         txok=padapter->mppriv.tx.sended;
11430         txfail=0;
11431         rxok = padapter->mppriv.rx_pktcount;
11432         rxfail = padapter->mppriv.rx_crcerrpktcount;
11433         rxfilterout = padapter->mppriv.rx_pktcount_filter_out;
11434
11435         _rtw_memset(extra, '\0', 128);
11436
11437         sprintf(extra, "Tx OK:%d, Tx Fail:%d, Rx OK:%d, CRC error:%d ,Rx Filter out:%d \n", txok, txfail,rxok,rxfail,rxfilterout);
11438
11439         wrqu->length=strlen(extra)+1;
11440
11441         return 0;
11442 }
11443
11444 static int rtw_mp_pwrtrk(struct net_device *dev,
11445                         struct iw_request_info *info,
11446                         struct iw_point *wrqu, char *extra)
11447 {
11448         u8 enable;
11449         u32 thermal;
11450         s32 ret;
11451         PADAPTER padapter = rtw_netdev_priv(dev);
11452         HAL_DATA_TYPE                   *pHalData = GET_HAL_DATA(padapter);
11453         u8              input[wrqu->length];
11454
11455         if (copy_from_user(input, wrqu->pointer, wrqu->length))
11456                         return -EFAULT;
11457
11458         _rtw_memset(extra, 0, wrqu->length);
11459
11460         enable = 1;
11461         if (wrqu->length > 1) { // not empty string
11462                 if (strncmp(input, "stop", 4) == 0)
11463                 {       
11464                         enable = 0;
11465                         sprintf(extra, "mp tx power tracking stop");
11466                         pHalData->TxPowerTrackControl = _FALSE;
11467                 }
11468                 else if (sscanf(input, "ther=%d", &thermal)) {
11469                         pHalData->TxPowerTrackControl = _TRUE;
11470                                 ret = Hal_SetThermalMeter(padapter, (u8)thermal);
11471                                 if (ret == _FAIL) return -EPERM;
11472                                 sprintf(extra, "mp tx power tracking start,target value=%d ok ",thermal);
11473                 }else   {
11474                                 return -EINVAL;
11475                 }
11476         }
11477
11478         ret = Hal_SetPowerTracking(padapter, enable);
11479         if (ret == _FAIL) return -EPERM;
11480
11481         wrqu->length = strlen(extra);
11482
11483         return 0;
11484 }
11485
11486 static int rtw_mp_psd(struct net_device *dev,
11487                         struct iw_request_info *info,
11488                         struct iw_point *wrqu, char *extra)
11489 {
11490         PADAPTER padapter = rtw_netdev_priv(dev);
11491         u8              input[wrqu->length];
11492         
11493         if (copy_from_user(input, wrqu->pointer, wrqu->length))
11494                 return -EFAULT;
11495         
11496         strcpy(extra,input);
11497         
11498         wrqu->length = mp_query_psd(padapter, extra);
11499         
11500         return 0;
11501 }
11502
11503 static int rtw_mp_thermal(struct net_device *dev,
11504                         struct iw_request_info *info,
11505                         struct iw_point *wrqu, char *extra)
11506 {
11507         u8 val;
11508         u16 bwrite=1;
11509         
11510         #ifdef CONFIG_RTL8192C
11511                         u16 addr=EEPROM_THERMAL_METER_92C;
11512         #endif
11513         #ifdef CONFIG_RTL8192D
11514                         u16 addr=EEPROM_THERMAL_METER_92D;
11515         #endif
11516         #ifdef CONFIG_RTL8723A
11517                         u16 addr=EEPROM_THERMAL_METER_8723A;
11518         #endif
11519         #ifdef CONFIG_RTL8188E
11520                         u16 addr=EEPROM_THERMAL_METER_88E;
11521         #endif
11522         #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11523                         u16 addr=EEPROM_THERMAL_METER_8812;
11524         #endif
11525         #ifdef CONFIG_RTL8192E
11526                         u16 addr=EEPROM_THERMAL_METER_8192E;
11527         #endif
11528         #ifdef CONFIG_RTL8723B
11529                         u16 addr=EEPROM_THERMAL_METER_8723B;
11530         #endif
11531         u16 cnt=1;
11532         u16 max_available_size=0;
11533         PADAPTER padapter = rtw_netdev_priv(dev);       
11534
11535         if (copy_from_user(extra, wrqu->pointer, wrqu->length))
11536                 return -EFAULT;
11537
11538         //DBG_871X("print extra %s \n",extra); 
11539          
11540          bwrite = strncmp(extra, "write", 6); // strncmp TRUE is 0
11541          
11542          Hal_GetThermalMeter(padapter, &val);
11543          
11544          if( bwrite == 0 )      
11545          {
11546                  //DBG_871X("to write val:%d",val);
11547                         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
11548                         if( 2 > max_available_size )
11549                         {                       
11550                                 DBG_871X("no available efuse!\n");
11551                                 return -EFAULT;
11552                         }       
11553                         if ( rtw_efuse_map_write(padapter, addr, cnt, &val) == _FAIL )
11554                         {
11555                                 DBG_871X("rtw_efuse_map_write error \n");                       
11556                                 return -EFAULT;
11557                         } 
11558                         else
11559                         {
11560                                  sprintf(extra, " efuse write ok :%d", val);    
11561                         }
11562           }
11563           else
11564           {
11565                          sprintf(extra, "%d", val);
11566           }
11567         wrqu->length = strlen(extra);
11568         
11569         return 0;
11570 }
11571
11572 static int rtw_mp_reset_stats(struct net_device *dev,
11573                         struct iw_request_info *info,
11574                         struct iw_point *wrqu, char *extra)
11575 {
11576         struct mp_priv *pmp_priv;
11577         struct pkt_attrib *pattrib;
11578         PADAPTER padapter = rtw_netdev_priv(dev);
11579         
11580         pmp_priv = &padapter->mppriv;
11581         
11582         pmp_priv->tx.sended = 0;
11583         pmp_priv->tx_pktcount = 0;
11584         pmp_priv->rx_pktcount = 0;
11585         pmp_priv->rx_pktcount_filter_out=0;
11586         pmp_priv->rx_crcerrpktcount = 0;
11587
11588         //reset phy counter
11589         if (IS_HARDWARE_TYPE_JAGUAR(padapter))
11590         {
11591                 write_bbreg(padapter, 0xB58, BIT0, 0x1);
11592                 write_bbreg(padapter, 0xB58, BIT0, 0x0);
11593
11594                 write_bbreg(padapter, 0x9A4, BIT17, 0x1);//reset  OFDA FA counter
11595                 write_bbreg(padapter, 0x9A4, BIT17, 0x0);
11596                 
11597                 write_bbreg(padapter, 0xA5C, BIT15, 0x0);//reset  CCK FA counter
11598                 write_bbreg(padapter, 0xA5C, BIT15, 0x1);
11599         }
11600         else
11601         {
11602                 write_bbreg(padapter, 0xF14, BIT16, 0x1);
11603                 rtw_msleep_os(10);
11604                 write_bbreg(padapter, 0xF14, BIT16, 0x0);
11605                 
11606                 write_bbreg(padapter, 0xD00, BIT27, 0x1);//reset  OFDA FA counter
11607                 write_bbreg(padapter, 0xC0C, BIT31, 0x1);//reset  OFDA FA counter
11608                 write_bbreg(padapter, 0xD00, BIT27, 0x0);
11609                 write_bbreg(padapter, 0xC0C, BIT31, 0x0);
11610                 
11611                 write_bbreg(padapter, 0xA2C, BIT15, 0x0);//reset  CCK FA counter
11612                 write_bbreg(padapter, 0xA2C, BIT15, 0x1);
11613         }
11614         //reset mac counter
11615         PHY_SetMacReg(padapter, 0x664, BIT27, 0x1); 
11616         PHY_SetMacReg(padapter, 0x664, BIT27, 0x0);
11617         return 0;
11618 }
11619
11620 static int rtw_mp_dump(struct net_device *dev,
11621                         struct iw_request_info *info,
11622                         struct iw_point *wrqu, char *extra)
11623 {
11624         struct mp_priv *pmp_priv;
11625         struct pkt_attrib *pattrib;
11626         u32 value;
11627     u8          input[wrqu->length];
11628         u8 rf_type,path_nums = 0;
11629         u32 i,j=1,path;
11630         PADAPTER padapter = rtw_netdev_priv(dev);
11631         
11632         pmp_priv = &padapter->mppriv;
11633
11634         if (copy_from_user(input, wrqu->pointer, wrqu->length))
11635                 return -EFAULT;
11636         
11637         if ( strncmp(input, "all", 4)==0 )
11638         {
11639                 mac_reg_dump(RTW_DBGDUMP, padapter);
11640                 bb_reg_dump(RTW_DBGDUMP, padapter);
11641                 rf_reg_dump(RTW_DBGDUMP, padapter);
11642         }
11643         return 0;
11644 }
11645
11646 static int rtw_mp_phypara(struct net_device *dev,
11647                         struct iw_request_info *info,
11648                         struct iw_point *wrqu, char *extra)
11649 {
11650
11651         PADAPTER padapter = rtw_netdev_priv(dev);
11652         HAL_DATA_TYPE   *pHalData       = GET_HAL_DATA(padapter);
11653         char    input[wrqu->length];
11654         u32             valxcap;
11655         
11656         if (copy_from_user(input, wrqu->pointer, wrqu->length))
11657                         return -EFAULT;
11658         
11659         DBG_871X("%s:iwpriv in=%s\n", __func__, input);
11660         
11661         sscanf(input, "xcap=%d", &valxcap);
11662
11663         pHalData->CrystalCap = (u8)valxcap;
11664         Hal_ProSetCrystalCap( padapter , valxcap );
11665
11666         sprintf( extra, "Set xcap=%d",valxcap );
11667         wrqu->length = strlen(extra) + 1;
11668         
11669 return 0;
11670
11671 }
11672
11673 static int rtw_mp_SetRFPath(struct net_device *dev,
11674                         struct iw_request_info *info,
11675                         union iwreq_data *wrqu, char *extra)
11676 {
11677         PADAPTER padapter = rtw_netdev_priv(dev);
11678         char    input[wrqu->data.length];
11679         s32             bMain=1,bTurnoff=1;
11680         
11681         if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
11682                         return -EFAULT;
11683         DBG_871X("%s:iwpriv in=%s\n", __func__, input); 
11684         
11685         bMain = strncmp(input, "1", 2); // strncmp TRUE is 0
11686         bTurnoff = strncmp(input, "0", 3); // strncmp TRUE is 0
11687
11688         if(bMain==0)
11689         {
11690                 MP_PHY_SetRFPathSwitch(padapter,_TRUE);
11691                 DBG_871X("%s:PHY_SetRFPathSwitch=TRUE\n", __func__);    
11692         }
11693         else if(bTurnoff==0)
11694         {
11695                 MP_PHY_SetRFPathSwitch(padapter,_FALSE);
11696                 DBG_871X("%s:PHY_SetRFPathSwitch=FALSE\n", __func__);   
11697         }
11698         
11699         return 0;
11700 }
11701
11702 static int rtw_mp_QueryDrv(struct net_device *dev,
11703                         struct iw_request_info *info,
11704                         union iwreq_data *wrqu, char *extra)
11705 {
11706         PADAPTER padapter = rtw_netdev_priv(dev);
11707         char    input[wrqu->data.length];
11708         s32     qAutoLoad=1;
11709
11710         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
11711         
11712         if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
11713                         return -EFAULT;
11714         DBG_871X("%s:iwpriv in=%s\n", __func__, input); 
11715         
11716         qAutoLoad = strncmp(input, "autoload", 8); // strncmp TRUE is 0
11717
11718         if(qAutoLoad==0)
11719         {
11720                 DBG_871X("%s:qAutoLoad\n", __func__);
11721                 
11722                 if(pEEPROM->bautoload_fail_flag)
11723                         sprintf(extra, "fail");
11724                 else
11725                 sprintf(extra, "ok");      
11726         }
11727                 wrqu->data.length = strlen(extra) + 1;
11728         return 0;
11729 }
11730
11731 /* update Tx AGC offset */
11732 static int rtw_mp_antBdiff(struct net_device *dev,
11733                         struct iw_request_info *info,
11734                         struct iw_point *wrqu, char *extra)
11735 {
11736
11737
11738         // MPT_ProSetTxAGCOffset
11739         return 0;
11740 }
11741
11742
11743 static int rtw_mp_PwrCtlDM(struct net_device *dev,
11744                         struct iw_request_info *info,
11745                         struct iw_point *wrqu, char *extra)
11746 {
11747         PADAPTER padapter = rtw_netdev_priv(dev);
11748         u8              input[wrqu->length];
11749         u8              bstart=1;
11750         
11751         if (copy_from_user(input, wrqu->pointer, wrqu->length))
11752                         return -EFAULT;
11753
11754         bstart = strncmp(input, "start", 5); // strncmp TRUE is 0
11755         if(bstart==0){
11756                 sprintf(extra, "PwrCtlDM start \n");
11757                 MPT_PwrCtlDM(padapter,1);
11758         }else{
11759                 sprintf(extra, "PwrCtlDM stop \n");
11760                 MPT_PwrCtlDM(padapter,0);
11761         }
11762         wrqu->length = strlen(extra);
11763
11764         return 0;
11765 }
11766
11767 #if (defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B))
11768 /* update Tx AGC offset */
11769 static int rtw_mp_SetBT(struct net_device *dev,
11770                         struct iw_request_info *info,
11771                         union iwreq_data *wrqu, char *extra)
11772 {
11773         PADAPTER padapter = rtw_netdev_priv(dev);
11774         struct hal_ops *pHalFunc = &padapter->HalFunc;
11775         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
11776         
11777         BT_REQ_CMD      BtReq;
11778         PMPT_CONTEXT    pMptCtx=&(padapter->mppriv.MptCtx);
11779         PBT_RSP_CMD     pBtRsp=(PBT_RSP_CMD)&pMptCtx->mptOutBuf[0];
11780         char    input[128];
11781         char *pch, *ptmp, *token, *tmp[2]={0x00,0x00};
11782         u8 setdata[100];
11783         u8 resetbt=0x00;
11784         u8 tempval,BTStatus;
11785         u8 H2cSetbtmac[6];
11786         u8 u1H2CBtMpOperParm[4]={0x01};
11787         u16 testmode=1,ready=1,trxparam=1,setgen=1,getgen=1,testctrl=1,testbt=1,readtherm=1,setbtmac=1;
11788         u32 i=0,ii=0,jj=0,kk=0,cnts=0,status=0;
11789         PRT_MP_FIRMWARE pBTFirmware = NULL;
11790         
11791         if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
11792                         return -EFAULT;
11793         if(strlen(extra)<1) return -EFAULT;
11794         
11795         DBG_871X("%s:iwpriv in=%s\n", __FUNCTION__, extra); 
11796         ready = strncmp(extra, "ready", 5); 
11797         testmode = strncmp(extra, "testmode", 8); // strncmp TRUE is 0
11798         trxparam = strncmp(extra, "trxparam", 8); 
11799         setgen = strncmp(extra, "setgen", 6);
11800         getgen = strncmp(extra, "getgen", 6); 
11801         testctrl = strncmp(extra, "testctrl", 8);
11802         testbt = strncmp(extra, "testbt", 6);
11803         readtherm = strncmp(extra, "readtherm", 9);
11804         setbtmac = strncmp(extra, "setbtmac", 8);
11805
11806         if ( strncmp(extra, "dlbt", 4) == 0)
11807         {
11808                 pHalData->LastHMEBoxNum=0;
11809                 padapter->bBTFWReady = _FALSE;
11810                 rtw_write8(padapter, 0xa3, 0x05);
11811                 BTStatus=rtw_read8(padapter, 0xa0);
11812                 DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus);
11813                 if (BTStatus != 0x04)
11814                 {
11815                         sprintf(extra, "BT Status not Active DLFW FAIL\n");
11816                         goto exit;
11817                 }
11818
11819                 tempval = rtw_read8(padapter, 0x6B);
11820                 tempval |= BIT7;
11821                 rtw_write8(padapter, 0x6B, tempval);
11822
11823                 // Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay
11824                 // So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together!
11825                 rtw_usleep_os(100);
11826                 // disable BT power cut
11827                 // 0x6A[14] = 0
11828                 tempval = rtw_read8(padapter, 0x6B);
11829                 tempval &= ~BIT6;
11830                 rtw_write8(padapter, 0x6B, tempval);
11831                 rtw_usleep_os(100);
11832                 MPT_PwrCtlDM(padapter,0);
11833                 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)| 0x00000004));
11834                 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)& 0xFFFFFFEF));
11835                 rtw_msleep_os(600);
11836                 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)| 0x00000010));
11837                 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)& 0xFFFFFFFB));
11838                 rtw_msleep_os(1200);            
11839                 pBTFirmware = (PRT_MP_FIRMWARE)rtw_zmalloc(sizeof(RT_MP_FIRMWARE));
11840                 if(pBTFirmware==NULL)
11841                         goto exit;
11842                 padapter->bBTFWReady = _FALSE;
11843                 FirmwareDownloadBT(padapter, pBTFirmware);
11844                 if (pBTFirmware)
11845                         rtw_mfree((u8*)pBTFirmware, sizeof(RT_MP_FIRMWARE));
11846                         
11847                 DBG_871X("Wait for FirmwareDownloadBT fw boot!\n");
11848                 rtw_msleep_os(2000);
11849                 _rtw_memset(extra,'\0', wrqu->data.length);
11850                 BtReq.opCodeVer = 1;
11851                 BtReq.OpCode = 0;
11852                 BtReq.paraLength = 0;
11853                 mptbt_BtControlProcess(padapter, &BtReq);
11854                 rtw_msleep_os(100);
11855
11856                 DBG_8192C("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4],pMptCtx->mptOutBuf[5]);
11857                 if( (pMptCtx->mptOutBuf[4]==0x00) && (pMptCtx->mptOutBuf[5]==0x00))
11858                         {
11859                                 if(padapter->mppriv.bTxBufCkFail==_TRUE)
11860                                         sprintf(extra, "check TxBuf Fail.\n");
11861                                 else
11862                                         sprintf(extra, "download FW Fail.\n");
11863                         }
11864                         else
11865                         {
11866                                 sprintf(extra, "download FW OK.\n");
11867                                 goto exit;
11868                         }
11869                 goto exit;
11870                 goto exit;      
11871         }
11872         if ( strncmp(extra, "dlfw", 4) == 0)
11873         {
11874                 #ifdef CONFIG_BT_COEXIST
11875                 rtw_btcoex_HaltNotify(padapter);
11876                 //DBG_871X("SetBT bt1ant !\n");
11877                 //hal_btcoex1ant_SetAntPath(padapter);
11878                 rtw_btcoex_SetManualControl(padapter, _TRUE);
11879                 #endif
11880                 pHalData->LastHMEBoxNum=0;
11881                 padapter->bBTFWReady = _FALSE;
11882                 rtw_write8(padapter, 0xa3, 0x05);
11883                 BTStatus=rtw_read8(padapter, 0xa0);
11884                 DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus);
11885                 if (BTStatus != 0x04)
11886                 {
11887                         sprintf(extra, "BT Status not Active DLFW FAIL\n");
11888                         goto exit;
11889                 }
11890
11891                 tempval = rtw_read8(padapter, 0x6B);
11892                 tempval |= BIT7;
11893                 rtw_write8(padapter, 0x6B, tempval);
11894
11895                 // Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay
11896                 // So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together!
11897                 rtw_usleep_os(100);
11898                 // disable BT power cut
11899                 // 0x6A[14] = 0
11900                 tempval = rtw_read8(padapter, 0x6B);
11901                 tempval &= ~BIT6;
11902                 rtw_write8(padapter, 0x6B, tempval);
11903                 rtw_usleep_os(100);
11904         
11905                 MPT_PwrCtlDM(padapter,0);
11906                 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)| 0x00000004));
11907                 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)& 0xFFFFFFEF));
11908                 rtw_msleep_os(600);
11909                 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)| 0x00000010));
11910                 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)& 0xFFFFFFFB));
11911                 rtw_msleep_os(1200);
11912
11913 #if defined(CONFIG_PLATFORM_SPRD) && (MP_DRIVER == 1)
11914                 // Pull up BT reset pin.
11915                 DBG_871X("%s: pull up BT reset pin when bt start mp test\n", __FUNCTION__);
11916                 rtw_wifi_gpio_wlan_ctrl(WLAN_BT_PWDN_ON);
11917 #endif
11918                 DBG_871X(" rtl8723a_FirmwareDownload!\n");
11919
11920 #ifdef CONFIG_RTL8723A
11921                 status = rtl8723a_FirmwareDownload(padapter);
11922 #elif defined(CONFIG_RTL8723B)
11923                 status = rtl8723b_FirmwareDownload(padapter, _FALSE);
11924 #endif
11925                 DBG_871X("Wait for FirmwareDownloadBT fw boot!\n");
11926                 rtw_msleep_os(1000);
11927                 _rtw_memset(extra,'\0', wrqu->data.length);
11928                 BtReq.opCodeVer = 1;
11929                 BtReq.OpCode = 0;
11930                 BtReq.paraLength = 0;
11931                 mptbt_BtControlProcess(padapter, &BtReq);
11932                 rtw_msleep_os(200);
11933
11934                 DBG_8192C("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4],pMptCtx->mptOutBuf[5]);
11935                 if( (pMptCtx->mptOutBuf[4]==0x00) && (pMptCtx->mptOutBuf[5]==0x00))
11936                         {
11937                                 if(padapter->mppriv.bTxBufCkFail==_TRUE)
11938                                         sprintf(extra, "check TxBuf Fail.\n");
11939                                 else
11940                                         sprintf(extra, "download FW Fail.\n");
11941                         }
11942                         else
11943                         {
11944                                 #ifdef CONFIG_BT_COEXIST
11945                                 rtw_btcoex_SwitchGntBt(padapter);
11946                                 #endif
11947                                 rtw_msleep_os(200);
11948                                 sprintf(extra, "download FW OK.\n");
11949                                 goto exit;
11950                         }
11951                 goto exit;
11952         }
11953
11954         if ( strncmp(extra, "down", 4) == 0){
11955                 DBG_871X("SetBT down for to hal_init !\n");
11956                 mp_stop_test(padapter);
11957                 pHalFunc->hal_init(padapter);
11958                 mp_start_test(padapter);
11959                 MPT_PwrCtlDM(padapter,0);
11960                 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)| 0x00000004));
11961                 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)& 0xFFFFFFEF));
11962                 rtw_msleep_os(600);
11963                         //rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFE));
11964                 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)| 0x00000010));
11965                 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)& 0xFFFFFFFB));
11966                 rtw_msleep_os(1200);
11967                 goto exit;
11968         }
11969         if ( strncmp(extra, "disable", 7) == 0){
11970                 DBG_871X("SetBT disable !\n");
11971                 rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFB));
11972                 rtw_msleep_os(500);
11973                 goto exit;
11974                 }
11975         if ( strncmp(extra, "enable", 6) == 0){
11976                 DBG_871X("SetBT enable !\n");
11977                 rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)| 0x00000004));
11978                 rtw_msleep_os(500);
11979                 goto exit;
11980         }
11981         if ( strncmp(extra, "h2c", 3) == 0){
11982                         DBG_871X("SetBT h2c !\n");
11983                         padapter->bBTFWReady = _TRUE;
11984                         FillH2CCmd(padapter, 0x63, 1, u1H2CBtMpOperParm);
11985                         goto exit;
11986                 }
11987         if ( strncmp(extra, "2ant", 4) == 0){
11988                 DBG_871X("Set BT 2ant use!\n");
11989                 PHY_SetMacReg(padapter,0x67,BIT5,0x1);
11990                 rtw_write32(padapter, 0x948, 0000);
11991                 
11992                 goto exit;
11993         }
11994                 
11995         if( ready!=0 && testmode!=0 && trxparam!=0 && setgen!=0 && getgen!=0 && testctrl!=0 && testbt!=0 && readtherm!=0 &&setbtmac!=0)
11996                 return -EFAULT;
11997                 
11998         if( testbt==0 )
11999         {
12000                         BtReq.opCodeVer=1;
12001                         BtReq.OpCode=6;
12002                         BtReq.paraLength=cnts/2;
12003                         goto todo;
12004         }
12005         if( ready==0 )
12006         {
12007                 BtReq.opCodeVer=1;
12008                 BtReq.OpCode=0;
12009                 BtReq.paraLength=0; 
12010                 goto todo;
12011         }
12012
12013         pch = extra;    
12014         i = 0;
12015         while ((token = strsep(&pch, ",")) != NULL)
12016         {
12017                 if (i > 1) break;
12018                 tmp[i] = token;
12019                 i++;
12020         }
12021
12022         if ((tmp[0]==NULL) && (tmp[1]==NULL))
12023         {
12024                 return -EFAULT;
12025         }
12026         else
12027         {
12028                 cnts = strlen(tmp[1]);
12029                 if (cnts<1) return -EFAULT;
12030         
12031                 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
12032                 DBG_871X("%s: data=%s\n", __FUNCTION__, tmp[1]);
12033                                 
12034                 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
12035                 {
12036                         BtReq.pParamStart[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
12037 //                      DBG_871X("BtReq.pParamStart[%d]=0x%02x\n", jj, BtReq.pParamStart[jj]);
12038                 }
12039         }
12040         
12041         if( testmode==0 )       
12042         {
12043                 BtReq.opCodeVer=1;
12044                 BtReq.OpCode=1;
12045                 BtReq.paraLength=1; 
12046         }
12047         if( trxparam==0 )
12048         {
12049                 BtReq.opCodeVer=1;
12050                 BtReq.OpCode=2;
12051                 BtReq.paraLength=cnts/2; 
12052         }
12053         if( setgen==0 )
12054         {       
12055                 DBG_871X("%s: BT_SET_GENERAL \n", __func__); 
12056                 BtReq.opCodeVer=1;
12057                 BtReq.OpCode=3; //BT_SET_GENERAL        3
12058                 BtReq.paraLength=cnts/2;        
12059         }
12060         if( getgen==0 )
12061         {       
12062                 DBG_871X("%s: BT_GET_GENERAL \n", __func__); 
12063                 BtReq.opCodeVer=1;
12064                 BtReq.OpCode=4;         //BT_GET_GENERAL        4
12065                 BtReq.paraLength=cnts/2;        
12066         }
12067         if( readtherm==0 )
12068         {       
12069                 DBG_871X("%s: BT_GET_GENERAL \n", __func__); 
12070                 BtReq.opCodeVer=1;
12071                 BtReq.OpCode=4;         //BT_GET_GENERAL        4
12072                 BtReq.paraLength=cnts/2;        
12073         }
12074         
12075         if( testctrl==0 )
12076         {       
12077                 DBG_871X("%s: BT_TEST_CTRL \n", __func__);
12078                 BtReq.opCodeVer=1;
12079                 BtReq.OpCode=5;         //BT_TEST_CTRL  5
12080                 BtReq.paraLength=cnts/2;        
12081         }
12082
12083         DBG_871X("%s: Req opCodeVer=%d OpCode=%d paraLength=%d\n",
12084                 __FUNCTION__, BtReq.opCodeVer, BtReq.OpCode, BtReq.paraLength);
12085
12086         if(BtReq.paraLength<1)
12087                 goto todo;
12088         for (i=0; i<BtReq.paraLength; i++)
12089         {
12090                 DBG_871X("%s: BtReq.pParamStart[%d] = 0x%02x \n",
12091                         __FUNCTION__, i, BtReq.pParamStart[i]);
12092         }
12093         
12094 todo:
12095         _rtw_memset(extra,'\0', wrqu->data.length);
12096
12097         if (padapter->bBTFWReady == _FALSE)
12098         {
12099                 sprintf(extra, "BTFWReady = FALSE.\n");
12100                 goto exit;
12101         }
12102
12103         mptbt_BtControlProcess(padapter, &BtReq);
12104
12105         if (readtherm == 0)
12106         {
12107                 sprintf(extra, "BT thermal=");
12108                 for (i=4; i<pMptCtx->mptOutLen; i++)
12109                 {
12110                         if ((pMptCtx->mptOutBuf[i]==0x00) && (pMptCtx->mptOutBuf[i+1]==0x00))
12111                                 goto exit;
12112
12113 #ifdef CONFIG_RTL8723A
12114                         sprintf(extra, "%s %d ", extra, (pMptCtx->mptOutBuf[i]& 0x3f));
12115 #else
12116                         sprintf(extra, "%s %d ", extra, (pMptCtx->mptOutBuf[i]& 0x1f));
12117 #endif
12118                 }
12119         }
12120         else
12121         {
12122                 for (i=4; i<pMptCtx->mptOutLen; i++)
12123                 {
12124                         sprintf(extra, "%s 0x%x ", extra, pMptCtx->mptOutBuf[i]);
12125                 }
12126         }
12127         
12128 exit:
12129         wrqu->data.length = strlen(extra) + 1;
12130         DBG_871X("-%s: output len=%d data=%s\n", __FUNCTION__, wrqu->data.length, extra);
12131
12132         return status;
12133 }
12134
12135 #endif //#ifdef CONFIG_RTL8723A
12136
12137 static int rtw_mp_set(struct net_device *dev,
12138                         struct iw_request_info *info,
12139                         union iwreq_data *wdata, char *extra)
12140 {
12141         struct iw_point *wrqu = (struct iw_point *)wdata;
12142         u32 subcmd = wrqu->flags;
12143         PADAPTER padapter = rtw_netdev_priv(dev);
12144
12145         if (padapter == NULL)
12146         {
12147                 return -ENETDOWN;
12148         }
12149
12150         if((padapter->bup == _FALSE ))
12151         {
12152                 DBG_871X(" %s fail =>(padapter->bup == _FALSE )\n",__FUNCTION__);
12153                 return -ENETDOWN;
12154         }
12155
12156         if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE))
12157        {        
12158         DBG_871X("%s fail =>(padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE) \n",__FUNCTION__);
12159              return -ENETDOWN;
12160        }
12161
12162         
12163         //_rtw_memset(extra, 0x00, IW_PRIV_SIZE_MASK);
12164
12165         if (extra == NULL)
12166         {
12167                 wrqu->length = 0;
12168                 return -EIO;
12169         }
12170
12171         switch(subcmd)
12172         {
12173         case MP_START:
12174                         DBG_871X("set case mp_start \n");
12175                         rtw_mp_start (dev,info,wrqu,extra);
12176                          break; 
12177                          
12178         case MP_STOP:
12179                         DBG_871X("set case mp_stop \n");
12180                         rtw_mp_stop (dev,info,wrqu,extra);
12181                          break; 
12182                          
12183         case MP_BANDWIDTH:
12184                         DBG_871X("set case mp_bandwidth \n");
12185                         rtw_mp_bandwidth (dev,info,wrqu,extra);
12186                         break;
12187                                 
12188         case MP_RESET_STATS:
12189                         DBG_871X("set case MP_RESET_STATS \n");
12190                         rtw_mp_reset_stats      (dev,info,wrqu,extra);
12191                         break;
12192         case MP_SetRFPathSwh:           
12193                         DBG_871X("set MP_SetRFPathSwitch \n");
12194                         rtw_mp_SetRFPath  (dev,info,wdata,extra);
12195                         break;
12196         case CTA_TEST:
12197                         DBG_871X("set CTA_TEST\n");
12198                         rtw_cta_test_start (dev, info, wdata, extra);
12199                         break;
12200         case MP_DISABLE_BT_COEXIST:
12201                         DBG_871X("set case MP_DISABLE_BT_COEXIST \n");
12202                         rtw_mp_disable_bt_coexist(dev, info, wdata, extra);
12203                 break;
12204 #ifdef CONFIG_AP_WOWLAN
12205         case MP_AP_WOW_ENABLE:
12206                         DBG_871X("set case MP_AP_WOW_ENABLE: %s \n", extra);
12207                         rtw_ap_wowlan_ctrl(dev, info, wdata, extra);
12208         break;
12209 #endif
12210         }
12211
12212           
12213         return 0;               
12214 }
12215
12216
12217 static int rtw_mp_get(struct net_device *dev,
12218                         struct iw_request_info *info,
12219                         union iwreq_data *wdata, char *extra)
12220 {
12221         struct iw_point *wrqu = (struct iw_point *)wdata;
12222         u32 subcmd = wrqu->flags;
12223         PADAPTER padapter = rtw_netdev_priv(dev);
12224
12225         //DBG_871X("in mp_get extra= %s \n",extra);
12226
12227         if (padapter == NULL)
12228         {
12229                 return -ENETDOWN;
12230         }
12231         if((padapter->bup == _FALSE ))
12232         {
12233                 DBG_871X(" %s fail =>(padapter->bup == _FALSE )\n",__FUNCTION__);
12234                 return -ENETDOWN;
12235         }
12236
12237         if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE))
12238        {        
12239         DBG_871X("%s fail =>(padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE) \n",__FUNCTION__);
12240              return -ENETDOWN;
12241        }
12242         
12243         if (extra == NULL)
12244         {
12245                 wrqu->length = 0;
12246                 return -EIO;
12247         }
12248         
12249         switch(subcmd)
12250         {
12251         case WRITE_REG :
12252                         rtw_mp_write_reg (dev,info,wrqu,extra);
12253                          break;
12254                          
12255         case WRITE_RF:
12256                         rtw_mp_write_rf (dev,info,wrqu,extra);
12257                          break; 
12258                          
12259         case MP_PHYPARA:
12260                         DBG_871X("mp_get  MP_PHYPARA \n");
12261                         rtw_mp_phypara(dev,info,wrqu,extra);    
12262                         break;
12263
12264         case MP_CHANNEL:
12265                         DBG_871X("set case mp_channel \n");
12266                         rtw_mp_channel (dev,info,wrqu,extra);
12267                         break;
12268                         
12269         case READ_REG:
12270                         DBG_871X("mp_get  READ_REG \n");
12271                         rtw_mp_read_reg (dev,info,wrqu,extra);
12272                          break; 
12273         case READ_RF:
12274                         DBG_871X("mp_get  READ_RF \n");
12275                         rtw_mp_read_rf (dev,info,wrqu,extra);
12276                         break; 
12277                         
12278         case MP_RATE:
12279                         DBG_871X("set case mp_rate \n");
12280                         rtw_mp_rate (dev,info,wrqu,extra);
12281                         break;
12282                         
12283         case MP_TXPOWER:
12284                         DBG_871X("set case MP_TXPOWER \n");
12285                         rtw_mp_txpower (dev,info,wrqu,extra);
12286                         break;
12287                         
12288         case MP_ANT_TX:
12289                         DBG_871X("set case MP_ANT_TX \n");
12290                         rtw_mp_ant_tx (dev,info,wrqu,extra);
12291                         break;
12292                         
12293         case MP_ANT_RX:
12294                         DBG_871X("set case MP_ANT_RX \n");
12295                         rtw_mp_ant_rx (dev,info,wrqu,extra);
12296                         break;
12297                         
12298         case MP_QUERY:
12299                         //DBG_871X("mp_get mp_query MP_QUERY \n");
12300                         rtw_mp_trx_query(dev,info,wrqu,extra);
12301                         break;
12302                                         
12303         case MP_CTX:
12304                         DBG_871X("set case MP_CTX \n");
12305                         rtw_mp_ctx (dev,info,wrqu,extra);
12306                         break;
12307                         
12308         case MP_ARX:
12309                         DBG_871X("set case MP_ARX \n");
12310                         rtw_mp_arx (dev,info,wrqu,extra);
12311                         break;
12312                         
12313         case EFUSE_GET:
12314                         DBG_871X("efuse get EFUSE_GET \n");
12315                         rtw_mp_efuse_get(dev,info,wdata,extra);
12316                  break; 
12317                  
12318         case MP_DUMP:
12319                         DBG_871X("set case MP_DUMP \n");
12320                         rtw_mp_dump (dev,info,wrqu,extra);
12321                  break; 
12322         case MP_PSD:
12323                         DBG_871X("set case MP_PSD \n");
12324                         rtw_mp_psd (dev,info,wrqu,extra);
12325                  break;
12326         case MP_THER:
12327                         DBG_871X("set case MP_THER \n");
12328                         rtw_mp_thermal (dev,info,wrqu,extra);
12329                 break;
12330         case MP_PwrCtlDM:
12331                         DBG_871X("set MP_PwrCtlDM\n");
12332                         rtw_mp_PwrCtlDM (dev,info,wrqu,extra);
12333                 break;
12334         case MP_QueryDrvStats:          
12335                         DBG_871X("mp_get MP_QueryDrvStats \n");
12336                         rtw_mp_QueryDrv(dev,info,wdata,extra);
12337                         break;
12338                 case MP_PWRTRK:
12339                         DBG_871X("set case MP_PWRTRK \n");
12340                         rtw_mp_pwrtrk(dev,info,wrqu,extra);
12341                         break;                   
12342         case EFUSE_SET:
12343                         DBG_871X("set case efuse set \n");
12344                         rtw_mp_efuse_set(dev,info,wdata,extra);
12345                         break;                   
12346         case MP_GET_TXPOWER_INX:
12347                         DBG_871X("mp_get MP_GET_TXPOWER_INX \n");
12348                         rtw_mp_txpower_index(dev,info,wrqu,extra);
12349                 break;
12350
12351 #if defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B)
12352         case MP_SetBT:          
12353                         DBG_871X("set MP_SetBT \n");
12354                         rtw_mp_SetBT(dev,info,wdata,extra);
12355                         break;           
12356 #endif
12357
12358         }
12359
12360         rtw_msleep_os(10); //delay 5ms for sending pkt before exit adb shell operation
12361 return 0;       
12362 }
12363
12364 #endif //#if defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT)
12365
12366 static int rtw_wfd_tdls_enable(struct net_device *dev,
12367                                 struct iw_request_info *info,
12368                                 union iwreq_data *wrqu, char *extra)
12369 {
12370         int ret = 0;
12371
12372 #ifdef CONFIG_TDLS
12373 #ifdef CONFIG_WFD
12374
12375         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12376
12377         printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12378
12379         if ( extra[ 0 ] == '0' )
12380         {
12381                 padapter->wdinfo.wfd_tdls_enable = 0;
12382         }
12383         else
12384         {
12385                 padapter->wdinfo.wfd_tdls_enable = 1;
12386         }
12387
12388 #endif //CONFIG_WFD
12389 #endif //CONFIG_TDLS
12390         
12391         return ret;
12392 }
12393
12394 static int rtw_tdls_weaksec(struct net_device *dev,
12395                                 struct iw_request_info *info,
12396                                 union iwreq_data *wrqu, char *extra)
12397 {
12398         int ret = 0;
12399
12400 #ifdef CONFIG_TDLS
12401
12402         u8 i, j;
12403         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12404
12405         DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12406
12407         if ( extra[ 0 ] == '0' )
12408         {
12409                 padapter->wdinfo.wfd_tdls_weaksec = 0;
12410         }
12411         else
12412         {
12413                 padapter->wdinfo.wfd_tdls_weaksec = 1;
12414         }
12415 #endif
12416         
12417         return ret;
12418 }
12419
12420
12421 static int rtw_tdls_enable(struct net_device *dev,
12422                                 struct iw_request_info *info,
12423                                 union iwreq_data *wrqu, char *extra)
12424 {
12425         int ret = 0;
12426
12427 #ifdef CONFIG_TDLS
12428
12429         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12430         struct tdls_info        *ptdlsinfo = &padapter->tdlsinfo;
12431         _irqL    irqL;
12432         _list   *plist, *phead;
12433         s32     index;
12434         struct sta_info *psta = NULL;
12435         struct  sta_priv *pstapriv = &padapter->stapriv;
12436         u8 tdls_sta[NUM_STA][ETH_ALEN];
12437         u8 empty_hwaddr[ETH_ALEN] = { 0x00 };
12438         struct tdls_txmgmt txmgmt;
12439
12440         printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12441
12442         _rtw_memset(tdls_sta, 0x00, sizeof(tdls_sta));
12443         _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12444
12445         if ( extra[ 0 ] == '0' )
12446         {
12447                 ptdlsinfo->tdls_enable = 0;
12448
12449                 if(pstapriv->asoc_sta_count==1)
12450                         return ret;
12451
12452                 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12453                 for(index=0; index< NUM_STA; index++)
12454                 {
12455                         phead = &(pstapriv->sta_hash[index]);
12456                         plist = get_next(phead);
12457                         
12458                         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12459                         {
12460                                 psta = LIST_CONTAINOR(plist, struct sta_info ,hash_list);
12461
12462                                 plist = get_next(plist);
12463
12464                                 if(psta->tdls_sta_state != TDLS_STATE_NONE)
12465                                 {
12466                                         _rtw_memcpy(tdls_sta[index], psta->hwaddr, ETH_ALEN);
12467                                 }
12468                         }
12469                 }
12470                 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12471
12472                 for(index=0; index< NUM_STA; index++)
12473                 {
12474                         if( !_rtw_memcmp(tdls_sta[index], empty_hwaddr, ETH_ALEN) )
12475                         {
12476                                 printk("issue tear down to "MAC_FMT"\n", MAC_ARG(tdls_sta[index]));
12477                                 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
12478                                 _rtw_memcpy(txmgmt.peer, tdls_sta[index], ETH_ALEN);
12479                                 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12480                         }
12481                 }
12482                 rtw_tdls_cmd(padapter, myid(&(padapter->eeprompriv)), TDLS_RS_RCR);
12483                 rtw_reset_tdls_info(padapter);
12484         }
12485         else if ( extra[ 0 ] == '1' )
12486         {
12487                 ptdlsinfo->tdls_enable = 1;
12488         }
12489 #endif //CONFIG_TDLS
12490         
12491         return ret;
12492 }
12493
12494 static int rtw_tdls_setup(struct net_device *dev,
12495                                 struct iw_request_info *info,
12496                                 union iwreq_data *wrqu, char *extra)
12497 {
12498         int ret = 0;
12499 #ifdef CONFIG_TDLS
12500         u8 i, j;
12501         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12502         struct tdls_txmgmt txmgmt;
12503 #ifdef CONFIG_WFD
12504         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
12505 #endif // CONFIG_WFD
12506
12507         printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12508
12509         if(wrqu->data.length - 1 != 17 )
12510         {
12511                 printk( "[%s] length:%d != 17\n", __FUNCTION__, (wrqu->data.length -1)  );
12512                 return ret;
12513         }
12514
12515         _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12516         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12517                 txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1));
12518         }
12519
12520 #ifdef CONFIG_WFD
12521         if ( _AES_ != padapter->securitypriv.dot11PrivacyAlgrthm )
12522         {
12523                 //      Weak Security situation with AP.
12524                 if ( 0 == pwdinfo->wfd_tdls_weaksec )
12525                 {
12526                         //      Can't send the tdls setup request out!!
12527                         DBG_871X( "[%s] Current link is not AES, SKIP sending the tdls setup request!!\n", __FUNCTION__ );
12528                 }
12529                 else
12530                 {
12531                         issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
12532                 }
12533         }
12534         else
12535 #endif // CONFIG_WFD
12536         {
12537                 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
12538         }
12539 #endif
12540         
12541         return ret;
12542 }
12543
12544 static int rtw_tdls_teardown(struct net_device *dev,
12545                                 struct iw_request_info *info,
12546                                 union iwreq_data *wrqu, char *extra)
12547 {
12548         int ret = 0;
12549
12550 #ifdef CONFIG_TDLS
12551
12552         u8 i,j;
12553         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12554         struct sta_info *ptdls_sta = NULL;
12555         struct tdls_txmgmt txmgmt;
12556
12557         DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12558
12559         if(wrqu->data.length - 1 != 17 && wrqu->data.length - 1 != 19)
12560         {
12561                 printk( "[%s] length:%d != 17 or 19\n", __FUNCTION__, (wrqu->data.length -1)  );
12562                 return ret;
12563         }
12564
12565         _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12566         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12567                 txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1));
12568         }
12569
12570         ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), txmgmt.peer);
12571         
12572         if(ptdls_sta != NULL)
12573         {
12574                 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
12575                 if(wrqu->data.length - 1 == 17)
12576                         issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12577                 else if(wrqu->data.length - 1 == 19)
12578                         issue_tdls_teardown(padapter, &txmgmt, _TRUE);
12579         }
12580         else
12581                 DBG_871X( "TDLS peer not found\n");
12582 #endif //CONFIG_TDLS
12583         
12584         return ret;
12585 }
12586
12587 static int rtw_tdls_discovery(struct net_device *dev,
12588                                 struct iw_request_info *info,
12589                                 union iwreq_data *wrqu, char *extra)
12590 {
12591         int ret = 0;
12592
12593 #ifdef CONFIG_TDLS
12594         
12595         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12596         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
12597         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12598         struct tdls_txmgmt      txmgmt;
12599         int i = 0, j=0;
12600
12601         DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12602
12603         _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12604         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12605                 txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1));
12606         }
12607
12608         issue_tdls_dis_req(padapter, &txmgmt);
12609
12610 #endif //CONFIG_TDLS
12611
12612         return ret;
12613 }
12614
12615 static int rtw_tdls_ch_switch(struct net_device *dev,
12616                                 struct iw_request_info *info,
12617                                 union iwreq_data *wrqu, char *extra)
12618 {
12619         int ret = 0;
12620
12621 #ifdef CONFIG_TDLS
12622         
12623         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12624         struct tdls_info        *ptdlsinfo = &padapter->tdlsinfo;
12625         u8 i, j, mac_addr[ETH_ALEN];
12626         struct sta_info *ptdls_sta = NULL;
12627
12628         DBG_8192C( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12629
12630         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12631                 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
12632         }
12633
12634         ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
12635         if( ptdls_sta == NULL )
12636                 return ret;
12637
12638 //      ptdlsinfo->ch_sensing=1;
12639
12640 //      rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_INIT_CH_SEN);
12641
12642 #endif //CONFIG_TDLS
12643
12644                 return ret;
12645 }
12646         
12647 static int rtw_tdls_pson(struct net_device *dev,
12648                                 struct iw_request_info *info,
12649                                 union iwreq_data *wrqu, char *extra)
12650 {
12651         int ret = 0;
12652
12653 #ifdef CONFIG_TDLS
12654         
12655         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12656         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
12657         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12658         u8 i, j, mac_addr[ETH_ALEN];
12659         struct sta_info *ptdls_sta = NULL;
12660
12661         DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12662
12663         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12664                 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
12665         }
12666
12667         ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
12668
12669         issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 1, 3, 500);
12670
12671 #endif //CONFIG_TDLS
12672
12673                 return ret;
12674 }
12675         
12676 static int rtw_tdls_psoff(struct net_device *dev,
12677                                 struct iw_request_info *info,
12678                                 union iwreq_data *wrqu, char *extra)
12679 {
12680         int ret = 0;
12681
12682 #ifdef CONFIG_TDLS
12683         
12684         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12685         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
12686         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12687         u8 i, j, mac_addr[ETH_ALEN];
12688         struct sta_info *ptdls_sta = NULL;
12689         
12690         DBG_8192C( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12691
12692         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12693                 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
12694         }
12695
12696         ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
12697
12698         if(ptdls_sta)
12699         {
12700                 //issue_tdls_peer_traffic_rsp(padapter, ptdls_sta);
12701                 issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 0, 3, 500);
12702         }
12703 #endif //CONFIG_TDLS
12704
12705         return ret;
12706 }
12707
12708 static int rtw_tdls_setip(struct net_device *dev,
12709                                 struct iw_request_info *info,
12710                                 union iwreq_data *wrqu, char *extra)
12711 {
12712         int ret = 0;
12713
12714 #ifdef CONFIG_TDLS
12715 #ifdef CONFIG_WFD
12716         
12717         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12718         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12719         struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
12720         u8 i=0, j=0, k=0, tag=0, ip[3] = { 0xff }, *ptr = extra;
12721         
12722         printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1  );
12723
12724
12725         while( i < 4 )
12726         {
12727                 for( j=0; j < 4; j++)
12728                 {
12729                         if( *( extra + j + tag ) == '.' || *( extra + j + tag ) == '\0' )
12730                         {
12731                                 if( j == 1 )
12732                                         pwfd_info->ip_address[i]=convert_ip_addr( '0', '0', *(extra+(j-1)+tag));
12733                                 if( j == 2 )
12734                                         pwfd_info->ip_address[i]=convert_ip_addr( '0', *(extra+(j-2)+tag), *(extra+(j-1)+tag));
12735                                 if( j == 3 )
12736                                         pwfd_info->ip_address[i]=convert_ip_addr( *(extra+(j-3)+tag), *(extra+(j-2)+tag), *(extra+(j-1)+tag));  
12737
12738                                 tag += j + 1;
12739                                 break;
12740                         }
12741                 }
12742                 i++;
12743         }
12744
12745         printk( "[%s] Set IP = %u.%u.%u.%u \n", __FUNCTION__, 
12746                 ptdlsinfo->wfd_info->ip_address[0], ptdlsinfo->wfd_info->ip_address[1],
12747                 ptdlsinfo->wfd_info->ip_address[2], ptdlsinfo->wfd_info->ip_address[3]
12748         );
12749
12750 #endif //CONFIG_WFD     
12751 #endif //CONFIG_TDLS
12752
12753         return ret;
12754 }
12755
12756 static int rtw_tdls_getip(struct net_device *dev,
12757                                 struct iw_request_info *info,
12758                                 union iwreq_data *wrqu, char *extra)
12759 {
12760         int ret = 0;
12761
12762 #ifdef CONFIG_TDLS
12763 #ifdef CONFIG_WFD
12764         
12765         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12766         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12767         struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
12768         
12769         printk( "[%s]\n", __FUNCTION__);
12770
12771         sprintf( extra, "\n\n%u.%u.%u.%u\n", 
12772                 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1], 
12773                 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]
12774                 );
12775
12776         printk( "[%s] IP=%u.%u.%u.%u\n", __FUNCTION__,
12777                 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1], 
12778                 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]
12779                 );
12780         
12781         wrqu->data.length = strlen( extra );
12782
12783 #endif //CONFIG_WFD     
12784 #endif //CONFIG_TDLS
12785
12786         return ret;
12787 }
12788
12789 static int rtw_tdls_getport(struct net_device *dev,
12790                                struct iw_request_info *info,
12791                                union iwreq_data *wrqu, char *extra)
12792 {
12793         
12794         int ret = 0;    
12795
12796 #ifdef CONFIG_TDLS
12797 #ifdef CONFIG_WFD
12798
12799         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12800         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12801         struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
12802
12803         printk( "[%s]\n", __FUNCTION__);
12804
12805         sprintf( extra, "\n\n%d\n", pwfd_info->peer_rtsp_ctrlport );
12806         printk( "[%s] remote port = %d\n", __FUNCTION__, pwfd_info->peer_rtsp_ctrlport );
12807         
12808         wrqu->data.length = strlen( extra );
12809
12810 #endif //CONFIG_WFD
12811 #endif //CONFIG_TDLS
12812
12813         return ret;
12814                 
12815 }
12816
12817 //WFDTDLS, for sigma test
12818 static int rtw_tdls_dis_result(struct net_device *dev,
12819                                struct iw_request_info *info,
12820                                union iwreq_data *wrqu, char *extra)
12821 {
12822         
12823         int ret = 0;    
12824
12825 #ifdef CONFIG_TDLS
12826 #ifdef CONFIG_WFD
12827
12828         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12829         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12830         struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
12831
12832         printk( "[%s]\n", __FUNCTION__);
12833
12834         if(ptdlsinfo->dev_discovered == 1 )
12835         {
12836                 sprintf( extra, "\n\nDis=1\n" );
12837                 ptdlsinfo->dev_discovered = 0;
12838         }
12839         
12840         wrqu->data.length = strlen( extra );
12841
12842 #endif //CONFIG_WFD
12843 #endif //CONFIG_TDLS
12844
12845         return ret;
12846                 
12847 }
12848
12849 //WFDTDLS, for sigma test
12850 static int rtw_wfd_tdls_status(struct net_device *dev,
12851                                struct iw_request_info *info,
12852                                union iwreq_data *wrqu, char *extra)
12853 {
12854         
12855         int ret = 0;    
12856
12857 #ifdef CONFIG_TDLS
12858
12859         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12860         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12861
12862         printk( "[%s]\n", __FUNCTION__);
12863
12864         sprintf( extra, "\nlink_established:0x%08x \n"
12865                 "sta_cnt:%d \n"
12866                 "sta_maximum:%d \n"
12867                 "cur_channel:%d \n"
12868                 "tdls_enable:%d",
12869                 ptdlsinfo->link_established, ptdlsinfo->sta_cnt, ptdlsinfo->sta_maximum,
12870                 ptdlsinfo->cur_channel, ptdlsinfo->tdls_enable
12871                 );
12872
12873         wrqu->data.length = strlen( extra );
12874
12875 #endif //CONFIG_TDLS
12876
12877         return ret;
12878                 
12879         }
12880
12881 static int rtw_tdls_getsta(struct net_device *dev,
12882                                struct iw_request_info *info,
12883                                union iwreq_data *wrqu, char *extra)
12884         {
12885         
12886         int ret = 0;
12887 #ifdef CONFIG_TDLS
12888         u8 i, j;
12889         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12890         u8 addr[ETH_ALEN] = {0};
12891         char charmac[17];
12892         struct sta_info *ptdls_sta = NULL;
12893
12894         printk( "[%s] %s %d\n", __FUNCTION__, (char *)wrqu->data.pointer, wrqu->data.length -1  );
12895
12896         if(copy_from_user(charmac, wrqu->data.pointer+9, 17)){
12897                 ret = -EFAULT;
12898                 goto exit;
12899         }
12900         
12901         printk("[%s] %d, charmac:%s\n", __FUNCTION__, __LINE__, charmac);
12902         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12903                 addr[i]=key_2char2num(*(charmac+j), *(charmac+j+1));
12904         }
12905
12906         printk("[%s] %d, charmac:%s, addr:"MAC_FMT"\n", __FUNCTION__, __LINE__, charmac, MAC_ARG(addr));
12907         ptdls_sta = rtw_get_stainfo(&padapter->stapriv, addr);  
12908         if(ptdls_sta) {
12909                 sprintf(extra, "\n\ntdls_sta_state=%d\n", ptdls_sta->tdls_sta_state);
12910                 printk("\n\ntdls_sta_state=%d\n", ptdls_sta->tdls_sta_state);
12911         }
12912         else {
12913                 sprintf(extra, "\n\nNot found this sta\n");
12914                 printk("\n\nNot found this sta\n");
12915         }
12916         wrqu->data.length = strlen( extra );
12917
12918 #endif //CONFIG_TDLS
12919 exit:
12920         return ret;
12921                 
12922 }
12923
12924 static int rtw_tdls_ch_switch_off(struct net_device *dev,
12925                                 struct iw_request_info *info,
12926                                 union iwreq_data *wrqu, char *extra)
12927 {
12928         int ret = 0;
12929
12930 #ifdef CONFIG_TDLS
12931         
12932         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12933         u8 i, j, mac_addr[ETH_ALEN];
12934         struct sta_info *ptdls_sta = NULL;
12935         
12936         DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1  );
12937
12938         for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12939                 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
12940         }
12941
12942         ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
12943
12944         ptdls_sta->tdls_sta_state |= TDLS_SW_OFF_STATE;
12945 /*
12946         if((ptdls_sta->tdls_sta_state & TDLS_AT_OFF_CH_STATE) && (ptdls_sta->tdls_sta_state & TDLS_PEER_AT_OFF_STATE)){
12947                 pmlmeinfo->tdls_candidate_ch= pmlmeext->cur_channel;
12948                 issue_tdls_ch_switch_req(padapter, mac_addr);
12949                 DBG_871X("issue tdls ch switch req back to base channel\n");
12950         }
12951 */
12952         
12953 #endif //CONFIG_TDLS
12954
12955         return ret;
12956 }
12957
12958 static int rtw_tdls(struct net_device *dev,
12959                                 struct iw_request_info *info,
12960                                 union iwreq_data *wrqu, char *extra)
12961 {
12962         int ret = 0;
12963
12964 #ifdef CONFIG_TDLS
12965         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12966
12967
12968
12969         DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra );
12970         //      WFD Sigma will use the tdls enable command to let the driver know we want to test the tdls now!
12971         if ( _rtw_memcmp( extra, "wfdenable=", 10 ) )
12972         {
12973                 wrqu->data.length -=10;
12974                 rtw_wfd_tdls_enable( dev, info, wrqu, &extra[10] );
12975                 return ret;
12976         }
12977         else if ( _rtw_memcmp( extra, "weaksec=", 8 ) )
12978         {
12979                 wrqu->data.length -=8;
12980                 rtw_tdls_weaksec( dev, info, wrqu, &extra[8] );
12981                 return ret;
12982         }
12983         else if ( _rtw_memcmp( extra, "tdlsenable=", 11 ) )
12984         {
12985                 wrqu->data.length -=11;
12986                 rtw_tdls_enable( dev, info, wrqu, &extra[11] );
12987                 return ret;
12988         }
12989
12990         if( padapter->tdlsinfo.tdls_enable == 0 )
12991         {
12992                 printk("tdls haven't enabled\n");
12993                 return 0;
12994         }
12995
12996         if ( _rtw_memcmp( extra, "setup=", 6 ) )
12997         {
12998                 wrqu->data.length -=6;
12999                 rtw_tdls_setup( dev, info, wrqu, &extra[6] );
13000         }
13001         else if (_rtw_memcmp( extra, "tear=", 5 ) )
13002         {
13003                 wrqu->data.length -= 5;
13004                 rtw_tdls_teardown( dev, info, wrqu, &extra[5] );
13005         }
13006         else if (_rtw_memcmp( extra, "dis=", 4 ) )
13007         {
13008                 wrqu->data.length -= 4;
13009                 rtw_tdls_discovery( dev, info, wrqu, &extra[4] );
13010         }
13011         else if (_rtw_memcmp( extra, "sw=", 3 ) )
13012         {
13013                 wrqu->data.length -= 3;
13014                 rtw_tdls_ch_switch( dev, info, wrqu, &extra[3] );
13015         }
13016         else if (_rtw_memcmp( extra, "swoff=", 6 ) )
13017         {
13018                 wrqu->data.length -= 6;
13019                 rtw_tdls_ch_switch_off( dev, info, wrqu, &extra[6] );
13020         }       
13021         else if (_rtw_memcmp( extra, "pson=", 5 ) )
13022         {
13023                 wrqu->data.length -= 5;
13024                 rtw_tdls_pson( dev, info, wrqu, &extra[5] );
13025         }
13026         else if (_rtw_memcmp( extra, "psoff=", 6 ) )
13027         {
13028                 wrqu->data.length -= 6;
13029                 rtw_tdls_psoff( dev, info, wrqu, &extra[6] );
13030         }
13031 #ifdef CONFIG_WFD
13032         else if (_rtw_memcmp( extra, "setip=", 6 ) )
13033         {
13034                 wrqu->data.length -= 6;
13035                 rtw_tdls_setip( dev, info, wrqu, &extra[6] );
13036         }
13037         else if (_rtw_memcmp( extra, "tprobe=", 6 ) )
13038         {
13039                 issue_tunneled_probe_req((_adapter *)rtw_netdev_priv(dev));
13040         }
13041 #endif //CONFIG_WFD
13042
13043 #endif //CONFIG_TDLS
13044         
13045         return ret;
13046 }
13047
13048
13049 static int rtw_tdls_get(struct net_device *dev,
13050                                 struct iw_request_info *info,
13051                                 union iwreq_data *wrqu, char *extra)
13052 {
13053         int ret = 0;
13054
13055 #ifdef CONFIG_WFD
13056
13057         DBG_871X( "[%s] extra = %s\n", __FUNCTION__, (char*) wrqu->data.pointer );
13058
13059         if ( _rtw_memcmp( wrqu->data.pointer, "ip", 2 ) )
13060         {
13061                 rtw_tdls_getip( dev, info, wrqu, extra );
13062         }
13063         if ( _rtw_memcmp( wrqu->data.pointer, "port", 4 ) )
13064         {
13065                 rtw_tdls_getport( dev, info, wrqu, extra );
13066         }
13067         //WFDTDLS, for sigma test
13068         if ( _rtw_memcmp( wrqu->data.pointer, "dis", 3 ) )
13069         {
13070                 rtw_tdls_dis_result( dev, info, wrqu, extra );
13071         }
13072         if ( _rtw_memcmp( wrqu->data.pointer, "status", 6 ) )
13073         {
13074                 rtw_wfd_tdls_status( dev, info, wrqu, extra );
13075         }
13076         if ( _rtw_memcmp( wrqu->data.pointer, "tdls_sta=", 9 ) )
13077         {
13078                 rtw_tdls_getsta( dev, info, wrqu, extra );
13079         }
13080
13081 #endif //CONFIG_WFD
13082
13083         return ret;
13084 }
13085
13086
13087
13088
13089
13090 #ifdef CONFIG_INTEL_WIDI
13091 static int rtw_widi_set(struct net_device *dev,
13092                                struct iw_request_info *info,
13093                                union iwreq_data *wrqu, char *extra)
13094 {
13095         int ret = 0;
13096         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
13097
13098         process_intel_widi_cmd(padapter, extra);
13099
13100         return ret;
13101 }
13102
13103 static int rtw_widi_set_probe_request(struct net_device *dev,
13104                                struct iw_request_info *info,
13105                                union iwreq_data *wrqu, char *extra)
13106 {
13107         int     ret = 0;
13108         u8      *pbuf = NULL;
13109         _adapter        *padapter = (_adapter *)rtw_netdev_priv(dev);
13110
13111         pbuf = rtw_malloc(sizeof(l2_msg_t));
13112         if(pbuf)
13113         {
13114                 if ( copy_from_user(pbuf, wrqu->data.pointer, wrqu->data.length) )
13115                         ret = -EFAULT;
13116                 //_rtw_memcpy(pbuf, wrqu->data.pointer, wrqu->data.length);
13117
13118                 if( wrqu->data.flags == 0 )
13119                         intel_widi_wk_cmd(padapter, INTEL_WIDI_ISSUE_PROB_WK, pbuf, sizeof(l2_msg_t));
13120                 else if( wrqu->data.flags == 1 )
13121                         rtw_set_wfd_rds_sink_info( padapter, (l2_msg_t *)pbuf );
13122         }
13123         return ret;
13124 }
13125 #endif // CONFIG_INTEL_WIDI
13126
13127 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
13128
13129 #ifdef CONFIG_RTL8723A
13130 extern void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc);
13131 #define cal_txdesc_chksum rtl8723a_cal_txdesc_chksum
13132 extern void rtl8723a_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
13133 #define fill_default_txdesc rtl8723a_fill_default_txdesc
13134 #endif
13135 #if defined(CONFIG_RTL8188E)
13136 #include <rtl8188e_hal.h>
13137 extern void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc);
13138 #define cal_txdesc_chksum rtl8188e_cal_txdesc_chksum
13139 #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)
13140 extern void rtl8188es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
13141 #define fill_default_txdesc rtl8188es_fill_default_txdesc
13142 #endif // CONFIG_SDIO_HCI
13143 #endif // CONFIG_RTL8188E
13144 #if defined(CONFIG_RTL8723B)
13145 extern void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc);
13146 #define cal_txdesc_chksum rtl8723b_cal_txdesc_chksum
13147 extern void rtl8723b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
13148 #define fill_default_txdesc rtl8723b_fill_default_txdesc
13149 #endif // CONFIG_RTL8723B
13150
13151 static s32 initLoopback(PADAPTER padapter)
13152 {
13153         PLOOPBACKDATA ploopback;
13154
13155
13156         if (padapter->ploopback == NULL) {
13157                 ploopback = (PLOOPBACKDATA)rtw_zmalloc(sizeof(LOOPBACKDATA));
13158                 if (ploopback == NULL) return -ENOMEM;
13159
13160                 _rtw_init_sema(&ploopback->sema, 0);
13161                 ploopback->bstop = _TRUE;
13162                 ploopback->cnt = 0;
13163                 ploopback->size = 300;
13164                 _rtw_memset(ploopback->msg, 0, sizeof(ploopback->msg));
13165
13166                 padapter->ploopback = ploopback;
13167         }
13168
13169         return 0;
13170 }
13171
13172 static void freeLoopback(PADAPTER padapter)
13173 {
13174         PLOOPBACKDATA ploopback;
13175
13176
13177         ploopback = padapter->ploopback;
13178         if (ploopback) {
13179                 rtw_mfree((u8*)ploopback, sizeof(LOOPBACKDATA));
13180                 padapter->ploopback = NULL;
13181         }
13182 }
13183
13184 static s32 initpseudoadhoc(PADAPTER padapter)
13185 {
13186         NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
13187         s32 err;
13188
13189         networkType = Ndis802_11IBSS;
13190         err = rtw_set_802_11_infrastructure_mode(padapter, networkType);
13191         if (err == _FALSE) return _FAIL;
13192
13193         err = rtw_setopmode_cmd(padapter, networkType,_TRUE);
13194         if (err == _FAIL) return _FAIL;
13195
13196         return _SUCCESS;
13197 }
13198
13199 static s32 createpseudoadhoc(PADAPTER padapter)
13200 {
13201         NDIS_802_11_AUTHENTICATION_MODE authmode;
13202         struct mlme_priv *pmlmepriv;
13203         NDIS_802_11_SSID *passoc_ssid;
13204         WLAN_BSSID_EX *pdev_network;
13205         u8 *pibss;
13206         u8 ssid[] = "pseduo_ad-hoc";
13207         s32 err;
13208         _irqL irqL;
13209
13210
13211         pmlmepriv = &padapter->mlmepriv;
13212
13213         authmode = Ndis802_11AuthModeOpen;
13214         err = rtw_set_802_11_authentication_mode(padapter, authmode);
13215         if (err == _FALSE) return _FAIL;
13216
13217         passoc_ssid = &pmlmepriv->assoc_ssid;
13218         _rtw_memset(passoc_ssid, 0, sizeof(NDIS_802_11_SSID));
13219         passoc_ssid->SsidLength = sizeof(ssid) - 1;
13220         _rtw_memcpy(passoc_ssid->Ssid, ssid, passoc_ssid->SsidLength);
13221
13222         pdev_network = &padapter->registrypriv.dev_network;
13223         pibss = padapter->registrypriv.dev_network.MacAddress;
13224         _rtw_memcpy(&pdev_network->Ssid, passoc_ssid, sizeof(NDIS_802_11_SSID));
13225
13226         rtw_update_registrypriv_dev_network(padapter);
13227         rtw_generate_random_ibss(pibss);
13228
13229         _enter_critical_bh(&pmlmepriv->lock, &irqL);
13230         pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
13231         _exit_critical_bh(&pmlmepriv->lock, &irqL);
13232
13233 #if 0
13234         err = rtw_createbss_cmd(padapter);
13235         if (err == _FAIL) return _FAIL;
13236 #else
13237 {
13238         struct wlan_network *pcur_network;
13239         struct sta_info *psta;
13240
13241         //3  create a new psta
13242         pcur_network = &pmlmepriv->cur_network;
13243
13244         //clear psta in the cur_network, if any
13245         psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress);
13246         if (psta) rtw_free_stainfo(padapter, psta);
13247
13248         psta = rtw_alloc_stainfo(&padapter->stapriv, pibss);
13249         if (psta == NULL) return _FAIL;
13250
13251         //3  join psudo AdHoc
13252         pcur_network->join_res = 1;
13253         pcur_network->aid = psta->aid = 1;
13254         _rtw_memcpy(&pcur_network->network, pdev_network, get_WLAN_BSSID_EX_sz(pdev_network));
13255
13256         // set msr to WIFI_FW_ADHOC_STATE
13257 #if 0
13258         Set_NETYPE0_MSR(padapter, WIFI_FW_ADHOC_STATE);
13259 #else
13260         {
13261                 u8 val8;
13262
13263                 val8 = rtw_read8(padapter, MSR);
13264                 val8 &= 0xFC; // clear NETYPE0
13265                 val8 |= WIFI_FW_ADHOC_STATE & 0x3;
13266                 rtw_write8(padapter, MSR, val8);
13267         }
13268 #endif
13269 }
13270 #endif
13271
13272         return _SUCCESS;
13273 }
13274
13275 static struct xmit_frame* createloopbackpkt(PADAPTER padapter, u32 size)
13276 {
13277         struct xmit_priv *pxmitpriv;
13278         struct xmit_frame *pframe;
13279         struct xmit_buf *pxmitbuf;
13280         struct pkt_attrib *pattrib;
13281         struct tx_desc *desc;
13282         u8 *pkt_start, *pkt_end, *ptr;
13283         struct rtw_ieee80211_hdr *hdr;
13284         s32 bmcast;
13285         _irqL irqL;
13286
13287
13288         if ((TXDESC_SIZE + WLANHDR_OFFSET + size) > MAX_XMITBUF_SZ) return NULL;
13289
13290         pxmitpriv = &padapter->xmitpriv;
13291         pframe = NULL;
13292
13293         //2 1. allocate xmit frame
13294         pframe = rtw_alloc_xmitframe(pxmitpriv);
13295         if (pframe == NULL) return NULL;
13296         pframe->padapter = padapter;
13297
13298         //2 2. allocate xmit buffer
13299         _enter_critical_bh(&pxmitpriv->lock, &irqL);
13300         pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
13301         _exit_critical_bh(&pxmitpriv->lock, &irqL);
13302         if (pxmitbuf == NULL) {
13303                 rtw_free_xmitframe(pxmitpriv, pframe);
13304                 return NULL;
13305         }
13306
13307         pframe->pxmitbuf = pxmitbuf;
13308         pframe->buf_addr = pxmitbuf->pbuf;
13309         pxmitbuf->priv_data = pframe;
13310
13311         //2 3. update_attrib()
13312         pattrib = &pframe->attrib;
13313
13314         // init xmitframe attribute
13315         _rtw_memset(pattrib, 0, sizeof(struct pkt_attrib));
13316
13317         pattrib->ether_type = 0x8723;
13318         _rtw_memcpy(pattrib->src, padapter->eeprompriv.mac_addr, ETH_ALEN);
13319         _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
13320         _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);
13321         _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
13322
13323 //      pattrib->dhcp_pkt = 0;
13324 //      pattrib->pktlen = 0;
13325         pattrib->ack_policy = 0;
13326 //      pattrib->pkt_hdrlen = ETH_HLEN;
13327         pattrib->hdrlen = WLAN_HDR_A3_LEN;
13328         pattrib->subtype = WIFI_DATA;
13329         pattrib->priority = 0;
13330         pattrib->qsel = pattrib->priority;
13331 //      do_queue_select(padapter, pattrib);
13332         pattrib->nr_frags = 1;
13333         pattrib->encrypt = 0;
13334         pattrib->bswenc = _FALSE;
13335         pattrib->qos_en = _FALSE;
13336
13337         bmcast = IS_MCAST(pattrib->ra);
13338         if (bmcast) {
13339                 pattrib->mac_id = 1;
13340                 pattrib->psta = rtw_get_bcmc_stainfo(padapter);
13341         } else {
13342                 pattrib->mac_id = 0;
13343                 pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
13344         }
13345
13346         pattrib->pktlen = size;
13347         pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen;
13348
13349         //2 4. fill TX descriptor
13350         desc = (struct tx_desc*)pframe->buf_addr;
13351         _rtw_memset(desc, 0, TXDESC_SIZE);
13352
13353         fill_default_txdesc(pframe, (u8*)desc);
13354
13355         // Hw set sequence number
13356         ((PTXDESC)desc)->hwseq_en = 0; // HWSEQ_EN, 0:disable, 1:enable
13357 //      ((PTXDESC)desc)->hwseq_sel = 0; // HWSEQ_SEL
13358
13359         ((PTXDESC)desc)->disdatafb = 1;
13360
13361         // convert to little endian
13362         desc->txdw0 = cpu_to_le32(desc->txdw0);
13363         desc->txdw1 = cpu_to_le32(desc->txdw1);
13364         desc->txdw2 = cpu_to_le32(desc->txdw2);
13365         desc->txdw3 = cpu_to_le32(desc->txdw3);
13366         desc->txdw4 = cpu_to_le32(desc->txdw4);
13367         desc->txdw5 = cpu_to_le32(desc->txdw5);
13368         desc->txdw6 = cpu_to_le32(desc->txdw6);
13369         desc->txdw7 = cpu_to_le32(desc->txdw7);
13370 #ifdef CONFIG_PCI_HCI
13371         desc->txdw8 = cpu_to_le32(desc->txdw8);
13372         desc->txdw9 = cpu_to_le32(desc->txdw9);
13373         desc->txdw10 = cpu_to_le32(desc->txdw10);
13374         desc->txdw11 = cpu_to_le32(desc->txdw11);
13375         desc->txdw12 = cpu_to_le32(desc->txdw12);
13376         desc->txdw13 = cpu_to_le32(desc->txdw13);
13377         desc->txdw14 = cpu_to_le32(desc->txdw14);
13378         desc->txdw15 = cpu_to_le32(desc->txdw15);
13379 #endif
13380
13381         cal_txdesc_chksum(desc);
13382
13383         //2 5. coalesce
13384         pkt_start = pframe->buf_addr + TXDESC_SIZE;
13385         pkt_end = pkt_start + pattrib->last_txcmdsz;
13386
13387         //3 5.1. make wlan header, make_wlanhdr()
13388         hdr = (struct rtw_ieee80211_hdr *)pkt_start;
13389         SetFrameSubType(&hdr->frame_ctl, pattrib->subtype);
13390         _rtw_memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); // DA
13391         _rtw_memcpy(hdr->addr2, pattrib->src, ETH_ALEN); // SA
13392         _rtw_memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); // RA, BSSID
13393
13394         //3 5.2. make payload
13395         ptr = pkt_start + pattrib->hdrlen;
13396         get_random_bytes(ptr, pkt_end - ptr);
13397
13398         pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz;
13399         pxmitbuf->ptail += pxmitbuf->len;
13400
13401         return pframe;
13402 }
13403
13404 static void freeloopbackpkt(PADAPTER padapter, struct xmit_frame *pframe)
13405 {
13406         struct xmit_priv *pxmitpriv;
13407         struct xmit_buf *pxmitbuf;
13408
13409
13410         pxmitpriv = &padapter->xmitpriv;
13411         pxmitbuf = pframe->pxmitbuf;
13412
13413         rtw_free_xmitframe(pxmitpriv, pframe);
13414         rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
13415 }
13416
13417 static void printdata(u8 *pbuf, u32 len)
13418 {
13419         u32 i, val;
13420
13421
13422         for (i = 0; (i+4) <= len; i+=4) {
13423                 printk("%08X", *(u32*)(pbuf + i));
13424                 if ((i+4) & 0x1F) printk(" ");
13425                 else printk("\n");
13426         }
13427
13428         if (i < len)
13429         {
13430 #ifdef CONFIG_BIG_ENDIAN
13431                 for (; i < len, i++)
13432                         printk("%02X", pbuf+i);
13433 #else // CONFIG_LITTLE_ENDIAN
13434 #if 0
13435                 val = 0;
13436                 _rtw_memcpy(&val, pbuf + i, len - i);
13437                 printk("%8X", val);
13438 #else
13439                 u8 str[9];
13440                 u8 n;
13441                 val = 0;
13442                 n = len - i;
13443                 _rtw_memcpy(&val, pbuf+i, n);
13444                 sprintf(str, "%08X", val);
13445                 n = (4 - n) * 2;
13446                 printk("%8s", str+n);
13447 #endif
13448 #endif // CONFIG_LITTLE_ENDIAN
13449         }
13450         printk("\n");
13451 }
13452
13453 static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz)
13454 {
13455         PHAL_DATA_TYPE phal;
13456         struct recv_stat *prxstat;
13457         struct recv_stat report;
13458         PRXREPORT prxreport;
13459         u32 drvinfosize;
13460         u32 rxpktsize;
13461         u8 fcssize;
13462         u8 ret = _FALSE;
13463
13464         prxstat = (struct recv_stat*)rxbuf;
13465         report.rxdw0 = le32_to_cpu(prxstat->rxdw0);
13466         report.rxdw1 = le32_to_cpu(prxstat->rxdw1);
13467         report.rxdw2 = le32_to_cpu(prxstat->rxdw2);
13468         report.rxdw3 = le32_to_cpu(prxstat->rxdw3);
13469         report.rxdw4 = le32_to_cpu(prxstat->rxdw4);
13470         report.rxdw5 = le32_to_cpu(prxstat->rxdw5);
13471
13472         prxreport = (PRXREPORT)&report;
13473         drvinfosize = prxreport->drvinfosize << 3;
13474         rxpktsize = prxreport->pktlen;
13475
13476         phal = GET_HAL_DATA(padapter);
13477         if (phal->ReceiveConfig & RCR_APPFCS) fcssize = IEEE80211_FCS_LEN;
13478         else fcssize = 0;
13479
13480         if ((txsz - TXDESC_SIZE) != (rxpktsize - fcssize)) {
13481                 DBG_8192C("%s: ERROR! size not match tx/rx=%d/%d !\n",
13482                         __func__, txsz - TXDESC_SIZE, rxpktsize - fcssize);
13483                 ret = _FALSE;
13484         } else {
13485                 ret = _rtw_memcmp(txbuf + TXDESC_SIZE,\
13486                                                   rxbuf + RXDESC_SIZE + drvinfosize,\
13487                                                   txsz - TXDESC_SIZE);
13488                 if (ret == _FALSE) {
13489                         DBG_8192C("%s: ERROR! pkt content mismatch!\n", __func__);
13490                 }
13491         }
13492
13493         if (ret == _FALSE)
13494         {
13495                 DBG_8192C("\n%s: TX PKT total=%d, desc=%d, content=%d\n",
13496                         __func__, txsz, TXDESC_SIZE, txsz - TXDESC_SIZE);
13497                 DBG_8192C("%s: TX DESC size=%d\n", __func__, TXDESC_SIZE);
13498                 printdata(txbuf, TXDESC_SIZE);
13499                 DBG_8192C("%s: TX content size=%d\n", __func__, txsz - TXDESC_SIZE);
13500                 printdata(txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE);
13501
13502                 DBG_8192C("\n%s: RX PKT read=%d offset=%d(%d,%d) content=%d\n",
13503                         __func__, rxsz, RXDESC_SIZE + drvinfosize, RXDESC_SIZE, drvinfosize, rxpktsize);
13504                 if (rxpktsize != 0)
13505                 {
13506                         DBG_8192C("%s: RX DESC size=%d\n", __func__, RXDESC_SIZE);
13507                         printdata(rxbuf, RXDESC_SIZE);
13508                         DBG_8192C("%s: RX drvinfo size=%d\n", __func__, drvinfosize);
13509                         printdata(rxbuf + RXDESC_SIZE, drvinfosize);
13510                         DBG_8192C("%s: RX content size=%d\n", __func__, rxpktsize);
13511                         printdata(rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize);
13512                 } else {
13513                         DBG_8192C("%s: RX data size=%d\n", __func__, rxsz);
13514                         printdata(rxbuf, rxsz);
13515                 }
13516         }
13517
13518         return ret;
13519 }
13520
13521 thread_return lbk_thread(thread_context context)
13522 {
13523         s32 err;
13524         PADAPTER padapter;
13525         PLOOPBACKDATA ploopback;
13526         struct xmit_frame *pxmitframe;
13527         u32 cnt, ok, fail, headerlen;
13528         u32 pktsize;
13529         u32 ff_hwaddr;
13530
13531
13532         padapter = (PADAPTER)context;
13533         ploopback = padapter->ploopback;
13534         if (ploopback == NULL) return -1;
13535         cnt = 0;
13536         ok = 0;
13537         fail = 0;
13538
13539         daemonize("%s", "RTW_LBK_THREAD");
13540         allow_signal(SIGTERM);
13541
13542         do {
13543                 if (ploopback->size == 0) {
13544                         get_random_bytes(&pktsize, 4);
13545                         pktsize = (pktsize % 1535) + 1; // 1~1535
13546                 } else
13547                         pktsize = ploopback->size;
13548                 
13549                 pxmitframe = createloopbackpkt(padapter, pktsize);
13550                 if (pxmitframe == NULL) {
13551                         sprintf(ploopback->msg, "loopback FAIL! 3. create Packet FAIL!");
13552                         break;
13553                 }
13554
13555                 ploopback->txsize = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz;
13556                 _rtw_memcpy(ploopback->txbuf, pxmitframe->buf_addr, ploopback->txsize);
13557                 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
13558                 cnt++;
13559                 DBG_8192C("%s: wirte port cnt=%d size=%d\n", __func__, cnt, ploopback->txsize);
13560                 pxmitframe->pxmitbuf->pdata = ploopback->txbuf;
13561                 rtw_write_port(padapter, ff_hwaddr, ploopback->txsize, (u8 *)pxmitframe->pxmitbuf);
13562
13563                 // wait for rx pkt
13564                 _rtw_down_sema(&ploopback->sema);
13565
13566                 err = pktcmp(padapter, ploopback->txbuf, ploopback->txsize, ploopback->rxbuf, ploopback->rxsize);
13567                 if (err == _TRUE)
13568                         ok++;
13569                 else
13570                         fail++;
13571
13572                 ploopback->txsize = 0;
13573                 _rtw_memset(ploopback->txbuf, 0, 0x8000);
13574                 ploopback->rxsize = 0;
13575                 _rtw_memset(ploopback->rxbuf, 0, 0x8000);
13576
13577                 freeloopbackpkt(padapter, pxmitframe);
13578                 pxmitframe = NULL;
13579
13580                 if (signal_pending(current)) {
13581                         flush_signals(current);
13582                 }
13583
13584                 if ((ploopback->bstop == _TRUE) ||
13585                         ((ploopback->cnt != 0) && (ploopback->cnt == cnt)))
13586                 {
13587                         u32 ok_rate, fail_rate, all;
13588                         all = cnt;
13589                         ok_rate = (ok*100)/all;
13590                         fail_rate = (fail*100)/all;
13591                         sprintf(ploopback->msg,\
13592                                         "loopback result: ok=%d%%(%d/%d),error=%d%%(%d/%d)",\
13593                                         ok_rate, ok, all, fail_rate, fail, all);
13594                         break;
13595                 }
13596         } while (1);
13597
13598         ploopback->bstop = _TRUE;
13599
13600         thread_exit();
13601 }
13602
13603 static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8* pmsg)
13604 {
13605         PLOOPBACKDATA ploopback;
13606         u32 len;
13607         s32 err;
13608
13609
13610         ploopback = padapter->ploopback;
13611
13612         if (ploopback)
13613         {
13614                 if (ploopback->bstop == _FALSE) {
13615                         ploopback->bstop = _TRUE;
13616                         _rtw_up_sema(&ploopback->sema);
13617                 }
13618                 len = 0;
13619                 do {
13620                         len = strlen(ploopback->msg);
13621                         if (len) break;
13622                         rtw_msleep_os(1);
13623                 } while (1);
13624                 _rtw_memcpy(pmsg, ploopback->msg, len+1);
13625                 freeLoopback(padapter);
13626
13627                 return;
13628         }
13629
13630         // disable dynamic algorithm
13631         {
13632         u32 DMFlag = DYNAMIC_FUNC_DISABLE;
13633         rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8*)&DMFlag);
13634         }
13635
13636         // create pseudo ad-hoc connection
13637         err = initpseudoadhoc(padapter);
13638         if (err == _FAIL) {
13639                 sprintf(pmsg, "loopback FAIL! 1.1 init ad-hoc FAIL!");
13640                 return;
13641         }
13642
13643         err = createpseudoadhoc(padapter);
13644         if (err == _FAIL) {
13645                 sprintf(pmsg, "loopback FAIL! 1.2 create ad-hoc master FAIL!");
13646                 return;
13647         }
13648
13649         err = initLoopback(padapter);
13650         if (err) {
13651                 sprintf(pmsg, "loopback FAIL! 2. init FAIL! error code=%d", err);
13652                 return;
13653         }
13654
13655         ploopback = padapter->ploopback;
13656
13657         ploopback->bstop = _FALSE;
13658         ploopback->cnt = cnt;
13659         ploopback->size = size;
13660         ploopback->lbkthread = kthread_run(lbk_thread, padapter, "RTW_LBK_THREAD");
13661         if (IS_ERR(padapter->lbkthread))
13662         {
13663                 freeLoopback(padapter);
13664                 sprintf(pmsg, "loopback start FAIL! cnt=%d", cnt);
13665                 return;
13666         }
13667
13668         sprintf(pmsg, "loopback start! cnt=%d", cnt);
13669 }
13670 #endif // CONFIG_MAC_LOOPBACK_DRIVER
13671
13672 static int rtw_test(
13673         struct net_device *dev,
13674         struct iw_request_info *info,
13675         union iwreq_data *wrqu, char *extra)
13676 {
13677         u32 len;
13678         u8 *pbuf, *pch;
13679         char *ptmp;
13680         u8 *delim = ",";
13681         PADAPTER padapter = rtw_netdev_priv(dev);
13682
13683
13684         DBG_871X("+%s\n", __func__);
13685         len = wrqu->data.length;
13686
13687         pbuf = (u8*)rtw_zmalloc(len);
13688         if (pbuf == NULL) {
13689                 DBG_871X("%s: no memory!\n", __func__);
13690                 return -ENOMEM;
13691         }
13692
13693         if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
13694                 rtw_mfree(pbuf, len);
13695                 DBG_871X("%s: copy from user fail!\n", __func__);
13696                 return -EFAULT;
13697         }
13698         DBG_871X("%s: string=\"%s\"\n", __func__, pbuf);
13699
13700         ptmp = (char*)pbuf;
13701         pch = strsep(&ptmp, delim);
13702         if ((pch == NULL) || (strlen(pch) == 0)) {
13703                 rtw_mfree(pbuf, len);
13704                 DBG_871X("%s: parameter error(level 1)!\n", __func__);
13705                 return -EFAULT;
13706         }
13707
13708 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
13709         if (strcmp(pch, "loopback") == 0)
13710         {
13711                 s32 cnt = 0;
13712                 u32 size = 64;
13713
13714                 pch = strsep(&ptmp, delim);
13715                 if ((pch == NULL) || (strlen(pch) == 0)) {
13716                         rtw_mfree(pbuf, len);
13717                         DBG_871X("%s: parameter error(level 2)!\n", __func__);
13718                         return -EFAULT;
13719                 }
13720
13721                 sscanf(pch, "%d", &cnt);
13722                 DBG_871X("%s: loopback cnt=%d\n", __func__, cnt);
13723
13724                 pch = strsep(&ptmp, delim);
13725                 if ((pch == NULL) || (strlen(pch) == 0)) {
13726                         rtw_mfree(pbuf, len);
13727                         DBG_871X("%s: parameter error(level 2)!\n", __func__);
13728                         return -EFAULT;
13729                 }
13730
13731                 sscanf(pch, "%d", &size);
13732                 DBG_871X("%s: loopback size=%d\n", __func__, size);
13733
13734                 loopbackTest(padapter, cnt, size, extra);
13735                 wrqu->data.length = strlen(extra) + 1;
13736
13737                 rtw_mfree(pbuf, len);
13738                 return 0;
13739         }
13740 #endif
13741
13742 #if 0
13743 //#ifdef CONFIG_RTL8723A
13744         if (strcmp(pch, "poweron") == 0)
13745         {
13746                 s32 ret;
13747
13748                 ret = _InitPowerOn(padapter);
13749                 DBG_871X("%s: power on %s\n", __func__, (_FAIL==ret) ? "FAIL!":"OK.");
13750                 sprintf(extra, "Power ON %s", (_FAIL==ret) ? "FAIL!":"OK.");
13751                 wrqu->data.length = strlen(extra) + 1;
13752
13753                 rtw_mfree(pbuf, len);
13754                 return 0;
13755         }
13756
13757         if (strcmp(pch, "dlfw") == 0)
13758         {
13759                 s32 ret;
13760
13761                 ret = rtl8723a_FirmwareDownload(padapter);
13762                 DBG_871X("%s: download FW %s\n", __func__, (_FAIL==ret) ? "FAIL!":"OK.");
13763                 sprintf(extra, "download FW %s", (_FAIL==ret) ? "FAIL!":"OK.");
13764                 wrqu->data.length = strlen(extra) + 1;
13765
13766                 rtw_mfree(pbuf, len);
13767                 return 0;
13768         }
13769 #endif
13770
13771 #ifdef CONFIG_BT_COEXIST
13772         if (strcmp(pch, "bton") == 0)
13773         {
13774                 rtw_btcoex_SetManualControl(padapter, _FALSE);
13775         }
13776
13777         if (strcmp(pch, "btoff") == 0)
13778         {
13779                 rtw_btcoex_SetManualControl(padapter, _TRUE);
13780         }
13781
13782         if (strcmp(pch, "h2c") == 0)
13783         {
13784                 u8 param[8];
13785                 u8 count = 0;
13786                 u32 tmp;
13787                 u8 i;
13788                 u32 pos;
13789                 s32 ret;
13790
13791
13792                 do {
13793                         pch = strsep(&ptmp, delim);
13794                         if ((pch == NULL) || (strlen(pch) == 0))
13795                                 break;
13796
13797                         sscanf(pch, "%x", &tmp);
13798                         param[count++] = (u8)tmp;
13799                 } while (count < 8);
13800
13801                 if (count == 0) {
13802                         rtw_mfree(pbuf, len);
13803                         DBG_871X("%s: parameter error(level 2)!\n", __func__);
13804                         return -EFAULT;
13805                 }
13806
13807                 ret = rtw_hal_fill_h2c_cmd(padapter, param[0], count-1, &param[1]);
13808
13809                 pos = sprintf(extra, "H2C ID=0x%02x content=", param[0]);
13810                 for (i=1; i<count; i++) {
13811                         pos += sprintf(extra+pos, "%02x,", param[i]);
13812                 }
13813                 extra[pos] = 0;
13814                 pos--;
13815                 pos += sprintf(extra+pos, " %s", ret==_FAIL?"FAIL":"OK");
13816
13817                 wrqu->data.length = strlen(extra) + 1;
13818         }
13819 #endif // CONFIG_BT_COEXIST
13820
13821         rtw_mfree(pbuf, len);
13822         return 0;
13823 }
13824
13825 static iw_handler rtw_handlers[] =
13826 {
13827         NULL,                                   /* SIOCSIWCOMMIT */
13828         rtw_wx_get_name,                /* SIOCGIWNAME */
13829         dummy,                                  /* SIOCSIWNWID */
13830         dummy,                                  /* SIOCGIWNWID */
13831         rtw_wx_set_freq,                /* SIOCSIWFREQ */
13832         rtw_wx_get_freq,                /* SIOCGIWFREQ */
13833         rtw_wx_set_mode,                /* SIOCSIWMODE */
13834         rtw_wx_get_mode,                /* SIOCGIWMODE */
13835         dummy,                                  /* SIOCSIWSENS */
13836         rtw_wx_get_sens,                /* SIOCGIWSENS */
13837         NULL,                                   /* SIOCSIWRANGE */
13838         rtw_wx_get_range,               /* SIOCGIWRANGE */
13839         rtw_wx_set_priv,                /* SIOCSIWPRIV */
13840         NULL,                                   /* SIOCGIWPRIV */
13841         NULL,                                   /* SIOCSIWSTATS */
13842         NULL,                                   /* SIOCGIWSTATS */
13843         dummy,                                  /* SIOCSIWSPY */
13844         dummy,                                  /* SIOCGIWSPY */
13845         NULL,                                   /* SIOCGIWTHRSPY */
13846         NULL,                                   /* SIOCWIWTHRSPY */
13847         rtw_wx_set_wap,         /* SIOCSIWAP */
13848         rtw_wx_get_wap,         /* SIOCGIWAP */
13849         rtw_wx_set_mlme,                /* request MLME operation; uses struct iw_mlme */
13850         dummy,                                  /* SIOCGIWAPLIST -- depricated */
13851         rtw_wx_set_scan,                /* SIOCSIWSCAN */
13852         rtw_wx_get_scan,                /* SIOCGIWSCAN */
13853         rtw_wx_set_essid,               /* SIOCSIWESSID */
13854         rtw_wx_get_essid,               /* SIOCGIWESSID */
13855         dummy,                                  /* SIOCSIWNICKN */
13856         rtw_wx_get_nick,                /* SIOCGIWNICKN */
13857         NULL,                                   /* -- hole -- */
13858         NULL,                                   /* -- hole -- */
13859         rtw_wx_set_rate,                /* SIOCSIWRATE */
13860         rtw_wx_get_rate,                /* SIOCGIWRATE */
13861         rtw_wx_set_rts,                 /* SIOCSIWRTS */
13862         rtw_wx_get_rts,                 /* SIOCGIWRTS */
13863         rtw_wx_set_frag,                /* SIOCSIWFRAG */
13864         rtw_wx_get_frag,                /* SIOCGIWFRAG */
13865         dummy,                                  /* SIOCSIWTXPOW */
13866         dummy,                                  /* SIOCGIWTXPOW */
13867         dummy,                                  /* SIOCSIWRETRY */
13868         rtw_wx_get_retry,               /* SIOCGIWRETRY */
13869         rtw_wx_set_enc,                 /* SIOCSIWENCODE */
13870         rtw_wx_get_enc,                 /* SIOCGIWENCODE */
13871         dummy,                                  /* SIOCSIWPOWER */
13872         rtw_wx_get_power,               /* SIOCGIWPOWER */
13873         NULL,                                   /*---hole---*/
13874         NULL,                                   /*---hole---*/
13875         rtw_wx_set_gen_ie,              /* SIOCSIWGENIE */
13876         NULL,                                   /* SIOCGWGENIE */
13877         rtw_wx_set_auth,                /* SIOCSIWAUTH */
13878         NULL,                                   /* SIOCGIWAUTH */
13879         rtw_wx_set_enc_ext,             /* SIOCSIWENCODEEXT */
13880         NULL,                                   /* SIOCGIWENCODEEXT */
13881         rtw_wx_set_pmkid,               /* SIOCSIWPMKSA */
13882         NULL,                                   /*---hole---*/
13883 }; 
13884
13885 #if 0
13886 //defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT)
13887 static const struct iw_priv_args rtw_private_args[] =
13888 {       
13889         { SIOCIWFIRSTPRIV + 0x00, IW_PRIV_TYPE_CHAR | 1024, 0 , ""},  //set 
13890         { SIOCIWFIRSTPRIV + 0x01, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , ""},//get
13891 /* --- sub-ioctls definitions --- */   
13892                 { MP_START , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_start" }, //set
13893                 { MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara" },//get
13894                 { MP_STOP , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_stop" }, //set
13895                 { MP_CHANNEL , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel" },//get
13896                 { MP_BANDWIDTH , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_bandwidth"}, //set
13897                 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },//get
13898                 { MP_RESET_STATS , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_reset_stats"},
13899                 { MP_QUERY , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "mp_query"}, //get
13900                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13901                 { READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" },
13902                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13903                 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
13904                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13905                 { READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" },
13906                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13907                 { MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"}, 
13908                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13909                 { MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" },
13910                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13911                 { MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},
13912                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13913                 { MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024,  IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},
13914                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13915                 { MP_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},
13916                 { WRITE_REG, IW_PRIV_TYPE_CHAR | 1024, 0,"write_reg"},//set
13917                 { MP_NULL, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL" },
13918                 { WRITE_RF, IW_PRIV_TYPE_CHAR | 1024, 0,"write_rf"},//set
13919                 { MP_NULL, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL" },
13920                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13921                 { MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},
13922                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13923                 { MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},
13924                 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
13925                 { MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},
13926                 { EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set" },
13927                 { EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get" },
13928                 { MP_PWRTRK , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_pwrtrk"},
13929                 { MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery" },
13930                 { MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"}, // mp_ioctl       
13931                 { MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_setrfpath" },
13932 #ifdef CONFIG_RTL8723A
13933                 { MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" },
13934 #endif
13935         { SIOCIWFIRSTPRIV + 0x02, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "test"},//set
13936 };
13937 static iw_handler rtw_private_handler[] = 
13938 {
13939         rtw_mp_set,
13940         rtw_mp_get,
13941 };
13942 #else // not inlucde MP
13943
13944 static const struct iw_priv_args rtw_private_args[] = {
13945         {
13946                 SIOCIWFIRSTPRIV + 0x0,
13947                 IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
13948         },
13949         {
13950                 SIOCIWFIRSTPRIV + 0x1,
13951                 IW_PRIV_TYPE_CHAR | 0x7FF,
13952                 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
13953         },
13954         {
13955                 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
13956         },
13957         {
13958                 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
13959         },
13960         {
13961                 SIOCIWFIRSTPRIV + 0x4,
13962                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
13963         },
13964         {
13965                 SIOCIWFIRSTPRIV + 0x5,
13966                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
13967         },
13968         {
13969                 SIOCIWFIRSTPRIV + 0x6,
13970                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
13971         },
13972 //for PLATFORM_MT53XX   
13973         {
13974                 SIOCIWFIRSTPRIV + 0x7,
13975                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
13976         },
13977         {
13978                 SIOCIWFIRSTPRIV + 0x8,
13979                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
13980         },
13981         {
13982                 SIOCIWFIRSTPRIV + 0x9,
13983                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
13984         },
13985
13986 //for RTK_DMP_PLATFORM  
13987         {
13988                 SIOCIWFIRSTPRIV + 0xA,
13989                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
13990         },
13991
13992         {
13993                 SIOCIWFIRSTPRIV + 0xB,
13994                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
13995         },      
13996         {
13997                 SIOCIWFIRSTPRIV + 0xC,
13998                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
13999         },
14000         {
14001                 SIOCIWFIRSTPRIV + 0xD,
14002                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
14003         },
14004 #if 0
14005         {
14006                 SIOCIWFIRSTPRIV + 0xE,0,0, "wowlan_ctrl"
14007         },
14008 #endif
14009         {
14010                 SIOCIWFIRSTPRIV + 0x10,
14011                 IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set"
14012         },
14013         {
14014                 SIOCIWFIRSTPRIV + 0x11,
14015                 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get"
14016         },
14017         {
14018                 SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL"
14019         },
14020         {
14021                 SIOCIWFIRSTPRIV + 0x13,
14022                 IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2"
14023         },      
14024         {
14025                 SIOCIWFIRSTPRIV + 0x14,
14026                 IW_PRIV_TYPE_CHAR  | 64, 0, "tdls"
14027         },
14028         {
14029                 SIOCIWFIRSTPRIV + 0x15,
14030                 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "tdls_get"
14031         },      
14032         {
14033                 SIOCIWFIRSTPRIV + 0x16,
14034                 IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
14035         },
14036
14037         {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"},
14038 #ifdef CONFIG_MP_INCLUDED
14039         {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0,  "NULL"},
14040         {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL"},
14041 #else
14042         {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"},
14043         {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
14044 #endif
14045         {
14046                 SIOCIWFIRSTPRIV + 0x1D,
14047                 IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
14048         },
14049
14050 #ifdef CONFIG_INTEL_WIDI
14051         {
14052                 SIOCIWFIRSTPRIV + 0x1E,
14053                 IW_PRIV_TYPE_CHAR | 1024, 0, "widi_set"
14054         },
14055         {
14056                 SIOCIWFIRSTPRIV + 0x1F,
14057                 IW_PRIV_TYPE_CHAR | 128, 0, "widi_prob_req"
14058         },
14059 #endif // CONFIG_INTEL_WIDI
14060
14061 #ifdef CONFIG_MP_INCLUDED
14062         { SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0 , ""},  //set 
14063         { SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , ""},//get
14064 /* --- sub-ioctls definitions --- */   
14065                 { MP_START , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_start" }, //set
14066                 { MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara" },//get
14067                 { MP_STOP , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_stop" }, //set
14068                 { MP_CHANNEL , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel" },//get
14069                 { MP_BANDWIDTH , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_bandwidth"}, //set
14070                 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },//get
14071                 { MP_RESET_STATS , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_reset_stats"},
14072                 { MP_QUERY , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "mp_query"}, //get
14073                 { READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" },
14074                 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
14075                 { READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" },
14076                 { MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"}, 
14077                 { MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" },
14078                 { MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},
14079                 { MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024,  IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},
14080                 { MP_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},
14081                 { WRITE_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg" },
14082                 { WRITE_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf" },
14083                 { MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},
14084                 { MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},
14085                 { MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},
14086                 { EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_set" },
14087                 { EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get" },
14088                 { MP_PWRTRK , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_pwrtrk"},
14089                 { MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery" },
14090                 { MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"}, // mp_ioctl       
14091                 { MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_setrfpath" },               
14092                 { MP_PwrCtlDM, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrctldm" },                
14093                 { MP_GET_TXPOWER_INX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_get_txpower" },
14094                 
14095 #if defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B)
14096                 { MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" },
14097         { MP_DISABLE_BT_COEXIST, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_disa_btcoex"},
14098 #endif
14099                 { CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"},
14100 #endif
14101 #ifdef CONFIG_AP_WOWLAN
14102                 { MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_enable" }, //set 
14103 #endif
14104 };
14105
14106 static iw_handler rtw_private_handler[] = 
14107 {
14108         rtw_wx_write32,                                 //0x00
14109         rtw_wx_read32,                                  //0x01
14110         rtw_drvext_hdl,                                 //0x02
14111         rtw_mp_ioctl_hdl,                               //0x03
14112
14113 // for MM DTV platform
14114         rtw_get_ap_info,                                        //0x04
14115
14116         rtw_set_pid,                                            //0x05
14117         rtw_wps_start,                                  //0x06
14118
14119 // for PLATFORM_MT53XX
14120         rtw_wx_get_sensitivity,                 //0x07
14121         rtw_wx_set_mtk_wps_probe_ie,    //0x08
14122         rtw_wx_set_mtk_wps_ie,                  //0x09
14123
14124 // for RTK_DMP_PLATFORM
14125 // Set Channel depend on the country code
14126         rtw_wx_set_channel_plan,                //0x0A
14127
14128         rtw_dbg_port,                                   //0x0B
14129         rtw_wx_write_rf,                                        //0x0C
14130         rtw_wx_read_rf,                                 //0x0D
14131 #ifdef CONFIG_MP_INCLUDED
14132         rtw_mp_set,                                     //0x0E
14133         rtw_mp_get,                                     //0x0F
14134 #else
14135         rtw_wx_priv_null,                               //0x0E
14136         rtw_wx_priv_null,                               //0x0F
14137 #endif
14138         rtw_p2p_set,                                    //0x10
14139         rtw_p2p_get,                                    //0x11
14140         NULL,                                                   //0x12
14141         rtw_p2p_get2,                                   //0x13
14142
14143         rtw_tdls,                                               //0x14
14144         rtw_tdls_get,                                   //0x15
14145
14146         rtw_pm_set,                                             //0x16
14147         rtw_wx_priv_null,                               //0x17
14148         rtw_rereg_nd_name,                              //0x18
14149         rtw_wx_priv_null,                               //0x19
14150 #ifdef CONFIG_MP_INCLUDED
14151         rtw_wx_priv_null,                               //0x1A
14152         rtw_wx_priv_null,                               //0x1B
14153 #else
14154         rtw_mp_efuse_set,                               //0x1A
14155         rtw_mp_efuse_get,                               //0x1B
14156 #endif
14157         NULL,                                                   // 0x1C is reserved for hostapd
14158         rtw_test,                                               // 0x1D
14159 #ifdef CONFIG_INTEL_WIDI
14160         rtw_widi_set,                                   //0x1E
14161         rtw_widi_set_probe_request,             //0x1F
14162 #endif // CONFIG_INTEL_WIDI
14163 };
14164
14165 #endif // #if defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT)
14166
14167 #if WIRELESS_EXT >= 17  
14168 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
14169 {
14170        _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
14171            struct iw_statistics *piwstats=&padapter->iwstats;
14172         int tmp_level = 0;
14173         int tmp_qual = 0;
14174         int tmp_noise = 0;
14175
14176         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != _TRUE)
14177         {
14178                 piwstats->qual.qual = 0;
14179                 piwstats->qual.level = 0;
14180                 piwstats->qual.noise = 0;
14181                 //DBG_871X("No link  level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
14182         }
14183         else{
14184                 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
14185                 tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength); 
14186                 #else
14187                 tmp_level = padapter->recvpriv.signal_strength;
14188                 #endif
14189                 
14190                 tmp_qual = padapter->recvpriv.signal_qual;
14191                 tmp_noise =padapter->recvpriv.noise;            
14192                 //DBG_871X("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise,padapter->recvpriv.rssi);
14193
14194                 piwstats->qual.level = tmp_level;
14195                 piwstats->qual.qual = tmp_qual;
14196                 piwstats->qual.noise = tmp_noise;
14197         }
14198 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
14199         piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;//|IW_QUAL_DBM;
14200 #else
14201 #ifdef RTK_DMP_PLATFORM
14202         //IW_QUAL_DBM= 0x8, if driver use this flag, wireless extension will show value of dbm.
14203         //remove this flag for show percentage 0~100
14204         piwstats->qual.updated = 0x07;
14205 #else
14206         piwstats->qual.updated = 0x0f;
14207 #endif
14208 #endif
14209
14210         #ifdef CONFIG_SIGNAL_DISPLAY_DBM
14211         piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM;
14212         #endif
14213
14214         return &padapter->iwstats;
14215 }
14216 #endif
14217
14218 #ifdef CONFIG_WIRELESS_EXT
14219 struct iw_handler_def rtw_handlers_def =
14220 {
14221         .standard = rtw_handlers,
14222         .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
14223 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) || defined(CONFIG_WEXT_PRIV)
14224         .private = rtw_private_handler,
14225         .private_args = (struct iw_priv_args *)rtw_private_args,
14226         .num_private = sizeof(rtw_private_handler) / sizeof(iw_handler),
14227         .num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args),
14228 #endif
14229 #if WIRELESS_EXT >= 17
14230         .get_wireless_stats = rtw_get_wireless_stats,
14231 #endif
14232 };
14233 #endif
14234
14235 // copy from net/wireless/wext.c start
14236 /* ---------------------------------------------------------------- */
14237 /*
14238  * Calculate size of private arguments
14239  */
14240 static const char iw_priv_type_size[] = {
14241         0,                              /* IW_PRIV_TYPE_NONE */
14242         1,                              /* IW_PRIV_TYPE_BYTE */
14243         1,                              /* IW_PRIV_TYPE_CHAR */
14244         0,                              /* Not defined */
14245         sizeof(__u32),                  /* IW_PRIV_TYPE_INT */
14246         sizeof(struct iw_freq),         /* IW_PRIV_TYPE_FLOAT */
14247         sizeof(struct sockaddr),        /* IW_PRIV_TYPE_ADDR */
14248         0,                              /* Not defined */
14249 };
14250
14251 static int get_priv_size(__u16 args)
14252 {
14253         int num = args & IW_PRIV_SIZE_MASK;
14254         int type = (args & IW_PRIV_TYPE_MASK) >> 12;
14255
14256         return num * iw_priv_type_size[type];
14257 }
14258 // copy from net/wireless/wext.c end
14259
14260 static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)
14261 {
14262         int err = 0;
14263         u8 *input = NULL;
14264         u32 input_len = 0;
14265         const char delim[] = " ";
14266         u8 *output = NULL;
14267         u32 output_len = 0;
14268         u32 count = 0;
14269         u8 *buffer= NULL;
14270         u32 buffer_len = 0;
14271         char *ptr = NULL;
14272         u8 cmdname[17] = {0}; // IFNAMSIZ+1
14273         u32 cmdlen;
14274         s32 len;
14275         u8 *extra = NULL;
14276         u32 extra_size = 0;
14277
14278         s32 k;
14279         const iw_handler *priv;         /* Private ioctl */
14280         const struct iw_priv_args *priv_args;   /* Private ioctl description */
14281         u32 num_priv;                           /* Number of ioctl */
14282         u32 num_priv_args;                      /* Number of descriptions */
14283         iw_handler handler;
14284         int temp;
14285         int subcmd = 0;                         /* sub-ioctl index */
14286         int offset = 0;                         /* Space for sub-ioctl index */
14287
14288         union iwreq_data wdata;
14289
14290
14291         _rtw_memcpy(&wdata, wrq_data, sizeof(wdata));
14292
14293         input_len = wdata.data.length;
14294         input = rtw_zmalloc(input_len);
14295         if (NULL == input)
14296                 return -ENOMEM;
14297         if (copy_from_user(input, wdata.data.pointer, input_len)) {
14298                 err = -EFAULT;
14299                 goto exit;
14300         }
14301         ptr = input;
14302         len = input_len;
14303
14304         sscanf(ptr, "%16s", cmdname);
14305         cmdlen = strlen(cmdname);
14306         DBG_8192C("%s: cmd=%s\n", __func__, cmdname);
14307
14308         // skip command string
14309         if (cmdlen > 0)
14310                 cmdlen += 1; // skip one space
14311         ptr += cmdlen;
14312         len -= cmdlen;
14313         DBG_8192C("%s: parameters=%s\n", __func__, ptr);
14314
14315         priv = rtw_private_handler;
14316         priv_args = rtw_private_args;
14317         num_priv = sizeof(rtw_private_handler) / sizeof(iw_handler);
14318         num_priv_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args);
14319
14320         if (num_priv_args == 0) {
14321                 err = -EOPNOTSUPP;
14322                 goto exit;
14323         }
14324
14325         /* Search the correct ioctl */
14326         k = -1;
14327         while((++k < num_priv_args) && strcmp(priv_args[k].name, cmdname));
14328
14329         /* If not found... */
14330         if (k == num_priv_args) {
14331                 err = -EOPNOTSUPP;
14332                 goto exit;
14333         }
14334
14335         /* Watch out for sub-ioctls ! */
14336         if (priv_args[k].cmd < SIOCDEVPRIVATE)
14337         {
14338                 int j = -1;
14339
14340                 /* Find the matching *real* ioctl */
14341                 while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||
14342                         (priv_args[j].set_args != priv_args[k].set_args) ||
14343                         (priv_args[j].get_args != priv_args[k].get_args)));
14344
14345                 /* If not found... */
14346                 if (j == num_priv_args) {
14347                         err = -EINVAL;
14348                         goto exit;
14349                 }
14350
14351                 /* Save sub-ioctl number */
14352                 subcmd = priv_args[k].cmd;
14353                 /* Reserve one int (simplify alignment issues) */
14354                 offset = sizeof(__u32);
14355                 /* Use real ioctl definition from now on */
14356                 k = j;
14357         }
14358
14359         buffer = rtw_zmalloc(4096);
14360         if (NULL == buffer) {
14361                 err = -ENOMEM;
14362                 goto exit;
14363         }
14364
14365         /* If we have to set some data */
14366         if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&
14367                 (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
14368         {
14369                 u8 *str;
14370
14371                 switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK)
14372                 {
14373                         case IW_PRIV_TYPE_BYTE:
14374                                 /* Fetch args */
14375                                 count = 0;
14376                                 do {
14377                                         str = strsep(&ptr, delim);
14378                                         if (NULL == str) break;
14379                                         sscanf(str, "%i", &temp);
14380                                         buffer[count++] = (u8)temp;
14381                                 } while (1);
14382                                 buffer_len = count;
14383
14384                                 /* Number of args to fetch */
14385                                 wdata.data.length = count;
14386                                 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
14387                                         wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
14388
14389                                 break;
14390
14391                         case IW_PRIV_TYPE_INT:
14392                                 /* Fetch args */
14393                                 count = 0;
14394                                 do {
14395                                         str = strsep(&ptr, delim);
14396                                         if (NULL == str) break;
14397                                         sscanf(str, "%i", &temp);
14398                                         ((s32*)buffer)[count++] = (s32)temp;
14399                                 } while (1);
14400                                 buffer_len = count * sizeof(s32);
14401
14402                                 /* Number of args to fetch */
14403                                 wdata.data.length = count;
14404                                 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
14405                                         wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
14406
14407                                 break;
14408
14409                         case IW_PRIV_TYPE_CHAR:
14410                                 if (len > 0)
14411                                 {
14412                                         /* Size of the string to fetch */
14413                                         wdata.data.length = len;
14414                                         if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
14415                                                 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
14416
14417                                         /* Fetch string */
14418                                         _rtw_memcpy(buffer, ptr, wdata.data.length);
14419                                 }
14420                                 else
14421                                 {
14422                                         wdata.data.length = 1;
14423                                         buffer[0] = '\0';
14424                                 }
14425                                 buffer_len = wdata.data.length;
14426                                 break;
14427
14428                         default:
14429                                 DBG_8192C("%s: Not yet implemented...\n", __func__);
14430                                 err = -1;
14431                                 goto exit;
14432                 }
14433
14434                 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
14435                         (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK)))
14436                 {
14437                         DBG_8192C("%s: The command %s needs exactly %d argument(s)...\n",
14438                                         __func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK);
14439                         err = -EINVAL;
14440                         goto exit;
14441                 }
14442         }   /* if args to set */
14443         else
14444         {
14445                 wdata.data.length = 0L;
14446         }
14447
14448         /* Those two tests are important. They define how the driver
14449         * will have to handle the data */
14450         if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
14451                 ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ))
14452         {
14453                 /* First case : all SET args fit within wrq */
14454                 if (offset)
14455                         wdata.mode = subcmd;
14456                 _rtw_memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
14457         }
14458         else
14459         {
14460                 if ((priv_args[k].set_args == 0) &&
14461                         (priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
14462                         (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
14463                 {
14464                         /* Second case : no SET args, GET args fit within wrq */
14465                         if (offset)
14466                                 wdata.mode = subcmd;
14467                 }
14468                 else
14469                 {
14470                         /* Third case : args won't fit in wrq, or variable number of args */
14471                         if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {
14472                                 err = -EFAULT;
14473                                 goto exit;
14474                         }
14475                         wdata.data.flags = subcmd;
14476                 }
14477         }
14478
14479         rtw_mfree(input, input_len);
14480         input = NULL;
14481
14482         extra_size = 0;
14483         if (IW_IS_SET(priv_args[k].cmd))
14484         {
14485                 /* Size of set arguments */
14486                 extra_size = get_priv_size(priv_args[k].set_args);
14487
14488                 /* Does it fits in iwr ? */
14489                 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
14490                         ((extra_size + offset) <= IFNAMSIZ))
14491                         extra_size = 0;
14492         } else {
14493                 /* Size of get arguments */
14494                 extra_size = get_priv_size(priv_args[k].get_args);
14495
14496                 /* Does it fits in iwr ? */
14497                 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
14498                         (extra_size <= IFNAMSIZ))
14499                         extra_size = 0;
14500         }
14501
14502         if (extra_size == 0) {
14503                 extra = (u8*)&wdata;
14504                 rtw_mfree(buffer, 4096);
14505                 buffer = NULL;
14506         } else
14507                 extra = buffer;
14508
14509         handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];
14510         err = handler(dev, NULL, &wdata, extra);
14511
14512         /* If we have to get some data */
14513         if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&
14514                 (priv_args[k].get_args & IW_PRIV_SIZE_MASK))
14515         {
14516                 int j;
14517                 int n = 0;      /* number of args */
14518                 u8 str[20] = {0};
14519
14520                 /* Check where is the returned data */
14521                 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
14522                         (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
14523                         n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;
14524                 else
14525                         n = wdata.data.length;
14526
14527                 output = rtw_zmalloc(4096);
14528                 if (NULL == output) {
14529                         err =  -ENOMEM;
14530                         goto exit;
14531                 }
14532
14533                 switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK)
14534                 {
14535                         case IW_PRIV_TYPE_BYTE:
14536                                 /* Display args */
14537                                 for (j = 0; j < n; j++)
14538                                 {
14539                                         sprintf(str, "%d  ", extra[j]);
14540                                         len = strlen(str);
14541                                         output_len = strlen(output);
14542                                         if ((output_len + len + 1) > 4096) {
14543                                                 err = -E2BIG;
14544                                                 goto exit;
14545                                         }
14546                                         _rtw_memcpy(output+output_len, str, len);
14547                                 }
14548                                 break;
14549
14550                         case IW_PRIV_TYPE_INT:
14551                                 /* Display args */
14552                                 for (j = 0; j < n; j++)
14553                                 {
14554                                         sprintf(str, "%d  ", ((__s32*)extra)[j]);
14555                                         len = strlen(str);
14556                                         output_len = strlen(output);
14557                                         if ((output_len + len + 1) > 4096) {
14558                                                 err = -E2BIG;
14559                                                 goto exit;
14560                                         }
14561                                         _rtw_memcpy(output+output_len, str, len);
14562                                 }
14563                                 break;
14564
14565                         case IW_PRIV_TYPE_CHAR:
14566                                 /* Display args */
14567                                 _rtw_memcpy(output, extra, n);
14568                                 break;
14569
14570                         default:
14571                                 DBG_8192C("%s: Not yet implemented...\n", __func__);
14572                                 err = -1;
14573                                 goto exit;
14574                 }
14575
14576                 output_len = strlen(output) + 1;
14577                 wrq_data->data.length = output_len;
14578                 if (copy_to_user(wrq_data->data.pointer, output, output_len)) {
14579                         err = -EFAULT;
14580                         goto exit;
14581                 }
14582         }   /* if args to set */
14583         else
14584         {
14585                 wrq_data->data.length = 0;
14586         }
14587
14588 exit:
14589         if (input)
14590                 rtw_mfree(input, input_len);
14591         if (buffer)
14592                 rtw_mfree(buffer, 4096);
14593         if (output)
14594                 rtw_mfree(output, 4096);
14595
14596         return err;
14597 }
14598
14599 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
14600 {
14601         struct iwreq *wrq = (struct iwreq *)rq;
14602         int ret=0;
14603
14604         switch (cmd)
14605         {
14606                 case RTL_IOCTL_WPA_SUPPLICANT:
14607                         ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
14608                         break;
14609 #ifdef CONFIG_AP_MODE
14610                 case RTL_IOCTL_HOSTAPD:
14611                         ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
14612                         break;
14613 #ifdef CONFIG_NO_WIRELESS_HANDLERS
14614                 case SIOCSIWMODE:
14615                         ret = rtw_wx_set_mode(dev, NULL, &wrq->u, NULL);
14616                         break;
14617 #endif
14618 #endif // CONFIG_AP_MODE
14619                 case SIOCDEVPRIVATE:
14620                         ret = rtw_ioctl_wext_private(dev, &wrq->u);
14621                         break;
14622                 case (SIOCDEVPRIVATE+1):
14623                         ret = rtw_android_priv_cmd(dev, rq, cmd);
14624                         break;
14625                 default:
14626                         ret = -EOPNOTSUPP;
14627                         break;
14628         }
14629
14630         return ret;
14631 }
14632
14633