aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/chan.c49
-rw-r--r--net/mac80211/ieee80211_i.h4
2 files changed, 53 insertions, 0 deletions
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
378int 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
378void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) 427void 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
1613ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, 1613ieee80211_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);
1616int __must_check
1617ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
1618 const struct cfg80211_chan_def *chandef,
1619 u32 *changed);
1616void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); 1620void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
1617void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata); 1621void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata);
1618void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, 1622void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,