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.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c55
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c49
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c50
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c4
8 files changed, 106 insertions, 80 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index e81577b1a25..f88f75dfd96 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -184,7 +184,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
184{ 184{
185 int idx; 185 int idx;
186 186
187 for (idx = 0; idx < IWL_RATE_COUNT; idx++) 187 for (idx = 0; idx < IWL_RATE_COUNT_3945; idx++)
188 if (iwl3945_rates[idx].plcp == plcp) 188 if (iwl3945_rates[idx].plcp == plcp)
189 return idx; 189 return idx;
190 return -1; 190 return -1;
@@ -755,7 +755,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
755 int sta_id, int tx_id) 755 int sta_id, int tx_id)
756{ 756{
757 u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; 757 u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
758 u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1); 758 u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT_3945);
759 u16 rate_mask; 759 u16 rate_mask;
760 int rate; 760 int rate;
761 u8 rts_retry_limit; 761 u8 rts_retry_limit;
@@ -2088,7 +2088,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv)
2088 2088
2089 /* fill in channel group's nominal powers for each rate */ 2089 /* fill in channel group's nominal powers for each rate */
2090 for (rate_index = 0; 2090 for (rate_index = 0;
2091 rate_index < IWL_RATE_COUNT; rate_index++, clip_pwrs++) { 2091 rate_index < IWL_RATE_COUNT_3945; rate_index++, clip_pwrs++) {
2092 switch (rate_index) { 2092 switch (rate_index) {
2093 case IWL_RATE_36M_INDEX_TABLE: 2093 case IWL_RATE_36M_INDEX_TABLE:
2094 if (i == 0) /* B/G */ 2094 if (i == 0) /* B/G */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 9a220d41544..6edae9b83bb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2040,16 +2040,14 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2040 tx_resp->failure_frame); 2040 tx_resp->failure_frame);
2041 2041
2042 freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); 2042 freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
2043 if (qc && likely(sta_id != IWL_INVALID_STATION)) 2043 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
2044 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
2045 2044
2046 if (priv->mac80211_registered && 2045 if (priv->mac80211_registered &&
2047 (iwl_queue_space(&txq->q) > txq->q.low_mark)) 2046 (iwl_queue_space(&txq->q) > txq->q.low_mark))
2048 iwl_wake_queue(priv, txq_id); 2047 iwl_wake_queue(priv, txq_id);
2049 } 2048 }
2050 2049
2051 if (qc && likely(sta_id != IWL_INVALID_STATION)) 2050 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
2052 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
2053 2051
2054 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) 2052 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
2055 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); 2053 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 0f881947627..0c3c76803c5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -345,6 +345,17 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
345 !!(rate_n_flags & RATE_MCS_ANT_C_MSK); 345 !!(rate_n_flags & RATE_MCS_ANT_C_MSK);
346} 346}
347 347
348/*
349 * Static function to get the expected throughput from an iwl_scale_tbl_info
350 * that wraps a NULL pointer check
351 */
352static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
353{
354 if (tbl->expected_tpt)
355 return tbl->expected_tpt[rs_index];
356 return 0;
357}
358
348/** 359/**
349 * rs_collect_tx_data - Update the success/failure sliding window 360 * rs_collect_tx_data - Update the success/failure sliding window
350 * 361 *
@@ -352,19 +363,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 363 * at this rate. window->data contains the bitmask of successful
353 * packets. 364 * packets.
354 */ 365 */
355static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, 366static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
356 int scale_index, s32 tpt, int attempts, 367 int scale_index, int attempts, int successes)
357 int successes)
358{ 368{
359 struct iwl_rate_scale_data *window = NULL; 369 struct iwl_rate_scale_data *window = NULL;
360 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); 370 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
361 s32 fail_count; 371 s32 fail_count, tpt;
362 372
363 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) 373 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
364 return -EINVAL; 374 return -EINVAL;
365 375
366 /* Select window for current tx bit rate */ 376 /* Select window for current tx bit rate */
367 window = &(windows[scale_index]); 377 window = &(tbl->win[scale_index]);
378
379 /* Get expected throughput */
380 tpt = get_expected_tpt(tbl, scale_index);
368 381
369 /* 382 /*
370 * Keep track of only the latest 62 tx frame attempts in this rate's 383 * Keep track of only the latest 62 tx frame attempts in this rate's
@@ -734,16 +747,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) && 747 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
735 (a->is_SGI == b->is_SGI); 748 (a->is_SGI == b->is_SGI);
736} 749}
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 750
748/* 751/*
749 * mac80211 sends us Tx status 752 * mac80211 sends us Tx status
@@ -760,12 +763,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
760 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 763 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
761 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 764 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
762 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 765 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; 766 enum mac80211_rate_control_flags mac_flags;
765 u32 tx_rate; 767 u32 tx_rate;
766 struct iwl_scale_tbl_info tbl_type; 768 struct iwl_scale_tbl_info tbl_type;
767 struct iwl_scale_tbl_info *curr_tbl, *other_tbl; 769 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
768 s32 tpt = 0;
769 770
770 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); 771 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
771 772
@@ -853,7 +854,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"); 854 IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
854 return; 855 return;
855 } 856 }
856 window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
857 857
858 /* 858 /*
859 * Updating the frame history depends on whether packets were 859 * Updating the frame history depends on whether packets were
@@ -866,8 +866,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); 866 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, 867 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
868 &rs_index); 868 &rs_index);
869 tpt = get_expected_tpt(curr_tbl, rs_index); 869 rs_collect_tx_data(curr_tbl, rs_index,
870 rs_collect_tx_data(window, rs_index, tpt,
871 info->status.ampdu_ack_len, 870 info->status.ampdu_ack_len,
872 info->status.ampdu_ack_map); 871 info->status.ampdu_ack_map);
873 872
@@ -897,19 +896,13 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
897 * table as active/search. 896 * table as active/search.
898 */ 897 */
899 if (table_type_matches(&tbl_type, curr_tbl)) 898 if (table_type_matches(&tbl_type, curr_tbl))
900 tpt = get_expected_tpt(curr_tbl, rs_index); 899 tmp_tbl = curr_tbl;
901 else if (table_type_matches(&tbl_type, other_tbl)) 900 else if (table_type_matches(&tbl_type, other_tbl))
902 tpt = get_expected_tpt(other_tbl, rs_index); 901 tmp_tbl = other_tbl;
903 else 902 else
904 continue; 903 continue;
905 904 rs_collect_tx_data(tmp_tbl, rs_index, 1,
906 /* Constants mean 1 transmission, 0 successes */ 905 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 } 906 }
914 907
915 /* 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 629cbf38aa9..4f0cb803f73 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1229,7 +1229,15 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1229 /* Ack/clear/reset pending uCode interrupts. 1229 /* Ack/clear/reset pending uCode interrupts.
1230 * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, 1230 * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
1231 */ 1231 */
1232 iwl_write32(priv, CSR_INT, priv->_agn.inta); 1232 /* There is a hardware bug in the interrupt mask function that some
1233 * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if
1234 * they are disabled in the CSR_INT_MASK register. Furthermore the
1235 * ICT interrupt handling mechanism has another bug that might cause
1236 * these unmasked interrupts fail to be detected. We workaround the
1237 * hardware bugs here by ACKing all the possible interrupts so that
1238 * interrupt coalescing can still be achieved.
1239 */
1240 iwl_write32(priv, CSR_INT, priv->_agn.inta | ~priv->inta_mask);
1233 1241
1234 inta = priv->_agn.inta; 1242 inta = priv->_agn.inta;
1235 1243
@@ -2653,7 +2661,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
2653 BIT(NL80211_IFTYPE_STATION) | 2661 BIT(NL80211_IFTYPE_STATION) |
2654 BIT(NL80211_IFTYPE_ADHOC); 2662 BIT(NL80211_IFTYPE_ADHOC);
2655 2663
2656 hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY | 2664 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
2657 WIPHY_FLAG_DISABLE_BEACON_HINTS; 2665 WIPHY_FLAG_DISABLE_BEACON_HINTS;
2658 2666
2659 /* 2667 /*
@@ -2662,7 +2670,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
2662 */ 2670 */
2663 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 2671 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2664 2672
2665 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX + 1; 2673 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
2666 /* we create the 802.11 header and a zero-length SSID element */ 2674 /* we create the 802.11 header and a zero-length SSID element */
2667 hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; 2675 hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
2668 2676
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index bc04b43cad3..10f95724536 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -458,6 +458,8 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
458void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); 458void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
459int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, 459int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
460 int slots_num, u32 txq_id); 460 int slots_num, u32 txq_id);
461void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
462 int slots_num, u32 txq_id);
461void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); 463void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
462/***************************************************** 464/*****************************************************
463 * TX power 465 * TX power
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 0daa1c9f1c6..d817c9c184a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -637,20 +637,9 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
637 if (left < 0) 637 if (left < 0)
638 return 0; 638 return 0;
639 *pos++ = WLAN_EID_SSID; 639 *pos++ = WLAN_EID_SSID;
640 if (!priv->is_internal_short_scan && 640 *pos++ = 0;
641 priv->scan_request->n_ssids) { 641
642 struct cfg80211_ssid *ssid = 642 len += 2;
643 priv->scan_request->ssids;
644
645 /* Broadcast if ssid_len is 0 */
646 *pos++ = ssid->ssid_len;
647 memcpy(pos, ssid->ssid, ssid->ssid_len);
648 pos += ssid->ssid_len;
649 len += 2 + ssid->ssid_len;
650 } else {
651 *pos++ = 0;
652 len += 2;
653 }
654 643
655 if (WARN_ON(left < ie_len)) 644 if (WARN_ON(left < ie_len))
656 return len; 645 return len;
@@ -778,26 +767,20 @@ static void iwl_bg_request_scan(struct work_struct *data)
778 if (priv->is_internal_short_scan) { 767 if (priv->is_internal_short_scan) {
779 IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); 768 IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
780 } else if (priv->scan_request->n_ssids) { 769 } else if (priv->scan_request->n_ssids) {
770 int i, p = 0;
781 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); 771 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
782 /* 772 for (i = 0; i < priv->scan_request->n_ssids; i++) {
783 * The first SSID to scan is stuffed into the probe request 773 /* always does wildcard anyway */
784 * template and the remaining ones are handled through the 774 if (!priv->scan_request->ssids[i].ssid_len)
785 * direct_scan array. 775 continue;
786 */ 776 scan->direct_scan[p].id = WLAN_EID_SSID;
787 if (priv->scan_request->n_ssids > 1) { 777 scan->direct_scan[p].len =
788 int i, p = 0; 778 priv->scan_request->ssids[i].ssid_len;
789 for (i = 1; i < priv->scan_request->n_ssids; i++) { 779 memcpy(scan->direct_scan[p].ssid,
790 if (!priv->scan_request->ssids[i].ssid_len) 780 priv->scan_request->ssids[i].ssid,
791 continue; 781 priv->scan_request->ssids[i].ssid_len);
792 scan->direct_scan[p].id = WLAN_EID_SSID; 782 n_probes++;
793 scan->direct_scan[p].len = 783 p++;
794 priv->scan_request->ssids[i].ssid_len;
795 memcpy(scan->direct_scan[p].ssid,
796 priv->scan_request->ssids[i].ssid,
797 priv->scan_request->ssids[i].ssid_len);
798 n_probes++;
799 p++;
800 }
801 } 784 }
802 is_active = true; 785 is_active = true;
803 } else 786 } else
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 65090d386a5..a631afef5e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -83,7 +83,7 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
83 if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) 83 if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
84 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 84 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
85 else { 85 else {
86 IWL_ERR(priv, "free more than tfds_in_queue (%u:%d)\n", 86 IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
87 priv->stations[sta_id].tid[tid].tfds_in_queue, 87 priv->stations[sta_id].tid[tid].tfds_in_queue,
88 freed); 88 freed);
89 priv->stations[sta_id].tid[tid].tfds_in_queue = 0; 89 priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
@@ -152,10 +152,34 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
152 struct iwl_queue *q = &txq->q; 152 struct iwl_queue *q = &txq->q;
153 struct device *dev = &priv->pci_dev->dev; 153 struct device *dev = &priv->pci_dev->dev;
154 int i; 154 int i;
155 bool huge = false;
155 156
156 if (q->n_bd == 0) 157 if (q->n_bd == 0)
157 return; 158 return;
158 159
160 for (; q->read_ptr != q->write_ptr;
161 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
162 /* we have no way to tell if it is a huge cmd ATM */
163 i = get_cmd_index(q, q->read_ptr, 0);
164
165 if (txq->meta[i].flags & CMD_SIZE_HUGE) {
166 huge = true;
167 continue;
168 }
169
170 pci_unmap_single(priv->pci_dev,
171 pci_unmap_addr(&txq->meta[i], mapping),
172 pci_unmap_len(&txq->meta[i], len),
173 PCI_DMA_BIDIRECTIONAL);
174 }
175 if (huge) {
176 i = q->n_window;
177 pci_unmap_single(priv->pci_dev,
178 pci_unmap_addr(&txq->meta[i], mapping),
179 pci_unmap_len(&txq->meta[i], len),
180 PCI_DMA_BIDIRECTIONAL);
181 }
182
159 /* De-alloc array of command/tx buffers */ 183 /* De-alloc array of command/tx buffers */
160 for (i = 0; i <= TFD_CMD_SLOTS; i++) 184 for (i = 0; i <= TFD_CMD_SLOTS; i++)
161 kfree(txq->cmd[i]); 185 kfree(txq->cmd[i]);
@@ -424,6 +448,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
424 448
425 spin_lock_irqsave(&priv->hcmd_lock, flags); 449 spin_lock_irqsave(&priv->hcmd_lock, flags);
426 450
451 /* If this is a huge cmd, mark the huge flag also on the meta.flags
452 * of the _original_ cmd. This is used for DMA mapping clean up.
453 */
454 if (cmd->flags & CMD_SIZE_HUGE) {
455 idx = get_cmd_index(q, q->write_ptr, 0);
456 txq->meta[idx].flags = CMD_SIZE_HUGE;
457 }
458
427 idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); 459 idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
428 out_cmd = txq->cmd[idx]; 460 out_cmd = txq->cmd[idx];
429 out_meta = &txq->meta[idx]; 461 out_meta = &txq->meta[idx];
@@ -546,6 +578,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
546 bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); 578 bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
547 struct iwl_device_cmd *cmd; 579 struct iwl_device_cmd *cmd;
548 struct iwl_cmd_meta *meta; 580 struct iwl_cmd_meta *meta;
581 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
549 582
550 /* If a Tx command is being handled and it isn't in the actual 583 /* If a Tx command is being handled and it isn't in the actual
551 * command queue then there a command routing bug has been introduced 584 * command queue then there a command routing bug has been introduced
@@ -559,9 +592,17 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
559 return; 592 return;
560 } 593 }
561 594
562 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); 595 /* If this is a huge cmd, clear the huge flag on the meta.flags
563 cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; 596 * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap
564 meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index]; 597 * the DMA buffer for the scan (huge) command.
598 */
599 if (huge) {
600 cmd_index = get_cmd_index(&txq->q, index, 0);
601 txq->meta[cmd_index].flags = 0;
602 }
603 cmd_index = get_cmd_index(&txq->q, index, huge);
604 cmd = txq->cmd[cmd_index];
605 meta = &txq->meta[cmd_index];
565 606
566 pci_unmap_single(priv->pci_dev, 607 pci_unmap_single(priv->pci_dev,
567 pci_unmap_addr(meta, mapping), 608 pci_unmap_addr(meta, mapping),
@@ -583,6 +624,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
583 get_cmd_string(cmd->hdr.cmd)); 624 get_cmd_string(cmd->hdr.cmd));
584 wake_up_interruptible(&priv->wait_command_queue); 625 wake_up_interruptible(&priv->wait_command_queue);
585 } 626 }
627 meta->flags = 0;
586} 628}
587EXPORT_SYMBOL(iwl_tx_cmd_complete); 629EXPORT_SYMBOL(iwl_tx_cmd_complete);
588 630
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 4d0394b3fb5..c9188b9c565 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1946,7 +1946,7 @@ static void iwl3945_init_hw_rates(struct iwl_priv *priv,
1946{ 1946{
1947 int i; 1947 int i;
1948 1948
1949 for (i = 0; i < IWL_RATE_COUNT; i++) { 1949 for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
1950 rates[i].bitrate = iwl3945_rates[i].ieee * 5; 1950 rates[i].bitrate = iwl3945_rates[i].ieee * 5;
1951 rates[i].hw_value = i; /* Rate scaling will work on indexes */ 1951 rates[i].hw_value = i; /* Rate scaling will work on indexes */
1952 rates[i].hw_value_short = i; 1952 rates[i].hw_value_short = i;
@@ -3943,7 +3943,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
3943 BIT(NL80211_IFTYPE_STATION) | 3943 BIT(NL80211_IFTYPE_STATION) |
3944 BIT(NL80211_IFTYPE_ADHOC); 3944 BIT(NL80211_IFTYPE_ADHOC);
3945 3945
3946 hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY | 3946 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
3947 WIPHY_FLAG_DISABLE_BEACON_HINTS; 3947 WIPHY_FLAG_DISABLE_BEACON_HINTS;
3948 3948
3949 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; 3949 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;