LinuxKPI: 802.11: make sure we are scheduled before wake_tx_queue()

If we are not scheduled before calling wake_tx_queue() packets may
never go out, which at first will look like EAPOL fails (as
wpa_supplicant suggest possibly with a wrong key).  Using monitor
mode it will be clear what is going on.
Pass a flag down to wake_tx_queue() to call ieee80211_schedule_txq()
in case (*wake_tx_queue)() is supported or not, which solves the
problem for the lkpi_80211_txq_tx_one() which was failing.

Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
This commit is contained in:
Bjoern A. Zeeb
2026-02-04 22:39:01 +00:00
parent c529e1a8f8
commit 7d60647a1a
3 changed files with 15 additions and 8 deletions
+4 -4
View File
@@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2020-2025 The FreeBSD Foundation * Copyright (c) 2020-2026 The FreeBSD Foundation
* Copyright (c) 2020-2025 Bjoern A. Zeeb * Copyright (c) 2020-2025 Bjoern A. Zeeb
* *
* This software was developed by Björn Zeeb under sponsorship from * This software was developed by Björn Zeeb under sponsorship from
@@ -2150,7 +2150,7 @@ lkpi_wake_tx_queues(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
if (no_emptyq && ltxq_empty) if (no_emptyq && ltxq_empty)
continue; continue;
lkpi_80211_mo_wake_tx_queue(hw, sta->txq[tid]); lkpi_80211_mo_wake_tx_queue(hw, sta->txq[tid], false);
} }
} }
@@ -5764,7 +5764,7 @@ lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
#endif #endif
LKPI_80211_LTXQ_UNLOCK(ltxq); LKPI_80211_LTXQ_UNLOCK(ltxq);
wiphy_lock(hw->wiphy); wiphy_lock(hw->wiphy);
lkpi_80211_mo_wake_tx_queue(hw, &ltxq->txq); lkpi_80211_mo_wake_tx_queue(hw, &ltxq->txq, true);
wiphy_unlock(hw->wiphy); wiphy_unlock(hw->wiphy);
return; return;
@@ -8751,7 +8751,7 @@ lkpi_ieee80211_wake_queues(struct ieee80211_hw *hw, int hwq)
ltxq->stopped = false; ltxq->stopped = false;
if (!skb_queue_empty(&ltxq->skbq)) if (!skb_queue_empty(&ltxq->skbq))
lkpi_80211_mo_wake_tx_queue(hw, sta->txq[tid]); lkpi_80211_mo_wake_tx_queue(hw, sta->txq[tid], false);
} }
} }
rcu_read_unlock(); rcu_read_unlock();
+3 -2
View File
@@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2020-2023 The FreeBSD Foundation * Copyright (c) 2020-2026 The FreeBSD Foundation
* Copyright (c) 2020-2021 Bjoern A. Zeeb * Copyright (c) 2020-2021 Bjoern A. Zeeb
* *
* This software was developed by Björn Zeeb under sponsorship from * This software was developed by Björn Zeeb under sponsorship from
@@ -481,7 +481,8 @@ void lkpi_80211_mo_mgd_complete_tx(struct ieee80211_hw *, struct ieee80211_vif *
struct ieee80211_prep_tx_info *); struct ieee80211_prep_tx_info *);
void lkpi_80211_mo_tx(struct ieee80211_hw *, struct ieee80211_tx_control *, void lkpi_80211_mo_tx(struct ieee80211_hw *, struct ieee80211_tx_control *,
struct sk_buff *); struct sk_buff *);
void lkpi_80211_mo_wake_tx_queue(struct ieee80211_hw *, struct ieee80211_txq *); void lkpi_80211_mo_wake_tx_queue(struct ieee80211_hw *, struct ieee80211_txq *,
bool);
void lkpi_80211_mo_sync_rx_queues(struct ieee80211_hw *); void lkpi_80211_mo_sync_rx_queues(struct ieee80211_hw *);
void lkpi_80211_mo_sta_pre_rcu_remove(struct ieee80211_hw *, void lkpi_80211_mo_sta_pre_rcu_remove(struct ieee80211_hw *,
struct ieee80211_vif *, struct ieee80211_sta *); struct ieee80211_vif *, struct ieee80211_sta *);
@@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2021-2022 The FreeBSD Foundation * Copyright (c) 2021-2026 The FreeBSD Foundation
* *
* This software was developed by Björn Zeeb under sponsorship from * This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation. * the FreeBSD Foundation.
@@ -644,11 +644,17 @@ lkpi_80211_mo_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *txctrl,
} }
void void
lkpi_80211_mo_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq) lkpi_80211_mo_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq,
bool schedule)
{ {
struct lkpi_hw *lhw; struct lkpi_hw *lhw;
lhw = HW_TO_LHW(hw); lhw = HW_TO_LHW(hw);
/* Do the schedule before the check for wake_tx_queue supported! */
if (schedule)
ieee80211_schedule_txq(hw, txq);
if (lhw->ops->wake_tx_queue == NULL) if (lhw->ops->wake_tx_queue == NULL)
return; return;