+ sband = local->hw.wiphy->bands[cbss->channel->band];
+
+ ifmgd->flags &= ~IEEE80211_STA_DISABLE_40MHZ;
+
+ if (sband->ht_cap.ht_supported) {
+ ht_oper_ie = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
+ cbss->information_elements,
+ cbss->len_information_elements);
+ if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper))
+ ht_oper = (void *)(ht_oper_ie + 2);
+ }
+
+ if (ht_oper) {
+ ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan,
+ cbss->channel->band);
+ /* check that channel matches the right operating channel */
+ if (cbss->channel->center_freq != ht_cfreq) {
+ /*
+ * It's possible that some APs are confused here;
+ * Netgear WNDR3700 sometimes reports 4 higher than
+ * the actual channel in association responses, but
+ * since we look at probe response/beacon data here
+ * it should be OK.
+ */
+ printk(KERN_DEBUG
+ "%s: Wrong control channel: center-freq: %d"
+ " ht-cfreq: %d ht->primary_chan: %d"
+ " band: %d. Disabling HT.\n",
+ sdata->name, cbss->channel->center_freq,
+ ht_cfreq, ht_oper->primary_chan,
+ cbss->channel->band);
+ ht_oper = NULL;
+ }
+ }
+
+ if (ht_oper) {
+ channel_type = NL80211_CHAN_HT20;
+
+ if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
+ switch (ht_oper->ht_param &
+ IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
+ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+ channel_type = NL80211_CHAN_HT40PLUS;
+ break;
+ case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+ channel_type = NL80211_CHAN_HT40MINUS;
+ break;
+ }
+ }
+ }
+
+ if (!ieee80211_set_channel_type(local, sdata, channel_type)) {
+ /* can only fail due to HT40+/- mismatch */
+ channel_type = NL80211_CHAN_HT20;
+ printk(KERN_DEBUG
+ "%s: disabling 40 MHz due to multi-vif mismatch\n",
+ sdata->name);
+ ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ;
+ WARN_ON(!ieee80211_set_channel_type(local, sdata,
+ channel_type));
+ }
+