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_
23 #include <osdep_service.h>
24 #include <drv_types.h>
25 #include <wlan_bssdef.h>
26 #include <rtw_debug.h>
27 #include <linux/ieee80211.h>
30 #include <rtw_mlme_ext.h>
31 #include <rtw_ioctl.h>
32 #include <rtw_ioctl_set.h>
35 #include <rtw_version.h>
37 #ifdef CONFIG_RTL8192C
38 #include <rtl8192c_hal.h>
40 #ifdef CONFIG_RTL8192D
41 #include <rtl8192d_hal.h>
43 #ifdef CONFIG_RTL8723A
44 #include <rtl8723a_pg.h>
45 #include <rtl8723a_hal.h>
47 #ifdef CONFIG_RTL8188E
48 #include <rtl8188e_hal.h>
51 extern s32 FillH2CCmd(struct rtw_adapter *padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer);
53 #define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
55 #define SCAN_ITEM_SIZE 768
56 #define MAX_CUSTOM_LEN 64
59 #ifdef CONFIG_GLOBAL_UI_PID
64 #define WEXT_CSCAN_AMOUNT 9
65 #define WEXT_CSCAN_BUF_LEN 360
66 #define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
67 #define WEXT_CSCAN_HEADER_SIZE 12
68 #define WEXT_CSCAN_SSID_SECTION 'S'
69 #define WEXT_CSCAN_CHANNEL_SECTION 'C'
70 #define WEXT_CSCAN_NPROBE_SECTION 'N'
71 #define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
72 #define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
73 #define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
74 #define WEXT_CSCAN_TYPE_SECTION 'T'
77 extern u8 key_2char2num(u8 hch, u8 lch);
78 extern u8 str_2char2num(u8 hch, u8 lch);
79 extern u8 convert_ip_addr(u8 hch, u8 mch, u8 lch);
97 static const char *const iw_operation_mode[] =
108 static int hex2num_i(char c)
110 if (c >= '0' && c <= '9')
112 if (c >= 'a' && c <= 'f')
114 if (c >= 'A' && c <= 'F')
119 static int hex2byte_i(const char *hex)
122 a = hex2num_i(*hex++);
125 b = hex2num_i(*hex++);
132 * hwaddr_aton - Convert ASCII string to MAC address
133 * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
134 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
135 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
137 static int hwaddr_aton_i(const char *txt, u8 *addr)
141 for (i = 0; i < 6; i++) {
144 a = hex2num_i(*txt++);
147 b = hex2num_i(*txt++);
150 *addr++ = (a << 4) | b;
151 if (i < 5 && *txt++ != ':')
158 static void indicate_wx_custom_event(struct rtw_adapter *padapter, char *msg)
161 union iwreq_data wrqu;
163 if (strlen(msg) > IW_CUSTOM_MAX) {
164 DBG_8723A("%s strlen(msg):%zu > IW_CUSTOM_MAX:%u\n",
165 __func__ , strlen(msg), IW_CUSTOM_MAX);
169 buff = kzalloc(IW_CUSTOM_MAX + 1, GFP_KERNEL);
173 memcpy(buff, msg, strlen(msg));
175 memset(&wrqu, 0, sizeof(wrqu));
176 wrqu.data.length = strlen(msg);
178 DBG_8723A("%s %s\n", __func__, buff);
179 #ifndef CONFIG_IOCTL_CFG80211
180 wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
187 static void request_wps_pbc_event(struct rtw_adapter *padapter)
190 union iwreq_data wrqu;
192 buff = kzalloc(IW_CUSTOM_MAX, GFP_KERNEL);
197 p += sprintf(p, "WPS_PBC_START.request=TRUE");
199 memset(&wrqu, 0, sizeof(wrqu));
201 wrqu.data.length = p-buff;
203 wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ? wrqu.data.length:IW_CUSTOM_MAX;
205 DBG_8723A("%s\n", __func__);
207 #ifndef CONFIG_IOCTL_CFG80211
208 wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
216 void indicate_wx_scan_complete_event(struct rtw_adapter *padapter)
218 union iwreq_data wrqu;
219 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
221 memset(&wrqu, 0, sizeof(union iwreq_data));
223 //DBG_8723A("+rtw_indicate_wx_scan_complete_event\n");
224 #ifndef CONFIG_IOCTL_CFG80211
225 wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
230 void rtw_indicate_wx_assoc_event(struct rtw_adapter *padapter)
232 union iwreq_data wrqu;
233 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
235 memset(&wrqu, 0, sizeof(union iwreq_data));
237 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
239 memcpy(wrqu.ap_addr.sa_data,
240 pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
242 DBG_8723A_LEVEL(_drv_always_, "assoc success\n");
243 #ifndef CONFIG_IOCTL_CFG80211
244 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
248 void rtw_indicate_wx_disassoc_event(struct rtw_adapter *padapter)
250 union iwreq_data wrqu;
252 memset(&wrqu, 0, sizeof(union iwreq_data));
254 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
255 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
257 #ifndef CONFIG_IOCTL_CFG80211
258 DBG_8723A_LEVEL(_drv_always_, "indicate disassoc\n");
259 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
264 uint rtw_is_cckrates_included(u8 *rate)
270 if ( (((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) ||
271 (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22) )
279 uint rtw_is_cckratesonly_included(u8 *rate)
285 if ( (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
286 (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22) )
295 static char *translate_scan(struct rtw_adapter *padapter,
296 struct iw_request_info* info,
297 struct wlan_network *pnetwork,
298 char *start, char *stop)
303 char custom[MAX_CUSTOM_LEN];
305 u16 max_rate=0, rate, ht_cap=_FALSE;
309 u8 bw_40MHz=0, short_GI=0;
311 struct registry_priv *pregpriv = &padapter->registrypriv;
313 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
318 if (pwdinfo->wfd_info->scan_result_type == SCAN_RESULT_ALL) {
319 } else if ((pwdinfo->wfd_info->scan_result_type == SCAN_RESULT_P2P_ONLY) ||
320 (pwdinfo->wfd_info->scan_result_type == SCAN_RESULT_WFD_TYPE))
323 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
324 u32 blnGotP2PIE = _FALSE;
327 * User is doing the P2P device discovery
328 * The prefix of SSID should be "DIRECT-" and the IE
329 * should contains the P2P IE. If not, the driver
330 * should ignore this AP and go to the next AP.
334 if (!memcmp(pnetwork->network.Ssid.Ssid,
335 pwdinfo->p2p_wildcard_ssid,
336 P2P_WILDCARD_SSID_LEN)) {
340 if (pnetwork->network.Reserved[0] == 2) {
341 /* Verifying the P2P IE */
342 if (rtw_get_p2p_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &p2pielen)) {
345 } else { /* Beacon or Probe Respones */
346 /* Verifying the P2P IE */
347 if (rtw_get_p2p_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen)) {
353 if (blnGotP2PIE == _FALSE)
362 if (pwdinfo->wfd_info->scan_result_type == SCAN_RESULT_WFD_TYPE) {
363 u32 blnGotWFD = _FALSE;
364 u8 wfd_ie[128] = {0x00};
367 if (rtw_get_wfd_ie(&pnetwork->network.IEs[12],
368 pnetwork->network.IELength - 12,
369 wfd_ie, &wfd_ielen)) {
370 u8 wfd_devinfo[6] = {0x00};
373 if (rtw_get_wfd_attr_content(wfd_ie, wfd_ielen,
374 WFD_ATTR_DEVICE_INFO,
377 if (pwdinfo->wfd_info->wfd_device_type ==
379 /* the first two bits will indicate
380 the WFD device type */
381 if ((wfd_devinfo[1] & 0x03) ==
382 WFD_DEVINFO_SOURCE) {
383 /* If this device is Miracast
384 * PSink device, the scan
385 * reuslt should just provide
386 * the Miracast source. */
390 else if (pwdinfo->wfd_info->wfd_device_type ==
391 WFD_DEVINFO_SOURCE) {
392 /* the first two bits will indicate
393 the WFD device type */
394 if ((wfd_devinfo[1] & 0x03) ==
397 * If this device is Miracast
398 * source device, the scan
399 * reuslt should just provide
400 * the Miracast PSink.
401 * Todo: How about the SSink?!
409 if (blnGotWFD == _FALSE)
420 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
422 memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
423 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
426 iwe.cmd = SIOCGIWESSID;
427 iwe.u.data.flags = 1;
428 iwe.u.data.length = min((u16)pnetwork->network.Ssid.SsidLength,
430 start = iwe_stream_add_point(info, start, stop, &iwe,
431 pnetwork->network.Ssid.Ssid);
434 p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
435 &ht_ielen, pnetwork->network.IELength - 12);
439 struct ieee80211_ht_cap *pht_capie;
441 pht_capie = (struct ieee80211_ht_cap *)(p+2);
442 memcpy(&mcs_rate , &pht_capie->mcs, 2);
443 bw_40MHz = (pht_capie->cap_info &
444 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1:0;
445 short_GI = (pht_capie->cap_info &
446 (IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1:0;
449 /* Add the protocol name */
450 iwe.cmd = SIOCGIWNAME;
451 if ((rtw_is_cckratesonly_included((u8*)&pnetwork->network.SupportedRates)) == _TRUE) {
453 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
455 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
456 } else if ((rtw_is_cckrates_included((u8*)&pnetwork->network.SupportedRates)) == _TRUE) {
458 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
460 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
462 if (pnetwork->network.Configuration.DSConfig > 14)
465 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11an");
467 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
470 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
472 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
476 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
479 iwe.cmd = SIOCGIWMODE;
481 rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
484 cap = le16_to_cpu(cap);
486 if (cap & (WLAN_CAPABILITY_IBSS |WLAN_CAPABILITY_ESS)) {
487 if (cap & WLAN_CAPABILITY_ESS)
488 iwe.u.mode = IW_MODE_MASTER;
490 iwe.u.mode = IW_MODE_ADHOC;
492 start = iwe_stream_add_event(info, start, stop, &iwe,
496 if (pnetwork->network.Configuration.DSConfig<1 /*|| pnetwork->network.Configuration.DSConfig>14*/)
497 pnetwork->network.Configuration.DSConfig = 1;
499 /* Add frequency/channel */
500 iwe.cmd = SIOCGIWFREQ;
502 rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
504 iwe.u.freq.i = pnetwork->network.Configuration.DSConfig;
505 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
507 /* Add encryption capability */
508 iwe.cmd = SIOCGIWENCODE;
509 if (cap & WLAN_CAPABILITY_PRIVACY)
510 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
512 iwe.u.data.flags = IW_ENCODE_DISABLED;
513 iwe.u.data.length = 0;
514 start = iwe_stream_add_point(info, start, stop, &iwe,
515 pnetwork->network.Ssid.Ssid);
517 /*Add basic and extended rates */
520 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
521 while (pnetwork->network.SupportedRates[i] != 0) {
522 rate = pnetwork->network.SupportedRates[i]&0x7F;
525 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
526 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
532 if (mcs_rate & 0x8000)//MCS15
534 max_rate = (bw_40MHz) ?
535 ((short_GI) ? 300 : 270) : ((short_GI)?144:130);
537 } else if (mcs_rate & 0x0080)//MCS7
539 max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
540 } else { //default MCS7
541 //DBG_8723A("wx_get_scan, mcs_rate_bitmap=0x%x\n", mcs_rate);
542 max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
545 max_rate = max_rate*2;//Mbps/2;
548 iwe.cmd = SIOCGIWRATE;
549 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
550 iwe.u.bitrate.value = max_rate * 500000;
551 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
553 //parsing WPA/WPA2 IE
555 u8 buf[MAX_WPA_IE_LEN];
556 u8 wpa_ie[255],rsn_ie[255];
557 u16 wpa_len=0,rsn_len=0;
560 out_len=rtw_get_sec_ie(pnetwork->network.IEs ,pnetwork->network.IELength,rsn_ie,&rsn_len,wpa_ie,&wpa_len);
561 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: ssid=%s\n",pnetwork->network.Ssid.Ssid));
562 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: wpa_len=%d rsn_len=%d\n",wpa_len,rsn_len));
566 memset(buf, 0, MAX_WPA_IE_LEN);
567 p += sprintf(p, "wpa_ie=");
568 for (i = 0; i < wpa_len; i++) {
569 p += sprintf(p, "%02x", wpa_ie[i]);
572 memset(&iwe, 0, sizeof(iwe));
573 iwe.cmd = IWEVCUSTOM;
574 iwe.u.data.length = strlen(buf);
575 start = iwe_stream_add_point(info, start, stop,
578 memset(&iwe, 0, sizeof(iwe));
580 iwe.u.data.length = wpa_len;
581 start = iwe_stream_add_point(info, start, stop,
586 memset(buf, 0, MAX_WPA_IE_LEN);
587 p += sprintf(p, "rsn_ie=");
588 for (i = 0; i < rsn_len; i++) {
589 p += sprintf(p, "%02x", rsn_ie[i]);
591 memset(&iwe, 0, sizeof(iwe));
592 iwe.cmd = IWEVCUSTOM;
593 iwe.u.data.length = strlen(buf);
594 start = iwe_stream_add_point(info, start, stop,
597 memset(&iwe, 0, sizeof(iwe));
599 iwe.u.data.length = rsn_len;
600 start = iwe_stream_add_point(info, start, stop,
607 uint cnt = 0,total_ielen;
611 u8 *ie_ptr = pnetwork->network.IEs +_FIXED_IE_LENGTH_;
612 total_ielen= pnetwork->network.IELength - _FIXED_IE_LENGTH_;
614 while(cnt < total_ielen)
616 if(rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen>2))
618 wpsie_ptr = &ie_ptr[cnt];
620 iwe.u.data.length = (u16)wps_ielen;
621 start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr);
623 cnt+=ie_ptr[cnt+1]+2; //goto next
628 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
631 /* Add quality statistics */
633 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID
634 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
639 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
640 is_same_network(&pmlmepriv->cur_network.network,
641 &pnetwork->network)) {
642 ss = padapter->recvpriv.signal_strength;
643 sq = padapter->recvpriv.signal_qual;
645 ss = pnetwork->network.PhyInfo.SignalStrength;
646 sq = pnetwork->network.PhyInfo.SignalQuality;
650 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
651 iwe.u.qual.level = (u8) translate_percentage_to_dbm(ss);//dbm
653 iwe.u.qual.level = (u8)ss;//%
654 #ifdef CONFIG_BT_COEXIST
655 BT_SignalCompensation(padapter, &iwe.u.qual.level, NULL);
656 #endif // CONFIG_BT_COEXIST
659 iwe.u.qual.qual = (u8)sq; // signal quality
661 iwe.u.qual.noise = 0; // noise level
663 //DBG_8723A("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);
665 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
671 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
673 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
676 if ((value & AUTH_ALG_SHARED_KEY)&&(value & AUTH_ALG_OPEN_SYSTEM))
678 DBG_8723A("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n",value);
679 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
680 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
681 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
683 else if (value & AUTH_ALG_SHARED_KEY)
685 DBG_8723A("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n",value);
686 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
688 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
689 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
691 else if(value & AUTH_ALG_OPEN_SYSTEM)
693 DBG_8723A("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
694 //padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
695 if(padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK)
697 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
698 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
702 else if(value & AUTH_ALG_LEAP)
704 DBG_8723A("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
708 DBG_8723A("wpa_set_auth_algs, error!\n");
716 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
719 u32 wep_key_idx, wep_key_len,wep_total_len;
720 NDIS_802_11_WEP *pwep = NULL;
721 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
722 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
723 struct security_priv *psecuritypriv = &padapter->securitypriv;
725 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
730 param->u.crypt.err = 0;
731 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
733 if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
739 if (is_broadcast_ether_addr(param->sta_addr)) {
740 if (param->u.crypt.idx >= WEP_KEYS)
752 if (strcmp(param->u.crypt.alg, "WEP") == 0)
754 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n"));
755 DBG_8723A("wpa_set_encryption, crypt.alg = WEP\n");
757 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
758 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
759 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
761 wep_key_idx = param->u.crypt.idx;
762 wep_key_len = param->u.crypt.key_len;
764 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("(1)wep_key_idx=%d\n", wep_key_idx));
765 DBG_8723A("(1)wep_key_idx=%d\n", wep_key_idx);
767 if (wep_key_idx > WEP_KEYS)
770 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("(2)wep_key_idx=%d\n", wep_key_idx));
774 wep_key_len = wep_key_len <= 5 ? 5 : 13;
775 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
776 pwep =(NDIS_802_11_WEP *) kzalloc(wep_total_len, GFP_KERNEL);
778 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,(" wpa_set_encryption: pwep allocate fail !!!\n"));
782 pwep->KeyLength = wep_key_len;
783 pwep->Length = wep_total_len;
787 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
788 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
796 pwep->KeyIndex = wep_key_idx;
797 pwep->KeyIndex |= 0x80000000;
799 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
801 if(param->u.crypt.set_tx)
803 DBG_8723A("wep, set_tx=1\n");
805 if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
812 DBG_8723A("wep, set_tx=0\n");
814 //don't update "psecuritypriv->dot11PrivacyAlgrthm" and
815 //"psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to fw/cam
817 if (wep_key_idx >= WEP_KEYS) {
822 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
823 psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength;
824 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0);
830 if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x
832 struct sta_info * psta,*pbcmc_sta;
833 struct sta_priv * pstapriv = &padapter->stapriv;
835 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode
837 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
839 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
843 //Jeff: don't disable ieee8021x_blocked while clearing key
844 if (strcmp(param->u.crypt.alg, "none") != 0)
845 psta->ieee8021x_blocked = _FALSE;
847 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
848 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
850 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
853 if(param->u.crypt.set_tx ==1)//pairwise key
855 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
857 if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key
859 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
860 memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
861 memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
863 padapter->securitypriv.busetkipkey=_FALSE;
864 //_set_timer(&padapter->securitypriv.tkip_timer, 50);
867 //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
868 DBG_8723A(" ~~~~set sta key:unicastkey\n");
870 rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE);
874 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));
875 memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8);
876 memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8);
877 padapter->securitypriv.binstallGrpkey = _TRUE;
878 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
879 DBG_8723A(" ~~~~set sta key:groupkey\n");
881 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
883 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1);
885 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
887 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
894 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
897 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
901 //Jeff: don't disable ieee8021x_blocked while clearing key
902 if (strcmp(param->u.crypt.alg, "none") != 0)
903 pbcmc_sta->ieee8021x_blocked = _FALSE;
905 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
906 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
908 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
912 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode
928 static int rtw_set_wpa_ie(struct rtw_adapter *padapter, char *pie, unsigned short ielen)
930 u8 *buf=NULL, *pos=NULL;
932 int group_cipher = 0, pairwise_cipher = 0;
934 u8 null_addr[]= {0,0,0,0,0,0};
936 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
939 if((ielen > MAX_WPA_IE_LEN) || (pie == NULL)){
940 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
949 buf = kmalloc(ielen, GFP_KERNEL);
955 memcpy(buf, pie , ielen);
960 DBG_8723A("\n wpa_ie(length:%d):\n", ielen);
961 for(i=0;i<ielen;i=i+8)
962 DBG_8723A("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]);
966 if(ielen < RSN_HEADER_LEN){
967 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
972 if(rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
974 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
975 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
976 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
979 if(rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
981 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
982 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;
983 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
986 if (group_cipher == 0)
988 group_cipher = WPA_CIPHER_NONE;
990 if (pairwise_cipher == 0)
992 pairwise_cipher = WPA_CIPHER_NONE;
997 case WPA_CIPHER_NONE:
998 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
999 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
1001 case WPA_CIPHER_WEP40:
1002 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
1003 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1005 case WPA_CIPHER_TKIP:
1006 padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
1007 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1009 case WPA_CIPHER_CCMP:
1010 padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
1011 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1013 case WPA_CIPHER_WEP104:
1014 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
1015 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1019 switch(pairwise_cipher)
1021 case WPA_CIPHER_NONE:
1022 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
1023 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
1025 case WPA_CIPHER_WEP40:
1026 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
1027 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1029 case WPA_CIPHER_TKIP:
1030 padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
1031 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1033 case WPA_CIPHER_CCMP:
1034 padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
1035 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1037 case WPA_CIPHER_WEP104:
1038 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
1039 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1043 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1046 u8 eid, wps_oui[4]={0x0,0x50,0xf2,0x04};
1048 while( cnt < ielen )
1052 if ((eid ==_VENDOR_SPECIFIC_IE_) &&
1053 (!memcmp(&buf[cnt+2], wps_oui, 4))) {
1054 DBG_8723A("SET WPS_IE\n");
1056 padapter->securitypriv.wps_ie_len = ( (buf[cnt+1]+2) < (MAX_WPA_IE_LEN<<2)) ? (buf[cnt+1]+2):(MAX_WPA_IE_LEN<<2);
1058 memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
1060 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
1063 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
1065 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING);
1068 cnt += buf[cnt+1]+2;
1072 cnt += buf[cnt+1]+2; //goto next
1078 //TKIP and AES disallow multicast packets until installing group key
1079 if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
1080 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
1081 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
1082 //WPS open need to enable multicast
1083 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
1084 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
1086 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1087 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
1088 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
1098 static int rtw_wx_get_name(struct net_device *dev,
1099 struct iw_request_info *info,
1100 union iwreq_data *wrqu, char *extra)
1102 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
1107 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1108 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1109 NDIS_802_11_RATES_EX* prates = NULL;
1111 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("cmd_code=%x\n", info->cmd));
1115 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE)
1118 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12);
1124 prates = &pcur_bss->SupportedRates;
1126 if (rtw_is_cckratesonly_included((u8*)prates) == _TRUE)
1129 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
1131 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
1133 else if ((rtw_is_cckrates_included((u8*)prates)) == _TRUE)
1136 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
1138 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
1142 if(pcur_bss->Configuration.DSConfig > 14)
1145 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
1147 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
1152 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
1154 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
1160 //prates = &padapter->registrypriv.dev_network.SupportedRates;
1161 //snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
1162 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
1170 static int rtw_wx_set_freq(struct net_device *dev,
1171 struct iw_request_info *info,
1172 union iwreq_data *wrqu, char *extra)
1176 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n"));
1183 static int rtw_wx_get_freq(struct net_device *dev,
1184 struct iw_request_info *info,
1185 union iwreq_data *wrqu, char *extra)
1187 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
1188 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1189 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1191 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
1193 //wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000;
1194 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
1196 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
1200 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
1202 wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
1208 static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
1209 union iwreq_data *wrqu, char *b)
1211 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
1212 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
1217 if(_FAIL == rtw_pwr_wakeup(padapter)) {
1222 if (padapter->hw_init_completed==_FALSE){
1230 networkType = Ndis802_11AutoUnknown;
1231 DBG_8723A("set_mode = IW_MODE_AUTO\n");
1234 networkType = Ndis802_11IBSS;
1235 DBG_8723A("set_mode = IW_MODE_ADHOC\n");
1237 case IW_MODE_MASTER:
1238 networkType = Ndis802_11APMode;
1239 DBG_8723A("set_mode = IW_MODE_MASTER\n");
1240 //rtw_setopmode_cmd(padapter, networkType);
1243 networkType = Ndis802_11Infrastructure;
1244 DBG_8723A("set_mode = IW_MODE_INFRA\n");
1249 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("\n Mode: %s is not supported \n", iw_operation_mode[wrqu->mode]));
1254 if(Ndis802_11APMode == networkType)
1256 rtw_setopmode_cmd(padapter, networkType);
1260 rtw_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
1264 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE){
1271 rtw_setopmode_cmd(padapter, networkType);
1281 static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
1282 union iwreq_data *wrqu, char *b)
1284 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
1285 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1287 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,(" rtw_wx_get_mode \n"));
1291 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1293 wrqu->mode = IW_MODE_INFRA;
1295 else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
1296 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
1299 wrqu->mode = IW_MODE_ADHOC;
1301 else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1303 wrqu->mode = IW_MODE_MASTER;
1307 wrqu->mode = IW_MODE_AUTO;
1317 static int rtw_wx_set_pmkid(struct net_device *dev,
1318 struct iw_request_info *a,
1319 union iwreq_data *wrqu, char *extra)
1321 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
1322 u8 j,blInserted = _FALSE;
1323 int intReturn = _FALSE;
1324 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1325 struct security_priv *psecuritypriv = &padapter->securitypriv;
1326 struct iw_pmksa* pPMK = ( struct iw_pmksa* ) extra;
1327 u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
1328 u8 strIssueBssid[ ETH_ALEN ] = { 0x00 };
1334 struct sockaddr bssid;
1335 __u8 pmkid[IW_PMKID_LEN]; //IW_PMKID_LEN=16
1337 There are the BSSID information in the bssid.sa_data array.
1338 If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear all the PMKID information.
1339 If cmd is IW_PMKSA_ADD, it means the wpa_supplicant wants to add a PMKID/BSSID to driver.
1340 If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to remove a PMKID/BSSID from driver.
1343 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
1344 if ( pPMK->cmd == IW_PMKSA_ADD )
1346 DBG_8723A( "[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n" );
1347 if (!memcmp( strIssueBssid, strZeroMacAddress, ETH_ALEN))
1355 blInserted = _FALSE;
1358 for(j=0 ; j<NUM_PMKID_CACHE; j++)
1360 if (!memcmp( psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN))
1361 { // BSSID is matched, the same AP => rewrite with new PMKID.
1363 DBG_8723A( "[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n" );
1365 memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1366 psecuritypriv->PMKIDList[ j ].bUsed = _TRUE;
1367 psecuritypriv->PMKIDIndex = j+1;
1376 DBG_8723A( "[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
1377 psecuritypriv->PMKIDIndex );
1379 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
1380 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1382 psecuritypriv->PMKIDList[ psecuritypriv->PMKIDIndex ].bUsed = _TRUE;
1383 psecuritypriv->PMKIDIndex++ ;
1384 if(psecuritypriv->PMKIDIndex==16)
1386 psecuritypriv->PMKIDIndex =0;
1390 else if ( pPMK->cmd == IW_PMKSA_REMOVE )
1392 DBG_8723A( "[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n" );
1394 for(j=0 ; j<NUM_PMKID_CACHE; j++)
1396 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN))
1397 { // BSSID is matched, the same AP => Remove this PMKID information and reset it.
1398 memset( psecuritypriv->PMKIDList[ j ].Bssid, 0x00, ETH_ALEN );
1399 psecuritypriv->PMKIDList[ j ].bUsed = _FALSE;
1404 else if ( pPMK->cmd == IW_PMKSA_FLUSH )
1406 DBG_8723A( "[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n" );
1407 memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
1408 psecuritypriv->PMKIDIndex = 0;
1411 return( intReturn );
1414 static int rtw_wx_get_sens(struct net_device *dev,
1415 struct iw_request_info *info,
1416 union iwreq_data *wrqu, char *extra)
1419 wrqu->sens.value = 0;
1420 wrqu->sens.fixed = 0; /* no auto select */
1421 wrqu->sens.disabled = 1;
1426 static int rtw_wx_get_range(struct net_device *dev,
1427 struct iw_request_info *info,
1428 union iwreq_data *wrqu, char *extra)
1430 struct iw_range *range = (struct iw_range *)extra;
1431 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
1432 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1439 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_range. cmd_code=%x\n", info->cmd));
1441 wrqu->data.length = sizeof(*range);
1442 memset(range, 0, sizeof(*range));
1444 /* Let's try to keep this struct in the same order as in
1445 * linux/include/wireless.h
1448 /* TODO: See what values we can set, and remove the ones we can't
1449 * set, or fill them with some default data.
1452 /* ~5 Mb/s real (802.11b) */
1453 range->throughput = 5 * 1000 * 1000;
1455 // TODO: Not used in 802.11b?
1456 // range->min_nwid; /* Minimal NWID we are able to set */
1457 // TODO: Not used in 802.11b?
1458 // range->max_nwid; /* Maximal NWID we are able to set */
1460 /* Old Frequency (backward compat - moved lower ) */
1461 // range->old_num_channels;
1462 // range->old_num_frequency;
1463 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
1465 /* signal level threshold range */
1467 //percent values between 0 and 100.
1468 range->max_qual.qual = 100;
1469 range->max_qual.level = 100;
1470 range->max_qual.noise = 100;
1471 range->max_qual.updated = 7; /* Updated all three */
1474 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
1475 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
1476 range->avg_qual.level = 178; /* -78 dBm */
1477 range->avg_qual.noise = 0;
1478 range->avg_qual.updated = 7; /* Updated all three */
1480 range->num_bitrates = RATE_COUNT;
1482 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
1483 range->bitrate[i] = rtw_rates[i];
1485 range->min_frag = MIN_FRAG_THRESHOLD;
1486 range->max_frag = MAX_FRAG_THRESHOLD;
1490 range->we_version_compiled = WIRELESS_EXT;
1491 range->we_version_source = 16;
1493 // range->retry_capa; /* What retry options are supported */
1494 // range->retry_flags; /* How to decode max/min retry limit */
1495 // range->r_time_flags; /* How to decode max/min retry life */
1496 // range->min_retry; /* Minimal number of retries */
1497 // range->max_retry; /* Maximal number of retries */
1498 // range->min_r_time; /* Minimal retry lifetime */
1499 // range->max_r_time; /* Maximal retry lifetime */
1501 for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
1503 // Include only legal frequencies for some countries
1504 if(pmlmeext->channel_set[i].ChannelNum != 0)
1506 range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
1507 range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
1508 range->freq[val].e = 1;
1512 if (val == IW_MAX_FREQUENCIES)
1516 range->num_channels = val;
1517 range->num_frequency = val;
1519 // Commented by Albert 2009/10/13
1520 // The following code will proivde the security capability to network manager.
1521 // If the driver doesn't provide this capability to network manager,
1522 // the WPA/WPA2 routers can't be choosen in the network manager.
1525 #define IW_SCAN_CAPA_NONE 0x00
1526 #define IW_SCAN_CAPA_ESSID 0x01
1527 #define IW_SCAN_CAPA_BSSID 0x02
1528 #define IW_SCAN_CAPA_CHANNEL 0x04
1529 #define IW_SCAN_CAPA_MODE 0x08
1530 #define IW_SCAN_CAPA_RATE 0x10
1531 #define IW_SCAN_CAPA_TYPE 0x20
1532 #define IW_SCAN_CAPA_TIME 0x40
1535 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
1536 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
1538 #ifdef IW_SCAN_CAPA_ESSID //WIRELESS_EXT > 21
1539 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |IW_SCAN_CAPA_BSSID|
1540 IW_SCAN_CAPA_CHANNEL|IW_SCAN_CAPA_MODE|IW_SCAN_CAPA_RATE;
1551 //s1. rtw_set_802_11_infrastructure_mode()
1552 //s2. rtw_set_802_11_authentication_mode()
1553 //s3. set_802_11_encryption_mode()
1554 //s4. rtw_set_802_11_bssid()
1555 static int rtw_wx_set_wap(struct net_device *dev,
1556 struct iw_request_info *info,
1557 union iwreq_data *awrq,
1561 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
1562 struct sockaddr *temp = (struct sockaddr *)awrq;
1563 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1564 struct list_head *phead;
1565 u8 *dst_bssid, *src_bssid;
1566 _queue *queue = &(pmlmepriv->scanned_queue);
1567 struct wlan_network *pnetwork = NULL;
1568 NDIS_802_11_AUTHENTICATION_MODE authmode;
1572 #ifdef CONFIG_CONCURRENT_MODE
1573 if(padapter->iface_type > PRIMARY_IFACE)
1581 #ifdef CONFIG_CONCURRENT_MODE
1582 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
1584 DBG_8723A("set bssid, but buddy_intf is under scanning or linking\n");
1592 #ifdef CONFIG_DUALMAC_CONCURRENT
1593 if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE)
1595 DBG_8723A("set bssid, but buddy_intf is under scanning or linking\n");
1601 if(_FAIL == rtw_pwr_wakeup(padapter))
1613 if (temp->sa_family != ARPHRD_ETHER){
1618 authmode = padapter->securitypriv.ndisauthtype;
1619 spin_lock_bh(&queue->lock);
1620 phead = get_list_head(queue);
1621 pmlmepriv->pscanned = phead->next;
1626 if ((rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) == _TRUE)
1629 pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
1631 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1633 dst_bssid = pnetwork->network.MacAddress;
1635 src_bssid = temp->sa_data;
1637 if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN)))
1639 if(!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode))
1642 spin_unlock_bh(&queue->lock);
1650 spin_unlock_bh(&queue->lock);
1652 rtw_set_802_11_authentication_mode(padapter, authmode);
1653 //set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
1654 if (rtw_set_802_11_bssid(padapter, temp->sa_data) == _FALSE) {
1666 static int rtw_wx_get_wap(struct net_device *dev,
1667 struct iw_request_info *info,
1668 union iwreq_data *wrqu, char *extra)
1671 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
1672 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1673 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1675 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1677 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1679 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_wap\n"));
1683 if ( ((check_fwstate(pmlmepriv, _FW_LINKED)) == _TRUE) ||
1684 ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) ||
1685 ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == _TRUE) )
1688 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1692 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1701 static int rtw_wx_set_mlme(struct net_device *dev,
1702 struct iw_request_info *info,
1703 union iwreq_data *wrqu, char *extra)
1707 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
1708 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1714 DBG_8723A("%s\n", __func__);
1716 reason = cpu_to_le16(mlme->reason_code);
1719 DBG_8723A("%s, cmd=%d, reason=%d\n", __func__, mlme->cmd, reason);
1724 case IW_MLME_DEAUTH:
1725 if(!rtw_set_802_11_disassociate(padapter))
1729 case IW_MLME_DISASSOC:
1730 if(!rtw_set_802_11_disassociate(padapter))
1742 static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
1743 union iwreq_data *wrqu, char *extra)
1745 u8 _status = _FALSE;
1747 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
1748 struct mlme_priv *pmlmepriv= &padapter->mlmepriv;
1749 NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
1751 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
1753 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_set_scan\n"));
1758 DBG_8723A("DBG_IOCTL %s:%d\n",__func__, __LINE__);
1761 #ifdef CONFIG_CONCURRENT_MODE
1762 if(padapter->iface_type > PRIMARY_IFACE)
1770 if(_FAIL == rtw_pwr_wakeup(padapter))
1776 if(padapter->bDriverStopped){
1777 DBG_8723A("bDriverStopped=%d\n", padapter->bDriverStopped);
1787 if (padapter->hw_init_completed==_FALSE){
1792 // When Busy Traffic, driver do not site survey. So driver return success.
1793 // wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout.
1794 // modify by thomas 2011-02-22.
1795 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)
1797 indicate_wx_scan_complete_event(padapter);
1801 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
1803 indicate_wx_scan_complete_event(padapter);
1807 #ifdef CONFIG_BT_COEXIST
1809 u32 curr_time, delta_time;
1811 // under DHCP(Special packet)
1812 curr_time = rtw_get_current_time();
1813 delta_time = curr_time - padapter->pwrctrlpriv.DelayLPSLastTimeStamp;
1814 delta_time = rtw_systime_to_ms(delta_time);
1815 if (delta_time < 500) // 500ms
1817 DBG_8723A("%s: send DHCP pkt before %d ms, Skip scan\n", __func__, delta_time);
1824 #ifdef CONFIG_CONCURRENT_MODE
1825 if (check_buddy_fwstate(padapter,
1826 _FW_UNDER_SURVEY|_FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
1828 if(check_buddy_fwstate(padapter, _FW_UNDER_SURVEY))
1830 DBG_8723A("scanning_via_buddy_intf\n");
1831 pmlmepriv->scanning_via_buddy_intf = _TRUE;
1834 indicate_wx_scan_complete_event(padapter);
1840 #ifdef CONFIG_DUALMAC_CONCURRENT
1841 if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE)
1843 indicate_wx_scan_complete_event(padapter);
1848 // Mareded by Albert 20101103
1849 // For the DMP WiFi Display project, the driver won't to scan because
1850 // the pmlmepriv->scan_interval is always equal to 3.
1851 // So, the wpa_supplicant won't find out the WPS SoftAP.
1854 if(pmlmepriv->scan_interval>10)
1855 pmlmepriv->scan_interval = 0;
1857 if(pmlmepriv->scan_interval > 0)
1859 DBG_8723A("scan done\n");
1866 if ( pwdinfo->p2p_state != P2P_STATE_NONE )
1868 rtw_p2p_set_pre_state( pwdinfo, rtw_p2p_state( pwdinfo ) );
1869 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
1870 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL);
1871 rtw_free_network_queue(padapter, _TRUE);
1875 memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
1877 if (wrqu->data.length == sizeof(struct iw_scan_req))
1879 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1881 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
1883 int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
1885 memcpy(ssid[0].Ssid, req->essid, len);
1886 ssid[0].SsidLength = len;
1888 DBG_8723A("IW_SCAN_THIS_ESSID, ssid=%s, len=%d\n", req->essid, req->essid_len);
1890 spin_lock_bh(&pmlmepriv->lock);
1892 _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0);
1894 spin_unlock_bh(&pmlmepriv->lock);
1897 else if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
1899 DBG_8723A("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
1905 if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE &&
1906 !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
1907 int len = wrqu->data.length -WEXT_CSCAN_HEADER_SIZE;
1908 char *pos = extra+WEXT_CSCAN_HEADER_SIZE;
1913 //DBG_8723A("%s COMBO_SCAN header is recognized\n", __func__);
1916 section = *(pos++); len-=1;
1919 case WEXT_CSCAN_SSID_SECTION:
1920 //DBG_8723A("WEXT_CSCAN_SSID_SECTION\n");
1926 sec_len = *(pos++); len-=1;
1928 if(sec_len>0 && sec_len<=len) {
1929 ssid[ssid_index].SsidLength = sec_len;
1930 memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength);
1931 //DBG_8723A("%s COMBO_SCAN with specific ssid:%s, %d\n", __func__
1932 // , ssid[ssid_index].Ssid, ssid[ssid_index].SsidLength);
1936 pos+=sec_len; len-=sec_len;
1940 case WEXT_CSCAN_CHANNEL_SECTION:
1941 //DBG_8723A("WEXT_CSCAN_CHANNEL_SECTION\n");
1944 case WEXT_CSCAN_ACTV_DWELL_SECTION:
1945 //DBG_8723A("WEXT_CSCAN_ACTV_DWELL_SECTION\n");
1948 case WEXT_CSCAN_PASV_DWELL_SECTION:
1949 //DBG_8723A("WEXT_CSCAN_PASV_DWELL_SECTION\n");
1952 case WEXT_CSCAN_HOME_DWELL_SECTION:
1953 //DBG_8723A("WEXT_CSCAN_HOME_DWELL_SECTION\n");
1956 case WEXT_CSCAN_TYPE_SECTION:
1957 //DBG_8723A("WEXT_CSCAN_TYPE_SECTION\n");
1961 //DBG_8723A("Unknown CSCAN section %c\n", section);
1962 len = 0; // stop parsing
1964 //DBG_8723A("len:%d\n", len);
1968 //jeff: it has still some scan paramater to parse, we only do this now...
1969 _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
1974 _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
1977 if(_status == _FALSE)
1982 DBG_8723A("DBG_IOCTL %s:%d return %d\n",__func__, __LINE__, ret);
1990 static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
1991 union iwreq_data *wrqu, char *extra)
1993 struct list_head *plist, *phead;
1994 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
1995 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1996 _queue *queue = &(pmlmepriv->scanned_queue);
1997 struct wlan_network *pnetwork = NULL;
1999 char *stop = ev + wrqu->data.length;
2002 u32 wait_for_surveydone;
2004 #ifdef CONFIG_CONCURRENT_MODE
2005 //struct rtw_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
2006 //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
2009 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
2011 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan\n"));
2012 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_, (" Start of Query SIOCGIWSCAN .\n"));
2017 DBG_8723A("DBG_IOCTL %s:%d\n",__func__, __LINE__);
2021 #ifdef CONFIG_CONCURRENT_MODE
2022 if(padapter->iface_type > PRIMARY_IFACE)
2029 if(padapter->pwrctrlpriv.brfoffbyhw && padapter->bDriverStopped)
2036 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2039 if ( padapter->chip_type == RTL8192D )
2040 wait_for_surveydone = 300; // Because the 8192du supports more channels.
2042 wait_for_surveydone = 200;
2047 wait_for_surveydone = 100;
2051 wait_for_surveydone = 100;
2056 #ifdef CONFIG_CONCURRENT_MODE
2057 if(pmlmepriv->scanning_via_buddy_intf == _TRUE)
2059 pmlmepriv->scanning_via_buddy_intf = _FALSE;//reset
2061 // change pointers to buddy interface
2062 padapter = pbuddy_adapter;
2063 pmlmepriv = pbuddy_mlmepriv;
2064 queue = &(pbuddy_mlmepriv->scanned_queue);
2067 #endif // CONFIG_CONCURRENT_MODE
2070 wait_status = _FW_UNDER_SURVEY
2071 #ifndef CONFIG_ANDROID
2076 #ifdef CONFIG_DUALMAC_CONCURRENT
2077 while(dc_check_fwstate(padapter, wait_status)== _TRUE)
2081 if(cnt > wait_for_surveydone )
2084 #endif // CONFIG_DUALMAC_CONCURRENT
2086 while(check_fwstate(pmlmepriv, wait_status) == _TRUE)
2090 if(cnt > wait_for_surveydone )
2094 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
2096 phead = get_list_head(queue);
2097 plist = phead->next;
2101 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
2104 if((stop - ev) < SCAN_ITEM_SIZE) {
2109 pnetwork = container_of(plist, struct wlan_network, list);
2111 //report network only if the current channel set contains the channel to which this network belongs
2112 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
2113 #ifdef CONFIG_VALIDATE_SSID
2114 && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
2118 ev=translate_scan(padapter, a, pnetwork, ev, stop);
2121 plist = plist->next;
2125 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
2127 wrqu->data.length = ev-extra;
2128 wrqu->data.flags = 0;
2135 DBG_8723A("DBG_IOCTL %s:%d return %d\n",__func__, __LINE__, ret);
2143 //s1. rtw_set_802_11_infrastructure_mode()
2144 //s2. set_802_11_authenticaion_mode()
2145 //s3. set_802_11_encryption_mode()
2146 //s4. rtw_set_802_11_ssid()
2147 static int rtw_wx_set_essid(struct net_device *dev,
2148 struct iw_request_info *a,
2149 union iwreq_data *wrqu, char *extra)
2151 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
2152 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2153 _queue *queue = &pmlmepriv->scanned_queue;
2154 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
2155 struct list_head *phead;
2157 struct wlan_network *pnetwork = NULL;
2158 NDIS_802_11_AUTHENTICATION_MODE authmode;
2159 NDIS_802_11_SSID ndis_ssid;
2160 u8 *dst_ssid, *src_ssid;
2167 DBG_8723A("DBG_IOCTL %s:%d\n",__func__, __LINE__);
2171 #ifdef CONFIG_CONCURRENT_MODE
2172 if(padapter->iface_type > PRIMARY_IFACE)
2180 #ifdef CONFIG_CONCURRENT_MODE
2181 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2183 DBG_8723A("set ssid, but buddy_intf is under scanning or linking\n");
2191 #ifdef CONFIG_DUALMAC_CONCURRENT
2192 if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE)
2194 DBG_8723A("set bssid, but buddy_intf is under scanning or linking\n");
2200 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2201 ("+rtw_wx_set_essid: fw_state=0x%08x\n", get_fwstate(pmlmepriv)));
2202 if(_FAIL == rtw_pwr_wakeup(padapter))
2213 if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
2218 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2223 authmode = padapter->securitypriv.ndisauthtype;
2224 DBG_8723A("=>%s\n",__func__);
2225 if (wrqu->essid.flags && wrqu->essid.length)
2227 // Commented by Albert 20100519
2228 // We got the codes in "set_info" function of iwconfig source code.
2229 // =========================================
2230 // wrq.u.essid.length = strlen(essid) + 1;
2231 // if(we_kernel_version > 20)
2232 // wrq.u.essid.length--;
2233 // =========================================
2234 // That means, if the WIRELESS_EXT less than or equal to 20, the correct ssid len should subtract 1.
2235 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
2237 if( wrqu->essid.length != 33 )
2238 DBG_8723A("ssid=%s, len=%d\n", extra, wrqu->essid.length);
2240 memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
2241 ndis_ssid.SsidLength = len;
2242 memcpy(ndis_ssid.Ssid, extra, len);
2243 src_ssid = ndis_ssid.Ssid;
2245 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid=[%s]\n", src_ssid));
2246 spin_lock_bh(&queue->lock);
2247 phead = get_list_head(queue);
2248 pmlmepriv->pscanned = phead->next;
2252 if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == _TRUE)
2254 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_warning_,
2255 ("rtw_wx_set_essid: scan_q is empty, set ssid to check if scanning again!\n"));
2260 pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
2262 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
2264 dst_ssid = pnetwork->network.Ssid.Ssid;
2266 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2267 ("rtw_wx_set_essid: dst_ssid=%s\n",
2268 pnetwork->network.Ssid.Ssid));
2270 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) &&
2271 (pnetwork->network.Ssid.SsidLength==ndis_ssid.SsidLength))
2273 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2274 ("rtw_wx_set_essid: find match, set infra mode\n"));
2276 if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
2278 if(pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
2282 if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == _FALSE)
2285 spin_unlock_bh(&queue->lock);
2292 spin_unlock_bh(&queue->lock);
2293 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2294 ("set ssid: set_802_11_auth. mode=%d\n", authmode));
2295 rtw_set_802_11_authentication_mode(padapter, authmode);
2296 //set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
2297 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {
2305 DBG_8723A("<=%s, ret %d\n",__func__, ret);
2308 DBG_8723A("DBG_IOCTL %s:%d return %d\n",__func__, __LINE__, ret);
2316 static int rtw_wx_get_essid(struct net_device *dev,
2317 struct iw_request_info *a,
2318 union iwreq_data *wrqu, char *extra)
2321 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
2322 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2323 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
2325 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_essid\n"));
2329 if ( (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ||
2330 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE))
2332 len = pcur_bss->Ssid.SsidLength;
2334 wrqu->essid.length = len;
2336 memcpy(extra, pcur_bss->Ssid.Ssid, len);
2338 wrqu->essid.flags = 1;
2354 static int rtw_wx_set_rate(struct net_device *dev,
2355 struct iw_request_info *a,
2356 union iwreq_data *wrqu, char *extra)
2359 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
2360 u8 datarates[NumRates];
2361 u32 target_rate = wrqu->bitrate.value;
2362 u32 fixed = wrqu->bitrate.fixed;
2364 u8 mpdatarate[NumRates]={11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
2368 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,(" rtw_wx_set_rate \n"));
2369 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("target_rate = %d, fixed = %d\n",target_rate,fixed));
2371 if(target_rate == -1){
2375 target_rate = target_rate/100000;
2377 switch(target_rate){
2421 for(i=0; i<NumRates; i++)
2423 if(ratevalue==mpdatarate[i])
2425 datarates[i] = mpdatarate[i];
2430 datarates[i] = 0xff;
2433 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("datarate_inx=%d\n",datarates[i]));
2436 if( rtw_setdatarate_cmd(padapter, datarates) !=_SUCCESS){
2437 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("rtw_wx_set_rate Fail!!!\n"));
2446 static int rtw_wx_get_rate(struct net_device *dev,
2447 struct iw_request_info *info,
2448 union iwreq_data *wrqu, char *extra)
2452 max_rate = rtw_get_cur_max_rate((struct rtw_adapter *)rtw_netdev_priv(dev));
2457 wrqu->bitrate.fixed = 0; /* no auto select */
2458 wrqu->bitrate.value = max_rate * 100000;
2463 static int rtw_wx_set_rts(struct net_device *dev,
2464 struct iw_request_info *info,
2465 union iwreq_data *wrqu, char *extra)
2467 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
2471 if (wrqu->rts.disabled)
2472 padapter->registrypriv.rts_thresh = 2347;
2474 if (wrqu->rts.value < 0 ||
2475 wrqu->rts.value > 2347)
2478 padapter->registrypriv.rts_thresh = wrqu->rts.value;
2481 DBG_8723A("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
2489 static int rtw_wx_get_rts(struct net_device *dev,
2490 struct iw_request_info *info,
2491 union iwreq_data *wrqu, char *extra)
2493 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
2497 DBG_8723A("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
2499 wrqu->rts.value = padapter->registrypriv.rts_thresh;
2500 wrqu->rts.fixed = 0; /* no auto select */
2501 //wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
2508 static int rtw_wx_set_frag(struct net_device *dev,
2509 struct iw_request_info *info,
2510 union iwreq_data *wrqu, char *extra)
2512 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
2516 if (wrqu->frag.disabled)
2517 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
2519 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
2520 wrqu->frag.value > MAX_FRAG_THRESHOLD)
2523 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
2526 DBG_8723A("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
2534 static int rtw_wx_get_frag(struct net_device *dev,
2535 struct iw_request_info *info,
2536 union iwreq_data *wrqu, char *extra)
2538 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
2542 DBG_8723A("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
2544 wrqu->frag.value = padapter->xmitpriv.frag_len;
2545 wrqu->frag.fixed = 0; /* no auto select */
2546 //wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
2553 static int rtw_wx_get_retry(struct net_device *dev,
2554 struct iw_request_info *info,
2555 union iwreq_data *wrqu, char *extra)
2557 //struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
2560 wrqu->retry.value = 7;
2561 wrqu->retry.fixed = 0; /* no auto select */
2562 wrqu->retry.disabled = 1;
2568 static int rtw_wx_set_enc(struct net_device *dev,
2569 struct iw_request_info *info,
2570 union iwreq_data *wrqu, char *keybuf)
2573 u32 keyindex_provided;
2574 NDIS_802_11_WEP wep;
2575 NDIS_802_11_AUTHENTICATION_MODE authmode;
2577 struct iw_point *erq = &(wrqu->encoding);
2578 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
2579 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
2580 DBG_8723A("+rtw_wx_set_enc, flags=0x%x\n", erq->flags);
2582 memset(&wep, 0, sizeof(NDIS_802_11_WEP));
2584 key = erq->flags & IW_ENCODE_INDEX;
2588 if (erq->flags & IW_ENCODE_DISABLED)
2590 DBG_8723A("EncryptionDisabled\n");
2591 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
2592 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
2593 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
2594 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
2595 authmode = Ndis802_11AuthModeOpen;
2596 padapter->securitypriv.ndisauthtype=authmode;
2605 keyindex_provided = 1;
2609 keyindex_provided = 0;
2610 key = padapter->securitypriv.dot11PrivacyKeyIndex;
2611 DBG_8723A("rtw_wx_set_enc, key=%d\n", key);
2614 //set authentication mode
2615 if(erq->flags & IW_ENCODE_OPEN)
2617 DBG_8723A("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
2618 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;//Ndis802_11EncryptionDisabled;
2620 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open;
2622 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
2623 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
2624 authmode = Ndis802_11AuthModeOpen;
2625 padapter->securitypriv.ndisauthtype=authmode;
2627 else if(erq->flags & IW_ENCODE_RESTRICTED)
2629 DBG_8723A("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
2630 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2632 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Shared;
2634 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
2635 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
2636 authmode = Ndis802_11AuthModeShared;
2637 padapter->securitypriv.ndisauthtype=authmode;
2641 DBG_8723A("rtw_wx_set_enc():erq->flags=0x%x\n", erq->flags);
2643 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;//Ndis802_11EncryptionDisabled;
2644 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
2645 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
2646 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
2647 authmode = Ndis802_11AuthModeOpen;
2648 padapter->securitypriv.ndisauthtype=authmode;
2652 if (erq->length > 0)
2654 wep.KeyLength = erq->length <= 5 ? 5 : 13;
2656 wep.Length = wep.KeyLength + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
2662 if(keyindex_provided == 1)// set key_id only, no given KeyMaterial(erq->length==0).
2664 padapter->securitypriv.dot11PrivacyKeyIndex = key;
2666 DBG_8723A("(keyindex_provided == 1), keyid=%d, key_len=%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
2668 switch(padapter->securitypriv.dot11DefKeylen[key])
2671 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
2674 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
2677 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
2687 wep.KeyIndex |= 0x80000000;
2689 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
2691 if (rtw_set_802_11_add_wep(padapter, &wep) == _FALSE) {
2692 if(rf_on == pwrpriv->rf_pwrstate )
2705 static int rtw_wx_get_enc(struct net_device *dev,
2706 struct iw_request_info *info,
2707 union iwreq_data *wrqu, char *keybuf)
2710 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
2711 struct iw_point *erq = &(wrqu->encoding);
2712 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2716 if(check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE)
2718 if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE)
2721 erq->flags |= IW_ENCODE_DISABLED;
2727 key = erq->flags & IW_ENCODE_INDEX;
2735 key = padapter->securitypriv.dot11PrivacyKeyIndex;
2738 erq->flags = key + 1;
2740 //if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
2742 // erq->flags |= IW_ENCODE_OPEN;
2745 switch(padapter->securitypriv.ndisencryptstatus)
2747 case Ndis802_11EncryptionNotSupported:
2748 case Ndis802_11EncryptionDisabled:
2751 erq->flags |= IW_ENCODE_DISABLED;
2755 case Ndis802_11Encryption1Enabled:
2757 erq->length = padapter->securitypriv.dot11DefKeylen[key];
2761 memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
2763 erq->flags |= IW_ENCODE_ENABLED;
2765 if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
2767 erq->flags |= IW_ENCODE_OPEN;
2769 else if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
2771 erq->flags |= IW_ENCODE_RESTRICTED;
2777 erq->flags |= IW_ENCODE_DISABLED;
2782 case Ndis802_11Encryption2Enabled:
2783 case Ndis802_11Encryption3Enabled:
2786 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
2792 erq->flags |= IW_ENCODE_DISABLED;
2804 static int rtw_wx_get_power(struct net_device *dev,
2805 struct iw_request_info *info,
2806 union iwreq_data *wrqu, char *extra)
2808 //struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
2810 wrqu->power.value = 0;
2811 wrqu->power.fixed = 0; /* no auto select */
2812 wrqu->power.disabled = 1;
2818 static int rtw_wx_set_gen_ie(struct net_device *dev,
2819 struct iw_request_info *info,
2820 union iwreq_data *wrqu, char *extra)
2823 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
2825 ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
2830 static int rtw_wx_set_auth(struct net_device *dev,
2831 struct iw_request_info *info,
2832 union iwreq_data *wrqu, char *extra)
2834 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
2835 struct iw_param *param = (struct iw_param*)&(wrqu->param);
2836 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2837 struct security_priv *psecuritypriv = &padapter->securitypriv;
2838 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2839 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2840 u32 value = param->value;
2843 switch (param->flags & IW_AUTH_INDEX) {
2845 case IW_AUTH_WPA_VERSION:
2847 case IW_AUTH_CIPHER_PAIRWISE:
2850 case IW_AUTH_CIPHER_GROUP:
2853 case IW_AUTH_KEY_MGMT:
2855 * ??? does not use these parameters
2859 case IW_AUTH_TKIP_COUNTERMEASURES:
2862 { // wpa_supplicant is enabling the tkip countermeasure.
2863 padapter->securitypriv.btkip_countermeasure = _TRUE;
2866 { // wpa_supplicant is disabling the tkip countermeasure.
2867 padapter->securitypriv.btkip_countermeasure = _FALSE;
2871 case IW_AUTH_DROP_UNENCRYPTED:
2875 * wpa_supplicant calls set_wpa_enabled when the driver
2876 * is loaded and unloaded, regardless of if WPA is being
2877 * used. No other calls are made which can be used to
2878 * determine if encryption will be used or not prior to
2879 * association being expected. If encryption is not being
2880 * used, drop_unencrypted is set to false, else true -- we
2881 * can use this to determine if the CAP_PRIVACY_ON bit should
2885 if(padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
2887 break;//it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled,
2888 // then it needn't reset it;
2892 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
2893 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
2894 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
2895 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
2896 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeOpen;
2902 case IW_AUTH_80211_AUTH_ALG:
2904 #if defined(CONFIG_ANDROID) || 1
2906 * It's the starting point of a link layer connection using wpa_supplicant
2908 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
2909 LeaveAllPowerSaveMode(padapter);
2910 rtw_disassoc_cmd(padapter, 500, _FALSE);
2911 DBG_8723A("%s...call rtw_indicate_disconnect\n ",__func__);
2912 rtw_indicate_disconnect(padapter);
2913 rtw_free_assoc_resources(padapter, 1);
2918 ret = wpa_set_auth_algs(dev, (u32)param->value);
2922 case IW_AUTH_WPA_ENABLED:
2925 // padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; //802.1x
2927 // padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;//open system
2929 //_disassociate(priv);
2933 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2934 //ieee->ieee802_1x = param->value;
2937 case IW_AUTH_PRIVACY_INVOKED:
2938 //ieee->privacy_invoked = param->value;
2950 static int rtw_wx_set_enc_ext(struct net_device *dev,
2951 struct iw_request_info *info,
2952 union iwreq_data *wrqu, char *extra)
2956 struct ieee_param *param = NULL;
2957 struct iw_point *pencoding = &wrqu->encoding;
2958 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
2961 param_len = sizeof(struct ieee_param) + pext->key_len;
2962 param = (struct ieee_param *)kzalloc(param_len, GFP_KERNEL);
2966 param->cmd = IEEE_CMD_SET_ENCRYPTION;
2967 memset(param->sta_addr, 0xff, ETH_ALEN);
2970 switch (pext->alg) {
2971 case IW_ENCODE_ALG_NONE:
2976 case IW_ENCODE_ALG_WEP:
2979 case IW_ENCODE_ALG_TKIP:
2982 case IW_ENCODE_ALG_CCMP:
2990 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
2992 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2994 param->u.crypt.set_tx = 1;
2997 /* cliW: WEP does not have group key
2998 * just not checking GROUP key setting
3000 if ((pext->alg != IW_ENCODE_ALG_WEP) &&
3001 (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
3003 param->u.crypt.set_tx = 0;
3006 param->u.crypt.idx = (pencoding->flags&0x00FF) -1 ;
3008 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
3010 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
3015 param->u.crypt.key_len = pext->key_len;
3016 //memcpy(param + 1, pext + 1, pext->key_len);
3017 memcpy(param->u.crypt.key, pext + 1, pext->key_len);
3020 if (pencoding->flags & IW_ENCODE_DISABLED)
3026 ret = wpa_set_encryption(dev, param, param_len);
3035 static int rtw_wx_get_nick(struct net_device *dev,
3036 struct iw_request_info *info,
3037 union iwreq_data *wrqu, char *extra)
3039 //struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3040 //struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3041 //struct security_priv *psecuritypriv = &padapter->securitypriv;
3045 wrqu->data.length = 14;
3046 wrqu->data.flags = 1;
3047 memcpy(extra, "<WIFI@REALTEK>", 14);
3052 static int rtw_wx_read32(struct net_device *dev,
3053 struct iw_request_info *info,
3054 union iwreq_data *wrqu, char *extra)
3056 struct rtw_adapter *padapter;
3066 padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3069 ptmp = (u8*)kmalloc(len, GFP_KERNEL);
3073 if (copy_from_user(ptmp, p->pointer, len)) {
3080 sscanf(ptmp, "%d,%x", &bytes, &addr);
3084 data32 = rtw_read8(padapter, addr);
3085 sprintf(extra, "0x%02X", data32);
3088 data32 = rtw_read16(padapter, addr);
3089 sprintf(extra, "0x%04X", data32);
3092 data32 = rtw_read32(padapter, addr);
3093 sprintf(extra, "0x%08X", data32);
3096 DBG_8723A(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__);
3100 DBG_8723A(KERN_INFO "%s: addr=0x%08X data=%s\n", __func__, addr, extra);
3107 static int rtw_wx_write32(struct net_device *dev,
3108 struct iw_request_info *info,
3109 union iwreq_data *wrqu, char *extra)
3111 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3120 sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
3124 rtw_write8(padapter, addr, (u8)data32);
3125 DBG_8723A(KERN_INFO "%s: addr=0x%08X data=0x%02X\n", __func__, addr, (u8)data32);
3128 rtw_write16(padapter, addr, (u16)data32);
3129 DBG_8723A(KERN_INFO "%s: addr=0x%08X data=0x%04X\n", __func__, addr, (u16)data32);
3132 rtw_write32(padapter, addr, data32);
3133 DBG_8723A(KERN_INFO "%s: addr=0x%08X data=0x%08X\n", __func__, addr, data32);
3136 DBG_8723A(KERN_INFO "%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);
3143 static int rtw_wx_read_rf(struct net_device *dev,
3144 struct iw_request_info *info,
3145 union iwreq_data *wrqu, char *extra)
3147 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3148 u32 path, addr, data32;
3151 path = *(u32*)extra;
3152 addr = *((u32*)extra + 1);
3153 data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);
3154 // DBG_8723A("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32);
3157 * Only when wireless private ioctl is at odd order,
3158 * "extra" would be copied to user space.
3160 sprintf(extra, "0x%05x", data32);
3165 static int rtw_wx_write_rf(struct net_device *dev,
3166 struct iw_request_info *info,
3167 union iwreq_data *wrqu, char *extra)
3169 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3170 u32 path, addr, data32;
3173 path = *(u32*)extra;
3174 addr = *((u32*)extra + 1);
3175 data32 = *((u32*)extra + 2);
3176 // DBG_8723A("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32);
3177 rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);
3182 static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
3183 union iwreq_data *wrqu, char *b)
3188 static int dummy(struct net_device *dev, struct iw_request_info *a,
3189 union iwreq_data *wrqu, char *b)
3191 //struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3192 //struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3194 //DBG_8723A("cmd_code=%x, fwstate=0x%x\n", a->cmd, get_fwstate(pmlmepriv));
3200 static int rtw_wx_set_channel_plan(struct net_device *dev,
3201 struct iw_request_info *info,
3202 union iwreq_data *wrqu, char *extra)
3204 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3205 struct registry_priv *pregistrypriv = &padapter->registrypriv;
3206 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3207 extern int rtw_channel_plan;
3208 u8 channel_plan_req = (u8) (*((int *)wrqu));
3210 if( _SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1) ) {
3211 DBG_8723A("%s set channel_plan = 0x%02X\n", __func__, pmlmepriv->ChannelPlan);
3218 static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
3219 struct iw_request_info *a,
3220 union iwreq_data *wrqu, char *b)
3225 static int rtw_wx_get_sensitivity(struct net_device *dev,
3226 struct iw_request_info *info,
3227 union iwreq_data *wrqu, char *buf)
3232 static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
3233 struct iw_request_info *info,
3234 union iwreq_data *wrqu, char *extra)
3240 typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
3241 union iwreq_data *wrqu, char *extra);
3244 * For all data larger than 16 octets, we need to use a
3245 * pointer to memory allocated in user space.
3247 static int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info,
3248 union iwreq_data *wrqu, char *extra)
3250 #ifdef CONFIG_DRVEXT_MODULE
3252 struct drvext_handler *phandler;
3253 struct drvext_oidparam *poidparam;
3257 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3258 struct iw_point *p = &wrqu->data;
3260 if( (!p->length) || (!p->pointer)){
3262 goto _rtw_drvext_hdl_exit;
3266 bset = (u8)(p->flags&0xFFFF);
3268 pparmbuf = (u8*)kmalloc(len, GFP_KERNEL);
3269 if (pparmbuf == NULL){
3276 if (copy_from_user(pparmbuf, p->pointer,len)) {
3278 goto _rtw_drvext_hdl_exit;
3288 poidparam = (struct drvext_oidparam *)pparmbuf;
3290 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("drvext set oid subcode [%d], len[%d], InformationBufferLength[%d]\r\n",
3291 poidparam->subcode, poidparam->len, len));
3295 if ( poidparam->subcode >= MAX_DRVEXT_HANDLERS)
3297 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext handlers\r\n"));
3299 goto _rtw_drvext_hdl_exit;
3303 if ( poidparam->subcode >= MAX_DRVEXT_OID_SUBCODES)
3305 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext subcodes\r\n"));
3307 goto _rtw_drvext_hdl_exit;
3311 phandler = drvextoidhandlers + poidparam->subcode;
3313 if (poidparam->len != phandler->parmsize)
3315 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext param size %d vs %d\r\n",
3316 poidparam->len , phandler->parmsize));
3318 goto _rtw_drvext_hdl_exit;
3322 res = phandler->handler(&padapter->drvextpriv, bset, poidparam->data);
3328 if (bset == 0x00) {//query info
3329 //memcpy(p->pointer, pparmbuf, len);
3330 if (copy_to_user(p->pointer, pparmbuf, len))
3338 _rtw_drvext_hdl_exit:
3349 static int rtw_get_ap_info(struct net_device *dev,
3350 struct iw_request_info *info,
3351 union iwreq_data *wrqu, char *extra)
3353 int bssid_match, ret = 0;
3354 u32 cnt=0, wpa_ielen;
3355 struct list_head *plist, *phead;
3356 unsigned char *pbuf;
3359 struct wlan_network *pnetwork = NULL;
3360 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3361 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3362 _queue *queue = &(pmlmepriv->scanned_queue);
3363 struct iw_point *pdata = &wrqu->data;
3365 DBG_8723A("+rtw_get_aplist_info\n");
3367 if((padapter->bDriverStopped) || (pdata==NULL))
3373 while((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) == _TRUE)
3382 //pdata->length = 0;//?
3384 if(pdata->length>=32)
3386 if(copy_from_user(data, pdata->pointer, 32))
3398 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
3400 phead = get_list_head(queue);
3401 plist = phead->next;
3405 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
3409 pnetwork = container_of(plist, struct wlan_network, list);
3411 //if(hwaddr_aton_i(pdata->pointer, bssid))
3412 if(hwaddr_aton_i(data, bssid))
3414 DBG_8723A("Invalid BSSID '%s'.\n", (u8*)data);
3415 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
3420 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN))//BSSID match, then check if supporting wpa/wpa2
3422 DBG_8723A("BSSID:" MAC_FMT "\n", MAC_ARG(bssid));
3424 pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
3425 if(pbuf && (wpa_ielen>0))
3431 pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
3432 if(pbuf && (wpa_ielen>0))
3440 plist = plist->next;
3444 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
3446 if(pdata->length>=34)
3448 if(copy_to_user((u8*)pdata->pointer+32, (u8*)&pdata->flags, 1))
3461 static int rtw_set_pid(struct net_device *dev,
3462 struct iw_request_info *info,
3463 union iwreq_data *wrqu, char *extra)
3467 struct rtw_adapter *padapter = rtw_netdev_priv(dev);
3468 int *pdata = (int *)wrqu;
3471 if((padapter->bDriverStopped) || (pdata==NULL))
3478 if(selector < 3 && selector >=0) {
3479 padapter->pid[selector] = *(pdata+1);
3480 #ifdef CONFIG_GLOBAL_UI_PID
3481 ui_pid[selector] = *(pdata+1);
3483 DBG_8723A("%s set pid[%d]=%d\n", __func__, selector ,padapter->pid[selector]);
3486 DBG_8723A("%s selector %d error\n", __func__, selector);
3494 static int rtw_wps_start(struct net_device *dev,
3495 struct iw_request_info *info,
3496 union iwreq_data *wrqu, char *extra)
3500 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3501 struct iw_point *pdata = &wrqu->data;
3502 u32 u32wps_start = 0;
3503 unsigned int uintRet = 0;
3505 uintRet = copy_from_user( ( void* ) &u32wps_start, pdata->pointer, 4 );
3507 if((padapter->bDriverStopped) || (pdata==NULL))
3513 if ( u32wps_start == 0 )
3515 u32wps_start = *extra;
3518 DBG_8723A( "[%s] wps_start = %d\n", __func__, u32wps_start );
3520 if ( u32wps_start == 1 ) // WPS Start
3522 rtw_led_control(padapter, LED_CTL_START_WPS);
3524 else if ( u32wps_start == 2 ) // WPS Stop because of wps success
3526 rtw_led_control(padapter, LED_CTL_STOP_WPS);
3528 else if ( u32wps_start == 3 ) // WPS Stop because of wps fail
3530 rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);
3539 static int rtw_wext_p2p_enable(struct net_device *dev,
3540 struct iw_request_info *info,
3541 union iwreq_data *wrqu, char *extra)
3545 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3546 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3547 struct iw_point *pdata = &wrqu->data;
3548 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3549 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3550 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
3551 enum P2P_ROLE init_role = P2P_ROLE_DISABLE;
3554 init_role = P2P_ROLE_DISABLE;
3555 else if(*extra == '1')
3556 init_role = P2P_ROLE_DEVICE;
3557 else if(*extra == '2')
3558 init_role = P2P_ROLE_CLIENT;
3559 else if(*extra == '3')
3560 init_role = P2P_ROLE_GO;
3562 if(_FAIL == rtw_p2p_enable(padapter, init_role))
3568 //set channel/bandwidth
3569 if(init_role != P2P_ROLE_DISABLE)
3571 u8 channel, ch_offset;
3574 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN))
3576 // Stay at the listen state and wait for discovery.
3577 channel = pwdinfo->listen_channel;
3578 pwdinfo->operating_channel = pwdinfo->listen_channel;
3579 ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
3580 bwmode = HT_CHANNEL_WIDTH_20;
3582 #ifdef CONFIG_CONCURRENT_MODE
3583 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
3585 struct rtw_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3586 //struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
3587 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
3588 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3590 _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval );
3591 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
3593 pwdinfo->operating_channel = pbuddy_mlmeext->cur_channel;
3594 // How about the ch_offset and bwmode ??
3598 pwdinfo->operating_channel = pwdinfo->listen_channel;
3601 channel = pbuddy_mlmeext->cur_channel;
3602 ch_offset = pbuddy_mlmeext->cur_ch_offset;
3603 bwmode = pbuddy_mlmeext->cur_bwmode;
3608 pwdinfo->operating_channel = pmlmeext->cur_channel;
3610 channel = pwdinfo->operating_channel;
3611 ch_offset = pmlmeext->cur_ch_offset;
3612 bwmode = pmlmeext->cur_bwmode;
3615 set_channel_bwmode(padapter, channel, ch_offset, bwmode);
3623 static int rtw_p2p_set_go_nego_ssid(struct net_device *dev,
3624 struct iw_request_info *info,
3625 union iwreq_data *wrqu, char *extra)
3629 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3630 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3631 struct iw_point *pdata = &wrqu->data;
3632 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3634 DBG_8723A( "[%s] ssid = %s, len = %zu\n", __func__, extra, strlen( extra ) );
3635 memcpy(pwdinfo->nego_ssid, extra, strlen( extra ) );
3636 pwdinfo->nego_ssidlen = strlen( extra );
3643 static int rtw_p2p_set_intent(struct net_device *dev,
3644 struct iw_request_info *info,
3645 union iwreq_data *wrqu, char *extra)
3648 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3649 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3650 u8 intent = pwdinfo->intent;
3652 switch (wrqu->data.length) {
3655 intent = extra[ 0 ] - '0';
3660 intent = str_2char2num( extra[ 0 ], extra[ 1 ]);
3667 pwdinfo->intent= intent;
3674 DBG_8723A( "[%s] intent = %d\n", __func__, intent);
3680 static int rtw_p2p_set_listen_ch(struct net_device *dev,
3681 struct iw_request_info *info,
3682 union iwreq_data *wrqu, char *extra)
3686 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3687 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3688 u8 listen_ch = pwdinfo->listen_channel; // Listen channel number
3690 switch( wrqu->data.length )
3694 listen_ch = extra[ 0 ] - '0';
3699 listen_ch = str_2char2num( extra[ 0 ], extra[ 1 ]);
3704 if ( ( listen_ch == 1 ) || ( listen_ch == 6 ) || ( listen_ch == 11 ) )
3706 pwdinfo->listen_channel = listen_ch;
3707 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
3714 DBG_8723A( "[%s] listen_ch = %d\n", __func__, pwdinfo->listen_channel );
3720 static int rtw_p2p_set_op_ch(struct net_device *dev,
3721 struct iw_request_info *info,
3722 union iwreq_data *wrqu, char *extra)
3724 // Commented by Albert 20110524
3725 // This function is used to set the operating channel if the driver will become the group owner
3728 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3729 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3730 u8 op_ch = pwdinfo->operating_channel; // Operating channel number
3732 switch( wrqu->data.length )
3736 op_ch = extra[ 0 ] - '0';
3741 op_ch = str_2char2num( extra[ 0 ], extra[ 1 ]);
3748 pwdinfo->operating_channel = op_ch;
3755 DBG_8723A( "[%s] op_ch = %d\n", __func__, pwdinfo->operating_channel );
3762 static int rtw_p2p_profilefound(struct net_device *dev,
3763 struct iw_request_info *info,
3764 union iwreq_data *wrqu, char *extra)
3768 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3769 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3771 // Comment by Albert 2010/10/13
3772 // Input data format:
3774 // Ex: 1XX:XX:XX:XX:XX:XXYYSSID
3775 // 0 => Reflush the profile record list.
3776 // 1 => Add the profile list
3777 // XX:XX:XX:XX:XX:XX => peer's MAC Address ( ex: 00:E0:4C:00:00:01 )
3778 // YY => SSID Length
3779 // SSID => SSID for persistence group
3781 DBG_8723A( "[%s] In value = %s, len = %d \n", __func__, extra, wrqu->data.length -1);
3784 // The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function.
3785 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
3787 if ( extra[ 0 ] == '0' )
3789 // Remove all the profile information of wifidirect_info structure.
3790 memset( &pwdinfo->profileinfo[ 0 ], 0x00, sizeof( struct profile_info ) * P2P_MAX_PERSISTENT_GROUP_NUM );
3791 pwdinfo->profileindex = 0;
3795 if ( pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM )
3803 // Add this profile information into pwdinfo->profileinfo
3804 // Ex: 1XX:XX:XX:XX:XX:XXYYSSID
3805 for( jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3 )
3807 pwdinfo->profileinfo[ pwdinfo->profileindex ].peermac[ jj ] = key_2char2num(extra[ kk ], extra[ kk+ 1 ]);
3810 pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen = ( extra[18] - '0' ) * 10 + ( extra[ 19 ] - '0' );
3811 memcpy(pwdinfo->profileinfo[ pwdinfo->profileindex ].ssid, &extra[ 20 ], pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen );
3812 pwdinfo->profileindex++;
3821 static int rtw_p2p_setDN(struct net_device *dev,
3822 struct iw_request_info *info,
3823 union iwreq_data *wrqu, char *extra)
3827 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3828 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3831 DBG_8723A( "[%s] %s %d\n", __func__, extra, wrqu->data.length -1 );
3832 memset( pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN );
3833 memcpy(pwdinfo->device_name, extra, wrqu->data.length - 1 );
3834 pwdinfo->device_name_len = wrqu->data.length - 1;
3841 static int rtw_p2p_get_status(struct net_device *dev,
3842 struct iw_request_info *info,
3843 union iwreq_data *wrqu, char *extra)
3847 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3848 struct iw_point *pdata = &wrqu->data;
3849 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
3850 #ifdef CONFIG_CONCURRENT_MODE
3851 struct rtw_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3852 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
3853 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
3854 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3857 if ( padapter->bShowGetP2PState )
3859 DBG_8723A( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
3860 pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
3861 pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
3864 // Commented by Albert 2010/10/12
3865 // Because of the output size limitation, I had removed the "Role" information.
3866 // About the "Role" information, we will use the new private IOCTL to get the "Role" information.
3867 sprintf( extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo) );
3868 wrqu->data.length = strlen( extra );
3874 // Commented by Albert 20110520
3875 // This function will return the config method description
3876 // This config method description will show us which config method the remote P2P device is intented to use
3877 // by sending the provisioning discovery request frame.
3879 static int rtw_p2p_get_req_cm(struct net_device *dev,
3880 struct iw_request_info *info,
3881 union iwreq_data *wrqu, char *extra)
3885 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3886 struct iw_point *pdata = &wrqu->data;
3887 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
3889 sprintf( extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req );
3890 wrqu->data.length = strlen( extra );
3896 static int rtw_p2p_get_role(struct net_device *dev,
3897 struct iw_request_info *info,
3898 union iwreq_data *wrqu, char *extra)
3902 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3903 struct iw_point *pdata = &wrqu->data;
3904 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
3907 DBG_8723A( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
3908 pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
3909 pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
3911 sprintf( extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo) );
3912 wrqu->data.length = strlen( extra );
3918 static int rtw_p2p_get_peer_ifaddr(struct net_device *dev,
3919 struct iw_request_info *info,
3920 union iwreq_data *wrqu, char *extra)
3924 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3925 struct iw_point *pdata = &wrqu->data;
3926 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
3929 DBG_8723A( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
3930 pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
3931 pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
3933 sprintf( extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
3934 pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
3935 pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
3936 wrqu->data.length = strlen( extra );
3941 static int rtw_p2p_get_peer_devaddr(struct net_device *dev,
3942 struct iw_request_info *info,
3943 union iwreq_data *wrqu, char *extra)
3948 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3949 struct iw_point *pdata = &wrqu->data;
3950 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
3952 DBG_8723A( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
3953 pwdinfo->rx_prov_disc_info.peerDevAddr[ 0 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 1 ],
3954 pwdinfo->rx_prov_disc_info.peerDevAddr[ 2 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 3 ],
3955 pwdinfo->rx_prov_disc_info.peerDevAddr[ 4 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 5 ]);
3956 sprintf( extra, "\n%.2X%.2X%.2X%.2X%.2X%.2X",
3957 pwdinfo->rx_prov_disc_info.peerDevAddr[ 0 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 1 ],
3958 pwdinfo->rx_prov_disc_info.peerDevAddr[ 2 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 3 ],
3959 pwdinfo->rx_prov_disc_info.peerDevAddr[ 4 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 5 ]);
3960 wrqu->data.length = strlen( extra );
3965 static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev,
3966 struct iw_request_info *info,
3967 union iwreq_data *wrqu, char *extra)
3972 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3973 struct iw_point *pdata = &wrqu->data;
3974 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
3976 DBG_8723A( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
3977 pwdinfo->p2p_peer_device_addr[ 0 ], pwdinfo->p2p_peer_device_addr[ 1 ],
3978 pwdinfo->p2p_peer_device_addr[ 2 ], pwdinfo->p2p_peer_device_addr[ 3 ],
3979 pwdinfo->p2p_peer_device_addr[ 4 ], pwdinfo->p2p_peer_device_addr[ 5 ]);
3980 sprintf( extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
3981 pwdinfo->p2p_peer_device_addr[ 0 ], pwdinfo->p2p_peer_device_addr[ 1 ],
3982 pwdinfo->p2p_peer_device_addr[ 2 ], pwdinfo->p2p_peer_device_addr[ 3 ],
3983 pwdinfo->p2p_peer_device_addr[ 4 ], pwdinfo->p2p_peer_device_addr[ 5 ]);
3984 wrqu->data.length = strlen( extra );
3989 static int rtw_p2p_get_groupid(struct net_device *dev,
3990 struct iw_request_info *info,
3991 union iwreq_data *wrqu, char *extra)
3996 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
3997 struct iw_point *pdata = &wrqu->data;
3998 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4000 sprintf( extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s",
4001 pwdinfo->groupid_info.go_device_addr[ 0 ], pwdinfo->groupid_info.go_device_addr[ 1 ],
4002 pwdinfo->groupid_info.go_device_addr[ 2 ], pwdinfo->groupid_info.go_device_addr[ 3 ],
4003 pwdinfo->groupid_info.go_device_addr[ 4 ], pwdinfo->groupid_info.go_device_addr[ 5 ],
4004 pwdinfo->groupid_info.ssid);
4005 wrqu->data.length = strlen( extra );
4010 static int rtw_p2p_get_op_ch(struct net_device *dev,
4011 struct iw_request_info *info,
4012 union iwreq_data *wrqu, char *extra)
4017 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
4018 struct iw_point *pdata = &wrqu->data;
4019 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4022 DBG_8723A( "[%s] Op_ch = %02x\n", __func__, pwdinfo->operating_channel);
4024 sprintf( extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel );
4025 wrqu->data.length = strlen( extra );
4030 inline static void macstr2num(u8 *dst, u8 *src)
4033 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
4035 dst[jj] = key_2char2num(src[kk], src[kk + 1]);
4039 static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
4040 struct iw_request_info *info,
4041 union iwreq_data *wrqu, char *extra, char *subcmd)
4045 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
4046 u8 peerMAC[ETH_ALEN] = { 0x00 };
4047 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4048 struct list_head * plist,*phead;
4049 _queue *queue = &(pmlmepriv->scanned_queue);
4050 struct wlan_network *pnetwork = NULL;
4052 u16 attr_content = 0;
4053 uint attr_contentlen = 0;
4054 u8 attr_content_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4056 // Commented by Albert 20110727
4057 // The input data is the MAC address which the application wants to know its WPS config method.
4058 // After knowing its WPS config method, the application can decide the config method for provisioning discovery.
4059 // Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05
4061 DBG_8723A("[%s] data = %s\n", __func__, subcmd);
4063 macstr2num(peerMAC, subcmd);
4065 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
4067 phead = get_list_head(queue);
4068 plist = phead->next;
4072 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
4074 pnetwork = container_of(plist, struct wlan_network, list);
4075 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
4080 // The mac address is matched.
4082 if ((wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len)))
4084 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&attr_content, &attr_contentlen);
4085 if (attr_contentlen)
4087 attr_content = be16_to_cpu(attr_content);
4088 sprintf(attr_content_str, "\n\nM=%.4d", attr_content);
4096 plist = plist->next;
4100 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
4104 sprintf(attr_content_str, "\n\nM=0000");
4107 wrqu->data.length = strlen(attr_content_str);
4108 memcpy(extra, attr_content_str, wrqu->data.length);
4115 static int rtw_p2p_get_peer_wfd_port(struct net_device *dev,
4116 struct iw_request_info *info,
4117 union iwreq_data *wrqu, char *extra)
4121 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
4122 struct iw_point *pdata = &wrqu->data;
4123 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4125 DBG_8723A( "[%s] p2p_state = %d\n", __func__, rtw_p2p_state(pwdinfo) );
4127 sprintf( extra, "\n\nPort=%d\n", pwdinfo->wfd_info->peer_rtsp_ctrlport );
4128 DBG_8723A( "[%s] remote port = %d\n", __func__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
4130 wrqu->data.length = strlen( extra );
4135 static int rtw_p2p_get_peer_wfd_preferred_connection(struct net_device *dev,
4136 struct iw_request_info *info,
4137 union iwreq_data *wrqu, char *extra)
4141 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
4142 struct iw_point *pdata = &wrqu->data;
4143 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4145 sprintf( extra, "\n\nwfd_pc=%d\n", pwdinfo->wfd_info->wfd_pc );
4146 DBG_8723A( "[%s] wfd_pc = %d\n", __func__, pwdinfo->wfd_info->wfd_pc );
4148 wrqu->data.length = strlen( extra );
4149 pwdinfo->wfd_info->wfd_pc = _FALSE; // Reset the WFD preferred connection to P2P
4154 static int rtw_p2p_get_peer_wfd_session_available(struct net_device *dev,
4155 struct iw_request_info *info,
4156 union iwreq_data *wrqu, char *extra)
4160 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
4161 struct iw_point *pdata = &wrqu->data;
4162 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4164 sprintf( extra, "\n\nwfd_sa=%d\n", pwdinfo->wfd_info->peer_session_avail );
4165 DBG_8723A( "[%s] wfd_sa = %d\n", __func__, pwdinfo->wfd_info->peer_session_avail );
4167 wrqu->data.length = strlen( extra );
4168 pwdinfo->wfd_info->peer_session_avail = _TRUE; // Reset the WFD session available
4173 #endif // CONFIG_WFD
4175 static int rtw_p2p_get_go_device_address(struct net_device *dev,
4176 struct iw_request_info *info,
4177 union iwreq_data *wrqu, char *extra, char *subcmd)
4181 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
4182 u8 peerMAC[ETH_ALEN] = { 0x00 };
4183 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4184 struct list_head *plist, *phead;
4185 _queue *queue = &(pmlmepriv->scanned_queue);
4186 struct wlan_network *pnetwork = NULL;
4189 uint p2pielen = 0, attr_contentlen = 0;
4190 u8 attr_content[100] = { 0x00 };
4191 u8 go_devadd_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4193 // Commented by Albert 20121209
4194 // The input data is the GO's interface address which the application wants to know its device address.
4195 // Format: iwpriv wlanx p2p_get2 go_devadd=00:E0:4C:00:00:05
4197 DBG_8723A("[%s] data = %s\n", __func__, subcmd);
4199 macstr2num(peerMAC, subcmd);
4201 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
4203 phead = get_list_head(queue);
4204 plist = phead->next;
4208 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
4210 pnetwork = container_of(plist, struct wlan_network, list);
4211 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
4213 // Commented by Albert 2011/05/18
4214 // Match the device address located in the P2P IE
4215 // This is for the case that the P2P device address is not the same as the P2P interface address.
4217 if ((p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen)))
4221 // The P2P Device ID attribute is included in the Beacon frame.
4222 // The P2P Device Info attribute is included in the probe response frame.
4224 memset(attr_content, 0x00, 100);
4225 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen))
4227 // Handle the P2P Device ID attribute of Beacon first
4231 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen))
4233 // Handle the P2P Device Info attribute of probe response
4238 //Get the next P2P IE
4239 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
4244 plist = plist->next;
4248 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
4252 sprintf(go_devadd_str, "\n\ndev_add=NULL");
4255 sprintf(go_devadd_str, "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4256 attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
4259 wrqu->data.length = strlen(go_devadd_str);
4260 memcpy(extra, go_devadd_str, wrqu->data.length);
4266 static int rtw_p2p_get_device_type(struct net_device *dev,
4267 struct iw_request_info *info,
4268 union iwreq_data *wrqu, char *extra, char *subcmd)
4272 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
4273 u8 peerMAC[ETH_ALEN] = { 0x00 };
4274 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4275 struct list_head *plist, *phead;
4276 _queue *queue = &(pmlmepriv->scanned_queue);
4277 struct wlan_network *pnetwork = NULL;
4279 u8 dev_type[8] = { 0x00 };
4280 uint dev_type_len = 0;
4281 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
4283 // Commented by Albert 20121209
4284 // The input data is the MAC address which the application wants to know its device type.
4285 // Such user interface could know the device type.
4286 // Format: iwpriv wlanx p2p_get2 dev_type=00:E0:4C:00:00:05
4288 DBG_8723A("[%s] data = %s\n", __func__, subcmd);
4290 macstr2num(peerMAC, subcmd);
4292 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
4294 phead = get_list_head(queue);
4295 plist = phead->next;
4299 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
4301 pnetwork = container_of(plist, struct wlan_network, list);
4302 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
4307 // The mac address is matched.
4309 if ((wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len)))
4311 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len);
4316 memcpy(&type, dev_type, 2);
4317 type = be16_to_cpu(type);
4318 sprintf(dev_type_str, "\n\nN=%.2d", type);
4325 plist = plist->next;
4329 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
4333 sprintf(dev_type_str, "\n\nN=00");
4336 wrqu->data.length = strlen(dev_type_str);
4337 memcpy(extra, dev_type_str, wrqu->data.length);
4343 static int rtw_p2p_get_device_name(struct net_device *dev,
4344 struct iw_request_info *info,
4345 union iwreq_data *wrqu, char *extra, char *subcmd)
4349 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
4350 u8 peerMAC[ETH_ALEN] = { 0x00 };
4351 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4352 struct list_head *plist, *phead;
4353 _queue *queue = &(pmlmepriv->scanned_queue);
4354 struct wlan_network *pnetwork = NULL;
4356 u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = { 0x00 };
4358 u8 dev_name_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4360 // Commented by Albert 20121225
4361 // The input data is the MAC address which the application wants to know its device name.
4362 // Such user interface could show peer device's device name instead of ssid.
4363 // Format: iwpriv wlanx p2p_get2 devN=00:E0:4C:00:00:05
4365 DBG_8723A("[%s] data = %s\n", __func__, subcmd);
4367 macstr2num(peerMAC, subcmd);
4369 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
4371 phead = get_list_head(queue);
4372 plist = phead->next;
4376 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
4378 pnetwork = container_of(plist, struct wlan_network, list);
4379 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
4384 // The mac address is matched.
4386 if ((wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len)))
4388 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
4391 sprintf(dev_name_str, "\n\nN=%s", dev_name);
4398 plist = plist->next;
4402 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
4406 sprintf(dev_name_str, "\n\nN=0000");
4409 wrqu->data.length = strlen(dev_name_str);
4410 memcpy(extra, dev_name_str, wrqu->data.length);
4416 static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
4417 struct iw_request_info *info,
4418 union iwreq_data *wrqu, char *extra, char *subcmd)
4422 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
4423 u8 peerMAC[ETH_ALEN] = { 0x00 };
4424 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4425 struct list_head *plist, *phead;
4426 _queue *queue = &(pmlmepriv->scanned_queue);
4427 struct wlan_network *pnetwork = NULL;
4430 uint p2pielen = 0, attr_contentlen = 0;
4431 u8 attr_content[2] = { 0x00 };
4432 u8 inv_proc_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4434 // Commented by Ouden 20121226
4435 // The application wants to know P2P initation procedure is support or not.
4436 // Format: iwpriv wlanx p2p_get2 InvProc=00:E0:4C:00:00:05
4438 DBG_8723A("[%s] data = %s\n", __func__, subcmd);
4440 macstr2num(peerMAC, subcmd);
4442 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
4444 phead = get_list_head(queue);
4445 plist = phead->next;
4448 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4451 pnetwork = container_of(plist, struct wlan_network, list);
4452 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4453 // Commented by Albert 20121226
4454 // Match the device address located in the P2P IE
4455 // This is for the case that the P2P device address is not the same as the P2P interface address.
4457 if ((p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen))) {
4459 //memset( attr_content, 0x00, 2);
4460 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen)) {
4461 // Handle the P2P capability attribute
4466 //Get the next P2P IE
4467 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
4471 plist = plist->next;
4474 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
4477 sprintf(inv_proc_str, "\nIP=-1");
4479 if (attr_content[0] & 0x20)
4480 sprintf(inv_proc_str, "\nIP=1");
4482 sprintf(inv_proc_str, "\nIP=0");
4485 wrqu->data.length = strlen(inv_proc_str);
4486 memcpy(extra, inv_proc_str, wrqu->data.length);
4491 static int rtw_p2p_connect(struct net_device *dev,
4492 struct iw_request_info *info,
4493 union iwreq_data *wrqu, char *extra)
4497 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
4498 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4499 u8 peerMAC[ ETH_ALEN ] = { 0x00 };
4501 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
4502 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4503 struct list_head *plist, *phead;
4504 _queue *queue = &(pmlmepriv->scanned_queue);
4505 struct wlan_network *pnetwork = NULL;
4506 uint uintPeerChannel = 0;
4507 #ifdef CONFIG_CONCURRENT_MODE
4508 struct rtw_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4509 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4510 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4511 #endif // CONFIG_CONCURRENT_MODE
4513 // Commented by Albert 20110304
4514 // The input data contains two informations.
4515 // 1. First information is the MAC address which wants to formate with
4516 // 2. Second information is the WPS PINCode or "pbc" string for push button method
4517 // Format: 00:E0:4C:00:00:05
4518 // Format: 00:E0:4C:00:00:05
4520 DBG_8723A( "[%s] data = %s\n", __func__, extra );
4522 if ( pwdinfo->p2p_state == P2P_STATE_NONE )
4524 DBG_8723A( "[%s] WiFi Direct is disable!\n", __func__ );
4528 if ( pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO )
4533 for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
4535 peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
4538 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
4540 phead = get_list_head(queue);
4541 plist = phead->next;
4545 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
4548 pnetwork = container_of(plist, struct wlan_network, list);
4549 if (!memcmp( pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
4551 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
4555 plist = plist->next;
4559 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
4561 if ( uintPeerChannel )
4563 #ifdef CONFIG_CONCURRENT_MODE
4564 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
4566 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
4568 #endif // CONFIG_CONCURRENT_MODE
4570 memset( &pwdinfo->nego_req_info, 0x00, sizeof( struct tx_nego_req_info ) );
4571 memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
4573 pwdinfo->nego_req_info.peer_channel_num[ 0 ] = uintPeerChannel;
4574 memcpy(pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN );
4575 pwdinfo->nego_req_info.benable = _TRUE;
4577 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
4578 if ( rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK )
4580 // Restore to the listen state if the current p2p state is not nego OK
4581 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN );
4584 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4585 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
4587 #ifdef CONFIG_CONCURRENT_MODE
4588 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
4590 // Have to enter the power saving with the AP
4591 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
4593 issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
4595 #endif // CONFIG_CONCURRENT_MODE
4597 DBG_8723A( "[%s] Start PreTx Procedure!\n", __func__ );
4598 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
4599 #ifdef CONFIG_CONCURRENT_MODE
4600 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
4602 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_GO_NEGO_TIMEOUT );
4606 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT );
4609 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT );
4610 #endif // CONFIG_CONCURRENT_MODE
4615 DBG_8723A( "[%s] Not Found in Scanning Queue~\n", __func__ );
4622 static int rtw_p2p_invite_req(struct net_device *dev,
4623 struct iw_request_info *info,
4624 union iwreq_data *wrqu, char *extra)
4628 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
4629 struct iw_point *pdata = &wrqu->data;
4630 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4632 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
4633 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4634 struct list_head *plist, *phead;
4635 _queue *queue = &(pmlmepriv->scanned_queue);
4636 struct wlan_network *pnetwork = NULL;
4637 uint uintPeerChannel = 0;
4638 u8 attr_content[50] = { 0x00 }, _status = 0;
4640 uint p2pielen = 0, attr_contentlen = 0;
4641 struct tx_invite_req_info* pinvite_req_info = &pwdinfo->invitereq_info;
4642 #ifdef CONFIG_CONCURRENT_MODE
4643 struct rtw_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4644 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4645 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4646 #endif // CONFIG_CONCURRENT_MODE
4649 struct wifi_display_info* pwfd_info = pwdinfo->wfd_info;
4650 #endif // CONFIG_WFD
4652 // Commented by Albert 20120321
4653 // The input data contains two informations.
4654 // 1. First information is the P2P device address which you want to send to.
4655 // 2. Second information is the group id which combines with GO's mac address, space and GO's ssid.
4656 // Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy"
4657 // Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy
4659 DBG_8723A( "[%s] data = %s\n", __func__, extra );
4661 if ( wrqu->data.length <= 37 )
4663 DBG_8723A( "[%s] Wrong format!\n", __func__ );
4667 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4669 DBG_8723A( "[%s] WiFi Direct is disable!\n", __func__ );
4674 // Reset the content of struct tx_invite_req_info
4675 pinvite_req_info->benable = _FALSE;
4676 memset( pinvite_req_info->go_bssid, 0x00, ETH_ALEN );
4677 memset( pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN );
4678 pinvite_req_info->ssidlen = 0x00;
4679 pinvite_req_info->operating_ch = pwdinfo->operating_channel;
4680 memset( pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN );
4681 pinvite_req_info->token = 3;
4684 for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
4686 pinvite_req_info->peer_macaddr[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
4689 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
4691 phead = get_list_head(queue);
4692 plist = phead->next;
4696 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
4699 pnetwork = container_of(plist, struct wlan_network, list);
4701 // Commented by Albert 2011/05/18
4702 // Match the device address located in the P2P IE
4703 // This is for the case that the P2P device address is not the same as the P2P interface address.
4705 if ( (p2pie=rtw_get_p2p_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen)) )
4707 // The P2P Device ID attribute is included in the Beacon frame.
4708 // The P2P Device Info attribute is included in the probe response frame.
4710 if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
4712 // Handle the P2P Device ID attribute of Beacon first
4713 if (!memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN))
4715 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
4719 else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
4721 // Handle the P2P Device Info attribute of probe response
4722 if (!memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN))
4724 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
4731 plist = plist->next;
4735 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
4738 if ( uintPeerChannel )
4740 u8 wfd_ie[ 128 ] = { 0x00 };
4743 if ( rtw_get_wfd_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, wfd_ie, &wfd_ielen ) )
4745 u8 wfd_devinfo[ 6 ] = { 0x00 };
4746 uint wfd_devlen = 6;
4748 DBG_8723A( "[%s] Found WFD IE!\n", __func__ );
4749 if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) )
4751 u16 wfd_devinfo_field = 0;
4753 // Commented by Albert 20120319
4754 // The first two bytes are the WFD device information field of WFD device information subelement.
4755 // In big endian format.
4756 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
4757 if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL )
4759 pwfd_info->peer_session_avail = _TRUE;
4763 pwfd_info->peer_session_avail = _FALSE;
4768 if ( _FALSE == pwfd_info->peer_session_avail )
4770 DBG_8723A( "[%s] WFD Session not avaiable!\n", __func__ );
4774 #endif // CONFIG_WFD
4776 if ( uintPeerChannel )
4778 #ifdef CONFIG_CONCURRENT_MODE
4779 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
4781 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
4783 #endif // CONFIG_CONCURRENT_MODE
4785 // Store the GO's bssid
4786 for( jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3 )
4788 pinvite_req_info->go_bssid[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
4791 // Store the GO's ssid
4792 pinvite_req_info->ssidlen = wrqu->data.length - 36;
4793 memcpy(pinvite_req_info->go_ssid, &extra[ 36 ], (u32) pinvite_req_info->ssidlen );
4794 pinvite_req_info->benable = _TRUE;
4795 pinvite_req_info->peer_ch = uintPeerChannel;
4797 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4798 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ);
4800 #ifdef CONFIG_CONCURRENT_MODE
4801 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
4803 // Have to enter the power saving with the AP
4804 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
4806 issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
4810 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4813 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4816 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
4818 #ifdef CONFIG_CONCURRENT_MODE
4819 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
4821 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_INVITE_TIMEOUT );
4825 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT );
4828 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT );
4829 #endif // CONFIG_CONCURRENT_MODE
4835 DBG_8723A( "[%s] NOT Found in the Scanning Queue!\n", __func__ );
4843 static int rtw_p2p_set_persistent(struct net_device *dev,
4844 struct iw_request_info *info,
4845 union iwreq_data *wrqu, char *extra)
4849 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
4850 struct iw_point *pdata = &wrqu->data;
4851 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4853 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
4854 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4855 struct list_head *plist, *phead;
4856 _queue *queue = &(pmlmepriv->scanned_queue);
4857 struct wlan_network *pnetwork = NULL;
4858 uint uintPeerChannel = 0;
4859 u8 attr_content[50] = { 0x00 }, _status = 0;
4861 uint p2pielen = 0, attr_contentlen = 0;
4862 struct tx_invite_req_info* pinvite_req_info = &pwdinfo->invitereq_info;
4863 #ifdef CONFIG_CONCURRENT_MODE
4864 struct rtw_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4865 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4866 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4867 #endif // CONFIG_CONCURRENT_MODE
4870 struct wifi_display_info* pwfd_info = pwdinfo->wfd_info;
4871 #endif // CONFIG_WFD
4873 // Commented by Albert 20120328
4874 // The input data is 0 or 1
4875 // 0: disable persistent group functionality
4876 // 1: enable persistent group founctionality
4878 DBG_8723A( "[%s] data = %s\n", __func__, extra );
4880 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4882 DBG_8723A( "[%s] WiFi Direct is disable!\n", __func__ );
4887 if ( extra[ 0 ] == '0' ) // Disable the persistent group function.
4889 pwdinfo->persistent_supported = _FALSE;
4891 else if ( extra[ 0 ] == '1' ) // Enable the persistent group function.
4893 pwdinfo->persistent_supported = _TRUE;
4897 pwdinfo->persistent_supported = _FALSE;
4900 printk( "[%s] persistent_supported = %d\n", __func__, pwdinfo->persistent_supported );
4909 static int rtw_p2p_set_pc(struct net_device *dev,
4910 struct iw_request_info *info,
4911 union iwreq_data *wrqu, char *extra)
4915 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
4916 struct iw_point *pdata = &wrqu->data;
4917 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4918 u8 peerMAC[ ETH_ALEN ] = { 0x00 };
4920 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
4921 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4922 struct list_head *plist, *phead;
4923 _queue *queue = &(pmlmepriv->scanned_queue);
4924 struct wlan_network *pnetwork = NULL;
4925 u8 attr_content[50] = { 0x00 }, _status = 0;
4927 uint p2pielen = 0, attr_contentlen = 0;
4928 uint uintPeerChannel = 0;
4929 #ifdef CONFIG_CONCURRENT_MODE
4930 struct rtw_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4931 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4932 #endif // CONFIG_CONCURRENT_MODE
4933 struct wifi_display_info* pwfd_info = pwdinfo->wfd_info;
4935 // Commented by Albert 20120512
4936 // 1. Input information is the MAC address which wants to know the Preferred Connection bit (PC bit)
4937 // Format: 00:E0:4C:00:00:05
4939 DBG_8723A( "[%s] data = %s\n", __func__, extra );
4941 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4943 DBG_8723A( "[%s] WiFi Direct is disable!\n", __func__ );
4947 for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
4949 peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
4952 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
4954 phead = get_list_head(queue);
4955 plist = phead->next;
4959 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
4962 pnetwork = container_of(plist, struct wlan_network, list);
4964 // Commented by Albert 2011/05/18
4965 // Match the device address located in the P2P IE
4966 // This is for the case that the P2P device address is not the same as the P2P interface address.
4968 if ( (p2pie=rtw_get_p2p_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen)) )
4970 // The P2P Device ID attribute is included in the Beacon frame.
4971 // The P2P Device Info attribute is included in the probe response frame.
4972 printk( "[%s] Got P2P IE\n", __func__ );
4973 if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
4975 // Handle the P2P Device ID attribute of Beacon first
4976 printk( "[%s] P2P_ATTR_DEVICE_ID \n", __func__ );
4977 if (!memcmp(attr_content, peerMAC, ETH_ALEN))
4979 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
4983 else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
4985 // Handle the P2P Device Info attribute of probe response
4986 printk( "[%s] P2P_ATTR_DEVICE_INFO \n", __func__ );
4987 if (!memcmp( attr_content, peerMAC, ETH_ALEN))
4989 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
4996 plist = plist->next;
5000 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
5001 printk( "[%s] channel = %d\n", __func__, uintPeerChannel );
5003 if ( uintPeerChannel )
5005 u8 wfd_ie[ 128 ] = { 0x00 };
5008 if ( rtw_get_wfd_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, wfd_ie, &wfd_ielen ) )
5010 u8 wfd_devinfo[ 6 ] = { 0x00 };
5011 uint wfd_devlen = 6;
5013 DBG_8723A( "[%s] Found WFD IE!\n", __func__ );
5014 if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) )
5016 u16 wfd_devinfo_field = 0;
5018 // Commented by Albert 20120319
5019 // The first two bytes are the WFD device information field of WFD device information subelement.
5020 // In big endian format.
5021 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5022 if ( wfd_devinfo_field & WFD_DEVINFO_PC_TDLS )
5024 pwfd_info->wfd_pc = _TRUE;
5028 pwfd_info->wfd_pc = _FALSE;
5035 DBG_8723A( "[%s] NOT Found in the Scanning Queue!\n", __func__ );
5044 static int rtw_p2p_set_wfd_device_type(struct net_device *dev,
5045 struct iw_request_info *info,
5046 union iwreq_data *wrqu, char *extra)
5050 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
5051 struct iw_point *pdata = &wrqu->data;
5052 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5053 struct wifi_display_info* pwfd_info = pwdinfo->wfd_info;
5055 // Commented by Albert 20120328
5056 // The input data is 0 or 1
5057 // 0: specify to Miracast source device
5058 // 1 or others: specify to Miracast sink device (display device)
5060 DBG_8723A( "[%s] data = %s\n", __func__, extra );
5062 if ( extra[ 0 ] == '0' ) // Set to Miracast source device.
5064 pwfd_info->wfd_device_type = WFD_DEVINFO_SOURCE;
5066 else // Set to Miracast sink device.
5068 pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK;
5077 static int rtw_p2p_set_scan_result_type(struct net_device *dev,
5078 struct iw_request_info *info,
5079 union iwreq_data *wrqu, char *extra)
5083 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
5084 struct iw_point *pdata = &wrqu->data;
5085 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5086 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5088 // Commented by Albert 20120328
5089 // The input data is 0 , 1 , 2
5090 // 0: when the P2P is enabled, the scan result will return all the found P2P device.
5091 // 1: when the P2P is enabled, the scan result will return all the found P2P device and AP.
5092 // 2: when the P2P is enabled, the scan result will show up the found Miracast devices base on...
5093 // It will show up all the Miracast source device if this device is sink.
5094 // It will show up all the Miracast sink device if this device is source.
5096 DBG_8723A( "[%s] data = %s\n", __func__, extra );
5098 if ( extra[ 0 ] == '0' )
5100 pwfd_info->scan_result_type = SCAN_RESULT_P2P_ONLY;
5102 else if ( extra[ 0 ] == '1' )
5104 pwfd_info->scan_result_type = SCAN_RESULT_ALL;
5106 else if ( extra[ 0 ] == '2' )
5108 pwfd_info->scan_result_type = SCAN_RESULT_WFD_TYPE;
5112 pwfd_info->scan_result_type = SCAN_RESULT_P2P_ONLY;
5121 // To set the WFD session available to enable or disable
5122 static int rtw_p2p_set_sa(struct net_device *dev,
5123 struct iw_request_info *info,
5124 union iwreq_data *wrqu, char *extra)
5128 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
5129 struct iw_point *pdata = &wrqu->data;
5130 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5131 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5133 DBG_8723A( "[%s] data = %s\n", __func__, extra );
5137 DBG_8723A( "[%s] WiFi Direct is disable!\n", __func__ );
5142 if ( extra[ 0 ] == '0' ) // Disable the session available.
5144 pwdinfo->session_available = _FALSE;
5146 else if ( extra[ 0 ] == '1' ) // Enable the session available.
5148 pwdinfo->session_available = _TRUE;
5152 pwdinfo->session_available = _FALSE;
5155 printk( "[%s] session available = %d\n", __func__, pwdinfo->session_available );
5162 #endif // CONFIG_WFD
5164 static int rtw_p2p_prov_disc(struct net_device *dev,
5165 struct iw_request_info *info,
5166 union iwreq_data *wrqu, char *extra)
5169 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
5170 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5171 u8 peerMAC[ ETH_ALEN ] = { 0x00 };
5173 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5174 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5175 struct list_head *plist, *phead;
5176 _queue *queue = &(pmlmepriv->scanned_queue);
5177 struct wlan_network *pnetwork = NULL;
5178 uint uintPeerChannel = 0;
5179 u8 attr_content[100] = { 0x00 }, _status = 0;
5181 uint p2pielen = 0, attr_contentlen = 0;
5182 #ifdef CONFIG_CONCURRENT_MODE
5183 struct rtw_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5184 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5185 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5186 #endif // CONFIG_CONCURRENT_MODE
5188 struct wifi_display_info* pwfd_info = pwdinfo->wfd_info;
5189 #endif // CONFIG_WFD
5191 // Commented by Albert 20110301
5192 // The input data contains two informations.
5193 // 1. First information is the MAC address which wants to issue the provisioning discovery request frame.
5194 // 2. Second information is the WPS configuration method which wants to discovery
5195 // Format: 00:E0:4C:00:00:05_display
5196 // Format: 00:E0:4C:00:00:05_keypad
5197 // Format: 00:E0:4C:00:00:05_pbc
5198 // Format: 00:E0:4C:00:00:05_label
5200 DBG_8723A( "[%s] data = %s\n", __func__, extra );
5202 if ( pwdinfo->p2p_state == P2P_STATE_NONE )
5204 DBG_8723A( "[%s] WiFi Direct is disable!\n", __func__ );
5209 // Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request.
5210 memset( pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN );
5211 memset( pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN );
5212 memset( &pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof( NDIS_802_11_SSID ) );
5213 pwdinfo->tx_prov_disc_info.peer_channel_num[ 0 ] = 0;
5214 pwdinfo->tx_prov_disc_info.peer_channel_num[ 1 ] = 0;
5215 pwdinfo->tx_prov_disc_info.benable = _FALSE;
5218 for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
5220 peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
5223 if (!memcmp(&extra[ 18 ], "display", 7))
5225 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
5227 else if (!memcmp( &extra[ 18 ], "keypad", 7))
5229 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
5231 else if (!memcmp( &extra[ 18 ], "pbc", 3))
5233 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
5235 else if (!memcmp( &extra[ 18 ], "label", 5))
5237 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
5241 DBG_8723A( "[%s] Unknown WPS config methodn", __func__ );
5245 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
5247 phead = get_list_head(queue);
5248 plist = phead->next;
5252 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
5255 if( uintPeerChannel != 0 )
5258 pnetwork = container_of(plist, struct wlan_network, list);
5260 // Commented by Albert 2011/05/18
5261 // Match the device address located in the P2P IE
5262 // This is for the case that the P2P device address is not the same as the P2P interface address.
5264 if ( (p2pie=rtw_get_p2p_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen)) )
5268 // The P2P Device ID attribute is included in the Beacon frame.
5269 // The P2P Device Info attribute is included in the probe response frame.
5271 if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
5273 // Handle the P2P Device ID attribute of Beacon first
5274 if (!memcmp( attr_content, peerMAC, ETH_ALEN))
5276 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5280 else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
5282 // Handle the P2P Device Info attribute of probe response
5283 if (!memcmp( attr_content, peerMAC, ETH_ALEN))
5285 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5290 //Get the next P2P IE
5291 p2pie = rtw_get_p2p_ie(p2pie+p2pielen, pnetwork->network.IELength - 12 -(p2pie -&pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
5296 plist = plist->next;
5300 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
5304 u8 wfd_ie[ 128 ] = { 0x00 };
5307 if ( rtw_get_wfd_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, wfd_ie, &wfd_ielen ) )
5309 u8 wfd_devinfo[ 6 ] = { 0x00 };
5310 uint wfd_devlen = 6;
5312 DBG_8723A( "[%s] Found WFD IE!\n", __func__ );
5313 if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) )
5315 u16 wfd_devinfo_field = 0;
5317 // Commented by Albert 20120319
5318 // The first two bytes are the WFD device information field of WFD device information subelement.
5319 // In big endian format.
5320 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5321 if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL )
5323 pwfd_info->peer_session_avail = _TRUE;
5327 pwfd_info->peer_session_avail = _FALSE;
5332 if ( _FALSE == pwfd_info->peer_session_avail )
5334 DBG_8723A( "[%s] WFD Session not avaiable!\n", __func__ );
5338 #endif // CONFIG_WFD
5340 if ( uintPeerChannel )
5343 DBG_8723A( "[%s] peer channel: %d!\n", __func__, uintPeerChannel );
5344 #ifdef CONFIG_CONCURRENT_MODE
5345 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5347 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
5349 #endif // CONFIG_CONCURRENT_MODE
5350 memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN );
5351 memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN );
5352 pwdinfo->tx_prov_disc_info.peer_channel_num[0] = ( u16 ) uintPeerChannel;
5353 pwdinfo->tx_prov_disc_info.benable = _TRUE;
5354 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5355 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ);
5357 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
5359 memcpy(&pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof( NDIS_802_11_SSID ) );
5361 else if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
5363 memcpy(pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN );
5364 pwdinfo->tx_prov_disc_info.ssid.SsidLength= P2P_WILDCARD_SSID_LEN;
5367 #ifdef CONFIG_CONCURRENT_MODE
5368 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5370 // Have to enter the power saving with the AP
5371 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
5373 issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
5377 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
5380 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
5383 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
5385 #ifdef CONFIG_CONCURRENT_MODE
5386 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5388 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_PROVISION_TIMEOUT );
5392 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
5395 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
5396 #endif // CONFIG_CONCURRENT_MODE
5401 DBG_8723A( "[%s] NOT Found in the Scanning Queue!\n", __func__ );
5409 // Added by Albert 20110328
5410 // This function is used to inform the driver the user had specified the pin code value or pbc
5413 static int rtw_p2p_got_wpsinfo(struct net_device *dev,
5414 struct iw_request_info *info,
5415 union iwreq_data *wrqu, char *extra)
5419 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
5420 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5423 DBG_8723A( "[%s] data = %s\n", __func__, extra );
5424 // Added by Albert 20110328
5425 // if the input data is P2P_NO_WPSINFO -> reset the wpsinfo
5426 // if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device.
5427 // if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself.
5428 // if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC
5430 if ( *extra == '0' )
5432 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
5434 else if ( *extra == '1' )
5436 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN;
5438 else if ( *extra == '2' )
5440 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN;
5442 else if ( *extra == '3' )
5444 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC;
5448 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
5457 static int rtw_p2p_set(struct net_device *dev,
5458 struct iw_request_info *info,
5459 union iwreq_data *wrqu, char *extra)
5465 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
5466 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5467 struct iw_point *pdata = &wrqu->data;
5468 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
5469 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5471 DBG_8723A( "[%s] extra = %s\n", __func__, extra );
5473 if (!memcmp( extra, "enable=", 7))
5475 rtw_wext_p2p_enable( dev, info, wrqu, &extra[7] );
5477 else if (!memcmp( extra, "setDN=", 6))
5479 wrqu->data.length -= 6;
5480 rtw_p2p_setDN( dev, info, wrqu, &extra[6] );
5482 else if (!memcmp( extra, "profilefound=", 13))
5484 wrqu->data.length -= 13;
5485 rtw_p2p_profilefound( dev, info, wrqu, &extra[13] );
5487 else if (!memcmp( extra, "prov_disc=", 10))
5489 wrqu->data.length -= 10;
5490 rtw_p2p_prov_disc( dev, info, wrqu, &extra[10] );
5492 else if (!memcmp( extra, "nego=", 5))
5494 wrqu->data.length -= 5;
5495 rtw_p2p_connect( dev, info, wrqu, &extra[5] );
5497 else if (!memcmp( extra, "intent=", 7))
5499 // Commented by Albert 2011/03/23
5500 // The wrqu->data.length will include the null character
5501 // So, we will decrease 7 + 1
5502 wrqu->data.length -= 8;
5503 rtw_p2p_set_intent( dev, info, wrqu, &extra[7] );
5505 else if (!memcmp( extra, "ssid=", 5))
5507 wrqu->data.length -= 5;
5508 rtw_p2p_set_go_nego_ssid( dev, info, wrqu, &extra[5] );
5510 else if (!memcmp( extra, "got_wpsinfo=", 12))
5512 wrqu->data.length -= 12;
5513 rtw_p2p_got_wpsinfo( dev, info, wrqu, &extra[12] );
5515 else if (!memcmp( extra, "listen_ch=", 10))
5517 // Commented by Albert 2011/05/24
5518 // The wrqu->data.length will include the null character
5519 // So, we will decrease (10 + 1)
5520 wrqu->data.length -= 11;
5521 rtw_p2p_set_listen_ch( dev, info, wrqu, &extra[10] );
5523 else if (!memcmp( extra, "op_ch=", 6))
5525 // Commented by Albert 2011/05/24
5526 // The wrqu->data.length will include the null character
5527 // So, we will decrease (6 + 1)
5528 wrqu->data.length -= 7;
5529 rtw_p2p_set_op_ch( dev, info, wrqu, &extra[6] );
5531 else if (!memcmp( extra, "invite=", 7))
5533 wrqu->data.length -= 8;
5534 rtw_p2p_invite_req( dev, info, wrqu, &extra[7] );
5536 else if (!memcmp( extra, "persistent=", 11))
5538 wrqu->data.length -= 11;
5539 rtw_p2p_set_persistent( dev, info, wrqu, &extra[11] );
5542 else if (!memcmp( extra, "sa=", 3))
5544 // sa: WFD Session Available information
5545 wrqu->data.length -= 3;
5546 rtw_p2p_set_sa( dev, info, wrqu, &extra[3] );
5548 else if (!memcmp( extra, "pc=", 3))
5550 // pc: WFD Preferred Connection
5551 wrqu->data.length -= 3;
5552 rtw_p2p_set_pc( dev, info, wrqu, &extra[3] );
5554 else if (!memcmp( extra, "wfd_type=", 9))
5556 // Specify this device is Mircast source or sink
5557 wrqu->data.length -= 9;
5558 rtw_p2p_set_wfd_device_type( dev, info, wrqu, &extra[9] );
5560 else if (!memcmp( extra, "scan_type=", 10))
5562 wrqu->data.length -= 10;
5563 rtw_p2p_set_scan_result_type( dev, info, wrqu, &extra[10] );
5573 static int rtw_p2p_get(struct net_device *dev,
5574 struct iw_request_info *info,
5575 union iwreq_data *wrqu, char *extra)
5582 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
5583 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5584 struct iw_point *pdata = &wrqu->data;
5585 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
5586 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5588 if ( padapter->bShowGetP2PState )
5590 DBG_8723A( "[%s] extra = %s\n", __func__, (char*) wrqu->data.pointer );
5593 if (!memcmp(wrqu->data.pointer, "status", 6))
5595 rtw_p2p_get_status( dev, info, wrqu, extra );
5597 else if (!memcmp(wrqu->data.pointer, "role", 4))
5599 rtw_p2p_get_role( dev, info, wrqu, extra);
5601 else if (!memcmp(wrqu->data.pointer, "peer_ifa", 8))
5603 rtw_p2p_get_peer_ifaddr( dev, info, wrqu, extra);
5605 else if (!memcmp(wrqu->data.pointer, "req_cm", 6))
5607 rtw_p2p_get_req_cm( dev, info, wrqu, extra);
5609 else if (!memcmp(wrqu->data.pointer, "peer_deva", 9))
5611 // Get the P2P device address when receiving the provision discovery request frame.
5612 rtw_p2p_get_peer_devaddr( dev, info, wrqu, extra);
5614 else if (!memcmp(wrqu->data.pointer, "group_id", 8))
5616 rtw_p2p_get_groupid( dev, info, wrqu, extra);
5618 else if (!memcmp(wrqu->data.pointer, "peer_deva_inv", 9))
5620 // Get the P2P device address when receiving the P2P Invitation request frame.
5621 rtw_p2p_get_peer_devaddr_by_invitation( dev, info, wrqu, extra);
5623 else if (!memcmp(wrqu->data.pointer, "op_ch", 5))
5625 rtw_p2p_get_op_ch( dev, info, wrqu, extra);
5628 else if (!memcmp(wrqu->data.pointer, "peer_port", 9))
5630 rtw_p2p_get_peer_wfd_port( dev, info, wrqu, extra );
5632 else if (!memcmp(wrqu->data.pointer, "wfd_sa", 6))
5634 rtw_p2p_get_peer_wfd_session_available( dev, info, wrqu, extra );
5636 else if (!memcmp( wrqu->data.pointer, "wfd_pc", 6))
5638 rtw_p2p_get_peer_wfd_preferred_connection( dev, info, wrqu, extra );
5640 #endif // CONFIG_WFD
5648 static int rtw_p2p_get2(struct net_device *dev,
5649 struct iw_request_info *info,
5650 union iwreq_data *wrqu, char *extra)
5656 int length = wrqu->data.length;
5657 char *buffer = (u8 *)kmalloc(length, GFP_KERNEL);
5659 if (buffer == NULL) {
5664 if (copy_from_user(buffer, wrqu->data.pointer, wrqu->data.length)) {
5669 DBG_8723A("[%s] buffer = %s\n", __func__, buffer);
5671 if (!memcmp(buffer, "wpsCM=", 6)) {
5672 ret = rtw_p2p_get_wps_configmethod(dev, info, wrqu, extra, &buffer[6]);
5673 } else if (!memcmp(buffer, "devN=", 5)) {
5674 ret = rtw_p2p_get_device_name(dev, info, wrqu, extra, &buffer[5]);
5675 } else if (!memcmp(buffer, "dev_type=", 9)) {
5676 ret = rtw_p2p_get_device_type(dev, info, wrqu, extra, &buffer[9]);
5677 } else if (!memcmp(buffer, "go_devadd=", 10)) {
5678 ret = rtw_p2p_get_go_device_address(dev, info, wrqu, extra, &buffer[10]);
5679 } else if (!memcmp(buffer, "InvProc=", 8)) {
5680 ret = rtw_p2p_get_invitation_procedure(dev, info, wrqu, extra, &buffer[8]);
5682 snprintf(extra, sizeof("Command not found."), "Command not found.");
5683 wrqu->data.length = strlen(extra);
5694 static int rtw_cta_test_start(struct net_device *dev,
5695 struct iw_request_info *info,
5696 union iwreq_data *wrqu, char *extra)
5699 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
5700 DBG_8723A("%s %s\n", __func__, extra);
5701 if (!strcmp(extra, "1"))
5702 padapter->in_cta_test = 1;
5704 padapter->in_cta_test = 0;
5706 if(padapter->in_cta_test)
5708 u32 v = rtw_read32(padapter, REG_RCR);
5709 v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN );//| RCR_ADF
5710 rtw_write32(padapter, REG_RCR, v);
5711 DBG_8723A("enable RCR_ADF\n");
5715 u32 v = rtw_read32(padapter, REG_RCR);
5716 v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN ;//| RCR_ADF
5717 rtw_write32(padapter, REG_RCR, v);
5718 DBG_8723A("disable RCR_ADF\n");
5724 extern int rtw_change_ifname(struct rtw_adapter *padapter, const char *ifname);
5725 static int rtw_rereg_nd_name(struct net_device *dev,
5726 struct iw_request_info *info,
5727 union iwreq_data *wrqu, char *extra)
5730 struct rtw_adapter *padapter = rtw_netdev_priv(dev);
5731 struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;
5732 char new_ifname[IFNAMSIZ];
5734 if(rereg_priv->old_ifname[0] == 0) {
5736 #ifdef CONFIG_CONCURRENT_MODE
5737 if (padapter->isprimary)
5738 reg_ifname = padapter->registrypriv.ifname;
5741 reg_ifname = padapter->registrypriv.if2name;
5743 strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);
5744 rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
5747 //DBG_8723A("%s wrqu->data.length:%d\n", __func__, wrqu->data.length);
5748 if(wrqu->data.length > IFNAMSIZ)
5751 if ( copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ) ) {
5755 if( 0 == strcmp(rereg_priv->old_ifname, new_ifname) ) {
5759 DBG_8723A("%s new_ifname:%s\n", __func__, new_ifname);
5760 if( 0 != (ret = rtw_change_ifname(padapter, new_ifname)) ) {
5764 if(!memcmp(rereg_priv->old_ifname, "disable%d", 9)) {
5765 padapter->ledpriv.bRegUseLed= rereg_priv->old_bRegUseLed;
5766 rtw_hal_sw_led_init(padapter);
5767 rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode);
5770 strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
5771 rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
5773 if(!memcmp(new_ifname, "disable%d", 9)) {
5775 DBG_8723A("%s disable\n", __func__);
5776 // free network queue for Android's timming issue
5777 rtw_free_network_queue(padapter, _TRUE);
5780 rtw_led_control(padapter, LED_CTL_POWER_OFF);
5781 rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed;
5782 padapter->ledpriv.bRegUseLed= _FALSE;
5783 rtw_hal_sw_led_deinit(padapter);
5785 // the interface is being "disabled", we can do deeper IPS
5786 rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv);
5787 rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL);
5794 static void mac_reg_dump(struct rtw_adapter *padapter)
5797 printk("\n======= MAC REG =======\n");
5798 for(i=0x0;i<0x300;i+=4)
5800 if(j%4==1) printk("0x%02x",i);
5801 printk(" 0x%08x ",rtw_read32(padapter,i));
5802 if((j++)%4 == 0) printk("\n");
5804 for(i=0x400;i<0x800;i+=4)
5806 if(j%4==1) printk("0x%02x",i);
5807 printk(" 0x%08x ",rtw_read32(padapter,i));
5808 if((j++)%4 == 0) printk("\n");
5811 void bb_reg_dump(struct rtw_adapter *padapter)
5814 printk("\n======= BB REG =======\n");
5815 for(i=0x800;i<0x1000;i+=4)
5817 if(j%4==1) printk("0x%02x",i);
5819 printk(" 0x%08x ",rtw_read32(padapter,i));
5820 if((j++)%4 == 0) printk("\n");
5823 void rf_reg_dump(struct rtw_adapter *padapter)
5827 u8 rf_type,path_nums = 0;
5828 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
5830 printk("\n======= RF REG =======\n");
5831 if((RF_1T2R == rf_type) ||(RF_1T1R ==rf_type ))
5836 for(path=0;path<path_nums;path++)
5838 printk("\nRF_Path(%x)\n",path);
5839 for(i=0;i<0x100;i++)
5841 //value = PHY_QueryRFReg(padapter, (RF_RADIO_PATH_E)path,i, bMaskDWord);
5842 value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
5843 if(j%4==1) printk("0x%02x ",i);
5844 printk(" 0x%08x ",value);
5845 if((j++)%4==0) printk("\n");
5851 #include <rtw_iol.h>
5853 static int rtw_dbg_port(struct net_device *dev,
5854 struct iw_request_info *info,
5855 union iwreq_data *wrqu, char *extra)
5858 u8 major_cmd, minor_cmd;
5860 u32 extra_arg, *pdata, val32;
5861 struct sta_info *psta;
5862 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
5863 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5864 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5865 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5866 struct security_priv *psecuritypriv = &padapter->securitypriv;
5867 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
5868 struct sta_priv *pstapriv = &padapter->stapriv;
5871 pdata = (u32*)&wrqu->data;
5874 arg = (u16)(val32&0x0000ffff);
5875 major_cmd = (u8)(val32>>24);
5876 minor_cmd = (u8)((val32>>16)&0x00ff);
5878 extra_arg = *(pdata+1);
5882 case 0x70://read_reg
5886 DBG_8723A("rtw_read8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
5889 DBG_8723A("rtw_read16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
5892 DBG_8723A("rtw_read32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
5896 case 0x71://write_reg
5900 rtw_write8(padapter, arg, extra_arg);
5901 DBG_8723A("rtw_write8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
5904 rtw_write16(padapter, arg, extra_arg);
5905 DBG_8723A("rtw_write16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
5908 rtw_write32(padapter, arg, extra_arg);
5909 DBG_8723A("rtw_write32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
5914 DBG_8723A("read_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
5916 case 0x73://write_bb
5917 rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);
5918 DBG_8723A("write_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
5921 DBG_8723A("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));
5923 case 0x75://write_rf
5924 rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
5925 DBG_8723A("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));
5930 case 0x00: //normal mode,
5931 padapter->recvpriv.is_signal_dbg = 0;
5933 case 0x01: //dbg mode
5934 padapter->recvpriv.is_signal_dbg = 1;
5935 extra_arg = extra_arg > 100 ? 100 : extra_arg;
5936 padapter->recvpriv.signal_strength_dbg = extra_arg;
5940 case 0x78: //IOL test
5943 case 0x04: //LLT table initialization test
5945 u8 page_boundary = 0xf9;
5947 struct xmit_frame *xmit_frame;
5949 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
5954 rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary);
5957 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500,0) )
5962 case 0x05: //blink LED test
5966 u32 blink_delay_ms = 200;
5970 struct xmit_frame *xmit_frame;
5972 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
5977 for(i=0;i<blink_num;i++){
5978 #ifdef CONFIG_IOL_NEW_GENERATION
5979 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00,0xff);
5980 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5981 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08,0xff);
5982 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5984 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00);
5985 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5986 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08);
5987 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5990 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms*blink_num*2)+200,0) )
5996 case 0x06: //continuous write byte test
5999 u16 start_value = 0;
6000 u32 write_num = extra_arg;
6005 struct xmit_frame *xmit_frame;
6007 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6012 for(i=0;i<write_num;i++){
6013 #ifdef CONFIG_IOL_NEW_GENERATION
6014 rtw_IOL_append_WB_cmd(xmit_frame, reg, i+start_value,0xFF);
6016 rtw_IOL_append_WB_cmd(xmit_frame, reg, i+start_value);
6019 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
6023 if(start_value+write_num-1 == (final=rtw_read8(padapter, reg)) ) {
6024 DBG_8723A("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6026 DBG_8723A("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6031 case 0x07: //continuous write word test
6034 u16 start_value = 200;
6035 u32 write_num = extra_arg;
6041 struct xmit_frame *xmit_frame;
6043 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6048 for(i=0;i<write_num;i++){
6049 #ifdef CONFIG_IOL_NEW_GENERATION
6050 rtw_IOL_append_WW_cmd(xmit_frame, reg, i+start_value,0xFFFF);
6052 rtw_IOL_append_WW_cmd(xmit_frame, reg, i+start_value);
6055 if(_SUCCESS !=rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
6059 if(start_value+write_num-1 == (final=rtw_read16(padapter, reg)) ) {
6060 DBG_8723A("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6062 DBG_8723A("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6067 case 0x08: //continuous write dword test
6070 u32 start_value = 0x110000c7;
6071 u32 write_num = extra_arg;
6075 struct xmit_frame *xmit_frame;
6077 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
6082 for(i=0;i<write_num;i++){
6083 #ifdef CONFIG_IOL_NEW_GENERATION
6084 rtw_IOL_append_WD_cmd(xmit_frame, reg, i+start_value,0xFFFFFFFF);
6086 rtw_IOL_append_WD_cmd(xmit_frame, reg, i+start_value);
6089 if(_SUCCESS !=rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
6093 if(start_value+write_num-1 == (final=rtw_read32(padapter, reg)) ) {
6094 DBG_8723A("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6096 DBG_8723A("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6105 * dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15
6106 * dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15
6108 u8 value = extra_arg & 0x0f;
6109 u8 sign = minor_cmd;
6110 u16 write_value = 0;
6112 DBG_8723A("%s set RESP_TXAGC to %s %u\n", __func__, sign?"minus":"plus", value);
6115 value = value | 0x10;
6117 write_value = value | (value << 5);
6118 rtw_write16(padapter, 0x6d9, write_value);
6122 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
6123 , WLAN_REASON_EXPIRATION_CHK);
6129 DBG_8723A("fwstate=0x%x\n", get_fwstate(pmlmepriv));
6132 DBG_8723A("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",
6133 psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
6134 psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
6137 DBG_8723A("pmlmeinfo->state=0x%x\n", pmlmeinfo->state);
6140 DBG_8723A("qos_option=%d\n", pmlmepriv->qospriv.qos_option);
6141 #ifdef CONFIG_80211N_HT
6142 DBG_8723A("ht_option=%d\n", pmlmepriv->htpriv.ht_option);
6143 #endif //CONFIG_80211N_HT
6146 DBG_8723A("cur_ch=%d\n", pmlmeext->cur_channel);
6147 DBG_8723A("cur_bw=%d\n", pmlmeext->cur_bwmode);
6148 DBG_8723A("cur_ch_off=%d\n", pmlmeext->cur_ch_offset);
6151 psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
6155 struct recv_reorder_ctrl *preorder_ctrl;
6157 DBG_8723A("SSID=%s\n", cur_network->network.Ssid.Ssid);
6158 DBG_8723A("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
6159 DBG_8723A("cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
6160 DBG_8723A("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
6161 DBG_8723A("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
6162 #ifdef CONFIG_80211N_HT
6163 DBG_8723A("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
6164 DBG_8723A("bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
6165 DBG_8723A("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
6166 DBG_8723A("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
6167 #endif //CONFIG_80211N_HT
6171 preorder_ctrl = &psta->recvreorder_ctrl[i];
6172 if(preorder_ctrl->enable)
6174 DBG_8723A("tid=%d, indicate_seq=%d\n", i, preorder_ctrl->indicate_seq);
6181 DBG_8723A("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));
6187 rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8*)(&ODMFlag));
6188 DBG_8723A("(B)DMFlag=0x%x, arg=0x%x\n", ODMFlag, arg);
6189 ODMFlag = (u32)(0x0f&arg);
6190 DBG_8723A("(A)DMFlag=0x%x\n", ODMFlag);
6191 rtw_hal_set_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
6195 DBG_8723A("bSurpriseRemoved=%d, bDriverStopped=%d\n",
6196 padapter->bSurpriseRemoved, padapter->bDriverStopped);
6200 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6201 struct recv_priv *precvpriv = &padapter->recvpriv;
6203 DBG_8723A("free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d"
6204 ", free_xmit_extbuf_cnt=%d, free_xframe_ext_cnt=%d"
6205 ", free_recvframe_cnt=%d\n",
6206 pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt,
6207 pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt,
6208 precvpriv->free_recvframe_cnt);
6209 DBG_8723A("rx_urb_pending_cn=%d\n", precvpriv->rx_pending_cnt);
6215 struct list_head *plist, *phead;
6216 struct recv_reorder_ctrl *preorder_ctrl;
6218 #ifdef CONFIG_AP_MODE
6219 DBG_8723A("sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
6221 spin_lock_bh(&pstapriv->sta_hash_lock);
6223 for(i=0; i< NUM_STA; i++)
6225 phead = &(pstapriv->sta_hash[i]);
6226 plist = phead->next;
6228 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
6230 psta = container_of(plist, struct sta_info, hash_list);
6232 plist = plist->next;
6234 if(extra_arg == psta->aid)
6236 DBG_8723A("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
6237 DBG_8723A("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
6238 DBG_8723A("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
6239 #ifdef CONFIG_80211N_HT
6240 DBG_8723A("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
6241 DBG_8723A("bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
6242 DBG_8723A("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
6243 DBG_8723A("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
6244 #endif //CONFIG_80211N_HT
6246 #ifdef CONFIG_AP_MODE
6247 DBG_8723A("capability=0x%x\n", psta->capability);
6248 DBG_8723A("flags=0x%x\n", psta->flags);
6249 DBG_8723A("wpa_psk=0x%x\n", psta->wpa_psk);
6250 DBG_8723A("wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher);
6251 DBG_8723A("wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher);
6252 DBG_8723A("qos_info=0x%x\n", psta->qos_info);
6254 DBG_8723A("dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy);
6260 preorder_ctrl = &psta->recvreorder_ctrl[j];
6261 if(preorder_ctrl->enable)
6263 DBG_8723A("tid=%d, indicate_seq=%d\n", j, preorder_ctrl->indicate_seq);
6272 spin_unlock_bh(&pstapriv->sta_hash_lock);
6277 case 0x0c://dump rx/tx packet
6280 DBG_8723A("dump rx packet (%d)\n",extra_arg);
6281 //pHalData->bDumpRxPkt =extra_arg;
6282 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
6285 DBG_8723A("dump tx packet (%d)\n",extra_arg);
6286 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
6290 #ifdef DBG_CONFIG_ERROR_DETECT
6294 DBG_8723A("###### silent reset test.......#####\n");
6295 rtw_hal_sreset_reset(padapter);
6297 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
6298 struct sreset_priv *psrtpriv = &pHalData->srestpriv;
6299 psrtpriv->dbg_trigger_point = extra_arg;
6306 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
6307 DBG_8723A("==>silent resete cnts:%d\n",pwrpriv->ips_enter_cnts);
6313 case 0x10:// driver version display
6314 DBG_8723A("rtw driver version=%s\n", DRIVERVERSION);
6318 DBG_8723A("turn %s Rx RSSI display function\n",(extra_arg==1)?"on":"off");
6319 padapter->bRxRSSIDisplay = extra_arg ;
6320 rtw_hal_set_def_var(padapter, HW_DEF_FA_CNT_DUMP,&extra_arg);
6323 case 0x12: //set rx_stbc
6325 struct registry_priv *pregpriv = &padapter->registrypriv;
6326 // 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g
6327 //default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ
6328 if( pregpriv && (extra_arg == 0 || extra_arg == 1|| extra_arg == 2 || extra_arg == 3))
6330 pregpriv->rx_stbc= extra_arg;
6331 DBG_8723A("set rx_stbc=%d\n",pregpriv->rx_stbc);
6334 DBG_8723A("get rx_stbc=%d\n",pregpriv->rx_stbc);
6338 case 0x13: //set ampdu_enable
6340 struct registry_priv *pregpriv = &padapter->registrypriv;
6341 // 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec)
6342 if( pregpriv && extra_arg >= 0 && extra_arg < 3 )
6344 pregpriv->ampdu_enable= extra_arg;
6345 DBG_8723A("set ampdu_enable=%d\n",pregpriv->ampdu_enable);
6348 DBG_8723A("get ampdu_enable=%d\n",pregpriv->ampdu_enable);
6352 case 0x14: //get wifi_spec
6354 struct registry_priv *pregpriv = &padapter->registrypriv;
6355 DBG_8723A("get wifi_spec=%d\n",pregpriv->wifi_spec);
6362 printk("ODM_COMP_DIG\t\tBIT0\n");
6363 printk("ODM_COMP_RA_MASK\t\tBIT1\n");
6364 printk("ODM_COMP_DYNAMIC_TXPWR\tBIT2\n");
6365 printk("ODM_COMP_FA_CNT\t\tBIT3\n");
6366 printk("ODM_COMP_RSSI_MONITOR\tBIT4\n");
6367 printk("ODM_COMP_CCK_PD\t\tBIT5\n");
6368 printk("ODM_COMP_ANT_DIV\t\tBIT6\n");
6369 printk("ODM_COMP_PWR_SAVE\t\tBIT7\n");
6370 printk("ODM_COMP_PWR_TRAIN\tBIT8\n");
6371 printk("ODM_COMP_RATE_ADAPTIVE\tBIT9\n");
6372 printk("ODM_COMP_PATH_DIV\t\tBIT10\n");
6373 printk("ODM_COMP_PSD \tBIT11\n");
6374 printk("ODM_COMP_DYNAMIC_PRICCA\tBIT12\n");
6375 printk("ODM_COMP_RXHP\t\tBIT13\n");
6376 printk("ODM_COMP_EDCA_TURBO\tBIT16\n");
6377 printk("ODM_COMP_EARLY_MODE\tBIT17\n");
6378 printk("ODM_COMP_TX_PWR_TRACK\tBIT24\n");
6379 printk("ODM_COMP_RX_GAIN_TRACK\tBIT25\n");
6380 printk("ODM_COMP_CALIBRATION\tBIT26\n");
6381 rtw_hal_get_def_var(padapter, HW_DEF_ODM_DBG_FLAG,&extra_arg);
6384 rtw_hal_set_def_var(padapter, HW_DEF_ODM_DBG_FLAG,&extra_arg);
6388 #ifdef DBG_FIXED_CHAN
6391 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6392 printk("===> Fixed channel to %d \n",extra_arg);
6393 pmlmeext->fixed_chan = extra_arg;
6400 rtw_hal_get_hwreg(padapter, HW_VAR_READ_LLT_TAB,(u8 *)&extra_arg);
6405 DBG_8723A("turn %s the bNotifyChannelChange Variable\n",(extra_arg==1)?"on":"off");
6406 padapter->bNotifyChannelChange = extra_arg;
6412 DBG_8723A("turn %s the bShowGetP2PState Variable\n",(extra_arg==1)?"on":"off");
6413 padapter->bShowGetP2PState = extra_arg;
6414 #endif // CONFIG_P2P
6419 if(extra_arg> 0x13) extra_arg = 0xFF;
6420 DBG_8723A("chang data rate to :0x%02x\n",extra_arg);
6421 padapter->fix_rate = extra_arg;
6424 case 0xdd://registers dump , 0 for mac reg,1 for bb reg, 2 for rf reg
6427 mac_reg_dump(padapter);
6429 else if(extra_arg==1){
6430 bb_reg_dump(padapter);
6432 else if(extra_arg==2){
6433 rf_reg_dump(padapter);
6439 case 0xee://turn on/off dynamic funcs
6444 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&odm_flag);
6445 DBG_8723A(" === DMFlag(0x%08x) === \n",odm_flag);
6446 DBG_8723A("extra_arg = 0 - disable all dynamic func \n");
6447 DBG_8723A("extra_arg = 1 - disable DIG- BIT(0)\n");
6448 DBG_8723A("extra_arg = 2 - disable High power - BIT(1)\n");
6449 DBG_8723A("extra_arg = 3 - disable tx power tracking - BIT(2)\n");
6450 DBG_8723A("extra_arg = 4 - disable BT coexistence - BIT(3)\n");
6451 DBG_8723A("extra_arg = 5 - disable antenna diversity - BIT(4)\n");
6452 DBG_8723A("extra_arg = 6 - enable all dynamic func \n");
6455 /* extra_arg = 0 - disable all dynamic func
6456 extra_arg = 1 - disable DIG
6457 extra_arg = 2 - disable tx power tracking
6458 extra_arg = 3 - turn on all dynamic func
6460 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &(extra_arg));
6461 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&odm_flag);
6462 DBG_8723A(" === DMFlag(0x%08x) === \n",odm_flag);
6468 rtw_write8(padapter, 0xc50, arg);
6469 DBG_8723A("wr(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
6470 rtw_write8(padapter, 0xc58, arg);
6471 DBG_8723A("wr(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
6474 DBG_8723A("rd(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
6475 DBG_8723A("rd(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
6479 DBG_8723A("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
6480 DBG_8723A("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
6481 DBG_8723A("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
6482 DBG_8723A("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
6483 DBG_8723A("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
6485 DBG_8723A("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
6490 DBG_8723A("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
6491 DBG_8723A("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
6493 DBG_8723A("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
6495 DBG_8723A("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
6497 DBG_8723A("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
6498 DBG_8723A("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
6500 DBG_8723A("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
6501 DBG_8723A("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
6502 DBG_8723A("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
6503 DBG_8723A("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
6509 DBG_8723A("error dbg cmd!\n");
6518 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
6522 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
6525 case IEEE_PARAM_WPA_ENABLED:
6527 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; //802.1x
6529 //ret = ieee80211_wpa_enable(ieee, value);
6531 switch((value)&0xff)
6534 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; //WPA_PSK
6535 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
6538 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; //WPA2_PSK
6539 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
6543 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("wpa_set_param:padapter->securitypriv.ndisauthtype=%d\n", padapter->securitypriv.ndisauthtype));
6547 case IEEE_PARAM_TKIP_COUNTERMEASURES:
6548 //ieee->tkip_countermeasures=value;
6551 case IEEE_PARAM_DROP_UNENCRYPTED:
6555 * wpa_supplicant calls set_wpa_enabled when the driver
6556 * is loaded and unloaded, regardless of if WPA is being
6557 * used. No other calls are made which can be used to
6558 * determine if encryption will be used or not prior to
6559 * association being expected. If encryption is not being
6560 * used, drop_unencrypted is set to false, else true -- we
6561 * can use this to determine if the CAP_PRIVACY_ON bit should
6567 case IEEE_PARAM_PRIVACY_INVOKED:
6569 //ieee->privacy_invoked=value;
6573 case IEEE_PARAM_AUTH_ALGS:
6575 ret = wpa_set_auth_algs(dev, value);
6579 case IEEE_PARAM_IEEE_802_1X:
6581 //ieee->ieee802_1x=value;
6585 case IEEE_PARAM_WPAX_SELECT:
6587 // added for WPA2 mixed mode
6588 //DBG_8723A(KERN_WARNING "------------------------>wpax value = %x\n", value);
6590 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
6591 ieee->wpax_type_set = 1;
6592 ieee->wpax_type_notify = value;
6593 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
6613 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
6616 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
6620 case IEEE_MLME_STA_DEAUTH:
6622 if(!rtw_set_802_11_disassociate(padapter))
6627 case IEEE_MLME_STA_DISASSOC:
6629 if(!rtw_set_802_11_disassociate(padapter))
6643 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
6645 struct ieee_param *param;
6648 //down(&ieee->wx_sem);
6650 if (p->length < sizeof(struct ieee_param) || !p->pointer){
6655 param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
6662 if (copy_from_user(param, p->pointer, p->length))
6668 switch (param->cmd) {
6670 case IEEE_CMD_SET_WPA_PARAM:
6671 ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
6674 case IEEE_CMD_SET_WPA_IE:
6675 //ret = wpa_set_wpa_ie(dev, param, p->length);
6676 ret = rtw_set_wpa_ie((struct rtw_adapter *)rtw_netdev_priv(dev), (char*)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
6679 case IEEE_CMD_SET_ENCRYPTION:
6680 ret = wpa_set_encryption(dev, param, p->length);
6684 ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
6688 DBG_8723A("Unknown WPA supplicant request: %d\n", param->cmd);
6694 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
6700 //up(&ieee->wx_sem);
6706 #ifdef CONFIG_AP_MODE
6707 static u8 set_pairwise_key(struct rtw_adapter *padapter, struct sta_info *psta)
6709 struct cmd_obj* ph2c;
6710 struct set_stakey_parm *psetstakey_para;
6711 struct cmd_priv *pcmdpriv=&padapter->cmdpriv;
6714 ph2c = (struct cmd_obj*)kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
6720 psetstakey_para = (struct set_stakey_parm*)kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
6721 if(psetstakey_para==NULL){
6727 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
6730 psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy;
6732 memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN);
6734 memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);
6737 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
6739 kfree(psetstakey_para);
6747 static int set_group_key(struct rtw_adapter *padapter, u8 *key, u8 alg, int keyid)
6750 struct cmd_obj* pcmd;
6751 struct setkey_parm *psetkeyparm;
6752 struct cmd_priv *pcmdpriv=&(padapter->cmdpriv);
6755 DBG_8723A("%s\n", __func__);
6757 pcmd = (struct cmd_obj*)kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
6762 psetkeyparm=(struct setkey_parm*)kzalloc(sizeof(struct setkey_parm),
6769 psetkeyparm->keyid=(u8)keyid;
6770 if (is_wep_enc(alg))
6771 padapter->mlmepriv.key_mask |= BIT(psetkeyparm->keyid);
6772 psetkeyparm->algorithm = alg;
6774 psetkeyparm->set_tx = 1;
6789 memcpy(&(psetkeyparm->key[0]), key, keylen);
6790 pcmd->cmdcode = _SetKey_CMD_;
6791 pcmd->parmbuf = (u8 *)psetkeyparm;
6792 pcmd->cmdsz = (sizeof(struct setkey_parm));
6796 INIT_LIST_HEAD(&pcmd->list);
6798 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
6807 static int set_wep_key(struct rtw_adapter *padapter, u8 *key, u8 keylen, int keyid)
6822 return set_group_key(padapter, key, alg, keyid);
6826 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
6829 u32 wep_key_idx, wep_key_len,wep_total_len;
6830 NDIS_802_11_WEP *pwep = NULL;
6831 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
6832 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
6833 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6834 struct security_priv* psecuritypriv=&(padapter->securitypriv);
6835 struct sta_priv *pstapriv = &padapter->stapriv;
6837 DBG_8723A("%s\n", __func__);
6839 param->u.crypt.err = 0;
6840 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
6842 //sizeof(struct ieee_param) = 64 bytes;
6843 //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
6844 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len)
6850 if (is_broadcast_ether_addr(param->sta_addr)) {
6851 if (param->u.crypt.idx >= WEP_KEYS)
6859 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
6863 DBG_8723A("rtw_set_encryption(), sta has already been removed or never been added\n");
6868 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
6870 //todo:clear default encryption keys
6872 DBG_8723A("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
6878 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
6880 DBG_8723A("r871x_set_encryption, crypt.alg = WEP\n");
6882 wep_key_idx = param->u.crypt.idx;
6883 wep_key_len = param->u.crypt.key_len;
6885 DBG_8723A("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
6887 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
6894 if (wep_key_len > 0)
6896 wep_key_len = wep_key_len <= 5 ? 5 : 13;
6897 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
6898 pwep = (NDIS_802_11_WEP *)kzalloc(wep_total_len,
6901 DBG_8723A(" r871x_set_encryption: pwep allocate fail !!!\n");
6905 pwep->KeyLength = wep_key_len;
6906 pwep->Length = wep_total_len;
6910 pwep->KeyIndex = wep_key_idx;
6912 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
6914 if(param->u.crypt.set_tx)
6916 DBG_8723A("wep, set_tx=1\n");
6918 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
6919 psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
6920 psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
6922 if(pwep->KeyLength==13)
6924 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
6925 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
6929 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
6931 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
6933 psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength;
6935 set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
6941 DBG_8723A("wep, set_tx=0\n");
6943 //don't update "psecuritypriv->dot11PrivacyAlgrthm" and
6944 //"psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to cam
6946 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
6948 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
6950 set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
6959 if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
6961 if(param->u.crypt.set_tx ==1)
6963 if(strcmp(param->u.crypt.alg, "WEP") == 0)
6965 DBG_8723A("%s, set group_key, WEP\n", __func__);
6967 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
6969 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
6970 if(param->u.crypt.key_len==13)
6972 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
6976 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
6978 DBG_8723A("%s, set group_key, TKIP\n", __func__);
6980 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
6982 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
6984 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
6986 memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
6987 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
6989 psecuritypriv->busetkipkey = _TRUE;
6992 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
6994 DBG_8723A("%s, set group_key, CCMP\n", __func__);
6996 psecuritypriv->dot118021XGrpPrivacy = _AES_;
6998 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
7002 DBG_8723A("%s, set group_key, none\n", __func__);
7004 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
7007 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
7009 psecuritypriv->binstallGrpkey = _TRUE;
7011 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
7013 set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
7015 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
7018 pbcmc_sta->ieee8021x_blocked = _FALSE;
7019 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
7028 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
7030 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
7032 if(param->u.crypt.set_tx ==1)
7034 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
7036 if(strcmp(param->u.crypt.alg, "WEP") == 0)
7038 DBG_8723A("%s, set pairwise key, WEP\n", __func__);
7040 psta->dot118021XPrivacy = _WEP40_;
7041 if(param->u.crypt.key_len==13)
7043 psta->dot118021XPrivacy = _WEP104_;
7046 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
7048 DBG_8723A("%s, set pairwise key, TKIP\n", __func__);
7050 psta->dot118021XPrivacy = _TKIP_;
7052 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
7054 memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
7055 memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
7057 psecuritypriv->busetkipkey = _TRUE;
7060 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
7063 DBG_8723A("%s, set pairwise key, CCMP\n", __func__);
7065 psta->dot118021XPrivacy = _AES_;
7069 DBG_8723A("%s, set pairwise key, none\n", __func__);
7071 psta->dot118021XPrivacy = _NO_PRIVACY_;
7074 set_pairwise_key(padapter, psta);
7076 psta->ieee8021x_blocked = _FALSE;
7081 if(strcmp(param->u.crypt.alg, "WEP") == 0)
7083 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
7085 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
7086 if(param->u.crypt.key_len==13)
7088 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
7091 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
7093 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
7095 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
7097 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
7099 memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
7100 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
7102 psecuritypriv->busetkipkey = _TRUE;
7105 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
7107 psecuritypriv->dot118021XGrpPrivacy = _AES_;
7109 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
7113 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
7116 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
7118 psecuritypriv->binstallGrpkey = _TRUE;
7120 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
7122 set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
7124 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
7127 pbcmc_sta->ieee8021x_blocked = _FALSE;
7128 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
7147 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
7150 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7151 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7152 struct sta_priv *pstapriv = &padapter->stapriv;
7153 unsigned char *pbuf = param->u.bcn_ie.buf;
7156 DBG_8723A("%s, len=%d\n", __func__, len);
7158 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7161 memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
7163 if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
7164 pstapriv->max_num_sta = NUM_STA;
7167 if(rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS)// 12 = param header, 2:no packed
7177 static int rtw_hostapd_sta_flush(struct net_device *dev)
7179 //struct list_head *phead, *plist;
7181 //struct sta_info *psta = NULL;
7182 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7183 //struct sta_priv *pstapriv = &padapter->stapriv;
7185 DBG_8723A("%s\n", __func__);
7187 flush_all_cam_entry(padapter); //clear CAM
7189 ret = rtw_sta_flush(padapter);
7195 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
7198 struct sta_info *psta = NULL;
7199 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7200 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7201 struct sta_priv *pstapriv = &padapter->stapriv;
7203 DBG_8723A("rtw_add_sta(aid=%d)=" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr));
7205 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
7210 if (is_broadcast_ether_addr(param->sta_addr))
7214 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7217 DBG_8723A("rtw_add_sta(), free has been added psta=%p\n", psta);
7218 spin_lock_bh(&(pstapriv->sta_hash_lock));
7219 rtw_free_stainfo(padapter, psta);
7220 spin_unlock_bh(&(pstapriv->sta_hash_lock));
7225 //psta = rtw_alloc_stainfo(pstapriv, param->sta_addr);
7226 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7229 int flags = param->u.add_sta.flags;
7231 //DBG_8723A("rtw_add_sta(), init sta's variables, psta=%p\n", psta);
7233 psta->aid = param->u.add_sta.aid;//aid=1~2007
7235 memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
7239 if(WLAN_STA_WME&flags)
7240 psta->qos_option = 1;
7242 psta->qos_option = 0;
7244 if(pmlmepriv->qospriv.qos_option == 0)
7245 psta->qos_option = 0;
7248 #ifdef CONFIG_80211N_HT
7249 //chec 802.11n ht cap.
7250 if(WLAN_STA_HT&flags)
7252 psta->htpriv.ht_option = _TRUE;
7253 psta->qos_option = 1;
7254 memcpy((void*)&psta->htpriv.ht_cap, (void*)¶m->u.add_sta.ht_cap, sizeof(struct ieee80211_ht_cap));
7258 psta->htpriv.ht_option = _FALSE;
7261 if(pmlmepriv->htpriv.ht_option == _FALSE)
7262 psta->htpriv.ht_option = _FALSE;
7266 update_sta_info_apmode(padapter, psta);
7279 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
7282 struct sta_info *psta = NULL;
7283 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7284 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7285 struct sta_priv *pstapriv = &padapter->stapriv;
7287 DBG_8723A("rtw_del_sta=" MAC_FMT "\n", MAC_ARG(param->sta_addr));
7289 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
7294 if (is_broadcast_ether_addr(param->sta_addr))
7297 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7302 //DBG_8723A("free psta=%p, aid=%d\n", psta, psta->aid);
7304 spin_lock_bh(&pstapriv->asoc_list_lock);
7305 if (!list_empty(&psta->asoc_list)) {
7306 list_del_init(&psta->asoc_list);
7307 pstapriv->asoc_list_cnt--;
7308 updated = ap_free_sta(padapter, psta, _TRUE,
7309 WLAN_REASON_DEAUTH_LEAVING);
7311 spin_unlock_bh(&pstapriv->asoc_list_lock);
7313 associated_clients_update(padapter, updated);
7320 DBG_8723A("rtw_del_sta(), sta has already been removed or never been added\n");
7330 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
7333 struct sta_info *psta = NULL;
7334 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7335 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7336 struct sta_priv *pstapriv = &padapter->stapriv;
7337 struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
7338 struct sta_data *psta_data = (struct sta_data *)param_ex->data;
7340 DBG_8723A("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr));
7342 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
7347 if (is_broadcast_ether_addr(param_ex->sta_addr))
7350 psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
7353 psta_data->aid = (u16)psta->aid;
7354 psta_data->capability = psta->capability;
7355 psta_data->flags = psta->flags;
7359 no_short_slot_time_set : BIT(1)
7360 no_short_preamble_set : BIT(2)
7361 no_ht_gf_set : BIT(3)
7363 ht_20mhz_set : BIT(5)
7366 psta_data->sta_set =((psta->nonerp_set) |
7367 (psta->no_short_slot_time_set <<1) |
7368 (psta->no_short_preamble_set <<2) |
7369 (psta->no_ht_gf_set <<3) |
7370 (psta->no_ht_set <<4) |
7371 (psta->ht_20mhz_set <<5));
7373 psta_data->tx_supp_rates_len = psta->bssratelen;
7374 memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
7375 #ifdef CONFIG_80211N_HT
7376 memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct ieee80211_ht_cap));
7377 #endif //CONFIG_80211N_HT
7378 psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
7379 psta_data->rx_bytes = psta->sta_stats.rx_bytes;
7380 psta_data->rx_drops = psta->sta_stats.rx_drops;
7382 psta_data->tx_pkts = psta->sta_stats.tx_pkts;
7383 psta_data->tx_bytes = psta->sta_stats.tx_bytes;
7384 psta_data->tx_drops = psta->sta_stats.tx_drops;
7397 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
7400 struct sta_info *psta = NULL;
7401 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7402 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7403 struct sta_priv *pstapriv = &padapter->stapriv;
7405 DBG_8723A("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr));
7407 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
7412 if (is_broadcast_ether_addr(param->sta_addr))
7415 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7418 if((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC))
7423 wpa_ie_len = psta->wpa_ie[1];
7425 copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)):(wpa_ie_len+2);
7427 param->u.wpa_ie.len = copy_len;
7429 memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
7434 DBG_8723A("sta's wpa_ie is NONE\n");
7446 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
7449 unsigned char wps_oui[4]={0x0,0x50,0xf2,0x04};
7450 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7451 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7452 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7453 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7456 DBG_8723A("%s, len=%d\n", __func__, len);
7458 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7461 ie_len = len-12-2;// 12 = param header, 2:no packed
7464 if(pmlmepriv->wps_beacon_ie)
7466 kfree(pmlmepriv->wps_beacon_ie);
7467 pmlmepriv->wps_beacon_ie = NULL;
7472 pmlmepriv->wps_beacon_ie = kmalloc(ie_len, GFP_KERNEL);
7473 pmlmepriv->wps_beacon_ie_len = ie_len;
7474 if ( pmlmepriv->wps_beacon_ie == NULL) {
7475 DBG_8723A("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
7479 memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
7481 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
7483 pmlmeext->bstart_bss = _TRUE;
7489 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
7492 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7493 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7496 DBG_8723A("%s, len=%d\n", __func__, len);
7498 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7501 ie_len = len-12-2;// 12 = param header, 2:no packed
7504 if(pmlmepriv->wps_probe_resp_ie)
7506 kfree(pmlmepriv->wps_probe_resp_ie);
7507 pmlmepriv->wps_probe_resp_ie = NULL;
7512 pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
7513 pmlmepriv->wps_probe_resp_ie_len = ie_len;
7514 if ( pmlmepriv->wps_probe_resp_ie == NULL) {
7515 DBG_8723A("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
7518 memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
7526 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
7529 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7530 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7533 DBG_8723A("%s, len=%d\n", __func__, len);
7535 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7538 ie_len = len-12-2;// 12 = param header, 2:no packed
7541 if(pmlmepriv->wps_assoc_resp_ie)
7543 kfree(pmlmepriv->wps_assoc_resp_ie);
7544 pmlmepriv->wps_assoc_resp_ie = NULL;
7549 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
7550 pmlmepriv->wps_assoc_resp_ie_len = ie_len;
7551 if ( pmlmepriv->wps_assoc_resp_ie == NULL) {
7552 DBG_8723A("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
7556 memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
7564 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
7567 struct rtw_adapter *adapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7568 struct mlme_priv *mlmepriv = &(adapter->mlmepriv);
7569 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
7570 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
7573 char ssid[NDIS_802_11_LENGTH_SSID + 1];
7575 u8 ignore_broadcast_ssid;
7577 if(check_fwstate(mlmepriv, WIFI_AP_STATE) != _TRUE)
7580 if (param->u.bcn_ie.reserved[0] != 0xea)
7583 mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];
7585 ie_len = len-12-2;// 12 = param header, 2:no packed
7586 ssid_ie = rtw_get_ie(param->u.bcn_ie.buf, WLAN_EID_SSID, &ssid_len, ie_len);
7588 if (ssid_ie && ssid_len) {
7589 WLAN_BSSID_EX *pbss_network = &mlmepriv->cur_network.network;
7590 WLAN_BSSID_EX *pbss_network_ext = &mlmeinfo->network;
7592 memcpy(ssid, ssid_ie+2, ssid_len);
7593 ssid[ssid_len>NDIS_802_11_LENGTH_SSID?NDIS_802_11_LENGTH_SSID:ssid_len] = 0x0;
7596 DBG_8723A(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
7598 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
7599 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
7601 memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len);
7602 pbss_network->Ssid.SsidLength = ssid_len;
7603 memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len);
7604 pbss_network_ext->Ssid.SsidLength = ssid_len;
7607 DBG_8723A(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
7608 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
7609 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
7612 DBG_8723A(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter),
7613 ignore_broadcast_ssid, ssid, ssid_len);
7618 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
7621 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7622 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7624 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7627 if (is_broadcast_ether_addr(param->sta_addr))
7630 ret = rtw_acl_remove_sta(padapter, param->sta_addr);
7635 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
7638 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7639 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7641 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7644 if (is_broadcast_ether_addr(param->sta_addr))
7647 ret = rtw_acl_add_sta(padapter, param->sta_addr);
7653 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
7656 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7657 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7659 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7662 rtw_set_macaddr_acl(padapter, param->u.mlme.command);
7667 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
7669 struct ieee_param *param;
7671 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7673 //DBG_8723A("%s\n", __func__);
7676 * this function is expect to call in master mode, which allows no power saving
7677 * so, we just check hw_init_completed
7680 if (padapter->hw_init_completed==_FALSE){
7686 //if (p->length < sizeof(struct ieee_param) || !p->pointer){
7692 param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
7699 if (copy_from_user(param, p->pointer, p->length))
7705 //DBG_8723A("%s, cmd=%d\n", __func__, param->cmd);
7709 case RTL871X_HOSTAPD_FLUSH:
7711 ret = rtw_hostapd_sta_flush(dev);
7715 case RTL871X_HOSTAPD_ADD_STA:
7717 ret = rtw_add_sta(dev, param);
7721 case RTL871X_HOSTAPD_REMOVE_STA:
7723 ret = rtw_del_sta(dev, param);
7727 case RTL871X_HOSTAPD_SET_BEACON:
7729 ret = rtw_set_beacon(dev, param, p->length);
7733 case RTL871X_SET_ENCRYPTION:
7735 ret = rtw_set_encryption(dev, param, p->length);
7739 case RTL871X_HOSTAPD_GET_WPAIE_STA:
7741 ret = rtw_get_sta_wpaie(dev, param);
7745 case RTL871X_HOSTAPD_SET_WPS_BEACON:
7747 ret = rtw_set_wps_beacon(dev, param, p->length);
7751 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
7753 ret = rtw_set_wps_probe_resp(dev, param, p->length);
7757 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
7759 ret = rtw_set_wps_assoc_resp(dev, param, p->length);
7763 case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
7765 ret = rtw_set_hidden_ssid(dev, param, p->length);
7769 case RTL871X_HOSTAPD_GET_INFO_STA:
7771 ret = rtw_ioctl_get_sta_data(dev, param, p->length);
7775 case RTL871X_HOSTAPD_SET_MACADDR_ACL:
7777 ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
7781 case RTL871X_HOSTAPD_ACL_ADD_STA:
7783 ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
7787 case RTL871X_HOSTAPD_ACL_REMOVE_STA:
7789 ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
7794 DBG_8723A("Unknown hostapd request: %d\n", param->cmd);
7800 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
7811 #include <rtw_android.h>
7812 static int rtw_wx_set_priv(struct net_device *dev,
7813 struct iw_request_info *info,
7814 union iwreq_data *awrq,
7818 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7827 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
7828 struct iw_point *dwrq = (struct iw_point*)awrq;
7830 //RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, ("+rtw_wx_set_priv\n"));
7831 if(dwrq->length == 0)
7835 if (!(ext = rtw_vmalloc(len)))
7838 if (copy_from_user(ext, dwrq->pointer, len)) {
7839 rtw_vmfree(ext, len);
7844 //RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_,
7845 // ("rtw_wx_set_priv: %s req=%s\n",
7846 // dev->name, ext));
7848 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7849 if (!(ext_dbg = rtw_vmalloc(len)))
7851 rtw_vmfree(ext, len);
7855 memcpy(ext_dbg, ext, len);
7858 //added for wps2.0 @20110524
7859 if(dwrq->flags == 0x8766 && len > 8)
7862 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7863 u8 *probereq_wpsie = ext;
7864 int probereq_wpsie_len = len;
7865 u8 wps_oui[4]={0x0,0x50,0xf2,0x04};
7867 if((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
7868 (!memcmp(&probereq_wpsie[2], wps_oui, 4)))
7870 cp_sz = probereq_wpsie_len>MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN:probereq_wpsie_len;
7872 //memcpy(pmlmepriv->probereq_wpsie, probereq_wpsie, cp_sz);
7873 //pmlmepriv->probereq_wpsie_len = cp_sz;
7874 if(pmlmepriv->wps_probe_req_ie)
7876 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
7877 pmlmepriv->wps_probe_req_ie_len = 0;
7878 kfree(pmlmepriv->wps_probe_req_ie);
7879 pmlmepriv->wps_probe_req_ie = NULL;
7882 pmlmepriv->wps_probe_req_ie = kmalloc(cp_sz,
7884 if ( pmlmepriv->wps_probe_req_ie == NULL) {
7885 printk("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
7891 memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
7892 pmlmepriv->wps_probe_req_ie_len = cp_sz;
7900 if (len >= WEXT_CSCAN_HEADER_SIZE &&
7901 !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
7902 ret = rtw_wx_set_scan(dev, info, awrq, ext);
7906 #ifdef CONFIG_ANDROID
7907 //DBG_8723A("rtw_wx_set_priv: %s req=%s\n", dev->name, ext);
7909 i = rtw_android_cmdstr_to_num(ext);
7912 case ANDROID_WIFI_CMD_START :
7913 indicate_wx_custom_event(padapter, "START");
7915 case ANDROID_WIFI_CMD_STOP :
7916 indicate_wx_custom_event(padapter, "STOP");
7918 case ANDROID_WIFI_CMD_RSSI :
7920 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7921 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
7923 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
7924 sprintf(ext, "%s rssi %d", pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi);
7930 case ANDROID_WIFI_CMD_LINKSPEED :
7932 u16 mbps = rtw_get_cur_max_rate(padapter)/10;
7933 sprintf(ext, "LINKSPEED %d", mbps);
7936 case ANDROID_WIFI_CMD_MACADDR :
7937 sprintf(ext, "MACADDR = " MAC_FMT, MAC_ARG(dev->dev_addr));
7939 case ANDROID_WIFI_CMD_SCAN_ACTIVE :
7941 //rtw_set_scan_mode(padapter, SCAN_ACTIVE);
7945 case ANDROID_WIFI_CMD_SCAN_PASSIVE :
7947 //rtw_set_scan_mode(padapter, SCAN_PASSIVE);
7952 case ANDROID_WIFI_CMD_COUNTRY :
7954 char country_code[10];
7955 sscanf(ext, "%*s %s", country_code);
7956 rtw_set_country(padapter, country_code);
7961 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7962 DBG_8723A("%s: %s unknowned req=%s\n", __func__,
7963 dev->name, ext_dbg);
7970 if (copy_to_user(dwrq->pointer, ext, min(dwrq->length, (u16)(strlen(ext)+1)) ) )
7973 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7974 DBG_8723A("%s: %s req=%s rep=%s dwrq->length=%d, strlen(ext)+1=%d\n", __func__,
7975 dev->name, ext_dbg ,ext, dwrq->length, (u16)(strlen(ext)+1));
7977 #endif //end of CONFIG_ANDROID
7982 rtw_vmfree(ext, len);
7983 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7984 rtw_vmfree(ext_dbg, len);
7987 //DBG_8723A("rtw_wx_set_priv: (SIOCSIWPRIV) %s ret=%d\n",
7993 static int rtw_pm_set(struct net_device *dev,
7994 struct iw_request_info *info,
7995 union iwreq_data *wrqu, char *extra)
7999 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8001 DBG_8723A( "[%s] extra = %s\n", __func__, extra );
8003 if (!memcmp(extra, "lps=", 4))
8005 sscanf(extra+4, "%u", &mode);
8006 ret = rtw_pm_set_lps(padapter,mode);
8008 else if (!memcmp(extra, "ips=", 4))
8010 sscanf(extra+4, "%u", &mode);
8011 ret = rtw_pm_set_ips(padapter,mode);
8021 static int rtw_wfd_tdls_enable(struct net_device *dev,
8022 struct iw_request_info *info,
8023 union iwreq_data *wrqu, char *extra)
8030 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8032 printk( "[%s] %s %d\n", __func__, extra, wrqu->data.length -1 );
8034 if ( extra[ 0 ] == '0' )
8036 padapter->wdinfo.wfd_tdls_enable = 0;
8040 padapter->wdinfo.wfd_tdls_enable = 1;
8044 #endif //CONFIG_TDLS
8049 static int rtw_tdls_weaksec(struct net_device *dev,
8050 struct iw_request_info *info,
8051 union iwreq_data *wrqu, char *extra)
8058 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8060 DBG_8723A( "[%s] %s %d\n", __func__, extra, wrqu->data.length -1 );
8062 if ( extra[ 0 ] == '0' )
8064 padapter->wdinfo.wfd_tdls_weaksec = 0;
8068 padapter->wdinfo.wfd_tdls_weaksec = 1;
8076 static int rtw_tdls_enable(struct net_device *dev,
8077 struct iw_request_info *info,
8078 union iwreq_data *wrqu, char *extra)
8084 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8085 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
8086 struct list_head *plist, *phead;
8088 struct sta_info *psta = NULL;
8089 struct sta_priv *pstapriv = &padapter->stapriv;
8090 u8 tdls_sta[NUM_STA][ETH_ALEN];
8091 u8 empty_hwaddr[ETH_ALEN] = { 0x00 };
8093 printk( "[%s] %s %d\n", __func__, extra, wrqu->data.length -1 );
8095 memset(tdls_sta, 0x00, sizeof(tdls_sta));
8097 if ( extra[ 0 ] == '0' )
8099 ptdlsinfo->enable = 0;
8101 if(pstapriv->asoc_sta_count==1)
8104 spin_lock_bh(&pstapriv->sta_hash_lock);
8105 for(index=0; index< NUM_STA; index++)
8107 phead = &(pstapriv->sta_hash[index]);
8108 plist = phead->next;
8110 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
8112 psta = container_of(plist, struct sta_info ,hash_list);
8114 plist = plist->next;
8116 if(psta->tdls_sta_state != TDLS_STATE_NONE)
8118 memcpy(tdls_sta[index], psta->hwaddr, ETH_ALEN);
8122 spin_unlock_bh(&pstapriv->sta_hash_lock);
8124 for (index=0; index< NUM_STA; index++)
8126 if (memcmp(tdls_sta[index], empty_hwaddr, ETH_ALEN))
8128 printk("issue tear down to "MAC_FMT"\n", MAC_ARG(tdls_sta[index]));
8129 issue_tdls_teardown(padapter, tdls_sta[index]);
8132 rtw_tdls_cmd(padapter, myid(&(padapter->eeprompriv)), TDLS_RS_RCR);
8133 rtw_reset_tdls_info(padapter);
8135 else if ( extra[ 0 ] == '1' )
8137 ptdlsinfo->enable = 1;
8139 #endif //CONFIG_TDLS
8144 static int rtw_tdls_setup(struct net_device *dev,
8145 struct iw_request_info *info,
8146 union iwreq_data *wrqu, char *extra)
8153 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8154 u8 mac_addr[ETH_ALEN];
8157 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
8158 #endif // CONFIG_WFD
8160 printk( "[%s] %s %d\n", __func__, extra, wrqu->data.length -1 );
8162 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
8163 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
8167 if ( _AES_ != padapter->securitypriv.dot11PrivacyAlgrthm )
8169 // Weak Security situation with AP.
8170 if ( 0 == pwdinfo->wfd_tdls_weaksec )
8172 // Can't send the tdls setup request out!!
8173 DBG_8723A( "[%s] Current link is not AES, SKIP sending the tdls setup request!!\n", __func__ );
8177 issue_tdls_setup_req(padapter, mac_addr);
8181 #endif // CONFIG_WFD
8183 issue_tdls_setup_req(padapter, mac_addr);
8190 static int rtw_tdls_teardown(struct net_device *dev,
8191 struct iw_request_info *info,
8192 union iwreq_data *wrqu, char *extra)
8199 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8200 struct sta_info *ptdls_sta = NULL;
8201 u8 mac_addr[ETH_ALEN];
8203 DBG_8723A( "[%s] %s %d\n", __func__, extra, wrqu->data.length -1 );
8205 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
8206 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
8209 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), mac_addr);
8211 if(ptdls_sta != NULL)
8213 ptdls_sta->stat_code = _RSON_TDLS_TEAR_UN_RSN_;
8214 issue_tdls_teardown(padapter, mac_addr);
8217 #endif //CONFIG_TDLS
8222 static int rtw_tdls_discovery(struct net_device *dev,
8223 struct iw_request_info *info,
8224 union iwreq_data *wrqu, char *extra)
8230 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8231 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8232 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8234 DBG_8723A( "[%s] %s %d\n", __func__, extra, wrqu->data.length -1 );
8236 issue_tdls_dis_req(padapter, NULL);
8238 #endif //CONFIG_TDLS
8243 static int rtw_tdls_ch_switch(struct net_device *dev,
8244 struct iw_request_info *info,
8245 union iwreq_data *wrqu, char *extra)
8251 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8252 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
8253 u8 i, j, mac_addr[ETH_ALEN];
8254 struct sta_info *ptdls_sta = NULL;
8256 DBG_8723A( "[%s] %s %d\n", __func__, extra, wrqu->data.length -1 );
8258 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
8259 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
8262 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
8263 if( ptdls_sta == NULL )
8265 ptdlsinfo->ch_sensing=1;
8267 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_INIT_CH_SEN);
8269 #endif //CONFIG_TDLS
8274 static int rtw_tdls_pson(struct net_device *dev,
8275 struct iw_request_info *info,
8276 union iwreq_data *wrqu, char *extra)
8282 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8283 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8284 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8285 u8 i, j, mac_addr[ETH_ALEN];
8286 struct sta_info *ptdls_sta = NULL;
8288 DBG_8723A( "[%s] %s %d\n", __func__, extra, wrqu->data.length -1 );
8290 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
8291 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
8294 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
8296 issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta, 1);
8298 #endif //CONFIG_TDLS
8303 static int rtw_tdls_psoff(struct net_device *dev,
8304 struct iw_request_info *info,
8305 union iwreq_data *wrqu, char *extra)
8311 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8312 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8313 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8314 u8 i, j, mac_addr[ETH_ALEN];
8315 struct sta_info *ptdls_sta = NULL;
8317 DBG_8723A( "[%s] %s %d\n", __func__, extra, wrqu->data.length -1 );
8319 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
8320 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
8323 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
8325 issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta, 0);
8327 #endif //CONFIG_TDLS
8332 static int rtw_tdls_setip(struct net_device *dev,
8333 struct iw_request_info *info,
8334 union iwreq_data *wrqu, char *extra)
8341 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8342 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
8343 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
8344 u8 i=0, j=0, k=0, tag=0, ip[3] = { 0xff }, *ptr = extra;
8346 printk( "[%s] %s %d\n", __func__, extra, wrqu->data.length - 1 );
8351 for( j=0; j < 4; j++)
8353 if( *( extra + j + tag ) == '.' || *( extra + j + tag ) == '\0' )
8356 pwfd_info->ip_address[i]=convert_ip_addr( '0', '0', *(extra+(j-1)+tag));
8358 pwfd_info->ip_address[i]=convert_ip_addr( '0', *(extra+(j-2)+tag), *(extra+(j-1)+tag));
8360 pwfd_info->ip_address[i]=convert_ip_addr( *(extra+(j-3)+tag), *(extra+(j-2)+tag), *(extra+(j-1)+tag));
8369 printk( "[%s] Set IP = %u.%u.%u.%u \n", __func__,
8370 ptdlsinfo->wfd_info->ip_address[0], ptdlsinfo->wfd_info->ip_address[1],
8371 ptdlsinfo->wfd_info->ip_address[2], ptdlsinfo->wfd_info->ip_address[3]
8375 #endif //CONFIG_TDLS
8380 static int rtw_tdls_getip(struct net_device *dev,
8381 struct iw_request_info *info,
8382 union iwreq_data *wrqu, char *extra)
8389 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8390 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
8391 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
8393 printk( "[%s]\n", __func__);
8395 sprintf( extra, "\n\n%u.%u.%u.%u\n",
8396 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],
8397 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]
8400 printk( "[%s] IP=%u.%u.%u.%u\n", __func__,
8401 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],
8402 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]
8405 wrqu->data.length = strlen( extra );
8408 #endif //CONFIG_TDLS
8413 static int rtw_tdls_getport(struct net_device *dev,
8414 struct iw_request_info *info,
8415 union iwreq_data *wrqu, char *extra)
8423 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8424 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
8425 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
8427 printk( "[%s]\n", __func__);
8429 sprintf( extra, "\n\n%d\n", pwfd_info->peer_rtsp_ctrlport );
8430 printk( "[%s] remote port = %d\n", __func__, pwfd_info->peer_rtsp_ctrlport );
8432 wrqu->data.length = strlen( extra );
8435 #endif //CONFIG_TDLS
8441 //WFDTDLS, for sigma test
8442 static int rtw_tdls_dis_result(struct net_device *dev,
8443 struct iw_request_info *info,
8444 union iwreq_data *wrqu, char *extra)
8452 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8453 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
8454 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
8456 printk( "[%s]\n", __func__);
8458 if(ptdlsinfo->dev_discovered == 1 )
8460 sprintf( extra, "\n\nDis=1\n" );
8461 ptdlsinfo->dev_discovered = 0;
8464 wrqu->data.length = strlen( extra );
8467 #endif //CONFIG_TDLS
8473 //WFDTDLS, for sigma test
8474 static int rtw_wfd_tdls_status(struct net_device *dev,
8475 struct iw_request_info *info,
8476 union iwreq_data *wrqu, char *extra)
8484 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8485 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
8486 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
8488 printk( "[%s]\n", __func__);
8490 if(ptdlsinfo->setup_state == TDLS_LINKED_STATE )
8492 sprintf( extra, "\n\nStatus=1\n" );
8496 sprintf( extra, "\n\nStatus=0\n" );
8499 wrqu->data.length = strlen( extra );
8502 #endif //CONFIG_TDLS
8508 static int rtw_tdls_ch_switch_off(struct net_device *dev,
8509 struct iw_request_info *info,
8510 union iwreq_data *wrqu, char *extra)
8516 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8517 u8 i, j, mac_addr[ETH_ALEN];
8518 struct sta_info *ptdls_sta = NULL;
8520 DBG_8723A( "[%s] %s %d\n", __func__, extra, wrqu->data.length -1 );
8522 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
8523 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
8526 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
8528 ptdls_sta->tdls_sta_state |= TDLS_SW_OFF_STATE;
8530 if((ptdls_sta->tdls_sta_state & TDLS_AT_OFF_CH_STATE) && (ptdls_sta->tdls_sta_state & TDLS_PEER_AT_OFF_STATE)){
8531 pmlmeinfo->tdls_candidate_ch= pmlmeext->cur_channel;
8532 issue_tdls_ch_switch_req(padapter, mac_addr);
8533 DBG_8723A("issue tdls ch switch req back to base channel\n");
8537 #endif //CONFIG_TDLS
8542 static int rtw_tdls(struct net_device *dev,
8543 struct iw_request_info *info,
8544 union iwreq_data *wrqu, char *extra)
8549 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
8551 DBG_8723A( "[%s] extra = %s\n", __func__, extra );
8552 // WFD Sigma will use the tdls enable command to let the driver know we want to test the tdls now!
8553 if (!memcmp(extra, "wfdenable=", 10))
8555 wrqu->data.length -=10;
8556 rtw_wfd_tdls_enable( dev, info, wrqu, &extra[10] );
8559 else if (!memcmp(extra, "weaksec=", 8))
8561 wrqu->data.length -=8;
8562 rtw_tdls_weaksec( dev, info, wrqu, &extra[8] );
8565 else if (!memcmp(extra, "tdlsenable=", 11))
8567 wrqu->data.length -=11;
8568 rtw_tdls_enable( dev, info, wrqu, &extra[11] );
8572 if( padapter->tdlsinfo.enable == 0 )
8574 printk("tdls haven't enabled\n");
8578 if (!memcmp(extra, "setup=", 6))
8580 wrqu->data.length -=6;
8581 rtw_tdls_setup( dev, info, wrqu, &extra[6] );
8583 else if (!memcmp(extra, "tear=", 5))
8585 wrqu->data.length -= 5;
8586 rtw_tdls_teardown( dev, info, wrqu, &extra[5] );
8588 else if (!memcmp(extra, "dis=", 4))
8590 wrqu->data.length -= 4;
8591 rtw_tdls_discovery( dev, info, wrqu, &extra[4] );
8593 else if (!memcmp(extra, "sw=", 3))
8595 wrqu->data.length -= 3;
8596 rtw_tdls_ch_switch( dev, info, wrqu, &extra[3] );
8598 else if (!memcmp(extra, "swoff=", 6))
8600 wrqu->data.length -= 6;
8601 rtw_tdls_ch_switch_off( dev, info, wrqu, &extra[6] );
8603 else if (!memcmp(extra, "pson=", 5))
8605 wrqu->data.length -= 5;
8606 rtw_tdls_pson( dev, info, wrqu, &extra[5] );
8608 else if (!memcmp(extra, "psoff=", 6))
8610 wrqu->data.length -= 6;
8611 rtw_tdls_psoff( dev, info, wrqu, &extra[6] );
8614 else if (!memcmp(extra, "setip=", 6))
8616 wrqu->data.length -= 6;
8617 rtw_tdls_setip( dev, info, wrqu, &extra[6] );
8619 else if (!memcmp(extra, "tprobe=", 6))
8621 issue_tunneled_probe_req((struct rtw_adapter *)rtw_netdev_priv(dev));
8625 #endif //CONFIG_TDLS
8631 static int rtw_tdls_get(struct net_device *dev,
8632 struct iw_request_info *info,
8633 union iwreq_data *wrqu, char *extra)
8639 DBG_8723A( "[%s] extra = %s\n", __func__, (char*) wrqu->data.pointer );
8641 if (!memcmp(wrqu->data.pointer, "ip", 2))
8643 rtw_tdls_getip( dev, info, wrqu, extra );
8645 if (!memcmp(wrqu->data.pointer, "port", 4))
8647 rtw_tdls_getport( dev, info, wrqu, extra );
8649 //WFDTDLS, for sigma test
8650 if (!memcmp(wrqu->data.pointer, "dis", 3))
8652 rtw_tdls_dis_result( dev, info, wrqu, extra );
8654 if (!memcmp(wrqu->data.pointer, "status", 6))
8656 rtw_wfd_tdls_status( dev, info, wrqu, extra );
8668 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
8670 extern void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc);
8671 #define cal_txdesc_chksum rtl8723a_cal_txdesc_chksum
8672 extern void rtl8723a_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
8673 #define fill_default_txdesc rtl8723a_fill_default_txdesc
8675 static s32 initLoopback(struct rtw_adapter *padapter)
8677 PLOOPBACKDATA ploopback;
8679 if (padapter->ploopback == NULL) {
8680 ploopback = (PLOOPBACKDATA)kzalloc(sizeof(LOOPBACKDATA),
8682 if (ploopback == NULL)
8685 sema_init(&ploopback->sema, 0);
8686 ploopback->bstop = _TRUE;
8688 ploopback->size = 300;
8689 memset(ploopback->msg, 0, sizeof(ploopback->msg));
8691 padapter->ploopback = ploopback;
8696 static void freeLoopback(struct rtw_adapter *padapter)
8698 PLOOPBACKDATA ploopback;
8700 ploopback = padapter->ploopback;
8702 padapter->ploopback = NULL;
8703 kfree((u8*)ploopback);
8707 static s32 initpseudoadhoc(struct rtw_adapter *padapter)
8709 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
8712 networkType = Ndis802_11IBSS;
8713 err = rtw_set_802_11_infrastructure_mode(padapter, networkType);
8714 if (err == _FALSE) return _FAIL;
8716 err = rtw_setopmode_cmd(padapter, networkType);
8717 if (err == _FAIL) return _FAIL;
8722 static s32 createpseudoadhoc(struct rtw_adapter *padapter)
8724 NDIS_802_11_AUTHENTICATION_MODE authmode;
8725 struct mlme_priv *pmlmepriv;
8726 NDIS_802_11_SSID *passoc_ssid;
8727 WLAN_BSSID_EX *pdev_network;
8729 u8 ssid[] = "pseduo_ad-hoc";
8732 pmlmepriv = &padapter->mlmepriv;
8734 authmode = Ndis802_11AuthModeOpen;
8735 err = rtw_set_802_11_authentication_mode(padapter, authmode);
8736 if (err == _FALSE) return _FAIL;
8738 passoc_ssid = &pmlmepriv->assoc_ssid;
8739 memset(passoc_ssid, 0, sizeof(NDIS_802_11_SSID));
8740 passoc_ssid->SsidLength = sizeof(ssid) - 1;
8741 memcpy(passoc_ssid->Ssid, ssid, passoc_ssid->SsidLength);
8743 pdev_network = &padapter->registrypriv.dev_network;
8744 pibss = padapter->registrypriv.dev_network.MacAddress;
8745 memcpy(&pdev_network->Ssid, passoc_ssid, sizeof(NDIS_802_11_SSID));
8747 rtw_update_registrypriv_dev_network(padapter);
8748 rtw_generate_random_ibss(pibss);
8750 spin_lock_bh(&pmlmepriv->lock);
8751 pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
8752 spin_unlock_bh(&pmlmepriv->lock);
8755 struct wlan_network *pcur_network;
8756 struct sta_info *psta;
8758 //3 create a new psta
8759 pcur_network = &pmlmepriv->cur_network;
8761 //clear psta in the cur_network, if any
8762 psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress);
8763 if (psta) rtw_free_stainfo(padapter, psta);
8765 psta = rtw_alloc_stainfo(&padapter->stapriv, pibss);
8766 if (psta == NULL) return _FAIL;
8768 //3 join psudo AdHoc
8769 pcur_network->join_res = 1;
8770 pcur_network->aid = psta->aid = 1;
8771 memcpy(&pcur_network->network, pdev_network, get_WLAN_BSSID_EX_sz(pdev_network));
8773 // set msr to WIFI_FW_ADHOC_STATE
8777 val8 = rtw_read8(padapter, MSR);
8778 val8 &= 0xFC; // clear NETYPE0
8779 val8 |= WIFI_FW_ADHOC_STATE & 0x3;
8780 rtw_write8(padapter, MSR, val8);
8786 static struct xmit_frame* createloopbackpkt(struct rtw_adapter *padapter, u32 size)
8788 struct xmit_priv *pxmitpriv;
8789 struct xmit_frame *pframe;
8790 struct xmit_buf *pxmitbuf;
8791 struct pkt_attrib *pattrib;
8792 struct tx_desc *desc;
8793 u8 *pkt_start, *pkt_end, *ptr;
8794 struct rtw_ieee80211_hdr *hdr;
8798 if ((TXDESC_SIZE + WLANHDR_OFFSET + size) > MAX_XMITBUF_SZ) return NULL;
8800 pxmitpriv = &padapter->xmitpriv;
8803 //2 1. allocate xmit frame
8804 pframe = rtw_alloc_xmitframe(pxmitpriv);
8805 if (pframe == NULL) return NULL;
8806 pframe->padapter = padapter;
8808 //2 2. allocate xmit buffer
8809 spin_lock_bh(&pxmitpriv->lock);
8810 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
8811 spin_unlock_bh(&pxmitpriv->lock);
8812 if (pxmitbuf == NULL) {
8813 rtw_free_xmitframe(pxmitpriv, pframe);
8817 pframe->pxmitbuf = pxmitbuf;
8818 pframe->buf_addr = pxmitbuf->pbuf;
8819 pxmitbuf->priv_data = pframe;
8821 //2 3. update_attrib()
8822 pattrib = &pframe->attrib;
8824 // init xmitframe attribute
8825 memset(pattrib, 0, sizeof(struct pkt_attrib));
8827 pattrib->ether_type = 0x8723;
8828 memcpy(pattrib->src, padapter->eeprompriv.mac_addr, ETH_ALEN);
8829 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
8830 memset(pattrib->dst, 0xFF, ETH_ALEN);
8831 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
8832 // pattrib->pctrl = 0;
8833 // pattrib->dhcp_pkt = 0;
8834 // pattrib->pktlen = 0;
8835 pattrib->ack_policy = 0;
8836 // pattrib->pkt_hdrlen = ETH_HLEN;
8837 pattrib->hdrlen = WLAN_HDR_A3_LEN;
8838 pattrib->subtype = WIFI_DATA;
8839 pattrib->priority = 0;
8840 pattrib->qsel = pattrib->priority;
8841 // do_queue_select(padapter, pattrib);
8842 pattrib->nr_frags = 1;
8843 pattrib->encrypt = 0;
8844 pattrib->bswenc = _FALSE;
8845 pattrib->qos_en = _FALSE;
8847 bmcast = is_multicast_ether_addr(pattrib->ra);
8849 pattrib->mac_id = 1;
8850 pattrib->psta = rtw_get_bcmc_stainfo(padapter);
8852 pattrib->mac_id = 0;
8853 pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
8856 pattrib->pktlen = size;
8857 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen;
8859 //2 4. fill TX descriptor
8860 desc = (struct tx_desc*)pframe->buf_addr;
8861 memset(desc, 0, TXDESC_SIZE);
8863 fill_default_txdesc(pframe, (u8*)desc);
8865 // Hw set sequence number
8866 ((PTXDESC)desc)->hwseq_en = 0; // HWSEQ_EN, 0:disable, 1:enable
8867 // ((PTXDESC)desc)->hwseq_sel = 0; // HWSEQ_SEL
8869 ((PTXDESC)desc)->disdatafb = 1;
8871 // convert to little endian
8872 desc->txdw0 = cpu_to_le32(desc->txdw0);
8873 desc->txdw1 = cpu_to_le32(desc->txdw1);
8874 desc->txdw2 = cpu_to_le32(desc->txdw2);
8875 desc->txdw3 = cpu_to_le32(desc->txdw3);
8876 desc->txdw4 = cpu_to_le32(desc->txdw4);
8877 desc->txdw5 = cpu_to_le32(desc->txdw5);
8878 desc->txdw6 = cpu_to_le32(desc->txdw6);
8879 desc->txdw7 = cpu_to_le32(desc->txdw7);
8881 cal_txdesc_chksum(desc);
8884 pkt_start = pframe->buf_addr + TXDESC_SIZE;
8885 pkt_end = pkt_start + pattrib->last_txcmdsz;
8887 //3 5.1. make wlan header, make_wlanhdr()
8888 hdr = (struct rtw_ieee80211_hdr *)pkt_start;
8889 SetFrameSubType(&hdr->frame_ctl, pattrib->subtype);
8890 memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); // DA
8891 memcpy(hdr->addr2, pattrib->src, ETH_ALEN); // SA
8892 memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); // RA, BSSID
8894 //3 5.2. make payload
8895 ptr = pkt_start + pattrib->hdrlen;
8896 get_random_bytes(ptr, pkt_end - ptr);
8898 pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz;
8899 pxmitbuf->ptail += pxmitbuf->len;
8904 static void freeloopbackpkt(struct rtw_adapter *padapter, struct xmit_frame *pframe)
8906 struct xmit_priv *pxmitpriv;
8907 struct xmit_buf *pxmitbuf;
8910 pxmitpriv = &padapter->xmitpriv;
8911 pxmitbuf = pframe->pxmitbuf;
8913 rtw_free_xmitframe(pxmitpriv, pframe);
8914 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
8917 static void printdata(u8 *pbuf, u32 len)
8922 for (i = 0; (i+4) <= len; i+=4) {
8923 printk("%08X", *(u32*)(pbuf + i));
8924 if ((i+4) & 0x1F) printk(" ");
8931 for (; i < len, i++)
8932 printk("%02X", pbuf+i);
8933 #else // __LITTLE_ENDIAN
8938 memcpy(&val, pbuf+i, n);
8939 sprintf(str, "%08X", val);
8941 printk("%8s", str+n);
8942 #endif // __LITTLE_ENDIAN
8947 static u8 pktcmp(struct rtw_adapter *padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz)
8949 PHAL_DATA_TYPE phal;
8950 struct recv_stat *prxstat;
8951 struct recv_stat report;
8952 PRXREPORT prxreport;
8958 prxstat = (struct recv_stat*)rxbuf;
8959 report.rxdw0 = le32_to_cpu(prxstat->rxdw0);
8960 report.rxdw1 = le32_to_cpu(prxstat->rxdw1);
8961 report.rxdw2 = le32_to_cpu(prxstat->rxdw2);
8962 report.rxdw3 = le32_to_cpu(prxstat->rxdw3);
8963 report.rxdw4 = le32_to_cpu(prxstat->rxdw4);
8964 report.rxdw5 = le32_to_cpu(prxstat->rxdw5);
8966 prxreport = (PRXREPORT)&report;
8967 drvinfosize = prxreport->drvinfosize << 3;
8968 rxpktsize = prxreport->pktlen;
8970 phal = GET_HAL_DATA(padapter);
8971 if (phal->ReceiveConfig & RCR_APPFCS)
8972 fcssize = IEEE80211_FCS_LEN;
8976 if ((txsz - TXDESC_SIZE) != (rxpktsize - fcssize)) {
8977 DBG_8723A("%s: ERROR! size not match tx/rx=%d/%d !\n",
8978 __func__, txsz - TXDESC_SIZE, rxpktsize - fcssize);
8981 if (!memcmp(txbuf + TXDESC_SIZE,
8982 rxbuf + RXDESC_SIZE + drvinfosize,
8983 txsz - TXDESC_SIZE)) {
8987 DBG_8723A("%s: ERROR! pkt content mismatch!\n",
8994 DBG_8723A("\n%s: TX PKT total=%d, desc=%d, content=%d\n",
8995 __func__, txsz, TXDESC_SIZE, txsz - TXDESC_SIZE);
8996 DBG_8723A("%s: TX DESC size=%d\n", __func__, TXDESC_SIZE);
8997 printdata(txbuf, TXDESC_SIZE);
8998 DBG_8723A("%s: TX content size=%d\n", __func__, txsz - TXDESC_SIZE);
8999 printdata(txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE);
9001 DBG_8723A("\n%s: RX PKT read=%d offset=%d(%d,%d) content=%d\n",
9002 __func__, rxsz, RXDESC_SIZE + drvinfosize, RXDESC_SIZE, drvinfosize, rxpktsize);
9005 DBG_8723A("%s: RX DESC size=%d\n", __func__, RXDESC_SIZE);
9006 printdata(rxbuf, RXDESC_SIZE);
9007 DBG_8723A("%s: RX drvinfo size=%d\n", __func__, drvinfosize);
9008 printdata(rxbuf + RXDESC_SIZE, drvinfosize);
9009 DBG_8723A("%s: RX content size=%d\n", __func__, rxpktsize);
9010 printdata(rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize);
9012 DBG_8723A("%s: RX data size=%d\n", __func__, rxsz);
9013 printdata(rxbuf, rxsz);
9020 int lbk_thread(void *context)
9023 struct rtw_adapter *padapter;
9024 PLOOPBACKDATA ploopback;
9025 struct xmit_frame *pxmitframe;
9026 u32 cnt, ok, fail, headerlen;
9031 padapter = (struct rtw_adapter *)context;
9032 ploopback = padapter->ploopback;
9033 if (ploopback == NULL) return -1;
9038 daemonize("%s", "RTW_LBK_THREAD");
9039 allow_signal(SIGTERM);
9042 if (ploopback->size == 0) {
9043 get_random_bytes(&pktsize, 4);
9044 pktsize = (pktsize % 1535) + 1; // 1~1535
9046 pktsize = ploopback->size;
9048 pxmitframe = createloopbackpkt(padapter, pktsize);
9049 if (pxmitframe == NULL) {
9050 sprintf(ploopback->msg, "loopback FAIL! 3. create Packet FAIL!");
9054 ploopback->txsize = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz;
9055 memcpy(ploopback->txbuf, pxmitframe->buf_addr, ploopback->txsize);
9056 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
9058 DBG_8723A("%s: write port cnt=%d size=%d\n", __func__, cnt, ploopback->txsize);
9059 pxmitframe->pxmitbuf->pdata = ploopback->txbuf;
9060 rtw_write_port(padapter, ff_hwaddr, ploopback->txsize, (u8 *)pxmitframe->pxmitbuf);
9063 down(&ploopback->sema)
9065 err = pktcmp(padapter, ploopback->txbuf, ploopback->txsize, ploopback->rxbuf, ploopback->rxsize);
9071 ploopback->txsize = 0;
9072 memset(ploopback->txbuf, 0, 0x8000);
9073 ploopback->rxsize = 0;
9074 memset(ploopback->rxbuf, 0, 0x8000);
9076 freeloopbackpkt(padapter, pxmitframe);
9079 if (signal_pending(current)) {
9080 flush_signals(current);
9083 if ((ploopback->bstop == _TRUE) ||
9084 ((ploopback->cnt != 0) && (ploopback->cnt == cnt)))
9086 u32 ok_rate, fail_rate, all;
9088 ok_rate = (ok*100)/all;
9089 fail_rate = (fail*100)/all;
9090 sprintf(ploopback->msg,\
9091 "loopback result: ok=%d%%(%d/%d),error=%d%%(%d/%d)",\
9092 ok_rate, ok, all, fail_rate, fail, all);
9097 ploopback->bstop = _TRUE;
9102 static void loopbackTest(struct rtw_adapter *padapter, u32 cnt, u32 size, u8* pmsg)
9104 PLOOPBACKDATA ploopback;
9109 ploopback = padapter->ploopback;
9113 if (ploopback->bstop == _FALSE) {
9114 ploopback->bstop = _TRUE;
9115 up(&ploopback->sema);
9119 len = strlen(ploopback->msg);
9123 memcpy(pmsg, ploopback->msg, len+1);
9124 freeLoopback(padapter);
9129 // disable dynamic algorithm
9131 u32 DMFlag = DYNAMIC_FUNC_DISABLE;
9132 rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8*)&DMFlag);
9135 // create pseudo ad-hoc connection
9136 err = initpseudoadhoc(padapter);
9138 sprintf(pmsg, "loopback FAIL! 1.1 init ad-hoc FAIL!");
9142 err = createpseudoadhoc(padapter);
9144 sprintf(pmsg, "loopback FAIL! 1.2 create ad-hoc master FAIL!");
9148 err = initLoopback(padapter);
9150 sprintf(pmsg, "loopback FAIL! 2. init FAIL! error code=%d", err);
9154 ploopback = padapter->ploopback;
9156 ploopback->bstop = _FALSE;
9157 ploopback->cnt = cnt;
9158 ploopback->size = size;
9159 ploopback->lbkthread = kthread_run(lbk_thread, padapter, "RTW_LBK_THREAD");
9160 if (IS_ERR(padapter->lbkthread))
9162 freeLoopback(padapter);
9163 sprintf(pmsg, "loopback start FAIL! cnt=%d", cnt);
9167 sprintf(pmsg, "loopback start! cnt=%d", cnt);
9169 #endif // CONFIG_MAC_LOOPBACK_DRIVER
9171 static int rtw_test(
9172 struct net_device *dev,
9173 struct iw_request_info *info,
9174 union iwreq_data *wrqu, char *extra)
9181 struct rtw_adapter *padapter = rtw_netdev_priv(dev);
9184 DBG_8723A("+%s\n", __func__);
9185 len = wrqu->data.length;
9187 pbuf = (u8*)kzalloc(len, GFP_KERNEL);
9189 DBG_8723A("%s: no memory!\n", __func__);
9193 if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
9194 DBG_8723A("%s: copy from user fail!\n", __func__);
9198 DBG_8723A("%s: string=\"%s\"\n", __func__, pbuf);
9201 pch = strsep(&ptmp, delim);
9202 if ((pch == NULL) || (strlen(pch) == 0)) {
9203 DBG_8723A("%s: parameter error(level 1)!\n", __func__);
9208 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
9209 if (strcmp(pch, "loopback") == 0)
9214 pch = strsep(&ptmp, delim);
9215 if ((pch == NULL) || (strlen(pch) == 0)) {
9216 DBG_8723A("%s: parameter error(level 2)!\n", __func__);
9221 sscanf(pch, "%d", &cnt);
9222 DBG_8723A("%s: loopback cnt=%d\n", __func__, cnt);
9224 pch = strsep(&ptmp, delim);
9225 if ((pch == NULL) || (strlen(pch) == 0)) {
9226 DBG_8723A("%s: parameter error(level 2)!\n", __func__);
9231 sscanf(pch, "%d", &size);
9232 DBG_8723A("%s: loopback size=%d\n", __func__, size);
9234 loopbackTest(padapter, cnt, size, extra);
9235 wrqu->data.length = strlen(extra) + 1;
9242 #ifdef CONFIG_BT_COEXIST
9243 #define GET_BT_INFO(padapter) (&GET_HAL_DATA(padapter)->BtInfo)
9245 if (strcmp(pch, "btdbg") == 0)
9247 DBG_8723A("===== BT debug information Start =====\n");
9248 DBG_8723A("WIFI status=\n");
9249 DBG_8723A("BT status=\n");
9250 DBG_8723A("BT profile=\n");
9251 DBG_8723A("WIFI RSSI=%d\n", GET_HAL_DATA(padapter)->dmpriv.UndecoratedSmoothedPWDB);
9252 DBG_8723A("BT RSSI=\n");
9253 DBG_8723A("coex mechanism=\n");
9254 DBG_8723A("BT counter TX/RX=/\n");
9255 DBG_8723A("0x880=0x%08x\n", rtw_read32(padapter, 0x880));
9256 DBG_8723A("0x6c0=0x%08x\n", rtw_read32(padapter, 0x6c0));
9257 DBG_8723A("0x6c4=0x%08x\n", rtw_read32(padapter, 0x6c4));
9258 DBG_8723A("0x6c8=0x%08x\n", rtw_read32(padapter, 0x6c8));
9259 DBG_8723A("0x6cc=0x%08x\n", rtw_read32(padapter, 0x6cc));
9260 DBG_8723A("0x778=0x%08x\n", rtw_read32(padapter, 0x778));
9261 DBG_8723A("0xc50=0x%08x\n", rtw_read32(padapter, 0xc50));
9262 BT_DisplayBtCoexInfo(padapter);
9263 DBG_8723A("===== BT debug information End =====\n");
9266 if (strcmp(pch, "bton") == 0)
9268 PBT30Info pBTInfo = GET_BT_INFO(padapter);
9269 PBT_MGNT pBtMgnt = &pBTInfo->BtMgnt;
9271 pBtMgnt->ExtConfig.bManualControl = _FALSE;
9274 if (strcmp(pch, "btoff") == 0)
9276 PBT30Info pBTInfo = GET_BT_INFO(padapter);
9277 PBT_MGNT pBtMgnt = &pBTInfo->BtMgnt;
9279 pBtMgnt->ExtConfig.bManualControl = _TRUE;
9281 #endif // CONFIG_BT_COEXIST
9283 if (strcmp(pch, "h2c") == 0)
9294 pch = strsep(&ptmp, delim);
9295 if ((pch == NULL) || (strlen(pch) == 0))
9298 sscanf(pch, "%x", &tmp);
9299 param[count++] = (u8)tmp;
9300 } while (count < 6);
9304 DBG_8723A("%s: parameter error(level 2)!\n", __func__);
9308 ret = FillH2CCmd(padapter, param[0], count-1, ¶m[1]);
9310 pos = sprintf(extra, "H2C ID=%x content=", param[0]);
9311 for (i=0; i<count; i++) {
9312 pos += sprintf(extra+pos, "%x,", param[i]);
9316 pos += sprintf(extra+pos, " %s", ret==_FAIL?"FAIL":"OK");
9318 wrqu->data.length = strlen(extra) + 1;
9325 static iw_handler rtw_handlers[] =
9327 NULL, /* SIOCSIWCOMMIT */
9328 rtw_wx_get_name, /* SIOCGIWNAME */
9329 dummy, /* SIOCSIWNWID */
9330 dummy, /* SIOCGIWNWID */
9331 rtw_wx_set_freq, /* SIOCSIWFREQ */
9332 rtw_wx_get_freq, /* SIOCGIWFREQ */
9333 rtw_wx_set_mode, /* SIOCSIWMODE */
9334 rtw_wx_get_mode, /* SIOCGIWMODE */
9335 dummy, /* SIOCSIWSENS */
9336 rtw_wx_get_sens, /* SIOCGIWSENS */
9337 NULL, /* SIOCSIWRANGE */
9338 rtw_wx_get_range, /* SIOCGIWRANGE */
9339 rtw_wx_set_priv, /* SIOCSIWPRIV */
9340 NULL, /* SIOCGIWPRIV */
9341 NULL, /* SIOCSIWSTATS */
9342 NULL, /* SIOCGIWSTATS */
9343 dummy, /* SIOCSIWSPY */
9344 dummy, /* SIOCGIWSPY */
9345 NULL, /* SIOCGIWTHRSPY */
9346 NULL, /* SIOCWIWTHRSPY */
9347 rtw_wx_set_wap, /* SIOCSIWAP */
9348 rtw_wx_get_wap, /* SIOCGIWAP */
9349 rtw_wx_set_mlme, /* request MLME operation; uses struct iw_mlme */
9350 dummy, /* SIOCGIWAPLIST -- depricated */
9351 rtw_wx_set_scan, /* SIOCSIWSCAN */
9352 rtw_wx_get_scan, /* SIOCGIWSCAN */
9353 rtw_wx_set_essid, /* SIOCSIWESSID */
9354 rtw_wx_get_essid, /* SIOCGIWESSID */
9355 dummy, /* SIOCSIWNICKN */
9356 rtw_wx_get_nick, /* SIOCGIWNICKN */
9357 NULL, /* -- hole -- */
9358 NULL, /* -- hole -- */
9359 rtw_wx_set_rate, /* SIOCSIWRATE */
9360 rtw_wx_get_rate, /* SIOCGIWRATE */
9361 rtw_wx_set_rts, /* SIOCSIWRTS */
9362 rtw_wx_get_rts, /* SIOCGIWRTS */
9363 rtw_wx_set_frag, /* SIOCSIWFRAG */
9364 rtw_wx_get_frag, /* SIOCGIWFRAG */
9365 dummy, /* SIOCSIWTXPOW */
9366 dummy, /* SIOCGIWTXPOW */
9367 dummy, /* SIOCSIWRETRY */
9368 rtw_wx_get_retry, /* SIOCGIWRETRY */
9369 rtw_wx_set_enc, /* SIOCSIWENCODE */
9370 rtw_wx_get_enc, /* SIOCGIWENCODE */
9371 dummy, /* SIOCSIWPOWER */
9372 rtw_wx_get_power, /* SIOCGIWPOWER */
9373 NULL, /*---hole---*/
9374 NULL, /*---hole---*/
9375 rtw_wx_set_gen_ie, /* SIOCSIWGENIE */
9376 NULL, /* SIOCGWGENIE */
9377 rtw_wx_set_auth, /* SIOCSIWAUTH */
9378 NULL, /* SIOCGIWAUTH */
9379 rtw_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
9380 NULL, /* SIOCGIWENCODEEXT */
9381 rtw_wx_set_pmkid, /* SIOCSIWPMKSA */
9382 NULL, /*---hole---*/
9386 static const struct iw_priv_args rtw_private_args[] = {
9388 SIOCIWFIRSTPRIV + 0x0,
9389 IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
9392 SIOCIWFIRSTPRIV + 0x1,
9393 IW_PRIV_TYPE_CHAR | 0x7FF,
9394 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
9397 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
9400 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
9403 SIOCIWFIRSTPRIV + 0x4,
9404 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
9407 SIOCIWFIRSTPRIV + 0x5,
9408 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
9411 SIOCIWFIRSTPRIV + 0x6,
9412 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
9414 //for PLATFORM_MT53XX
9416 SIOCIWFIRSTPRIV + 0x7,
9417 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
9420 SIOCIWFIRSTPRIV + 0x8,
9421 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
9424 SIOCIWFIRSTPRIV + 0x9,
9425 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
9428 //for RTK_DMP_PLATFORM
9430 SIOCIWFIRSTPRIV + 0xA,
9431 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
9435 SIOCIWFIRSTPRIV + 0xB,
9436 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
9439 SIOCIWFIRSTPRIV + 0xC,
9440 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
9443 SIOCIWFIRSTPRIV + 0xD,
9444 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
9447 SIOCIWFIRSTPRIV + 0x10,
9448 IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, 0, "p2p_set"
9451 SIOCIWFIRSTPRIV + 0x11,
9452 IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN , "p2p_get"
9455 SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL"
9458 SIOCIWFIRSTPRIV + 0x13,
9459 IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2"
9462 SIOCIWFIRSTPRIV + 0x14,
9463 IW_PRIV_TYPE_CHAR | 64, 0, "tdls"
9466 SIOCIWFIRSTPRIV + 0x15,
9467 IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN , "tdls_get"
9470 SIOCIWFIRSTPRIV + 0x16,
9471 IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
9474 {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"},
9476 {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"},
9477 {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
9479 SIOCIWFIRSTPRIV + 0x1D,
9480 IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
9484 static iw_handler rtw_private_handler[] =
9486 rtw_wx_write32, //0x00
9487 rtw_wx_read32, //0x01
9488 rtw_drvext_hdl, //0x02
9491 // for MM DTV platform
9492 rtw_get_ap_info, //0x04
9495 rtw_wps_start, //0x06
9497 // for PLATFORM_MT53XX
9498 rtw_wx_get_sensitivity, //0x07
9499 rtw_wx_set_mtk_wps_probe_ie, //0x08
9500 rtw_wx_set_mtk_wps_ie, //0x09
9502 // for RTK_DMP_PLATFORM
9503 // Set Channel depend on the country code
9504 rtw_wx_set_channel_plan, //0x0A
9506 rtw_dbg_port, //0x0B
9507 rtw_wx_write_rf, //0x0C
9508 rtw_wx_read_rf, //0x0D
9510 rtw_wx_priv_null, //0x0E
9511 rtw_wx_priv_null, //0x0F
9516 rtw_p2p_get2, //0x13
9519 rtw_tdls_get, //0x15
9522 rtw_wx_priv_null, //0x17
9523 rtw_rereg_nd_name, //0x18
9524 rtw_wx_priv_null, //0x19
9526 NULL /*rtw_mp_efuse_set*/, //0x1A
9527 NULL /*rtw_mp_efuse_get*/, //0x1B
9528 NULL, // 0x1C is reserved for hostapd
9532 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
9534 struct rtw_adapter *padapter = (struct rtw_adapter *)rtw_netdev_priv(dev);
9535 struct iw_statistics *piwstats = &padapter->iwstats;
9540 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != _TRUE)
9542 piwstats->qual.qual = 0;
9543 piwstats->qual.level = 0;
9544 piwstats->qual.noise = 0;
9545 //DBG_8723A("No link level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
9548 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
9549 tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
9551 tmp_level = padapter->recvpriv.signal_strength;
9552 #ifdef CONFIG_BT_COEXIST
9554 u8 signal = (u8)tmp_level;
9555 BT_SignalCompensation(padapter, &signal, NULL);
9558 #endif // CONFIG_BT_COEXIST
9561 tmp_qual = padapter->recvpriv.signal_qual;
9562 tmp_noise =padapter->recvpriv.noise;
9563 //DBG_8723A("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise,padapter->recvpriv.rssi);
9565 piwstats->qual.level = tmp_level;
9566 piwstats->qual.qual = tmp_qual;
9567 piwstats->qual.noise = tmp_noise;
9569 piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;//|IW_QUAL_DBM;
9571 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
9572 piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM;
9575 return &padapter->iwstats;
9578 #ifdef CONFIG_WIRELESS_EXT
9579 struct iw_handler_def rtw_handlers_def =
9581 .standard = rtw_handlers,
9582 .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
9583 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) || defined(CONFIG_WEXT_PRIV)
9584 .private = rtw_private_handler,
9585 .private_args = (struct iw_priv_args *)rtw_private_args,
9586 .num_private = sizeof(rtw_private_handler) / sizeof(iw_handler),
9587 .num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args),
9589 .get_wireless_stats = rtw_get_wireless_stats,
9593 // copy from net/wireless/wext.c start
9594 /* ---------------------------------------------------------------- */
9596 * Calculate size of private arguments
9598 static const char iw_priv_type_size[] = {
9599 0, /* IW_PRIV_TYPE_NONE */
9600 1, /* IW_PRIV_TYPE_BYTE */
9601 1, /* IW_PRIV_TYPE_CHAR */
9602 0, /* Not defined */
9603 sizeof(__u32), /* IW_PRIV_TYPE_INT */
9604 sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */
9605 sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */
9606 0, /* Not defined */
9609 static int get_priv_size(__u16 args)
9611 int num = args & IW_PRIV_SIZE_MASK;
9612 int type = (args & IW_PRIV_TYPE_MASK) >> 12;
9614 return num * iw_priv_type_size[type];
9616 // copy from net/wireless/wext.c end
9618 static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)
9623 const char delim[] = " ";
9630 u8 cmdname[17] = {0}; // IFNAMSIZ+1
9637 const iw_handler *priv; /* Private ioctl */
9638 const struct iw_priv_args *priv_args; /* Private ioctl description */
9639 u32 num_priv; /* Number of ioctl */
9640 u32 num_priv_args; /* Number of descriptions */
9643 int subcmd = 0; /* sub-ioctl index */
9644 int offset = 0; /* Space for sub-ioctl index */
9646 union iwreq_data wdata;
9649 memcpy(&wdata, wrq_data, sizeof(wdata));
9651 input_len = wdata.data.length;
9652 input = kzalloc(input_len, GFP_KERNEL);
9655 if (copy_from_user(input, wdata.data.pointer, input_len)) {
9662 sscanf(ptr, "%16s", cmdname);
9663 cmdlen = strlen(cmdname);
9664 DBG_8723A("%s: cmd=%s\n", __func__, cmdname);
9666 // skip command string
9668 cmdlen += 1; // skip one space
9671 DBG_8723A("%s: parameters=%s\n", __func__, ptr);
9673 priv = rtw_private_handler;
9674 priv_args = rtw_private_args;
9675 num_priv = sizeof(rtw_private_handler) / sizeof(iw_handler);
9676 num_priv_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args);
9678 if (num_priv_args == 0) {
9683 /* Search the correct ioctl */
9685 while((++k < num_priv_args) && strcmp(priv_args[k].name, cmdname));
9687 /* If not found... */
9688 if (k == num_priv_args) {
9693 /* Watch out for sub-ioctls ! */
9694 if (priv_args[k].cmd < SIOCDEVPRIVATE)
9698 /* Find the matching *real* ioctl */
9699 while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||
9700 (priv_args[j].set_args != priv_args[k].set_args) ||
9701 (priv_args[j].get_args != priv_args[k].get_args)));
9703 /* If not found... */
9704 if (j == num_priv_args) {
9709 /* Save sub-ioctl number */
9710 subcmd = priv_args[k].cmd;
9711 /* Reserve one int (simplify alignment issues) */
9712 offset = sizeof(__u32);
9713 /* Use real ioctl definition from now on */
9717 buffer = kzalloc(4096, GFP_KERNEL);
9718 if (NULL == buffer) {
9723 /* If we have to set some data */
9724 if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&
9725 (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
9729 switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK)
9731 case IW_PRIV_TYPE_BYTE:
9735 str = strsep(&ptr, delim);
9736 if (NULL == str) break;
9737 sscanf(str, "%i", &temp);
9738 buffer[count++] = (u8)temp;
9742 /* Number of args to fetch */
9743 wdata.data.length = count;
9744 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
9745 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
9749 case IW_PRIV_TYPE_INT:
9753 str = strsep(&ptr, delim);
9754 if (NULL == str) break;
9755 sscanf(str, "%i", &temp);
9756 ((s32*)buffer)[count++] = (s32)temp;
9758 buffer_len = count * sizeof(s32);
9760 /* Number of args to fetch */
9761 wdata.data.length = count;
9762 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
9763 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
9767 case IW_PRIV_TYPE_CHAR:
9770 /* Size of the string to fetch */
9771 wdata.data.length = len;
9772 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
9773 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
9776 memcpy(buffer, ptr, wdata.data.length);
9780 wdata.data.length = 1;
9783 buffer_len = wdata.data.length;
9787 DBG_8723A("%s: Not yet implemented...\n", __func__);
9792 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
9793 (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK)))
9795 DBG_8723A("%s: The command %s needs exactly %d argument(s)...\n",
9796 __func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK);
9800 } /* if args to set */
9803 wdata.data.length = 0L;
9806 /* Those two tests are important. They define how the driver
9807 * will have to handle the data */
9808 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
9809 ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ))
9811 /* First case : all SET args fit within wrq */
9813 wdata.mode = subcmd;
9814 memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
9818 if ((priv_args[k].set_args == 0) &&
9819 (priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
9820 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
9822 /* Second case : no SET args, GET args fit within wrq */
9824 wdata.mode = subcmd;
9828 /* Third case : args won't fit in wrq, or variable number of args */
9829 if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {
9833 wdata.data.flags = subcmd;
9841 if (IW_IS_SET(priv_args[k].cmd))
9843 /* Size of set arguments */
9844 extra_size = get_priv_size(priv_args[k].set_args);
9846 /* Does it fits in iwr ? */
9847 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
9848 ((extra_size + offset) <= IFNAMSIZ))
9851 /* Size of get arguments */
9852 extra_size = get_priv_size(priv_args[k].get_args);
9854 /* Does it fits in iwr ? */
9855 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
9856 (extra_size <= IFNAMSIZ))
9860 if (extra_size == 0) {
9861 extra = (u8*)&wdata;
9867 handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];
9868 err = handler(dev, NULL, &wdata, extra);
9870 /* If we have to get some data */
9871 if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&
9872 (priv_args[k].get_args & IW_PRIV_SIZE_MASK))
9875 int n = 0; /* number of args */
9878 /* Check where is the returned data */
9879 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
9880 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
9881 n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;
9883 n = wdata.data.length;
9885 output = kmalloc(4096, GFP_KERNEL);
9886 if (NULL == output) {
9891 switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK)
9893 case IW_PRIV_TYPE_BYTE:
9895 for (j = 0; j < n; j++)
9897 sprintf(str, "%d ", extra[j]);
9899 output_len = strlen(output);
9900 if ((output_len + len + 1) > 4096) {
9904 memcpy(output+output_len, str, len);
9908 case IW_PRIV_TYPE_INT:
9910 for (j = 0; j < n; j++)
9912 sprintf(str, "%d ", ((__s32*)extra)[j]);
9914 output_len = strlen(output);
9915 if ((output_len + len + 1) > 4096) {
9919 memcpy(output+output_len, str, len);
9923 case IW_PRIV_TYPE_CHAR:
9925 memcpy(output, extra, n);
9929 DBG_8723A("%s: Not yet implemented...\n", __func__);
9934 output_len = strlen(output) + 1;
9935 wrq_data->data.length = output_len;
9936 if (copy_to_user(wrq_data->data.pointer, output, output_len)) {
9940 } /* if args to set */
9943 wrq_data->data.length = 0;
9957 #include <rtw_android.h>
9958 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
9960 struct iwreq *wrq = (struct iwreq *)rq;
9965 case RTL_IOCTL_WPA_SUPPLICANT:
9966 ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
9968 #ifdef CONFIG_AP_MODE
9969 case RTL_IOCTL_HOSTAPD:
9970 ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
9972 #ifdef CONFIG_NO_WIRELESS_HANDLERS
9974 ret = rtw_wx_set_mode(dev, NULL, &wrq->u, NULL);
9977 #endif // CONFIG_AP_MODE
9978 case SIOCDEVPRIVATE:
9979 ret = rtw_ioctl_wext_private(dev, &wrq->u);