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:
Jérôme Pouiller 2020-01-15 13:54:29 +00:00 коммит произвёл Greg Kroah-Hartman
Родитель 0b2b0595ce
Коммит 044df863c9
2 изменённых файлов: 11 добавлений и 33 удалений

Просмотреть файл

@ -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;