mac80211: add beacon filtering support
Add IEEE80211_HW_BEACON_FILTERING flag so that driver inform that it supports beacon filtering. Drivers need to call the new function ieee80211_beacon_loss() to notify about beacon loss. Signed-off-by: Kalle Valo <kalle.valo@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
committed by
John W. Linville
parent
a08c1c1ac0
commit
04de838159
@ -610,6 +610,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
|
||||
bss_info_changed |= ieee80211_handle_bss_capability(sdata,
|
||||
bss->cbss.capability, bss->has_erp_value, bss->erp_value);
|
||||
|
||||
cfg80211_hold_bss(&bss->cbss);
|
||||
|
||||
ieee80211_rx_bss_put(local, bss);
|
||||
}
|
||||
|
||||
@ -751,6 +753,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
|
||||
{
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_conf *conf = &local_to_hw(local)->conf;
|
||||
struct ieee80211_bss *bss;
|
||||
struct sta_info *sta;
|
||||
u32 changed = 0, config_changed = 0;
|
||||
|
||||
@ -774,6 +778,15 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
ieee80211_sta_tear_down_BA_sessions(sta);
|
||||
|
||||
bss = ieee80211_rx_bss_get(local, ifmgd->bssid,
|
||||
conf->channel->center_freq,
|
||||
ifmgd->ssid, ifmgd->ssid_len);
|
||||
|
||||
if (bss) {
|
||||
cfg80211_unhold_bss(&bss->cbss);
|
||||
ieee80211_rx_bss_put(local, bss);
|
||||
}
|
||||
|
||||
if (self_disconnected) {
|
||||
if (deauth)
|
||||
ieee80211_send_deauth_disassoc(sdata,
|
||||
@ -925,6 +938,33 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
|
||||
jiffies + IEEE80211_MONITORING_INTERVAL);
|
||||
}
|
||||
|
||||
void ieee80211_beacon_loss_work(struct work_struct *work)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata =
|
||||
container_of(work, struct ieee80211_sub_if_data,
|
||||
u.mgd.beacon_loss_work);
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
|
||||
printk(KERN_DEBUG "%s: driver reports beacon loss from AP %pM "
|
||||
"- sending probe request\n", sdata->dev->name,
|
||||
sdata->u.mgd.bssid);
|
||||
|
||||
ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
|
||||
ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
|
||||
ifmgd->ssid_len, NULL, 0);
|
||||
|
||||
mod_timer(&ifmgd->timer, jiffies + IEEE80211_MONITORING_INTERVAL);
|
||||
}
|
||||
|
||||
void ieee80211_beacon_loss(struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||
|
||||
queue_work(sdata->local->hw.workqueue,
|
||||
&sdata->u.mgd.beacon_loss_work);
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_beacon_loss);
|
||||
|
||||
static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
@ -959,7 +999,13 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (time_after(jiffies,
|
||||
/*
|
||||
* Beacon filtering is only enabled with power save and then the
|
||||
* stack should not check for beacon loss.
|
||||
*/
|
||||
if (!((local->hw.flags & IEEE80211_HW_BEACON_FILTER) &&
|
||||
(local->hw.conf.flags & IEEE80211_CONF_PS)) &&
|
||||
time_after(jiffies,
|
||||
ifmgd->last_beacon + IEEE80211_MONITORING_INTERVAL)) {
|
||||
printk(KERN_DEBUG "%s: beacon loss from AP %pM "
|
||||
"- sending probe request\n",
|
||||
@ -1869,6 +1915,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
|
||||
ifmgd = &sdata->u.mgd;
|
||||
INIT_WORK(&ifmgd->work, ieee80211_sta_work);
|
||||
INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
|
||||
INIT_WORK(&ifmgd->beacon_loss_work, ieee80211_beacon_loss_work);
|
||||
setup_timer(&ifmgd->timer, ieee80211_sta_timer,
|
||||
(unsigned long) sdata);
|
||||
setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer,
|
||||
|
Reference in New Issue
Block a user