mac80211: allow drivers to request DTIM period
Some features require knowing the DTIM period before associating. This implements the ability to wait for a beacon in mac80211 before assoc to provide this value. It is optional since most likely not all drivers will need this. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:

committed by
John W. Linville

parent
d28232b461
commit
e5b900d228
@@ -560,6 +560,22 @@ ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk)
|
||||
return WORK_ACT_TIMEOUT;
|
||||
}
|
||||
|
||||
static enum work_action __must_check
|
||||
ieee80211_assoc_beacon_wait(struct ieee80211_work *wk)
|
||||
{
|
||||
if (wk->started)
|
||||
return WORK_ACT_TIMEOUT;
|
||||
|
||||
/*
|
||||
* Wait up to one beacon interval ...
|
||||
* should this be more if we miss one?
|
||||
*/
|
||||
printk(KERN_DEBUG "%s: waiting for beacon from %pM\n",
|
||||
wk->sdata->name, wk->filter_ta);
|
||||
wk->timeout = TU_TO_EXP_TIME(wk->assoc.bss->beacon_interval);
|
||||
return WORK_ACT_NONE;
|
||||
}
|
||||
|
||||
static void ieee80211_auth_challenge(struct ieee80211_work *wk,
|
||||
struct ieee80211_mgmt *mgmt,
|
||||
size_t len)
|
||||
@@ -709,6 +725,25 @@ ieee80211_rx_mgmt_probe_resp(struct ieee80211_work *wk,
|
||||
return WORK_ACT_DONE;
|
||||
}
|
||||
|
||||
static enum work_action __must_check
|
||||
ieee80211_rx_mgmt_beacon(struct ieee80211_work *wk,
|
||||
struct ieee80211_mgmt *mgmt, size_t len)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = wk->sdata;
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
|
||||
ASSERT_WORK_MTX(local);
|
||||
|
||||
if (wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
|
||||
return WORK_ACT_MISMATCH;
|
||||
|
||||
if (len < 24 + 12)
|
||||
return WORK_ACT_NONE;
|
||||
|
||||
printk(KERN_DEBUG "%s: beacon received\n", sdata->name);
|
||||
return WORK_ACT_DONE;
|
||||
}
|
||||
|
||||
static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
@@ -731,6 +766,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
|
||||
case IEEE80211_WORK_DIRECT_PROBE:
|
||||
case IEEE80211_WORK_AUTH:
|
||||
case IEEE80211_WORK_ASSOC:
|
||||
case IEEE80211_WORK_ASSOC_BEACON_WAIT:
|
||||
bssid = wk->filter_ta;
|
||||
break;
|
||||
default:
|
||||
@@ -745,6 +781,9 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
|
||||
continue;
|
||||
|
||||
switch (fc & IEEE80211_FCTL_STYPE) {
|
||||
case IEEE80211_STYPE_BEACON:
|
||||
rma = ieee80211_rx_mgmt_beacon(wk, mgmt, skb->len);
|
||||
break;
|
||||
case IEEE80211_STYPE_PROBE_RESP:
|
||||
rma = ieee80211_rx_mgmt_probe_resp(wk, mgmt, skb->len,
|
||||
rx_status);
|
||||
@@ -916,6 +955,9 @@ static void ieee80211_work_work(struct work_struct *work)
|
||||
case IEEE80211_WORK_REMAIN_ON_CHANNEL:
|
||||
rma = ieee80211_remain_on_channel_timeout(wk);
|
||||
break;
|
||||
case IEEE80211_WORK_ASSOC_BEACON_WAIT:
|
||||
rma = ieee80211_assoc_beacon_wait(wk);
|
||||
break;
|
||||
}
|
||||
|
||||
wk->started = started;
|
||||
@@ -1065,6 +1107,7 @@ ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
|
||||
case IEEE80211_STYPE_PROBE_RESP:
|
||||
case IEEE80211_STYPE_ASSOC_RESP:
|
||||
case IEEE80211_STYPE_REASSOC_RESP:
|
||||
case IEEE80211_STYPE_BEACON:
|
||||
skb_queue_tail(&local->work_skb_queue, skb);
|
||||
ieee80211_queue_work(&local->hw, &local->work_work);
|
||||
return RX_QUEUED;
|
||||
|
Reference in New Issue
Block a user