Linux Audio

Check our new training course

Loading...
v5.14.15
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * mac80211 - channel management
   4 * Copyright 2020 - 2021 Intel Corporation
   5 */
   6
   7#include <linux/nl80211.h>
   8#include <linux/export.h>
   9#include <linux/rtnetlink.h>
  10#include <net/cfg80211.h>
  11#include "ieee80211_i.h"
  12#include "driver-ops.h"
  13#include "rate.h"
  14
  15static int ieee80211_chanctx_num_assigned(struct ieee80211_local *local,
  16					  struct ieee80211_chanctx *ctx)
  17{
  18	struct ieee80211_sub_if_data *sdata;
  19	int num = 0;
  20
  21	lockdep_assert_held(&local->chanctx_mtx);
  22
  23	list_for_each_entry(sdata, &ctx->assigned_vifs, assigned_chanctx_list)
  24		num++;
  25
  26	return num;
  27}
  28
  29static int ieee80211_chanctx_num_reserved(struct ieee80211_local *local,
  30					  struct ieee80211_chanctx *ctx)
  31{
  32	struct ieee80211_sub_if_data *sdata;
  33	int num = 0;
  34
  35	lockdep_assert_held(&local->chanctx_mtx);
  36
  37	list_for_each_entry(sdata, &ctx->reserved_vifs, reserved_chanctx_list)
  38		num++;
  39
  40	return num;
  41}
  42
  43int ieee80211_chanctx_refcount(struct ieee80211_local *local,
  44			       struct ieee80211_chanctx *ctx)
  45{
  46	return ieee80211_chanctx_num_assigned(local, ctx) +
  47	       ieee80211_chanctx_num_reserved(local, ctx);
  48}
  49
  50static int ieee80211_num_chanctx(struct ieee80211_local *local)
  51{
  52	struct ieee80211_chanctx *ctx;
  53	int num = 0;
  54
  55	lockdep_assert_held(&local->chanctx_mtx);
  56
  57	list_for_each_entry(ctx, &local->chanctx_list, list)
  58		num++;
  59
  60	return num;
  61}
  62
  63static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local)
  64{
  65	lockdep_assert_held(&local->chanctx_mtx);
  66	return ieee80211_num_chanctx(local) < ieee80211_max_num_channels(local);
  67}
  68
  69static struct ieee80211_chanctx *
  70ieee80211_vif_get_chanctx(struct ieee80211_sub_if_data *sdata)
  71{
  72	struct ieee80211_local *local __maybe_unused = sdata->local;
  73	struct ieee80211_chanctx_conf *conf;
  74
  75	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
  76					 lockdep_is_held(&local->chanctx_mtx));
  77	if (!conf)
  78		return NULL;
  79
  80	return container_of(conf, struct ieee80211_chanctx, conf);
  81}
  82
  83static const struct cfg80211_chan_def *
  84ieee80211_chanctx_reserved_chandef(struct ieee80211_local *local,
  85				   struct ieee80211_chanctx *ctx,
  86				   const struct cfg80211_chan_def *compat)
  87{
  88	struct ieee80211_sub_if_data *sdata;
  89
  90	lockdep_assert_held(&local->chanctx_mtx);
  91
  92	list_for_each_entry(sdata, &ctx->reserved_vifs,
  93			    reserved_chanctx_list) {
  94		if (!compat)
  95			compat = &sdata->reserved_chandef;
  96
  97		compat = cfg80211_chandef_compatible(&sdata->reserved_chandef,
  98						     compat);
  99		if (!compat)
 100			break;
 101	}
 102
 103	return compat;
 104}
 105
 106static const struct cfg80211_chan_def *
 107ieee80211_chanctx_non_reserved_chandef(struct ieee80211_local *local,
 108				       struct ieee80211_chanctx *ctx,
 109				       const struct cfg80211_chan_def *compat)
 110{
 111	struct ieee80211_sub_if_data *sdata;
 112
 113	lockdep_assert_held(&local->chanctx_mtx);
 114
 115	list_for_each_entry(sdata, &ctx->assigned_vifs,
 116			    assigned_chanctx_list) {
 117		if (sdata->reserved_chanctx != NULL)
 118			continue;
 119
 120		if (!compat)
 121			compat = &sdata->vif.bss_conf.chandef;
 122
 123		compat = cfg80211_chandef_compatible(
 124				&sdata->vif.bss_conf.chandef, compat);
 125		if (!compat)
 126			break;
 127	}
 128
 129	return compat;
 130}
 131
 132static const struct cfg80211_chan_def *
 133ieee80211_chanctx_combined_chandef(struct ieee80211_local *local,
 134				   struct ieee80211_chanctx *ctx,
 135				   const struct cfg80211_chan_def *compat)
 136{
 137	lockdep_assert_held(&local->chanctx_mtx);
 138
 139	compat = ieee80211_chanctx_reserved_chandef(local, ctx, compat);
 140	if (!compat)
 141		return NULL;
 142
 143	compat = ieee80211_chanctx_non_reserved_chandef(local, ctx, compat);
 144	if (!compat)
 145		return NULL;
 146
 147	return compat;
 148}
 149
 150static bool
 151ieee80211_chanctx_can_reserve_chandef(struct ieee80211_local *local,
 152				      struct ieee80211_chanctx *ctx,
 153				      const struct cfg80211_chan_def *def)
 154{
 155	lockdep_assert_held(&local->chanctx_mtx);
 156
 157	if (ieee80211_chanctx_combined_chandef(local, ctx, def))
 158		return true;
 159
 160	if (!list_empty(&ctx->reserved_vifs) &&
 161	    ieee80211_chanctx_reserved_chandef(local, ctx, def))
 162		return true;
 163
 164	return false;
 165}
 166
 167static struct ieee80211_chanctx *
 168ieee80211_find_reservation_chanctx(struct ieee80211_local *local,
 169				   const struct cfg80211_chan_def *chandef,
 170				   enum ieee80211_chanctx_mode mode)
 171{
 172	struct ieee80211_chanctx *ctx;
 173
 174	lockdep_assert_held(&local->chanctx_mtx);
 175
 176	if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
 177		return NULL;
 178
 179	list_for_each_entry(ctx, &local->chanctx_list, list) {
 180		if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
 181			continue;
 182
 183		if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
 184			continue;
 185
 186		if (!ieee80211_chanctx_can_reserve_chandef(local, ctx,
 187							   chandef))
 188			continue;
 189
 190		return ctx;
 191	}
 192
 193	return NULL;
 194}
 195
 196static enum nl80211_chan_width ieee80211_get_sta_bw(struct sta_info *sta)
 197{
 198	enum ieee80211_sta_rx_bandwidth width = ieee80211_sta_cap_rx_bw(sta);
 199
 200	switch (width) {
 201	case IEEE80211_STA_RX_BW_20:
 202		if (sta->sta.ht_cap.ht_supported)
 203			return NL80211_CHAN_WIDTH_20;
 204		else
 205			return NL80211_CHAN_WIDTH_20_NOHT;
 206	case IEEE80211_STA_RX_BW_40:
 207		return NL80211_CHAN_WIDTH_40;
 208	case IEEE80211_STA_RX_BW_80:
 209		return NL80211_CHAN_WIDTH_80;
 210	case IEEE80211_STA_RX_BW_160:
 211		/*
 212		 * This applied for both 160 and 80+80. since we use
 213		 * the returned value to consider degradation of
 214		 * ctx->conf.min_def, we have to make sure to take
 215		 * the bigger one (NL80211_CHAN_WIDTH_160).
 216		 * Otherwise we might try degrading even when not
 217		 * needed, as the max required sta_bw returned (80+80)
 218		 * might be smaller than the configured bw (160).
 219		 */
 220		return NL80211_CHAN_WIDTH_160;
 221	default:
 222		WARN_ON(1);
 223		return NL80211_CHAN_WIDTH_20;
 224	}
 225}
 226
 227static enum nl80211_chan_width
 228ieee80211_get_max_required_bw(struct ieee80211_sub_if_data *sdata)
 229{
 230	enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
 231	struct sta_info *sta;
 232
 233	rcu_read_lock();
 234	list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) {
 235		if (sdata != sta->sdata &&
 236		    !(sta->sdata->bss && sta->sdata->bss == sdata->bss))
 237			continue;
 238
 239		max_bw = max(max_bw, ieee80211_get_sta_bw(sta));
 
 
 
 240	}
 241	rcu_read_unlock();
 242
 243	return max_bw;
 244}
 245
 246static enum nl80211_chan_width
 247ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
 248				      struct ieee80211_chanctx_conf *conf)
 249{
 250	struct ieee80211_sub_if_data *sdata;
 251	enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
 252
 253	rcu_read_lock();
 254	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 255		struct ieee80211_vif *vif = &sdata->vif;
 256		enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20_NOHT;
 257
 258		if (!ieee80211_sdata_running(sdata))
 259			continue;
 260
 261		if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
 262			continue;
 263
 264		switch (vif->type) {
 265		case NL80211_IFTYPE_AP:
 266		case NL80211_IFTYPE_AP_VLAN:
 267			width = ieee80211_get_max_required_bw(sdata);
 268			break;
 269		case NL80211_IFTYPE_STATION:
 270			/*
 271			 * The ap's sta->bandwidth is not set yet at this
 272			 * point, so take the width from the chandef, but
 273			 * account also for TDLS peers
 274			 */
 275			width = max(vif->bss_conf.chandef.width,
 276				    ieee80211_get_max_required_bw(sdata));
 277			break;
 278		case NL80211_IFTYPE_P2P_DEVICE:
 279		case NL80211_IFTYPE_NAN:
 280			continue;
 281		case NL80211_IFTYPE_ADHOC:
 
 282		case NL80211_IFTYPE_MESH_POINT:
 283		case NL80211_IFTYPE_OCB:
 284			width = vif->bss_conf.chandef.width;
 285			break;
 286		case NL80211_IFTYPE_WDS:
 287		case NL80211_IFTYPE_UNSPECIFIED:
 288		case NUM_NL80211_IFTYPES:
 289		case NL80211_IFTYPE_MONITOR:
 290		case NL80211_IFTYPE_P2P_CLIENT:
 291		case NL80211_IFTYPE_P2P_GO:
 292			WARN_ON_ONCE(1);
 293		}
 294		max_bw = max(max_bw, width);
 295	}
 296
 297	/* use the configured bandwidth in case of monitor interface */
 298	sdata = rcu_dereference(local->monitor_sdata);
 299	if (sdata && rcu_access_pointer(sdata->vif.chanctx_conf) == conf)
 300		max_bw = max(max_bw, conf->def.width);
 301
 302	rcu_read_unlock();
 303
 304	return max_bw;
 305}
 306
 307/*
 308 * recalc the min required chan width of the channel context, which is
 309 * the max of min required widths of all the interfaces bound to this
 310 * channel context.
 311 */
 312static u32 _ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
 313					     struct ieee80211_chanctx *ctx)
 314{
 315	enum nl80211_chan_width max_bw;
 316	struct cfg80211_chan_def min_def;
 317
 318	lockdep_assert_held(&local->chanctx_mtx);
 319
 320	/* don't optimize non-20MHz based and radar_enabled confs */
 321	if (ctx->conf.def.width == NL80211_CHAN_WIDTH_5 ||
 322	    ctx->conf.def.width == NL80211_CHAN_WIDTH_10 ||
 323	    ctx->conf.def.width == NL80211_CHAN_WIDTH_1 ||
 324	    ctx->conf.def.width == NL80211_CHAN_WIDTH_2 ||
 325	    ctx->conf.def.width == NL80211_CHAN_WIDTH_4 ||
 326	    ctx->conf.def.width == NL80211_CHAN_WIDTH_8 ||
 327	    ctx->conf.def.width == NL80211_CHAN_WIDTH_16 ||
 328	    ctx->conf.radar_enabled) {
 329		ctx->conf.min_def = ctx->conf.def;
 330		return 0;
 331	}
 332
 333	max_bw = ieee80211_get_chanctx_max_required_bw(local, &ctx->conf);
 334
 335	/* downgrade chandef up to max_bw */
 336	min_def = ctx->conf.def;
 337	while (min_def.width > max_bw)
 338		ieee80211_chandef_downgrade(&min_def);
 339
 340	if (cfg80211_chandef_identical(&ctx->conf.min_def, &min_def))
 341		return 0;
 342
 343	ctx->conf.min_def = min_def;
 344	if (!ctx->driver_present)
 345		return 0;
 346
 347	return IEEE80211_CHANCTX_CHANGE_MIN_WIDTH;
 348}
 349
 350/* calling this function is assuming that station vif is updated to
 351 * lates changes by calling ieee80211_vif_update_chandef
 352 */
 353static void ieee80211_chan_bw_change(struct ieee80211_local *local,
 354				     struct ieee80211_chanctx *ctx,
 355				     bool narrowed)
 356{
 357	struct sta_info *sta;
 358	struct ieee80211_supported_band *sband =
 359		local->hw.wiphy->bands[ctx->conf.def.chan->band];
 360
 361	rcu_read_lock();
 362	list_for_each_entry_rcu(sta, &local->sta_list,
 363				list) {
 364		enum ieee80211_sta_rx_bandwidth new_sta_bw;
 365
 366		if (!ieee80211_sdata_running(sta->sdata))
 367			continue;
 368
 369		if (rcu_access_pointer(sta->sdata->vif.chanctx_conf) !=
 370		    &ctx->conf)
 371			continue;
 372
 373		new_sta_bw = ieee80211_sta_cur_vht_bw(sta);
 374
 375		/* nothing change */
 376		if (new_sta_bw == sta->sta.bandwidth)
 377			continue;
 378
 379		/* vif changed to narrow BW and narrow BW for station wasn't
 380		 * requested or vise versa */
 381		if ((new_sta_bw < sta->sta.bandwidth) == !narrowed)
 382			continue;
 383
 384		sta->sta.bandwidth = new_sta_bw;
 385		rate_control_rate_update(local, sband, sta,
 386					 IEEE80211_RC_BW_CHANGED);
 387	}
 388	rcu_read_unlock();
 389}
 390
 391/*
 392 * recalc the min required chan width of the channel context, which is
 393 * the max of min required widths of all the interfaces bound to this
 394 * channel context.
 395 */
 396void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
 397				      struct ieee80211_chanctx *ctx)
 398{
 399	u32 changed = _ieee80211_recalc_chanctx_min_def(local, ctx);
 400
 401	if (!changed)
 402		return;
 403
 404	/* check is BW narrowed */
 405	ieee80211_chan_bw_change(local, ctx, true);
 406
 407	drv_change_chanctx(local, ctx, changed);
 408
 409	/* check is BW wider */
 410	ieee80211_chan_bw_change(local, ctx, false);
 411}
 412
 413static void ieee80211_change_chanctx(struct ieee80211_local *local,
 414				     struct ieee80211_chanctx *ctx,
 415				     struct ieee80211_chanctx *old_ctx,
 416				     const struct cfg80211_chan_def *chandef)
 417{
 418	u32 changed;
 419
 420	/* expected to handle only 20/40/80/160 channel widths */
 421	switch (chandef->width) {
 422	case NL80211_CHAN_WIDTH_20_NOHT:
 423	case NL80211_CHAN_WIDTH_20:
 424	case NL80211_CHAN_WIDTH_40:
 425	case NL80211_CHAN_WIDTH_80:
 426	case NL80211_CHAN_WIDTH_80P80:
 427	case NL80211_CHAN_WIDTH_160:
 428		break;
 429	default:
 430		WARN_ON(1);
 431	}
 432
 433	/* Check maybe BW narrowed - we do this _before_ calling recalc_chanctx_min_def
 434	 * due to maybe not returning from it, e.g in case new context was added
 435	 * first time with all parameters up to date.
 436	 */
 437	ieee80211_chan_bw_change(local, old_ctx, true);
 438
 439	if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) {
 440		ieee80211_recalc_chanctx_min_def(local, ctx);
 441		return;
 442	}
 443
 444	WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
 445
 446	ctx->conf.def = *chandef;
 447
 448	/* check if min chanctx also changed */
 449	changed = IEEE80211_CHANCTX_CHANGE_WIDTH |
 450		  _ieee80211_recalc_chanctx_min_def(local, ctx);
 451	drv_change_chanctx(local, ctx, changed);
 452
 453	if (!local->use_chanctx) {
 454		local->_oper_chandef = *chandef;
 455		ieee80211_hw_config(local, 0);
 456	}
 457
 458	/* check is BW wider */
 459	ieee80211_chan_bw_change(local, old_ctx, false);
 460}
 461
 462static struct ieee80211_chanctx *
 463ieee80211_find_chanctx(struct ieee80211_local *local,
 464		       const struct cfg80211_chan_def *chandef,
 465		       enum ieee80211_chanctx_mode mode)
 466{
 467	struct ieee80211_chanctx *ctx;
 468
 469	lockdep_assert_held(&local->chanctx_mtx);
 470
 471	if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
 472		return NULL;
 473
 474	list_for_each_entry(ctx, &local->chanctx_list, list) {
 475		const struct cfg80211_chan_def *compat;
 476
 477		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACE_NONE)
 478			continue;
 479
 480		if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
 481			continue;
 482
 483		compat = cfg80211_chandef_compatible(&ctx->conf.def, chandef);
 484		if (!compat)
 485			continue;
 486
 487		compat = ieee80211_chanctx_reserved_chandef(local, ctx,
 488							    compat);
 489		if (!compat)
 490			continue;
 491
 492		ieee80211_change_chanctx(local, ctx, ctx, compat);
 493
 494		return ctx;
 495	}
 496
 497	return NULL;
 498}
 499
 500bool ieee80211_is_radar_required(struct ieee80211_local *local)
 501{
 502	struct ieee80211_sub_if_data *sdata;
 503
 504	lockdep_assert_held(&local->mtx);
 505
 506	rcu_read_lock();
 507	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 508		if (sdata->radar_required) {
 509			rcu_read_unlock();
 510			return true;
 511		}
 512	}
 513	rcu_read_unlock();
 514
 515	return false;
 516}
 517
 518static bool
 519ieee80211_chanctx_radar_required(struct ieee80211_local *local,
 520				 struct ieee80211_chanctx *ctx)
 521{
 522	struct ieee80211_chanctx_conf *conf = &ctx->conf;
 523	struct ieee80211_sub_if_data *sdata;
 524	bool required = false;
 525
 526	lockdep_assert_held(&local->chanctx_mtx);
 527	lockdep_assert_held(&local->mtx);
 528
 529	rcu_read_lock();
 530	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 531		if (!ieee80211_sdata_running(sdata))
 532			continue;
 533		if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
 534			continue;
 535		if (!sdata->radar_required)
 536			continue;
 537
 538		required = true;
 539		break;
 540	}
 541	rcu_read_unlock();
 542
 543	return required;
 544}
 545
 546static struct ieee80211_chanctx *
 547ieee80211_alloc_chanctx(struct ieee80211_local *local,
 548			const struct cfg80211_chan_def *chandef,
 549			enum ieee80211_chanctx_mode mode)
 550{
 551	struct ieee80211_chanctx *ctx;
 552
 553	lockdep_assert_held(&local->chanctx_mtx);
 554
 555	ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL);
 556	if (!ctx)
 557		return NULL;
 558
 559	INIT_LIST_HEAD(&ctx->assigned_vifs);
 560	INIT_LIST_HEAD(&ctx->reserved_vifs);
 561	ctx->conf.def = *chandef;
 562	ctx->conf.rx_chains_static = 1;
 563	ctx->conf.rx_chains_dynamic = 1;
 564	ctx->mode = mode;
 565	ctx->conf.radar_enabled = false;
 566	ieee80211_recalc_chanctx_min_def(local, ctx);
 567
 568	return ctx;
 569}
 570
 571static int ieee80211_add_chanctx(struct ieee80211_local *local,
 572				 struct ieee80211_chanctx *ctx)
 573{
 574	u32 changed;
 575	int err;
 576
 577	lockdep_assert_held(&local->mtx);
 578	lockdep_assert_held(&local->chanctx_mtx);
 579
 580	if (!local->use_chanctx)
 581		local->hw.conf.radar_enabled = ctx->conf.radar_enabled;
 582
 583	/* turn idle off *before* setting channel -- some drivers need that */
 584	changed = ieee80211_idle_off(local);
 585	if (changed)
 586		ieee80211_hw_config(local, changed);
 587
 588	if (!local->use_chanctx) {
 589		local->_oper_chandef = ctx->conf.def;
 590		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 591	} else {
 592		err = drv_add_chanctx(local, ctx);
 593		if (err) {
 594			ieee80211_recalc_idle(local);
 595			return err;
 596		}
 597	}
 598
 599	return 0;
 600}
 601
 602static struct ieee80211_chanctx *
 603ieee80211_new_chanctx(struct ieee80211_local *local,
 604		      const struct cfg80211_chan_def *chandef,
 605		      enum ieee80211_chanctx_mode mode)
 606{
 607	struct ieee80211_chanctx *ctx;
 608	int err;
 609
 610	lockdep_assert_held(&local->mtx);
 611	lockdep_assert_held(&local->chanctx_mtx);
 612
 613	ctx = ieee80211_alloc_chanctx(local, chandef, mode);
 614	if (!ctx)
 615		return ERR_PTR(-ENOMEM);
 616
 617	err = ieee80211_add_chanctx(local, ctx);
 618	if (err) {
 619		kfree(ctx);
 620		return ERR_PTR(err);
 621	}
 622
 623	list_add_rcu(&ctx->list, &local->chanctx_list);
 624	return ctx;
 625}
 626
 627static void ieee80211_del_chanctx(struct ieee80211_local *local,
 628				  struct ieee80211_chanctx *ctx)
 629{
 630	lockdep_assert_held(&local->chanctx_mtx);
 631
 632	if (!local->use_chanctx) {
 633		struct cfg80211_chan_def *chandef = &local->_oper_chandef;
 634		/* S1G doesn't have 20MHz, so get the correct width for the
 635		 * current channel.
 636		 */
 637		if (chandef->chan->band == NL80211_BAND_S1GHZ)
 638			chandef->width =
 639				ieee80211_s1g_channel_width(chandef->chan);
 640		else
 641			chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
 642		chandef->center_freq1 = chandef->chan->center_freq;
 643		chandef->freq1_offset = chandef->chan->freq_offset;
 644		chandef->center_freq2 = 0;
 645
 646		/* NOTE: Disabling radar is only valid here for
 647		 * single channel context. To be sure, check it ...
 648		 */
 649		WARN_ON(local->hw.conf.radar_enabled &&
 650			!list_empty(&local->chanctx_list));
 651
 652		local->hw.conf.radar_enabled = false;
 653
 654		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 655	} else {
 656		drv_remove_chanctx(local, ctx);
 657	}
 658
 659	ieee80211_recalc_idle(local);
 660}
 661
 662static void ieee80211_free_chanctx(struct ieee80211_local *local,
 663				   struct ieee80211_chanctx *ctx)
 664{
 665	lockdep_assert_held(&local->chanctx_mtx);
 666
 667	WARN_ON_ONCE(ieee80211_chanctx_refcount(local, ctx) != 0);
 668
 669	list_del_rcu(&ctx->list);
 670	ieee80211_del_chanctx(local, ctx);
 671	kfree_rcu(ctx, rcu_head);
 672}
 673
 674void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
 675				       struct ieee80211_chanctx *ctx)
 676{
 677	struct ieee80211_chanctx_conf *conf = &ctx->conf;
 678	struct ieee80211_sub_if_data *sdata;
 679	const struct cfg80211_chan_def *compat = NULL;
 680	struct sta_info *sta;
 681
 682	lockdep_assert_held(&local->chanctx_mtx);
 683
 684	rcu_read_lock();
 685	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 686
 687		if (!ieee80211_sdata_running(sdata))
 688			continue;
 689		if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
 690			continue;
 691		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
 692			continue;
 693
 694		if (!compat)
 695			compat = &sdata->vif.bss_conf.chandef;
 696
 697		compat = cfg80211_chandef_compatible(
 698				&sdata->vif.bss_conf.chandef, compat);
 699		if (WARN_ON_ONCE(!compat))
 700			break;
 701	}
 702
 703	/* TDLS peers can sometimes affect the chandef width */
 704	list_for_each_entry_rcu(sta, &local->sta_list, list) {
 705		if (!sta->uploaded ||
 706		    !test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW) ||
 707		    !test_sta_flag(sta, WLAN_STA_AUTHORIZED) ||
 708		    !sta->tdls_chandef.chan)
 709			continue;
 710
 711		compat = cfg80211_chandef_compatible(&sta->tdls_chandef,
 712						     compat);
 713		if (WARN_ON_ONCE(!compat))
 714			break;
 715	}
 716	rcu_read_unlock();
 717
 718	if (!compat)
 719		return;
 720
 721	ieee80211_change_chanctx(local, ctx, ctx, compat);
 722}
 723
 724static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local,
 725					   struct ieee80211_chanctx *chanctx)
 726{
 727	bool radar_enabled;
 728
 729	lockdep_assert_held(&local->chanctx_mtx);
 730	/* for ieee80211_is_radar_required */
 731	lockdep_assert_held(&local->mtx);
 732
 733	radar_enabled = ieee80211_chanctx_radar_required(local, chanctx);
 734
 735	if (radar_enabled == chanctx->conf.radar_enabled)
 736		return;
 737
 738	chanctx->conf.radar_enabled = radar_enabled;
 739
 740	if (!local->use_chanctx) {
 741		local->hw.conf.radar_enabled = chanctx->conf.radar_enabled;
 742		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 743	}
 744
 745	drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR);
 746}
 747
 748static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
 749					struct ieee80211_chanctx *new_ctx)
 750{
 751	struct ieee80211_local *local = sdata->local;
 752	struct ieee80211_chanctx_conf *conf;
 753	struct ieee80211_chanctx *curr_ctx = NULL;
 754	int ret = 0;
 755
 756	if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_NAN))
 757		return -ENOTSUPP;
 758
 759	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
 760					 lockdep_is_held(&local->chanctx_mtx));
 761
 762	if (conf) {
 763		curr_ctx = container_of(conf, struct ieee80211_chanctx, conf);
 764
 765		drv_unassign_vif_chanctx(local, sdata, curr_ctx);
 766		conf = NULL;
 767		list_del(&sdata->assigned_chanctx_list);
 768	}
 769
 770	if (new_ctx) {
 771		ret = drv_assign_vif_chanctx(local, sdata, new_ctx);
 772		if (ret)
 773			goto out;
 774
 775		conf = &new_ctx->conf;
 776		list_add(&sdata->assigned_chanctx_list,
 777			 &new_ctx->assigned_vifs);
 778	}
 779
 780out:
 781	rcu_assign_pointer(sdata->vif.chanctx_conf, conf);
 782
 783	sdata->vif.bss_conf.idle = !conf;
 784
 785	if (curr_ctx && ieee80211_chanctx_num_assigned(local, curr_ctx) > 0) {
 786		ieee80211_recalc_chanctx_chantype(local, curr_ctx);
 787		ieee80211_recalc_smps_chanctx(local, curr_ctx);
 788		ieee80211_recalc_radar_chanctx(local, curr_ctx);
 789		ieee80211_recalc_chanctx_min_def(local, curr_ctx);
 790	}
 791
 792	if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) {
 793		ieee80211_recalc_txpower(sdata, false);
 794		ieee80211_recalc_chanctx_min_def(local, new_ctx);
 795	}
 796
 797	if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
 798	    sdata->vif.type != NL80211_IFTYPE_MONITOR)
 799		ieee80211_bss_info_change_notify(sdata,
 800						 BSS_CHANGED_IDLE);
 801
 802	ieee80211_check_fast_xmit_iface(sdata);
 803
 804	return ret;
 805}
 806
 807void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
 808				   struct ieee80211_chanctx *chanctx)
 809{
 810	struct ieee80211_sub_if_data *sdata;
 811	u8 rx_chains_static, rx_chains_dynamic;
 812
 813	lockdep_assert_held(&local->chanctx_mtx);
 814
 815	rx_chains_static = 1;
 816	rx_chains_dynamic = 1;
 817
 818	rcu_read_lock();
 819	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 820		u8 needed_static, needed_dynamic;
 821
 822		if (!ieee80211_sdata_running(sdata))
 823			continue;
 824
 825		if (rcu_access_pointer(sdata->vif.chanctx_conf) !=
 826						&chanctx->conf)
 827			continue;
 828
 829		switch (sdata->vif.type) {
 830		case NL80211_IFTYPE_P2P_DEVICE:
 831		case NL80211_IFTYPE_NAN:
 832			continue;
 833		case NL80211_IFTYPE_STATION:
 834			if (!sdata->u.mgd.associated)
 835				continue;
 836			break;
 837		case NL80211_IFTYPE_AP_VLAN:
 838			continue;
 839		case NL80211_IFTYPE_AP:
 840		case NL80211_IFTYPE_ADHOC:
 
 841		case NL80211_IFTYPE_MESH_POINT:
 842		case NL80211_IFTYPE_OCB:
 843			break;
 844		default:
 845			WARN_ON_ONCE(1);
 846		}
 847
 848		switch (sdata->smps_mode) {
 849		default:
 850			WARN_ONCE(1, "Invalid SMPS mode %d\n",
 851				  sdata->smps_mode);
 852			fallthrough;
 853		case IEEE80211_SMPS_OFF:
 854			needed_static = sdata->needed_rx_chains;
 855			needed_dynamic = sdata->needed_rx_chains;
 856			break;
 857		case IEEE80211_SMPS_DYNAMIC:
 858			needed_static = 1;
 859			needed_dynamic = sdata->needed_rx_chains;
 860			break;
 861		case IEEE80211_SMPS_STATIC:
 862			needed_static = 1;
 863			needed_dynamic = 1;
 864			break;
 865		}
 866
 867		rx_chains_static = max(rx_chains_static, needed_static);
 868		rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic);
 869	}
 870
 871	/* Disable SMPS for the monitor interface */
 872	sdata = rcu_dereference(local->monitor_sdata);
 873	if (sdata &&
 874	    rcu_access_pointer(sdata->vif.chanctx_conf) == &chanctx->conf)
 875		rx_chains_dynamic = rx_chains_static = local->rx_chains;
 876
 877	rcu_read_unlock();
 878
 879	if (!local->use_chanctx) {
 880		if (rx_chains_static > 1)
 881			local->smps_mode = IEEE80211_SMPS_OFF;
 882		else if (rx_chains_dynamic > 1)
 883			local->smps_mode = IEEE80211_SMPS_DYNAMIC;
 884		else
 885			local->smps_mode = IEEE80211_SMPS_STATIC;
 886		ieee80211_hw_config(local, 0);
 887	}
 888
 889	if (rx_chains_static == chanctx->conf.rx_chains_static &&
 890	    rx_chains_dynamic == chanctx->conf.rx_chains_dynamic)
 891		return;
 892
 893	chanctx->conf.rx_chains_static = rx_chains_static;
 894	chanctx->conf.rx_chains_dynamic = rx_chains_dynamic;
 895	drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS);
 896}
 897
 898static void
 899__ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
 900				      bool clear)
 901{
 902	struct ieee80211_local *local __maybe_unused = sdata->local;
 903	struct ieee80211_sub_if_data *vlan;
 904	struct ieee80211_chanctx_conf *conf;
 905
 906	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP))
 907		return;
 908
 909	lockdep_assert_held(&local->mtx);
 910
 911	/* Check that conf exists, even when clearing this function
 912	 * must be called with the AP's channel context still there
 913	 * as it would otherwise cause VLANs to have an invalid
 914	 * channel context pointer for a while, possibly pointing
 915	 * to a channel context that has already been freed.
 916	 */
 917	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
 918					 lockdep_is_held(&local->chanctx_mtx));
 919	WARN_ON(!conf);
 920
 921	if (clear)
 922		conf = NULL;
 923
 924	list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
 925		rcu_assign_pointer(vlan->vif.chanctx_conf, conf);
 926}
 927
 928void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
 929					 bool clear)
 930{
 931	struct ieee80211_local *local = sdata->local;
 932
 933	mutex_lock(&local->chanctx_mtx);
 934
 935	__ieee80211_vif_copy_chanctx_to_vlans(sdata, clear);
 936
 937	mutex_unlock(&local->chanctx_mtx);
 938}
 939
 940int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata)
 941{
 942	struct ieee80211_chanctx *ctx = sdata->reserved_chanctx;
 943
 944	lockdep_assert_held(&sdata->local->chanctx_mtx);
 945
 946	if (WARN_ON(!ctx))
 947		return -EINVAL;
 948
 949	list_del(&sdata->reserved_chanctx_list);
 950	sdata->reserved_chanctx = NULL;
 951
 952	if (ieee80211_chanctx_refcount(sdata->local, ctx) == 0) {
 953		if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
 954			if (WARN_ON(!ctx->replace_ctx))
 955				return -EINVAL;
 956
 957			WARN_ON(ctx->replace_ctx->replace_state !=
 958			        IEEE80211_CHANCTX_WILL_BE_REPLACED);
 959			WARN_ON(ctx->replace_ctx->replace_ctx != ctx);
 960
 961			ctx->replace_ctx->replace_ctx = NULL;
 962			ctx->replace_ctx->replace_state =
 963					IEEE80211_CHANCTX_REPLACE_NONE;
 964
 965			list_del_rcu(&ctx->list);
 966			kfree_rcu(ctx, rcu_head);
 967		} else {
 968			ieee80211_free_chanctx(sdata->local, ctx);
 969		}
 970	}
 971
 972	return 0;
 973}
 974
 975int ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata,
 976				  const struct cfg80211_chan_def *chandef,
 977				  enum ieee80211_chanctx_mode mode,
 978				  bool radar_required)
 979{
 980	struct ieee80211_local *local = sdata->local;
 981	struct ieee80211_chanctx *new_ctx, *curr_ctx, *ctx;
 982
 983	lockdep_assert_held(&local->chanctx_mtx);
 984
 985	curr_ctx = ieee80211_vif_get_chanctx(sdata);
 986	if (curr_ctx && local->use_chanctx && !local->ops->switch_vif_chanctx)
 987		return -ENOTSUPP;
 988
 989	new_ctx = ieee80211_find_reservation_chanctx(local, chandef, mode);
 990	if (!new_ctx) {
 991		if (ieee80211_can_create_new_chanctx(local)) {
 992			new_ctx = ieee80211_new_chanctx(local, chandef, mode);
 993			if (IS_ERR(new_ctx))
 994				return PTR_ERR(new_ctx);
 995		} else {
 996			if (!curr_ctx ||
 997			    (curr_ctx->replace_state ==
 998			     IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
 999			    !list_empty(&curr_ctx->reserved_vifs)) {
1000				/*
1001				 * Another vif already requested this context
1002				 * for a reservation. Find another one hoping
1003				 * all vifs assigned to it will also switch
1004				 * soon enough.
1005				 *
1006				 * TODO: This needs a little more work as some
1007				 * cases (more than 2 chanctx capable devices)
1008				 * may fail which could otherwise succeed
1009				 * provided some channel context juggling was
1010				 * performed.
1011				 *
1012				 * Consider ctx1..3, vif1..6, each ctx has 2
1013				 * vifs. vif1 and vif2 from ctx1 request new
1014				 * different chandefs starting 2 in-place
1015				 * reserations with ctx4 and ctx5 replacing
1016				 * ctx1 and ctx2 respectively. Next vif5 and
1017				 * vif6 from ctx3 reserve ctx4. If vif3 and
1018				 * vif4 remain on ctx2 as they are then this
1019				 * fails unless `replace_ctx` from ctx5 is
1020				 * replaced with ctx3.
1021				 */
1022				list_for_each_entry(ctx, &local->chanctx_list,
1023						    list) {
1024					if (ctx->replace_state !=
1025					    IEEE80211_CHANCTX_REPLACE_NONE)
1026						continue;
1027
1028					if (!list_empty(&ctx->reserved_vifs))
1029						continue;
1030
1031					curr_ctx = ctx;
1032					break;
1033				}
1034			}
1035
1036			/*
1037			 * If that's true then all available contexts already
1038			 * have reservations and cannot be used.
1039			 */
1040			if (!curr_ctx ||
1041			    (curr_ctx->replace_state ==
1042			     IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
1043			    !list_empty(&curr_ctx->reserved_vifs))
1044				return -EBUSY;
1045
1046			new_ctx = ieee80211_alloc_chanctx(local, chandef, mode);
1047			if (!new_ctx)
1048				return -ENOMEM;
1049
1050			new_ctx->replace_ctx = curr_ctx;
1051			new_ctx->replace_state =
1052					IEEE80211_CHANCTX_REPLACES_OTHER;
1053
1054			curr_ctx->replace_ctx = new_ctx;
1055			curr_ctx->replace_state =
1056					IEEE80211_CHANCTX_WILL_BE_REPLACED;
1057
1058			list_add_rcu(&new_ctx->list, &local->chanctx_list);
1059		}
1060	}
1061
1062	list_add(&sdata->reserved_chanctx_list, &new_ctx->reserved_vifs);
1063	sdata->reserved_chanctx = new_ctx;
1064	sdata->reserved_chandef = *chandef;
1065	sdata->reserved_radar_required = radar_required;
1066	sdata->reserved_ready = false;
1067
1068	return 0;
1069}
1070
1071static void
1072ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata)
1073{
1074	switch (sdata->vif.type) {
1075	case NL80211_IFTYPE_ADHOC:
1076	case NL80211_IFTYPE_AP:
1077	case NL80211_IFTYPE_MESH_POINT:
1078	case NL80211_IFTYPE_OCB:
1079		ieee80211_queue_work(&sdata->local->hw,
1080				     &sdata->csa_finalize_work);
1081		break;
1082	case NL80211_IFTYPE_STATION:
1083		ieee80211_queue_work(&sdata->local->hw,
1084				     &sdata->u.mgd.chswitch_work);
1085		break;
1086	case NL80211_IFTYPE_UNSPECIFIED:
1087	case NL80211_IFTYPE_AP_VLAN:
1088	case NL80211_IFTYPE_WDS:
1089	case NL80211_IFTYPE_MONITOR:
1090	case NL80211_IFTYPE_P2P_CLIENT:
1091	case NL80211_IFTYPE_P2P_GO:
1092	case NL80211_IFTYPE_P2P_DEVICE:
1093	case NL80211_IFTYPE_NAN:
1094	case NUM_NL80211_IFTYPES:
1095		WARN_ON(1);
1096		break;
1097	}
1098}
1099
1100static void
1101ieee80211_vif_update_chandef(struct ieee80211_sub_if_data *sdata,
1102			     const struct cfg80211_chan_def *chandef)
1103{
1104	struct ieee80211_sub_if_data *vlan;
1105
1106	sdata->vif.bss_conf.chandef = *chandef;
1107
1108	if (sdata->vif.type != NL80211_IFTYPE_AP)
1109		return;
1110
1111	list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
1112		vlan->vif.bss_conf.chandef = *chandef;
1113}
1114
1115static int
1116ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
1117{
1118	struct ieee80211_local *local = sdata->local;
1119	struct ieee80211_vif_chanctx_switch vif_chsw[1] = {};
1120	struct ieee80211_chanctx *old_ctx, *new_ctx;
1121	const struct cfg80211_chan_def *chandef;
1122	u32 changed = 0;
1123	int err;
1124
1125	lockdep_assert_held(&local->mtx);
1126	lockdep_assert_held(&local->chanctx_mtx);
1127
1128	new_ctx = sdata->reserved_chanctx;
1129	old_ctx = ieee80211_vif_get_chanctx(sdata);
1130
1131	if (WARN_ON(!sdata->reserved_ready))
1132		return -EBUSY;
1133
1134	if (WARN_ON(!new_ctx))
1135		return -EINVAL;
1136
1137	if (WARN_ON(!old_ctx))
1138		return -EINVAL;
1139
1140	if (WARN_ON(new_ctx->replace_state ==
1141		    IEEE80211_CHANCTX_REPLACES_OTHER))
1142		return -EINVAL;
1143
1144	chandef = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
1145				&sdata->reserved_chandef);
1146	if (WARN_ON(!chandef))
1147		return -EINVAL;
1148
1149	if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width)
1150		changed = BSS_CHANGED_BANDWIDTH;
1151
1152	ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
1153
1154	ieee80211_change_chanctx(local, new_ctx, old_ctx, chandef);
1155
1156	vif_chsw[0].vif = &sdata->vif;
1157	vif_chsw[0].old_ctx = &old_ctx->conf;
1158	vif_chsw[0].new_ctx = &new_ctx->conf;
1159
1160	list_del(&sdata->reserved_chanctx_list);
1161	sdata->reserved_chanctx = NULL;
1162
1163	err = drv_switch_vif_chanctx(local, vif_chsw, 1,
1164				     CHANCTX_SWMODE_REASSIGN_VIF);
1165	if (err) {
1166		if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
1167			ieee80211_free_chanctx(local, new_ctx);
1168
1169		goto out;
1170	}
1171
1172	list_move(&sdata->assigned_chanctx_list, &new_ctx->assigned_vifs);
1173	rcu_assign_pointer(sdata->vif.chanctx_conf, &new_ctx->conf);
1174
1175	if (sdata->vif.type == NL80211_IFTYPE_AP)
1176		__ieee80211_vif_copy_chanctx_to_vlans(sdata, false);
1177
1178	ieee80211_check_fast_xmit_iface(sdata);
1179
1180	if (ieee80211_chanctx_refcount(local, old_ctx) == 0)
1181		ieee80211_free_chanctx(local, old_ctx);
1182
1183	ieee80211_recalc_chanctx_min_def(local, new_ctx);
 
 
 
 
1184	ieee80211_recalc_smps_chanctx(local, new_ctx);
1185	ieee80211_recalc_radar_chanctx(local, new_ctx);
 
