mac80211: simplify TX aggregation start
authorJohannes Berg <johannes.berg@intel.com>
Wed, 2 Oct 2019 09:12:25 +0000 (11:12 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 4 Oct 2019 11:58:13 +0000 (13:58 +0200)
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>
20 files changed:
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/carl9170/main.c
drivers/net/wireless/ath/wcn36xx/main.c
drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/intel/iwlegacy/4965-mac.c
drivers/net/wireless/intel/iwlwifi/dvm/tx.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/marvell/mwl8k.c
drivers/net/wireless/mediatek/mt76/mt7603/main.c
drivers/net/wireless/mediatek/mt76/mt7615/main.c
drivers/net/wireless/mediatek/mt76/mt76x02_util.c
drivers/net/wireless/mediatek/mt7601u/main.c
drivers/net/wireless/ralink/rt2x00/rt2800lib.c
drivers/net/wireless/realtek/rtlwifi/base.c
drivers/net/wireless/realtek/rtw88/mac80211.c
drivers/net/wireless/rsi/rsi_91x_mac80211.c
include/net/mac80211.h
net/mac80211/agg-tx.c

index a82ad739ab80653efd17b2eae0929fb4c224432f..791f6633667ce516d10074b71d251fbd6862a18d 100644 (file)
@@ -1674,7 +1674,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
        case IEEE80211_AMPDU_TX_START:
                ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
                if (!ret)
-                       ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+                       ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
                break;
        case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
index 34121fbf32e37a9a3931b81fa384fe3e8e67408a..0548aa3702e3b4df782605200ab37855c6adb926 100644 (file)
@@ -1921,7 +1921,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
                ath9k_ps_wakeup(sc);
                ret = ath_tx_aggr_start(sc, sta, tid, ssn);
                if (!ret)
-                       ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+                       ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
                ath9k_ps_restore(sc);
                break;
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
index 40a8054f8aa680178997e412ffa772086b791d1b..5914926a5c5b8add0e387dff9dea1b39559f24e8 100644 (file)
@@ -1449,8 +1449,7 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw,
                rcu_assign_pointer(sta_info->agg[tid], tid_info);
                spin_unlock_bh(&ar->tx_ampdu_list_lock);
 
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
 
        case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
index 79998a3ddb7afaf4df76449e5567e59aaf69863f..a276dae30887128eddf529f25eb74f33ea771cc1 100644 (file)
@@ -1084,6 +1084,7 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
        enum ieee80211_ampdu_mlme_action action = params->action;
        u16 tid = params->tid;
        u16 *ssn = &params->ssn;
+       int ret = 0;
 
        wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n",
                    action, tid);
@@ -1106,7 +1107,7 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
                sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_START;
                spin_unlock_bh(&sta_priv->ampdu_lock);
 
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
                break;
        case IEEE80211_AMPDU_TX_OPERATIONAL:
                spin_lock_bh(&sta_priv->ampdu_lock);
@@ -1131,7 +1132,7 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
 
        mutex_unlock(&wcn->conf_mutex);
 
-       return 0;
+       return ret;
 }
 
 static const struct ieee80211_ops wcn36xx_ops = {
index 6188275b17e5aee8df963ee5c848a4d5d4921687..8e8b685cfe09b5161d3a2f7b1d03d8ee842472df 100644 (file)
@@ -850,8 +850,7 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw,
                                     "START: tid %d is not agg\'able\n", tid);
                        return -EINVAL;
                }
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
 
        case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
