diff options
author | Sara Sharon <sara.sharon@intel.com> | 2016-03-20 14:23:41 (GMT) |
---|---|---|
committer | Luca Coelho <luciano.coelho@intel.com> | 2016-05-10 19:14:40 (GMT) |
commit | 10b2b2019d810f6cc6cc1461615371014d0d11c8 (patch) | |
tree | d9f1ce1e25e50017f05a160e468ef827593905ad /drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | |
parent | d0ff5d2297aa03f346c82d8c90528f00f90ea26d (diff) | |
download | linux-10b2b2019d810f6cc6cc1461615371014d0d11c8.tar.xz |
iwlwifi: mvm: add infrastructure for tracking BA session in driver
According to the spec when a BA session is started there
is a timeout set for the session in the ADDBA request.
If there is not activity on the TA/TID then the session
expires and a DELBA is sent.
In order to check for the timeout, data must be shared
among the rx queues.
Add a timer that runs as long as BA session is active
for the station and stops aggregation session if needed.
This patch also lays the infrastructure for the reordering
buffer which will be enabled in the next patches.
Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 306dd9b..8d5717b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -424,6 +424,36 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, } } +static void iwl_mvm_agg_rx_received(struct iwl_mvm *mvm, u8 baid) +{ + unsigned long now = jiffies; + unsigned long timeout; + struct iwl_mvm_baid_data *data; + + rcu_read_lock(); + + data = rcu_dereference(mvm->baid_map[baid]); + if (WARN_ON(!data)) + goto out; + + if (!data->timeout) + goto out; + + timeout = data->timeout; + /* + * Do not update last rx all the time to avoid cache bouncing + * between the rx queues. + * Update it every timeout. Worst case is the session will + * expire after ~ 2 * timeout, which doesn't matter that much. + */ + if (time_before(data->last_rx + TU_TO_JIFFIES(timeout), now)) + /* Update is atomic */ + data->last_rx = now; + +out: + rcu_read_unlock(); +} + void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, struct iwl_rx_cmd_buffer *rxb, int queue) { @@ -494,6 +524,9 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, if (sta) { struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); + u8 baid = (u8)((le32_to_cpu(desc->reorder_data) & + IWL_RX_MPDU_REORDER_BAID_MASK) >> + IWL_RX_MPDU_REORDER_BAID_SHIFT); /* * We have tx blocked stations (with CS bit). If we heard @@ -546,6 +579,8 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, *qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; } + if (baid != IWL_RX_REORDER_DATA_INVALID_BAID) + iwl_mvm_agg_rx_received(mvm, baid); } /* |