Commit 044df863 authored by Jérôme Pouiller's avatar Jérôme Pouiller Committed by Greg Kroah-Hartman

staging: wfx: fix __wfx_flush() when drop == false

wfx_tx_queues_clear() only clear not yet sent requests. So, it always
necessary to wait for tx_queue_stats.wait_link_id_empty whatever the
value of "drop" argument.

In add, it is not necessary to return with tx queue locked since all
calls to __wfx_flush() unlock the tx queue just after the call to
__wfx_tx_flush().
Signed-off-by: default avatarJérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200115135338.14374-20-Jerome.Pouiller@silabs.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 0b2b0595
...@@ -31,8 +31,6 @@ void wfx_tx_flush(struct wfx_dev *wdev) ...@@ -31,8 +31,6 @@ void wfx_tx_flush(struct wfx_dev *wdev)
{ {
int ret; int ret;
WARN(!atomic_read(&wdev->tx_lock), "tx_lock is not locked");
// Do not wait for any reply if chip is frozen // Do not wait for any reply if chip is frozen
if (wdev->chip_frozen) if (wdev->chip_frozen)
return; return;
......
...@@ -343,42 +343,25 @@ int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) ...@@ -343,42 +343,25 @@ int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
return 0; return 0;
} }
/* If successful, LOCKS the TX queue! */
static int __wfx_flush(struct wfx_dev *wdev, bool drop) static int __wfx_flush(struct wfx_dev *wdev, bool drop)
{ {
int ret;
for (;;) { for (;;) {
if (drop) { if (drop)
wfx_tx_queues_clear(wdev); wfx_tx_queues_clear(wdev);
} else { if (wait_event_timeout(wdev->tx_queue_stats.wait_link_id_empty,
ret = wait_event_timeout( wfx_tx_queues_is_empty(wdev),
wdev->tx_queue_stats.wait_link_id_empty, 2 * HZ) <= 0)
wfx_tx_queues_is_empty(wdev), return -ETIMEDOUT;
2 * HZ); wfx_tx_flush(wdev);
} if (wfx_tx_queues_is_empty(wdev))
return 0;
if (!drop && ret <= 0) { dev_warn(wdev->dev, "frames queued while flushing tx queues");
ret = -ETIMEDOUT;
break;
}
ret = 0;
wfx_tx_lock_flush(wdev);
if (!wfx_tx_queues_is_empty(wdev)) {
/* Highly unlikely: WSM requeued frames. */
wfx_tx_unlock(wdev);
continue;
}
break;
} }
return ret;
} }
void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop) u32 queues, bool drop)
{ {
struct wfx_dev *wdev = hw->priv;
struct wfx_vif *wvif; struct wfx_vif *wvif;
if (vif) { if (vif) {
...@@ -389,10 +372,8 @@ void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -389,10 +372,8 @@ void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
!wvif->enable_beacon) !wvif->enable_beacon)
drop = true; drop = true;
} }
// FIXME: only flush requested vif // FIXME: only flush requested vif
if (!__wfx_flush(wdev, drop)) __wfx_flush(hw->priv, drop);
wfx_tx_unlock(wdev);
} }
/* WSM callbacks */ /* WSM callbacks */
...@@ -1046,8 +1027,7 @@ static int wfx_set_tim_impl(struct wfx_vif *wvif, bool aid0_bit_set) ...@@ -1046,8 +1027,7 @@ static int wfx_set_tim_impl(struct wfx_vif *wvif, bool aid0_bit_set)
skb = ieee80211_beacon_get_tim(wvif->wdev->hw, wvif->vif, skb = ieee80211_beacon_get_tim(wvif->wdev->hw, wvif->vif,
&tim_offset, &tim_length); &tim_offset, &tim_length);
if (!skb) { if (!skb) {
if (!__wfx_flush(wvif->wdev, true)) __wfx_flush(wvif->wdev, true);
wfx_tx_unlock(wvif->wdev);
return -ENOENT; return -ENOENT;
} }
tim_ptr = skb->data + tim_offset; tim_ptr = skb->data + tim_offset;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment