@@ -1360,6 +1360,18 @@ static inline void drv_wake_tx_queue(struct ieee80211_local *local,
return;
trace_drv_wake_tx_queue(local, sdata, txq);
+
+ /* Driver support for MPDU txqi support is optional */
+ if (unlikely(txq->txq.tid == IEEE80211_NUM_TIDS &&
+ ((sdata->vif.type == NL80211_IFTYPE_STATION &&
+ !ieee80211_hw_check(&sdata->local->hw, STA_MMPDU_TXQ)) ||
+ (sdata->vif.type != NL80211_IFTYPE_STATION &&
+ !ieee80211_hw_check(&sdata->local->hw,
+ BUFF_MMPDU_TXQ))))) {
+ ieee80211_handle_wake_tx_queue(&local->hw, &txq->txq);
+ return;
+ }
+
local->ops->wake_tx_queue(&local->hw, &txq->txq);
}
@@ -620,7 +620,6 @@ __sta_info_alloc(struct ieee80211_sub_if_data *sdata,
for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
struct txq_info *txq = txq_data + i * size;
- /* might not do anything for the (bufferable) MMPDU TXQ */
ieee80211_txq_init(sdata, sta, txq, i);
}
@@ -1310,10 +1310,6 @@ static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local,
ieee80211_is_bufferable_mmpdu(skb) ||
vif->type == NL80211_IFTYPE_STATION) &&
sta && sta->uploaded) {
- /*
- * This will be NULL if the driver didn't set the
- * opt-in hardware flag.
- */
txq = sta->sta.txq[IEEE80211_NUM_TIDS];
}
} else if (sta) {
@@ -1520,21 +1516,10 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
return;
}
- if (tid == IEEE80211_NUM_TIDS) {
- if (sdata->vif.type == NL80211_IFTYPE_STATION) {
- /* Drivers need to opt in to the management MPDU TXQ */
- if (!ieee80211_hw_check(&sdata->local->hw,
- STA_MMPDU_TXQ))
- return;
- } else if (!ieee80211_hw_check(&sdata->local->hw,
- BUFF_MMPDU_TXQ)) {
- /* Drivers need to opt in to the bufferable MMPDU TXQ */
- return;
- }
+ if (tid == IEEE80211_NUM_TIDS)
txqi->txq.ac = IEEE80211_AC_VO;
- } else {
+ else
txqi->txq.ac = ieee80211_ac_from_tid(tid);
- }
txqi->txq.sta = &sta->sta;
txqi->txq.tid = tid;