diff options
Diffstat (limited to 'net/mac80211/ieee80211.c')
-rw-r--r-- | net/mac80211/ieee80211.c | 73 |
1 files changed, 44 insertions, 29 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index aaa5480e204..5d30dd463f2 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
@@ -1046,54 +1046,69 @@ int ieee80211_hw_config(struct ieee80211_local *local) | |||
1046 | } | 1046 | } |
1047 | 1047 | ||
1048 | /** | 1048 | /** |
1049 | * ieee80211_hw_config_ht should be used only after legacy configuration | 1049 | * ieee80211_handle_ht should be used only after legacy configuration |
1050 | * has been determined, as ht configuration depends upon the hardware's | 1050 | * has been determined namely band, as ht configuration depends upon |
1051 | * HT abilities for a _specific_ band. | 1051 | * the hardware's HT abilities for a _specific_ band. |
1052 | */ | 1052 | */ |
1053 | int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, | 1053 | u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, |
1054 | struct ieee80211_ht_info *req_ht_cap, | 1054 | struct ieee80211_ht_info *req_ht_cap, |
1055 | struct ieee80211_ht_bss_info *req_bss_cap) | 1055 | struct ieee80211_ht_bss_info *req_bss_cap) |
1056 | { | 1056 | { |
1057 | struct ieee80211_conf *conf = &local->hw.conf; | 1057 | struct ieee80211_conf *conf = &local->hw.conf; |
1058 | struct ieee80211_supported_band *sband; | 1058 | struct ieee80211_supported_band *sband; |
1059 | struct ieee80211_ht_info ht_conf; | ||
1060 | struct ieee80211_ht_bss_info ht_bss_conf; | ||
1059 | int i; | 1061 | int i; |
1062 | u32 changed = 0; | ||
1060 | 1063 | ||
1061 | sband = local->hw.wiphy->bands[conf->channel->band]; | 1064 | sband = local->hw.wiphy->bands[conf->channel->band]; |
1062 | 1065 | ||
1063 | /* HT is not supported */ | 1066 | /* HT is not supported */ |
1064 | if (!sband->ht_info.ht_supported) { | 1067 | if (!sband->ht_info.ht_supported) { |
1065 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 1068 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; |
1066 | return -EOPNOTSUPP; | 1069 | return 0; |
1067 | } | 1070 | } |
1068 | 1071 | ||
1069 | /* disable HT */ | 1072 | memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info)); |
1070 | if (!enable_ht) { | 1073 | memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); |
1071 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 1074 | |
1072 | } else { | 1075 | if (enable_ht) { |
1076 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) | ||
1077 | changed |= BSS_CHANGED_HT; | ||
1078 | |||
1073 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; | 1079 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; |
1074 | conf->ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; | 1080 | ht_conf.ht_supported = 1; |
1075 | conf->ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); | 1081 | |
1076 | conf->ht_conf.cap |= | 1082 | ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; |
1077 | sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; | 1083 | ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); |
1078 | conf->ht_bss_conf.primary_channel = | 1084 | ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; |
1079 | req_bss_cap->primary_channel; | 1085 | |
1080 | conf->ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | ||
1081 | conf->ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | ||
1082 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) | 1086 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) |
1083 | conf->ht_conf.supp_mcs_set[i] = | 1087 | ht_conf.supp_mcs_set[i] = |
1084 | sband->ht_info.supp_mcs_set[i] & | 1088 | sband->ht_info.supp_mcs_set[i] & |
1085 | req_ht_cap->supp_mcs_set[i]; | 1089 | req_ht_cap->supp_mcs_set[i]; |
1086 | 1090 | ||
1087 | /* In STA mode, this gives us indication | 1091 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; |
1088 | * to the AP's mode of operation */ | 1092 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; |
1089 | conf->ht_conf.ht_supported = 1; | 1093 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; |
1090 | conf->ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; | 1094 | |
1091 | conf->ht_conf.ampdu_density = req_ht_cap->ampdu_density; | 1095 | ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; |
1096 | ht_conf.ampdu_density = req_ht_cap->ampdu_density; | ||
1097 | |||
1098 | /* if bss configuration changed store the new one */ | ||
1099 | if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) || | ||
1100 | memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { | ||
1101 | changed |= BSS_CHANGED_HT; | ||
1102 | memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf)); | ||
1103 | memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); | ||
1104 | } | ||
1105 | } else { | ||
1106 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) | ||
1107 | changed |= BSS_CHANGED_HT; | ||
1108 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
1092 | } | 1109 | } |
1093 | 1110 | ||
1094 | local->ops->conf_ht(local_to_hw(local), &local->hw.conf); | 1111 | return changed; |
1095 | |||
1096 | return 0; | ||
1097 | } | 1112 | } |
1098 | 1113 | ||
1099 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 1114 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |