diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-scan.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-scan.c | 57 |
1 files changed, 17 insertions, 40 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 78d16bd7b745..86b74571b513 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -64,12 +64,6 @@ | |||
64 | #define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1)))) | 64 | #define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1)))) |
65 | 65 | ||
66 | 66 | ||
67 | static int scan_tx_ant[3] = { | ||
68 | RATE_MCS_ANT_A_MSK, RATE_MCS_ANT_B_MSK, RATE_MCS_ANT_C_MSK | ||
69 | }; | ||
70 | |||
71 | |||
72 | |||
73 | static int iwl_is_empty_essid(const char *essid, int essid_len) | 67 | static int iwl_is_empty_essid(const char *essid, int essid_len) |
74 | { | 68 | { |
75 | /* Single white space is for Linksys APs */ | 69 | /* Single white space is for Linksys APs */ |
@@ -455,10 +449,11 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, | |||
455 | 449 | ||
456 | void iwl_init_scan_params(struct iwl_priv *priv) | 450 | void iwl_init_scan_params(struct iwl_priv *priv) |
457 | { | 451 | { |
452 | u8 ant_idx = fls(priv->hw_params.valid_tx_ant) - 1; | ||
458 | if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ]) | 453 | if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ]) |
459 | priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = RATE_MCS_ANT_INIT_IND; | 454 | priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = ant_idx; |
460 | if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) | 455 | if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) |
461 | priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = RATE_MCS_ANT_INIT_IND; | 456 | priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx; |
462 | } | 457 | } |
463 | 458 | ||
464 | int iwl_scan_initiate(struct iwl_priv *priv) | 459 | int iwl_scan_initiate(struct iwl_priv *priv) |
@@ -670,23 +665,6 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, | |||
670 | return (u16)len; | 665 | return (u16)len; |
671 | } | 666 | } |
672 | 667 | ||
673 | static u32 iwl_scan_tx_ant(struct iwl_priv *priv, enum ieee80211_band band) | ||
674 | { | ||
675 | int i, ind; | ||
676 | |||
677 | ind = priv->scan_tx_ant[band]; | ||
678 | for (i = 0; i < priv->hw_params.tx_chains_num; i++) { | ||
679 | ind = (ind+1) >= priv->hw_params.tx_chains_num ? 0 : ind+1; | ||
680 | if (priv->hw_params.valid_tx_ant & (1 << ind)) { | ||
681 | priv->scan_tx_ant[band] = ind; | ||
682 | break; | ||
683 | } | ||
684 | } | ||
685 | IWL_DEBUG_SCAN("select TX ANT = %c\n", 'A' + ind); | ||
686 | return scan_tx_ant[ind]; | ||
687 | } | ||
688 | |||
689 | |||
690 | static void iwl_bg_request_scan(struct work_struct *data) | 668 | static void iwl_bg_request_scan(struct work_struct *data) |
691 | { | 669 | { |
692 | struct iwl_priv *priv = | 670 | struct iwl_priv *priv = |
@@ -699,11 +677,12 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
699 | struct iwl_scan_cmd *scan; | 677 | struct iwl_scan_cmd *scan; |
700 | struct ieee80211_conf *conf = NULL; | 678 | struct ieee80211_conf *conf = NULL; |
701 | int ret = 0; | 679 | int ret = 0; |
702 | u32 tx_ant; | 680 | u32 rate_flags = 0; |
703 | u16 cmd_len; | 681 | u16 cmd_len; |
704 | enum ieee80211_band band; | 682 | enum ieee80211_band band; |
705 | u8 n_probes = 2; | 683 | u8 n_probes = 2; |
706 | u8 rx_chain = priv->hw_params.valid_rx_ant; | 684 | u8 rx_chain = priv->hw_params.valid_rx_ant; |
685 | u8 rate; | ||
707 | 686 | ||
708 | conf = ieee80211_get_hw_conf(priv->hw); | 687 | conf = ieee80211_get_hw_conf(priv->hw); |
709 | 688 | ||
@@ -822,23 +801,16 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
822 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) { | 801 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) { |
823 | band = IEEE80211_BAND_2GHZ; | 802 | band = IEEE80211_BAND_2GHZ; |
824 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | 803 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; |
825 | tx_ant = iwl_scan_tx_ant(priv, band); | 804 | if (priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) { |
826 | if (priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) | 805 | rate = IWL_RATE_6M_PLCP; |
827 | scan->tx_cmd.rate_n_flags = | 806 | } else { |
828 | iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, | 807 | rate = IWL_RATE_1M_PLCP; |
829 | tx_ant); | 808 | rate_flags = RATE_MCS_CCK_MSK; |
830 | else | 809 | } |
831 | scan->tx_cmd.rate_n_flags = | ||
832 | iwl_hw_set_rate_n_flags(IWL_RATE_1M_PLCP, | ||
833 | tx_ant | | ||
834 | RATE_MCS_CCK_MSK); | ||
835 | scan->good_CRC_th = 0; | 810 | scan->good_CRC_th = 0; |
836 | } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { | 811 | } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { |
837 | band = IEEE80211_BAND_5GHZ; | 812 | band = IEEE80211_BAND_5GHZ; |
838 | tx_ant = iwl_scan_tx_ant(priv, band); | 813 | rate = IWL_RATE_6M_PLCP; |
839 | scan->tx_cmd.rate_n_flags = | ||
840 | iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, | ||
841 | tx_ant); | ||
842 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 814 | scan->good_CRC_th = IWL_GOOD_CRC_TH; |
843 | 815 | ||
844 | /* Force use of chains B and C (0x6) for scan Rx for 4965 | 816 | /* Force use of chains B and C (0x6) for scan Rx for 4965 |
@@ -851,6 +823,11 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
851 | goto done; | 823 | goto done; |
852 | } | 824 | } |
853 | 825 | ||
826 | priv->scan_tx_ant[band] = | ||
827 | iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band]); | ||
828 | rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]); | ||
829 | scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags); | ||
830 | |||
854 | /* MIMO is not used here, but value is required */ | 831 | /* MIMO is not used here, but value is required */ |
855 | scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK | | 832 | scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK | |
856 | cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) | | 833 | cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) | |