Skip to content

Commit

Permalink
mac80211: support hw managing reorder logic
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sara Sharon authored and Johannes Berg committed Feb 24, 2016
1 parent 50ea05e commit 412a6d8
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 11 deletions.
6 changes: 6 additions & 0 deletions include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
24 changes: 22 additions & 2 deletions net/mac80211/agg-rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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 */
Expand Down Expand Up @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions net/mac80211/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 12 additions & 9 deletions net/mac80211/sta_info.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* 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
Expand Down Expand Up @@ -212,27 +213,29 @@ 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;
/* rx */
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];
Expand Down

0 comments on commit 412a6d8

Please sign in to comment.