@ -1065,16 +1065,20 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
}
void ieee80211_sta_tx_notify ( struct ieee80211_sub_if_data * sdata ,
struct ieee80211_hdr * hdr )
struct ieee80211_hdr * hdr , bool ack )
{
if ( ! ieee80211_is_data ( hdr - > frame_control ) )
return ;
ieee80211_sta_reset_conn_monitor ( sdata ) ;
if ( ack )
ieee80211_sta_reset_conn_monitor ( sdata ) ;
if ( ieee80211_is_nullfunc ( hdr - > frame_control ) & &
sdata - > u . mgd . probe_send_count > 0 ) {
sdata - > u . mgd . probe_send_count = 0 ;
if ( ack )
sdata - > u . mgd . probe_send_count = 0 ;
else
sdata - > u . mgd . nullfunc_failed = true ;
ieee80211_queue_work ( & sdata - > local - > hw , & sdata - > work ) ;
}
}
@ -1101,9 +1105,10 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
* anymore . The timeout will be reset if the frame is ACKed by
* the AP .
*/
if ( sdata - > local - > hw . flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS )
if ( sdata - > local - > hw . flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS ) {
ifmgd - > nullfunc_failed = false ;
ieee80211_send_nullfunc ( sdata - > local , sdata , 0 ) ;
else {
} else {
ssid = ieee80211_bss_get_ie ( ifmgd - > associated , WLAN_EID_SSID ) ;
ieee80211_send_probe_req ( sdata , dst , ssid + 2 , ssid [ 1 ] , NULL , 0 ) ;
}
@ -1912,6 +1917,31 @@ static void ieee80211_sta_timer(unsigned long data)
ieee80211_queue_work ( & local - > hw , & sdata - > work ) ;
}
static void ieee80211_sta_connection_lost ( struct ieee80211_sub_if_data * sdata ,
u8 * bssid )
{
struct ieee80211_local * local = sdata - > local ;
struct ieee80211_if_managed * ifmgd = & sdata - > u . mgd ;
ifmgd - > flags & = ~ ( IEEE80211_STA_CONNECTION_POLL |
IEEE80211_STA_BEACON_POLL ) ;
ieee80211_set_disassoc ( sdata , true , true ) ;
mutex_unlock ( & ifmgd - > mtx ) ;
mutex_lock ( & local - > mtx ) ;
ieee80211_recalc_idle ( local ) ;
mutex_unlock ( & local - > mtx ) ;
/*
* must be outside lock due to cfg80211 ,
* but that ' s not a problem .
*/
ieee80211_send_deauth_disassoc ( sdata , bssid ,
IEEE80211_STYPE_DEAUTH ,
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY ,
NULL , true ) ;
mutex_lock ( & ifmgd - > mtx ) ;
}
void ieee80211_sta_work ( struct ieee80211_sub_if_data * sdata )
{
struct ieee80211_local * local = sdata - > local ;
@ -1936,11 +1966,38 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
/* ACK received for nullfunc probing frame */
if ( ! ifmgd - > probe_send_count )
ieee80211_reset_ap_probe ( sdata ) ;
else if ( time_is_after_jiffies ( ifmgd - > probe_timeout ) )
else if ( ifmgd - > nullfunc_failed ) {
if ( ifmgd - > probe_send_count < max_tries ) {
# ifdef CONFIG_MAC80211_VERBOSE_DEBUG
wiphy_debug ( local - > hw . wiphy ,
" %s: No ack for nullfunc frame to "
" AP %pM, try %d \n " ,
sdata - > name , bssid ,
ifmgd - > probe_send_count ) ;
# endif
ieee80211_mgd_probe_ap_send ( sdata ) ;
} else {
# ifdef CONFIG_MAC80211_VERBOSE_DEBUG
wiphy_debug ( local - > hw . wiphy ,
" %s: No ack for nullfunc frame to "
" AP %pM, disconnecting. \n " ,
sdata - > name , bssid ,
ifmgd - > probe_send_count ) ;
# endif
ieee80211_sta_connection_lost ( sdata , bssid ) ;
}
} else if ( time_is_after_jiffies ( ifmgd - > probe_timeout ) )
run_again ( ifmgd , ifmgd - > probe_timeout ) ;
else if ( ifmgd - > probe_send_count < max_tries ) {
else if ( local - > hw . flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS ) {
# ifdef CONFIG_MAC80211_VERBOSE_DEBUG
wiphy_debug ( local - > hw . wiphy ,
" %s: Failed to send nullfunc to AP %pM "
" after %dms, disconnecting. \n " ,
sdata - > name ,
bssid , ( 1000 * IEEE80211_PROBE_WAIT ) / HZ ) ;
# endif
ieee80211_sta_connection_lost ( sdata , bssid ) ;
} else if ( ifmgd - > probe_send_count < max_tries ) {
# ifdef CONFIG_MAC80211_VERBOSE_DEBUG
wiphy_debug ( local - > hw . wiphy ,
" %s: No probe response from AP %pM "
@ -1955,27 +2012,13 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
* We actually lost the connection . . . or did we ?
* Let ' s make sure !
*/
ifmgd - > flags & = ~ ( IEEE80211_STA_CONNECTION_POLL |
IEEE80211_STA_BEACON_POLL ) ;
wiphy_debug ( local - > hw . wiphy ,
" %s: No probe response from AP %pM "
" after %dms, disconnecting. \n " ,
sdata - > name ,
bssid , ( 1000 * IEEE80211_PROBE_WAIT ) / HZ ) ;
ieee80211_set_disassoc ( sdata , true , true ) ;
mutex_unlock ( & ifmgd - > mtx ) ;
mutex_lock ( & local - > mtx ) ;
ieee80211_recalc_idle ( local ) ;
mutex_unlock ( & local - > mtx ) ;
/*
* must be outside lock due to cfg80211 ,
* but that ' s not a problem .
*/
ieee80211_send_deauth_disassoc ( sdata , bssid ,
IEEE80211_STYPE_DEAUTH ,
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY ,
NULL , true ) ;
mutex_lock ( & ifmgd - > mtx ) ;
ieee80211_sta_connection_lost ( sdata , bssid ) ;
}
}