aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2015-12-08 12:09:05 -0500
committerJohannes Berg <johannes.berg@intel.com>2016-02-24 03:04:16 -0500
commit412a6d800c7380c1b87c11080c7da905c27cfea8 (patch)
tree6ebbfc270d12f9da48558c0d445fae32495c8c73
parent50ea05efaf3bed7dd34bcc2635a8b3f53bd0ccc1 (diff)
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: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/mac80211.h6
-rw-r--r--net/mac80211/agg-rx.c24
-rw-r--r--net/mac80211/debugfs.c1
-rw-r--r--net/mac80211/sta_info.h21
4 files changed, 41 insertions, 11 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 6c9c559394b0..ee6305a52251 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1929,6 +1929,11 @@ struct ieee80211_txq {
1929 * by just its MAC address; this prevents, for example, the same station 1929 * by just its MAC address; this prevents, for example, the same station
1930 * from connecting to two virtual AP interfaces at the same time. 1930 * from connecting to two virtual AP interfaces at the same time.
1931 * 1931 *
1932 * @IEEE80211_HW_SUPPORTS_REORDERING_BUFFER: Hardware (or driver) manages the
1933 * reordering buffer internally, guaranteeing mac80211 receives frames in
1934 * order and does not need to manage its own reorder buffer or BA session
1935 * timeout.
1936 *
1932 * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays 1937 * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
1933 */ 1938 */
1934enum ieee80211_hw_flags { 1939enum ieee80211_hw_flags {
@@ -1965,6 +1970,7 @@ enum ieee80211_hw_flags {
1965 IEEE80211_HW_SUPPORTS_AMSDU_IN_AMPDU, 1970 IEEE80211_HW_SUPPORTS_AMSDU_IN_AMPDU,
1966 IEEE80211_HW_BEACON_TX_STATUS, 1971 IEEE80211_HW_BEACON_TX_STATUS,
1967 IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR, 1972 IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR,
1973 IEEE80211_HW_SUPPORTS_REORDERING_BUFFER,
1968 1974
1969 /* keep last, obviously */ 1975 /* keep last, obviously */
1970 NUM_IEEE80211_HW_FLAGS 1976 NUM_IEEE80211_HW_FLAGS
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index ec80db7c955c..2ab54791281d 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -76,10 +76,11 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
76 tid_rx = rcu_dereference_protected(sta->ampdu_mlme.tid_rx[tid], 76 tid_rx = rcu_dereference_protected(sta->ampdu_mlme.tid_rx[tid],
77 lockdep_is_held(&sta->ampdu_mlme.mtx)); 77 lockdep_is_held(&sta->ampdu_mlme.mtx));
78 78
79 if (!tid_rx) 79 if (!test_bit(tid, sta->ampdu_mlme.agg_session_valid))
80 return; 80 return;
81 81
82 RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], NULL); 82 RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], NULL);
83 __clear_bit(tid, sta->ampdu_mlme.agg_session_valid);
83 84
84 ht_dbg(sta->sdata, 85 ht_dbg(sta->sdata,
85 "Rx BA session stop requested for %pM tid %u %s reason: %d\n", 86 "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,
97 ieee80211_send_delba(sta->sdata, sta->sta.addr, 98 ieee80211_send_delba(sta->sdata, sta->sta.addr,
98 tid, WLAN_BACK_RECIPIENT, reason); 99 tid, WLAN_BACK_RECIPIENT, reason);
99 100
101 /*
102 * return here in case tid_rx is not assigned - which will happen if
103 * IEEE80211_HW_SUPPORTS_REORDERING_BUFFER is set.
104 */
105 if (!tid_rx)
106 return;
107
100 del_timer_sync(&tid_rx->session_timer); 108 del_timer_sync(&tid_rx->session_timer);
101 109
102 /* make sure ieee80211_sta_reorder_release() doesn't re-arm the timer */ 110 /* 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,
297 /* examine state machine */ 305 /* examine state machine */
298 mutex_lock(&sta->ampdu_mlme.mtx); 306 mutex_lock(&sta->ampdu_mlme.mtx);
299 307
300 if (sta->ampdu_mlme.tid_rx[tid]) { 308 if (test_bit(tid, sta->ampdu_mlme.agg_session_valid)) {
301 ht_dbg_ratelimited(sta->sdata, 309 ht_dbg_ratelimited(sta->sdata,
302 "unexpected AddBA Req from %pM on tid %u\n", 310 "unexpected AddBA Req from %pM on tid %u\n",
303 sta->sta.addr, tid); 311 sta->sta.addr, tid);
@@ -308,6 +316,16 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
308 false); 316 false);
309 } 317 }
310 318
319 if (ieee80211_hw_check(&local->hw, SUPPORTS_REORDERING_BUFFER)) {
320 ret = drv_ampdu_action(local, sta->sdata, &params);
321 ht_dbg(sta->sdata,
322 "Rx A-MPDU request on %pM tid %d result %d\n",
323 sta->sta.addr, tid, ret);
324 if (!ret)
325 status = WLAN_STATUS_SUCCESS;
326 goto end;
327 }
328
311 /* prepare A-MPDU MLME for Rx aggregation */ 329 /* prepare A-MPDU MLME for Rx aggregation */
312 tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL); 330 tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL);
313 if (!tid_agg_rx) 331 if (!tid_agg_rx)
@@ -369,6 +387,8 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
369 } 387 }
370 388
371end: 389end:
390 if (status == WLAN_STATUS_SUCCESS)
391 __set_bit(tid, sta->ampdu_mlme.agg_session_valid);
372 mutex_unlock(&sta->ampdu_mlme.mtx); 392 mutex_unlock(&sta->ampdu_mlme.mtx);
373 393
374end_no_lock: 394end_no_lock:
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index abbdff03ce92..e433d0c97e86 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -126,6 +126,7 @@ static const char *hw_flag_names[NUM_IEEE80211_HW_FLAGS + 1] = {
126 FLAG(SUPPORTS_AMSDU_IN_AMPDU), 126 FLAG(SUPPORTS_AMSDU_IN_AMPDU),
127 FLAG(BEACON_TX_STATUS), 127 FLAG(BEACON_TX_STATUS),
128 FLAG(NEEDS_UNIQUE_STA_ADDR), 128 FLAG(NEEDS_UNIQUE_STA_ADDR),
129 FLAG(SUPPORTS_REORDERING_BUFFER),
129 130
130 /* keep last for the build bug below */ 131 /* keep last for the build bug below */
131 (void *)0x1 132 (void *)0x1
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index d6051629ed15..f4d38994ecee 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright 2002-2005, Devicescape Software, Inc. 2 * Copyright 2002-2005, Devicescape Software, Inc.
3 * Copyright 2013-2014 Intel Mobile Communications GmbH 3 * Copyright 2013-2014 Intel Mobile Communications GmbH
4 * Copyright(c) 2015 Intel Deutschland GmbH
4 * 5 *
5 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
@@ -212,20 +213,21 @@ struct tid_ampdu_rx {
212/** 213/**
213 * struct sta_ampdu_mlme - STA aggregation information. 214 * struct sta_ampdu_mlme - STA aggregation information.
214 * 215 *
216 * @mtx: mutex to protect all TX data (except non-NULL assignments
217 * to tid_tx[idx], which are protected by the sta spinlock)
218 * tid_start_tx is also protected by sta->lock.
215 * @tid_rx: aggregation info for Rx per TID -- RCU protected 219 * @tid_rx: aggregation info for Rx per TID -- RCU protected
216 * @tid_tx: aggregation info for Tx per TID
217 * @tid_start_tx: sessions where start was requested
218 * @addba_req_num: number of times addBA request has been sent.
219 * @last_addba_req_time: timestamp of the last addBA request.
220 * @dialog_token_allocator: dialog token enumerator for each new session;
221 * @work: work struct for starting/stopping aggregation
222 * @tid_rx_timer_expired: bitmap indicating on which TIDs the 220 * @tid_rx_timer_expired: bitmap indicating on which TIDs the
223 * RX timer expired until the work for it runs 221 * RX timer expired until the work for it runs
224 * @tid_rx_stop_requested: bitmap indicating which BA sessions per TID the 222 * @tid_rx_stop_requested: bitmap indicating which BA sessions per TID the
225 * driver requested to close until the work for it runs 223 * driver requested to close until the work for it runs
226 * @mtx: mutex to protect all TX data (except non-NULL assignments 224 * @agg_session_valid: bitmap indicating which TID has a rx BA session open on
227 * to tid_tx[idx], which are protected by the sta spinlock) 225 * @work: work struct for starting/stopping aggregation
228 * tid_start_tx is also protected by sta->lock. 226 * @tid_tx: aggregation info for Tx per TID
227 * @tid_start_tx: sessions where start was requested
228 * @last_addba_req_time: timestamp of the last addBA request.
229 * @addba_req_num: number of times addBA request has been sent.
230 * @dialog_token_allocator: dialog token enumerator for each new session;
229 */ 231 */
230struct sta_ampdu_mlme { 232struct sta_ampdu_mlme {
231 struct mutex mtx; 233 struct mutex mtx;
@@ -233,6 +235,7 @@ struct sta_ampdu_mlme {
233 struct tid_ampdu_rx __rcu *tid_rx[IEEE80211_NUM_TIDS]; 235 struct tid_ampdu_rx __rcu *tid_rx[IEEE80211_NUM_TIDS];
234 unsigned long tid_rx_timer_expired[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; 236 unsigned long tid_rx_timer_expired[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
235 unsigned long tid_rx_stop_requested[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; 237 unsigned long tid_rx_stop_requested[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
238 unsigned long agg_session_valid[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
236 /* tx */ 239 /* tx */
237 struct work_struct work; 240 struct work_struct work;
238 struct tid_ampdu_tx __rcu *tid_tx[IEEE80211_NUM_TIDS]; 241 struct tid_ampdu_tx __rcu *tid_tx[IEEE80211_NUM_TIDS];