Commit bd2ce6e4 authored by Sujith Manoharan's avatar Sujith Manoharan Committed by John W. Linville

mac80211: Add timeout to BA session start API

Allow drivers or rate control algorithms to specify BlockAck session
timeout when initiating an ADDBA transaction. This is useful in cases
where maintaining persistent BA sessions does not incur any overhead.

The current timeout value of 5000 TUs is retained for all non ath9k/ath9k_htc
drivers.
Signed-off-by: default avatarSujith Manoharan <Sujith.Manoharan@atheros.com>
Reviewed-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent a293911d
...@@ -251,7 +251,7 @@ void ath9k_tx_tasklet(unsigned long data) ...@@ -251,7 +251,7 @@ void ath9k_tx_tasklet(unsigned long data)
ista = (struct ath9k_htc_sta *)sta->drv_priv; ista = (struct ath9k_htc_sta *)sta->drv_priv;
if (ath9k_htc_check_tx_aggr(priv, ista, tid)) { if (ath9k_htc_check_tx_aggr(priv, ista, tid)) {
ieee80211_start_tx_ba_session(sta, tid); ieee80211_start_tx_ba_session(sta, tid, 0);
spin_lock_bh(&priv->tx_lock); spin_lock_bh(&priv->tx_lock);
ista->tid_state[tid] = AGGR_PROGRESS; ista->tid_state[tid] = AGGR_PROGRESS;
spin_unlock_bh(&priv->tx_lock); spin_unlock_bh(&priv->tx_lock);
......
...@@ -1373,7 +1373,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, ...@@ -1373,7 +1373,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
an = (struct ath_node *)sta->drv_priv; an = (struct ath_node *)sta->drv_priv;
if(ath_tx_aggr_check(sc, an, tid)) if(ath_tx_aggr_check(sc, an, tid))
ieee80211_start_tx_ba_session(sta, tid); ieee80211_start_tx_ba_session(sta, tid, 0);
} }
} }
......
...@@ -387,7 +387,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, ...@@ -387,7 +387,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
if (load > IWL_AGG_LOAD_THRESHOLD) { if (load > IWL_AGG_LOAD_THRESHOLD) {
IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
sta->addr, tid); sta->addr, tid);
ret = ieee80211_start_tx_ba_session(sta, tid); ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
if (ret == -EAGAIN) { if (ret == -EAGAIN) {
/* /*
* driver and mac80211 is out of sync * driver and mac80211 is out of sync
......
...@@ -169,7 +169,7 @@ static void rtl_tx_status(void *ppriv, ...@@ -169,7 +169,7 @@ static void rtl_tx_status(void *ppriv,
tid = qc[0] & 0xf; tid = qc[0] & 0xf;
if (_rtl_tx_aggr_check(rtlpriv, tid)) if (_rtl_tx_aggr_check(rtlpriv, tid))
ieee80211_start_tx_ba_session(sta, tid); ieee80211_start_tx_ba_session(sta, tid, 5000);
} }
} }
} }
......
...@@ -2435,6 +2435,7 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, ...@@ -2435,6 +2435,7 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
* ieee80211_start_tx_ba_session - Start a tx Block Ack session. * ieee80211_start_tx_ba_session - Start a tx Block Ack session.
* @sta: the station for which to start a BA session * @sta: the station for which to start a BA session
* @tid: the TID to BA on. * @tid: the TID to BA on.
* @timeout: session timeout value (in TUs)
* *
* Return: success if addBA request was sent, failure otherwise * Return: success if addBA request was sent, failure otherwise
* *
...@@ -2442,7 +2443,8 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, ...@@ -2442,7 +2443,8 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
* the need to start aggregation on a certain RA/TID, the session level * the need to start aggregation on a certain RA/TID, the session level
* will be managed by the mac80211. * will be managed by the mac80211.
*/ */
int ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, u16 tid); int ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, u16 tid,
u16 timeout);
/** /**
* ieee80211_start_tx_ba_cb_irqsafe - low level driver ready to aggregate. * ieee80211_start_tx_ba_cb_irqsafe - low level driver ready to aggregate.
......
...@@ -342,10 +342,11 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) ...@@ -342,10 +342,11 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
/* send AddBA request */ /* send AddBA request */
ieee80211_send_addba_request(sdata, sta->sta.addr, tid, ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
tid_tx->dialog_token, start_seq_num, tid_tx->dialog_token, start_seq_num,
0x40, 5000); 0x40, tid_tx->timeout);
} }
int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
u16 timeout)
{ {
struct sta_info *sta = container_of(pubsta, struct sta_info, sta); struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
struct ieee80211_sub_if_data *sdata = sta->sdata; struct ieee80211_sub_if_data *sdata = sta->sdata;
...@@ -420,6 +421,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) ...@@ -420,6 +421,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
skb_queue_head_init(&tid_tx->pending); skb_queue_head_init(&tid_tx->pending);
__set_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); __set_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
tid_tx->timeout = timeout;
/* Tx timer */ /* Tx timer */
tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired; tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired;
tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid]; tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid];
......
...@@ -189,7 +189,7 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu ...@@ -189,7 +189,7 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu
if (tx) { if (tx) {
if (start) if (start)
ret = ieee80211_start_tx_ba_session(&sta->sta, tid); ret = ieee80211_start_tx_ba_session(&sta->sta, tid, 5000);
else else
ret = ieee80211_stop_tx_ba_session(&sta->sta, tid); ret = ieee80211_stop_tx_ba_session(&sta->sta, tid);
} else { } else {
......
...@@ -374,7 +374,7 @@ minstrel_aggr_check(struct minstrel_priv *mp, struct ieee80211_sta *pubsta, stru ...@@ -374,7 +374,7 @@ minstrel_aggr_check(struct minstrel_priv *mp, struct ieee80211_sta *pubsta, stru
if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
return; return;
ieee80211_start_tx_ba_session(pubsta, tid); ieee80211_start_tx_ba_session(pubsta, tid, 5000);
} }
static void static void
......
...@@ -78,6 +78,7 @@ enum ieee80211_sta_info_flags { ...@@ -78,6 +78,7 @@ enum ieee80211_sta_info_flags {
* @addba_resp_timer: timer for peer's response to addba request * @addba_resp_timer: timer for peer's response to addba request
* @pending: pending frames queue -- use sta's spinlock to protect * @pending: pending frames queue -- use sta's spinlock to protect
* @dialog_token: dialog token for aggregation session * @dialog_token: dialog token for aggregation session
* @timeout: session timeout value to be filled in ADDBA requests
* @state: session state (see above) * @state: session state (see above)
* @stop_initiator: initiator of a session stop * @stop_initiator: initiator of a session stop
* @tx_stop: TX DelBA frame when stopping * @tx_stop: TX DelBA frame when stopping
...@@ -96,6 +97,7 @@ struct tid_ampdu_tx { ...@@ -96,6 +97,7 @@ struct tid_ampdu_tx {
struct timer_list addba_resp_timer; struct timer_list addba_resp_timer;
struct sk_buff_head pending; struct sk_buff_head pending;
unsigned long state; unsigned long state;
u16 timeout;
u8 dialog_token; u8 dialog_token;
u8 stop_initiator; u8 stop_initiator;
bool tx_stop; bool tx_stop;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment