summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2017-09-26 12:24:51 +0200
committerLuca Coelho <luciano.coelho@intel.com>2017-10-18 13:00:43 +0300
commitdfdddd92a5781bb4bbd176a5c85b7244580a8efe (patch)
treed4576b5848f724148d75847867cc381e7cca34e5 /drivers/net/wireless/intel/iwlwifi/mvm/sta.c
parent66cc044249603e12e1dbba347f03bdbc9f171fdf (diff)
iwlwifi: mvm: allocate reorder buffer according to need
Now that we may have up to 256 entries per reorder buffer, and possibly up to 16 queues, we can use a LOT of memory for this (64k for each station). Allocate it according to what we need, which is of course much less for HT stations (only 16k at a max of 16 queues). However, this comes at the expense of complicating the code a bit to calculate the right entry structure to use for each frame. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/sta.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 282424f40c43..43e18e75ef42 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -2104,6 +2104,8 @@ static void iwl_mvm_free_reorder(struct iwl_mvm *mvm,
int j;
struct iwl_mvm_reorder_buffer *reorder_buf =
&data->reorder_buf[i];
+ struct iwl_mvm_reorder_buf_entry *entries =
+ &data->entries[i * data->entries_per_queue];
spin_lock_bh(&reorder_buf->lock);
if (likely(!reorder_buf->num_stored)) {
@@ -2119,7 +2121,7 @@ static void iwl_mvm_free_reorder(struct iwl_mvm *mvm,
WARN_ON(1);
for (j = 0; j < reorder_buf->buf_size; j++)
- __skb_queue_purge(&reorder_buf->entries[j]);
+ __skb_queue_purge(&entries[j].e.frames);
/*
* Prevent timer re-arm. This prevents a very far fetched case
* where we timed out on the notification. There may be prior
@@ -2144,6 +2146,8 @@ static void iwl_mvm_init_reorder_buffer(struct iwl_mvm *mvm,
for (i = 0; i < mvm->trans->num_rx_queues; i++) {
struct iwl_mvm_reorder_buffer *reorder_buf =
&data->reorder_buf[i];
+ struct iwl_mvm_reorder_buf_entry *entries =
+ &data->entries[i * data->entries_per_queue];
int j;
reorder_buf->num_stored = 0;
@@ -2161,7 +2165,7 @@ static void iwl_mvm_init_reorder_buffer(struct iwl_mvm *mvm,
reorder_buf->tid = data->tid;
reorder_buf->valid = false;
for (j = 0; j < reorder_buf->buf_size; j++)
- __skb_queue_head_init(&reorder_buf->entries[j]);
+ __skb_queue_head_init(&entries[j].e.frames);
}
}
@@ -2182,16 +2186,44 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
}
if (iwl_mvm_has_new_rx_api(mvm) && start) {
+ u16 reorder_buf_size = buf_size * sizeof(baid_data->entries[0]);
+
+ /* sparse doesn't like the __align() so don't check */
+#ifndef __CHECKER__
+ /*
+ * The division below will be OK if either the cache line size
+ * can be divided by the entry size (ALIGN will round up) or if
+ * if the entry size can be divided by the cache line size, in
+ * which case the ALIGN() will do nothing.
+ */
+ BUILD_BUG_ON(SMP_CACHE_BYTES % sizeof(baid_data->entries[0]) &&
+ sizeof(baid_data->entries[0]) % SMP_CACHE_BYTES);
+#endif
+
+ /*
+ * Upward align the reorder buffer size to fill an entire cache
+ * line for each queue, to avoid sharing cache lines between
+ * different queues.
+ */
+ reorder_buf_size = ALIGN(reorder_buf_size, SMP_CACHE_BYTES);
+
/*
* Allocate here so if allocation fails we can bail out early
* before starting the BA session in the firmware
*/
baid_data = kzalloc(sizeof(*baid_data) +
mvm->trans->num_rx_queues *
- sizeof(baid_data->reorder_buf[0]),
+ reorder_buf_size,
GFP_KERNEL);
if (!baid_data)
return -ENOMEM;
+
+ /*
+ * This division is why we need the above BUILD_BUG_ON(),
+ * if that doesn't hold then this will not be right.
+ */
+ baid_data->entries_per_queue =
+ reorder_buf_size / sizeof(baid_data->entries[0]);
}
cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);