diff options
author | Simon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de> | 2013-06-28 04:39:59 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-07-16 02:57:57 -0400 |
commit | 822854b0b1d8f893279ca717f3d084aa5fcd9ff5 (patch) | |
tree | e1966e30e509c4bce35845d07284928100a24773 | |
parent | 803768f54ef84cb4aaac0b51274b11b31885588c (diff) |
mac80211: enable HT overrides for ibss
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
-rw-r--r-- | net/mac80211/ht.c | 53 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 18 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 |
3 files changed, 57 insertions, 17 deletions
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index f83534f6a2ee..529bf58bc145 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -19,13 +19,14 @@ | |||
19 | #include "ieee80211_i.h" | 19 | #include "ieee80211_i.h" |
20 | #include "rate.h" | 20 | #include "rate.h" |
21 | 21 | ||
22 | static void __check_htcap_disable(struct ieee80211_sub_if_data *sdata, | 22 | static void __check_htcap_disable(struct ieee80211_ht_cap *ht_capa, |
23 | struct ieee80211_ht_cap *ht_capa_mask, | ||
23 | struct ieee80211_sta_ht_cap *ht_cap, | 24 | struct ieee80211_sta_ht_cap *ht_cap, |
24 | u16 flag) | 25 | u16 flag) |
25 | { | 26 | { |
26 | __le16 le_flag = cpu_to_le16(flag); | 27 | __le16 le_flag = cpu_to_le16(flag); |
27 | if (sdata->u.mgd.ht_capa_mask.cap_info & le_flag) { | 28 | if (ht_capa_mask->cap_info & le_flag) { |
28 | if (!(sdata->u.mgd.ht_capa.cap_info & le_flag)) | 29 | if (!(ht_capa->cap_info & le_flag)) |
29 | ht_cap->cap &= ~flag; | 30 | ht_cap->cap &= ~flag; |
30 | } | 31 | } |
31 | } | 32 | } |
@@ -33,13 +34,30 @@ static void __check_htcap_disable(struct ieee80211_sub_if_data *sdata, | |||
33 | void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, | 34 | void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, |
34 | struct ieee80211_sta_ht_cap *ht_cap) | 35 | struct ieee80211_sta_ht_cap *ht_cap) |
35 | { | 36 | { |
36 | u8 *scaps = (u8 *)(&sdata->u.mgd.ht_capa.mcs.rx_mask); | 37 | struct ieee80211_ht_cap *ht_capa, *ht_capa_mask; |
37 | u8 *smask = (u8 *)(&sdata->u.mgd.ht_capa_mask.mcs.rx_mask); | 38 | u8 *scaps, *smask; |
38 | int i; | 39 | int i; |
39 | 40 | ||
40 | if (!ht_cap->ht_supported) | 41 | if (!ht_cap->ht_supported) |
41 | return; | 42 | return; |
42 | 43 | ||
44 | switch (sdata->vif.type) { | ||
45 | case NL80211_IFTYPE_STATION: | ||
46 | ht_capa = &sdata->u.mgd.ht_capa; | ||
47 | ht_capa_mask = &sdata->u.mgd.ht_capa_mask; | ||
48 | break; | ||
49 | case NL80211_IFTYPE_ADHOC: | ||
50 | ht_capa = &sdata->u.ibss.ht_capa; | ||
51 | ht_capa_mask = &sdata->u.ibss.ht_capa_mask; | ||
52 | break; | ||
53 | default: | ||
54 | WARN_ON_ONCE(1); | ||
55 | return; | ||
56 | } | ||
57 | |||
58 | scaps = (u8 *)(&ht_capa->mcs.rx_mask); | ||
59 | smask = (u8 *)(&ht_capa_mask->mcs.rx_mask); | ||
60 | |||
43 | /* NOTE: If you add more over-rides here, update register_hw | 61 | /* NOTE: If you add more over-rides here, update register_hw |
44 | * ht_capa_mod_msk logic in main.c as well. | 62 | * ht_capa_mod_msk logic in main.c as well. |
45 | * And, if this method can ever change ht_cap.ht_supported, fix | 63 | * And, if this method can ever change ht_cap.ht_supported, fix |
@@ -55,28 +73,32 @@ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, | |||
55 | } | 73 | } |
56 | 74 | ||
57 | /* Force removal of HT-40 capabilities? */ | 75 | /* Force removal of HT-40 capabilities? */ |
58 | __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_SUP_WIDTH_20_40); | 76 | __check_htcap_disable(ht_capa, ht_capa_mask, ht_cap, |
59 | __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_SGI_40); | 77 | IEEE80211_HT_CAP_SUP_WIDTH_20_40); |
78 | __check_htcap_disable(ht_capa, ht_capa_mask, ht_cap, | ||
79 | IEEE80211_HT_CAP_SGI_40); | ||
60 | 80 | ||
61 | /* Allow user to disable SGI-20 (SGI-40 is handled above) */ | 81 | /* Allow user to disable SGI-20 (SGI-40 is handled above) */ |
62 | __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_SGI_20); | 82 | __check_htcap_disable(ht_capa, ht_capa_mask, ht_cap, |
83 | IEEE80211_HT_CAP_SGI_20); | ||
63 | 84 | ||
64 | /* Allow user to disable the max-AMSDU bit. */ | 85 | /* Allow user to disable the max-AMSDU bit. */ |
65 | __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_MAX_AMSDU); | 86 | __check_htcap_disable(ht_capa, ht_capa_mask, ht_cap, |
87 | IEEE80211_HT_CAP_MAX_AMSDU); | ||
66 | 88 | ||
67 | /* Allow user to decrease AMPDU factor */ | 89 | /* Allow user to decrease AMPDU factor */ |
68 | if (sdata->u.mgd.ht_capa_mask.ampdu_params_info & | 90 | if (ht_capa_mask->ampdu_params_info & |
69 | IEEE80211_HT_AMPDU_PARM_FACTOR) { | 91 | IEEE80211_HT_AMPDU_PARM_FACTOR) { |
70 | u8 n = sdata->u.mgd.ht_capa.ampdu_params_info | 92 | u8 n = ht_capa->ampdu_params_info & |
71 | & IEEE80211_HT_AMPDU_PARM_FACTOR; | 93 | IEEE80211_HT_AMPDU_PARM_FACTOR; |
72 | if (n < ht_cap->ampdu_factor) | 94 | if (n < ht_cap->ampdu_factor) |
73 | ht_cap->ampdu_factor = n; | 95 | ht_cap->ampdu_factor = n; |
74 | } | 96 | } |
75 | 97 | ||
76 | /* Allow the user to increase AMPDU density. */ | 98 | /* Allow the user to increase AMPDU density. */ |
77 | if (sdata->u.mgd.ht_capa_mask.ampdu_params_info & | 99 | if (ht_capa_mask->ampdu_params_info & |
78 | IEEE80211_HT_AMPDU_PARM_DENSITY) { | 100 | IEEE80211_HT_AMPDU_PARM_DENSITY) { |
79 | u8 n = (sdata->u.mgd.ht_capa.ampdu_params_info & | 101 | u8 n = (ht_capa->ampdu_params_info & |
80 | IEEE80211_HT_AMPDU_PARM_DENSITY) | 102 | IEEE80211_HT_AMPDU_PARM_DENSITY) |
81 | >> IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT; | 103 | >> IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT; |
82 | if (n > ht_cap->ampdu_density) | 104 | if (n > ht_cap->ampdu_density) |
@@ -112,7 +134,8 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata, | |||
112 | * we advertised a restricted capability set to. Override | 134 | * we advertised a restricted capability set to. Override |
113 | * our own capabilities and then use those below. | 135 | * our own capabilities and then use those below. |
114 | */ | 136 | */ |
115 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | 137 | if ((sdata->vif.type == NL80211_IFTYPE_STATION || |
138 | sdata->vif.type == NL80211_IFTYPE_ADHOC) && | ||
116 | !test_sta_flag(sta, WLAN_STA_TDLS_PEER)) | 139 | !test_sta_flag(sta, WLAN_STA_TDLS_PEER)) |
117 | ieee80211_apply_htcap_overrides(sdata, &own_cap); | 140 | ieee80211_apply_htcap_overrides(sdata, &own_cap); |
118 | 141 | ||
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index ea7b9c2c7e66..7f290a8562ef 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -179,8 +179,12 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
179 | chandef.width != NL80211_CHAN_WIDTH_5 && | 179 | chandef.width != NL80211_CHAN_WIDTH_5 && |
180 | chandef.width != NL80211_CHAN_WIDTH_10 && | 180 | chandef.width != NL80211_CHAN_WIDTH_10 && |
181 | sband->ht_cap.ht_supported) { | 181 | sband->ht_cap.ht_supported) { |
182 | pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, | 182 | struct ieee80211_sta_ht_cap ht_cap; |
183 | sband->ht_cap.cap); | 183 | |
184 | memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap)); | ||
185 | ieee80211_apply_htcap_overrides(sdata, &ht_cap); | ||
186 | |||
187 | pos = ieee80211_ie_build_ht_cap(pos, &ht_cap, ht_cap.cap); | ||
184 | /* | 188 | /* |
185 | * Note: According to 802.11n-2009 9.13.3.1, HT Protection | 189 | * Note: According to 802.11n-2009 9.13.3.1, HT Protection |
186 | * field and RIFS Mode are reserved in IBSS mode, therefore | 190 | * field and RIFS Mode are reserved in IBSS mode, therefore |
@@ -1051,6 +1055,11 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
1051 | memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); | 1055 | memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); |
1052 | sdata->u.ibss.ssid_len = params->ssid_len; | 1056 | sdata->u.ibss.ssid_len = params->ssid_len; |
1053 | 1057 | ||
1058 | memcpy(&sdata->u.ibss.ht_capa, ¶ms->ht_capa, | ||
1059 | sizeof(sdata->u.ibss.ht_capa)); | ||
1060 | memcpy(&sdata->u.ibss.ht_capa_mask, ¶ms->ht_capa_mask, | ||
1061 | sizeof(sdata->u.ibss.ht_capa_mask)); | ||
1062 | |||
1054 | /* | 1063 | /* |
1055 | * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is | 1064 | * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is |
1056 | * reserved, but an HT STA shall protect HT transmissions as though | 1065 | * reserved, but an HT STA shall protect HT transmissions as though |
@@ -1131,6 +1140,11 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
1131 | presp = rcu_dereference_protected(ifibss->presp, | 1140 | presp = rcu_dereference_protected(ifibss->presp, |
1132 | lockdep_is_held(&sdata->wdev.mtx)); | 1141 | lockdep_is_held(&sdata->wdev.mtx)); |
1133 | RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); | 1142 | RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); |
1143 | |||
1144 | /* on the next join, re-program HT parameters */ | ||
1145 | memset(&ifibss->ht_capa, 0, sizeof(ifibss->ht_capa)); | ||
1146 | memset(&ifibss->ht_capa_mask, 0, sizeof(ifibss->ht_capa_mask)); | ||
1147 | |||
1134 | sdata->vif.bss_conf.ibss_joined = false; | 1148 | sdata->vif.bss_conf.ibss_joined = false; |
1135 | sdata->vif.bss_conf.ibss_creator = false; | 1149 | sdata->vif.bss_conf.ibss_creator = false; |
1136 | sdata->vif.bss_conf.enable_beacon = false; | 1150 | sdata->vif.bss_conf.enable_beacon = false; |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8412a303993a..683751a1eceb 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -509,6 +509,9 @@ struct ieee80211_if_ibss { | |||
509 | /* probe response/beacon for IBSS */ | 509 | /* probe response/beacon for IBSS */ |
510 | struct beacon_data __rcu *presp; | 510 | struct beacon_data __rcu *presp; |
511 | 511 | ||
512 | struct ieee80211_ht_cap ht_capa; /* configured ht-cap over-rides */ | ||
513 | struct ieee80211_ht_cap ht_capa_mask; /* Valid parts of ht_capa */ | ||
514 | |||
512 | spinlock_t incomplete_lock; | 515 | spinlock_t incomplete_lock; |
513 | struct list_head incomplete_stations; | 516 | struct list_head incomplete_stations; |
514 | 517 | ||