mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
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>
This commit is contained in:
parent
4fd0328d2f
commit
2ce113de31
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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 = ¶ms->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 = {
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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, ¶ms);
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user