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