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