index ffb705b18fb13bd3a44753087358e72ded6aea75..51fdd7ce30aff66e5a5cbbc99254be5bd1e474c4 100644 (file)
@@ -2265,7 +2265,7 @@ il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif,
        if (tid_data->tfds_in_queue == 0) {
                D_HT("HW queue is empty\n");
                tid_data->agg.state = IL_AGG_ON;
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
        } else {
                D_HT("HW queue is NOT empty: %d packets in HW queue\n",
                     tid_data->tfds_in_queue);
index 3029e3f6de63b5e8feeab7ef0505c18c2ffd17e8..cd73fc5cfcbb21c537cde3e05e7025f6387edcc4 100644 (file)
@@ -621,7 +621,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
                IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n",
                                    tid_data->agg.ssn);
                tid_data->agg.state = IWL_AGG_STARTING;
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
        } else {
                IWL_DEBUG_TX_QUEUES(priv, "Can't proceed: ssn %d, "
                                    "next_reclaimed = %d\n",
index 0bedba4c61f2ae898c7ddbb612d041e9c9fdd7dc..1d6bc62b104cd3721d387eb325c554eb87be0ecf 100644 (file)
@@ -2818,13 +2818,12 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 
        if (normalized_ssn == tid_data->next_reclaimed) {
                tid_data->state = IWL_AGG_STARTING;
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
        } else {
                tid_data->state = IWL_EMPTYING_HW_QUEUE_ADDBA;
+               ret = 0;
        }
 
-       ret = 0;
-
 out:
        spin_unlock_bh(&mvmsta->lock);
 
index 635956024e8859308f0f42bf3670db2bb0abf614..1aeb38296ec3bf5e910354fc17fd6fb38c8f7905 100644 (file)
@@ -1979,8 +1979,7 @@ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
 
        switch (action) {
        case IEEE80211_AMPDU_TX_START:
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
        case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
        case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
index c4db6417748f346518619c65720c443968a3544e..d55f229abeea66a1cd4cc9c4938f00170f1d59bf 100644 (file)
@@ -5520,7 +5520,7 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        rc = -EBUSY;
                        break;
                }
-               ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid);
+               rc = IEEE80211_AMPDU_TX_START_IMMEDIATE;
                break;
        case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
index 25d5b1608bc91d7e2cdc49e8d191826e1007d6db..4b3217b43a04fe289cce6abc023c53e75e253f76 100644 (file)
@@ -582,8 +582,7 @@ mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                break;
        case IEEE80211_AMPDU_TX_START:
                mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn);
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
        case IEEE80211_AMPDU_TX_STOP_CONT:
                mtxq->aggr = false;
                mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, -1);
index 87c748715b5d70091ae38ad66d0bf318941e9bcf..b6d78212306a3d0e499692425c2738c1116c6ddc 100644 (file)
@@ -477,8 +477,7 @@ mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                break;
        case IEEE80211_AMPDU_TX_START:
                mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn);
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
        case IEEE80211_AMPDU_TX_STOP_CONT:
                mtxq->aggr = false;
                mt7615_mcu_set_tx_ba(dev, params, 0);
index aec73a0295e86eb800f38d9d47285b4a47faac13..414b22399d9366911b2f41ae62dee517e1d4f7a3 100644 (file)
@@ -393,8 +393,7 @@ int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                break;
        case IEEE80211_AMPDU_TX_START:
                mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn);
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
        case IEEE80211_AMPDU_TX_STOP_CONT:
                mtxq->aggr = false;
                ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
index 72e608cc53afcb6b2ecc1b5732674a6840fad8af..671d8897ae76c2b4c0c018c46d7de96ad24a49a0 100644 (file)
@@ -372,8 +372,7 @@ mt76_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                break;
        case IEEE80211_AMPDU_TX_START:
                msta->agg_ssn[tid] = ssn << 4;
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
        case IEEE80211_AMPDU_TX_STOP_CONT:
                ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
                break;
index f1cdcd61c54a5eeec18fc349e63a5cd832cb17fa..25466454b73e94cb802ee6a59058c14d539f38e1 100644 (file)
@@ -10476,7 +10476,7 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
         * when the hw reorders frames due to aggregation.
         */
        if (sta_priv->wcid > WCID_END)
