diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-04-08 13:34:54 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-08 13:34:54 -0400 |
commit | 0f2df9eac70423838a1f8d410fd3899ddd88317b (patch) | |
tree | 0617f723320d83eca5cef9c964c001014e74213f /drivers/net/wireless/iwlwifi | |
parent | 8c11e4ab09ffb975a89802dde0e9aa52a53b8aa5 (diff) | |
parent | 1144601118507f8b3b676a9a392584d216d3f2cc (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6 into merge
Conflicts:
Documentation/feature-removal-schedule.txt
drivers/net/wireless/ath/ath5k/phy.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-tx.c
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 55 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 14 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-scan.c | 49 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 50 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 |
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 | */ | ||
352 | static 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 | */ |
355 | static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, | 366 | static 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 | */ | ||
741 | static 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, | |||
458 | void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); | 458 | void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
459 | int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, | 459 | int 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); |
461 | void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, | ||
462 | int slots_num, u32 txq_id); | ||
461 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); | 463 | void 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 | } |
587 | EXPORT_SYMBOL(iwl_tx_cmd_complete); | 629 | EXPORT_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; |