Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mac80211: simplify TX aggregation start

There really is no need to make drivers call the
ieee80211_start_tx_ba_cb_irqsafe() function and then
schedule the worker if all we want is to set a bit.

Add a new return value (that was previously considered
invalid) to indicate that the driver is immediately
ready for the session, and make drivers use it. The
only drivers that remain different are the Intel ones
as they need to negotiate more with the firmware.

Link: https://lore.kernel.org/r/1570007543-I152912660131cbab2e5d80b4218238c20f8a06e5@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

+39 -35
+1 -1
drivers/net/wireless/ath/ath9k/htc_drv_main.c
··· 1674 1674 case IEEE80211_AMPDU_TX_START: 1675 1675 ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid); 1676 1676 if (!ret) 1677 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 1677 + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; 1678 1678 break; 1679 1679 case IEEE80211_AMPDU_TX_STOP_CONT: 1680 1680 case IEEE80211_AMPDU_TX_STOP_FLUSH:
+1 -1
drivers/net/wireless/ath/ath9k/main.c
··· 1921 1921 ath9k_ps_wakeup(sc); 1922 1922 ret = ath_tx_aggr_start(sc, sta, tid, ssn); 1923 1923 if (!ret) 1924 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 1924 + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; 1925 1925 ath9k_ps_restore(sc); 1926 1926 break; 1927 1927 case IEEE80211_AMPDU_TX_STOP_FLUSH:
+1 -2
drivers/net/wireless/ath/carl9170/main.c
··· 1449 1449 rcu_assign_pointer(sta_info->agg[tid], tid_info); 1450 1450 spin_unlock_bh(&ar->tx_ampdu_list_lock); 1451 1451 1452 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 1453 - break; 1452 + return IEEE80211_AMPDU_TX_START_IMMEDIATE; 1454 1453 1455 1454 case IEEE80211_AMPDU_TX_STOP_CONT: 1456 1455 case IEEE80211_AMPDU_TX_STOP_FLUSH:
+3 -2
drivers/net/wireless/ath/wcn36xx/main.c
··· 1084 1084 enum ieee80211_ampdu_mlme_action action = params->action; 1085 1085 u16 tid = params->tid; 1086 1086 u16 *ssn = &params->ssn; 1087 + int ret = 0; 1087 1088 1088 1089 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n", 1089 1090 action, tid); ··· 1107 1106 sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_START; 1108 1107 spin_unlock_bh(&sta_priv->ampdu_lock); 1109 1108 1110 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 1109 + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; 1111 1110 break; 1112 1111 case IEEE80211_AMPDU_TX_OPERATIONAL: 1113 1112 spin_lock_bh(&sta_priv->ampdu_lock); ··· 1132 1131 1133 1132 mutex_unlock(&wcn->conf_mutex); 1134 1133 1135 - return 0; 1134 + return ret; 1136 1135 } 1137 1136 1138 1137 static const struct ieee80211_ops wcn36xx_ops = {
+1 -2
drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
··· 850 850 "START: tid %d is not agg\'able\n", tid); 851 851 return -EINVAL; 852 852 } 853 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 854 - break; 853 + return IEEE80211_AMPDU_TX_START_IMMEDIATE; 855 854 856 855 case IEEE80211_AMPDU_TX_STOP_CONT: 857 856 case IEEE80211_AMPDU_TX_STOP_FLUSH:
+1 -1
drivers/net/wireless/intel/iwlegacy/4965-mac.c
··· 2265 2265 if (tid_data->tfds_in_queue == 0) { 2266 2266 D_HT("HW queue is empty\n"); 2267 2267 tid_data->agg.state = IL_AGG_ON; 2268 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 2268 + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; 2269 2269 } else { 2270 2270 D_HT("HW queue is NOT empty: %d packets in HW queue\n", 2271 2271 tid_data->tfds_in_queue);
+1 -1
drivers/net/wireless/intel/iwlwifi/dvm/tx.c
··· 621 621 IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n", 622 622 tid_data->agg.ssn); 623 623 tid_data->agg.state = IWL_AGG_STARTING; 624 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 624 + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; 625 625 } else { 626 626 IWL_DEBUG_TX_QUEUES(priv, "Can't proceed: ssn %d, " 627 627 "next_reclaimed = %d\n",
+2 -3
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
··· 2818 2818 2819 2819 if (normalized_ssn == tid_data->next_reclaimed) { 2820 2820 tid_data->state = IWL_AGG_STARTING; 2821 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 2821 + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; 2822 2822 } else { 2823 2823 tid_data->state = IWL_EMPTYING_HW_QUEUE_ADDBA; 2824 + ret = 0; 2824 2825 } 2825 - 2826 - ret = 0; 2827 2826 2828 2827 out: 2829 2828 spin_unlock_bh(&mvmsta->lock);
+1 -2
drivers/net/wireless/mac80211_hwsim.c
··· 1979 1979 1980 1980 switch (action) { 1981 1981 case IEEE80211_AMPDU_TX_START: 1982 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 1983 - break; 1982 + return IEEE80211_AMPDU_TX_START_IMMEDIATE; 1984 1983 case IEEE80211_AMPDU_TX_STOP_CONT: 1985 1984 case IEEE80211_AMPDU_TX_STOP_FLUSH: 1986 1985 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+1 -1
drivers/net/wireless/marvell/mwl8k.c
··· 5520 5520 rc = -EBUSY; 5521 5521 break; 5522 5522 } 5523 - ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid); 5523 + rc = IEEE80211_AMPDU_TX_START_IMMEDIATE; 5524 5524 break; 5525 5525 case IEEE80211_AMPDU_TX_STOP_CONT: 5526 5526 case IEEE80211_AMPDU_TX_STOP_FLUSH:
+1 -2
drivers/net/wireless/mediatek/mt76/mt7603/main.c
··· 582 582 break; 583 583 case IEEE80211_AMPDU_TX_START: 584 584 mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn); 585 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 586 - break; 585 + return IEEE80211_AMPDU_TX_START_IMMEDIATE; 587 586 case IEEE80211_AMPDU_TX_STOP_CONT: 588 587 mtxq->aggr = false; 589 588 mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, -1);
+1 -2
drivers/net/wireless/mediatek/mt76/mt7615/main.c
··· 477 477 break; 478 478 case IEEE80211_AMPDU_TX_START: 479 479 mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn); 480 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 481 - break; 480 + return IEEE80211_AMPDU_TX_START_IMMEDIATE; 482 481 case IEEE80211_AMPDU_TX_STOP_CONT: 483 482 mtxq->aggr = false; 484 483 mt7615_mcu_set_tx_ba(dev, params, 0);
+1 -2
drivers/net/wireless/mediatek/mt76/mt76x02_util.c
··· 393 393 break; 394 394 case IEEE80211_AMPDU_TX_START: 395 395 mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn); 396 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 397 - break; 396 + return IEEE80211_AMPDU_TX_START_IMMEDIATE; 398 397 case IEEE80211_AMPDU_TX_STOP_CONT: 399 398 mtxq->aggr = false; 400 399 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+1 -2
drivers/net/wireless/mediatek/mt7601u/main.c
··· 372 372 break; 373 373 case IEEE80211_AMPDU_TX_START: 374 374 msta->agg_ssn[tid] = ssn << 4; 375 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 376 - break; 375 + return IEEE80211_AMPDU_TX_START_IMMEDIATE; 377 376 case IEEE80211_AMPDU_TX_STOP_CONT: 378 377 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); 379 378 break;
+2 -2
drivers/net/wireless/ralink/rt2x00/rt2800lib.c
··· 10476 10476 * when the hw reorders frames due to aggregation. 10477 10477 */ 10478 10478 if (sta_priv->wcid > WCID_END) 10479 - return 1; 10479 + return -ENOSPC; 10480 10480 10481 10481 switch (action) { 10482 10482 case IEEE80211_AMPDU_RX_START: ··· 10489 10489 */ 10490 10490 break; 10491 10491 case IEEE80211_AMPDU_TX_START: 10492 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 10492 + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; 10493 10493 break; 10494 10494 case IEEE80211_AMPDU_TX_STOP_CONT: 10495 10495 case IEEE80211_AMPDU_TX_STOP_FLUSH:
+1 -2
drivers/net/wireless/realtek/rtlwifi/base.c
··· 1776 1776 1777 1777 tid_data->agg.agg_state = RTL_AGG_START; 1778 1778 1779 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 1780 - return 0; 1779 + return IEEE80211_AMPDU_TX_START_IMMEDIATE; 1781 1780 } 1782 1781 1783 1782 int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+1 -2
drivers/net/wireless/realtek/rtw88/mac80211.c
··· 437 437 438 438 switch (params->action) { 439 439 case IEEE80211_AMPDU_TX_START: 440 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 441 - break; 440 + return IEEE80211_AMPDU_TX_START_IMMEDIATE; 442 441 case IEEE80211_AMPDU_TX_STOP_CONT: 443 442 case IEEE80211_AMPDU_TX_STOP_FLUSH: 444 443 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+1 -2
drivers/net/wireless/rsi/rsi_91x_mac80211.c
··· 1140 1140 else if ((vif->type == NL80211_IFTYPE_AP) || 1141 1141 (vif->type == NL80211_IFTYPE_P2P_GO)) 1142 1142 rsta->seq_start[tid] = seq_no; 1143 - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 1144 - status = 0; 1143 + status = IEEE80211_AMPDU_TX_START_IMMEDIATE; 1145 1144 break; 1146 1145 1147 1146 case IEEE80211_AMPDU_TX_STOP_CONT:
+9 -2
include/net/mac80211.h
··· 3095 3095 * 3096 3096 * @IEEE80211_AMPDU_RX_START: start RX aggregation 3097 3097 * @IEEE80211_AMPDU_RX_STOP: stop RX aggregation 3098 - * @IEEE80211_AMPDU_TX_START: start TX aggregation 3098 + * @IEEE80211_AMPDU_TX_START: start TX aggregation, the driver must either 3099 + * call ieee80211_start_tx_ba_cb_irqsafe() or return the special 3100 + * status %IEEE80211_AMPDU_TX_START_IMMEDIATE. 3099 3101 * @IEEE80211_AMPDU_TX_OPERATIONAL: TX aggregation has become operational 3100 3102 * @IEEE80211_AMPDU_TX_STOP_CONT: stop TX aggregation but continue transmitting 3101 3103 * queued packets, now unaggregated. After all packets are transmitted the ··· 3120 3118 IEEE80211_AMPDU_TX_STOP_FLUSH_CONT, 3121 3119 IEEE80211_AMPDU_TX_OPERATIONAL, 3122 3120 }; 3121 + 3122 + #define IEEE80211_AMPDU_TX_START_IMMEDIATE 1 3123 3123 3124 3124 /** 3125 3125 * struct ieee80211_ampdu_params - AMPDU action parameters ··· 3900 3896 * 3901 3897 * Even ``189`` would be wrong since 1 could be lost again. 3902 3898 * 3903 - * Returns a negative error code on failure. 3899 + * Returns a negative error code on failure. The driver may return 3900 + * %IEEE80211_AMPDU_TX_START_IMMEDIATE for %IEEE80211_AMPDU_TX_START 3901 + * if the session can start immediately. 3902 + * 3904 3903 * The callback can sleep. 3905 3904 */ 3906 3905 int (*ampdu_action)(struct ieee80211_hw *hw,
+8 -1
net/mac80211/agg-tx.c
··· 485 485 486 486 params.ssn = sta->tid_seq[tid] >> 4; 487 487 ret = drv_ampdu_action(local, sdata, &params); 488 - if (ret) { 488 + if (ret == IEEE80211_AMPDU_TX_START_IMMEDIATE) { 489 + /* 490 + * We didn't send the request yet, so don't need to check 491 + * here if we already got a response, just mark as driver 492 + * ready immediately. 493 + */ 494 + set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state); 495 + } else if (ret) { 489 496 ht_dbg(sdata, 490 497 "BA request denied - HW unavailable for %pM tid %d\n", 491 498 sta->sta.addr, tid);