-               return 1;
+               return -ENOSPC;
 
        switch (action) {
        case IEEE80211_AMPDU_RX_START:
@@ -10489,7 +10489,7 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                 */
                break;
        case IEEE80211_AMPDU_TX_START:
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
                break;
        case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
index ac746c322554b393676f79f214b9fccdfddb3fda..c75192c4447f91ff2d91fe8042a8d2a2bd521487 100644 (file)
@@ -1776,8 +1776,7 @@ int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
        tid_data->agg.agg_state = RTL_AGG_START;
 
-       ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-       return 0;
+       return IEEE80211_AMPDU_TX_START_IMMEDIATE;
 }
 
 int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
index e5e3605bb6931c1c6f0d87a1434ce78eedc9f36a..a203b4705b9449cf670a5bee86fce487df276b8c 100644 (file)
@@ -437,8 +437,7 @@ static int rtw_ops_ampdu_action(struct ieee80211_hw *hw,
 
        switch (params->action) {
        case IEEE80211_AMPDU_TX_START:
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
        case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
        case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
index ce5e92d82efc8038dc02bd777a7805add811860a..440088293afff4a381c71e1f4759e100d6129e64 100644 (file)
@@ -1140,8 +1140,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
                else if ((vif->type == NL80211_IFTYPE_AP) ||
                         (vif->type == NL80211_IFTYPE_P2P_GO))
                        rsta->seq_start[tid] = seq_no;
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               status = 0;
+               status = IEEE80211_AMPDU_TX_START_IMMEDIATE;
                break;
 
        case IEEE80211_AMPDU_TX_STOP_CONT:
index 523c6a09e1c8c722a725b03f2ca0d09ff638afca..d69081c38788ac2474d389b6203323b58794e898 100644 (file)
@@ -3095,7 +3095,9 @@ enum ieee80211_filter_flags {
  *
  * @IEEE80211_AMPDU_RX_START: start RX aggregation
  * @IEEE80211_AMPDU_RX_STOP: stop RX aggregation
- * @IEEE80211_AMPDU_TX_START: start TX aggregation
+ * @IEEE80211_AMPDU_TX_START: start TX aggregation, the driver must either
+ *     call ieee80211_start_tx_ba_cb_irqsafe() or return the special
+ *     status %IEEE80211_AMPDU_TX_START_IMMEDIATE.
  * @IEEE80211_AMPDU_TX_OPERATIONAL: TX aggregation has become operational
  * @IEEE80211_AMPDU_TX_STOP_CONT: stop TX aggregation but continue transmitting
  *     queued packets, now unaggregated. After all packets are transmitted the
@@ -3119,6 +3121,8 @@ enum ieee80211_ampdu_mlme_action {
        IEEE80211_AMPDU_TX_OPERATIONAL,
 };
 
+#define IEEE80211_AMPDU_TX_START_IMMEDIATE 1
+
 /**
  * struct ieee80211_ampdu_params - AMPDU action parameters
  *
@@ -3896,7 +3900,10 @@ struct ieee80211_ops {
         *
         * Even ``189`` would be wrong since 1 could be lost again.
         *
-        * Returns a negative error code on failure.
+        * Returns a negative error code on failure. The driver may return
+        * %IEEE80211_AMPDU_TX_START_IMMEDIATE for %IEEE80211_AMPDU_TX_START
+        * if the session can start immediately.
+        *
         * The callback can sleep.
         */
        int (*ampdu_action)(struct ieee80211_hw *hw,
index b11883d268759a4f2eb138b7c3aa2027fc833b21..33da6f738c999270ebdfd1364cf30f57b8797166 100644 (file)
@@ -485,7 +485,14 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
 
        params.ssn = sta->tid_seq[tid] >> 4;
        ret = drv_ampdu_action(local, sdata, &params);
-       if (ret) {
+       if (ret == IEEE80211_AMPDU_TX_START_IMMEDIATE) {
+               /*
+                * We didn't send the request yet, so don't need to check
+                * here if we already got a response, just mark as driver
+                * ready immediately.
+                */
+               set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state);
+       } else if (ret) {
                ht_dbg(sdata,
                       "BA request denied - HW unavailable for %pM tid %d\n",
                       sta->sta.addr, tid);