diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 79a24410dd0..7c3eb3d8f7e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -552,17 +552,30 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) | |||
552 | static void iwl4965_ht_conf(struct iwl_priv *priv, | 552 | static void iwl4965_ht_conf(struct iwl_priv *priv, |
553 | struct ieee80211_bss_conf *bss_conf) | 553 | struct ieee80211_bss_conf *bss_conf) |
554 | { | 554 | { |
555 | struct ieee80211_sta_ht_cap *ht_conf = bss_conf->ht_cap; | 555 | struct ieee80211_sta_ht_cap *ht_conf; |
556 | struct ieee80211_ht_bss_info *ht_bss_conf = bss_conf->ht_bss_conf; | ||
557 | struct iwl_ht_info *iwl_conf = &priv->current_ht_config; | 556 | struct iwl_ht_info *iwl_conf = &priv->current_ht_config; |
557 | struct ieee80211_sta *sta; | ||
558 | 558 | ||
559 | IWL_DEBUG_MAC80211("enter: \n"); | 559 | IWL_DEBUG_MAC80211("enter: \n"); |
560 | 560 | ||
561 | iwl_conf->is_ht = bss_conf->assoc_ht; | ||
562 | |||
563 | if (!iwl_conf->is_ht) | 561 | if (!iwl_conf->is_ht) |
564 | return; | 562 | return; |
565 | 563 | ||
564 | |||
565 | /* | ||
566 | * It is totally wrong to base global information on something | ||
567 | * that is valid only when associated, alas, this driver works | ||
568 | * that way and I don't know how to fix it. | ||
569 | */ | ||
570 | |||
571 | rcu_read_lock(); | ||
572 | sta = ieee80211_find_sta(priv->hw, priv->bssid); | ||
573 | if (!sta) { | ||
574 | rcu_read_unlock(); | ||
575 | return; | ||
576 | } | ||
577 | ht_conf = &sta->ht_cap; | ||
578 | |||
566 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) | 579 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) |
567 | iwl_conf->sgf |= HT_SHORT_GI_20MHZ; | 580 | iwl_conf->sgf |= HT_SHORT_GI_20MHZ; |
568 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) | 581 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) |
@@ -574,8 +587,8 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, | |||
574 | 587 | ||
575 | iwl_conf->supported_chan_width = | 588 | iwl_conf->supported_chan_width = |
576 | !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40); | 589 | !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40); |
577 | iwl_conf->extension_chan_offset = | 590 | |
578 | ht_bss_conf->bss_cap & IEEE80211_HT_PARAM_CHA_SEC_OFFSET; | 591 | iwl_conf->extension_chan_offset = bss_conf->ht.secondary_channel_offset; |
579 | /* If no above or below channel supplied disable FAT channel */ | 592 | /* If no above or below channel supplied disable FAT channel */ |
580 | if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE && | 593 | if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE && |
581 | iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW) { | 594 | iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW) { |
@@ -587,15 +600,14 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, | |||
587 | 600 | ||
588 | memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16); | 601 | memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16); |
589 | 602 | ||
590 | iwl_conf->control_channel = ht_bss_conf->primary_channel; | 603 | iwl_conf->tx_chan_width = bss_conf->ht.width_40_ok; |
591 | iwl_conf->tx_chan_width = | ||
592 | !!(ht_bss_conf->bss_cap & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY); | ||
593 | iwl_conf->ht_protection = | 604 | iwl_conf->ht_protection = |
594 | ht_bss_conf->bss_op_mode & IEEE80211_HT_OP_MODE_PROTECTION; | 605 | bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; |
595 | iwl_conf->non_GF_STA_present = | 606 | iwl_conf->non_GF_STA_present = |
596 | !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | 607 | !!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); |
608 | |||
609 | rcu_read_unlock(); | ||
597 | 610 | ||
598 | IWL_DEBUG_MAC80211("control channel %d\n", iwl_conf->control_channel); | ||
599 | IWL_DEBUG_MAC80211("leave\n"); | 611 | IWL_DEBUG_MAC80211("leave\n"); |
600 | } | 612 | } |
601 | 613 | ||
@@ -2746,6 +2758,8 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2746 | mutex_lock(&priv->mutex); | 2758 | mutex_lock(&priv->mutex); |
2747 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); | 2759 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); |
2748 | 2760 | ||
2761 | priv->current_ht_config.is_ht = conf->ht.enabled; | ||
2762 | |||
2749 | if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) { | 2763 | if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) { |
2750 | IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n"); | 2764 | IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n"); |
2751 | goto out; | 2765 | goto out; |
@@ -3104,7 +3118,6 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, | |||
3104 | } | 3118 | } |
3105 | 3119 | ||
3106 | if (changes & BSS_CHANGED_HT) { | 3120 | if (changes & BSS_CHANGED_HT) { |
3107 | IWL_DEBUG_MAC80211("HT %d\n", bss_conf->assoc_ht); | ||
3108 | iwl4965_ht_conf(priv, bss_conf); | 3121 | iwl4965_ht_conf(priv, bss_conf); |
3109 | iwl_set_rxon_chain(priv); | 3122 | iwl_set_rxon_chain(priv); |
3110 | } | 3123 | } |