diff options
Diffstat (limited to 'drivers/net/wireless/rtl8723as/os_dep/linux/ioctl_linux.c')
-rwxr-xr-x | drivers/net/wireless/rtl8723as/os_dep/linux/ioctl_linux.c | 1089 |
1 files changed, 777 insertions, 312 deletions
diff --git a/drivers/net/wireless/rtl8723as/os_dep/linux/ioctl_linux.c b/drivers/net/wireless/rtl8723as/os_dep/linux/ioctl_linux.c index e3252e233511..d0fd7479ec1e 100755 --- a/drivers/net/wireless/rtl8723as/os_dep/linux/ioctl_linux.c +++ b/drivers/net/wireless/rtl8723as/os_dep/linux/ioctl_linux.c @@ -376,7 +376,7 @@ static char *translate_scan(_adapter *padapter, u8 wfd_ie[ 128 ] = { 0x00 }; uint wfd_ielen = 0; - if ( rtw_get_wfd_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, wfd_ie, &wfd_ielen ) ) + if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) ) { u8 wfd_devinfo[ 6 ] = { 0x00 }; uint wfd_devlen = 6; @@ -454,7 +454,7 @@ static char *translate_scan(_adapter *padapter, if(ht_cap == _TRUE) snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn"); else - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg"); + snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg"); } else { @@ -608,6 +608,17 @@ static char *translate_scan(_adapter *padapter, u8 *ie_ptr = pnetwork->network.IEs +_FIXED_IE_LENGTH_; total_ielen= pnetwork->network.IELength - _FIXED_IE_LENGTH_; + if (pnetwork->network.Reserved[0] == 2) // Probe Request + { + ie_ptr = pnetwork->network.IEs; + total_ielen = pnetwork->network.IELength; + } + else // Beacon or Probe Respones + { + ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_; + total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_; + } + while(cnt < total_ielen) { if(rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen>2)) @@ -661,7 +672,7 @@ static char *translate_scan(_adapter *padapter, start = iwe_stream_add_point(info, start, stop, &iwe, wapi_ie); } } -#endif +#endif //CONFIG_WAPI_SUPPORT { struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); @@ -676,7 +687,7 @@ static char *translate_scan(_adapter *padapter, ; if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE && - is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) { + is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) { ss = padapter->recvpriv.signal_strength; sq = padapter->recvpriv.signal_qual; } else { @@ -706,6 +717,20 @@ static char *translate_scan(_adapter *padapter, start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN); } + + { + u8 buf[MAX_WPA_IE_LEN]; + u8 * p,*pos; + int len; + p = buf; + pos = pnetwork->network.Reserved; + _rtw_memset(buf, 0, MAX_WPA_IE_LEN); + p += sprintf(p, "fm=%02X%02X", pos[1], pos[0]); + _rtw_memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVCUSTOM; + iwe.u.data.length = strlen(buf); + start = iwe_stream_add_point(info, start, stop, &iwe, buf); + } return start; } @@ -792,20 +817,26 @@ _func_enter_; param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { - if (param->u.crypt.idx >= WEP_KEYS) + + if (param->u.crypt.idx >= WEP_KEYS +#ifdef CONFIG_IEEE80211W + && param->u.crypt.idx > BIP_MAX_KEYID +#endif //CONFIG_IEEE80211W + ) { ret = -EINVAL; goto exit; } - } else { + } + else + { #ifdef CONFIG_WAPI_SUPPORT - if (strcmp(param->u.crypt.alg, "SMS4")) + if (strcmp(param->u.crypt.alg, "SMS4")) #endif - { - - ret = -EINVAL; - goto exit; - } + { + ret = -EINVAL; + goto exit; + } } if (strcmp(param->u.crypt.alg, "WEP") == 0) @@ -882,7 +913,7 @@ _func_enter_; _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength); psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength; - rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0); + rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0,_TRUE); } goto exit; @@ -928,20 +959,45 @@ _func_enter_; //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len)); DBG_871X(" ~~~~set sta key:unicastkey\n"); - rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE); + rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE, _TRUE); } else//group key { - _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); - _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8); - _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8); - padapter->securitypriv.binstallGrpkey = _TRUE; - //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len)); - DBG_871X(" ~~~~set sta key:groupkey\n"); - - padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx; - - rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1); + if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) + { + printk("[%s] GTK key_len=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.alg, param->u.crypt.key_len); + _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + //only TKIP group key need to install this + if(param->u.crypt.key_len > 16) + { + _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8); + _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8); + } + padapter->securitypriv.binstallGrpkey = _TRUE; + //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len)); + DBG_871X(" ~~~~set sta key:groupkey\n"); + + padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx; + + rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1,_TRUE); + } +#ifdef CONFIG_IEEE80211W + else if(strcmp(param->u.crypt.alg, "BIP") == 0) + { + int no; + //printk("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx); + //save the IGTK key, length 16 bytes + _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + /*printk("IGTK key below:\n"); + for(no=0;no<16;no++) + printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]); + printk("\n");*/ + padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx; + padapter->securitypriv.binstallBIPkey = _TRUE; + DBG_871X(" ~~~~set sta key:IGKT\n"); + } +#endif //CONFIG_IEEE80211W + #ifdef CONFIG_P2P if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) { @@ -967,8 +1023,8 @@ _func_enter_; (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) { pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; - } - } + } + } } else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode { @@ -1378,7 +1434,7 @@ static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a, case IW_MODE_MASTER: networkType = Ndis802_11APMode; DBG_871X("set_mode = IW_MODE_MASTER\n"); - //rtw_setopmode_cmd(padapter, networkType); + //rtw_setopmode_cmd(padapter, networkType,_TRUE); break; case IW_MODE_INFRA: networkType = Ndis802_11Infrastructure; @@ -1394,11 +1450,11 @@ static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a, /* if(Ndis802_11APMode == networkType) { - rtw_setopmode_cmd(padapter, networkType); + rtw_setopmode_cmd(padapter, networkType,_TRUE); } else { - rtw_setopmode_cmd(padapter, Ndis802_11AutoUnknown); + rtw_setopmode_cmd(padapter, Ndis802_11AutoUnknown,_TRUE); } */ @@ -1409,7 +1465,7 @@ static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a, } - rtw_setopmode_cmd(padapter, networkType); + rtw_setopmode_cmd(padapter, networkType,_TRUE); exit: @@ -2009,7 +2065,7 @@ if (padapter->registrypriv.mp_mode == 1) // under DHCP(Special packet) curr_time = rtw_get_current_time(); - delta_time = curr_time - padapter->pwrctrlpriv.DelayLPSLastTimeStamp; + delta_time = curr_time - adapter_to_pwrctl(padapter)->DelayLPSLastTimeStamp; delta_time = rtw_systime_to_ms(delta_time); if (delta_time < 500) // 500ms { @@ -2236,7 +2292,7 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, } #endif */ - if(padapter->pwrctrlpriv.brfoffbyhw && padapter->bDriverStopped) + if(adapter_to_pwrctl(padapter)->brfoffbyhw && padapter->bDriverStopped) { ret = -EINVAL; goto exit; @@ -2276,7 +2332,18 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, } #endif // CONFIG_CONCURRENT_MODE */ +#if 1 // Wireless Extension use EAGAIN to try + wait_status = _FW_UNDER_SURVEY +#ifndef CONFIG_ANDROID + | _FW_UNDER_LINKING +#endif + ; + while (check_fwstate(pmlmepriv, wait_status) == _TRUE) + { + return -EAGAIN; + } +#else wait_status = _FW_UNDER_SURVEY #ifndef CONFIG_ANDROID |_FW_UNDER_LINKING @@ -2300,6 +2367,7 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, if(cnt > wait_for_surveydone ) break; } +#endif _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); @@ -2320,9 +2388,7 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, //report network only if the current channel set contains the channel to which this network belongs if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0 - #ifdef CONFIG_VALIDATE_SSID && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid)) - #endif ) { ev=translate_scan(padapter, a, pnetwork, ev, stop); @@ -2362,7 +2428,6 @@ static int rtw_wx_set_essid(struct net_device *dev, _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; _queue *queue = &pmlmepriv->scanned_queue; - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; _list *phead; s8 status = _TRUE; struct wlan_network *pnetwork = NULL; @@ -2832,7 +2897,7 @@ static int rtw_wx_set_enc(struct net_device *dev, struct iw_point *erq = &(wrqu->encoding); _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); DBG_871X("+rtw_wx_set_enc, flags=0x%x\n", erq->flags); _rtw_memset(&wep, 0, sizeof(NDIS_802_11_WEP)); @@ -3280,6 +3345,11 @@ static int rtw_wx_set_enc_ext(struct net_device *dev, case IW_ENCODE_ALG_CCMP: alg_name = "CCMP"; break; +#ifdef CONFIG_IEEE80211W + case IW_ENCODE_ALG_AES_CMAC: + alg_name = "BIP"; + break; +#endif //CONFIG_IEEE80211W #ifdef CONFIG_WAPI_SUPPORT #ifndef CONFIG_IOCTL_CFG80211 case IW_ENCODE_ALG_SM4: @@ -3304,7 +3374,11 @@ static int rtw_wx_set_enc_ext(struct net_device *dev, * just not checking GROUP key setting */ if ((pext->alg != IW_ENCODE_ALG_WEP) && - (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)) + ((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) +#ifdef CONFIG_IEEE80211W + || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC) +#endif //CONFIG_IEEE80211W + )) { param->u.crypt.set_tx = 0; } @@ -3318,8 +3392,8 @@ static int rtw_wx_set_enc_ext(struct net_device *dev, if(pext->alg == IW_ENCODE_ALG_SM4) _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 16); else -#endif -#endif +#endif //CONFIG_IOCTL_CFG80211 +#endif //CONFIG_WAPI_SUPPORT _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 8); } @@ -4175,7 +4249,6 @@ static int rtw_wext_p2p_enable(struct net_device *dev, struct iw_point *pdata = &wrqu->data; struct wifidirect_info *pwdinfo= &(padapter->wdinfo); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; enum P2P_ROLE init_role = P2P_ROLE_DISABLE; if(*extra == '0' ) @@ -4277,19 +4350,9 @@ static int rtw_p2p_set_intent(struct net_device *dev, struct wifidirect_info *pwdinfo= &(padapter->wdinfo); u8 intent = pwdinfo->intent; - switch( wrqu->data.length ) - { - case 1: - { - intent = extra[ 0 ] - '0'; - break; - } - case 2: - { - intent = str_2char2num( extra[ 0 ], extra[ 1 ]); - break; - } - } + extra[ wrqu->data.length ] = 0x00; + + intent = rtw_atoi( extra ); if ( intent <= 15 ) { @@ -4303,7 +4366,7 @@ static int rtw_p2p_set_intent(struct net_device *dev, DBG_871X( "[%s] intent = %d\n", __FUNCTION__, intent); return ret; - + } static int rtw_p2p_set_listen_ch(struct net_device *dev, @@ -4316,19 +4379,8 @@ static int rtw_p2p_set_listen_ch(struct net_device *dev, struct wifidirect_info *pwdinfo= &(padapter->wdinfo); u8 listen_ch = pwdinfo->listen_channel; // Listen channel number - switch( wrqu->data.length ) - { - case 1: - { - listen_ch = extra[ 0 ] - '0'; - break; - } - case 2: - { - listen_ch = str_2char2num( extra[ 0 ], extra[ 1 ]); - break; - } - } + extra[ wrqu->data.length ] = 0x00; + listen_ch = rtw_atoi( extra ); if ( ( listen_ch == 1 ) || ( listen_ch == 6 ) || ( listen_ch == 11 ) ) { @@ -4358,20 +4410,9 @@ static int rtw_p2p_set_op_ch(struct net_device *dev, struct wifidirect_info *pwdinfo= &(padapter->wdinfo); u8 op_ch = pwdinfo->operating_channel; // Operating channel number - switch( wrqu->data.length ) - { - case 1: - { - op_ch = extra[ 0 ] - '0'; - break; - } - case 2: - { - op_ch = str_2char2num( extra[ 0 ], extra[ 1 ]); - break; - } - } + extra[ wrqu->data.length ] = 0x00; + op_ch = ( u8 ) rtw_atoi( extra ); if ( op_ch > 0 ) { pwdinfo->operating_channel = op_ch; @@ -4384,7 +4425,7 @@ static int rtw_p2p_set_op_ch(struct net_device *dev, DBG_871X( "[%s] op_ch = %d\n", __FUNCTION__, pwdinfo->operating_channel ); return ret; - + } @@ -4436,8 +4477,8 @@ static int rtw_p2p_profilefound(struct net_device *dev, pwdinfo->profileinfo[ pwdinfo->profileindex ].peermac[ jj ] = key_2char2num(extra[ kk ], extra[ kk+ 1 ]); } - pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen = ( extra[18] - '0' ) * 10 + ( extra[ 19 ] - '0' ); - _rtw_memcpy( pwdinfo->profileinfo[ pwdinfo->profileindex ].ssid, &extra[ 20 ], pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen ); + //pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen = ( extra[18] - '0' ) * 10 + ( extra[ 19 ] - '0' ); + //_rtw_memcpy( pwdinfo->profileinfo[ pwdinfo->profileindex ].ssid, &extra[ 20 ], pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen ); pwdinfo->profileindex++; } } @@ -4709,7 +4750,7 @@ static int rtw_p2p_get_wps_configmethod(struct net_device *dev, // The mac address is matched. - if ((wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len))) + if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) ) { rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&attr_content, &attr_contentlen); if (attr_contentlen) @@ -4845,7 +4886,7 @@ static int rtw_p2p_get_go_device_address(struct net_device *dev, // Match the device address located in the P2P IE // This is for the case that the P2P device address is not the same as the P2P interface address. - if ((p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen))) + if ((p2pie = rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0]))) { while (p2pie) { @@ -4938,7 +4979,7 @@ static int rtw_p2p_get_device_type(struct net_device *dev, // The mac address is matched. - if ((wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len))) + if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) ) { rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len); if (dev_type_len) @@ -5016,7 +5057,7 @@ static int rtw_p2p_get_device_name(struct net_device *dev, // The mac address is matched. - if ((wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len))) + if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) ) { rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len); if (dev_len) @@ -5089,7 +5130,7 @@ static int rtw_p2p_get_invitation_procedure(struct net_device *dev, // Match the device address located in the P2P IE // This is for the case that the P2P device address is not the same as the P2P interface address. - if ((p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen))) + if ((p2pie = rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0]))) { while (p2pie) { @@ -5351,7 +5392,7 @@ static int rtw_p2p_invite_req(struct net_device *dev, // Match the device address located in the P2P IE // This is for the case that the P2P device address is not the same as the P2P interface address. - if ( (p2pie=rtw_get_p2p_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen)) ) + if ( (p2pie=rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0]))) { // The P2P Device ID attribute is included in the Beacon frame. // The P2P Device Info attribute is included in the probe response frame. @@ -5389,7 +5430,7 @@ static int rtw_p2p_invite_req(struct net_device *dev, u8 wfd_ie[ 128 ] = { 0x00 }; uint wfd_ielen = 0; - if ( rtw_get_wfd_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, wfd_ie, &wfd_ielen ) ) + if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) ) { u8 wfd_devinfo[ 6 ] = { 0x00 }; uint wfd_devlen = 6; @@ -5555,6 +5596,79 @@ exit: } +static int hexstr2bin(const char *hex, u8 *buf, size_t len) +{ + size_t i; + int a; + const char *ipos = hex; + u8 *opos = buf; + + for (i = 0; i < len; i++) { + a = hex2byte_i(ipos); + if (a < 0) + return -1; + *opos++ = a; + ipos += 2; + } + return 0; +} + +static int uuid_str2bin(const char *str, u8 *bin) +{ + const char *pos; + u8 *opos; + + pos = str; + opos = bin; + + if (hexstr2bin(pos, opos, 4)) + return -1; + pos += 8; + opos += 4; + + if (*pos++ != '-' || hexstr2bin(pos, opos, 2)) + return -1; + pos += 4; + opos += 2; + + if (*pos++ != '-' || hexstr2bin(pos, opos, 2)) + return -1; + pos += 4; + opos += 2; + + if (*pos++ != '-' || hexstr2bin(pos, opos, 2)) + return -1; + pos += 4; + opos += 2; + + if (*pos++ != '-' || hexstr2bin(pos, opos, 6)) + return -1; + + return 0; +} + +static int rtw_p2p_set_wps_uuid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); + + DBG_871X("[%s] data = %s\n", __FUNCTION__, extra); + + if ((36 == strlen(extra)) && (uuid_str2bin(extra, pwdinfo->uuid) == 0)) + { + pwdinfo->external_uuid = 1; + } else { + pwdinfo->external_uuid = 0; + ret = -EINVAL; + } + + return ret; + +} #ifdef CONFIG_WFD static int rtw_p2p_set_pc(struct net_device *dev, struct iw_request_info *info, @@ -5616,7 +5730,7 @@ static int rtw_p2p_set_pc(struct net_device *dev, // Match the device address located in the P2P IE // This is for the case that the P2P device address is not the same as the P2P interface address. - if ( (p2pie=rtw_get_p2p_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen)) ) + if ( (p2pie=rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0]))) { // The P2P Device ID attribute is included in the Beacon frame. // The P2P Device Info attribute is included in the probe response frame. @@ -5656,7 +5770,7 @@ static int rtw_p2p_set_pc(struct net_device *dev, u8 wfd_ie[ 128 ] = { 0x00 }; uint wfd_ielen = 0; - if ( rtw_get_wfd_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, wfd_ie, &wfd_ielen ) ) + if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) ) { u8 wfd_devinfo[ 6 ] = { 0x00 }; uint wfd_devlen = 6; @@ -5769,6 +5883,53 @@ exit: } +static int rtw_p2p_set_wfd_enable(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ +// Commented by Kurt 20121206 +// This function is used to set wfd enabled + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + + if(*extra == '0' ) + pwdinfo->wfd_info->wfd_enable = _FALSE; + else if(*extra == '1') + pwdinfo->wfd_info->wfd_enable = _TRUE; + + DBG_871X( "[%s] wfd_enable = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_enable ); + + return ret; + +} + +static int rtw_p2p_set_driver_iface(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ +// Commented by Kurt 20121206 +// This function is used to set driver iface is WEXT or CFG80211 + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + + if(*extra == '1' ) + { + pwdinfo->driver_interface = DRIVER_WEXT; + DBG_871X( "[%s] driver_interface = WEXT\n", __FUNCTION__); + } + else if(*extra == '2') + { + pwdinfo->driver_interface = DRIVER_CFG80211; + DBG_871X( "[%s] driver_interface = CFG80211\n", __FUNCTION__); + } + + return ret; + +} + // To set the WFD session available to enable or disable static int rtw_p2p_set_sa(struct net_device *dev, struct iw_request_info *info, @@ -5831,11 +5992,13 @@ static int rtw_p2p_prov_disc(struct net_device *dev, u8 *p2pie; uint p2pielen = 0, attr_contentlen = 0; _irqL irqL; + u8 ie_offset; #ifdef CONFIG_CONCURRENT_MODE _adapter *pbuddy_adapter = padapter->pbuddy_adapter; struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv; struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; #endif // CONFIG_CONCURRENT_MODE + #ifdef CONFIG_WFD struct wifi_display_info* pwfd_info = pwdinfo->wfd_info; #endif // CONFIG_WFD @@ -5858,6 +6021,13 @@ static int rtw_p2p_prov_disc(struct net_device *dev, } else { +#ifdef CONFIG_INTEL_WIDI + if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE){ + DBG_871X( "[%s] WiFi is under survey!\n", __FUNCTION__ ); + return ret; + } +#endif //CONFIG_INTEL_WIDI + // Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request. _rtw_memset( pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN ); _rtw_memset( pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN ); @@ -5913,7 +6083,12 @@ static int rtw_p2p_prov_disc(struct net_device *dev, // Match the device address located in the P2P IE // This is for the case that the P2P device address is not the same as the P2P interface address. - if ( (p2pie=rtw_get_p2p_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen)) ) + if (pnetwork->network.Reserved[0] == 2) { // Probe Request + ie_offset = 0; + } else { // Beacon or Probe Respones + ie_offset = 12; + } + if ( (p2pie=rtw_get_p2p_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &p2pielen, pnetwork->network.Reserved[0]))) { while ( p2pie ) { @@ -5940,10 +6115,23 @@ static int rtw_p2p_prov_disc(struct net_device *dev, } //Get the next P2P IE - p2pie = rtw_get_p2p_ie(p2pie+p2pielen, pnetwork->network.IELength - 12 -(p2pie -&pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen); + p2pie = rtw_get_p2p_ie(p2pie+p2pielen, pnetwork->network.IELength - ie_offset -(p2pie -&pnetwork->network.IEs[ie_offset] + p2pielen), NULL, &p2pielen); } + } +#ifdef CONFIG_INTEL_WIDI + // Some Intel WiDi source may not provide P2P IE, + // so we could only compare mac addr by 802.11 Source Address + if( pmlmepriv->widi_state == INTEL_WIDI_STATE_WFD_CONNECTION + && uintPeerChannel == 0 ) + { + if ( _rtw_memcmp( pnetwork->network.MacAddress, peerMAC, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } } +#endif //CONFIG_INTEL_WIDI plist = get_next(plist); @@ -5951,47 +6139,46 @@ static int rtw_p2p_prov_disc(struct net_device *dev, _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); -#ifdef CONFIG_WFD + if ( uintPeerChannel ) { - u8 wfd_ie[ 128 ] = { 0x00 }; - uint wfd_ielen = 0; - - if ( rtw_get_wfd_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, wfd_ie, &wfd_ielen ) ) +#ifdef CONFIG_WFD { - u8 wfd_devinfo[ 6 ] = { 0x00 }; - uint wfd_devlen = 6; - - DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ ); - if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) ) + u8 wfd_ie[ 128 ] = { 0x00 }; + uint wfd_ielen = 0; + + if ( rtw_get_wfd_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, wfd_ie, &wfd_ielen, pnetwork->network.Reserved[0]) ) { - u16 wfd_devinfo_field = 0; - - // Commented by Albert 20120319 - // The first two bytes are the WFD device information field of WFD device information subelement. - // In big endian format. - wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo); - if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL ) - { - pwfd_info->peer_session_avail = _TRUE; - } - else + u8 wfd_devinfo[ 6 ] = { 0x00 }; + uint wfd_devlen = 6; + + DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ ); + if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) ) { - pwfd_info->peer_session_avail = _FALSE; + u16 wfd_devinfo_field = 0; + + // Commented by Albert 20120319 + // The first two bytes are the WFD device information field of WFD device information subelement. + // In big endian format. + wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo); + if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL ) + { + pwfd_info->peer_session_avail = _TRUE; + } + else + { + pwfd_info->peer_session_avail = _FALSE; + } } } + + if ( _FALSE == pwfd_info->peer_session_avail ) + { + DBG_871X( "[%s] WFD Session not avaiable!\n", __FUNCTION__ ); + goto exit; + } } - - if ( _FALSE == pwfd_info->peer_session_avail ) - { - DBG_871X( "[%s] WFD Session not avaiable!\n", __FUNCTION__ ); - goto exit; - } - } #endif // CONFIG_WFD - if ( uintPeerChannel ) - { - DBG_871X( "[%s] peer channel: %d!\n", __FUNCTION__, uintPeerChannel ); #ifdef CONFIG_CONCURRENT_MODE if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) @@ -6051,6 +6238,14 @@ static int rtw_p2p_prov_disc(struct net_device *dev, else { DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ ); +#ifdef CONFIG_INTEL_WIDI + rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE); + rtw_free_network_queue(padapter, _TRUE); + _enter_critical_bh(&pmlmepriv->lock, &irqL); + rtw_sitesurvey_cmd(padapter, NULL, 0, NULL, 0); + _exit_critical_bh(&pmlmepriv->lock, &irqL); +#endif //CONFIG_INTEL_WIDI } exit: @@ -6190,6 +6385,11 @@ static int rtw_p2p_set(struct net_device *dev, wrqu->data.length -= 11; rtw_p2p_set_persistent( dev, info, wrqu, &extra[11] ); } + else if ( _rtw_memcmp ( extra, "uuid=", 5) ) + { + wrqu->data.length -= 5; + ret = rtw_p2p_set_wps_uuid( dev, info, wrqu, &extra[5] ); + } #ifdef CONFIG_WFD else if ( _rtw_memcmp( extra, "sa=", 3 ) ) { @@ -6214,8 +6414,17 @@ static int rtw_p2p_set(struct net_device *dev, wrqu->data.length -= 10; rtw_p2p_set_scan_result_type( dev, info, wrqu, &extra[10] ); } + else if ( _rtw_memcmp( extra, "wfd_enable=", 11 ) ) + { + wrqu->data.length -= 11; + rtw_p2p_set_wfd_enable( dev, info, wrqu, &extra[11] ); + } + else if ( _rtw_memcmp( extra, "driver_iface=", 13 ) ) + { + wrqu->data.length -= 13; + rtw_p2p_set_driver_iface( dev, info, wrqu, &extra[13] ); + } #endif //CONFIG_WFD - #endif //CONFIG_P2P return ret; @@ -6267,7 +6476,7 @@ static int rtw_p2p_get(struct net_device *dev, { rtw_p2p_get_groupid( dev, info, wrqu, extra); } - else if ( _rtw_memcmp( wrqu->data.pointer, "peer_deva_inv", 9 ) ) + else if ( _rtw_memcmp( wrqu->data.pointer, "inv_peer_deva", 13 ) ) { // Get the P2P device address when receiving the P2P Invitation request frame. rtw_p2p_get_peer_devaddr_by_invitation( dev, info, wrqu, extra); @@ -6347,7 +6556,7 @@ static int rtw_p2p_get2(struct net_device *dev, bad: if (buffer) { - _rtw_mfree(buffer, length); + rtw_mfree(buffer, length); } #endif //CONFIG_P2P @@ -6429,7 +6638,7 @@ static int rtw_rereg_nd_name(struct net_device *dev, if(_rtw_memcmp(rereg_priv->old_ifname, "disable%d", 9) == _TRUE) { padapter->ledpriv.bRegUseLed= rereg_priv->old_bRegUseLed; rtw_hal_sw_led_init(padapter); - rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode); + /* rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode); */ } strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ); @@ -6446,10 +6655,12 @@ static int rtw_rereg_nd_name(struct net_device *dev, rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed; padapter->ledpriv.bRegUseLed= _FALSE; rtw_hal_sw_led_deinit(padapter); - + + /* // the interface is being "disabled", we can do deeper IPS rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv); rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL); + */ } exit: return ret; @@ -6998,8 +7209,58 @@ static int rtw_dbg_port(struct net_device *dev, } break; + case 0x0a: + { + #ifdef DBG_TRX_STA_PKTS + int i, j; + _list *plist, *phead; + + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + for(i=0; i< NUM_STA; i++) + { + phead = &(pstapriv->sta_hash[i]); + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, hash_list); - case 0x0c://dump rx/tx packet + plist = get_next(plist); + if(arg == 0xff){ + psta->rx_bk_cnt =0; + psta->rx_be_cnt =0; + psta->rx_vo_cnt =0; + psta->rx_vi_cnt =0; + psta->tx_bk_cnt =0; + psta->tx_be_cnt =0; + psta->tx_vo_cnt =0; + psta->tx_vi_cnt =0; + } + else{ + if(extra_arg == psta->mac_id) + { + DBG_871X("=== sta's macaddr:" MAC_FMT "===\n", MAC_ARG(psta->hwaddr)); + DBG_871X("rx_bk_cnt =%d\n", psta->rx_bk_cnt); + DBG_871X("rx_be_cnt =%d\n", psta->rx_be_cnt); + DBG_871X("rx_vo_cnt =%d\n", psta->rx_vo_cnt); + DBG_871X("rx_vi_cnt =%d\n\n", psta->rx_vi_cnt); + + DBG_871X("tx_bk_cnt =%d\n", psta->tx_bk_cnt); + DBG_871X("tx_be_cnt =%d\n", psta->tx_be_cnt); + DBG_871X("tx_vo_cnt =%d\n", psta->tx_vo_cnt); + DBG_871X("tx_vi_cnt =%dn\n", psta->tx_vi_cnt); + } + } + + } + } + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + #endif + } + break; + + case 0x0c://dump rx/tx packet { if(arg == 0){ DBG_871X("dump rx packet (%d)\n",extra_arg); @@ -7039,7 +7300,7 @@ static int rtw_dbg_port(struct net_device *dev, break; case 0x15: { - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); DBG_871X("==>silent resete cnts:%d\n",pwrpriv->ips_enter_cnts); } break; @@ -7050,10 +7311,10 @@ static int rtw_dbg_port(struct net_device *dev, DBG_871X("rtw driver version=%s\n", DRIVERVERSION); break; case 0x11: - { + { DBG_871X("turn %s Rx RSSI display function\n",(extra_arg==1)?"on":"off"); - padapter->bRxRSSIDisplay = extra_arg ; - rtw_hal_set_def_var(padapter, HW_DEF_FA_CNT_DUMP,&extra_arg); + padapter->bRxRSSIDisplay = extra_arg; + rtw_hal_set_def_var(padapter, HW_DEF_FA_CNT_DUMP, &(padapter->bRxRSSIDisplay)); } break; case 0x12: //set rx_stbc @@ -7095,29 +7356,11 @@ static int rtw_dbg_port(struct net_device *dev, case 0x16: { if(arg == 0xff){ - printk("ODM_COMP_DIG\t\tBIT0\n"); - printk("ODM_COMP_RA_MASK\t\tBIT1\n"); - printk("ODM_COMP_DYNAMIC_TXPWR\tBIT2\n"); - printk("ODM_COMP_FA_CNT\t\tBIT3\n"); - printk("ODM_COMP_RSSI_MONITOR\tBIT4\n"); - printk("ODM_COMP_CCK_PD\t\tBIT5\n"); - printk("ODM_COMP_ANT_DIV\t\tBIT6\n"); - printk("ODM_COMP_PWR_SAVE\t\tBIT7\n"); - printk("ODM_COMP_PWR_TRAIN\tBIT8\n"); - printk("ODM_COMP_RATE_ADAPTIVE\tBIT9\n"); - printk("ODM_COMP_PATH_DIV\t\tBIT10\n"); - printk("ODM_COMP_PSD \tBIT11\n"); - printk("ODM_COMP_DYNAMIC_PRICCA\tBIT12\n"); - printk("ODM_COMP_RXHP\t\tBIT13\n"); - printk("ODM_COMP_EDCA_TURBO\tBIT16\n"); - printk("ODM_COMP_EARLY_MODE\tBIT17\n"); - printk("ODM_COMP_TX_PWR_TRACK\tBIT24\n"); - printk("ODM_COMP_RX_GAIN_TRACK\tBIT25\n"); - printk("ODM_COMP_CALIBRATION\tBIT26\n"); - rtw_hal_get_def_var(padapter, HW_DEF_ODM_DBG_FLAG,&extra_arg); + rtw_odm_dbg_comp_msg(padapter); } else{ - rtw_hal_set_def_var(padapter, HW_DEF_ODM_DBG_FLAG,&extra_arg); + u64 dbg_comp = (u64)extra_arg; + rtw_odm_dbg_comp_set(padapter, dbg_comp); } } break; @@ -7527,7 +7770,7 @@ static int set_group_key(_adapter *padapter, u8 *key, u8 alg, int keyid) psetkeyparm->keyid=(u8)keyid; if (is_wep_enc(alg)) - padapter->mlmepriv.key_mask |= BIT(psetkeyparm->keyid); + padapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid); psetkeyparm->algorithm = alg; psetkeyparm->set_tx = 1; @@ -8814,6 +9057,101 @@ FREE_EXT: } +#ifdef CONFIG_WOWLAN +static int rtw_wowlan_ctrl(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wowlan_ioctl_param poidparam; + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct sta_info *psta = NULL; + int ret = 0; + u32 start_time = rtw_get_current_time(); + poidparam.subcode = 0; + + DBG_871X("+rtw_wowlan_ctrl: %s\n", extra); + + if(pwrctrlpriv->bSupportRemoteWakeup==_FALSE){ + ret = -EPERM; + DBG_871X("+rtw_wowlan_ctrl: Device didn't support the remote wakeup!!\n"); + goto _rtw_wowlan_ctrl_exit_free; + } + + if (!check_fwstate(pmlmepriv, _FW_LINKED) && + check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { + DBG_871X("[%s] WARNING: Please Connect With AP First!!\n", __func__); + goto _rtw_wowlan_ctrl_exit_free; + } + + if (_rtw_memcmp( extra, "enable", 6 )) { + + while (pwrctrlpriv->bips_processing == _TRUE) + rtw_msleep_os(1); + + rtw_cancel_all_timer(padapter); + + padapter->bDriverStopped = _TRUE; //for stop thread + rtw_stop_drv_threads(padapter); + padapter->bDriverStopped = _FALSE; //for 32k command + +#ifdef CONFIG_LPS + rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0); +#endif + rtw_hal_disable_interrupt(padapter); // It need wait for leaving 32K. + + // 2.1 clean interupt + if (padapter->HalFunc.clear_interrupt) + padapter->HalFunc.clear_interrupt(padapter); + + poidparam.subcode = WOWLAN_ENABLE; + + rtw_hal_set_hwreg(padapter,HW_VAR_WOWLAN,(u8 *)&poidparam); + } else if (_rtw_memcmp( extra, "disable", 6 )) { +#ifdef CONFIG_LPS + rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0); +#endif //CONFIG_LPS + pwrctrlpriv->bFwCurrentInPSMode = _FALSE; + + rtw_hal_disable_interrupt(padapter); + + if (padapter->HalFunc.clear_interrupt) + padapter->HalFunc.clear_interrupt(padapter); + + poidparam.subcode = WOWLAN_DISABLE; + + rtw_hal_set_hwreg(padapter,HW_VAR_WOWLAN,(u8 *)&poidparam); + + psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv)); + if (psta) { + set_sta_rate(padapter, psta); + } + + padapter->bDriverStopped = _FALSE; + DBG_871X("%s: wowmode resuming, DriverStopped:%d\n", __func__, padapter->bDriverStopped); + rtw_start_drv_threads(padapter); + + rtw_hal_enable_interrupt(padapter); + + _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); + pwrctrlpriv->bips_processing = _FALSE; + rtw_set_pwr_state_check_timer(pwrctrlpriv); + + } else { + DBG_871X("[%s] Invalid Parameter.\n", __func__); + goto _rtw_wowlan_ctrl_exit_free; + } + //mutex_lock(&ioctl_mutex); +_rtw_wowlan_ctrl_exit_free: + DBG_871X("-rtw_wowlan_ctrl( subcode = %d)\n", poidparam.subcode); + DBG_871X_LEVEL(_drv_always_, "%s in %d ms\n", __func__, + rtw_get_passing_time_ms(start_time)); +_rtw_wowlan_ctrl_exit: + return ret; +} +#endif //CONFIG_WOWLAN + static int rtw_pm_set(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -8867,17 +9205,17 @@ static int rtw_mp_efuse_get(struct net_device *dev, #endif wrqu = (struct iw_point*)wdata; - pwrctrlpriv = &padapter->pwrctrlpriv; + pwrctrlpriv = adapter_to_pwrctl(padapter); pEfuseHal = &pHalData->EfuseHal; err = 0; - data = _rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN); + data = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN); if (data == NULL) { err = -ENOMEM; goto exit; } - rawdata = _rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN); + rawdata = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN); if (rawdata == NULL) { err = -ENOMEM; @@ -9070,6 +9408,15 @@ static int rtw_mp_efuse_get(struct net_device *dev, addr = EEPROM_MAC_ADDR_8723AU; #endif #endif // CONFIG_RTL8723A + + #ifdef CONFIG_RTL8188E + #ifdef CONFIG_SDIO_HCI + addr = EEPROM_MAC_ADDR_88ES; + #else + addr = EEPROM_MAC_ADDR_88EU; + #endif + #endif + cnts = 6; EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); @@ -9388,9 +9735,9 @@ static int rtw_mp_efuse_get(struct net_device *dev, exit: if (data) - _rtw_mfree(data, EFUSE_BT_MAX_MAP_LEN); + rtw_mfree(data, EFUSE_BT_MAX_MAP_LEN); if (rawdata) - _rtw_mfree(rawdata, EFUSE_BT_MAX_MAP_LEN); + rtw_mfree(rawdata, EFUSE_BT_MAX_MAP_LEN); if (!err) wrqu->length = strlen(extra); @@ -9429,29 +9776,29 @@ static int rtw_mp_efuse_set(struct net_device *dev, wrqu = (struct iw_point*)wdata; padapter = rtw_netdev_priv(dev); - pwrctrlpriv = &padapter->pwrctrlpriv; + pwrctrlpriv = adapter_to_pwrctl(padapter); pHalData = GET_HAL_DATA(padapter); pEfuseHal = &pHalData->EfuseHal; err = 0; - setdata = _rtw_zmalloc(1024); + setdata = rtw_zmalloc(1024); if (setdata == NULL) { err = -ENOMEM; goto exit; } - ShadowMapBT = _rtw_malloc(EFUSE_BT_MAX_MAP_LEN); + ShadowMapBT = rtw_malloc(EFUSE_BT_MAX_MAP_LEN); if (ShadowMapBT == NULL) { err = -ENOMEM; goto exit; } - ShadowMapWiFi = _rtw_malloc(EFUSE_MAP_SIZE); + ShadowMapWiFi = rtw_malloc(EFUSE_MAP_SIZE); if (ShadowMapWiFi == NULL) { err = -ENOMEM; goto exit; } - setrawdata = _rtw_malloc(EFUSE_MAX_SIZE); + setrawdata = rtw_malloc(EFUSE_MAX_SIZE); if (setrawdata == NULL) { err = -ENOMEM; @@ -9890,13 +10237,13 @@ static int rtw_mp_efuse_set(struct net_device *dev, exit: if (setdata) - _rtw_mfree(setdata, 1024); + rtw_mfree(setdata, 1024); if (ShadowMapBT) - _rtw_mfree(ShadowMapBT, EFUSE_BT_MAX_MAP_LEN); + rtw_mfree(ShadowMapBT, EFUSE_BT_MAX_MAP_LEN); if (ShadowMapWiFi) - _rtw_mfree(ShadowMapWiFi, EFUSE_MAP_SIZE); + rtw_mfree(ShadowMapWiFi, EFUSE_MAP_SIZE); if (setrawdata) - _rtw_mfree(setrawdata, EFUSE_MAX_SIZE); + rtw_mfree(setrawdata, EFUSE_MAX_SIZE); #ifdef CONFIG_IPS rtw_pm_set_ips(padapter, ips_mode); @@ -9928,9 +10275,15 @@ static int rtw_mp_write_reg(struct net_device *dev, u32 addr, data; int ret; PADAPTER padapter = rtw_netdev_priv(dev); + char input[wrqu->length]; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + _rtw_memset(extra, 0, wrqu->length); + + pch = input; - - pch = extra; pnext = strpbrk(pch, " ,.-"); if (pnext == NULL) return -EINVAL; *pnext = 0; @@ -10141,9 +10494,13 @@ static int rtw_mp_read_reg(struct net_device *dev, u32 path, addr, data; int ret; PADAPTER padapter = rtw_netdev_priv(dev); + char input[wrqu->length]; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; - ret = sscanf(extra, "%d,%x,%x", &path, &addr, &data); + ret = sscanf(input, "%d,%x,%x", &path, &addr, &data); if (ret < 3) return -EINVAL; if (path >= MAX_RF_PATH_NUMS) return -EINVAL; @@ -10234,20 +10591,40 @@ static int rtw_mp_start(struct net_device *dev, { u8 val8; PADAPTER padapter = rtw_netdev_priv(dev); - + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct hal_ops *pHalFunc = &padapter->HalFunc; +#ifdef CONFIG_BT_COEXIST + PBT30Info pBTInfo; + PBT_MGNT pBtMgnt; + + pBTInfo = GET_BT_INFO(padapter); + pBtMgnt = &pBTInfo->BtMgnt; +#endif if(padapter->registrypriv.mp_mode ==0) { #ifdef CONFIG_RTL8723A DBG_871X("_rtw_mp_xmit_priv for Download BT patch FW\n"); _rtw_mp_xmit_priv(&padapter->xmitpriv); #endif - - padapter->registrypriv.mp_mode =1; - + + padapter->registrypriv.mp_mode =1; rtw_pm_set_ips(padapter,IPS_NONE); LeaveAllPowerSaveMode(padapter); - MPT_InitializeAdapter(padapter, 1); +#ifdef CONFIG_BT_COEXIST + pHalData->bt_coexist.BluetoothCoexist = 0; + pBtMgnt->ExtConfig.bManualControl = _TRUE; + pdmpriv->DMFlag &= (~DYNAMIC_FUNC_BT); + BT_HaltProcess(padapter); + DBG_871X("Set disable BT_COEXIST\n"); + //padapter->registrypriv.mp_mode =0; + //pHalFunc->hal_init(padapter); + //padapter->registrypriv.mp_mode =1; + // Force to switch Antenna to WiFi + rtw_write16(padapter, 0x870, 0x300); + rtw_write16(padapter, 0x860, 0x110); +#endif } if (padapter->registrypriv.mp_mode == 0) @@ -10257,6 +10634,7 @@ static int rtw_mp_start(struct net_device *dev, if (mp_start_test(padapter) == _FAIL) return -EPERM; padapter->mppriv.mode = MP_ON; + MPT_PwrCtlDM(padapter,0); } return 0; @@ -10370,24 +10748,30 @@ static int rtw_mp_txpower(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrqu, char *extra) { - u32 idx_a=0,idx_b=0; + u32 idx_a=0,idx_b=0,MsetPower=1; u8 input[wrqu->length]; PADAPTER padapter = rtw_netdev_priv(dev); - if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; + MsetPower = strncmp(input, "off", 3); sscanf(input,"patha=%d,pathb=%d",&idx_a,&idx_b); //DBG_871X("%s: tx_pwr_idx_a=%x b=%x\n", __func__, idx_a, idx_b); - + if(MsetPower==0) + { + padapter->mppriv.bSetTxPower = 0; + sprintf( extra, "MP Set power off"); + } + else + { sprintf( extra, "Set power level path_A:%d path_B:%d", idx_a , idx_b ); padapter->mppriv.txpoweridx = (u8)idx_a; padapter->mppriv.txpoweridx_b = (u8)idx_b; padapter->mppriv.bSetTxPower = 1; Hal_SetAntennaPathPower(padapter); - + } wrqu->length = strlen(extra) + 1; return 0; } @@ -10622,6 +11006,10 @@ static int rtw_mp_disable_bt_coexist(struct net_device *dev, union iwreq_data *wrqu, char *extra) { PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct hal_ops *pHalFunc = &padapter->HalFunc; + u8 input[wrqu->data.length]; u32 bt_coexist; @@ -10641,8 +11029,17 @@ static int rtw_mp_disable_bt_coexist(struct net_device *dev, { RT_TRACE(_module_mp_, _drv_info_, ("Set OID_RT_SET_DISABLE_BT_COEXIST: disable BT_COEXIST\n")); -#ifdef CONFIG_BT_COEXIST + DBG_871X("Set OID_RT_SET_DISABLE_BT_COEXIST: disable BT_COEXIST\n"); +#ifdef CONFIG_BT_COEXIST + pHalData->bt_coexist.BluetoothCoexist = 0; pBtMgnt->ExtConfig.bManualControl = _TRUE; + pdmpriv->DMFlag &= (~DYNAMIC_FUNC_BT); + BT_HaltProcess(padapter); +#if 1 + padapter->registrypriv.mp_mode=0; + pHalFunc->hal_init(padapter); + padapter->registrypriv.mp_mode=1; +#endif // Force to switch Antenna to WiFi rtw_write16(padapter, 0x870, 0x300); rtw_write16(padapter, 0x860, 0x110); @@ -10668,9 +11065,10 @@ static int rtw_mp_arx(struct net_device *dev, struct iw_point *wrqu, char *extra) { u8 bStartRx=0,bStopRx=0,bQueryPhy=0,bQueryMac=0; - u32 cckok=0,cckcrc=0,ofdmok=0,ofdmcrc=0,htok=0,htcrc=0,OFDM_FA=0,CCK_FA=0,DropPacket=0; + u32 cckok=0,cckcrc=0,ofdmok=0,ofdmcrc=0,htok=0,htcrc=0,OFDM_FA=0,CCK_FA=0,DropPacket=0,vht_ok=0,vht_err=0; u8 input[wrqu->length]; - + u32 mac_cck_ok=0, mac_ofdm_ok=0, mac_ht_ok=0, mac_vht_ok=0; + u32 mac_cck_err=0, mac_ofdm_err=0, mac_ht_err=0, mac_vht_err=0; PADAPTER padapter = rtw_netdev_priv(dev); @@ -10696,62 +11094,63 @@ static int rtw_mp_arx(struct net_device *dev, } else if(bQueryPhy) { - /* - OFDM FA - RegCF0[15:0] - RegCF2[31:16] - RegDA0[31:16] - RegDA4[15:0] - RegDA4[31:16] - RegDA8[15:0] - CCK FA - (RegA5B<<8) | RegA5C - */ - cckok = read_bbreg(padapter, 0xf88, 0xffffffff ); - cckcrc = read_bbreg(padapter, 0xf84, 0xffffffff ); - ofdmok = read_bbreg(padapter, 0xf94, 0x0000FFFF ); - ofdmcrc = read_bbreg(padapter, 0xf94 , 0xFFFF0000 ); - htok = read_bbreg(padapter, 0xf90, 0x0000FFFF ); - htcrc = read_bbreg(padapter,0xf90, 0xFFFF0000 ); - - OFDM_FA=+read_bbreg(padapter, 0xcf0, 0x0000FFFF ); - OFDM_FA=+read_bbreg(padapter, 0xcf2, 0xFFFF0000 ); - OFDM_FA=+read_bbreg(padapter, 0xda0, 0xFFFF0000 ); - OFDM_FA=+read_bbreg(padapter, 0xda4, 0x0000FFFF ); - OFDM_FA=+read_bbreg(padapter, 0xda4, 0xFFFF0000 ); - OFDM_FA=+read_bbreg(padapter, 0xda8, 0x0000FFFF ); + + //if (IS_HARDWARE_TYPE_JAGUAR(padapter)) + #ifdef CONFIG_RTL8188A + { + cckok = PHY_QueryBBReg(padapter, 0xF04, 0x3FFF); // [13:0] + ofdmok = PHY_QueryBBReg(padapter, 0xF14, 0x3FFF); // [13:0] + htok = PHY_QueryBBReg(padapter, 0xF10, 0x3FFF); // [13:0] + vht_ok = PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF); // [13:0] + + cckcrc = PHY_QueryBBReg(padapter, 0xF04, 0x3FFF0000); // [29:16] + ofdmcrc = PHY_QueryBBReg(padapter, 0xF14, 0x3FFF0000); // [29:16] + htcrc = PHY_QueryBBReg(padapter, 0xF10, 0x3FFF0000); // [29:16] + vht_err = PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF0000); // [29:16] + } + #else + { + cckok = PHY_QueryBBReg(padapter, 0xF88, bMaskDWord); + ofdmok = PHY_QueryBBReg(padapter, 0xF94, bMaskLWord); + htok = PHY_QueryBBReg(padapter, 0xF90, bMaskLWord); + vht_ok = 0; + + cckcrc = PHY_QueryBBReg(padapter, 0xF84, bMaskDWord); + ofdmcrc = PHY_QueryBBReg(padapter, 0xF94, bMaskHWord); + htcrc = PHY_QueryBBReg(padapter, 0xF90, bMaskHWord); + vht_err = 0; + } + #endif CCK_FA=(rtw_read8(padapter, 0xa5b )<<8 ) | (rtw_read8(padapter, 0xa5c)); - - sprintf( extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d",cckok+ofdmok+htok,cckcrc+ofdmcrc+htcrc,OFDM_FA+CCK_FA); + sprintf( extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d",cckok+ofdmok+htok+vht_ok,cckcrc+ofdmcrc+htcrc+vht_err,OFDM_FA+CCK_FA); } else if(bQueryMac) { - //OFDM - rtw_write32(padapter, 0x664, (rtw_read32(padapter, 0x0664)& 0x0FFFFFFF)| Mac_OFDM_OK); - ofdmok = rtw_read32(padapter, 0x664)& 0x0000FFFF; //[15:0] R/W 0 BIT_RPT_COUNTER - rtw_write32(padapter, 0x664, (rtw_read32(padapter, 0x0664)& 0x0FFFFFFF)| Mac_OFDM_Fail); - ofdmcrc = rtw_read32(padapter, 0x664)& 0x0000FFFF; - rtw_write32(padapter, 0x664, (rtw_read32(padapter, 0x0664)& 0x0FFFFFFF)| Mac_OFDM_FasleAlarm); - OFDM_FA = rtw_read32(padapter, 0x664)& 0x0000FFFF; - //CCK - rtw_write32(padapter, 0x664, (rtw_read32(padapter, 0x0664)& 0x0FFFFFFF)|Mac_CCK_OK); - cckok = rtw_read32(padapter, 0x664)& 0x0000FFFF; - rtw_write32(padapter, 0x664, (rtw_read32(padapter, 0x0664)& 0x0FFFFFFF)| Mac_CCK_Fail); - cckcrc = rtw_read32(padapter, 0x664)& 0x0000FFFF; - rtw_write32(padapter, 0x664, (rtw_read32(padapter, 0x0664)& 0x0FFFFFFF)| Mac_CCK_FasleAlarm); - CCK_FA = rtw_read32(padapter, 0x664)& 0x0000FFFF; - //HT - rtw_write32(padapter, 0x664, (rtw_read32(padapter, 0x0664)& 0x0FFFFFFF)| Mac_HT_OK); - htok = rtw_read32(padapter, 0x664)& 0x0000FFFF; - rtw_write32(padapter, 0x664, (rtw_read32(padapter, 0x0664)& 0x0FFFFFFF)| Mac_HT_Fail); - htcrc = rtw_read32(padapter, 0x664)& 0x0000FFFF; - rtw_write32(padapter, 0x664, (rtw_read32(padapter, 0x0664)& 0x0FFFFFFF)|Mac_HT_FasleAlarm); - OFDM_FA += rtw_read32(padapter, 0x664)& 0x0000FFFF; - //Mac_DropPacket + + // for 8723A + { + PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x3); + mac_cck_ok = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0] + PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x0); + mac_ofdm_ok = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0] + PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x6); + mac_ht_ok = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0] + mac_vht_ok = 0; + + PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x4); + mac_cck_err = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0] + PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x1); + mac_ofdm_err = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0] + PHY_SetMacReg(padapter, 0x664, BIT28|BIT29|BIT30|BIT31, 0x7); + mac_ht_err = PHY_QueryMacReg(padapter, 0x664, bMaskLWord); // [15:0] + mac_vht_err = 0; + //Mac_DropPacket rtw_write32(padapter, 0x664, (rtw_read32(padapter, 0x0664)& 0x0FFFFFFF)| Mac_DropPacket); DropPacket = rtw_read32(padapter, 0x664)& 0x0000FFFF; - - sprintf( extra, "Mac Received packet OK: %d , CRC error: %d , FA Counter: %d , Drop Packets: %d\n",cckok+ofdmok+htok,cckcrc+ofdmcrc+htcrc,OFDM_FA+CCK_FA,DropPacket); + } + + sprintf( extra, "Mac Received packet OK: %d , CRC error: %d , FA Counter: %d , Drop Packets: %d\n", + mac_cck_ok+mac_ofdm_ok+mac_ht_ok+mac_vht_ok,mac_cck_err+mac_ofdm_err+mac_ht_err+mac_vht_err,OFDM_FA+CCK_FA,DropPacket); } wrqu->length = strlen(extra) + 1; return 0; @@ -10913,7 +11312,9 @@ static int rtw_mp_reset_stats(struct net_device *dev, write_bbreg(padapter,0xf14,BIT16,0x1); rtw_msleep_os(10); write_bbreg(padapter,0xf14,BIT16,0x0); - + //reset mac counter + PHY_SetMacReg(padapter, 0x664, BIT27, 0x1); + PHY_SetMacReg(padapter, 0x664, BIT27, 0x0); return 0; } @@ -10921,39 +11322,40 @@ static int rtw_mp_dump(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrqu, char *extra) { - struct mp_priv *pmp_priv; - struct pkt_attrib *pattrib; - u32 value; + u32 value,i,j=1,path; + u8 input[wrqu->length]; u8 rf_type,path_nums = 0; - u32 i,j=1,path; PADAPTER padapter = rtw_netdev_priv(dev); - + struct mp_priv *pmp_priv; + struct pkt_attrib *pattrib; + pmp_priv = &padapter->mppriv; - - //if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) - // return -EFAULT; - - if ( strncmp(extra, "all", 4)==0 ) + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + if ( strncmp(input, "all", 4)==0 ) { - DBG_871X("\n======= MAC REG =======\n"); + printk("\n======= MAC REG =======\n"); for ( i=0x0;i<0x300;i+=4 ) { - if(j%4==1) DBG_871X("0x%02x",i); - DBG_871X(" 0x%08x ",rtw_read32(padapter,i)); - if((j++)%4 == 0) DBG_871X("\n"); + if(j%4==1) printk("0x%02x ",i); + printk(" 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) printk("\n"); } for( i=0x400;i<0x1000;i+=4 ) { if(j%4==1) DBG_871X("0x%02x",i); - DBG_871X(" 0x%08x ",rtw_read32(padapter,i)); - if((j++)%4 == 0) DBG_871X("\n"); + printk(" 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) printk("\n"); } i,j=1; rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); - - DBG_871X("\n======= RF REG =======\n"); + bb_reg_dump(padapter); + rf_reg_dump(padapter); + /* + printk("\n======= RF REG =======\n"); if(( RF_1T2R == rf_type ) ||( RF_1T1R ==rf_type )) path_nums = 1; else @@ -10969,11 +11371,11 @@ static int rtw_mp_dump(struct net_device *dev, { //value = PHY_QueryRFReg(padapter, (RF_RADIO_PATH_E)path,i, bMaskDWord); value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); - if(j%4==1) DBG_871X("0x%02x ",i); - DBG_871X(" 0x%08x ",value); - if((j++)%4==0) DBG_871X("\n"); + if(j%4==1) printk("0x%02x ",i); + printk(" 0x%08x ",value); + if((j++)%4==0) printk("\n"); } - } + }*/ } return 0; } @@ -11115,9 +11517,9 @@ static int rtw_mp_SetBT(struct net_device *dev, char *pch, *ptmp, *token, *tmp[2]={0x00,0x00}; u8 setdata[100]; u8 resetbt=0x00; - u16 dltime=0; + u8 H2cSetbtmac[6]; - u16 testmode=1,ready=1,trxparam=1,setgen=1,getgen=1,testctrl=1,testbt=1; + u16 testmode=1,ready=1,trxparam=1,setgen=1,getgen=1,testctrl=1,testbt=1,readtherm=1,setbtmac=1; u32 i,ii,jj,kk,cnts,status; PRT_FIRMWARE_8723A pBTFirmware = NULL; @@ -11133,26 +11535,28 @@ static int rtw_mp_SetBT(struct net_device *dev, getgen = strncmp(extra, "getgen", 6); testctrl = strncmp(extra, "testctrl", 8); testbt = strncmp(extra, "testbt", 6); + readtherm = strncmp(extra, "readtherm", 9); + setbtmac = strncmp(extra, "setbtmac", 8); if ( strncmp(extra, "dlfw", 4) == 0) { - - while(dltime<3) - { - //rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)| 0x00000002)); - //rtw_msleep_os(1000); - rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)| 0x00000002)); - rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)& 0xFFFFFFFB)); - rtw_msleep_os(500); - rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFE)); - rtw_msleep_os(500); - rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)| 0x00000004)); - rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)& 0xFFFFFFFD)); - rtw_msleep_os(1000); - #if 0 + padapter->registrypriv.mp_mode =0; + pHalFunc->hal_init(padapter); + padapter->registrypriv.mp_mode =1; + MPT_PwrCtlDM(padapter,0); + rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)| 0x00000004)); + rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)& 0xFFFFFFEF)); + rtw_msleep_os(600); + //rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFE)); + rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)| 0x00000010)); + rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)& 0xFFFFFFFB)); + rtw_msleep_os(1200); + + DBG_871X("padapter->bBTFWReady == _FALSE rtl8723a_FirmwareDownload !\n"); + status = rtl8723a_FirmwareDownload(padapter); + #if 0 FillH2CCmd(padapter, 0x32, 1, &resetbt); rtw_msleep_os(1000); - #endif if(padapter->bBTFWReady == _FALSE && padapter->registrypriv.mp_mode == 1) { @@ -11168,42 +11572,63 @@ static int rtw_mp_SetBT(struct net_device *dev, if (pBTFirmware) rtw_mfree((u8*)pBTFirmware, sizeof(RT_FIRMWARE_8723A)); } - - rtw_msleep_os(1200); + #endif + DBG_871X("Wait for FirmwareDownloadBT fw boot!\n"); + rtw_msleep_os(1000); _rtw_memset(extra,'\0', wrqu->data.length); BtReq.opCodeVer=1; BtReq.OpCode=0; BtReq.paraLength=0; mptbt_BtControlProcess(padapter,&BtReq); - + rtw_msleep_os(100); for (i=4; i<pMptCtx->mptOutLen; i++) { DBG_8192C("FirmwareDownloadBT ready = 0x%x ", pMptCtx->mptOutBuf[i]); if( (pMptCtx->mptOutBuf[i]==0x00) && (pMptCtx->mptOutBuf[i+1]==0x00)) { - sprintf(extra, "download FW Fail! retry = %d\n",dltime); - padapter->bBTFWReady = _FALSE; - + sprintf(extra, "download FW Fail.\n"); } else { - padapter->bBTFWReady = _TRUE; - sprintf(extra, "download FW OK. \n"); + sprintf(extra, "download FW OK.\n"); goto exit; } } - dltime++; - } - + goto exit; } if ( strncmp(extra, "down", 4) == 0){ DBG_871X("SetBT down for to hal_init !\n"); + mp_stop_test(padapter); pHalFunc->hal_init(padapter); + mp_start_test(padapter); + MPT_PwrCtlDM(padapter,0); + rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)| 0x00000004)); + rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)& 0xFFFFFFEF)); + rtw_msleep_os(600); + //rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFE)); + rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b)| 0x00000010)); + rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc)& 0xFFFFFFFB)); + rtw_msleep_os(1200); + goto exit; + } + if ( strncmp(extra, "disable", 4) == 0){ + DBG_871X("SetBT enable !\n"); + rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFB)); + rtw_msleep_os(500); + goto exit; + } + if ( strncmp(extra, "enable", 4) == 0){ + DBG_871X("SetBT disable !\n"); + rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)| 0x00000004)); + rtw_msleep_os(500); goto exit; } + if( ready!=0 && testmode!=0 && trxparam!=0 && setgen!=0 && getgen!=0 && testctrl!=0 && testbt!=0 && readtherm!=0 &&setbtmac!=0) + return -EFAULT; + if( testbt==0 ) { BtReq.opCodeVer=1; @@ -11247,6 +11672,25 @@ static int rtw_mp_SetBT(struct net_device *dev, DBG_871X("BtReq.pParamStart[%d]=%x \n",ii,BtReq.pParamStart[jj]); } } + if( setbtmac==0 ) { + H2cSetbtmac[0]=54; + H2cSetbtmac[1]=00; + H2cSetbtmac[2]=BtReq.pParamStart[0]; + H2cSetbtmac[3]=BtReq.pParamStart[1]; + H2cSetbtmac[4]=BtReq.pParamStart[2]; + H2cSetbtmac[5]=BtReq.pParamStart[3]; + FillH2CCmd(padapter, 70, 6, H2cSetbtmac); + sprintf(extra, "%s\n",H2cSetbtmac); + rtw_msleep_os(200); + H2cSetbtmac[0]=54; + H2cSetbtmac[1]=01; + H2cSetbtmac[2]=BtReq.pParamStart[4]; + H2cSetbtmac[3]=BtReq.pParamStart[5]; + FillH2CCmd(padapter, 70, 4, H2cSetbtmac); + + sprintf(extra, "setbtmac H2C part1=%s ,part2=%s \n",extra,H2cSetbtmac); + goto exit; + } if( testmode==0 ) { @@ -11274,6 +11718,14 @@ static int rtw_mp_SetBT(struct net_device *dev, BtReq.OpCode=4; //BT_GET_GENERAL 4 BtReq.paraLength=cnts/2; } + if( readtherm==0 ) + { + DBG_871X("%s: BT_GET_GENERAL \n", __func__); + BtReq.opCodeVer=1; + BtReq.OpCode=4; //BT_GET_GENERAL 4 + BtReq.paraLength=cnts/2; + } + if( testctrl==0 ) { DBG_871X("%s: BT_TEST_CTRL \n", __func__); @@ -11299,12 +11751,23 @@ todo: _rtw_memset(extra,'\0', wrqu->data.length); mptbt_BtControlProcess(padapter,&BtReq); - - for (i=4; i<pMptCtx->mptOutLen; i++) - { - DBG_8192C("0x%x ", pMptCtx->mptOutBuf[i]); - sprintf(extra, "%s 0x%x ", extra, pMptCtx->mptOutBuf[i]); - } + + if(readtherm==0){ + sprintf(extra,"BT thermal="); + for (i=4; i<pMptCtx->mptOutLen; i++) + { + if( (pMptCtx->mptOutBuf[i]==0x00) && (pMptCtx->mptOutBuf[i+1]==0x00)) + goto exit; + DBG_8192C("0x%x ", pMptCtx->mptOutBuf[i]); + sprintf(extra, "%s %d ", extra, pMptCtx->mptOutBuf[i]); + } + }else{ + for (i=4; i<pMptCtx->mptOutLen; i++) + { + DBG_8192C("0x%x ", pMptCtx->mptOutBuf[i]); + sprintf(extra, "%s 0x%x ", extra, pMptCtx->mptOutBuf[i]); + } + } exit: wrqu->data.length = strlen(extra) + 1; @@ -11368,7 +11831,13 @@ static int rtw_mp_set(struct net_device *dev, case MP_DISABLE_BT_COEXIST: DBG_871X("set case MP_DISABLE_BT_COEXIST \n"); rtw_mp_disable_bt_coexist(dev, info, wdata, extra); - break; + break; +#ifdef CONFIG_WOWLAN + case MP_WOW_ENABLE: + DBG_871X("set case MP_WOW_ENABLE: %s \n", extra); + rtw_wowlan_ctrl(dev, info, wdata, extra); + break; +#endif } @@ -12178,18 +12647,17 @@ static int rtw_widi_set_probe_request(struct net_device *dev, u8 *pbuf = NULL; _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); -#if 1 pbuf = rtw_malloc(sizeof(l2_msg_t)); if(pbuf) { - _rtw_memcpy(pbuf, wrqu->data.pointer, wrqu->data.length); + copy_from_user(pbuf, wrqu->data.pointer, wrqu->data.length); + //_rtw_memcpy(pbuf, wrqu->data.pointer, wrqu->data.length); + + if( wrqu->data.flags == 0 ) intel_widi_wk_cmd(padapter, INTEL_WIDI_ISSUE_PROB_WK, pbuf); + else if( wrqu->data.flags == 1 ) + rtw_set_wfd_rds_sink_info( padapter, (l2_msg_t *)pbuf ); } -#else - DBG_871X( "[%s] len = %d\n", __FUNCTION__,wrqu->data.length); - - issue_probereq_widi(padapter, wrqu->data.pointer); -#endif return ret; } #endif // CONFIG_INTEL_WIDI @@ -12253,7 +12721,7 @@ static s32 initpseudoadhoc(PADAPTER padapter) err = rtw_set_802_11_infrastructure_mode(padapter, networkType); if (err == _FALSE) return _FAIL; - err = rtw_setopmode_cmd(padapter, networkType); + err = rtw_setopmode_cmd(padapter, networkType,_TRUE); if (err == _FAIL) return _FAIL; return _SUCCESS; @@ -13100,18 +13568,13 @@ static const struct iw_priv_args rtw_private_args[] = { SIOCIWFIRSTPRIV + 0xD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr" }, -#if 0 - { - SIOCIWFIRSTPRIV + 0xE,0,0, "wowlan_ctrl" - }, -#endif { SIOCIWFIRSTPRIV + 0x10, - IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, 0, "p2p_set" + IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set" }, { SIOCIWFIRSTPRIV + 0x11, - IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN , "p2p_get" + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get" }, { SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL" @@ -13145,7 +13608,7 @@ static const struct iw_priv_args rtw_private_args[] = { #ifdef CONFIG_INTEL_WIDI { SIOCIWFIRSTPRIV + 0x1E, - IW_PRIV_TYPE_CHAR | 64, 0, "widi_set" + IW_PRIV_TYPE_CHAR | 1024, 0, "widi_set" }, { SIOCIWFIRSTPRIV + 0x1F, @@ -13193,6 +13656,9 @@ static const struct iw_priv_args rtw_private_args[] = { #endif { CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"}, #endif +#ifdef CONFIG_WOWLAN + { MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_enable" }, //set +#endif }; static iw_handler rtw_private_handler[] = @@ -13726,4 +14192,3 @@ int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return ret; } - |