diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-core.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 84 |
1 files changed, 49 insertions, 35 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c7cbb2e8090..a15f7955845 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -617,19 +617,23 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, | |||
617 | struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config; | 617 | struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config; |
618 | 618 | ||
619 | if ((!iwl_ht_conf->is_ht) || | 619 | if ((!iwl_ht_conf->is_ht) || |
620 | (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) || | 620 | (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ)) |
621 | (iwl_ht_conf->extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE)) | ||
622 | return 0; | 621 | return 0; |
623 | 622 | ||
623 | /* We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40 | ||
624 | * the bit will not set if it is pure 40MHz case | ||
625 | */ | ||
624 | if (sta_ht_inf) { | 626 | if (sta_ht_inf) { |
625 | if ((!sta_ht_inf->ht_supported) || | 627 | if (!sta_ht_inf->ht_supported) |
626 | (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))) | ||
627 | return 0; | 628 | return 0; |
628 | } | 629 | } |
629 | 630 | ||
630 | return iwl_is_channel_extension(priv, priv->band, | 631 | if (iwl_ht_conf->ht_protection & IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) |
631 | le16_to_cpu(priv->staging_rxon.channel), | 632 | return 1; |
632 | iwl_ht_conf->extension_chan_offset); | 633 | else |
634 | return iwl_is_channel_extension(priv, priv->band, | ||
635 | le16_to_cpu(priv->staging_rxon.channel), | ||
636 | iwl_ht_conf->extension_chan_offset); | ||
633 | } | 637 | } |
634 | EXPORT_SYMBOL(iwl_is_fat_tx_allowed); | 638 | EXPORT_SYMBOL(iwl_is_fat_tx_allowed); |
635 | 639 | ||
@@ -799,42 +803,51 @@ EXPORT_SYMBOL(iwl_rate_get_lowest_plcp); | |||
799 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) | 803 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) |
800 | { | 804 | { |
801 | struct iwl_rxon_cmd *rxon = &priv->staging_rxon; | 805 | struct iwl_rxon_cmd *rxon = &priv->staging_rxon; |
802 | u32 val; | ||
803 | 806 | ||
804 | if (!ht_info->is_ht) { | 807 | if (!ht_info->is_ht) { |
805 | rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | | 808 | rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | |
806 | RXON_FLG_CHANNEL_MODE_PURE_40_MSK | | ||
807 | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | | 809 | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | |
808 | RXON_FLG_FAT_PROT_MSK | | 810 | RXON_FLG_FAT_PROT_MSK | |
809 | RXON_FLG_HT_PROT_MSK); | 811 | RXON_FLG_HT_PROT_MSK); |
810 | return; | 812 | return; |
811 | } | 813 | } |
812 | 814 | ||
813 | /* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */ | 815 | /* FIXME: if the definition of ht_protection changed, the "translation" |
814 | if (iwl_is_fat_tx_allowed(priv, NULL)) | 816 | * will be needed for rxon->flags |
815 | rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED_MSK; | 817 | */ |
816 | else | 818 | rxon->flags |= cpu_to_le32(ht_info->ht_protection << RXON_FLG_HT_OPERATING_MODE_POS); |
817 | rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | | 819 | |
818 | RXON_FLG_CHANNEL_MODE_PURE_40_MSK); | 820 | /* Set up channel bandwidth: |
819 | 821 | * 20 MHz only, 20/40 mixed or pure 40 if fat ok */ | |
820 | /* Note: control channel is opposite of extension channel */ | 822 | /* clear the HT channel mode before set the mode */ |
821 | switch (ht_info->extension_chan_offset) { | 823 | rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | |
822 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 824 | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); |
823 | rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); | 825 | if (iwl_is_fat_tx_allowed(priv, NULL)) { |
824 | break; | 826 | /* pure 40 fat */ |
825 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | 827 | if (rxon->flags & RXON_FLG_FAT_PROT_MSK) |
826 | rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | 828 | rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40; |
827 | break; | 829 | else { |
828 | case IEEE80211_HT_PARAM_CHA_SEC_NONE: | 830 | /* Note: control channel is opposite of extension channel */ |
829 | default: | 831 | switch (ht_info->extension_chan_offset) { |
830 | rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK; | 832 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
831 | break; | 833 | rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); |
834 | rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED; | ||
835 | break; | ||
836 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | ||
837 | rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | ||
838 | rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED; | ||
839 | break; | ||
840 | case IEEE80211_HT_PARAM_CHA_SEC_NONE: | ||
841 | default: | ||
842 | /* channel location only valid if in Mixed mode */ | ||
843 | IWL_ERR(priv, "invalid extension channel offset\n"); | ||
844 | break; | ||
845 | } | ||
846 | } | ||
847 | } else { | ||
848 | rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY; | ||
832 | } | 849 | } |
833 | 850 | ||
834 | val = ht_info->ht_protection; | ||
835 | |||
836 | rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS); | ||
837 | |||
838 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 851 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
839 | priv->cfg->ops->hcmd->set_rxon_chain(priv); | 852 | priv->cfg->ops->hcmd->set_rxon_chain(priv); |
840 | 853 | ||
@@ -1122,8 +1135,9 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode) | |||
1122 | priv->staging_rxon.cck_basic_rates = | 1135 | priv->staging_rxon.cck_basic_rates = |
1123 | (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; | 1136 | (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; |
1124 | 1137 | ||
1125 | priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | | 1138 | /* clear both MIX and PURE40 mode flag */ |
1126 | RXON_FLG_CHANNEL_MODE_PURE_40_MSK); | 1139 | priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | |
1140 | RXON_FLG_CHANNEL_MODE_PURE_40); | ||
1127 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | 1141 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); |
1128 | memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN); | 1142 | memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN); |
1129 | priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff; | 1143 | priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff; |