2013-05-08 21:45:39 +00:00
/******************************************************************************
*
* Copyright ( c ) 2007 - 2011 Realtek Corporation . All rights reserved .
2013-05-19 04:28:07 +00:00
*
2013-05-08 21:45:39 +00:00
* This program is free software ; you can redistribute it and / or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License along with
* this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 , USA
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define _RTW_MLME_C_
# include <osdep_service.h>
# include <drv_types.h>
# include <recv_osdep.h>
# include <xmit_osdep.h>
# include <hal_intf.h>
# include <mlme_osdep.h>
# include <sta_info.h>
# include <wifi.h>
# include <wlan_bssdef.h>
# include <rtw_ioctl_set.h>
2013-06-03 19:52:18 +00:00
# include <usb_osintf.h>
2013-05-08 21:45:39 +00:00
extern void indicate_wx_scan_complete_event ( _adapter * padapter ) ;
extern u8 rtw_do_join ( _adapter * padapter ) ;
extern unsigned char MCS_rate_2R [ 16 ] ;
extern unsigned char MCS_rate_1R [ 16 ] ;
sint _rtw_init_mlme_priv ( _adapter * padapter )
{
sint i ;
u8 * pbuf ;
struct wlan_network * pnetwork ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
sint res = _SUCCESS ;
_func_enter_ ;
2013-07-09 22:38:46 +00:00
/* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
2013-05-08 21:45:39 +00:00
pmlmepriv - > nic_hdl = ( u8 * ) padapter ;
pmlmepriv - > pscanned = NULL ;
pmlmepriv - > fw_state = 0 ;
pmlmepriv - > cur_network . network . InfrastructureMode = Ndis802_11AutoUnknown ;
2013-07-09 22:38:46 +00:00
pmlmepriv - > scan_mode = SCAN_ACTIVE ; /* 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) */
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
_rtw_spinlock_init ( & ( pmlmepriv - > lock ) ) ;
2013-05-08 21:45:39 +00:00
_rtw_init_queue ( & ( pmlmepriv - > free_bss_pool ) ) ;
_rtw_init_queue ( & ( pmlmepriv - > scanned_queue ) ) ;
set_scanned_network_val ( pmlmepriv , 0 ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_rtw_memset ( & pmlmepriv - > assoc_ssid , 0 , sizeof ( NDIS_802_11_SSID ) ) ;
pbuf = rtw_zvmalloc ( MAX_BSS_CNT * ( sizeof ( struct wlan_network ) ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
if ( pbuf = = NULL ) {
res = _FAIL ;
goto exit ;
}
pmlmepriv - > free_bss_buf = pbuf ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
pnetwork = ( struct wlan_network * ) pbuf ;
2013-05-19 04:28:07 +00:00
2013-05-09 04:04:25 +00:00
for ( i = 0 ; i < MAX_BSS_CNT ; i + + )
2013-05-19 04:28:07 +00:00
{
2013-05-08 21:45:39 +00:00
_rtw_init_listhead ( & ( pnetwork - > list ) ) ;
rtw_list_insert_tail ( & ( pnetwork - > list ) , & ( pmlmepriv - > free_bss_pool . queue ) ) ;
pnetwork + + ;
}
2013-07-09 22:38:46 +00:00
/* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
2013-05-08 21:45:39 +00:00
rtw_clear_scan_deny ( padapter ) ;
rtw_init_mlme_timer ( padapter ) ;
exit :
_func_exit_ ;
return res ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
void rtw_mfree_mlme_priv_lock ( struct mlme_priv * pmlmepriv )
{
_rtw_spinlock_free ( & pmlmepriv - > lock ) ;
_rtw_spinlock_free ( & ( pmlmepriv - > free_bss_pool . lock ) ) ;
_rtw_spinlock_free ( & ( pmlmepriv - > scanned_queue . lock ) ) ;
}
static void rtw_free_mlme_ie_data ( u8 * * ppie , u32 * plen )
{
2013-05-09 04:04:25 +00:00
if ( * ppie )
2013-05-19 04:28:07 +00:00
{
2013-05-08 21:45:39 +00:00
_rtw_mfree ( * ppie , * plen ) ;
* plen = 0 ;
* ppie = NULL ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
}
void rtw_free_mlme_priv_ie_data ( struct mlme_priv * pmlmepriv )
{
2013-07-20 16:01:46 +00:00
# if defined (CONFIG_AP_MODE)
2013-05-08 21:45:39 +00:00
rtw_buf_free ( & pmlmepriv - > assoc_req , & pmlmepriv - > assoc_req_len ) ;
rtw_buf_free ( & pmlmepriv - > assoc_rsp , & pmlmepriv - > assoc_rsp_len ) ;
rtw_free_mlme_ie_data ( & pmlmepriv - > wps_beacon_ie , & pmlmepriv - > wps_beacon_ie_len ) ;
rtw_free_mlme_ie_data ( & pmlmepriv - > wps_probe_req_ie , & pmlmepriv - > wps_probe_req_ie_len ) ;
rtw_free_mlme_ie_data ( & pmlmepriv - > wps_probe_resp_ie , & pmlmepriv - > wps_probe_resp_ie_len ) ;
rtw_free_mlme_ie_data ( & pmlmepriv - > wps_assoc_resp_ie , & pmlmepriv - > wps_assoc_resp_ie_len ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
rtw_free_mlme_ie_data ( & pmlmepriv - > p2p_beacon_ie , & pmlmepriv - > p2p_beacon_ie_len ) ;
rtw_free_mlme_ie_data ( & pmlmepriv - > p2p_probe_req_ie , & pmlmepriv - > p2p_probe_req_ie_len ) ;
rtw_free_mlme_ie_data ( & pmlmepriv - > p2p_probe_resp_ie , & pmlmepriv - > p2p_probe_resp_ie_len ) ;
rtw_free_mlme_ie_data ( & pmlmepriv - > p2p_go_probe_resp_ie , & pmlmepriv - > p2p_go_probe_resp_ie_len ) ;
rtw_free_mlme_ie_data ( & pmlmepriv - > p2p_assoc_req_ie , & pmlmepriv - > p2p_assoc_req_ie_len ) ;
# endif
}
void _rtw_free_mlme_priv ( struct mlme_priv * pmlmepriv )
{
_func_enter_ ;
rtw_free_mlme_priv_ie_data ( pmlmepriv ) ;
2013-05-09 04:04:25 +00:00
if ( pmlmepriv ) {
2013-05-08 21:45:39 +00:00
rtw_mfree_mlme_priv_lock ( pmlmepriv ) ;
if ( pmlmepriv - > free_bss_buf ) {
rtw_vmfree ( pmlmepriv - > free_bss_buf , MAX_BSS_CNT * sizeof ( struct wlan_network ) ) ;
}
}
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
sint _rtw_enqueue_network ( _queue * queue , struct wlan_network * pnetwork )
{
_irqL irqL ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
if ( pnetwork = = NULL )
goto exit ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_enter_critical_bh ( & queue - > lock , & irqL ) ;
rtw_list_insert_tail ( & pnetwork - > list , & queue - > queue ) ;
_exit_critical_bh ( & queue - > lock , & irqL ) ;
2013-05-19 04:28:07 +00:00
exit :
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
}
struct wlan_network * _rtw_dequeue_network ( _queue * queue )
{
_irqL irqL ;
struct wlan_network * pnetwork ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
_enter_critical_bh ( & queue - > lock , & irqL ) ;
2013-05-26 03:02:10 +00:00
if ( _rtw_queue_empty ( queue ) = = true )
2013-05-08 21:45:39 +00:00
pnetwork = NULL ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
else
{
pnetwork = LIST_CONTAINOR ( get_next ( & queue - > queue ) , struct wlan_network , list ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
rtw_list_delete ( & ( pnetwork - > list ) ) ;
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_exit_critical_bh ( & queue - > lock , & irqL ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
return pnetwork ;
}
2013-07-09 22:38:46 +00:00
struct wlan_network * _rtw_alloc_network ( struct mlme_priv * pmlmepriv ) /* _queue *free_queue) */
2013-05-08 21:45:39 +00:00
{
_irqL irqL ;
2013-05-19 04:28:07 +00:00
struct wlan_network * pnetwork ;
2013-05-08 21:45:39 +00:00
_queue * free_queue = & pmlmepriv - > free_bss_pool ;
_list * plist = NULL ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
_enter_critical_bh ( & free_queue - > lock , & irqL ) ;
2013-05-19 04:28:07 +00:00
2013-05-26 03:02:10 +00:00
if ( _rtw_queue_empty ( free_queue ) = = true ) {
2013-05-08 21:45:39 +00:00
pnetwork = NULL ;
goto exit ;
}
plist = get_next ( & ( free_queue - > queue ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
pnetwork = LIST_CONTAINOR ( plist , struct wlan_network , list ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
rtw_list_delete ( & pnetwork - > list ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_info_ , ( " _rtw_alloc_network: ptr=%p \n " , plist ) ) ;
pnetwork - > network_type = 0 ;
2013-05-26 03:02:10 +00:00
pnetwork - > fixed = false ;
2013-05-08 21:45:39 +00:00
pnetwork - > last_scanned = rtw_get_current_time ( ) ;
2013-05-19 04:28:07 +00:00
pnetwork - > aid = 0 ;
2013-05-08 21:45:39 +00:00
pnetwork - > join_res = 0 ;
pmlmepriv - > num_of_scanned + + ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
exit :
_exit_critical_bh ( & free_queue - > lock , & irqL ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
return pnetwork ;
2013-05-08 21:45:39 +00:00
}
void _rtw_free_network ( struct mlme_priv * pmlmepriv , struct wlan_network * pnetwork , u8 isfreeall )
{
u32 curr_time , delta_time ;
u32 lifetime = SCANQUEUE_LIFETIME ;
2013-05-19 04:28:07 +00:00
_irqL irqL ;
2013-05-08 21:45:39 +00:00
_queue * free_queue = & ( pmlmepriv - > free_bss_pool ) ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
if ( pnetwork = = NULL )
goto exit ;
2013-05-26 03:02:10 +00:00
if ( pnetwork - > fixed = = true )
2013-05-08 21:45:39 +00:00
goto exit ;
2013-05-19 04:28:07 +00:00
curr_time = rtw_get_current_time ( ) ;
2013-05-08 21:45:39 +00:00
2013-05-26 03:02:10 +00:00
if ( ( check_fwstate ( pmlmepriv , WIFI_ADHOC_MASTER_STATE ) = = true ) | |
( check_fwstate ( pmlmepriv , WIFI_ADHOC_STATE ) = = true ) )
2013-05-08 21:45:39 +00:00
lifetime = 1 ;
2013-07-11 05:30:22 +00:00
if ( ! isfreeall ) {
2013-05-19 04:28:07 +00:00
delta_time = ( curr_time - pnetwork - > last_scanned ) / HZ ;
2013-05-08 21:45:39 +00:00
2013-07-09 22:38:46 +00:00
if ( delta_time < lifetime ) /* unit:sec */
2013-05-08 21:45:39 +00:00
goto exit ;
}
_enter_critical_bh ( & free_queue - > lock , & irqL ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
rtw_list_delete ( & ( pnetwork - > list ) ) ;
rtw_list_insert_tail ( & ( pnetwork - > list ) , & ( free_queue - > queue ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
pmlmepriv - > num_of_scanned - - ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_exit_critical_bh ( & free_queue - > lock , & irqL ) ;
2013-05-19 04:28:07 +00:00
exit :
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
void _rtw_free_network_nolock ( struct mlme_priv * pmlmepriv , struct wlan_network * pnetwork )
{
_queue * free_queue = & ( pmlmepriv - > free_bss_pool ) ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
if ( pnetwork = = NULL )
goto exit ;
2013-05-26 03:02:10 +00:00
if ( pnetwork - > fixed = = true )
2013-05-08 21:45:39 +00:00
goto exit ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
rtw_list_delete ( & ( pnetwork - > list ) ) ;
rtw_list_insert_tail ( & ( pnetwork - > list ) , get_list_head ( free_queue ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
pmlmepriv - > num_of_scanned - - ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
exit :
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
/*
return the wlan_network with the matching addr
Shall be calle under atomic context . . . to avoid possible racing condition . . .
*/
struct wlan_network * _rtw_find_network ( _queue * scanned_queue , u8 * addr )
{
_list * phead , * plist ;
struct wlan_network * pnetwork = NULL ;
u8 zero_addr [ ETH_ALEN ] = { 0 , 0 , 0 , 0 , 0 , 0 } ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
2013-05-09 04:04:25 +00:00
if ( _rtw_memcmp ( zero_addr , addr , ETH_ALEN ) ) {
2013-05-08 21:45:39 +00:00
pnetwork = NULL ;
goto exit ;
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
phead = get_list_head ( scanned_queue ) ;
plist = get_next ( phead ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
while ( plist ! = phead )
{
pnetwork = LIST_CONTAINOR ( plist , struct wlan_network , list ) ;
2013-05-26 03:02:10 +00:00
if ( _rtw_memcmp ( addr , pnetwork - > network . MacAddress , ETH_ALEN ) = = true )
2013-05-08 21:45:39 +00:00
break ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
plist = get_next ( plist ) ;
}
2013-05-09 04:04:25 +00:00
if ( plist = = phead )
2013-05-08 21:45:39 +00:00
pnetwork = NULL ;
2013-05-19 04:28:07 +00:00
exit :
_func_exit_ ;
2013-05-08 21:45:39 +00:00
return pnetwork ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
void _rtw_free_network_queue ( _adapter * padapter , u8 isfreeall )
{
_irqL irqL ;
_list * phead , * plist ;
struct wlan_network * pnetwork ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
_queue * scanned_queue = & pmlmepriv - > scanned_queue ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
_enter_critical_bh ( & scanned_queue - > lock , & irqL ) ;
phead = get_list_head ( scanned_queue ) ;
plist = get_next ( phead ) ;
2013-05-26 03:02:10 +00:00
while ( rtw_end_of_queue_search ( phead , plist ) = = false )
2013-05-08 21:45:39 +00:00
{
pnetwork = LIST_CONTAINOR ( plist , struct wlan_network , list ) ;
plist = get_next ( plist ) ;
_rtw_free_network ( pmlmepriv , pnetwork , isfreeall ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
_exit_critical_bh ( & scanned_queue - > lock , & irqL ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
sint rtw_if_up ( _adapter * padapter ) {
sint res ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
2013-05-09 04:04:25 +00:00
if ( padapter - > bDriverStopped | | padapter - > bSurpriseRemoved | |
2013-05-26 03:02:10 +00:00
( check_fwstate ( & padapter - > mlmepriv , _FW_LINKED ) = = false ) ) {
2013-05-19 04:28:07 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_info_ , ( " rtw_if_up:bDriverStopped(%d) OR bSurpriseRemoved(%d) " , padapter - > bDriverStopped , padapter - > bSurpriseRemoved ) ) ;
2013-05-26 03:02:10 +00:00
res = false ;
2013-05-08 21:45:39 +00:00
}
else
2013-05-26 03:02:10 +00:00
res = true ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_func_exit_ ;
return res ;
}
void rtw_generate_random_ibss ( u8 * pibss )
{
u32 curtime = rtw_get_current_time ( ) ;
_func_enter_ ;
2013-07-09 22:38:46 +00:00
pibss [ 0 ] = 0x02 ; /* in ad-hoc mode bit1 must set to 1 */
2013-05-08 21:45:39 +00:00
pibss [ 1 ] = 0x11 ;
pibss [ 2 ] = 0x87 ;
2013-07-09 22:38:46 +00:00
pibss [ 3 ] = ( u8 ) ( curtime & 0xff ) ; /* p[0]; */
pibss [ 4 ] = ( u8 ) ( ( curtime > > 8 ) & 0xff ) ; /* p[1]; */
pibss [ 5 ] = ( u8 ) ( ( curtime > > 16 ) & 0xff ) ; /* p[2]; */
2013-05-08 21:45:39 +00:00
_func_exit_ ;
return ;
}
u8 * rtw_get_capability_from_ie ( u8 * ie )
{
return ( ie + 8 + 2 ) ;
}
u16 rtw_get_capability ( WLAN_BSSID_EX * bss )
{
2013-06-07 14:43:09 +00:00
__le16 val ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
_rtw_memcpy ( ( u8 * ) & val , rtw_get_capability_from_ie ( bss - > IEs ) , 2 ) ;
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
return le16_to_cpu ( val ) ;
}
u8 * rtw_get_timestampe_from_ie ( u8 * ie )
{
2013-05-19 04:28:07 +00:00
return ( ie + 0 ) ;
2013-05-08 21:45:39 +00:00
}
u8 * rtw_get_beacon_interval_from_ie ( u8 * ie )
{
2013-05-19 04:28:07 +00:00
return ( ie + 8 ) ;
2013-05-08 21:45:39 +00:00
}
2013-07-09 22:38:46 +00:00
int rtw_init_mlme_priv ( _adapter * padapter ) /* struct mlme_priv *pmlmepriv) */
2013-05-08 21:45:39 +00:00
{
int res ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-07-09 22:38:46 +00:00
res = _rtw_init_mlme_priv ( padapter ) ; /* (pmlmepriv); */
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
return res ;
}
void rtw_free_mlme_priv ( struct mlme_priv * pmlmepriv )
{
_func_enter_ ;
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " rtw_free_mlme_priv \n " ) ) ;
_rtw_free_mlme_priv ( pmlmepriv ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
int rtw_enqueue_network ( _queue * queue , struct wlan_network * pnetwork ) ;
int rtw_enqueue_network ( _queue * queue , struct wlan_network * pnetwork )
{
int res ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
res = _rtw_enqueue_network ( queue , pnetwork ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
return res ;
}
static struct wlan_network * rtw_dequeue_network ( _queue * queue )
{
struct wlan_network * pnetwork ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
pnetwork = _rtw_dequeue_network ( queue ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
return pnetwork ;
}
struct wlan_network * rtw_alloc_network ( struct mlme_priv * pmlmepriv ) ;
2013-07-09 22:38:46 +00:00
struct wlan_network * rtw_alloc_network ( struct mlme_priv * pmlmepriv ) /* _queue *free_queue) */
2013-05-08 21:45:39 +00:00
{
struct wlan_network * pnetwork ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
pnetwork = _rtw_alloc_network ( pmlmepriv ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
return pnetwork ;
}
void rtw_free_network ( struct mlme_priv * pmlmepriv , struct wlan_network * pnetwork , u8 is_freeall ) ;
2013-07-09 22:38:46 +00:00
void rtw_free_network ( struct mlme_priv * pmlmepriv , struct wlan_network * pnetwork , u8 is_freeall ) /* struct wlan_network *pnetwork, _queue *free_queue) */
2013-05-08 21:45:39 +00:00
{
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-09 04:09:18 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " rtw_free_network==> ssid = %s \n \n " , pnetwork - > network . Ssid . Ssid ) ) ;
2013-05-08 21:45:39 +00:00
_rtw_free_network ( pmlmepriv , pnetwork , is_freeall ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
void rtw_free_network_nolock ( struct mlme_priv * pmlmepriv , struct wlan_network * pnetwork ) ;
void rtw_free_network_nolock ( struct mlme_priv * pmlmepriv , struct wlan_network * pnetwork )
{
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-07-09 22:38:46 +00:00
/* RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_network==> ssid = %s\n\n" , pnetwork->network.Ssid.Ssid)); */
2013-05-08 21:45:39 +00:00
_rtw_free_network_nolock ( pmlmepriv , pnetwork ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
void rtw_free_network_queue ( _adapter * dev , u8 isfreeall )
{
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
_rtw_free_network_queue ( dev , isfreeall ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
/*
return the wlan_network with the matching addr
Shall be calle under atomic context . . . to avoid possible racing condition . . .
*/
struct wlan_network * rtw_find_network ( _queue * scanned_queue , u8 * addr )
{
struct wlan_network * pnetwork = _rtw_find_network ( scanned_queue , addr ) ;
return pnetwork ;
}
int rtw_is_same_ibss ( _adapter * adapter , struct wlan_network * pnetwork )
{
2013-05-26 03:02:10 +00:00
int ret = true ;
2013-05-08 21:45:39 +00:00
struct security_priv * psecuritypriv = & adapter - > securitypriv ;
if ( ( psecuritypriv - > dot11PrivacyAlgrthm ! = _NO_PRIVACY_ ) & &
( pnetwork - > network . Privacy = = 0 ) )
{
2013-05-26 03:02:10 +00:00
ret = false ;
2013-05-08 21:45:39 +00:00
}
2013-05-09 04:04:25 +00:00
else if ( ( psecuritypriv - > dot11PrivacyAlgrthm = = _NO_PRIVACY_ ) & &
2013-05-08 21:45:39 +00:00
( pnetwork - > network . Privacy = = 1 ) )
{
2013-05-26 03:02:10 +00:00
ret = false ;
2013-05-08 21:45:39 +00:00
}
else
{
2013-05-26 03:02:10 +00:00
ret = true ;
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
return ret ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
inline int is_same_ess ( WLAN_BSSID_EX * a , WLAN_BSSID_EX * b ) ;
inline int is_same_ess ( WLAN_BSSID_EX * a , WLAN_BSSID_EX * b )
{
2013-05-19 04:28:07 +00:00
return ( a - > Ssid . SsidLength = = b - > Ssid . SsidLength )
2013-05-26 03:02:10 +00:00
& & _rtw_memcmp ( a - > Ssid . Ssid , b - > Ssid . Ssid , a - > Ssid . SsidLength ) = = true ;
2013-05-08 21:45:39 +00:00
}
int is_same_network ( WLAN_BSSID_EX * src , WLAN_BSSID_EX * dst )
{
u16 s_cap , d_cap ;
2013-06-07 14:43:09 +00:00
__le16 le_scap , le_dcap ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-06-07 14:43:09 +00:00
_rtw_memcpy ( ( u8 * ) & le_scap , rtw_get_capability_from_ie ( src - > IEs ) , 2 ) ;
_rtw_memcpy ( ( u8 * ) & le_dcap , rtw_get_capability_from_ie ( dst - > IEs ) , 2 ) ;
2013-05-08 21:45:39 +00:00
2013-06-07 14:43:09 +00:00
s_cap = le16_to_cpu ( le_scap ) ;
d_cap = le16_to_cpu ( le_dcap ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
return ( ( src - > Ssid . SsidLength = = dst - > Ssid . SsidLength ) & &
2013-06-07 14:43:09 +00:00
( ( _rtw_memcmp ( src - > MacAddress , dst - > MacAddress , ETH_ALEN ) ) = = true ) & &
( ( _rtw_memcmp ( src - > Ssid . Ssid , dst - > Ssid . Ssid , src - > Ssid . SsidLength ) ) = = true ) & &
( ( s_cap & WLAN_CAPABILITY_IBSS ) = =
( d_cap & WLAN_CAPABILITY_IBSS ) ) & &
( ( s_cap & WLAN_CAPABILITY_BSS ) = =
( d_cap & WLAN_CAPABILITY_BSS ) ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
struct wlan_network * rtw_get_oldest_wlan_network ( _queue * scanned_queue )
{
_list * plist , * phead ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
struct wlan_network * pwlan = NULL ;
struct wlan_network * oldest = NULL ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
phead = get_list_head ( scanned_queue ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
plist = get_next ( phead ) ;
2013-05-09 04:04:25 +00:00
while ( 1 )
2013-05-08 21:45:39 +00:00
{
2013-05-19 04:28:07 +00:00
2013-05-26 03:02:10 +00:00
if ( rtw_end_of_queue_search ( phead , plist ) = = true )
2013-05-08 21:45:39 +00:00
break ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
pwlan = LIST_CONTAINOR ( plist , struct wlan_network , list ) ;
2013-05-26 03:02:10 +00:00
if ( pwlan - > fixed ! = true )
2013-05-19 04:28:07 +00:00
{
2013-05-08 21:45:39 +00:00
if ( oldest = = NULL | | time_after ( oldest - > last_scanned , pwlan - > last_scanned ) )
oldest = pwlan ;
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
plist = get_next ( plist ) ;
}
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
return oldest ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
void update_network ( WLAN_BSSID_EX * dst , WLAN_BSSID_EX * src ,
_adapter * padapter , bool update_ie )
{
u8 ss_ori = dst - > PhyInfo . SignalStrength ;
u8 sq_ori = dst - > PhyInfo . SignalQuality ;
long rssi_ori = dst - > Rssi ;
u8 ss_smp = src - > PhyInfo . SignalStrength ;
u8 sq_smp = src - > PhyInfo . SignalQuality ;
long rssi_smp = src - > Rssi ;
u8 ss_final ;
u8 sq_final ;
long rssi_final ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
2013-07-09 22:38:46 +00:00
rtw_hal_antdiv_rssi_compared ( padapter , dst , src ) ; /* this will update src.Rssi, need consider again */
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
# if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
2013-05-09 04:04:25 +00:00
if ( strcmp ( dst - > Ssid . Ssid , DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED ) = = 0 ) {
2013-05-30 20:51:53 +00:00
DBG_88E ( " %s %s(%pm, ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld \n "
2013-05-09 16:23:32 +00:00
, __func__
2013-05-30 20:51:53 +00:00
, src - > Ssid . Ssid , src - > MacAddress , src - > Configuration . DSConfig
2013-05-08 21:45:39 +00:00
, ss_ori , sq_ori , rssi_ori
, ss_smp , sq_smp , rssi_smp
) ;
}
# endif
/* The rule below is 1/5 for sample value, 4/5 for history value */
if ( check_fwstate ( & padapter - > mlmepriv , _FW_LINKED ) & & is_same_network ( & ( padapter - > mlmepriv . cur_network . network ) , src ) ) {
/* Take the recvpriv's value for the connected AP*/
ss_final = padapter - > recvpriv . signal_strength ;
sq_final = padapter - > recvpriv . signal_qual ;
/* the rssi value here is undecorated, and will be used for antenna diversity */
2013-05-09 04:04:25 +00:00
if ( sq_smp ! = 101 ) /* from the right channel */
2013-05-08 21:45:39 +00:00
rssi_final = ( src - > Rssi + dst - > Rssi * 4 ) / 5 ;
else
rssi_final = rssi_ori ;
}
else {
2013-05-09 04:04:25 +00:00
if ( sq_smp ! = 101 ) { /* from the right channel */
2013-05-08 21:45:39 +00:00
ss_final = ( ( u32 ) ( src - > PhyInfo . SignalStrength ) + ( u32 ) ( dst - > PhyInfo . SignalStrength ) * 4 ) / 5 ;
sq_final = ( ( u32 ) ( src - > PhyInfo . SignalQuality ) + ( u32 ) ( dst - > PhyInfo . SignalQuality ) * 4 ) / 5 ;
rssi_final = ( src - > Rssi + dst - > Rssi * 4 ) / 5 ;
} else {
/* bss info not receving from the right channel, use the original RX signal infos */
ss_final = dst - > PhyInfo . SignalStrength ;
sq_final = dst - > PhyInfo . SignalQuality ;
rssi_final = dst - > Rssi ;
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
if ( update_ie )
_rtw_memcpy ( ( u8 * ) dst , ( u8 * ) src , get_WLAN_BSSID_EX_sz ( src ) ) ;
dst - > PhyInfo . SignalStrength = ss_final ;
dst - > PhyInfo . SignalQuality = sq_final ;
dst - > Rssi = rssi_final ;
# if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
2013-05-09 04:04:25 +00:00
if ( strcmp ( dst - > Ssid . Ssid , DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED ) = = 0 ) {
2013-05-30 20:51:53 +00:00
DBG_88E ( " %s %s(%pm SignalStrength:%u, SignalQuality:%u, RawRSSI:%ld \n " ,
__func__ , dst - > Ssid . Ssid , dst - > MacAddress ,
dst - > PhyInfo . SignalStrength ,
dst - > PhyInfo . SignalQuality , dst - > Rssi ) ;
2013-05-08 21:45:39 +00:00
}
# endif
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
static void update_current_network ( _adapter * adapter , WLAN_BSSID_EX * pnetwork )
{
struct mlme_priv * pmlmepriv = & ( adapter - > mlmepriv ) ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
2013-05-26 03:02:10 +00:00
if ( ( check_fwstate ( pmlmepriv , _FW_LINKED ) = = true ) & & ( is_same_network ( & ( pmlmepriv - > cur_network . network ) , pnetwork ) ) )
2013-05-08 21:45:39 +00:00
{
2013-05-26 03:02:10 +00:00
update_network ( & ( pmlmepriv - > cur_network . network ) , pnetwork , adapter , true ) ;
2013-05-19 04:28:07 +00:00
rtw_update_protection ( adapter , ( pmlmepriv - > cur_network . network . IEs ) + sizeof ( NDIS_802_11_FIXED_IEs ) ,
2013-05-18 21:16:10 +00:00
pmlmepriv - > cur_network . network . IELength ) ;
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
/*
Caller must hold pmlmepriv - > lock first .
*/
void rtw_update_scanned_network ( _adapter * adapter , WLAN_BSSID_EX * target )
{
_irqL irqL ;
_list * plist , * phead ;
ULONG bssid_ex_sz ;
struct mlme_priv * pmlmepriv = & ( adapter - > mlmepriv ) ;
_queue * queue = & ( pmlmepriv - > scanned_queue ) ;
struct wlan_network * pnetwork = NULL ;
struct wlan_network * oldest = NULL ;
_func_enter_ ;
_enter_critical_bh ( & queue - > lock , & irqL ) ;
phead = get_list_head ( queue ) ;
plist = get_next ( phead ) ;
2013-05-09 04:04:25 +00:00
while ( 1 )
2013-05-08 21:45:39 +00:00
{
2013-05-26 03:02:10 +00:00
if ( rtw_end_of_queue_search ( phead , plist ) = = true )
2013-05-08 21:45:39 +00:00
break ;
pnetwork = LIST_CONTAINOR ( plist , struct wlan_network , list ) ;
if ( ( unsigned long ) ( pnetwork ) < 0x7ffffff )
{
}
if ( is_same_network ( & ( pnetwork - > network ) , target ) )
break ;
if ( ( oldest = = ( ( struct wlan_network * ) 0 ) ) | |
time_after ( oldest - > last_scanned , pnetwork - > last_scanned ) )
oldest = pnetwork ;
plist = get_next ( plist ) ;
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
/* If we didn't find a match, then get a new network slot to initialize
* with this beacon ' s information */
2013-05-26 03:02:10 +00:00
if ( rtw_end_of_queue_search ( phead , plist ) = = true ) {
2013-05-19 04:28:07 +00:00
2013-05-26 03:02:10 +00:00
if ( _rtw_queue_empty ( & ( pmlmepriv - > free_bss_pool ) ) = = true ) {
2013-05-08 21:45:39 +00:00
/* If there are no more slots, expire the oldest */
2013-07-09 22:38:46 +00:00
/* list_del_init(&oldest->list); */
2013-05-08 21:45:39 +00:00
pnetwork = oldest ;
rtw_hal_get_def_var ( adapter , HAL_DEF_CURRENT_ANTENNA , & ( target - > PhyInfo . Optimum_antenna ) ) ;
_rtw_memcpy ( & ( pnetwork - > network ) , target , get_WLAN_BSSID_EX_sz ( target ) ) ;
2013-07-09 22:38:46 +00:00
/* variable initialize */
2013-05-26 03:02:10 +00:00
pnetwork - > fixed = false ;
2013-05-08 21:45:39 +00:00
pnetwork - > last_scanned = rtw_get_current_time ( ) ;
2013-05-19 04:28:07 +00:00
pnetwork - > network_type = 0 ;
pnetwork - > aid = 0 ;
2013-05-08 21:45:39 +00:00
pnetwork - > join_res = 0 ;
/* bss info not receving from the right channel */
if ( pnetwork - > network . PhyInfo . SignalQuality = = 101 )
pnetwork - > network . PhyInfo . SignalQuality = 0 ;
2013-07-14 19:10:10 +00:00
} else {
2013-05-08 21:45:39 +00:00
/* Otherwise just pull from the free list */
2013-07-09 22:38:46 +00:00
pnetwork = rtw_alloc_network ( pmlmepriv ) ; /* will update scan_time */
2013-05-08 21:45:39 +00:00
2013-07-14 19:10:10 +00:00
if ( pnetwork = = NULL ) {
2013-05-08 21:45:39 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " \n \n \n something wrong here \n \n \n " ) ) ;
goto exit ;
}
bssid_ex_sz = get_WLAN_BSSID_EX_sz ( target ) ;
target - > Length = bssid_ex_sz ;
rtw_hal_get_def_var ( adapter , HAL_DEF_CURRENT_ANTENNA , & ( target - > PhyInfo . Optimum_antenna ) ) ;
_rtw_memcpy ( & ( pnetwork - > network ) , target , bssid_ex_sz ) ;
pnetwork - > last_scanned = rtw_get_current_time ( ) ;
/* bss info not receving from the right channel */
if ( pnetwork - > network . PhyInfo . SignalQuality = = 101 )
pnetwork - > network . PhyInfo . SignalQuality = 0 ;
2013-05-19 04:28:07 +00:00
rtw_list_insert_tail ( & ( pnetwork - > list ) , & ( queue - > queue ) ) ;
2013-05-08 21:45:39 +00:00
}
}
else {
/* we have an entry and we are going to update it. But this entry may
2013-05-19 04:28:07 +00:00
* be already expired . In this case we do the same as we found a new
2013-05-08 21:45:39 +00:00
* net and call the new_net handler
*/
2013-05-26 03:02:10 +00:00
bool update_ie = true ;
2013-05-08 21:45:39 +00:00
pnetwork - > last_scanned = rtw_get_current_time ( ) ;
2013-07-09 22:38:46 +00:00
/* target.Reserved[0]==1, means that scaned network is a bcn frame. */
2013-05-09 04:04:25 +00:00
if ( ( pnetwork - > network . IELength > target - > IELength ) & & ( target - > Reserved [ 0 ] = = 1 ) )
2013-05-26 03:02:10 +00:00
update_ie = false ;
2013-05-08 21:45:39 +00:00
update_network ( & ( pnetwork - > network ) , target , adapter , update_ie ) ;
}
exit :
_exit_critical_bh ( & queue - > lock , & irqL ) ;
_func_exit_ ;
}
void rtw_add_network ( _adapter * adapter , WLAN_BSSID_EX * pnetwork )
{
_irqL irqL ;
struct mlme_priv * pmlmepriv = & ( ( ( _adapter * ) adapter ) - > mlmepriv ) ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
2013-07-20 16:25:24 +00:00
# if defined(CONFIG_P2P)
2013-05-08 21:45:39 +00:00
rtw_WLAN_BSSID_EX_remove_p2p_attr ( pnetwork , P2P_ATTR_GROUP_INFO ) ;
# endif
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
update_current_network ( adapter , pnetwork ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
rtw_update_scanned_network ( adapter , pnetwork ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
2013-07-09 22:38:46 +00:00
/* select the desired network based on the capability of the (i)bss. */
/* check items: (1) security */
/* (2) network_type */
/* (3) WMM */
/* (4) HT */
/* (5) others */
2013-07-10 21:11:59 +00:00
static int rtw_is_desired_network ( _adapter * adapter , struct wlan_network * pnetwork )
2013-05-08 21:45:39 +00:00
{
struct security_priv * psecuritypriv = & adapter - > securitypriv ;
struct mlme_priv * pmlmepriv = & adapter - > mlmepriv ;
u32 desired_encmode ;
u32 privacy ;
2013-07-09 22:38:46 +00:00
/* u8 wps_ie[512]; */
2013-05-08 21:45:39 +00:00
uint wps_ielen ;
2013-05-26 03:02:10 +00:00
int bselected = true ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
desired_encmode = psecuritypriv - > ndisencryptstatus ;
privacy = pnetwork - > network . Privacy ;
2013-05-09 04:04:25 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_UNDER_WPS ) )
2013-05-08 21:45:39 +00:00
{
2013-05-09 04:04:25 +00:00
if ( rtw_get_wps_ie ( pnetwork - > network . IEs + _FIXED_IE_LENGTH_ , pnetwork - > network . IELength - _FIXED_IE_LENGTH_ , NULL , & wps_ielen ) ! = NULL )
2013-05-08 21:45:39 +00:00
{
2013-05-26 03:02:10 +00:00
return true ;
2013-05-08 21:45:39 +00:00
}
else
2013-05-19 04:28:07 +00:00
{
2013-05-26 03:02:10 +00:00
return false ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
}
2013-07-09 22:38:46 +00:00
if ( adapter - > registrypriv . wifi_spec = = 1 ) /* for correct flow of 8021X to do.... */
2013-05-08 21:45:39 +00:00
{
if ( ( desired_encmode = = Ndis802_11EncryptionDisabled ) & & ( privacy ! = 0 ) )
2013-05-26 03:02:10 +00:00
bselected = false ;
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
if ( ( desired_encmode ! = Ndis802_11EncryptionDisabled ) & & ( privacy = = 0 ) ) {
2013-05-25 23:35:42 +00:00
DBG_88E ( " desired_encmode: %d, privacy: %d \n " , desired_encmode , privacy ) ;
2013-05-26 03:02:10 +00:00
bselected = false ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
2013-05-26 03:02:10 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_ADHOC_STATE ) = = true )
2013-05-08 21:45:39 +00:00
{
2013-05-09 04:04:25 +00:00
if ( pnetwork - > network . InfrastructureMode ! = pmlmepriv - > cur_network . network . InfrastructureMode )
2013-05-26 03:02:10 +00:00
bselected = false ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
return bselected ;
}
/* TODO: Perry : For Power Management */
void rtw_atimdone_event_callback ( _adapter * adapter , u8 * pbuf )
{
2013-05-19 04:28:07 +00:00
_func_enter_ ;
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " receive atimdone_evet \n " ) ) ;
_func_exit_ ;
return ;
2013-05-08 21:45:39 +00:00
}
void rtw_survey_event_callback ( _adapter * adapter , u8 * pbuf )
{
_irqL irqL ;
u32 len ;
WLAN_BSSID_EX * pnetwork ;
struct mlme_priv * pmlmepriv = & ( adapter - > mlmepriv ) ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
pnetwork = ( WLAN_BSSID_EX * ) pbuf ;
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_info_ , ( " rtw_survey_event_callback, ssid=%s \n " , pnetwork - > Ssid . Ssid ) ) ;
len = get_WLAN_BSSID_EX_sz ( pnetwork ) ;
2013-07-11 15:59:02 +00:00
if ( len > ( sizeof ( WLAN_BSSID_EX ) ) ) {
2013-05-08 21:45:39 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " \n ****rtw_survey_event_callback: return a wrong bss *** \n " ) ) ;
return ;
}
_enter_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
2013-07-09 22:38:46 +00:00
/* update IBSS_network 's timestamp */
2013-05-26 03:02:10 +00:00
if ( ( check_fwstate ( pmlmepriv , WIFI_ADHOC_MASTER_STATE ) ) = = true )
2013-05-08 21:45:39 +00:00
{
2013-05-09 04:04:25 +00:00
if ( _rtw_memcmp ( & ( pmlmepriv - > cur_network . network . MacAddress ) , pnetwork - > MacAddress , ETH_ALEN ) )
2013-05-08 21:45:39 +00:00
{
struct wlan_network * ibss_wlan = NULL ;
_irqL irqL ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_rtw_memcpy ( pmlmepriv - > cur_network . network . IEs , pnetwork - > IEs , 8 ) ;
_enter_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
ibss_wlan = rtw_find_network ( & pmlmepriv - > scanned_queue , pnetwork - > MacAddress ) ;
2013-05-09 04:04:25 +00:00
if ( ibss_wlan )
2013-05-08 21:45:39 +00:00
{
2013-05-19 04:28:07 +00:00
_rtw_memcpy ( ibss_wlan - > network . IEs , pnetwork - > IEs , 8 ) ;
_exit_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
2013-05-08 21:45:39 +00:00
goto exit ;
}
_exit_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
}
}
2013-07-09 22:38:46 +00:00
/* lock pmlmepriv->lock when you accessing network_q */
2013-05-26 03:02:10 +00:00
if ( ( check_fwstate ( pmlmepriv , _FW_UNDER_LINKING ) ) = = false )
2013-05-19 04:28:07 +00:00
{
if ( pnetwork - > Ssid . Ssid [ 0 ] = = 0 )
2013-05-08 21:45:39 +00:00
{
pnetwork - > Ssid . SsidLength = 0 ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
rtw_add_network ( adapter , pnetwork ) ;
2013-05-19 04:28:07 +00:00
}
exit :
2013-05-08 21:45:39 +00:00
_exit_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
return ;
2013-05-08 21:45:39 +00:00
}
void rtw_surveydone_event_callback ( _adapter * adapter , u8 * pbuf )
{
_irqL irqL ;
struct mlme_priv * pmlmepriv = & ( adapter - > mlmepriv ) ;
2013-05-19 04:28:07 +00:00
# ifdef CONFIG_MLME_EXT
2013-05-08 21:45:39 +00:00
mlmeext_surveydone_event_callback ( adapter ) ;
# endif
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
_enter_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
2013-05-09 04:04:25 +00:00
if ( pmlmepriv - > wps_probe_req_ie )
2013-05-08 21:45:39 +00:00
{
u32 free_len = pmlmepriv - > wps_probe_req_ie_len ;
pmlmepriv - > wps_probe_req_ie_len = 0 ;
rtw_mfree ( pmlmepriv - > wps_probe_req_ie , free_len ) ;
2013-05-19 04:28:07 +00:00
pmlmepriv - > wps_probe_req_ie = NULL ;
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_info_ , ( " rtw_surveydone_event_callback: fw_state:%x \n \n " , get_fwstate ( pmlmepriv ) ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
if ( check_fwstate ( pmlmepriv , _FW_UNDER_SURVEY ) )
{
u8 timer_cancelled ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_cancel_timer ( & pmlmepriv - > scan_to_timer , & timer_cancelled ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_clr_fwstate_ ( pmlmepriv , _FW_UNDER_SURVEY ) ;
}
else {
2013-05-19 04:28:07 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " nic status =%x, survey done event comes too late! \n " , get_fwstate ( pmlmepriv ) ) ) ;
2013-05-08 21:45:39 +00:00
}
rtw_set_signal_stat_timer ( & adapter - > recvpriv ) ;
2013-07-18 15:30:16 +00:00
if ( pmlmepriv - > to_join = = true ) {
if ( ( check_fwstate ( pmlmepriv , WIFI_ADHOC_STATE ) = = true ) ) {
if ( check_fwstate ( pmlmepriv , _FW_LINKED ) = = false ) {
2013-05-19 04:28:07 +00:00
set_fwstate ( pmlmepriv , _FW_UNDER_LINKING ) ;
2013-07-18 15:30:16 +00:00
if ( rtw_select_and_join_from_scanned_queue ( pmlmepriv ) = = _SUCCESS ) {
2013-05-19 04:28:07 +00:00
_set_timer ( & pmlmepriv - > assoc_timer , MAX_JOIN_TIMEOUT ) ;
2013-07-18 15:30:16 +00:00
} else {
2013-05-19 04:28:07 +00:00
WLAN_BSSID_EX * pdev_network = & ( adapter - > registrypriv . dev_network ) ;
2013-05-08 21:45:39 +00:00
u8 * pibss = adapter - > registrypriv . dev_network . MacAddress ;
_clr_fwstate_ ( pmlmepriv , _FW_UNDER_SURVEY ) ;
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " switching to adhoc master \n " ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_rtw_memset ( & pdev_network - > Ssid , 0 , sizeof ( NDIS_802_11_SSID ) ) ;
_rtw_memcpy ( & pdev_network - > Ssid , & pmlmepriv - > assoc_ssid , sizeof ( NDIS_802_11_SSID ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
rtw_update_registrypriv_dev_network ( adapter ) ;
rtw_generate_random_ibss ( pibss ) ;
2013-05-19 04:28:07 +00:00
pmlmepriv - > fw_state = WIFI_ADHOC_MASTER_STATE ;
2013-05-09 04:04:25 +00:00
if ( rtw_createbss_cmd ( adapter ) ! = _SUCCESS )
2013-05-08 21:45:39 +00:00
{
2013-05-19 04:28:07 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " Error=>rtw_createbss_cmd status FAIL \n " ) ) ;
}
2013-05-08 21:45:39 +00:00
2013-05-26 03:02:10 +00:00
pmlmepriv - > to_join = false ;
2013-05-19 04:28:07 +00:00
}
}
2013-07-18 15:30:16 +00:00
} else {
2013-05-08 21:45:39 +00:00
int s_ret ;
set_fwstate ( pmlmepriv , _FW_UNDER_LINKING ) ;
2013-05-26 03:02:10 +00:00
pmlmepriv - > to_join = false ;
2013-07-18 15:30:16 +00:00
if ( _SUCCESS = = ( s_ret = rtw_select_and_join_from_scanned_queue ( pmlmepriv ) ) ) {
2013-05-19 04:28:07 +00:00
_set_timer ( & pmlmepriv - > assoc_timer , MAX_JOIN_TIMEOUT ) ;
2013-07-18 15:30:16 +00:00
} else if ( s_ret = = 2 ) { /* there is no need to wait for join */
2013-05-08 21:45:39 +00:00
_clr_fwstate_ ( pmlmepriv , _FW_UNDER_LINKING ) ;
rtw_indicate_connect ( adapter ) ;
2013-07-18 15:30:16 +00:00
} else {
2013-05-25 23:35:42 +00:00
DBG_88E ( " try_to_join, but select scanning queue fail, to_roaming:%d \n " , pmlmepriv - > to_roaming ) ;
2013-05-08 21:45:39 +00:00
2013-05-09 04:04:25 +00:00
if ( pmlmepriv - > to_roaming ! = 0 ) {
2013-07-18 15:30:16 +00:00
if ( - - pmlmepriv - > to_roaming = = 0 | |
_SUCCESS ! = rtw_sitesurvey_cmd ( adapter , & pmlmepriv - > assoc_ssid , 1 , NULL , 0 ) ) {
2013-05-08 21:45:39 +00:00
pmlmepriv - > to_roaming = 0 ;
rtw_free_assoc_resources ( adapter , 1 ) ;
rtw_indicate_disconnect ( adapter ) ;
} else {
2013-05-26 03:02:10 +00:00
pmlmepriv - > to_join = true ;
2013-05-08 21:45:39 +00:00
}
}
_clr_fwstate_ ( pmlmepriv , _FW_UNDER_LINKING ) ;
}
}
}
indicate_wx_scan_complete_event ( adapter ) ;
_exit_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
2013-05-26 03:02:10 +00:00
if ( check_fwstate ( pmlmepriv , _FW_LINKED ) = = true ) {
2013-05-08 21:45:39 +00:00
p2p_ps_wk_cmd ( adapter , P2P_PS_SCAN_DONE , 0 ) ;
}
rtw_os_xmit_schedule ( adapter ) ;
{
2013-05-19 04:28:07 +00:00
struct mlme_ext_priv * pmlmeext = & adapter - > mlmeextpriv ;
2013-05-09 04:04:25 +00:00
if ( pmlmeext - > sitesurvey_res . bss_cnt = = 0 ) {
2013-05-19 04:28:07 +00:00
rtw_hal_sreset_reset ( adapter ) ;
2013-05-08 21:45:39 +00:00
}
}
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
void rtw_dummy_event_callback ( _adapter * adapter , u8 * pbuf )
{
}
void rtw_fwdbg_event_callback ( _adapter * adapter , u8 * pbuf )
{
}
static void free_scanqueue ( struct mlme_priv * pmlmepriv )
{
_irqL irqL , irqL0 ;
_queue * free_queue = & pmlmepriv - > free_bss_pool ;
_queue * scan_queue = & pmlmepriv - > scanned_queue ;
_list * plist , * phead , * ptemp ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_notice_ , ( " +free_scanqueue \n " ) ) ;
_enter_critical_bh ( & scan_queue - > lock , & irqL0 ) ;
_enter_critical_bh ( & free_queue - > lock , & irqL ) ;
phead = get_list_head ( scan_queue ) ;
plist = get_next ( phead ) ;
while ( plist ! = phead )
{
ptemp = get_next ( plist ) ;
rtw_list_delete ( plist ) ;
rtw_list_insert_tail ( plist , & free_queue - > queue ) ;
plist = ptemp ;
pmlmepriv - > num_of_scanned - - ;
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_exit_critical_bh ( & free_queue - > lock , & irqL ) ;
_exit_critical_bh ( & scan_queue - > lock , & irqL0 ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_func_exit_ ;
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
/*
* rtw_free_assoc_resources : the caller has to lock pmlmepriv - > lock
*/
void rtw_free_assoc_resources ( _adapter * adapter , int lock_scanned_queue )
{
_irqL irqL ;
struct wlan_network * pwlan = NULL ;
2013-05-19 04:28:07 +00:00
struct mlme_priv * pmlmepriv = & adapter - > mlmepriv ;
struct sta_priv * pstapriv = & adapter - > stapriv ;
2013-05-08 21:45:39 +00:00
struct wlan_network * tgt_network = & pmlmepriv - > cur_network ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_notice_ , ( " +rtw_free_assoc_resources \n " ) ) ;
2013-05-30 20:51:53 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_info_ , ( " tgt_network->network.MacAddress=%pM ssid=%s \n " ,
tgt_network - > network . MacAddress , tgt_network - > network . Ssid . Ssid ) ) ;
2013-05-08 21:45:39 +00:00
2013-06-03 19:52:18 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_STATION_STATE | WIFI_AP_STATE ) ) {
2013-05-08 21:45:39 +00:00
struct sta_info * psta ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
psta = rtw_get_stainfo ( & adapter - > stapriv , tgt_network - > network . MacAddress ) ;
2013-07-12 01:13:07 +00:00
_enter_critical_bh ( & ( pstapriv - > sta_hash_lock ) , & irqL ) ;
rtw_free_stainfo ( adapter , psta ) ;
_exit_critical_bh ( & ( pstapriv - > sta_hash_lock ) , & irqL ) ;
2013-05-08 21:45:39 +00:00
}
2013-06-03 19:52:18 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE ) ) {
2013-05-08 21:45:39 +00:00
struct sta_info * psta ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
rtw_free_all_stainfo ( adapter ) ;
psta = rtw_get_bcmc_stainfo ( adapter ) ;
2013-05-19 04:28:07 +00:00
_enter_critical_bh ( & ( pstapriv - > sta_hash_lock ) , & irqL ) ;
2013-05-08 21:45:39 +00:00
rtw_free_stainfo ( adapter , psta ) ;
2013-05-19 04:28:07 +00:00
_exit_critical_bh ( & ( pstapriv - > sta_hash_lock ) , & irqL ) ;
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
rtw_init_bcmc_stainfo ( adapter ) ;
2013-05-08 21:45:39 +00:00
}
2013-05-09 04:04:25 +00:00
if ( lock_scanned_queue )
2013-05-08 21:45:39 +00:00
_enter_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
pwlan = rtw_find_network ( & pmlmepriv - > scanned_queue , tgt_network - > network . MacAddress ) ;
2013-05-19 04:28:07 +00:00
if ( pwlan )
2013-05-26 03:02:10 +00:00
pwlan - > fixed = false ;
2013-05-08 21:45:39 +00:00
else
2013-05-09 04:09:18 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " rtw_free_assoc_resources : pwlan== NULL \n \n " ) ) ;
2013-05-08 21:45:39 +00:00
2013-06-03 19:52:18 +00:00
if ( ( check_fwstate ( pmlmepriv , WIFI_ADHOC_MASTER_STATE ) & & ( adapter - > stapriv . asoc_sta_count = = 1 ) ) )
2013-05-19 04:28:07 +00:00
rtw_free_network_nolock ( pmlmepriv , pwlan ) ;
2013-05-08 21:45:39 +00:00
2013-05-09 04:04:25 +00:00
if ( lock_scanned_queue )
2013-05-08 21:45:39 +00:00
_exit_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
pmlmepriv - > key_mask = 0 ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
/*
* rtw_indicate_connect : the caller has to lock pmlmepriv - > lock
*/
void rtw_indicate_connect ( _adapter * padapter )
{
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
struct xmit_priv * pxmitpriv = & padapter - > xmitpriv ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_func_enter_ ;
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " +rtw_indicate_connect \n " ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-26 03:02:10 +00:00
pmlmepriv - > to_join = false ;
2013-05-08 21:45:39 +00:00
2013-06-07 14:43:09 +00:00
if ( ! check_fwstate ( & padapter - > mlmepriv , _FW_LINKED ) ) {
2013-05-08 21:45:39 +00:00
set_fwstate ( pmlmepriv , _FW_LINKED ) ;
rtw_led_control ( padapter , LED_CTL_LINK ) ;
2013-07-21 18:12:53 +00:00
rtw_os_indicate_connect ( padapter ) ;
2013-05-08 21:45:39 +00:00
}
pmlmepriv - > to_roaming = 0 ;
rtw_set_scan_deny ( padapter , 3000 ) ;
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " -rtw_indicate_connect: fw_state=0x%08x \n " , get_fwstate ( pmlmepriv ) ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_func_exit_ ;
}
/*
* rtw_indicate_disconnect : the caller has to lock pmlmepriv - > lock
*/
void rtw_indicate_disconnect ( _adapter * padapter )
{
2013-05-19 04:28:07 +00:00
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
WLAN_BSSID_EX * cur_network = & ( pmlmeinfo - > network ) ;
struct sta_info * psta ;
struct sta_priv * pstapriv = & padapter - > stapriv ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " +rtw_indicate_disconnect \n " ) ) ;
_clr_fwstate_ ( pmlmepriv , _FW_UNDER_LINKING | WIFI_UNDER_WPS ) ;
2013-05-09 04:04:25 +00:00
if ( pmlmepriv - > to_roaming > 0 )
2013-05-08 21:45:39 +00:00
_clr_fwstate_ ( pmlmepriv , _FW_LINKED ) ;
2013-05-19 04:28:07 +00:00
2013-07-13 03:38:53 +00:00
if ( check_fwstate ( & padapter - > mlmepriv , _FW_LINKED ) | |
( pmlmepriv - > to_roaming < = 0 ) ) {
2013-05-08 21:45:39 +00:00
rtw_os_indicate_disconnect ( padapter ) ;
_clr_fwstate_ ( pmlmepriv , _FW_LINKED ) ;
rtw_led_control ( padapter , LED_CTL_NO_LINK ) ;
rtw_clear_scan_deny ( padapter ) ;
}
p2p_ps_wk_cmd ( padapter , P2P_PS_DISABLE , 1 ) ;
# ifdef CONFIG_WOWLAN
2013-05-26 03:02:10 +00:00
if ( padapter - > pwrctrlpriv . wowlan_mode = = false )
2013-07-09 22:38:46 +00:00
# endif /* CONFIG_WOWLAN */
2013-05-08 21:45:39 +00:00
rtw_lps_ctrl_wk_cmd ( padapter , LPS_CTRL_DISCONNECT , 1 ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
inline void rtw_indicate_scan_done ( _adapter * padapter , bool aborted )
{
rtw_os_indicate_scan_done ( padapter , aborted ) ;
}
void rtw_scan_abort ( _adapter * adapter )
{
u32 cnt = 0 ;
u32 start ;
struct mlme_priv * pmlmepriv = & ( adapter - > mlmepriv ) ;
struct mlme_ext_priv * pmlmeext = & ( adapter - > mlmeextpriv ) ;
start = rtw_get_current_time ( ) ;
2013-05-26 03:02:10 +00:00
pmlmeext - > scan_abort = true ;
2013-05-08 21:45:39 +00:00
while ( check_fwstate ( pmlmepriv , _FW_UNDER_SURVEY )
& & rtw_get_passing_time_ms ( start ) < = 200 ) {
if ( adapter - > bDriverStopped | | adapter - > bSurpriseRemoved )
break ;
2013-05-25 23:35:42 +00:00
DBG_88E ( FUNC_NDEV_FMT " fw_state=_FW_UNDER_SURVEY! \n " , FUNC_NDEV_ARG ( adapter - > pnetdev ) ) ;
2013-05-08 21:45:39 +00:00
rtw_msleep_os ( 20 ) ;
}
if ( check_fwstate ( pmlmepriv , _FW_UNDER_SURVEY ) ) {
if ( ! adapter - > bDriverStopped & & ! adapter - > bSurpriseRemoved )
2013-05-25 23:35:42 +00:00
DBG_88E ( FUNC_NDEV_FMT " waiting for scan_abort time out! \n " , FUNC_NDEV_ARG ( adapter - > pnetdev ) ) ;
2013-05-26 03:02:10 +00:00
rtw_indicate_scan_done ( adapter , true ) ;
2013-05-08 21:45:39 +00:00
}
2013-05-26 03:02:10 +00:00
pmlmeext - > scan_abort = false ;
2013-05-08 21:45:39 +00:00
}
static struct sta_info * rtw_joinbss_update_stainfo ( _adapter * padapter , struct wlan_network * pnetwork )
{
int i ;
struct sta_info * bmc_sta , * psta = NULL ;
struct recv_reorder_ctrl * preorder_ctrl ;
2013-05-19 04:28:07 +00:00
struct sta_priv * pstapriv = & padapter - > stapriv ;
2013-05-08 21:45:39 +00:00
psta = rtw_get_stainfo ( pstapriv , pnetwork - > network . MacAddress ) ;
2013-05-09 04:04:25 +00:00
if ( psta = = NULL ) {
2013-05-08 21:45:39 +00:00
psta = rtw_alloc_stainfo ( pstapriv , pnetwork - > network . MacAddress ) ;
}
2013-07-09 22:38:46 +00:00
if ( psta ) /* update ptarget_sta */
2013-05-08 21:45:39 +00:00
{
2013-05-25 23:35:42 +00:00
DBG_88E ( " %s \n " , __func__ ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
psta - > aid = pnetwork - > join_res ;
psta - > mac_id = 0 ;
2013-07-09 22:38:46 +00:00
/* sta mode */
2013-05-26 03:02:10 +00:00
rtw_hal_set_odm_var ( padapter , HAL_ODM_STA_INFO , psta , true ) ;
2013-05-08 21:45:39 +00:00
2013-07-09 22:38:46 +00:00
/* security related */
2013-05-09 04:04:25 +00:00
if ( padapter - > securitypriv . dot11AuthAlgrthm = = dot11AuthAlgrthm_8021X )
2013-05-19 04:28:07 +00:00
{
2013-05-26 03:02:10 +00:00
padapter - > securitypriv . binstallGrpkey = false ;
padapter - > securitypriv . busetkipkey = false ;
padapter - > securitypriv . bgrpkey_handshake = false ;
2013-05-08 21:45:39 +00:00
2013-05-26 03:02:10 +00:00
psta - > ieee8021x_blocked = true ;
2013-05-08 21:45:39 +00:00
psta - > dot118021XPrivacy = padapter - > securitypriv . dot11PrivacyAlgrthm ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_rtw_memset ( ( u8 * ) & psta - > dot118021x_UncstKey , 0 , sizeof ( union Keytype ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_rtw_memset ( ( u8 * ) & psta - > dot11tkiprxmickey , 0 , sizeof ( union Keytype ) ) ;
_rtw_memset ( ( u8 * ) & psta - > dot11tkiptxmickey , 0 , sizeof ( union Keytype ) ) ;
2013-05-19 04:28:07 +00:00
_rtw_memset ( ( u8 * ) & psta - > dot11txpn , 0 , sizeof ( union pn48 ) ) ;
_rtw_memset ( ( u8 * ) & psta - > dot11rxpn , 0 , sizeof ( union pn48 ) ) ;
2013-05-08 21:45:39 +00:00
}
2013-07-09 22:38:46 +00:00
/* Commented by Albert 2012/07/21 */
/* When doing the WPS, the wps_ie_len won't equal to 0 */
/* And the Wi-Fi driver shouldn't allow the data packet to be tramsmitted. */
2013-05-08 21:45:39 +00:00
if ( padapter - > securitypriv . wps_ie_len ! = 0 )
{
2013-05-26 03:02:10 +00:00
psta - > ieee8021x_blocked = true ;
2013-05-08 21:45:39 +00:00
padapter - > securitypriv . wps_ie_len = 0 ;
}
2013-07-09 22:38:46 +00:00
/* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */
/* if A-MPDU Rx is enabled, reseting rx_ordering_ctrl wstart_b(indicate_seq) to default value=0xffff */
/* todo: check if AP can send A-MPDU packets */
2013-05-09 04:04:25 +00:00
for ( i = 0 ; i < 16 ; i + + )
2013-05-08 21:45:39 +00:00
{
2013-07-09 22:38:46 +00:00
/* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
2013-05-08 21:45:39 +00:00
preorder_ctrl = & psta - > recvreorder_ctrl [ i ] ;
2013-05-26 03:02:10 +00:00
preorder_ctrl - > enable = false ;
2013-05-08 21:45:39 +00:00
preorder_ctrl - > indicate_seq = 0xffff ;
preorder_ctrl - > wend_b = 0xffff ;
2013-07-09 22:38:46 +00:00
preorder_ctrl - > wsize_b = 64 ; /* max_ampdu_sz; ex. 32(kbytes) -> wsize_b=32 */
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
bmc_sta = rtw_get_bcmc_stainfo ( padapter ) ;
2013-05-09 04:04:25 +00:00
if ( bmc_sta )
2013-05-08 21:45:39 +00:00
{
2013-05-09 04:04:25 +00:00
for ( i = 0 ; i < 16 ; i + + )
2013-05-08 21:45:39 +00:00
{
2013-07-09 22:38:46 +00:00
/* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
2013-05-08 21:45:39 +00:00
preorder_ctrl = & bmc_sta - > recvreorder_ctrl [ i ] ;
2013-05-26 03:02:10 +00:00
preorder_ctrl - > enable = false ;
2013-05-08 21:45:39 +00:00
preorder_ctrl - > indicate_seq = 0xffff ;
preorder_ctrl - > wend_b = 0xffff ;
2013-07-09 22:38:46 +00:00
preorder_ctrl - > wsize_b = 64 ; /* max_ampdu_sz; ex. 32(kbytes) -> wsize_b=32 */
2013-05-08 21:45:39 +00:00
}
}
2013-05-19 04:28:07 +00:00
2013-07-09 22:38:46 +00:00
/* misc. */
2013-05-08 21:45:39 +00:00
update_sta_info ( padapter , psta ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
return psta ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
2013-07-09 22:38:46 +00:00
/* pnetwork : returns from rtw_joinbss_event_callback */
/* ptarget_wlan: found from scanned_queue */
2013-05-08 21:45:39 +00:00
static void rtw_joinbss_update_network ( _adapter * padapter , struct wlan_network * ptarget_wlan , struct wlan_network * pnetwork )
{
2013-05-19 04:28:07 +00:00
struct mlme_priv * pmlmepriv = & ( padapter - > mlmepriv ) ;
2013-05-08 21:45:39 +00:00
struct wlan_network * cur_network = & ( pmlmepriv - > cur_network ) ;
2013-05-25 23:35:42 +00:00
DBG_88E ( " %s \n " , __func__ ) ;
2013-05-19 04:28:07 +00:00
2013-05-30 20:51:53 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_info_ , ( " \n fw_state:%x, BSSID:%pM \n " ,
get_fwstate ( pmlmepriv ) , pnetwork - > network . MacAddress ) ) ;
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
2013-07-09 22:38:46 +00:00
/* why not use ptarget_wlan?? */
2013-05-08 21:45:39 +00:00
_rtw_memcpy ( & cur_network - > network , & pnetwork - > network , pnetwork - > network . Length ) ;
2013-07-09 22:38:46 +00:00
/* some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
2013-05-08 21:45:39 +00:00
cur_network - > network . IELength = ptarget_wlan - > network . IELength ;
_rtw_memcpy ( & cur_network - > network . IEs [ 0 ] , & ptarget_wlan - > network . IEs [ 0 ] , MAX_IE_SZ ) ;
cur_network - > aid = pnetwork - > join_res ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
rtw_set_signal_stat_timer ( & padapter - > recvpriv ) ;
padapter - > recvpriv . signal_strength = ptarget_wlan - > network . PhyInfo . SignalStrength ;
padapter - > recvpriv . signal_qual = ptarget_wlan - > network . PhyInfo . SignalQuality ;
2013-07-09 22:38:46 +00:00
/* the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) */
2013-05-08 21:45:39 +00:00
padapter - > recvpriv . rssi = translate_percentage_to_dbm ( ptarget_wlan - > network . PhyInfo . SignalStrength ) ;
# if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
2013-05-25 23:35:42 +00:00
DBG_88E ( " %s signal_strength:%3u, rssi:%3d, signal_qual:%3u "
2013-05-08 21:45:39 +00:00
" \n "
2013-05-09 16:23:32 +00:00
, __func__
2013-05-08 21:45:39 +00:00
, padapter - > recvpriv . signal_strength
, padapter - > recvpriv . rssi
, padapter - > recvpriv . signal_qual
) ;
# endif
rtw_set_signal_stat_timer ( & padapter - > recvpriv ) ;
2013-05-19 04:28:07 +00:00
2013-07-09 22:38:46 +00:00
/* update fw_state will clr _FW_UNDER_LINKING here indirectly */
2013-05-09 04:04:25 +00:00
switch ( pnetwork - > network . InfrastructureMode )
2013-05-19 04:28:07 +00:00
{
case Ndis802_11Infrastructure :
2013-05-09 04:04:25 +00:00
if ( pmlmepriv - > fw_state & WIFI_UNDER_WPS )
2013-05-08 21:45:39 +00:00
pmlmepriv - > fw_state = WIFI_STATION_STATE | WIFI_UNDER_WPS ;
else
pmlmepriv - > fw_state = WIFI_STATION_STATE ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
break ;
2013-05-19 04:28:07 +00:00
case Ndis802_11IBSS :
2013-05-08 21:45:39 +00:00
pmlmepriv - > fw_state = WIFI_ADHOC_STATE ;
break ;
default :
pmlmepriv - > fw_state = WIFI_NULL_STATE ;
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " Invalid network_mode \n " ) ) ;
break ;
}
2013-05-19 04:28:07 +00:00
rtw_update_protection ( padapter , ( cur_network - > network . IEs ) + sizeof ( NDIS_802_11_FIXED_IEs ) ,
2013-05-08 21:45:39 +00:00
( cur_network - > network . IELength ) ) ;
2013-05-19 04:28:07 +00:00
# ifdef CONFIG_80211N_HT
2013-05-08 21:45:39 +00:00
rtw_update_ht_cap ( padapter , cur_network - > network . IEs , cur_network - > network . IELength ) ;
# endif
}
2013-07-09 22:38:46 +00:00
/* Notes: the fucntion could be > passive_level (the same context as Rx tasklet) */
/* pnetwork : returns from rtw_joinbss_event_callback */
/* ptarget_wlan: found from scanned_queue */
/* if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if "ptarget_sta" & "ptarget_wlan" exist. */
/* if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. */
/* if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan !=NULL). */
/* */
/* define REJOIN */
2013-05-08 21:45:39 +00:00
void rtw_joinbss_event_prehandle ( _adapter * adapter , u8 * pbuf )
{
_irqL irqL , irqL2 ;
2013-06-21 18:41:29 +00:00
# ifdef REJOIN
2013-05-08 21:45:39 +00:00
static u8 retry = 0 ;
2013-06-21 18:41:29 +00:00
# endif
2013-05-08 21:45:39 +00:00
u8 timer_cancelled ;
struct sta_info * ptarget_sta = NULL , * pcur_sta = NULL ;
2013-05-19 04:28:07 +00:00
struct sta_priv * pstapriv = & adapter - > stapriv ;
2013-05-08 21:45:39 +00:00
struct mlme_priv * pmlmepriv = & ( adapter - > mlmepriv ) ;
2013-05-19 04:28:07 +00:00
struct wlan_network * pnetwork = ( struct wlan_network * ) pbuf ;
struct wlan_network * cur_network = & ( pmlmepriv - > cur_network ) ;
2013-05-08 21:45:39 +00:00
struct wlan_network * pcur_wlan = NULL , * ptarget_wlan = NULL ;
2013-05-26 03:02:10 +00:00
unsigned int the_same_macaddr = false ;
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_info_ , ( " joinbss event call back received with res=%d \n " , pnetwork - > join_res ) ) ;
rtw_get_encrypt_decrypt_from_registrypriv ( adapter ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
if ( pmlmepriv - > assoc_ssid . SsidLength = = 0 )
2013-05-19 04:28:07 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " @@@@@ joinbss event call back for Any SSid \n " ) ) ;
2013-05-08 21:45:39 +00:00
else
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " @@@@@ rtw_joinbss_event_callback for SSid:%s \n " , pmlmepriv - > assoc_ssid . Ssid ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
the_same_macaddr = _rtw_memcmp ( pnetwork - > network . MacAddress , cur_network - > network . MacAddress , ETH_ALEN ) ;
pnetwork - > network . Length = get_WLAN_BSSID_EX_sz ( & pnetwork - > network ) ;
2013-06-03 19:52:18 +00:00
if ( pnetwork - > network . Length > sizeof ( WLAN_BSSID_EX ) ) {
2013-05-08 21:45:39 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " \n \n ***joinbss_evt_callback return a wrong bss *** \n \n " ) ) ;
2013-06-03 19:52:18 +00:00
goto ignore_nolock ;
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_enter_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
2013-05-19 04:28:07 +00:00
2013-05-09 04:09:18 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_info_ , ( " \n rtw_joinbss_event_callback !! _enter_critical \n " ) ) ;
2013-05-08 21:45:39 +00:00
2013-06-03 19:52:18 +00:00
if ( pnetwork - > join_res > 0 ) {
2013-05-08 21:45:39 +00:00
_enter_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
2013-06-21 18:41:29 +00:00
# ifdef REJOIN
2013-05-08 21:45:39 +00:00
retry = 0 ;
2013-06-21 18:41:29 +00:00
# endif
2013-06-03 19:52:18 +00:00
if ( check_fwstate ( pmlmepriv , _FW_UNDER_LINKING ) ) {
2013-07-09 22:38:46 +00:00
/* s1. find ptarget_wlan */
2013-06-03 19:52:18 +00:00
if ( check_fwstate ( pmlmepriv , _FW_LINKED ) ) {
if ( the_same_macaddr = = true ) {
2013-05-19 04:28:07 +00:00
ptarget_wlan = rtw_find_network ( & pmlmepriv - > scanned_queue , cur_network - > network . MacAddress ) ;
2013-06-03 19:52:18 +00:00
} else {
2013-05-08 21:45:39 +00:00
pcur_wlan = rtw_find_network ( & pmlmepriv - > scanned_queue , cur_network - > network . MacAddress ) ;
2013-06-03 19:52:18 +00:00
if ( pcur_wlan )
pcur_wlan - > fixed = false ;
2013-05-08 21:45:39 +00:00
pcur_sta = rtw_get_stainfo ( pstapriv , cur_network - > network . MacAddress ) ;
2013-05-09 04:04:25 +00:00
if ( pcur_sta ) {
2013-05-08 21:45:39 +00:00
_enter_critical_bh ( & ( pstapriv - > sta_hash_lock ) , & irqL2 ) ;
rtw_free_stainfo ( adapter , pcur_sta ) ;
_exit_critical_bh ( & ( pstapriv - > sta_hash_lock ) , & irqL2 ) ;
}
ptarget_wlan = rtw_find_network ( & pmlmepriv - > scanned_queue , pnetwork - > network . MacAddress ) ;
2013-06-03 19:52:18 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_STATION_STATE ) = = true ) {
if ( ptarget_wlan )
ptarget_wlan - > fixed = true ;
2013-05-08 21:45:39 +00:00
}
}
2013-06-03 19:52:18 +00:00
} else {
2013-05-08 21:45:39 +00:00
ptarget_wlan = rtw_find_network ( & pmlmepriv - > scanned_queue , pnetwork - > network . MacAddress ) ;
2013-05-26 03:02:10 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_STATION_STATE ) = = true ) {
2013-06-03 19:52:18 +00:00
if ( ptarget_wlan )
ptarget_wlan - > fixed = true ;
2013-05-08 21:45:39 +00:00
}
}
2013-05-19 04:28:07 +00:00
2013-07-09 22:38:46 +00:00
/* s2. update cur_network */
2013-06-03 19:52:18 +00:00
if ( ptarget_wlan ) {
2013-05-08 21:45:39 +00:00
rtw_joinbss_update_network ( adapter , ptarget_wlan , pnetwork ) ;
2013-06-03 19:52:18 +00:00
} else {
2013-05-08 21:45:39 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " Can't find ptarget_wlan when joinbss_event callback \n " ) ) ;
_exit_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
goto ignore_joinbss_callback ;
}
2013-05-19 04:28:07 +00:00
2013-07-09 22:38:46 +00:00
/* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */
2013-06-03 19:52:18 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_STATION_STATE ) = = true ) {
2013-05-08 21:45:39 +00:00
ptarget_sta = rtw_joinbss_update_stainfo ( adapter , pnetwork ) ;
2013-06-03 19:52:18 +00:00
if ( ptarget_sta = = NULL ) {
2013-05-08 21:45:39 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " Can't update stainfo when joinbss_event callback \n " ) ) ;
_exit_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
goto ignore_joinbss_callback ;
}
}
2013-07-09 22:38:46 +00:00
/* s4. indicate connect */
2013-06-03 19:52:18 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_STATION_STATE ) = = true ) {
2013-05-08 21:45:39 +00:00
rtw_indicate_connect ( adapter ) ;
2013-06-03 19:52:18 +00:00
} else {
2013-07-09 22:38:46 +00:00
/* adhoc mode will rtw_indicate_connect when rtw_stassoc_event_callback */
2013-05-08 21:45:39 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_info_ , ( " adhoc mode, fw_state:%x " , get_fwstate ( pmlmepriv ) ) ) ;
}
2013-07-09 22:38:46 +00:00
/* s5. Cancle assoc_timer */
2013-05-08 21:45:39 +00:00
_cancel_timer ( & pmlmepriv - > assoc_timer , & timer_cancelled ) ;
2013-05-19 04:28:07 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_info_ , ( " Cancle assoc_timer \n " ) ) ;
2013-06-03 19:52:18 +00:00
} else {
2013-05-19 04:28:07 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " rtw_joinbss_event_callback err: fw_state:%x " , get_fwstate ( pmlmepriv ) ) ) ;
2013-05-08 21:45:39 +00:00
_exit_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
goto ignore_joinbss_callback ;
}
2013-05-19 04:28:07 +00:00
_exit_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
2013-06-03 19:52:18 +00:00
} else if ( pnetwork - > join_res = = - 4 ) {
2013-05-08 21:45:39 +00:00
rtw_reset_securitypriv ( adapter ) ;
2013-05-19 04:28:07 +00:00
_set_timer ( & pmlmepriv - > assoc_timer , 1 ) ;
2013-05-08 21:45:39 +00:00
2013-06-03 19:52:18 +00:00
if ( ( check_fwstate ( pmlmepriv , _FW_UNDER_LINKING ) ) = = true ) {
2013-05-08 21:45:39 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " fail! clear _FW_UNDER_LINKING ^^^fw_state=%x \n " , get_fwstate ( pmlmepriv ) ) ) ;
_clr_fwstate_ ( pmlmepriv , _FW_UNDER_LINKING ) ;
2013-05-19 04:28:07 +00:00
}
2013-07-09 22:38:46 +00:00
} else { /* if join_res < 0 (join fails), then try again */
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
# ifdef REJOIN
res = _FAIL ;
2013-05-09 04:04:25 +00:00
if ( retry < 2 ) {
2013-05-08 21:45:39 +00:00
res = rtw_select_and_join_from_scanned_queue ( pmlmepriv ) ;
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " rtw_select_and_join_from_scanned_queue again! res:%d \n " , res ) ) ;
}
2013-06-03 19:52:18 +00:00
if ( res = = _SUCCESS ) {
2013-07-09 22:38:46 +00:00
/* extend time of assoc_timer */
2013-05-08 21:45:39 +00:00
_set_timer ( & pmlmepriv - > assoc_timer , MAX_JOIN_TIMEOUT ) ;
retry + + ;
2013-07-09 22:38:46 +00:00
} else if ( res = = 2 ) { /* there is no need to wait for join */
2013-05-08 21:45:39 +00:00
_clr_fwstate_ ( pmlmepriv , _FW_UNDER_LINKING ) ;
rtw_indicate_connect ( adapter ) ;
2013-06-03 19:52:18 +00:00
} else {
2013-05-09 04:09:18 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " Set Assoc_Timer = 1; can't find match ssid in scanned_q \n " ) ) ;
2013-05-08 21:45:39 +00:00
# endif
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_set_timer ( & pmlmepriv - > assoc_timer , 1 ) ;
_clr_fwstate_ ( pmlmepriv , _FW_UNDER_LINKING ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
# ifdef REJOIN
2013-05-19 04:28:07 +00:00
retry = 0 ;
2013-05-08 21:45:39 +00:00
}
# endif
}
ignore_joinbss_callback :
_exit_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
2013-06-03 19:52:18 +00:00
ignore_nolock :
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
void rtw_joinbss_event_callback ( _adapter * adapter , u8 * pbuf )
{
2013-05-19 04:28:07 +00:00
struct wlan_network * pnetwork = ( struct wlan_network * ) pbuf ;
2013-05-08 21:45:39 +00:00
_func_enter_ ;
mlmeext_joinbss_event_callback ( adapter , pnetwork - > join_res ) ;
rtw_os_xmit_schedule ( adapter ) ;
_func_exit_ ;
}
2013-06-03 19:52:18 +00:00
static u8 search_max_mac_id ( _adapter * padapter )
2013-05-08 21:45:39 +00:00
{
u8 mac_id , aid ;
2013-07-09 22:38:46 +00:00
# if (RATE_ADAPTIVE_SUPPORT==1) /* for 88E RA */
2013-05-08 21:45:39 +00:00
struct mlme_priv * pmlmepriv = & ( padapter - > mlmepriv ) ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct sta_priv * pstapriv = & padapter - > stapriv ;
2013-07-20 16:01:46 +00:00
# if defined (CONFIG_AP_MODE)
2013-05-19 04:28:07 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_AP_STATE ) ) {
2013-05-08 21:45:39 +00:00
for ( aid = ( pstapriv - > max_num_sta ) ; aid > 0 ; aid - - )
{
if ( pstapriv - > sta_aid [ aid - 1 ] ! = NULL )
break ;
}
mac_id = aid + 1 ;
}
else
# endif
2013-07-09 22:38:46 +00:00
{ /* adhoc id = 31~2 */
2013-05-08 21:45:39 +00:00
for ( mac_id = ( NUM_STA - 1 ) ; mac_id > = IBSS_START_MAC_ID ; mac_id - - )
{
if ( pmlmeinfo - > FW_sta_info [ mac_id ] . status = = 1 )
{
break ;
}
}
}
2013-05-19 04:28:07 +00:00
# endif
2013-05-08 21:45:39 +00:00
return mac_id ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
2013-07-09 22:38:46 +00:00
/* FOR AP ,AD-HOC mode */
2013-05-08 21:45:39 +00:00
void rtw_stassoc_hw_rpt ( _adapter * adapter , struct sta_info * psta )
{
u16 media_status ;
2013-05-09 04:04:25 +00:00
if ( psta = = NULL ) return ;
2013-05-08 21:45:39 +00:00
2013-07-09 22:38:46 +00:00
# if (RATE_ADAPTIVE_SUPPORT==1) /* for 88E RA */
2013-05-08 21:45:39 +00:00
{
2013-05-19 04:28:07 +00:00
u8 macid = search_max_mac_id ( adapter ) ;
2013-05-08 21:45:39 +00:00
rtw_hal_set_hwreg ( adapter , HW_VAR_TX_RPT_MAX_MACID , ( u8 * ) & macid ) ;
}
# endif
2013-07-09 22:38:46 +00:00
media_status = ( psta - > mac_id < < 8 ) | 1 ; /* MACID|OPMODE:1 connect */
2013-05-19 04:28:07 +00:00
rtw_hal_set_hwreg ( adapter , HW_VAR_H2C_MEDIA_STATUS_RPT , ( u8 * ) & media_status ) ;
2013-05-08 21:45:39 +00:00
}
void rtw_stassoc_event_callback ( _adapter * adapter , u8 * pbuf )
{
2013-05-19 04:28:07 +00:00
_irqL irqL ;
2013-05-08 21:45:39 +00:00
struct sta_info * psta ;
struct mlme_priv * pmlmepriv = & ( adapter - > mlmepriv ) ;
struct stassoc_event * pstassoc = ( struct stassoc_event * ) pbuf ;
2013-05-19 04:28:07 +00:00
struct wlan_network * cur_network = & ( pmlmepriv - > cur_network ) ;
2013-05-08 21:45:39 +00:00
struct wlan_network * ptarget_wlan = NULL ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-26 03:02:10 +00:00
if ( rtw_access_ctrl ( adapter , pstassoc - > macaddr ) = = false )
2013-05-08 21:45:39 +00:00
return ;
2013-07-20 16:01:46 +00:00
# if defined (CONFIG_AP_MODE)
2013-05-09 04:04:25 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_AP_STATE ) )
2013-05-08 21:45:39 +00:00
{
2013-05-19 04:28:07 +00:00
psta = rtw_get_stainfo ( & adapter - > stapriv , pstassoc - > macaddr ) ;
2013-05-09 04:04:25 +00:00
if ( psta )
2013-05-08 21:45:39 +00:00
{
2013-07-09 22:38:46 +00:00
/* bss_cap_update_on_sta_join(adapter, psta); */
/* sta_info_update(adapter, psta); */
2013-05-08 21:45:39 +00:00
ap_sta_info_defer_update ( adapter , psta ) ;
rtw_stassoc_hw_rpt ( adapter , psta ) ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
goto exit ;
2013-05-19 04:28:07 +00:00
}
# endif
2013-07-09 22:38:46 +00:00
/* for AD-HOC mode */
2013-05-19 04:28:07 +00:00
psta = rtw_get_stainfo ( & adapter - > stapriv , pstassoc - > macaddr ) ;
2013-05-09 04:04:25 +00:00
if ( psta ! = NULL )
2013-05-08 21:45:39 +00:00
{
2013-07-09 22:38:46 +00:00
/* the sta have been in sta_info_queue => do nothing */
2013-05-19 04:28:07 +00:00
2013-05-09 04:09:18 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " Error: rtw_stassoc_event_callback: sta has been in sta_hash_queue \n " ) ) ;
2013-05-19 04:28:07 +00:00
2013-07-09 22:38:46 +00:00
goto exit ; /* between drv has received this event before and fw have not yet to set key to CAM_ENTRY) */
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
psta = rtw_alloc_stainfo ( & adapter - > stapriv , pstassoc - > macaddr ) ;
2013-05-08 21:45:39 +00:00
if ( psta = = NULL ) {
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " Can't alloc sta_info when rtw_stassoc_event_callback \n " ) ) ;
goto exit ;
2013-05-19 04:28:07 +00:00
}
2013-07-09 22:38:46 +00:00
/* to do : init sta_info variable */
2013-05-08 21:45:39 +00:00
psta - > qos_option = 0 ;
psta - > mac_id = ( uint ) pstassoc - > cam_id ;
2013-07-09 22:38:46 +00:00
/* psta->aid = (uint)pstassoc->cam_id; */
2013-05-25 23:35:42 +00:00
DBG_88E ( " %s \n " , __func__ ) ;
2013-07-09 22:38:46 +00:00
/* for ad-hoc mode */
2013-05-26 03:02:10 +00:00
rtw_hal_set_odm_var ( adapter , HAL_ODM_STA_INFO , psta , true ) ;
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
rtw_stassoc_hw_rpt ( adapter , psta ) ;
2013-05-09 04:04:25 +00:00
if ( adapter - > securitypriv . dot11AuthAlgrthm = = dot11AuthAlgrthm_8021X )
2013-05-08 21:45:39 +00:00
psta - > dot118021XPrivacy = adapter - > securitypriv . dot11PrivacyAlgrthm ;
2013-05-19 04:28:07 +00:00
2013-05-26 03:02:10 +00:00
psta - > ieee8021x_blocked = false ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_enter_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
2013-05-26 03:02:10 +00:00
if ( ( check_fwstate ( pmlmepriv , WIFI_ADHOC_MASTER_STATE ) = = true ) | |
( check_fwstate ( pmlmepriv , WIFI_ADHOC_STATE ) = = true ) )
2013-05-08 21:45:39 +00:00
{
2013-05-09 04:04:25 +00:00
if ( adapter - > stapriv . asoc_sta_count = = 2 )
2013-05-08 21:45:39 +00:00
{
_enter_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
ptarget_wlan = rtw_find_network ( & pmlmepriv - > scanned_queue , cur_network - > network . MacAddress ) ;
2013-05-26 03:02:10 +00:00
if ( ptarget_wlan ) ptarget_wlan - > fixed = true ;
2013-05-08 21:45:39 +00:00
_exit_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
2013-07-09 22:38:46 +00:00
/* a sta + bc/mc_stainfo (not Ibss_stainfo) */
2013-05-08 21:45:39 +00:00
rtw_indicate_connect ( adapter ) ;
}
}
_exit_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
mlmeext_sta_add_event_callback ( adapter , psta ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
exit :
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
void rtw_stadel_event_callback ( _adapter * adapter , u8 * pbuf )
{
_irqL irqL , irqL2 ;
int mac_id = - 1 ;
struct sta_info * psta ;
struct wlan_network * pwlan = NULL ;
WLAN_BSSID_EX * pdev_network = NULL ;
u8 * pibss = NULL ;
struct mlme_priv * pmlmepriv = & ( adapter - > mlmepriv ) ;
2013-05-19 04:28:07 +00:00
struct stadel_event * pstadel = ( struct stadel_event * ) pbuf ;
struct sta_priv * pstapriv = & adapter - > stapriv ;
2013-05-08 21:45:39 +00:00
struct wlan_network * tgt_network = & ( pmlmepriv - > cur_network ) ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
psta = rtw_get_stainfo ( & adapter - > stapriv , pstadel - > macaddr ) ;
2013-05-09 04:04:25 +00:00
if ( psta )
2013-05-08 21:45:39 +00:00
mac_id = psta - > mac_id ;
else
mac_id = pstadel - > mac_id ;
2013-05-30 20:51:53 +00:00
DBG_88E ( " %s(mac_id=%d)= %pM \n " , __func__ , mac_id , pstadel - > macaddr ) ;
2013-05-08 21:45:39 +00:00
2013-05-09 04:04:25 +00:00
if ( mac_id > = 0 ) {
2013-05-08 21:45:39 +00:00
u16 media_status ;
2013-07-09 22:38:46 +00:00
media_status = ( mac_id < < 8 ) | 0 ; /* MACID|OPMODE:0 means disconnect */
/* for STA,AP,ADHOC mode, report disconnect stauts to FW */
2013-05-08 21:45:39 +00:00
rtw_hal_set_hwreg ( adapter , HW_VAR_H2C_MEDIA_STATUS_RPT , ( u8 * ) & media_status ) ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
2013-05-09 04:04:25 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_AP_STATE ) )
2013-05-08 21:45:39 +00:00
return ;
mlmeext_sta_del_event_callback ( adapter ) ;
_enter_critical_bh ( & pmlmepriv - > lock , & irqL2 ) ;
2013-05-09 04:04:25 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_STATION_STATE ) )
2013-05-08 21:45:39 +00:00
{
2013-05-09 04:04:25 +00:00
if ( pmlmepriv - > to_roaming > 0 )
2013-07-09 22:38:46 +00:00
pmlmepriv - > to_roaming - - ; /* this stadel_event is caused by roaming, decrease to_roaming */
2013-05-09 04:04:25 +00:00
else if ( pmlmepriv - > to_roaming = = 0 )
2013-05-08 21:45:39 +00:00
pmlmepriv - > to_roaming = adapter - > registrypriv . max_roaming_times ;
2013-05-09 04:04:25 +00:00
if ( * ( ( unsigned short * ) ( pstadel - > rsvd ) ) ! = WLAN_REASON_EXPIRATION_CHK )
2013-07-09 22:38:46 +00:00
pmlmepriv - > to_roaming = 0 ; /* don't roam */
2013-05-08 21:45:39 +00:00
rtw_free_uc_swdec_pending_queue ( adapter ) ;
rtw_free_assoc_resources ( adapter , 1 ) ;
rtw_indicate_disconnect ( adapter ) ;
_enter_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
2013-07-09 22:38:46 +00:00
/* remove the network entry in scanned_queue */
2013-05-19 04:28:07 +00:00
pwlan = rtw_find_network ( & pmlmepriv - > scanned_queue , tgt_network - > network . MacAddress ) ;
if ( pwlan ) {
2013-05-26 03:02:10 +00:00
pwlan - > fixed = false ;
2013-05-08 21:45:39 +00:00
rtw_free_network_nolock ( pmlmepriv , pwlan ) ;
}
_exit_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
_rtw_roaming ( adapter , tgt_network ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_ADHOC_MASTER_STATE ) | |
2013-05-08 21:45:39 +00:00
check_fwstate ( pmlmepriv , WIFI_ADHOC_STATE ) )
{
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_enter_critical_bh ( & ( pstapriv - > sta_hash_lock ) , & irqL ) ;
rtw_free_stainfo ( adapter , psta ) ;
_exit_critical_bh ( & ( pstapriv - > sta_hash_lock ) , & irqL ) ;
2013-05-19 04:28:07 +00:00
2013-07-09 22:38:46 +00:00
if ( adapter - > stapriv . asoc_sta_count = = 1 ) /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
2013-05-19 04:28:07 +00:00
{
2013-05-08 21:45:39 +00:00
_enter_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
2013-07-09 22:38:46 +00:00
/* free old ibss network */
2013-05-08 21:45:39 +00:00
pwlan = rtw_find_network ( & pmlmepriv - > scanned_queue , tgt_network - > network . MacAddress ) ;
2013-05-19 04:28:07 +00:00
if ( pwlan )
2013-05-08 21:45:39 +00:00
{
2013-05-26 03:02:10 +00:00
pwlan - > fixed = false ;
2013-05-19 04:28:07 +00:00
rtw_free_network_nolock ( pmlmepriv , pwlan ) ;
2013-05-08 21:45:39 +00:00
}
_exit_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
2013-07-09 22:38:46 +00:00
/* re-create ibss */
2013-05-19 04:28:07 +00:00
pdev_network = & ( adapter - > registrypriv . dev_network ) ;
2013-05-08 21:45:39 +00:00
pibss = adapter - > registrypriv . dev_network . MacAddress ;
_rtw_memcpy ( pdev_network , & tgt_network - > network , get_WLAN_BSSID_EX_sz ( & tgt_network - > network ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_rtw_memset ( & pdev_network - > Ssid , 0 , sizeof ( NDIS_802_11_SSID ) ) ;
_rtw_memcpy ( & pdev_network - > Ssid , & pmlmepriv - > assoc_ssid , sizeof ( NDIS_802_11_SSID ) ) ;
2013-05-19 04:28:07 +00:00
rtw_update_registrypriv_dev_network ( adapter ) ;
2013-05-08 21:45:39 +00:00
rtw_generate_random_ibss ( pibss ) ;
2013-05-19 04:28:07 +00:00
2013-05-09 04:04:25 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_ADHOC_STATE ) )
2013-05-08 21:45:39 +00:00
{
set_fwstate ( pmlmepriv , WIFI_ADHOC_MASTER_STATE ) ;
_clr_fwstate_ ( pmlmepriv , WIFI_ADHOC_STATE ) ;
}
2013-05-09 04:04:25 +00:00
if ( rtw_createbss_cmd ( adapter ) ! = _SUCCESS )
2013-05-08 21:45:39 +00:00
{
2013-05-19 04:28:07 +00:00
RT_TRACE ( _module_rtl871x_ioctl_set_c_ , _drv_err_ , ( " ***Error=>stadel_event_callback: rtw_createbss_cmd status FAIL*** \n " ) ) ;
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_exit_critical_bh ( & pmlmepriv - > lock , & irqL2 ) ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
void rtw_cpwm_event_callback ( PADAPTER padapter , u8 * pbuf )
{
_func_enter_ ;
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " +rtw_cpwm_event_callback !!! \n " ) ) ;
_func_exit_ ;
}
/*
* _rtw_join_timeout_handler - Timeout / faliure handler for CMD JoinBss
* @ adapter : pointer to _adapter structure
*/
void _rtw_join_timeout_handler ( _adapter * adapter )
{
_irqL irqL ;
struct mlme_priv * pmlmepriv = & adapter - > mlmepriv ;
int do_join_r ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
2013-05-25 23:35:42 +00:00
DBG_88E ( " %s, fw_state=%x \n " , __func__ , get_fwstate ( pmlmepriv ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-09 04:04:25 +00:00
if ( adapter - > bDriverStopped | | adapter - > bSurpriseRemoved )
2013-05-08 21:45:39 +00:00
return ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_enter_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
2013-07-09 22:38:46 +00:00
if ( pmlmepriv - > to_roaming > 0 ) { /* join timeout caused by roaming */
2013-05-09 04:04:25 +00:00
while ( 1 ) {
2013-05-08 21:45:39 +00:00
pmlmepriv - > to_roaming - - ;
2013-07-09 22:38:46 +00:00
if ( pmlmepriv - > to_roaming ! = 0 ) { /* try another , */
2013-05-25 23:35:42 +00:00
DBG_88E ( " %s try another roaming \n " , __func__ ) ;
2013-05-09 04:04:25 +00:00
if ( _SUCCESS ! = ( do_join_r = rtw_do_join ( adapter ) ) ) {
2013-05-25 23:35:42 +00:00
DBG_88E ( " %s roaming do_join return %d \n " , __func__ , do_join_r ) ;
2013-05-08 21:45:39 +00:00
continue ;
}
break ;
} else {
2013-05-25 23:35:42 +00:00
DBG_88E ( " %s We've try roaming but fail \n " , __func__ ) ;
2013-05-08 21:45:39 +00:00
rtw_indicate_disconnect ( adapter ) ;
break ;
}
}
2013-07-13 03:38:53 +00:00
} else {
2013-05-08 21:45:39 +00:00
rtw_indicate_disconnect ( adapter ) ;
2013-07-09 22:38:46 +00:00
free_scanqueue ( pmlmepriv ) ; /* */
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
_exit_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
_func_exit_ ;
}
/*
* rtw_scan_timeout_handler - Timeout / Faliure handler for CMD SiteSurvey
* @ adapter : pointer to _adapter structure
*/
void rtw_scan_timeout_handler ( _adapter * adapter )
2013-05-19 04:28:07 +00:00
{
2013-05-08 21:45:39 +00:00
_irqL irqL ;
struct mlme_priv * pmlmepriv = & adapter - > mlmepriv ;
2013-05-19 04:28:07 +00:00
2013-05-25 23:35:42 +00:00
DBG_88E ( FUNC_ADPT_FMT " fw_state=%x \n " , FUNC_ADPT_ARG ( adapter ) , get_fwstate ( pmlmepriv ) ) ;
2013-05-08 21:45:39 +00:00
_enter_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_clr_fwstate_ ( pmlmepriv , _FW_UNDER_SURVEY ) ;
_exit_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
2013-05-26 03:02:10 +00:00
rtw_indicate_scan_done ( adapter , true ) ;
2013-05-08 21:45:39 +00:00
}
static void rtw_auto_scan_handler ( _adapter * padapter )
{
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
struct pwrctrl_priv * pwrctrlpriv = & padapter - > pwrctrlpriv ;
2013-07-09 22:38:46 +00:00
/* auto site survey per 60sec */
2013-05-09 04:04:25 +00:00
if ( pmlmepriv - > scan_interval > 0 )
2013-05-08 21:45:39 +00:00
{
pmlmepriv - > scan_interval - - ;
2013-05-09 04:04:25 +00:00
if ( pmlmepriv - > scan_interval = = 0 )
2013-05-08 21:45:39 +00:00
{
2013-05-25 23:35:42 +00:00
DBG_88E ( " %s \n " , __func__ ) ;
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
rtw_set_802_11_bssid_list_scan ( padapter , NULL , 0 ) ;
2013-07-09 22:38:46 +00:00
pmlmepriv - > scan_interval = SCAN_INTERVAL ; /* 30*2 sec = 60sec */
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
}
void rtw_dynamic_check_timer_handlder ( _adapter * adapter )
{
# ifdef CONFIG_AP_MODE
struct mlme_priv * pmlmepriv = & adapter - > mlmepriv ;
2013-07-09 22:38:46 +00:00
# endif /* CONFIG_AP_MODE */
2013-05-08 21:45:39 +00:00
struct registry_priv * pregistrypriv = & adapter - > registrypriv ;
2013-05-09 04:04:25 +00:00
if ( ! adapter )
2013-05-19 04:28:07 +00:00
return ;
# if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST)
2013-05-09 04:04:25 +00:00
if ( adapter - > HalFunc . hal_checke_bt_hang )
2013-05-08 21:45:39 +00:00
adapter - > HalFunc . hal_checke_bt_hang ( adapter ) ;
# endif
2013-05-26 03:02:10 +00:00
if ( adapter - > hw_init_completed = = false )
2013-05-08 21:45:39 +00:00
return ;
2013-05-26 03:02:10 +00:00
if ( ( adapter - > bDriverStopped = = true ) | | ( adapter - > bSurpriseRemoved = = true ) )
2013-05-08 21:45:39 +00:00
return ;
2013-05-19 04:28:07 +00:00
2013-05-26 03:02:10 +00:00
if ( adapter - > net_closed = = true )
2013-05-08 21:45:39 +00:00
return ;
rtw_dynamic_chk_wk_cmd ( adapter ) ;
2013-05-09 04:04:25 +00:00
if ( pregistrypriv - > wifi_spec = = 1 )
2013-05-19 04:28:07 +00:00
{
2013-05-08 21:45:39 +00:00
# ifdef CONFIG_P2P
struct wifidirect_info * pwdinfo = & adapter - > wdinfo ;
2013-05-09 04:04:25 +00:00
if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_NONE ) )
2013-05-19 04:28:07 +00:00
# endif
2013-05-08 21:45:39 +00:00
{
2013-07-09 22:38:46 +00:00
/* auto site survey */
2013-05-08 21:45:39 +00:00
rtw_auto_scan_handler ( adapter ) ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
}
# if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
rcu_read_lock ( ) ;
2013-07-09 22:38:46 +00:00
# endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) */
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
# if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
if ( adapter - > pnetdev - > br_port
2013-07-11 01:10:20 +00:00
& & ( check_fwstate ( pmlmepriv , WIFI_STATION_STATE | WIFI_ADHOC_STATE ) = = true ) )
2013-07-09 22:38:46 +00:00
# else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
2013-05-09 04:04:25 +00:00
if ( rcu_dereference ( adapter - > pnetdev - > rx_handler_data )
2013-05-26 03:02:10 +00:00
& & ( check_fwstate ( pmlmepriv , WIFI_STATION_STATE | WIFI_ADHOC_STATE ) = = true ) )
2013-07-11 01:10:20 +00:00
# endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
2013-05-08 21:45:39 +00:00
{
2013-07-09 22:38:46 +00:00
/* expire NAT2.5 entry */
2013-05-08 21:45:39 +00:00
nat25_db_expire ( adapter ) ;
if ( adapter - > pppoe_connection_in_progress > 0 ) {
adapter - > pppoe_connection_in_progress - - ;
}
2013-05-19 04:28:07 +00:00
2013-07-09 22:38:46 +00:00
/* due to rtw_dynamic_check_timer_handlder() is called every 2 seconds */
2013-05-08 21:45:39 +00:00
if ( adapter - > pppoe_connection_in_progress > 0 ) {
adapter - > pppoe_connection_in_progress - - ;
}
}
# if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
rcu_read_unlock ( ) ;
2013-07-09 22:38:46 +00:00
# endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) */
2013-05-08 21:45:39 +00:00
}
# if defined(IEEE80211_SCAN_RESULT_EXPIRE)
2013-07-09 22:38:46 +00:00
# define RTW_SCAN_RESULT_EXPIRE IEEE80211_SCAN_RESULT_EXPIRE / HZ*1000 -1000 /* 3000 -1000 */
2013-05-08 21:45:39 +00:00
# else
# define RTW_SCAN_RESULT_EXPIRE 2000
# endif
/*
* Select a new join candidate from the original @ param candidate and @ param competitor
2013-05-26 03:02:10 +00:00
* @ return true : candidate is updated
* @ return false : candidate is not updated
2013-05-08 21:45:39 +00:00
*/
static int rtw_check_join_candidate ( struct mlme_priv * pmlmepriv
, struct wlan_network * * candidate , struct wlan_network * competitor )
{
2013-05-26 03:02:10 +00:00
int updated = false ;
2013-05-08 21:45:39 +00:00
_adapter * adapter = container_of ( pmlmepriv , _adapter , mlmepriv ) ;
2013-07-09 22:38:46 +00:00
/* check bssid, if needed */
2013-05-26 03:02:10 +00:00
if ( pmlmepriv - > assoc_by_bssid = = true ) {
if ( _rtw_memcmp ( competitor - > network . MacAddress , pmlmepriv - > assoc_bssid , ETH_ALEN ) = = false )
2013-05-08 21:45:39 +00:00
goto exit ;
}
2013-07-09 22:38:46 +00:00
/* check ssid, if needed */
2013-05-09 04:04:25 +00:00
if ( pmlmepriv - > assoc_ssid . Ssid & & pmlmepriv - > assoc_ssid . SsidLength ) {
if ( competitor - > network . Ssid . SsidLength ! = pmlmepriv - > assoc_ssid . SsidLength
2013-05-26 03:02:10 +00:00
| | _rtw_memcmp ( competitor - > network . Ssid . Ssid , pmlmepriv - > assoc_ssid . Ssid , pmlmepriv - > assoc_ssid . SsidLength ) = = false
2013-05-08 21:45:39 +00:00
)
goto exit ;
}
2013-05-26 03:02:10 +00:00
if ( rtw_is_desired_network ( adapter , competitor ) = = false )
2013-05-08 21:45:39 +00:00
goto exit ;
2013-05-09 04:04:25 +00:00
if ( pmlmepriv - > to_roaming ) {
if ( rtw_get_passing_time_ms ( ( u32 ) competitor - > last_scanned ) > = RTW_SCAN_RESULT_EXPIRE
2013-05-26 03:02:10 +00:00
| | is_same_ess ( & competitor - > network , & pmlmepriv - > cur_network . network ) = = false
2013-05-08 21:45:39 +00:00
)
goto exit ;
}
2013-05-19 04:28:07 +00:00
2013-05-09 04:04:25 +00:00
if ( * candidate = = NULL | | ( * candidate ) - > network . Rssi < competitor - > network . Rssi )
2013-05-08 21:45:39 +00:00
{
* candidate = competitor ;
2013-05-26 03:02:10 +00:00
updated = true ;
2013-05-08 21:45:39 +00:00
}
2013-05-09 04:04:25 +00:00
if ( updated ) {
2013-05-25 23:35:42 +00:00
DBG_88E ( " [by_bssid:%u][assoc_ssid:%s] "
2013-05-30 20:51:53 +00:00
" new candidate: %s(%pM rssi:%d \n " ,
2013-05-08 21:45:39 +00:00
pmlmepriv - > assoc_by_bssid ,
pmlmepriv - > assoc_ssid . Ssid ,
( * candidate ) - > network . Ssid . Ssid ,
2013-05-30 20:51:53 +00:00
( * candidate ) - > network . MacAddress ,
2013-06-03 19:52:18 +00:00
( int ) ( * candidate ) - > network . Rssi ) ;
DBG_88E ( " [to_roaming:%u] \n " , pmlmepriv - > to_roaming ) ;
2013-05-08 21:45:39 +00:00
}
exit :
return updated ;
}
/*
Calling context :
The caller of the sub - routine will be in critical section . . .
The caller must hold the following spinlock
pmlmepriv - > lock
*/
int rtw_select_and_join_from_scanned_queue ( struct mlme_priv * pmlmepriv )
{
_irqL irqL ;
int ret ;
_list * phead ;
2013-05-19 04:28:07 +00:00
_adapter * adapter ;
2013-05-08 21:45:39 +00:00
_queue * queue = & ( pmlmepriv - > scanned_queue ) ;
struct wlan_network * pnetwork = NULL ;
struct wlan_network * candidate = NULL ;
2013-05-26 03:02:10 +00:00
u8 bSupportAntDiv = false ;
2013-05-08 21:45:39 +00:00
_func_enter_ ;
_enter_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
2013-05-19 04:28:07 +00:00
phead = get_list_head ( queue ) ;
2013-05-08 21:45:39 +00:00
adapter = ( _adapter * ) pmlmepriv - > nic_hdl ;
pmlmepriv - > pscanned = get_next ( phead ) ;
while ( ! rtw_end_of_queue_search ( phead , pmlmepriv - > pscanned ) ) {
pnetwork = LIST_CONTAINOR ( pmlmepriv - > pscanned , struct wlan_network , list ) ;
2013-05-09 04:04:25 +00:00
if ( pnetwork = = NULL ) {
2013-05-09 16:23:32 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " %s return _FAIL:(pnetwork==NULL) \n " , __func__ ) ) ;
2013-05-08 21:45:39 +00:00
ret = _FAIL ;
goto exit ;
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
pmlmepriv - > pscanned = get_next ( pmlmepriv - > pscanned ) ;
rtw_check_join_candidate ( pmlmepriv , & candidate , pnetwork ) ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
2013-05-09 04:04:25 +00:00
if ( candidate = = NULL ) {
2013-05-25 23:35:42 +00:00
DBG_88E ( " %s: return _FAIL(candidate == NULL) \n " , __func__ ) ;
2013-05-08 21:45:39 +00:00
# ifdef CONFIG_WOWLAN
_clr_fwstate_ ( pmlmepriv , _FW_LINKED | _FW_UNDER_LINKING ) ;
# endif
ret = _FAIL ;
goto exit ;
} else {
2013-05-30 20:51:53 +00:00
DBG_88E ( " %s: candidate: %s(%pM ch:%u) \n " , __func__ ,
candidate - > network . Ssid . Ssid , candidate - > network . MacAddress ,
2013-05-08 21:45:39 +00:00
candidate - > network . Configuration . DSConfig ) ;
}
2013-05-19 04:28:07 +00:00
2013-07-09 22:38:46 +00:00
/* check for situation of _FW_LINKED */
2013-05-30 20:51:53 +00:00
if ( check_fwstate ( pmlmepriv , _FW_LINKED ) = = true ) {
2013-05-25 23:35:42 +00:00
DBG_88E ( " %s: _FW_LINKED while ask_for_joinbss!!! \n " , __func__ ) ;
2013-05-08 21:45:39 +00:00
2013-05-30 20:51:53 +00:00
rtw_disassoc_cmd ( adapter , 0 , true ) ;
rtw_indicate_disconnect ( adapter ) ;
rtw_free_assoc_resources ( adapter , 0 ) ;
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
rtw_hal_get_def_var ( adapter , HAL_DEF_IS_SUPPORT_ANT_DIV , & ( bSupportAntDiv ) ) ;
2013-05-26 03:02:10 +00:00
if ( true = = bSupportAntDiv )
2013-05-08 21:45:39 +00:00
{
u8 CurrentAntenna ;
2013-05-19 04:28:07 +00:00
rtw_hal_get_def_var ( adapter , HAL_DEF_CURRENT_ANTENNA , & ( CurrentAntenna ) ) ;
2013-05-25 23:35:42 +00:00
DBG_88E ( " #### Opt_Ant_(%s) , cur_Ant(%s) \n " ,
2013-05-08 21:45:39 +00:00
( 2 = = candidate - > network . PhyInfo . Optimum_antenna ) ? " A " : " B " ,
( 2 = = CurrentAntenna ) ? " A " : " B "
) ;
}
ret = rtw_joinbss_cmd ( adapter , candidate ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
exit :
_exit_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
_func_exit_ ;
return ret ;
}
sint rtw_set_auth ( _adapter * adapter , struct security_priv * psecuritypriv )
{
struct cmd_obj * pcmd ;
2013-05-19 04:28:07 +00:00
struct setauth_parm * psetauthparm ;
2013-05-08 21:45:39 +00:00
struct cmd_priv * pcmdpriv = & ( adapter - > cmdpriv ) ;
sint res = _SUCCESS ;
2013-05-19 04:28:07 +00:00
_func_enter_ ;
2013-05-08 21:45:39 +00:00
pcmd = ( struct cmd_obj * ) rtw_zmalloc ( sizeof ( struct cmd_obj ) ) ;
2013-05-09 04:04:25 +00:00
if ( pcmd = = NULL ) {
2013-07-09 22:38:46 +00:00
res = _FAIL ; /* try again */
2013-05-08 21:45:39 +00:00
goto exit ;
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
psetauthparm = ( struct setauth_parm * ) rtw_zmalloc ( sizeof ( struct setauth_parm ) ) ;
2013-05-09 04:04:25 +00:00
if ( psetauthparm = = NULL ) {
2013-05-08 21:45:39 +00:00
rtw_mfree ( ( unsigned char * ) pcmd , sizeof ( struct cmd_obj ) ) ;
res = _FAIL ;
goto exit ;
}
_rtw_memset ( psetauthparm , 0 , sizeof ( struct setauth_parm ) ) ;
psetauthparm - > mode = ( unsigned char ) psecuritypriv - > dot11AuthAlgrthm ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
pcmd - > cmdcode = _SetAuth_CMD_ ;
2013-05-19 04:28:07 +00:00
pcmd - > parmbuf = ( unsigned char * ) psetauthparm ;
pcmd - > cmdsz = ( sizeof ( struct setauth_parm ) ) ;
2013-05-08 21:45:39 +00:00
pcmd - > rsp = NULL ;
pcmd - > rspsz = 0 ;
_rtw_init_listhead ( & pcmd - > list ) ;
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " after enqueue set_auth_cmd, auth_mode=%x \n " , psecuritypriv - > dot11AuthAlgrthm ) ) ;
res = rtw_enqueue_cmd ( pcmdpriv , pcmd ) ;
exit :
_func_exit_ ;
return res ;
}
sint rtw_set_key ( _adapter * adapter , struct security_priv * psecuritypriv , sint keyid , u8 set_tx )
{
u8 keylen ;
struct cmd_obj * pcmd ;
struct setkey_parm * psetkeyparm ;
struct cmd_priv * pcmdpriv = & ( adapter - > cmdpriv ) ;
struct mlme_priv * pmlmepriv = & ( adapter - > mlmepriv ) ;
sint res = _SUCCESS ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_func_enter_ ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
pcmd = ( struct cmd_obj * ) rtw_zmalloc ( sizeof ( struct cmd_obj ) ) ;
2013-05-09 04:04:25 +00:00
if ( pcmd = = NULL ) {
2013-07-09 22:38:46 +00:00
res = _FAIL ; /* try again */
2013-05-08 21:45:39 +00:00
goto exit ;
}
psetkeyparm = ( struct setkey_parm * ) rtw_zmalloc ( sizeof ( struct setkey_parm ) ) ;
2013-05-09 04:04:25 +00:00
if ( psetkeyparm = = NULL ) {
2013-05-08 21:45:39 +00:00
rtw_mfree ( ( unsigned char * ) pcmd , sizeof ( struct cmd_obj ) ) ;
res = _FAIL ;
goto exit ;
}
_rtw_memset ( psetkeyparm , 0 , sizeof ( struct setkey_parm ) ) ;
2013-05-19 04:28:07 +00:00
if ( psecuritypriv - > dot11AuthAlgrthm = = dot11AuthAlgrthm_8021X ) {
psetkeyparm - > algorithm = ( unsigned char ) psecuritypriv - > dot118021XGrpPrivacy ;
2013-05-09 04:09:18 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " \n rtw_set_key: psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy=%d \n " , psetkeyparm - > algorithm ) ) ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
else {
psetkeyparm - > algorithm = ( u8 ) psecuritypriv - > dot11PrivacyAlgrthm ;
2013-05-09 04:09:18 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " \n rtw_set_key: psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm=%d \n " , psetkeyparm - > algorithm ) ) ;
2013-05-08 21:45:39 +00:00
}
2013-07-09 22:38:46 +00:00
psetkeyparm - > keyid = ( u8 ) keyid ; /* 0~3 */
2013-05-08 21:45:39 +00:00
psetkeyparm - > set_tx = set_tx ;
pmlmepriv - > key_mask | = BIT ( psetkeyparm - > keyid ) ;
# ifdef CONFIG_AUTOSUSPEND
2013-05-26 03:02:10 +00:00
if ( true = = adapter - > pwrctrlpriv . bInternalAutoSuspend )
2013-05-08 21:45:39 +00:00
{
adapter - > pwrctrlpriv . wepkeymask = pmlmepriv - > key_mask ;
2013-05-25 23:35:42 +00:00
DBG_88E ( " ....AutoSuspend pwrctrlpriv.wepkeymask(%x) \n " , adapter - > pwrctrlpriv . wepkeymask ) ;
2013-05-08 21:45:39 +00:00
}
# endif
2013-05-25 23:35:42 +00:00
DBG_88E ( " ==> rtw_set_key algorithm(%x),keyid(%x),key_mask(%x) \n " , psetkeyparm - > algorithm , psetkeyparm - > keyid , pmlmepriv - > key_mask ) ;
2013-05-09 04:09:18 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " \n rtw_set_key: psetkeyparm->algorithm=%d psetkeyparm->keyid=(u8)keyid=%d \n " , psetkeyparm - > algorithm , keyid ) ) ;
2013-05-08 21:45:39 +00:00
2013-05-09 04:04:25 +00:00
switch ( psetkeyparm - > algorithm ) {
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
case _WEP40_ :
keylen = 5 ;
_rtw_memcpy ( & ( psetkeyparm - > key [ 0 ] ) , & ( psecuritypriv - > dot11DefKey [ keyid ] . skey [ 0 ] ) , keylen ) ;
break ;
case _WEP104_ :
keylen = 13 ;
_rtw_memcpy ( & ( psetkeyparm - > key [ 0 ] ) , & ( psecuritypriv - > dot11DefKey [ keyid ] . skey [ 0 ] ) , keylen ) ;
break ;
case _TKIP_ :
2013-05-19 04:28:07 +00:00
keylen = 16 ;
2013-05-08 21:45:39 +00:00
_rtw_memcpy ( & psetkeyparm - > key , & psecuritypriv - > dot118021XGrpKey [ keyid ] , keylen ) ;
psetkeyparm - > grpkey = 1 ;
break ;
case _AES_ :
2013-05-19 04:28:07 +00:00
keylen = 16 ;
2013-05-08 21:45:39 +00:00
_rtw_memcpy ( & psetkeyparm - > key , & psecuritypriv - > dot118021XGrpKey [ keyid ] , keylen ) ;
psetkeyparm - > grpkey = 1 ;
break ;
default :
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " \n rtw_set_key:psecuritypriv->dot11PrivacyAlgrthm = %x (must be 1 or 2 or 4 or 5) \n " , psecuritypriv - > dot11PrivacyAlgrthm ) ) ;
res = _FAIL ;
goto exit ;
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
pcmd - > cmdcode = _SetKey_CMD_ ;
2013-05-19 04:28:07 +00:00
pcmd - > parmbuf = ( u8 * ) psetkeyparm ;
pcmd - > cmdsz = ( sizeof ( struct setkey_parm ) ) ;
2013-05-08 21:45:39 +00:00
pcmd - > rsp = NULL ;
pcmd - > rspsz = 0 ;
_rtw_init_listhead ( & pcmd - > list ) ;
2013-07-09 22:38:46 +00:00
/* _rtw_init_sema(&(pcmd->cmd_sem), 0); */
2013-05-08 21:45:39 +00:00
res = rtw_enqueue_cmd ( pcmdpriv , pcmd ) ;
exit :
_func_exit_ ;
return res ;
}
2013-07-09 22:38:46 +00:00
/* adjust IEs for rtw_joinbss_cmd in WMM */
2013-05-08 21:45:39 +00:00
int rtw_restruct_wmm_ie ( _adapter * adapter , u8 * in_ie , u8 * out_ie , uint in_len , uint initial_out_len )
{
unsigned int ielength = 0 ;
unsigned int i , j ;
2013-07-09 22:38:46 +00:00
i = 12 ; /* after the fixed IE */
2013-05-09 04:04:25 +00:00
while ( i < in_len )
2013-05-08 21:45:39 +00:00
{
2013-05-19 04:28:07 +00:00
ielength = initial_out_len ;
2013-07-09 22:38:46 +00:00
if ( in_ie [ i ] = = 0xDD & & in_ie [ i + 2 ] = = 0x00 & & in_ie [ i + 3 ] = = 0x50 & & in_ie [ i + 4 ] = = 0xF2 & & in_ie [ i + 5 ] = = 0x02 & & i + 5 < in_len ) /* WMM element ID and OUI */
2013-05-08 21:45:39 +00:00
{
2013-07-09 22:38:46 +00:00
/* Append WMM IE to the last index of out_ie */
2013-05-19 04:28:07 +00:00
2013-06-21 18:41:29 +00:00
for ( j = i ; j < i + 9 ; j + + ) {
2013-05-08 21:45:39 +00:00
out_ie [ ielength ] = in_ie [ j ] ;
ielength + + ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
out_ie [ initial_out_len + 1 ] = 0x07 ;
out_ie [ initial_out_len + 6 ] = 0x00 ;
out_ie [ initial_out_len + 8 ] = 0x00 ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
break ;
}
2013-07-09 22:38:46 +00:00
i + = ( in_ie [ i + 1 ] + 2 ) ; /* to the next IE element */
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
return ielength ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
2013-07-09 22:38:46 +00:00
/* */
/* Ported from 8185: IsInPreAuthKeyList(). (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.) */
/* Added by Annie, 2006-05-07. */
/* */
/* Search by BSSID, */
/* Return Value: */
/* -1 :if there is no pre-auth key in the table */
/* >=0 :if there is pre-auth key, and return the entry id */
/* */
/* */
2013-05-08 21:45:39 +00:00
static int SecIsInPMKIDList ( _adapter * Adapter , u8 * bssid )
{
struct security_priv * psecuritypriv = & Adapter - > securitypriv ;
int i = 0 ;
do
{
2013-05-19 04:28:07 +00:00
if ( ( psecuritypriv - > PMKIDList [ i ] . bUsed ) & &
2013-05-26 03:02:10 +00:00
( _rtw_memcmp ( psecuritypriv - > PMKIDList [ i ] . Bssid , bssid , ETH_ALEN ) = = true ) )
2013-05-08 21:45:39 +00:00
{
break ;
}
else
2013-05-19 04:28:07 +00:00
{
2013-05-08 21:45:39 +00:00
i + + ;
2013-07-09 22:38:46 +00:00
/* continue; */
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2013-05-09 04:04:25 +00:00
} while ( i < NUM_PMKID_CACHE ) ;
2013-05-08 21:45:39 +00:00
2013-05-09 04:04:25 +00:00
if ( i = = NUM_PMKID_CACHE )
2013-05-19 04:28:07 +00:00
{
2013-07-09 22:38:46 +00:00
i = - 1 ; /* Could not find. */
2013-05-08 21:45:39 +00:00
}
else
2013-05-19 04:28:07 +00:00
{
2013-07-09 22:38:46 +00:00
/* There is one Pre-Authentication Key for the specific BSSID. */
2013-05-08 21:45:39 +00:00
}
return ( i ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
2013-07-09 22:38:46 +00:00
/* */
/* Check the RSN IE length */
/* If the RSN IE length <= 20, the RSN IE didn't include the PMKID information */
/* 0-11th element in the array are the fixed IE */
/* 12th element in the array is the IE */
/* 13th element in the array is the IE length */
/* */
2013-05-08 21:45:39 +00:00
static int rtw_append_pmkid ( _adapter * Adapter , int iEntry , u8 * ie , uint ie_len )
{
struct security_priv * psecuritypriv = & Adapter - > securitypriv ;
2013-05-19 04:28:07 +00:00
if ( ie [ 13 ] < = 20 ) {
2013-07-09 22:38:46 +00:00
/* The RSN IE didn't include the PMK ID, append the PMK information */
2013-05-08 21:45:39 +00:00
ie [ ie_len ] = 1 ;
ie_len + + ;
2013-07-09 22:38:46 +00:00
ie [ ie_len ] = 0 ; /* PMKID count = 0x0100 */
2013-05-08 21:45:39 +00:00
ie_len + + ;
_rtw_memcpy ( & ie [ ie_len ] , & psecuritypriv - > PMKIDList [ iEntry ] . PMKID , 16 ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
ie_len + = 16 ;
2013-07-09 22:38:46 +00:00
ie [ 13 ] + = 18 ; /* PMKID length = 2+16 */
2013-05-08 21:45:39 +00:00
}
return ( ie_len ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
sint rtw_restruct_sec_ie ( _adapter * adapter , u8 * in_ie , u8 * out_ie , uint in_len )
{
u8 authmode , securitytype , match ;
u8 sec_ie [ 255 ] , uncst_oui [ 4 ] , bkup_ie [ 255 ] ;
u8 wpa_oui [ 4 ] = { 0x0 , 0x50 , 0xf2 , 0x01 } ;
2013-05-19 04:28:07 +00:00
uint ielength , cnt , remove_cnt ;
2013-05-08 21:45:39 +00:00
int iEntry ;
struct mlme_priv * pmlmepriv = & adapter - > mlmepriv ;
struct security_priv * psecuritypriv = & adapter - > securitypriv ;
2013-05-19 04:28:07 +00:00
uint ndisauthmode = psecuritypriv - > ndisauthtype ;
2013-05-08 21:45:39 +00:00
uint ndissecuritytype = psecuritypriv - > ndisencryptstatus ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_func_enter_ ;
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_notice_ ,
( " +rtw_restruct_sec_ie: ndisauthmode=%d ndissecuritytype=%d \n " ,
ndisauthmode , ndissecuritytype ) ) ;
2013-05-19 04:28:07 +00:00
2013-07-09 22:38:46 +00:00
/* copy fixed ie only */
2013-05-08 21:45:39 +00:00
_rtw_memcpy ( out_ie , in_ie , 12 ) ;
ielength = 12 ;
2013-05-09 04:04:25 +00:00
if ( ( ndisauthmode = = Ndis802_11AuthModeWPA ) | | ( ndisauthmode = = Ndis802_11AuthModeWPAPSK ) )
2013-05-08 21:45:39 +00:00
authmode = _WPA_IE_ID_ ;
2013-05-09 04:04:25 +00:00
if ( ( ndisauthmode = = Ndis802_11AuthModeWPA2 ) | | ( ndisauthmode = = Ndis802_11AuthModeWPA2PSK ) )
2013-05-08 21:45:39 +00:00
authmode = _WPA2_IE_ID_ ;
2013-05-09 04:04:25 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_UNDER_WPS ) )
2013-05-08 21:45:39 +00:00
{
_rtw_memcpy ( out_ie + ielength , psecuritypriv - > wps_ie , psecuritypriv - > wps_ie_len ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
ielength + = psecuritypriv - > wps_ie_len ;
}
2013-05-09 04:04:25 +00:00
else if ( ( authmode = = _WPA_IE_ID_ ) | | ( authmode = = _WPA2_IE_ID_ ) )
2013-05-19 04:28:07 +00:00
{
2013-07-09 22:38:46 +00:00
/* copy RSN or SSN */
2013-05-08 21:45:39 +00:00
_rtw_memcpy ( & out_ie [ ielength ] , & psecuritypriv - > supplicant_ie [ 0 ] , psecuritypriv - > supplicant_ie [ 1 ] + 2 ) ;
ielength + = psecuritypriv - > supplicant_ie [ 1 ] + 2 ;
rtw_report_sec_ie ( adapter , authmode , psecuritypriv - > supplicant_ie ) ;
}
iEntry = SecIsInPMKIDList ( adapter , pmlmepriv - > assoc_bssid ) ;
2013-05-09 04:04:25 +00:00
if ( iEntry < 0 )
2013-05-08 21:45:39 +00:00
{
return ielength ;
}
else
{
2013-05-09 04:04:25 +00:00
if ( authmode = = _WPA2_IE_ID_ )
2013-05-08 21:45:39 +00:00
{
ielength = rtw_append_pmkid ( adapter , iEntry , out_ie , ielength ) ;
}
}
_func_exit_ ;
2013-05-19 04:28:07 +00:00
return ielength ;
2013-05-08 21:45:39 +00:00
}
void rtw_init_registrypriv_dev_network ( _adapter * adapter )
{
struct registry_priv * pregistrypriv = & adapter - > registrypriv ;
struct eeprom_priv * peepriv = & adapter - > eeprompriv ;
WLAN_BSSID_EX * pdev_network = & pregistrypriv - > dev_network ;
u8 * myhwaddr = myid ( peepriv ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
_func_enter_ ;
_rtw_memcpy ( pdev_network - > MacAddress , myhwaddr , ETH_ALEN ) ;
_rtw_memcpy ( & pdev_network - > Ssid , & pregistrypriv - > ssid , sizeof ( NDIS_802_11_SSID ) ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
pdev_network - > Configuration . Length = sizeof ( NDIS_802_11_CONFIGURATION ) ;
2013-05-19 04:28:07 +00:00
pdev_network - > Configuration . BeaconPeriod = 100 ;
2013-05-08 21:45:39 +00:00
pdev_network - > Configuration . FHConfig . Length = 0 ;
pdev_network - > Configuration . FHConfig . HopPattern = 0 ;
pdev_network - > Configuration . FHConfig . HopSet = 0 ;
pdev_network - > Configuration . FHConfig . DwellTime = 0 ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
void rtw_update_registrypriv_dev_network ( _adapter * adapter )
2013-05-08 21:45:39 +00:00
{
int sz = 0 ;
2013-05-19 04:28:07 +00:00
struct registry_priv * pregistrypriv = & adapter - > registrypriv ;
2013-05-08 21:45:39 +00:00
WLAN_BSSID_EX * pdev_network = & pregistrypriv - > dev_network ;
struct security_priv * psecuritypriv = & adapter - > securitypriv ;
struct wlan_network * cur_network = & adapter - > mlmepriv . cur_network ;
2013-07-09 22:38:46 +00:00
/* struct xmit_priv *pxmitpriv = &adapter->xmitpriv; */
2013-05-08 21:45:39 +00:00
_func_enter_ ;
2013-07-09 22:38:46 +00:00
pdev_network - > Privacy = ( psecuritypriv - > dot11PrivacyAlgrthm > 0 ? 1 : 0 ) ; /* adhoc no 802.1x */
2013-05-08 21:45:39 +00:00
pdev_network - > Rssi = 0 ;
2013-05-09 04:04:25 +00:00
switch ( pregistrypriv - > wireless_mode )
2013-05-08 21:45:39 +00:00
{
case WIRELESS_11B :
pdev_network - > NetworkTypeInUse = ( Ndis802_11DS ) ;
2013-05-19 04:28:07 +00:00
break ;
2013-05-08 21:45:39 +00:00
case WIRELESS_11G :
case WIRELESS_11BG :
case WIRELESS_11_24N :
case WIRELESS_11G_24N :
case WIRELESS_11BG_24N :
pdev_network - > NetworkTypeInUse = ( Ndis802_11OFDM24 ) ;
break ;
case WIRELESS_11A :
case WIRELESS_11A_5N :
pdev_network - > NetworkTypeInUse = ( Ndis802_11OFDM5 ) ;
break ;
case WIRELESS_11ABGN :
2013-05-09 04:04:25 +00:00
if ( pregistrypriv - > channel > 14 )
2013-05-08 21:45:39 +00:00
pdev_network - > NetworkTypeInUse = ( Ndis802_11OFDM5 ) ;
else
pdev_network - > NetworkTypeInUse = ( Ndis802_11OFDM24 ) ;
break ;
default :
2013-07-09 22:38:46 +00:00
/* TODO */
2013-05-08 21:45:39 +00:00
break ;
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
pdev_network - > Configuration . DSConfig = ( pregistrypriv - > channel ) ;
2013-05-19 04:28:07 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_info_ , ( " pregistrypriv->channel=%d, pdev_network->Configuration.DSConfig=0x%x \n " , pregistrypriv - > channel , pdev_network - > Configuration . DSConfig ) ) ;
2013-05-08 21:45:39 +00:00
2013-05-09 04:04:25 +00:00
if ( cur_network - > network . InfrastructureMode = = Ndis802_11IBSS )
2013-05-08 21:45:39 +00:00
pdev_network - > Configuration . ATIMWindow = ( 0 ) ;
pdev_network - > InfrastructureMode = ( cur_network - > network . InfrastructureMode ) ;
2013-07-09 22:38:46 +00:00
/* 1. Supported rates */
/* 2. IE */
2013-05-08 21:45:39 +00:00
sz = rtw_generate_ie ( pregistrypriv ) ;
pdev_network - > IELength = sz ;
pdev_network - > Length = get_WLAN_BSSID_EX_sz ( ( WLAN_BSSID_EX * ) pdev_network ) ;
2013-07-09 22:38:46 +00:00
/* notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); */
/* pdev_network->IELength = cpu_to_le32(sz); */
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
void rtw_get_encrypt_decrypt_from_registrypriv ( _adapter * adapter )
{
_func_enter_ ;
2013-05-19 04:28:07 +00:00
_func_exit_ ;
2013-05-08 21:45:39 +00:00
}
2013-07-09 22:38:46 +00:00
/* the fucntion is at passive_level */
2013-05-08 21:45:39 +00:00
void rtw_joinbss_reset ( _adapter * padapter )
{
u8 threshold ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
2013-05-19 04:28:07 +00:00
# ifdef CONFIG_80211N_HT
2013-05-08 21:45:39 +00:00
struct ht_priv * phtpriv = & pmlmepriv - > htpriv ;
# endif
2013-07-09 22:38:46 +00:00
/* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
# ifdef CONFIG_80211N_HT
pmlmepriv - > num_FortyMHzIntolerant = 0 ;
pmlmepriv - > num_sta_no_ht = 0 ;
2013-07-09 22:38:46 +00:00
phtpriv - > ampdu_enable = false ; /* reset to disabled */
2013-05-08 21:45:39 +00:00
2013-07-09 22:38:46 +00:00
/* TH=1 => means that invalidate usb rx aggregation */
/* TH=0 => means that validate usb rx aggregation, use init value. */
2013-05-09 04:04:25 +00:00
if ( phtpriv - > ht_option )
2013-05-08 21:45:39 +00:00
{
2013-05-19 04:28:07 +00:00
if ( padapter - > registrypriv . wifi_spec = = 1 )
2013-05-08 21:45:39 +00:00
threshold = 1 ;
else
threshold = 0 ;
rtw_hal_set_hwreg ( padapter , HW_VAR_RXDMA_AGG_PG_TH , ( u8 * ) ( & threshold ) ) ;
}
else
{
threshold = 1 ;
rtw_hal_set_hwreg ( padapter , HW_VAR_RXDMA_AGG_PG_TH , ( u8 * ) ( & threshold ) ) ;
}
# endif
}
# ifdef CONFIG_80211N_HT
2013-07-09 22:38:46 +00:00
/* the fucntion is >= passive_level */
2013-05-08 21:45:39 +00:00
unsigned int rtw_restructure_ht_ie ( _adapter * padapter , u8 * in_ie , u8 * out_ie , uint in_len , uint * pout_len )
{
2013-07-10 21:02:38 +00:00
u32 ielen , out_len ;
2013-05-08 21:45:39 +00:00
HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor ;
2013-07-10 21:11:59 +00:00
unsigned char * p ;
2013-05-08 21:45:39 +00:00
struct rtw_ieee80211_ht_cap ht_capie ;
unsigned char WMM_IE [ ] = { 0x00 , 0x50 , 0xf2 , 0x02 , 0x00 , 0x01 , 0x00 } ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
2013-05-19 04:28:07 +00:00
struct qos_priv * pqospriv = & pmlmepriv - > qospriv ;
2013-05-08 21:45:39 +00:00
struct ht_priv * phtpriv = & pmlmepriv - > htpriv ;
2013-05-26 03:02:10 +00:00
phtpriv - > ht_option = false ;
2013-05-08 21:45:39 +00:00
p = rtw_get_ie ( in_ie + 12 , _HT_CAPABILITY_IE_ , & ielen , in_len - 12 ) ;
2013-07-10 21:02:38 +00:00
if ( p & & ielen > 0 )
{
if ( pqospriv - > qos_option = = 0 )
{
out_len = * pout_len ;
2013-07-10 21:11:59 +00:00
rtw_set_ie ( out_ie + out_len , _VENDOR_SPECIFIC_IE_ ,
_WMM_IE_Length_ , WMM_IE , pout_len ) ;
2013-07-10 21:02:38 +00:00
2013-05-08 21:45:39 +00:00
pqospriv - > qos_option = 1 ;
}
2013-07-10 21:02:38 +00:00
out_len = * pout_len ;
2013-05-08 21:45:39 +00:00
_rtw_memset ( & ht_capie , 0 , sizeof ( struct rtw_ieee80211_ht_cap ) ) ;
ht_capie . cap_info = IEEE80211_HT_CAP_SUP_WIDTH | IEEE80211_HT_CAP_SGI_20 |
IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_TX_STBC |
IEEE80211_HT_CAP_DSSSCCK40 ;
{
u32 rx_packet_offset , max_recvbuf_sz ;
rtw_hal_get_def_var ( padapter , HAL_DEF_RX_PACKET_OFFSET , & rx_packet_offset ) ;
rtw_hal_get_def_var ( padapter , HAL_DEF_MAX_RECVBUF_SZ , & max_recvbuf_sz ) ;
2013-07-09 22:38:46 +00:00
/* if (max_recvbuf_sz-rx_packet_offset>(8191-256)) { */
/* DBG_88E("%s IEEE80211_HT_CAP_MAX_AMSDU is set\n", __func__); */
/* ht_capie.cap_info = ht_capie.cap_info |IEEE80211_HT_CAP_MAX_AMSDU; */
/* */
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
/*
2013-05-08 21:45:39 +00:00
AMPDU_para [ 1 : 0 ] : Max AMPDU Len = > 0 : 8 k , 1 : 16 k , 2 : 32 k , 3 : 64 k
2013-05-19 04:28:07 +00:00
AMPDU_para [ 4 : 2 ] : Min MPDU Start Spacing
2013-05-08 21:45:39 +00:00
*/
rtw_hal_get_def_var ( padapter , HW_VAR_MAX_RX_AMPDU_FACTOR , & max_rx_ampdu_factor ) ;
ht_capie . ampdu_params_info = ( max_rx_ampdu_factor & 0x03 ) ;
2013-05-19 04:28:07 +00:00
2013-05-09 04:04:25 +00:00
if ( padapter - > securitypriv . dot11PrivacyAlgrthm = = _AES_ )
2013-05-08 21:45:39 +00:00
ht_capie . ampdu_params_info | = ( IEEE80211_HT_CAP_AMPDU_DENSITY & ( 0x07 < < 2 ) ) ;
else
2013-05-19 04:28:07 +00:00
ht_capie . ampdu_params_info | = ( IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00 ) ;
2013-07-10 21:02:38 +00:00
2013-07-10 21:11:59 +00:00
rtw_set_ie ( out_ie + out_len , _HT_CAPABILITY_IE_ ,
sizeof ( struct rtw_ieee80211_ht_cap ) , ( unsigned char * ) & ht_capie , pout_len ) ;
2013-07-10 21:02:38 +00:00
2013-05-26 03:02:10 +00:00
phtpriv - > ht_option = true ;
2013-05-08 21:45:39 +00:00
p = rtw_get_ie ( in_ie + 12 , _HT_ADD_INFO_IE_ , & ielen , in_len - 12 ) ;
2013-07-10 21:02:38 +00:00
if ( p & & ( ielen = = sizeof ( struct ieee80211_ht_addt_info ) ) )
{
out_len = * pout_len ;
2013-07-10 21:11:59 +00:00
rtw_set_ie ( out_ie + out_len , _HT_ADD_INFO_IE_ , ielen , p + 2 , pout_len ) ;
2013-07-10 21:02:38 +00:00
}
2013-05-08 21:45:39 +00:00
}
2013-07-10 21:02:38 +00:00
2013-05-08 21:45:39 +00:00
return ( phtpriv - > ht_option ) ;
2013-07-10 21:02:38 +00:00
2013-05-08 21:45:39 +00:00
}
2013-07-09 22:38:46 +00:00
/* the fucntion is > passive_level (in critical_section) */
2013-05-08 21:45:39 +00:00
void rtw_update_ht_cap ( _adapter * padapter , u8 * pie , uint ie_len )
2013-05-19 04:28:07 +00:00
{
2013-05-08 21:45:39 +00:00
u8 * p , max_ampdu_sz ;
2013-05-19 04:28:07 +00:00
int len ;
2013-07-09 22:38:46 +00:00
/* struct sta_info *bmc_sta, *psta; */
2013-05-08 21:45:39 +00:00
struct rtw_ieee80211_ht_cap * pht_capie ;
2013-07-09 22:38:46 +00:00
/* struct recv_reorder_ctrl *preorder_ctrl; */
2013-05-08 21:45:39 +00:00
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
struct ht_priv * phtpriv = & pmlmepriv - > htpriv ;
2013-07-09 22:38:46 +00:00
/* struct recv_priv *precvpriv = &padapter->recvpriv; */
2013-05-08 21:45:39 +00:00
struct registry_priv * pregistrypriv = & padapter - > registrypriv ;
2013-07-09 22:38:46 +00:00
/* struct wlan_network *pcur_network = &(pmlmepriv->cur_network);; */
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
2013-05-19 04:28:07 +00:00
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2013-05-08 21:45:39 +00:00
2013-05-09 04:04:25 +00:00
if ( ! phtpriv - > ht_option )
2013-05-08 21:45:39 +00:00
return ;
if ( ( ! pmlmeinfo - > HT_info_enable ) | | ( ! pmlmeinfo - > HT_caps_enable ) )
return ;
2013-05-25 23:35:42 +00:00
DBG_88E ( " +rtw_update_ht_cap() \n " ) ;
2013-05-08 21:45:39 +00:00
2013-07-09 22:38:46 +00:00
/* maybe needs check if ap supports rx ampdu. */
2013-05-26 03:02:10 +00:00
if ( ( phtpriv - > ampdu_enable = = false ) & & ( pregistrypriv - > ampdu_enable = = 1 ) )
2013-05-08 21:45:39 +00:00
{
2013-05-09 04:04:25 +00:00
if ( pregistrypriv - > wifi_spec = = 1 )
2013-05-08 21:45:39 +00:00
{
2013-05-26 03:02:10 +00:00
phtpriv - > ampdu_enable = false ;
2013-05-08 21:45:39 +00:00
}
else
{
2013-05-26 03:02:10 +00:00
phtpriv - > ampdu_enable = true ;
2013-05-08 21:45:39 +00:00
}
}
2013-05-09 04:04:25 +00:00
else if ( pregistrypriv - > ampdu_enable = = 2 )
2013-05-08 21:45:39 +00:00
{
2013-05-26 03:02:10 +00:00
phtpriv - > ampdu_enable = true ;
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2013-07-09 22:38:46 +00:00
/* check Max Rx A-MPDU Size */
2013-05-08 21:45:39 +00:00
len = 0 ;
p = rtw_get_ie ( pie + sizeof ( NDIS_802_11_FIXED_IEs ) , _HT_CAPABILITY_IE_ , & len , ie_len - sizeof ( NDIS_802_11_FIXED_IEs ) ) ;
2013-05-19 04:28:07 +00:00
if ( p & & len > 0 )
2013-05-08 21:45:39 +00:00
{
pht_capie = ( struct rtw_ieee80211_ht_cap * ) ( p + 2 ) ;
max_ampdu_sz = ( pht_capie - > ampdu_params_info & IEEE80211_HT_CAP_AMPDU_FACTOR ) ;
2013-07-09 22:38:46 +00:00
max_ampdu_sz = 1 < < ( max_ampdu_sz + 3 ) ; /* max_ampdu_sz (kbytes); */
2013-05-19 04:28:07 +00:00
2013-07-09 22:38:46 +00:00
/* DBG_88E("rtw_update_ht_cap(): max_ampdu_sz=%d\n", max_ampdu_sz); */
2013-05-08 21:45:39 +00:00
phtpriv - > rx_ampdu_maxlen = max_ampdu_sz ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
len = 0 ;
p = rtw_get_ie ( pie + sizeof ( NDIS_802_11_FIXED_IEs ) , _HT_ADD_INFO_IE_ , & len , ie_len - sizeof ( NDIS_802_11_FIXED_IEs ) ) ;
2013-06-21 18:41:29 +00:00
if ( p & & len > 0 ) {
2013-07-09 22:38:46 +00:00
/* todo: */
2013-05-08 21:45:39 +00:00
}
2013-07-09 22:38:46 +00:00
/* update cur_bwmode & cur_ch_offset */
2013-05-08 21:45:39 +00:00
if ( ( pregistrypriv - > cbw40_enable ) & &
2013-06-07 14:43:09 +00:00
( le16_to_cpu ( pmlmeinfo - > HT_caps . u . HT_cap_element . HT_caps_info ) & BIT ( 1 ) ) & &
( pmlmeinfo - > HT_info . infos [ 0 ] & BIT ( 2 ) ) ) {
2013-05-08 21:45:39 +00:00
int i ;
u8 rf_type ;
padapter - > HalFunc . GetHwRegHandler ( padapter , HW_VAR_RF_TYPE , ( u8 * ) ( & rf_type ) ) ;
2013-07-09 22:38:46 +00:00
/* update the MCS rates */
2013-07-19 21:41:41 +00:00
for ( i = 0 ; i < 16 ; i + + ) {
2013-05-09 04:04:25 +00:00
if ( ( rf_type = = RF_1T1R ) | | ( rf_type = = RF_1T2R ) )
2013-05-08 21:45:39 +00:00
pmlmeinfo - > HT_caps . u . HT_cap_element . MCS_rate [ i ] & = MCS_rate_1R [ i ] ;
else
pmlmeinfo - > HT_caps . u . HT_cap_element . MCS_rate [ i ] & = MCS_rate_2R [ i ] ;
}
2013-07-09 22:38:46 +00:00
/* switch to the 40M Hz mode accoring to the AP */
2013-05-08 21:45:39 +00:00
pmlmeext - > cur_bwmode = HT_CHANNEL_WIDTH_40 ;
2013-07-20 03:15:17 +00:00
switch ( ( pmlmeinfo - > HT_info . infos [ 0 ] & 0x3 ) ) {
case HT_EXTCHNL_OFFSET_UPPER :
pmlmeext - > cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER ;
break ;
case HT_EXTCHNL_OFFSET_LOWER :
pmlmeext - > cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER ;
break ;
default :
pmlmeext - > cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE ;
break ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
}
2013-07-09 22:38:46 +00:00
/* */
/* Config SM Power Save setting */
/* */
2013-06-07 14:43:09 +00:00
pmlmeinfo - > SM_PS = ( le16_to_cpu ( pmlmeinfo - > HT_caps . u . HT_cap_element . HT_caps_info ) & 0x0C ) > > 2 ;
2013-05-09 04:04:25 +00:00
if ( pmlmeinfo - > SM_PS = = WLAN_HT_CAP_SM_PS_STATIC )
2013-05-25 23:35:42 +00:00
DBG_88E ( " %s(): WLAN_HT_CAP_SM_PS_STATIC \n " , __func__ ) ;
2013-05-08 21:45:39 +00:00
2013-07-09 22:38:46 +00:00
/* */
/* Config current HT Protection mode. */
/* */
2013-05-08 21:45:39 +00:00
pmlmeinfo - > HT_protection = pmlmeinfo - > HT_info . infos [ 1 ] & 0x3 ;
}
void rtw_issue_addbareq_cmd ( _adapter * padapter , struct xmit_frame * pxmitframe )
{
u8 issued ;
int priority ;
struct sta_info * psta = NULL ;
struct ht_priv * phtpriv ;
struct pkt_attrib * pattrib = & pxmitframe - > attrib ;
s32 bmcst = IS_MCAST ( pattrib - > ra ) ;
2013-05-19 04:28:07 +00:00
if ( bmcst | | ( padapter - > mlmepriv . LinkDetectInfo . NumTxOkInPeriod < 100 ) )
2013-05-08 21:45:39 +00:00
return ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
priority = pattrib - > priority ;
if ( pattrib - > psta )
psta = pattrib - > psta ;
else
psta = rtw_get_stainfo ( & padapter - > stapriv , pattrib - > ra ) ;
2013-05-19 04:28:07 +00:00
2013-05-09 04:04:25 +00:00
if ( psta = = NULL )
2013-05-08 21:45:39 +00:00
return ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
phtpriv = & psta - > htpriv ;
2013-05-26 03:02:10 +00:00
if ( ( phtpriv - > ht_option = = true ) & & ( phtpriv - > ampdu_enable = = true ) )
2013-05-08 21:45:39 +00:00
{
issued = ( phtpriv - > agg_enable_bitmap > > priority ) & 0x1 ;
issued | = ( phtpriv - > candidate_tid_bitmap > > priority ) & 0x1 ;
2013-05-09 04:04:25 +00:00
if ( 0 = = issued )
2013-05-08 21:45:39 +00:00
{
2013-05-25 23:35:42 +00:00
DBG_88E ( " rtw_issue_addbareq_cmd, p=%d \n " , priority ) ;
2013-05-08 21:45:39 +00:00
psta - > htpriv . candidate_tid_bitmap | = BIT ( ( u8 ) priority ) ;
rtw_addbareq_cmd ( padapter , ( u8 ) priority , pattrib - > ra ) ;
}
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
# endif
void rtw_roaming ( _adapter * padapter , struct wlan_network * tgt_network )
{
_irqL irqL ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
_enter_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
_rtw_roaming ( padapter , tgt_network ) ;
_exit_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
}
void _rtw_roaming ( _adapter * padapter , struct wlan_network * tgt_network )
{
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
int do_join_r ;
struct wlan_network * pnetwork ;
2013-05-09 04:04:25 +00:00
if ( tgt_network ! = NULL )
2013-05-08 21:45:39 +00:00
pnetwork = tgt_network ;
else
pnetwork = & pmlmepriv - > cur_network ;
2013-05-19 04:28:07 +00:00
2013-05-09 04:04:25 +00:00
if ( 0 < pmlmepriv - > to_roaming ) {
2013-05-30 20:51:53 +00:00
DBG_88E ( " roaming from %s(%pM length:%d \n " ,
pnetwork - > network . Ssid . Ssid , pnetwork - > network . MacAddress ,
pnetwork - > network . Ssid . SsidLength ) ;
2013-05-08 21:45:39 +00:00
_rtw_memcpy ( & pmlmepriv - > assoc_ssid , & pnetwork - > network . Ssid , sizeof ( NDIS_802_11_SSID ) ) ;
2013-05-26 03:02:10 +00:00
pmlmepriv - > assoc_by_bssid = false ;
2013-05-08 21:45:39 +00:00
2013-05-09 04:04:25 +00:00
while ( 1 ) {
if ( _SUCCESS = = ( do_join_r = rtw_do_join ( padapter ) ) ) {
2013-05-08 21:45:39 +00:00
break ;
} else {
2013-05-25 23:35:42 +00:00
DBG_88E ( " roaming do_join return %d \n " , do_join_r ) ;
2013-05-08 21:45:39 +00:00
pmlmepriv - > to_roaming - - ;
2013-05-19 04:28:07 +00:00
2013-05-09 04:04:25 +00:00
if ( 0 < pmlmepriv - > to_roaming ) {
2013-05-08 21:45:39 +00:00
continue ;
} else {
2013-05-25 23:35:42 +00:00
DBG_88E ( " %s(%d) -to roaming fail, indicate_disconnect \n " , __func__ , __LINE__ ) ;
2013-05-08 21:45:39 +00:00
rtw_indicate_disconnect ( padapter ) ;
break ;
}
}
}
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}