aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/mac80211.h4
-rw-r--r--net/mac80211/chan.c49
-rw-r--r--net/mac80211/ieee80211_i.h4
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 */
219enum ieee80211_bss_change { 222enum 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
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,