diff options
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r-- | drivers/net/wireless/b43/main.c | 48 |
1 files changed, 20 insertions, 28 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 9d2eb273b72..381dbd33dfc 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -1675,14 +1675,24 @@ static void b43_beacon_update_trigger_work(struct work_struct *work) | |||
1675 | 1675 | ||
1676 | /* Asynchronously update the packet templates in template RAM. | 1676 | /* Asynchronously update the packet templates in template RAM. |
1677 | * Locking: Requires wl->irq_lock to be locked. */ | 1677 | * Locking: Requires wl->irq_lock to be locked. */ |
1678 | static void b43_update_templates(struct b43_wl *wl, struct sk_buff *beacon) | 1678 | static void b43_update_templates(struct b43_wl *wl) |
1679 | { | 1679 | { |
1680 | struct sk_buff *beacon; | ||
1681 | |||
1680 | /* This is the top half of the ansynchronous beacon update. | 1682 | /* This is the top half of the ansynchronous beacon update. |
1681 | * The bottom half is the beacon IRQ. | 1683 | * The bottom half is the beacon IRQ. |
1682 | * Beacon update must be asynchronous to avoid sending an | 1684 | * Beacon update must be asynchronous to avoid sending an |
1683 | * invalid beacon. This can happen for example, if the firmware | 1685 | * invalid beacon. This can happen for example, if the firmware |
1684 | * transmits a beacon while we are updating it. */ | 1686 | * transmits a beacon while we are updating it. */ |
1685 | 1687 | ||
1688 | /* We could modify the existing beacon and set the aid bit in | ||
1689 | * the TIM field, but that would probably require resizing and | ||
1690 | * moving of data within the beacon template. | ||
1691 | * Simply request a new beacon and let mac80211 do the hard work. */ | ||
1692 | beacon = ieee80211_beacon_get(wl->hw, wl->vif); | ||
1693 | if (unlikely(!beacon)) | ||
1694 | return; | ||
1695 | |||
1686 | if (wl->current_beacon) | 1696 | if (wl->current_beacon) |
1687 | dev_kfree_skb_any(wl->current_beacon); | 1697 | dev_kfree_skb_any(wl->current_beacon); |
1688 | wl->current_beacon = beacon; | 1698 | wl->current_beacon = beacon; |
@@ -3645,10 +3655,14 @@ static int b43_op_config_interface(struct ieee80211_hw *hw, | |||
3645 | if (b43_status(dev) >= B43_STAT_INITIALIZED) { | 3655 | if (b43_status(dev) >= B43_STAT_INITIALIZED) { |
3646 | if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP) || | 3656 | if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP) || |
3647 | b43_is_mode(wl, IEEE80211_IF_TYPE_MESH_POINT)) { | 3657 | b43_is_mode(wl, IEEE80211_IF_TYPE_MESH_POINT)) { |
3648 | B43_WARN_ON(conf->type != wl->if_type); | 3658 | B43_WARN_ON(vif->type != wl->if_type); |
3649 | b43_set_ssid(dev, conf->ssid, conf->ssid_len); | 3659 | if (conf->changed & IEEE80211_IFCC_SSID) |
3650 | if (conf->beacon) | 3660 | b43_set_ssid(dev, conf->ssid, conf->ssid_len); |
3651 | b43_update_templates(wl, conf->beacon); | 3661 | if (conf->changed & IEEE80211_IFCC_BEACON) |
3662 | b43_update_templates(wl); | ||
3663 | } else if (b43_is_mode(wl, IEEE80211_IF_TYPE_IBSS)) { | ||
3664 | if (conf->changed & IEEE80211_IFCC_BEACON) | ||
3665 | b43_update_templates(wl); | ||
3652 | } | 3666 | } |
3653 | b43_write_mac_bssid_templates(dev); | 3667 | b43_write_mac_bssid_templates(dev); |
3654 | } | 3668 | } |
@@ -4336,31 +4350,10 @@ out_unlock: | |||
4336 | static int b43_op_beacon_set_tim(struct ieee80211_hw *hw, int aid, int set) | 4350 | static int b43_op_beacon_set_tim(struct ieee80211_hw *hw, int aid, int set) |
4337 | { | 4351 | { |
4338 | struct b43_wl *wl = hw_to_b43_wl(hw); | 4352 | struct b43_wl *wl = hw_to_b43_wl(hw); |
4339 | struct sk_buff *beacon; | ||
4340 | unsigned long flags; | ||
4341 | |||
4342 | /* We could modify the existing beacon and set the aid bit in | ||
4343 | * the TIM field, but that would probably require resizing and | ||
4344 | * moving of data within the beacon template. | ||
4345 | * Simply request a new beacon and let mac80211 do the hard work. */ | ||
4346 | beacon = ieee80211_beacon_get(hw, wl->vif); | ||
4347 | if (unlikely(!beacon)) | ||
4348 | return -ENOMEM; | ||
4349 | spin_lock_irqsave(&wl->irq_lock, flags); | ||
4350 | b43_update_templates(wl, beacon); | ||
4351 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
4352 | |||
4353 | return 0; | ||
4354 | } | ||
4355 | |||
4356 | static int b43_op_ibss_beacon_update(struct ieee80211_hw *hw, | ||
4357 | struct sk_buff *beacon) | ||
4358 | { | ||
4359 | struct b43_wl *wl = hw_to_b43_wl(hw); | ||
4360 | unsigned long flags; | 4353 | unsigned long flags; |
4361 | 4354 | ||
4362 | spin_lock_irqsave(&wl->irq_lock, flags); | 4355 | spin_lock_irqsave(&wl->irq_lock, flags); |
4363 | b43_update_templates(wl, beacon); | 4356 | b43_update_templates(wl); |
4364 | spin_unlock_irqrestore(&wl->irq_lock, flags); | 4357 | spin_unlock_irqrestore(&wl->irq_lock, flags); |
4365 | 4358 | ||
4366 | return 0; | 4359 | return 0; |
@@ -4391,7 +4384,6 @@ static const struct ieee80211_ops b43_hw_ops = { | |||
4391 | .stop = b43_op_stop, | 4384 | .stop = b43_op_stop, |
4392 | .set_retry_limit = b43_op_set_retry_limit, | 4385 | .set_retry_limit = b43_op_set_retry_limit, |
4393 | .set_tim = b43_op_beacon_set_tim, | 4386 | .set_tim = b43_op_beacon_set_tim, |
4394 | .beacon_update = b43_op_ibss_beacon_update, | ||
4395 | .sta_notify = b43_op_sta_notify, | 4387 | .sta_notify = b43_op_sta_notify, |
4396 | }; | 4388 | }; |
4397 | 4389 | ||