aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/chan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/chan.c')
-rw-r--r--net/mac80211/chan.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 03e8d2e3270e..3a4764b2869e 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -410,6 +410,64 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
410 return ret; 410 return ret;
411} 411}
412 412
413int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
414 const struct cfg80211_chan_def *chandef,
415 u32 *changed)
416{
417 struct ieee80211_local *local = sdata->local;
418 struct ieee80211_chanctx_conf *conf;
419 struct ieee80211_chanctx *ctx;
420 int ret;
421 u32 chanctx_changed = 0;
422
423 /* should never be called if not performing a channel switch. */
424 if (WARN_ON(!sdata->vif.csa_active))
425 return -EINVAL;
426
427 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
428 IEEE80211_CHAN_DISABLED))
429 return -EINVAL;
430
431 mutex_lock(&local->chanctx_mtx);
432 conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
433 lockdep_is_held(&local->chanctx_mtx));
434 if (!conf) {
435 ret = -EINVAL;
436 goto out;
437 }
438
439 ctx = container_of(conf, struct ieee80211_chanctx, conf);
440 if (ctx->refcount != 1) {
441 ret = -EINVAL;
442 goto out;
443 }
444
445 if (sdata->vif.bss_conf.chandef.width != chandef->width) {
446 chanctx_changed = IEEE80211_CHANCTX_CHANGE_WIDTH;
447 *changed |= BSS_CHANGED_BANDWIDTH;
448 }
449
450 sdata->vif.bss_conf.chandef = *chandef;
451 ctx->conf.def = *chandef;
452
453 chanctx_changed |= IEEE80211_CHANCTX_CHANGE_CHANNEL;
454 drv_change_chanctx(local, ctx, chanctx_changed);
455
456 if (!local->use_chanctx) {
457 local->_oper_chandef = *chandef;
458 ieee80211_hw_config(local, 0);
459 }
460
461 ieee80211_recalc_chanctx_chantype(local, ctx);
462 ieee80211_recalc_smps_chanctx(local, ctx);
463 ieee80211_recalc_radar_chanctx(local, ctx);
464
465 ret = 0;
466 out:
467 mutex_unlock(&local->chanctx_mtx);
468 return ret;
469}
470
413int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, 471int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
414 const struct cfg80211_chan_def *chandef, 472 const struct cfg80211_chan_def *chandef,
415 u32 *changed) 473 u32 *changed)