mac80211: revamp beacon configuration

This patch changes mac80211's beacon configuration handling
to never pass skbs to the driver directly but rather always
require the driver to use ieee80211_beacon_get(). Additionally,
it introduces "change flags" on the config_interface() call
to enable drivers to figure out what is changing. Finally, it
removes the beacon_update() driver callback in favour of
having IBSS beacon delivered by ieee80211_beacon_get() as well.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Johannes Berg
2008-07-09 14:40:37 +02:00
committed by John W. Linville
parent f3947e2dfa
commit 9d139c810a
21 changed files with 228 additions and 250 deletions

View File

@@ -1138,14 +1138,22 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev,
/* Asynchronously update the packet templates in template RAM.
* Locking: Requires wl->irq_lock to be locked. */
static void b43legacy_update_templates(struct b43legacy_wl *wl,
struct sk_buff *beacon)
static void b43legacy_update_templates(struct b43legacy_wl *wl)
{
struct sk_buff *beacon;
/* This is the top half of the ansynchronous beacon update. The bottom
* half is the beacon IRQ. Beacon update must be asynchronous to avoid
* sending an invalid beacon. This can happen for example, if the
* firmware transmits a beacon while we are updating it. */
/* We could modify the existing beacon and set the aid bit in the TIM
* field, but that would probably require resizing and moving of data
* within the beacon template. Simply request a new beacon and let
* mac80211 do the hard work. */
beacon = ieee80211_beacon_get(wl->hw, wl->vif);
if (unlikely(!beacon))
return;
if (wl->current_beacon)
dev_kfree_skb_any(wl->current_beacon);
wl->current_beacon = beacon;
@@ -2727,10 +2735,13 @@ static int b43legacy_op_config_interface(struct ieee80211_hw *hw,
memset(wl->bssid, 0, ETH_ALEN);
if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) {
if (b43legacy_is_mode(wl, IEEE80211_IF_TYPE_AP)) {
B43legacy_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP);
B43legacy_WARN_ON(vif->type != IEEE80211_IF_TYPE_AP);
b43legacy_set_ssid(dev, conf->ssid, conf->ssid_len);
if (conf->beacon)
b43legacy_update_templates(wl, conf->beacon);
if (conf->changed & IEEE80211_IFCC_BEACON)
b43legacy_update_templates(wl);
} else if (b43legacy_is_mode(wl, IEEE80211_IF_TYPE_IBSS)) {
if (conf->changed & IEEE80211_IFCC_BEACON)
b43legacy_update_templates(wl);
}
b43legacy_write_mac_bssid_templates(dev);
}
@@ -3394,33 +3405,12 @@ out_unlock:
static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw,
int aid, int set)
{
struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
struct sk_buff *beacon;
unsigned long flags;
/* We could modify the existing beacon and set the aid bit in the TIM
* field, but that would probably require resizing and moving of data
* within the beacon template. Simply request a new beacon and let
* mac80211 do the hard work. */
beacon = ieee80211_beacon_get(hw, wl->vif);
if (unlikely(!beacon))
return -ENOMEM;
spin_lock_irqsave(&wl->irq_lock, flags);
b43legacy_update_templates(wl, beacon);
spin_unlock_irqrestore(&wl->irq_lock, flags);
return 0;
}
static int b43legacy_op_ibss_beacon_update(struct ieee80211_hw *hw,
struct sk_buff *beacon)
{
struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
unsigned long flags;
spin_lock_irqsave(&wl->irq_lock, flags);
b43legacy_update_templates(wl, beacon);
b43legacy_update_templates(wl);
spin_unlock_irqrestore(&wl->irq_lock, flags);
return 0;
@@ -3440,7 +3430,6 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
.stop = b43legacy_op_stop,
.set_retry_limit = b43legacy_op_set_retry_limit,
.set_tim = b43legacy_op_beacon_set_tim,
.beacon_update = b43legacy_op_ibss_beacon_update,
};
/* Hard-reset the chip. Do not call this directly.