aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-04-26 03:08:27 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-04-26 03:08:27 -0400
commite19553427c2e8fdb04fdd98e407164bb59a840ba (patch)
tree5332234b2dad07c03c27e4608afb16f297f41e61 /drivers/net/wireless/iwlwifi
parent35f6cd4a06432034665a1499ca4b022437423aac (diff)
parent83515bc7df812555e20cda48614674e2f346f9f5 (diff)
Merge branch 'sh/stable-updates'
Conflicts: arch/sh/kernel/dwarf.c drivers/dma/shdma.c Signed-off-by: Paul Mundt <lethal@linux-sh.org>
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.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c56
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h1
-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-eeprom.h4
-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.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c108
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c5
21 files changed, 204 insertions, 72 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 47909f94271e..902c4d4293e9 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 e0678d921055..0728054a22d4 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 1bd2cd836026..8972166386cb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2015,7 +2015,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2015 IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " 2015 IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
2016 "%d index %d\n", scd_ssn , index); 2016 "%d index %d\n", scd_ssn , index);
2017 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 2017 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
2018 iwl_free_tfds_in_queue(priv, sta_id, tid, freed); 2018 if (qc)
2019 iwl_free_tfds_in_queue(priv, sta_id,
2020 tid, freed);
2019 2021
2020 if (priv->mac80211_registered && 2022 if (priv->mac80211_registered &&
2021 (iwl_queue_space(&txq->q) > txq->q.low_mark) && 2023 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
@@ -2042,13 +2044,14 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2042 2044
2043 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 2045 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
2044 if (qc && likely(sta_id != IWL_INVALID_STATION)) 2046 if (qc && likely(sta_id != IWL_INVALID_STATION))
2045 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 2047 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
2048 else if (sta_id == IWL_INVALID_STATION)
2049 IWL_DEBUG_TX_REPLY(priv, "Station not known\n");
2046 2050
2047 if (priv->mac80211_registered && 2051 if (priv->mac80211_registered &&
2048 (iwl_queue_space(&txq->q) > txq->q.low_mark)) 2052 (iwl_queue_space(&txq->q) > txq->q.low_mark))
2049 iwl_wake_queue(priv, txq_id); 2053 iwl_wake_queue(priv, txq_id);
2050 } 2054 }
2051
2052 if (qc && likely(sta_id != IWL_INVALID_STATION)) 2055 if (qc && likely(sta_id != IWL_INVALID_STATION))
2053 iwl_txq_check_empty(priv, sta_id, tid, txq_id); 2056 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
2054 2057
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index c4844adff92a..92b3e64fc14d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -259,7 +259,7 @@ static struct iwl_lib_ops iwl6000_lib = {
259 EEPROM_5000_REG_BAND_3_CHANNELS, 259 EEPROM_5000_REG_BAND_3_CHANNELS,
260 EEPROM_5000_REG_BAND_4_CHANNELS, 260 EEPROM_5000_REG_BAND_4_CHANNELS,
261 EEPROM_5000_REG_BAND_5_CHANNELS, 261 EEPROM_5000_REG_BAND_5_CHANNELS,
262 EEPROM_5000_REG_BAND_24_HT40_CHANNELS, 262 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
263 EEPROM_5000_REG_BAND_52_HT40_CHANNELS 263 EEPROM_5000_REG_BAND_52_HT40_CHANNELS
264 }, 264 },
265 .verify_signature = iwlcore_eeprom_verify_signature, 265 .verify_signature = iwlcore_eeprom_verify_signature,
@@ -323,7 +323,7 @@ static struct iwl_lib_ops iwl6050_lib = {
323 EEPROM_5000_REG_BAND_3_CHANNELS, 323 EEPROM_5000_REG_BAND_3_CHANNELS,
324 EEPROM_5000_REG_BAND_4_CHANNELS, 324 EEPROM_5000_REG_BAND_4_CHANNELS,
325 EEPROM_5000_REG_BAND_5_CHANNELS, 325 EEPROM_5000_REG_BAND_5_CHANNELS,
326 EEPROM_5000_REG_BAND_24_HT40_CHANNELS, 326 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
327 EEPROM_5000_REG_BAND_52_HT40_CHANNELS 327 EEPROM_5000_REG_BAND_52_HT40_CHANNELS
328 }, 328 },
329 .verify_signature = iwlcore_eeprom_verify_signature, 329 .verify_signature = iwlcore_eeprom_verify_signature,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 8bf7c20b9d39..1460116d329f 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
@@ -738,16 +752,6 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a,
738 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && 752 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
739 (a->is_SGI == b->is_SGI); 753 (a->is_SGI == b->is_SGI);
740} 754}
741/*
742 * Static function to get the expected throughput from an iwl_scale_tbl_info
743 * that wraps a NULL pointer check
744 */
745static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
746{
747 if (tbl->expected_tpt)
748 return tbl->expected_tpt[rs_index];
749 return 0;
750}
751 755
752/* 756/*
753 * mac80211 sends us Tx status 757 * mac80211 sends us Tx status
@@ -764,12 +768,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
764 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 768 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
765 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 769 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
766 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 770 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
767 struct iwl_rate_scale_data *window = NULL;
768 enum mac80211_rate_control_flags mac_flags; 771 enum mac80211_rate_control_flags mac_flags;
769 u32 tx_rate; 772 u32 tx_rate;
770 struct iwl_scale_tbl_info tbl_type; 773 struct iwl_scale_tbl_info tbl_type;
771 struct iwl_scale_tbl_info *curr_tbl, *other_tbl; 774 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
772 s32 tpt = 0;
773 775
774 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); 776 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
775 777
@@ -852,7 +854,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
852 IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n"); 854 IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
853 return; 855 return;
854 } 856 }
855 window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
856 857
857 /* 858 /*
858 * Updating the frame history depends on whether packets were 859 * Updating the frame history depends on whether packets were
@@ -865,8 +866,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
865 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); 866 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
866 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, 867 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
867 &rs_index); 868 &rs_index);
868 tpt = get_expected_tpt(curr_tbl, rs_index); 869 rs_collect_tx_data(curr_tbl, rs_index,
869 rs_collect_tx_data(window, rs_index, tpt,
870 info->status.ampdu_ack_len, 870 info->status.ampdu_ack_len,
871 info->status.ampdu_ack_map); 871 info->status.ampdu_ack_map);
872 872
@@ -896,19 +896,13 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
896 * table as active/search. 896 * table as active/search.
897 */ 897 */
898 if (table_type_matches(&tbl_type, curr_tbl)) 898 if (table_type_matches(&tbl_type, curr_tbl))
899 tpt = get_expected_tpt(curr_tbl, rs_index); 899 tmp_tbl = curr_tbl;
900 else if (table_type_matches(&tbl_type, other_tbl)) 900 else if (table_type_matches(&tbl_type, other_tbl))
901 tpt = get_expected_tpt(other_tbl, rs_index); 901 tmp_tbl = other_tbl;
902 else 902 else
903 continue; 903 continue;
904 904 rs_collect_tx_data(tmp_tbl, rs_index, 1,
905 /* Constants mean 1 transmission, 0 successes */ 905 i < retries ? 0 : legacy_success);
906 if (i < retries)
907 rs_collect_tx_data(window, rs_index, tpt, 1,
908 0);
909 else
910 rs_collect_tx_data(window, rs_index, tpt, 1,
911 legacy_success);
912 } 906 }
913 907
914 /* Update success/fail counts if not searching for new mode */ 908 /* 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 818367b57bab..bdff56583e11 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>
@@ -1258,7 +1259,15 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1258 /* Ack/clear/reset pending uCode interrupts. 1259 /* Ack/clear/reset pending uCode interrupts.
1259 * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, 1260 * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
1260 */ 1261 */
1261 iwl_write32(priv, CSR_INT, priv->inta); 1262 /* There is a hardware bug in the interrupt mask function that some
1263 * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if
1264 * they are disabled in the CSR_INT_MASK register. Furthermore the
1265 * ICT interrupt handling mechanism has another bug that might cause
1266 * these unmasked interrupts fail to be detected. We workaround the
1267 * hardware bugs here by ACKing all the possible interrupts so that
1268 * interrupt coalescing can still be achieved.
1269 */
1270 iwl_write32(priv, CSR_INT, priv->inta | ~priv->inta_mask);
1262 1271
1263 inta = priv->inta; 1272 inta = priv->inta;
1264 1273
@@ -2644,7 +2653,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
2644 BIT(NL80211_IFTYPE_STATION) | 2653 BIT(NL80211_IFTYPE_STATION) |
2645 BIT(NL80211_IFTYPE_ADHOC); 2654 BIT(NL80211_IFTYPE_ADHOC);
2646 2655
2647 hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY | 2656 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
2648 WIPHY_FLAG_DISABLE_BEACON_HINTS; 2657 WIPHY_FLAG_DISABLE_BEACON_HINTS;
2649 2658
2650 /* 2659 /*
@@ -3322,6 +3331,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
3322 3331
3323 cancel_delayed_work_sync(&priv->init_alive_start); 3332 cancel_delayed_work_sync(&priv->init_alive_start);
3324 cancel_delayed_work(&priv->scan_check); 3333 cancel_delayed_work(&priv->scan_check);
3334 cancel_work_sync(&priv->start_internal_scan);
3325 cancel_delayed_work(&priv->alive_start); 3335 cancel_delayed_work(&priv->alive_start);
3326 cancel_work_sync(&priv->beacon_update); 3336 cancel_work_sync(&priv->beacon_update);
3327 del_timer_sync(&priv->statistics_periodic); 3337 del_timer_sync(&priv->statistics_periodic);
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 845831ac053e..8b516c5ff0bb 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"
@@ -807,6 +808,18 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
807 } 808 }
808 } 809 }
809 810
811 /*
812 * The above algorithm sometimes fails when the ucode
813 * reports 0 for all chains. It's not clear why that
814 * happens to start with, but it is then causing trouble
815 * because this can make us enable more chains than the
816 * hardware really has.
817 *
818 * To be safe, simply mask out any chains that we know
819 * are not on the device.
820 */
821 active_chains &= priv->hw_params.valid_rx_ant;
822
810 num_tx_chains = 0; 823 num_tx_chains = 0;
811 for (i = 0; i < NUM_RX_CHAINS; i++) { 824 for (i = 0; i < NUM_RX_CHAINS; i++) {
812 /* loops on all the bits of 825 /* loops on all the bits of
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 112149e9b31e..049b652bcb5e 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"
@@ -307,10 +308,13 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
307 308
308 spin_unlock_irqrestore(&priv->lock, flags); 309 spin_unlock_irqrestore(&priv->lock, flags);
309 310
310 /* Allocate and init all Tx and Command queues */ 311 /* Allocate or reset and init all Tx and Command queues */
311 ret = iwl_txq_ctx_reset(priv); 312 if (!priv->txq) {
312 if (ret) 313 ret = iwl_txq_ctx_alloc(priv);
313 return ret; 314 if (ret)
315 return ret;
316 } else
317 iwl_txq_ctx_reset(priv);
314 318
315 set_bit(STATUS_INIT, &priv->status); 319 set_bit(STATUS_INIT, &priv->status);
316 320
@@ -3354,7 +3358,6 @@ static void iwl_force_rf_reset(struct iwl_priv *priv)
3354 */ 3358 */
3355 IWL_DEBUG_INFO(priv, "perform radio reset.\n"); 3359 IWL_DEBUG_INFO(priv, "perform radio reset.\n");
3356 iwl_internal_short_hw_scan(priv); 3360 iwl_internal_short_hw_scan(priv);
3357 return;
3358} 3361}
3359 3362
3360 3363
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 4ef7739f9e8e..36940a9ec6b9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -442,7 +442,8 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
442/***************************************************** 442/*****************************************************
443* TX 443* TX
444******************************************************/ 444******************************************************/
445int iwl_txq_ctx_reset(struct iwl_priv *priv); 445int iwl_txq_ctx_alloc(struct iwl_priv *priv);
446void iwl_txq_ctx_reset(struct iwl_priv *priv);
446void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); 447void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
447int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, 448int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
448 struct iwl_tx_queue *txq, 449 struct iwl_tx_queue *txq,
@@ -456,6 +457,8 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
456void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); 457void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
457int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, 458int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
458 int slots_num, u32 txq_id); 459 int slots_num, u32 txq_id);
460void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
461 int slots_num, u32 txq_id);
459void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); 462void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
460int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); 463int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
461int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid); 464int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
@@ -503,7 +506,7 @@ void iwl_init_scan_params(struct iwl_priv *priv);
503int iwl_scan_cancel(struct iwl_priv *priv); 506int iwl_scan_cancel(struct iwl_priv *priv);
504int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); 507int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
505int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); 508int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
506int iwl_internal_short_hw_scan(struct iwl_priv *priv); 509void iwl_internal_short_hw_scan(struct iwl_priv *priv);
507int iwl_force_reset(struct iwl_priv *priv, int mode); 510int iwl_force_reset(struct iwl_priv *priv, int mode);
508u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, 511u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
509 const u8 *ie, int ie_len, int left); 512 const u8 *ie, int ie_len, int left);
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 7bf44f146799..b6e1b0ebe230 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-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 6054c5fba0c1..ef1720a852e9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1296,6 +1296,7 @@ struct iwl_priv {
1296 struct work_struct tt_work; 1296 struct work_struct tt_work;
1297 struct work_struct ct_enter; 1297 struct work_struct ct_enter;
1298 struct work_struct ct_exit; 1298 struct work_struct ct_exit;
1299 struct work_struct start_internal_scan;
1299 1300
1300 struct tasklet_struct irq_tasklet; 1301 struct tasklet_struct irq_tasklet;
1301 1302
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-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 4e1ba824dc50..8171c701e4e1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -203,6 +203,10 @@ struct iwl_eeprom_enhanced_txpwr {
203#define EEPROM_5000_REG_BAND_52_HT40_CHANNELS ((0x92)\ 203#define EEPROM_5000_REG_BAND_52_HT40_CHANNELS ((0x92)\
204 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */ 204 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */
205 205
206/* 6000 regulatory - indirect access */
207#define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\
208 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */
209
206/* 6000 and up regulatory tx power - indirect access */ 210/* 6000 and up regulatory tx power - indirect access */
207/* max. elements per section */ 211/* max. elements per section */
208#define EEPROM_MAX_TXPOWER_SECTION_ELEMENTS (8) 212#define EEPROM_MAX_TXPOWER_SECTION_ELEMENTS (8)
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 df257bc15f49..e5eb339107dd 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 bd2f7c420563..12e455a4b90e 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>
@@ -469,6 +470,8 @@ EXPORT_SYMBOL(iwl_init_scan_params);
469 470
470static int iwl_scan_initiate(struct iwl_priv *priv) 471static int iwl_scan_initiate(struct iwl_priv *priv)
471{ 472{
473 WARN_ON(!mutex_is_locked(&priv->mutex));
474
472 IWL_DEBUG_INFO(priv, "Starting scan...\n"); 475 IWL_DEBUG_INFO(priv, "Starting scan...\n");
473 set_bit(STATUS_SCANNING, &priv->status); 476 set_bit(STATUS_SCANNING, &priv->status);
474 priv->is_internal_short_scan = false; 477 priv->is_internal_short_scan = false;
@@ -546,24 +549,31 @@ EXPORT_SYMBOL(iwl_mac_hw_scan);
546 * internal short scan, this function should only been called while associated. 549 * internal short scan, this function should only been called while associated.
547 * It will reset and tune the radio to prevent possible RF related problem 550 * It will reset and tune the radio to prevent possible RF related problem
548 */ 551 */
549int iwl_internal_short_hw_scan(struct iwl_priv *priv) 552void iwl_internal_short_hw_scan(struct iwl_priv *priv)
550{ 553{
551 int ret = 0; 554 queue_work(priv->workqueue, &priv->start_internal_scan);
555}
556
557static void iwl_bg_start_internal_scan(struct work_struct *work)
558{
559 struct iwl_priv *priv =
560 container_of(work, struct iwl_priv, start_internal_scan);
561
562 mutex_lock(&priv->mutex);
552 563
553 if (!iwl_is_ready_rf(priv)) { 564 if (!iwl_is_ready_rf(priv)) {
554 ret = -EIO;
555 IWL_DEBUG_SCAN(priv, "not ready or exit pending\n"); 565 IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
556 goto out; 566 goto unlock;
557 } 567 }
568
558 if (test_bit(STATUS_SCANNING, &priv->status)) { 569 if (test_bit(STATUS_SCANNING, &priv->status)) {
559 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); 570 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
560 ret = -EAGAIN; 571 goto unlock;
561 goto out;
562 } 572 }
573
563 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { 574 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
564 IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n"); 575 IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
565 ret = -EAGAIN; 576 goto unlock;
566 goto out;
567 } 577 }
568 578
569 priv->scan_bands = 0; 579 priv->scan_bands = 0;
@@ -576,9 +586,8 @@ int iwl_internal_short_hw_scan(struct iwl_priv *priv)
576 set_bit(STATUS_SCANNING, &priv->status); 586 set_bit(STATUS_SCANNING, &priv->status);
577 priv->is_internal_short_scan = true; 587 priv->is_internal_short_scan = true;
578 queue_work(priv->workqueue, &priv->request_scan); 588 queue_work(priv->workqueue, &priv->request_scan);
579 589 unlock:
580out: 590 mutex_unlock(&priv->mutex);
581 return ret;
582} 591}
583EXPORT_SYMBOL(iwl_internal_short_hw_scan); 592EXPORT_SYMBOL(iwl_internal_short_hw_scan);
584 593
@@ -964,6 +973,7 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
964 INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); 973 INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
965 INIT_WORK(&priv->request_scan, iwl_bg_request_scan); 974 INIT_WORK(&priv->request_scan, iwl_bg_request_scan);
966 INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); 975 INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
976 INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan);
967 INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); 977 INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
968} 978}
969EXPORT_SYMBOL(iwl_setup_scan_deferred_work); 979EXPORT_SYMBOL(iwl_setup_scan_deferred_work);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 8c12311dbb0a..8dd0c036d547 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"
@@ -193,10 +194,34 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
193 struct iwl_queue *q = &txq->q; 194 struct iwl_queue *q = &txq->q;
194 struct device *dev = &priv->pci_dev->dev; 195 struct device *dev = &priv->pci_dev->dev;
195 int i; 196 int i;
197 bool huge = false;
196 198
197 if (q->n_bd == 0) 199 if (q->n_bd == 0)
198 return; 200 return;
199 201
202 for (; q->read_ptr != q->write_ptr;
203 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
204 /* we have no way to tell if it is a huge cmd ATM */
205 i = get_cmd_index(q, q->read_ptr, 0);
206
207 if (txq->meta[i].flags & CMD_SIZE_HUGE) {
208 huge = true;
209 continue;
210 }
211
212 pci_unmap_single(priv->pci_dev,
213 pci_unmap_addr(&txq->meta[i], mapping),
214 pci_unmap_len(&txq->meta[i], len),
215 PCI_DMA_BIDIRECTIONAL);
216 }
217 if (huge) {
218 i = q->n_window;
219 pci_unmap_single(priv->pci_dev,
220 pci_unmap_addr(&txq->meta[i], mapping),
221 pci_unmap_len(&txq->meta[i], len),
222 PCI_DMA_BIDIRECTIONAL);
223 }
224
200 /* De-alloc array of command/tx buffers */ 225 /* De-alloc array of command/tx buffers */
201 for (i = 0; i <= TFD_CMD_SLOTS; i++) 226 for (i = 0; i <= TFD_CMD_SLOTS; i++)
202 kfree(txq->cmd[i]); 227 kfree(txq->cmd[i]);
@@ -409,6 +434,26 @@ out_free_arrays:
409} 434}
410EXPORT_SYMBOL(iwl_tx_queue_init); 435EXPORT_SYMBOL(iwl_tx_queue_init);
411 436
437void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
438 int slots_num, u32 txq_id)
439{
440 int actual_slots = slots_num;
441
442 if (txq_id == IWL_CMD_QUEUE_NUM)
443 actual_slots++;
444
445 memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
446
447 txq->need_update = 0;
448
449 /* Initialize queue's high/low-water marks, and head/tail indexes */
450 iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
451
452 /* Tell device where to find queue */
453 priv->cfg->ops->lib->txq_init(priv, txq);
454}
455EXPORT_SYMBOL(iwl_tx_queue_reset);
456
412/** 457/**
413 * iwl_hw_txq_ctx_free - Free TXQ Context 458 * iwl_hw_txq_ctx_free - Free TXQ Context
414 * 459 *
@@ -420,8 +465,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
420 465
421 /* Tx queues */ 466 /* Tx queues */
422 if (priv->txq) { 467 if (priv->txq) {
423 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; 468 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
424 txq_id++)
425 if (txq_id == IWL_CMD_QUEUE_NUM) 469 if (txq_id == IWL_CMD_QUEUE_NUM)
426 iwl_cmd_queue_free(priv); 470 iwl_cmd_queue_free(priv);
427 else 471 else
@@ -437,15 +481,15 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
437EXPORT_SYMBOL(iwl_hw_txq_ctx_free); 481EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
438 482
439/** 483/**
440 * iwl_txq_ctx_reset - Reset TX queue context 484 * iwl_txq_ctx_alloc - allocate TX queue context
441 * Destroys all DMA structures and initialize them again 485 * Allocate all Tx DMA structures and initialize them
442 * 486 *
443 * @param priv 487 * @param priv
444 * @return error code 488 * @return error code
445 */ 489 */
446int iwl_txq_ctx_reset(struct iwl_priv *priv) 490int iwl_txq_ctx_alloc(struct iwl_priv *priv)
447{ 491{
448 int ret = 0; 492 int ret;
449 int txq_id, slots_num; 493 int txq_id, slots_num;
450 unsigned long flags; 494 unsigned long flags;
451 495
@@ -503,8 +547,31 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
503 return ret; 547 return ret;
504} 548}
505 549
550void iwl_txq_ctx_reset(struct iwl_priv *priv)
551{
552 int txq_id, slots_num;
553 unsigned long flags;
554
555 spin_lock_irqsave(&priv->lock, flags);
556
557 /* Turn off all Tx DMA fifos */
558 priv->cfg->ops->lib->txq_set_sched(priv, 0);
559
560 /* Tell NIC where to find the "keep warm" buffer */
561 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
562
563 spin_unlock_irqrestore(&priv->lock, flags);
564
565 /* Alloc and init all Tx queues, including the command queue (#4) */
566 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
567 slots_num = txq_id == IWL_CMD_QUEUE_NUM ?
568 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
569 iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
570 }
571}
572
506/** 573/**
507 * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory 574 * iwl_txq_ctx_stop - Stop all Tx DMA channels
508 */ 575 */
509void iwl_txq_ctx_stop(struct iwl_priv *priv) 576void iwl_txq_ctx_stop(struct iwl_priv *priv)
510{ 577{
@@ -524,9 +591,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv)
524 1000); 591 1000);
525 } 592 }
526 spin_unlock_irqrestore(&priv->lock, flags); 593 spin_unlock_irqrestore(&priv->lock, flags);
527
528 /* Deallocate memory for all Tx queues */
529 iwl_hw_txq_ctx_free(priv);
530} 594}
531EXPORT_SYMBOL(iwl_txq_ctx_stop); 595EXPORT_SYMBOL(iwl_txq_ctx_stop);
532 596
@@ -1049,6 +1113,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1049 1113
1050 spin_lock_irqsave(&priv->hcmd_lock, flags); 1114 spin_lock_irqsave(&priv->hcmd_lock, flags);
1051 1115
1116 /* If this is a huge cmd, mark the huge flag also on the meta.flags
1117 * of the _original_ cmd. This is used for DMA mapping clean up.
1118 */
1119 if (cmd->flags & CMD_SIZE_HUGE) {
1120 idx = get_cmd_index(q, q->write_ptr, 0);
1121 txq->meta[idx].flags = CMD_SIZE_HUGE;
1122 }
1123
1052 idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); 1124 idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
1053 out_cmd = txq->cmd[idx]; 1125 out_cmd = txq->cmd[idx];
1054 out_meta = &txq->meta[idx]; 1126 out_meta = &txq->meta[idx];
@@ -1226,6 +1298,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1226 bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); 1298 bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
1227 struct iwl_device_cmd *cmd; 1299 struct iwl_device_cmd *cmd;
1228 struct iwl_cmd_meta *meta; 1300 struct iwl_cmd_meta *meta;
1301 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
1229 1302
1230 /* If a Tx command is being handled and it isn't in the actual 1303 /* If a Tx command is being handled and it isn't in the actual
1231 * command queue then there a command routing bug has been introduced 1304 * command queue then there a command routing bug has been introduced
@@ -1239,9 +1312,17 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1239 return; 1312 return;
1240 } 1313 }
1241 1314
1242 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); 1315 /* If this is a huge cmd, clear the huge flag on the meta.flags
1243 cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; 1316 * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap
1244 meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index]; 1317 * the DMA buffer for the scan (huge) command.
1318 */
1319 if (huge) {
1320 cmd_index = get_cmd_index(&txq->q, index, 0);
1321 txq->meta[cmd_index].flags = 0;
1322 }
1323 cmd_index = get_cmd_index(&txq->q, index, huge);
1324 cmd = txq->cmd[cmd_index];
1325 meta = &txq->meta[cmd_index];
1245 1326
1246 pci_unmap_single(priv->pci_dev, 1327 pci_unmap_single(priv->pci_dev,
1247 pci_unmap_addr(meta, mapping), 1328 pci_unmap_addr(meta, mapping),
@@ -1263,6 +1344,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1263 get_cmd_string(cmd->hdr.cmd)); 1344 get_cmd_string(cmd->hdr.cmd));
1264 wake_up_interruptible(&priv->wait_command_queue); 1345 wake_up_interruptible(&priv->wait_command_queue);
1265 } 1346 }
1347 meta->flags = 0;
1266} 1348}
1267EXPORT_SYMBOL(iwl_tx_cmd_complete); 1349EXPORT_SYMBOL(iwl_tx_cmd_complete);
1268 1350
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 54daa38ecba3..b55e4f39a9e1 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>
@@ -1955,7 +1956,7 @@ static void iwl3945_init_hw_rates(struct iwl_priv *priv,
1955{ 1956{
1956 int i; 1957 int i;
1957 1958
1958 for (i = 0; i < IWL_RATE_COUNT; i++) { 1959 for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
1959 rates[i].bitrate = iwl3945_rates[i].ieee * 5; 1960 rates[i].bitrate = iwl3945_rates[i].ieee * 5;
1960 rates[i].hw_value = i; /* Rate scaling will work on indexes */ 1961 rates[i].hw_value = i; /* Rate scaling will work on indexes */
1961 rates[i].hw_value_short = i; 1962 rates[i].hw_value_short = i;
@@ -3921,7 +3922,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
3921 BIT(NL80211_IFTYPE_STATION) | 3922 BIT(NL80211_IFTYPE_STATION) |
3922 BIT(NL80211_IFTYPE_ADHOC); 3923 BIT(NL80211_IFTYPE_ADHOC);
3923 3924
3924 hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY | 3925 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
3925 WIPHY_FLAG_DISABLE_BEACON_HINTS; 3926 WIPHY_FLAG_DISABLE_BEACON_HINTS;
3926 3927
3927 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; 3928 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;