diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-04-26 03:08:27 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-04-26 03:08:27 -0400 |
commit | e19553427c2e8fdb04fdd98e407164bb59a840ba (patch) | |
tree | 5332234b2dad07c03c27e4608afb16f297f41e61 /drivers/net/wireless/iwlwifi | |
parent | 35f6cd4a06432034665a1499ca4b022437423aac (diff) | |
parent | 83515bc7df812555e20cda48614674e2f346f9f5 (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')
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 | */ | ||
353 | static 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 | */ |
355 | static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, | 367 | static 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 | */ | ||
745 | static 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 | ******************************************************/ |
445 | int iwl_txq_ctx_reset(struct iwl_priv *priv); | 445 | int iwl_txq_ctx_alloc(struct iwl_priv *priv); |
446 | void iwl_txq_ctx_reset(struct iwl_priv *priv); | ||
446 | void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); | 447 | void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
447 | int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, | 448 | int 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, | |||
456 | void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); | 457 | void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
457 | int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, | 458 | int 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); |
460 | void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, | ||
461 | int slots_num, u32 txq_id); | ||
459 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); | 462 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); |
460 | int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); | 463 | int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); |
461 | int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid); | 464 | int 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); | |||
503 | int iwl_scan_cancel(struct iwl_priv *priv); | 506 | int iwl_scan_cancel(struct iwl_priv *priv); |
504 | int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); | 507 | int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); |
505 | int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); | 508 | int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); |
506 | int iwl_internal_short_hw_scan(struct iwl_priv *priv); | 509 | void iwl_internal_short_hw_scan(struct iwl_priv *priv); |
507 | int iwl_force_reset(struct iwl_priv *priv, int mode); | 510 | int iwl_force_reset(struct iwl_priv *priv, int mode); |
508 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, | 511 | u16 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 | ||
470 | static int iwl_scan_initiate(struct iwl_priv *priv) | 471 | static 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 | */ |
549 | int iwl_internal_short_hw_scan(struct iwl_priv *priv) | 552 | void 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 | |||
557 | static 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: | |
580 | out: | 590 | mutex_unlock(&priv->mutex); |
581 | return ret; | ||
582 | } | 591 | } |
583 | EXPORT_SYMBOL(iwl_internal_short_hw_scan); | 592 | EXPORT_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 | } |
969 | EXPORT_SYMBOL(iwl_setup_scan_deferred_work); | 979 | EXPORT_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 | } |
410 | EXPORT_SYMBOL(iwl_tx_queue_init); | 435 | EXPORT_SYMBOL(iwl_tx_queue_init); |
411 | 436 | ||
437 | void 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 | } | ||
455 | EXPORT_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) | |||
437 | EXPORT_SYMBOL(iwl_hw_txq_ctx_free); | 481 | EXPORT_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 | */ |
446 | int iwl_txq_ctx_reset(struct iwl_priv *priv) | 490 | int 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 | ||
550 | void 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 | */ |
509 | void iwl_txq_ctx_stop(struct iwl_priv *priv) | 576 | void 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 | } |
531 | EXPORT_SYMBOL(iwl_txq_ctx_stop); | 595 | EXPORT_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 | } |
1267 | EXPORT_SYMBOL(iwl_tx_cmd_complete); | 1349 | EXPORT_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; |