aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2015-10-25 04:59:34 -0400
committerJohannes Berg <johannes.berg@intel.com>2015-11-03 04:42:47 -0500
commit57f255f58165974c131f048b4302728052d92d29 (patch)
treeacd1ba928536735713b08174a627f2a999e2e058
parent0d440ea294a00b60ced66c0bc5cb5caa42fd4fbd (diff)
mac80211: TDLS: add proper HT-oper IE
When 11n peers performs a TDLS connection on a legacy BSS, the HT operation IE must be specified according to IEEE802.11-2012 section 9.23.3.2. Otherwise HT-protection is compromised and the medium becomes noisy for both the TDLS and the BSS links. Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/ibss.c2
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/mesh.c3
-rw-r--r--net/mac80211/tdls.c13
-rw-r--r--net/mac80211/util.c5
5 files changed, 18 insertions, 7 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 2001555d49cb..3b5874e0174f 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -188,7 +188,7 @@ ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata,
188 * keep them at 0 188 * keep them at 0
189 */ 189 */
190 pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, 190 pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap,
191 chandef, 0); 191 chandef, 0, false);
192 192
193 /* add VHT capability and information IEs */ 193 /* add VHT capability and information IEs */
194 if (chandef->width != NL80211_CHAN_WIDTH_20 && 194 if (chandef->width != NL80211_CHAN_WIDTH_20 &&
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 68680ad04cef..5c76ba7aaf57 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1962,7 +1962,7 @@ u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1962 u16 cap); 1962 u16 cap);
1963u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, 1963u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1964 const struct cfg80211_chan_def *chandef, 1964 const struct cfg80211_chan_def *chandef,
1965 u16 prot_mode); 1965 u16 prot_mode, bool rifs_mode);
1966u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, 1966u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
1967 u32 cap); 1967 u32 cap);
1968u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, 1968u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 626e8de70842..fa28500f28fd 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -466,7 +466,8 @@ int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata,
466 466
467 pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_operation)); 467 pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_operation));
468 ieee80211_ie_build_ht_oper(pos, ht_cap, &sdata->vif.bss_conf.chandef, 468 ieee80211_ie_build_ht_oper(pos, ht_cap, &sdata->vif.bss_conf.chandef,
469 sdata->vif.bss_conf.ht_operation_mode); 469 sdata->vif.bss_conf.ht_operation_mode,
470 false);
470 471
471 return 0; 472 return 0;
472} 473}
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index ecc5e2a8f80b..c9eeb3f12808 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -591,12 +591,19 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata,
591 offset = noffset; 591 offset = noffset;
592 } 592 }
593 593
594 /* if HT support is only added in TDLS, we need an HT-operation IE */ 594 /*
595 * if HT support is only added in TDLS, we need an HT-operation IE.
596 * add the IE as required by IEEE802.11-2012 9.23.3.2.
597 */
595 if (!ap_sta->sta.ht_cap.ht_supported && sta->sta.ht_cap.ht_supported) { 598 if (!ap_sta->sta.ht_cap.ht_supported && sta->sta.ht_cap.ht_supported) {
599 u16 prot = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED |
600 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
601 IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
602
596 pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_operation)); 603 pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_operation));
597 /* send an empty HT operation IE */
598 ieee80211_ie_build_ht_oper(pos, &sta->sta.ht_cap, 604 ieee80211_ie_build_ht_oper(pos, &sta->sta.ht_cap,
599 &sdata->vif.bss_conf.chandef, 0); 605 &sdata->vif.bss_conf.chandef, prot,
606 true);
600 } 607 }
601 608
602 ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator); 609 ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index d38daf0181e8..8802aa4da2a4 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2292,7 +2292,7 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
2292 2292
2293u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, 2293u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
2294 const struct cfg80211_chan_def *chandef, 2294 const struct cfg80211_chan_def *chandef,
2295 u16 prot_mode) 2295 u16 prot_mode, bool rifs_mode)
2296{ 2296{
2297 struct ieee80211_ht_operation *ht_oper; 2297 struct ieee80211_ht_operation *ht_oper;
2298 /* Build HT Information */ 2298 /* Build HT Information */
@@ -2320,6 +2320,9 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
2320 chandef->width != NL80211_CHAN_WIDTH_20) 2320 chandef->width != NL80211_CHAN_WIDTH_20)
2321 ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; 2321 ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
2322 2322
2323 if (rifs_mode)
2324 ht_oper->ht_param |= IEEE80211_HT_PARAM_RIFS_MODE;
2325
2323 ht_oper->operation_mode = cpu_to_le16(prot_mode); 2326 ht_oper->operation_mode = cpu_to_le16(prot_mode);
2324 ht_oper->stbc_param = 0x0000; 2327 ht_oper->stbc_param = 0x0000;
2325 2328