mac80211: split aggregation stop by reason
authorJohannes Berg <johannes.berg@intel.com>
Wed, 18 Jul 2012 11:31:31 +0000 (13:31 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 3 Jan 2013 12:01:41 +0000 (13:01 +0100)
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: Johannes Berg <johannes.berg@intel.com>
net/mac80211/agg-tx.c
net/mac80211/ht.c
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/pm.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/util.c

index eb9df22418f08106241c51e6646b3c3d25c2f128..e0656d77b313d5eb3223361498e92c4b406d3cc8 100644 (file)
@@ -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,
-                                   enum ieee80211_back_parties initiator,
-                                   bool tx)
+                                   enum ieee80211_agg_stop_reason reason)
 {
        struct ieee80211_local *local = sta->local;
        struct tid_ampdu_tx *tid_tx;
@@ -212,8 +211,10 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
         */
        synchronize_net();
 
-       tid_tx->stop_initiator = initiator;
-       tid_tx->tx_stop = tx;
+       tid_tx->stop_initiator = reason == AGG_STOP_PEER_REQUEST ?
+                                       WLAN_BACK_RECIPIENT :
+                                       WLAN_BACK_INITIATOR;
+       tid_tx->tx_stop = reason == AGG_STOP_LOCAL_REQUEST;
 
        ret = drv_ampdu_action(local, sta->sdata,
                               IEEE80211_AMPDU_TX_STOP,
@@ -660,14 +661,13 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
 
 int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
-                                  enum ieee80211_back_parties initiator,
-                                  bool tx)
+                                  enum ieee80211_agg_stop_reason reason)
 {
        int ret;
 
        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);
 
@@ -868,8 +868,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
                }
 
        } else {
-               ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR,
-                                               false);
+               ___ieee80211_stop_tx_ba_session(sta, tid, AGG_STOP_DECLINED);
        }
 
  out:
index 8a6d68f1f404cf590a936ed1f058666337953572..df46cd8e55f580b329818c9b7177a9ed904bc5ef 100644 (file)
@@ -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);
 }
 
-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;
 
        cancel_work_sync(&sta->ampdu_mlme.work);
 
        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,
-                                              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)
                if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
                                                 &tid_tx->state))
                        ___ieee80211_stop_tx_ba_session(sta, tid,
-                                                       WLAN_BACK_INITIATOR,
-                                                       true);
+                                                       AGG_STOP_LOCAL_REQUEST);
        }
        mutex_unlock(&sta->ampdu_mlme.mtx);
 }
@@ -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,
                                               true);
        else
-               __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
-                                              true);
+               __ieee80211_stop_tx_ba_session(sta, tid, AGG_STOP_PEER_REQUEST);
 }
 
 int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
index 7182907e282a2290488fa05f8ff552d31b3022ad..0fa44a965ad923ff09619f9d040f42cb62535887 100644 (file)
@@ -1432,7 +1432,8 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
                                     u16 initiator, u16 reason, bool stop);
 void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
                                    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,
                             struct sta_info *sta,
                             struct ieee80211_mgmt *mgmt, size_t len);
@@ -1446,11 +1447,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
                                     size_t len);
 
 int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
-                                  enum ieee80211_back_parties initiator,
-                                  bool tx);
+                                  enum ieee80211_agg_stop_reason reason);
 int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
-                                   enum ieee80211_back_parties initiator,
-                                   bool tx);
+                                   enum ieee80211_agg_stop_reason reason);
 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_ba_session_work(struct work_struct *work);
index 6ffbf701de95a72bb15b5dba18b6a790038efc39..d90c07b1795f284db3036d1b472ecceb7660ff96 100644 (file)
@@ -1525,7 +1525,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
        sta = sta_info_get(sdata, ifmgd->bssid);
        if (sta) {
                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);
 
index f81fd30581d9e69cc91cc8be9a15d25e0094c2ac..e45b83610e850fdf8df47f9f2774686665a13f8d 100644 (file)
@@ -42,7 +42,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
                mutex_lock(&local->sta_mtx);
                list_for_each_entry(sta, &local->sta_list, list) {
                        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);
        }
index 738f9349c0a2bbf333ced18e6318b19e40b51650..9d864ed5f3da15c05c12d5d1a5f0bf14c645e781 100644 (file)
@@ -784,7 +784,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
         * will be sufficient.
         */
        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);
        if (ret)
index 031e4a5bbeca3ec7026854f732d56377e3f06636..af7d78aa55230e49e07252d9e87ef7c2f4fb2b31 100644 (file)
@@ -92,6 +92,13 @@ enum ieee80211_sta_info_flags {
 #define HT_AGG_STATE_WANT_START                4
 #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).
  *
index e27c89c27bf4647d6e24e0bfb5204b7c4b87be99..1b9420730d8cf52628d22ff60b97d599ea87e1f2 100644 (file)
@@ -1639,7 +1639,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                mutex_lock(&local->sta_mtx);
 
                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);
                }