brcmsmac: AP mode: update beacon when TIM changes
Beacons are not updated to reflect TIM changes. This is not compliant with power-saving client stations as the beacons do not have valid TIM and can cause the network to stall at random occasions and to have highly variable latencies. Fix it by updating beacon templates on mac80211 set_tim callback. Addresses an issue described in: https://marc.info/?i=20180911163534.21312d08%20()%20manjaro Signed-off-by: Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Родитель
c894696188
Коммит
2258ee58ba
|
@ -502,6 +502,7 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_bh(&wl->lock);
|
spin_lock_bh(&wl->lock);
|
||||||
|
wl->wlc->vif = vif;
|
||||||
wl->mute_tx = false;
|
wl->mute_tx = false;
|
||||||
brcms_c_mute(wl->wlc, false);
|
brcms_c_mute(wl->wlc, false);
|
||||||
if (vif->type == NL80211_IFTYPE_STATION)
|
if (vif->type == NL80211_IFTYPE_STATION)
|
||||||
|
@ -519,6 +520,11 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||||
static void
|
static void
|
||||||
brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||||
{
|
{
|
||||||
|
struct brcms_info *wl = hw->priv;
|
||||||
|
|
||||||
|
spin_lock_bh(&wl->lock);
|
||||||
|
wl->wlc->vif = NULL;
|
||||||
|
spin_unlock_bh(&wl->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
|
static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
|
||||||
|
@ -937,6 +943,25 @@ static void brcms_ops_set_tsf(struct ieee80211_hw *hw,
|
||||||
spin_unlock_bh(&wl->lock);
|
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 = NULL;
|
||||||
|
u16 tim_offset = 0;
|
||||||
|
|
||||||
|
spin_lock_bh(&wl->lock);
|
||||||
|
if (wl->wlc->vif)
|
||||||
|
beacon = ieee80211_beacon_get_tim(hw, wl->wlc->vif,
|
||||||
|
&tim_offset, NULL);
|
||||||
|
if (beacon)
|
||||||
|
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 = {
|
static const struct ieee80211_ops brcms_ops = {
|
||||||
.tx = brcms_ops_tx,
|
.tx = brcms_ops_tx,
|
||||||
.start = brcms_ops_start,
|
.start = brcms_ops_start,
|
||||||
|
@ -955,6 +980,7 @@ static const struct ieee80211_ops brcms_ops = {
|
||||||
.flush = brcms_ops_flush,
|
.flush = brcms_ops_flush,
|
||||||
.get_tsf = brcms_ops_get_tsf,
|
.get_tsf = brcms_ops_get_tsf,
|
||||||
.set_tsf = brcms_ops_set_tsf,
|
.set_tsf = brcms_ops_set_tsf,
|
||||||
|
.set_tim = brcms_ops_beacon_set_tim,
|
||||||
};
|
};
|
||||||
|
|
||||||
void brcms_dpc(unsigned long data)
|
void brcms_dpc(unsigned long data)
|
||||||
|
|
|
@ -563,6 +563,7 @@ struct brcms_c_info {
|
||||||
|
|
||||||
struct wiphy *wiphy;
|
struct wiphy *wiphy;
|
||||||
struct scb pri_scb;
|
struct scb pri_scb;
|
||||||
|
struct ieee80211_vif *vif;
|
||||||
|
|
||||||
struct sk_buff *beacon;
|
struct sk_buff *beacon;
|
||||||
u16 beacon_tim_offset;
|
u16 beacon_tim_offset;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче