diff options
author | Jérôme Pouiller <jerome.pouiller@silabs.com> | 2020-01-15 13:55:25 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-01-16 20:59:52 +0100 |
commit | a3c529a835890b0eecd324d9f0c37c67345f84e2 (patch) | |
tree | 6fe2feabcbb779233a3c2314d8d73abd781d3145 /drivers/staging/wfx/sta.c | |
parent | 22c03264e5a914966c93baa367d63eb77f60ebaf (diff) |
staging: wfx: simplify handling of IEEE80211_TX_CTL_SEND_AFTER_DTIM
When mac80211 ask for a frame to be sent after a DTIM, driver should:
1. Update TIM with multicast bit set (using update_ie). This function
can be called whenever.
2. Keep buffered all frames marked "after dtim"
3. When it receive a suspend_resume indication (see
wfx_suspend_resume_mc()), send all the buffered frames. This
indication is sent by the firmware 4ms before the dtim.
4. If one of the frames returns status "REQUEUE", it means that the
DTIM period was ended before to be able to send the frame.
5. When all the buffered frames were sent or if DTIM period was ended,
driver should update the TIM with multicast bit reset.
All the mess with the asynchronous works can be dropped.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200115135338.14374-58-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/wfx/sta.c')
-rw-r--r-- | drivers/staging/wfx/sta.c | 78 |
1 files changed, 6 insertions, 72 deletions
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index bdc15554958c..a9b58e4a9fa3 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -851,16 +851,12 @@ static void wfx_ps_notify_sta(struct wfx_vif *wvif, switch (notify_cmd) { case STA_NOTIFY_SLEEP: if (!prev) { - if (wvif->mcast_buffered && !wvif->sta_asleep_mask) - schedule_work(&wvif->mcast_start_work); wvif->sta_asleep_mask |= bit; } break; case STA_NOTIFY_AWAKE: if (prev) { wvif->sta_asleep_mask &= ~bit; - if (!wvif->sta_asleep_mask) - schedule_work(&wvif->mcast_stop_work); wfx_bh_request_tx(wvif->wdev); } break; @@ -898,7 +894,7 @@ static int wfx_update_tim(struct wfx_vif *wvif) tim_ptr[2] = 0; /* Set/reset aid0 bit */ - if (wvif->aid0_bit_set) + if (wfx_tx_queues_get_after_dtim(wvif)) tim_ptr[4] |= 1; else tim_ptr[4] &= ~1; @@ -927,47 +923,12 @@ int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) return 0; } -static void wfx_mcast_start_work(struct work_struct *work) -{ - struct wfx_vif *wvif = - container_of(work, struct wfx_vif, mcast_start_work); - struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf; - long tmo = conf->dtim_period * TU_TO_JIFFIES(wvif->beacon_int + 20); - - cancel_work_sync(&wvif->mcast_stop_work); - if (!wvif->aid0_bit_set) { - wfx_tx_lock_flush(wvif->wdev); - wvif->aid0_bit_set = true; - wfx_update_tim(wvif); - mod_timer(&wvif->mcast_timeout, jiffies + tmo); - wfx_tx_unlock(wvif->wdev); - } -} - -static void wfx_mcast_stop_work(struct work_struct *work) -{ - struct wfx_vif *wvif = container_of(work, struct wfx_vif, - mcast_stop_work); - - if (wvif->aid0_bit_set) { - del_timer_sync(&wvif->mcast_timeout); - wfx_tx_lock_flush(wvif->wdev); - wvif->aid0_bit_set = false; - wfx_update_tim(wvif); - wfx_tx_unlock(wvif->wdev); - } -} - -static void wfx_mcast_timeout(struct timer_list *t) +void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd) { - struct wfx_vif *wvif = from_timer(wvif, t, mcast_timeout); - - dev_warn(wvif->wdev->dev, "multicast delivery timeout\n"); - spin_lock_bh(&wvif->ps_state_lock); - wvif->mcast_tx = wvif->aid0_bit_set && wvif->mcast_buffered; - if (wvif->mcast_tx) - wfx_bh_request_tx(wvif->wdev); - spin_unlock_bh(&wvif->ps_state_lock); + WARN(!wfx_tx_queues_get_after_dtim(wvif), "incorrect sequence"); + WARN(wvif->after_dtim_tx_allowed, "incorrect sequence"); + wvif->after_dtim_tx_allowed = true; + wfx_bh_request_tx(wvif->wdev); } int wfx_ampdu_action(struct ieee80211_hw *hw, @@ -985,25 +946,6 @@ int wfx_ampdu_action(struct ieee80211_hw *hw, return -ENOTSUPP; } -void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd) -{ - bool cancel_tmo = false; - - spin_lock_bh(&wvif->ps_state_lock); - if (notify_cmd == STA_NOTIFY_SLEEP) - wvif->mcast_tx = false; - else - wvif->mcast_tx = wvif->aid0_bit_set && - wvif->mcast_buffered; - if (wvif->mcast_tx) { - cancel_tmo = true; - wfx_bh_request_tx(wvif->wdev); - } - spin_unlock_bh(&wvif->ps_state_lock); - if (cancel_tmo) - del_timer_sync(&wvif->mcast_timeout); -} - int wfx_add_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *conf) { @@ -1090,10 +1032,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) spin_lock_init(&wvif->ps_state_lock); INIT_WORK(&wvif->update_tim_work, wfx_update_tim_work); - INIT_WORK(&wvif->mcast_start_work, wfx_mcast_start_work); - INIT_WORK(&wvif->mcast_stop_work, wfx_mcast_stop_work); - timer_setup(&wvif->mcast_timeout, wfx_mcast_timeout, 0); - memset(&wvif->bss_params, 0, sizeof(wvif->bss_params)); mutex_init(&wvif->bss_loss_lock); @@ -1156,9 +1094,6 @@ void wfx_remove_interface(struct ieee80211_hw *hw, break; case WFX_STATE_AP: wvif->sta_asleep_mask = 0; - wvif->mcast_tx = false; - wvif->aid0_bit_set = false; - wvif->mcast_buffered = false; /* reset.link_id = 0; */ hif_reset(wvif, false); break; @@ -1175,7 +1110,6 @@ void wfx_remove_interface(struct ieee80211_hw *hw, wfx_cqm_bssloss_sm(wvif, 0, 0, 0); cancel_work_sync(&wvif->unjoin_work); - del_timer_sync(&wvif->mcast_timeout); wfx_free_event_queue(wvif); wdev->vif[wvif->id] = NULL; |