aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorSimon Wunderlich <sw@simonwunderlich.de>2017-05-23 11:00:42 -0400
committerJohannes Berg <johannes.berg@intel.com>2017-05-24 02:58:54 -0400
commit75d627d53e015027d0f85c928673d368807243cc (patch)
treebb3c83d7ec03ed07d2fd68a3456bf43fe704d1b7 /net/mac80211/util.c
parent3b23782f7d004f3d7fa655623ebca3137b442656 (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.c37
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
2417void 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
2417u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, 2446u8 *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}