1186
1187	if (changed)
1188		ieee80211_bss_info_change_notify(sdata, changed);
1189
1190out:
1191	ieee80211_vif_chanctx_reservation_complete(sdata);
1192	return err;
1193}
1194
1195static int
1196ieee80211_vif_use_reserved_assign(struct ieee80211_sub_if_data *sdata)
1197{
1198	struct ieee80211_local *local = sdata->local;
1199	struct ieee80211_chanctx *old_ctx, *new_ctx;
1200	const struct cfg80211_chan_def *chandef;
1201	int err;
1202
1203	old_ctx = ieee80211_vif_get_chanctx(sdata);
1204	new_ctx = sdata->reserved_chanctx;
1205
1206	if (WARN_ON(!sdata->reserved_ready))
1207		return -EINVAL;
1208
1209	if (WARN_ON(old_ctx))
1210		return -EINVAL;
1211
1212	if (WARN_ON(!new_ctx))
1213		return -EINVAL;
1214
1215	if (WARN_ON(new_ctx->replace_state ==
1216		    IEEE80211_CHANCTX_REPLACES_OTHER))
1217		return -EINVAL;
1218
1219	chandef = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
1220				&sdata->reserved_chandef);
1221	if (WARN_ON(!chandef))
1222		return -EINVAL;
1223
1224	ieee80211_change_chanctx(local, new_ctx, new_ctx, chandef);
1225
1226	list_del(&sdata->reserved_chanctx_list);
1227	sdata->reserved_chanctx = NULL;
1228
1229	err = ieee80211_assign_vif_chanctx(sdata, new_ctx);
1230	if (err) {
1231		if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
1232			ieee80211_free_chanctx(local, new_ctx);
1233
1234		goto out;
1235	}
1236
1237out:
1238	ieee80211_vif_chanctx_reservation_complete(sdata);
1239	return err;
1240}
1241
1242static bool
1243ieee80211_vif_has_in_place_reservation(struct ieee80211_sub_if_data *sdata)
1244{
1245	struct ieee80211_chanctx *old_ctx, *new_ctx;
1246
1247	lockdep_assert_held(&sdata->local->chanctx_mtx);
1248
1249	new_ctx = sdata->reserved_chanctx;
1250	old_ctx = ieee80211_vif_get_chanctx(sdata);
1251
1252	if (!old_ctx)
1253		return false;
1254
1255	if (WARN_ON(!new_ctx))
1256		return false;
1257
1258	if (old_ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED)
1259		return false;
1260
1261	if (new_ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1262		return false;
1263
1264	return true;
1265}
1266
1267static int ieee80211_chsw_switch_hwconf(struct ieee80211_local *local,
1268					struct ieee80211_chanctx *new_ctx)
1269{
1270	const struct cfg80211_chan_def *chandef;
1271
1272	lockdep_assert_held(&local->mtx);
1273	lockdep_assert_held(&local->chanctx_mtx);
1274
1275	chandef = ieee80211_chanctx_reserved_chandef(local, new_ctx, NULL);
1276	if (WARN_ON(!chandef))
1277		return -EINVAL;
1278
1279	local->hw.conf.radar_enabled = new_ctx->conf.radar_enabled;
1280	local->_oper_chandef = *chandef;
1281	ieee80211_hw_config(local, 0);
1282
1283	return 0;
1284}
1285
1286static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local,
1287				      int n_vifs)
1288{
1289	struct ieee80211_vif_chanctx_switch *vif_chsw;
1290	struct ieee80211_sub_if_data *sdata;
1291	struct ieee80211_chanctx *ctx, *old_ctx;
1292	int i, err;
1293
1294	lockdep_assert_held(&local->mtx);
1295	lockdep_assert_held(&local->chanctx_mtx);
1296
1297	vif_chsw = kcalloc(n_vifs, sizeof(vif_chsw[0]), GFP_KERNEL);
1298	if (!vif_chsw)
1299		return -ENOMEM;
1300
1301	i = 0;
1302	list_for_each_entry(ctx, &local->chanctx_list, list) {
1303		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1304			continue;
1305
1306		if (WARN_ON(!ctx->replace_ctx)) {
1307			err = -EINVAL;
1308			goto out;
1309		}
1310
1311		list_for_each_entry(sdata, &ctx->reserved_vifs,
1312				    reserved_chanctx_list) {
1313			if (!ieee80211_vif_has_in_place_reservation(
1314					sdata))
1315				continue;
1316
1317			old_ctx = ieee80211_vif_get_chanctx(sdata);
1318			vif_chsw[i].vif = &sdata->vif;
1319			vif_chsw[i].old_ctx = &old_ctx->conf;
1320			vif_chsw[i].new_ctx = &ctx->conf;
1321
1322			i++;
1323		}
1324	}
1325
1326	err = drv_switch_vif_chanctx(local, vif_chsw, n_vifs,
1327				     CHANCTX_SWMODE_SWAP_CONTEXTS);
1328
1329out:
1330	kfree(vif_chsw);
1331	return err;
1332}
1333
1334static int ieee80211_chsw_switch_ctxs(struct ieee80211_local *local)
1335{
1336	struct ieee80211_chanctx *ctx;
1337	int err;
1338
1339	lockdep_assert_held(&local->mtx);
1340	lockdep_assert_held(&local->chanctx_mtx);
1341
1342	list_for_each_entry(ctx, &local->chanctx_list, list) {
1343		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1344			continue;
1345
1346		if (!list_empty(&ctx->replace_ctx->assigned_vifs))
1347			continue;
1348
1349		ieee80211_del_chanctx(local, ctx->replace_ctx);
1350		err = ieee80211_add_chanctx(local, ctx);
1351		if (err)
1352			goto err;
1353	}
1354
1355	return 0;
1356
1357err:
1358	WARN_ON(ieee80211_add_chanctx(local, ctx));
1359	list_for_each_entry_continue_reverse(ctx, &local->chanctx_list, list) {
1360		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1361			continue;
1362
1363		if (!list_empty(&ctx->replace_ctx->assigned_vifs))
1364			continue;
1365
1366		ieee80211_del_chanctx(local, ctx);
1367		WARN_ON(ieee80211_add_chanctx(local, ctx->replace_ctx));
1368	}
1369
1370	return err;
1371}
1372
1373static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
1374{
1375	struct ieee80211_sub_if_data *sdata, *sdata_tmp;
1376	struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx;
1377	struct ieee80211_chanctx *new_ctx = NULL;
1378	int err, n_assigned, n_reserved, n_ready;
1379	int n_ctx = 0, n_vifs_switch = 0, n_vifs_assign = 0, n_vifs_ctxless = 0;
1380
1381	lockdep_assert_held(&local->mtx);
1382	lockdep_assert_held(&local->chanctx_mtx);
1383
1384	/*
1385	 * If there are 2 independent pairs of channel contexts performing
1386	 * cross-switch of their vifs this code will still wait until both are
1387	 * ready even though it could be possible to switch one before the
1388	 * other is ready.
1389	 *
1390	 * For practical reasons and code simplicity just do a single huge
1391	 * switch.
1392	 */
1393
1394	/*
1395	 * Verify if the reservation is still feasible.
1396	 *  - if it's not then disconnect
1397	 *  - if it is but not all vifs necessary are ready then defer
1398	 */
1399
1400	list_for_each_entry(ctx, &local->chanctx_list, list) {
1401		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1402			continue;
1403
1404		if (WARN_ON(!ctx->replace_ctx)) {
1405			err = -EINVAL;
1406			goto err;
1407		}
1408
1409		if (!local->use_chanctx)
1410			new_ctx = ctx;
1411
1412		n_ctx++;
1413
1414		n_assigned = 0;
1415		n_reserved = 0;
1416		n_ready = 0;
1417
1418		list_for_each_entry(sdata, &ctx->replace_ctx->assigned_vifs,
1419				    assigned_chanctx_list) {
1420			n_assigned++;
1421			if (sdata->reserved_chanctx) {
1422				n_reserved++;
1423				if (sdata->reserved_ready)
1424					n_ready++;
1425			}
1426		}
1427
1428		if (n_assigned != n_reserved) {
1429			if (n_ready == n_reserved) {
1430				wiphy_info(local->hw.wiphy,
1431					   "channel context reservation cannot be finalized because some interfaces aren't switching\n");
1432				err = -EBUSY;
1433				goto err;
1434			}
1435
1436			return -EAGAIN;
1437		}
1438
1439		ctx->conf.radar_enabled = false;
1440		list_for_each_entry(sdata, &ctx->reserved_vifs,
1441				    reserved_chanctx_list) {
1442			if (ieee80211_vif_has_in_place_reservation(sdata) &&
1443			    !sdata->reserved_ready)
1444				return -EAGAIN;
1445
1446			old_ctx = ieee80211_vif_get_chanctx(sdata);
1447			if (old_ctx) {
1448				if (old_ctx->replace_state ==
1449				    IEEE80211_CHANCTX_WILL_BE_REPLACED)
1450					n_vifs_switch++;
1451				else
1452					n_vifs_assign++;
1453			} else {
1454				n_vifs_ctxless++;
1455			}
1456
1457			if (sdata->reserved_radar_required)
1458				ctx->conf.radar_enabled = true;
1459		}
1460	}
1461
1462	if (WARN_ON(n_ctx == 0) ||
1463	    WARN_ON(n_vifs_switch == 0 &&
1464		    n_vifs_assign == 0 &&
1465		    n_vifs_ctxless == 0) ||
1466	    WARN_ON(n_ctx > 1 && !local->use_chanctx) ||
1467	    WARN_ON(!new_ctx && !local->use_chanctx)) {
1468		err = -EINVAL;
1469		goto err;
1470	}
1471
1472	/*
1473	 * All necessary vifs are ready. Perform the switch now depending on
1474	 * reservations and driver capabilities.
1475	 */
1476
1477	if (local->use_chanctx) {
1478		if (n_vifs_switch > 0) {
1479			err = ieee80211_chsw_switch_vifs(local, n_vifs_switch);
1480			if (err)
1481				goto err;
1482		}
1483
1484		if (n_vifs_assign > 0 || n_vifs_ctxless > 0) {
1485			err = ieee80211_chsw_switch_ctxs(local);
1486			if (err)
1487				goto err;
1488		}
1489	} else {
1490		err = ieee80211_chsw_switch_hwconf(local, new_ctx);
1491		if (err)
1492			goto err;
1493	}
1494
1495	/*
1496	 * Update all structures, values and pointers to point to new channel
1497	 * context(s).
1498	 */
 
 
1499	list_for_each_entry(ctx, &local->chanctx_list, list) {
1500		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1501			continue;
1502
1503		if (WARN_ON(!ctx->replace_ctx)) {
1504			err = -EINVAL;
1505			goto err;
1506		}
1507
1508		list_for_each_entry(sdata, &ctx->reserved_vifs,
1509				    reserved_chanctx_list) {
1510			u32 changed = 0;
1511
1512			if (!ieee80211_vif_has_in_place_reservation(sdata))
1513				continue;
1514
1515			rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf);
1516
1517			if (sdata->vif.type == NL80211_IFTYPE_AP)
1518				__ieee80211_vif_copy_chanctx_to_vlans(sdata,
1519								      false);
1520
1521			ieee80211_check_fast_xmit_iface(sdata);
1522
1523			sdata->radar_required = sdata->reserved_radar_required;
1524
1525			if (sdata->vif.bss_conf.chandef.width !=
1526			    sdata->reserved_chandef.width)
1527				changed = BSS_CHANGED_BANDWIDTH;
1528
1529			ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
1530			if (changed)
1531				ieee80211_bss_info_change_notify(sdata,
1532								 changed);
1533
1534			ieee80211_recalc_txpower(sdata, false);
1535		}
1536
1537		ieee80211_recalc_chanctx_chantype(local, ctx);
1538		ieee80211_recalc_smps_chanctx(local, ctx);
1539		ieee80211_recalc_radar_chanctx(local, ctx);
1540		ieee80211_recalc_chanctx_min_def(local, ctx);
1541
1542		list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1543					 reserved_chanctx_list) {
1544			if (ieee80211_vif_get_chanctx(sdata) != ctx)
1545				continue;
1546
1547			list_del(&sdata->reserved_chanctx_list);
1548			list_move(&sdata->assigned_chanctx_list,
1549				  &ctx->assigned_vifs);
1550			sdata->reserved_chanctx = NULL;
1551
1552			ieee80211_vif_chanctx_reservation_complete(sdata);
1553		}
1554
1555		/*
1556		 * This context might have been a dependency for an already
1557		 * ready re-assign reservation interface that was deferred. Do
1558		 * not propagate error to the caller though. The in-place
1559		 * reservation for originally requested interface has already
1560		 * succeeded at this point.
1561		 */
1562		list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1563					 reserved_chanctx_list) {
1564			if (WARN_ON(ieee80211_vif_has_in_place_reservation(
1565					sdata)))
1566				continue;
1567
1568			if (WARN_ON(sdata->reserved_chanctx != ctx))
1569				continue;
1570
1571			if (!sdata->reserved_ready)
1572				continue;
1573
1574			if (ieee80211_vif_get_chanctx(sdata))
1575				err = ieee80211_vif_use_reserved_reassign(
1576						sdata);
1577			else
1578				err = ieee80211_vif_use_reserved_assign(sdata);
1579
1580			if (err) {
1581				sdata_info(sdata,
1582					   "failed to finalize (re-)assign reservation (err=%d)\n",
1583					   err);
1584				ieee80211_vif_unreserve_chanctx(sdata);
1585				cfg80211_stop_iface(local->hw.wiphy,
1586						    &sdata->wdev,
1587						    GFP_KERNEL);
1588			}
1589		}
1590	}
1591
1592	/*
1593	 * Finally free old contexts
1594	 */
1595
1596	list_for_each_entry_safe(ctx, ctx_tmp, &local->chanctx_list, list) {
1597		if (ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED)
1598			continue;
1599
1600		ctx->replace_ctx->replace_ctx = NULL;
1601		ctx->replace_ctx->replace_state =
1602				IEEE80211_CHANCTX_REPLACE_NONE;
1603
1604		list_del_rcu(&ctx->list);
1605		kfree_rcu(ctx, rcu_head);
1606	}
1607
1608	return 0;
1609
1610err:
1611	list_for_each_entry(ctx, &local->chanctx_list, list) {
1612		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1613			continue;
1614
1615		list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1616					 reserved_chanctx_list) {
1617			ieee80211_vif_unreserve_chanctx(sdata);
1618			ieee80211_vif_chanctx_reservation_complete(sdata);
1619		}
1620	}
1621
1622	return err;
1623}
1624
1625static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
1626{
1627	struct ieee80211_local *local = sdata->local;
1628	struct ieee80211_chanctx_conf *conf;
1629	struct ieee80211_chanctx *ctx;
1630	bool use_reserved_switch = false;
1631
1632	lockdep_assert_held(&local->chanctx_mtx);
1633
1634	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1635					 lockdep_is_held(&local->chanctx_mtx));
1636	if (!conf)
1637		return;
1638
1639	ctx = container_of(conf, struct ieee80211_chanctx, conf);
1640
1641	if (sdata->reserved_chanctx) {
1642		if (sdata->reserved_chanctx->replace_state ==
1643		    IEEE80211_CHANCTX_REPLACES_OTHER &&
1644		    ieee80211_chanctx_num_reserved(local,
1645						   sdata->reserved_chanctx) > 1)
1646			use_reserved_switch = true;
1647
1648		ieee80211_vif_unreserve_chanctx(sdata);
1649	}
1650
1651	ieee80211_assign_vif_chanctx(sdata, NULL);
1652	if (ieee80211_chanctx_refcount(local, ctx) == 0)
1653		ieee80211_free_chanctx(local, ctx);
1654
1655	sdata->radar_required = false;
1656
1657	/* Unreserving may ready an in-place reservation. */
1658	if (use_reserved_switch)
1659		ieee80211_vif_use_reserved_switch(local);
1660}
1661
1662int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
1663			      const struct cfg80211_chan_def *chandef,
1664			      enum ieee80211_chanctx_mode mode)
1665{
1666	struct ieee80211_local *local = sdata->local;
1667	struct ieee80211_chanctx *ctx;
1668	u8 radar_detect_width = 0;
1669	int ret;
1670
1671	lockdep_assert_held(&local->mtx);
1672
1673	WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev));
1674
1675	mutex_lock(&local->chanctx_mtx);
1676
1677	ret = cfg80211_chandef_dfs_required(local->hw.wiphy,
1678					    chandef,
1679					    sdata->wdev.iftype);
1680	if (ret < 0)
1681		goto out;
1682	if (ret > 0)
1683		radar_detect_width = BIT(chandef->width);
1684
1685	sdata->radar_required = ret;
1686
1687	ret = ieee80211_check_combinations(sdata, chandef, mode,
1688					   radar_detect_width);
1689	if (ret < 0)
1690		goto out;
1691
1692	__ieee80211_vif_release_channel(sdata);
1693
1694	ctx = ieee80211_find_chanctx(local, chandef, mode);
1695	if (!ctx)
1696		ctx = ieee80211_new_chanctx(local, chandef, mode);
1697	if (IS_ERR(ctx)) {
1698		ret = PTR_ERR(ctx);
1699		goto out;
1700	}
1701
1702	ieee80211_vif_update_chandef(sdata, chandef);
1703
1704	ret = ieee80211_assign_vif_chanctx(sdata, ctx);
1705	if (ret) {
1706		/* if assign fails refcount stays the same */
1707		if (ieee80211_chanctx_refcount(local, ctx) == 0)
1708			ieee80211_free_chanctx(local, ctx);
1709		goto out;
1710	}
1711
1712	ieee80211_recalc_smps_chanctx(local, ctx);
1713	ieee80211_recalc_radar_chanctx(local, ctx);
1714 out:
1715	if (ret)
1716		sdata->radar_required = false;
1717
1718	mutex_unlock(&local->chanctx_mtx);
1719	return ret;
1720}
1721
1722int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata)
1723{
1724	struct ieee80211_local *local = sdata->local;
1725	struct ieee80211_chanctx *new_ctx;
1726	struct ieee80211_chanctx *old_ctx;
1727	int err;
1728
1729	lockdep_assert_held(&local->mtx);
1730	lockdep_assert_held(&local->chanctx_mtx);
1731
1732	new_ctx = sdata->reserved_chanctx;
1733	old_ctx = ieee80211_vif_get_chanctx(sdata);
1734
1735	if (WARN_ON(!new_ctx))
1736		return -EINVAL;
1737
1738	if (WARN_ON(new_ctx->replace_state ==
1739		    IEEE80211_CHANCTX_WILL_BE_REPLACED))
1740		return -EINVAL;
1741
1742	if (WARN_ON(sdata->reserved_ready))
1743		return -EINVAL;
1744
1745	sdata->reserved_ready = true;
1746
1747	if (new_ctx->replace_state == IEEE80211_CHANCTX_REPLACE_NONE) {
1748		if (old_ctx)
1749			err = ieee80211_vif_use_reserved_reassign(sdata);
1750		else
1751			err = ieee80211_vif_use_reserved_assign(sdata);
1752
1753		if (err)
1754			return err;
1755	}
1756
1757	/*
1758	 * In-place reservation may need to be finalized now either if:
1759	 *  a) sdata is taking part in the swapping itself and is the last one
1760	 *  b) sdata has switched with a re-assign reservation to an existing
1761	 *     context readying in-place switching of old_ctx
1762	 *
1763	 * In case of (b) do not propagate the error up because the requested
1764	 * sdata already switched successfully. Just spill an extra warning.
1765	 * The ieee80211_vif_use_reserved_switch() already stops all necessary
1766	 * interfaces upon failure.
1767	 */
1768	if ((old_ctx &&
1769	     old_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
1770	    new_ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
1771		err = ieee80211_vif_use_reserved_switch(local);
1772		if (err && err != -EAGAIN) {
1773			if (new_ctx->replace_state ==
1774			    IEEE80211_CHANCTX_REPLACES_OTHER)
1775				return err;
1776
1777			wiphy_info(local->hw.wiphy,
1778				   "depending in-place reservation failed (err=%d)\n",
1779				   err);
1780		}
1781	}
1782
1783	return 0;
1784}
1785
1786int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
1787				   const struct cfg80211_chan_def *chandef,
1788				   u32 *changed)
1789{
1790	struct ieee80211_local *local = sdata->local;
1791	struct ieee80211_chanctx_conf *conf;
1792	struct ieee80211_chanctx *ctx;
1793	const struct cfg80211_chan_def *compat;
1794	int ret;
1795
1796	if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
1797				     IEEE80211_CHAN_DISABLED))
1798		return -EINVAL;
1799
1800	mutex_lock(&local->chanctx_mtx);
1801	if (cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef)) {
1802		ret = 0;
1803		goto out;
1804	}
1805
1806	if (chandef->width == NL80211_CHAN_WIDTH_20_NOHT ||
1807	    sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) {
1808		ret = -EINVAL;
1809		goto out;
1810	}
1811
1812	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1813					 lockdep_is_held(&local->chanctx_mtx));
1814	if (!conf) {
1815		ret = -EINVAL;
1816		goto out;
1817	}
1818
1819	ctx = container_of(conf, struct ieee80211_chanctx, conf);
1820
1821	compat = cfg80211_chandef_compatible(&conf->def, chandef);
1822	if (!compat) {
1823		ret = -EINVAL;
1824		goto out;
1825	}
1826
1827	switch (ctx->replace_state) {
1828	case IEEE80211_CHANCTX_REPLACE_NONE:
1829		if (!ieee80211_chanctx_reserved_chandef(local, ctx, compat)) {
1830			ret = -EBUSY;
1831			goto out;
1832		}
1833		break;
1834	case IEEE80211_CHANCTX_WILL_BE_REPLACED:
1835		/* TODO: Perhaps the bandwidth change could be treated as a
1836		 * reservation itself? */
1837		ret = -EBUSY;
1838		goto out;
1839	case IEEE80211_CHANCTX_REPLACES_OTHER:
1840		/* channel context that is going to replace another channel
1841		 * context doesn't really exist and shouldn't be assigned
1842		 * anywhere yet */
1843		WARN_ON(1);
1844		break;
1845	}
1846
1847	ieee80211_vif_update_chandef(sdata, chandef);
1848
1849	ieee80211_recalc_chanctx_chantype(local, ctx);
1850
1851	*changed |= BSS_CHANGED_BANDWIDTH;
1852	ret = 0;
1853 out:
1854	mutex_unlock(&local->chanctx_mtx);
1855	return ret;
1856}
1857
1858void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
1859{
1860	WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev));
1861
1862	lockdep_assert_held(&sdata->local->mtx);
1863
1864	mutex_lock(&sdata->local->chanctx_mtx);
1865	__ieee80211_vif_release_channel(sdata);
1866	mutex_unlock(&sdata->local->chanctx_mtx);
1867}
1868
1869void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata)
1870{
1871	struct ieee80211_local *local = sdata->local;
1872	struct ieee80211_sub_if_data *ap;
1873	struct ieee80211_chanctx_conf *conf;
1874
1875	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss))
1876		return;
1877
1878	ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
1879
1880	mutex_lock(&local->chanctx_mtx);
1881
1882	conf = rcu_dereference_protected(ap->vif.chanctx_conf,
1883					 lockdep_is_held(&local->chanctx_mtx));
1884	rcu_assign_pointer(sdata->vif.chanctx_conf, conf);
1885	mutex_unlock(&local->chanctx_mtx);
1886}
1887
1888void ieee80211_iter_chan_contexts_atomic(
1889	struct ieee80211_hw *hw,
1890	void (*iter)(struct ieee80211_hw *hw,
1891		     struct ieee80211_chanctx_conf *chanctx_conf,
1892		     void *data),
1893	void *iter_data)
1894{
1895	struct ieee80211_local *local = hw_to_local(hw);
1896	struct ieee80211_chanctx *ctx;
1897
1898	rcu_read_lock();
1899	list_for_each_entry_rcu(ctx, &local->chanctx_list, list)
1900		if (ctx->driver_present)
1901			iter(hw, &ctx->conf, iter_data);
1902	rcu_read_unlock();
1903}
1904EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic);
v4.6
 
   1/*
   2 * mac80211 - channel management
 
   3 */
   4
   5#include <linux/nl80211.h>
   6#include <linux/export.h>
   7#include <linux/rtnetlink.h>
   8#include <net/cfg80211.h>
   9#include "ieee80211_i.h"
  10#include "driver-ops.h"
 
  11
  12static int ieee80211_chanctx_num_assigned(struct ieee80211_local *local,
  13					  struct ieee80211_chanctx *ctx)
  14{
  15	struct ieee80211_sub_if_data *sdata;
  16	int num = 0;
  17
  18	lockdep_assert_held(&local->chanctx_mtx);
  19
  20	list_for_each_entry(sdata, &ctx->assigned_vifs, assigned_chanctx_list)
  21		num++;
  22
  23	return num;
  24}
  25
  26static int ieee80211_chanctx_num_reserved(struct ieee80211_local *local,
  27					  struct ieee80211_chanctx *ctx)
  28{
  29	struct ieee80211_sub_if_data *sdata;
  30	int num = 0;
  31
  32	lockdep_assert_held(&local->chanctx_mtx);
  33
  34	list_for_each_entry(sdata, &ctx->reserved_vifs, reserved_chanctx_list)
  35		num++;
  36
  37	return num;
  38}
  39
  40int ieee80211_chanctx_refcount(struct ieee80211_local *local,
  41			       struct ieee80211_chanctx *ctx)
  42{
  43	return ieee80211_chanctx_num_assigned(local, ctx) +
  44	       ieee80211_chanctx_num_reserved(local, ctx);
  45}
  46
  47static int ieee80211_num_chanctx(struct ieee80211_local *local)
  48{
  49	struct ieee80211_chanctx *ctx;
  50	int num = 0;
  51
  52	lockdep_assert_held(&local->chanctx_mtx);
  53
  54	list_for_each_entry(ctx, &local->chanctx_list, list)
  55		num++;
  56
  57	return num;
  58}
  59
  60static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local)
  61{
  62	lockdep_assert_held(&local->chanctx_mtx);
  63	return ieee80211_num_chanctx(local) < ieee80211_max_num_channels(local);
  64}
  65
  66static struct ieee80211_chanctx *
  67ieee80211_vif_get_chanctx(struct ieee80211_sub_if_data *sdata)
  68{
  69	struct ieee80211_local *local __maybe_unused = sdata->local;
  70	struct ieee80211_chanctx_conf *conf;
  71
  72	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
  73					 lockdep_is_held(&local->chanctx_mtx));
  74	if (!conf)
  75		return NULL;
  76
  77	return container_of(conf, struct ieee80211_chanctx, conf);
  78}
  79
  80static const struct cfg80211_chan_def *
  81ieee80211_chanctx_reserved_chandef(struct ieee80211_local *local,
  82				   struct ieee80211_chanctx *ctx,
  83				   const struct cfg80211_chan_def *compat)
  84{
  85	struct ieee80211_sub_if_data *sdata;
  86
  87	lockdep_assert_held(&local->chanctx_mtx);
  88
  89	list_for_each_entry(sdata, &ctx->reserved_vifs,
  90			    reserved_chanctx_list) {
  91		if (!compat)
  92			compat = &sdata->reserved_chandef;
  93
  94		compat = cfg80211_chandef_compatible(&sdata->reserved_chandef,
  95						     compat);
  96		if (!compat)
  97			break;
  98	}
  99
 100	return compat;
 101}
 102
 103static const struct cfg80211_chan_def *
 104ieee80211_chanctx_non_reserved_chandef(struct ieee80211_local *local,
 105				       struct ieee80211_chanctx *ctx,
 106				       const struct cfg80211_chan_def *compat)
 107{
 108	struct ieee80211_sub_if_data *sdata;
 109
 110	lockdep_assert_held(&local->chanctx_mtx);
 111
 112	list_for_each_entry(sdata, &ctx->assigned_vifs,
 113			    assigned_chanctx_list) {
 114		if (sdata->reserved_chanctx != NULL)
 115			continue;
 116
 117		if (!compat)
 118			compat = &sdata->vif.bss_conf.chandef;
 119
 120		compat = cfg80211_chandef_compatible(
 121				&sdata->vif.bss_conf.chandef, compat);
 122		if (!compat)
 123			break;
 124	}
 125
 126	return compat;
 127}
 128
 129static const struct cfg80211_chan_def *
 130ieee80211_chanctx_combined_chandef(struct ieee80211_local *local,
 131				   struct ieee80211_chanctx *ctx,
 132				   const struct cfg80211_chan_def *compat)
 133{
 134	lockdep_assert_held(&local->chanctx_mtx);
 135
 136	compat = ieee80211_chanctx_reserved_chandef(local, ctx, compat);
 137	if (!compat)
 138		return NULL;
 139
 140	compat = ieee80211_chanctx_non_reserved_chandef(local, ctx, compat);
 141	if (!compat)
 142		return NULL;
 143
 144	return compat;
 145}
 146
 147static bool
 148ieee80211_chanctx_can_reserve_chandef(struct ieee80211_local *local,
 149				      struct ieee80211_chanctx *ctx,
 150				      const struct cfg80211_chan_def *def)
 151{
 152	lockdep_assert_held(&local->chanctx_mtx);
 153
 154	if (ieee80211_chanctx_combined_chandef(local, ctx, def))
 155		return true;
 156
 157	if (!list_empty(&ctx->reserved_vifs) &&
 158	    ieee80211_chanctx_reserved_chandef(local, ctx, def))
 159		return true;
 160
 161	return false;
 162}
 163
 164static struct ieee80211_chanctx *
 165ieee80211_find_reservation_chanctx(struct ieee80211_local *local,
 166				   const struct cfg80211_chan_def *chandef,
 167				   enum ieee80211_chanctx_mode mode)
 168{
 169	struct ieee80211_chanctx *ctx;
 170
 171	lockdep_assert_held(&local->chanctx_mtx);
 172
 173	if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
 174		return NULL;
 175
 176	list_for_each_entry(ctx, &local->chanctx_list, list) {
 177		if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
 178			continue;
 179
 180		if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
 181			continue;
 182
 183		if (!ieee80211_chanctx_can_reserve_chandef(local, ctx,
 184							   chandef))
 185			continue;
 186
 187		return ctx;
 188	}
 189
 190	return NULL;
 191}
 192
 193enum nl80211_chan_width ieee80211_get_sta_bw(struct ieee80211_sta *sta)
 194{
 195	switch (sta->bandwidth) {
 
 
 196	case IEEE80211_STA_RX_BW_20:
 197		if (sta->ht_cap.ht_supported)
 198			return NL80211_CHAN_WIDTH_20;
 199		else
 200			return NL80211_CHAN_WIDTH_20_NOHT;
 201	case IEEE80211_STA_RX_BW_40:
 202		return NL80211_CHAN_WIDTH_40;
 203	case IEEE80211_STA_RX_BW_80:
 204		return NL80211_CHAN_WIDTH_80;
 205	case IEEE80211_STA_RX_BW_160:
 206		/*
 207		 * This applied for both 160 and 80+80. since we use
 208		 * the returned value to consider degradation of
 209		 * ctx->conf.min_def, we have to make sure to take
 210		 * the bigger one (NL80211_CHAN_WIDTH_160).
 211		 * Otherwise we might try degrading even when not
 212		 * needed, as the max required sta_bw returned (80+80)
 213		 * might be smaller than the configured bw (160).
 214		 */
 215		return NL80211_CHAN_WIDTH_160;
 216	default:
 217		WARN_ON(1);
 218		return NL80211_CHAN_WIDTH_20;
 219	}
 220}
 221
 222static enum nl80211_chan_width
 223ieee80211_get_max_required_bw(struct ieee80211_sub_if_data *sdata)
 224{
 225	enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
 226	struct sta_info *sta;
 227
 228	rcu_read_lock();
 229	list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) {
 230		if (sdata != sta->sdata &&
 231		    !(sta->sdata->bss && sta->sdata->bss == sdata->bss))
 232			continue;
 233
 234		if (!sta->uploaded || !test_sta_flag(sta, WLAN_STA_ASSOC))
 235			continue;
 236
 237		max_bw = max(max_bw, ieee80211_get_sta_bw(&sta->sta));
 238	}
 239	rcu_read_unlock();
 240
 241	return max_bw;
 242}
 243
 244static enum nl80211_chan_width
 245ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
 246				      struct ieee80211_chanctx_conf *conf)
 247{
 248	struct ieee80211_sub_if_data *sdata;
 249	enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
 250
 251	rcu_read_lock();
 252	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 253		struct ieee80211_vif *vif = &sdata->vif;
 254		enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20_NOHT;
 255
 256		if (!ieee80211_sdata_running(sdata))
 257			continue;
 258
 259		if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
 260			continue;
 261
 262		switch (vif->type) {
 263		case NL80211_IFTYPE_AP:
 264		case NL80211_IFTYPE_AP_VLAN:
 265			width = ieee80211_get_max_required_bw(sdata);
 266			break;
 267		case NL80211_IFTYPE_STATION:
 268			/*
 269			 * The ap's sta->bandwidth is not set yet at this
 270			 * point, so take the width from the chandef, but
 271			 * account also for TDLS peers
 272			 */
 273			width = max(vif->bss_conf.chandef.width,
 274				    ieee80211_get_max_required_bw(sdata));
 275			break;
 276		case NL80211_IFTYPE_P2P_DEVICE:
 
 277			continue;
 278		case NL80211_IFTYPE_ADHOC:
 279		case NL80211_IFTYPE_WDS:
 280		case NL80211_IFTYPE_MESH_POINT:
 281		case NL80211_IFTYPE_OCB:
 282			width = vif->bss_conf.chandef.width;
 283			break;
 
 284		case NL80211_IFTYPE_UNSPECIFIED:
 285		case NUM_NL80211_IFTYPES:
 286		case NL80211_IFTYPE_MONITOR:
 287		case NL80211_IFTYPE_P2P_CLIENT:
 288		case NL80211_IFTYPE_P2P_GO:
 289			WARN_ON_ONCE(1);
 290		}
 291		max_bw = max(max_bw, width);
 292	}
 293
 294	/* use the configured bandwidth in case of monitor interface */
 295	sdata = rcu_dereference(local->monitor_sdata);
 296	if (sdata && rcu_access_pointer(sdata->vif.chanctx_conf) == conf)
 297		max_bw = max(max_bw, conf->def.width);
 298
 299	rcu_read_unlock();
 300
 301	return max_bw;
 302}
 303
 304/*
 305 * recalc the min required chan width of the channel context, which is
 306 * the max of min required widths of all the interfaces bound to this
 307 * channel context.
 308 */
 309void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
 310				      struct ieee80211_chanctx *ctx)
 311{
 312	enum nl80211_chan_width max_bw;
 313	struct cfg80211_chan_def min_def;
 314
 315	lockdep_assert_held(&local->chanctx_mtx);
 316
 317	/* don't optimize 5MHz, 10MHz, and radar_enabled confs */
 318	if (ctx->conf.def.width == NL80211_CHAN_WIDTH_5 ||
 319	    ctx->conf.def.width == NL80211_CHAN_WIDTH_10 ||
 
 
 
 
 
 320	    ctx->conf.radar_enabled) {
 321		ctx->conf.min_def = ctx->conf.def;
 322		return;
 323	}
 324
 325	max_bw = ieee80211_get_chanctx_max_required_bw(local, &ctx->conf);
 326
 327	/* downgrade chandef up to max_bw */
 328	min_def = ctx->conf.def;
 329	while (min_def.width > max_bw)
 330		ieee80211_chandef_downgrade(&min_def);
 331
 332	if (cfg80211_chandef_identical(&ctx->conf.min_def, &min_def))
 333		return;
 334
 335	ctx->conf.min_def = min_def;
 336	if (!ctx->driver_present)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 337		return;
 338
 339	drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_MIN_WIDTH);
 
 
 
 
 
 
 340}
 341
 342static void ieee80211_change_chanctx(struct ieee80211_local *local,
 343				     struct ieee80211_chanctx *ctx,
 
 344				     const struct cfg80211_chan_def *chandef)
 345{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 346	if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) {
 347		ieee80211_recalc_chanctx_min_def(local, ctx);
 348		return;
 349	}
 350
 351	WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
 352
 353	ctx->conf.def = *chandef;
 354	drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH);
 355	ieee80211_recalc_chanctx_min_def(local, ctx);
 
 
 
 356
 357	if (!local->use_chanctx) {
 358		local->_oper_chandef = *chandef;
 359		ieee80211_hw_config(local, 0);
 360	}
 
 
 
 361}
 362
 363static struct ieee80211_chanctx *
 364ieee80211_find_chanctx(struct ieee80211_local *local,
 365		       const struct cfg80211_chan_def *chandef,
 366		       enum ieee80211_chanctx_mode mode)
 367{
 368	struct ieee80211_chanctx *ctx;
 369
 370	lockdep_assert_held(&local->chanctx_mtx);
 371
 372	if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
 373		return NULL;
 374
 375	list_for_each_entry(ctx, &local->chanctx_list, list) {
 376		const struct cfg80211_chan_def *compat;
 377
 378		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACE_NONE)
 379			continue;
 380
 381		if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
 382			continue;
 383
 384		compat = cfg80211_chandef_compatible(&ctx->conf.def, chandef);
 385		if (!compat)
 386			continue;
 387
 388		compat = ieee80211_chanctx_reserved_chandef(local, ctx,
 389							    compat);
 390		if (!compat)
 391			continue;
 392
 393		ieee80211_change_chanctx(local, ctx, compat);
 394
 395		return ctx;
 396	}
 397
 398	return NULL;
 399}
 400
 401bool ieee80211_is_radar_required(struct ieee80211_local *local)
 402{
 403	struct ieee80211_sub_if_data *sdata;
 404
 405	lockdep_assert_held(&local->mtx);
 406
 407	rcu_read_lock();
 408	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 409		if (sdata->radar_required) {
 410			rcu_read_unlock();
 411			return true;
 412		}
 413	}
 414	rcu_read_unlock();
 415
 416	return false;
 417}
 418
 419static bool
 420ieee80211_chanctx_radar_required(struct ieee80211_local *local,
 421				 struct ieee80211_chanctx *ctx)
 422{
 423	struct ieee80211_chanctx_conf *conf = &ctx->conf;
 424	struct ieee80211_sub_if_data *sdata;
 425	bool required = false;
 426
 427	lockdep_assert_held(&local->chanctx_mtx);
 428	lockdep_assert_held(&local->mtx);
 429
 430	rcu_read_lock();
 431	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 432		if (!ieee80211_sdata_running(sdata))
 433			continue;
 434		if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
 435			continue;
 436		if (!sdata->radar_required)
 437			continue;
 438
 439		required = true;
 440		break;
 441	}
 442	rcu_read_unlock();
 443
 444	return required;
 445}
 446
 447static struct ieee80211_chanctx *
 448ieee80211_alloc_chanctx(struct ieee80211_local *local,
 449			const struct cfg80211_chan_def *chandef,
 450			enum ieee80211_chanctx_mode mode)
 451{
 452	struct ieee80211_chanctx *ctx;
 453
 454	lockdep_assert_held(&local->chanctx_mtx);
 455
 456	ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL);
 457	if (!ctx)
 458		return NULL;
 459
 460	INIT_LIST_HEAD(&ctx->assigned_vifs);
 461	INIT_LIST_HEAD(&ctx->reserved_vifs);
 462	ctx->conf.def = *chandef;
 463	ctx->conf.rx_chains_static = 1;
 464	ctx->conf.rx_chains_dynamic = 1;
 465	ctx->mode = mode;
 466	ctx->conf.radar_enabled = false;
 467	ieee80211_recalc_chanctx_min_def(local, ctx);
 468
 469	return ctx;
 470}
 471
 472static int ieee80211_add_chanctx(struct ieee80211_local *local,
 473				 struct ieee80211_chanctx *ctx)
 474{
 475	u32 changed;
 476	int err;
 477
 478	lockdep_assert_held(&local->mtx);
 479	lockdep_assert_held(&local->chanctx_mtx);
 480
 481	if (!local->use_chanctx)
 482		local->hw.conf.radar_enabled = ctx->conf.radar_enabled;
 483
 484	/* turn idle off *before* setting channel -- some drivers need that */
 485	changed = ieee80211_idle_off(local);
 486	if (changed)
 487		ieee80211_hw_config(local, changed);
 488
 489	if (!local->use_chanctx) {
 490		local->_oper_chandef = ctx->conf.def;
 491		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 492	} else {
 493		err = drv_add_chanctx(local, ctx);
 494		if (err) {
 495			ieee80211_recalc_idle(local);
 496			return err;
 497		}
 498	}
 499
 500	return 0;
 501}
 502
 503static struct ieee80211_chanctx *
 504ieee80211_new_chanctx(struct ieee80211_local *local,
 505		      const struct cfg80211_chan_def *chandef,
 506		      enum ieee80211_chanctx_mode mode)
 507{
 508	struct ieee80211_chanctx *ctx;
 509	int err;
 510
 511	lockdep_assert_held(&local->mtx);
 512	lockdep_assert_held(&local->chanctx_mtx);
 513
 514	ctx = ieee80211_alloc_chanctx(local, chandef, mode);
 515	if (!ctx)
 516		return ERR_PTR(-ENOMEM);
 517
 518	err = ieee80211_add_chanctx(local, ctx);
 519	if (err) {
 520		kfree(ctx);
 521		return ERR_PTR(err);
 522	}
 523
 524	list_add_rcu(&ctx->list, &local->chanctx_list);
 525	return ctx;
 526}
 527
 528static void ieee80211_del_chanctx(struct ieee80211_local *local,
 529				  struct ieee80211_chanctx *ctx)
 530{
 531	lockdep_assert_held(&local->chanctx_mtx);
 532
 533	if (!local->use_chanctx) {
 534		struct cfg80211_chan_def *chandef = &local->_oper_chandef;
 535		chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
 
 
 
 
 
 
 
 536		chandef->center_freq1 = chandef->chan->center_freq;
 
 537		chandef->center_freq2 = 0;
 538
 539		/* NOTE: Disabling radar is only valid here for
 540		 * single channel context. To be sure, check it ...
 541		 */
 542		WARN_ON(local->hw.conf.radar_enabled &&
 543			!list_empty(&local->chanctx_list));
 544
 545		local->hw.conf.radar_enabled = false;
 546
 547		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 548	} else {
 549		drv_remove_chanctx(local, ctx);
 550	}
 551
 552	ieee80211_recalc_idle(local);
 553}
 554
 555static void ieee80211_free_chanctx(struct ieee80211_local *local,
 556				   struct ieee80211_chanctx *ctx)
 557{
 558	lockdep_assert_held(&local->chanctx_mtx);
 559
 560	WARN_ON_ONCE(ieee80211_chanctx_refcount(local, ctx) != 0);
 561
 562	list_del_rcu(&ctx->list);
 563	ieee80211_del_chanctx(local, ctx);
 564	kfree_rcu(ctx, rcu_head);
 565}
 566
 567void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
 568				       struct ieee80211_chanctx *ctx)
 569{
 570	struct ieee80211_chanctx_conf *conf = &ctx->conf;
 571	struct ieee80211_sub_if_data *sdata;
 572	const struct cfg80211_chan_def *compat = NULL;
 573	struct sta_info *sta;
 574
 575	lockdep_assert_held(&local->chanctx_mtx);
 576
 577	rcu_read_lock();
 578	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 579
 580		if (!ieee80211_sdata_running(sdata))
 581			continue;
 582		if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
 583			continue;
 584		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
 585			continue;
 586
 587		if (!compat)
 588			compat = &sdata->vif.bss_conf.chandef;
 589
 590		compat = cfg80211_chandef_compatible(
 591				&sdata->vif.bss_conf.chandef, compat);
 592		if (WARN_ON_ONCE(!compat))
 593			break;
 594	}
 595
 596	/* TDLS peers can sometimes affect the chandef width */
 597	list_for_each_entry_rcu(sta, &local->sta_list, list) {
 598		if (!sta->uploaded ||
 599		    !test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW) ||
 600		    !test_sta_flag(sta, WLAN_STA_AUTHORIZED) ||
 601		    !sta->tdls_chandef.chan)
 602			continue;
 603
 604		compat = cfg80211_chandef_compatible(&sta->tdls_chandef,
 605						     compat);
 606		if (WARN_ON_ONCE(!compat))
 607			break;
 608	}
 609	rcu_read_unlock();
 610
 611	if (!compat)
 612		return;
 613
 614	ieee80211_change_chanctx(local, ctx, compat);
 615}
 616
 617static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local,
 618					   struct ieee80211_chanctx *chanctx)
 619{
 620	bool radar_enabled;
 621
 622	lockdep_assert_held(&local->chanctx_mtx);
 623	/* for ieee80211_is_radar_required */
 624	lockdep_assert_held(&local->mtx);
 625
 626	radar_enabled = ieee80211_chanctx_radar_required(local, chanctx);
 627
 628	if (radar_enabled == chanctx->conf.radar_enabled)
 629		return;
 630
 631	chanctx->conf.radar_enabled = radar_enabled;
 632
 633	if (!local->use_chanctx) {
 634		local->hw.conf.radar_enabled = chanctx->conf.radar_enabled;
 635		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 636	}
 637
 638	drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR);
 639}
 640
 641static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
 642					struct ieee80211_chanctx *new_ctx)
 643{
 644	struct ieee80211_local *local = sdata->local;
 645	struct ieee80211_chanctx_conf *conf;
 646	struct ieee80211_chanctx *curr_ctx = NULL;
 647	int ret = 0;
 648
 
 
 
 649	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
 650					 lockdep_is_held(&local->chanctx_mtx));
 651
 652	if (conf) {
 653		curr_ctx = container_of(conf, struct ieee80211_chanctx, conf);
 654
 655		drv_unassign_vif_chanctx(local, sdata, curr_ctx);
 656		conf = NULL;
 657		list_del(&sdata->assigned_chanctx_list);
 658	}
 659
 660	if (new_ctx) {
 661		ret = drv_assign_vif_chanctx(local, sdata, new_ctx);
 662		if (ret)
 663			goto out;
 664
 665		conf = &new_ctx->conf;
 666		list_add(&sdata->assigned_chanctx_list,
 667			 &new_ctx->assigned_vifs);
 668	}
 669
 670out:
 671	rcu_assign_pointer(sdata->vif.chanctx_conf, conf);
 672
 673	sdata->vif.bss_conf.idle = !conf;
 674
 675	if (curr_ctx && ieee80211_chanctx_num_assigned(local, curr_ctx) > 0) {
 676		ieee80211_recalc_chanctx_chantype(local, curr_ctx);
 677		ieee80211_recalc_smps_chanctx(local, curr_ctx);
 678		ieee80211_recalc_radar_chanctx(local, curr_ctx);
 679		ieee80211_recalc_chanctx_min_def(local, curr_ctx);
 680	}
 681
 682	if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) {
 683		ieee80211_recalc_txpower(sdata, false);
 684		ieee80211_recalc_chanctx_min_def(local, new_ctx);
 685	}
 686
 687	if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
 688	    sdata->vif.type != NL80211_IFTYPE_MONITOR)
 689		ieee80211_bss_info_change_notify(sdata,
 690						 BSS_CHANGED_IDLE);
 691
 692	ieee80211_check_fast_xmit_iface(sdata);
 693
 694	return ret;
 695}
 696
 697void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
 698				   struct ieee80211_chanctx *chanctx)
 699{
 700	struct ieee80211_sub_if_data *sdata;
 701	u8 rx_chains_static, rx_chains_dynamic;
 702
 703	lockdep_assert_held(&local->chanctx_mtx);
 704
 705	rx_chains_static = 1;
 706	rx_chains_dynamic = 1;
 707
 708	rcu_read_lock();
 709	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 710		u8 needed_static, needed_dynamic;
 711
 712		if (!ieee80211_sdata_running(sdata))
 713			continue;
 714
 715		if (rcu_access_pointer(sdata->vif.chanctx_conf) !=
 716						&chanctx->conf)
 717			continue;
 718
 719		switch (sdata->vif.type) {
 720		case NL80211_IFTYPE_P2P_DEVICE:
 
 721			continue;
 722		case NL80211_IFTYPE_STATION:
 723			if (!sdata->u.mgd.associated)
 724				continue;
 725			break;
 726		case NL80211_IFTYPE_AP_VLAN:
 727			continue;
 728		case NL80211_IFTYPE_AP:
 729		case NL80211_IFTYPE_ADHOC:
 730		case NL80211_IFTYPE_WDS:
 731		case NL80211_IFTYPE_MESH_POINT:
 732		case NL80211_IFTYPE_OCB:
 733			break;
 734		default:
 735			WARN_ON_ONCE(1);
 736		}
 737
 738		switch (sdata->smps_mode) {
 739		default:
 740			WARN_ONCE(1, "Invalid SMPS mode %d\n",
 741				  sdata->smps_mode);
 742			/* fall through */
 743		case IEEE80211_SMPS_OFF:
 744			needed_static = sdata->needed_rx_chains;
 745			needed_dynamic = sdata->needed_rx_chains;
 746			break;
 747		case IEEE80211_SMPS_DYNAMIC:
 748			needed_static = 1;
 749			needed_dynamic = sdata->needed_rx_chains;
 750			break;
 751		case IEEE80211_SMPS_STATIC:
 752			needed_static = 1;
 753			needed_dynamic = 1;
 754			break;
 755		}
 756
 757		rx_chains_static = max(rx_chains_static, needed_static);
 758		rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic);
 759	}
 760
 761	/* Disable SMPS for the monitor interface */
 762	sdata = rcu_dereference(local->monitor_sdata);
 763	if (sdata &&
 764	    rcu_access_pointer(sdata->vif.chanctx_conf) == &chanctx->conf)
 765		rx_chains_dynamic = rx_chains_static = local->rx_chains;
 766
 767	rcu_read_unlock();
 768
 769	if (!local->use_chanctx) {
 770		if (rx_chains_static > 1)
 771			local->smps_mode = IEEE80211_SMPS_OFF;
 772		else if (rx_chains_dynamic > 1)
 773			local->smps_mode = IEEE80211_SMPS_DYNAMIC;
 774		else
 775			local->smps_mode = IEEE80211_SMPS_STATIC;
 776		ieee80211_hw_config(local, 0);
 777	}
 778
 779	if (rx_chains_static == chanctx->conf.rx_chains_static &&
 780	    rx_chains_dynamic == chanctx->conf.rx_chains_dynamic)
 781		return;
 782
 783	chanctx->conf.rx_chains_static = rx_chains_static;
 784	chanctx->conf.rx_chains_dynamic = rx_chains_dynamic;
 785	drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS);
 786}
 787
 788static void
 789__ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
 790				      bool clear)
 791{
 792	struct ieee80211_local *local __maybe_unused = sdata->local;
 793	struct ieee80211_sub_if_data *vlan;
 794	struct ieee80211_chanctx_conf *conf;
 795
 796	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP))
 797		return;
 798
 799	lockdep_assert_held(&local->mtx);
 800
 801	/* Check that conf exists, even when clearing this function
 802	 * must be called with the AP's channel context still there
 803	 * as it would otherwise cause VLANs to have an invalid
 804	 * channel context pointer for a while, possibly pointing
 805	 * to a channel context that has already been freed.
 806	 */
 807	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
 808					 lockdep_is_held(&local->chanctx_mtx));
 809	WARN_ON(!conf);
 810
 811	if (clear)
 812		conf = NULL;
 813
 814	list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
 815		rcu_assign_pointer(vlan->vif.chanctx_conf, conf);
 816}
 817
 818void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
 819					 bool clear)
 820{
 821	struct ieee80211_local *local = sdata->local;
 822
 823	mutex_lock(&local->chanctx_mtx);
 824
 825	__ieee80211_vif_copy_chanctx_to_vlans(sdata, clear);
 826
 827	mutex_unlock(&local->chanctx_mtx);
 828}
 829
 830int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata)
 831{
 832	struct ieee80211_chanctx *ctx = sdata->reserved_chanctx;
 833
 834	lockdep_assert_held(&sdata->local->chanctx_mtx);
 835
 836	if (WARN_ON(!ctx))
 837		return -EINVAL;
 838
 839	list_del(&sdata->reserved_chanctx_list);
 840	sdata->reserved_chanctx = NULL;
 841
 842	if (ieee80211_chanctx_refcount(sdata->local, ctx) == 0) {
 843		if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
 844			if (WARN_ON(!ctx->replace_ctx))
 845				return -EINVAL;
 846
 847			WARN_ON(ctx->replace_ctx->replace_state !=
 848			        IEEE80211_CHANCTX_WILL_BE_REPLACED);
 849			WARN_ON(ctx->replace_ctx->replace_ctx != ctx);
 850
 851			ctx->replace_ctx->replace_ctx = NULL;
 852			ctx->replace_ctx->replace_state =
 853					IEEE80211_CHANCTX_REPLACE_NONE;
 854
 855			list_del_rcu(&ctx->list);
 856			kfree_rcu(ctx, rcu_head);
 857		} else {
 858			ieee80211_free_chanctx(sdata->local, ctx);
 859		}
 860	}
 861
 862	return 0;
 863}
 864
 865int ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata,
 866				  const struct cfg80211_chan_def *chandef,
 867				  enum ieee80211_chanctx_mode mode,
 868				  bool radar_required)
 869{
 870	struct ieee80211_local *local = sdata->local;
 871	struct ieee80211_chanctx *new_ctx, *curr_ctx, *ctx;
 872
 873	lockdep_assert_held(&local->chanctx_mtx);
 874
 875	curr_ctx = ieee80211_vif_get_chanctx(sdata);
 876	if (curr_ctx && local->use_chanctx && !local->ops->switch_vif_chanctx)
 877		return -ENOTSUPP;
 878
 879	new_ctx = ieee80211_find_reservation_chanctx(local, chandef, mode);
 880	if (!new_ctx) {
 881		if (ieee80211_can_create_new_chanctx(local)) {
 882			new_ctx = ieee80211_new_chanctx(local, chandef, mode);
 883			if (IS_ERR(new_ctx))
 884				return PTR_ERR(new_ctx);
 885		} else {
 886			if (!curr_ctx ||
 887			    (curr_ctx->replace_state ==
 888			     IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
 889			    !list_empty(&curr_ctx->reserved_vifs)) {
 890				/*
 891				 * Another vif already requested this context
 892				 * for a reservation. Find another one hoping
 893				 * all vifs assigned to it will also switch
 894				 * soon enough.
 895				 *
 896				 * TODO: This needs a little more work as some
 897				 * cases (more than 2 chanctx capable devices)
 898				 * may fail which could otherwise succeed
 899				 * provided some channel context juggling was
 900				 * performed.
 901				 *
 902				 * Consider ctx1..3, vif1..6, each ctx has 2
 903				 * vifs. vif1 and vif2 from ctx1 request new
 904				 * different chandefs starting 2 in-place
 905				 * reserations with ctx4 and ctx5 replacing
 906				 * ctx1 and ctx2 respectively. Next vif5 and
 907				 * vif6 from ctx3 reserve ctx4. If vif3 and
 908				 * vif4 remain on ctx2 as they are then this
 909				 * fails unless `replace_ctx` from ctx5 is
 910				 * replaced with ctx3.
 911				 */
 912				list_for_each_entry(ctx, &local->chanctx_list,
 913						    list) {
 914					if (ctx->replace_state !=
 915					    IEEE80211_CHANCTX_REPLACE_NONE)
 916						continue;
 917
 918					if (!list_empty(&ctx->reserved_vifs))
 919						continue;
 920
 921					curr_ctx = ctx;
 922					break;
 923				}
 924			}
 925
 926			/*
 927			 * If that's true then all available contexts already
 928			 * have reservations and cannot be used.
 929			 */
 930			if (!curr_ctx ||
 931			    (curr_ctx->replace_state ==
 932			     IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
 933			    !list_empty(&curr_ctx->reserved_vifs))
 934				return -EBUSY;
 935
 936			new_ctx = ieee80211_alloc_chanctx(local, chandef, mode);
 937			if (!new_ctx)
 938				return -ENOMEM;
 939
 940			new_ctx->replace_ctx = curr_ctx;
 941			new_ctx->replace_state =
 942					IEEE80211_CHANCTX_REPLACES_OTHER;
 943
 944			curr_ctx->replace_ctx = new_ctx;
 945			curr_ctx->replace_state =
 946					IEEE80211_CHANCTX_WILL_BE_REPLACED;
 947
 948			list_add_rcu(&new_ctx->list, &local->chanctx_list);
 949		}
 950	}
 951
 952	list_add(&sdata->reserved_chanctx_list, &new_ctx->reserved_vifs);
 953	sdata->reserved_chanctx = new_ctx;
 954	sdata->reserved_chandef = *chandef;
 955	sdata->reserved_radar_required = radar_required;
 956	sdata->reserved_ready = false;
 957
 958	return 0;
 959}
 960
 961static void
 962ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata)
 963{
 964	switch (sdata->vif.type) {
 965	case NL80211_IFTYPE_ADHOC:
 966	case NL80211_IFTYPE_AP:
 967	case NL80211_IFTYPE_MESH_POINT:
 968	case NL80211_IFTYPE_OCB:
 969		ieee80211_queue_work(&sdata->local->hw,
 970				     &sdata->csa_finalize_work);
 971		break;
 972	case NL80211_IFTYPE_STATION:
 973		ieee80211_queue_work(&sdata->local->hw,
 974				     &sdata->u.mgd.chswitch_work);
 975		break;
 976	case NL80211_IFTYPE_UNSPECIFIED:
 977	case NL80211_IFTYPE_AP_VLAN:
 978	case NL80211_IFTYPE_WDS:
 979	case NL80211_IFTYPE_MONITOR:
 980	case NL80211_IFTYPE_P2P_CLIENT:
 981	case NL80211_IFTYPE_P2P_GO:
 982	case NL80211_IFTYPE_P2P_DEVICE:
 
 983	case NUM_NL80211_IFTYPES:
 984		WARN_ON(1);
 985		break;
 986	}
 987}
 988
 989static void
 990ieee80211_vif_update_chandef(struct ieee80211_sub_if_data *sdata,
 991			     const struct cfg80211_chan_def *chandef)
 992{
 993	struct ieee80211_sub_if_data *vlan;
 994
 995	sdata->vif.bss_conf.chandef = *chandef;
 996
 997	if (sdata->vif.type != NL80211_IFTYPE_AP)
 998		return;
 999
1000	list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
1001		vlan->vif.bss_conf.chandef = *chandef;
1002}
1003
1004static int
1005ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
1006{
1007	struct ieee80211_local *local = sdata->local;
1008	struct ieee80211_vif_chanctx_switch vif_chsw[1] = {};
1009	struct ieee80211_chanctx *old_ctx, *new_ctx;
1010	const struct cfg80211_chan_def *chandef;
1011	u32 changed = 0;
1012	int err;
1013
1014	lockdep_assert_held(&local->mtx);
1015	lockdep_assert_held(&local->chanctx_mtx);
1016
1017	new_ctx = sdata->reserved_chanctx;
1018	old_ctx = ieee80211_vif_get_chanctx(sdata);
1019
1020	if (WARN_ON(!sdata->reserved_ready))
1021		return -EBUSY;
1022
1023	if (WARN_ON(!new_ctx))
1024		return -EINVAL;
1025
1026	if (WARN_ON(!old_ctx))
1027		return -EINVAL;
1028
1029	if (WARN_ON(new_ctx->replace_state ==
1030		    IEEE80211_CHANCTX_REPLACES_OTHER))
1031		return -EINVAL;
1032
1033	chandef = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
1034				&sdata->reserved_chandef);
1035	if (WARN_ON(!chandef))
1036		return -EINVAL;
1037
1038	ieee80211_change_chanctx(local, new_ctx, chandef);
 
 
 
 
 
1039
1040	vif_chsw[0].vif = &sdata->vif;
1041	vif_chsw[0].old_ctx = &old_ctx->conf;
1042	vif_chsw[0].new_ctx = &new_ctx->conf;
1043
1044	list_del(&sdata->reserved_chanctx_list);
1045	sdata->reserved_chanctx = NULL;
1046
1047	err = drv_switch_vif_chanctx(local, vif_chsw, 1,
1048				     CHANCTX_SWMODE_REASSIGN_VIF);
1049	if (err) {
1050		if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
1051			ieee80211_free_chanctx(local, new_ctx);
1052
1053		goto out;
1054	}
1055
1056	list_move(&sdata->assigned_chanctx_list, &new_ctx->assigned_vifs);
1057	rcu_assign_pointer(sdata->vif.chanctx_conf, &new_ctx->conf);
1058
1059	if (sdata->vif.type == NL80211_IFTYPE_AP)
1060		__ieee80211_vif_copy_chanctx_to_vlans(sdata, false);
1061
1062	ieee80211_check_fast_xmit_iface(sdata);
1063
1064	if (ieee80211_chanctx_refcount(local, old_ctx) == 0)
1065		ieee80211_free_chanctx(local, old_ctx);
1066
1067	if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width)
1068		changed = BSS_CHANGED_BANDWIDTH;
1069
1070	ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
1071
1072	ieee80211_recalc_smps_chanctx(local, new_ctx);
1073	ieee80211_recalc_radar_chanctx(local, new_ctx);
1074	ieee80211_recalc_chanctx_min_def(local, new_ctx);
1075
1076	if (changed)
1077		ieee80211_bss_info_change_notify(sdata, changed);
1078
1079out:
1080	ieee80211_vif_chanctx_reservation_complete(sdata);
1081	return err;
1082}
1083
1084static int
1085ieee80211_vif_use_reserved_assign(struct ieee80211_sub_if_data *sdata)
1086{
1087	struct ieee80211_local *local = sdata->local;
1088	struct ieee80211_chanctx *old_ctx, *new_ctx;
1089	const struct cfg80211_chan_def *chandef;
1090	int err;
1091
1092	old_ctx = ieee80211_vif_get_chanctx(sdata);
1093	new_ctx = sdata->reserved_chanctx;
1094
1095	if (WARN_ON(!sdata->reserved_ready))
1096		return -EINVAL;
1097
1098	if (WARN_ON(old_ctx))
1099		return -EINVAL;
1100
1101	if (WARN_ON(!new_ctx))
1102		return -EINVAL;
1103
1104	if (WARN_ON(new_ctx->replace_state ==
1105		    IEEE80211_CHANCTX_REPLACES_OTHER))
1106		return -EINVAL;
1107
1108	chandef = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
1109				&sdata->reserved_chandef);
1110	if (WARN_ON(!chandef))
1111		return -EINVAL;
1112
1113	ieee80211_change_chanctx(local, new_ctx, chandef);
1114
1115	list_del(&sdata->reserved_chanctx_list);
1116	sdata->reserved_chanctx = NULL;
1117
1118	err = ieee80211_assign_vif_chanctx(sdata, new_ctx);
1119	if (err) {
1120		if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
1121			ieee80211_free_chanctx(local, new_ctx);
1122
1123		goto out;
1124	}
1125
1126out:
1127	ieee80211_vif_chanctx_reservation_complete(sdata);
1128	return err;
1129}
1130
1131static bool
1132ieee80211_vif_has_in_place_reservation(struct ieee80211_sub_if_data *sdata)
1133{
1134	struct ieee80211_chanctx *old_ctx, *new_ctx;
1135
1136	lockdep_assert_held(&sdata->local->chanctx_mtx);
1137
1138	new_ctx = sdata->reserved_chanctx;
1139	old_ctx = ieee80211_vif_get_chanctx(sdata);
1140
1141	if (!old_ctx)
1142		return false;
1143
1144	if (WARN_ON(!new_ctx))
1145		return false;
1146
1147	if (old_ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED)
1148		return false;
1149
1150	if (new_ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1151		return false;
1152
1153	return true;
1154}
1155
1156static int ieee80211_chsw_switch_hwconf(struct ieee80211_local *local,
1157					struct ieee80211_chanctx *new_ctx)
1158{
1159	const struct cfg80211_chan_def *chandef;
1160
1161	lockdep_assert_held(&local->mtx);
1162	lockdep_assert_held(&local->chanctx_mtx);
1163
1164	chandef = ieee80211_chanctx_reserved_chandef(local, new_ctx, NULL);
1165	if (WARN_ON(!chandef))
1166		return -EINVAL;
1167
1168	local->hw.conf.radar_enabled = new_ctx->conf.radar_enabled;
1169	local->_oper_chandef = *chandef;
1170	ieee80211_hw_config(local, 0);
1171
1172	return 0;
1173}
1174
1175static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local,
1176				      int n_vifs)
1177{
1178	struct ieee80211_vif_chanctx_switch *vif_chsw;
1179	struct ieee80211_sub_if_data *sdata;
1180	struct ieee80211_chanctx *ctx, *old_ctx;
1181	int i, err;
1182
1183	lockdep_assert_held(&local->mtx);
1184	lockdep_assert_held(&local->chanctx_mtx);
1185
1186	vif_chsw = kzalloc(sizeof(vif_chsw[0]) * n_vifs, GFP_KERNEL);
1187	if (!vif_chsw)
1188		return -ENOMEM;
1189
1190	i = 0;
1191	list_for_each_entry(ctx, &local->chanctx_list, list) {
1192		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1193			continue;
1194
1195		if (WARN_ON(!ctx->replace_ctx)) {
1196			err = -EINVAL;
1197			goto out;
1198		}
1199
1200		list_for_each_entry(sdata, &ctx->reserved_vifs,
1201				    reserved_chanctx_list) {
1202			if (!ieee80211_vif_has_in_place_reservation(
1203					sdata))
1204				continue;
1205
1206			old_ctx = ieee80211_vif_get_chanctx(sdata);
1207			vif_chsw[i].vif = &sdata->vif;
1208			vif_chsw[i].old_ctx = &old_ctx->conf;
1209			vif_chsw[i].new_ctx = &ctx->conf;
1210
1211			i++;
1212		}
1213	}
1214
1215	err = drv_switch_vif_chanctx(local, vif_chsw, n_vifs,
1216				     CHANCTX_SWMODE_SWAP_CONTEXTS);
1217
1218out:
1219	kfree(vif_chsw);
1220	return err;
1221}
1222
1223static int ieee80211_chsw_switch_ctxs(struct ieee80211_local *local)
1224{
1225	struct ieee80211_chanctx *ctx;
1226	int err;
1227
1228	lockdep_assert_held(&local->mtx);
1229	lockdep_assert_held(&local->chanctx_mtx);
1230
1231	list_for_each_entry(ctx, &local->chanctx_list, list) {
1232		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1233			continue;
1234
1235		if (!list_empty(&ctx->replace_ctx->assigned_vifs))
1236			continue;
1237
1238		ieee80211_del_chanctx(local, ctx->replace_ctx);
1239		err = ieee80211_add_chanctx(local, ctx);
1240		if (err)
1241			goto err;
1242	}
1243
1244	return 0;
1245
1246err:
1247	WARN_ON(ieee80211_add_chanctx(local, ctx));
1248	list_for_each_entry_continue_reverse(ctx, &local->chanctx_list, list) {
1249		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1250			continue;
1251
1252		if (!list_empty(&ctx->replace_ctx->assigned_vifs))
1253			continue;
1254
1255		ieee80211_del_chanctx(local, ctx);
1256		WARN_ON(ieee80211_add_chanctx(local, ctx->replace_ctx));
1257	}
1258
1259	return err;
1260}
1261
1262static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
1263{
1264	struct ieee80211_sub_if_data *sdata, *sdata_tmp;
1265	struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx;
1266	struct ieee80211_chanctx *new_ctx = NULL;
1267	int i, err, n_assigned, n_reserved, n_ready;
1268	int n_ctx = 0, n_vifs_switch = 0, n_vifs_assign = 0, n_vifs_ctxless = 0;
1269
1270	lockdep_assert_held(&local->mtx);
1271	lockdep_assert_held(&local->chanctx_mtx);
1272
1273	/*
1274	 * If there are 2 independent pairs of channel contexts performing
1275	 * cross-switch of their vifs this code will still wait until both are
1276	 * ready even though it could be possible to switch one before the
1277	 * other is ready.
1278	 *
1279	 * For practical reasons and code simplicity just do a single huge
1280	 * switch.
1281	 */
1282
1283	/*
1284	 * Verify if the reservation is still feasible.
1285	 *  - if it's not then disconnect
1286	 *  - if it is but not all vifs necessary are ready then defer
1287	 */
1288
1289	list_for_each_entry(ctx, &local->chanctx_list, list) {
1290		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1291			continue;
1292
1293		if (WARN_ON(!ctx->replace_ctx)) {
1294			err = -EINVAL;
1295			goto err;
1296		}
1297
1298		if (!local->use_chanctx)
1299			new_ctx = ctx;
1300
1301		n_ctx++;
1302
1303		n_assigned = 0;
1304		n_reserved = 0;
1305		n_ready = 0;
1306
1307		list_for_each_entry(sdata, &ctx->replace_ctx->assigned_vifs,
1308				    assigned_chanctx_list) {
1309			n_assigned++;
1310			if (sdata->reserved_chanctx) {
1311				n_reserved++;
1312				if (sdata->reserved_ready)
1313					n_ready++;
1314			}
1315		}
1316
1317		if (n_assigned != n_reserved) {
1318			if (n_ready == n_reserved) {
1319				wiphy_info(local->hw.wiphy,
1320					   "channel context reservation cannot be finalized because some interfaces aren't switching\n");
1321				err = -EBUSY;
1322				goto err;
1323			}
1324
1325			return -EAGAIN;
1326		}
1327
1328		ctx->conf.radar_enabled = false;
1329		list_for_each_entry(sdata, &ctx->reserved_vifs,
1330				    reserved_chanctx_list) {
1331			if (ieee80211_vif_has_in_place_reservation(sdata) &&
1332			    !sdata->reserved_ready)
1333				return -EAGAIN;
1334
1335			old_ctx = ieee80211_vif_get_chanctx(sdata);
1336			if (old_ctx) {
1337				if (old_ctx->replace_state ==
1338				    IEEE80211_CHANCTX_WILL_BE_REPLACED)
1339					n_vifs_switch++;
1340				else
1341					n_vifs_assign++;
1342			} else {
1343				n_vifs_ctxless++;
1344			}
1345
1346			if (sdata->reserved_radar_required)
1347				ctx->conf.radar_enabled = true;
1348		}
1349	}
1350
1351	if (WARN_ON(n_ctx == 0) ||
1352	    WARN_ON(n_vifs_switch == 0 &&
1353		    n_vifs_assign == 0 &&
1354		    n_vifs_ctxless == 0) ||
1355	    WARN_ON(n_ctx > 1 && !local->use_chanctx) ||
1356	    WARN_ON(!new_ctx && !local->use_chanctx)) {
1357		err = -EINVAL;
1358		goto err;
1359	}
1360
1361	/*
1362	 * All necessary vifs are ready. Perform the switch now depending on
1363	 * reservations and driver capabilities.
1364	 */
1365
1366	if (local->use_chanctx) {
1367		if (n_vifs_switch > 0) {
1368			err = ieee80211_chsw_switch_vifs(local, n_vifs_switch);
1369			if (err)
1370				goto err;
1371		}
1372
1373		if (n_vifs_assign > 0 || n_vifs_ctxless > 0) {
1374			err = ieee80211_chsw_switch_ctxs(local);
1375			if (err)
1376				goto err;
1377		}
1378	} else {
1379		err = ieee80211_chsw_switch_hwconf(local, new_ctx);
1380		if (err)
1381			goto err;
1382	}
1383
1384	/*
1385	 * Update all structures, values and pointers to point to new channel
1386	 * context(s).
1387	 */
1388
1389	i = 0;
1390	list_for_each_entry(ctx, &local->chanctx_list, list) {
1391		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1392			continue;
1393
1394		if (WARN_ON(!ctx->replace_ctx)) {
1395			err = -EINVAL;
1396			goto err;
1397		}
1398
1399		list_for_each_entry(sdata, &ctx->reserved_vifs,
1400				    reserved_chanctx_list) {
1401			u32 changed = 0;
1402
1403			if (!ieee80211_vif_has_in_place_reservation(sdata))
1404				continue;
1405
1406			rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf);
1407
1408			if (sdata->vif.type == NL80211_IFTYPE_AP)
1409				__ieee80211_vif_copy_chanctx_to_vlans(sdata,
1410								      false);
1411
1412			ieee80211_check_fast_xmit_iface(sdata);
1413
1414			sdata->radar_required = sdata->reserved_radar_required;
1415
1416			if (sdata->vif.bss_conf.chandef.width !=
1417			    sdata->reserved_chandef.width)
1418				changed = BSS_CHANGED_BANDWIDTH;
1419
1420			ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
1421			if (changed)
1422				ieee80211_bss_info_change_notify(sdata,
1423								 changed);
1424
1425			ieee80211_recalc_txpower(sdata, false);
1426		}
1427
1428		ieee80211_recalc_chanctx_chantype(local, ctx);
1429		ieee80211_recalc_smps_chanctx(local, ctx);
1430		ieee80211_recalc_radar_chanctx(local, ctx);
1431		ieee80211_recalc_chanctx_min_def(local, ctx);
1432
1433		list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1434					 reserved_chanctx_list) {
1435			if (ieee80211_vif_get_chanctx(sdata) != ctx)
1436				continue;
1437
1438			list_del(&sdata->reserved_chanctx_list);
1439			list_move(&sdata->assigned_chanctx_list,
1440				  &ctx->assigned_vifs);
1441			sdata->reserved_chanctx = NULL;
1442
1443			ieee80211_vif_chanctx_reservation_complete(sdata);
1444		}
1445
1446		/*
1447		 * This context might have been a dependency for an already
1448		 * ready re-assign reservation interface that was deferred. Do
1449		 * not propagate error to the caller though. The in-place
1450		 * reservation for originally requested interface has already
1451		 * succeeded at this point.
1452		 */
1453		list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1454					 reserved_chanctx_list) {
1455			if (WARN_ON(ieee80211_vif_has_in_place_reservation(
1456					sdata)))
1457				continue;
1458
1459			if (WARN_ON(sdata->reserved_chanctx != ctx))
1460				continue;
1461
1462			if (!sdata->reserved_ready)
1463				continue;
1464
1465			if (ieee80211_vif_get_chanctx(sdata))
1466				err = ieee80211_vif_use_reserved_reassign(
1467						sdata);
1468			else
1469				err = ieee80211_vif_use_reserved_assign(sdata);
1470
1471			if (err) {
1472				sdata_info(sdata,
1473					   "failed to finalize (re-)assign reservation (err=%d)\n",
1474					   err);
1475				ieee80211_vif_unreserve_chanctx(sdata);
1476				cfg80211_stop_iface(local->hw.wiphy,
1477						    &sdata->wdev,
1478						    GFP_KERNEL);
1479			}
1480		}
1481	}
1482
1483	/*
1484	 * Finally free old contexts
1485	 */
1486
1487	list_for_each_entry_safe(ctx, ctx_tmp, &local->chanctx_list, list) {
1488		if (ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED)
1489			continue;
1490
1491		ctx->replace_ctx->replace_ctx = NULL;
1492		ctx->replace_ctx->replace_state =
1493				IEEE80211_CHANCTX_REPLACE_NONE;
1494
1495		list_del_rcu(&ctx->list);
1496		kfree_rcu(ctx, rcu_head);
1497	}
1498
1499	return 0;
1500
1501err:
1502	list_for_each_entry(ctx, &local->chanctx_list, list) {
1503		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1504			continue;
1505
1506		list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1507					 reserved_chanctx_list) {
1508			ieee80211_vif_unreserve_chanctx(sdata);
1509			ieee80211_vif_chanctx_reservation_complete(sdata);
1510		}
1511	}
1512
1513	return err;
1514}
1515
1516static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
1517{
1518	struct ieee80211_local *local = sdata->local;
1519	struct ieee80211_chanctx_conf *conf;
1520	struct ieee80211_chanctx *ctx;
1521	bool use_reserved_switch = false;
1522
1523	lockdep_assert_held(&local->chanctx_mtx);
1524
1525	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1526					 lockdep_is_held(&local->chanctx_mtx));
1527	if (!conf)
1528		return;
1529
1530	ctx = container_of(conf, struct ieee80211_chanctx, conf);
1531
1532	if (sdata->reserved_chanctx) {
1533		if (sdata->reserved_chanctx->replace_state ==
1534		    IEEE80211_CHANCTX_REPLACES_OTHER &&
1535		    ieee80211_chanctx_num_reserved(local,
1536						   sdata->reserved_chanctx) > 1)
1537			use_reserved_switch = true;
1538
1539		ieee80211_vif_unreserve_chanctx(sdata);
1540	}
1541
1542	ieee80211_assign_vif_chanctx(sdata, NULL);
1543	if (ieee80211_chanctx_refcount(local, ctx) == 0)
1544		ieee80211_free_chanctx(local, ctx);
1545
1546	sdata->radar_required = false;
1547
1548	/* Unreserving may ready an in-place reservation. */
1549	if (use_reserved_switch)
1550		ieee80211_vif_use_reserved_switch(local);
1551}
1552
1553int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
1554			      const struct cfg80211_chan_def *chandef,
1555			      enum ieee80211_chanctx_mode mode)
1556{
1557	struct ieee80211_local *local = sdata->local;
1558	struct ieee80211_chanctx *ctx;
1559	u8 radar_detect_width = 0;
1560	int ret;
1561
1562	lockdep_assert_held(&local->mtx);
1563
1564	WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev));
1565
1566	mutex_lock(&local->chanctx_mtx);
1567
1568	ret = cfg80211_chandef_dfs_required(local->hw.wiphy,
1569					    chandef,
1570					    sdata->wdev.iftype);
1571	if (ret < 0)
1572		goto out;
1573	if (ret > 0)
1574		radar_detect_width = BIT(chandef->width);
1575
1576	sdata->radar_required = ret;
1577
1578	ret = ieee80211_check_combinations(sdata, chandef, mode,
1579					   radar_detect_width);
1580	if (ret < 0)
1581		goto out;
1582
1583	__ieee80211_vif_release_channel(sdata);
1584
1585	ctx = ieee80211_find_chanctx(local, chandef, mode);
1586	if (!ctx)
1587		ctx = ieee80211_new_chanctx(local, chandef, mode);
1588	if (IS_ERR(ctx)) {
1589		ret = PTR_ERR(ctx);
1590		goto out;
1591	}
1592
1593	ieee80211_vif_update_chandef(sdata, chandef);
1594
1595	ret = ieee80211_assign_vif_chanctx(sdata, ctx);
1596	if (ret) {
1597		/* if assign fails refcount stays the same */
1598		if (ieee80211_chanctx_refcount(local, ctx) == 0)
1599			ieee80211_free_chanctx(local, ctx);
1600		goto out;
1601	}
1602
1603	ieee80211_recalc_smps_chanctx(local, ctx);
1604	ieee80211_recalc_radar_chanctx(local, ctx);
1605 out:
1606	if (ret)
1607		sdata->radar_required = false;
1608
1609	mutex_unlock(&local->chanctx_mtx);
1610	return ret;
1611}
1612
1613int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata)
1614{
1615	struct ieee80211_local *local = sdata->local;
1616	struct ieee80211_chanctx *new_ctx;
1617	struct ieee80211_chanctx *old_ctx;
1618	int err;
1619
1620	lockdep_assert_held(&local->mtx);
1621	lockdep_assert_held(&local->chanctx_mtx);
1622
1623	new_ctx = sdata->reserved_chanctx;
1624	old_ctx = ieee80211_vif_get_chanctx(sdata);
1625
1626	if (WARN_ON(!new_ctx))
1627		return -EINVAL;
1628
1629	if (WARN_ON(new_ctx->replace_state ==
1630		    IEEE80211_CHANCTX_WILL_BE_REPLACED))
1631		return -EINVAL;
1632
1633	if (WARN_ON(sdata->reserved_ready))
1634		return -EINVAL;
1635
1636	sdata->reserved_ready = true;
1637
1638	if (new_ctx->replace_state == IEEE80211_CHANCTX_REPLACE_NONE) {
1639		if (old_ctx)
1640			err = ieee80211_vif_use_reserved_reassign(sdata);
1641		else
1642			err = ieee80211_vif_use_reserved_assign(sdata);
1643
1644		if (err)
1645			return err;
1646	}
1647
1648	/*
1649	 * In-place reservation may need to be finalized now either if:
1650	 *  a) sdata is taking part in the swapping itself and is the last one
1651	 *  b) sdata has switched with a re-assign reservation to an existing
1652	 *     context readying in-place switching of old_ctx
1653	 *
1654	 * In case of (b) do not propagate the error up because the requested
1655	 * sdata already switched successfully. Just spill an extra warning.
1656	 * The ieee80211_vif_use_reserved_switch() already stops all necessary
1657	 * interfaces upon failure.
1658	 */
1659	if ((old_ctx &&
1660	     old_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
1661	    new_ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
1662		err = ieee80211_vif_use_reserved_switch(local);
1663		if (err && err != -EAGAIN) {
1664			if (new_ctx->replace_state ==
1665			    IEEE80211_CHANCTX_REPLACES_OTHER)
1666				return err;
1667
1668			wiphy_info(local->hw.wiphy,
1669				   "depending in-place reservation failed (err=%d)\n",
1670				   err);
1671		}
1672	}
1673
1674	return 0;
1675}
1676
1677int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
1678				   const struct cfg80211_chan_def *chandef,
1679				   u32 *changed)
1680{
1681	struct ieee80211_local *local = sdata->local;
1682	struct ieee80211_chanctx_conf *conf;
1683	struct ieee80211_chanctx *ctx;
1684	const struct cfg80211_chan_def *compat;
1685	int ret;
1686
1687	if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
1688				     IEEE80211_CHAN_DISABLED))
1689		return -EINVAL;
1690
1691	mutex_lock(&local->chanctx_mtx);
1692	if (cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef)) {
1693		ret = 0;
1694		goto out;
1695	}
1696
1697	if (chandef->width == NL80211_CHAN_WIDTH_20_NOHT ||
1698	    sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) {
1699		ret = -EINVAL;
1700		goto out;
1701	}
1702
1703	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1704					 lockdep_is_held(&local->chanctx_mtx));
1705	if (!conf) {
1706		ret = -EINVAL;
1707		goto out;
1708	}
1709
1710	ctx = container_of(conf, struct ieee80211_chanctx, conf);
1711
1712	compat = cfg80211_chandef_compatible(&conf->def, chandef);
1713	if (!compat) {
1714		ret = -EINVAL;
1715		goto out;
1716	}
1717
1718	switch (ctx->replace_state) {
1719	case IEEE80211_CHANCTX_REPLACE_NONE:
1720		if (!ieee80211_chanctx_reserved_chandef(local, ctx, compat)) {
1721			ret = -EBUSY;
1722			goto out;
1723		}
1724		break;
1725	case IEEE80211_CHANCTX_WILL_BE_REPLACED:
1726		/* TODO: Perhaps the bandwidth change could be treated as a
1727		 * reservation itself? */
1728		ret = -EBUSY;
1729		goto out;
1730	case IEEE80211_CHANCTX_REPLACES_OTHER:
1731		/* channel context that is going to replace another channel
1732		 * context doesn't really exist and shouldn't be assigned
1733		 * anywhere yet */
1734		WARN_ON(1);
1735		break;
1736	}
1737
1738	ieee80211_vif_update_chandef(sdata, chandef);
1739
1740	ieee80211_recalc_chanctx_chantype(local, ctx);
1741
1742	*changed |= BSS_CHANGED_BANDWIDTH;
1743	ret = 0;
1744 out:
1745	mutex_unlock(&local->chanctx_mtx);
1746	return ret;
1747}
1748
1749void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
1750{
1751	WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev));
1752
1753	lockdep_assert_held(&sdata->local->mtx);
1754
1755	mutex_lock(&sdata->local->chanctx_mtx);
1756	__ieee80211_vif_release_channel(sdata);
1757	mutex_unlock(&sdata->local->chanctx_mtx);
1758}
1759
1760void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata)
1761{
1762	struct ieee80211_local *local = sdata->local;
1763	struct ieee80211_sub_if_data *ap;
1764	struct ieee80211_chanctx_conf *conf;
1765
1766	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss))
1767		return;
1768
1769	ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
1770
1771	mutex_lock(&local->chanctx_mtx);
1772
1773	conf = rcu_dereference_protected(ap->vif.chanctx_conf,
1774					 lockdep_is_held(&local->chanctx_mtx));
1775	rcu_assign_pointer(sdata->vif.chanctx_conf, conf);
1776	mutex_unlock(&local->chanctx_mtx);
1777}
1778
1779void ieee80211_iter_chan_contexts_atomic(
1780	struct ieee80211_hw *hw,
1781	void (*iter)(struct ieee80211_hw *hw,
1782		     struct ieee80211_chanctx_conf *chanctx_conf,
1783		     void *data),
1784	void *iter_data)
1785{
1786	struct ieee80211_local *local = hw_to_local(hw);
1787	struct ieee80211_chanctx *ctx;
1788
1789	rcu_read_lock();
1790	list_for_each_entry_rcu(ctx, &local->chanctx_list, list)
1791		if (ctx->driver_present)
1792			iter(hw, &ctx->conf, iter_data);
1793	rcu_read_unlock();
1794}
1795EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic);