@ -2352,6 +2352,58 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
return 0 ;
}
static bool ieee80211_coalesce_started_roc ( struct ieee80211_local * local ,
struct ieee80211_roc_work * new_roc ,
struct ieee80211_roc_work * cur_roc )
{
unsigned long j = jiffies ;
unsigned long cur_roc_end = cur_roc - > hw_start_time +
msecs_to_jiffies ( cur_roc - > duration ) ;
struct ieee80211_roc_work * next_roc ;
int new_dur ;
if ( WARN_ON ( ! cur_roc - > started | | ! cur_roc - > hw_begun ) )
return false ;
if ( time_after ( j + IEEE80211_ROC_MIN_LEFT , cur_roc_end ) )
return false ;
ieee80211_handle_roc_started ( new_roc ) ;
new_dur = new_roc - > duration - jiffies_to_msecs ( cur_roc_end - j ) ;
/* cur_roc is long enough - add new_roc to the dependents list. */
if ( new_dur < = 0 ) {
list_add_tail ( & new_roc - > list , & cur_roc - > dependents ) ;
return true ;
}
new_roc - > duration = new_dur ;
/*
* if cur_roc was already coalesced before , we might
* want to extend the next roc instead of adding
* a new one .
*/
next_roc = list_entry ( cur_roc - > list . next ,
struct ieee80211_roc_work , list ) ;
if ( & next_roc - > list ! = & local - > roc_list & &
next_roc - > chan = = new_roc - > chan & &
next_roc - > sdata = = new_roc - > sdata & &
! WARN_ON ( next_roc - > started ) ) {
list_add_tail ( & new_roc - > list , & next_roc - > dependents ) ;
next_roc - > duration = max ( next_roc - > duration ,
new_roc - > duration ) ;
next_roc - > type = max ( next_roc - > type , new_roc - > type ) ;
return true ;
}
/* add right after cur_roc */
list_add ( & new_roc - > list , & cur_roc - > list ) ;
return true ;
}
static int ieee80211_start_roc_work ( struct ieee80211_local * local ,
struct ieee80211_sub_if_data * sdata ,
struct ieee80211_channel * channel ,
@ -2457,8 +2509,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
/* If it has already started, it's more difficult ... */
if ( local - > ops - > remain_on_channel ) {
unsigned long j = jiffies ;
/*
* In the offloaded ROC case , if it hasn ' t begun , add
* this new one to the dependent list to be handled
@ -2481,29 +2531,8 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
break ;
}
if ( time_before ( j + IEEE80211_ROC_MIN_LEFT ,
tmp - > hw_start_time +
msecs_to_jiffies ( tmp - > duration ) ) ) {
int new_dur ;
ieee80211_handle_roc_started ( roc ) ;
new_dur = roc - > duration -
jiffies_to_msecs ( tmp - > hw_start_time +
msecs_to_jiffies (
tmp - > duration ) -
j ) ;
if ( new_dur > 0 ) {
/* add right after tmp */
roc - > duration = new_dur ;
list_add ( & roc - > list , & tmp - > list ) ;
} else {
list_add_tail ( & roc - > list ,
& tmp - > dependents ) ;
}
if ( ieee80211_coalesce_started_roc ( local , roc , tmp ) )
queued = true ;
}
} else if ( del_timer_sync ( & tmp - > work . timer ) ) {
unsigned long new_end ;