diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-scan.c | 99 |
3 files changed, 62 insertions, 49 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index fcfb410aca90..baaf48616cc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -2770,15 +2770,6 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, | |||
2770 | 2770 | ||
2771 | mutex_lock(&priv->shrd->mutex); | 2771 | mutex_lock(&priv->shrd->mutex); |
2772 | 2772 | ||
2773 | /* | ||
2774 | * TODO: Remove this hack! Firmware needs to be updated | ||
2775 | * to allow longer off-channel periods in scanning for | ||
2776 | * this use case, based on a flag (and we'll need an API | ||
2777 | * flag in the firmware when it has that). | ||
2778 | */ | ||
2779 | if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && duration > 80) | ||
2780 | duration = 80; | ||
2781 | |||
2782 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | 2773 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { |
2783 | err = -EBUSY; | 2774 | err = -EBUSY; |
2784 | goto out; | 2775 | goto out; |
@@ -2787,6 +2778,7 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, | |||
2787 | priv->hw_roc_channel = channel; | 2778 | priv->hw_roc_channel = channel; |
2788 | priv->hw_roc_chantype = channel_type; | 2779 | priv->hw_roc_chantype = channel_type; |
2789 | priv->hw_roc_duration = duration; | 2780 | priv->hw_roc_duration = duration; |
2781 | priv->hw_roc_start_notified = false; | ||
2790 | cancel_delayed_work(&priv->hw_roc_disable_work); | 2782 | cancel_delayed_work(&priv->hw_roc_disable_work); |
2791 | 2783 | ||
2792 | if (!ctx->is_active) { | 2784 | if (!ctx->is_active) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index fabfc8bf4971..7f534c45d1fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1029,7 +1029,7 @@ struct iwl_priv { | |||
1029 | struct delayed_work hw_roc_disable_work; | 1029 | struct delayed_work hw_roc_disable_work; |
1030 | enum nl80211_channel_type hw_roc_chantype; | 1030 | enum nl80211_channel_type hw_roc_chantype; |
1031 | int hw_roc_duration; | 1031 | int hw_roc_duration; |
1032 | bool hw_roc_setup; | 1032 | bool hw_roc_setup, hw_roc_start_notified; |
1033 | 1033 | ||
1034 | /* bt coex */ | 1034 | /* bt coex */ |
1035 | u8 bt_enable_flag; | 1035 | u8 bt_enable_flag; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 8ac6b05c6c78..8386a86e2ca2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -218,8 +218,11 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv, | |||
218 | le32_to_cpu(notif->tsf_low), | 218 | le32_to_cpu(notif->tsf_low), |
219 | notif->status, notif->beacon_timer); | 219 | notif->status, notif->beacon_timer); |
220 | 220 | ||
221 | if (priv->scan_type == IWL_SCAN_ROC) | 221 | if (priv->scan_type == IWL_SCAN_ROC && |
222 | !priv->hw_roc_start_notified) { | ||
222 | ieee80211_ready_on_channel(priv->hw); | 223 | ieee80211_ready_on_channel(priv->hw); |
224 | priv->hw_roc_start_notified = true; | ||
225 | } | ||
223 | } | 226 | } |
224 | 227 | ||
225 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ | 228 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ |
@@ -310,34 +313,38 @@ static u16 iwl_get_active_dwell_time(struct iwl_priv *priv, | |||
310 | IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1); | 313 | IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1); |
311 | } | 314 | } |
312 | 315 | ||
316 | static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time) | ||
317 | { | ||
318 | struct iwl_rxon_context *ctx; | ||
319 | |||
320 | /* | ||
321 | * If we're associated, we clamp the dwell time 98% | ||
322 | * of the smallest beacon interval (minus 2 * channel | ||
323 | * tune time) | ||
324 | */ | ||
325 | for_each_context(priv, ctx) { | ||
326 | u16 value; | ||
327 | |||
328 | if (!iwl_is_associated_ctx(ctx)) | ||
329 | continue; | ||
330 | value = ctx->beacon_int; | ||
331 | if (!value) | ||
332 | value = IWL_PASSIVE_DWELL_BASE; | ||
333 | value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; | ||
334 | dwell_time = min(value, dwell_time); | ||
335 | } | ||
336 | |||
337 | return dwell_time; | ||
338 | } | ||
339 | |||
313 | static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, | 340 | static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, |
314 | enum ieee80211_band band) | 341 | enum ieee80211_band band) |
315 | { | 342 | { |
316 | struct iwl_rxon_context *ctx; | ||
317 | u16 passive = (band == IEEE80211_BAND_2GHZ) ? | 343 | u16 passive = (band == IEEE80211_BAND_2GHZ) ? |
318 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | 344 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : |
319 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; | 345 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; |
320 | 346 | ||
321 | if (iwl_is_any_associated(priv)) { | 347 | return iwl_limit_dwell(priv, passive); |
322 | /* | ||
323 | * If we're associated, we clamp the maximum passive | ||
324 | * dwell time to be 98% of the smallest beacon interval | ||
325 | * (minus 2 * channel tune time) | ||
326 | */ | ||
327 | for_each_context(priv, ctx) { | ||
328 | u16 value; | ||
329 | |||
330 | if (!iwl_is_associated_ctx(ctx)) | ||
331 | continue; | ||
332 | value = ctx->vif ? ctx->vif->bss_conf.beacon_int : 0; | ||
333 | if ((value > IWL_PASSIVE_DWELL_BASE) || !value) | ||
334 | value = IWL_PASSIVE_DWELL_BASE; | ||
335 | value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; | ||
336 | passive = min(value, passive); | ||
337 | } | ||
338 | } | ||
339 | |||
340 | return passive; | ||
341 | } | 348 | } |
342 | 349 | ||
343 | static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, | 350 | static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, |
@@ -716,29 +723,43 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
716 | break; | 723 | break; |
717 | case IWL_SCAN_ROC: { | 724 | case IWL_SCAN_ROC: { |
718 | struct iwl_scan_channel *scan_ch; | 725 | struct iwl_scan_channel *scan_ch; |
726 | int n_chan, i; | ||
727 | u16 dwell; | ||
728 | |||
729 | dwell = iwl_limit_dwell(priv, priv->hw_roc_duration); | ||
730 | n_chan = DIV_ROUND_UP(priv->hw_roc_duration, dwell); | ||
719 | 731 | ||
720 | scan->channel_count = 1; | 732 | scan->channel_count = n_chan; |
721 | 733 | ||
722 | scan_ch = (void *)&scan->data[cmd_len]; | 734 | scan_ch = (void *)&scan->data[cmd_len]; |
723 | scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; | ||
724 | scan_ch->channel = | ||
725 | cpu_to_le16(priv->hw_roc_channel->hw_value); | ||
726 | scan_ch->active_dwell = | ||
727 | scan_ch->passive_dwell = | ||
728 | cpu_to_le16(priv->hw_roc_duration); | ||
729 | 735 | ||
730 | /* Set txpower levels to defaults */ | 736 | for (i = 0; i < n_chan; i++) { |
731 | scan_ch->dsp_atten = 110; | 737 | scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; |
738 | scan_ch->channel = | ||
739 | cpu_to_le16(priv->hw_roc_channel->hw_value); | ||
732 | 740 | ||
733 | /* NOTE: if we were doing 6Mb OFDM for scans we'd use | 741 | if (i == n_chan - 1) |
734 | * power level: | 742 | dwell = priv->hw_roc_duration - i * dwell; |
735 | * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; | 743 | |
736 | */ | 744 | scan_ch->active_dwell = |
737 | if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ) | 745 | scan_ch->passive_dwell = cpu_to_le16(dwell); |
738 | scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; | 746 | |
739 | else | 747 | /* Set txpower levels to defaults */ |
740 | scan_ch->tx_gain = ((1 << 5) | (5 << 3)); | 748 | scan_ch->dsp_atten = 110; |
749 | |||
750 | /* NOTE: if we were doing 6Mb OFDM for scans we'd use | ||
751 | * power level: | ||
752 | * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; | ||
753 | */ | ||
754 | if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ) | ||
755 | scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; | ||
756 | else | ||
757 | scan_ch->tx_gain = ((1 << 5) | (5 << 3)); | ||
758 | |||
759 | scan_ch++; | ||
741 | } | 760 | } |
761 | } | ||
762 | |||
742 | break; | 763 | break; |
743 | } | 764 | } |
744 | 765 | ||