1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
20 #define _IOCTL_LINUX_C_
22 #include <drv_types.h>
24 //#ifdef CONFIG_MP_INCLUDED
25 #include <rtw_mp_ioctl.h>
26 #include "../../hal/OUTSRC/odm_precomp.h"
29 #if defined(CONFIG_RTL8723A)
30 #include "rtl8723a_hal.h"
31 #include <rtw_bt_mp.h>
34 #if defined(CONFIG_RTL8723B)
35 #include <rtw_bt_mp.h>
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)
43 #ifdef CONFIG_80211N_HT
44 extern int rtw_ht_enable;
48 #define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
50 #define SCAN_ITEM_SIZE 768
51 #define MAX_CUSTOM_LEN 64
54 #ifdef CONFIG_GLOBAL_UI_PID
59 #define WEXT_CSCAN_AMOUNT 9
60 #define WEXT_CSCAN_BUF_LEN 360
61 #define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
62 #define WEXT_CSCAN_HEADER_SIZE 12
63 #define WEXT_CSCAN_SSID_SECTION 'S'
64 #define WEXT_CSCAN_CHANNEL_SECTION 'C'
65 #define WEXT_CSCAN_NPROBE_SECTION 'N'
66 #define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
67 #define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
68 #define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
69 #define WEXT_CSCAN_TYPE_SECTION 'T'
72 extern u8 key_2char2num(u8 hch, u8 lch);
73 extern u8 str_2char2num(u8 hch, u8 lch);
74 extern void macstr2num(u8 *dst, u8 *src);
75 extern u8 convert_ip_addr(u8 hch, u8 mch, u8 lch);
77 u32 rtw_rates[] = {1000000,2000000,5500000,11000000,
78 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
80 static const char * const iw_operation_mode[] =
82 "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary", "Monitor"
85 static int hex2num_i(char c)
87 if (c >= '0' && c <= '9')
89 if (c >= 'a' && c <= 'f')
91 if (c >= 'A' && c <= 'F')
96 static int hex2byte_i(const char *hex)
99 a = hex2num_i(*hex++);
102 b = hex2num_i(*hex++);
109 * hwaddr_aton - Convert ASCII string to MAC address
110 * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
111 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
112 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
114 static int hwaddr_aton_i(const char *txt, u8 *addr)
118 for (i = 0; i < 6; i++) {
121 a = hex2num_i(*txt++);
124 b = hex2num_i(*txt++);
127 *addr++ = (a << 4) | b;
128 if (i < 5 && *txt++ != ':')
135 static void indicate_wx_custom_event(_adapter *padapter, char *msg)
138 union iwreq_data wrqu;
140 if (strlen(msg) > IW_CUSTOM_MAX) {
141 DBG_871X("%s strlen(msg):%zu > IW_CUSTOM_MAX:%u\n", __FUNCTION__ , strlen(msg), IW_CUSTOM_MAX);
145 buff = rtw_zmalloc(IW_CUSTOM_MAX+1);
149 _rtw_memcpy(buff, msg, strlen(msg));
151 _rtw_memset(&wrqu,0,sizeof(wrqu));
152 wrqu.data.length = strlen(msg);
154 DBG_871X("%s %s\n", __FUNCTION__, buff);
155 #ifndef CONFIG_IOCTL_CFG80211
156 wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
159 rtw_mfree(buff, IW_CUSTOM_MAX+1);
164 static void request_wps_pbc_event(_adapter *padapter)
167 union iwreq_data wrqu;
170 buff = rtw_malloc(IW_CUSTOM_MAX);
174 _rtw_memset(buff, 0, IW_CUSTOM_MAX);
178 p+=sprintf(p, "WPS_PBC_START.request=TRUE");
180 _rtw_memset(&wrqu,0,sizeof(wrqu));
182 wrqu.data.length = p-buff;
184 wrqu.data.length = (wrqu.data.length<IW_CUSTOM_MAX) ? wrqu.data.length:IW_CUSTOM_MAX;
186 DBG_871X("%s\n", __FUNCTION__);
188 #ifndef CONFIG_IOCTL_CFG80211
189 wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
194 rtw_mfree(buff, IW_CUSTOM_MAX);
199 #ifdef CONFIG_SUPPORT_HW_WPS_PBC
200 void rtw_request_wps_pbc_event(_adapter *padapter)
202 #ifdef RTK_DMP_PLATFORM
203 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12))
204 kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_NET_PBC);
206 kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_NET_PBC);
210 if ( padapter->pid[0] == 0 )
211 { // 0 is the default value and it means the application monitors the HW PBC doesn't privde its pid to driver.
215 rtw_signal_process(padapter->pid[0], SIGUSR1);
219 rtw_led_control(padapter, LED_CTL_START_WPS_BOTTON);
221 #endif//#ifdef CONFIG_SUPPORT_HW_WPS_PBC
223 void indicate_wx_scan_complete_event(_adapter *padapter)
225 union iwreq_data wrqu;
226 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
228 _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
230 //DBG_871X("+rtw_indicate_wx_scan_complete_event\n");
231 #ifndef CONFIG_IOCTL_CFG80211
232 wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
237 void rtw_indicate_wx_assoc_event(_adapter *padapter)
239 union iwreq_data wrqu;
240 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
241 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
242 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
243 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
245 _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
247 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
249 if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE )
250 _rtw_memcpy(wrqu.ap_addr.sa_data, pnetwork->MacAddress, ETH_ALEN);
252 _rtw_memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
254 DBG_871X_LEVEL(_drv_always_, "assoc success\n");
255 #ifndef CONFIG_IOCTL_CFG80211
256 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
260 void rtw_indicate_wx_disassoc_event(_adapter *padapter)
262 union iwreq_data wrqu;
264 _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
266 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
267 _rtw_memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
269 #ifndef CONFIG_IOCTL_CFG80211
270 DBG_871X_LEVEL(_drv_always_, "indicate disassoc\n");
271 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
276 uint rtw_is_cckrates_included(u8 *rate)
282 if ( (((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) ||
283 (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22) )
291 uint rtw_is_cckratesonly_included(u8 *rate)
297 if ( (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
298 (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22) )
307 static char *translate_scan(_adapter *padapter,
308 struct iw_request_info* info, struct wlan_network *pnetwork,
309 char *start, char *stop)
313 u32 ht_ielen = 0, vht_ielen = 0;
314 char custom[MAX_CUSTOM_LEN];
316 u16 max_rate=0, rate, ht_cap=_FALSE, vht_cap = _FALSE;
320 u8 bw_40MHz=0, short_GI=0, bw_160MHz=0, vht_highest_rate = 0;
321 u16 mcs_rate=0, vht_data_rate=0;
322 u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);
323 struct registry_priv *pregpriv = &padapter->registrypriv;
325 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
330 if ( SCAN_RESULT_ALL == pwdinfo->wfd_info->scan_result_type )
334 else if ( ( SCAN_RESULT_P2P_ONLY == pwdinfo->wfd_info->scan_result_type ) ||
335 ( SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type ) )
338 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
340 u32 blnGotP2PIE = _FALSE;
342 // User is doing the P2P device discovery
343 // The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE.
344 // If not, the driver should ignore this AP and go to the next AP.
346 // Verifying the SSID
347 if ( _rtw_memcmp( pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN ) )
351 // Verifying the P2P IE
352 if (rtw_get_p2p_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0]))
358 if ( blnGotP2PIE == _FALSE )
367 if ( SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type )
369 u32 blnGotWFD = _FALSE;
370 u8 wfd_ie[ 128 ] = { 0x00 };
373 if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) )
375 u8 wfd_devinfo[ 6 ] = { 0x00 };
378 if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen) )
380 if ( pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_PSINK )
382 // the first two bits will indicate the WFD device type
383 if ( ( wfd_devinfo[ 1 ] & 0x03 ) == WFD_DEVINFO_SOURCE )
385 // If this device is Miracast PSink device, the scan reuslt should just provide the Miracast source.
389 else if ( pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_SOURCE )
391 // the first two bits will indicate the WFD device type
392 if ( ( wfd_devinfo[ 1 ] & 0x03 ) == WFD_DEVINFO_PSINK )
394 // If this device is Miracast source device, the scan reuslt should just provide the Miracast PSink.
395 // Todo: How about the SSink?!
402 if ( blnGotWFD == _FALSE )
413 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
415 _rtw_memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
416 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
419 iwe.cmd = SIOCGIWESSID;
420 iwe.u.data.flags = 1;
421 iwe.u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32);
422 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
425 if (pnetwork->network.Reserved[0] == 2) // Probe Request
427 p = rtw_get_ie(&pnetwork->network.IEs[0], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength);
431 p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-12);
435 struct rtw_ieee80211_ht_cap *pht_capie;
437 pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
438 _rtw_memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
439 bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH) ? 1:0;
440 short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1:0;
443 #ifdef CONFIG_80211AC_VHT
445 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength-ie_offset);
451 bw_160MHz = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p+2);
453 short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI160M(p+2);
455 short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI80M(p+2);
457 _rtw_memcpy(mcs_map, GET_VHT_CAPABILITY_ELE_TX_MCS(p+2), 2);
459 vht_highest_rate = rtw_get_vht_highest_rate(mcs_map);
460 vht_data_rate = rtw_vht_mcs_to_data_rate(CHANNEL_WIDTH_80, short_GI, vht_highest_rate);
464 /* Add the protocol name */
465 iwe.cmd = SIOCGIWNAME;
466 if ((rtw_is_cckratesonly_included((u8*)&pnetwork->network.SupportedRates)) == _TRUE)
469 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
471 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
473 else if ((rtw_is_cckrates_included((u8*)&pnetwork->network.SupportedRates)) == _TRUE)
476 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
478 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
482 if(pnetwork->network.Configuration.DSConfig > 14)
485 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11AC");
486 else if(ht_cap == _TRUE)
487 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11an");
489 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
494 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
496 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
500 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
503 if (pnetwork->network.Reserved[0] == 2) // Probe Request
509 iwe.cmd = SIOCGIWMODE;
510 _rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
511 cap = le16_to_cpu(cap);
514 if(cap & (WLAN_CAPABILITY_IBSS |WLAN_CAPABILITY_BSS)){
515 if (cap & WLAN_CAPABILITY_BSS)
516 iwe.u.mode = IW_MODE_MASTER;
518 iwe.u.mode = IW_MODE_ADHOC;
520 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
523 if(pnetwork->network.Configuration.DSConfig<1 /*|| pnetwork->network.Configuration.DSConfig>14*/)
524 pnetwork->network.Configuration.DSConfig = 1;
526 /* Add frequency/channel */
527 iwe.cmd = SIOCGIWFREQ;
528 iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
530 iwe.u.freq.i = pnetwork->network.Configuration.DSConfig;
531 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
533 /* Add encryption capability */
534 iwe.cmd = SIOCGIWENCODE;
535 if (cap & WLAN_CAPABILITY_PRIVACY)
536 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
538 iwe.u.data.flags = IW_ENCODE_DISABLED;
539 iwe.u.data.length = 0;
540 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
542 /*Add basic and extended rates */
545 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
546 while(pnetwork->network.SupportedRates[i]!=0)
548 rate = pnetwork->network.SupportedRates[i]&0x7F;
551 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
552 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
556 if(vht_cap == _TRUE) {
557 max_rate = vht_data_rate;
559 else if(ht_cap == _TRUE)
561 if(mcs_rate&0x8000)//MCS15
563 max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130);
566 else if(mcs_rate&0x0080)//MCS7
568 max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
572 //DBG_871X("wx_get_scan, mcs_rate_bitmap=0x%x\n", mcs_rate);
573 max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
576 max_rate = max_rate*2;//Mbps/2;
579 iwe.cmd = SIOCGIWRATE;
580 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
581 iwe.u.bitrate.value = max_rate * 500000;
582 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
584 //parsing WPA/WPA2 IE
585 if (pnetwork->network.Reserved[0] != 2) // Probe Request
587 u8 buf[MAX_WPA_IE_LEN*2];
588 u8 wpa_ie[255],rsn_ie[255];
589 u16 wpa_len=0,rsn_len=0;
592 out_len=rtw_get_sec_ie(pnetwork->network.IEs ,pnetwork->network.IELength,rsn_ie,&rsn_len,wpa_ie,&wpa_len);
593 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: ssid=%s\n",pnetwork->network.Ssid.Ssid));
594 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: wpa_len=%d rsn_len=%d\n",wpa_len,rsn_len));
599 _rtw_memset(buf, 0, MAX_WPA_IE_LEN*2);
600 p += sprintf(p, "wpa_ie=");
601 for (i = 0; i < wpa_len; i++) {
602 p += sprintf(p, "%02x", wpa_ie[i]);
606 printk("-----------------Len %d----------------\n", wpa_len);
607 for (i = 0; i < wpa_len; i++) {
608 printk("%02x ", wpa_ie[i]);
611 printk("-----------------Len %d----------------\n", wpa_len);
614 _rtw_memset(&iwe, 0, sizeof(iwe));
615 iwe.cmd = IWEVCUSTOM;
616 iwe.u.data.length = strlen(buf);
617 start = iwe_stream_add_point(info, start, stop, &iwe,buf);
619 _rtw_memset(&iwe, 0, sizeof(iwe));
621 iwe.u.data.length = wpa_len;
622 start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie);
627 _rtw_memset(buf, 0, MAX_WPA_IE_LEN*2);
628 p += sprintf(p, "rsn_ie=");
629 for (i = 0; i < rsn_len; i++) {
630 p += sprintf(p, "%02x", rsn_ie[i]);
632 _rtw_memset(&iwe, 0, sizeof(iwe));
633 iwe.cmd = IWEVCUSTOM;
634 iwe.u.data.length = strlen(buf);
635 start = iwe_stream_add_point(info, start, stop, &iwe,buf);
637 _rtw_memset(&iwe, 0, sizeof(iwe));
639 iwe.u.data.length = rsn_len;
640 start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
645 uint cnt = 0,total_ielen;
649 u8 *ie_ptr = pnetwork->network.IEs + ie_offset;
650 total_ielen= pnetwork->network.IELength - ie_offset;
652 if (pnetwork->network.Reserved[0] == 2) // Probe Request
654 ie_ptr = pnetwork->network.IEs;
655 total_ielen = pnetwork->network.IELength;
657 else // Beacon or Probe Respones
659 ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
660 total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
663 while(cnt < total_ielen)
665 if(rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen>2))
667 wpsie_ptr = &ie_ptr[cnt];
669 iwe.u.data.length = (u16)wps_ielen;
670 start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr);
672 cnt+=ie_ptr[cnt+1]+2; //goto next
676 #ifdef CONFIG_WAPI_SUPPORT
677 if (pnetwork->network.Reserved[0] != 2) // Probe Request
680 /* here use static for stack size */
681 static u8 buf_wapi[MAX_WAPI_IE_LEN*2];
682 static u8 wapi_ie[MAX_WAPI_IE_LEN];
686 _rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN);
687 _rtw_memset(wapi_ie, 0, MAX_WAPI_IE_LEN);
689 out_len_wapi=rtw_get_wapi_ie(pnetwork->network.IEs ,pnetwork->network.IELength,wapi_ie,&wapi_len);
690 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: ssid=%s\n",pnetwork->network.Ssid.Ssid));
691 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: wapi_len=%d \n",wapi_len));
693 DBG_871X("rtw_wx_get_scan: %s ",pnetwork->network.Ssid.Ssid);
694 DBG_871X("rtw_wx_get_scan: ssid = %d ",wapi_len);
700 _rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN*2);
701 p += sprintf(p, "wapi_ie=");
702 for (i = 0; i < wapi_len; i++) {
703 p += sprintf(p, "%02x", wapi_ie[i]);
706 _rtw_memset(&iwe, 0, sizeof(iwe));
707 iwe.cmd = IWEVCUSTOM;
708 iwe.u.data.length = strlen(buf_wapi);
709 start = iwe_stream_add_point(info, start, stop, &iwe,buf_wapi);
711 _rtw_memset(&iwe, 0, sizeof(iwe));
713 iwe.u.data.length = wapi_len;
714 start = iwe_stream_add_point(info, start, stop, &iwe, wapi_ie);
720 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
723 /* Add quality statistics */
725 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
726 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
727 | IW_QUAL_NOISE_UPDATED
729 | IW_QUAL_NOISE_INVALID
731 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
736 if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE &&
737 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)){
738 ss = padapter->recvpriv.signal_strength;
739 sq = padapter->recvpriv.signal_qual;
741 ss = pnetwork->network.PhyInfo.SignalStrength;
742 sq = pnetwork->network.PhyInfo.SignalQuality;
746 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
747 iwe.u.qual.level = (u8) translate_percentage_to_dbm(ss);//dbm
749 #ifdef CONFIG_SKIP_SIGNAL_SCALE_MAPPING
751 /* Do signal scale mapping when using percentage as the unit of signal strength, since the scale mapping is skipped in odm */
753 HAL_DATA_TYPE *pHal = GET_HAL_DATA(padapter);
755 iwe.u.qual.level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, ss);
758 iwe.u.qual.level = (u8)ss;//%
762 iwe.u.qual.qual = (u8)sq; // signal quality
764 #ifdef CONFIG_PLATFORM_ROCKCHIPS
765 iwe.u.qual.noise = -100; // noise level suggest by zhf@rockchips
767 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
770 rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&(pnetwork->network.Configuration.DSConfig), &(tmp_noise));
771 iwe.u.qual.noise = tmp_noise ;
774 iwe.u.qual.noise = 0; // noise level
776 #endif //CONFIG_PLATFORM_ROCKCHIPS
778 //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);
780 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
784 u8 buf[MAX_WPA_IE_LEN];
788 pos = pnetwork->network.Reserved;
789 _rtw_memset(buf, 0, MAX_WPA_IE_LEN);
790 p += sprintf(p, "fm=%02X%02X", pos[1], pos[0]);
791 _rtw_memset(&iwe, 0, sizeof(iwe));
792 iwe.cmd = IWEVCUSTOM;
793 iwe.u.data.length = strlen(buf);
794 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
800 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
802 _adapter *padapter = (_adapter *) rtw_netdev_priv(dev);
805 if ((value & AUTH_ALG_SHARED_KEY)&&(value & AUTH_ALG_OPEN_SYSTEM))
807 DBG_871X("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n",value);
808 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
809 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
810 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
812 else if (value & AUTH_ALG_SHARED_KEY)
814 DBG_871X("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n",value);
815 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
817 #ifdef CONFIG_PLATFORM_MT53XX
818 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
819 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
821 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
822 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
825 else if(value & AUTH_ALG_OPEN_SYSTEM)
827 DBG_871X("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
828 //padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
829 if(padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK)
831 #ifdef CONFIG_PLATFORM_MT53XX
832 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
833 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
835 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
836 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
841 else if(value & AUTH_ALG_LEAP)
843 DBG_871X("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
847 DBG_871X("wpa_set_auth_algs, error!\n");
855 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
858 u32 wep_key_idx, wep_key_len,wep_total_len;
859 NDIS_802_11_WEP *pwep = NULL;
860 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
861 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
862 struct security_priv *psecuritypriv = &padapter->securitypriv;
864 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
869 param->u.crypt.err = 0;
870 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
872 if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
878 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
879 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
880 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
883 if (param->u.crypt.idx >= WEP_KEYS
884 #ifdef CONFIG_IEEE80211W
885 && param->u.crypt.idx > BIP_MAX_KEYID
886 #endif //CONFIG_IEEE80211W
895 #ifdef CONFIG_WAPI_SUPPORT
896 if (strcmp(param->u.crypt.alg, "SMS4"))
904 if (strcmp(param->u.crypt.alg, "WEP") == 0)
906 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n"));
907 DBG_871X("wpa_set_encryption, crypt.alg = WEP\n");
909 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
910 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
911 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
913 wep_key_idx = param->u.crypt.idx;
914 wep_key_len = param->u.crypt.key_len;
916 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("(1)wep_key_idx=%d\n", wep_key_idx));
917 DBG_871X("(1)wep_key_idx=%d\n", wep_key_idx);
919 if (wep_key_idx > WEP_KEYS)
922 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("(2)wep_key_idx=%d\n", wep_key_idx));
926 wep_key_len = wep_key_len <= 5 ? 5 : 13;
927 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
928 pwep =(NDIS_802_11_WEP *) rtw_malloc(wep_total_len);
930 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,(" wpa_set_encryption: pwep allocate fail !!!\n"));
934 _rtw_memset(pwep, 0, wep_total_len);
936 pwep->KeyLength = wep_key_len;
937 pwep->Length = wep_total_len;
941 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
942 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
950 pwep->KeyIndex = wep_key_idx;
951 pwep->KeyIndex |= 0x80000000;
953 _rtw_memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
955 if(param->u.crypt.set_tx)
957 DBG_871X("wep, set_tx=1\n");
959 if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
966 DBG_871X("wep, set_tx=0\n");
968 //don't update "psecuritypriv->dot11PrivacyAlgrthm" and
969 //"psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to fw/cam
971 if (wep_key_idx >= WEP_KEYS) {
976 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
977 psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength;
978 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, _TRUE);
984 if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x
986 struct sta_info * psta,*pbcmc_sta;
987 struct sta_priv * pstapriv = &padapter->stapriv;
989 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode
991 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
993 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
997 //Jeff: don't disable ieee8021x_blocked while clearing key
998 if (strcmp(param->u.crypt.alg, "none") != 0)
999 psta->ieee8021x_blocked = _FALSE;
1001 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1002 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1004 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1007 if(param->u.crypt.set_tx ==1)//pairwise key
1009 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1011 if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key
1013 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1014 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1015 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1017 padapter->securitypriv.busetkipkey=_FALSE;
1018 //_set_timer(&padapter->securitypriv.tkip_timer, 50);
1021 //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
1022 DBG_871X(" ~~~~set sta key:unicastkey\n");
1024 rtw_setstakey_cmd(padapter, psta, _TRUE, _TRUE);
1028 if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
1030 _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));
1031 //only TKIP group key need to install this
1032 if(param->u.crypt.key_len > 16)
1034 _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8);
1035 _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8);
1037 padapter->securitypriv.binstallGrpkey = _TRUE;
1038 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1039 DBG_871X(" ~~~~set sta key:groupkey\n");
1041 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
1043 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1, _TRUE);
1045 #ifdef CONFIG_IEEE80211W
1046 else if(strcmp(param->u.crypt.alg, "BIP") == 0)
1049 //printk("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx);
1050 //save the IGTK key, length 16 bytes
1051 _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));
1052 /*printk("IGTK key below:\n");
1053 for(no=0;no<16;no++)
1054 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
1056 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
1057 padapter->securitypriv.binstallBIPkey = _TRUE;
1058 DBG_871X(" ~~~~set sta key:IGKT\n");
1060 #endif //CONFIG_IEEE80211W
1063 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
1065 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
1072 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
1075 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
1079 //Jeff: don't disable ieee8021x_blocked while clearing key
1080 if (strcmp(param->u.crypt.alg, "none") != 0)
1081 pbcmc_sta->ieee8021x_blocked = _FALSE;
1083 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1084 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1086 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1090 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode
1095 #ifdef CONFIG_WAPI_SUPPORT
1096 if (strcmp(param->u.crypt.alg, "SMS4") == 0)
1098 PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
1099 PRT_WAPI_STA_INFO pWapiSta;
1100 u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
1101 u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
1102 u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
1104 if(param->u.crypt.set_tx == 1)
1106 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1107 if(_rtw_memcmp(pWapiSta->PeerMacAddr,param->sta_addr,6))
1109 _rtw_memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16);
1111 pWapiSta->wapiUsk.bSet = true;
1112 _rtw_memcpy(pWapiSta->wapiUsk.dataKey,param->u.crypt.key,16);
1113 _rtw_memcpy(pWapiSta->wapiUsk.micKey,param->u.crypt.key+16,16);
1114 pWapiSta->wapiUsk.keyId = param->u.crypt.idx ;
1115 pWapiSta->wapiUsk.bTxEnable = true;
1117 _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16);
1118 _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16);
1119 _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16);
1120 _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16);
1121 _rtw_memcpy(pWapiSta->lastRxUnicastPN,WapiAEPNInitialValueSrc,16);
1122 pWapiSta->wapiUskUpdate.bTxEnable = false;
1123 pWapiSta->wapiUskUpdate.bSet = false;
1125 if (psecuritypriv->sw_encrypt== false || psecuritypriv->sw_decrypt == false)
1127 //set unicast key for ASUE
1128 rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false);
1135 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1136 if(_rtw_memcmp(pWapiSta->PeerMacAddr,get_bssid(pmlmepriv),6))
1138 pWapiSta->wapiMsk.bSet = true;
1139 _rtw_memcpy(pWapiSta->wapiMsk.dataKey,param->u.crypt.key,16);
1140 _rtw_memcpy(pWapiSta->wapiMsk.micKey,param->u.crypt.key+16,16);
1141 pWapiSta->wapiMsk.keyId = param->u.crypt.idx ;
1142 pWapiSta->wapiMsk.bTxEnable = false;
1143 if(!pWapiSta->bSetkeyOk)
1144 pWapiSta->bSetkeyOk = true;
1145 pWapiSta->bAuthenticateInProgress = false;
1147 _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
1149 if (psecuritypriv->sw_decrypt == false)
1151 //set rx broadcast key for ASUE
1152 rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false);
1164 rtw_mfree((u8 *)pwep, wep_total_len);
1172 static int rtw_set_wpa_ie(_adapter *padapter, char *pie, unsigned short ielen)
1174 u8 *buf=NULL, *pos=NULL;
1176 int group_cipher = 0, pairwise_cipher = 0;
1178 u8 null_addr[]= {0,0,0,0,0,0};
1180 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
1183 if((ielen > MAX_WPA_IE_LEN) || (pie == NULL)){
1184 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1193 buf = rtw_zmalloc(ielen);
1199 _rtw_memcpy(buf, pie , ielen);
1204 DBG_871X("\n wpa_ie(length:%d):\n", ielen);
1205 for(i=0;i<ielen;i=i+8)
1206 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]);
1210 if(ielen < RSN_HEADER_LEN){
1211 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
1217 pos += RSN_HEADER_LEN;
1218 left = ielen - RSN_HEADER_LEN;
1220 if (left >= RSN_SELECTOR_LEN){
1221 pos += RSN_SELECTOR_LEN;
1222 left -= RSN_SELECTOR_LEN;
1225 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie length mismatch, %u too much \n", left));
1231 if(rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
1233 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
1234 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
1235 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
1238 if(rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
1240 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
1241 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;
1242 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
1245 if (group_cipher == 0)
1247 group_cipher = WPA_CIPHER_NONE;
1249 if (pairwise_cipher == 0)
1251 pairwise_cipher = WPA_CIPHER_NONE;
1254 switch(group_cipher)
1256 case WPA_CIPHER_NONE:
1257 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
1258 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
1260 case WPA_CIPHER_WEP40:
1261 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
1262 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1264 case WPA_CIPHER_TKIP:
1265 padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
1266 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1268 case WPA_CIPHER_CCMP:
1269 padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
1270 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1272 case WPA_CIPHER_WEP104:
1273 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
1274 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1278 switch(pairwise_cipher)
1280 case WPA_CIPHER_NONE:
1281 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
1282 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
1284 case WPA_CIPHER_WEP40:
1285 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
1286 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1288 case WPA_CIPHER_TKIP:
1289 padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
1290 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1292 case WPA_CIPHER_CCMP:
1293 padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
1294 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1296 case WPA_CIPHER_WEP104:
1297 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
1298 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1302 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1305 u8 eid, wps_oui[4]={0x0,0x50,0xf2,0x04};
1307 while( cnt < ielen )
1311 if((eid==_VENDOR_SPECIFIC_IE_)&&(_rtw_memcmp(&buf[cnt+2], wps_oui, 4)==_TRUE))
1313 DBG_871X("SET WPS_IE\n");
1315 padapter->securitypriv.wps_ie_len = ((buf[cnt+1]+2) < MAX_WPS_IE_LEN) ? (buf[cnt+1]+2):MAX_WPS_IE_LEN;
1317 _rtw_memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
1319 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
1322 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
1324 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING);
1327 cnt += buf[cnt+1]+2;
1331 cnt += buf[cnt+1]+2; //goto next
1337 //TKIP and AES disallow multicast packets until installing group key
1338 if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
1339 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
1340 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
1341 //WPS open need to enable multicast
1342 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
1343 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
1345 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1346 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
1347 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
1351 if (buf) rtw_mfree(buf, ielen);
1356 static int rtw_wx_get_name(struct net_device *dev,
1357 struct iw_request_info *info,
1358 union iwreq_data *wrqu, char *extra)
1360 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1364 u8 ht_cap=_FALSE, vht_cap=_FALSE;
1365 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1366 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1367 NDIS_802_11_RATES_EX* prates = NULL;
1369 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("cmd_code=%x\n", info->cmd));
1373 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE)
1376 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12);
1382 #ifdef CONFIG_80211AC_VHT
1383 if(pmlmepriv->vhtpriv.vht_option == _TRUE)
1387 prates = &pcur_bss->SupportedRates;
1389 if (rtw_is_cckratesonly_included((u8*)prates) == _TRUE)
1392 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
1394 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
1396 else if ((rtw_is_cckrates_included((u8*)prates)) == _TRUE)
1399 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
1401 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
1405 if(pcur_bss->Configuration.DSConfig > 14)
1407 if(vht_cap == _TRUE)
1408 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC");
1409 else if(ht_cap == _TRUE)
1410 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
1412 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
1417 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
1419 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
1425 //prates = &padapter->registrypriv.dev_network.SupportedRates;
1426 //snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
1427 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
1435 static int rtw_wx_set_freq(struct net_device *dev,
1436 struct iw_request_info *info,
1437 union iwreq_data *wrqu, char *extra)
1441 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n"));
1448 static int rtw_wx_get_freq(struct net_device *dev,
1449 struct iw_request_info *info,
1450 union iwreq_data *wrqu, char *extra)
1452 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1453 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1454 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1456 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
1458 //wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000;
1459 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
1461 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
1465 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
1467 wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
1473 static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
1474 union iwreq_data *wrqu, char *b)
1476 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1477 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
1482 if(_FAIL == rtw_pwr_wakeup(padapter)) {
1487 if (padapter->hw_init_completed==_FALSE){
1495 networkType = Ndis802_11AutoUnknown;
1496 DBG_871X("set_mode = IW_MODE_AUTO\n");
1499 networkType = Ndis802_11IBSS;
1500 DBG_871X("set_mode = IW_MODE_ADHOC\n");
1502 case IW_MODE_MASTER:
1503 networkType = Ndis802_11APMode;
1504 DBG_871X("set_mode = IW_MODE_MASTER\n");
1505 //rtw_setopmode_cmd(padapter, networkType,_TRUE);
1508 networkType = Ndis802_11Infrastructure;
1509 DBG_871X("set_mode = IW_MODE_INFRA\n");
1514 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("\n Mode: %s is not supported \n", iw_operation_mode[wrqu->mode]));
1519 if(Ndis802_11APMode == networkType)
1521 rtw_setopmode_cmd(padapter, networkType,_TRUE);
1525 rtw_setopmode_cmd(padapter, Ndis802_11AutoUnknown,_TRUE);
1529 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE){
1536 rtw_setopmode_cmd(padapter, networkType,_TRUE);
1546 static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
1547 union iwreq_data *wrqu, char *b)
1549 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1550 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1552 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,(" rtw_wx_get_mode \n"));
1556 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1558 wrqu->mode = IW_MODE_INFRA;
1560 else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
1561 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
1564 wrqu->mode = IW_MODE_ADHOC;
1566 else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1568 wrqu->mode = IW_MODE_MASTER;
1572 wrqu->mode = IW_MODE_AUTO;
1582 static int rtw_wx_set_pmkid(struct net_device *dev,
1583 struct iw_request_info *a,
1584 union iwreq_data *wrqu, char *extra)
1586 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1587 u8 j,blInserted = _FALSE;
1588 int intReturn = _FALSE;
1589 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1590 struct security_priv *psecuritypriv = &padapter->securitypriv;
1591 struct iw_pmksa* pPMK = ( struct iw_pmksa* ) extra;
1592 u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
1593 u8 strIssueBssid[ ETH_ALEN ] = { 0x00 };
1599 struct sockaddr bssid;
1600 __u8 pmkid[IW_PMKID_LEN]; //IW_PMKID_LEN=16
1602 There are the BSSID information in the bssid.sa_data array.
1603 If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear all the PMKID information.
1604 If cmd is IW_PMKSA_ADD, it means the wpa_supplicant wants to add a PMKID/BSSID to driver.
1605 If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to remove a PMKID/BSSID from driver.
1608 _rtw_memcpy( strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
1609 if ( pPMK->cmd == IW_PMKSA_ADD )
1611 DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n" );
1612 if ( _rtw_memcmp( strIssueBssid, strZeroMacAddress, ETH_ALEN ) == _TRUE )
1614 return( intReturn );
1620 blInserted = _FALSE;
1623 for(j=0 ; j<NUM_PMKID_CACHE; j++)
1625 if( _rtw_memcmp( psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) ==_TRUE )
1626 { // BSSID is matched, the same AP => rewrite with new PMKID.
1628 DBG_871X( "[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n" );
1630 _rtw_memcpy( psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1631 psecuritypriv->PMKIDList[ j ].bUsed = _TRUE;
1632 psecuritypriv->PMKIDIndex = j+1;
1641 DBG_871X( "[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
1642 psecuritypriv->PMKIDIndex );
1644 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
1645 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1647 psecuritypriv->PMKIDList[ psecuritypriv->PMKIDIndex ].bUsed = _TRUE;
1648 psecuritypriv->PMKIDIndex++ ;
1649 if(psecuritypriv->PMKIDIndex==16)
1651 psecuritypriv->PMKIDIndex =0;
1655 else if ( pPMK->cmd == IW_PMKSA_REMOVE )
1657 DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n" );
1659 for(j=0 ; j<NUM_PMKID_CACHE; j++)
1661 if( _rtw_memcmp( psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) ==_TRUE )
1662 { // BSSID is matched, the same AP => Remove this PMKID information and reset it.
1663 _rtw_memset( psecuritypriv->PMKIDList[ j ].Bssid, 0x00, ETH_ALEN );
1664 psecuritypriv->PMKIDList[ j ].bUsed = _FALSE;
1669 else if ( pPMK->cmd == IW_PMKSA_FLUSH )
1671 DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n" );
1672 _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
1673 psecuritypriv->PMKIDIndex = 0;
1676 return( intReturn );
1679 static int rtw_wx_get_sens(struct net_device *dev,
1680 struct iw_request_info *info,
1681 union iwreq_data *wrqu, char *extra)
1683 #ifdef CONFIG_PLATFORM_ROCKCHIPS
1684 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1685 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1688 * 20110311 Commented by Jeff
1689 * For rockchip platform's wpa_driver_wext_get_rssi
1691 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
1692 //wrqu->sens.value=-padapter->recvpriv.signal_strength;
1693 wrqu->sens.value=-padapter->recvpriv.rssi;
1694 //DBG_871X("%s: %d\n", __FUNCTION__, wrqu->sens.value);
1695 wrqu->sens.fixed = 0; /* no auto select */
1699 wrqu->sens.value = 0;
1700 wrqu->sens.fixed = 0; /* no auto select */
1701 wrqu->sens.disabled = 1;
1706 static int rtw_wx_get_range(struct net_device *dev,
1707 struct iw_request_info *info,
1708 union iwreq_data *wrqu, char *extra)
1710 struct iw_range *range = (struct iw_range *)extra;
1711 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1712 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1719 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_range. cmd_code=%x\n", info->cmd));
1721 wrqu->data.length = sizeof(*range);
1722 _rtw_memset(range, 0, sizeof(*range));
1724 /* Let's try to keep this struct in the same order as in
1725 * linux/include/wireless.h
1728 /* TODO: See what values we can set, and remove the ones we can't
1729 * set, or fill them with some default data.
1732 /* ~5 Mb/s real (802.11b) */
1733 range->throughput = 5 * 1000 * 1000;
1735 // TODO: Not used in 802.11b?
1736 // range->min_nwid; /* Minimal NWID we are able to set */
1737 // TODO: Not used in 802.11b?
1738 // range->max_nwid; /* Maximal NWID we are able to set */
1740 /* Old Frequency (backward compat - moved lower ) */
1741 // range->old_num_channels;
1742 // range->old_num_frequency;
1743 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
1745 /* signal level threshold range */
1747 //percent values between 0 and 100.
1748 range->max_qual.qual = 100;
1749 range->max_qual.level = 100;
1750 range->max_qual.noise = 100;
1751 range->max_qual.updated = 7; /* Updated all three */
1754 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
1755 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
1756 range->avg_qual.level = 20 + -98;
1757 range->avg_qual.noise = 0;
1758 range->avg_qual.updated = 7; /* Updated all three */
1760 range->num_bitrates = RATE_COUNT;
1762 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
1763 range->bitrate[i] = rtw_rates[i];
1766 range->min_frag = MIN_FRAG_THRESHOLD;
1767 range->max_frag = MAX_FRAG_THRESHOLD;
1771 range->we_version_compiled = WIRELESS_EXT;
1772 range->we_version_source = 16;
1774 // range->retry_capa; /* What retry options are supported */
1775 // range->retry_flags; /* How to decode max/min retry limit */
1776 // range->r_time_flags; /* How to decode max/min retry life */
1777 // range->min_retry; /* Minimal number of retries */
1778 // range->max_retry; /* Maximal number of retries */
1779 // range->min_r_time; /* Minimal retry lifetime */
1780 // range->max_r_time; /* Maximal retry lifetime */
1782 for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
1784 // Include only legal frequencies for some countries
1785 if(pmlmeext->channel_set[i].ChannelNum != 0)
1787 range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
1788 range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
1789 range->freq[val].e = 1;
1793 if (val == IW_MAX_FREQUENCIES)
1797 range->num_channels = val;
1798 range->num_frequency = val;
1800 // Commented by Albert 2009/10/13
1801 // The following code will proivde the security capability to network manager.
1802 // If the driver doesn't provide this capability to network manager,
1803 // the WPA/WPA2 routers can't be choosen in the network manager.
1806 #define IW_SCAN_CAPA_NONE 0x00
1807 #define IW_SCAN_CAPA_ESSID 0x01
1808 #define IW_SCAN_CAPA_BSSID 0x02
1809 #define IW_SCAN_CAPA_CHANNEL 0x04
1810 #define IW_SCAN_CAPA_MODE 0x08
1811 #define IW_SCAN_CAPA_RATE 0x10
1812 #define IW_SCAN_CAPA_TYPE 0x20
1813 #define IW_SCAN_CAPA_TIME 0x40
1816 #if WIRELESS_EXT > 17
1817 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
1818 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
1821 #ifdef IW_SCAN_CAPA_ESSID //WIRELESS_EXT > 21
1822 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |IW_SCAN_CAPA_BSSID|
1823 IW_SCAN_CAPA_CHANNEL|IW_SCAN_CAPA_MODE|IW_SCAN_CAPA_RATE;
1834 //s1. rtw_set_802_11_infrastructure_mode()
1835 //s2. rtw_set_802_11_authentication_mode()
1836 //s3. set_802_11_encryption_mode()
1837 //s4. rtw_set_802_11_bssid()
1838 static int rtw_wx_set_wap(struct net_device *dev,
1839 struct iw_request_info *info,
1840 union iwreq_data *awrq,
1845 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1846 struct sockaddr *temp = (struct sockaddr *)awrq;
1847 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1849 u8 *dst_bssid, *src_bssid;
1850 _queue *queue = &(pmlmepriv->scanned_queue);
1851 struct wlan_network *pnetwork = NULL;
1852 NDIS_802_11_AUTHENTICATION_MODE authmode;
1856 #ifdef CONFIG_CONCURRENT_MODE
1857 if(padapter->iface_type > PRIMARY_IFACE)
1865 #ifdef CONFIG_CONCURRENT_MODE
1866 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
1868 DBG_871X("set bssid, but buddy_intf is under scanning or linking\n");
1876 #ifdef CONFIG_DUALMAC_CONCURRENT
1877 if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE)
1879 DBG_871X("set bssid, but buddy_intf is under scanning or linking\n");
1885 rtw_ps_deny(padapter, PS_DENY_JOIN);
1886 if(_FAIL == rtw_pwr_wakeup(padapter))
1898 if (temp->sa_family != ARPHRD_ETHER){
1903 authmode = padapter->securitypriv.ndisauthtype;
1904 _enter_critical_bh(&queue->lock, &irqL);
1905 phead = get_list_head(queue);
1906 pmlmepriv->pscanned = get_next(phead);
1911 if ((rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) == _TRUE)
1917 if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
1919 rtw_set_802_11_bssid(padapter, temp->sa_data);
1932 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
1934 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1936 dst_bssid = pnetwork->network.MacAddress;
1938 src_bssid = temp->sa_data;
1940 if ((_rtw_memcmp(dst_bssid, src_bssid, ETH_ALEN)) == _TRUE)
1942 if(!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode))
1945 _exit_critical_bh(&queue->lock, &irqL);
1953 _exit_critical_bh(&queue->lock, &irqL);
1955 rtw_set_802_11_authentication_mode(padapter, authmode);
1956 //set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
1957 if (rtw_set_802_11_bssid(padapter, temp->sa_data) == _FALSE) {
1964 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
1971 static int rtw_wx_get_wap(struct net_device *dev,
1972 struct iw_request_info *info,
1973 union iwreq_data *wrqu, char *extra)
1976 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1977 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1978 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1980 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1982 _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1984 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_wap\n"));
1988 if ( ((check_fwstate(pmlmepriv, _FW_LINKED)) == _TRUE) ||
1989 ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) ||
1990 ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == _TRUE) )
1993 _rtw_memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1997 _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
2006 static int rtw_wx_set_mlme(struct net_device *dev,
2007 struct iw_request_info *info,
2008 union iwreq_data *wrqu, char *extra)
2011 /* SIOCSIWMLME data */
2014 __u16 cmd; /* IW_MLME_* */
2016 struct sockaddr addr;
2022 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2023 struct iw_mlme *mlme = (struct iw_mlme *) extra;
2029 DBG_871X("%s\n", __FUNCTION__);
2031 reason = cpu_to_le16(mlme->reason_code);
2034 DBG_871X("%s, cmd=%d, reason=%d\n", __FUNCTION__, mlme->cmd, reason);
2039 case IW_MLME_DEAUTH:
2040 if(!rtw_set_802_11_disassociate(padapter))
2044 case IW_MLME_DISASSOC:
2045 if(!rtw_set_802_11_disassociate(padapter))
2057 static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
2058 union iwreq_data *wrqu, char *extra)
2060 u8 _status = _FALSE;
2062 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2063 struct mlme_priv *pmlmepriv= &padapter->mlmepriv;
2064 NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
2067 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
2069 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_set_scan\n"));
2074 DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__);
2077 #ifdef CONFIG_CONCURRENT_MODE
2078 if(padapter->iface_type > PRIMARY_IFACE)
2085 #ifdef CONFIG_MP_INCLUDED
2086 if (padapter->registrypriv.mp_mode == 1)
2088 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter));
2092 #ifdef CONFIG_CONCURRENT_MODE
2093 if (padapter->pbuddy_adapter) {
2094 if (padapter->pbuddy_adapter->registrypriv.mp_mode == 1)
2096 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter->pbuddy_adapter));
2101 #endif //CONFIG_CONCURRENT_MODE
2104 rtw_ps_deny(padapter, PS_DENY_SCAN);
2105 if(_FAIL == rtw_pwr_wakeup(padapter))
2111 if(padapter->bDriverStopped){
2112 DBG_871X("bDriverStopped=%d\n", padapter->bDriverStopped);
2122 if (padapter->hw_init_completed==_FALSE){
2127 // When Busy Traffic, driver do not site survey. So driver return success.
2128 // wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout.
2129 // modify by thomas 2011-02-22.
2130 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE
2131 #ifdef CONFIG_CONCURRENT_MODE
2132 || rtw_get_buddy_bBusyTraffic(padapter) == _TRUE
2133 #endif //CONFIG_CONCURRENT_MODE
2136 indicate_wx_scan_complete_event(padapter);
2140 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2142 indicate_wx_scan_complete_event(padapter);
2146 #ifdef CONFIG_CONCURRENT_MODE
2147 if (check_buddy_fwstate(padapter,
2148 _FW_UNDER_SURVEY|_FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
2150 indicate_wx_scan_complete_event(padapter);
2155 #ifdef CONFIG_DUALMAC_CONCURRENT
2156 if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE)
2158 indicate_wx_scan_complete_event(padapter);
2164 if ( pwdinfo->p2p_state != P2P_STATE_NONE )
2166 rtw_p2p_set_pre_state( pwdinfo, rtw_p2p_state( pwdinfo ) );
2167 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
2168 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL);
2169 rtw_free_network_queue(padapter, _TRUE);
2173 _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
2175 #if WIRELESS_EXT >= 17
2176 if (wrqu->data.length == sizeof(struct iw_scan_req))
2178 struct iw_scan_req *req = (struct iw_scan_req *)extra;
2180 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
2182 int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
2184 _rtw_memcpy(ssid[0].Ssid, req->essid, len);
2185 ssid[0].SsidLength = len;
2187 DBG_871X("IW_SCAN_THIS_ESSID, ssid=%s, len=%d\n", req->essid, req->essid_len);
2189 _enter_critical_bh(&pmlmepriv->lock, &irqL);
2191 _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0);
2193 _exit_critical_bh(&pmlmepriv->lock, &irqL);
2196 else if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
2198 DBG_871X("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
2205 if( wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE
2206 && _rtw_memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
2209 int len = wrqu->data.length -WEXT_CSCAN_HEADER_SIZE;
2210 char *pos = extra+WEXT_CSCAN_HEADER_SIZE;
2215 //DBG_871X("%s COMBO_SCAN header is recognized\n", __FUNCTION__);
2218 section = *(pos++); len-=1;
2221 case WEXT_CSCAN_SSID_SECTION:
2222 //DBG_871X("WEXT_CSCAN_SSID_SECTION\n");
2228 sec_len = *(pos++); len-=1;
2230 if(sec_len>0 && sec_len<=len) {
2231 ssid[ssid_index].SsidLength = sec_len;
2232 _rtw_memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength);
2233 //DBG_871X("%s COMBO_SCAN with specific ssid:%s, %d\n", __FUNCTION__
2234 // , ssid[ssid_index].Ssid, ssid[ssid_index].SsidLength);
2238 pos+=sec_len; len-=sec_len;
2242 case WEXT_CSCAN_CHANNEL_SECTION:
2243 //DBG_871X("WEXT_CSCAN_CHANNEL_SECTION\n");
2246 case WEXT_CSCAN_ACTV_DWELL_SECTION:
2247 //DBG_871X("WEXT_CSCAN_ACTV_DWELL_SECTION\n");
2250 case WEXT_CSCAN_PASV_DWELL_SECTION:
2251 //DBG_871X("WEXT_CSCAN_PASV_DWELL_SECTION\n");
2254 case WEXT_CSCAN_HOME_DWELL_SECTION:
2255 //DBG_871X("WEXT_CSCAN_HOME_DWELL_SECTION\n");
2258 case WEXT_CSCAN_TYPE_SECTION:
2259 //DBG_871X("WEXT_CSCAN_TYPE_SECTION\n");
2263 case WEXT_CSCAN_NPROBE_SECTION:
2264 DBG_871X("WEXT_CSCAN_NPROBE_SECTION\n");
2269 //DBG_871X("Unknown CSCAN section %c\n", section);
2270 len = 0; // stop parsing
2272 //DBG_871X("len:%d\n", len);
2276 //jeff: it has still some scan paramater to parse, we only do this now...
2277 _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
2282 _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
2285 if(_status == _FALSE)
2290 rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
2293 DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret);
2301 static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
2302 union iwreq_data *wrqu, char *extra)
2305 _list *plist, *phead;
2306 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2307 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2308 _queue *queue = &(pmlmepriv->scanned_queue);
2309 struct wlan_network *pnetwork = NULL;
2311 char *stop = ev + wrqu->data.length;
2314 u32 wait_for_surveydone;
2316 #ifdef CONFIG_CONCURRENT_MODE
2317 //PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
2318 //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
2321 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
2323 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan\n"));
2324 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_, (" Start of Query SIOCGIWSCAN .\n"));
2329 DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__);
2332 #ifdef CONFIG_CONCURRENT_MODE
2333 if(padapter->iface_type > PRIMARY_IFACE)
2340 if(adapter_to_pwrctl(padapter)->brfoffbyhw && padapter->bDriverStopped)
2347 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2350 if ( padapter->chip_type == RTL8192D )
2351 wait_for_surveydone = 300; // Because the 8192du supports more channels.
2353 wait_for_surveydone = 200;
2358 wait_for_surveydone = 100;
2362 wait_for_surveydone = 100;
2366 #if 1 // Wireless Extension use EAGAIN to try
2367 wait_status = _FW_UNDER_SURVEY
2368 #ifndef CONFIG_ANDROID
2373 while (check_fwstate(pmlmepriv, wait_status) == _TRUE)
2378 wait_status = _FW_UNDER_SURVEY
2379 #ifndef CONFIG_ANDROID
2384 #ifdef CONFIG_DUALMAC_CONCURRENT
2385 while(dc_check_fwstate(padapter, wait_status)== _TRUE)
2389 if(cnt > wait_for_surveydone )
2392 #endif // CONFIG_DUALMAC_CONCURRENT
2394 while(check_fwstate(pmlmepriv, wait_status) == _TRUE)
2398 if(cnt > wait_for_surveydone )
2402 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2404 phead = get_list_head(queue);
2405 plist = get_next(phead);
2409 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
2412 if((stop - ev) < SCAN_ITEM_SIZE) {
2417 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2419 //report network only if the current channel set contains the channel to which this network belongs
2420 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
2421 && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE
2422 && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
2425 ev=translate_scan(padapter, a, pnetwork, ev, stop);
2428 plist = get_next(plist);
2432 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2434 wrqu->data.length = ev-extra;
2435 wrqu->data.flags = 0;
2442 DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret);
2450 //s1. rtw_set_802_11_infrastructure_mode()
2451 //s2. set_802_11_authenticaion_mode()
2452 //s3. set_802_11_encryption_mode()
2453 //s4. rtw_set_802_11_ssid()
2454 static int rtw_wx_set_essid(struct net_device *dev,
2455 struct iw_request_info *a,
2456 union iwreq_data *wrqu, char *extra)
2459 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2460 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2461 _queue *queue = &pmlmepriv->scanned_queue;
2464 struct wlan_network *pnetwork = NULL;
2465 NDIS_802_11_AUTHENTICATION_MODE authmode;
2466 NDIS_802_11_SSID ndis_ssid;
2467 u8 *dst_ssid, *src_ssid;
2474 DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__);
2478 #ifdef CONFIG_CONCURRENT_MODE
2479 if(padapter->iface_type > PRIMARY_IFACE)
2487 #ifdef CONFIG_CONCURRENT_MODE
2488 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2490 DBG_871X("set ssid, but buddy_intf is under scanning or linking\n");
2498 #ifdef CONFIG_DUALMAC_CONCURRENT
2499 if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE)
2501 DBG_871X("set bssid, but buddy_intf is under scanning or linking\n");
2507 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2508 ("+rtw_wx_set_essid: fw_state=0x%08x\n", get_fwstate(pmlmepriv)));
2510 rtw_ps_deny(padapter, PS_DENY_JOIN);
2511 if(_FAIL == rtw_pwr_wakeup(padapter))
2522 #if WIRELESS_EXT <= 20
2523 if ((wrqu->essid.length-1) > IW_ESSID_MAX_SIZE){
2525 if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
2531 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2536 authmode = padapter->securitypriv.ndisauthtype;
2537 DBG_871X("=>%s\n",__FUNCTION__);
2538 if (wrqu->essid.flags && wrqu->essid.length)
2540 // Commented by Albert 20100519
2541 // We got the codes in "set_info" function of iwconfig source code.
2542 // =========================================
2543 // wrq.u.essid.length = strlen(essid) + 1;
2544 // if(we_kernel_version > 20)
2545 // wrq.u.essid.length--;
2546 // =========================================
2547 // That means, if the WIRELESS_EXT less than or equal to 20, the correct ssid len should subtract 1.
2548 #if WIRELESS_EXT <= 20
2549 len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
2551 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
2554 if( wrqu->essid.length != 33 )
2555 DBG_871X("ssid=%s, len=%d\n", extra, wrqu->essid.length);
2557 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
2558 ndis_ssid.SsidLength = len;
2559 _rtw_memcpy(ndis_ssid.Ssid, extra, len);
2560 src_ssid = ndis_ssid.Ssid;
2562 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid=[%s]\n", src_ssid));
2563 _enter_critical_bh(&queue->lock, &irqL);
2564 phead = get_list_head(queue);
2565 pmlmepriv->pscanned = get_next(phead);
2569 if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == _TRUE)
2572 if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
2574 rtw_set_802_11_ssid(padapter, &ndis_ssid);
2580 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("rtw_wx_set_ssid(): scanned_queue is empty\n"));
2585 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_warning_,
2586 ("rtw_wx_set_essid: scan_q is empty, set ssid to check if scanning again!\n"));
2591 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
2593 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
2595 dst_ssid = pnetwork->network.Ssid.Ssid;
2597 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2598 ("rtw_wx_set_essid: dst_ssid=%s\n",
2599 pnetwork->network.Ssid.Ssid));
2601 if ((_rtw_memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength) == _TRUE) &&
2602 (pnetwork->network.Ssid.SsidLength==ndis_ssid.SsidLength))
2604 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2605 ("rtw_wx_set_essid: find match, set infra mode\n"));
2607 if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
2609 if(pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
2613 if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == _FALSE)
2616 _exit_critical_bh(&queue->lock, &irqL);
2623 _exit_critical_bh(&queue->lock, &irqL);
2624 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2625 ("set ssid: set_802_11_auth. mode=%d\n", authmode));
2626 rtw_set_802_11_authentication_mode(padapter, authmode);
2627 //set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
2628 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {
2636 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
2638 DBG_871X("<=%s, ret %d\n",__FUNCTION__, ret);
2641 DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret);
2649 static int rtw_wx_get_essid(struct net_device *dev,
2650 struct iw_request_info *a,
2651 union iwreq_data *wrqu, char *extra)
2654 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2655 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2656 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
2658 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_essid\n"));
2662 if ( (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ||
2663 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE))
2665 len = pcur_bss->Ssid.SsidLength;
2667 wrqu->essid.length = len;
2669 _rtw_memcpy(extra, pcur_bss->Ssid.Ssid, len);
2671 wrqu->essid.flags = 1;
2687 static int rtw_wx_set_rate(struct net_device *dev,
2688 struct iw_request_info *a,
2689 union iwreq_data *wrqu, char *extra)
2692 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2693 u8 datarates[NumRates];
2694 u32 target_rate = wrqu->bitrate.value;
2695 u32 fixed = wrqu->bitrate.fixed;
2697 u8 mpdatarate[NumRates]={11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
2701 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,(" rtw_wx_set_rate \n"));
2702 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("target_rate = %d, fixed = %d\n",target_rate,fixed));
2704 if(target_rate == -1){
2708 target_rate = target_rate/100000;
2710 switch(target_rate){
2754 for(i=0; i<NumRates; i++)
2756 if(ratevalue==mpdatarate[i])
2758 datarates[i] = mpdatarate[i];
2763 datarates[i] = 0xff;
2766 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("datarate_inx=%d\n",datarates[i]));
2769 if( rtw_setdatarate_cmd(padapter, datarates) !=_SUCCESS){
2770 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("rtw_wx_set_rate Fail!!!\n"));
2779 static int rtw_wx_get_rate(struct net_device *dev,
2780 struct iw_request_info *info,
2781 union iwreq_data *wrqu, char *extra)
2785 max_rate = rtw_get_cur_max_rate((_adapter *)rtw_netdev_priv(dev));
2790 wrqu->bitrate.fixed = 0; /* no auto select */
2791 wrqu->bitrate.value = max_rate * 100000;
2796 static int rtw_wx_set_rts(struct net_device *dev,
2797 struct iw_request_info *info,
2798 union iwreq_data *wrqu, char *extra)
2800 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2804 if (wrqu->rts.disabled)
2805 padapter->registrypriv.rts_thresh = 2347;
2807 if (wrqu->rts.value < 0 ||
2808 wrqu->rts.value > 2347)
2811 padapter->registrypriv.rts_thresh = wrqu->rts.value;
2814 DBG_871X("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
2822 static int rtw_wx_get_rts(struct net_device *dev,
2823 struct iw_request_info *info,
2824 union iwreq_data *wrqu, char *extra)
2826 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2830 DBG_871X("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
2832 wrqu->rts.value = padapter->registrypriv.rts_thresh;
2833 wrqu->rts.fixed = 0; /* no auto select */
2834 //wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
2841 static int rtw_wx_set_frag(struct net_device *dev,
2842 struct iw_request_info *info,
2843 union iwreq_data *wrqu, char *extra)
2845 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2849 if (wrqu->frag.disabled)
2850 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
2852 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
2853 wrqu->frag.value > MAX_FRAG_THRESHOLD)
2856 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
2859 DBG_871X("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
2867 static int rtw_wx_get_frag(struct net_device *dev,
2868 struct iw_request_info *info,
2869 union iwreq_data *wrqu, char *extra)
2871 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2875 DBG_871X("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
2877 wrqu->frag.value = padapter->xmitpriv.frag_len;
2878 wrqu->frag.fixed = 0; /* no auto select */
2879 //wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
2886 static int rtw_wx_get_retry(struct net_device *dev,
2887 struct iw_request_info *info,
2888 union iwreq_data *wrqu, char *extra)
2890 //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2893 wrqu->retry.value = 7;
2894 wrqu->retry.fixed = 0; /* no auto select */
2895 wrqu->retry.disabled = 1;
2902 #define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */
2903 #define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */
2904 #define IW_ENCODE_MODE 0xF000 /* Modes defined below */
2905 #define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */
2906 #define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */
2907 #define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */
2908 #define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */
2909 #define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
2910 #define IW_ENCODE_TEMP 0x0400 /* Temporary key */
2912 iwconfig wlan0 key on -> flags = 0x6001 -> maybe it means auto
2913 iwconfig wlan0 key off -> flags = 0x8800
2914 iwconfig wlan0 key open -> flags = 0x2800
2915 iwconfig wlan0 key open 1234567890 -> flags = 0x2000
2916 iwconfig wlan0 key restricted -> flags = 0x4800
2917 iwconfig wlan0 key open [3] 1234567890 -> flags = 0x2003
2918 iwconfig wlan0 key restricted [2] 1234567890 -> flags = 0x4002
2919 iwconfig wlan0 key open [3] -> flags = 0x2803
2920 iwconfig wlan0 key restricted [2] -> flags = 0x4802
2924 static int rtw_wx_set_enc(struct net_device *dev,
2925 struct iw_request_info *info,
2926 union iwreq_data *wrqu, char *keybuf)
2929 u32 keyindex_provided;
2930 NDIS_802_11_WEP wep;
2931 NDIS_802_11_AUTHENTICATION_MODE authmode;
2933 struct iw_point *erq = &(wrqu->encoding);
2934 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2935 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
2936 DBG_871X("+rtw_wx_set_enc, flags=0x%x\n", erq->flags);
2938 _rtw_memset(&wep, 0, sizeof(NDIS_802_11_WEP));
2940 key = erq->flags & IW_ENCODE_INDEX;
2944 if (erq->flags & IW_ENCODE_DISABLED)
2946 DBG_871X("EncryptionDisabled\n");
2947 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
2948 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
2949 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
2950 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
2951 authmode = Ndis802_11AuthModeOpen;
2952 padapter->securitypriv.ndisauthtype=authmode;
2961 keyindex_provided = 1;
2965 keyindex_provided = 0;
2966 key = padapter->securitypriv.dot11PrivacyKeyIndex;
2967 DBG_871X("rtw_wx_set_enc, key=%d\n", key);
2970 //set authentication mode
2971 if(erq->flags & IW_ENCODE_OPEN)
2973 DBG_871X("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
2974 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;//Ndis802_11EncryptionDisabled;
2976 #ifdef CONFIG_PLATFORM_MT53XX
2977 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
2979 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open;
2982 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
2983 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
2984 authmode = Ndis802_11AuthModeOpen;
2985 padapter->securitypriv.ndisauthtype=authmode;
2987 else if(erq->flags & IW_ENCODE_RESTRICTED)
2989 DBG_871X("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
2990 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2992 #ifdef CONFIG_PLATFORM_MT53XX
2993 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
2995 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Shared;
2998 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
2999 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
3000 authmode = Ndis802_11AuthModeShared;
3001 padapter->securitypriv.ndisauthtype=authmode;
3005 DBG_871X("rtw_wx_set_enc():erq->flags=0x%x\n", erq->flags);
3007 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;//Ndis802_11EncryptionDisabled;
3008 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
3009 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3010 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
3011 authmode = Ndis802_11AuthModeOpen;
3012 padapter->securitypriv.ndisauthtype=authmode;
3016 if (erq->length > 0)
3018 wep.KeyLength = erq->length <= 5 ? 5 : 13;
3020 wep.Length = wep.KeyLength + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
3026 if(keyindex_provided == 1)// set key_id only, no given KeyMaterial(erq->length==0).
3028 padapter->securitypriv.dot11PrivacyKeyIndex = key;
3030 DBG_871X("(keyindex_provided == 1), keyid=%d, key_len=%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
3032 switch(padapter->securitypriv.dot11DefKeylen[key])
3035 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
3038 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
3041 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3051 wep.KeyIndex |= 0x80000000;
3053 _rtw_memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
3055 if (rtw_set_802_11_add_wep(padapter, &wep) == _FALSE) {
3056 if(rf_on == pwrpriv->rf_pwrstate )
3069 static int rtw_wx_get_enc(struct net_device *dev,
3070 struct iw_request_info *info,
3071 union iwreq_data *wrqu, char *keybuf)
3074 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3075 struct iw_point *erq = &(wrqu->encoding);
3076 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3080 if(check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE)
3082 if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE)
3085 erq->flags |= IW_ENCODE_DISABLED;
3091 key = erq->flags & IW_ENCODE_INDEX;
3099 key = padapter->securitypriv.dot11PrivacyKeyIndex;
3102 erq->flags = key + 1;
3104 //if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
3106 // erq->flags |= IW_ENCODE_OPEN;
3109 switch(padapter->securitypriv.ndisencryptstatus)
3111 case Ndis802_11EncryptionNotSupported:
3112 case Ndis802_11EncryptionDisabled:
3115 erq->flags |= IW_ENCODE_DISABLED;
3119 case Ndis802_11Encryption1Enabled:
3121 erq->length = padapter->securitypriv.dot11DefKeylen[key];
3125 _rtw_memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
3127 erq->flags |= IW_ENCODE_ENABLED;
3129 if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
3131 erq->flags |= IW_ENCODE_OPEN;
3133 else if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
3135 erq->flags |= IW_ENCODE_RESTRICTED;
3141 erq->flags |= IW_ENCODE_DISABLED;
3146 case Ndis802_11Encryption2Enabled:
3147 case Ndis802_11Encryption3Enabled:
3150 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
3156 erq->flags |= IW_ENCODE_DISABLED;
3168 static int rtw_wx_get_power(struct net_device *dev,
3169 struct iw_request_info *info,
3170 union iwreq_data *wrqu, char *extra)
3172 //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3174 wrqu->power.value = 0;
3175 wrqu->power.fixed = 0; /* no auto select */
3176 wrqu->power.disabled = 1;
3182 static int rtw_wx_set_gen_ie(struct net_device *dev,
3183 struct iw_request_info *info,
3184 union iwreq_data *wrqu, char *extra)
3187 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3189 ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
3194 static int rtw_wx_set_auth(struct net_device *dev,
3195 struct iw_request_info *info,
3196 union iwreq_data *wrqu, char *extra)
3198 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3199 struct iw_param *param = (struct iw_param*)&(wrqu->param);
3200 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3201 struct security_priv *psecuritypriv = &padapter->securitypriv;
3202 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3203 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3204 u32 value = param->value;
3207 switch (param->flags & IW_AUTH_INDEX) {
3209 case IW_AUTH_WPA_VERSION:
3210 #ifdef CONFIG_WAPI_SUPPORT
3211 #ifndef CONFIG_IOCTL_CFG80211
3212 padapter->wapiInfo.bWapiEnable = false;
3213 if(value == IW_AUTH_WAPI_VERSION_1)
3215 padapter->wapiInfo.bWapiEnable = true;
3216 psecuritypriv->dot11PrivacyAlgrthm = _SMS4_;
3217 psecuritypriv->dot118021XGrpPrivacy = _SMS4_;
3218 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
3219 pmlmeinfo->auth_algo = psecuritypriv->dot11AuthAlgrthm;
3220 padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
3221 padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
3226 case IW_AUTH_CIPHER_PAIRWISE:
3229 case IW_AUTH_CIPHER_GROUP:
3232 case IW_AUTH_KEY_MGMT:
3233 #ifdef CONFIG_WAPI_SUPPORT
3234 #ifndef CONFIG_IOCTL_CFG80211
3235 DBG_871X("rtw_wx_set_auth: IW_AUTH_KEY_MGMT case \n");
3236 if(value == IW_AUTH_KEY_MGMT_WAPI_PSK)
3237 padapter->wapiInfo.bWapiPSK = true;
3239 padapter->wapiInfo.bWapiPSK = false;
3240 DBG_871X("rtw_wx_set_auth: IW_AUTH_KEY_MGMT bwapipsk %d \n",padapter->wapiInfo.bWapiPSK);
3244 * ??? does not use these parameters
3248 case IW_AUTH_TKIP_COUNTERMEASURES:
3251 { // wpa_supplicant is enabling the tkip countermeasure.
3252 padapter->securitypriv.btkip_countermeasure = _TRUE;
3255 { // wpa_supplicant is disabling the tkip countermeasure.
3256 padapter->securitypriv.btkip_countermeasure = _FALSE;
3260 case IW_AUTH_DROP_UNENCRYPTED:
3264 * wpa_supplicant calls set_wpa_enabled when the driver
3265 * is loaded and unloaded, regardless of if WPA is being
3266 * used. No other calls are made which can be used to
3267 * determine if encryption will be used or not prior to
3268 * association being expected. If encryption is not being
3269 * used, drop_unencrypted is set to false, else true -- we
3270 * can use this to determine if the CAP_PRIVACY_ON bit should
3274 if(padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
3276 break;//it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled,
3277 // then it needn't reset it;
3281 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
3282 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3283 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
3284 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
3285 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeOpen;
3291 case IW_AUTH_80211_AUTH_ALG:
3293 #if defined(CONFIG_ANDROID) || 1
3295 * It's the starting point of a link layer connection using wpa_supplicant
3297 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
3298 LeaveAllPowerSaveMode(padapter);
3299 rtw_disassoc_cmd(padapter, 500, _FALSE);
3300 DBG_871X("%s...call rtw_indicate_disconnect\n ",__FUNCTION__);
3301 rtw_indicate_disconnect(padapter);
3302 rtw_free_assoc_resources(padapter, 1);
3307 ret = wpa_set_auth_algs(dev, (u32)param->value);
3311 case IW_AUTH_WPA_ENABLED:
3314 // padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; //802.1x
3316 // padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;//open system
3318 //_disassociate(priv);
3322 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3323 //ieee->ieee802_1x = param->value;
3326 case IW_AUTH_PRIVACY_INVOKED:
3327 //ieee->privacy_invoked = param->value;
3330 #ifdef CONFIG_WAPI_SUPPORT
3331 #ifndef CONFIG_IOCTL_CFG80211
3332 case IW_AUTH_WAPI_ENABLED:
3346 static int rtw_wx_set_enc_ext(struct net_device *dev,
3347 struct iw_request_info *info,
3348 union iwreq_data *wrqu, char *extra)
3352 struct ieee_param *param = NULL;
3353 struct iw_point *pencoding = &wrqu->encoding;
3354 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
3357 param_len = sizeof(struct ieee_param) + pext->key_len;
3358 param = (struct ieee_param *)rtw_malloc(param_len);
3362 _rtw_memset(param, 0, param_len);
3364 param->cmd = IEEE_CMD_SET_ENCRYPTION;
3365 _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
3368 switch (pext->alg) {
3369 case IW_ENCODE_ALG_NONE:
3374 case IW_ENCODE_ALG_WEP:
3377 case IW_ENCODE_ALG_TKIP:
3380 case IW_ENCODE_ALG_CCMP:
3383 #ifdef CONFIG_IEEE80211W
3384 case IW_ENCODE_ALG_AES_CMAC:
3387 #endif //CONFIG_IEEE80211W
3388 #ifdef CONFIG_WAPI_SUPPORT
3389 #ifndef CONFIG_IOCTL_CFG80211
3390 case IW_ENCODE_ALG_SM4:
3392 _rtw_memcpy(param->sta_addr, pext->addr.sa_data, ETH_ALEN);
3393 DBG_871X("rtw_wx_set_enc_ext: SMS4 case \n");
3402 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
3404 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
3406 param->u.crypt.set_tx = 1;
3409 /* cliW: WEP does not have group key
3410 * just not checking GROUP key setting
3412 if ((pext->alg != IW_ENCODE_ALG_WEP) &&
3413 ((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
3414 #ifdef CONFIG_IEEE80211W
3415 || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC)
3416 #endif //CONFIG_IEEE80211W
3419 param->u.crypt.set_tx = 0;
3422 param->u.crypt.idx = (pencoding->flags&0x00FF) -1 ;
3424 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
3426 #ifdef CONFIG_WAPI_SUPPORT
3427 #ifndef CONFIG_IOCTL_CFG80211
3428 if(pext->alg == IW_ENCODE_ALG_SM4)
3429 _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 16);
3431 #endif //CONFIG_IOCTL_CFG80211
3432 #endif //CONFIG_WAPI_SUPPORT
3433 _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 8);
3438 param->u.crypt.key_len = pext->key_len;
3439 //_rtw_memcpy(param + 1, pext + 1, pext->key_len);
3440 _rtw_memcpy(param->u.crypt.key, pext + 1, pext->key_len);
3443 if (pencoding->flags & IW_ENCODE_DISABLED)
3449 ret = wpa_set_encryption(dev, param, param_len);
3454 rtw_mfree((u8*)param, param_len);
3461 static int rtw_wx_get_nick(struct net_device *dev,
3462 struct iw_request_info *info,
3463 union iwreq_data *wrqu, char *extra)
3465 //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3466 //struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3467 //struct security_priv *psecuritypriv = &padapter->securitypriv;
3471 wrqu->data.length = 14;
3472 wrqu->data.flags = 1;
3473 _rtw_memcpy(extra, "<WIFI@REALTEK>", 14);
3476 //rtw_signal_process(pid, SIGUSR1); //for test
3478 //dump debug info here
3480 u32 dot11AuthAlgrthm; // 802.11 auth, could be open, shared, and 8021x
3481 u32 dot11PrivacyAlgrthm; // This specify the privacy for shared auth. algorithm.
3482 u32 dot118021XGrpPrivacy; // This specify the privacy algthm. used for Grp key
3484 u32 ndisencryptstatus;
3487 //DBG_871X("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",
3488 // psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
3489 // psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
3491 //DBG_871X("enc_alg=0x%x\n", psecuritypriv->dot11PrivacyAlgrthm);
3492 //DBG_871X("auth_type=0x%x\n", psecuritypriv->ndisauthtype);
3493 //DBG_871X("enc_type=0x%x\n", psecuritypriv->ndisencryptstatus);
3496 DBG_871X("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
3497 DBG_871X("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
3498 DBG_871X("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
3499 DBG_871X("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
3500 DBG_871X("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
3502 DBG_871X("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
3507 DBG_871X("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
3508 DBG_871X("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
3510 DBG_871X("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
3512 DBG_871X("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
3514 DBG_871X("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
3515 DBG_871X("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
3517 DBG_871X("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
3518 DBG_871X("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
3519 DBG_871X("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
3520 DBG_871X("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
3527 static int rtw_wx_read32(struct net_device *dev,
3528 struct iw_request_info *info,
3529 union iwreq_data *wrqu, char *extra)
3542 padapter = (PADAPTER)rtw_netdev_priv(dev);
3548 ptmp = (u8*)rtw_malloc(len);
3552 if (copy_from_user(ptmp, p->pointer, len)) {
3559 sscanf(ptmp, "%d,%x", &bytes, &addr);
3563 data32 = rtw_read8(padapter, addr);
3564 sprintf(extra, "0x%02X", data32);
3567 data32 = rtw_read16(padapter, addr);
3568 sprintf(extra, "0x%04X", data32);
3571 data32 = rtw_read32(padapter, addr);
3572 sprintf(extra, "0x%08X", data32);
3575 DBG_871X(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__);
3579 DBG_871X(KERN_INFO "%s: addr=0x%08X data=%s\n", __func__, addr, extra);
3582 rtw_mfree(ptmp, len);
3587 static int rtw_wx_write32(struct net_device *dev,
3588 struct iw_request_info *info,
3589 union iwreq_data *wrqu, char *extra)
3591 PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
3601 sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
3605 rtw_write8(padapter, addr, (u8)data32);
3606 DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%02X\n", __func__, addr, (u8)data32);
3609 rtw_write16(padapter, addr, (u16)data32);
3610 DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%04X\n", __func__, addr, (u16)data32);
3613 rtw_write32(padapter, addr, data32);
3614 DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%08X\n", __func__, addr, data32);
3617 DBG_871X(KERN_INFO "%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);
3624 static int rtw_wx_read_rf(struct net_device *dev,
3625 struct iw_request_info *info,
3626 union iwreq_data *wrqu, char *extra)
3628 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3629 u32 path, addr, data32;
3632 path = *(u32*)extra;
3633 addr = *((u32*)extra + 1);
3634 data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);
3635 // DBG_871X("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32);
3638 * Only when wireless private ioctl is at odd order,
3639 * "extra" would be copied to user space.
3641 sprintf(extra, "0x%05x", data32);
3646 static int rtw_wx_write_rf(struct net_device *dev,
3647 struct iw_request_info *info,
3648 union iwreq_data *wrqu, char *extra)
3650 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3651 u32 path, addr, data32;
3654 path = *(u32*)extra;
3655 addr = *((u32*)extra + 1);
3656 data32 = *((u32*)extra + 2);
3657 // DBG_871X("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32);
3658 rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);
3663 static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
3664 union iwreq_data *wrqu, char *b)
3669 static int dummy(struct net_device *dev, struct iw_request_info *a,
3670 union iwreq_data *wrqu, char *b)
3672 //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3673 //struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3675 //DBG_871X("cmd_code=%x, fwstate=0x%x\n", a->cmd, get_fwstate(pmlmepriv));
3681 static int rtw_wx_set_channel_plan(struct net_device *dev,
3682 struct iw_request_info *info,
3683 union iwreq_data *wrqu, char *extra)
3685 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3686 struct registry_priv *pregistrypriv = &padapter->registrypriv;
3687 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3688 extern int rtw_channel_plan;
3689 u8 channel_plan_req = (u8) (*((int *)wrqu));
3692 rtw_channel_plan = (int)wrqu->data.pointer;
3693 pregistrypriv->channel_plan = rtw_channel_plan;
3694 pmlmepriv->ChannelPlan = pregistrypriv->channel_plan;
3697 if (_SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1, 1)) {
3698 DBG_871X("%s set channel_plan = 0x%02X\n", __func__, pmlmepriv->ChannelPlan);
3705 static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
3706 struct iw_request_info *a,
3707 union iwreq_data *wrqu, char *b)
3709 #ifdef CONFIG_PLATFORM_MT53XX
3710 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3711 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3713 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_,
3714 ("WLAN IOCTL: cmd_code=%x, fwstate=0x%x\n",
3715 a->cmd, get_fwstate(pmlmepriv)));
3720 static int rtw_wx_get_sensitivity(struct net_device *dev,
3721 struct iw_request_info *info,
3722 union iwreq_data *wrqu, char *buf)
3724 #ifdef CONFIG_PLATFORM_MT53XX
3725 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3727 // Modified by Albert 20110914
3728 // This is in dbm format for MTK platform.
3729 wrqu->qual.level = padapter->recvpriv.rssi;
3730 DBG_871X(" level = %u\n", wrqu->qual.level );
3735 static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
3736 struct iw_request_info *info,
3737 union iwreq_data *wrqu, char *extra)
3739 #ifdef CONFIG_PLATFORM_MT53XX
3740 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3742 return rtw_set_wpa_ie(padapter, wrqu->data.pointer, wrqu->data.length);
3749 typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
3750 union iwreq_data *wrqu, char *extra);
3753 * For all data larger than 16 octets, we need to use a
3754 * pointer to memory allocated in user space.
3756 static int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info,
3757 union iwreq_data *wrqu, char *extra)
3763 void __user *pointer; /* Pointer to the data (in user space) */
3764 __u16 length; /* number of fields or size in bytes */
3765 __u16 flags; /* Optional params */
3769 #ifdef CONFIG_DRVEXT_MODULE
3771 struct drvext_handler *phandler;
3772 struct drvext_oidparam *poidparam;
3776 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3777 struct iw_point *p = &wrqu->data;
3779 if( (!p->length) || (!p->pointer)){
3781 goto _rtw_drvext_hdl_exit;
3785 bset = (u8)(p->flags&0xFFFF);
3787 pparmbuf = (u8*)rtw_malloc(len);
3788 if (pparmbuf == NULL){
3790 goto _rtw_drvext_hdl_exit;
3795 if (copy_from_user(pparmbuf, p->pointer,len)) {
3796 rtw_mfree(pparmbuf, len);
3798 goto _rtw_drvext_hdl_exit;
3808 poidparam = (struct drvext_oidparam *)pparmbuf;
3810 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("drvext set oid subcode [%d], len[%d], InformationBufferLength[%d]\r\n",
3811 poidparam->subcode, poidparam->len, len));
3815 if ( poidparam->subcode >= MAX_DRVEXT_HANDLERS)
3817 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext handlers\r\n"));
3819 goto _rtw_drvext_hdl_exit;
3823 if ( poidparam->subcode >= MAX_DRVEXT_OID_SUBCODES)
3825 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext subcodes\r\n"));
3827 goto _rtw_drvext_hdl_exit;
3831 phandler = drvextoidhandlers + poidparam->subcode;
3833 if (poidparam->len != phandler->parmsize)
3835 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext param size %d vs %d\r\n",
3836 poidparam->len , phandler->parmsize));
3838 goto _rtw_drvext_hdl_exit;
3842 res = phandler->handler(&padapter->drvextpriv, bset, poidparam->data);
3848 if (bset == 0x00) {//query info
3849 //_rtw_memcpy(p->pointer, pparmbuf, len);
3850 if (copy_to_user(p->pointer, pparmbuf, len))
3858 _rtw_drvext_hdl_exit:
3868 static void rtw_dbg_mode_hdl(_adapter *padapter, u32 id, u8 *pdata, u32 len)
3870 pRW_Reg RegRWStruct;
3871 struct rf_reg_param *prfreg;
3876 DBG_871X("%s\n", __FUNCTION__);
3880 case GEN_MP_IOCTL_SUBCODE(MP_START):
3881 DBG_871X("871x_driver is only for normal mode, can't enter mp mode\n");
3883 case GEN_MP_IOCTL_SUBCODE(READ_REG):
3884 RegRWStruct = (pRW_Reg)pdata;
3885 switch (RegRWStruct->width)
3888 RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
3891 RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
3894 RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
3901 case GEN_MP_IOCTL_SUBCODE(WRITE_REG):
3902 RegRWStruct = (pRW_Reg)pdata;
3903 switch (RegRWStruct->width)
3906 rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value);
3909 rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value);
3912 rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value);
3919 case GEN_MP_IOCTL_SUBCODE(READ_RF_REG):
3921 prfreg = (struct rf_reg_param *)pdata;
3923 path = (u8)prfreg->path;
3924 offset = (u8)prfreg->offset;
3926 value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff);
3928 prfreg->value = value;
3931 case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG):
3933 prfreg = (struct rf_reg_param *)pdata;
3935 path = (u8)prfreg->path;
3936 offset = (u8)prfreg->offset;
3937 value = prfreg->value;
3939 rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value);
3942 case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO):
3943 DBG_871X("==> trigger gpio 0\n");
3944 rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, 0);
3946 #ifdef CONFIG_BT_COEXIST
3947 case GEN_MP_IOCTL_SUBCODE(SET_DM_BT):
3948 DBG_871X("==> set dm_bt_coexist:%x\n",*(u8 *)pdata);
3949 rtw_hal_set_hwreg(padapter, HW_VAR_BT_SET_COEXIST, pdata);
3951 case GEN_MP_IOCTL_SUBCODE(DEL_BA):
3952 DBG_871X("==> delete ba:%x\n",*(u8 *)pdata);
3953 rtw_hal_set_hwreg(padapter, HW_VAR_BT_ISSUE_DELBA, pdata);
3956 #ifdef DBG_CONFIG_ERROR_DETECT
3957 case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS):
3958 *pdata = rtw_hal_sreset_get_wifi_status(padapter);
3968 static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info,
3969 union iwreq_data *wrqu, char *extra)
3972 u32 BytesRead, BytesWritten, BytesNeeded;
3973 struct oid_par_priv oid_par;
3974 struct mp_ioctl_handler *phandler;
3975 struct mp_ioctl_param *poidparam;
3978 u8 *pparmbuf = NULL, bset;
3979 PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
3980 struct iw_point *p = &wrqu->data;
3982 //DBG_871X("+rtw_mp_ioctl_hdl\n");
3984 //mutex_lock(&ioctl_mutex);
3986 if ((!p->length) || (!p->pointer)) {
3988 goto _rtw_mp_ioctl_hdl_exit;
3992 bset = (u8)(p->flags & 0xFFFF);
3994 pparmbuf = (u8*)rtw_malloc(len);
3995 if (pparmbuf == NULL){
3997 goto _rtw_mp_ioctl_hdl_exit;
4000 if (copy_from_user(pparmbuf, p->pointer, len)) {
4002 goto _rtw_mp_ioctl_hdl_exit;
4005 poidparam = (struct mp_ioctl_param *)pparmbuf;
4006 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
4007 ("rtw_mp_ioctl_hdl: subcode [%d], len[%d], buffer_len[%d]\r\n",
4008 poidparam->subcode, poidparam->len, len));
4010 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
4011 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("no matching drvext subcodes\r\n"));
4013 goto _rtw_mp_ioctl_hdl_exit;
4016 //DBG_871X("%s: %d\n", __func__, poidparam->subcode);
4017 #ifdef CONFIG_MP_INCLUDED
4018 if (padapter->registrypriv.mp_mode == 1)
4020 phandler = mp_ioctl_hdl + poidparam->subcode;
4022 if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize))
4024 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
4025 ("no matching drvext param size %d vs %d\r\n",
4026 poidparam->len, phandler->paramsize));
4028 goto _rtw_mp_ioctl_hdl_exit;
4031 if (phandler->handler)
4033 oid_par.adapter_context = padapter;
4034 oid_par.oid = phandler->oid;
4035 oid_par.information_buf = poidparam->data;
4036 oid_par.information_buf_len = poidparam->len;
4043 oid_par.bytes_rw = &BytesRead;
4044 oid_par.bytes_needed = &BytesNeeded;
4045 oid_par.type_of_oid = SET_OID;
4047 oid_par.bytes_rw = &BytesWritten;
4048 oid_par.bytes_needed = &BytesNeeded;
4049 oid_par.type_of_oid = QUERY_OID;
4052 status = phandler->handler(&oid_par);
4054 //todo:check status, BytesNeeded, etc.
4057 DBG_871X("rtw_mp_ioctl_hdl(): err!, subcode=%d, oid=%d, handler=%p\n",
4058 poidparam->subcode, phandler->oid, phandler->handler);
4060 goto _rtw_mp_ioctl_hdl_exit;
4066 rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len);
4069 if (bset == 0x00) {//query info
4070 if (copy_to_user(p->pointer, pparmbuf, len))
4076 goto _rtw_mp_ioctl_hdl_exit;
4079 _rtw_mp_ioctl_hdl_exit:
4082 rtw_mfree(pparmbuf, len);
4084 //mutex_unlock(&ioctl_mutex);
4089 static int rtw_get_ap_info(struct net_device *dev,
4090 struct iw_request_info *info,
4091 union iwreq_data *wrqu, char *extra)
4093 int bssid_match, ret = 0;
4094 u32 cnt=0, wpa_ielen;
4096 _list *plist, *phead;
4097 unsigned char *pbuf;
4100 struct wlan_network *pnetwork = NULL;
4101 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4102 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4103 _queue *queue = &(pmlmepriv->scanned_queue);
4104 struct iw_point *pdata = &wrqu->data;
4106 DBG_871X("+rtw_get_aplist_info\n");
4108 if((padapter->bDriverStopped) || (pdata==NULL))
4114 while((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) == _TRUE)
4123 //pdata->length = 0;//?
4125 if(pdata->length>=32)
4127 if(copy_from_user(data, pdata->pointer, 32))
4139 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4141 phead = get_list_head(queue);
4142 plist = get_next(phead);
4146 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
4150 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4152 //if(hwaddr_aton_i(pdata->pointer, bssid))
4153 if(hwaddr_aton_i(data, bssid))
4155 DBG_871X("Invalid BSSID '%s'.\n", (u8*)data);
4156 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4161 if(_rtw_memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE)//BSSID match, then check if supporting wpa/wpa2
4163 DBG_871X("BSSID:" MAC_FMT "\n", MAC_ARG(bssid));
4165 pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
4166 if(pbuf && (wpa_ielen>0))
4172 pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
4173 if(pbuf && (wpa_ielen>0))
4181 plist = get_next(plist);
4185 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4187 if(pdata->length>=34)
4189 if(copy_to_user((u8*)pdata->pointer+32, (u8*)&pdata->flags, 1))
4202 static int rtw_set_pid(struct net_device *dev,
4203 struct iw_request_info *info,
4204 union iwreq_data *wrqu, char *extra)
4208 _adapter *padapter = rtw_netdev_priv(dev);
4209 int *pdata = (int *)wrqu;
4212 if((padapter->bDriverStopped) || (pdata==NULL))
4219 if(selector < 3 && selector >=0) {
4220 padapter->pid[selector] = *(pdata+1);
4221 #ifdef CONFIG_GLOBAL_UI_PID
4222 ui_pid[selector] = *(pdata+1);
4224 DBG_871X("%s set pid[%d]=%d\n", __FUNCTION__, selector ,padapter->pid[selector]);
4227 DBG_871X("%s selector %d error\n", __FUNCTION__, selector);
4235 static int rtw_wps_start(struct net_device *dev,
4236 struct iw_request_info *info,
4237 union iwreq_data *wrqu, char *extra)
4241 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4242 struct iw_point *pdata = &wrqu->data;
4243 u32 u32wps_start = 0;
4244 unsigned int uintRet = 0;
4246 if((_TRUE == padapter->bDriverStopped) ||(_TRUE==padapter->bSurpriseRemoved) || (NULL== pdata))
4252 uintRet = copy_from_user( ( void* ) &u32wps_start, pdata->pointer, 4 );
4253 if ( u32wps_start == 0 )
4255 u32wps_start = *extra;
4258 DBG_871X( "[%s] wps_start = %d\n", __FUNCTION__, u32wps_start );
4260 if ( u32wps_start == 1 ) // WPS Start
4262 rtw_led_control(padapter, LED_CTL_START_WPS);
4264 else if ( u32wps_start == 2 ) // WPS Stop because of wps success
4266 rtw_led_control(padapter, LED_CTL_STOP_WPS);
4268 else if ( u32wps_start == 3 ) // WPS Stop because of wps fail
4270 rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);
4273 #ifdef CONFIG_INTEL_WIDI
4274 process_intel_widi_wps_status(padapter, u32wps_start);
4275 #endif //CONFIG_INTEL_WIDI
4284 static int rtw_wext_p2p_enable(struct net_device *dev,
4285 struct iw_request_info *info,
4286 union iwreq_data *wrqu, char *extra)
4290 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4291 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4292 struct iw_point *pdata = &wrqu->data;
4293 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4294 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4295 enum P2P_ROLE init_role = P2P_ROLE_DISABLE;
4298 init_role = P2P_ROLE_DISABLE;
4299 else if(*extra == '1')
4300 init_role = P2P_ROLE_DEVICE;
4301 else if(*extra == '2')
4302 init_role = P2P_ROLE_CLIENT;
4303 else if(*extra == '3')
4304 init_role = P2P_ROLE_GO;
4306 if(_FAIL == rtw_p2p_enable(padapter, init_role))
4312 //set channel/bandwidth
4313 if(init_role != P2P_ROLE_DISABLE)
4315 u8 channel, ch_offset;
4318 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN))
4320 // Stay at the listen state and wait for discovery.
4321 channel = pwdinfo->listen_channel;
4322 pwdinfo->operating_channel = pwdinfo->listen_channel;
4323 ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4324 bwmode = CHANNEL_WIDTH_20;
4326 #ifdef CONFIG_CONCURRENT_MODE
4327 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
4329 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4330 //struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4331 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4332 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4334 _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval );
4335 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
4337 pwdinfo->operating_channel = pbuddy_mlmeext->cur_channel;
4338 // How about the ch_offset and bwmode ??
4342 pwdinfo->operating_channel = pwdinfo->listen_channel;
4345 channel = pbuddy_mlmeext->cur_channel;
4346 ch_offset = pbuddy_mlmeext->cur_ch_offset;
4347 bwmode = pbuddy_mlmeext->cur_bwmode;
4352 pwdinfo->operating_channel = pmlmeext->cur_channel;
4354 channel = pwdinfo->operating_channel;
4355 ch_offset = pmlmeext->cur_ch_offset;
4356 bwmode = pmlmeext->cur_bwmode;
4359 set_channel_bwmode(padapter, channel, ch_offset, bwmode);
4367 static int rtw_p2p_set_go_nego_ssid(struct net_device *dev,
4368 struct iw_request_info *info,
4369 union iwreq_data *wrqu, char *extra)
4373 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4374 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4375 struct iw_point *pdata = &wrqu->data;
4376 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4378 DBG_871X( "[%s] ssid = %s, len = %zu\n", __FUNCTION__, extra, strlen( extra ) );
4379 _rtw_memcpy( pwdinfo->nego_ssid, extra, strlen( extra ) );
4380 pwdinfo->nego_ssidlen = strlen( extra );
4387 static int rtw_p2p_set_intent(struct net_device *dev,
4388 struct iw_request_info *info,
4389 union iwreq_data *wrqu, char *extra)
4392 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4393 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4394 u8 intent = pwdinfo->intent;
4396 extra[ wrqu->data.length ] = 0x00;
4398 intent = rtw_atoi( extra );
4402 pwdinfo->intent= intent;
4409 DBG_871X( "[%s] intent = %d\n", __FUNCTION__, intent);
4415 static int rtw_p2p_set_listen_ch(struct net_device *dev,
4416 struct iw_request_info *info,
4417 union iwreq_data *wrqu, char *extra)
4421 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4422 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4423 u8 listen_ch = pwdinfo->listen_channel; // Listen channel number
4425 extra[ wrqu->data.length ] = 0x00;
4426 listen_ch = rtw_atoi( extra );
4428 if ( ( listen_ch == 1 ) || ( listen_ch == 6 ) || ( listen_ch == 11 ) )
4430 pwdinfo->listen_channel = listen_ch;
4431 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
4438 DBG_871X( "[%s] listen_ch = %d\n", __FUNCTION__, pwdinfo->listen_channel );
4444 static int rtw_p2p_set_op_ch(struct net_device *dev,
4445 struct iw_request_info *info,
4446 union iwreq_data *wrqu, char *extra)
4448 // Commented by Albert 20110524
4449 // This function is used to set the operating channel if the driver will become the group owner
4452 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4453 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4454 u8 op_ch = pwdinfo->operating_channel; // Operating channel number
4456 extra[ wrqu->data.length ] = 0x00;
4458 op_ch = ( u8 ) rtw_atoi( extra );
4461 pwdinfo->operating_channel = op_ch;
4468 DBG_871X( "[%s] op_ch = %d\n", __FUNCTION__, pwdinfo->operating_channel );
4475 static int rtw_p2p_profilefound(struct net_device *dev,
4476 struct iw_request_info *info,
4477 union iwreq_data *wrqu, char *extra)
4481 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4482 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4484 // Comment by Albert 2010/10/13
4485 // Input data format:
4487 // Ex: 1XX:XX:XX:XX:XX:XXYYSSID
4488 // 0 => Reflush the profile record list.
4489 // 1 => Add the profile list
4490 // XX:XX:XX:XX:XX:XX => peer's MAC Address ( ex: 00:E0:4C:00:00:01 )
4491 // YY => SSID Length
4492 // SSID => SSID for persistence group
4494 DBG_871X( "[%s] In value = %s, len = %d \n", __FUNCTION__, extra, wrqu->data.length -1);
4497 // The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function.
4498 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4500 if ( extra[ 0 ] == '0' )
4502 // Remove all the profile information of wifidirect_info structure.
4503 _rtw_memset( &pwdinfo->profileinfo[ 0 ], 0x00, sizeof( struct profile_info ) * P2P_MAX_PERSISTENT_GROUP_NUM );
4504 pwdinfo->profileindex = 0;
4508 if ( pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM )
4516 // Add this profile information into pwdinfo->profileinfo
4517 // Ex: 1XX:XX:XX:XX:XX:XXYYSSID
4518 for( jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3 )
4520 pwdinfo->profileinfo[ pwdinfo->profileindex ].peermac[ jj ] = key_2char2num(extra[ kk ], extra[ kk+ 1 ]);
4523 //pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen = ( extra[18] - '0' ) * 10 + ( extra[ 19 ] - '0' );
4524 //_rtw_memcpy( pwdinfo->profileinfo[ pwdinfo->profileindex ].ssid, &extra[ 20 ], pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen );
4525 pwdinfo->profileindex++;
4534 static int rtw_p2p_setDN(struct net_device *dev,
4535 struct iw_request_info *info,
4536 union iwreq_data *wrqu, char *extra)
4540 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4541 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4544 DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
4545 _rtw_memset( pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN );
4546 _rtw_memcpy( pwdinfo->device_name, extra, wrqu->data.length - 1 );
4547 pwdinfo->device_name_len = wrqu->data.length - 1;
4554 static int rtw_p2p_get_status(struct net_device *dev,
4555 struct iw_request_info *info,
4556 union iwreq_data *wrqu, char *extra)
4560 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4561 struct iw_point *pdata = &wrqu->data;
4562 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4563 #ifdef CONFIG_CONCURRENT_MODE
4564 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4565 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4566 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4567 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4570 if ( padapter->bShowGetP2PState )
4572 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),
4573 pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
4574 pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
4577 // Commented by Albert 2010/10/12
4578 // Because of the output size limitation, I had removed the "Role" information.
4579 // About the "Role" information, we will use the new private IOCTL to get the "Role" information.
4580 sprintf( extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo) );
4581 wrqu->data.length = strlen( extra );
4587 // Commented by Albert 20110520
4588 // This function will return the config method description
4589 // This config method description will show us which config method the remote P2P device is intented to use
4590 // by sending the provisioning discovery request frame.
4592 static int rtw_p2p_get_req_cm(struct net_device *dev,
4593 struct iw_request_info *info,
4594 union iwreq_data *wrqu, char *extra)
4598 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4599 struct iw_point *pdata = &wrqu->data;
4600 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4602 sprintf( extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req );
4603 wrqu->data.length = strlen( extra );
4609 static int rtw_p2p_get_role(struct net_device *dev,
4610 struct iw_request_info *info,
4611 union iwreq_data *wrqu, char *extra)
4615 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4616 struct iw_point *pdata = &wrqu->data;
4617 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4620 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),
4621 pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
4622 pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
4624 sprintf( extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo) );
4625 wrqu->data.length = strlen( extra );
4631 static int rtw_p2p_get_peer_ifaddr(struct net_device *dev,
4632 struct iw_request_info *info,
4633 union iwreq_data *wrqu, char *extra)
4637 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4638 struct iw_point *pdata = &wrqu->data;
4639 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4642 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),
4643 pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
4644 pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
4646 sprintf( extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4647 pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
4648 pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
4649 wrqu->data.length = strlen( extra );
4654 static int rtw_p2p_get_peer_devaddr(struct net_device *dev,
4655 struct iw_request_info *info,
4656 union iwreq_data *wrqu, char *extra)
4661 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4662 struct iw_point *pdata = &wrqu->data;
4663 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4665 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),
4666 pwdinfo->rx_prov_disc_info.peerDevAddr[ 0 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 1 ],
4667 pwdinfo->rx_prov_disc_info.peerDevAddr[ 2 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 3 ],
4668 pwdinfo->rx_prov_disc_info.peerDevAddr[ 4 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 5 ]);
4669 sprintf( extra, "\n%.2X%.2X%.2X%.2X%.2X%.2X",
4670 pwdinfo->rx_prov_disc_info.peerDevAddr[ 0 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 1 ],
4671 pwdinfo->rx_prov_disc_info.peerDevAddr[ 2 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 3 ],
4672 pwdinfo->rx_prov_disc_info.peerDevAddr[ 4 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 5 ]);
4673 wrqu->data.length = strlen( extra );
4678 static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev,
4679 struct iw_request_info *info,
4680 union iwreq_data *wrqu, char *extra)
4685 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4686 struct iw_point *pdata = &wrqu->data;
4687 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4689 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),
4690 pwdinfo->p2p_peer_device_addr[ 0 ], pwdinfo->p2p_peer_device_addr[ 1 ],
4691 pwdinfo->p2p_peer_device_addr[ 2 ], pwdinfo->p2p_peer_device_addr[ 3 ],
4692 pwdinfo->p2p_peer_device_addr[ 4 ], pwdinfo->p2p_peer_device_addr[ 5 ]);
4693 sprintf( extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4694 pwdinfo->p2p_peer_device_addr[ 0 ], pwdinfo->p2p_peer_device_addr[ 1 ],
4695 pwdinfo->p2p_peer_device_addr[ 2 ], pwdinfo->p2p_peer_device_addr[ 3 ],
4696 pwdinfo->p2p_peer_device_addr[ 4 ], pwdinfo->p2p_peer_device_addr[ 5 ]);
4697 wrqu->data.length = strlen( extra );
4702 static int rtw_p2p_get_groupid(struct net_device *dev,
4703 struct iw_request_info *info,
4704 union iwreq_data *wrqu, char *extra)
4709 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4710 struct iw_point *pdata = &wrqu->data;
4711 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4713 sprintf( extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s",
4714 pwdinfo->groupid_info.go_device_addr[ 0 ], pwdinfo->groupid_info.go_device_addr[ 1 ],
4715 pwdinfo->groupid_info.go_device_addr[ 2 ], pwdinfo->groupid_info.go_device_addr[ 3 ],
4716 pwdinfo->groupid_info.go_device_addr[ 4 ], pwdinfo->groupid_info.go_device_addr[ 5 ],
4717 pwdinfo->groupid_info.ssid);
4718 wrqu->data.length = strlen( extra );
4723 static int rtw_p2p_get_op_ch(struct net_device *dev,
4724 struct iw_request_info *info,
4725 union iwreq_data *wrqu, char *extra)
4730 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4731 struct iw_point *pdata = &wrqu->data;
4732 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4735 DBG_871X( "[%s] Op_ch = %02x\n", __FUNCTION__, pwdinfo->operating_channel);
4737 sprintf( extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel );
4738 wrqu->data.length = strlen( extra );
4743 static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
4744 struct iw_request_info *info,
4745 union iwreq_data *wrqu, char *extra, char *subcmd)
4749 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4750 u8 peerMAC[ETH_ALEN] = { 0x00 };
4751 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4753 _list * plist,*phead;
4754 _queue *queue = &(pmlmepriv->scanned_queue);
4755 struct wlan_network *pnetwork = NULL;
4757 u16 attr_content = 0;
4758 uint attr_contentlen = 0;
4759 u8 attr_content_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4761 // Commented by Albert 20110727
4762 // The input data is the MAC address which the application wants to know its WPS config method.
4763 // After knowing its WPS config method, the application can decide the config method for provisioning discovery.
4764 // Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05
4766 DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
4768 macstr2num(peerMAC, subcmd);
4770 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4772 phead = get_list_head(queue);
4773 plist = get_next(phead);
4777 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
4779 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4780 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
4785 // The mac address is matched.
4787 if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) )
4789 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&attr_content, &attr_contentlen);
4790 if (attr_contentlen)
4792 attr_content = be16_to_cpu(attr_content);
4793 sprintf(attr_content_str, "\n\nM=%.4d", attr_content);
4801 plist = get_next(plist);
4805 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4809 sprintf(attr_content_str, "\n\nM=0000");
4812 wrqu->data.length = strlen(attr_content_str);
4813 _rtw_memcpy(extra, attr_content_str, wrqu->data.length);
4820 static int rtw_p2p_get_peer_wfd_port(struct net_device *dev,
4821 struct iw_request_info *info,
4822 union iwreq_data *wrqu, char *extra)
4826 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4827 struct iw_point *pdata = &wrqu->data;
4828 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4830 DBG_871X( "[%s] p2p_state = %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
4832 sprintf( extra, "\n\nPort=%d\n", pwdinfo->wfd_info->peer_rtsp_ctrlport );
4833 DBG_871X( "[%s] remote port = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
4835 wrqu->data.length = strlen( extra );
4840 static int rtw_p2p_get_peer_wfd_preferred_connection(struct net_device *dev,
4841 struct iw_request_info *info,
4842 union iwreq_data *wrqu, char *extra)
4846 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4847 struct iw_point *pdata = &wrqu->data;
4848 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4850 sprintf( extra, "\n\nwfd_pc=%d\n", pwdinfo->wfd_info->wfd_pc );
4851 DBG_871X( "[%s] wfd_pc = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_pc );
4853 wrqu->data.length = strlen( extra );
4854 pwdinfo->wfd_info->wfd_pc = _FALSE; // Reset the WFD preferred connection to P2P
4859 static int rtw_p2p_get_peer_wfd_session_available(struct net_device *dev,
4860 struct iw_request_info *info,
4861 union iwreq_data *wrqu, char *extra)
4865 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4866 struct iw_point *pdata = &wrqu->data;
4867 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4869 sprintf( extra, "\n\nwfd_sa=%d\n", pwdinfo->wfd_info->peer_session_avail );
4870 DBG_871X( "[%s] wfd_sa = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_session_avail );
4872 wrqu->data.length = strlen( extra );
4873 pwdinfo->wfd_info->peer_session_avail = _TRUE; // Reset the WFD session available
4878 #endif // CONFIG_WFD
4880 static int rtw_p2p_get_go_device_address(struct net_device *dev,
4881 struct iw_request_info *info,
4882 union iwreq_data *wrqu, char *extra, char *subcmd)
4886 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4887 u8 peerMAC[ETH_ALEN] = { 0x00 };
4888 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4890 _list *plist, *phead;
4891 _queue *queue = &(pmlmepriv->scanned_queue);
4892 struct wlan_network *pnetwork = NULL;
4895 uint p2pielen = 0, attr_contentlen = 0;
4896 u8 attr_content[100] = { 0x00 };
4897 u8 go_devadd_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4899 // Commented by Albert 20121209
4900 // The input data is the GO's interface address which the application wants to know its device address.
4901 // Format: iwpriv wlanx p2p_get2 go_devadd=00:E0:4C:00:00:05
4903 DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
4905 macstr2num(peerMAC, subcmd);
4907 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4909 phead = get_list_head(queue);
4910 plist = get_next(phead);
4914 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
4916 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4917 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
4919 // Commented by Albert 2011/05/18
4920 // Match the device address located in the P2P IE
4921 // This is for the case that the P2P device address is not the same as the P2P interface address.
4923 if ((p2pie = rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
4927 // The P2P Device ID attribute is included in the Beacon frame.
4928 // The P2P Device Info attribute is included in the probe response frame.
4930 _rtw_memset(attr_content, 0x00, 100);
4931 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen))
4933 // Handle the P2P Device ID attribute of Beacon first
4937 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen))
4939 // Handle the P2P Device Info attribute of probe response
4944 //Get the next P2P IE
4945 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
4950 plist = get_next(plist);
4954 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4958 sprintf(go_devadd_str, "\n\ndev_add=NULL");
4961 sprintf(go_devadd_str, "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4962 attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
4965 wrqu->data.length = strlen(go_devadd_str);
4966 _rtw_memcpy(extra, go_devadd_str, wrqu->data.length);
4972 static int rtw_p2p_get_device_type(struct net_device *dev,
4973 struct iw_request_info *info,
4974 union iwreq_data *wrqu, char *extra, char *subcmd)
4978 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4979 u8 peerMAC[ETH_ALEN] = { 0x00 };
4980 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4982 _list *plist, *phead;
4983 _queue *queue = &(pmlmepriv->scanned_queue);
4984 struct wlan_network *pnetwork = NULL;
4986 u8 dev_type[8] = { 0x00 };
4987 uint dev_type_len = 0;
4988 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
4990 // Commented by Albert 20121209
4991 // The input data is the MAC address which the application wants to know its device type.
4992 // Such user interface could know the device type.
4993 // Format: iwpriv wlanx p2p_get2 dev_type=00:E0:4C:00:00:05
4995 DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
4997 macstr2num(peerMAC, subcmd);
4999 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5001 phead = get_list_head(queue);
5002 plist = get_next(phead);
5006 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5008 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5009 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5014 // The mac address is matched.
5016 if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) )
5018 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len);
5023 _rtw_memcpy(&type, dev_type, 2);
5024 type = be16_to_cpu(type);
5025 sprintf(dev_type_str, "\n\nN=%.2d", type);
5032 plist = get_next(plist);
5036 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5040 sprintf(dev_type_str, "\n\nN=00");
5043 wrqu->data.length = strlen(dev_type_str);
5044 _rtw_memcpy(extra, dev_type_str, wrqu->data.length);
5050 static int rtw_p2p_get_device_name(struct net_device *dev,
5051 struct iw_request_info *info,
5052 union iwreq_data *wrqu, char *extra, char *subcmd)
5056 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5057 u8 peerMAC[ETH_ALEN] = { 0x00 };
5058 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5060 _list *plist, *phead;
5061 _queue *queue = &(pmlmepriv->scanned_queue);
5062 struct wlan_network *pnetwork = NULL;
5064 u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = { 0x00 };
5066 u8 dev_name_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
5068 // Commented by Albert 20121225
5069 // The input data is the MAC address which the application wants to know its device name.
5070 // Such user interface could show peer device's device name instead of ssid.
5071 // Format: iwpriv wlanx p2p_get2 devN=00:E0:4C:00:00:05
5073 DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5075 macstr2num(peerMAC, subcmd);
5077 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5079 phead = get_list_head(queue);
5080 plist = get_next(phead);
5084 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5086 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5087 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5092 // The mac address is matched.
5094 if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) )
5096 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
5099 sprintf(dev_name_str, "\n\nN=%s", dev_name);
5106 plist = get_next(plist);
5110 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5114 sprintf(dev_name_str, "\n\nN=0000");
5117 wrqu->data.length = strlen(dev_name_str);
5118 _rtw_memcpy(extra, dev_name_str, wrqu->data.length);
5124 static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
5125 struct iw_request_info *info,
5126 union iwreq_data *wrqu, char *extra, char *subcmd)
5130 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5131 u8 peerMAC[ETH_ALEN] = { 0x00 };
5132 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5134 _list *plist, *phead;
5135 _queue *queue = &(pmlmepriv->scanned_queue);
5136 struct wlan_network *pnetwork = NULL;
5139 uint p2pielen = 0, attr_contentlen = 0;
5140 u8 attr_content[2] = { 0x00 };
5141 u8 inv_proc_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
5143 // Commented by Ouden 20121226
5144 // The application wants to know P2P initation procedure is support or not.
5145 // Format: iwpriv wlanx p2p_get2 InvProc=00:E0:4C:00:00:05
5147 DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5149 macstr2num(peerMAC, subcmd);
5151 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5153 phead = get_list_head(queue);
5154 plist = get_next(phead);
5158 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5160 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5161 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5163 // Commented by Albert 20121226
5164 // Match the device address located in the P2P IE
5165 // This is for the case that the P2P device address is not the same as the P2P interface address.
5167 if ((p2pie = rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
5171 //_rtw_memset( attr_content, 0x00, 2);
5172 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen))
5174 // Handle the P2P capability attribute
5180 //Get the next P2P IE
5181 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
5186 plist = get_next(plist);
5190 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5194 sprintf(inv_proc_str, "\nIP=-1");
5197 if (attr_content[0] && 0x20)
5199 sprintf(inv_proc_str, "\nIP=1");
5202 sprintf(inv_proc_str, "\nIP=0");
5206 wrqu->data.length = strlen(inv_proc_str);
5207 _rtw_memcpy(extra, inv_proc_str, wrqu->data.length);
5213 static int rtw_p2p_connect(struct net_device *dev,
5214 struct iw_request_info *info,
5215 union iwreq_data *wrqu, char *extra)
5219 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5220 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5221 u8 peerMAC[ ETH_ALEN ] = { 0x00 };
5223 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5224 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5226 _list *plist, *phead;
5227 _queue *queue = &(pmlmepriv->scanned_queue);
5228 struct wlan_network *pnetwork = NULL;
5229 uint uintPeerChannel = 0;
5230 #ifdef CONFIG_CONCURRENT_MODE
5231 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5232 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5233 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5234 #endif // CONFIG_CONCURRENT_MODE
5236 // Commented by Albert 20110304
5237 // The input data contains two informations.
5238 // 1. First information is the MAC address which wants to formate with
5239 // 2. Second information is the WPS PINCode or "pbc" string for push button method
5240 // Format: 00:E0:4C:00:00:05
5241 // Format: 00:E0:4C:00:00:05
5243 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5245 if ( pwdinfo->p2p_state == P2P_STATE_NONE )
5247 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5251 #ifdef CONFIG_INTEL_WIDI
5252 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
5253 DBG_871X( "[%s] WiFi is under survey!\n", __FUNCTION__ );
5256 #endif //CONFIG_INTEL_WIDI
5258 if ( pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO )
5263 for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
5265 peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
5268 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5270 phead = get_list_head(queue);
5271 plist = get_next(phead);
5275 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
5278 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5279 if ( _rtw_memcmp( pnetwork->network.MacAddress, peerMAC, ETH_ALEN ) )
5281 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5285 plist = get_next(plist);
5289 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5291 if ( uintPeerChannel )
5293 #ifdef CONFIG_CONCURRENT_MODE
5294 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5296 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
5298 #endif // CONFIG_CONCURRENT_MODE
5300 _rtw_memset( &pwdinfo->nego_req_info, 0x00, sizeof( struct tx_nego_req_info ) );
5301 _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
5303 pwdinfo->nego_req_info.peer_channel_num[ 0 ] = uintPeerChannel;
5304 _rtw_memcpy( pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN );
5305 pwdinfo->nego_req_info.benable = _TRUE;
5307 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5308 if ( rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK )
5310 // Restore to the listen state if the current p2p state is not nego OK
5311 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN );
5314 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5315 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
5317 #ifdef CONFIG_CONCURRENT_MODE
5318 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5320 // Have to enter the power saving with the AP
5321 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
5323 issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
5325 #endif // CONFIG_CONCURRENT_MODE
5327 DBG_871X( "[%s] Start PreTx Procedure!\n", __FUNCTION__ );
5328 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
5329 #ifdef CONFIG_CONCURRENT_MODE
5330 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5332 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_GO_NEGO_TIMEOUT );
5336 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT );
5339 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT );
5340 #endif // CONFIG_CONCURRENT_MODE
5345 DBG_871X( "[%s] Not Found in Scanning Queue~\n", __FUNCTION__ );
5346 #ifdef CONFIG_INTEL_WIDI
5347 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5348 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
5349 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
5350 rtw_free_network_queue(padapter, _TRUE);
5352 * For WiDi, if we can't find candidate device in scanning queue,
5353 * driver will do scanning itself
5355 _enter_critical_bh(&pmlmepriv->lock, &irqL);
5356 rtw_sitesurvey_cmd(padapter, NULL, 0, NULL, 0);
5357 _exit_critical_bh(&pmlmepriv->lock, &irqL);
5358 #endif //CONFIG_INTEL_WIDI
5365 static int rtw_p2p_invite_req(struct net_device *dev,
5366 struct iw_request_info *info,
5367 union iwreq_data *wrqu, char *extra)
5371 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5372 struct iw_point *pdata = &wrqu->data;
5373 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5375 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5376 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5377 _list *plist, *phead;
5378 _queue *queue = &(pmlmepriv->scanned_queue);
5379 struct wlan_network *pnetwork = NULL;
5380 uint uintPeerChannel = 0;
5381 u8 attr_content[50] = { 0x00 }, _status = 0;
5383 uint p2pielen = 0, attr_contentlen = 0;
5385 struct tx_invite_req_info* pinvite_req_info = &pwdinfo->invitereq_info;
5387 #ifdef CONFIG_CONCURRENT_MODE
5388 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5389 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5390 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5391 #endif // CONFIG_CONCURRENT_MODE
5394 struct wifi_display_info* pwfd_info = pwdinfo->wfd_info;
5395 #endif // CONFIG_WFD
5397 // Commented by Albert 20120321
5398 // The input data contains two informations.
5399 // 1. First information is the P2P device address which you want to send to.
5400 // 2. Second information is the group id which combines with GO's mac address, space and GO's ssid.
5401 // Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy"
5402 // Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy
5404 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5406 if ( wrqu->data.length <= 37 )
5408 DBG_871X( "[%s] Wrong format!\n", __FUNCTION__ );
5412 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
5414 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5419 // Reset the content of struct tx_invite_req_info
5420 pinvite_req_info->benable = _FALSE;
5421 _rtw_memset( pinvite_req_info->go_bssid, 0x00, ETH_ALEN );
5422 _rtw_memset( pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN );
5423 pinvite_req_info->ssidlen = 0x00;
5424 pinvite_req_info->operating_ch = pwdinfo->operating_channel;
5425 _rtw_memset( pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN );
5426 pinvite_req_info->token = 3;
5429 for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
5431 pinvite_req_info->peer_macaddr[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
5434 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5436 phead = get_list_head(queue);
5437 plist = get_next(phead);
5441 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
5444 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5446 // Commented by Albert 2011/05/18
5447 // Match the device address located in the P2P IE
5448 // This is for the case that the P2P device address is not the same as the P2P interface address.
5450 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);
5451 if ( (p2pie=rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
5453 // The P2P Device ID attribute is included in the Beacon frame.
5454 // The P2P Device Info attribute is included in the probe response frame.
5456 if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
5458 // Handle the P2P Device ID attribute of Beacon first
5459 if ( _rtw_memcmp( attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN ) )
5461 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5465 else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
5467 // Handle the P2P Device Info attribute of probe response
5468 if ( _rtw_memcmp( attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN ) )
5470 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5477 plist = get_next(plist);
5481 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5484 if ( uintPeerChannel )
5486 u8 wfd_ie[ 128 ] = { 0x00 };
5489 if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) )
5491 u8 wfd_devinfo[ 6 ] = { 0x00 };
5492 uint wfd_devlen = 6;
5494 DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ );
5495 if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) )
5497 u16 wfd_devinfo_field = 0;
5499 // Commented by Albert 20120319
5500 // The first two bytes are the WFD device information field of WFD device information subelement.
5501 // In big endian format.
5502 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5503 if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL )
5505 pwfd_info->peer_session_avail = _TRUE;
5509 pwfd_info->peer_session_avail = _FALSE;
5514 if ( _FALSE == pwfd_info->peer_session_avail )
5516 DBG_871X( "[%s] WFD Session not avaiable!\n", __FUNCTION__ );
5520 #endif // CONFIG_WFD
5522 if ( uintPeerChannel )
5524 #ifdef CONFIG_CONCURRENT_MODE
5525 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5527 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
5529 #endif // CONFIG_CONCURRENT_MODE
5531 // Store the GO's bssid
5532 for( jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3 )
5534 pinvite_req_info->go_bssid[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
5537 // Store the GO's ssid
5538 pinvite_req_info->ssidlen = wrqu->data.length - 36;
5539 _rtw_memcpy( pinvite_req_info->go_ssid, &extra[ 36 ], (u32) pinvite_req_info->ssidlen );
5540 pinvite_req_info->benable = _TRUE;
5541 pinvite_req_info->peer_ch = uintPeerChannel;
5543 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5544 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ);
5546 #ifdef CONFIG_CONCURRENT_MODE
5547 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5549 // Have to enter the power saving with the AP
5550 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
5552 issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
5556 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5559 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5562 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
5564 #ifdef CONFIG_CONCURRENT_MODE
5565 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5567 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_INVITE_TIMEOUT );
5571 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT );
5574 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT );
5575 #endif // CONFIG_CONCURRENT_MODE
5581 DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ );
5589 static int rtw_p2p_set_persistent(struct net_device *dev,
5590 struct iw_request_info *info,
5591 union iwreq_data *wrqu, char *extra)
5595 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5596 struct iw_point *pdata = &wrqu->data;
5597 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5599 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5600 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5601 _list *plist, *phead;
5602 _queue *queue = &(pmlmepriv->scanned_queue);
5603 struct wlan_network *pnetwork = NULL;
5604 uint uintPeerChannel = 0;
5605 u8 attr_content[50] = { 0x00 }, _status = 0;
5607 uint p2pielen = 0, attr_contentlen = 0;
5609 struct tx_invite_req_info* pinvite_req_info = &pwdinfo->invitereq_info;
5610 #ifdef CONFIG_CONCURRENT_MODE
5611 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5612 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5613 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5614 #endif // CONFIG_CONCURRENT_MODE
5617 struct wifi_display_info* pwfd_info = pwdinfo->wfd_info;
5618 #endif // CONFIG_WFD
5620 // Commented by Albert 20120328
5621 // The input data is 0 or 1
5622 // 0: disable persistent group functionality
5623 // 1: enable persistent group founctionality
5625 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5627 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
5629 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5634 if ( extra[ 0 ] == '0' ) // Disable the persistent group function.
5636 pwdinfo->persistent_supported = _FALSE;
5638 else if ( extra[ 0 ] == '1' ) // Enable the persistent group function.
5640 pwdinfo->persistent_supported = _TRUE;
5644 pwdinfo->persistent_supported = _FALSE;
5647 printk( "[%s] persistent_supported = %d\n", __FUNCTION__, pwdinfo->persistent_supported );
5655 static int hexstr2bin(const char *hex, u8 *buf, size_t len)
5659 const char *ipos = hex;
5662 for (i = 0; i < len; i++) {
5663 a = hex2byte_i(ipos);
5672 static int uuid_str2bin(const char *str, u8 *bin)
5680 if (hexstr2bin(pos, opos, 4))
5685 if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5690 if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5695 if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5700 if (*pos++ != '-' || hexstr2bin(pos, opos, 6))
5706 static int rtw_p2p_set_wps_uuid(struct net_device *dev,
5707 struct iw_request_info *info,
5708 union iwreq_data *wrqu, char *extra)
5712 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5713 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5715 DBG_871X("[%s] data = %s\n", __FUNCTION__, extra);
5717 if ((36 == strlen(extra)) && (uuid_str2bin(extra, pwdinfo->uuid) == 0))
5719 pwdinfo->external_uuid = 1;
5721 pwdinfo->external_uuid = 0;
5729 static int rtw_p2p_set_pc(struct net_device *dev,
5730 struct iw_request_info *info,
5731 union iwreq_data *wrqu, char *extra)
5735 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5736 struct iw_point *pdata = &wrqu->data;
5737 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5738 u8 peerMAC[ ETH_ALEN ] = { 0x00 };
5740 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5741 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5742 _list *plist, *phead;
5743 _queue *queue = &(pmlmepriv->scanned_queue);
5744 struct wlan_network *pnetwork = NULL;
5745 u8 attr_content[50] = { 0x00 }, _status = 0;
5747 uint p2pielen = 0, attr_contentlen = 0;
5749 uint uintPeerChannel = 0;
5750 #ifdef CONFIG_CONCURRENT_MODE
5751 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5752 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5753 #endif // CONFIG_CONCURRENT_MODE
5755 struct wifi_display_info* pwfd_info = pwdinfo->wfd_info;
5757 // Commented by Albert 20120512
5758 // 1. Input information is the MAC address which wants to know the Preferred Connection bit (PC bit)
5759 // Format: 00:E0:4C:00:00:05
5761 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5763 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
5765 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5769 for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
5771 peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
5774 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5776 phead = get_list_head(queue);
5777 plist = get_next(phead);
5781 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
5784 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5786 // Commented by Albert 2011/05/18
5787 // Match the device address located in the P2P IE
5788 // This is for the case that the P2P device address is not the same as the P2P interface address.
5790 if ( (p2pie=rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
5792 // The P2P Device ID attribute is included in the Beacon frame.
5793 // The P2P Device Info attribute is included in the probe response frame.
5794 printk( "[%s] Got P2P IE\n", __FUNCTION__ );
5795 if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
5797 // Handle the P2P Device ID attribute of Beacon first
5798 printk( "[%s] P2P_ATTR_DEVICE_ID \n", __FUNCTION__ );
5799 if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
5801 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5805 else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
5807 // Handle the P2P Device Info attribute of probe response
5808 printk( "[%s] P2P_ATTR_DEVICE_INFO \n", __FUNCTION__ );
5809 if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
5811 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5818 plist = get_next(plist);
5822 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5823 printk( "[%s] channel = %d\n", __FUNCTION__, uintPeerChannel );
5825 if ( uintPeerChannel )
5827 u8 wfd_ie[ 128 ] = { 0x00 };
5829 u8 ie_offset = (pnetwork->network.Reserved[0] == 2 ? 0:12);
5831 if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) )
5833 u8 wfd_devinfo[ 6 ] = { 0x00 };
5834 uint wfd_devlen = 6;
5836 DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ );
5837 if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) )
5839 u16 wfd_devinfo_field = 0;
5841 // Commented by Albert 20120319
5842 // The first two bytes are the WFD device information field of WFD device information subelement.
5843 // In big endian format.
5844 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5845 if ( wfd_devinfo_field & WFD_DEVINFO_PC_TDLS )
5847 pwfd_info->wfd_pc = _TRUE;
5851 pwfd_info->wfd_pc = _FALSE;
5858 DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ );
5867 static int rtw_p2p_set_wfd_device_type(struct net_device *dev,
5868 struct iw_request_info *info,
5869 union iwreq_data *wrqu, char *extra)
5873 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5874 struct iw_point *pdata = &wrqu->data;
5875 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5876 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5878 // Commented by Albert 20120328
5879 // The input data is 0 or 1
5880 // 0: specify to Miracast source device
5881 // 1 or others: specify to Miracast sink device (display device)
5883 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5885 if ( extra[ 0 ] == '0' ) // Set to Miracast source device.
5887 pwfd_info->wfd_device_type = WFD_DEVINFO_SOURCE;
5889 else // Set to Miracast sink device.
5891 pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK;
5900 static int rtw_p2p_set_wfd_enable(struct net_device *dev,
5901 struct iw_request_info *info,
5902 union iwreq_data *wrqu, char *extra)
5904 // Commented by Kurt 20121206
5905 // This function is used to set wfd enabled
5908 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5909 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
5912 pwdinfo->wfd_info->wfd_enable = _FALSE;
5913 else if(*extra == '1')
5914 pwdinfo->wfd_info->wfd_enable = _TRUE;
5916 DBG_871X( "[%s] wfd_enable = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_enable );
5922 static int rtw_p2p_set_driver_iface(struct net_device *dev,
5923 struct iw_request_info *info,
5924 union iwreq_data *wrqu, char *extra)
5926 // Commented by Kurt 20121206
5927 // This function is used to set driver iface is WEXT or CFG80211
5929 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5930 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
5934 pwdinfo->driver_interface = DRIVER_WEXT;
5935 DBG_871X( "[%s] driver_interface = WEXT\n", __FUNCTION__);
5937 else if(*extra == '2')
5939 pwdinfo->driver_interface = DRIVER_CFG80211;
5940 DBG_871X( "[%s] driver_interface = CFG80211\n", __FUNCTION__);
5947 // To set the WFD session available to enable or disable
5948 static int rtw_p2p_set_sa(struct net_device *dev,
5949 struct iw_request_info *info,
5950 union iwreq_data *wrqu, char *extra)
5954 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5955 struct iw_point *pdata = &wrqu->data;
5956 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5957 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5959 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5963 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5968 if ( extra[ 0 ] == '0' ) // Disable the session available.
5970 pwdinfo->session_available = _FALSE;
5972 else if ( extra[ 0 ] == '1' ) // Enable the session available.
5974 pwdinfo->session_available = _TRUE;
5978 pwdinfo->session_available = _FALSE;
5981 printk( "[%s] session available = %d\n", __FUNCTION__, pwdinfo->session_available );
5988 #endif // CONFIG_WFD
5990 static int rtw_p2p_prov_disc(struct net_device *dev,
5991 struct iw_request_info *info,
5992 union iwreq_data *wrqu, char *extra)
5995 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5996 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5997 u8 peerMAC[ ETH_ALEN ] = { 0x00 };
5999 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
6000 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6001 _list *plist, *phead;
6002 _queue *queue = &(pmlmepriv->scanned_queue);
6003 struct wlan_network *pnetwork = NULL;
6004 uint uintPeerChannel = 0;
6005 u8 attr_content[100] = { 0x00 }, _status = 0;
6007 uint p2pielen = 0, attr_contentlen = 0;
6010 #ifdef CONFIG_CONCURRENT_MODE
6011 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
6012 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
6013 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
6014 #endif // CONFIG_CONCURRENT_MODE
6016 struct wifi_display_info* pwfd_info = pwdinfo->wfd_info;
6017 #endif // CONFIG_WFD
6019 // Commented by Albert 20110301
6020 // The input data contains two informations.
6021 // 1. First information is the MAC address which wants to issue the provisioning discovery request frame.
6022 // 2. Second information is the WPS configuration method which wants to discovery
6023 // Format: 00:E0:4C:00:00:05_display
6024 // Format: 00:E0:4C:00:00:05_keypad
6025 // Format: 00:E0:4C:00:00:05_pbc
6026 // Format: 00:E0:4C:00:00:05_label
6028 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6030 if ( pwdinfo->p2p_state == P2P_STATE_NONE )
6032 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
6037 #ifdef CONFIG_INTEL_WIDI
6038 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
6039 DBG_871X( "[%s] WiFi is under survey!\n", __FUNCTION__ );
6042 #endif //CONFIG_INTEL_WIDI
6044 // Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request.
6045 _rtw_memset( pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN );
6046 _rtw_memset( pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN );
6047 _rtw_memset( &pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof( NDIS_802_11_SSID ) );
6048 pwdinfo->tx_prov_disc_info.peer_channel_num[ 0 ] = 0;
6049 pwdinfo->tx_prov_disc_info.peer_channel_num[ 1 ] = 0;
6050 pwdinfo->tx_prov_disc_info.benable = _FALSE;
6053 for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
6055 peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
6058 if ( _rtw_memcmp( &extra[ 18 ], "display", 7 ) )
6060 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
6062 else if ( _rtw_memcmp( &extra[ 18 ], "keypad", 7 ) )
6064 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
6066 else if ( _rtw_memcmp( &extra[ 18 ], "pbc", 3 ) )
6068 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
6070 else if ( _rtw_memcmp( &extra[ 18 ], "label", 5 ) )
6072 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
6076 DBG_871X( "[%s] Unknown WPS config methodn", __FUNCTION__ );
6080 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
6082 phead = get_list_head(queue);
6083 plist = get_next(phead);
6087 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
6090 if( uintPeerChannel != 0 )
6093 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
6095 // Commented by Albert 2011/05/18
6096 // Match the device address located in the P2P IE
6097 // This is for the case that the P2P device address is not the same as the P2P interface address.
6099 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);
6100 if ( (p2pie=rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0])))
6104 // The P2P Device ID attribute is included in the Beacon frame.
6105 // The P2P Device Info attribute is included in the probe response frame.
6107 if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
6109 // Handle the P2P Device ID attribute of Beacon first
6110 if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
6112 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6116 else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
6118 // Handle the P2P Device Info attribute of probe response
6119 if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
6121 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6126 //Get the next P2P IE
6127 p2pie = rtw_get_p2p_ie(p2pie+p2pielen, pnetwork->network.IELength - ie_offset -(p2pie -&pnetwork->network.IEs[ie_offset] + p2pielen), NULL, &p2pielen);
6132 #ifdef CONFIG_INTEL_WIDI
6133 // Some Intel WiDi source may not provide P2P IE,
6134 // so we could only compare mac addr by 802.11 Source Address
6135 if( pmlmepriv->widi_state == INTEL_WIDI_STATE_WFD_CONNECTION
6136 && uintPeerChannel == 0 )
6138 if ( _rtw_memcmp( pnetwork->network.MacAddress, peerMAC, ETH_ALEN ) )
6140 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6144 #endif //CONFIG_INTEL_WIDI
6146 plist = get_next(plist);
6150 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
6152 if ( uintPeerChannel )
6156 u8 wfd_ie[ 128 ] = { 0x00 };
6159 if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) )
6161 u8 wfd_devinfo[ 6 ] = { 0x00 };
6162 uint wfd_devlen = 6;
6164 DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ );
6165 if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) )
6167 u16 wfd_devinfo_field = 0;
6169 // Commented by Albert 20120319
6170 // The first two bytes are the WFD device information field of WFD device information subelement.
6171 // In big endian format.
6172 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
6173 if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL )
6175 pwfd_info->peer_session_avail = _TRUE;
6179 pwfd_info->peer_session_avail = _FALSE;
6184 if ( _FALSE == pwfd_info->peer_session_avail )
6186 DBG_871X( "[%s] WFD Session not avaiable!\n", __FUNCTION__ );
6190 #endif // CONFIG_WFD
6192 DBG_871X( "[%s] peer channel: %d!\n", __FUNCTION__, uintPeerChannel );
6193 #ifdef CONFIG_CONCURRENT_MODE
6194 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6196 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
6198 #endif // CONFIG_CONCURRENT_MODE
6199 _rtw_memcpy( pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN );
6200 _rtw_memcpy( pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN );
6201 pwdinfo->tx_prov_disc_info.peer_channel_num[0] = ( u16 ) uintPeerChannel;
6202 pwdinfo->tx_prov_disc_info.benable = _TRUE;
6203 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6204 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ);
6206 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
6208 _rtw_memcpy( &pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof( NDIS_802_11_SSID ) );
6210 else if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
6212 _rtw_memcpy( pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN );
6213 pwdinfo->tx_prov_disc_info.ssid.SsidLength= P2P_WILDCARD_SSID_LEN;
6216 #ifdef CONFIG_CONCURRENT_MODE
6217 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6219 // Have to enter the power saving with the AP
6220 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
6222 issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
6226 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
6229 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
6232 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
6234 #ifdef CONFIG_CONCURRENT_MODE
6235 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6237 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_PROVISION_TIMEOUT );
6241 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6244 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6245 #endif // CONFIG_CONCURRENT_MODE
6250 DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ );
6251 #ifdef CONFIG_INTEL_WIDI
6252 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6253 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
6254 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
6255 rtw_free_network_queue(padapter, _TRUE);
6256 _enter_critical_bh(&pmlmepriv->lock, &irqL);
6257 rtw_sitesurvey_cmd(padapter, NULL, 0, NULL, 0);
6258 _exit_critical_bh(&pmlmepriv->lock, &irqL);
6259 #endif //CONFIG_INTEL_WIDI
6267 // Added by Albert 20110328
6268 // This function is used to inform the driver the user had specified the pin code value or pbc
6271 static int rtw_p2p_got_wpsinfo(struct net_device *dev,
6272 struct iw_request_info *info,
6273 union iwreq_data *wrqu, char *extra)
6277 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6278 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
6281 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6282 // Added by Albert 20110328
6283 // if the input data is P2P_NO_WPSINFO -> reset the wpsinfo
6284 // if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device.
6285 // if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself.
6286 // if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC
6288 if ( *extra == '0' )
6290 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
6292 else if ( *extra == '1' )
6294 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN;
6296 else if ( *extra == '2' )
6298 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN;
6300 else if ( *extra == '3' )
6302 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC;
6306 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
6315 static int rtw_p2p_set(struct net_device *dev,
6316 struct iw_request_info *info,
6317 union iwreq_data *wrqu, char *extra)
6323 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6324 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6325 struct iw_point *pdata = &wrqu->data;
6326 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
6327 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6329 DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra );
6331 if ( _rtw_memcmp( extra, "enable=", 7 ) )
6333 rtw_wext_p2p_enable( dev, info, wrqu, &extra[7] );
6335 else if ( _rtw_memcmp( extra, "setDN=", 6 ) )
6337 wrqu->data.length -= 6;
6338 rtw_p2p_setDN( dev, info, wrqu, &extra[6] );
6340 else if ( _rtw_memcmp( extra, "profilefound=", 13 ) )
6342 wrqu->data.length -= 13;
6343 rtw_p2p_profilefound( dev, info, wrqu, &extra[13] );
6345 else if ( _rtw_memcmp( extra, "prov_disc=", 10 ) )
6347 wrqu->data.length -= 10;
6348 rtw_p2p_prov_disc( dev, info, wrqu, &extra[10] );
6350 else if ( _rtw_memcmp( extra, "nego=", 5 ) )
6352 wrqu->data.length -= 5;
6353 rtw_p2p_connect( dev, info, wrqu, &extra[5] );
6355 else if ( _rtw_memcmp( extra, "intent=", 7 ) )
6357 // Commented by Albert 2011/03/23
6358 // The wrqu->data.length will include the null character
6359 // So, we will decrease 7 + 1
6360 wrqu->data.length -= 8;
6361 rtw_p2p_set_intent( dev, info, wrqu, &extra[7] );
6363 else if ( _rtw_memcmp( extra, "ssid=", 5 ) )
6365 wrqu->data.length -= 5;
6366 rtw_p2p_set_go_nego_ssid( dev, info, wrqu, &extra[5] );
6368 else if ( _rtw_memcmp( extra, "got_wpsinfo=", 12 ) )
6370 wrqu->data.length -= 12;
6371 rtw_p2p_got_wpsinfo( dev, info, wrqu, &extra[12] );
6373 else if ( _rtw_memcmp( extra, "listen_ch=", 10 ) )
6375 // Commented by Albert 2011/05/24
6376 // The wrqu->data.length will include the null character
6377 // So, we will decrease (10 + 1)
6378 wrqu->data.length -= 11;
6379 rtw_p2p_set_listen_ch( dev, info, wrqu, &extra[10] );
6381 else if ( _rtw_memcmp( extra, "op_ch=", 6 ) )
6383 // Commented by Albert 2011/05/24
6384 // The wrqu->data.length will include the null character
6385 // So, we will decrease (6 + 1)
6386 wrqu->data.length -= 7;
6387 rtw_p2p_set_op_ch( dev, info, wrqu, &extra[6] );
6389 else if ( _rtw_memcmp( extra, "invite=", 7 ) )
6391 wrqu->data.length -= 8;
6392 rtw_p2p_invite_req( dev, info, wrqu, &extra[7] );
6394 else if ( _rtw_memcmp( extra, "persistent=", 11 ) )
6396 wrqu->data.length -= 11;
6397 rtw_p2p_set_persistent( dev, info, wrqu, &extra[11] );
6399 else if ( _rtw_memcmp ( extra, "uuid=", 5) )
6401 wrqu->data.length -= 5;
6402 ret = rtw_p2p_set_wps_uuid( dev, info, wrqu, &extra[5] );
6405 else if ( _rtw_memcmp( extra, "sa=", 3 ) )
6407 // sa: WFD Session Available information
6408 wrqu->data.length -= 3;
6409 rtw_p2p_set_sa( dev, info, wrqu, &extra[3] );
6411 else if ( _rtw_memcmp( extra, "pc=", 3 ) )
6413 // pc: WFD Preferred Connection
6414 wrqu->data.length -= 3;
6415 rtw_p2p_set_pc( dev, info, wrqu, &extra[3] );
6417 else if ( _rtw_memcmp( extra, "wfd_type=", 9 ) )
6419 // pc: WFD Preferred Connection
6420 wrqu->data.length -= 9;
6421 rtw_p2p_set_wfd_device_type( dev, info, wrqu, &extra[9] );
6423 else if ( _rtw_memcmp( extra, "wfd_enable=", 11 ) )
6425 wrqu->data.length -= 11;
6426 rtw_p2p_set_wfd_enable( dev, info, wrqu, &extra[11] );
6428 else if ( _rtw_memcmp( extra, "driver_iface=", 13 ) )
6430 wrqu->data.length -= 13;
6431 rtw_p2p_set_driver_iface( dev, info, wrqu, &extra[13] );
6441 static int rtw_p2p_get(struct net_device *dev,
6442 struct iw_request_info *info,
6443 union iwreq_data *wrqu, char *extra)
6450 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6451 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6452 struct iw_point *pdata = &wrqu->data;
6453 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
6454 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6456 if ( padapter->bShowGetP2PState )
6458 DBG_871X( "[%s] extra = %s\n", __FUNCTION__, (char*) wrqu->data.pointer );
6461 if ( _rtw_memcmp( wrqu->data.pointer, "status", 6 ) )
6463 rtw_p2p_get_status( dev, info, wrqu, extra );
6465 else if ( _rtw_memcmp( wrqu->data.pointer, "role", 4 ) )
6467 rtw_p2p_get_role( dev, info, wrqu, extra);
6469 else if ( _rtw_memcmp( wrqu->data.pointer, "peer_ifa", 8 ) )
6471 rtw_p2p_get_peer_ifaddr( dev, info, wrqu, extra);
6473 else if ( _rtw_memcmp( wrqu->data.pointer, "req_cm", 6 ) )
6475 rtw_p2p_get_req_cm( dev, info, wrqu, extra);
6477 else if ( _rtw_memcmp( wrqu->data.pointer, "peer_deva", 9 ) )
6479 // Get the P2P device address when receiving the provision discovery request frame.
6480 rtw_p2p_get_peer_devaddr( dev, info, wrqu, extra);
6482 else if ( _rtw_memcmp( wrqu->data.pointer, "group_id", 8 ) )
6484 rtw_p2p_get_groupid( dev, info, wrqu, extra);
6486 else if ( _rtw_memcmp( wrqu->data.pointer, "inv_peer_deva", 13 ) )
6488 // Get the P2P device address when receiving the P2P Invitation request frame.
6489 rtw_p2p_get_peer_devaddr_by_invitation( dev, info, wrqu, extra);
6491 else if ( _rtw_memcmp( wrqu->data.pointer, "op_ch", 5 ) )
6493 rtw_p2p_get_op_ch( dev, info, wrqu, extra);
6496 else if ( _rtw_memcmp( wrqu->data.pointer, "peer_port", 9 ) )
6498 rtw_p2p_get_peer_wfd_port( dev, info, wrqu, extra );
6500 else if ( _rtw_memcmp( wrqu->data.pointer, "wfd_sa", 6 ) )
6502 rtw_p2p_get_peer_wfd_session_available( dev, info, wrqu, extra );
6504 else if ( _rtw_memcmp( wrqu->data.pointer, "wfd_pc", 6 ) )
6506 rtw_p2p_get_peer_wfd_preferred_connection( dev, info, wrqu, extra );
6508 #endif // CONFIG_WFD
6516 static int rtw_p2p_get2(struct net_device *dev,
6517 struct iw_request_info *info,
6518 union iwreq_data *wrqu, char *extra)
6525 int length = wrqu->data.length;
6526 char *buffer = (u8 *)rtw_malloc(length);
6534 if (copy_from_user(buffer, wrqu->data.pointer, wrqu->data.length))
6540 DBG_871X("[%s] buffer = %s\n", __FUNCTION__, buffer);
6542 if (_rtw_memcmp(buffer, "wpsCM=", 6))
6544 ret = rtw_p2p_get_wps_configmethod(dev, info, wrqu, extra, &buffer[6]);
6545 } else if (_rtw_memcmp(buffer, "devN=", 5))
6547 ret = rtw_p2p_get_device_name(dev, info, wrqu, extra, &buffer[5]);
6548 } else if (_rtw_memcmp(buffer, "dev_type=", 9))
6550 ret = rtw_p2p_get_device_type(dev, info, wrqu, extra, &buffer[9]);
6551 } else if (_rtw_memcmp(buffer, "go_devadd=", 10))
6553 ret = rtw_p2p_get_go_device_address(dev, info, wrqu, extra, &buffer[10]);
6554 } else if (_rtw_memcmp(buffer, "InvProc=", 8))
6556 ret = rtw_p2p_get_invitation_procedure(dev, info, wrqu, extra, &buffer[8]);
6559 snprintf(extra, sizeof("Command not found."), "Command not found.");
6560 wrqu->data.length = strlen(extra);
6566 rtw_mfree(buffer, length);
6575 static int rtw_cta_test_start(struct net_device *dev,
6576 struct iw_request_info *info,
6577 union iwreq_data *wrqu, char *extra)
6580 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6581 DBG_871X("%s %s\n", __func__, extra);
6582 if (!strcmp(extra, "1"))
6583 padapter->in_cta_test = 1;
6585 padapter->in_cta_test = 0;
6587 if(padapter->in_cta_test)
6589 u32 v = rtw_read32(padapter, REG_RCR);
6590 v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN );//| RCR_ADF
6591 rtw_write32(padapter, REG_RCR, v);
6592 DBG_871X("enable RCR_ADF\n");
6596 u32 v = rtw_read32(padapter, REG_RCR);
6597 v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN ;//| RCR_ADF
6598 rtw_write32(padapter, REG_RCR, v);
6599 DBG_871X("disable RCR_ADF\n");
6605 extern int rtw_change_ifname(_adapter *padapter, const char *ifname);
6606 static int rtw_rereg_nd_name(struct net_device *dev,
6607 struct iw_request_info *info,
6608 union iwreq_data *wrqu, char *extra)
6611 _adapter *padapter = rtw_netdev_priv(dev);
6612 struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;
6613 char new_ifname[IFNAMSIZ];
6615 if(rereg_priv->old_ifname[0] == 0) {
6617 #ifdef CONFIG_CONCURRENT_MODE
6618 if (padapter->isprimary)
6619 reg_ifname = padapter->registrypriv.ifname;
6622 reg_ifname = padapter->registrypriv.if2name;
6624 strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);
6625 rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
6628 //DBG_871X("%s wrqu->data.length:%d\n", __FUNCTION__, wrqu->data.length);
6629 if(wrqu->data.length > IFNAMSIZ)
6632 if ( copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ) ) {
6636 if( 0 == strcmp(rereg_priv->old_ifname, new_ifname) ) {
6640 DBG_871X("%s new_ifname:%s\n", __FUNCTION__, new_ifname);
6641 if( 0 != (ret = rtw_change_ifname(padapter, new_ifname)) ) {
6645 if(_rtw_memcmp(rereg_priv->old_ifname, "disable%d", 9) == _TRUE) {
6646 padapter->ledpriv.bRegUseLed= rereg_priv->old_bRegUseLed;
6647 rtw_hal_sw_led_init(padapter);
6648 //rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode);
6651 strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
6652 rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
6654 if(_rtw_memcmp(new_ifname, "disable%d", 9) == _TRUE) {
6656 DBG_871X("%s disable\n", __FUNCTION__);
6657 // free network queue for Android's timming issue
6658 rtw_free_network_queue(padapter, _TRUE);
6661 rtw_led_control(padapter, LED_CTL_POWER_OFF);
6662 rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed;
6663 padapter->ledpriv.bRegUseLed= _FALSE;
6664 rtw_hal_sw_led_deinit(padapter);
6666 // the interface is being "disabled", we can do deeper IPS
6667 //rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv);
6668 //rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL);
6676 #include <rtw_iol.h>
6678 static int rtw_dbg_port(struct net_device *dev,
6679 struct iw_request_info *info,
6680 union iwreq_data *wrqu, char *extra)
6684 u8 major_cmd, minor_cmd;
6686 u32 extra_arg, *pdata, val32;
6687 struct sta_info *psta;
6688 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6689 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6690 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6691 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6692 struct security_priv *psecuritypriv = &padapter->securitypriv;
6693 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
6694 struct sta_priv *pstapriv = &padapter->stapriv;
6697 pdata = (u32*)&wrqu->data;
6700 arg = (u16)(val32&0x0000ffff);
6701 major_cmd = (u8)(val32>>24);
6702 minor_cmd = (u8)((val32>>16)&0x00ff);
6704 extra_arg = *(pdata+1);
6708 case 0x70://read_reg
6712 DBG_871X("rtw_read8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
6715 DBG_871X("rtw_read16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
6718 DBG_871X("rtw_read32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
6722 case 0x71://write_reg
6726 rtw_write8(padapter, arg, extra_arg);
6727 DBG_871X("rtw_write8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
6730 rtw_write16(padapter, arg, extra_arg);
6731 DBG_871X("rtw_write16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
6734 rtw_write32(padapter, arg, extra_arg);
6735 DBG_871X("rtw_write32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
6740 DBG_871X("read_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
6742 case 0x73://write_bb
6743 rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);
6744 DBG_871X("write_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
6747 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));
6749 case 0x75://write_rf
6750 rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
6751 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));
6757 case 0x00: //normal mode,
6758 padapter->recvpriv.is_signal_dbg = 0;
6760 case 0x01: //dbg mode
6761 padapter->recvpriv.is_signal_dbg = 1;
6762 extra_arg = extra_arg>100?100:extra_arg;
6763 extra_arg = extra_arg<0?0:extra_arg;
6764 padapter->recvpriv.signal_strength_dbg=extra_arg;
6768 case 0x78: //IOL test
6772 case 0x04: //LLT table initialization test
6774 u8 page_boundary = 0xf9;
6776 struct xmit_frame *xmit_frame;
6778 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6783 rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary);
6786 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500,0) )
6791 case 0x05: //blink LED test
6795 u32 blink_delay_ms = 200;
6799 struct xmit_frame *xmit_frame;
6801 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6806 for(i=0;i<blink_num;i++){
6807 #ifdef CONFIG_IOL_NEW_GENERATION
6808 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00,0xff);
6809 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6810 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08,0xff);
6811 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6813 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00);
6814 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6815 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08);
6816 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6819 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms*blink_num*2)+200,0) )
6825 case 0x06: //continuous wirte byte test
6828 u16 start_value = 0;
6829 u32 write_num = extra_arg;
6834 struct xmit_frame *xmit_frame;
6836 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6841 for(i=0;i<write_num;i++){
6842 #ifdef CONFIG_IOL_NEW_GENERATION
6843 rtw_IOL_append_WB_cmd(xmit_frame, reg, i+start_value,0xFF);
6845 rtw_IOL_append_WB_cmd(xmit_frame, reg, i+start_value);
6848 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
6852 if(start_value+write_num-1 == (final=rtw_read8(padapter, reg)) ) {
6853 DBG_871X("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6855 DBG_871X("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6860 case 0x07: //continuous wirte word test
6863 u16 start_value = 200;
6864 u32 write_num = extra_arg;
6870 struct xmit_frame *xmit_frame;
6872 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6877 for(i=0;i<write_num;i++){
6878 #ifdef CONFIG_IOL_NEW_GENERATION
6879 rtw_IOL_append_WW_cmd(xmit_frame, reg, i+start_value,0xFFFF);
6881 rtw_IOL_append_WW_cmd(xmit_frame, reg, i+start_value);
6884 if(_SUCCESS !=rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
6888 if(start_value+write_num-1 == (final=rtw_read16(padapter, reg)) ) {
6889 DBG_871X("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6891 DBG_871X("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6896 case 0x08: //continuous wirte dword test
6899 u32 start_value = 0x110000c7;
6900 u32 write_num = extra_arg;
6906 struct xmit_frame *xmit_frame;
6908 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6913 for(i=0;i<write_num;i++){
6914 #ifdef CONFIG_IOL_NEW_GENERATION
6915 rtw_IOL_append_WD_cmd(xmit_frame, reg, i+start_value,0xFFFFFFFF);
6917 rtw_IOL_append_WD_cmd(xmit_frame, reg, i+start_value);
6920 if(_SUCCESS !=rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
6925 if(start_value+write_num-1 == (final=rtw_read32(padapter, reg)) ) {
6926 DBG_871X("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6928 DBG_871X("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6938 * dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15
6939 * dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15
6941 u8 value = extra_arg & 0x0f;
6942 u8 sign = minor_cmd;
6943 u16 write_value = 0;
6945 DBG_871X("%s set RESP_TXAGC to %s %u\n", __func__, sign?"minus":"plus", value);
6948 value = value | 0x10;
6950 write_value = value | (value << 5);
6951 rtw_write16(padapter, 0x6d9, write_value);
6955 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
6956 , WLAN_REASON_EXPIRATION_CHK);
6962 DBG_871X("fwstate=0x%x\n", get_fwstate(pmlmepriv));
6965 DBG_871X("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",
6966 psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
6967 psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
6970 DBG_871X("pmlmeinfo->state=0x%x\n", pmlmeinfo->state);
6971 DBG_871X("DrvBcnEarly=%d\n", pmlmeext->DrvBcnEarly);
6972 DBG_871X("DrvBcnTimeOut=%d\n", pmlmeext->DrvBcnTimeOut);
6975 DBG_871X("qos_option=%d\n", pmlmepriv->qospriv.qos_option);
6976 #ifdef CONFIG_80211N_HT
6977 DBG_871X("ht_option=%d\n", pmlmepriv->htpriv.ht_option);
6978 #endif //CONFIG_80211N_HT
6981 DBG_871X("cur_ch=%d\n", pmlmeext->cur_channel);
6982 DBG_871X("cur_bw=%d\n", pmlmeext->cur_bwmode);
6983 DBG_871X("cur_ch_off=%d\n", pmlmeext->cur_ch_offset);
6985 DBG_871X("oper_ch=%d\n", rtw_get_oper_ch(padapter));
6986 DBG_871X("oper_bw=%d\n", rtw_get_oper_bw(padapter));
6987 DBG_871X("oper_ch_offet=%d\n", rtw_get_oper_choffset(padapter));
6991 psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
6995 struct recv_reorder_ctrl *preorder_ctrl;
6997 DBG_871X("SSID=%s\n", cur_network->network.Ssid.Ssid);
6998 DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
6999 DBG_871X("cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
7000 DBG_871X("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
7001 DBG_871X("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
7002 #ifdef CONFIG_80211N_HT
7003 DBG_871X("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
7004 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);
7005 DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
7006 DBG_871X("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
7007 #endif //CONFIG_80211N_HT
7011 preorder_ctrl = &psta->recvreorder_ctrl[i];
7012 if(preorder_ctrl->enable)
7014 DBG_871X("tid=%d, indicate_seq=%d\n", i, preorder_ctrl->indicate_seq);
7021 DBG_871X("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));
7027 rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8*)(&ODMFlag));
7028 DBG_871X("(B)DMFlag=0x%x, arg=0x%x\n", ODMFlag, arg);
7029 ODMFlag = (u32)(0x0f&arg);
7030 DBG_871X("(A)DMFlag=0x%x\n", ODMFlag);
7031 rtw_hal_set_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
7035 DBG_871X("bSurpriseRemoved=%d, bDriverStopped=%d\n",
7036 padapter->bSurpriseRemoved, padapter->bDriverStopped);
7040 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7041 struct recv_priv *precvpriv = &padapter->recvpriv;
7043 DBG_871X("free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d"
7044 ", free_xmit_extbuf_cnt=%d, free_xframe_ext_cnt=%d"
7045 ", free_recvframe_cnt=%d\n",
7046 pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt,
7047 pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt,
7048 precvpriv->free_recvframe_cnt);
7049 #ifdef CONFIG_USB_HCI
7050 DBG_871X("rx_urb_pending_cn=%d\n", precvpriv->rx_pending_cnt);
7057 _list *plist, *phead;
7058 struct recv_reorder_ctrl *preorder_ctrl;
7060 #ifdef CONFIG_AP_MODE
7061 DBG_871X("sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
7063 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
7065 for(i=0; i< NUM_STA; i++)
7067 phead = &(pstapriv->sta_hash[i]);
7068 plist = get_next(phead);
7070 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
7072 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
7074 plist = get_next(plist);
7076 if(extra_arg == psta->aid)
7078 DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
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
7088 #ifdef CONFIG_AP_MODE
7089 DBG_871X("capability=0x%x\n", psta->capability);
7090 DBG_871X("flags=0x%x\n", psta->flags);
7091 DBG_871X("wpa_psk=0x%x\n", psta->wpa_psk);
7092 DBG_871X("wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher);
7093 DBG_871X("wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher);
7094 DBG_871X("qos_info=0x%x\n", psta->qos_info);
7096 DBG_871X("dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy);
7102 preorder_ctrl = &psta->recvreorder_ctrl[j];
7103 if(preorder_ctrl->enable)
7105 DBG_871X("tid=%d, indicate_seq=%d\n", j, preorder_ctrl->indicate_seq);
7114 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
7121 max_mac_id = rtw_search_max_mac_id( padapter);
7122 printk("%s ==> max_mac_id = %d \n",__FUNCTION__,max_mac_id);
7125 case 0x0b: //Enable=1, Disable=0 driver control vrtl_carrier_sense.
7127 //u8 driver_vcs_en; //Enable=1, Disable=0 driver control vrtl_carrier_sense.
7128 //u8 driver_vcs_type;//force 0:disable VCS, 1:RTS-CTS, 2:CTS-to-self when vcs_en=1.
7131 DBG_871X("disable driver ctrl vcs\n");
7132 padapter->driver_vcs_en = 0;
7135 DBG_871X("enable driver ctrl vcs = %d\n", extra_arg);
7136 padapter->driver_vcs_en = 1;
7139 padapter->driver_vcs_type = 1;
7141 padapter->driver_vcs_type = extra_arg;
7145 case 0x0c://dump rx/tx packet
7148 DBG_871X("dump rx packet (%d)\n",extra_arg);
7149 //pHalData->bDumpRxPkt =extra_arg;
7150 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
7153 DBG_871X("dump tx packet (%d)\n",extra_arg);
7154 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
7159 case 0x0d://dump cam
7161 //u8 entry = (u8) extra_arg;
7164 for(entry=0;entry<32;entry++)
7165 read_cam(padapter,entry);
7172 DBG_871X("disable driver ctrl rx_ampdu_factor\n");
7173 padapter->driver_rx_ampdu_factor = 0xFF;
7177 DBG_871X("enable driver ctrl rx_ampdu_factor = %d\n", extra_arg);
7179 if((extra_arg & 0x03) > 0x03)
7180 padapter->driver_rx_ampdu_factor = 0xFF;
7182 padapter->driver_rx_ampdu_factor = extra_arg;
7186 #ifdef DBG_CONFIG_ERROR_DETECT
7190 DBG_871X("###### silent reset test.......#####\n");
7191 rtw_hal_sreset_reset(padapter);
7193 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
7194 struct sreset_priv *psrtpriv = &pHalData->srestpriv;
7195 psrtpriv->dbg_trigger_point = extra_arg;
7202 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
7203 DBG_871X("==>silent resete cnts:%d\n",pwrpriv->ips_enter_cnts);
7209 case 0x10:// driver version display
7210 dump_drv_version(RTW_DBGDUMP);
7212 case 0x11://dump linked status
7214 linked_info_dump(padapter,extra_arg);
7217 #ifdef CONFIG_80211N_HT
7218 case 0x12: //set rx_stbc
7220 struct registry_priv *pregpriv = &padapter->registrypriv;
7221 // 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g
7222 //default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ
7223 if( pregpriv && (extra_arg == 0 || extra_arg == 1|| extra_arg == 2 || extra_arg == 3))
7225 pregpriv->rx_stbc= extra_arg;
7226 DBG_871X("set rx_stbc=%d\n",pregpriv->rx_stbc);
7229 DBG_871X("get rx_stbc=%d\n",pregpriv->rx_stbc);
7233 case 0x13: //set ampdu_enable
7235 struct registry_priv *pregpriv = &padapter->registrypriv;
7236 // 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec)
7237 if( pregpriv && extra_arg < 3 )
7239 pregpriv->ampdu_enable= extra_arg;
7240 DBG_871X("set ampdu_enable=%d\n",pregpriv->ampdu_enable);
7243 DBG_871X("get ampdu_enable=%d\n",pregpriv->ampdu_enable);
7248 case 0x14: //get wifi_spec
7250 struct registry_priv *pregpriv = &padapter->registrypriv;
7251 DBG_871X("get wifi_spec=%d\n",pregpriv->wifi_spec);
7258 rtw_odm_dbg_comp_msg(RTW_DBGDUMP,padapter);
7261 u64 dbg_comp = (u64)extra_arg;
7262 rtw_odm_dbg_comp_set(padapter, dbg_comp);
7266 #ifdef DBG_FIXED_CHAN
7269 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7270 printk("===> Fixed channel to %d \n",extra_arg);
7271 pmlmeext->fixed_chan = extra_arg;
7278 printk("===> Switch USB Mode %d \n",extra_arg);
7279 rtw_hal_set_hwreg(padapter, HW_VAR_USB_MODE, (u8 *)&extra_arg);
7282 #ifdef CONFIG_80211N_HT
7285 struct registry_priv *pregistrypriv = &padapter->registrypriv;
7287 // BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx,
7288 // BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx
7290 DBG_871X("driver disable LDPC\n");
7291 pregistrypriv->ldpc_cap = 0x00;
7294 DBG_871X("driver set LDPC cap = 0x%x\n", extra_arg);
7295 pregistrypriv->ldpc_cap = (u8)(extra_arg&0x33);
7301 struct registry_priv *pregistrypriv = &padapter->registrypriv;
7303 // BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx,
7304 // BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx
7306 DBG_871X("driver disable STBC\n");
7307 pregistrypriv->stbc_cap = 0x00;
7310 DBG_871X("driver set STBC cap = 0x%x\n", extra_arg);
7311 pregistrypriv->stbc_cap = (u8)(extra_arg&0x33);
7315 #endif //CONFIG_80211N_HT
7318 struct registry_priv *pregistrypriv = &padapter->registrypriv;
7321 DBG_871X("disable driver ctrl max_rx_rate, reset to default_rate_set\n");
7322 init_mlme_default_rate_set(padapter);
7323 #ifdef CONFIG_80211N_HT
7324 pregistrypriv->ht_enable = (u8)rtw_ht_enable;
7325 #endif //CONFIG_80211N_HT
7332 DBG_871X("enable driver ctrl max_rx_rate = 0x%x\n", extra_arg);
7334 max_rx_rate = (u8)extra_arg;
7336 if(max_rx_rate < 0xc) // max_rx_rate < MSC0 -> B or G -> disable HT
7338 #ifdef CONFIG_80211N_HT
7339 pregistrypriv->ht_enable = 0;
7340 #endif //CONFIG_80211N_HT
7341 for(i=0; i<NumRates; i++)
7343 if(pmlmeext->datarate[i] > max_rx_rate)
7344 pmlmeext->datarate[i] = 0xff;
7348 #ifdef CONFIG_80211N_HT
7349 else if(max_rx_rate < 0x1c) // mcs0~mcs15
7353 for(i=0; i<((max_rx_rate+1)-0xc); i++)
7354 mcs_bitmap |= BIT(i);
7356 set_mcs_rate_by_mask(pmlmeext->default_supported_mcs_set, mcs_bitmap);
7358 #endif //CONFIG_80211N_HT
7362 case 0x1c: //enable/disable driver control AMPDU Density for peer sta's rx
7365 DBG_871X("disable driver ctrl ampdu density\n");
7366 padapter->driver_ampdu_spacing = 0xFF;
7370 DBG_871X("enable driver ctrl ampdu density = %d\n", extra_arg);
7372 if((extra_arg & 0x07) > 0x07)
7373 padapter->driver_ampdu_spacing = 0xFF;
7375 padapter->driver_ampdu_spacing = extra_arg;
7379 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
7382 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
7383 PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
7384 u8 chan = rtw_get_oper_ch(padapter);
7385 DBG_871X("===========================================\n");
7386 ODM_InbandNoise_Monitor(pDM_Odm,_TRUE,0x1e,100);
7387 DBG_871X("channel(%d),noise_a = %d, noise_b = %d , noise_all:%d \n",
7388 chan,pDM_Odm->noise_level.noise[ODM_RF_PATH_A],
7389 pDM_Odm->noise_level.noise[ODM_RF_PATH_B],
7390 pDM_Odm->noise_level.noise_all);
7391 DBG_871X("===========================================\n");
7398 DBG_871X("turn %s the bNotifyChannelChange Variable\n",(extra_arg==1)?"on":"off");
7399 padapter->bNotifyChannelChange = extra_arg;
7405 DBG_871X("turn %s the bShowGetP2PState Variable\n",(extra_arg==1)?"on":"off");
7406 padapter->bShowGetP2PState = extra_arg;
7407 #endif // CONFIG_P2P
7410 #ifdef CONFIG_GPIO_API
7411 case 0x25: //Get GPIO register
7414 * dbg 0x7f250000 [gpio_num], Get gpio value, gpio_num:0~7
7418 DBG_871X("Read GPIO Value extra_arg = %d\n",extra_arg);
7419 value = rtw_get_gpio(dev,extra_arg);
7420 DBG_871X("Read GPIO Value = %d\n",value);
7423 case 0x26: //Set GPIO direction
7426 /* dbg 0x7f26000x [y], Set gpio direction,
7427 * x: gpio_num,4~7 y: indicate direction, 0~1
7431 DBG_871X("Set GPIO Direction! arg = %d ,extra_arg=%d\n",arg ,extra_arg);
7432 value = rtw_config_gpio(dev, arg, extra_arg);
7433 DBG_871X("Set GPIO Direction %s \n",(value==-1)?"Fail!!!":"Success");
7436 case 0x27: //Set GPIO output direction value
7439 * dbg 0x7f27000x [y], Set gpio output direction value,
7440 * x: gpio_num,4~7 y: indicate direction, 0~1
7444 DBG_871X("Set GPIO Value! arg = %d ,extra_arg=%d\n",arg ,extra_arg);
7445 value = rtw_set_gpio_output_value(dev,arg,extra_arg);
7446 DBG_871X("Set GPIO Value %s \n",(value==-1)?"Fail!!!":"Success");
7452 if((extra_arg & 0x7F)> 0x3F) extra_arg = 0xFF;
7453 DBG_871X("chang data rate to :0x%02x\n",extra_arg);
7454 padapter->fix_rate = extra_arg;
7457 case 0xdd://registers dump , 0 for mac reg,1 for bb reg, 2 for rf reg
7460 mac_reg_dump(RTW_DBGDUMP, padapter);
7462 else if(extra_arg==1){
7463 bb_reg_dump(RTW_DBGDUMP, padapter);
7465 else if(extra_arg==2){
7466 rf_reg_dump(RTW_DBGDUMP, padapter);
7471 case 0xee://turn on/off dynamic funcs
7476 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&odm_flag);
7477 DBG_871X(" === DMFlag(0x%08x) === \n",odm_flag);
7478 DBG_871X("extra_arg = 0 - disable all dynamic func \n");
7479 DBG_871X("extra_arg = 1 - disable DIG- BIT(0)\n");
7480 DBG_871X("extra_arg = 2 - disable High power - BIT(1)\n");
7481 DBG_871X("extra_arg = 3 - disable tx power tracking - BIT(2)\n");
7482 DBG_871X("extra_arg = 4 - disable BT coexistence - BIT(3)\n");
7483 DBG_871X("extra_arg = 5 - disable antenna diversity - BIT(4)\n");
7484 DBG_871X("extra_arg = 6 - enable all dynamic func \n");
7487 /* extra_arg = 0 - disable all dynamic func
7488 extra_arg = 1 - disable DIG
7489 extra_arg = 2 - disable tx power tracking
7490 extra_arg = 3 - turn on all dynamic func
7492 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &(extra_arg));
7493 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&odm_flag);
7494 DBG_871X(" === DMFlag(0x%08x) === \n",odm_flag);
7500 rtw_write8(padapter, 0xc50, arg);
7501 DBG_871X("wr(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
7502 rtw_write8(padapter, 0xc58, arg);
7503 DBG_871X("wr(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
7506 DBG_871X("rd(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
7507 DBG_871X("rd(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
7511 DBG_871X("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
7512 DBG_871X("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
7513 DBG_871X("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
7514 DBG_871X("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
7515 DBG_871X("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
7517 DBG_871X("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
7522 DBG_871X("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
7523 DBG_871X("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
7525 DBG_871X("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
7527 DBG_871X("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
7529 DBG_871X("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
7530 DBG_871X("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
7532 DBG_871X("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
7533 DBG_871X("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
7534 DBG_871X("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
7535 DBG_871X("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
7541 DBG_871X("error dbg cmd!\n");
7550 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
7554 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7557 case IEEE_PARAM_WPA_ENABLED:
7559 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; //802.1x
7561 //ret = ieee80211_wpa_enable(ieee, value);
7563 switch((value)&0xff)
7566 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; //WPA_PSK
7567 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
7570 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; //WPA2_PSK
7571 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
7575 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("wpa_set_param:padapter->securitypriv.ndisauthtype=%d\n", padapter->securitypriv.ndisauthtype));
7579 case IEEE_PARAM_TKIP_COUNTERMEASURES:
7580 //ieee->tkip_countermeasures=value;
7583 case IEEE_PARAM_DROP_UNENCRYPTED:
7587 * wpa_supplicant calls set_wpa_enabled when the driver
7588 * is loaded and unloaded, regardless of if WPA is being
7589 * used. No other calls are made which can be used to
7590 * determine if encryption will be used or not prior to
7591 * association being expected. If encryption is not being
7592 * used, drop_unencrypted is set to false, else true -- we
7593 * can use this to determine if the CAP_PRIVACY_ON bit should
7598 struct ieee80211_security sec = {
7599 .flags = SEC_ENABLED,
7602 ieee->drop_unencrypted = value;
7603 /* We only change SEC_LEVEL for open mode. Others
7604 * are set by ipw_wpa_set_encryption.
7607 sec.flags |= SEC_LEVEL;
7608 sec.level = SEC_LEVEL_0;
7611 sec.flags |= SEC_LEVEL;
7612 sec.level = SEC_LEVEL_1;
7614 if (ieee->set_security)
7615 ieee->set_security(ieee->dev, &sec);
7620 case IEEE_PARAM_PRIVACY_INVOKED:
7622 //ieee->privacy_invoked=value;
7626 case IEEE_PARAM_AUTH_ALGS:
7628 ret = wpa_set_auth_algs(dev, value);
7632 case IEEE_PARAM_IEEE_802_1X:
7634 //ieee->ieee802_1x=value;
7638 case IEEE_PARAM_WPAX_SELECT:
7640 // added for WPA2 mixed mode
7641 //DBG_871X(KERN_WARNING "------------------------>wpax value = %x\n", value);
7643 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
7644 ieee->wpax_type_set = 1;
7645 ieee->wpax_type_notify = value;
7646 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
7666 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
7669 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7673 case IEEE_MLME_STA_DEAUTH:
7675 if(!rtw_set_802_11_disassociate(padapter))
7680 case IEEE_MLME_STA_DISASSOC:
7682 if(!rtw_set_802_11_disassociate(padapter))
7696 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
7698 struct ieee_param *param;
7701 //down(&ieee->wx_sem);
7703 if (p->length < sizeof(struct ieee_param) || !p->pointer){
7708 param = (struct ieee_param *)rtw_malloc(p->length);
7715 if (copy_from_user(param, p->pointer, p->length))
7717 rtw_mfree((u8*)param, p->length);
7722 switch (param->cmd) {
7724 case IEEE_CMD_SET_WPA_PARAM:
7725 ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
7728 case IEEE_CMD_SET_WPA_IE:
7729 //ret = wpa_set_wpa_ie(dev, param, p->length);
7730 ret = rtw_set_wpa_ie((_adapter *)rtw_netdev_priv(dev), (char*)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
7733 case IEEE_CMD_SET_ENCRYPTION:
7734 ret = wpa_set_encryption(dev, param, p->length);
7738 ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
7742 DBG_871X("Unknown WPA supplicant request: %d\n", param->cmd);
7748 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
7751 rtw_mfree((u8 *)param, p->length);
7755 //up(&ieee->wx_sem);
7761 #ifdef CONFIG_AP_MODE
7762 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
7765 u32 wep_key_idx, wep_key_len,wep_total_len;
7766 NDIS_802_11_WEP *pwep = NULL;
7767 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
7768 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7769 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7770 struct security_priv* psecuritypriv=&(padapter->securitypriv);
7771 struct sta_priv *pstapriv = &padapter->stapriv;
7773 DBG_871X("%s\n", __FUNCTION__);
7775 param->u.crypt.err = 0;
7776 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
7778 //sizeof(struct ieee_param) = 64 bytes;
7779 //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
7780 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len)
7786 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7787 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7788 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7790 if (param->u.crypt.idx >= WEP_KEYS)
7798 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7802 DBG_871X("rtw_set_encryption(), sta has already been removed or never been added\n");
7807 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
7809 //todo:clear default encryption keys
7811 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
7812 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
7813 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
7814 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
7816 DBG_871X("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
7822 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
7824 DBG_871X("r871x_set_encryption, crypt.alg = WEP\n");
7826 wep_key_idx = param->u.crypt.idx;
7827 wep_key_len = param->u.crypt.key_len;
7829 DBG_871X("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
7831 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
7838 if (wep_key_len > 0)
7840 wep_key_len = wep_key_len <= 5 ? 5 : 13;
7841 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
7842 pwep =(NDIS_802_11_WEP *)rtw_malloc(wep_total_len);
7844 DBG_871X(" r871x_set_encryption: pwep allocate fail !!!\n");
7848 _rtw_memset(pwep, 0, wep_total_len);
7850 pwep->KeyLength = wep_key_len;
7851 pwep->Length = wep_total_len;
7855 pwep->KeyIndex = wep_key_idx;
7857 _rtw_memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
7859 if(param->u.crypt.set_tx)
7861 DBG_871X("wep, set_tx=1\n");
7863 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
7864 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
7865 psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
7866 psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
7868 if(pwep->KeyLength==13)
7870 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
7871 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
7875 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
7877 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
7879 psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength;
7881 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1);
7885 DBG_871X("wep, set_tx=0\n");
7887 //don't update "psecuritypriv->dot11PrivacyAlgrthm" and
7888 //"psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to cam
7890 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
7892 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
7894 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0);
7902 if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
7904 if(param->u.crypt.set_tx ==1)
7906 if(strcmp(param->u.crypt.alg, "WEP") == 0)
7908 DBG_871X("%s, set group_key, WEP\n", __FUNCTION__);
7910 _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));
7912 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
7913 if(param->u.crypt.key_len==13)
7915 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
7919 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
7921 DBG_871X("%s, set group_key, TKIP\n", __FUNCTION__);
7923 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
7925 _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 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
7929 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
7930 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
7932 psecuritypriv->busetkipkey = _TRUE;
7935 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
7937 DBG_871X("%s, set group_key, CCMP\n", __FUNCTION__);
7939 psecuritypriv->dot118021XGrpPrivacy = _AES_;
7941 _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));
7945 DBG_871X("%s, set group_key, none\n", __FUNCTION__);
7947 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
7950 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
7952 psecuritypriv->binstallGrpkey = _TRUE;
7954 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
7956 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
7958 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
7961 pbcmc_sta->ieee8021x_blocked = _FALSE;
7962 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
7971 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
7973 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
7975 if(param->u.crypt.set_tx ==1)
7977 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
7979 if(strcmp(param->u.crypt.alg, "WEP") == 0)
7981 DBG_871X("%s, set pairwise key, WEP\n", __FUNCTION__);
7983 psta->dot118021XPrivacy = _WEP40_;
7984 if(param->u.crypt.key_len==13)
7986 psta->dot118021XPrivacy = _WEP104_;
7989 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
7991 DBG_871X("%s, set pairwise key, TKIP\n", __FUNCTION__);
7993 psta->dot118021XPrivacy = _TKIP_;
7995 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
7997 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
7998 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
8000 psecuritypriv->busetkipkey = _TRUE;
8003 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
8006 DBG_871X("%s, set pairwise key, CCMP\n", __FUNCTION__);
8008 psta->dot118021XPrivacy = _AES_;
8012 DBG_871X("%s, set pairwise key, none\n", __FUNCTION__);
8014 psta->dot118021XPrivacy = _NO_PRIVACY_;
8017 rtw_ap_set_pairwise_key(padapter, psta);
8019 psta->ieee8021x_blocked = _FALSE;
8024 if(strcmp(param->u.crypt.alg, "WEP") == 0)
8026 _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));
8028 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
8029 if(param->u.crypt.key_len==13)
8031 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
8034 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
8036 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
8038 _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));
8040 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
8042 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
8043 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
8045 psecuritypriv->busetkipkey = _TRUE;
8048 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
8050 psecuritypriv->dot118021XGrpPrivacy = _AES_;
8052 _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));
8056 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
8059 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
8061 psecuritypriv->binstallGrpkey = _TRUE;
8063 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
8065 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
8067 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
8070 pbcmc_sta->ieee8021x_blocked = _FALSE;
8071 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
8084 rtw_mfree((u8 *)pwep, wep_total_len);
8091 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
8094 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8095 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8096 struct sta_priv *pstapriv = &padapter->stapriv;
8097 unsigned char *pbuf = param->u.bcn_ie.buf;
8100 DBG_871X("%s, len=%d\n", __FUNCTION__, len);
8102 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8105 _rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
8107 if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
8108 pstapriv->max_num_sta = NUM_STA;
8111 if(rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS)// 12 = param header, 2:no packed
8121 static int rtw_hostapd_sta_flush(struct net_device *dev)
8124 //_list *phead, *plist;
8126 //struct sta_info *psta = NULL;
8127 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8128 //struct sta_priv *pstapriv = &padapter->stapriv;
8130 DBG_871X("%s\n", __FUNCTION__);
8132 flush_all_cam_entry(padapter); //clear CAM
8134 ret = rtw_sta_flush(padapter);
8140 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
8144 struct sta_info *psta = NULL;
8145 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8146 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8147 struct sta_priv *pstapriv = &padapter->stapriv;
8149 DBG_871X("rtw_add_sta(aid=%d)=" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr));
8151 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
8156 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8157 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8158 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
8164 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8167 DBG_871X("rtw_add_sta(), free has been added psta=%p\n", psta);
8168 _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
8169 rtw_free_stainfo(padapter, psta);
8170 _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
8175 //psta = rtw_alloc_stainfo(pstapriv, param->sta_addr);
8176 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8179 int flags = param->u.add_sta.flags;
8181 //DBG_871X("rtw_add_sta(), init sta's variables, psta=%p\n", psta);
8183 psta->aid = param->u.add_sta.aid;//aid=1~2007
8185 _rtw_memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
8189 if(WLAN_STA_WME&flags)
8190 psta->qos_option = 1;
8192 psta->qos_option = 0;
8194 if(pmlmepriv->qospriv.qos_option == 0)
8195 psta->qos_option = 0;
8198 #ifdef CONFIG_80211N_HT
8199 //chec 802.11n ht cap.
8200 if(WLAN_STA_HT&flags)
8202 psta->htpriv.ht_option = _TRUE;
8203 psta->qos_option = 1;
8204 _rtw_memcpy((void*)&psta->htpriv.ht_cap, (void*)¶m->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
8208 psta->htpriv.ht_option = _FALSE;
8211 if(pmlmepriv->htpriv.ht_option == _FALSE)
8212 psta->htpriv.ht_option = _FALSE;
8216 update_sta_info_apmode(padapter, psta);
8229 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
8233 struct sta_info *psta = NULL;
8234 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8235 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8236 struct sta_priv *pstapriv = &padapter->stapriv;
8238 DBG_871X("rtw_del_sta=" MAC_FMT "\n", MAC_ARG(param->sta_addr));
8240 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
8245 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8246 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8247 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
8252 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8257 //DBG_871X("free psta=%p, aid=%d\n", psta, psta->aid);
8259 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
8260 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
8262 rtw_list_delete(&psta->asoc_list);
8263 pstapriv->asoc_list_cnt--;
8264 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
8267 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
8269 associated_clients_update(padapter, updated);
8276 DBG_871X("rtw_del_sta(), sta has already been removed or never been added\n");
8286 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
8289 struct sta_info *psta = NULL;
8290 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8291 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8292 struct sta_priv *pstapriv = &padapter->stapriv;
8293 struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
8294 struct sta_data *psta_data = (struct sta_data *)param_ex->data;
8296 DBG_871X("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr));
8298 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
8303 if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
8304 param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
8305 param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff)
8310 psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
8319 u8 tx_supp_rates[16];
8320 u32 tx_supp_rates_len;
8321 struct rtw_ieee80211_ht_cap ht_cap;
8330 psta_data->aid = (u16)psta->aid;
8331 psta_data->capability = psta->capability;
8332 psta_data->flags = psta->flags;
8336 no_short_slot_time_set : BIT(1)
8337 no_short_preamble_set : BIT(2)
8338 no_ht_gf_set : BIT(3)
8340 ht_20mhz_set : BIT(5)
8343 psta_data->sta_set =((psta->nonerp_set) |
8344 (psta->no_short_slot_time_set <<1) |
8345 (psta->no_short_preamble_set <<2) |
8346 (psta->no_ht_gf_set <<3) |
8347 (psta->no_ht_set <<4) |
8348 (psta->ht_20mhz_set <<5));
8350 psta_data->tx_supp_rates_len = psta->bssratelen;
8351 _rtw_memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
8352 #ifdef CONFIG_80211N_HT
8353 _rtw_memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
8354 #endif //CONFIG_80211N_HT
8355 psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
8356 psta_data->rx_bytes = psta->sta_stats.rx_bytes;
8357 psta_data->rx_drops = psta->sta_stats.rx_drops;
8359 psta_data->tx_pkts = psta->sta_stats.tx_pkts;
8360 psta_data->tx_bytes = psta->sta_stats.tx_bytes;
8361 psta_data->tx_drops = psta->sta_stats.tx_drops;
8374 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
8377 struct sta_info *psta = NULL;
8378 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8379 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8380 struct sta_priv *pstapriv = &padapter->stapriv;
8382 DBG_871X("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr));
8384 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
8389 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8390 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8391 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
8396 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8399 if((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC))
8404 wpa_ie_len = psta->wpa_ie[1];
8406 copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)):(wpa_ie_len+2);
8408 param->u.wpa_ie.len = copy_len;
8410 _rtw_memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
8415 DBG_871X("sta's wpa_ie is NONE\n");
8427 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
8430 unsigned char wps_oui[4]={0x0,0x50,0xf2,0x04};
8431 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8432 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8433 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8434 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8437 DBG_871X("%s, len=%d\n", __FUNCTION__, len);
8439 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8442 ie_len = len-12-2;// 12 = param header, 2:no packed
8445 if(pmlmepriv->wps_beacon_ie)
8447 rtw_mfree(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
8448 pmlmepriv->wps_beacon_ie = NULL;
8453 pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
8454 pmlmepriv->wps_beacon_ie_len = ie_len;
8455 if ( pmlmepriv->wps_beacon_ie == NULL) {
8456 DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8460 _rtw_memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
8462 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
8464 pmlmeext->bstart_bss = _TRUE;
8473 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
8476 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8477 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8480 DBG_871X("%s, len=%d\n", __FUNCTION__, len);
8482 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8485 ie_len = len-12-2;// 12 = param header, 2:no packed
8488 if(pmlmepriv->wps_probe_resp_ie)
8490 rtw_mfree(pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
8491 pmlmepriv->wps_probe_resp_ie = NULL;
8496 pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
8497 pmlmepriv->wps_probe_resp_ie_len = ie_len;
8498 if ( pmlmepriv->wps_probe_resp_ie == NULL) {
8499 DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8502 _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
8510 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
8513 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8514 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8517 DBG_871X("%s, len=%d\n", __FUNCTION__, len);
8519 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8522 ie_len = len-12-2;// 12 = param header, 2:no packed
8525 if(pmlmepriv->wps_assoc_resp_ie)
8527 rtw_mfree(pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
8528 pmlmepriv->wps_assoc_resp_ie = NULL;
8533 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
8534 pmlmepriv->wps_assoc_resp_ie_len = ie_len;
8535 if ( pmlmepriv->wps_assoc_resp_ie == NULL) {
8536 DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8540 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
8548 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
8551 _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8552 struct mlme_priv *mlmepriv = &(adapter->mlmepriv);
8553 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
8554 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
8557 char ssid[NDIS_802_11_LENGTH_SSID + 1];
8559 u8 ignore_broadcast_ssid;
8561 if(check_fwstate(mlmepriv, WIFI_AP_STATE) != _TRUE)
8564 if (param->u.bcn_ie.reserved[0] != 0xea)
8567 mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];
8569 ie_len = len-12-2;// 12 = param header, 2:no packed
8570 ssid_ie = rtw_get_ie(param->u.bcn_ie.buf, WLAN_EID_SSID, &ssid_len, ie_len);
8572 if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) {
8573 WLAN_BSSID_EX *pbss_network = &mlmepriv->cur_network.network;
8574 WLAN_BSSID_EX *pbss_network_ext = &mlmeinfo->network;
8576 _rtw_memcpy(ssid, ssid_ie+2, ssid_len);
8577 ssid[ssid_len] = 0x0;
8580 DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
8582 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
8583 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
8585 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len);
8586 pbss_network->Ssid.SsidLength = ssid_len;
8587 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len);
8588 pbss_network_ext->Ssid.SsidLength = ssid_len;
8591 DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
8592 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
8593 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
8596 DBG_871X(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter),
8597 ignore_broadcast_ssid, ssid, ssid_len);
8602 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
8605 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8606 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8608 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8611 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8612 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8613 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
8618 ret = rtw_acl_remove_sta(padapter, param->sta_addr);
8624 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
8627 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8628 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8630 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8633 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8634 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8635 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
8640 ret = rtw_acl_add_sta(padapter, param->sta_addr);
8646 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
8649 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8650 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8652 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8655 rtw_set_macaddr_acl(padapter, param->u.mlme.command);
8660 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
8662 struct ieee_param *param;
8664 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8666 //DBG_871X("%s\n", __FUNCTION__);
8669 * this function is expect to call in master mode, which allows no power saving
8670 * so, we just check hw_init_completed
8673 if (padapter->hw_init_completed==_FALSE){
8679 //if (p->length < sizeof(struct ieee_param) || !p->pointer){
8685 param = (struct ieee_param *)rtw_malloc(p->length);
8692 if (copy_from_user(param, p->pointer, p->length))
8694 rtw_mfree((u8*)param, p->length);
8699 //DBG_871X("%s, cmd=%d\n", __FUNCTION__, param->cmd);
8703 case RTL871X_HOSTAPD_FLUSH:
8705 ret = rtw_hostapd_sta_flush(dev);
8709 case RTL871X_HOSTAPD_ADD_STA:
8711 ret = rtw_add_sta(dev, param);
8715 case RTL871X_HOSTAPD_REMOVE_STA:
8717 ret = rtw_del_sta(dev, param);
8721 case RTL871X_HOSTAPD_SET_BEACON:
8723 ret = rtw_set_beacon(dev, param, p->length);
8727 case RTL871X_SET_ENCRYPTION:
8729 ret = rtw_set_encryption(dev, param, p->length);
8733 case RTL871X_HOSTAPD_GET_WPAIE_STA:
8735 ret = rtw_get_sta_wpaie(dev, param);
8739 case RTL871X_HOSTAPD_SET_WPS_BEACON:
8741 ret = rtw_set_wps_beacon(dev, param, p->length);
8745 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
8747 ret = rtw_set_wps_probe_resp(dev, param, p->length);
8751 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
8753 ret = rtw_set_wps_assoc_resp(dev, param, p->length);
8757 case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
8759 ret = rtw_set_hidden_ssid(dev, param, p->length);
8763 case RTL871X_HOSTAPD_GET_INFO_STA:
8765 ret = rtw_ioctl_get_sta_data(dev, param, p->length);
8769 case RTL871X_HOSTAPD_SET_MACADDR_ACL:
8771 ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
8775 case RTL871X_HOSTAPD_ACL_ADD_STA:
8777 ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
8781 case RTL871X_HOSTAPD_ACL_REMOVE_STA:
8783 ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
8788 DBG_871X("Unknown hostapd request: %d\n", param->cmd);
8794 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
8798 rtw_mfree((u8 *)param, p->length);
8807 static int rtw_wx_set_priv(struct net_device *dev,
8808 struct iw_request_info *info,
8809 union iwreq_data *awrq,
8813 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8822 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8823 struct iw_point *dwrq = (struct iw_point*)awrq;
8825 //RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, ("+rtw_wx_set_priv\n"));
8826 if(dwrq->length == 0)
8830 if (!(ext = rtw_vmalloc(len)))
8833 if (copy_from_user(ext, dwrq->pointer, len)) {
8834 rtw_vmfree(ext, len);
8839 //RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_,
8840 // ("rtw_wx_set_priv: %s req=%s\n",
8841 // dev->name, ext));
8843 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8844 if (!(ext_dbg = rtw_vmalloc(len)))
8846 rtw_vmfree(ext, len);
8850 _rtw_memcpy(ext_dbg, ext, len);
8853 //added for wps2.0 @20110524
8854 if(dwrq->flags == 0x8766 && len > 8)
8857 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8858 u8 *probereq_wpsie = ext;
8859 int probereq_wpsie_len = len;
8860 u8 wps_oui[4]={0x0,0x50,0xf2,0x04};
8862 if((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
8863 (_rtw_memcmp(&probereq_wpsie[2], wps_oui, 4) ==_TRUE))
8865 cp_sz = probereq_wpsie_len>MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN:probereq_wpsie_len;
8867 if(pmlmepriv->wps_probe_req_ie)
8869 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
8870 pmlmepriv->wps_probe_req_ie_len = 0;
8871 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
8872 pmlmepriv->wps_probe_req_ie = NULL;
8875 pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
8876 if ( pmlmepriv->wps_probe_req_ie == NULL) {
8877 printk("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8883 _rtw_memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
8884 pmlmepriv->wps_probe_req_ie_len = cp_sz;
8892 if( len >= WEXT_CSCAN_HEADER_SIZE
8893 && _rtw_memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
8895 ret = rtw_wx_set_scan(dev, info, awrq, ext);
8899 #ifdef CONFIG_ANDROID
8900 //DBG_871X("rtw_wx_set_priv: %s req=%s\n", dev->name, ext);
8902 i = rtw_android_cmdstr_to_num(ext);
8905 case ANDROID_WIFI_CMD_START :
8906 indicate_wx_custom_event(padapter, "START");
8908 case ANDROID_WIFI_CMD_STOP :
8909 indicate_wx_custom_event(padapter, "STOP");
8911 case ANDROID_WIFI_CMD_RSSI :
8913 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8914 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
8916 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
8917 sprintf(ext, "%s rssi %d", pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi);
8923 case ANDROID_WIFI_CMD_LINKSPEED :
8925 u16 mbps = rtw_get_cur_max_rate(padapter)/10;
8926 sprintf(ext, "LINKSPEED %d", mbps);
8929 case ANDROID_WIFI_CMD_MACADDR :
8930 sprintf(ext, "MACADDR = " MAC_FMT, MAC_ARG(dev->dev_addr));
8932 case ANDROID_WIFI_CMD_SCAN_ACTIVE :
8934 //rtw_set_scan_mode(padapter, SCAN_ACTIVE);
8938 case ANDROID_WIFI_CMD_SCAN_PASSIVE :
8940 //rtw_set_scan_mode(padapter, SCAN_PASSIVE);
8945 case ANDROID_WIFI_CMD_COUNTRY :
8947 char country_code[10];
8948 sscanf(ext, "%*s %s", country_code);
8949 rtw_set_country(padapter, country_code);
8954 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8955 DBG_871X("%s: %s unknowned req=%s\n", __FUNCTION__,
8956 dev->name, ext_dbg);
8963 if (copy_to_user(dwrq->pointer, ext, min(dwrq->length, (u16)(strlen(ext)+1)) ) )
8966 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8967 DBG_871X("%s: %s req=%s rep=%s dwrq->length=%d, strlen(ext)+1=%d\n", __FUNCTION__,
8968 dev->name, ext_dbg ,ext, dwrq->length, (u16)(strlen(ext)+1));
8970 #endif //end of CONFIG_ANDROID
8975 rtw_vmfree(ext, len);
8976 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8977 rtw_vmfree(ext_dbg, len);
8980 //DBG_871X("rtw_wx_set_priv: (SIOCSIWPRIV) %s ret=%d\n",
8986 #ifdef CONFIG_WOWLAN
8987 static int rtw_wowlan_ctrl(struct net_device *dev,
8988 struct iw_request_info *info,
8989 union iwreq_data *wrqu, char *extra)
8991 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8992 struct wowlan_ioctl_param poidparam;
8993 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
8994 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8995 struct net_device *pnetdev = padapter->pnetdev;
8996 #ifdef CONFIG_CONCURRENT_MODE
8997 struct net_device *pbuddy_netdev = padapter->pbuddy_adapter->pnetdev;
8999 struct sta_info *psta = NULL;
9001 u32 start_time = rtw_get_current_time();
9002 poidparam.subcode = 0;
9004 DBG_871X("+rtw_wowlan_ctrl: %s\n", extra);
9006 if(pwrctrlpriv->bSupportRemoteWakeup==_FALSE){
9008 DBG_871X("+rtw_wowlan_ctrl: Device didn't support the remote wakeup!!\n");
9009 goto _rtw_wowlan_ctrl_exit_free;
9012 if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
9013 check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
9014 DBG_871X("[%s] WARNING: Please Connect With AP First!!\n", __func__);
9015 goto _rtw_wowlan_ctrl_exit_free;
9018 if (_rtw_memcmp( extra, "enable", 6 )) {
9020 padapter->registrypriv.mp_mode = 1;
9022 while (pwrctrlpriv->bips_processing == _TRUE)
9025 rtw_ps_deny(padapter, PS_DENY_SUSPEND);
9027 rtw_cancel_all_timer(padapter);
9029 #ifdef CONFIG_CONCURRENT_MODE
9030 if (padapter->pbuddy_adapter){
9031 rtw_cancel_all_timer(padapter->pbuddy_adapter);
9033 #endif // CONFIG_CONCURRENT_MODE
9035 LeaveAllPowerSaveModeDirect(padapter);
9037 rtw_stop_cmd_thread(padapter);
9039 rtw_ps_deny_cancel(padapter, PS_DENY_SUSPEND);
9041 rtw_suspend_wow(padapter);
9043 } else if (_rtw_memcmp( extra, "disable", 6 )) {
9044 rtw_resume_process_wow(padapter);
9045 padapter->registrypriv.mp_mode = 0;
9047 DBG_871X("[%s] Invalid Parameter.\n", __func__);
9048 goto _rtw_wowlan_ctrl_exit_free;
9050 //mutex_lock(&ioctl_mutex);
9051 _rtw_wowlan_ctrl_exit_free:
9052 DBG_871X("-rtw_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);
9053 DBG_871X_LEVEL(_drv_always_, "%s in %d ms\n", __func__,
9054 rtw_get_passing_time_ms(start_time));
9055 _rtw_wowlan_ctrl_exit:
9058 #endif //CONFIG_WOWLAN
9060 #ifdef CONFIG_AP_WOWLAN
9061 static int rtw_ap_wowlan_ctrl(struct net_device *dev,
9062 struct iw_request_info *info,
9063 union iwreq_data *wrqu, char *extra)
9065 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
9066 struct wowlan_ioctl_param poidparam;
9067 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
9068 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9069 struct sta_info *psta = NULL;
9071 u32 start_time = rtw_get_current_time();
9072 poidparam.subcode = 0;
9074 DBG_871X("+rtw_ap_wowlan_ctrl: %s\n", extra);
9076 if(pwrctrlpriv->bSupportRemoteWakeup==_FALSE){
9078 DBG_871X("+rtw_wowlan_ctrl: Device didn't support the remote wakeup!!\n");
9079 goto _rtw_ap_wowlan_ctrl_exit_free;
9082 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
9083 DBG_871X("[%s] It is not AP mode!!\n", __func__);
9084 goto _rtw_ap_wowlan_ctrl_exit_free;
9087 if (_rtw_memcmp( extra, "enable", 6 )) {
9088 pwrctrlpriv->wowlan_ap_mode = _TRUE;
9089 while (pwrctrlpriv->bips_processing == _TRUE)
9092 rtw_cancel_all_timer(padapter);
9094 padapter->bDriverStopped = _TRUE; //for stop thread
9095 rtw_stop_drv_threads(padapter);
9096 padapter->bDriverStopped = _FALSE; //for 32k command
9099 LeaveAllPowerSaveModeDirect(padapter);
9101 rtw_hal_disable_interrupt(padapter); // It need wait for leaving 32K.
9103 // 2.1 clean interupt
9104 if (padapter->HalFunc.clear_interrupt)
9105 padapter->HalFunc.clear_interrupt(padapter);
9107 poidparam.subcode = WOWLAN_AP_ENABLE;
9109 rtw_hal_set_hwreg(padapter, HW_VAR_AP_WOWLAN,(u8 *)&poidparam);
9110 } else if (_rtw_memcmp( extra, "disable", 6 )) {
9112 LeaveAllPowerSaveModeDirect(padapter);
9114 pwrctrlpriv->bFwCurrentInPSMode = _FALSE;
9116 rtw_hal_disable_interrupt(padapter);
9118 if (padapter->HalFunc.clear_interrupt)
9119 padapter->HalFunc.clear_interrupt(padapter);
9121 poidparam.subcode = WOWLAN_AP_ENABLE;
9123 rtw_hal_set_hwreg(padapter, HW_VAR_AP_WOWLAN,(u8 *)&poidparam);
9125 pwrctrlpriv->wowlan_ap_mode = _FALSE;
9127 psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
9129 set_sta_rate(padapter, psta);
9132 padapter->bDriverStopped = _FALSE;
9133 DBG_871X("%s: wowmode resuming, DriverStopped:%d\n", __func__, padapter->bDriverStopped);
9134 rtw_start_drv_threads(padapter);
9136 rtw_hal_enable_interrupt(padapter);
9138 _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000);
9139 pwrctrlpriv->bips_processing = _FALSE;
9140 rtw_set_pwr_state_check_timer(pwrctrlpriv);
9143 DBG_871X("[%s] Invalid Parameter.\n", __func__);
9144 goto _rtw_ap_wowlan_ctrl_exit_free;
9146 //mutex_lock(&ioctl_mutex);
9147 _rtw_ap_wowlan_ctrl_exit_free:
9148 DBG_871X("-rtw_ap_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);
9149 DBG_871X_LEVEL(_drv_always_, "%s in %d ms\n", __func__,
9150 rtw_get_passing_time_ms(start_time));
9151 _rtw_ap_wowlan_ctrl_exit:
9154 #endif //CONFIG_AP_WOWLAN
9156 static int rtw_pm_set(struct net_device *dev,
9157 struct iw_request_info *info,
9158 union iwreq_data *wrqu, char *extra)
9162 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
9164 DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra );
9166 if ( _rtw_memcmp( extra, "lps=", 4 ) )
9168 sscanf(extra+4, "%u", &mode);
9169 ret = rtw_pm_set_lps(padapter,mode);
9171 else if ( _rtw_memcmp( extra, "ips=", 4 ) )
9173 sscanf(extra+4, "%u", &mode);
9174 ret = rtw_pm_set_ips(padapter,mode);
9183 static int rtw_mp_efuse_get(struct net_device *dev,
9184 struct iw_request_info *info,
9185 union iwreq_data *wdata, char *extra)
9187 PADAPTER padapter = rtw_netdev_priv(dev);
9188 EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
9189 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
9190 PEFUSE_HAL pEfuseHal;
9191 struct iw_point *wrqu;
9193 u8 *PROMContent = pEEPROM->efuse_eeprom_data;
9194 u8 ips_mode = IPS_NUM; // init invalid value
9195 u8 lps_mode = PS_MODE_NUM; // init invalid value
9196 struct pwrctrl_priv *pwrctrlpriv ;
9199 char *pch, *ptmp, *token, *tmp[3]={0x00,0x00,0x00};
9200 u16 i=0, j=0, mapLen=0, addr=0, cnts=0;
9201 u16 max_available_size=0, raw_cursize=0, raw_maxsize=0;
9204 u8 org_fw_iol = padapter->registrypriv.fw_iol;// 0:Disable, 1:enable, 2:by usb speed
9207 wrqu = (struct iw_point*)wdata;
9208 pwrctrlpriv = adapter_to_pwrctl(padapter);
9209 pEfuseHal = &pHalData->EfuseHal;
9212 data = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
9218 rawdata = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
9219 if (rawdata == NULL)
9225 if (copy_from_user(extra, wrqu->pointer, wrqu->length))
9231 lps_mode = pwrctrlpriv->power_mgnt;//keep org value
9232 rtw_pm_set_lps(padapter,PS_MODE_ACTIVE);
9236 ips_mode = pwrctrlpriv->ips_mode;//keep org value
9237 rtw_pm_set_ips(padapter,IPS_NONE);
9241 DBG_871X("%s: in=%s\n", __FUNCTION__, extra);
9244 //mac 16 "00e04c871200" rmap,00,2
9245 while ((token = strsep(&pch, ",")) != NULL)
9252 padapter->registrypriv.fw_iol = 0;// 0:Disable, 1:enable, 2:by usb speed
9255 if(strcmp(tmp[0], "status") == 0){
9256 sprintf(extra, "Load File efuse=%s,Load File MAC=%s",(pEEPROM->bloadfile_fail_flag? "FAIL" : "OK"),(pEEPROM->bloadmac_fail_flag? "FAIL" : "OK"));
9260 else if (strcmp(tmp[0], "drvmap") == 0)
9262 mapLen = EFUSE_MAP_SIZE;
9264 sprintf(extra, "\n");
9265 for (i = 0; i < EFUSE_MAP_SIZE; i += 16)
9267 // DBG_871X("0x%02x\t", i);
9268 sprintf(extra, "%s0x%02x\t", extra, i);
9269 for (j=0; j<8; j++) {
9270 // DBG_871X("%02X ", data[i+j]);
9271 sprintf(extra, "%s%02X ", extra, PROMContent[i+j]);
9274 sprintf(extra, "%s\t", extra);
9276 // DBG_871X("%02X ", data[i+j]);
9277 sprintf(extra, "%s%02X ", extra, PROMContent[i+j]);
9280 sprintf(extra,"%s\n",extra);
9284 else if (strcmp(tmp[0], "realmap") == 0)
9286 mapLen = EFUSE_MAP_SIZE;
9287 if (rtw_efuse_map_read(padapter, EFUSE_WIFI , mapLen, pEfuseHal->fakeEfuseInitMap) == _FAIL)
9289 DBG_871X("%s: read realmap Fail!!\n", __FUNCTION__);
9294 // DBG_871X("OFFSET\tVALUE(hex)\n");
9295 sprintf(extra, "\n");
9296 for (i = 0; i < EFUSE_MAP_SIZE; i += 16)
9298 // DBG_871X("0x%02x\t", i);
9299 sprintf(extra, "%s0x%02x\t", extra, i);
9300 for (j=0; j<8; j++) {
9301 // DBG_871X("%02X ", data[i+j]);
9302 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseInitMap[i+j]);
9305 sprintf(extra, "%s\t", extra);
9307 // DBG_871X("%02X ", data[i+j]);
9308 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseInitMap[i+j]);
9311 sprintf(extra,"%s\n",extra);
9315 else if (strcmp(tmp[0], "rmap") == 0)
9317 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9319 DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9325 addr = simple_strtoul(tmp[1], &ptmp, 16);
9326 DBG_871X("%s: addr=%x\n", __FUNCTION__, addr);
9328 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9331 DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9335 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9337 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (PVOID)&max_available_size, _FALSE);
9338 if ((addr+ cnts) > max_available_size)
9340 DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9345 if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL)
9347 DBG_871X("%s: rtw_efuse_map_read error!\n", __FUNCTION__);
9352 // DBG_871X("%s: data={", __FUNCTION__);
9354 for (i=0; i<cnts; i++) {
9355 // DBG_871X("0x%02x ", data[i]);
9356 sprintf(extra, "%s0x%02X ", extra, data[i]);
9360 else if (strcmp(tmp[0], "realraw") == 0)
9363 mapLen = EFUSE_MAX_SIZE;
9364 if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL)
9366 DBG_871X("%s: rtw_efuse_access Fail!!\n", __FUNCTION__);
9370 _rtw_memset(extra,'\0',strlen(extra));
9371 // DBG_871X("%s: realraw={\n", __FUNCTION__);
9372 sprintf(extra, "\n0x00\t");
9373 for (i=0; i< mapLen; i++)
9375 // DBG_871X("%02X", rawdata[i]);
9376 sprintf(extra, "%s%02X", extra, rawdata[i]);
9377 if ((i & 0xF) == 0xF) {
9379 sprintf(extra, "%s\n", extra);
9380 sprintf(extra, "%s0x%02x\t", extra, i+1);
9382 else if ((i & 0x7) == 0x7){
9384 sprintf(extra, "%s \t", extra);
9387 sprintf(extra, "%s ", extra);
9392 else if (strcmp(tmp[0], "mac") == 0)
9394 #ifdef CONFIG_RTL8192C
9395 addr = EEPROM_MAC_ADDR_92C;
9396 #endif // CONFIG_RTL8192C
9397 #ifdef CONFIG_RTL8192D
9398 #ifdef CONFIG_USB_HCI
9399 if (pHalData->interfaceIndex == 0)
9400 addr = EEPROM_MAC_ADDR_MAC0_92DU;
9402 addr = EEPROM_MAC_ADDR_MAC1_92DU;
9404 if (pHalData->interfaceIndex == 0)
9405 addr = EEPROM_MAC_ADDR_MAC0_92DE;
9407 addr = EEPROM_MAC_ADDR_MAC1_92DE;
9409 #endif // CONFIG_RTL8192D
9410 #ifdef CONFIG_RTL8723A
9411 #ifdef CONFIG_SDIO_HCI
9412 addr = EEPROM_MAC_ADDR_8723AS;
9414 #ifdef CONFIG_GSPI_HCI
9415 addr = EEPROM_MAC_ADDR_8723AS;
9417 #ifdef CONFIG_USB_HCI
9418 addr = EEPROM_MAC_ADDR_8723AU;
9420 #endif // CONFIG_RTL8723A
9421 #ifdef CONFIG_RTL8188E
9422 #ifdef CONFIG_USB_HCI
9423 addr = EEPROM_MAC_ADDR_88EU;
9425 #ifdef CONFIG_SDIO_HCI
9426 addr = EEPROM_MAC_ADDR_88ES;
9428 #ifdef CONFIG_PCI_HCI
9429 addr = EEPROM_MAC_ADDR_88EE;
9431 #endif // CONFIG_RTL8188E
9433 #ifdef CONFIG_RTL8192E
9434 #ifdef CONFIG_USB_HCI
9435 addr = EEPROM_MAC_ADDR_8192EU;
9437 #ifdef CONFIG_SDIO_HCI
9438 addr = EEPROM_MAC_ADDR_8192ES;
9440 #ifdef CONFIG_PCI_HCI
9441 addr = EEPROM_MAC_ADDR_8192EE;
9444 #ifdef CONFIG_RTL8723B
9445 #ifdef CONFIG_SDIO_HCI
9446 addr = EEPROM_MAC_ADDR_8723BS;
9448 #ifdef CONFIG_GSPI_HCI
9449 addr = EEPROM_MAC_ADDR_8723BS;
9451 #ifdef CONFIG_USB_HCI
9452 addr = EEPROM_MAC_ADDR_8723BU;
9454 #endif // CONFIG_RTL8723B
9457 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
9458 if ((addr + cnts) > max_available_size) {
9459 DBG_871X("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9464 if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL)
9466 DBG_871X("%s: rtw_efuse_map_read error!\n", __FUNCTION__);
9471 // DBG_871X("%s: MAC address={", __FUNCTION__);
9473 for (i=0; i<cnts; i++)
9475 // DBG_871X("%02X", data[i]);
9476 sprintf(extra, "%s%02X", extra, data[i]);
9480 sprintf(extra,"%s:",extra);
9485 else if (strcmp(tmp[0], "vidpid") == 0)
9487 #ifdef CONFIG_RTL8192C
9488 addr = EEPROM_VID_92C;
9489 #endif // CONFIG_RTL8192C
9490 #ifdef CONFIG_RTL8192D
9491 #ifdef CONFIG_USB_HCI
9492 addr = EEPROM_VID_92DU;
9494 addr = EEPROM_VID_92DE;
9496 #endif // CONFIG_RTL8192D
9497 #ifdef CONFIG_RTL8723A
9498 #ifdef CONFIG_USB_HCI
9499 addr = EEPROM_VID_8723AU;
9501 #endif // CONFIG_RTL8723A
9502 #ifdef CONFIG_RTL8188E
9503 #ifdef CONFIG_USB_HCI
9504 addr = EEPROM_VID_88EU;
9506 #ifdef CONFIG_PCI_HCI
9507 addr = EEPROM_VID_88EE;
9509 #endif // CONFIG_RTL8188E
9511 #ifdef CONFIG_RTL8192E
9512 #ifdef CONFIG_USB_HCI
9513 addr = EEPROM_VID_8192EU;
9515 #ifdef CONFIG_PCI_HCI
9516 addr = EEPROM_VID_8192EE;
9518 #endif // CONFIG_RTL8192E
9519 #ifdef CONFIG_RTL8723B
9520 addr = EEPROM_VID_8723BU;
9521 #endif // CONFIG_RTL8192E
9524 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
9525 if ((addr + cnts) > max_available_size)
9527 DBG_871X("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9531 if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL)
9533 DBG_871X("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9538 // DBG_871X("%s: {VID,PID}={", __FUNCTION__);
9540 for (i=0; i<cnts; i++)
9542 // DBG_871X("0x%02x", data[i]);
9543 sprintf(extra, "%s0x%02X", extra, data[i]);
9547 sprintf(extra,"%s,",extra);
9552 else if (strcmp(tmp[0], "ableraw") == 0)
9554 efuse_GetCurrentSize(padapter,&raw_cursize);
9555 raw_maxsize = efuse_GetMaxSize(padapter);
9556 sprintf(extra, "[available raw size]= %d bytes", raw_maxsize-raw_cursize);
9558 else if (strcmp(tmp[0], "btfmap") == 0)
9560 BTEfuse_PowerSwitch(padapter,1,_TRUE);
9562 mapLen = EFUSE_BT_MAX_MAP_LEN;
9563 if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL)
9565 DBG_871X("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
9570 // DBG_871X("OFFSET\tVALUE(hex)\n");
9571 sprintf(extra, "\n");
9572 for (i=0; i<512; i+=16) // set 512 because the iwpriv's extra size have limit 0x7FF
9574 // DBG_871X("0x%03x\t", i);
9575 sprintf(extra, "%s0x%03x\t", extra, i);
9576 for (j=0; j<8; j++) {
9577 // DBG_871X("%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
9578 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
9581 sprintf(extra,"%s\t",extra);
9583 // DBG_871X("%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
9584 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
9587 sprintf(extra, "%s\n", extra);
9591 else if (strcmp(tmp[0],"btbmap") == 0)
9593 BTEfuse_PowerSwitch(padapter,1,_TRUE);
9595 mapLen = EFUSE_BT_MAX_MAP_LEN;
9596 if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL)
9598 DBG_871X("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
9603 // DBG_871X("OFFSET\tVALUE(hex)\n");
9604 sprintf(extra, "\n");
9605 for (i=512; i<1024 ; i+=16)
9607 // DBG_871X("0x%03x\t", i);
9608 sprintf(extra, "%s0x%03x\t", extra, i);
9611 // DBG_871X("%02X ", data[i+j]);
9612 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
9615 sprintf(extra,"%s\t",extra);
9617 // DBG_871X("%02X ", data[i+j]);
9618 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
9621 sprintf(extra, "%s\n", extra);
9625 else if (strcmp(tmp[0],"btrmap") == 0)
9627 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9633 BTEfuse_PowerSwitch(padapter,1,_TRUE);
9636 addr = simple_strtoul(tmp[1], &ptmp, 16);
9637 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
9639 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9642 DBG_871X("%s: btrmap Fail!! cnts error!\n", __FUNCTION__);
9646 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9648 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
9649 if ((addr + cnts) > max_available_size)
9651 DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9656 if (rtw_BT_efuse_map_read(padapter, addr, cnts, data) == _FAIL)
9658 DBG_871X("%s: rtw_BT_efuse_map_read error!!\n", __FUNCTION__);
9664 // DBG_871X("%s: bt efuse data={", __FUNCTION__);
9665 for (i=0; i<cnts; i++)
9667 // DBG_871X("0x%02x ", data[i]);
9668 sprintf(extra, "%s 0x%02X ", extra, data[i]);
9671 DBG_871X(FUNC_ADPT_FMT ": BT MAC=[%s]\n", FUNC_ADPT_ARG(padapter), extra);
9673 else if (strcmp(tmp[0], "btffake") == 0)
9675 // DBG_871X("OFFSET\tVALUE(hex)\n");
9676 sprintf(extra, "\n");
9677 for (i=0; i<512; i+=16)
9679 // DBG_871X("0x%03x\t", i);
9680 sprintf(extra, "%s0x%03x\t", extra, i);
9681 for (j=0; j<8; j++) {
9682 // DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9683 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9686 sprintf(extra, "%s\t", extra);
9688 // DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9689 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9692 sprintf(extra, "%s\n", extra);
9696 else if (strcmp(tmp[0],"btbfake") == 0)
9698 // DBG_871X("OFFSET\tVALUE(hex)\n");
9699 sprintf(extra, "\n");
9700 for (i=512; i<1024; i+=16)
9702 // DBG_871X("0x%03x\t", i);
9703 sprintf(extra, "%s0x%03x\t", extra, i);
9704 for (j=0; j<8; j++) {
9705 // DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9706 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9709 sprintf(extra, "%s\t", extra);
9711 // DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9712 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9715 sprintf(extra, "%s\n", extra);
9719 else if (strcmp(tmp[0],"wlrfkmap")== 0)
9721 // DBG_871X("OFFSET\tVALUE(hex)\n");
9722 sprintf(extra, "\n");
9723 for (i=0; i<EFUSE_MAP_SIZE; i+=16)
9725 // DBG_871X("\t0x%02x\t", i);
9726 sprintf(extra, "%s0x%02x\t", extra, i);
9727 for (j=0; j<8; j++) {
9728 // DBG_871X("%02X ", pEfuseHal->fakeEfuseModifiedMap[i+j]);
9729 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseModifiedMap[i+j]);
9732 sprintf(extra, "%s\t", extra);
9734 // DBG_871X("%02X ", pEfuseHal->fakeEfuseModifiedMap[i+j]);
9735 sprintf(extra, "%s %02X", extra, pEfuseHal->fakeEfuseModifiedMap[i+j]);
9738 sprintf(extra, "%s\n", extra);
9743 else if (strcmp(tmp[0],"wlrfkrmap")== 0)
9745 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9747 DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9752 addr = simple_strtoul(tmp[1], &ptmp, 16);
9753 DBG_871X("%s: addr=%x\n", __FUNCTION__, addr);
9755 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9758 DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9762 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9764 // DBG_871X("%s: data={", __FUNCTION__);
9766 for (i=0; i<cnts; i++) {
9767 DBG_871X("wlrfkrmap = 0x%02x \n", pEfuseHal->fakeEfuseModifiedMap[addr+i]);
9768 sprintf(extra, "%s0x%02X ", extra, pEfuseHal->fakeEfuseModifiedMap[addr+i]);
9771 else if (strcmp(tmp[0],"btrfkrmap")== 0)
9773 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9775 DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9780 addr = simple_strtoul(tmp[1], &ptmp, 16);
9781 DBG_871X("%s: addr=%x\n", __FUNCTION__, addr);
9783 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9786 DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9790 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9792 // DBG_871X("%s: data={", __FUNCTION__);
9794 for (i=0; i<cnts; i++) {
9795 DBG_871X("wlrfkrmap = 0x%02x \n", pEfuseHal->fakeBTEfuseModifiedMap[addr+i]);
9796 sprintf(extra, "%s0x%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[addr+i]);
9801 sprintf(extra, "Command not found!");
9806 rtw_mfree(data, EFUSE_BT_MAX_MAP_LEN);
9808 rtw_mfree(rawdata, EFUSE_BT_MAX_MAP_LEN);
9810 wrqu->length = strlen(extra);
9812 if (padapter->registrypriv.mp_mode == 0)
9815 rtw_pm_set_ips(padapter, ips_mode);
9816 #endif // CONFIG_IPS
9819 rtw_pm_set_lps(padapter, lps_mode);
9820 #endif // CONFIG_LPS
9824 padapter->registrypriv.fw_iol = org_fw_iol;// 0:Disable, 1:enable, 2:by usb speed
9829 static int rtw_mp_efuse_set(struct net_device *dev,
9830 struct iw_request_info *info,
9831 union iwreq_data *wdata, char *extra)
9833 struct iw_point *wrqu;
9835 struct pwrctrl_priv *pwrctrlpriv ;
9836 PHAL_DATA_TYPE pHalData;
9837 PEFUSE_HAL pEfuseHal;
9839 u8 ips_mode = IPS_NUM; // init invalid value
9840 u8 lps_mode = PS_MODE_NUM; // init invalid value
9841 u32 i=0,j=0, jj, kk;
9843 u8 *ShadowMapBT = NULL;
9844 u8 *ShadowMapWiFi = NULL;
9845 u8 *setrawdata = NULL;
9846 char *pch, *ptmp, *token, *tmp[3]={0x00,0x00,0x00};
9847 u16 addr=0, cnts=0, BTStatus=0 , max_available_size=0;
9850 wrqu = (struct iw_point*)wdata;
9851 padapter = rtw_netdev_priv(dev);
9852 pwrctrlpriv = adapter_to_pwrctl(padapter);
9853 pHalData = GET_HAL_DATA(padapter);
9854 pEfuseHal = &pHalData->EfuseHal;
9857 if (copy_from_user(extra, wrqu->pointer, wrqu->length))
9860 setdata = rtw_zmalloc(1024);
9861 if (setdata == NULL)
9866 ShadowMapBT = rtw_malloc(EFUSE_BT_MAX_MAP_LEN);
9867 if (ShadowMapBT == NULL)
9872 ShadowMapWiFi = rtw_malloc(EFUSE_MAP_SIZE);
9873 if (ShadowMapWiFi == NULL)
9878 setrawdata = rtw_malloc(EFUSE_MAX_SIZE);
9879 if (setrawdata == NULL)
9886 lps_mode = pwrctrlpriv->power_mgnt;//keep org value
9887 rtw_pm_set_lps(padapter,PS_MODE_ACTIVE);
9891 ips_mode = pwrctrlpriv->ips_mode;//keep org value
9892 rtw_pm_set_ips(padapter,IPS_NONE);
9896 DBG_871X("%s: in=%s\n", __FUNCTION__, extra);
9899 while ((token = strsep(&pch, ",")) != NULL)
9907 // wmap,addr,00e04c871200
9908 if (strcmp(tmp[0], "wmap") == 0)
9910 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9917 // unknown bug workaround, need to fix later
9919 rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff));
9921 rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03));
9923 rtw_write8(padapter, EFUSE_CTRL+3, 0x72);
9925 rtw_read8(padapter, EFUSE_CTRL);
9928 addr = simple_strtoul(tmp[1], &ptmp, 16);
9931 cnts = strlen(tmp[2]);
9944 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
9945 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9946 DBG_871X("%s: map data=%s\n", __FUNCTION__, tmp[2]);
9948 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
9950 setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
9952 #ifndef CONFIG_RTL8188E
9953 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
9955 //Change to check TYPE_EFUSE_MAP_LEN ,beacuse 8188E raw 256,logic map over 256.
9956 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_size, _FALSE);
9958 if ((addr+cnts) > max_available_size)
9960 DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9965 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
9967 DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9972 DBG_871X("%s: after rtw_BT_efuse_map_write to _rtw_memcmp \n", __FUNCTION__);
9973 if ( (rtw_efuse_map_read(padapter, addr, cnts, ShadowMapWiFi) == _SUCCESS ) )
9975 if (_rtw_memcmp((void*)ShadowMapWiFi ,(void*)setdata,cnts))
9977 DBG_871X("%s: WiFi write map afterf compare success\n", __FUNCTION__);
9978 sprintf(extra, "WiFi write map compare OK\n");
9984 sprintf(extra, "WiFi write map compare FAIL\n");
9985 DBG_871X("%s: WiFi write map compare Fail\n", __FUNCTION__);
9991 else if (strcmp(tmp[0], "wraw") == 0)
9993 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9999 addr = simple_strtoul( tmp[1], &ptmp, 16 );
10002 cnts = strlen(tmp[2]);
10015 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10016 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10017 DBG_871X("%s: raw data=%s\n", __FUNCTION__, tmp[2]);
10019 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10021 setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
10024 if (rtw_efuse_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL)
10026 DBG_871X("%s: rtw_efuse_access error!!\n", __FUNCTION__);
10031 else if (strcmp(tmp[0], "mac") == 0)
10040 #ifdef CONFIG_RTL8192C
10041 addr = EEPROM_MAC_ADDR_92C;
10043 #ifdef CONFIG_RTL8192D
10044 #ifdef CONFIG_USB_HCI
10045 if (pHalData->interfaceIndex == 0)
10046 addr = EEPROM_MAC_ADDR_MAC0_92DU;
10048 addr = EEPROM_MAC_ADDR_MAC1_92DU;
10050 if (pHalData->interfaceIndex == 0)
10051 addr = EEPROM_MAC_ADDR_MAC0_92DE;
10053 addr = EEPROM_MAC_ADDR_MAC1_92DE;
10056 #ifdef CONFIG_RTL8723A
10057 #ifdef CONFIG_SDIO_HCI
10058 addr = EEPROM_MAC_ADDR_8723AS;
10060 #ifdef CONFIG_GSPI_HCI
10061 addr = EEPROM_MAC_ADDR_8723AS;
10063 #ifdef CONFIG_USB_HCI
10064 addr = EEPROM_MAC_ADDR_8723AU;
10066 #endif // CONFIG_RTL8723A
10067 #ifdef CONFIG_RTL8188E
10068 #ifdef CONFIG_USB_HCI
10069 addr = EEPROM_MAC_ADDR_88EU;
10071 #ifdef CONFIG_SDIO_HCI
10072 addr = EEPROM_MAC_ADDR_88ES;
10074 #ifdef CONFIG_PCI_HCI
10075 addr = EEPROM_MAC_ADDR_88EE;
10077 #endif //#ifdef CONFIG_RTL8188E
10079 #ifdef CONFIG_RTL8192E
10080 #ifdef CONFIG_USB_HCI
10081 addr = EEPROM_MAC_ADDR_8192EU;
10083 #ifdef CONFIG_SDIO_HCI
10084 addr = EEPROM_MAC_ADDR_8192ES;
10086 #ifdef CONFIG_PCI_HCI
10087 addr = EEPROM_MAC_ADDR_8192EE;
10089 #endif //#ifdef CONFIG_RTL8192E
10091 #ifdef CONFIG_RTL8723B
10092 #ifdef CONFIG_SDIO_HCI
10093 addr = EEPROM_MAC_ADDR_8723BS;
10095 #ifdef CONFIG_GSPI_HCI
10096 addr = EEPROM_MAC_ADDR_8723BS;
10098 #ifdef CONFIG_USB_HCI
10099 addr = EEPROM_MAC_ADDR_8723BU;
10101 #endif // CONFIG_RTL8723B
10103 cnts = strlen(tmp[1]);
10117 DBG_871X("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]);
10122 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10123 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10124 DBG_871X("%s: MAC address=%s\n", __FUNCTION__, tmp[1]);
10126 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10128 setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
10130 #ifndef CONFIG_RTL8188E
10131 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
10133 //Change to check TYPE_EFUSE_MAP_LEN ,beacuse 8188E raw 256,logic map over 256.
10134 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_size, _FALSE);
10136 if ((addr+cnts) > max_available_size)
10138 DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10143 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
10145 DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
10150 else if (strcmp(tmp[0], "vidpid") == 0)
10159 #ifdef CONFIG_RTL8192C
10160 addr = EEPROM_VID_92C;
10161 #endif // CONFIG_RTL8192C
10162 #ifdef CONFIG_RTL8192D
10163 #ifdef CONFIG_USB_HCI
10164 addr = EEPROM_VID_92DU;
10166 addr = EEPROM_VID_92DE;
10168 #endif // CONFIG_RTL8192D
10169 #ifdef CONFIG_RTL8723A
10170 #ifdef CONFIG_USB_HCI
10171 addr = EEPROM_VID_8723AU;
10173 #endif // CONFIG_RTL8723A
10174 #ifdef CONFIG_RTL8188E
10175 #ifdef CONFIG_USB_HCI
10176 addr = EEPROM_VID_88EU;
10178 #ifdef CONFIG_PCI_HCI
10179 addr = EEPROM_VID_88EE;
10181 #endif // CONFIG_RTL8188E
10183 #ifdef CONFIG_RTL8192E
10184 #ifdef CONFIG_USB_HCI
10185 addr = EEPROM_VID_8192EU;
10187 #ifdef CONFIG_PCI_HCI
10188 addr = EEPROM_VID_8192EE;
10190 #endif // CONFIG_RTL8188E
10192 #ifdef CONFIG_RTL8723B
10193 addr = EEPROM_VID_8723BU;
10196 cnts = strlen(tmp[1]);
10209 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10210 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10211 DBG_871X("%s: VID/PID=%s\n", __FUNCTION__, tmp[1]);
10213 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10215 setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
10218 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
10219 if ((addr+cnts) > max_available_size)
10221 DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10226 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
10228 DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
10233 else if (strcmp(tmp[0], "wldumpfake") == 0)
10235 if (rtw_efuse_map_read(padapter, 0, EFUSE_MAP_SIZE, pEfuseHal->fakeEfuseModifiedMap) == _SUCCESS) {
10236 DBG_871X("%s: WiFi hw efuse dump to Fake map success \n", __FUNCTION__);
10238 DBG_871X("%s: WiFi hw efuse dump to Fake map Fail \n", __FUNCTION__);
10242 else if (strcmp(tmp[0], "btwmap") == 0)
10244 rtw_write8(padapter, 0xa3, 0x05); //For 8723AB ,8821S ?
10245 BTStatus=rtw_read8(padapter, 0xa0);
10246 DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus);
10247 if (BTStatus != 0x04)
10249 sprintf(extra, "BT Status not Active Write FAIL\n");
10253 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10258 BTEfuse_PowerSwitch(padapter,1,_TRUE);
10261 rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff));
10263 rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03));
10265 rtw_write8(padapter, EFUSE_CTRL+3, 0x72);
10267 rtw_read8(padapter, EFUSE_CTRL);
10269 addr = simple_strtoul(tmp[1], &ptmp, 16);
10272 cnts = strlen(tmp[2]);
10285 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10286 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10287 DBG_871X("%s: BT data=%s\n", __FUNCTION__, tmp[2]);
10289 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10291 setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
10294 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
10295 if ((addr+cnts) > max_available_size)
10297 DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10302 if (rtw_BT_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
10304 DBG_871X("%s: rtw_BT_efuse_map_write error!!\n", __FUNCTION__);
10309 DBG_871X("%s: after rtw_BT_efuse_map_write to _rtw_memcmp \n", __FUNCTION__);
10310 if ( (rtw_BT_efuse_map_read(padapter, addr, cnts, ShadowMapBT ) == _SUCCESS ) )
10312 if (_rtw_memcmp((void*)ShadowMapBT ,(void*)setdata,cnts))
10314 DBG_871X("%s: BT write map compare OK BTStatus=0x%x\n", __FUNCTION__,BTStatus);
10315 sprintf(extra, "BT write map compare OK");
10321 sprintf(extra, "BT write map compare FAIL");
10322 DBG_871X("%s: BT write map compare FAIL BTStatus=0x%x\n", __FUNCTION__,BTStatus);
10328 else if (strcmp(tmp[0], "btwfake") == 0)
10330 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10336 addr = simple_strtoul(tmp[1], &ptmp, 16);
10339 cnts = strlen(tmp[2]);
10352 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10353 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10354 DBG_871X("%s: BT tmp data=%s\n", __FUNCTION__, tmp[2]);
10356 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10358 pEfuseHal->fakeBTEfuseModifiedMap[addr+jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
10361 else if (strcmp(tmp[0], "btdumpfake") == 0)
10363 if (rtw_BT_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _SUCCESS) {
10364 DBG_871X("%s: BT read all map success\n", __FUNCTION__);
10366 DBG_871X("%s: BT read all map Fail!\n", __FUNCTION__);
10370 else if (strcmp(tmp[0], "btfk2map") == 0)
10372 rtw_write8(padapter, 0xa3, 0x05);
10373 BTStatus=rtw_read8(padapter, 0xa0);
10374 DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus);
10375 if (BTStatus != 0x04)
10377 sprintf(extra, "BT Status not Active Write FAIL\n");
10381 BTEfuse_PowerSwitch(padapter,1,_TRUE);
10384 rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff));
10386 rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03));
10388 rtw_write8(padapter, EFUSE_CTRL+3, 0x72);
10390 rtw_read8(padapter, EFUSE_CTRL);
10392 _rtw_memcpy(pEfuseHal->BTEfuseModifiedMap, pEfuseHal->fakeBTEfuseModifiedMap, EFUSE_BT_MAX_MAP_LEN);
10394 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
10395 if (max_available_size < 1)
10401 if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL)
10403 DBG_871X("%s: rtw_BT_efuse_map_write error!\n", __FUNCTION__);
10408 DBG_871X("pEfuseHal->fakeBTEfuseModifiedMap OFFSET\tVALUE(hex)\n");
10409 for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16)
10411 printk("0x%02x\t", i);
10412 for (j=0; j<8; j++) {
10413 printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10417 for (; j<16; j++) {
10418 printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10425 DBG_871X("%s: rtw_BT_efuse_map_read _rtw_memcmp \n", __FUNCTION__);
10426 if ( (rtw_BT_efuse_map_read(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS ) )
10428 if (_rtw_memcmp((void*)pEfuseHal->fakeBTEfuseModifiedMap,(void*)pEfuseHal->fakeBTEfuseInitMap,EFUSE_BT_MAX_MAP_LEN))
10430 sprintf(extra, "BT write map compare OK");
10431 DBG_871X("%s: BT write map afterf compare success BTStatus=0x%x \n", __FUNCTION__,BTStatus);
10437 sprintf(extra, "BT write map compare FAIL");
10438 if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL)
10440 DBG_871X("%s: rtw_BT_efuse_map_write compare error,retry = %d!\n", __FUNCTION__,i);
10443 if (rtw_BT_efuse_map_read(padapter, EFUSE_BT, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS)
10445 DBG_871X("pEfuseHal->fakeBTEfuseInitMap OFFSET\tVALUE(hex)\n");
10447 for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16)
10449 printk("0x%02x\t", i);
10450 for (j=0; j<8; j++) {
10451 printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i+j]);
10454 for (; j<16; j++) {
10455 printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i+j]);
10461 DBG_871X("%s: BT write map afterf compare not match to write efuse try write Map again , BTStatus=0x%x\n", __FUNCTION__,BTStatus);
10468 else if (strcmp(tmp[0], "wlfk2map") == 0)
10470 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
10471 if (max_available_size < 1)
10476 if (rtw_efuse_map_write(padapter, 0x00, EFUSE_MAP_SIZE, pEfuseHal->fakeEfuseModifiedMap) == _FAIL)
10478 DBG_871X("%s: rtw_efuse_map_write fakeEfuseModifiedMap error!\n", __FUNCTION__);
10483 DBG_871X("%s: after rtw_BT_efuse_map_write to _rtw_memcmp \n", __FUNCTION__);
10484 if ( (rtw_efuse_map_read(padapter, 0x00, EFUSE_MAP_SIZE, ShadowMapWiFi) == _SUCCESS ) )
10486 if (_rtw_memcmp((void*)ShadowMapWiFi ,(void*)setdata,cnts))
10488 DBG_871X("%s: WiFi write map afterf compare OK\n", __FUNCTION__);
10489 sprintf(extra, "WiFi write map compare OK\n");
10495 sprintf(extra, "WiFi write map compare FAIL\n");
10496 DBG_871X("%s: WiFi write map compare Fail\n", __FUNCTION__);
10502 else if (strcmp(tmp[0], "wlwfake") == 0)
10504 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10510 addr = simple_strtoul(tmp[1], &ptmp, 16);
10513 cnts = strlen(tmp[2]);
10526 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10527 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10528 DBG_871X("%s: map tmp data=%s\n", __FUNCTION__, tmp[2]);
10530 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10532 pEfuseHal->fakeEfuseModifiedMap[addr+jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
10538 rtw_mfree(setdata, 1024);
10540 rtw_mfree(ShadowMapBT, EFUSE_BT_MAX_MAP_LEN);
10542 rtw_mfree(ShadowMapWiFi, EFUSE_MAP_SIZE);
10544 rtw_mfree(setrawdata, EFUSE_MAX_SIZE);
10546 wrqu->length = strlen(extra);
10548 if (padapter->registrypriv.mp_mode == 0)
10551 rtw_pm_set_ips(padapter, ips_mode);
10552 #endif // CONFIG_IPS
10555 rtw_pm_set_lps(padapter, lps_mode);
10556 #endif // CONFIG_LPS
10562 #if defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT)
10564 * Input Format: %s,%d,%d
10565 * %s is width, could be
10567 * "w" for WORD (2 bytes)
10568 * "dw" for DWORD (4 bytes)
10569 * 1st %d is address(offset)
10570 * 2st %d is data to write
10572 static int rtw_mp_write_reg(struct net_device *dev,
10573 struct iw_request_info *info,
10574 struct iw_point *wrqu, char *extra)
10576 char *pch, *pnext, *ptmp;
10581 PADAPTER padapter = rtw_netdev_priv(dev);
10582 char input[wrqu->length];
10584 if (copy_from_user(input, wrqu->pointer, wrqu->length))
10587 _rtw_memset(extra, 0, wrqu->length);
10591 pnext = strpbrk(pch, " ,.-");
10592 if (pnext == NULL) return -EINVAL;
10597 pnext = strpbrk(pch, " ,.-");
10598 if (pnext == NULL) return -EINVAL;
10600 addr = simple_strtoul(pch, &ptmp, 16);
10601 if (addr > 0x3FFF) return -EINVAL;
10604 if ((pch - extra) >= wrqu->length) return -EINVAL;
10605 data = simple_strtoul(pch, &ptmp, 16);
10608 width = width_str[0];
10616 rtw_write8(padapter, addr, data);
10620 if (data > 0xFFFF) {
10624 rtw_write16(padapter, addr, data);
10628 rtw_write32(padapter, addr, data);
10639 * Input Format: %s,%d
10640 * %s is width, could be
10642 * "w" for WORD (2 bytes)
10643 * "dw" for DWORD (4 bytes)
10644 * %d is address(offset)
10647 * %d for data readed
10649 static int rtw_mp_read_reg(struct net_device *dev,
10650 struct iw_request_info *info,
10651 struct iw_point *wrqu, char *extra)
10653 char input[wrqu->length];
10654 char *pch, *pnext, *ptmp;
10657 char data[20],tmp[20];
10659 //u32 *data = (u32*)extra;
10660 u32 ret, i=0, j=0, strtout=0;
10661 PADAPTER padapter = rtw_netdev_priv(dev);
10664 if (wrqu->length > 128)
10667 if (copy_from_user(input, wrqu->pointer, wrqu->length))
10670 _rtw_memset(data, 0, 20);
10671 _rtw_memset(tmp, 0, 20);
10672 _rtw_memset(extra, 0, wrqu->length);
10675 pnext = strpbrk(pch, " ,.-");
10676 if (pnext == NULL) return -EINVAL;
10681 if ((pch - input) >= wrqu->length) return -EINVAL;
10683 addr = simple_strtoul(pch, &ptmp, 16);
10684 if (addr > 0x3FFF) return -EINVAL;
10687 width = width_str[0];
10692 // *(u8*)data = rtw_read8(padapter, addr);
10693 sprintf(extra, "%d\n", rtw_read8(padapter, addr));
10694 wrqu->length = strlen(extra);
10698 //*(u16*)data = rtw_read16(padapter, addr);
10699 sprintf(data, "%04x\n", rtw_read16(padapter, addr));
10700 for( i=0 ; i <= strlen(data) ; i++)
10707 if ( data[i] != '\0' )
10713 DBG_871X("pch=%s",pch);
10715 while( *pch != '\0' )
10717 pnext = strpbrk(pch, " ");
10722 if ( *pnext != '\0' )
10724 strtout = simple_strtoul (pnext , &ptmp, 16);
10725 sprintf( extra, "%s %d" ,extra ,strtout );
10736 //*data = rtw_read32(padapter, addr);
10737 sprintf(data, "%08x", rtw_read32(padapter, addr));
10738 //add read data format blank
10739 for( i=0 ; i <= strlen(data) ; i++)
10746 if ( data[i] != '\0' )
10752 DBG_871X("pch=%s",pch);
10754 while( *pch != '\0' )
10756 pnext = strpbrk(pch, " ");
10761 if ( *pnext != '\0' )
10763 strtout = simple_strtoul (pnext , &ptmp, 16);
10764 sprintf( extra, "%s %d" ,extra ,strtout );
10771 wrqu->length = strlen(extra);
10785 * Input Format: %d,%x,%x
10786 * %d is RF path, should be smaller than MAX_RF_PATH_NUMS
10787 * 1st %x is address(offset)
10788 * 2st %x is data to write
10790 static int rtw_mp_write_rf(struct net_device *dev,
10791 struct iw_request_info *info,
10792 struct iw_point *wrqu, char *extra)
10794 /*static int rtw_mp_write_rf(struct net_device *dev,
10795 struct iw_request_info *info,
10796 union iwreq_data *wrqu, char *extra)
10798 u32 path, addr, data;
10800 PADAPTER padapter = rtw_netdev_priv(dev);
10801 char input[wrqu->length];
10803 if (copy_from_user(input, wrqu->pointer, wrqu->length))
10807 ret = sscanf(input, "%d,%x,%x", &path, &addr, &data);
10808 if (ret < 3) return -EINVAL;
10810 if (path >= GET_HAL_RFPATH_NUM(padapter)) return -EINVAL;
10811 if (addr > 0xFF) return -EINVAL;
10812 if (data > 0xFFFFF) return -EINVAL;
10814 _rtw_memset(extra, 0, wrqu->length);
10816 write_rfreg(padapter, path, addr, data);
10818 sprintf(extra, "write_rf completed \n");
10819 wrqu->length = strlen(extra);
10825 * Input Format: %d,%x
10826 * %d is RF path, should be smaller than MAX_RF_PATH_NUMS
10827 * %x is address(offset)
10830 * %d for data readed
10832 static int rtw_mp_read_rf(struct net_device *dev,
10833 struct iw_request_info *info,
10834 struct iw_point *wrqu, char *extra)
10836 char input[wrqu->length];
10837 char *pch, *pnext, *ptmp;
10838 char data[20],tmp[20];
10839 //u32 *data = (u32*)extra;
10841 u32 ret,i=0 ,j=0,strtou=0;
10842 PADAPTER padapter = rtw_netdev_priv(dev);
10845 if (wrqu->length > 128) return -EFAULT;
10846 if (copy_from_user(input, wrqu->pointer, wrqu->length))
10849 ret = sscanf(input, "%d,%x", &path, &addr);
10850 if (ret < 2) return -EINVAL;
10852 if (path >= GET_HAL_RFPATH_NUM(padapter)) return -EINVAL;
10853 if (addr > 0xFF) return -EINVAL;
10855 _rtw_memset(extra, 0, wrqu->length);
10857 //*data = read_rfreg(padapter, path, addr);
10858 sprintf(data, "%08x", read_rfreg(padapter, path, addr));
10859 //add read data format blank
10860 for( i=0 ; i <= strlen(data) ; i++)
10871 DBG_871X("pch=%s",pch);
10873 while( *pch != '\0' )
10875 pnext = strpbrk(pch, " ");
10877 if ( *pnext != '\0' )
10879 strtou = simple_strtoul (pnext , &ptmp, 16);
10880 sprintf( extra, "%s %d" ,extra ,strtou );
10887 wrqu->length = strlen(extra);
10892 static int rtw_mp_start(struct net_device *dev,
10893 struct iw_request_info *info,
10894 struct iw_point *wrqu, char *extra)
10897 PADAPTER padapter = rtw_netdev_priv(dev);
10898 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10899 struct dm_priv *pdmpriv = &pHalData->dmpriv;
10900 struct hal_ops *pHalFunc = &padapter->HalFunc;
10902 rtw_pm_set_ips(padapter,IPS_NONE);
10903 LeaveAllPowerSaveMode(padapter);
10905 if(padapter->registrypriv.mp_mode ==0)
10908 #ifdef CONFIG_BT_COEXIST
10909 pdmpriv->DMFlag &= ~DYNAMIC_FUNC_BT;
10911 pHalFunc->hal_deinit(padapter);
10912 padapter->registrypriv.mp_mode =1;
10913 pHalFunc->hal_init(padapter);
10915 rtw_pm_set_ips(padapter,IPS_NONE);
10916 LeaveAllPowerSaveMode(padapter);
10919 if (padapter->registrypriv.mp_mode == 0)
10922 if (padapter->mppriv.mode == MP_OFF) {
10923 if (mp_start_test(padapter) == _FAIL)
10925 padapter->mppriv.mode = MP_ON;
10926 MPT_PwrCtlDM(padapter,0);
10928 padapter->mppriv.bmac_filter = _FALSE;
10929 #ifdef CONFIG_RTL8723B
10930 #ifdef CONFIG_USB_HCI
10931 rtw_write32(padapter, 0x765, 0x0000);
10932 rtw_write32(padapter, 0x948, 0x0280);
10934 rtw_write32(padapter, 0x765, 0x0000);
10935 rtw_write32(padapter, 0x948, 0x0000);
10938 #ifdef CONFIG_RTL8723B
10939 rtw_write8(padapter, 0x66, 0x27); //Open BT uart Log
10940 rtw_write8(padapter, 0xc50, 0x20); //for RX init Gain
10942 ODM_Write_DIG(&pHalData->odmpriv,0x20);
10947 static int rtw_mp_stop(struct net_device *dev,
10948 struct iw_request_info *info,
10949 struct iw_point *wrqu, char *extra)
10951 PADAPTER padapter = rtw_netdev_priv(dev);
10952 struct hal_ops *pHalFunc = &padapter->HalFunc;
10954 if(padapter->registrypriv.mp_mode ==1)
10957 MPT_DeInitAdapter(padapter);
10958 pHalFunc->hal_deinit(padapter);
10959 padapter->registrypriv.mp_mode=0;
10960 pHalFunc->hal_init(padapter);
10963 if (padapter->mppriv.mode != MP_OFF) {
10964 mp_stop_test(padapter);
10965 padapter->mppriv.mode = MP_OFF;
10971 extern int wifirate2_ratetbl_inx(unsigned char rate);
10973 static int rtw_mp_rate(struct net_device *dev,
10974 struct iw_request_info *info,
10975 struct iw_point *wrqu, char *extra)
10977 u32 rate = MPT_RATE_1M;
10978 u8 input[wrqu->length];
10979 PADAPTER padapter = rtw_netdev_priv(dev);
10981 if (copy_from_user(input, wrqu->pointer, wrqu->length))
10984 rate = rtw_atoi(input);
10985 sprintf( extra, "Set data rate to %d" , rate );
10988 rate = wifirate2_ratetbl_inx( (u8)rate);
10989 else if (rate < 0x90)
10990 //HT rate 0x80(MCS0) ~ 0x8F(MCS15) 128~143
10991 rate =(rate - 0x80 + MPT_RATE_MCS0);
10993 //VHT rate 0x90(VHT1SS_MCS0) ~ 0x99(VHT1SS_MCS9) 144~153
10994 rate =(rate - MPT_RATE_VHT1SS_MCS0);
10996 //DBG_871X("%s: rate=%d\n", __func__, rate);
10998 if (rate >= MPT_RATE_LAST )
11001 padapter->mppriv.rateidx = rate;
11002 Hal_SetDataRate(padapter);
11004 wrqu->length = strlen(extra) + 1;
11008 static int rtw_mp_channel(struct net_device *dev,
11009 struct iw_request_info *info,
11010 struct iw_point *wrqu, char *extra)
11013 PADAPTER padapter = rtw_netdev_priv(dev);
11014 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11015 u8 input[wrqu->length];
11019 if (copy_from_user(input, wrqu->pointer, wrqu->length))
11022 channel = rtw_atoi(input);
11023 //DBG_871X("%s: channel=%d\n", __func__, channel);
11024 sprintf( extra, "Change channel %d to channel %d", padapter->mppriv.channel , channel );
11025 padapter->mppriv.channel = channel;
11026 pHalData->CurrentChannel = channel;
11027 Hal_SetChannel(padapter);
11029 //cur_ch_offset = rtw_get_offset_by_ch(padapter->mppriv.channel);
11030 //set_channel_bwmode(padapter, padapter->mppriv.channel, cur_ch_offset, padapter->mppriv.bandwidth);
11031 wrqu->length = strlen(extra) + 1;
11035 static int rtw_mp_bandwidth(struct net_device *dev,
11036 struct iw_request_info *info,
11037 struct iw_point *wrqu, char *extra)
11039 u32 bandwidth=0, sg=0;
11042 PADAPTER padapter = rtw_netdev_priv(dev);
11043 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11044 //if (copy_from_user(buffer, (void*)wrqu->data.pointer, wrqu->data.length))
11047 //DBG_871X("%s:iwpriv in=%s\n", __func__, extra);
11049 sscanf(extra, "40M=%d,shortGI=%d", &bandwidth, &sg);
11051 if (bandwidth == 1)
11052 bandwidth=CHANNEL_WIDTH_40;
11053 else if (bandwidth == 2)
11054 bandwidth=CHANNEL_WIDTH_80;
11055 DBG_871X("%s: bw=%d sg=%d \n", __func__, bandwidth , sg);
11057 padapter->mppriv.bandwidth = (u8)bandwidth;
11058 pHalData->CurrentChannelBW = bandwidth;
11059 padapter->mppriv.preamble = sg;
11061 SetBandwidth(padapter);
11062 //cur_ch_offset = rtw_get_offset_by_ch(padapter->mppriv.channel);
11063 //set_channel_bwmode(padapter, padapter->mppriv.channel, cur_ch_offset, bandwidth);
11069 static int rtw_mp_txpower_index(struct net_device *dev,
11070 struct iw_request_info *info,
11071 struct iw_point *wrqu, char *extra)
11073 PADAPTER padapter = rtw_netdev_priv(dev);
11074 char input[wrqu->length];
11078 if (wrqu->length > 128)
11081 if (copy_from_user(input, wrqu->pointer, wrqu->length))
11084 rfpath = rtw_atoi(input);
11085 txpower_inx = mpt_ProQueryCalTxPower(padapter, rfpath);
11086 sprintf(extra, " %d", txpower_inx);
11087 wrqu->length = strlen(extra) + 1;
11093 static int rtw_mp_txpower(struct net_device *dev,
11094 struct iw_request_info *info,
11095 struct iw_point *wrqu, char *extra)
11097 u32 idx_a=0,idx_b=0,MsetPower=1;
11098 u8 input[wrqu->length];
11100 PADAPTER padapter = rtw_netdev_priv(dev);
11102 if (copy_from_user(input, wrqu->pointer, wrqu->length))
11105 MsetPower = strncmp(input, "off", 3);
11106 sscanf(input,"patha=%d,pathb=%d",&idx_a,&idx_b);
11107 //DBG_871X("%s: tx_pwr_idx_a=%x b=%x\n", __func__, idx_a, idx_b);
11110 padapter->mppriv.bSetTxPower = 0;
11111 sprintf( extra, "MP Set power off");
11115 sprintf( extra, "Set power level path_A:%d path_B:%d", idx_a , idx_b );
11116 padapter->mppriv.txpoweridx = (u8)idx_a;
11117 padapter->mppriv.txpoweridx_b = (u8)idx_b;
11118 padapter->mppriv.bSetTxPower = 1;
11119 Hal_SetAntennaPathPower(padapter);
11121 wrqu->length = strlen(extra) + 1;
11125 static int rtw_mp_ant_tx(struct net_device *dev,
11126 struct iw_request_info *info,
11127 struct iw_point *wrqu, char *extra)
11130 u8 input[wrqu->length];
11132 PADAPTER padapter = rtw_netdev_priv(dev);
11134 if (copy_from_user(input, wrqu->pointer, wrqu->length))
11137 //DBG_871X("%s: input=%s\n", __func__, input);
11139 sprintf( extra, "switch Tx antenna to %s", input );
11141 for (i=0; i < strlen(input); i++)
11146 antenna|=ANTENNA_A;
11149 antenna|=ANTENNA_B;
11153 //antenna |= BIT(extra[i]-'a');
11154 //DBG_871X("%s: antenna=0x%x\n", __func__, antenna);
11155 padapter->mppriv.antenna_tx = antenna;
11156 //DBG_871X("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_tx);
11158 Hal_SetAntenna(padapter);
11160 wrqu->length = strlen(extra) + 1;
11164 static int rtw_mp_ant_rx(struct net_device *dev,
11165 struct iw_request_info *info,
11166 struct iw_point *wrqu, char *extra)
11170 u8 input[wrqu->length];
11171 PADAPTER padapter = rtw_netdev_priv(dev);
11173 if (copy_from_user(input, wrqu->pointer, wrqu->length))
11175 //DBG_871X("%s: input=%s\n", __func__, input);
11176 _rtw_memset(extra, 0, wrqu->length);
11178 sprintf( extra, "switch Rx antenna to %s", input );
11180 for (i=0; i < strlen(input); i++) {
11184 antenna|=ANTENNA_A;
11187 antenna|=ANTENNA_B;
11190 antenna|=ANTENNA_C;
11195 //DBG_871X("%s: antenna=0x%x\n", __func__, antenna);
11196 padapter->mppriv.antenna_rx = antenna;
11197 //DBG_871X("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_rx);
11198 Hal_SetAntenna(padapter);
11199 wrqu->length = strlen(extra);
11204 static int rtw_mp_ctx(struct net_device *dev,
11205 struct iw_request_info *info,
11206 struct iw_point *wrqu, char *extra)
11208 u32 pkTx = 1, countPkTx = 1, cotuTx = 1, CarrSprTx = 1, scTx = 1, sgleTx = 1, stop = 1;
11209 u32 bStartTest = 1;
11210 u32 count = 0,pktinterval=0;
11211 struct mp_priv *pmp_priv;
11212 struct pkt_attrib *pattrib;
11214 PADAPTER padapter = rtw_netdev_priv(dev);
11217 pmp_priv = &padapter->mppriv;
11219 if (copy_from_user(extra, wrqu->pointer, wrqu->length))
11222 DBG_871X("%s: in=%s\n", __func__, extra);
11224 countPkTx = strncmp(extra, "count=", 5); // strncmp TRUE is 0
11225 cotuTx = strncmp(extra, "background", 20);
11226 CarrSprTx = strncmp(extra, "background,cs", 20);
11227 scTx = strncmp(extra, "background,sc", 20);
11228 sgleTx = strncmp(extra, "background,stone", 20);
11229 pkTx = strncmp(extra, "background,pkt", 20);
11230 stop = strncmp(extra, "stop", 4);
11231 sscanf(extra, "count=%d,pkt", &count);
11232 sscanf(extra, "pktinterval=%d", &pktinterval);
11234 //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);
11235 _rtw_memset(extra, '\0', sizeof(extra));
11237 if( pktinterval !=0 )
11239 sprintf( extra, "Pkt Interval = %d",pktinterval);
11240 padapter->mppriv.pktInterval = pktinterval;
11242 wrqu->length = strlen(extra);
11247 bStartTest = 0; // To set Stop
11248 pmp_priv->tx.stop = 1;
11249 sprintf( extra, "Stop continuous Tx");
11252 if (pmp_priv->mode != MP_ON) {
11253 if (pmp_priv->tx.stop != 1) {
11254 DBG_871X("%s: MP_MODE != ON %d\n", __func__, pmp_priv->mode);
11260 if (pkTx == 0 || countPkTx == 0)
11261 pmp_priv->mode = MP_PACKET_TX;
11263 pmp_priv->mode = MP_SINGLE_TONE_TX;
11265 pmp_priv->mode = MP_CONTINUOUS_TX;
11266 if (CarrSprTx == 0)
11267 pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX;
11269 pmp_priv->mode = MP_SINGLE_CARRIER_TX;
11271 switch (pmp_priv->mode)
11275 //DBG_871X("%s:pkTx %d\n", __func__,bStartTest);
11276 if (bStartTest == 0)
11278 pmp_priv->tx.stop = 1;
11279 pmp_priv->mode = MP_ON;
11280 sprintf( extra, "Stop continuous Tx");
11282 else if (pmp_priv->tx.stop == 1)
11284 sprintf( extra, "Start continuous DA=ffffffffffff len=1500 count=%u,\n",count);
11285 //DBG_871X("%s:countPkTx %d\n", __func__,count);
11286 pmp_priv->tx.stop = 0;
11287 pmp_priv->tx.count = count;
11288 pmp_priv->tx.payload = 2;
11289 #ifdef CONFIG_80211N_HT
11290 pmp_priv->tx.attrib.ht_en = 1;
11292 #ifdef CONFIG_80211AC_VHT
11293 pmp_priv->tx.attrib.raid = RATEID_IDX_VHT_1SS; //10
11295 pattrib = &pmp_priv->tx.attrib;
11296 pattrib->pktlen = 1000;
11297 _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);
11298 SetPacketTx(padapter);
11301 //DBG_871X("%s: pkTx not stop\n", __func__);
11304 wrqu->length = strlen(extra);
11307 case MP_SINGLE_TONE_TX:
11308 //DBG_871X("%s: sgleTx %d \n", __func__, bStartTest);
11309 if (bStartTest != 0){
11310 sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes.");
11312 Hal_SetSingleToneTx(padapter, (u8)bStartTest);
11315 case MP_CONTINUOUS_TX:
11316 //DBG_871X("%s: cotuTx %d\n", __func__, bStartTest);
11317 if (bStartTest != 0){
11318 sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes.");
11320 Hal_SetContinuousTx(padapter, (u8)bStartTest);
11323 case MP_CARRIER_SUPPRISSION_TX:
11324 //DBG_871X("%s: CarrSprTx %d\n", __func__, bStartTest);
11325 if (bStartTest != 0){
11326 if( pmp_priv->rateidx <= MPT_RATE_11M )
11328 sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes.");
11331 sprintf( extra, "Specify carrier suppression but not CCK rate");
11333 Hal_SetCarrierSuppressionTx(padapter, (u8)bStartTest);
11336 case MP_SINGLE_CARRIER_TX:
11337 //DBG_871X("%s: scTx %d\n", __func__, bStartTest);
11338 if (bStartTest != 0){
11339 sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes.");
11341 Hal_SetSingleCarrierTx(padapter, (u8)bStartTest);
11345 //DBG_871X("%s:No Match MP_MODE\n", __func__);
11346 sprintf( extra, "Error! Continuous-Tx is not on-going.");
11350 if ( bStartTest==1 && pmp_priv->mode != MP_ON) {
11351 struct mp_priv *pmp_priv = &padapter->mppriv;
11352 if (pmp_priv->tx.stop == 0) {
11353 pmp_priv->tx.stop = 1;
11354 //DBG_871X("%s: pkt tx is running...\n", __func__);
11357 #ifdef CONFIG_80211N_HT
11358 pmp_priv->tx.attrib.ht_en = 1;
11360 #ifdef CONFIG_80211AC_VHT
11361 pmp_priv->tx.attrib.raid = RATEID_IDX_VHT_1SS; //10
11363 pmp_priv->tx.stop = 0;
11364 pmp_priv->tx.count = 1;
11365 SetPacketTx(padapter);
11367 pmp_priv->mode = MP_ON;
11370 wrqu->length = strlen(extra);
11375 static int rtw_mp_disable_bt_coexist(struct net_device *dev,
11376 struct iw_request_info *info,
11377 union iwreq_data *wrqu, char *extra)
11379 PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
11380 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11381 struct dm_priv *pdmpriv = &pHalData->dmpriv;
11382 struct hal_ops *pHalFunc = &padapter->HalFunc;
11384 u8 input[wrqu->data.length];
11387 if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
11390 bt_coexist = rtw_atoi(input);
11392 if( bt_coexist == 0 )
11394 RT_TRACE(_module_mp_, _drv_info_,
11395 ("Set OID_RT_SET_DISABLE_BT_COEXIST: disable BT_COEXIST\n"));
11396 DBG_871X("Set OID_RT_SET_DISABLE_BT_COEXIST: disable BT_COEXIST\n");
11397 #ifdef CONFIG_BT_COEXIST
11398 rtw_btcoex_HaltNotify(padapter);
11399 rtw_btcoex_SetManualControl(padapter, _TRUE);
11400 pdmpriv->DMFlag &= ~DYNAMIC_FUNC_BT;
11401 // Force to switch Antenna to WiFi
11402 rtw_write16(padapter, 0x870, 0x300);
11403 rtw_write16(padapter, 0x860, 0x110);
11404 #endif // CONFIG_BT_COEXIST
11408 RT_TRACE(_module_mp_, _drv_info_,
11409 ("Set OID_RT_SET_DISABLE_BT_COEXIST: enable BT_COEXIST\n"));
11410 #ifdef CONFIG_BT_COEXIST
11411 pdmpriv->DMFlag |= DYNAMIC_FUNC_BT;
11412 rtw_btcoex_SetManualControl(padapter, _FALSE);
11420 static int rtw_mp_arx(struct net_device *dev,
11421 struct iw_request_info *info,
11422 struct iw_point *wrqu, char *extra)
11424 u8 bStartRx=0,bStopRx=0,bQueryPhy=0,bQueryMac=0,bSetBssid=0;
11425 u8 bmac_filter = 0,bfilter_init=0;
11426 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;
11427 u32 mac_cck_ok=0, mac_ofdm_ok=0, mac_ht_ok=0, mac_vht_ok=0;
11428 u32 mac_cck_err=0, mac_ofdm_err=0, mac_ht_err=0, mac_vht_err=0;
11429 u8 input[wrqu->length];
11430 char *pch, *ptmp, *token, *tmp[2]={0x00,0x00};
11431 u32 i=0,ii=0,jj=0,kk=0,cnts=0,bmon=0;
11432 PADAPTER padapter = rtw_netdev_priv(dev);
11433 struct mp_priv *pmppriv = &padapter->mppriv;
11435 if (copy_from_user(input, wrqu->pointer, wrqu->length))
11438 DBG_871X("%s: %s\n", __func__, input);
11440 bStartRx = (strncmp(input, "start", 5)==0)?1:0; // strncmp TRUE is 0
11441 bStopRx = (strncmp(input, "stop", 5)==0)?1:0; // strncmp TRUE is 0
11442 bQueryPhy = (strncmp(input, "phy", 3)==0)?1:0; // strncmp TRUE is 0
11443 bQueryMac = (strncmp(input, "mac", 3)==0)?1:0; // strncmp TRUE is 0
11444 bSetBssid = (strncmp(input, "setbssid=", 8)==0)?1:0; // strncmp TRUE is 0
11445 //bfilter_init = (strncmp(input, "filter_init",11)==0)?1:0;
11446 bmac_filter = (strncmp(input, "accept_mac",10)==0)?1:0;
11447 bmon = (strncmp(input, "mon=",4)==0)?1:0;
11451 while ((token = strsep(&pch, "=")) != NULL)
11457 if ((tmp[0]==NULL) && (tmp[1]==NULL)){
11461 cnts = strlen(tmp[1])/2;
11462 if (cnts<1) return -EFAULT;
11463 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
11464 DBG_871X("%s: data=%s\n", __FUNCTION__, tmp[1]);
11465 for (jj=0, kk=0; jj < cnts ; jj++, kk+=2){
11466 pmppriv->network_macaddr[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
11467 DBG_871X("network_macaddr[%d]=%x \n",jj, pmppriv->network_macaddr[jj]);
11470 pmppriv->bSetRxBssid = _TRUE;
11475 pmppriv->bmac_filter = bmac_filter;
11477 while ((token = strsep(&pch, "=")) != NULL)
11483 if ((tmp[0]==NULL) && (tmp[1]==NULL)){
11487 cnts = strlen(tmp[1])/2;
11488 if (cnts<1) return -EFAULT;
11489 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
11490 DBG_871X("%s: data=%s\n", __FUNCTION__, tmp[1]);
11491 for (jj=0, kk=0; jj < cnts ; jj++, kk+=2){
11492 pmppriv->mac_filter[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
11493 DBG_871X("%s mac_filter[%d]=%x \n",__FUNCTION__,jj, pmppriv->mac_filter[jj]);
11500 sprintf( extra, "start");
11501 SetPacketRx(padapter, bStartRx);
11505 SetPacketRx(padapter, 0);
11506 pmppriv->bmac_filter = _FALSE;
11507 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);
11512 if (IS_HARDWARE_TYPE_JAGUAR(padapter))
11514 cckok = PHY_QueryBBReg(padapter, 0xF04, 0x3FFF); // [13:0]
11515 ofdmok = PHY_QueryBBReg(padapter, 0xF14, 0x3FFF); // [13:0]
11516 htok = PHY_QueryBBReg(padapter, 0xF10, 0x3FFF); // [13:0]
11517 vht_ok = PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF); // [13:0]
11519 cckcrc = PHY_QueryBBReg(padapter, 0xF04, 0x3FFF0000); // [29:16]
11520 ofdmcrc = PHY_QueryBBReg(padapter, 0xF14, 0x3FFF0000); // [29:16]
11521 htcrc = PHY_QueryBBReg(padapter, 0xF10, 0x3FFF0000); // [29:16]
11522 vht_err = PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF0000); // [29:16]
11524 CCK_FA = PHY_QueryBBReg(padapter, 0xa5c, bMaskLWord);
11525 OFDM_FA = PHY_QueryBBReg(padapter, 0xF48, bMaskLWord);
11529 cckok = PHY_QueryBBReg(padapter, 0xF88, bMaskDWord);
11530 ofdmok = PHY_QueryBBReg(padapter, 0xF94, bMaskLWord);
11531 htok = PHY_QueryBBReg(padapter, 0xF90, bMaskLWord);
11534 cckcrc = PHY_QueryBBReg(padapter, 0xF84, bMaskDWord);
11535 ofdmcrc = PHY_QueryBBReg(padapter, 0xF94, bMaskHWord);
11536 htcrc = PHY_QueryBBReg(padapter, 0xF90, bMaskHWord);
11539 OFDM_FA = PHY_QueryBBReg(padapter, 0xCF0, bMaskLWord) + PHY_QueryBBReg(padapter, 0xCF2, bMaskLWord) +
11540 PHY_QueryBBReg(padapter, 0xDA2, bMaskLWord)+ PHY_QueryBBReg(padapter, 0xDA4, bMaskLWord) +
11541 PHY_QueryBBReg(padapter, 0xDA6, bMaskLWord) + PHY_QueryBBReg(padapter, 0xDA8, bMaskLWord);
11543 CCK_FA=(rtw_read8(padapter, 0xa5b )<<8 ) | (rtw_read8(padapter, 0xa5c));
11545 DBG_871X("%s: OFDM_FA =%d\n", __FUNCTION__, OFDM_FA);
11546 DBG_871X("%s: CCK_FA =%d\n", __FUNCTION__, CCK_FA);
11547 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);
11553 PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x3);
11554 mac_cck_ok = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0]
11555 PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x0);
11556 mac_ofdm_ok = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0]
11557 PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x6);
11558 mac_ht_ok = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0]
11561 PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x4);
11562 mac_cck_err = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0]
11563 PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x1);
11564 mac_ofdm_err = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0]
11565 PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x7);
11566 mac_ht_err = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0]
11569 rtw_write32(padapter, 0x664, (rtw_read32(padapter, 0x0664)& 0x0FFFFFFF)| Mac_DropPacket);
11570 DropPacket = rtw_read32(padapter, 0x664)& 0x0000FFFF;
11573 sprintf( extra, "Mac Received packet OK: %d , CRC error: %d , Drop Packets: %d\n",
11574 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);
11578 sscanf(input, "mon=%d", &bmon);
11582 pmppriv->rx_bindicatePkt= _TRUE;
11583 sprintf( extra, "Indicating Receive Packet to network start\n");
11585 pmppriv->rx_bindicatePkt= _FALSE;
11586 sprintf( extra, "Indicating Receive Packet to network Stop\n");
11590 wrqu->length = strlen(extra) + 1;
11595 static int rtw_mp_trx_query(struct net_device *dev,
11596 struct iw_request_info *info,
11597 struct iw_point *wrqu, char *extra)
11599 u32 txok,txfail,rxok,rxfail,rxfilterout;
11600 PADAPTER padapter = rtw_netdev_priv(dev);
11601 //if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
11604 txok=padapter->mppriv.tx.sended;
11606 rxok = padapter->mppriv.rx_pktcount;
11607 rxfail = padapter->mppriv.rx_crcerrpktcount;
11608 rxfilterout = padapter->mppriv.rx_pktcount_filter_out;
11610 _rtw_memset(extra, '\0', 128);
11612 sprintf(extra, "Tx OK:%d, Tx Fail:%d, Rx OK:%d, CRC error:%d ,Rx Filter out:%d \n", txok, txfail,rxok,rxfail,rxfilterout);
11614 wrqu->length=strlen(extra)+1;
11619 static int rtw_mp_pwrtrk(struct net_device *dev,
11620 struct iw_request_info *info,
11621 struct iw_point *wrqu, char *extra)
11626 PADAPTER padapter = rtw_netdev_priv(dev);
11627 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11628 u8 input[wrqu->length];
11630 if (copy_from_user(input, wrqu->pointer, wrqu->length))
11633 _rtw_memset(extra, 0, wrqu->length);
11636 if (wrqu->length > 1) { // not empty string
11637 if (strncmp(input, "stop", 4) == 0)
11640 sprintf(extra, "mp tx power tracking stop");
11641 pHalData->TxPowerTrackControl = _FALSE;
11643 else if (sscanf(input, "ther=%d", &thermal)) {
11644 pHalData->TxPowerTrackControl = _TRUE;
11645 ret = Hal_SetThermalMeter(padapter, (u8)thermal);
11646 if (ret == _FAIL) return -EPERM;
11647 sprintf(extra, "mp tx power tracking start,target value=%d ok ",thermal);
11653 ret = Hal_SetPowerTracking(padapter, enable);
11654 if (ret == _FAIL) return -EPERM;
11656 wrqu->length = strlen(extra);
11661 static int rtw_mp_psd(struct net_device *dev,
11662 struct iw_request_info *info,
11663 struct iw_point *wrqu, char *extra)
11665 PADAPTER padapter = rtw_netdev_priv(dev);
11666 u8 input[wrqu->length];
11668 if (copy_from_user(input, wrqu->pointer, wrqu->length))
11671 strcpy(extra,input);
11673 wrqu->length = mp_query_psd(padapter, extra);
11678 static int rtw_mp_thermal(struct net_device *dev,
11679 struct iw_request_info *info,
11680 struct iw_point *wrqu, char *extra)
11685 #ifdef CONFIG_RTL8192C
11686 u16 addr=EEPROM_THERMAL_METER_92C;
11688 #ifdef CONFIG_RTL8192D
11689 u16 addr=EEPROM_THERMAL_METER_92D;
11691 #ifdef CONFIG_RTL8723A
11692 u16 addr=EEPROM_THERMAL_METER_8723A;
11694 #ifdef CONFIG_RTL8188E
11695 u16 addr=EEPROM_THERMAL_METER_88E;
11697 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11698 u16 addr=EEPROM_THERMAL_METER_8812;
11700 #ifdef CONFIG_RTL8192E
11701 u16 addr=EEPROM_THERMAL_METER_8192E;
11703 #ifdef CONFIG_RTL8723B
11704 u16 addr=EEPROM_THERMAL_METER_8723B;
11707 u16 max_available_size=0;
11708 PADAPTER padapter = rtw_netdev_priv(dev);
11710 if (copy_from_user(extra, wrqu->pointer, wrqu->length))
11713 //DBG_871X("print extra %s \n",extra);
11715 bwrite = strncmp(extra, "write", 6); // strncmp TRUE is 0
11717 Hal_GetThermalMeter(padapter, &val);
11721 //DBG_871X("to write val:%d",val);
11722 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
11723 if( 2 > max_available_size )
11725 DBG_871X("no available efuse!\n");
11728 if ( rtw_efuse_map_write(padapter, addr, cnt, &val) == _FAIL )
11730 DBG_871X("rtw_efuse_map_write error \n");
11735 sprintf(extra, " efuse write ok :%d", val);
11740 sprintf(extra, "%d", val);
11742 wrqu->length = strlen(extra);
11747 static int rtw_mp_reset_stats(struct net_device *dev,
11748 struct iw_request_info *info,
11749 struct iw_point *wrqu, char *extra)
11751 struct mp_priv *pmp_priv;
11752 struct pkt_attrib *pattrib;
11753 PADAPTER padapter = rtw_netdev_priv(dev);
11755 pmp_priv = &padapter->mppriv;
11757 pmp_priv->tx.sended = 0;
11758 pmp_priv->tx_pktcount = 0;
11759 pmp_priv->rx_pktcount = 0;
11760 pmp_priv->rx_pktcount_filter_out=0;
11761 pmp_priv->rx_crcerrpktcount = 0;
11763 //reset phy counter
11764 if (IS_HARDWARE_TYPE_JAGUAR(padapter))
11766 write_bbreg(padapter, 0xB58, BIT0, 0x1);
11767 write_bbreg(padapter, 0xB58, BIT0, 0x0);
11769 write_bbreg(padapter, 0x9A4, BIT17, 0x1);//reset OFDA FA counter
11770 write_bbreg(padapter, 0x9A4, BIT17, 0x0);
11772 write_bbreg(padapter, 0xA5C, BIT15, 0x0);//reset CCK FA counter
11773 write_bbreg(padapter, 0xA5C, BIT15, 0x1);
11777 write_bbreg(padapter, 0xF14, BIT16, 0x1);
11779 write_bbreg(padapter, 0xF14, BIT16, 0x0);
11781 write_bbreg(padapter, 0xD00, BIT27, 0x1);//reset OFDA FA counter
11782 write_bbreg(padapter, 0xC0C, BIT31, 0x1);//reset OFDA FA counter
11783 write_bbreg(padapter, 0xD00, BIT27, 0x0);
11784 write_bbreg(padapter, 0xC0C, BIT31, 0x0);
11786 write_bbreg(padapter, 0xA2C, BIT15, 0x0);//reset CCK FA counter
11787 write_bbreg(padapter, 0xA2C, BIT15, 0x1);
11789 //reset mac counter
11790 PHY_SetMacReg(padapter, 0x664, BIT27, 0x1);
11791 PHY_SetMacReg(padapter, 0x664, BIT27, 0x0);
11795 static int rtw_mp_dump(struct net_device *dev,
11796 struct iw_request_info *info,
11797 struct iw_point *wrqu, char *extra)
11799 struct mp_priv *pmp_priv;
11800 struct pkt_attrib *pattrib;
11802 u8 input[wrqu->length];
11803 u8 rf_type,path_nums = 0;
11805 PADAPTER padapter = rtw_netdev_priv(dev);
11807 pmp_priv = &padapter->mppriv;
11809 if (copy_from_user(input, wrqu->pointer, wrqu->length))
11812 if ( strncmp(input, "all", 4)==0 )
11814 mac_reg_dump(RTW_DBGDUMP, padapter);
11815 bb_reg_dump(RTW_DBGDUMP, padapter);
11816 rf_reg_dump(RTW_DBGDUMP, padapter);
11821 static int rtw_mp_phypara(struct net_device *dev,
11822 struct iw_request_info *info,
11823 struct iw_point *wrqu, char *extra)
11826 PADAPTER padapter = rtw_netdev_priv(dev);
11827 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11828 char input[wrqu->length];
11831 if (copy_from_user(input, wrqu->pointer, wrqu->length))
11834 DBG_871X("%s:iwpriv in=%s\n", __func__, input);
11836 sscanf(input, "xcap=%d", &valxcap);
11838 pHalData->CrystalCap = (u8)valxcap;
11839 Hal_ProSetCrystalCap( padapter , valxcap );
11841 sprintf( extra, "Set xcap=%d",valxcap );
11842 wrqu->length = strlen(extra) + 1;
11848 static int rtw_mp_SetRFPath(struct net_device *dev,
11849 struct iw_request_info *info,
11850 union iwreq_data *wrqu, char *extra)
11852 PADAPTER padapter = rtw_netdev_priv(dev);
11853 char input[wrqu->data.length];
11854 s32 bMain=1,bTurnoff=1;
11856 if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
11858 DBG_871X("%s:iwpriv in=%s\n", __func__, input);
11860 bMain = strncmp(input, "1", 2); // strncmp TRUE is 0
11861 bTurnoff = strncmp(input, "0", 3); // strncmp TRUE is 0
11865 MP_PHY_SetRFPathSwitch(padapter,_TRUE);
11866 DBG_871X("%s:PHY_SetRFPathSwitch=TRUE\n", __func__);
11868 else if(bTurnoff==0)
11870 MP_PHY_SetRFPathSwitch(padapter,_FALSE);
11871 DBG_871X("%s:PHY_SetRFPathSwitch=FALSE\n", __func__);
11877 static int rtw_mp_QueryDrv(struct net_device *dev,
11878 struct iw_request_info *info,
11879 union iwreq_data *wrqu, char *extra)
11881 PADAPTER padapter = rtw_netdev_priv(dev);
11882 char input[wrqu->data.length];
11885 EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
11887 if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
11889 DBG_871X("%s:iwpriv in=%s\n", __func__, input);
11891 qAutoLoad = strncmp(input, "autoload", 8); // strncmp TRUE is 0
11895 DBG_871X("%s:qAutoLoad\n", __func__);
11897 if(pEEPROM->bautoload_fail_flag)
11898 sprintf(extra, "fail");
11900 sprintf(extra, "ok");
11902 wrqu->data.length = strlen(extra) + 1;
11906 /* update Tx AGC offset */
11907 static int rtw_mp_antBdiff(struct net_device *dev,
11908 struct iw_request_info *info,
11909 struct iw_point *wrqu, char *extra)
11913 // MPT_ProSetTxAGCOffset
11918 static int rtw_mp_PwrCtlDM(struct net_device *dev,
11919 struct iw_request_info *info,
11920 struct iw_point *wrqu, char *extra)
11922 PADAPTER padapter = rtw_netdev_priv(dev);
11923 u8 input[wrqu->length];
11926 if (copy_from_user(input, wrqu->pointer, wrqu->length))
11929 bstart = strncmp(input, "start", 5); // strncmp TRUE is 0
11931 sprintf(extra, "PwrCtlDM start \n");
11932 MPT_PwrCtlDM(padapter,1);
11934 sprintf(extra, "PwrCtlDM stop \n");
11935 MPT_PwrCtlDM(padapter,0);
11937 wrqu->length = strlen(extra);
11942 #if (defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B))
11943 /* update Tx AGC offset */
11944 static int rtw_mp_SetBT(struct net_device *dev,
11945 struct iw_request_info *info,
11946 union iwreq_data *wrqu, char *extra)
11948 PADAPTER padapter = rtw_netdev_priv(dev);
11949 struct hal_ops *pHalFunc = &padapter->HalFunc;
11950 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11953 PMPT_CONTEXT pMptCtx=&(padapter->mppriv.MptCtx);
11954 PBT_RSP_CMD pBtRsp=(PBT_RSP_CMD)&pMptCtx->mptOutBuf[0];
11956 char *pch, *ptmp, *token, *tmp[2]={0x00,0x00};
11959 u8 tempval,BTStatus;
11961 u8 u1H2CBtMpOperParm[4]={0x01};
11962 u16 testmode=1,ready=1,trxparam=1,setgen=1,getgen=1,testctrl=1,testbt=1,readtherm=1,setbtmac=1;
11963 u32 i=0,ii=0,jj=0,kk=0,cnts=0,status=0;
11964 PRT_MP_FIRMWARE pBTFirmware = NULL;
11966 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
11968 if(strlen(extra)<1) return -EFAULT;
11970 DBG_871X("%s:iwpriv in=%s\n", __FUNCTION__, extra);
11971 ready = strncmp(extra, "ready", 5);
11972 testmode = strncmp(extra, "testmode", 8); // strncmp TRUE is 0
11973 trxparam = strncmp(extra, "trxparam", 8);
11974 setgen = strncmp(extra, "setgen", 6);
11975 getgen = strncmp(extra, "getgen", 6);
11976 testctrl = strncmp(extra, "testctrl", 8);
11977 testbt = strncmp(extra, "testbt", 6);
11978 readtherm = strncmp(extra, "readtherm", 9);
11979 setbtmac = strncmp(extra, "setbtmac", 8);
11981 if ( strncmp(extra, "dlbt", 4) == 0)
11983 pHalData->LastHMEBoxNum=0;
11984 padapter->bBTFWReady = _FALSE;
11985 rtw_write8(padapter, 0xa3, 0x05);
11986 BTStatus=rtw_read8(padapter, 0xa0);
11987 DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus);
11988 if (BTStatus != 0x04)
11990 sprintf(extra, "BT Status not Active DLFW FAIL\n");
11994 tempval = rtw_read8(padapter, 0x6B);
11996 rtw_write8(padapter, 0x6B, tempval);
11998 // Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay
11999 // So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together!
12000 rtw_usleep_os(100);
12001 // disable BT power cut
12003 tempval = rtw_read8(padapter, 0x6B);
12005 rtw_write8(padapter, 0x6B, tempval);
12006 rtw_usleep_os(100);
12007 MPT_PwrCtlDM(padapter,0);
12008 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)| 0x00000004));
12009 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)& 0xFFFFFFEF));
12010 rtw_msleep_os(600);
12011 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)| 0x00000010));
12012 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)& 0xFFFFFFFB));
12013 rtw_msleep_os(1200);
12014 pBTFirmware = (PRT_MP_FIRMWARE)rtw_zmalloc(sizeof(RT_MP_FIRMWARE));
12015 if(pBTFirmware==NULL)
12017 padapter->bBTFWReady = _FALSE;
12018 FirmwareDownloadBT(padapter, pBTFirmware);
12020 rtw_mfree((u8*)pBTFirmware, sizeof(RT_MP_FIRMWARE));
12022 DBG_871X("Wait for FirmwareDownloadBT fw boot!\n");
12023 rtw_msleep_os(2000);
12024 _rtw_memset(extra,'\0', wrqu->data.length);
12025 BtReq.opCodeVer = 1;
12027 BtReq.paraLength = 0;
12028 mptbt_BtControlProcess(padapter, &BtReq);
12029 rtw_msleep_os(100);
12031 DBG_8192C("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4],pMptCtx->mptOutBuf[5]);
12032 if( (pMptCtx->mptOutBuf[4]==0x00) && (pMptCtx->mptOutBuf[5]==0x00))
12034 if(padapter->mppriv.bTxBufCkFail==_TRUE)
12035 sprintf(extra, "check TxBuf Fail.\n");
12037 sprintf(extra, "download FW Fail.\n");
12041 sprintf(extra, "download FW OK.\n");
12047 if ( strncmp(extra, "dlfw", 4) == 0)
12049 pHalData->LastHMEBoxNum=0;
12050 padapter->bBTFWReady = _FALSE;
12051 rtw_write8(padapter, 0xa3, 0x05);
12052 BTStatus=rtw_read8(padapter, 0xa0);
12053 DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus);
12054 if (BTStatus != 0x04)
12056 sprintf(extra, "BT Status not Active DLFW FAIL\n");
12060 tempval = rtw_read8(padapter, 0x6B);
12062 rtw_write8(padapter, 0x6B, tempval);
12064 // Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay
12065 // So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together!
12066 rtw_usleep_os(100);
12067 // disable BT power cut
12069 tempval = rtw_read8(padapter, 0x6B);
12071 rtw_write8(padapter, 0x6B, tempval);
12072 rtw_usleep_os(100);
12074 MPT_PwrCtlDM(padapter,0);
12075 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)| 0x00000004));
12076 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)& 0xFFFFFFEF));
12077 rtw_msleep_os(600);
12078 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)| 0x00000010));
12079 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)& 0xFFFFFFFB));
12080 rtw_msleep_os(1200);
12082 #if defined(CONFIG_PLATFORM_SPRD) && (MP_DRIVER == 1)
12083 // Pull up BT reset pin.
12084 DBG_871X("%s: pull up BT reset pin when bt start mp test\n", __FUNCTION__);
12085 rtw_wifi_gpio_wlan_ctrl(WLAN_BT_PWDN_ON);
12087 DBG_871X(" rtl8723a_FirmwareDownload!\n");
12089 #ifdef CONFIG_RTL8723A
12090 status = rtl8723a_FirmwareDownload(padapter);
12091 #elif defined(CONFIG_RTL8723B)
12092 status = rtl8723b_FirmwareDownload(padapter, _FALSE);
12094 DBG_871X("Wait for FirmwareDownloadBT fw boot!\n");
12095 rtw_msleep_os(1000);
12096 #ifdef CONFIG_BT_COEXIST
12097 rtw_btcoex_HaltNotify(padapter);
12098 DBG_871X("SetBT btcoex HaltNotify !\n");
12099 //hal_btcoex1ant_SetAntPath(padapter);
12100 rtw_btcoex_SetManualControl(padapter, _TRUE);
12102 _rtw_memset(extra,'\0', wrqu->data.length);
12103 BtReq.opCodeVer = 1;
12105 BtReq.paraLength = 0;
12106 mptbt_BtControlProcess(padapter, &BtReq);
12107 rtw_msleep_os(200);
12109 DBG_8192C("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4],pMptCtx->mptOutBuf[5]);
12110 if( (pMptCtx->mptOutBuf[4]==0x00) && (pMptCtx->mptOutBuf[5]==0x00))
12112 if(padapter->mppriv.bTxBufCkFail==_TRUE)
12113 sprintf(extra, "check TxBuf Fail.\n");
12115 sprintf(extra, "download FW Fail.\n");
12119 #ifdef CONFIG_BT_COEXIST
12120 rtw_btcoex_SwitchBtTRxMask(padapter);
12122 rtw_msleep_os(200);
12123 sprintf(extra, "download FW OK.\n");
12129 if ( strncmp(extra, "down", 4) == 0){
12130 DBG_871X("SetBT down for to hal_init !\n");
12131 #ifdef CONFIG_BT_COEXIST
12132 rtw_btcoex_SetManualControl(padapter, _FALSE);
12133 rtw_btcoex_Initialize(padapter);
12135 pHalFunc->read_adapter_info(padapter);
12136 pHalFunc->hal_deinit(padapter);
12137 pHalFunc->hal_init(padapter);
12138 rtw_pm_set_ips(padapter,IPS_NONE);
12139 LeaveAllPowerSaveMode(padapter);
12140 MPT_PwrCtlDM(padapter,0);
12141 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)| 0x00000004));
12142 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)& 0xFFFFFFEF));
12143 rtw_msleep_os(600);
12144 //rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFE));
12145 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)| 0x00000010));
12146 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)& 0xFFFFFFFB));
12147 rtw_msleep_os(1200);
12150 if ( strncmp(extra, "disable", 7) == 0){
12151 DBG_871X("SetBT disable !\n");
12152 rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFB));
12153 rtw_msleep_os(500);
12156 if ( strncmp(extra, "enable", 6) == 0){
12157 DBG_871X("SetBT enable !\n");
12158 rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)| 0x00000004));
12159 rtw_msleep_os(500);
12162 if ( strncmp(extra, "h2c", 3) == 0){
12163 DBG_871X("SetBT h2c !\n");
12164 padapter->bBTFWReady = _TRUE;
12165 FillH2CCmd(padapter, 0x63, 1, u1H2CBtMpOperParm);
12168 if ( strncmp(extra, "2ant", 4) == 0){
12169 DBG_871X("Set BT 2ant use!\n");
12170 PHY_SetMacReg(padapter,0x67,BIT5,0x1);
12171 rtw_write32(padapter, 0x948, 0000);
12176 if( ready!=0 && testmode!=0 && trxparam!=0 && setgen!=0 && getgen!=0 && testctrl!=0 && testbt!=0 && readtherm!=0 &&setbtmac!=0)
12183 BtReq.paraLength=cnts/2;
12190 BtReq.paraLength=0;
12196 while ((token = strsep(&pch, ",")) != NULL)
12203 if ((tmp[0]==NULL) && (tmp[1]==NULL))
12209 cnts = strlen(tmp[1]);
12210 if (cnts<1) return -EFAULT;
12212 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
12213 DBG_871X("%s: data=%s\n", __FUNCTION__, tmp[1]);
12215 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
12217 BtReq.pParamStart[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
12218 // DBG_871X("BtReq.pParamStart[%d]=0x%02x\n", jj, BtReq.pParamStart[jj]);
12226 BtReq.paraLength=1;
12232 BtReq.paraLength=cnts/2;
12236 DBG_871X("%s: BT_SET_GENERAL \n", __func__);
12238 BtReq.OpCode=3; //BT_SET_GENERAL 3
12239 BtReq.paraLength=cnts/2;
12243 DBG_871X("%s: BT_GET_GENERAL \n", __func__);
12245 BtReq.OpCode=4; //BT_GET_GENERAL 4
12246 BtReq.paraLength=cnts/2;
12250 DBG_871X("%s: BT_GET_GENERAL \n", __func__);
12252 BtReq.OpCode=4; //BT_GET_GENERAL 4
12253 BtReq.paraLength=cnts/2;
12258 DBG_871X("%s: BT_TEST_CTRL \n", __func__);
12260 BtReq.OpCode=5; //BT_TEST_CTRL 5
12261 BtReq.paraLength=cnts/2;
12264 DBG_871X("%s: Req opCodeVer=%d OpCode=%d paraLength=%d\n",
12265 __FUNCTION__, BtReq.opCodeVer, BtReq.OpCode, BtReq.paraLength);
12267 if(BtReq.paraLength<1)
12269 for (i=0; i<BtReq.paraLength; i++)
12271 DBG_871X("%s: BtReq.pParamStart[%d] = 0x%02x \n",
12272 __FUNCTION__, i, BtReq.pParamStart[i]);
12276 _rtw_memset(extra,'\0', wrqu->data.length);
12278 if (padapter->bBTFWReady == _FALSE)
12280 sprintf(extra, "BTFWReady = FALSE.\n");
12284 mptbt_BtControlProcess(padapter, &BtReq);
12286 if (readtherm == 0)
12288 sprintf(extra, "BT thermal=");
12289 for (i=4; i<pMptCtx->mptOutLen; i++)
12291 if ((pMptCtx->mptOutBuf[i]==0x00) && (pMptCtx->mptOutBuf[i+1]==0x00))
12294 #ifdef CONFIG_RTL8723A
12295 sprintf(extra, "%s %d ", extra, (pMptCtx->mptOutBuf[i]& 0x3f));
12297 sprintf(extra, "%s %d ", extra, (pMptCtx->mptOutBuf[i]& 0x1f));
12303 for (i=4; i<pMptCtx->mptOutLen; i++)
12305 sprintf(extra, "%s 0x%x ", extra, pMptCtx->mptOutBuf[i]);
12310 wrqu->data.length = strlen(extra) + 1;
12311 DBG_871X("-%s: output len=%d data=%s\n", __FUNCTION__, wrqu->data.length, extra);
12316 #endif //#ifdef CONFIG_RTL8723A
12318 static int rtw_mp_set(struct net_device *dev,
12319 struct iw_request_info *info,
12320 union iwreq_data *wdata, char *extra)
12322 struct iw_point *wrqu = (struct iw_point *)wdata;
12323 u32 subcmd = wrqu->flags;
12324 PADAPTER padapter = rtw_netdev_priv(dev);
12326 if (padapter == NULL)
12331 if((padapter->bup == _FALSE ))
12333 DBG_871X(" %s fail =>(padapter->bup == _FALSE )\n",__FUNCTION__);
12337 if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE))
12339 DBG_871X("%s fail =>(padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE) \n",__FUNCTION__);
12344 //_rtw_memset(extra, 0x00, IW_PRIV_SIZE_MASK);
12355 DBG_871X("set case mp_start \n");
12356 rtw_mp_start (dev,info,wrqu,extra);
12360 DBG_871X("set case mp_stop \n");
12361 rtw_mp_stop (dev,info,wrqu,extra);
12365 DBG_871X("set case mp_bandwidth \n");
12366 rtw_mp_bandwidth (dev,info,wrqu,extra);
12369 case MP_RESET_STATS:
12370 DBG_871X("set case MP_RESET_STATS \n");
12371 rtw_mp_reset_stats (dev,info,wrqu,extra);
12373 case MP_SetRFPathSwh:
12374 DBG_871X("set MP_SetRFPathSwitch \n");
12375 rtw_mp_SetRFPath (dev,info,wdata,extra);
12378 DBG_871X("set CTA_TEST\n");
12379 rtw_cta_test_start (dev, info, wdata, extra);
12381 case MP_DISABLE_BT_COEXIST:
12382 DBG_871X("set case MP_DISABLE_BT_COEXIST \n");
12383 rtw_mp_disable_bt_coexist(dev, info, wdata, extra);
12385 #ifdef CONFIG_WOWLAN
12386 case MP_WOW_ENABLE:
12387 DBG_871X("set case MP_WOW_ENABLE: %s \n", extra);
12388 rtw_wowlan_ctrl(dev, info, wdata, extra);
12391 #ifdef CONFIG_AP_WOWLAN
12392 case MP_AP_WOW_ENABLE:
12393 DBG_871X("set case MP_AP_WOW_ENABLE: %s \n", extra);
12394 rtw_ap_wowlan_ctrl(dev, info, wdata, extra);
12404 static int rtw_mp_get(struct net_device *dev,
12405 struct iw_request_info *info,
12406 union iwreq_data *wdata, char *extra)
12408 struct iw_point *wrqu = (struct iw_point *)wdata;
12409 u32 subcmd = wrqu->flags;
12410 PADAPTER padapter = rtw_netdev_priv(dev);
12412 //DBG_871X("in mp_get extra= %s \n",extra);
12414 if (padapter == NULL)
12418 if((padapter->bup == _FALSE ))
12420 DBG_871X(" %s fail =>(padapter->bup == _FALSE )\n",__FUNCTION__);
12424 if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE))
12426 DBG_871X("%s fail =>(padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE) \n",__FUNCTION__);
12439 rtw_mp_write_reg (dev,info,wrqu,extra);
12443 rtw_mp_write_rf (dev,info,wrqu,extra);
12447 DBG_871X("mp_get MP_PHYPARA \n");
12448 rtw_mp_phypara(dev,info,wrqu,extra);
12452 DBG_871X("set case mp_channel \n");
12453 rtw_mp_channel (dev,info,wrqu,extra);
12457 DBG_871X("mp_get READ_REG \n");
12458 rtw_mp_read_reg (dev,info,wrqu,extra);
12461 DBG_871X("mp_get READ_RF \n");
12462 rtw_mp_read_rf (dev,info,wrqu,extra);
12466 DBG_871X("set case mp_rate \n");
12467 rtw_mp_rate (dev,info,wrqu,extra);
12471 DBG_871X("set case MP_TXPOWER \n");
12472 rtw_mp_txpower (dev,info,wrqu,extra);
12476 DBG_871X("set case MP_ANT_TX \n");
12477 rtw_mp_ant_tx (dev,info,wrqu,extra);
12481 DBG_871X("set case MP_ANT_RX \n");
12482 rtw_mp_ant_rx (dev,info,wrqu,extra);
12486 //DBG_871X("mp_get mp_query MP_QUERY \n");
12487 rtw_mp_trx_query(dev,info,wrqu,extra);
12491 DBG_871X("set case MP_CTX \n");
12492 rtw_mp_ctx (dev,info,wrqu,extra);
12496 DBG_871X("set case MP_ARX \n");
12497 rtw_mp_arx (dev,info,wrqu,extra);
12501 DBG_871X("efuse get EFUSE_GET \n");
12502 rtw_mp_efuse_get(dev,info,wdata,extra);
12506 DBG_871X("set case MP_DUMP \n");
12507 rtw_mp_dump (dev,info,wrqu,extra);
12510 DBG_871X("set case MP_PSD \n");
12511 rtw_mp_psd (dev,info,wrqu,extra);
12514 DBG_871X("set case MP_THER \n");
12515 rtw_mp_thermal (dev,info,wrqu,extra);
12518 DBG_871X("set MP_PwrCtlDM\n");
12519 rtw_mp_PwrCtlDM (dev,info,wrqu,extra);
12521 case MP_QueryDrvStats:
12522 DBG_871X("mp_get MP_QueryDrvStats \n");
12523 rtw_mp_QueryDrv(dev,info,wdata,extra);
12526 DBG_871X("set case MP_PWRTRK \n");
12527 rtw_mp_pwrtrk(dev,info,wrqu,extra);
12530 DBG_871X("set case efuse set \n");
12531 rtw_mp_efuse_set(dev,info,wdata,extra);
12533 case MP_GET_TXPOWER_INX:
12534 DBG_871X("mp_get MP_GET_TXPOWER_INX \n");
12535 rtw_mp_txpower_index(dev,info,wrqu,extra);
12538 #if defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B)
12540 DBG_871X("set MP_SetBT \n");
12541 rtw_mp_SetBT(dev,info,wdata,extra);
12547 rtw_msleep_os(10); //delay 5ms for sending pkt before exit adb shell operation
12551 #endif //#if defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT)
12553 static int rtw_wfd_tdls_enable(struct net_device *dev,
12554 struct iw_request_info *info,
12555 union iwreq_data *wrqu, char *extra)
12562 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12564 printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
12566 if ( extra[ 0 ] == '0' )
12568 padapter->wdinfo.wfd_tdls_enable = 0;
12572 padapter->wdinfo.wfd_tdls_enable = 1;
12575 #endif //CONFIG_WFD
12576 #endif //CONFIG_TDLS
12581 static int rtw_tdls_weaksec(struct net_device *dev,
12582 struct iw_request_info *info,
12583 union iwreq_data *wrqu, char *extra)
12590 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12592 DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
12594 if ( extra[ 0 ] == '0' )
12596 padapter->wdinfo.wfd_tdls_weaksec = 0;
12600 padapter->wdinfo.wfd_tdls_weaksec = 1;
12608 static int rtw_tdls_enable(struct net_device *dev,
12609 struct iw_request_info *info,
12610 union iwreq_data *wrqu, char *extra)
12616 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12617 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12619 _list *plist, *phead;
12621 struct sta_info *psta = NULL;
12622 struct sta_priv *pstapriv = &padapter->stapriv;
12623 u8 tdls_sta[NUM_STA][ETH_ALEN];
12624 u8 empty_hwaddr[ETH_ALEN] = { 0x00 };
12625 struct tdls_txmgmt txmgmt;
12627 printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
12629 _rtw_memset(tdls_sta, 0x00, sizeof(tdls_sta));
12630 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12632 if ( extra[ 0 ] == '0' )
12634 ptdlsinfo->tdls_enable = 0;
12636 if(pstapriv->asoc_sta_count==1)
12639 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12640 for(index=0; index< NUM_STA; index++)
12642 phead = &(pstapriv->sta_hash[index]);
12643 plist = get_next(phead);
12645 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12647 psta = LIST_CONTAINOR(plist, struct sta_info ,hash_list);
12649 plist = get_next(plist);
12651 if(psta->tdls_sta_state != TDLS_STATE_NONE)
12653 _rtw_memcpy(tdls_sta[index], psta->hwaddr, ETH_ALEN);
12657 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12659 for(index=0; index< NUM_STA; index++)
12661 if( !_rtw_memcmp(tdls_sta[index], empty_hwaddr, ETH_ALEN) )
12663 printk("issue tear down to "MAC_FMT"\n", MAC_ARG(tdls_sta[index]));
12664 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
12665 _rtw_memcpy(txmgmt.peer, tdls_sta[index], ETH_ALEN);
12666 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12669 rtw_tdls_cmd(padapter, myid(&(padapter->eeprompriv)), TDLS_RS_RCR);
12670 rtw_reset_tdls_info(padapter);
12672 else if ( extra[ 0 ] == '1' )
12674 ptdlsinfo->tdls_enable = 1;
12676 #endif //CONFIG_TDLS
12681 static int rtw_tdls_setup(struct net_device *dev,
12682 struct iw_request_info *info,
12683 union iwreq_data *wrqu, char *extra)
12688 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12689 struct tdls_txmgmt txmgmt;
12691 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
12692 #endif // CONFIG_WFD
12694 printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
12696 if(wrqu->data.length - 1 != 17 )
12698 printk( "[%s] length:%d != 17\n", __FUNCTION__, (wrqu->data.length -1) );
12702 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12703 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12704 txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1));
12708 if ( _AES_ != padapter->securitypriv.dot11PrivacyAlgrthm )
12710 // Weak Security situation with AP.
12711 if ( 0 == pwdinfo->wfd_tdls_weaksec )
12713 // Can't send the tdls setup request out!!
12714 DBG_871X( "[%s] Current link is not AES, SKIP sending the tdls setup request!!\n", __FUNCTION__ );
12718 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
12722 #endif // CONFIG_WFD
12724 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
12731 static int rtw_tdls_teardown(struct net_device *dev,
12732 struct iw_request_info *info,
12733 union iwreq_data *wrqu, char *extra)
12740 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12741 struct sta_info *ptdls_sta = NULL;
12742 struct tdls_txmgmt txmgmt;
12744 DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
12746 if(wrqu->data.length - 1 != 17 && wrqu->data.length - 1 != 19)
12748 printk( "[%s] length:%d != 17 or 19\n", __FUNCTION__, (wrqu->data.length -1) );
12752 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12753 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12754 txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1));
12757 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), txmgmt.peer);
12759 if(ptdls_sta != NULL)
12761 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
12762 if(wrqu->data.length - 1 == 17)
12763 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12764 else if(wrqu->data.length - 1 == 19)
12765 issue_tdls_teardown(padapter, &txmgmt, _TRUE);
12768 DBG_871X( "TDLS peer not found\n");
12769 #endif //CONFIG_TDLS
12774 static int rtw_tdls_discovery(struct net_device *dev,
12775 struct iw_request_info *info,
12776 union iwreq_data *wrqu, char *extra)
12782 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12783 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
12784 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12785 struct tdls_txmgmt txmgmt;
12788 DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
12790 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12791 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12792 txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1));
12795 issue_tdls_dis_req(padapter, &txmgmt);
12797 #endif //CONFIG_TDLS
12802 static int rtw_tdls_ch_switch(struct net_device *dev,
12803 struct iw_request_info *info,
12804 union iwreq_data *wrqu, char *extra)
12810 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12811 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12812 u8 i, j, mac_addr[ETH_ALEN];
12813 struct sta_info *ptdls_sta = NULL;
12815 DBG_8192C( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
12817 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12818 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
12821 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
12822 if( ptdls_sta == NULL )
12825 // ptdlsinfo->ch_sensing=1;
12827 // rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_INIT_CH_SEN);
12829 #endif //CONFIG_TDLS
12834 static int rtw_tdls_pson(struct net_device *dev,
12835 struct iw_request_info *info,
12836 union iwreq_data *wrqu, char *extra)
12842 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12843 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
12844 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12845 u8 i, j, mac_addr[ETH_ALEN];
12846 struct sta_info *ptdls_sta = NULL;
12848 DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
12850 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12851 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
12854 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
12856 issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 1, 3, 500);
12858 #endif //CONFIG_TDLS
12863 static int rtw_tdls_psoff(struct net_device *dev,
12864 struct iw_request_info *info,
12865 union iwreq_data *wrqu, char *extra)
12871 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12872 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
12873 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12874 u8 i, j, mac_addr[ETH_ALEN];
12875 struct sta_info *ptdls_sta = NULL;
12877 DBG_8192C( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
12879 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
12880 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
12883 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
12887 //issue_tdls_peer_traffic_rsp(padapter, ptdls_sta);
12888 issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 0, 3, 500);
12890 #endif //CONFIG_TDLS
12895 static int rtw_tdls_setip(struct net_device *dev,
12896 struct iw_request_info *info,
12897 union iwreq_data *wrqu, char *extra)
12904 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12905 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12906 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
12907 u8 i=0, j=0, k=0, tag=0, ip[3] = { 0xff }, *ptr = extra;
12909 printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1 );
12914 for( j=0; j < 4; j++)
12916 if( *( extra + j + tag ) == '.' || *( extra + j + tag ) == '\0' )
12919 pwfd_info->ip_address[i]=convert_ip_addr( '0', '0', *(extra+(j-1)+tag));
12921 pwfd_info->ip_address[i]=convert_ip_addr( '0', *(extra+(j-2)+tag), *(extra+(j-1)+tag));
12923 pwfd_info->ip_address[i]=convert_ip_addr( *(extra+(j-3)+tag), *(extra+(j-2)+tag), *(extra+(j-1)+tag));
12932 printk( "[%s] Set IP = %u.%u.%u.%u \n", __FUNCTION__,
12933 ptdlsinfo->wfd_info->ip_address[0], ptdlsinfo->wfd_info->ip_address[1],
12934 ptdlsinfo->wfd_info->ip_address[2], ptdlsinfo->wfd_info->ip_address[3]
12937 #endif //CONFIG_WFD
12938 #endif //CONFIG_TDLS
12943 static int rtw_tdls_getip(struct net_device *dev,
12944 struct iw_request_info *info,
12945 union iwreq_data *wrqu, char *extra)
12952 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12953 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12954 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
12956 printk( "[%s]\n", __FUNCTION__);
12958 sprintf( extra, "\n\n%u.%u.%u.%u\n",
12959 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],
12960 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]
12963 printk( "[%s] IP=%u.%u.%u.%u\n", __FUNCTION__,
12964 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],
12965 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]
12968 wrqu->data.length = strlen( extra );
12970 #endif //CONFIG_WFD
12971 #endif //CONFIG_TDLS
12976 static int rtw_tdls_getport(struct net_device *dev,
12977 struct iw_request_info *info,
12978 union iwreq_data *wrqu, char *extra)
12986 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12987 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12988 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
12990 printk( "[%s]\n", __FUNCTION__);
12992 sprintf( extra, "\n\n%d\n", pwfd_info->peer_rtsp_ctrlport );
12993 printk( "[%s] remote port = %d\n", __FUNCTION__, pwfd_info->peer_rtsp_ctrlport );
12995 wrqu->data.length = strlen( extra );
12997 #endif //CONFIG_WFD
12998 #endif //CONFIG_TDLS
13004 //WFDTDLS, for sigma test
13005 static int rtw_tdls_dis_result(struct net_device *dev,
13006 struct iw_request_info *info,
13007 union iwreq_data *wrqu, char *extra)
13015 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
13016 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
13017 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
13019 printk( "[%s]\n", __FUNCTION__);
13021 if(ptdlsinfo->dev_discovered == 1 )
13023 sprintf( extra, "\n\nDis=1\n" );
13024 ptdlsinfo->dev_discovered = 0;
13027 wrqu->data.length = strlen( extra );
13029 #endif //CONFIG_WFD
13030 #endif //CONFIG_TDLS
13036 //WFDTDLS, for sigma test
13037 static int rtw_wfd_tdls_status(struct net_device *dev,
13038 struct iw_request_info *info,
13039 union iwreq_data *wrqu, char *extra)
13046 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
13047 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
13049 printk( "[%s]\n", __FUNCTION__);
13051 sprintf( extra, "\nlink_established:0x%08x \n"
13053 "sta_maximum:%d \n"
13054 "cur_channel:%d \n"
13056 ptdlsinfo->link_established, ptdlsinfo->sta_cnt, ptdlsinfo->sta_maximum,
13057 ptdlsinfo->cur_channel, ptdlsinfo->tdls_enable
13060 wrqu->data.length = strlen( extra );
13062 #endif //CONFIG_TDLS
13068 static int rtw_tdls_getsta(struct net_device *dev,
13069 struct iw_request_info *info,
13070 union iwreq_data *wrqu, char *extra)
13076 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
13077 u8 addr[ETH_ALEN] = {0};
13079 struct sta_info *ptdls_sta = NULL;
13081 printk( "[%s] %s %d\n", __FUNCTION__, (char *)wrqu->data.pointer, wrqu->data.length -1 );
13083 if(copy_from_user(charmac, wrqu->data.pointer+9, 17)){
13088 printk("[%s] %d, charmac:%s\n", __FUNCTION__, __LINE__, charmac);
13089 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
13090 addr[i]=key_2char2num(*(charmac+j), *(charmac+j+1));
13093 printk("[%s] %d, charmac:%s, addr:"MAC_FMT"\n", __FUNCTION__, __LINE__, charmac, MAC_ARG(addr));
13094 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, addr);
13096 sprintf(extra, "\n\ntdls_sta_state=%d\n", ptdls_sta->tdls_sta_state);
13097 printk("\n\ntdls_sta_state=%d\n", ptdls_sta->tdls_sta_state);
13100 sprintf(extra, "\n\nNot found this sta\n");
13101 printk("\n\nNot found this sta\n");
13103 wrqu->data.length = strlen( extra );
13105 #endif //CONFIG_TDLS
13111 static int rtw_tdls_ch_switch_off(struct net_device *dev,
13112 struct iw_request_info *info,
13113 union iwreq_data *wrqu, char *extra)
13119 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
13120 u8 i, j, mac_addr[ETH_ALEN];
13121 struct sta_info *ptdls_sta = NULL;
13123 DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
13125 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
13126 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
13129 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
13131 ptdls_sta->tdls_sta_state |= TDLS_SW_OFF_STATE;
13133 if((ptdls_sta->tdls_sta_state & TDLS_AT_OFF_CH_STATE) && (ptdls_sta->tdls_sta_state & TDLS_PEER_AT_OFF_STATE)){
13134 pmlmeinfo->tdls_candidate_ch= pmlmeext->cur_channel;
13135 issue_tdls_ch_switch_req(padapter, mac_addr);
13136 DBG_871X("issue tdls ch switch req back to base channel\n");
13140 #endif //CONFIG_TDLS
13145 static int rtw_tdls(struct net_device *dev,
13146 struct iw_request_info *info,
13147 union iwreq_data *wrqu, char *extra)
13152 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
13156 DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra );
13157 // WFD Sigma will use the tdls enable command to let the driver know we want to test the tdls now!
13158 if ( _rtw_memcmp( extra, "wfdenable=", 10 ) )
13160 wrqu->data.length -=10;
13161 rtw_wfd_tdls_enable( dev, info, wrqu, &extra[10] );
13164 else if ( _rtw_memcmp( extra, "weaksec=", 8 ) )
13166 wrqu->data.length -=8;
13167 rtw_tdls_weaksec( dev, info, wrqu, &extra[8] );
13170 else if ( _rtw_memcmp( extra, "tdlsenable=", 11 ) )
13172 wrqu->data.length -=11;
13173 rtw_tdls_enable( dev, info, wrqu, &extra[11] );
13177 if( padapter->tdlsinfo.tdls_enable == 0 )
13179 printk("tdls haven't enabled\n");
13183 if ( _rtw_memcmp( extra, "setup=", 6 ) )
13185 wrqu->data.length -=6;
13186 rtw_tdls_setup( dev, info, wrqu, &extra[6] );
13188 else if (_rtw_memcmp( extra, "tear=", 5 ) )
13190 wrqu->data.length -= 5;
13191 rtw_tdls_teardown( dev, info, wrqu, &extra[5] );
13193 else if (_rtw_memcmp( extra, "dis=", 4 ) )
13195 wrqu->data.length -= 4;
13196 rtw_tdls_discovery( dev, info, wrqu, &extra[4] );
13198 else if (_rtw_memcmp( extra, "sw=", 3 ) )
13200 wrqu->data.length -= 3;
13201 rtw_tdls_ch_switch( dev, info, wrqu, &extra[3] );
13203 else if (_rtw_memcmp( extra, "swoff=", 6 ) )
13205 wrqu->data.length -= 6;
13206 rtw_tdls_ch_switch_off( dev, info, wrqu, &extra[6] );
13208 else if (_rtw_memcmp( extra, "pson=", 5 ) )
13210 wrqu->data.length -= 5;
13211 rtw_tdls_pson( dev, info, wrqu, &extra[5] );
13213 else if (_rtw_memcmp( extra, "psoff=", 6 ) )
13215 wrqu->data.length -= 6;
13216 rtw_tdls_psoff( dev, info, wrqu, &extra[6] );
13219 else if (_rtw_memcmp( extra, "setip=", 6 ) )
13221 wrqu->data.length -= 6;
13222 rtw_tdls_setip( dev, info, wrqu, &extra[6] );
13224 else if (_rtw_memcmp( extra, "tprobe=", 6 ) )
13226 issue_tunneled_probe_req((_adapter *)rtw_netdev_priv(dev));
13228 #endif //CONFIG_WFD
13230 #endif //CONFIG_TDLS
13236 static int rtw_tdls_get(struct net_device *dev,
13237 struct iw_request_info *info,
13238 union iwreq_data *wrqu, char *extra)
13244 DBG_871X( "[%s] extra = %s\n", __FUNCTION__, (char*) wrqu->data.pointer );
13246 if ( _rtw_memcmp( wrqu->data.pointer, "ip", 2 ) )
13248 rtw_tdls_getip( dev, info, wrqu, extra );
13250 if ( _rtw_memcmp( wrqu->data.pointer, "port", 4 ) )
13252 rtw_tdls_getport( dev, info, wrqu, extra );
13254 //WFDTDLS, for sigma test
13255 if ( _rtw_memcmp( wrqu->data.pointer, "dis", 3 ) )
13257 rtw_tdls_dis_result( dev, info, wrqu, extra );
13259 if ( _rtw_memcmp( wrqu->data.pointer, "status", 6 ) )
13261 rtw_wfd_tdls_status( dev, info, wrqu, extra );
13263 if ( _rtw_memcmp( wrqu->data.pointer, "tdls_sta=", 9 ) )
13265 rtw_tdls_getsta( dev, info, wrqu, extra );
13268 #endif //CONFIG_WFD
13277 #ifdef CONFIG_INTEL_WIDI
13278 static int rtw_widi_set(struct net_device *dev,
13279 struct iw_request_info *info,
13280 union iwreq_data *wrqu, char *extra)
13283 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
13285 process_intel_widi_cmd(padapter, extra);
13290 static int rtw_widi_set_probe_request(struct net_device *dev,
13291 struct iw_request_info *info,
13292 union iwreq_data *wrqu, char *extra)
13296 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
13298 pbuf = rtw_malloc(sizeof(l2_msg_t));
13301 if ( copy_from_user(pbuf, wrqu->data.pointer, wrqu->data.length) )
13303 //_rtw_memcpy(pbuf, wrqu->data.pointer, wrqu->data.length);
13305 if( wrqu->data.flags == 0 )
13306 intel_widi_wk_cmd(padapter, INTEL_WIDI_ISSUE_PROB_WK, pbuf, sizeof(l2_msg_t));
13307 else if( wrqu->data.flags == 1 )
13308 rtw_set_wfd_rds_sink_info( padapter, (l2_msg_t *)pbuf );
13312 #endif // CONFIG_INTEL_WIDI
13314 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
13316 #ifdef CONFIG_RTL8723A
13317 extern void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc);
13318 #define cal_txdesc_chksum rtl8723a_cal_txdesc_chksum
13319 extern void rtl8723a_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
13320 #define fill_default_txdesc rtl8723a_fill_default_txdesc
13322 #if defined(CONFIG_RTL8188E)
13323 #include <rtl8188e_hal.h>
13324 extern void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc);
13325 #define cal_txdesc_chksum rtl8188e_cal_txdesc_chksum
13326 #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)
13327 extern void rtl8188es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
13328 #define fill_default_txdesc rtl8188es_fill_default_txdesc
13329 #endif // CONFIG_SDIO_HCI
13330 #endif // CONFIG_RTL8188E
13331 #if defined(CONFIG_RTL8723B)
13332 extern void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc);
13333 #define cal_txdesc_chksum rtl8723b_cal_txdesc_chksum
13334 extern void rtl8723b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
13335 #define fill_default_txdesc rtl8723b_fill_default_txdesc
13336 #endif // CONFIG_RTL8723B
13338 static s32 initLoopback(PADAPTER padapter)
13340 PLOOPBACKDATA ploopback;
13343 if (padapter->ploopback == NULL) {
13344 ploopback = (PLOOPBACKDATA)rtw_zmalloc(sizeof(LOOPBACKDATA));
13345 if (ploopback == NULL) return -ENOMEM;
13347 _rtw_init_sema(&ploopback->sema, 0);
13348 ploopback->bstop = _TRUE;
13349 ploopback->cnt = 0;
13350 ploopback->size = 300;
13351 _rtw_memset(ploopback->msg, 0, sizeof(ploopback->msg));
13353 padapter->ploopback = ploopback;
13359 static void freeLoopback(PADAPTER padapter)
13361 PLOOPBACKDATA ploopback;
13364 ploopback = padapter->ploopback;
13366 rtw_mfree((u8*)ploopback, sizeof(LOOPBACKDATA));
13367 padapter->ploopback = NULL;
13371 static s32 initpseudoadhoc(PADAPTER padapter)
13373 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
13376 networkType = Ndis802_11IBSS;
13377 err = rtw_set_802_11_infrastructure_mode(padapter, networkType);
13378 if (err == _FALSE) return _FAIL;
13380 err = rtw_setopmode_cmd(padapter, networkType,_TRUE);
13381 if (err == _FAIL) return _FAIL;
13386 static s32 createpseudoadhoc(PADAPTER padapter)
13388 NDIS_802_11_AUTHENTICATION_MODE authmode;
13389 struct mlme_priv *pmlmepriv;
13390 NDIS_802_11_SSID *passoc_ssid;
13391 WLAN_BSSID_EX *pdev_network;
13393 u8 ssid[] = "pseduo_ad-hoc";
13398 pmlmepriv = &padapter->mlmepriv;
13400 authmode = Ndis802_11AuthModeOpen;
13401 err = rtw_set_802_11_authentication_mode(padapter, authmode);
13402 if (err == _FALSE) return _FAIL;
13404 passoc_ssid = &pmlmepriv->assoc_ssid;
13405 _rtw_memset(passoc_ssid, 0, sizeof(NDIS_802_11_SSID));
13406 passoc_ssid->SsidLength = sizeof(ssid) - 1;
13407 _rtw_memcpy(passoc_ssid->Ssid, ssid, passoc_ssid->SsidLength);
13409 pdev_network = &padapter->registrypriv.dev_network;
13410 pibss = padapter->registrypriv.dev_network.MacAddress;
13411 _rtw_memcpy(&pdev_network->Ssid, passoc_ssid, sizeof(NDIS_802_11_SSID));
13413 rtw_update_registrypriv_dev_network(padapter);
13414 rtw_generate_random_ibss(pibss);
13416 _enter_critical_bh(&pmlmepriv->lock, &irqL);
13417 pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
13418 _exit_critical_bh(&pmlmepriv->lock, &irqL);
13421 err = rtw_createbss_cmd(padapter);
13422 if (err == _FAIL) return _FAIL;
13425 struct wlan_network *pcur_network;
13426 struct sta_info *psta;
13428 //3 create a new psta
13429 pcur_network = &pmlmepriv->cur_network;
13431 //clear psta in the cur_network, if any
13432 psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress);
13433 if (psta) rtw_free_stainfo(padapter, psta);
13435 psta = rtw_alloc_stainfo(&padapter->stapriv, pibss);
13436 if (psta == NULL) return _FAIL;
13438 //3 join psudo AdHoc
13439 pcur_network->join_res = 1;
13440 pcur_network->aid = psta->aid = 1;
13441 _rtw_memcpy(&pcur_network->network, pdev_network, get_WLAN_BSSID_EX_sz(pdev_network));
13443 // set msr to WIFI_FW_ADHOC_STATE
13445 Set_NETYPE0_MSR(padapter, WIFI_FW_ADHOC_STATE);
13450 val8 = rtw_read8(padapter, MSR);
13451 val8 &= 0xFC; // clear NETYPE0
13452 val8 |= WIFI_FW_ADHOC_STATE & 0x3;
13453 rtw_write8(padapter, MSR, val8);
13462 static struct xmit_frame* createloopbackpkt(PADAPTER padapter, u32 size)
13464 struct xmit_priv *pxmitpriv;
13465 struct xmit_frame *pframe;
13466 struct xmit_buf *pxmitbuf;
13467 struct pkt_attrib *pattrib;
13468 struct tx_desc *desc;
13469 u8 *pkt_start, *pkt_end, *ptr;
13470 struct rtw_ieee80211_hdr *hdr;
13475 if ((TXDESC_SIZE + WLANHDR_OFFSET + size) > MAX_XMITBUF_SZ) return NULL;
13477 pxmitpriv = &padapter->xmitpriv;
13480 //2 1. allocate xmit frame
13481 pframe = rtw_alloc_xmitframe(pxmitpriv);
13482 if (pframe == NULL) return NULL;
13483 pframe->padapter = padapter;
13485 //2 2. allocate xmit buffer
13486 _enter_critical_bh(&pxmitpriv->lock, &irqL);
13487 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
13488 _exit_critical_bh(&pxmitpriv->lock, &irqL);
13489 if (pxmitbuf == NULL) {
13490 rtw_free_xmitframe(pxmitpriv, pframe);
13494 pframe->pxmitbuf = pxmitbuf;
13495 pframe->buf_addr = pxmitbuf->pbuf;
13496 pxmitbuf->priv_data = pframe;
13498 //2 3. update_attrib()
13499 pattrib = &pframe->attrib;
13501 // init xmitframe attribute
13502 _rtw_memset(pattrib, 0, sizeof(struct pkt_attrib));
13504 pattrib->ether_type = 0x8723;
13505 _rtw_memcpy(pattrib->src, padapter->eeprompriv.mac_addr, ETH_ALEN);
13506 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
13507 _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);
13508 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
13510 // pattrib->dhcp_pkt = 0;
13511 // pattrib->pktlen = 0;
13512 pattrib->ack_policy = 0;
13513 // pattrib->pkt_hdrlen = ETH_HLEN;
13514 pattrib->hdrlen = WLAN_HDR_A3_LEN;
13515 pattrib->subtype = WIFI_DATA;
13516 pattrib->priority = 0;
13517 pattrib->qsel = pattrib->priority;
13518 // do_queue_select(padapter, pattrib);
13519 pattrib->nr_frags = 1;
13520 pattrib->encrypt = 0;
13521 pattrib->bswenc = _FALSE;
13522 pattrib->qos_en = _FALSE;
13524 bmcast = IS_MCAST(pattrib->ra);
13526 pattrib->mac_id = 1;
13527 pattrib->psta = rtw_get_bcmc_stainfo(padapter);
13529 pattrib->mac_id = 0;
13530 pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
13533 pattrib->pktlen = size;
13534 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen;
13536 //2 4. fill TX descriptor
13537 desc = (struct tx_desc*)pframe->buf_addr;
13538 _rtw_memset(desc, 0, TXDESC_SIZE);
13540 fill_default_txdesc(pframe, (u8*)desc);
13542 // Hw set sequence number
13543 ((PTXDESC)desc)->hwseq_en = 0; // HWSEQ_EN, 0:disable, 1:enable
13544 // ((PTXDESC)desc)->hwseq_sel = 0; // HWSEQ_SEL
13546 ((PTXDESC)desc)->disdatafb = 1;
13548 // convert to little endian
13549 desc->txdw0 = cpu_to_le32(desc->txdw0);
13550 desc->txdw1 = cpu_to_le32(desc->txdw1);
13551 desc->txdw2 = cpu_to_le32(desc->txdw2);
13552 desc->txdw3 = cpu_to_le32(desc->txdw3);
13553 desc->txdw4 = cpu_to_le32(desc->txdw4);
13554 desc->txdw5 = cpu_to_le32(desc->txdw5);
13555 desc->txdw6 = cpu_to_le32(desc->txdw6);
13556 desc->txdw7 = cpu_to_le32(desc->txdw7);
13557 #ifdef CONFIG_PCI_HCI
13558 desc->txdw8 = cpu_to_le32(desc->txdw8);
13559 desc->txdw9 = cpu_to_le32(desc->txdw9);
13560 desc->txdw10 = cpu_to_le32(desc->txdw10);
13561 desc->txdw11 = cpu_to_le32(desc->txdw11);
13562 desc->txdw12 = cpu_to_le32(desc->txdw12);
13563 desc->txdw13 = cpu_to_le32(desc->txdw13);
13564 desc->txdw14 = cpu_to_le32(desc->txdw14);
13565 desc->txdw15 = cpu_to_le32(desc->txdw15);
13568 cal_txdesc_chksum(desc);
13571 pkt_start = pframe->buf_addr + TXDESC_SIZE;
13572 pkt_end = pkt_start + pattrib->last_txcmdsz;
13574 //3 5.1. make wlan header, make_wlanhdr()
13575 hdr = (struct rtw_ieee80211_hdr *)pkt_start;
13576 SetFrameSubType(&hdr->frame_ctl, pattrib->subtype);
13577 _rtw_memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); // DA
13578 _rtw_memcpy(hdr->addr2, pattrib->src, ETH_ALEN); // SA
13579 _rtw_memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); // RA, BSSID
13581 //3 5.2. make payload
13582 ptr = pkt_start + pattrib->hdrlen;
13583 get_random_bytes(ptr, pkt_end - ptr);
13585 pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz;
13586 pxmitbuf->ptail += pxmitbuf->len;
13591 static void freeloopbackpkt(PADAPTER padapter, struct xmit_frame *pframe)
13593 struct xmit_priv *pxmitpriv;
13594 struct xmit_buf *pxmitbuf;
13597 pxmitpriv = &padapter->xmitpriv;
13598 pxmitbuf = pframe->pxmitbuf;
13600 rtw_free_xmitframe(pxmitpriv, pframe);
13601 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
13604 static void printdata(u8 *pbuf, u32 len)
13609 for (i = 0; (i+4) <= len; i+=4) {
13610 printk("%08X", *(u32*)(pbuf + i));
13611 if ((i+4) & 0x1F) printk(" ");
13617 #ifdef CONFIG_BIG_ENDIAN
13618 for (; i < len, i++)
13619 printk("%02X", pbuf+i);
13620 #else // CONFIG_LITTLE_ENDIAN
13623 _rtw_memcpy(&val, pbuf + i, len - i);
13624 printk("%8X", val);
13630 _rtw_memcpy(&val, pbuf+i, n);
13631 sprintf(str, "%08X", val);
13633 printk("%8s", str+n);
13635 #endif // CONFIG_LITTLE_ENDIAN
13640 static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz)
13642 PHAL_DATA_TYPE phal;
13643 struct recv_stat *prxstat;
13644 struct recv_stat report;
13645 PRXREPORT prxreport;
13651 prxstat = (struct recv_stat*)rxbuf;
13652 report.rxdw0 = le32_to_cpu(prxstat->rxdw0);
13653 report.rxdw1 = le32_to_cpu(prxstat->rxdw1);
13654 report.rxdw2 = le32_to_cpu(prxstat->rxdw2);
13655 report.rxdw3 = le32_to_cpu(prxstat->rxdw3);
13656 report.rxdw4 = le32_to_cpu(prxstat->rxdw4);
13657 report.rxdw5 = le32_to_cpu(prxstat->rxdw5);
13659 prxreport = (PRXREPORT)&report;
13660 drvinfosize = prxreport->drvinfosize << 3;
13661 rxpktsize = prxreport->pktlen;
13663 phal = GET_HAL_DATA(padapter);
13664 if (phal->ReceiveConfig & RCR_APPFCS) fcssize = IEEE80211_FCS_LEN;
13667 if ((txsz - TXDESC_SIZE) != (rxpktsize - fcssize)) {
13668 DBG_8192C("%s: ERROR! size not match tx/rx=%d/%d !\n",
13669 __func__, txsz - TXDESC_SIZE, rxpktsize - fcssize);
13672 ret = _rtw_memcmp(txbuf + TXDESC_SIZE,\
13673 rxbuf + RXDESC_SIZE + drvinfosize,\
13674 txsz - TXDESC_SIZE);
13675 if (ret == _FALSE) {
13676 DBG_8192C("%s: ERROR! pkt content mismatch!\n", __func__);
13682 DBG_8192C("\n%s: TX PKT total=%d, desc=%d, content=%d\n",
13683 __func__, txsz, TXDESC_SIZE, txsz - TXDESC_SIZE);
13684 DBG_8192C("%s: TX DESC size=%d\n", __func__, TXDESC_SIZE);
13685 printdata(txbuf, TXDESC_SIZE);
13686 DBG_8192C("%s: TX content size=%d\n", __func__, txsz - TXDESC_SIZE);
13687 printdata(txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE);
13689 DBG_8192C("\n%s: RX PKT read=%d offset=%d(%d,%d) content=%d\n",
13690 __func__, rxsz, RXDESC_SIZE + drvinfosize, RXDESC_SIZE, drvinfosize, rxpktsize);
13691 if (rxpktsize != 0)
13693 DBG_8192C("%s: RX DESC size=%d\n", __func__, RXDESC_SIZE);
13694 printdata(rxbuf, RXDESC_SIZE);
13695 DBG_8192C("%s: RX drvinfo size=%d\n", __func__, drvinfosize);
13696 printdata(rxbuf + RXDESC_SIZE, drvinfosize);
13697 DBG_8192C("%s: RX content size=%d\n", __func__, rxpktsize);
13698 printdata(rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize);
13700 DBG_8192C("%s: RX data size=%d\n", __func__, rxsz);
13701 printdata(rxbuf, rxsz);
13708 thread_return lbk_thread(thread_context context)
13712 PLOOPBACKDATA ploopback;
13713 struct xmit_frame *pxmitframe;
13714 u32 cnt, ok, fail, headerlen;
13719 padapter = (PADAPTER)context;
13720 ploopback = padapter->ploopback;
13721 if (ploopback == NULL) return -1;
13726 daemonize("%s", "RTW_LBK_THREAD");
13727 allow_signal(SIGTERM);
13730 if (ploopback->size == 0) {
13731 get_random_bytes(&pktsize, 4);
13732 pktsize = (pktsize % 1535) + 1; // 1~1535
13734 pktsize = ploopback->size;
13736 pxmitframe = createloopbackpkt(padapter, pktsize);
13737 if (pxmitframe == NULL) {
13738 sprintf(ploopback->msg, "loopback FAIL! 3. create Packet FAIL!");
13742 ploopback->txsize = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz;
13743 _rtw_memcpy(ploopback->txbuf, pxmitframe->buf_addr, ploopback->txsize);
13744 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
13746 DBG_8192C("%s: wirte port cnt=%d size=%d\n", __func__, cnt, ploopback->txsize);
13747 pxmitframe->pxmitbuf->pdata = ploopback->txbuf;
13748 rtw_write_port(padapter, ff_hwaddr, ploopback->txsize, (u8 *)pxmitframe->pxmitbuf);
13751 _rtw_down_sema(&ploopback->sema);
13753 err = pktcmp(padapter, ploopback->txbuf, ploopback->txsize, ploopback->rxbuf, ploopback->rxsize);
13759 ploopback->txsize = 0;
13760 _rtw_memset(ploopback->txbuf, 0, 0x8000);
13761 ploopback->rxsize = 0;
13762 _rtw_memset(ploopback->rxbuf, 0, 0x8000);
13764 freeloopbackpkt(padapter, pxmitframe);
13767 if (signal_pending(current)) {
13768 flush_signals(current);
13771 if ((ploopback->bstop == _TRUE) ||
13772 ((ploopback->cnt != 0) && (ploopback->cnt == cnt)))
13774 u32 ok_rate, fail_rate, all;
13776 ok_rate = (ok*100)/all;
13777 fail_rate = (fail*100)/all;
13778 sprintf(ploopback->msg,\
13779 "loopback result: ok=%d%%(%d/%d),error=%d%%(%d/%d)",\
13780 ok_rate, ok, all, fail_rate, fail, all);
13785 ploopback->bstop = _TRUE;
13790 static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8* pmsg)
13792 PLOOPBACKDATA ploopback;
13797 ploopback = padapter->ploopback;
13801 if (ploopback->bstop == _FALSE) {
13802 ploopback->bstop = _TRUE;
13803 _rtw_up_sema(&ploopback->sema);
13807 len = strlen(ploopback->msg);
13811 _rtw_memcpy(pmsg, ploopback->msg, len+1);
13812 freeLoopback(padapter);
13817 // disable dynamic algorithm
13819 u32 DMFlag = DYNAMIC_FUNC_DISABLE;
13820 rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8*)&DMFlag);
13823 // create pseudo ad-hoc connection
13824 err = initpseudoadhoc(padapter);
13825 if (err == _FAIL) {
13826 sprintf(pmsg, "loopback FAIL! 1.1 init ad-hoc FAIL!");
13830 err = createpseudoadhoc(padapter);
13831 if (err == _FAIL) {
13832 sprintf(pmsg, "loopback FAIL! 1.2 create ad-hoc master FAIL!");
13836 err = initLoopback(padapter);
13838 sprintf(pmsg, "loopback FAIL! 2. init FAIL! error code=%d", err);
13842 ploopback = padapter->ploopback;
13844 ploopback->bstop = _FALSE;
13845 ploopback->cnt = cnt;
13846 ploopback->size = size;
13847 ploopback->lbkthread = kthread_run(lbk_thread, padapter, "RTW_LBK_THREAD");
13848 if (IS_ERR(padapter->lbkthread))
13850 freeLoopback(padapter);
13851 sprintf(pmsg, "loopback start FAIL! cnt=%d", cnt);
13855 sprintf(pmsg, "loopback start! cnt=%d", cnt);
13857 #endif // CONFIG_MAC_LOOPBACK_DRIVER
13859 static int rtw_test(
13860 struct net_device *dev,
13861 struct iw_request_info *info,
13862 union iwreq_data *wrqu, char *extra)
13868 PADAPTER padapter = rtw_netdev_priv(dev);
13871 DBG_871X("+%s\n", __func__);
13872 len = wrqu->data.length;
13874 pbuf = (u8*)rtw_zmalloc(len);
13875 if (pbuf == NULL) {
13876 DBG_871X("%s: no memory!\n", __func__);
13880 if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
13881 rtw_mfree(pbuf, len);
13882 DBG_871X("%s: copy from user fail!\n", __func__);
13885 DBG_871X("%s: string=\"%s\"\n", __func__, pbuf);
13887 ptmp = (char*)pbuf;
13888 pch = strsep(&ptmp, delim);
13889 if ((pch == NULL) || (strlen(pch) == 0)) {
13890 rtw_mfree(pbuf, len);
13891 DBG_871X("%s: parameter error(level 1)!\n", __func__);
13895 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
13896 if (strcmp(pch, "loopback") == 0)
13901 pch = strsep(&ptmp, delim);
13902 if ((pch == NULL) || (strlen(pch) == 0)) {
13903 rtw_mfree(pbuf, len);
13904 DBG_871X("%s: parameter error(level 2)!\n", __func__);
13908 sscanf(pch, "%d", &cnt);
13909 DBG_871X("%s: loopback cnt=%d\n", __func__, cnt);
13911 pch = strsep(&ptmp, delim);
13912 if ((pch == NULL) || (strlen(pch) == 0)) {
13913 rtw_mfree(pbuf, len);
13914 DBG_871X("%s: parameter error(level 2)!\n", __func__);
13918 sscanf(pch, "%d", &size);
13919 DBG_871X("%s: loopback size=%d\n", __func__, size);
13921 loopbackTest(padapter, cnt, size, extra);
13922 wrqu->data.length = strlen(extra) + 1;
13924 rtw_mfree(pbuf, len);
13930 //#ifdef CONFIG_RTL8723A
13931 if (strcmp(pch, "poweron") == 0)
13935 ret = _InitPowerOn(padapter);
13936 DBG_871X("%s: power on %s\n", __func__, (_FAIL==ret) ? "FAIL!":"OK.");
13937 sprintf(extra, "Power ON %s", (_FAIL==ret) ? "FAIL!":"OK.");
13938 wrqu->data.length = strlen(extra) + 1;
13940 rtw_mfree(pbuf, len);
13944 if (strcmp(pch, "dlfw") == 0)
13948 ret = rtl8723a_FirmwareDownload(padapter);
13949 DBG_871X("%s: download FW %s\n", __func__, (_FAIL==ret) ? "FAIL!":"OK.");
13950 sprintf(extra, "download FW %s", (_FAIL==ret) ? "FAIL!":"OK.");
13951 wrqu->data.length = strlen(extra) + 1;
13953 rtw_mfree(pbuf, len);
13958 #ifdef CONFIG_BT_COEXIST
13959 if (strcmp(pch, "bton") == 0)
13961 rtw_btcoex_SetManualControl(padapter, _FALSE);
13964 if (strcmp(pch, "btoff") == 0)
13966 rtw_btcoex_SetManualControl(padapter, _TRUE);
13969 if (strcmp(pch, "h2c") == 0)
13980 pch = strsep(&ptmp, delim);
13981 if ((pch == NULL) || (strlen(pch) == 0))
13984 sscanf(pch, "%x", &tmp);
13985 param[count++] = (u8)tmp;
13986 } while (count < 8);
13989 rtw_mfree(pbuf, len);
13990 DBG_871X("%s: parameter error(level 2)!\n", __func__);
13994 ret = rtw_hal_fill_h2c_cmd(padapter, param[0], count-1, ¶m[1]);
13996 pos = sprintf(extra, "H2C ID=0x%02x content=", param[0]);
13997 for (i=1; i<count; i++) {
13998 pos += sprintf(extra+pos, "%02x,", param[i]);
14002 pos += sprintf(extra+pos, " %s", ret==_FAIL?"FAIL":"OK");
14004 wrqu->data.length = strlen(extra) + 1;
14006 #endif // CONFIG_BT_COEXIST
14008 rtw_mfree(pbuf, len);
14012 static iw_handler rtw_handlers[] =
14014 NULL, /* SIOCSIWCOMMIT */
14015 rtw_wx_get_name, /* SIOCGIWNAME */
14016 dummy, /* SIOCSIWNWID */
14017 dummy, /* SIOCGIWNWID */
14018 rtw_wx_set_freq, /* SIOCSIWFREQ */
14019 rtw_wx_get_freq, /* SIOCGIWFREQ */
14020 rtw_wx_set_mode, /* SIOCSIWMODE */
14021 rtw_wx_get_mode, /* SIOCGIWMODE */
14022 dummy, /* SIOCSIWSENS */
14023 rtw_wx_get_sens, /* SIOCGIWSENS */
14024 NULL, /* SIOCSIWRANGE */
14025 rtw_wx_get_range, /* SIOCGIWRANGE */
14026 rtw_wx_set_priv, /* SIOCSIWPRIV */
14027 NULL, /* SIOCGIWPRIV */
14028 NULL, /* SIOCSIWSTATS */
14029 NULL, /* SIOCGIWSTATS */
14030 dummy, /* SIOCSIWSPY */
14031 dummy, /* SIOCGIWSPY */
14032 NULL, /* SIOCGIWTHRSPY */
14033 NULL, /* SIOCWIWTHRSPY */
14034 rtw_wx_set_wap, /* SIOCSIWAP */
14035 rtw_wx_get_wap, /* SIOCGIWAP */
14036 rtw_wx_set_mlme, /* request MLME operation; uses struct iw_mlme */
14037 dummy, /* SIOCGIWAPLIST -- depricated */
14038 rtw_wx_set_scan, /* SIOCSIWSCAN */
14039 rtw_wx_get_scan, /* SIOCGIWSCAN */
14040 rtw_wx_set_essid, /* SIOCSIWESSID */
14041 rtw_wx_get_essid, /* SIOCGIWESSID */
14042 dummy, /* SIOCSIWNICKN */
14043 rtw_wx_get_nick, /* SIOCGIWNICKN */
14044 NULL, /* -- hole -- */
14045 NULL, /* -- hole -- */
14046 rtw_wx_set_rate, /* SIOCSIWRATE */
14047 rtw_wx_get_rate, /* SIOCGIWRATE */
14048 rtw_wx_set_rts, /* SIOCSIWRTS */
14049 rtw_wx_get_rts, /* SIOCGIWRTS */
14050 rtw_wx_set_frag, /* SIOCSIWFRAG */
14051 rtw_wx_get_frag, /* SIOCGIWFRAG */
14052 dummy, /* SIOCSIWTXPOW */
14053 dummy, /* SIOCGIWTXPOW */
14054 dummy, /* SIOCSIWRETRY */
14055 rtw_wx_get_retry, /* SIOCGIWRETRY */
14056 rtw_wx_set_enc, /* SIOCSIWENCODE */
14057 rtw_wx_get_enc, /* SIOCGIWENCODE */
14058 dummy, /* SIOCSIWPOWER */
14059 rtw_wx_get_power, /* SIOCGIWPOWER */
14060 NULL, /*---hole---*/
14061 NULL, /*---hole---*/
14062 rtw_wx_set_gen_ie, /* SIOCSIWGENIE */
14063 NULL, /* SIOCGWGENIE */
14064 rtw_wx_set_auth, /* SIOCSIWAUTH */
14065 NULL, /* SIOCGIWAUTH */
14066 rtw_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
14067 NULL, /* SIOCGIWENCODEEXT */
14068 rtw_wx_set_pmkid, /* SIOCSIWPMKSA */
14069 NULL, /*---hole---*/
14073 //defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT)
14074 static const struct iw_priv_args rtw_private_args[] =
14076 { SIOCIWFIRSTPRIV + 0x00, IW_PRIV_TYPE_CHAR | 1024, 0 , ""}, //set
14077 { SIOCIWFIRSTPRIV + 0x01, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , ""},//get
14078 /* --- sub-ioctls definitions --- */
14079 { MP_START , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_start" }, //set
14080 { MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara" },//get
14081 { MP_STOP , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_stop" }, //set
14082 { MP_CHANNEL , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel" },//get
14083 { MP_BANDWIDTH , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_bandwidth"}, //set
14084 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },//get
14085 { MP_RESET_STATS , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_reset_stats"},
14086 { MP_QUERY , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "mp_query"}, //get
14087 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
14088 { READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" },
14089 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
14090 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
14091 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
14092 { READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" },
14093 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
14094 { MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"},
14095 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
14096 { MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" },
14097 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
14098 { MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},
14099 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
14100 { MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},
14101 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
14102 { MP_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},
14103 { WRITE_REG, IW_PRIV_TYPE_CHAR | 1024, 0,"write_reg"},//set
14104 { MP_NULL, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL" },
14105 { WRITE_RF, IW_PRIV_TYPE_CHAR | 1024, 0,"write_rf"},//set
14106 { MP_NULL, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL" },
14107 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
14108 { MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},
14109 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
14110 { MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},
14111 { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set
14112 { MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},
14113 { EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set" },
14114 { EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get" },
14115 { MP_PWRTRK , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_pwrtrk"},
14116 { MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery" },
14117 { MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"}, // mp_ioctl
14118 { MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_setrfpath" },
14119 #ifdef CONFIG_RTL8723A
14120 { MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" },
14122 { SIOCIWFIRSTPRIV + 0x02, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "test"},//set
14124 static iw_handler rtw_private_handler[] =
14129 #else // not inlucde MP
14131 static const struct iw_priv_args rtw_private_args[] = {
14133 SIOCIWFIRSTPRIV + 0x0,
14134 IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
14137 SIOCIWFIRSTPRIV + 0x1,
14138 IW_PRIV_TYPE_CHAR | 0x7FF,
14139 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
14142 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
14145 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
14148 SIOCIWFIRSTPRIV + 0x4,
14149 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
14152 SIOCIWFIRSTPRIV + 0x5,
14153 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
14156 SIOCIWFIRSTPRIV + 0x6,
14157 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
14159 //for PLATFORM_MT53XX
14161 SIOCIWFIRSTPRIV + 0x7,
14162 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
14165 SIOCIWFIRSTPRIV + 0x8,
14166 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
14169 SIOCIWFIRSTPRIV + 0x9,
14170 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
14173 //for RTK_DMP_PLATFORM
14175 SIOCIWFIRSTPRIV + 0xA,
14176 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
14180 SIOCIWFIRSTPRIV + 0xB,
14181 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
14184 SIOCIWFIRSTPRIV + 0xC,
14185 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
14188 SIOCIWFIRSTPRIV + 0xD,
14189 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
14193 SIOCIWFIRSTPRIV + 0xE,0,0, "wowlan_ctrl"
14197 SIOCIWFIRSTPRIV + 0x10,
14198 IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set"
14201 SIOCIWFIRSTPRIV + 0x11,
14202 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get"
14205 SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL"
14208 SIOCIWFIRSTPRIV + 0x13,
14209 IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2"
14212 SIOCIWFIRSTPRIV + 0x14,
14213 IW_PRIV_TYPE_CHAR | 64, 0, "tdls"
14216 SIOCIWFIRSTPRIV + 0x15,
14217 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "tdls_get"
14220 SIOCIWFIRSTPRIV + 0x16,
14221 IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
14224 {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"},
14225 #ifdef CONFIG_MP_INCLUDED
14226 {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"},
14227 {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL"},
14229 {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"},
14230 {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
14233 SIOCIWFIRSTPRIV + 0x1D,
14234 IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
14237 #ifdef CONFIG_INTEL_WIDI
14239 SIOCIWFIRSTPRIV + 0x1E,
14240 IW_PRIV_TYPE_CHAR | 1024, 0, "widi_set"
14243 SIOCIWFIRSTPRIV + 0x1F,
14244 IW_PRIV_TYPE_CHAR | 128, 0, "widi_prob_req"
14246 #endif // CONFIG_INTEL_WIDI
14248 #ifdef CONFIG_MP_INCLUDED
14249 { SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0 , ""}, //set
14250 { SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , ""},//get
14251 /* --- sub-ioctls definitions --- */
14252 { MP_START , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_start" }, //set
14253 { MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara" },//get
14254 { MP_STOP , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_stop" }, //set
14255 { MP_CHANNEL , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel" },//get
14256 { MP_BANDWIDTH , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_bandwidth"}, //set
14257 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },//get
14258 { MP_RESET_STATS , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_reset_stats"},
14259 { MP_QUERY , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "mp_query"}, //get
14260 { READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" },
14261 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
14262 { READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" },
14263 { MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"},
14264 { MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" },
14265 { MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},
14266 { MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},
14267 { MP_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},
14268 { WRITE_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg" },
14269 { WRITE_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf" },
14270 { MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},
14271 { MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},
14272 { MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},
14273 { EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_set" },
14274 { EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get" },
14275 { MP_PWRTRK , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_pwrtrk"},
14276 { MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery" },
14277 { MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"}, // mp_ioctl
14278 { MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_setrfpath" },
14279 { MP_PwrCtlDM, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrctldm" },
14280 { MP_GET_TXPOWER_INX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_get_txpower" },
14282 #if defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B)
14283 { MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" },
14284 { MP_DISABLE_BT_COEXIST, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_disa_btcoex"},
14286 { CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"},
14288 #ifdef CONFIG_WOWLAN
14289 { MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_mode" }, //set
14291 #ifdef CONFIG_AP_WOWLAN
14292 { MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_mode" }, //set
14296 static iw_handler rtw_private_handler[] =
14298 rtw_wx_write32, //0x00
14299 rtw_wx_read32, //0x01
14300 rtw_drvext_hdl, //0x02
14301 rtw_mp_ioctl_hdl, //0x03
14303 // for MM DTV platform
14304 rtw_get_ap_info, //0x04
14306 rtw_set_pid, //0x05
14307 rtw_wps_start, //0x06
14309 // for PLATFORM_MT53XX
14310 rtw_wx_get_sensitivity, //0x07
14311 rtw_wx_set_mtk_wps_probe_ie, //0x08
14312 rtw_wx_set_mtk_wps_ie, //0x09
14314 // for RTK_DMP_PLATFORM
14315 // Set Channel depend on the country code
14316 rtw_wx_set_channel_plan, //0x0A
14318 rtw_dbg_port, //0x0B
14319 rtw_wx_write_rf, //0x0C
14320 rtw_wx_read_rf, //0x0D
14321 #ifdef CONFIG_MP_INCLUDED
14325 rtw_wx_priv_null, //0x0E
14326 rtw_wx_priv_null, //0x0F
14328 rtw_p2p_set, //0x10
14329 rtw_p2p_get, //0x11
14331 rtw_p2p_get2, //0x13
14334 rtw_tdls_get, //0x15
14337 rtw_wx_priv_null, //0x17
14338 rtw_rereg_nd_name, //0x18
14339 rtw_wx_priv_null, //0x19
14340 #ifdef CONFIG_MP_INCLUDED
14341 rtw_wx_priv_null, //0x1A
14342 rtw_wx_priv_null, //0x1B
14344 rtw_mp_efuse_set, //0x1A
14345 rtw_mp_efuse_get, //0x1B
14347 NULL, // 0x1C is reserved for hostapd
14349 #ifdef CONFIG_INTEL_WIDI
14350 rtw_widi_set, //0x1E
14351 rtw_widi_set_probe_request, //0x1F
14352 #endif // CONFIG_INTEL_WIDI
14355 #endif // #if defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT)
14357 #if WIRELESS_EXT >= 17
14358 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
14360 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
14361 struct iw_statistics *piwstats=&padapter->iwstats;
14366 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != _TRUE)
14368 piwstats->qual.qual = 0;
14369 piwstats->qual.level = 0;
14370 piwstats->qual.noise = 0;
14371 //DBG_871X("No link level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
14374 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
14375 tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
14377 #ifdef CONFIG_SKIP_SIGNAL_SCALE_MAPPING
14379 /* Do signal scale mapping when using percentage as the unit of signal strength, since the scale mapping is skipped in odm */
14381 HAL_DATA_TYPE *pHal = GET_HAL_DATA(padapter);
14383 tmp_level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, padapter->recvpriv.signal_strength);
14386 tmp_level = padapter->recvpriv.signal_strength;
14390 tmp_qual = padapter->recvpriv.signal_qual;
14391 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
14392 if(rtw_linked_check(padapter)){
14393 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14394 struct noise_info info;
14395 info.bPauseDIG = _TRUE;
14396 info.IGIValue = 0x1e;
14397 info.max_time = 100;//ms
14398 info.chan = pmlmeext->cur_channel ;//rtw_get_oper_ch(padapter);
14399 rtw_ps_deny(padapter, PS_DENY_IOCTL);
14400 LeaveAllPowerSaveModeDirect(padapter);
14402 rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&info, _FALSE);
14403 //ODM_InbandNoise_Monitor(podmpriv,_TRUE,0x20,100);
14404 rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
14405 rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&(info.chan), &(padapter->recvpriv.noise));
14406 DBG_871X("chan:%d,noise_level:%d\n",info.chan,padapter->recvpriv.noise);
14409 tmp_noise = padapter->recvpriv.noise;
14410 DBG_871X("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise,padapter->recvpriv.rssi);
14412 piwstats->qual.level = tmp_level;
14413 piwstats->qual.qual = tmp_qual;
14414 piwstats->qual.noise = tmp_noise;
14416 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
14417 piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;//|IW_QUAL_DBM;
14419 #ifdef RTK_DMP_PLATFORM
14420 //IW_QUAL_DBM= 0x8, if driver use this flag, wireless extension will show value of dbm.
14421 //remove this flag for show percentage 0~100
14422 piwstats->qual.updated = 0x07;
14424 piwstats->qual.updated = 0x0f;
14428 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
14429 piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM;
14432 return &padapter->iwstats;
14436 #ifdef CONFIG_WIRELESS_EXT
14437 struct iw_handler_def rtw_handlers_def =
14439 .standard = rtw_handlers,
14440 .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
14441 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) || defined(CONFIG_WEXT_PRIV)
14442 .private = rtw_private_handler,
14443 .private_args = (struct iw_priv_args *)rtw_private_args,
14444 .num_private = sizeof(rtw_private_handler) / sizeof(iw_handler),
14445 .num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args),
14447 #if WIRELESS_EXT >= 17
14448 .get_wireless_stats = rtw_get_wireless_stats,
14453 // copy from net/wireless/wext.c start
14454 /* ---------------------------------------------------------------- */
14456 * Calculate size of private arguments
14458 static const char iw_priv_type_size[] = {
14459 0, /* IW_PRIV_TYPE_NONE */
14460 1, /* IW_PRIV_TYPE_BYTE */
14461 1, /* IW_PRIV_TYPE_CHAR */
14462 0, /* Not defined */
14463 sizeof(__u32), /* IW_PRIV_TYPE_INT */
14464 sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */
14465 sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */
14466 0, /* Not defined */
14469 static int get_priv_size(__u16 args)
14471 int num = args & IW_PRIV_SIZE_MASK;
14472 int type = (args & IW_PRIV_TYPE_MASK) >> 12;
14474 return num * iw_priv_type_size[type];
14476 // copy from net/wireless/wext.c end
14478 static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)
14483 const char delim[] = " ";
14485 u32 output_len = 0;
14488 u32 buffer_len = 0;
14490 u8 cmdname[17] = {0}; // IFNAMSIZ+1
14494 u32 extra_size = 0;
14497 const iw_handler *priv; /* Private ioctl */
14498 const struct iw_priv_args *priv_args; /* Private ioctl description */
14499 u32 num_priv; /* Number of ioctl */
14500 u32 num_priv_args; /* Number of descriptions */
14501 iw_handler handler;
14503 int subcmd = 0; /* sub-ioctl index */
14504 int offset = 0; /* Space for sub-ioctl index */
14506 union iwreq_data wdata;
14509 _rtw_memcpy(&wdata, wrq_data, sizeof(wdata));
14512 input = rtw_zmalloc(input_len);
14515 if (copy_from_user(input, wdata.data.pointer, input_len)) {
14520 len = strlen(input);
14522 sscanf(ptr, "%16s", cmdname);
14523 cmdlen = strlen(cmdname);
14524 DBG_8192C("%s: cmd=%s\n", __func__, cmdname);
14526 // skip command string
14528 cmdlen += 1; // skip one space
14531 DBG_8192C("%s: parameters=%s\n", __func__, ptr);
14533 priv = rtw_private_handler;
14534 priv_args = rtw_private_args;
14535 num_priv = sizeof(rtw_private_handler) / sizeof(iw_handler);
14536 num_priv_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args);
14538 if (num_priv_args == 0) {
14543 /* Search the correct ioctl */
14545 while((++k < num_priv_args) && strcmp(priv_args[k].name, cmdname));
14547 /* If not found... */
14548 if (k == num_priv_args) {
14553 /* Watch out for sub-ioctls ! */
14554 if (priv_args[k].cmd < SIOCDEVPRIVATE)
14558 /* Find the matching *real* ioctl */
14559 while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||
14560 (priv_args[j].set_args != priv_args[k].set_args) ||
14561 (priv_args[j].get_args != priv_args[k].get_args)));
14563 /* If not found... */
14564 if (j == num_priv_args) {
14569 /* Save sub-ioctl number */
14570 subcmd = priv_args[k].cmd;
14571 /* Reserve one int (simplify alignment issues) */
14572 offset = sizeof(__u32);
14573 /* Use real ioctl definition from now on */
14577 buffer = rtw_zmalloc(4096);
14578 if (NULL == buffer) {
14583 /* If we have to set some data */
14584 if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&
14585 (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
14589 switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK)
14591 case IW_PRIV_TYPE_BYTE:
14595 str = strsep(&ptr, delim);
14596 if (NULL == str) break;
14597 sscanf(str, "%i", &temp);
14598 buffer[count++] = (u8)temp;
14600 buffer_len = count;
14602 /* Number of args to fetch */
14603 wdata.data.length = count;
14604 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
14605 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
14609 case IW_PRIV_TYPE_INT:
14613 str = strsep(&ptr, delim);
14614 if (NULL == str) break;
14615 sscanf(str, "%i", &temp);
14616 ((s32*)buffer)[count++] = (s32)temp;
14618 buffer_len = count * sizeof(s32);
14620 /* Number of args to fetch */
14621 wdata.data.length = count;
14622 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
14623 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
14627 case IW_PRIV_TYPE_CHAR:
14630 /* Size of the string to fetch */
14631 wdata.data.length = len;
14632 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
14633 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
14636 _rtw_memcpy(buffer, ptr, wdata.data.length);
14640 wdata.data.length = 1;
14643 buffer_len = wdata.data.length;
14647 DBG_8192C("%s: Not yet implemented...\n", __func__);
14652 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
14653 (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK)))
14655 DBG_8192C("%s: The command %s needs exactly %d argument(s)...\n",
14656 __func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK);
14660 } /* if args to set */
14663 wdata.data.length = 0L;
14666 /* Those two tests are important. They define how the driver
14667 * will have to handle the data */
14668 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
14669 ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ))
14671 /* First case : all SET args fit within wrq */
14673 wdata.mode = subcmd;
14674 _rtw_memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
14678 if ((priv_args[k].set_args == 0) &&
14679 (priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
14680 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
14682 /* Second case : no SET args, GET args fit within wrq */
14684 wdata.mode = subcmd;
14688 /* Third case : args won't fit in wrq, or variable number of args */
14689 if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {
14693 wdata.data.flags = subcmd;
14697 rtw_mfree(input, input_len);
14701 if (IW_IS_SET(priv_args[k].cmd))
14703 /* Size of set arguments */
14704 extra_size = get_priv_size(priv_args[k].set_args);
14706 /* Does it fits in iwr ? */
14707 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
14708 ((extra_size + offset) <= IFNAMSIZ))
14711 /* Size of get arguments */
14712 extra_size = get_priv_size(priv_args[k].get_args);
14714 /* Does it fits in iwr ? */
14715 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
14716 (extra_size <= IFNAMSIZ))
14720 if (extra_size == 0) {
14721 extra = (u8*)&wdata;
14722 rtw_mfree(buffer, 4096);
14727 handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];
14728 err = handler(dev, NULL, &wdata, extra);
14730 /* If we have to get some data */
14731 if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&
14732 (priv_args[k].get_args & IW_PRIV_SIZE_MASK))
14735 int n = 0; /* number of args */
14738 /* Check where is the returned data */
14739 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
14740 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
14741 n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;
14743 n = wdata.data.length;
14745 output = rtw_zmalloc(4096);
14746 if (NULL == output) {
14751 switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK)
14753 case IW_PRIV_TYPE_BYTE:
14755 for (j = 0; j < n; j++)
14757 sprintf(str, "%d ", extra[j]);
14759 output_len = strlen(output);
14760 if ((output_len + len + 1) > 4096) {
14764 _rtw_memcpy(output+output_len, str, len);
14768 case IW_PRIV_TYPE_INT:
14770 for (j = 0; j < n; j++)
14772 sprintf(str, "%d ", ((__s32*)extra)[j]);
14774 output_len = strlen(output);
14775 if ((output_len + len + 1) > 4096) {
14779 _rtw_memcpy(output+output_len, str, len);
14783 case IW_PRIV_TYPE_CHAR:
14785 _rtw_memcpy(output, extra, n);
14789 DBG_8192C("%s: Not yet implemented...\n", __func__);
14794 output_len = strlen(output) + 1;
14795 wrq_data->data.length = output_len;
14796 if (copy_to_user(wrq_data->data.pointer, output, output_len)) {
14800 } /* if args to set */
14803 wrq_data->data.length = 0;
14808 rtw_mfree(input, input_len);
14810 rtw_mfree(buffer, 4096);
14812 rtw_mfree(output, 4096);
14817 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
14819 struct iwreq *wrq = (struct iwreq *)rq;
14824 case RTL_IOCTL_WPA_SUPPLICANT:
14825 ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
14827 #ifdef CONFIG_AP_MODE
14828 case RTL_IOCTL_HOSTAPD:
14829 ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
14831 #ifdef CONFIG_NO_WIRELESS_HANDLERS
14833 ret = rtw_wx_set_mode(dev, NULL, &wrq->u, NULL);
14836 #endif // CONFIG_AP_MODE
14837 case SIOCDEVPRIVATE:
14838 ret = rtw_ioctl_wext_private(dev, &wrq->u);
14840 case (SIOCDEVPRIVATE+1):
14841 ret = rtw_android_priv_cmd(dev, rq, cmd);