Commit c82c4a80 authored by Johannes Berg's avatar Johannes Berg

mac80211: split aggregation stop by reason

The initiator/tx doesn't really identify why an
aggregation session is stopped, give a reason
for stopping that more clearly identifies what's
going on. This will help tell the driver clearly
what is expected of it.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent d582cffb
...@@ -150,8 +150,7 @@ void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, ...@@ -150,8 +150,7 @@ void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
} }
int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
enum ieee80211_back_parties initiator, enum ieee80211_agg_stop_reason reason)
bool tx)
{ {
struct ieee80211_local *local = sta->local; struct ieee80211_local *local = sta->local;
struct tid_ampdu_tx *tid_tx; struct tid_ampdu_tx *tid_tx;
...@@ -212,8 +211,10 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, ...@@ -212,8 +211,10 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
*/ */
synchronize_net(); synchronize_net();
tid_tx->stop_initiator = initiator; tid_tx->stop_initiator = reason == AGG_STOP_PEER_REQUEST ?
tid_tx->tx_stop = tx; WLAN_BACK_RECIPIENT :
WLAN_BACK_INITIATOR;
tid_tx->tx_stop = reason == AGG_STOP_LOCAL_REQUEST;
ret = drv_ampdu_action(local, sta->sdata, ret = drv_ampdu_action(local, sta->sdata,
IEEE80211_AMPDU_TX_STOP, IEEE80211_AMPDU_TX_STOP,
...@@ -660,14 +661,13 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, ...@@ -660,14 +661,13 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
enum ieee80211_back_parties initiator, enum ieee80211_agg_stop_reason reason)
bool tx)
{ {
int ret; int ret;
mutex_lock(&sta->ampdu_mlme.mtx); mutex_lock(&sta->ampdu_mlme.mtx);
ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator, tx); ret = ___ieee80211_stop_tx_ba_session(sta, tid, reason);
mutex_unlock(&sta->ampdu_mlme.mtx); mutex_unlock(&sta->ampdu_mlme.mtx);
...@@ -868,8 +868,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, ...@@ -868,8 +868,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
} }
} else { } else {
___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR, ___ieee80211_stop_tx_ba_session(sta, tid, AGG_STOP_DECLINED);
false);
} }
out: out:
......
...@@ -182,16 +182,19 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata, ...@@ -182,16 +182,19 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
ieee80211_apply_htcap_overrides(sdata, ht_cap); ieee80211_apply_htcap_overrides(sdata, ht_cap);
} }
void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx) void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
enum ieee80211_agg_stop_reason reason)
{ {
int i; int i;
cancel_work_sync(&sta->ampdu_mlme.work); cancel_work_sync(&sta->ampdu_mlme.work);
for (i = 0; i < IEEE80211_NUM_TIDS; i++) { for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
__ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR, tx); __ieee80211_stop_tx_ba_session(sta, i, reason);
__ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
WLAN_REASON_QSTA_LEAVE_QBSS, tx); WLAN_REASON_QSTA_LEAVE_QBSS,
reason != AGG_STOP_DESTROY_STA &&
reason != AGG_STOP_PEER_REQUEST);
} }
} }
...@@ -248,8 +251,7 @@ void ieee80211_ba_session_work(struct work_struct *work) ...@@ -248,8 +251,7 @@ void ieee80211_ba_session_work(struct work_struct *work)
if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP, if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
&tid_tx->state)) &tid_tx->state))
___ieee80211_stop_tx_ba_session(sta, tid, ___ieee80211_stop_tx_ba_session(sta, tid,
WLAN_BACK_INITIATOR, AGG_STOP_LOCAL_REQUEST);
true);
} }
mutex_unlock(&sta->ampdu_mlme.mtx); mutex_unlock(&sta->ampdu_mlme.mtx);
} }
...@@ -317,8 +319,7 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, ...@@ -317,8 +319,7 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
__ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0, __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0,
true); true);
else else
__ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, __ieee80211_stop_tx_ba_session(sta, tid, AGG_STOP_PEER_REQUEST);
true);
} }
int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
......
...@@ -1432,7 +1432,8 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, ...@@ -1432,7 +1432,8 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
u16 initiator, u16 reason, bool stop); u16 initiator, u16 reason, bool stop);
void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
u16 initiator, u16 reason, bool stop); u16 initiator, u16 reason, bool stop);
void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx); void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
enum ieee80211_agg_stop_reason reason);
void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta, struct sta_info *sta,
struct ieee80211_mgmt *mgmt, size_t len); struct ieee80211_mgmt *mgmt, size_t len);
...@@ -1446,11 +1447,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, ...@@ -1446,11 +1447,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
size_t len); size_t len);
int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
enum ieee80211_back_parties initiator, enum ieee80211_agg_stop_reason reason);
bool tx);
int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
enum ieee80211_back_parties initiator, enum ieee80211_agg_stop_reason reason);
bool tx);
void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid); void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid);
void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid);
void ieee80211_ba_session_work(struct work_struct *work); void ieee80211_ba_session_work(struct work_struct *work);
......
...@@ -1525,7 +1525,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, ...@@ -1525,7 +1525,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
sta = sta_info_get(sdata, ifmgd->bssid); sta = sta_info_get(sdata, ifmgd->bssid);
if (sta) { if (sta) {
set_sta_flag(sta, WLAN_STA_BLOCK_BA); set_sta_flag(sta, WLAN_STA_BLOCK_BA);
ieee80211_sta_tear_down_BA_sessions(sta, false); ieee80211_sta_tear_down_BA_sessions(sta, AGG_STOP_DESTROY_STA);
} }
mutex_unlock(&local->sta_mtx); mutex_unlock(&local->sta_mtx);
......
...@@ -42,7 +42,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) ...@@ -42,7 +42,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
mutex_lock(&local->sta_mtx); mutex_lock(&local->sta_mtx);
list_for_each_entry(sta, &local->sta_list, list) { list_for_each_entry(sta, &local->sta_list, list) {
set_sta_flag(sta, WLAN_STA_BLOCK_BA); set_sta_flag(sta, WLAN_STA_BLOCK_BA);
ieee80211_sta_tear_down_BA_sessions(sta, true); ieee80211_sta_tear_down_BA_sessions(
sta, AGG_STOP_LOCAL_REQUEST);
} }
mutex_unlock(&local->sta_mtx); mutex_unlock(&local->sta_mtx);
} }
......
...@@ -784,7 +784,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta) ...@@ -784,7 +784,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
* will be sufficient. * will be sufficient.
*/ */
set_sta_flag(sta, WLAN_STA_BLOCK_BA); set_sta_flag(sta, WLAN_STA_BLOCK_BA);
ieee80211_sta_tear_down_BA_sessions(sta, false); ieee80211_sta_tear_down_BA_sessions(sta, AGG_STOP_DESTROY_STA);
ret = sta_info_hash_del(local, sta); ret = sta_info_hash_del(local, sta);
if (ret) if (ret)
......
...@@ -92,6 +92,13 @@ enum ieee80211_sta_info_flags { ...@@ -92,6 +92,13 @@ enum ieee80211_sta_info_flags {
#define HT_AGG_STATE_WANT_START 4 #define HT_AGG_STATE_WANT_START 4
#define HT_AGG_STATE_WANT_STOP 5 #define HT_AGG_STATE_WANT_STOP 5
enum ieee80211_agg_stop_reason {
AGG_STOP_DECLINED,
AGG_STOP_LOCAL_REQUEST,
AGG_STOP_PEER_REQUEST,
AGG_STOP_DESTROY_STA,
};
/** /**
* struct tid_ampdu_tx - TID aggregation information (Tx). * struct tid_ampdu_tx - TID aggregation information (Tx).
* *
......
...@@ -1639,7 +1639,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) ...@@ -1639,7 +1639,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
mutex_lock(&local->sta_mtx); mutex_lock(&local->sta_mtx);
list_for_each_entry(sta, &local->sta_list, list) { list_for_each_entry(sta, &local->sta_list, list) {
ieee80211_sta_tear_down_BA_sessions(sta, true); ieee80211_sta_tear_down_BA_sessions(
sta, AGG_STOP_LOCAL_REQUEST);
clear_sta_flag(sta, WLAN_STA_BLOCK_BA); clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
} }
......
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