diff options
author | Simon Wunderlich <sw@simonwunderlich.de> | 2017-05-23 11:00:42 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2017-05-24 02:58:54 -0400 |
commit | 75d627d53e015027d0f85c928673d368807243cc (patch) | |
tree | bb3c83d7ec03ed07d2fd68a3456bf43fe704d1b7 /net/mac80211/util.c | |
parent | 3b23782f7d004f3d7fa655623ebca3137b442656 (diff) |
mac80211: mesh: support sending wide bandwidth CSA
To support HT and VHT CSA, beacons and action frames must include the
corresponding IEs.
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
[make ieee80211_ie_build_wide_bw_cs() return void]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index ac9ac6c35594..de0f1cdb64d4 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -2414,6 +2414,35 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, | |||
2414 | return pos + sizeof(struct ieee80211_ht_operation); | 2414 | return pos + sizeof(struct ieee80211_ht_operation); |
2415 | } | 2415 | } |
2416 | 2416 | ||
2417 | void ieee80211_ie_build_wide_bw_cs(u8 *pos, | ||
2418 | const struct cfg80211_chan_def *chandef) | ||
2419 | { | ||
2420 | *pos++ = WLAN_EID_WIDE_BW_CHANNEL_SWITCH; /* EID */ | ||
2421 | *pos++ = 3; /* IE length */ | ||
2422 | /* New channel width */ | ||
2423 | switch (chandef->width) { | ||
2424 | case NL80211_CHAN_WIDTH_80: | ||
2425 | *pos++ = IEEE80211_VHT_CHANWIDTH_80MHZ; | ||
2426 | break; | ||
2427 | case NL80211_CHAN_WIDTH_160: | ||
2428 | *pos++ = IEEE80211_VHT_CHANWIDTH_160MHZ; | ||
2429 | break; | ||
2430 | case NL80211_CHAN_WIDTH_80P80: | ||
2431 | *pos++ = IEEE80211_VHT_CHANWIDTH_80P80MHZ; | ||
2432 | break; | ||
2433 | default: | ||
2434 | *pos++ = IEEE80211_VHT_CHANWIDTH_USE_HT; | ||
2435 | } | ||
2436 | |||
2437 | /* new center frequency segment 0 */ | ||
2438 | *pos++ = ieee80211_frequency_to_channel(chandef->center_freq1); | ||
2439 | /* new center frequency segment 1 */ | ||
2440 | if (chandef->center_freq2) | ||
2441 | *pos++ = ieee80211_frequency_to_channel(chandef->center_freq2); | ||
2442 | else | ||
2443 | *pos++ = 0; | ||
2444 | } | ||
2445 | |||
2417 | u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, | 2446 | u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, |
2418 | const struct cfg80211_chan_def *chandef) | 2447 | const struct cfg80211_chan_def *chandef) |
2419 | { | 2448 | { |
@@ -2964,6 +2993,7 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, | |||
2964 | skb = dev_alloc_skb(local->tx_headroom + hdr_len + | 2993 | skb = dev_alloc_skb(local->tx_headroom + hdr_len + |
2965 | 5 + /* channel switch announcement element */ | 2994 | 5 + /* channel switch announcement element */ |
2966 | 3 + /* secondary channel offset element */ | 2995 | 3 + /* secondary channel offset element */ |
2996 | 5 + /* wide bandwidth channel switch announcement */ | ||
2967 | 8); /* mesh channel switch parameters element */ | 2997 | 8); /* mesh channel switch parameters element */ |
2968 | if (!skb) | 2998 | if (!skb) |
2969 | return -ENOMEM; | 2999 | return -ENOMEM; |
@@ -3022,6 +3052,13 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, | |||
3022 | pos += 2; | 3052 | pos += 2; |
3023 | } | 3053 | } |
3024 | 3054 | ||
3055 | if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_80 || | ||
3056 | csa_settings->chandef.width == NL80211_CHAN_WIDTH_80P80 || | ||
3057 | csa_settings->chandef.width == NL80211_CHAN_WIDTH_160) { | ||
3058 | skb_put(skb, 5); | ||
3059 | ieee80211_ie_build_wide_bw_cs(pos, &csa_settings->chandef); | ||
3060 | } | ||
3061 | |||
3025 | ieee80211_tx_skb(sdata, skb); | 3062 | ieee80211_tx_skb(sdata, skb); |
3026 | return 0; | 3063 | return 0; |
3027 | } | 3064 | } |