diff options
Diffstat (limited to 'drivers/net/wireless/rtl8723as/core/rtw_p2p.c')
-rwxr-xr-x | drivers/net/wireless/rtl8723as/core/rtw_p2p.c | 911 |
1 files changed, 706 insertions, 205 deletions
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_p2p.c b/drivers/net/wireless/rtl8723as/core/rtw_p2p.c index 0ed4b5e31065..348bdb88357c 100755 --- a/drivers/net/wireless/rtl8723as/core/rtw_p2p.c +++ b/drivers/net/wireless/rtl8723as/core/rtw_p2p.c @@ -1888,7 +1888,18 @@ u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 }; u32 len=0, p2pielen = 0; #ifdef CONFIG_INTEL_WIDI + struct mlme_priv *pmlmepriv = &(pwdinfo->padapter->mlmepriv); u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 }; + u8 widi_version = 0, i = 0; + + if( _rtw_memcmp( pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN ) == _FALSE ) + { + widi_version = 35; + } + else if( pmlmepriv->num_p2p_sdt != 0 ) + { + widi_version = 40; + } #endif //CONFIG_INTEL_WIDI // P2P OUI @@ -1977,10 +1988,14 @@ u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len ); #ifdef CONFIG_INTEL_WIDI - if( _rtw_memcmp( pwdinfo->padapter->mlmepriv.sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN ) == _FALSE ) + if( widi_version == 35 ) { RTW_PUT_LE16(p2pie + p2pielen, 21 + 8 + pwdinfo->device_name_len); } + else if( widi_version == 40 ) + { + RTW_PUT_LE16(p2pie + p2pielen, 21 + 8 * pmlmepriv->num_p2p_sdt + pwdinfo->device_name_len); + } else #endif //CONFIG_INTEL_WIDI RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len); @@ -1997,25 +2012,48 @@ u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->supported_wps_cm); p2pielen += 2; - // Primary Device Type - // Category ID - //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA ); - RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA); - p2pielen += 2; +#ifdef CONFIG_INTEL_WIDI + if( widi_version == 40 ) + { + // Primary Device Type + // Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA ); + RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_pdt_cid ); + p2pielen += 2; - // OUI - //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI ); - RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); - p2pielen += 4; + // OUI + //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI ); + RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); + p2pielen += 4; - // Sub Category ID - //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER ); - RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER); - p2pielen += 2; + // Sub Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER ); + RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_pdt_scid); + p2pielen += 2; + } + else +#endif //CONFIG_INTEL_WIDI + { + // Primary Device Type + // Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA); + p2pielen += 2; + + // OUI + //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI ); + RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); + p2pielen += 4; + + // Sub Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER); + p2pielen += 2; + } // Number of Secondary Device Types #ifdef CONFIG_INTEL_WIDI - if( _rtw_memcmp( pwdinfo->padapter->mlmepriv.sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN ) == _FALSE ) + if( widi_version == 35 ) { p2pie[ p2pielen++ ] = 0x01; @@ -2028,6 +2066,21 @@ u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) RTW_PUT_BE16(p2pie + p2pielen, P2P_SCID_WIDI_CONSUMER_SINK); p2pielen += 2; } + else if( widi_version == 40 ) + { + p2pie[ p2pielen++ ] = pmlmepriv->num_p2p_sdt; + for( ; i < pmlmepriv->num_p2p_sdt; i++ ) + { + RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_sdt_cid[i]); + p2pielen += 2; + + RTW_PUT_BE32(p2pie + p2pielen, INTEL_DEV_TYPE_OUI); + p2pielen += 4; + + RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_sdt_scid[i]); + p2pielen += 2; + } + } else #endif //CONFIG_INTEL_WIDI p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List @@ -2732,11 +2785,11 @@ u8 process_p2p_group_negotation_req( struct wifidirect_info *pwdinfo, u8 *pframe { u8 attr_content = 0x00; u32 attr_contentlen = 0; - u8 ch_content[50] = { 0x00 }; + u8 ch_content[100] = { 0x00 }; uint ch_cnt = 0; - u8 peer_ch_list[50] = { 0x00 }; + u8 peer_ch_list[100] = { 0x00 }; u8 peer_ch_num = 0; - u8 ch_list_inclusioned[50] = { 0x00 }; + u8 ch_list_inclusioned[100] = { 0x00 }; u8 ch_num_inclusioned = 0; u16 cap_attr; @@ -2934,12 +2987,12 @@ u8 process_p2p_group_negotation_resp( struct wifidirect_info *pwdinfo, u8 *pfram u32 attr_contentlen = 0; u8 operatingch_info[5] = { 0x00 }; uint ch_cnt = 0; - u8 ch_content[50] = { 0x00 }; + u8 ch_content[100] = { 0x00 }; u8 groupid[ 38 ]; u16 cap_attr; - u8 peer_ch_list[50] = { 0x00 }; + u8 peer_ch_list[100] = { 0x00 }; u8 peer_ch_num = 0; - u8 ch_list_inclusioned[50] = { 0x00 }; + u8 ch_list_inclusioned[100] = { 0x00 }; u8 ch_num_inclusioned = 0; while ( p2p_ie ) // Found the P2P IE. @@ -3392,98 +3445,100 @@ _func_enter_; struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; pwdinfo->operating_channel = pbuddy_mlmeext->cur_channel; -#ifdef CONFIG_IOCTL_CFG80211 - DBG_871X("%s, switch ch back to buddy's cur_channel=%d\n", __func__, pbuddy_mlmeext->cur_channel); + if( pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + DBG_871X("%s, switch ch back to buddy's cur_channel=%d\n", __func__, pbuddy_mlmeext->cur_channel); - set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); - issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500); - -#else //CONFIG_IOCTL_CFG80211 - if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) + issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500); + } + else if( pwdinfo->driver_interface == DRIVER_WEXT ) { - // Now, the driver stays on the AP's channel. - // If the pwdinfo->ext_listen_period = 0, that means the P2P listen state is not available on listen channel. - if ( pwdinfo->ext_listen_period > 0 ) + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) + { + // Now, the driver stays on the AP's channel. + // If the pwdinfo->ext_listen_period = 0, that means the P2P listen state is not available on listen channel. + if ( pwdinfo->ext_listen_period > 0 ) + { + DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_period = %d\n", __FUNCTION__, pwdinfo->ext_listen_period ); + + if ( pbuddy_mlmeext->cur_channel != pwdinfo->listen_channel ) + { + // Will switch to listen channel so that need to send the NULL data with PW bit to AP. + issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500); + set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + } + + rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); + val8 = 1; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + + // Todo: To check the value of pwdinfo->ext_listen_period is equal to 0 or not. + _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period ); + } + } + else if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) || + rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL) || + ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _FALSE ) || + rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ) ) { - DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_period = %d\n", __FUNCTION__, pwdinfo->ext_listen_period ); + // Now, the driver is in the listen state of P2P mode. + DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_interval = %d\n", __FUNCTION__, pwdinfo->ext_listen_interval ); + // Commented by Albert 2012/11/01 + // If the AP's channel is the same as the listen channel, we should still be in the listen state + // Other P2P device is still able to find this device out even this device is in the AP's channel. + // So, configure this device to be able to receive the probe request frame and set it to listen state. if ( pbuddy_mlmeext->cur_channel != pwdinfo->listen_channel ) { - // Will switch to listen channel so that need to send the NULL data with PW bit to AP. - issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500); - set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + val8 = 0; + padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE); + issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500); } - rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); - val8 = 1; - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - - // Todo: To check the value of pwdinfo->ext_listen_period is equal to 0 or not. - _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period ); + // Todo: To check the value of pwdinfo->ext_listen_interval is equal to 0 or not. + _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval ); } - } - else if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) || - rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL) || - ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _FALSE ) || - rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ) ) - { - // Now, the driver is in the listen state of P2P mode. - DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_interval = %d\n", __FUNCTION__, pwdinfo->ext_listen_interval ); - - // Commented by Albert 2012/11/01 - // If the AP's channel is the same as the listen channel, we should still be in the listen state - // Other P2P device is still able to find this device out even this device is in the AP's channel. - // So, configure this device to be able to receive the probe request frame and set it to listen state. - if ( pbuddy_mlmeext->cur_channel != pwdinfo->listen_channel ) + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK)) { - set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + // The driver had finished the P2P handshake successfully. val8 = 0; - padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500); } - - // Todo: To check the value of pwdinfo->ext_listen_interval is equal to 0 or not. - _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval ); - } - else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK)) - { - // The driver had finished the P2P handshake successfully. - val8 = 0; - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); - issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500); - } - else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) - { - val8 = 1; - set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - issue_probereq_p2p(padapter, NULL); - _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); - } - else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _TRUE) - { - val8 = 1; - set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - issue_probereq_p2p(padapter, NULL); - _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); - } - else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) && pwdinfo->invitereq_info.benable == _TRUE) - { - /* - val8 = 1; - set_channel_bwmode(padapter, , HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - issue_probereq_p2p(padapter, NULL); - _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); - */ + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) + { + val8 = 1; + set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + } + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _TRUE) + { + val8 = 1; + set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + } + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) && pwdinfo->invitereq_info.benable == _TRUE) + { + /* + val8 = 1; + set_channel_bwmode(padapter, , HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + */ + } } -#endif //CONFIG_IOCTL_CFG80211 - } + } else { set_channel_bwmode( padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); @@ -3498,39 +3553,38 @@ static void ro_ch_handler(_adapter *padapter) { struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; struct wifidirect_info *pwdinfo = &padapter->wdinfo; - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + u8 ch, bw, offset; _func_enter_; - { - -#ifdef CONFIG_CONCURRENT_MODE - if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) - { - PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; - struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; - - DBG_871X("%s, switch ch back to buddy's cur_channel=%d\n", __func__, pbuddy_mlmeext->cur_channel); - - set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + if (rtw_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { + if (0) + DBG_871X(FUNC_ADPT_FMT" back to linked union - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + } + else if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->listen_channel) { + ch = pwdinfo->listen_channel; + bw = HT_CHANNEL_WIDTH_20; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + if (0) + DBG_871X(FUNC_ADPT_FMT" back to listen ch - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + } + else { + ch = pcfg80211_wdinfo->restore_channel; + bw = HT_CHANNEL_WIDTH_20; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + if (0) + DBG_871X(FUNC_ADPT_FMT" back to restore ch - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + } - pmlmeext->cur_channel = pbuddy_mlmeext->cur_channel; - - }else -#endif //CONFIG_CONCURRENT_MODE - if( pcfg80211_wdinfo->restore_channel != pmlmeext->cur_channel ) - { - if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) ) - pmlmeext->cur_channel = pcfg80211_wdinfo->restore_channel; + set_channel_bwmode(padapter, ch, offset, bw); - set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); - } - - rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); -#ifdef CONFIG_DEBUG_CFG80211 - DBG_871X("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo)); + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); +#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo)); #endif - } pcfg80211_wdinfo->is_ro_ch = _FALSE; @@ -3558,6 +3612,162 @@ static void ro_ch_timer_process (void *FunctionContext) p2p_protocol_wk_cmd( adapter, P2P_RO_CH_WK); } +static void rtw_change_p2pie_op_ch(_adapter *padapter, const u8 *frame_body, u32 len, u8 ch) +{ + u8 *ies, *p2p_ie; + u32 ies_len, p2p_ielen; + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_); + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + while ( p2p_ie ) { + u32 attr_contentlen = 0; + u8 *pattr = NULL; + + //Check P2P_ATTR_OPERATING_CH + attr_contentlen = 0; + pattr = NULL; + if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL) + { + *(pattr+4) = ch; + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + } +} + +static void rtw_change_p2pie_ch_list(_adapter *padapter, const u8 *frame_body, u32 len, u8 ch) +{ + u8 *ies, *p2p_ie; + u32 ies_len, p2p_ielen; + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_); + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + while (p2p_ie) { + u32 attr_contentlen = 0; + u8 *pattr = NULL; + + //Check P2P_ATTR_CH_LIST + if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL) { + int i; + u32 num_of_ch; + u8 *pattr_temp = pattr + 3 ; + + attr_contentlen -= 3; + + while (attr_contentlen>0) { + num_of_ch = *(pattr_temp+1); + + for(i=0; i<num_of_ch; i++) + *(pattr_temp+2+i) = ch; + + pattr_temp += (2+num_of_ch); + attr_contentlen -= (2+num_of_ch); + } + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + } +} + +static bool rtw_chk_p2pie_ch_list_with_buddy(_adapter *padapter, const u8 *frame_body, u32 len) +{ + bool fit = _FALSE; +#ifdef CONFIG_CONCURRENT_MODE + u8 *ies, *p2p_ie; + u32 ies_len, p2p_ielen; + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + u8 buddy_ch = pbuddy_mlmeext->cur_channel; + + ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_); + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + while (p2p_ie) { + u32 attr_contentlen = 0; + u8 *pattr = NULL; + + //Check P2P_ATTR_CH_LIST + if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL) { + int i; + u32 num_of_ch; + u8 *pattr_temp = pattr + 3 ; + + attr_contentlen -= 3; + + while (attr_contentlen>0) { + num_of_ch = *(pattr_temp+1); + + for(i=0; i<num_of_ch; i++) { + if (*(pattr_temp+2+i) == buddy_ch) { + DBG_871X(FUNC_ADPT_FMT" ch_list fit buddy_ch:%u\n", FUNC_ADPT_ARG(padapter), buddy_ch); + fit = _TRUE; + break; + } + } + + pattr_temp += (2+num_of_ch); + attr_contentlen -= (2+num_of_ch); + } + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + } +#endif + return fit; +} + +static bool rtw_chk_p2pie_op_ch_with_buddy(_adapter *padapter, const u8 *frame_body, u32 len) +{ + bool fit = _FALSE; +#ifdef CONFIG_CONCURRENT_MODE + u8 *ies, *p2p_ie; + u32 ies_len, p2p_ielen; + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + u8 buddy_ch = pbuddy_mlmeext->cur_channel; + + ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_); + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + while (p2p_ie) { + u32 attr_contentlen = 0; + u8 *pattr = NULL; + + //Check P2P_ATTR_OPERATING_CH + attr_contentlen = 0; + pattr = NULL; + if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL) { + if (*(pattr+4) == buddy_ch) { + DBG_871X(FUNC_ADPT_FMT" op_ch fit buddy_ch:%u\n", FUNC_ADPT_ARG(padapter), buddy_ch); + fit = _TRUE; + break; + } + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + } +#endif + return fit; +} + static void rtw_cfg80211_adjust_p2pie_channel(_adapter *padapter, const u8 *frame_body, u32 len) { #ifdef CONFIG_CONCURRENT_MODE @@ -3730,6 +3940,69 @@ void rtw_append_wfd_ie(_adapter *padapter, u8 *buf, u32* len) } #endif +u8 *dump_p2p_attr_ch_list(u8 *p2p_ie, uint p2p_ielen, u8 *buf, u32 buf_len) +{ + uint attr_contentlen = 0; + u8 *pattr = NULL; + int w_sz = 0; + u8 ch_cnt = 0; + u8 ch_list[40]; + bool continuous = _FALSE; + + if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, &attr_contentlen))!=NULL) { + int i, j; + u32 num_of_ch; + u8 *pattr_temp = pattr + 3 ; + + attr_contentlen -= 3; + + _rtw_memset(ch_list, 0, 40); + + while (attr_contentlen>0) { + num_of_ch = *(pattr_temp+1); + + for(i=0; i<num_of_ch; i++) { + for (j=0;j<ch_cnt;j++) { + if (ch_list[j] == *(pattr_temp+2+i)) + break; + } + if (j>=ch_cnt) + ch_list[ch_cnt++] = *(pattr_temp+2+i); + + } + + pattr_temp += (2+num_of_ch); + attr_contentlen -= (2+num_of_ch); + } + + for (j=0;j<ch_cnt;j++) { + if (j == 0) { + w_sz += snprintf(buf+w_sz, buf_len-w_sz, "%u", ch_list[j]); + } else if (ch_list[j] - ch_list[j-1] != 1) { + w_sz += snprintf(buf+w_sz, buf_len-w_sz, ", %u", ch_list[j]); + } else if (j != ch_cnt-1 && ch_list[j+1] - ch_list[j] == 1) { + /* empty */ + } else { + w_sz += snprintf(buf+w_sz, buf_len-w_sz, "-%u", ch_list[j]); + } + } + } + return buf; +} + +/* + * return _TRUE if requester is GO, _FALSE if responder is GO + */ +bool rtw_p2p_nego_intent_compare(u8 req, u8 resp) +{ + if (req>>1 == resp >>1) + return req&0x01 ? _TRUE : _FALSE; + else if (req>>1 > resp>>1) + return _TRUE; + else + return _FALSE; +} + int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx) { int is_p2p_frame = (-1); @@ -3738,6 +4011,11 @@ int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx) u8 *p2p_ie = NULL; uint p2p_ielen = 0; struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); + int status = -1; + u8 ch_list_buf[128] = {'\0'}; + int op_ch = -1; + int listen_ch = -1; + u8 intent = 0; frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr)); category = frame_body[0]; @@ -3767,60 +4045,152 @@ int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx) u8 *cont; uint cont_len; case P2P_GO_NEGO_REQ: - DBG_871X("RTW_%s:P2P_GO_NEGO_REQ, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken); - - if(tx) - { -#ifdef CONFIG_DRV_ISSUE_PROV_REQ // IOT FOR S2 + { + struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info; + + if (tx) { + #ifdef CONFIG_DRV_ISSUE_PROV_REQ // IOT FOR S2 if(pwdev_priv->provdisc_req_issued == _FALSE) rtw_cfg80211_issue_p2p_provision_request(padapter, buf, len); -#endif //CONFIG_DRV_ISSUE_PROV_REQ + #endif //CONFIG_DRV_ISSUE_PROV_REQ //pwdev_priv->provdisc_req_issued = _FALSE; - -#ifdef CONFIG_CONCURRENT_MODE + + #ifdef CONFIG_CONCURRENT_MODE if(check_buddy_fwstate(padapter, _FW_LINKED)) rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)); -#endif + #endif } - + + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len))) + op_ch = *(cont+4); + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, NULL, &cont_len))) + listen_ch = *(cont+4); + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, NULL, &cont_len))) + intent = *cont; + + if (nego_info->token != dialogToken) + rtw_wdev_nego_info_init(nego_info); + + _rtw_memcpy(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN); + nego_info->active = tx ? 1 : 0; + nego_info->token = dialogToken; + nego_info->req_op_ch = op_ch; + nego_info->req_listen_ch = listen_ch; + nego_info->req_intent = intent; + nego_info->state = 0; + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_GO_NEGO_REQ, dialogToken=%d, intent:%u%s, listen_ch:%d, op_ch:%d, ch_list:%s\n", + (tx==_TRUE)?"Tx":"Rx", dialogToken, (intent>>1), intent&0x1 ? "+" : "-", listen_ch, op_ch, ch_list_buf); + + if (!tx) { + #ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, _FW_LINKED) + && rtw_chk_p2pie_ch_list_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE) + { + DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter)); + rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0); + } + #endif + } + break; + } case P2P_GO_NEGO_RESP: - cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len); - DBG_871X("RTW_%s:P2P_GO_NEGO_RESP, dialogToken=%d, status:%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken, cont?*cont:-1); + { + struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info; - if(!tx) - { - pwdev_priv->provdisc_req_issued = _FALSE; - } -#ifdef CONFIG_CONCURRENT_MODE - else - { + if (tx) { + #ifdef CONFIG_CONCURRENT_MODE if(check_buddy_fwstate(padapter, _FW_LINKED)) rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)); + #endif } -#endif - break; + + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len))) + op_ch = *(cont+4); + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, NULL, &cont_len))) + intent = *cont; + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len))) + status = *cont; + + if (nego_info->token == dialogToken && nego_info->state == 0 + && _rtw_memcmp(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE + ) { + nego_info->status = (status==-1) ? 0xff : status; + nego_info->rsp_op_ch= op_ch; + nego_info->rsp_intent = intent; + nego_info->state = 1; + if (status != 0) + nego_info->token = 0; /* init */ + } + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_GO_NEGO_RESP, dialogToken=%d, intent:%u%s, status:%d, op_ch:%d, ch_list:%s\n", + (tx==_TRUE)?"Tx":"Rx", dialogToken, (intent>>1), intent&0x1 ? "+" : "-", status, op_ch, ch_list_buf); + + if (!tx) { + pwdev_priv->provdisc_req_issued = _FALSE; + #ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, _FW_LINKED) + && rtw_chk_p2pie_ch_list_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE) + { + DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter)); + rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0); + } + #endif + } + + break; + } case P2P_GO_NEGO_CONF: - cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len); - DBG_871X("RTW_%s:P2P_GO_NEGO_CONF, dialogToken=%d, status:%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken, cont?*cont:-1); + { + struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info; + bool is_go = _FALSE; -#ifdef CONFIG_CONCURRENT_MODE - if(tx) - { + if (tx) { + #ifdef CONFIG_CONCURRENT_MODE if(check_buddy_fwstate(padapter, _FW_LINKED)) rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)); + #endif } -#endif - break; + + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len))) + op_ch = *(cont+4); + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len))) + status = *cont; + + if (nego_info->token == dialogToken && nego_info->state == 1 + && _rtw_memcmp(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE + ) { + nego_info->status = (status==-1) ? 0xff : status; + nego_info->conf_op_ch = (op_ch==-1) ? 0 : op_ch; + nego_info->state = 2; + + if (status == 0) { + if (rtw_p2p_nego_intent_compare(nego_info->req_intent, nego_info->rsp_intent) && tx) + is_go = _TRUE; + } + + nego_info->token = 0; /* init */ + } + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_GO_NEGO_CONF, dialogToken=%d, status:%d, op_ch:%d, ch_list:%s\n", + (tx==_TRUE)?"Tx":"Rx", dialogToken, status, op_ch, ch_list_buf); + + if (!tx) { + } + + break; + } case P2P_INVIT_REQ: { struct rtw_wdev_invit_info* invit_info = &pwdev_priv->invit_info; int flags = -1; - int op_ch = 0; - if(tx) - { + if (tx) { #ifdef CONFIG_CONCURRENT_MODE if(check_buddy_fwstate(padapter, _FW_LINKED)) rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)); @@ -3835,21 +4205,38 @@ int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx) if (invit_info->token != dialogToken) rtw_wdev_invit_info_init(invit_info); + _rtw_memcpy(invit_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN); + invit_info->active = tx ? 1 : 0; invit_info->token = dialogToken; invit_info->flags = (flags==-1) ? 0x0 : flags; invit_info->req_op_ch= op_ch; + invit_info->state = 0; + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_INVIT_REQ, dialogToken=%d, flags:0x%02x, op_ch:%d, ch_list:%s\n", + (tx==_TRUE)?"Tx":"Rx", dialogToken, flags, op_ch, ch_list_buf); + + if (!tx) { + #ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, _FW_LINKED)) { + if (op_ch != -1 && rtw_chk_p2pie_op_ch_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE) { + DBG_871X(FUNC_ADPT_FMT" op_ch:%u has no intersect with buddy\n", FUNC_ADPT_ARG(padapter), op_ch); + rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0); + } else if (rtw_chk_p2pie_ch_list_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE) { + DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter)); + rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0); + } + } + #endif + } - DBG_871X("RTW_%s:P2P_INVIT_REQ, dialogToken=%d, flags:0x%02x, op_ch:%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken, flags, op_ch); break; } case P2P_INVIT_RESP: { struct rtw_wdev_invit_info* invit_info = &pwdev_priv->invit_info; - int status = -1; - int op_ch = 0; - if(tx) - { + if (tx) { #ifdef CONFIG_CONCURRENT_MODE if(check_buddy_fwstate(padapter, _FW_LINKED)) rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)); @@ -3857,19 +4244,35 @@ int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx) } if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len))) + { +#ifdef CONFIG_P2P_INVITE_IOT + if(tx && *cont==7) + { + DBG_871X("TX_P2P_INVITE_RESP, status is no common channel, change to unknown group\n"); + *cont = 8; //unknow group status + } +#endif //CONFIG_P2P_INVITE_IOT status = *cont; + } if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len))) op_ch = *(cont+4); - if (invit_info->token != dialogToken) { - rtw_wdev_invit_info_init(invit_info); - } else { - invit_info->token = 0; + if (invit_info->token == dialogToken && invit_info->state == 0 + && _rtw_memcmp(invit_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE + ) { invit_info->status = (status==-1) ? 0xff : status; invit_info->rsp_op_ch= op_ch; + invit_info->state = 1; + invit_info->token = 0; /* init */ + } + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_INVIT_RESP, dialogToken=%d, status:%d, op_ch:%d, ch_list:%s\n", + (tx==_TRUE)?"Tx":"Rx", dialogToken, status, op_ch, ch_list_buf); + + if (!tx) { } - DBG_871X("RTW_%s:P2P_INVIT_RESP, dialogToken=%d, status:%d, op_ch:%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken, status, op_ch); break; } case P2P_DEVDISC_REQ: @@ -3954,10 +4357,9 @@ int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx) } } - else + else { DBG_871X("RTW_%s:action frame category=%d\n", (tx==_TRUE)?"TX":"RX", category); - //is_p2p_frame = (-1); } return is_p2p_frame; @@ -4138,7 +4540,7 @@ _func_enter_; { pwdinfo->p2p_ps_mode = P2P_PS_CTWINDOW; // driver should wait LPS for entering CTWindow - if(padapter->pwrctrlpriv.bFwCurrentInPSMode == _TRUE) + if(adapter_to_pwrctl(padapter)->bFwCurrentInPSMode == _TRUE) { p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1); } @@ -4175,7 +4577,7 @@ _func_exit_; void p2p_ps_wk_hdl(_adapter *padapter, u8 p2p_ps_state) { - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); struct wifidirect_info *pwdinfo= &(padapter->wdinfo); _func_enter_; @@ -4193,12 +4595,12 @@ _func_enter_; pwdinfo->opp_ps = 0; pwdinfo->noa_num = 0; pwdinfo->p2p_ps_mode = P2P_PS_NONE; - if(padapter->pwrctrlpriv.bFwCurrentInPSMode == _TRUE) + if(pwrpriv->bFwCurrentInPSMode == _TRUE) { if(pwrpriv->smart_ps == 0) { pwrpriv->smart_ps = 2; - rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(padapter->pwrctrlpriv.pwr_mode))); + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(pwrpriv->pwr_mode))); } } break; @@ -4212,7 +4614,7 @@ _func_enter_; { pwrpriv->smart_ps = 0; DBG_871X("%s(): Enter CTW, change SmartPS\n", __FUNCTION__); - rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(padapter->pwrctrlpriv.pwr_mode))); + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(pwrpriv->pwr_mode))); } } rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); @@ -4300,6 +4702,11 @@ static void reset_ch_sitesurvey_timer_process (void *FunctionContext) DBG_871X( "[%s] In\n", __FUNCTION__ ); // Reset the operation channel information pwdinfo->rx_invitereq_info.operation_ch[0] = 0; +#ifdef P2P_OP_CHECK_SOCIAL_CH + pwdinfo->rx_invitereq_info.operation_ch[1] = 0; + pwdinfo->rx_invitereq_info.operation_ch[2] = 0; + pwdinfo->rx_invitereq_info.operation_ch[3] = 0; +#endif //P2P_OP_CHECK_SOCIAL_CH pwdinfo->rx_invitereq_info.scan_op_ch_only = 0; } @@ -4314,6 +4721,11 @@ static void reset_ch_sitesurvey_timer_process2 (void *FunctionContext) DBG_871X( "[%s] In\n", __FUNCTION__ ); // Reset the operation channel information pwdinfo->p2p_info.operation_ch[0] = 0; +#ifdef P2P_OP_CHECK_SOCIAL_CH + pwdinfo->p2p_info.operation_ch[1] = 0; + pwdinfo->p2p_info.operation_ch[2] = 0; + pwdinfo->p2p_info.operation_ch[3] = 0; +#endif //P2P_OP_CHECK_SOCIAL_CH pwdinfo->p2p_info.scan_op_ch_only = 0; } @@ -4611,45 +5023,118 @@ void init_wifidirect_info( _adapter* padapter, enum P2P_ROLE role) pwdinfo->ext_listen_period = 1000; #endif //!CONFIG_IOCTL_CFG80211 #endif + +// Commented by Kurt 20130319 +// For WiDi purpose: Use CFG80211 interface but controled WFD/RDS frame by driver itself. +#ifdef CONFIG_IOCTL_CFG80211 + pwdinfo->driver_interface = DRIVER_CFG80211; +#else + pwdinfo->driver_interface = DRIVER_WEXT; +#endif //CONFIG_IOCTL_CFG80211 + pwdinfo->wfd_tdls_enable = 0; _rtw_memset( pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN ); _rtw_memset( pwdinfo->p2p_peer_device_addr, 0x00, ETH_ALEN ); pwdinfo->rx_invitereq_info.operation_ch[0] = 0; pwdinfo->rx_invitereq_info.operation_ch[1] = 0; // Used to indicate the scan end in site survey function +#ifdef P2P_OP_CHECK_SOCIAL_CH + pwdinfo->rx_invitereq_info.operation_ch[2] = 0; + pwdinfo->rx_invitereq_info.operation_ch[3] = 0; + pwdinfo->rx_invitereq_info.operation_ch[4] = 0; +#endif //P2P_OP_CHECK_SOCIAL_CH pwdinfo->rx_invitereq_info.scan_op_ch_only = 0; pwdinfo->p2p_info.operation_ch[0] = 0; pwdinfo->p2p_info.operation_ch[1] = 0; // Used to indicate the scan end in site survey function +#ifdef P2P_OP_CHECK_SOCIAL_CH + pwdinfo->p2p_info.operation_ch[2] = 0; + pwdinfo->p2p_info.operation_ch[3] = 0; + pwdinfo->p2p_info.operation_ch[4] = 0; +#endif //P2P_OP_CHECK_SOCIAL_CH pwdinfo->p2p_info.scan_op_ch_only = 0; } #ifdef CONFIG_DBG_P2P -char * p2p_role_str[] = { - "P2P_ROLE_DISABLE", - "P2P_ROLE_DEVICE", - "P2P_ROLE_CLIENT", - "P2P_ROLE_GO" -}; - -char * p2p_state_str[] = { - "P2P_STATE_NONE", - "P2P_STATE_IDLE", - "P2P_STATE_LISTEN", - "P2P_STATE_SCAN", - "P2P_STATE_FIND_PHASE_LISTEN", - "P2P_STATE_FIND_PHASE_SEARCH", - "P2P_STATE_TX_PROVISION_DIS_REQ", - "P2P_STATE_RX_PROVISION_DIS_RSP", - "P2P_STATE_RX_PROVISION_DIS_REQ", - "P2P_STATE_GONEGO_ING", - "P2P_STATE_GONEGO_OK", - "P2P_STATE_GONEGO_FAIL", - "P2P_STATE_RECV_INVITE_REQ_MATCH", - "P2P_STATE_PROVISIONING_ING", - "P2P_STATE_PROVISIONING_DONE", - "P2P_STATE_RECV_INVITE_REQ_DISMATCH", - "P2P_STATE_RECV_INVITE_REQ_GO" -}; + +/** + * rtw_p2p_role_txt - Get the p2p role name as a text string + * @role: P2P role + * Returns: The state name as a printable text string + */ +const char * rtw_p2p_role_txt(enum P2P_ROLE role) +{ + switch (role) { + case P2P_ROLE_DISABLE: + return "P2P_ROLE_DISABLE"; + case P2P_ROLE_DEVICE: + return "P2P_ROLE_DEVICE"; + case P2P_ROLE_CLIENT: + return "P2P_ROLE_CLIENT"; + case P2P_ROLE_GO: + return "P2P_ROLE_GO"; + default: + return "UNKNOWN"; + } +} + +/** + * rtw_p2p_state_txt - Get the p2p state name as a text string + * @state: P2P state + * Returns: The state name as a printable text string + */ +const char * rtw_p2p_state_txt(enum P2P_STATE state) +{ + switch (state) { + case P2P_STATE_NONE: + return "P2P_STATE_NONE"; + case P2P_STATE_IDLE: + return "P2P_STATE_IDLE"; + case P2P_STATE_LISTEN: + return "P2P_STATE_LISTEN"; + case P2P_STATE_SCAN: + return "P2P_STATE_SCAN"; + case P2P_STATE_FIND_PHASE_LISTEN: + return "P2P_STATE_FIND_PHASE_LISTEN"; + case P2P_STATE_FIND_PHASE_SEARCH: + return "P2P_STATE_FIND_PHASE_SEARCH"; + case P2P_STATE_TX_PROVISION_DIS_REQ: + return "P2P_STATE_TX_PROVISION_DIS_REQ"; + case P2P_STATE_RX_PROVISION_DIS_RSP: + return "P2P_STATE_RX_PROVISION_DIS_RSP"; + case P2P_STATE_RX_PROVISION_DIS_REQ: + return "P2P_STATE_RX_PROVISION_DIS_REQ"; + case P2P_STATE_GONEGO_ING: + return "P2P_STATE_GONEGO_ING"; + case P2P_STATE_GONEGO_OK: + return "P2P_STATE_GONEGO_OK"; + case P2P_STATE_GONEGO_FAIL: + return "P2P_STATE_GONEGO_FAIL"; + case P2P_STATE_RECV_INVITE_REQ_MATCH: + return "P2P_STATE_RECV_INVITE_REQ_MATCH"; + case P2P_STATE_PROVISIONING_ING: + return "P2P_STATE_PROVISIONING_ING"; + case P2P_STATE_PROVISIONING_DONE: + return "P2P_STATE_PROVISIONING_DONE"; + case P2P_STATE_TX_INVITE_REQ: + return "P2P_STATE_TX_INVITE_REQ"; + case P2P_STATE_RX_INVITE_RESP_OK: + return "P2P_STATE_RX_INVITE_RESP_OK"; + case P2P_STATE_RECV_INVITE_REQ_DISMATCH: + return "P2P_STATE_RECV_INVITE_REQ_DISMATCH"; + case P2P_STATE_RECV_INVITE_REQ_GO: + return "P2P_STATE_RECV_INVITE_REQ_GO"; + case P2P_STATE_RECV_INVITE_REQ_JOIN: + return "P2P_STATE_RECV_INVITE_REQ_JOIN"; + case P2P_STATE_RX_INVITE_RESP_FAIL: + return "P2P_STATE_RX_INVITE_RESP_FAIL"; + case P2P_STATE_RX_INFOR_NOREADY: + return "P2P_STATE_RX_INFOR_NOREADY"; + case P2P_STATE_TX_INFOR_NOREADY: + return "P2P_STATE_TX_INFOR_NOREADY"; + default: + return "UNKNOWN"; + } +} void dbg_rtw_p2p_set_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, const char *caller, int line) { @@ -4657,11 +5142,11 @@ void dbg_rtw_p2p_set_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, enum P2P_STATE old_state = _rtw_p2p_state(wdinfo); _rtw_p2p_set_state(wdinfo, state); DBG_871X("[CONFIG_DBG_P2P]%s:%d set_state from %s to %s\n", caller, line - , p2p_state_str[old_state], p2p_state_str[_rtw_p2p_state(wdinfo)] + , rtw_p2p_state_txt(old_state), rtw_p2p_state_txt(_rtw_p2p_state(wdinfo)) ); } else { DBG_871X("[CONFIG_DBG_P2P]%s:%d set_state to same state %s\n", caller, line - , p2p_state_str[_rtw_p2p_state(wdinfo)] + , rtw_p2p_state_txt(_rtw_p2p_state(wdinfo)) ); } } @@ -4671,11 +5156,11 @@ void dbg_rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo, enum P2P_STATE st enum P2P_STATE old_state = _rtw_p2p_pre_state(wdinfo); _rtw_p2p_set_pre_state(wdinfo, state); DBG_871X("[CONFIG_DBG_P2P]%s:%d set_pre_state from %s to %s\n", caller, line - , p2p_state_str[old_state], p2p_state_str[_rtw_p2p_pre_state(wdinfo)] + , rtw_p2p_state_txt(old_state), rtw_p2p_state_txt(_rtw_p2p_pre_state(wdinfo)) ); } else { DBG_871X("[CONFIG_DBG_P2P]%s:%d set_pre_state to same state %s\n", caller, line - , p2p_state_str[_rtw_p2p_pre_state(wdinfo)] + , rtw_p2p_state_txt(_rtw_p2p_pre_state(wdinfo)) ); } } @@ -4700,11 +5185,11 @@ void dbg_rtw_p2p_set_role(struct wifidirect_info *wdinfo, enum P2P_ROLE role, co enum P2P_ROLE old_role = wdinfo->role; _rtw_p2p_set_role(wdinfo, role); DBG_871X("[CONFIG_DBG_P2P]%s:%d set_role from %s to %s\n", caller, line - , p2p_role_str[old_role], p2p_role_str[wdinfo->role] + , rtw_p2p_role_txt(old_role), rtw_p2p_role_txt(wdinfo->role) ); } else { DBG_871X("[CONFIG_DBG_P2P]%s:%d set_role to same role %s\n", caller, line - , p2p_role_str[wdinfo->role] + , rtw_p2p_role_txt(wdinfo->role) ); } } @@ -4715,7 +5200,6 @@ int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role) { int ret = _SUCCESS; struct wifidirect_info *pwdinfo= &(padapter->wdinfo); - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT|| role == P2P_ROLE_GO) { @@ -4757,6 +5241,11 @@ int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role) } else if (role == P2P_ROLE_DISABLE) { +#ifdef CONFIG_INTEL_WIDI + if( padapter->mlmepriv.p2p_reject_disable == _TRUE ) + return ret; +#endif //CONFIG_INTEL_WIDI + if (_FAIL == rtw_pwr_wakeup(padapter)) { ret = _FAIL; goto exit; @@ -4787,6 +5276,18 @@ int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role) //Restore to initial setting. update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); + +#ifdef CONFIG_INTEL_WIDI + rtw_reset_widi_info(padapter); +#endif //CONFIG_INTEL_WIDI + + //For WiDi purpose. +#ifdef CONFIG_IOCTL_CFG80211 + pwdinfo->driver_interface = DRIVER_CFG80211; +#else + pwdinfo->driver_interface = DRIVER_WEXT; +#endif //CONFIG_IOCTL_CFG80211 + } exit: |