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) 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 return; 348 349 WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef)); 350 351 ctx->conf.def = *chandef; 352 drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH); 353 ieee80211_recalc_chanctx_min_def(local, ctx); 354 355 if (!local->use_chanctx) { 356 local->_oper_chandef = *chandef; 357 ieee80211_hw_config(local, 0); 358 } 359} 360 361static struct ieee80211_chanctx * 362ieee80211_find_chanctx(struct ieee80211_local *local, 363 const struct cfg80211_chan_def *chandef, 364 enum ieee80211_chanctx_mode mode) 365{ 366 struct ieee80211_chanctx *ctx; 367 368 lockdep_assert_held(&local->chanctx_mtx); 369 370 if (mode == IEEE80211_CHANCTX_EXCLUSIVE) 371 return NULL; 372 373 list_for_each_entry(ctx, &local->chanctx_list, list) { 374 const struct cfg80211_chan_def *compat; 375 376 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACE_NONE) 377 continue; 378 379 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) 380 continue; 381 382 compat = cfg80211_chandef_compatible(&ctx->conf.def, chandef); 383 if (!compat) 384 continue; 385 386 compat = ieee80211_chanctx_reserved_chandef(local, ctx, 387 compat); 388 if (!compat) 389 continue; 390 391 ieee80211_change_chanctx(local, ctx, compat); 392 393 return ctx; 394 } 395 396 return NULL; 397} 398 399bool ieee80211_is_radar_required(struct ieee80211_local *local) 400{ 401 struct ieee80211_sub_if_data *sdata; 402 403 lockdep_assert_held(&local->mtx); 404 405 rcu_read_lock(); 406 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 407 if (sdata->radar_required) { 408 rcu_read_unlock(); 409 return true; 410 } 411 } 412 rcu_read_unlock(); 413 414 return false; 415} 416 417static bool 418ieee80211_chanctx_radar_required(struct ieee80211_local *local, 419 struct ieee80211_chanctx *ctx) 420{ 421 struct ieee80211_chanctx_conf *conf = &ctx->conf; 422 struct ieee80211_sub_if_data *sdata; 423 bool required = false; 424 425 lockdep_assert_held(&local->chanctx_mtx); 426 lockdep_assert_held(&local->mtx); 427 428 rcu_read_lock(); 429 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 430 if (!ieee80211_sdata_running(sdata)) 431 continue; 432 if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) 433 continue; 434 if (!sdata->radar_required) 435 continue; 436 437 required = true; 438 break; 439 } 440 rcu_read_unlock(); 441 442 return required; 443} 444 445static struct ieee80211_chanctx * 446ieee80211_alloc_chanctx(struct ieee80211_local *local, 447 const struct cfg80211_chan_def *chandef, 448 enum ieee80211_chanctx_mode mode) 449{ 450 struct ieee80211_chanctx *ctx; 451 452 lockdep_assert_held(&local->chanctx_mtx); 453 454 ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL); 455 if (!ctx) 456 return NULL; 457 458 INIT_LIST_HEAD(&ctx->assigned_vifs); 459 INIT_LIST_HEAD(&ctx->reserved_vifs); 460 ctx->conf.def = *chandef; 461 ctx->conf.rx_chains_static = 1; 462 ctx->conf.rx_chains_dynamic = 1; 463 ctx->mode = mode; 464 ctx->conf.radar_enabled = false; 465 ieee80211_recalc_chanctx_min_def(local, ctx); 466 467 return ctx; 468} 469 470static int ieee80211_add_chanctx(struct ieee80211_local *local, 471 struct ieee80211_chanctx *ctx) 472{ 473 u32 changed; 474 int err; 475 476 lockdep_assert_held(&local->mtx); 477 lockdep_assert_held(&local->chanctx_mtx); 478 479 if (!local->use_chanctx) 480 local->hw.conf.radar_enabled = ctx->conf.radar_enabled; 481 482 /* turn idle off *before* setting channel -- some drivers need that */ 483 changed = ieee80211_idle_off(local); 484 if (changed) 485 ieee80211_hw_config(local, changed); 486 487 if (!local->use_chanctx) { 488 local->_oper_chandef = ctx->conf.def; 489 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 490 } else { 491 err = drv_add_chanctx(local, ctx); 492 if (err) { 493 ieee80211_recalc_idle(local); 494 return err; 495 } 496 } 497 498 return 0; 499} 500 501static struct ieee80211_chanctx * 502ieee80211_new_chanctx(struct ieee80211_local *local, 503 const struct cfg80211_chan_def *chandef, 504 enum ieee80211_chanctx_mode mode) 505{ 506 struct ieee80211_chanctx *ctx; 507 int err; 508 509 lockdep_assert_held(&local->mtx); 510 lockdep_assert_held(&local->chanctx_mtx); 511 512 ctx = ieee80211_alloc_chanctx(local, chandef, mode); 513 if (!ctx) 514 return ERR_PTR(-ENOMEM); 515 516 err = ieee80211_add_chanctx(local, ctx); 517 if (err) { 518 kfree(ctx); 519 return ERR_PTR(err); 520 } 521 522 list_add_rcu(&ctx->list, &local->chanctx_list); 523 return ctx; 524} 525 526static void ieee80211_del_chanctx(struct ieee80211_local *local, 527 struct ieee80211_chanctx *ctx) 528{ 529 lockdep_assert_held(&local->chanctx_mtx); 530 531 if (!local->use_chanctx) { 532 struct cfg80211_chan_def *chandef = &local->_oper_chandef; 533 chandef->width = NL80211_CHAN_WIDTH_20_NOHT; 534 chandef->center_freq1 = chandef->chan->center_freq; 535 chandef->center_freq2 = 0; 536 537 /* NOTE: Disabling radar is only valid here for 538 * single channel context. To be sure, check it ... 539 */ 540 WARN_ON(local->hw.conf.radar_enabled && 541 !list_empty(&local->chanctx_list)); 542 543 local->hw.conf.radar_enabled = false; 544 545 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 546 } else { 547 drv_remove_chanctx(local, ctx); 548 } 549 550 ieee80211_recalc_idle(local); 551} 552 553static void ieee80211_free_chanctx(struct ieee80211_local *local, 554 struct ieee80211_chanctx *ctx) 555{ 556 lockdep_assert_held(&local->chanctx_mtx); 557 558 WARN_ON_ONCE(ieee80211_chanctx_refcount(local, ctx) != 0); 559 560 list_del_rcu(&ctx->list); 561 ieee80211_del_chanctx(local, ctx); 562 kfree_rcu(ctx, rcu_head); 563} 564 565void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, 566 struct ieee80211_chanctx *ctx) 567{ 568 struct ieee80211_chanctx_conf *conf = &ctx->conf; 569 struct ieee80211_sub_if_data *sdata; 570 const struct cfg80211_chan_def *compat = NULL; 571 struct sta_info *sta; 572 573 lockdep_assert_held(&local->chanctx_mtx); 574 575 rcu_read_lock(); 576 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 577 578 if (!ieee80211_sdata_running(sdata)) 579 continue; 580 if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) 581 continue; 582 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 583 continue; 584 585 if (!compat) 586 compat = &sdata->vif.bss_conf.chandef; 587 588 compat = cfg80211_chandef_compatible( 589 &sdata->vif.bss_conf.chandef, compat); 590 if (WARN_ON_ONCE(!compat)) 591 break; 592 } 593 594 /* TDLS peers can sometimes affect the chandef width */ 595 list_for_each_entry_rcu(sta, &local->sta_list, list) { 596 if (!sta->uploaded || 597 !test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW) || 598 !test_sta_flag(sta, WLAN_STA_AUTHORIZED) || 599 !sta->tdls_chandef.chan) 600 continue; 601 602 compat = cfg80211_chandef_compatible(&sta->tdls_chandef, 603 compat); 604 if (WARN_ON_ONCE(!compat)) 605 break; 606 } 607 rcu_read_unlock(); 608 609 if (!compat) 610 return; 611 612 ieee80211_change_chanctx(local, ctx, compat); 613} 614 615static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, 616 struct ieee80211_chanctx *chanctx) 617{ 618 bool radar_enabled; 619 620 lockdep_assert_held(&local->chanctx_mtx); 621 /* for ieee80211_is_radar_required */ 622 lockdep_assert_held(&local->mtx); 623 624 radar_enabled = ieee80211_chanctx_radar_required(local, chanctx); 625 626 if (radar_enabled == chanctx->conf.radar_enabled) 627 return; 628 629 chanctx->conf.radar_enabled = radar_enabled; 630 631 if (!local->use_chanctx) { 632 local->hw.conf.radar_enabled = chanctx->conf.radar_enabled; 633 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 634 } 635 636 drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR); 637} 638 639static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, 640 struct ieee80211_chanctx *new_ctx) 641{ 642 struct ieee80211_local *local = sdata->local; 643 struct ieee80211_chanctx_conf *conf; 644 struct ieee80211_chanctx *curr_ctx = NULL; 645 int ret = 0; 646 647 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 648 lockdep_is_held(&local->chanctx_mtx)); 649 650 if (conf) { 651 curr_ctx = container_of(conf, struct ieee80211_chanctx, conf); 652 653 drv_unassign_vif_chanctx(local, sdata, curr_ctx); 654 conf = NULL; 655 list_del(&sdata->assigned_chanctx_list); 656 } 657 658 if (new_ctx) { 659 ret = drv_assign_vif_chanctx(local, sdata, new_ctx); 660 if (ret) 661 goto out; 662 663 conf = &new_ctx->conf; 664 list_add(&sdata->assigned_chanctx_list, 665 &new_ctx->assigned_vifs); 666 } 667 668out: 669 rcu_assign_pointer(sdata->vif.chanctx_conf, conf); 670 671 sdata->vif.bss_conf.idle = !conf; 672 673 if (curr_ctx && ieee80211_chanctx_num_assigned(local, curr_ctx) > 0) { 674 ieee80211_recalc_chanctx_chantype(local, curr_ctx); 675 ieee80211_recalc_smps_chanctx(local, curr_ctx); 676 ieee80211_recalc_radar_chanctx(local, curr_ctx); 677 ieee80211_recalc_chanctx_min_def(local, curr_ctx); 678 } 679 680 if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) { 681 ieee80211_recalc_txpower(sdata, false); 682 ieee80211_recalc_chanctx_min_def(local, new_ctx); 683 } 684 685 if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && 686 sdata->vif.type != NL80211_IFTYPE_MONITOR) 687 ieee80211_bss_info_change_notify(sdata, 688 BSS_CHANGED_IDLE); 689 690 ieee80211_check_fast_xmit_iface(sdata); 691 692 return ret; 693} 694 695void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, 696 struct ieee80211_chanctx *chanctx) 697{ 698 struct ieee80211_sub_if_data *sdata; 699 u8 rx_chains_static, rx_chains_dynamic; 700 701 lockdep_assert_held(&local->chanctx_mtx); 702 703 rx_chains_static = 1; 704 rx_chains_dynamic = 1; 705 706 rcu_read_lock(); 707 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 708 u8 needed_static, needed_dynamic; 709 710 if (!ieee80211_sdata_running(sdata)) 711 continue; 712 713 if (rcu_access_pointer(sdata->vif.chanctx_conf) != 714 &chanctx->conf) 715 continue; 716 717 switch (sdata->vif.type) { 718 case NL80211_IFTYPE_P2P_DEVICE: 719 continue; 720 case NL80211_IFTYPE_STATION: 721 if (!sdata->u.mgd.associated) 722 continue; 723 break; 724 case NL80211_IFTYPE_AP_VLAN: 725 continue; 726 case NL80211_IFTYPE_AP: 727 case NL80211_IFTYPE_ADHOC: 728 case NL80211_IFTYPE_WDS: 729 case NL80211_IFTYPE_MESH_POINT: 730 case NL80211_IFTYPE_OCB: 731 break; 732 default: 733 WARN_ON_ONCE(1); 734 } 735 736 switch (sdata->smps_mode) { 737 default: 738 WARN_ONCE(1, "Invalid SMPS mode %d\n", 739 sdata->smps_mode); 740 /* fall through */ 741 case IEEE80211_SMPS_OFF: 742 needed_static = sdata->needed_rx_chains; 743 needed_dynamic = sdata->needed_rx_chains; 744 break; 745 case IEEE80211_SMPS_DYNAMIC: 746 needed_static = 1; 747 needed_dynamic = sdata->needed_rx_chains; 748 break; 749 case IEEE80211_SMPS_STATIC: 750 needed_static = 1; 751 needed_dynamic = 1; 752 break; 753 } 754 755 rx_chains_static = max(rx_chains_static, needed_static); 756 rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic); 757 } 758 759 /* Disable SMPS for the monitor interface */ 760 sdata = rcu_dereference(local->monitor_sdata); 761 if (sdata && 762 rcu_access_pointer(sdata->vif.chanctx_conf) == &chanctx->conf) 763 rx_chains_dynamic = rx_chains_static = local->rx_chains; 764 765 rcu_read_unlock(); 766 767 if (!local->use_chanctx) { 768 if (rx_chains_static > 1) 769 local->smps_mode = IEEE80211_SMPS_OFF; 770 else if (rx_chains_dynamic > 1) 771 local->smps_mode = IEEE80211_SMPS_DYNAMIC; 772 else 773 local->smps_mode = IEEE80211_SMPS_STATIC; 774 ieee80211_hw_config(local, 0); 775 } 776 777 if (rx_chains_static == chanctx->conf.rx_chains_static && 778 rx_chains_dynamic == chanctx->conf.rx_chains_dynamic) 779 return; 780 781 chanctx->conf.rx_chains_static = rx_chains_static; 782 chanctx->conf.rx_chains_dynamic = rx_chains_dynamic; 783 drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS); 784} 785 786static void 787__ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, 788 bool clear) 789{ 790 struct ieee80211_local *local __maybe_unused = sdata->local; 791 struct ieee80211_sub_if_data *vlan; 792 struct ieee80211_chanctx_conf *conf; 793 794 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP)) 795 return; 796 797 lockdep_assert_held(&local->mtx); 798 799 /* Check that conf exists, even when clearing this function 800 * must be called with the AP's channel context still there 801 * as it would otherwise cause VLANs to have an invalid 802 * channel context pointer for a while, possibly pointing 803 * to a channel context that has already been freed. 804 */ 805 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 806 lockdep_is_held(&local->chanctx_mtx)); 807 WARN_ON(!conf); 808 809 if (clear) 810 conf = NULL; 811 812 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) 813 rcu_assign_pointer(vlan->vif.chanctx_conf, conf); 814} 815 816void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, 817 bool clear) 818{ 819 struct ieee80211_local *local = sdata->local; 820 821 mutex_lock(&local->chanctx_mtx); 822 823 __ieee80211_vif_copy_chanctx_to_vlans(sdata, clear); 824 825 mutex_unlock(&local->chanctx_mtx); 826} 827 828int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata) 829{ 830 struct ieee80211_chanctx *ctx = sdata->reserved_chanctx; 831 832 lockdep_assert_held(&sdata->local->chanctx_mtx); 833 834 if (WARN_ON(!ctx)) 835 return -EINVAL; 836 837 list_del(&sdata->reserved_chanctx_list); 838 sdata->reserved_chanctx = NULL; 839 840 if (ieee80211_chanctx_refcount(sdata->local, ctx) == 0) { 841 if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) { 842 if (WARN_ON(!ctx->replace_ctx)) 843 return -EINVAL; 844 845 WARN_ON(ctx->replace_ctx->replace_state != 846 IEEE80211_CHANCTX_WILL_BE_REPLACED); 847 WARN_ON(ctx->replace_ctx->replace_ctx != ctx); 848 849 ctx->replace_ctx->replace_ctx = NULL; 850 ctx->replace_ctx->replace_state = 851 IEEE80211_CHANCTX_REPLACE_NONE; 852 853 list_del_rcu(&ctx->list); 854 kfree_rcu(ctx, rcu_head); 855 } else { 856 ieee80211_free_chanctx(sdata->local, ctx); 857 } 858 } 859 860 return 0; 861} 862 863int ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata, 864 const struct cfg80211_chan_def *chandef, 865 enum ieee80211_chanctx_mode mode, 866 bool radar_required) 867{ 868 struct ieee80211_local *local = sdata->local; 869 struct ieee80211_chanctx *new_ctx, *curr_ctx, *ctx; 870 871 lockdep_assert_held(&local->chanctx_mtx); 872 873 curr_ctx = ieee80211_vif_get_chanctx(sdata); 874 if (curr_ctx && local->use_chanctx && !local->ops->switch_vif_chanctx) 875 return -ENOTSUPP; 876 877 new_ctx = ieee80211_find_reservation_chanctx(local, chandef, mode); 878 if (!new_ctx) { 879 if (ieee80211_can_create_new_chanctx(local)) { 880 new_ctx = ieee80211_new_chanctx(local, chandef, mode); 881 if (IS_ERR(new_ctx)) 882 return PTR_ERR(new_ctx); 883 } else { 884 if (!curr_ctx || 885 (curr_ctx->replace_state == 886 IEEE80211_CHANCTX_WILL_BE_REPLACED) || 887 !list_empty(&curr_ctx->reserved_vifs)) { 888 /* 889 * Another vif already requested this context 890 * for a reservation. Find another one hoping 891 * all vifs assigned to it will also switch 892 * soon enough. 893 * 894 * TODO: This needs a little more work as some 895 * cases (more than 2 chanctx capable devices) 896 * may fail which could otherwise succeed 897 * provided some channel context juggling was 898 * performed. 899 * 900 * Consider ctx1..3, vif1..6, each ctx has 2 901 * vifs. vif1 and vif2 from ctx1 request new 902 * different chandefs starting 2 in-place 903 * reserations with ctx4 and ctx5 replacing 904 * ctx1 and ctx2 respectively. Next vif5 and 905 * vif6 from ctx3 reserve ctx4. If vif3 and 906 * vif4 remain on ctx2 as they are then this 907 * fails unless `replace_ctx` from ctx5 is 908 * replaced with ctx3. 909 */ 910 list_for_each_entry(ctx, &local->chanctx_list, 911 list) { 912 if (ctx->replace_state != 913 IEEE80211_CHANCTX_REPLACE_NONE) 914 continue; 915 916 if (!list_empty(&ctx->reserved_vifs)) 917 continue; 918 919 curr_ctx = ctx; 920 break; 921 } 922 } 923 924 /* 925 * If that's true then all available contexts already 926 * have reservations and cannot be used. 927 */ 928 if (!curr_ctx || 929 (curr_ctx->replace_state == 930 IEEE80211_CHANCTX_WILL_BE_REPLACED) || 931 !list_empty(&curr_ctx->reserved_vifs)) 932 return -EBUSY; 933 934 new_ctx = ieee80211_alloc_chanctx(local, chandef, mode); 935 if (!new_ctx) 936 return -ENOMEM; 937 938 new_ctx->replace_ctx = curr_ctx; 939 new_ctx->replace_state = 940 IEEE80211_CHANCTX_REPLACES_OTHER; 941 942 curr_ctx->replace_ctx = new_ctx; 943 curr_ctx->replace_state = 944 IEEE80211_CHANCTX_WILL_BE_REPLACED; 945 946 list_add_rcu(&new_ctx->list, &local->chanctx_list); 947 } 948 } 949 950 list_add(&sdata->reserved_chanctx_list, &new_ctx->reserved_vifs); 951 sdata->reserved_chanctx = new_ctx; 952 sdata->reserved_chandef = *chandef; 953 sdata->reserved_radar_required = radar_required; 954 sdata->reserved_ready = false; 955 956 return 0; 957} 958 959static void 960ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata) 961{ 962 switch (sdata->vif.type) { 963 case NL80211_IFTYPE_ADHOC: 964 case NL80211_IFTYPE_AP: 965 case NL80211_IFTYPE_MESH_POINT: 966 case NL80211_IFTYPE_OCB: 967 ieee80211_queue_work(&sdata->local->hw, 968 &sdata->csa_finalize_work); 969 break; 970 case NL80211_IFTYPE_STATION: 971 ieee80211_queue_work(&sdata->local->hw, 972 &sdata->u.mgd.chswitch_work); 973 break; 974 case NL80211_IFTYPE_UNSPECIFIED: 975 case NL80211_IFTYPE_AP_VLAN: 976 case NL80211_IFTYPE_WDS: 977 case NL80211_IFTYPE_MONITOR: 978 case NL80211_IFTYPE_P2P_CLIENT: 979 case NL80211_IFTYPE_P2P_GO: 980 case NL80211_IFTYPE_P2P_DEVICE: 981 case NUM_NL80211_IFTYPES: 982 WARN_ON(1); 983 break; 984 } 985} 986 987static void 988ieee80211_vif_update_chandef(struct ieee80211_sub_if_data *sdata, 989 const struct cfg80211_chan_def *chandef) 990{ 991 struct ieee80211_sub_if_data *vlan; 992 993 sdata->vif.bss_conf.chandef = *chandef; 994 995 if (sdata->vif.type != NL80211_IFTYPE_AP) 996 return; 997 998 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) 999 vlan->vif.bss_conf.chandef = *chandef; 1000} 1001 1002static int 1003ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata) 1004{ 1005 struct ieee80211_local *local = sdata->local; 1006 struct ieee80211_vif_chanctx_switch vif_chsw[1] = {}; 1007 struct ieee80211_chanctx *old_ctx, *new_ctx; 1008 const struct cfg80211_chan_def *chandef; 1009 u32 changed = 0; 1010 int err; 1011 1012 lockdep_assert_held(&local->mtx); 1013 lockdep_assert_held(&local->chanctx_mtx); 1014 1015 new_ctx = sdata->reserved_chanctx; 1016 old_ctx = ieee80211_vif_get_chanctx(sdata); 1017 1018 if (WARN_ON(!sdata->reserved_ready)) 1019 return -EBUSY; 1020 1021 if (WARN_ON(!new_ctx)) 1022 return -EINVAL; 1023 1024 if (WARN_ON(!old_ctx)) 1025 return -EINVAL; 1026 1027 if (WARN_ON(new_ctx->replace_state == 1028 IEEE80211_CHANCTX_REPLACES_OTHER)) 1029 return -EINVAL; 1030 1031 chandef = ieee80211_chanctx_non_reserved_chandef(local, new_ctx, 1032 &sdata->reserved_chandef); 1033 if (WARN_ON(!chandef)) 1034 return -EINVAL; 1035 1036 ieee80211_change_chanctx(local, new_ctx, chandef); 1037 1038 vif_chsw[0].vif = &sdata->vif; 1039 vif_chsw[0].old_ctx = &old_ctx->conf; 1040 vif_chsw[0].new_ctx = &new_ctx->conf; 1041 1042 list_del(&sdata->reserved_chanctx_list); 1043 sdata->reserved_chanctx = NULL; 1044 1045 err = drv_switch_vif_chanctx(local, vif_chsw, 1, 1046 CHANCTX_SWMODE_REASSIGN_VIF); 1047 if (err) { 1048 if (ieee80211_chanctx_refcount(local, new_ctx) == 0) 1049 ieee80211_free_chanctx(local, new_ctx); 1050 1051 goto out; 1052 } 1053 1054 list_move(&sdata->assigned_chanctx_list, &new_ctx->assigned_vifs); 1055 rcu_assign_pointer(sdata->vif.chanctx_conf, &new_ctx->conf); 1056 1057 if (sdata->vif.type == NL80211_IFTYPE_AP) 1058 __ieee80211_vif_copy_chanctx_to_vlans(sdata, false); 1059 1060 ieee80211_check_fast_xmit_iface(sdata); 1061 1062 if (ieee80211_chanctx_refcount(local, old_ctx) == 0) 1063 ieee80211_free_chanctx(local, old_ctx); 1064 1065 if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width) 1066 changed = BSS_CHANGED_BANDWIDTH; 1067 1068 ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef); 1069 1070 ieee80211_recalc_smps_chanctx(local, new_ctx); 1071 ieee80211_recalc_radar_chanctx(local, new_ctx); 1072 ieee80211_recalc_chanctx_min_def(local, new_ctx); 1073 1074 if (changed) 1075 ieee80211_bss_info_change_notify(sdata, changed); 1076 1077out: 1078 ieee80211_vif_chanctx_reservation_complete(sdata); 1079 return err; 1080} 1081 1082static int 1083ieee80211_vif_use_reserved_assign(struct ieee80211_sub_if_data *sdata) 1084{ 1085 struct ieee80211_local *local = sdata->local; 1086 struct ieee80211_chanctx *old_ctx, *new_ctx; 1087 const struct cfg80211_chan_def *chandef; 1088 int err; 1089 1090 old_ctx = ieee80211_vif_get_chanctx(sdata); 1091 new_ctx = sdata->reserved_chanctx; 1092 1093 if (WARN_ON(!sdata->reserved_ready)) 1094 return -EINVAL; 1095 1096 if (WARN_ON(old_ctx)) 1097 return -EINVAL; 1098 1099 if (WARN_ON(!new_ctx)) 1100 return -EINVAL; 1101 1102 if (WARN_ON(new_ctx->replace_state == 1103 IEEE80211_CHANCTX_REPLACES_OTHER)) 1104 return -EINVAL; 1105 1106 chandef = ieee80211_chanctx_non_reserved_chandef(local, new_ctx, 1107 &sdata->reserved_chandef); 1108 if (WARN_ON(!chandef)) 1109 return -EINVAL; 1110 1111 ieee80211_change_chanctx(local, new_ctx, chandef); 1112 1113 list_del(&sdata->reserved_chanctx_list); 1114 sdata->reserved_chanctx = NULL; 1115 1116 err = ieee80211_assign_vif_chanctx(sdata, new_ctx); 1117 if (err) { 1118 if (ieee80211_chanctx_refcount(local, new_ctx) == 0) 1119 ieee80211_free_chanctx(local, new_ctx); 1120 1121 goto out; 1122 } 1123 1124out: 1125 ieee80211_vif_chanctx_reservation_complete(sdata); 1126 return err; 1127} 1128 1129static bool 1130ieee80211_vif_has_in_place_reservation(struct ieee80211_sub_if_data *sdata) 1131{ 1132 struct ieee80211_chanctx *old_ctx, *new_ctx; 1133 1134 lockdep_assert_held(&sdata->local->chanctx_mtx); 1135 1136 new_ctx = sdata->reserved_chanctx; 1137 old_ctx = ieee80211_vif_get_chanctx(sdata); 1138 1139 if (!old_ctx) 1140 return false; 1141 1142 if (WARN_ON(!new_ctx)) 1143 return false; 1144 1145 if (old_ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED) 1146 return false; 1147 1148 if (new_ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1149 return false; 1150 1151 return true; 1152} 1153 1154static int ieee80211_chsw_switch_hwconf(struct ieee80211_local *local, 1155 struct ieee80211_chanctx *new_ctx) 1156{ 1157 const struct cfg80211_chan_def *chandef; 1158 1159 lockdep_assert_held(&local->mtx); 1160 lockdep_assert_held(&local->chanctx_mtx); 1161 1162 chandef = ieee80211_chanctx_reserved_chandef(local, new_ctx, NULL); 1163 if (WARN_ON(!chandef)) 1164 return -EINVAL; 1165 1166 local->hw.conf.radar_enabled = new_ctx->conf.radar_enabled; 1167 local->_oper_chandef = *chandef; 1168 ieee80211_hw_config(local, 0); 1169 1170 return 0; 1171} 1172 1173static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local, 1174 int n_vifs) 1175{ 1176 struct ieee80211_vif_chanctx_switch *vif_chsw; 1177 struct ieee80211_sub_if_data *sdata; 1178 struct ieee80211_chanctx *ctx, *old_ctx; 1179 int i, err; 1180 1181 lockdep_assert_held(&local->mtx); 1182 lockdep_assert_held(&local->chanctx_mtx); 1183 1184 vif_chsw = kzalloc(sizeof(vif_chsw[0]) * n_vifs, GFP_KERNEL); 1185 if (!vif_chsw) 1186 return -ENOMEM; 1187 1188 i = 0; 1189 list_for_each_entry(ctx, &local->chanctx_list, list) { 1190 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1191 continue; 1192 1193 if (WARN_ON(!ctx->replace_ctx)) { 1194 err = -EINVAL; 1195 goto out; 1196 } 1197 1198 list_for_each_entry(sdata, &ctx->reserved_vifs, 1199 reserved_chanctx_list) { 1200 if (!ieee80211_vif_has_in_place_reservation( 1201 sdata)) 1202 continue; 1203 1204 old_ctx = ieee80211_vif_get_chanctx(sdata); 1205 vif_chsw[i].vif = &sdata->vif; 1206 vif_chsw[i].old_ctx = &old_ctx->conf; 1207 vif_chsw[i].new_ctx = &ctx->conf; 1208 1209 i++; 1210 } 1211 } 1212 1213 err = drv_switch_vif_chanctx(local, vif_chsw, n_vifs, 1214 CHANCTX_SWMODE_SWAP_CONTEXTS); 1215 1216out: 1217 kfree(vif_chsw); 1218 return err; 1219} 1220 1221static int ieee80211_chsw_switch_ctxs(struct ieee80211_local *local) 1222{ 1223 struct ieee80211_chanctx *ctx; 1224 int err; 1225 1226 lockdep_assert_held(&local->mtx); 1227 lockdep_assert_held(&local->chanctx_mtx); 1228 1229 list_for_each_entry(ctx, &local->chanctx_list, list) { 1230 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1231 continue; 1232 1233 if (!list_empty(&ctx->replace_ctx->assigned_vifs)) 1234 continue; 1235 1236 ieee80211_del_chanctx(local, ctx->replace_ctx); 1237 err = ieee80211_add_chanctx(local, ctx); 1238 if (err) 1239 goto err; 1240 } 1241 1242 return 0; 1243 1244err: 1245 WARN_ON(ieee80211_add_chanctx(local, ctx)); 1246 list_for_each_entry_continue_reverse(ctx, &local->chanctx_list, list) { 1247 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1248 continue; 1249 1250 if (!list_empty(&ctx->replace_ctx->assigned_vifs)) 1251 continue; 1252 1253 ieee80211_del_chanctx(local, ctx); 1254 WARN_ON(ieee80211_add_chanctx(local, ctx->replace_ctx)); 1255 } 1256 1257 return err; 1258} 1259 1260static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) 1261{ 1262 struct ieee80211_sub_if_data *sdata, *sdata_tmp; 1263 struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx; 1264 struct ieee80211_chanctx *new_ctx = NULL; 1265 int i, err, n_assigned, n_reserved, n_ready; 1266 int n_ctx = 0, n_vifs_switch = 0, n_vifs_assign = 0, n_vifs_ctxless = 0; 1267 1268 lockdep_assert_held(&local->mtx); 1269 lockdep_assert_held(&local->chanctx_mtx); 1270 1271 /* 1272 * If there are 2 independent pairs of channel contexts performing 1273 * cross-switch of their vifs this code will still wait until both are 1274 * ready even though it could be possible to switch one before the 1275 * other is ready. 1276 * 1277 * For practical reasons and code simplicity just do a single huge 1278 * switch. 1279 */ 1280 1281 /* 1282 * Verify if the reservation is still feasible. 1283 * - if it's not then disconnect 1284 * - if it is but not all vifs necessary are ready then defer 1285 */ 1286 1287 list_for_each_entry(ctx, &local->chanctx_list, list) { 1288 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1289 continue; 1290 1291 if (WARN_ON(!ctx->replace_ctx)) { 1292 err = -EINVAL; 1293 goto err; 1294 } 1295 1296 if (!local->use_chanctx) 1297 new_ctx = ctx; 1298 1299 n_ctx++; 1300 1301 n_assigned = 0; 1302 n_reserved = 0; 1303 n_ready = 0; 1304 1305 list_for_each_entry(sdata, &ctx->replace_ctx->assigned_vifs, 1306 assigned_chanctx_list) { 1307 n_assigned++; 1308 if (sdata->reserved_chanctx) { 1309 n_reserved++; 1310 if (sdata->reserved_ready) 1311 n_ready++; 1312 } 1313 } 1314 1315 if (n_assigned != n_reserved) { 1316 if (n_ready == n_reserved) { 1317 wiphy_info(local->hw.wiphy, 1318 "channel context reservation cannot be finalized because some interfaces aren't switching\n"); 1319 err = -EBUSY; 1320 goto err; 1321 } 1322 1323 return -EAGAIN; 1324 } 1325 1326 ctx->conf.radar_enabled = false; 1327 list_for_each_entry(sdata, &ctx->reserved_vifs, 1328 reserved_chanctx_list) { 1329 if (ieee80211_vif_has_in_place_reservation(sdata) && 1330 !sdata->reserved_ready) 1331 return -EAGAIN; 1332 1333 old_ctx = ieee80211_vif_get_chanctx(sdata); 1334 if (old_ctx) { 1335 if (old_ctx->replace_state == 1336 IEEE80211_CHANCTX_WILL_BE_REPLACED) 1337 n_vifs_switch++; 1338 else 1339 n_vifs_assign++; 1340 } else { 1341 n_vifs_ctxless++; 1342 } 1343 1344 if (sdata->reserved_radar_required) 1345 ctx->conf.radar_enabled = true; 1346 } 1347 } 1348 1349 if (WARN_ON(n_ctx == 0) || 1350 WARN_ON(n_vifs_switch == 0 && 1351 n_vifs_assign == 0 && 1352 n_vifs_ctxless == 0) || 1353 WARN_ON(n_ctx > 1 && !local->use_chanctx) || 1354 WARN_ON(!new_ctx && !local->use_chanctx)) { 1355 err = -EINVAL; 1356 goto err; 1357 } 1358 1359 /* 1360 * All necessary vifs are ready. Perform the switch now depending on 1361 * reservations and driver capabilities. 1362 */ 1363 1364 if (local->use_chanctx) { 1365 if (n_vifs_switch > 0) { 1366 err = ieee80211_chsw_switch_vifs(local, n_vifs_switch); 1367 if (err) 1368 goto err; 1369 } 1370 1371 if (n_vifs_assign > 0 || n_vifs_ctxless > 0) { 1372 err = ieee80211_chsw_switch_ctxs(local); 1373 if (err) 1374 goto err; 1375 } 1376 } else { 1377 err = ieee80211_chsw_switch_hwconf(local, new_ctx); 1378 if (err) 1379 goto err; 1380 } 1381 1382 /* 1383 * Update all structures, values and pointers to point to new channel 1384 * context(s). 1385 */ 1386 1387 i = 0; 1388 list_for_each_entry(ctx, &local->chanctx_list, list) { 1389 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1390 continue; 1391 1392 if (WARN_ON(!ctx->replace_ctx)) { 1393 err = -EINVAL; 1394 goto err; 1395 } 1396 1397 list_for_each_entry(sdata, &ctx->reserved_vifs, 1398 reserved_chanctx_list) { 1399 u32 changed = 0; 1400 1401 if (!ieee80211_vif_has_in_place_reservation(sdata)) 1402 continue; 1403 1404 rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf); 1405 1406 if (sdata->vif.type == NL80211_IFTYPE_AP) 1407 __ieee80211_vif_copy_chanctx_to_vlans(sdata, 1408 false); 1409 1410 ieee80211_check_fast_xmit_iface(sdata); 1411 1412 sdata->radar_required = sdata->reserved_radar_required; 1413 1414 if (sdata->vif.bss_conf.chandef.width != 1415 sdata->reserved_chandef.width) 1416 changed = BSS_CHANGED_BANDWIDTH; 1417 1418 ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef); 1419 if (changed) 1420 ieee80211_bss_info_change_notify(sdata, 1421 changed); 1422 1423 ieee80211_recalc_txpower(sdata, false); 1424 } 1425 1426 ieee80211_recalc_chanctx_chantype(local, ctx); 1427 ieee80211_recalc_smps_chanctx(local, ctx); 1428 ieee80211_recalc_radar_chanctx(local, ctx); 1429 ieee80211_recalc_chanctx_min_def(local, ctx); 1430 1431 list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs, 1432 reserved_chanctx_list) { 1433 if (ieee80211_vif_get_chanctx(sdata) != ctx) 1434 continue; 1435 1436 list_del(&sdata->reserved_chanctx_list); 1437 list_move(&sdata->assigned_chanctx_list, 1438 &ctx->assigned_vifs); 1439 sdata->reserved_chanctx = NULL; 1440 1441 ieee80211_vif_chanctx_reservation_complete(sdata); 1442 } 1443 1444 /* 1445 * This context might have been a dependency for an already 1446 * ready re-assign reservation interface that was deferred. Do 1447 * not propagate error to the caller though. The in-place 1448 * reservation for originally requested interface has already 1449 * succeeded at this point. 1450 */ 1451 list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs, 1452 reserved_chanctx_list) { 1453 if (WARN_ON(ieee80211_vif_has_in_place_reservation( 1454 sdata))) 1455 continue; 1456 1457 if (WARN_ON(sdata->reserved_chanctx != ctx)) 1458 continue; 1459 1460 if (!sdata->reserved_ready) 1461 continue; 1462 1463 if (ieee80211_vif_get_chanctx(sdata)) 1464 err = ieee80211_vif_use_reserved_reassign( 1465 sdata); 1466 else 1467 err = ieee80211_vif_use_reserved_assign(sdata); 1468 1469 if (err) { 1470 sdata_info(sdata, 1471 "failed to finalize (re-)assign reservation (err=%d)\n", 1472 err); 1473 ieee80211_vif_unreserve_chanctx(sdata); 1474 cfg80211_stop_iface(local->hw.wiphy, 1475 &sdata->wdev, 1476 GFP_KERNEL); 1477 } 1478 } 1479 } 1480 1481 /* 1482 * Finally free old contexts 1483 */ 1484 1485 list_for_each_entry_safe(ctx, ctx_tmp, &local->chanctx_list, list) { 1486 if (ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED) 1487 continue; 1488 1489 ctx->replace_ctx->replace_ctx = NULL; 1490 ctx->replace_ctx->replace_state = 1491 IEEE80211_CHANCTX_REPLACE_NONE; 1492 1493 list_del_rcu(&ctx->list); 1494 kfree_rcu(ctx, rcu_head); 1495 } 1496 1497 return 0; 1498 1499err: 1500 list_for_each_entry(ctx, &local->chanctx_list, list) { 1501 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1502 continue; 1503 1504 list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs, 1505 reserved_chanctx_list) { 1506 ieee80211_vif_unreserve_chanctx(sdata); 1507 ieee80211_vif_chanctx_reservation_complete(sdata); 1508 } 1509 } 1510 1511 return err; 1512} 1513 1514static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) 1515{ 1516 struct ieee80211_local *local = sdata->local; 1517 struct ieee80211_chanctx_conf *conf; 1518 struct ieee80211_chanctx *ctx; 1519 bool use_reserved_switch = false; 1520 1521 lockdep_assert_held(&local->chanctx_mtx); 1522 1523 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 1524 lockdep_is_held(&local->chanctx_mtx)); 1525 if (!conf) 1526 return; 1527 1528 ctx = container_of(conf, struct ieee80211_chanctx, conf); 1529 1530 if (sdata->reserved_chanctx) { 1531 if (sdata->reserved_chanctx->replace_state == 1532 IEEE80211_CHANCTX_REPLACES_OTHER && 1533 ieee80211_chanctx_num_reserved(local, 1534 sdata->reserved_chanctx) > 1) 1535 use_reserved_switch = true; 1536 1537 ieee80211_vif_unreserve_chanctx(sdata); 1538 } 1539 1540 ieee80211_assign_vif_chanctx(sdata, NULL); 1541 if (ieee80211_chanctx_refcount(local, ctx) == 0) 1542 ieee80211_free_chanctx(local, ctx); 1543 1544 sdata->radar_required = false; 1545 1546 /* Unreserving may ready an in-place reservation. */ 1547 if (use_reserved_switch) 1548 ieee80211_vif_use_reserved_switch(local); 1549} 1550 1551int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, 1552 const struct cfg80211_chan_def *chandef, 1553 enum ieee80211_chanctx_mode mode) 1554{ 1555 struct ieee80211_local *local = sdata->local; 1556 struct ieee80211_chanctx *ctx; 1557 u8 radar_detect_width = 0; 1558 int ret; 1559 1560 lockdep_assert_held(&local->mtx); 1561 1562 WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); 1563 1564 mutex_lock(&local->chanctx_mtx); 1565 1566 ret = cfg80211_chandef_dfs_required(local->hw.wiphy, 1567 chandef, 1568 sdata->wdev.iftype); 1569 if (ret < 0) 1570 goto out; 1571 if (ret > 0) 1572 radar_detect_width = BIT(chandef->width); 1573 1574 sdata->radar_required = ret; 1575 1576 ret = ieee80211_check_combinations(sdata, chandef, mode, 1577 radar_detect_width); 1578 if (ret < 0) 1579 goto out; 1580 1581 __ieee80211_vif_release_channel(sdata); 1582 1583 ctx = ieee80211_find_chanctx(local, chandef, mode); 1584 if (!ctx) 1585 ctx = ieee80211_new_chanctx(local, chandef, mode); 1586 if (IS_ERR(ctx)) { 1587 ret = PTR_ERR(ctx); 1588 goto out; 1589 } 1590 1591 ieee80211_vif_update_chandef(sdata, chandef); 1592 1593 ret = ieee80211_assign_vif_chanctx(sdata, ctx); 1594 if (ret) { 1595 /* if assign fails refcount stays the same */ 1596 if (ieee80211_chanctx_refcount(local, ctx) == 0) 1597 ieee80211_free_chanctx(local, ctx); 1598 goto out; 1599 } 1600 1601 ieee80211_recalc_smps_chanctx(local, ctx); 1602 ieee80211_recalc_radar_chanctx(local, ctx); 1603 out: 1604 if (ret) 1605 sdata->radar_required = false; 1606 1607 mutex_unlock(&local->chanctx_mtx); 1608 return ret; 1609} 1610 1611int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata) 1612{ 1613 struct ieee80211_local *local = sdata->local; 1614 struct ieee80211_chanctx *new_ctx; 1615 struct ieee80211_chanctx *old_ctx; 1616 int err; 1617 1618 lockdep_assert_held(&local->mtx); 1619 lockdep_assert_held(&local->chanctx_mtx); 1620 1621 new_ctx = sdata->reserved_chanctx; 1622 old_ctx = ieee80211_vif_get_chanctx(sdata); 1623 1624 if (WARN_ON(!new_ctx)) 1625 return -EINVAL; 1626 1627 if (WARN_ON(new_ctx->replace_state == 1628 IEEE80211_CHANCTX_WILL_BE_REPLACED)) 1629 return -EINVAL; 1630 1631 if (WARN_ON(sdata->reserved_ready)) 1632 return -EINVAL; 1633 1634 sdata->reserved_ready = true; 1635 1636 if (new_ctx->replace_state == IEEE80211_CHANCTX_REPLACE_NONE) { 1637 if (old_ctx) 1638 err = ieee80211_vif_use_reserved_reassign(sdata); 1639 else 1640 err = ieee80211_vif_use_reserved_assign(sdata); 1641 1642 if (err) 1643 return err; 1644 } 1645 1646 /* 1647 * In-place reservation may need to be finalized now either if: 1648 * a) sdata is taking part in the swapping itself and is the last one 1649 * b) sdata has switched with a re-assign reservation to an existing 1650 * context readying in-place switching of old_ctx 1651 * 1652 * In case of (b) do not propagate the error up because the requested 1653 * sdata already switched successfully. Just spill an extra warning. 1654 * The ieee80211_vif_use_reserved_switch() already stops all necessary 1655 * interfaces upon failure. 1656 */ 1657 if ((old_ctx && 1658 old_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) || 1659 new_ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) { 1660 err = ieee80211_vif_use_reserved_switch(local); 1661 if (err && err != -EAGAIN) { 1662 if (new_ctx->replace_state == 1663 IEEE80211_CHANCTX_REPLACES_OTHER) 1664 return err; 1665 1666 wiphy_info(local->hw.wiphy, 1667 "depending in-place reservation failed (err=%d)\n", 1668 err); 1669 } 1670 } 1671 1672 return 0; 1673} 1674 1675int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, 1676 const struct cfg80211_chan_def *chandef, 1677 u32 *changed) 1678{ 1679 struct ieee80211_local *local = sdata->local; 1680 struct ieee80211_chanctx_conf *conf; 1681 struct ieee80211_chanctx *ctx; 1682 const struct cfg80211_chan_def *compat; 1683 int ret; 1684 1685 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef, 1686 IEEE80211_CHAN_DISABLED)) 1687 return -EINVAL; 1688 1689 mutex_lock(&local->chanctx_mtx); 1690 if (cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef)) { 1691 ret = 0; 1692 goto out; 1693 } 1694 1695 if (chandef->width == NL80211_CHAN_WIDTH_20_NOHT || 1696 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) { 1697 ret = -EINVAL; 1698 goto out; 1699 } 1700 1701 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 1702 lockdep_is_held(&local->chanctx_mtx)); 1703 if (!conf) { 1704 ret = -EINVAL; 1705 goto out; 1706 } 1707 1708 ctx = container_of(conf, struct ieee80211_chanctx, conf); 1709 1710 compat = cfg80211_chandef_compatible(&conf->def, chandef); 1711 if (!compat) { 1712 ret = -EINVAL; 1713 goto out; 1714 } 1715 1716 switch (ctx->replace_state) { 1717 case IEEE80211_CHANCTX_REPLACE_NONE: 1718 if (!ieee80211_chanctx_reserved_chandef(local, ctx, compat)) { 1719 ret = -EBUSY; 1720 goto out; 1721 } 1722 break; 1723 case IEEE80211_CHANCTX_WILL_BE_REPLACED: 1724 /* TODO: Perhaps the bandwidth change could be treated as a 1725 * reservation itself? */ 1726 ret = -EBUSY; 1727 goto out; 1728 case IEEE80211_CHANCTX_REPLACES_OTHER: 1729 /* channel context that is going to replace another channel 1730 * context doesn't really exist and shouldn't be assigned 1731 * anywhere yet */ 1732 WARN_ON(1); 1733 break; 1734 } 1735 1736 ieee80211_vif_update_chandef(sdata, chandef); 1737 1738 ieee80211_recalc_chanctx_chantype(local, ctx); 1739 1740 *changed |= BSS_CHANGED_BANDWIDTH; 1741 ret = 0; 1742 out: 1743 mutex_unlock(&local->chanctx_mtx); 1744 return ret; 1745} 1746 1747void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) 1748{ 1749 WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); 1750 1751 lockdep_assert_held(&sdata->local->mtx); 1752 1753 mutex_lock(&sdata->local->chanctx_mtx); 1754 __ieee80211_vif_release_channel(sdata); 1755 mutex_unlock(&sdata->local->chanctx_mtx); 1756} 1757 1758void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata) 1759{ 1760 struct ieee80211_local *local = sdata->local; 1761 struct ieee80211_sub_if_data *ap; 1762 struct ieee80211_chanctx_conf *conf; 1763 1764 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss)) 1765 return; 1766 1767 ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); 1768 1769 mutex_lock(&local->chanctx_mtx); 1770 1771 conf = rcu_dereference_protected(ap->vif.chanctx_conf, 1772 lockdep_is_held(&local->chanctx_mtx)); 1773 rcu_assign_pointer(sdata->vif.chanctx_conf, conf); 1774 mutex_unlock(&local->chanctx_mtx); 1775} 1776 1777void ieee80211_iter_chan_contexts_atomic( 1778 struct ieee80211_hw *hw, 1779 void (*iter)(struct ieee80211_hw *hw, 1780 struct ieee80211_chanctx_conf *chanctx_conf, 1781 void *data), 1782 void *iter_data) 1783{ 1784 struct ieee80211_local *local = hw_to_local(hw); 1785 struct ieee80211_chanctx *ctx; 1786 1787 rcu_read_lock(); 1788 list_for_each_entry_rcu(ctx, &local->chanctx_list, list) 1789 if (ctx->driver_present) 1790 iter(hw, &ctx->conf, iter_data); 1791 rcu_read_unlock(); 1792} 1793EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic); 1794