Commit c82c4a80 authored by Johannes Berg's avatar Johannes Berg
Browse files

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
Loading
Loading
Loading
Loading
+8 −9
Original line number Original line Diff line number Diff line
@@ -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,
	 */
	 */
	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,
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,
		}
		}


	} 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:
+8 −7
Original line number Original line Diff line number Diff line
@@ -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)
		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,
		__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,
+4 −5
Original line number Original line Diff line number Diff line
@@ -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,
				     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);
+1 −1
Original line number Original line Diff line number Diff line
@@ -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);


+2 −1
Original line number Original line Diff line number Diff line
@@ -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);
	}
	}
Loading