diff options
-rw-r--r-- | include/net/mac80211.h | 4 | ||||
-rw-r--r-- | net/mac80211/chan.c | 49 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 4 |
3 files changed, 57 insertions, 0 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index b7fb311e83f4..54e2add8429f 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -215,6 +215,9 @@ struct ieee80211_chanctx_conf { | |||
215 | * changed (currently only in P2P client mode, GO mode will be later) | 215 | * changed (currently only in P2P client mode, GO mode will be later) |
216 | * @BSS_CHANGED_DTIM_PERIOD: the DTIM period value was changed (set when | 216 | * @BSS_CHANGED_DTIM_PERIOD: the DTIM period value was changed (set when |
217 | * it becomes valid, managed mode only) | 217 | * it becomes valid, managed mode only) |
218 | * @BSS_CHANGED_BANDWIDTH: The bandwidth used by this interface changed, | ||
219 | * note that this is only called when it changes after the channel | ||
220 | * context had been assigned. | ||
218 | */ | 221 | */ |
219 | enum ieee80211_bss_change { | 222 | enum ieee80211_bss_change { |
220 | BSS_CHANGED_ASSOC = 1<<0, | 223 | BSS_CHANGED_ASSOC = 1<<0, |
@@ -238,6 +241,7 @@ enum ieee80211_bss_change { | |||
238 | BSS_CHANGED_TXPOWER = 1<<18, | 241 | BSS_CHANGED_TXPOWER = 1<<18, |
239 | BSS_CHANGED_P2P_PS = 1<<19, | 242 | BSS_CHANGED_P2P_PS = 1<<19, |
240 | BSS_CHANGED_DTIM_PERIOD = 1<<20, | 243 | BSS_CHANGED_DTIM_PERIOD = 1<<20, |
244 | BSS_CHANGED_BANDWIDTH = 1<<21, | ||
241 | 245 | ||
242 | /* when adding here, make sure to change ieee80211_reconfig */ | 246 | /* when adding here, make sure to change ieee80211_reconfig */ |
243 | }; | 247 | }; |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 78dbb371f16e..78c0d90dd641 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -375,6 +375,55 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, | |||
375 | return ret; | 375 | return ret; |
376 | } | 376 | } |
377 | 377 | ||
378 | int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, | ||
379 | const struct cfg80211_chan_def *chandef, | ||
380 | u32 *changed) | ||
381 | { | ||
382 | struct ieee80211_local *local = sdata->local; | ||
383 | struct ieee80211_chanctx_conf *conf; | ||
384 | struct ieee80211_chanctx *ctx; | ||
385 | int ret; | ||
386 | |||
387 | if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef, | ||
388 | IEEE80211_CHAN_DISABLED)) | ||
389 | return -EINVAL; | ||
390 | |||
391 | mutex_lock(&local->chanctx_mtx); | ||
392 | if (cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef)) { | ||
393 | ret = 0; | ||
394 | goto out; | ||
395 | } | ||
396 | |||
397 | if (chandef->width == NL80211_CHAN_WIDTH_20_NOHT || | ||
398 | sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) { | ||
399 | ret = -EINVAL; | ||
400 | goto out; | ||
401 | } | ||
402 | |||
403 | conf = rcu_dereference_protected(sdata->vif.chanctx_conf, | ||
404 | lockdep_is_held(&local->chanctx_mtx)); | ||
405 | if (!conf) { | ||
406 | ret = -EINVAL; | ||
407 | goto out; | ||
408 | } | ||
409 | |||
410 | ctx = container_of(conf, struct ieee80211_chanctx, conf); | ||
411 | if (!cfg80211_chandef_compatible(&conf->def, chandef)) { | ||
412 | ret = -EINVAL; | ||
413 | goto out; | ||
414 | } | ||
415 | |||
416 | sdata->vif.bss_conf.chandef = *chandef; | ||
417 | |||
418 | ieee80211_recalc_chanctx_chantype(local, ctx); | ||
419 | |||
420 | *changed |= BSS_CHANGED_BANDWIDTH; | ||
421 | ret = 0; | ||
422 | out: | ||
423 | mutex_unlock(&local->chanctx_mtx); | ||
424 | return ret; | ||
425 | } | ||
426 | |||
378 | void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) | 427 | void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) |
379 | { | 428 | { |
380 | WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); | 429 | WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 892bac64a189..d1074442f1b5 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1613,6 +1613,10 @@ int __must_check | |||
1613 | ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, | 1613 | ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, |
1614 | const struct cfg80211_chan_def *chandef, | 1614 | const struct cfg80211_chan_def *chandef, |
1615 | enum ieee80211_chanctx_mode mode); | 1615 | enum ieee80211_chanctx_mode mode); |
1616 | int __must_check | ||
1617 | ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, | ||
1618 | const struct cfg80211_chan_def *chandef, | ||
1619 | u32 *changed); | ||
1616 | void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); | 1620 | void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); |
1617 | void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata); | 1621 | void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata); |
1618 | void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, | 1622 | void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, |