- TEST(TDLS_PEER_AUTH));
---- a/net/mac80211/ht.c
-+++ b/net/mac80211/ht.c
-@@ -47,7 +47,9 @@ void ieee80211_apply_htcap_overrides(str
- int i;
-
- if (sdata->vif.type != NL80211_IFTYPE_STATION) {
-- WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
-+ /* AP interfaces call this code when adding new stations,
-+ * so just silently ignore non station interfaces.
-+ */
- return;
- }
-
-@@ -282,6 +284,8 @@ void ieee80211_send_delba(struct ieee802
- memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
- else if (sdata->vif.type == NL80211_IFTYPE_STATION)
- memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
-+ else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-+ memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
-
- mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_ACTION);
---- a/net/mac80211/ibss.c
-+++ b/net/mac80211/ibss.c
-@@ -77,6 +77,7 @@ static void __ieee80211_sta_join_ibss(st
- struct cfg80211_bss *bss;
- u32 bss_change;
- u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
-+ enum nl80211_channel_type channel_type;
-
- lockdep_assert_held(&ifibss->mtx);
-
-@@ -105,8 +106,16 @@ static void __ieee80211_sta_join_ibss(st
-
- sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
-
-- local->oper_channel = chan;
-- WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
-+ channel_type = ifibss->channel_type;
-+ if (channel_type > NL80211_CHAN_HT20 &&
-+ !cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type))
-+ channel_type = NL80211_CHAN_HT20;
-+ if (!ieee80211_set_channel_type(local, sdata, channel_type)) {
-+ /* can only fail due to HT40+/- mismatch */
-+ channel_type = NL80211_CHAN_HT20;
-+ WARN_ON(!ieee80211_set_channel_type(local, sdata,
-+ NL80211_CHAN_HT20));
-+ }
- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
-
- sband = local->hw.wiphy->bands[chan->band];
-@@ -172,6 +181,19 @@ static void __ieee80211_sta_join_ibss(st
- memcpy(skb_put(skb, ifibss->ie_len),
- ifibss->ie, ifibss->ie_len);
-
-+ /* add HT capability and information IEs */
-+ if (channel_type && sband->ht_cap.ht_supported) {
-+ pos = skb_put(skb, 4 +
-+ sizeof(struct ieee80211_ht_cap) +
-+ sizeof(struct ieee80211_ht_info));
-+ pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap,
-+ sband->ht_cap.cap);
-+ pos = ieee80211_ie_build_ht_info(pos,
-+ &sband->ht_cap,
-+ chan,
-+ channel_type);
-+ }
-+
- if (local->hw.queues >= 4) {
- pos = skb_put(skb, 9);
- *pos++ = WLAN_EID_VENDOR_SPECIFIC;
-@@ -195,6 +217,7 @@ static void __ieee80211_sta_join_ibss(st
- bss_change |= BSS_CHANGED_BEACON;
- bss_change |= BSS_CHANGED_BEACON_ENABLED;
- bss_change |= BSS_CHANGED_BASIC_RATES;
-+ bss_change |= BSS_CHANGED_HT;
- bss_change |= BSS_CHANGED_IBSS;
- sdata->vif.bss_conf.ibss_joined = true;
- ieee80211_bss_info_change_notify(sdata, bss_change);
-@@ -268,6 +291,8 @@ static void ieee80211_rx_bss_info(struct
- u64 beacon_timestamp, rx_timestamp;
- u32 supp_rates = 0;
- enum ieee80211_band band = rx_status->band;
-+ struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
-+ bool rates_updated = false;
-
- if (elems->ds_params && elems->ds_params_len == 1)
- freq = ieee80211_channel_to_frequency(elems->ds_params[0],
-@@ -307,7 +332,7 @@ static void ieee80211_rx_bss_info(struct
- prev_rates,
- sta->sta.supp_rates[band]);
- #endif
-- rate_control_rate_init(sta);
-+ rates_updated = true;
- }
- } else
- sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
-@@ -318,6 +343,39 @@ static void ieee80211_rx_bss_info(struct
- if (sta && elems->wmm_info)
- set_sta_flag(sta, WLAN_STA_WME);
-
-+ if (sta && elems->ht_info_elem && elems->ht_cap_elem &&
-+ sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) {
-+ /* we both use HT */
-+ struct ieee80211_sta_ht_cap sta_ht_cap_new;
-+ enum nl80211_channel_type channel_type =
-+ ieee80211_ht_info_to_channel_type(
-+ elems->ht_info_elem);
-+
-+ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
-+ elems->ht_cap_elem,
-+ &sta_ht_cap_new);
-+
-+ /*
-+ * fall back to HT20 if we don't use or use
-+ * the other extension channel
-+ */
-+ if ((channel_type == NL80211_CHAN_HT40MINUS ||
-+ channel_type == NL80211_CHAN_HT40PLUS) &&
-+ channel_type != sdata->u.ibss.channel_type)
-+ sta_ht_cap_new.cap &=
-+ ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
-+
-+ if (memcmp(&sta->sta.ht_cap, &sta_ht_cap_new,
-+ sizeof(sta_ht_cap_new))) {
-+ memcpy(&sta->sta.ht_cap, &sta_ht_cap_new,
-+ sizeof(sta_ht_cap_new));
-+ rates_updated = true;
-+ }
-+ }
-+
-+ if (sta && rates_updated)
-+ rate_control_rate_init(sta);
-+
- rcu_read_unlock();
- }
-
-@@ -896,12 +954,18 @@ int ieee80211_ibss_join(struct ieee80211
- struct cfg80211_ibss_params *params)
- {
- struct sk_buff *skb;
-+ u32 changed = 0;
-
- skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
-- 36 /* bitrates */ +
-- 34 /* SSID */ +
-- 3 /* DS params */ +
-- 4 /* IBSS params */ +
-+ sizeof(struct ieee80211_hdr_3addr) +
-+ 12 /* struct ieee80211_mgmt.u.beacon */ +
-+ 2 + IEEE80211_MAX_SSID_LEN /* max SSID */ +
-+ 2 + 8 /* max Supported Rates */ +
-+ 3 /* max DS params */ +
-+ 4 /* IBSS params */ +
-+ 2 + (IEEE80211_MAX_SUPP_RATES - 8) +
-+ 2 + sizeof(struct ieee80211_ht_cap) +
-+ 2 + sizeof(struct ieee80211_ht_info) +
- params->ie_len);
- if (!skb)
- return -ENOMEM;
-@@ -922,13 +986,15 @@ int ieee80211_ibss_join(struct ieee80211
- sdata->vif.bss_conf.beacon_int = params->beacon_interval;
-
- sdata->u.ibss.channel = params->channel;
-+ sdata->u.ibss.channel_type = params->channel_type;
- sdata->u.ibss.fixed_channel = params->channel_fixed;
-
- /* fix ourselves to that channel now already */
- if (params->channel_fixed) {
- sdata->local->oper_channel = params->channel;
-- WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata,
-- NL80211_CHAN_NO_HT));
-+ if (!ieee80211_set_channel_type(sdata->local, sdata,
-+ params->channel_type))
-+ return -EINVAL;
- }
-
- if (params->ie) {
-@@ -951,6 +1017,23 @@ int ieee80211_ibss_join(struct ieee80211
- ieee80211_recalc_idle(sdata->local);
- mutex_unlock(&sdata->local->mtx);
-
-+ /*
-+ * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is
-+ * reserved, but an HT STA shall protect HT transmissions as though
-+ * the HT Protection field were set to non-HT mixed mode.
-+ *
-+ * In an IBSS, the RIFS Mode field of the HT Operation element is
-+ * also reserved, but an HT STA shall operate as though this field
-+ * were set to 1.
-+ */
-+
-+ sdata->vif.bss_conf.ht_operation_mode |=
-+ IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED
-+ | IEEE80211_HT_PARAM_RIFS_MODE;
-+
-+ changed |= BSS_CHANGED_HT;
-+ ieee80211_bss_info_change_notify(sdata, changed);
-+
- ieee80211_queue_work(&sdata->local->hw, &sdata->work);
-
- return 0;
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -474,6 +474,7 @@ struct ieee80211_if_ibss {
- u8 ssid_len, ie_len;
- u8 *ie;
- struct ieee80211_channel *channel;
-+ enum nl80211_channel_type channel_type;
-
- unsigned long ibss_join_req;
- /* probe response/beacon for IBSS */