diff options
author | Janusz.Dziedzic@tieto.com <Janusz.Dziedzic@tieto.com> | 2015-03-20 01:37:01 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2015-03-30 04:48:26 -0400 |
commit | abcff6ef01f9ffa6958e50457574132f8f786308 (patch) | |
tree | 54c40e220974486318c8b5c4e3c1d0d45a4333ba /net/mac80211 | |
parent | 76bed0f43b27d37cbe5fe9f3c27362db59451dea (diff) |
mac80211: add VHT support for IBSS
Add VHT support for IBSS. Drivers could activate
this feature by setting NL80211_EXT_FEATURE_VHT_IBSS
flag.
Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/ht.c | 2 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 49 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 4 | ||||
-rw-r--r-- | net/mac80211/util.c | 33 |
5 files changed, 80 insertions, 11 deletions
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index ff630be2ca75..7a76ce639d58 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -252,8 +252,6 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata, | |||
252 | break; | 252 | break; |
253 | } | 253 | } |
254 | 254 | ||
255 | if (bw != sta->sta.bandwidth) | ||
256 | changed = true; | ||
257 | sta->sta.bandwidth = bw; | 255 | sta->sta.bandwidth = bw; |
258 | 256 | ||
259 | sta->cur_max_bandwidth = | 257 | sta->cur_max_bandwidth = |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 8f8391e008ed..52d629d5e797 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -188,6 +188,16 @@ ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata, | |||
188 | */ | 188 | */ |
189 | pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, | 189 | pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, |
190 | chandef, 0); | 190 | chandef, 0); |
191 | |||
192 | /* add VHT capability and information IEs */ | ||
193 | if (chandef->width != NL80211_CHAN_WIDTH_20 && | ||
194 | chandef->width != NL80211_CHAN_WIDTH_40 && | ||
195 | sband->vht_cap.vht_supported) { | ||
196 | pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap, | ||
197 | sband->vht_cap.cap); | ||
198 | pos = ieee80211_ie_build_vht_oper(pos, &sband->vht_cap, | ||
199 | chandef); | ||
200 | } | ||
191 | } | 201 | } |
192 | 202 | ||
193 | if (local->hw.queues >= IEEE80211_NUM_ACS) | 203 | if (local->hw.queues >= IEEE80211_NUM_ACS) |
@@ -415,6 +425,11 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
415 | NL80211_CHAN_WIDTH_20_NOHT); | 425 | NL80211_CHAN_WIDTH_20_NOHT); |
416 | chandef.width = sdata->u.ibss.chandef.width; | 426 | chandef.width = sdata->u.ibss.chandef.width; |
417 | break; | 427 | break; |
428 | case NL80211_CHAN_WIDTH_80: | ||
429 | case NL80211_CHAN_WIDTH_160: | ||
430 | chandef = sdata->u.ibss.chandef; | ||
431 | chandef.chan = cbss->channel; | ||
432 | break; | ||
418 | default: | 433 | default: |
419 | /* fall back to 20 MHz for unsupported modes */ | 434 | /* fall back to 20 MHz for unsupported modes */ |
420 | cfg80211_chandef_create(&chandef, cbss->channel, | 435 | cfg80211_chandef_create(&chandef, cbss->channel, |
@@ -1026,24 +1041,40 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata, | |||
1026 | /* we both use HT */ | 1041 | /* we both use HT */ |
1027 | struct ieee80211_ht_cap htcap_ie; | 1042 | struct ieee80211_ht_cap htcap_ie; |
1028 | struct cfg80211_chan_def chandef; | 1043 | struct cfg80211_chan_def chandef; |
1044 | enum ieee80211_sta_rx_bandwidth bw = sta->sta.bandwidth; | ||
1029 | 1045 | ||
1030 | ieee80211_ht_oper_to_chandef(channel, | 1046 | ieee80211_ht_oper_to_chandef(channel, |
1031 | elems->ht_operation, | 1047 | elems->ht_operation, |
1032 | &chandef); | 1048 | &chandef); |
1033 | 1049 | ||
1034 | memcpy(&htcap_ie, elems->ht_cap_elem, sizeof(htcap_ie)); | 1050 | memcpy(&htcap_ie, elems->ht_cap_elem, sizeof(htcap_ie)); |
1035 | |||
1036 | /* | ||
1037 | * fall back to HT20 if we don't use or use | ||
1038 | * the other extension channel | ||
1039 | */ | ||
1040 | if (chandef.center_freq1 != sdata->u.ibss.chandef.center_freq1) | ||
1041 | htcap_ie.cap_info &= | ||
1042 | cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40); | ||
1043 | |||
1044 | rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, | 1051 | rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, |
1045 | &htcap_ie, | 1052 | &htcap_ie, |
1046 | sta); | 1053 | sta); |
1054 | |||
1055 | if (elems->vht_operation && elems->vht_cap_elem && | ||
1056 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20 && | ||
1057 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_40) { | ||
1058 | /* we both use VHT */ | ||
1059 | struct ieee80211_vht_cap cap_ie; | ||
1060 | struct ieee80211_sta_vht_cap cap = sta->sta.vht_cap; | ||
1061 | |||
1062 | ieee80211_vht_oper_to_chandef(channel, | ||
1063 | elems->vht_operation, | ||
1064 | &chandef); | ||
1065 | memcpy(&cap_ie, elems->vht_cap_elem, sizeof(cap_ie)); | ||
1066 | ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, | ||
1067 | &cap_ie, sta); | ||
1068 | if (memcmp(&cap, &sta->sta.vht_cap, sizeof(cap))) | ||
1069 | rates_updated |= true; | ||
1070 | } | ||
1071 | |||
1072 | if (bw != sta->sta.bandwidth) | ||
1073 | rates_updated |= true; | ||
1074 | |||
1075 | if (!cfg80211_chandef_compatible(&sdata->u.ibss.chandef, | ||
1076 | &chandef)) | ||
1077 | WARN_ON_ONCE(1); | ||
1047 | } | 1078 | } |
1048 | 1079 | ||
1049 | if (sta && rates_updated) { | 1080 | if (sta && rates_updated) { |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3331c62b4433..81340abb3876 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1960,6 +1960,9 @@ u8 *ieee80211_add_wmm_info_ie(u8 *buf, u8 qosinfo); | |||
1960 | void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan, | 1960 | void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan, |
1961 | const struct ieee80211_ht_operation *ht_oper, | 1961 | const struct ieee80211_ht_operation *ht_oper, |
1962 | struct cfg80211_chan_def *chandef); | 1962 | struct cfg80211_chan_def *chandef); |
1963 | void ieee80211_vht_oper_to_chandef(struct ieee80211_channel *control_chan, | ||
1964 | const struct ieee80211_vht_operation *oper, | ||
1965 | struct cfg80211_chan_def *chandef); | ||
1963 | u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c); | 1966 | u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c); |
1964 | 1967 | ||
1965 | int __must_check | 1968 | int __must_check |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 8465c055a371..60d737f144e3 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -382,6 +382,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, | |||
382 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); | 382 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); |
383 | struct ieee80211_supported_band *sband; | 383 | struct ieee80211_supported_band *sband; |
384 | u32 rates, basic_rates = 0, changed = 0; | 384 | u32 rates, basic_rates = 0, changed = 0; |
385 | enum ieee80211_sta_rx_bandwidth bw = sta->sta.bandwidth; | ||
385 | 386 | ||
386 | sband = local->hw.wiphy->bands[band]; | 387 | sband = local->hw.wiphy->bands[band]; |
387 | rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates); | 388 | rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates); |
@@ -401,6 +402,9 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, | |||
401 | elems->ht_cap_elem, sta)) | 402 | elems->ht_cap_elem, sta)) |
402 | changed |= IEEE80211_RC_BW_CHANGED; | 403 | changed |= IEEE80211_RC_BW_CHANGED; |
403 | 404 | ||
405 | if (bw != sta->sta.bandwidth) | ||
406 | changed |= IEEE80211_RC_BW_CHANGED; | ||
407 | |||
404 | /* HT peer is operating 20MHz-only */ | 408 | /* HT peer is operating 20MHz-only */ |
405 | if (elems->ht_operation && | 409 | if (elems->ht_operation && |
406 | !(elems->ht_operation->ht_param & | 410 | !(elems->ht_operation->ht_param & |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index e664b28821a2..256647cb1d24 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -2440,6 +2440,39 @@ void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan, | |||
2440 | cfg80211_chandef_create(chandef, control_chan, channel_type); | 2440 | cfg80211_chandef_create(chandef, control_chan, channel_type); |
2441 | } | 2441 | } |
2442 | 2442 | ||
2443 | void ieee80211_vht_oper_to_chandef(struct ieee80211_channel *control_chan, | ||
2444 | const struct ieee80211_vht_operation *oper, | ||
2445 | struct cfg80211_chan_def *chandef) | ||
2446 | { | ||
2447 | if (!oper) | ||
2448 | return; | ||
2449 | |||
2450 | chandef->chan = control_chan; | ||
2451 | |||
2452 | switch (oper->chan_width) { | ||
2453 | case IEEE80211_VHT_CHANWIDTH_USE_HT: | ||
2454 | break; | ||
2455 | case IEEE80211_VHT_CHANWIDTH_80MHZ: | ||
2456 | chandef->width = NL80211_CHAN_WIDTH_80; | ||
2457 | break; | ||
2458 | case IEEE80211_VHT_CHANWIDTH_160MHZ: | ||
2459 | chandef->width = NL80211_CHAN_WIDTH_160; | ||
2460 | break; | ||
2461 | case IEEE80211_VHT_CHANWIDTH_80P80MHZ: | ||
2462 | chandef->width = NL80211_CHAN_WIDTH_80P80; | ||
2463 | break; | ||
2464 | default: | ||
2465 | break; | ||
2466 | } | ||
2467 | |||
2468 | chandef->center_freq1 = | ||
2469 | ieee80211_channel_to_frequency(oper->center_freq_seg1_idx, | ||
2470 | control_chan->band); | ||
2471 | chandef->center_freq2 = | ||
2472 | ieee80211_channel_to_frequency(oper->center_freq_seg2_idx, | ||
2473 | control_chan->band); | ||
2474 | } | ||
2475 | |||
2443 | int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef, | 2476 | int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef, |
2444 | const struct ieee80211_supported_band *sband, | 2477 | const struct ieee80211_supported_band *sband, |
2445 | const u8 *srates, int srates_len, u32 *rates) | 2478 | const u8 *srates, int srates_len, u32 *rates) |