aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c56
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c108
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c1
18 files changed, 154 insertions, 54 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 605aca4c78c8..8f85a0db5c39 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -27,6 +27,7 @@
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/skbuff.h> 29#include <linux/skbuff.h>
30#include <linux/slab.h>
30#include <linux/wireless.h> 31#include <linux/wireless.h>
31#include <net/mac80211.h> 32#include <net/mac80211.h>
32 33
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 3b5889d8d662..7ac6cec006d0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -27,6 +27,7 @@
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/slab.h>
30#include <linux/pci.h> 31#include <linux/pci.h>
31#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
32#include <linux/delay.h> 33#include <linux/delay.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 3297fc7b80bf..89aba76e4a2c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2021,7 +2021,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2021 IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " 2021 IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
2022 "%d index %d\n", scd_ssn , index); 2022 "%d index %d\n", scd_ssn , index);
2023 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 2023 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
2024 iwl_free_tfds_in_queue(priv, sta_id, tid, freed); 2024 if (qc)
2025 iwl_free_tfds_in_queue(priv, sta_id,
2026 tid, freed);
2025 2027
2026 if (priv->mac80211_registered && 2028 if (priv->mac80211_registered &&
2027 (iwl_queue_space(&txq->q) > txq->q.low_mark) && 2029 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
@@ -2047,14 +2049,17 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2047 tx_resp->failure_frame); 2049 tx_resp->failure_frame);
2048 2050
2049 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 2051 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
2050 iwl_free_tfds_in_queue(priv, sta_id, tid, freed); 2052 if (qc && likely(sta_id != IWL_INVALID_STATION))
2053 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
2054 else if (sta_id == IWL_INVALID_STATION)
2055 IWL_DEBUG_TX_REPLY(priv, "Station not known\n");
2051 2056
2052 if (priv->mac80211_registered && 2057 if (priv->mac80211_registered &&
2053 (iwl_queue_space(&txq->q) > txq->q.low_mark)) 2058 (iwl_queue_space(&txq->q) > txq->q.low_mark))
2054 iwl_wake_queue(priv, txq_id); 2059 iwl_wake_queue(priv, txq_id);
2055 } 2060 }
2056 2061 if (qc && likely(sta_id != IWL_INVALID_STATION))
2057 iwl_txq_check_empty(priv, sta_id, tid, txq_id); 2062 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
2058 2063
2059 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) 2064 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
2060 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); 2065 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 5155b1a027eb..0de80914be77 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -26,6 +26,7 @@
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/skbuff.h> 28#include <linux/skbuff.h>
29#include <linux/slab.h>
29#include <linux/wireless.h> 30#include <linux/wireless.h>
30#include <net/mac80211.h> 31#include <net/mac80211.h>
31 32
@@ -345,6 +346,17 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
345 !!(rate_n_flags & RATE_MCS_ANT_C_MSK); 346 !!(rate_n_flags & RATE_MCS_ANT_C_MSK);
346} 347}
347 348
349/*
350 * Static function to get the expected throughput from an iwl_scale_tbl_info
351 * that wraps a NULL pointer check
352 */
353static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
354{
355 if (tbl->expected_tpt)
356 return tbl->expected_tpt[rs_index];
357 return 0;
358}
359
348/** 360/**
349 * rs_collect_tx_data - Update the success/failure sliding window 361 * rs_collect_tx_data - Update the success/failure sliding window
350 * 362 *
@@ -352,19 +364,21 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
352 * at this rate. window->data contains the bitmask of successful 364 * at this rate. window->data contains the bitmask of successful
353 * packets. 365 * packets.
354 */ 366 */
355static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, 367static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
356 int scale_index, s32 tpt, int attempts, 368 int scale_index, int attempts, int successes)
357 int successes)
358{ 369{
359 struct iwl_rate_scale_data *window = NULL; 370 struct iwl_rate_scale_data *window = NULL;
360 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); 371 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
361 s32 fail_count; 372 s32 fail_count, tpt;
362 373
363 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) 374 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
364 return -EINVAL; 375 return -EINVAL;
365 376
366 /* Select window for current tx bit rate */ 377 /* Select window for current tx bit rate */
367 window = &(windows[scale_index]); 378 window = &(tbl->win[scale_index]);
379
380 /* Get expected throughput */
381 tpt = get_expected_tpt(tbl, scale_index);
368 382
369 /* 383 /*
370 * Keep track of only the latest 62 tx frame attempts in this rate's 384 * Keep track of only the latest 62 tx frame attempts in this rate's
@@ -734,16 +748,6 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a,
734 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && 748 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
735 (a->is_SGI == b->is_SGI); 749 (a->is_SGI == b->is_SGI);
736} 750}
737/*
738 * Static function to get the expected throughput from an iwl_scale_tbl_info
739 * that wraps a NULL pointer check
740 */
741static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
742{
743 if (tbl->expected_tpt)
744 return tbl->expected_tpt[rs_index];
745 return 0;
746}
747 751
748/* 752/*
749 * mac80211 sends us Tx status 753 * mac80211 sends us Tx status
@@ -760,12 +764,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
760 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 764 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
761 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 765 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
762 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 766 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
763 struct iwl_rate_scale_data *window = NULL;
764 enum mac80211_rate_control_flags mac_flags; 767 enum mac80211_rate_control_flags mac_flags;
765 u32 tx_rate; 768 u32 tx_rate;
766 struct iwl_scale_tbl_info tbl_type; 769 struct iwl_scale_tbl_info tbl_type;
767 struct iwl_scale_tbl_info *curr_tbl, *other_tbl; 770 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
768 s32 tpt = 0;
769 771
770 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); 772 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
771 773
@@ -853,7 +855,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
853 IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n"); 855 IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
854 return; 856 return;
855 } 857 }
856 window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
857 858
858 /* 859 /*
859 * Updating the frame history depends on whether packets were 860 * Updating the frame history depends on whether packets were
@@ -866,8 +867,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
866 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); 867 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
867 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, 868 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
868 &rs_index); 869 &rs_index);
869 tpt = get_expected_tpt(curr_tbl, rs_index); 870 rs_collect_tx_data(curr_tbl, rs_index,
870 rs_collect_tx_data(window, rs_index, tpt,
871 info->status.ampdu_ack_len, 871 info->status.ampdu_ack_len,
872 info->status.ampdu_ack_map); 872 info->status.ampdu_ack_map);
873 873
@@ -897,19 +897,13 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
897 * table as active/search. 897 * table as active/search.
898 */ 898 */
899 if (table_type_matches(&tbl_type, curr_tbl)) 899 if (table_type_matches(&tbl_type, curr_tbl))
900 tpt = get_expected_tpt(curr_tbl, rs_index); 900 tmp_tbl = curr_tbl;
901 else if (table_type_matches(&tbl_type, other_tbl)) 901 else if (table_type_matches(&tbl_type, other_tbl))
902 tpt = get_expected_tpt(other_tbl, rs_index); 902 tmp_tbl = other_tbl;
903 else 903 else
904 continue; 904 continue;
905 905 rs_collect_tx_data(tmp_tbl, rs_index, 1,
906 /* Constants mean 1 transmission, 0 successes */ 906 i < retries ? 0 : legacy_success);
907 if (i < retries)
908 rs_collect_tx_data(window, rs_index, tpt, 1,
909 0);
910 else
911 rs_collect_tx_data(window, rs_index, tpt, 1,
912 legacy_success);
913 } 907 }
914 908
915 /* Update success/fail counts if not searching for new mode */ 909 /* Update success/fail counts if not searching for new mode */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index f43a45d0f1dd..fe4cec61bdec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -31,6 +31,7 @@
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/slab.h>
34#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
35#include <linux/delay.h> 36#include <linux/delay.h>
36#include <linux/sched.h> 37#include <linux/sched.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 845831ac053e..de3b3f403d1f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -60,6 +60,7 @@
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/ 61 *****************************************************************************/
62 62
63#include <linux/slab.h>
63#include <net/mac80211.h> 64#include <net/mac80211.h>
64 65
65#include "iwl-dev.h" 66#include "iwl-dev.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 5180fb24cd38..0ee8cc296e48 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -30,6 +30,7 @@
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/etherdevice.h> 31#include <linux/etherdevice.h>
32#include <linux/sched.h> 32#include <linux/sched.h>
33#include <linux/slab.h>
33#include <net/mac80211.h> 34#include <net/mac80211.h>
34 35
35#include "iwl-eeprom.h" 36#include "iwl-eeprom.h"
@@ -305,10 +306,13 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
305 306
306 spin_unlock_irqrestore(&priv->lock, flags); 307 spin_unlock_irqrestore(&priv->lock, flags);
307 308
308 /* Allocate and init all Tx and Command queues */ 309 /* Allocate or reset and init all Tx and Command queues */
309 ret = iwl_txq_ctx_reset(priv); 310 if (!priv->txq) {
310 if (ret) 311 ret = iwl_txq_ctx_alloc(priv);
311 return ret; 312 if (ret)
313 return ret;
314 } else
315 iwl_txq_ctx_reset(priv);
312 316
313 set_bit(STATUS_INIT, &priv->status); 317 set_bit(STATUS_INIT, &priv->status);
314 318
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index b3e698b576e1..f3b6c72d82cd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -455,7 +455,8 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
455/***************************************************** 455/*****************************************************
456* TX 456* TX
457******************************************************/ 457******************************************************/
458int iwl_txq_ctx_reset(struct iwl_priv *priv); 458int iwl_txq_ctx_alloc(struct iwl_priv *priv);
459void iwl_txq_ctx_reset(struct iwl_priv *priv);
459void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); 460void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
460int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, 461int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
461 struct iwl_tx_queue *txq, 462 struct iwl_tx_queue *txq,
@@ -469,6 +470,8 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
469void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); 470void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
470int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, 471int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
471 int slots_num, u32 txq_id); 472 int slots_num, u32 txq_id);
473void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
474 int slots_num, u32 txq_id);
472void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); 475void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
473int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); 476int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
474int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid); 477int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 5f5820249a29..607a91f3eb6b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -26,6 +26,7 @@
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *****************************************************************************/ 27 *****************************************************************************/
28 28
29#include <linux/slab.h>
29#include <linux/kernel.h> 30#include <linux/kernel.h>
30#include <linux/module.h> 31#include <linux/module.h>
31#include <linux/debugfs.h> 32#include <linux/debugfs.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index 36580d8d8b8d..2ffc2edbf4f0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -28,6 +28,8 @@
28 28
29/* sparse doesn't like tracepoint macros */ 29/* sparse doesn't like tracepoint macros */
30#ifndef __CHECKER__ 30#ifndef __CHECKER__
31#include "iwl-dev.h"
32
31#define CREATE_TRACE_POINTS 33#define CREATE_TRACE_POINTS
32#include "iwl-devtrace.h" 34#include "iwl-devtrace.h"
33 35
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index ff4d012ce260..ae7319bb3a99 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -28,7 +28,6 @@
28#define __IWLWIFI_DEVICE_TRACE 28#define __IWLWIFI_DEVICE_TRACE
29 29
30#include <linux/tracepoint.h> 30#include <linux/tracepoint.h>
31#include "iwl-dev.h"
32 31
33#if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) 32#if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__)
34#undef TRACE_EVENT 33#undef TRACE_EVENT
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index fd37152abae3..fb5bb487f3bc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -63,6 +63,7 @@
63 63
64#include <linux/kernel.h> 64#include <linux/kernel.h>
65#include <linux/module.h> 65#include <linux/module.h>
66#include <linux/slab.h>
66#include <linux/init.h> 67#include <linux/init.h>
67 68
68#include <net/mac80211.h> 69#include <net/mac80211.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index c719baf2585a..16eb3ced9b30 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -31,6 +31,7 @@
31 31
32#include <linux/io.h> 32#include <linux/io.h>
33 33
34#include "iwl-dev.h"
34#include "iwl-debug.h" 35#include "iwl-debug.h"
35#include "iwl-devtrace.h" 36#include "iwl-devtrace.h"
36 37
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 1a1a9f081cc7..548dac2f6a96 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -29,6 +29,7 @@
29 29
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/slab.h>
32#include <linux/init.h> 33#include <linux/init.h>
33 34
34#include <net/mac80211.h> 35#include <net/mac80211.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 2fa30dfb7c59..d3b2fb389e58 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -28,6 +28,7 @@
28 *****************************************************************************/ 28 *****************************************************************************/
29 29
30#include <linux/etherdevice.h> 30#include <linux/etherdevice.h>
31#include <linux/slab.h>
31#include <net/mac80211.h> 32#include <net/mac80211.h>
32#include <asm/unaligned.h> 33#include <asm/unaligned.h>
33#include "iwl-eeprom.h" 34#include "iwl-eeprom.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 84b19b12ff03..e8e4b5493e89 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -25,6 +25,7 @@
25 * Intel Linux Wireless <ilw@linux.intel.com> 25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *****************************************************************************/ 27 *****************************************************************************/
28#include <linux/slab.h>
28#include <linux/types.h> 29#include <linux/types.h>
29#include <linux/etherdevice.h> 30#include <linux/etherdevice.h>
30#include <net/mac80211.h> 31#include <net/mac80211.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 1e481f3fcabf..b798fbabc3b6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -29,6 +29,7 @@
29 29
30#include <linux/etherdevice.h> 30#include <linux/etherdevice.h>
31#include <linux/sched.h> 31#include <linux/sched.h>
32#include <linux/slab.h>
32#include <net/mac80211.h> 33#include <net/mac80211.h>
33#include "iwl-eeprom.h" 34#include "iwl-eeprom.h"
34#include "iwl-dev.h" 35#include "iwl-dev.h"
@@ -230,10 +231,34 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
230 struct iwl_queue *q = &txq->q; 231 struct iwl_queue *q = &txq->q;
231 struct device *dev = &priv->pci_dev->dev; 232 struct device *dev = &priv->pci_dev->dev;
232 int i; 233 int i;
234 bool huge = false;
233 235
234 if (q->n_bd == 0) 236 if (q->n_bd == 0)
235 return; 237 return;
236 238
239 for (; q->read_ptr != q->write_ptr;
240 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
241 /* we have no way to tell if it is a huge cmd ATM */
242 i = get_cmd_index(q, q->read_ptr, 0);
243
244 if (txq->meta[i].flags & CMD_SIZE_HUGE) {
245 huge = true;
246 continue;
247 }
248
249 pci_unmap_single(priv->pci_dev,
250 pci_unmap_addr(&txq->meta[i], mapping),
251 pci_unmap_len(&txq->meta[i], len),
252 PCI_DMA_BIDIRECTIONAL);
253 }
254 if (huge) {
255 i = q->n_window;
256 pci_unmap_single(priv->pci_dev,
257 pci_unmap_addr(&txq->meta[i], mapping),
258 pci_unmap_len(&txq->meta[i], len),
259 PCI_DMA_BIDIRECTIONAL);
260 }
261
237 /* De-alloc array of command/tx buffers */ 262 /* De-alloc array of command/tx buffers */
238 for (i = 0; i <= TFD_CMD_SLOTS; i++) 263 for (i = 0; i <= TFD_CMD_SLOTS; i++)
239 kfree(txq->cmd[i]); 264 kfree(txq->cmd[i]);
@@ -448,6 +473,26 @@ out_free_arrays:
448} 473}
449EXPORT_SYMBOL(iwl_tx_queue_init); 474EXPORT_SYMBOL(iwl_tx_queue_init);
450 475
476void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
477 int slots_num, u32 txq_id)
478{
479 int actual_slots = slots_num;
480
481 if (txq_id == IWL_CMD_QUEUE_NUM)
482 actual_slots++;
483
484 memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
485
486 txq->need_update = 0;
487
488 /* Initialize queue's high/low-water marks, and head/tail indexes */
489 iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
490
491 /* Tell device where to find queue */
492 priv->cfg->ops->lib->txq_init(priv, txq);
493}
494EXPORT_SYMBOL(iwl_tx_queue_reset);
495
451/** 496/**
452 * iwl_hw_txq_ctx_free - Free TXQ Context 497 * iwl_hw_txq_ctx_free - Free TXQ Context
453 * 498 *
@@ -459,8 +504,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
459 504
460 /* Tx queues */ 505 /* Tx queues */
461 if (priv->txq) { 506 if (priv->txq) {
462 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; 507 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
463 txq_id++)
464 if (txq_id == IWL_CMD_QUEUE_NUM) 508 if (txq_id == IWL_CMD_QUEUE_NUM)
465 iwl_cmd_queue_free(priv); 509 iwl_cmd_queue_free(priv);
466 else 510 else
@@ -476,15 +520,15 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
476EXPORT_SYMBOL(iwl_hw_txq_ctx_free); 520EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
477 521
478/** 522/**
479 * iwl_txq_ctx_reset - Reset TX queue context 523 * iwl_txq_ctx_alloc - allocate TX queue context
480 * Destroys all DMA structures and initialize them again 524 * Allocate all Tx DMA structures and initialize them
481 * 525 *
482 * @param priv 526 * @param priv
483 * @return error code 527 * @return error code
484 */ 528 */
485int iwl_txq_ctx_reset(struct iwl_priv *priv) 529int iwl_txq_ctx_alloc(struct iwl_priv *priv)
486{ 530{
487 int ret = 0; 531 int ret;
488 int txq_id, slots_num; 532 int txq_id, slots_num;
489 unsigned long flags; 533 unsigned long flags;
490 534
@@ -542,8 +586,31 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
542 return ret; 586 return ret;
543} 587}
544 588
589void iwl_txq_ctx_reset(struct iwl_priv *priv)
590{
591 int txq_id, slots_num;
592 unsigned long flags;
593
594 spin_lock_irqsave(&priv->lock, flags);
595
596 /* Turn off all Tx DMA fifos */
597 priv->cfg->ops->lib->txq_set_sched(priv, 0);
598
599 /* Tell NIC where to find the "keep warm" buffer */
600 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
601
602 spin_unlock_irqrestore(&priv->lock, flags);
603
604 /* Alloc and init all Tx queues, including the command queue (#4) */
605 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
606 slots_num = txq_id == IWL_CMD_QUEUE_NUM ?
607 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
608 iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
609 }
610}
611
545/** 612/**
546 * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory 613 * iwl_txq_ctx_stop - Stop all Tx DMA channels
547 */ 614 */
548void iwl_txq_ctx_stop(struct iwl_priv *priv) 615void iwl_txq_ctx_stop(struct iwl_priv *priv)
549{ 616{
@@ -563,9 +630,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv)
563 1000); 630 1000);
564 } 631 }
565 spin_unlock_irqrestore(&priv->lock, flags); 632 spin_unlock_irqrestore(&priv->lock, flags);
566
567 /* Deallocate memory for all Tx queues */
568 iwl_hw_txq_ctx_free(priv);
569} 633}
570EXPORT_SYMBOL(iwl_txq_ctx_stop); 634EXPORT_SYMBOL(iwl_txq_ctx_stop);
571 635
@@ -1075,6 +1139,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1075 1139
1076 spin_lock_irqsave(&priv->hcmd_lock, flags); 1140 spin_lock_irqsave(&priv->hcmd_lock, flags);
1077 1141
1142 /* If this is a huge cmd, mark the huge flag also on the meta.flags
1143 * of the _original_ cmd. This is used for DMA mapping clean up.
1144 */
1145 if (cmd->flags & CMD_SIZE_HUGE) {
1146 idx = get_cmd_index(q, q->write_ptr, 0);
1147 txq->meta[idx].flags = CMD_SIZE_HUGE;
1148 }
1149
1078 idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); 1150 idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
1079 out_cmd = txq->cmd[idx]; 1151 out_cmd = txq->cmd[idx];
1080 out_meta = &txq->meta[idx]; 1152 out_meta = &txq->meta[idx];
@@ -1252,6 +1324,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1252 bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); 1324 bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
1253 struct iwl_device_cmd *cmd; 1325 struct iwl_device_cmd *cmd;
1254 struct iwl_cmd_meta *meta; 1326 struct iwl_cmd_meta *meta;
1327 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
1255 1328
1256 /* If a Tx command is being handled and it isn't in the actual 1329 /* If a Tx command is being handled and it isn't in the actual
1257 * command queue then there a command routing bug has been introduced 1330 * command queue then there a command routing bug has been introduced
@@ -1265,9 +1338,17 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1265 return; 1338 return;
1266 } 1339 }
1267 1340
1268 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); 1341 /* If this is a huge cmd, clear the huge flag on the meta.flags
1269 cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; 1342 * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap
1270 meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index]; 1343 * the DMA buffer for the scan (huge) command.
1344 */
1345 if (huge) {
1346 cmd_index = get_cmd_index(&txq->q, index, 0);
1347 txq->meta[cmd_index].flags = 0;
1348 }
1349 cmd_index = get_cmd_index(&txq->q, index, huge);
1350 cmd = txq->cmd[cmd_index];
1351 meta = &txq->meta[cmd_index];
1271 1352
1272 pci_unmap_single(priv->pci_dev, 1353 pci_unmap_single(priv->pci_dev,
1273 pci_unmap_addr(meta, mapping), 1354 pci_unmap_addr(meta, mapping),
@@ -1289,6 +1370,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1289 get_cmd_string(cmd->hdr.cmd)); 1370 get_cmd_string(cmd->hdr.cmd));
1290 wake_up_interruptible(&priv->wait_command_queue); 1371 wake_up_interruptible(&priv->wait_command_queue);
1291 } 1372 }
1373 meta->flags = 0;
1292} 1374}
1293EXPORT_SYMBOL(iwl_tx_cmd_complete); 1375EXPORT_SYMBOL(iwl_tx_cmd_complete);
1294 1376
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 64f150b19771..e0c05feb296c 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -31,6 +31,7 @@
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/slab.h>
34#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
35#include <linux/delay.h> 36#include <linux/delay.h>
36#include <linux/sched.h> 37#include <linux/sched.h>