Beacons+TIM are created/updated for beaconing only when BSS_CHANGED_BEACON.
This is not compliant with power-saving stations. Fix it by updating
beacon templates on mac80211 set_tim callback.

Signed-off-by: Ali MJ Al-Nasrawy <[email protected]>
---
 .../broadcom/brcm80211/brcmsmac/mac80211_if.c | 21 +++++++++++++++++++
 .../broadcom/brcm80211/brcmsmac/main.h        |  1 +
 2 files changed, 22 insertions(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
index ddfdfe1..85e7b77 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
@@ -502,6 +502,7 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif)
        }
 
        spin_lock_bh(&wl->lock);
+       wl->wlc->vif = vif;
        wl->mute_tx = false;
        brcms_c_mute(wl->wlc, false);
        if (vif->type == NL80211_IFTYPE_STATION)
@@ -937,6 +938,25 @@ static void brcms_ops_set_tsf(struct ieee80211_hw *hw,
        spin_unlock_bh(&wl->lock);
 }
 
+static int brcms_ops_beacon_set_tim(struct ieee80211_hw *hw,
+                                struct ieee80211_sta *sta, bool set)
+{
+       struct brcms_info *wl = hw->priv;
+       struct sk_buff *beacon;
+       u16 tim_offset = 0;
+       
+       beacon = ieee80211_beacon_get_tim(hw, wl->wlc->vif,
+                                         &tim_offset, NULL);
+       if (beacon){
+               spin_lock_bh(&wl->lock);
+               brcms_c_set_new_beacon(wl->wlc, beacon, tim_offset,
+                                      wl->wlc->vif->bss_conf.dtim_period);
+               spin_unlock_bh(&wl->lock);
+       }
+       
+       return 0;
+}
+
 static const struct ieee80211_ops brcms_ops = {
        .tx = brcms_ops_tx,
        .start = brcms_ops_start,
@@ -955,6 +975,7 @@ static const struct ieee80211_ops brcms_ops = {
        .flush = brcms_ops_flush,
        .get_tsf = brcms_ops_get_tsf,
        .set_tsf = brcms_ops_set_tsf,
+       .set_tim = brcms_ops_beacon_set_tim,
 };
 
 void brcms_dpc(unsigned long data)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.h
index c4d135c..6ece25c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.h
@@ -568,6 +568,7 @@ struct brcms_c_info {
        u16 beacon_tim_offset;
        u16 beacon_dtim_period;
        struct sk_buff *probe_resp;
+       struct ieee80211_vif *vif;
 };
 
 /* antsel module specific state */
-- 
2.18.0

Reply via email to