Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 412a6d80 authored by Sara Sharon's avatar Sara Sharon Committed by Johannes Berg
Browse files

mac80211: support hw managing reorder logic



Enable driver to manage the reordering logic itself.
This is needed for example for the iwlwifi driver that
will support hardware assisted reordering.

Signed-off-by: default avatarSara Sharon <sara.sharon@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 50ea05ef
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1929,6 +1929,11 @@ struct ieee80211_txq {
 *	by just its MAC address; this prevents, for example, the same station
 *	from connecting to two virtual AP interfaces at the same time.
 *
 * @IEEE80211_HW_SUPPORTS_REORDERING_BUFFER: Hardware (or driver) manages the
 *	reordering buffer internally, guaranteeing mac80211 receives frames in
 *	order and does not need to manage its own reorder buffer or BA session
 *	timeout.
 *
 * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
 */
enum ieee80211_hw_flags {
@@ -1965,6 +1970,7 @@ enum ieee80211_hw_flags {
	IEEE80211_HW_SUPPORTS_AMSDU_IN_AMPDU,
	IEEE80211_HW_BEACON_TX_STATUS,
	IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR,
	IEEE80211_HW_SUPPORTS_REORDERING_BUFFER,

	/* keep last, obviously */
	NUM_IEEE80211_HW_FLAGS
+22 −2
Original line number Diff line number Diff line
@@ -76,10 +76,11 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
	tid_rx = rcu_dereference_protected(sta->ampdu_mlme.tid_rx[tid],
					lockdep_is_held(&sta->ampdu_mlme.mtx));

	if (!tid_rx)
	if (!test_bit(tid, sta->ampdu_mlme.agg_session_valid))
		return;

	RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], NULL);
	__clear_bit(tid, sta->ampdu_mlme.agg_session_valid);

	ht_dbg(sta->sdata,
	       "Rx BA session stop requested for %pM tid %u %s reason: %d\n",
@@ -97,6 +98,13 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
		ieee80211_send_delba(sta->sdata, sta->sta.addr,
				     tid, WLAN_BACK_RECIPIENT, reason);

	/*
	 * return here in case tid_rx is not assigned - which will happen if
	 * IEEE80211_HW_SUPPORTS_REORDERING_BUFFER is set.
	 */
	if (!tid_rx)
		return;

	del_timer_sync(&tid_rx->session_timer);

	/* make sure ieee80211_sta_reorder_release() doesn't re-arm the timer */
@@ -297,7 +305,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
	/* examine state machine */
	mutex_lock(&sta->ampdu_mlme.mtx);

	if (sta->ampdu_mlme.tid_rx[tid]) {
	if (test_bit(tid, sta->ampdu_mlme.agg_session_valid)) {
		ht_dbg_ratelimited(sta->sdata,
				   "unexpected AddBA Req from %pM on tid %u\n",
				   sta->sta.addr, tid);
@@ -308,6 +316,16 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
						false);
	}

	if (ieee80211_hw_check(&local->hw, SUPPORTS_REORDERING_BUFFER)) {
		ret = drv_ampdu_action(local, sta->sdata, &params);
		ht_dbg(sta->sdata,
		       "Rx A-MPDU request on %pM tid %d result %d\n",
		       sta->sta.addr, tid, ret);
		if (!ret)
			status = WLAN_STATUS_SUCCESS;
		goto end;
	}

	/* prepare A-MPDU MLME for Rx aggregation */
	tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL);
	if (!tid_agg_rx)
@@ -369,6 +387,8 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
	}

end:
	if (status == WLAN_STATUS_SUCCESS)
		__set_bit(tid, sta->ampdu_mlme.agg_session_valid);
	mutex_unlock(&sta->ampdu_mlme.mtx);

end_no_lock:
+1 −0
Original line number Diff line number Diff line
@@ -126,6 +126,7 @@ static const char *hw_flag_names[NUM_IEEE80211_HW_FLAGS + 1] = {
	FLAG(SUPPORTS_AMSDU_IN_AMPDU),
	FLAG(BEACON_TX_STATUS),
	FLAG(NEEDS_UNIQUE_STA_ADDR),
	FLAG(SUPPORTS_REORDERING_BUFFER),

	/* keep last for the build bug below */
	(void *)0x1
+12 −9
Original line number Diff line number Diff line
/*
 * Copyright 2002-2005, Devicescape Software, Inc.
 * Copyright 2013-2014  Intel Mobile Communications GmbH
 * Copyright(c) 2015 Intel Deutschland GmbH
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
@@ -212,20 +213,21 @@ struct tid_ampdu_rx {
/**
 * struct sta_ampdu_mlme - STA aggregation information.
 *
 * @mtx: mutex to protect all TX data (except non-NULL assignments
 *	to tid_tx[idx], which are protected by the sta spinlock)
 *	tid_start_tx is also protected by sta->lock.
 * @tid_rx: aggregation info for Rx per TID -- RCU protected
 * @tid_tx: aggregation info for Tx per TID
 * @tid_start_tx: sessions where start was requested
 * @addba_req_num: number of times addBA request has been sent.
 * @last_addba_req_time: timestamp of the last addBA request.
 * @dialog_token_allocator: dialog token enumerator for each new session;
 * @work: work struct for starting/stopping aggregation
 * @tid_rx_timer_expired: bitmap indicating on which TIDs the
 *	RX timer expired until the work for it runs
 * @tid_rx_stop_requested:  bitmap indicating which BA sessions per TID the
 *	driver requested to close until the work for it runs
 * @mtx: mutex to protect all TX data (except non-NULL assignments
 *	to tid_tx[idx], which are protected by the sta spinlock)
 *	tid_start_tx is also protected by sta->lock.
 * @agg_session_valid: bitmap indicating which TID has a rx BA session open on
 * @work: work struct for starting/stopping aggregation
 * @tid_tx: aggregation info for Tx per TID
 * @tid_start_tx: sessions where start was requested
 * @last_addba_req_time: timestamp of the last addBA request.
 * @addba_req_num: number of times addBA request has been sent.
 * @dialog_token_allocator: dialog token enumerator for each new session;
 */
struct sta_ampdu_mlme {
	struct mutex mtx;
@@ -233,6 +235,7 @@ struct sta_ampdu_mlme {
	struct tid_ampdu_rx __rcu *tid_rx[IEEE80211_NUM_TIDS];
	unsigned long tid_rx_timer_expired[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
	unsigned long tid_rx_stop_requested[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
	unsigned long agg_session_valid[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
	/* tx */
	struct work_struct work;
	struct tid_ampdu_tx __rcu *tid_tx[IEEE80211_NUM_TIDS];