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: Jérôme Pouiller <jerome.pouiller@silabs.com> Link: https://lore.kernel.org/r/20200115135338.14374-20-Jerome.Pouiller@silabs.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
0b2b0595ce
Коммит
044df863c9
|
@ -31,8 +31,6 @@ void wfx_tx_flush(struct wfx_dev *wdev)
|
|||
{
|
||||
int ret;
|
||||
|
||||
WARN(!atomic_read(&wdev->tx_lock), "tx_lock is not locked");
|
||||
|
||||
// Do not wait for any reply if chip is frozen
|
||||
if (wdev->chip_frozen)
|
||||
return;
|
||||
|
|
|
@ -343,42 +343,25 @@ int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* If successful, LOCKS the TX queue! */
|
||||
static int __wfx_flush(struct wfx_dev *wdev, bool drop)
|
||||
{
|
||||
int ret;
|
||||
|
||||
for (;;) {
|
||||
if (drop) {
|
||||
if (drop)
|
||||
wfx_tx_queues_clear(wdev);
|
||||
} else {
|
||||
ret = wait_event_timeout(
|
||||
wdev->tx_queue_stats.wait_link_id_empty,
|
||||
if (wait_event_timeout(wdev->tx_queue_stats.wait_link_id_empty,
|
||||
wfx_tx_queues_is_empty(wdev),
|
||||
2 * HZ);
|
||||
2 * HZ) <= 0)
|
||||
return -ETIMEDOUT;
|
||||
wfx_tx_flush(wdev);
|
||||
if (wfx_tx_queues_is_empty(wdev))
|
||||
return 0;
|
||||
dev_warn(wdev->dev, "frames queued while flushing tx queues");
|
||||
}
|
||||
|
||||
if (!drop && ret <= 0) {
|
||||
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,
|
||||
u32 queues, bool drop)
|
||||
{
|
||||
struct wfx_dev *wdev = hw->priv;
|
||||
struct wfx_vif *wvif;
|
||||
|
||||
if (vif) {
|
||||
|
@ -389,10 +372,8 @@ void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
!wvif->enable_beacon)
|
||||
drop = true;
|
||||
}
|
||||
|
||||
// FIXME: only flush requested vif
|
||||
if (!__wfx_flush(wdev, drop))
|
||||
wfx_tx_unlock(wdev);
|
||||
__wfx_flush(hw->priv, drop);
|
||||
}
|
||||
|
||||
/* WSM callbacks */
|
||||
|
@ -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,
|
||||
&tim_offset, &tim_length);
|
||||
if (!skb) {
|
||||
if (!__wfx_flush(wvif->wdev, true))
|
||||
wfx_tx_unlock(wvif->wdev);
|
||||
__wfx_flush(wvif->wdev, true);
|
||||
return -ENOENT;
|
||||
}
|
||||
tim_ptr = skb->data + tim_offset;
|
||||
|
|
Загрузка…
Ссылка в новой задаче