1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * mac80211 - channel management 4 * Copyright 2020-2026 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 struct ieee80211_chanctx_user_iter { 16 struct ieee80211_chan_req *chanreq; 17 struct ieee80211_sub_if_data *sdata; 18 struct ieee80211_link_data *link; 19 struct ieee80211_nan_channel *nan_channel; 20 int nan_channel_next_idx; 21 enum nl80211_iftype iftype; 22 bool reserved, radar_required, done; 23 enum { 24 CHANCTX_ITER_POS_ASSIGNED, 25 CHANCTX_ITER_POS_RESERVED, 26 CHANCTX_ITER_POS_DONE, 27 } per_link; 28 }; 29 30 enum ieee80211_chanctx_iter_type { 31 CHANCTX_ITER_ALL, 32 CHANCTX_ITER_RESERVED, 33 CHANCTX_ITER_ASSIGNED, 34 }; 35 36 static bool 37 ieee80211_chanctx_user_iter_next_nan_channel(struct ieee80211_chanctx *ctx, 38 struct ieee80211_chanctx_user_iter *iter) 39 { 40 /* Start from the next index after current position */ 41 for (int i = iter->nan_channel_next_idx; 42 i < ARRAY_SIZE(iter->sdata->vif.cfg.nan_sched.channels); i++) { 43 struct ieee80211_nan_channel *nan_channel = 44 &iter->sdata->vif.cfg.nan_sched.channels[i]; 45 46 if (!nan_channel->chanreq.oper.chan) 47 continue; 48 49 if (nan_channel->chanctx_conf != &ctx->conf) 50 continue; 51 52 iter->nan_channel = nan_channel; 53 iter->nan_channel_next_idx = i + 1; 54 iter->chanreq = &nan_channel->chanreq; 55 iter->link = NULL; 56 iter->reserved = false; 57 iter->radar_required = false; 58 return true; 59 } 60 return false; 61 } 62 63 static bool 64 ieee80211_chanctx_user_iter_next_link(struct ieee80211_chanctx *ctx, 65 struct ieee80211_chanctx_user_iter *iter, 66 enum ieee80211_chanctx_iter_type type) 67 { 68 for (int link_id = iter->link ? iter->link->link_id : 0; 69 link_id < ARRAY_SIZE(iter->sdata->link); 70 link_id++) { 71 struct ieee80211_link_data *link; 72 73 link = sdata_dereference(iter->sdata->link[link_id], 74 iter->sdata); 75 if (!link) 76 continue; 77 78 switch (iter->per_link) { 79 case CHANCTX_ITER_POS_ASSIGNED: 80 iter->per_link = CHANCTX_ITER_POS_RESERVED; 81 if (type != CHANCTX_ITER_RESERVED && 82 rcu_access_pointer(link->conf->chanctx_conf) == &ctx->conf) { 83 iter->link = link; 84 iter->reserved = false; 85 iter->radar_required = link->radar_required; 86 iter->chanreq = &link->conf->chanreq; 87 return true; 88 } 89 fallthrough; 90 case CHANCTX_ITER_POS_RESERVED: 91 iter->per_link = CHANCTX_ITER_POS_DONE; 92 if (type != CHANCTX_ITER_ASSIGNED && 93 link->reserved_chanctx == ctx) { 94 iter->link = link; 95 iter->reserved = true; 96 iter->radar_required = 97 link->reserved_radar_required; 98 99 iter->chanreq = &link->reserved; 100 return true; 101 } 102 fallthrough; 103 case CHANCTX_ITER_POS_DONE: 104 iter->per_link = CHANCTX_ITER_POS_ASSIGNED; 105 continue; 106 } 107 } 108 return false; 109 } 110 111 static void 112 ieee80211_chanctx_user_iter_next(struct ieee80211_local *local, 113 struct ieee80211_chanctx *ctx, 114 struct ieee80211_chanctx_user_iter *iter, 115 enum ieee80211_chanctx_iter_type type, 116 bool start) 117 { 118 bool found; 119 120 lockdep_assert_wiphy(local->hw.wiphy); 121 122 if (start) { 123 memset(iter, 0, sizeof(*iter)); 124 goto next_interface; 125 } 126 127 next_user: 128 if (iter->iftype == NL80211_IFTYPE_NAN) 129 found = ieee80211_chanctx_user_iter_next_nan_channel(ctx, iter); 130 else 131 found = ieee80211_chanctx_user_iter_next_link(ctx, iter, type); 132 133 if (found) 134 return; 135 136 next_interface: 137 /* next (or first) interface */ 138 iter->sdata = list_prepare_entry(iter->sdata, &local->interfaces, list); 139 list_for_each_entry_continue(iter->sdata, &local->interfaces, list) { 140 if (!ieee80211_sdata_running(iter->sdata)) 141 continue; 142 143 /* AP_VLAN has a chanctx pointer but follows AP */ 144 if (iter->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 145 continue; 146 147 /* NAN channels don't reserve channel context */ 148 if (iter->sdata->vif.type == NL80211_IFTYPE_NAN && 149 type == CHANCTX_ITER_RESERVED) 150 continue; 151 152 iter->nan_channel = NULL; 153 iter->link = NULL; 154 iter->iftype = iter->sdata->vif.type; 155 iter->chanreq = NULL; 156 iter->per_link = CHANCTX_ITER_POS_ASSIGNED; 157 iter->nan_channel_next_idx = 0; 158 goto next_user; 159 } 160 161 iter->done = true; 162 } 163 164 #define for_each_chanctx_user_assigned(local, ctx, iter) \ 165 for (ieee80211_chanctx_user_iter_next(local, ctx, iter, \ 166 CHANCTX_ITER_ASSIGNED, \ 167 true); \ 168 !((iter)->done); \ 169 ieee80211_chanctx_user_iter_next(local, ctx, iter, \ 170 CHANCTX_ITER_ASSIGNED, \ 171 false)) 172 173 #define for_each_chanctx_user_reserved(local, ctx, iter) \ 174 for (ieee80211_chanctx_user_iter_next(local, ctx, iter, \ 175 CHANCTX_ITER_RESERVED, \ 176 true); \ 177 !((iter)->done); \ 178 ieee80211_chanctx_user_iter_next(local, ctx, iter, \ 179 CHANCTX_ITER_RESERVED, \ 180 false)) 181 182 #define for_each_chanctx_user_all(local, ctx, iter) \ 183 for (ieee80211_chanctx_user_iter_next(local, ctx, iter, \ 184 CHANCTX_ITER_ALL, \ 185 true); \ 186 !((iter)->done); \ 187 ieee80211_chanctx_user_iter_next(local, ctx, iter, \ 188 CHANCTX_ITER_ALL, \ 189 false)) 190 191 int ieee80211_chanctx_num_assigned(struct ieee80211_local *local, 192 struct ieee80211_chanctx *ctx) 193 { 194 struct ieee80211_chanctx_user_iter iter; 195 int num = 0; 196 197 for_each_chanctx_user_assigned(local, ctx, &iter) 198 num++; 199 200 return num; 201 } 202 203 static int ieee80211_chanctx_num_reserved(struct ieee80211_local *local, 204 struct ieee80211_chanctx *ctx) 205 { 206 struct ieee80211_chanctx_user_iter iter; 207 int num = 0; 208 209 for_each_chanctx_user_reserved(local, ctx, &iter) 210 num++; 211 212 return num; 213 } 214 215 int ieee80211_chanctx_refcount(struct ieee80211_local *local, 216 struct ieee80211_chanctx *ctx) 217 { 218 struct ieee80211_chanctx_user_iter iter; 219 int num = 0; 220 221 for_each_chanctx_user_all(local, ctx, &iter) 222 num++; 223 224 /* 225 * This ctx is in the process of getting used, 226 * take it into consideration 227 */ 228 if (ctx->will_be_used) 229 num++; 230 231 return num; 232 } 233 234 static int ieee80211_num_chanctx(struct ieee80211_local *local, int radio_idx) 235 { 236 struct ieee80211_chanctx *ctx; 237 int num = 0; 238 239 lockdep_assert_wiphy(local->hw.wiphy); 240 241 list_for_each_entry(ctx, &local->chanctx_list, list) { 242 if (radio_idx >= 0 && ctx->conf.radio_idx != radio_idx) 243 continue; 244 num++; 245 } 246 247 return num; 248 } 249 250 static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local, 251 int radio_idx) 252 { 253 lockdep_assert_wiphy(local->hw.wiphy); 254 255 return ieee80211_num_chanctx(local, radio_idx) < 256 ieee80211_max_num_channels(local, radio_idx); 257 } 258 259 static struct ieee80211_chanctx * 260 ieee80211_link_get_chanctx(struct ieee80211_link_data *link) 261 { 262 struct ieee80211_local *local __maybe_unused = link->sdata->local; 263 struct ieee80211_chanctx_conf *conf; 264 265 conf = rcu_dereference_protected(link->conf->chanctx_conf, 266 lockdep_is_held(&local->hw.wiphy->mtx)); 267 if (!conf) 268 return NULL; 269 270 return container_of(conf, struct ieee80211_chanctx, conf); 271 } 272 273 bool ieee80211_chanreq_identical(const struct ieee80211_chan_req *a, 274 const struct ieee80211_chan_req *b) 275 { 276 if (!cfg80211_chandef_identical(&a->oper, &b->oper)) 277 return false; 278 if (!a->ap.chan && !b->ap.chan) 279 return true; 280 return cfg80211_chandef_identical(&a->ap, &b->ap); 281 } 282 283 static const struct ieee80211_chan_req * 284 ieee80211_chanreq_compatible(const struct ieee80211_chan_req *a, 285 const struct ieee80211_chan_req *b, 286 struct ieee80211_chan_req *tmp) 287 { 288 struct ieee80211_chan_req _a = *a, _b = *b; 289 const struct cfg80211_chan_def *compat; 290 291 if (a->ap.chan && b->ap.chan && 292 !cfg80211_chandef_identical(&a->ap, &b->ap)) 293 return NULL; 294 295 /* 296 * Remove NPCA if it's not required, so that interfaces 297 * sharing a channel context will not use NPCA while the 298 * channel context is shared. 299 * If both sides are AP interfaces requiring NPC, there's 300 * an assumption that userspace will set them up with 301 * identical configurations and the same BSS color 302 * (if the config is not identical, sharing will fail due 303 * to cfg80211_chandef_compatible() failing below.) 304 */ 305 if (!_a.require_npca) { 306 _a.oper.npca_chan = NULL; 307 _a.oper.npca_punctured = 0; 308 } 309 310 if (!_b.require_npca) { 311 _b.oper.npca_chan = NULL; 312 _b.oper.npca_punctured = 0; 313 } 314 315 compat = cfg80211_chandef_compatible(&_a.oper, &_b.oper); 316 if (!compat) 317 return NULL; 318 319 /* Note: later code assumes this always fills & returns tmp if compat */ 320 tmp->oper = *compat; 321 tmp->ap = a->ap.chan ? a->ap : b->ap; 322 tmp->require_npca = a->require_npca && b->require_npca; 323 return tmp; 324 } 325 326 /* 327 * When checking for compatible, check against all the links using 328 * the chanctx (except the one passed that might be changing) to 329 * allow changes to the AP's bandwidth for wider bandwidth OFDMA 330 * purposes, which wouldn't be treated as compatible by checking 331 * against the chanctx's oper/ap chandefs. 332 */ 333 static const struct ieee80211_chan_req * 334 _ieee80211_chanctx_compatible(struct ieee80211_local *local, 335 struct ieee80211_link_data *skip_link, 336 struct ieee80211_chanctx *ctx, 337 const struct ieee80211_chan_req *req, 338 struct ieee80211_chan_req *tmp) 339 { 340 const struct ieee80211_chan_req *ret = req; 341 struct ieee80211_chanctx_user_iter iter; 342 343 lockdep_assert_wiphy(local->hw.wiphy); 344 345 for_each_chanctx_user_all(local, ctx, &iter) { 346 if (iter.link && iter.link == skip_link) 347 continue; 348 349 ret = ieee80211_chanreq_compatible(ret, iter.chanreq, tmp); 350 if (!ret) 351 return NULL; 352 } 353 354 *tmp = *ret; 355 return tmp; 356 } 357 358 static const struct ieee80211_chan_req * 359 ieee80211_chanctx_compatible(struct ieee80211_local *local, 360 struct ieee80211_chanctx *ctx, 361 const struct ieee80211_chan_req *req, 362 struct ieee80211_chan_req *tmp) 363 { 364 return _ieee80211_chanctx_compatible(local, NULL, ctx, req, tmp); 365 } 366 367 static const struct ieee80211_chan_req * 368 ieee80211_chanctx_reserved_chanreq(struct ieee80211_local *local, 369 struct ieee80211_chanctx *ctx, 370 const struct ieee80211_chan_req *req, 371 struct ieee80211_chan_req *tmp) 372 { 373 struct ieee80211_chanctx_user_iter iter; 374 375 lockdep_assert_wiphy(local->hw.wiphy); 376 377 if (WARN_ON(!req)) 378 return NULL; 379 380 for_each_chanctx_user_reserved(local, ctx, &iter) { 381 req = ieee80211_chanreq_compatible(iter.chanreq, req, tmp); 382 if (!req) 383 break; 384 } 385 386 return req; 387 } 388 389 static const struct ieee80211_chan_req * 390 ieee80211_chanctx_non_reserved_chandef(struct ieee80211_local *local, 391 struct ieee80211_chanctx *ctx, 392 const struct ieee80211_chan_req *compat, 393 struct ieee80211_chan_req *tmp) 394 { 395 const struct ieee80211_chan_req *comp_def = compat; 396 struct ieee80211_chanctx_user_iter iter; 397 398 lockdep_assert_wiphy(local->hw.wiphy); 399 400 for_each_chanctx_user_assigned(local, ctx, &iter) { 401 if (iter.link && iter.link->reserved_chanctx) 402 continue; 403 404 comp_def = ieee80211_chanreq_compatible(iter.chanreq, 405 comp_def, tmp); 406 if (!comp_def) 407 break; 408 } 409 410 return comp_def; 411 } 412 413 static bool 414 ieee80211_chanctx_can_reserve(struct ieee80211_local *local, 415 struct ieee80211_chanctx *ctx, 416 const struct ieee80211_chan_req *req) 417 { 418 struct ieee80211_chan_req tmp; 419 420 lockdep_assert_wiphy(local->hw.wiphy); 421 422 if (!ieee80211_chanctx_reserved_chanreq(local, ctx, req, &tmp)) 423 return false; 424 425 if (!ieee80211_chanctx_non_reserved_chandef(local, ctx, req, &tmp)) 426 return false; 427 428 if (ieee80211_chanctx_num_reserved(local, ctx) != 0 && 429 ieee80211_chanctx_reserved_chanreq(local, ctx, req, &tmp)) 430 return true; 431 432 return false; 433 } 434 435 static struct ieee80211_chanctx * 436 ieee80211_find_reservation_chanctx(struct ieee80211_local *local, 437 const struct ieee80211_chan_req *chanreq, 438 enum ieee80211_chanctx_mode mode) 439 { 440 struct ieee80211_chanctx *ctx; 441 442 lockdep_assert_wiphy(local->hw.wiphy); 443 444 if (mode == IEEE80211_CHANCTX_EXCLUSIVE) 445 return NULL; 446 447 list_for_each_entry(ctx, &local->chanctx_list, list) { 448 if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) 449 continue; 450 451 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) 452 continue; 453 454 if (!ieee80211_chanctx_can_reserve(local, ctx, chanreq)) 455 continue; 456 457 return ctx; 458 } 459 460 return NULL; 461 } 462 463 static enum nl80211_chan_width 464 ieee80211_get_sta_bw(struct sta_info *sta, struct ieee80211_link_data *link) 465 { 466 enum ieee80211_sta_rx_bandwidth width; 467 struct link_sta_info *link_sta; 468 int link_id = link->link_id; 469 470 link_sta = wiphy_dereference(sta->local->hw.wiphy, sta->link[link_id]); 471 472 /* no effect if this STA has no presence on this link */ 473 if (!link_sta) 474 return NL80211_CHAN_WIDTH_20_NOHT; 475 476 /* 477 * We assume that TX/RX might be asymmetric (so e.g. VHT operating 478 * mode notification changes what a STA wants to receive, but not 479 * necessarily what it will transmit to us), and therefore use the 480 * "from station" bandwidth here. 481 */ 482 width = ieee80211_sta_current_bw(link_sta, &link->conf->chanreq.oper, 483 IEEE80211_STA_BW_RX_FROM_STA); 484 485 if (width == IEEE80211_STA_RX_BW_20 && 486 !link_sta->pub->ht_cap.ht_supported && 487 !link_sta->pub->he_cap.has_he) 488 return NL80211_CHAN_WIDTH_20_NOHT; 489 490 /* 491 * This returns 160 for both 160 and 80+80. Since we use 492 * the returned value to consider narrowing for 493 * ctx->conf.min_def, that's correct and necessary. 494 */ 495 return ieee80211_sta_rx_bw_to_chan_width(width); 496 } 497 498 static enum nl80211_chan_width 499 ieee80211_get_max_required_bw(struct ieee80211_link_data *link) 500 { 501 struct ieee80211_sub_if_data *sdata = link->sdata; 502 enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT; 503 struct sta_info *sta; 504 505 lockdep_assert_wiphy(sdata->local->hw.wiphy); 506 507 list_for_each_entry(sta, &sdata->local->sta_list, list) { 508 if (sdata != sta->sdata && 509 !(sta->sdata->bss && sta->sdata->bss == sdata->bss)) 510 continue; 511 512 max_bw = max(max_bw, ieee80211_get_sta_bw(sta, link)); 513 } 514 515 return max_bw; 516 } 517 518 static enum nl80211_chan_width 519 ieee80211_get_width_of_link(struct ieee80211_link_data *link) 520 { 521 struct ieee80211_local *local = link->sdata->local; 522 523 switch (link->sdata->vif.type) { 524 case NL80211_IFTYPE_STATION: 525 if (!link->sdata->vif.cfg.assoc) { 526 /* 527 * The AP's sta->bandwidth may not yet be set 528 * at this point (pre-association), so simply 529 * take the width from the chandef. We cannot 530 * have TDLS peers yet (only after association). 531 */ 532 return link->conf->chanreq.oper.width; 533 } 534 /* 535 * otherwise just use min_def like in AP, depending on what 536 * we currently think the AP STA (and possibly TDLS peers) 537 * require(s) 538 */ 539 fallthrough; 540 case NL80211_IFTYPE_AP: 541 case NL80211_IFTYPE_AP_VLAN: 542 return ieee80211_get_max_required_bw(link); 543 case NL80211_IFTYPE_P2P_DEVICE: 544 break; 545 case NL80211_IFTYPE_MONITOR: 546 WARN_ON_ONCE(!ieee80211_hw_check(&local->hw, 547 NO_VIRTUAL_MONITOR)); 548 fallthrough; 549 case NL80211_IFTYPE_ADHOC: 550 case NL80211_IFTYPE_MESH_POINT: 551 case NL80211_IFTYPE_OCB: 552 return link->conf->chanreq.oper.width; 553 case NL80211_IFTYPE_WDS: 554 case NL80211_IFTYPE_UNSPECIFIED: 555 case NUM_NL80211_IFTYPES: 556 case NL80211_IFTYPE_P2P_CLIENT: 557 case NL80211_IFTYPE_P2P_GO: 558 case NL80211_IFTYPE_NAN: 559 case NL80211_IFTYPE_NAN_DATA: 560 case NL80211_IFTYPE_PD: 561 WARN_ON_ONCE(1); 562 break; 563 } 564 565 /* Take the lowest possible, so it won't change the max width */ 566 return NL80211_CHAN_WIDTH_20_NOHT; 567 } 568 569 static enum nl80211_chan_width 570 ieee80211_get_width_of_chanctx_user(struct ieee80211_chanctx_user_iter *iter) 571 { 572 if (iter->link) 573 return ieee80211_get_width_of_link(iter->link); 574 575 if (WARN_ON_ONCE(!iter->nan_channel || iter->reserved)) 576 return NL80211_CHAN_WIDTH_20_NOHT; 577 578 return iter->nan_channel->chanreq.oper.width; 579 } 580 581 static enum nl80211_chan_width 582 ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local, 583 struct ieee80211_chanctx *ctx, 584 struct ieee80211_link_data *rsvd_for, 585 bool check_reserved) 586 { 587 enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT; 588 struct ieee80211_chanctx_user_iter iter; 589 struct ieee80211_sub_if_data *sdata; 590 enum nl80211_chan_width width; 591 592 if (WARN_ON(check_reserved && rsvd_for)) 593 return ctx->conf.def.width; 594 595 /* When this is true we only care about the reserving links */ 596 if (check_reserved) { 597 for_each_chanctx_user_reserved(local, ctx, &iter) { 598 width = ieee80211_get_width_of_chanctx_user(&iter); 599 max_bw = max(max_bw, width); 600 } 601 goto check_monitor; 602 } 603 604 /* Consider all assigned links */ 605 for_each_chanctx_user_assigned(local, ctx, &iter) { 606 width = ieee80211_get_width_of_chanctx_user(&iter); 607 max_bw = max(max_bw, width); 608 } 609 610 if (!rsvd_for || 611 rsvd_for->sdata == rcu_access_pointer(local->monitor_sdata)) 612 goto check_monitor; 613 614 /* Consider the link for which this chanctx is reserved/going to be assigned */ 615 width = ieee80211_get_width_of_link(rsvd_for); 616 max_bw = max(max_bw, width); 617 618 check_monitor: 619 /* use the configured bandwidth in case of monitor interface */ 620 sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata); 621 if (sdata && 622 rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) == &ctx->conf) 623 max_bw = max(max_bw, ctx->conf.def.width); 624 625 return max_bw; 626 } 627 628 /* 629 * recalc the min required chan width of the channel context, which is 630 * the max of min required widths of all the interfaces bound to this 631 * channel context. 632 */ 633 static u32 634 __ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, 635 struct ieee80211_chanctx *ctx, 636 struct ieee80211_link_data *rsvd_for, 637 bool check_reserved) 638 { 639 enum nl80211_chan_width max_bw; 640 struct cfg80211_chan_def min_def; 641 642 lockdep_assert_wiphy(local->hw.wiphy); 643 644 /* don't optimize non-20MHz based and radar_enabled confs */ 645 if (ctx->conf.def.width == NL80211_CHAN_WIDTH_1 || 646 ctx->conf.def.width == NL80211_CHAN_WIDTH_2 || 647 ctx->conf.def.width == NL80211_CHAN_WIDTH_4 || 648 ctx->conf.def.width == NL80211_CHAN_WIDTH_8 || 649 ctx->conf.def.width == NL80211_CHAN_WIDTH_16 || 650 ctx->conf.radar_enabled) { 651 ctx->conf.min_def = ctx->conf.def; 652 return 0; 653 } 654 655 max_bw = ieee80211_get_chanctx_max_required_bw(local, ctx, rsvd_for, 656 check_reserved); 657 658 /* downgrade chandef up to max_bw */ 659 min_def = ctx->conf.def; 660 while (min_def.width > max_bw) 661 ieee80211_chandef_downgrade(&min_def, NULL); 662 663 if (cfg80211_chandef_identical(&ctx->conf.min_def, &min_def)) 664 return 0; 665 666 ctx->conf.min_def = min_def; 667 if (!ctx->driver_present) 668 return 0; 669 670 return IEEE80211_CHANCTX_CHANGE_MIN_DEF; 671 } 672 673 static void ieee80211_chan_bw_change(struct ieee80211_local *local, 674 struct ieee80211_chanctx *ctx, 675 bool reserved, bool narrowed) 676 { 677 struct sta_info *sta; 678 struct ieee80211_supported_band *sband = 679 local->hw.wiphy->bands[ctx->conf.def.chan->band]; 680 681 rcu_read_lock(); 682 list_for_each_entry_rcu(sta, &local->sta_list, 683 list) { 684 struct ieee80211_sub_if_data *sdata; 685 enum ieee80211_sta_rx_bandwidth new_sta_bw; 686 unsigned int link_id; 687 688 if (!ieee80211_sdata_running(sta->sdata)) 689 continue; 690 691 sdata = get_bss_sdata(sta->sdata); 692 693 for (link_id = 0; link_id < ARRAY_SIZE(sdata->link); link_id++) { 694 struct ieee80211_link_data *link = 695 rcu_dereference(sdata->link[link_id]); 696 struct ieee80211_bss_conf *link_conf; 697 struct cfg80211_chan_def *new_chandef; 698 struct link_sta_info *link_sta; 699 700 if (!link) 701 continue; 702 703 link_conf = link->conf; 704 705 if (rcu_access_pointer(link_conf->chanctx_conf) != &ctx->conf) 706 continue; 707 708 link_sta = rcu_dereference(sta->link[link_id]); 709 if (!link_sta) 710 continue; 711 712 if (reserved) 713 new_chandef = &link->reserved.oper; 714 else 715 new_chandef = &link_conf->chanreq.oper; 716 717 new_sta_bw = ieee80211_sta_current_bw(link_sta, 718 new_chandef, 719 IEEE80211_STA_BW_TX_TO_STA); 720 721 /* nothing change */ 722 if (new_sta_bw == link_sta->pub->bandwidth) 723 continue; 724 725 /* vif changed to narrow BW and narrow BW for station wasn't 726 * requested or vice versa */ 727 if ((new_sta_bw < link_sta->pub->bandwidth) == !narrowed) 728 continue; 729 730 link_sta->pub->bandwidth = new_sta_bw; 731 rate_control_rate_update(local, sband, link_sta, 732 IEEE80211_RC_BW_CHANGED); 733 } 734 } 735 rcu_read_unlock(); 736 } 737 738 /* 739 * recalc the min required chan width of the channel context, which is 740 * the max of min required widths of all the interfaces bound to this 741 * channel context. 742 * 743 * Note: ieee80211_update_ap_bandwidth() relies on this iterating all 744 * affected stations, even if min_def didn't change. 745 */ 746 static void 747 _ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, 748 struct ieee80211_chanctx *ctx, 749 struct ieee80211_link_data *rsvd_for, 750 bool check_reserved) 751 { 752 u32 changed; 753 754 /* No recalc for S1G chan ctx's */ 755 if (cfg80211_chandef_is_s1g(&ctx->conf.def)) 756 return; 757 758 changed = __ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for, 759 check_reserved); 760 761 /* check is BW narrowed */ 762 ieee80211_chan_bw_change(local, ctx, false, true); 763 764 if (changed) 765 drv_change_chanctx(local, ctx, changed); 766 767 /* check is BW wider */ 768 ieee80211_chan_bw_change(local, ctx, false, false); 769 } 770 771 void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, 772 struct ieee80211_chanctx *ctx) 773 { 774 _ieee80211_recalc_chanctx_min_def(local, ctx, NULL, false); 775 } 776 777 static void 778 ieee80211_chanctx_update_npca_links(struct ieee80211_local *local, 779 struct ieee80211_chanctx *ctx, 780 bool enable) 781 { 782 struct ieee80211_chanctx_user_iter iter; 783 784 if (!!ctx->conf.def.npca_chan != enable) 785 return; 786 787 for_each_chanctx_user_assigned(local, ctx, &iter) { 788 if (!iter.link) 789 continue; 790 if (!iter.sdata->vif.cfg.assoc) 791 continue; 792 793 if (enable) { 794 if (!iter.link->conf->chanreq.oper.npca_chan) 795 continue; 796 } else { 797 if (!iter.link->conf->npca.enabled) 798 continue; 799 } 800 801 iter.link->conf->npca.enabled = enable; 802 drv_link_info_changed(local, iter.sdata, 803 iter.link->conf, 804 iter.link->link_id, 805 BSS_CHANGED_NPCA); 806 } 807 } 808 809 static void _ieee80211_change_chanctx(struct ieee80211_local *local, 810 struct ieee80211_chanctx *ctx, 811 struct ieee80211_chanctx *old_ctx, 812 const struct ieee80211_chan_req *chanreq, 813 struct ieee80211_link_data *rsvd_for) 814 { 815 struct ieee80211_chan_req ctx_req = { 816 .oper = ctx->conf.def, 817 .ap = ctx->conf.ap, 818 }; 819 u32 changed = 0; 820 821 /* 5/10 MHz not handled here */ 822 switch (chanreq->oper.width) { 823 case NL80211_CHAN_WIDTH_1: 824 case NL80211_CHAN_WIDTH_2: 825 case NL80211_CHAN_WIDTH_4: 826 case NL80211_CHAN_WIDTH_8: 827 case NL80211_CHAN_WIDTH_16: 828 /* 829 * mac80211 currently only supports sharing identical 830 * chanctx's for S1G interfaces. 831 */ 832 WARN_ON(!ieee80211_chanreq_identical(&ctx_req, chanreq)); 833 return; 834 case NL80211_CHAN_WIDTH_20_NOHT: 835 case NL80211_CHAN_WIDTH_20: 836 case NL80211_CHAN_WIDTH_40: 837 case NL80211_CHAN_WIDTH_80: 838 case NL80211_CHAN_WIDTH_80P80: 839 case NL80211_CHAN_WIDTH_160: 840 case NL80211_CHAN_WIDTH_320: 841 break; 842 default: 843 WARN_ON(1); 844 } 845 846 /* Check maybe BW narrowed - we do this _before_ calling recalc_chanctx_min_def 847 * due to maybe not returning from it, e.g in case new context was added 848 * first time with all parameters up to date. 849 */ 850 ieee80211_chan_bw_change(local, old_ctx, false, true); 851 852 if (ieee80211_chanreq_identical(&ctx_req, chanreq)) { 853 _ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for, false); 854 return; 855 } 856 857 WARN_ON(ieee80211_chanctx_refcount(local, ctx) > 1 && 858 !cfg80211_chandef_compatible(&ctx->conf.def, &chanreq->oper)); 859 860 ieee80211_remove_wbrf(local, &ctx->conf.def); 861 862 if (!cfg80211_chandef_identical(&ctx->conf.def, &chanreq->oper)) { 863 if (ctx->conf.def.width != chanreq->oper.width) 864 changed |= IEEE80211_CHANCTX_CHANGE_WIDTH; 865 if (ctx->conf.def.punctured != chanreq->oper.punctured) 866 changed |= IEEE80211_CHANCTX_CHANGE_PUNCTURING; 867 if (ctx->conf.def.npca_chan != chanreq->oper.npca_chan) 868 changed |= IEEE80211_CHANCTX_CHANGE_NPCA; 869 if (chanreq->oper.npca_chan && 870 ctx->conf.def.npca_punctured != chanreq->oper.npca_punctured) 871 changed |= IEEE80211_CHANCTX_CHANGE_NPCA_PUNCT; 872 } 873 if (!cfg80211_chandef_identical(&ctx->conf.ap, &chanreq->ap)) 874 changed |= IEEE80211_CHANCTX_CHANGE_AP; 875 ctx->conf.def = chanreq->oper; 876 ctx->conf.ap = chanreq->ap; 877 878 /* check if min chanctx also changed */ 879 changed |= __ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for, 880 false); 881 882 ieee80211_add_wbrf(local, &ctx->conf.def); 883 884 /* disable NPCA on the link using it */ 885 ieee80211_chanctx_update_npca_links(local, ctx, false); 886 887 drv_change_chanctx(local, ctx, changed); 888 889 /* check if BW is wider */ 890 ieee80211_chan_bw_change(local, old_ctx, false, false); 891 892 /* enable NPCA on the link that requested it */ 893 ieee80211_chanctx_update_npca_links(local, ctx, true); 894 } 895 896 static void ieee80211_change_chanctx(struct ieee80211_local *local, 897 struct ieee80211_chanctx *ctx, 898 struct ieee80211_chanctx *old_ctx, 899 const struct ieee80211_chan_req *chanreq) 900 { 901 _ieee80211_change_chanctx(local, ctx, old_ctx, chanreq, NULL); 902 } 903 904 /* Note: if successful, the returned chanctx will_be_used flag is set */ 905 static struct ieee80211_chanctx * 906 ieee80211_find_chanctx(struct ieee80211_local *local, 907 const struct ieee80211_chan_req *chanreq, 908 enum ieee80211_chanctx_mode mode) 909 { 910 struct ieee80211_chan_req tmp; 911 struct ieee80211_chanctx *ctx; 912 913 lockdep_assert_wiphy(local->hw.wiphy); 914 915 if (mode == IEEE80211_CHANCTX_EXCLUSIVE) 916 return NULL; 917 918 list_for_each_entry(ctx, &local->chanctx_list, list) { 919 const struct ieee80211_chan_req *compat; 920 921 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACE_NONE) 922 continue; 923 924 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) 925 continue; 926 927 compat = ieee80211_chanctx_compatible(local, ctx, chanreq, 928 &tmp); 929 if (!compat) 930 continue; 931 932 compat = ieee80211_chanctx_reserved_chanreq(local, ctx, 933 compat, &tmp); 934 if (!compat) 935 continue; 936 937 /* 938 * Mark the chanctx as will be used, as the driver might change 939 * active links during callbacks we make into it below and/or 940 * later during assignment, which could (otherwise) cause the 941 * context to actually be removed. 942 */ 943 ctx->will_be_used = true; 944 945 ieee80211_change_chanctx(local, ctx, ctx, compat); 946 947 return ctx; 948 } 949 950 return NULL; 951 } 952 953 bool ieee80211_is_radar_required(struct ieee80211_local *local, 954 struct cfg80211_scan_request *req) 955 { 956 struct wiphy *wiphy = local->hw.wiphy; 957 struct ieee80211_link_data *link; 958 struct ieee80211_channel *chan; 959 int radio_idx; 960 961 lockdep_assert_wiphy(local->hw.wiphy); 962 963 if (!req) 964 return false; 965 966 for_each_sdata_link(local, link) { 967 if (link->radar_required) { 968 chan = link->conf->chanreq.oper.chan; 969 radio_idx = cfg80211_get_radio_idx_by_chan(wiphy, chan); 970 971 if (ieee80211_is_radio_idx_in_scan_req(wiphy, req, 972 radio_idx)) 973 return true; 974 } 975 } 976 977 return false; 978 } 979 980 static bool 981 ieee80211_chanctx_radar_required(struct ieee80211_local *local, 982 struct ieee80211_chanctx *ctx) 983 { 984 struct ieee80211_chanctx_user_iter iter; 985 986 lockdep_assert_wiphy(local->hw.wiphy); 987 988 for_each_chanctx_user_assigned(local, ctx, &iter) { 989 if (iter.radar_required) 990 return true; 991 } 992 993 return false; 994 } 995 996 static struct ieee80211_chanctx * 997 ieee80211_alloc_chanctx(struct ieee80211_local *local, 998 const struct ieee80211_chan_req *chanreq, 999 enum ieee80211_chanctx_mode mode, 1000 int radio_idx) 1001 { 1002 struct ieee80211_chanctx *ctx; 1003 1004 lockdep_assert_wiphy(local->hw.wiphy); 1005 1006 ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL); 1007 if (!ctx) 1008 return NULL; 1009 1010 ctx->conf.def = chanreq->oper; 1011 ctx->conf.ap = chanreq->ap; 1012 ctx->conf.rx_chains_static = 1; 1013 ctx->conf.rx_chains_dynamic = 1; 1014 ctx->mode = mode; 1015 ctx->conf.radar_enabled = false; 1016 ctx->conf.radio_idx = radio_idx; 1017 ctx->radar_detected = false; 1018 __ieee80211_recalc_chanctx_min_def(local, ctx, NULL, false); 1019 1020 return ctx; 1021 } 1022 1023 static int ieee80211_add_chanctx(struct ieee80211_local *local, 1024 struct ieee80211_chanctx *ctx) 1025 { 1026 u32 changed; 1027 int err; 1028 1029 lockdep_assert_wiphy(local->hw.wiphy); 1030 1031 ieee80211_add_wbrf(local, &ctx->conf.def); 1032 1033 /* turn idle off *before* setting channel -- some drivers need that */ 1034 changed = ieee80211_idle_off(local); 1035 if (changed) 1036 ieee80211_hw_config(local, -1, changed); 1037 1038 err = drv_add_chanctx(local, ctx); 1039 if (err) { 1040 ieee80211_recalc_idle(local); 1041 return err; 1042 } 1043 1044 return 0; 1045 } 1046 1047 static struct ieee80211_chanctx * 1048 ieee80211_new_chanctx(struct ieee80211_local *local, 1049 const struct ieee80211_chan_req *chanreq, 1050 enum ieee80211_chanctx_mode mode, 1051 bool assign_on_failure, 1052 int radio_idx) 1053 { 1054 struct ieee80211_chanctx *ctx; 1055 int err; 1056 1057 lockdep_assert_wiphy(local->hw.wiphy); 1058 1059 ctx = ieee80211_alloc_chanctx(local, chanreq, mode, radio_idx); 1060 if (!ctx) 1061 return ERR_PTR(-ENOMEM); 1062 1063 err = ieee80211_add_chanctx(local, ctx); 1064 if (!assign_on_failure && err) { 1065 kfree(ctx); 1066 return ERR_PTR(err); 1067 } 1068 /* 1069 * We ignored a driver error, see _ieee80211_set_active_links and/or 1070 * ieee80211_nan_set_local_sched 1071 */ 1072 WARN_ON_ONCE(err && !local->in_reconfig); 1073 1074 list_add_rcu(&ctx->list, &local->chanctx_list); 1075 return ctx; 1076 } 1077 1078 static void ieee80211_del_chanctx(struct ieee80211_local *local, 1079 struct ieee80211_chanctx *ctx, 1080 bool skip_idle_recalc) 1081 { 1082 lockdep_assert_wiphy(local->hw.wiphy); 1083 1084 drv_remove_chanctx(local, ctx); 1085 1086 if (!skip_idle_recalc) 1087 ieee80211_recalc_idle(local); 1088 1089 ieee80211_remove_wbrf(local, &ctx->conf.def); 1090 } 1091 1092 void ieee80211_free_chanctx(struct ieee80211_local *local, 1093 struct ieee80211_chanctx *ctx, 1094 bool skip_idle_recalc) 1095 { 1096 lockdep_assert_wiphy(local->hw.wiphy); 1097 1098 WARN_ON_ONCE(ieee80211_chanctx_refcount(local, ctx) != 0); 1099 1100 list_del_rcu(&ctx->list); 1101 ieee80211_del_chanctx(local, ctx, skip_idle_recalc); 1102 kfree_rcu(ctx, rcu_head); 1103 } 1104 1105 void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, 1106 struct ieee80211_chanctx *ctx) 1107 { 1108 struct ieee80211_chanctx_conf *conf = &ctx->conf; 1109 const struct ieee80211_chan_req *compat = NULL; 1110 struct ieee80211_chanctx_user_iter iter; 1111 struct ieee80211_chan_req tmp; 1112 struct sta_info *sta; 1113 1114 lockdep_assert_wiphy(local->hw.wiphy); 1115 1116 for_each_chanctx_user_assigned(local, ctx, &iter) { 1117 if (!compat) 1118 compat = iter.chanreq; 1119 1120 compat = ieee80211_chanreq_compatible(iter.chanreq, 1121 compat, &tmp); 1122 if (WARN_ON_ONCE(!compat)) 1123 return; 1124 } 1125 1126 if (WARN_ON_ONCE(!compat)) 1127 return; 1128 1129 /* TDLS peers can sometimes affect the chandef width */ 1130 list_for_each_entry(sta, &local->sta_list, list) { 1131 struct ieee80211_sub_if_data *sdata = sta->sdata; 1132 struct ieee80211_chan_req tdls_chanreq = {}; 1133 struct ieee80211_link_data *link; 1134 int tdls_link_id; 1135 1136 if (!sta->uploaded || 1137 !test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW) || 1138 !test_sta_flag(sta, WLAN_STA_AUTHORIZED) || 1139 !sta->tdls_chandef.chan) 1140 continue; 1141 1142 tdls_link_id = ieee80211_tdls_sta_link_id(sta); 1143 link = sdata_dereference(sdata->link[tdls_link_id], sdata); 1144 if (!link) 1145 continue; 1146 1147 if (rcu_access_pointer(link->conf->chanctx_conf) != conf) 1148 continue; 1149 1150 tdls_chanreq.oper = sta->tdls_chandef; 1151 1152 /* note this always fills and returns &tmp if compat */ 1153 compat = ieee80211_chanreq_compatible(&tdls_chanreq, 1154 compat, &tmp); 1155 if (WARN_ON_ONCE(!compat)) 1156 return; 1157 } 1158 1159 ieee80211_change_chanctx(local, ctx, ctx, compat); 1160 } 1161 1162 static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, 1163 struct ieee80211_chanctx *chanctx) 1164 { 1165 bool radar_enabled; 1166 1167 lockdep_assert_wiphy(local->hw.wiphy); 1168 1169 radar_enabled = ieee80211_chanctx_radar_required(local, chanctx); 1170 1171 if (radar_enabled == chanctx->conf.radar_enabled) 1172 return; 1173 1174 chanctx->conf.radar_enabled = radar_enabled; 1175 1176 drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR); 1177 } 1178 1179 static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link, 1180 struct ieee80211_chanctx *new_ctx, 1181 bool assign_on_failure) 1182 { 1183 struct ieee80211_sub_if_data *sdata = link->sdata; 1184 struct ieee80211_local *local = sdata->local; 1185 struct ieee80211_chanctx_conf *conf; 1186 struct ieee80211_chanctx *curr_ctx = NULL; 1187 bool new_idle; 1188 int ret; 1189 1190 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_NAN)) 1191 return -EOPNOTSUPP; 1192 1193 conf = rcu_dereference_protected(link->conf->chanctx_conf, 1194 lockdep_is_held(&local->hw.wiphy->mtx)); 1195 1196 if (conf && !local->in_reconfig) { 1197 curr_ctx = container_of(conf, struct ieee80211_chanctx, conf); 1198 1199 drv_unassign_vif_chanctx(local, sdata, link->conf, curr_ctx); 1200 conf = NULL; 1201 } 1202 1203 if (new_ctx) { 1204 /* recalc considering the link we'll use it for now */ 1205 _ieee80211_recalc_chanctx_min_def(local, new_ctx, link, false); 1206 1207 ret = drv_assign_vif_chanctx(local, sdata, link->conf, new_ctx); 1208 if (assign_on_failure || !ret) { 1209 /* Need to continue, see _ieee80211_set_active_links */ 1210 WARN_ON_ONCE(ret && !local->in_reconfig); 1211 ret = 0; 1212 1213 /* succeeded, so commit it to the data structures */ 1214 conf = &new_ctx->conf; 1215 } 1216 } else { 1217 ret = 0; 1218 } 1219 1220 rcu_assign_pointer(link->conf->chanctx_conf, conf); 1221 1222 if (curr_ctx && ieee80211_chanctx_num_assigned(local, curr_ctx) > 0) { 1223 ieee80211_recalc_chanctx_chantype(local, curr_ctx); 1224 ieee80211_recalc_smps_chanctx(local, curr_ctx); 1225 ieee80211_recalc_radar_chanctx(local, curr_ctx); 1226 ieee80211_recalc_chanctx_min_def(local, curr_ctx); 1227 } 1228 1229 if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) { 1230 ieee80211_recalc_txpower(link, false); 1231 ieee80211_recalc_chanctx_min_def(local, new_ctx); 1232 } 1233 1234 if (conf) { 1235 new_idle = false; 1236 } else { 1237 struct ieee80211_link_data *tmp; 1238 1239 new_idle = true; 1240 for_each_sdata_link(local, tmp) { 1241 if (rcu_access_pointer(tmp->conf->chanctx_conf)) { 1242 new_idle = false; 1243 break; 1244 } 1245 } 1246 } 1247 1248 if (new_idle != sdata->vif.cfg.idle) { 1249 sdata->vif.cfg.idle = new_idle; 1250 1251 if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && 1252 sdata->vif.type != NL80211_IFTYPE_MONITOR) 1253 ieee80211_vif_cfg_change_notify(sdata, BSS_CHANGED_IDLE); 1254 } 1255 1256 ieee80211_check_fast_xmit_iface(sdata); 1257 1258 return ret; 1259 } 1260 1261 void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, 1262 struct ieee80211_chanctx *chanctx) 1263 { 1264 struct ieee80211_chanctx_user_iter iter; 1265 struct ieee80211_sub_if_data *sdata; 1266 u8 rx_chains_static, rx_chains_dynamic; 1267 1268 lockdep_assert_wiphy(local->hw.wiphy); 1269 1270 rx_chains_static = 1; 1271 rx_chains_dynamic = 1; 1272 1273 for_each_chanctx_user_assigned(local, chanctx, &iter) { 1274 u8 needed_static, needed_dynamic; 1275 1276 switch (iter.iftype) { 1277 case NL80211_IFTYPE_STATION: 1278 if (!iter.sdata->u.mgd.associated) 1279 continue; 1280 break; 1281 case NL80211_IFTYPE_MONITOR: 1282 if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) 1283 continue; 1284 break; 1285 case NL80211_IFTYPE_AP: 1286 case NL80211_IFTYPE_ADHOC: 1287 case NL80211_IFTYPE_MESH_POINT: 1288 case NL80211_IFTYPE_OCB: 1289 case NL80211_IFTYPE_NAN: 1290 break; 1291 default: 1292 continue; 1293 } 1294 1295 if (iter.iftype == NL80211_IFTYPE_MONITOR) { 1296 rx_chains_dynamic = rx_chains_static = local->rx_chains; 1297 break; 1298 } 1299 1300 if (iter.nan_channel) { 1301 rx_chains_dynamic = rx_chains_static = 1302 iter.nan_channel->needed_rx_chains; 1303 break; 1304 } 1305 1306 if (!iter.link) 1307 continue; 1308 1309 switch (iter.link->smps_mode) { 1310 default: 1311 WARN_ONCE(1, "Invalid SMPS mode %d\n", 1312 iter.link->smps_mode); 1313 fallthrough; 1314 case IEEE80211_SMPS_OFF: 1315 needed_static = iter.link->needed_rx_chains; 1316 needed_dynamic = iter.link->needed_rx_chains; 1317 break; 1318 case IEEE80211_SMPS_DYNAMIC: 1319 needed_static = 1; 1320 needed_dynamic = iter.link->needed_rx_chains; 1321 break; 1322 case IEEE80211_SMPS_STATIC: 1323 needed_static = 1; 1324 needed_dynamic = 1; 1325 break; 1326 } 1327 1328 rx_chains_static = max(rx_chains_static, needed_static); 1329 rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic); 1330 } 1331 1332 /* Disable SMPS for the monitor interface */ 1333 sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata); 1334 if (sdata && 1335 rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) == &chanctx->conf) 1336 rx_chains_dynamic = rx_chains_static = local->rx_chains; 1337 1338 if (rx_chains_static == chanctx->conf.rx_chains_static && 1339 rx_chains_dynamic == chanctx->conf.rx_chains_dynamic) 1340 return; 1341 1342 chanctx->conf.rx_chains_static = rx_chains_static; 1343 chanctx->conf.rx_chains_dynamic = rx_chains_dynamic; 1344 drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS); 1345 } 1346 1347 static void 1348 __ieee80211_link_copy_chanctx_to_vlans(struct ieee80211_link_data *link, 1349 bool clear) 1350 { 1351 struct ieee80211_sub_if_data *sdata = link->sdata; 1352 unsigned int link_id = link->link_id; 1353 struct ieee80211_bss_conf *link_conf = link->conf; 1354 struct ieee80211_local *local __maybe_unused = sdata->local; 1355 struct ieee80211_sub_if_data *vlan; 1356 struct ieee80211_chanctx_conf *conf; 1357 1358 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP)) 1359 return; 1360 1361 lockdep_assert_wiphy(local->hw.wiphy); 1362 1363 /* Check that conf exists, even when clearing this function 1364 * must be called with the AP's channel context still there 1365 * as it would otherwise cause VLANs to have an invalid 1366 * channel context pointer for a while, possibly pointing 1367 * to a channel context that has already been freed. 1368 */ 1369 conf = rcu_dereference_protected(link_conf->chanctx_conf, 1370 lockdep_is_held(&local->hw.wiphy->mtx)); 1371 WARN_ON(!conf); 1372 1373 if (clear) 1374 conf = NULL; 1375 1376 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { 1377 struct ieee80211_bss_conf *vlan_conf; 1378 1379 if (vlan->vif.valid_links && 1380 !(vlan->vif.valid_links & BIT(link_id))) 1381 continue; 1382 1383 vlan_conf = wiphy_dereference(local->hw.wiphy, 1384 vlan->vif.link_conf[link_id]); 1385 if (WARN_ON(!vlan_conf)) 1386 continue; 1387 1388 rcu_assign_pointer(vlan_conf->chanctx_conf, conf); 1389 } 1390 } 1391 1392 void ieee80211_link_copy_chanctx_to_vlans(struct ieee80211_link_data *link, 1393 bool clear) 1394 { 1395 struct ieee80211_local *local = link->sdata->local; 1396 1397 lockdep_assert_wiphy(local->hw.wiphy); 1398 1399 __ieee80211_link_copy_chanctx_to_vlans(link, clear); 1400 } 1401 1402 void ieee80211_link_unreserve_chanctx(struct ieee80211_link_data *link) 1403 { 1404 struct ieee80211_sub_if_data *sdata = link->sdata; 1405 struct ieee80211_chanctx *ctx = link->reserved_chanctx; 1406 1407 lockdep_assert_wiphy(sdata->local->hw.wiphy); 1408 1409 if (WARN_ON(!ctx)) 1410 return; 1411 1412 link->reserved_chanctx = NULL; 1413 1414 if (ieee80211_chanctx_refcount(sdata->local, ctx) == 0) { 1415 if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) { 1416 if (WARN_ON(!ctx->replace_ctx)) 1417 return; 1418 1419 WARN_ON(ctx->replace_ctx->replace_state != 1420 IEEE80211_CHANCTX_WILL_BE_REPLACED); 1421 WARN_ON(ctx->replace_ctx->replace_ctx != ctx); 1422 1423 ctx->replace_ctx->replace_ctx = NULL; 1424 ctx->replace_ctx->replace_state = 1425 IEEE80211_CHANCTX_REPLACE_NONE; 1426 1427 list_del_rcu(&ctx->list); 1428 kfree_rcu(ctx, rcu_head); 1429 } else { 1430 ieee80211_free_chanctx(sdata->local, ctx, false); 1431 } 1432 } 1433 } 1434 1435 static struct ieee80211_chanctx * 1436 ieee80211_replace_chanctx(struct ieee80211_local *local, 1437 const struct ieee80211_chan_req *chanreq, 1438 enum ieee80211_chanctx_mode mode, 1439 struct ieee80211_chanctx *curr_ctx) 1440 { 1441 struct ieee80211_chanctx *new_ctx, *ctx; 1442 struct wiphy *wiphy = local->hw.wiphy; 1443 const struct wiphy_radio *radio; 1444 1445 if (!curr_ctx || 1446 curr_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED || 1447 ieee80211_chanctx_num_reserved(local, curr_ctx) != 0) { 1448 /* 1449 * Another link already requested this context for a 1450 * reservation. Find another one hoping all links assigned 1451 * to it will also switch soon enough. 1452 * 1453 * TODO: This needs a little more work as some cases 1454 * (more than 2 chanctx capable devices) may fail which could 1455 * otherwise succeed provided some channel context juggling was 1456 * performed. 1457 * 1458 * Consider ctx1..3, link1..6, each ctx has 2 links. link1 and 1459 * link2 from ctx1 request new different chandefs starting 2 1460 * in-place reservations with ctx4 and ctx5 replacing ctx1 and 1461 * ctx2 respectively. Next link5 and link6 from ctx3 reserve 1462 * ctx4. If link3 and link4 remain on ctx2 as they are then this 1463 * fails unless `replace_ctx` from ctx5 is replaced with ctx3. 1464 */ 1465 list_for_each_entry(ctx, &local->chanctx_list, list) { 1466 if (ctx->replace_state != 1467 IEEE80211_CHANCTX_REPLACE_NONE) 1468 continue; 1469 1470 if (ieee80211_chanctx_num_reserved(local, ctx) != 0) 1471 continue; 1472 1473 if (ctx->conf.radio_idx >= 0) { 1474 radio = &wiphy->radio[ctx->conf.radio_idx]; 1475 if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper)) 1476 continue; 1477 } 1478 1479 curr_ctx = ctx; 1480 break; 1481 } 1482 } 1483 1484 /* 1485 * If that's true then all available contexts already have reservations 1486 * and cannot be used. 1487 */ 1488 if (!curr_ctx || 1489 curr_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED || 1490 ieee80211_chanctx_num_reserved(local, curr_ctx) != 0) 1491 return ERR_PTR(-EBUSY); 1492 1493 new_ctx = ieee80211_alloc_chanctx(local, chanreq, mode, -1); 1494 if (!new_ctx) 1495 return ERR_PTR(-ENOMEM); 1496 1497 new_ctx->replace_ctx = curr_ctx; 1498 new_ctx->replace_state = IEEE80211_CHANCTX_REPLACES_OTHER; 1499 1500 curr_ctx->replace_ctx = new_ctx; 1501 curr_ctx->replace_state = IEEE80211_CHANCTX_WILL_BE_REPLACED; 1502 1503 list_add_rcu(&new_ctx->list, &local->chanctx_list); 1504 1505 return new_ctx; 1506 } 1507 1508 static bool 1509 ieee80211_find_available_radio(struct ieee80211_local *local, 1510 const struct ieee80211_chan_req *chanreq, 1511 u32 radio_mask, int *radio_idx) 1512 { 1513 struct wiphy *wiphy = local->hw.wiphy; 1514 const struct wiphy_radio *radio; 1515 int i; 1516 1517 *radio_idx = -1; 1518 if (!wiphy->n_radio) 1519 return true; 1520 1521 for (i = 0; i < wiphy->n_radio; i++) { 1522 if (!(radio_mask & BIT(i))) 1523 continue; 1524 1525 radio = &wiphy->radio[i]; 1526 if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper)) 1527 continue; 1528 1529 if (!ieee80211_can_create_new_chanctx(local, i)) 1530 continue; 1531 1532 *radio_idx = i; 1533 return true; 1534 } 1535 1536 return false; 1537 } 1538 1539 int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link, 1540 const struct ieee80211_chan_req *chanreq, 1541 enum ieee80211_chanctx_mode mode, 1542 bool radar_required) 1543 { 1544 struct ieee80211_sub_if_data *sdata = link->sdata; 1545 struct ieee80211_local *local = sdata->local; 1546 struct ieee80211_chanctx *new_ctx, *curr_ctx; 1547 int radio_idx; 1548 1549 lockdep_assert_wiphy(local->hw.wiphy); 1550 1551 curr_ctx = ieee80211_link_get_chanctx(link); 1552 if (curr_ctx && !local->ops->switch_vif_chanctx) 1553 return -EOPNOTSUPP; 1554 1555 new_ctx = ieee80211_find_reservation_chanctx(local, chanreq, mode); 1556 if (!new_ctx) { 1557 if (ieee80211_can_create_new_chanctx(local, -1) && 1558 ieee80211_find_available_radio(local, chanreq, 1559 sdata->wdev.radio_mask, 1560 &radio_idx)) 1561 new_ctx = ieee80211_new_chanctx(local, chanreq, mode, 1562 false, radio_idx); 1563 else 1564 new_ctx = ieee80211_replace_chanctx(local, chanreq, 1565 mode, curr_ctx); 1566 if (IS_ERR(new_ctx)) 1567 return PTR_ERR(new_ctx); 1568 } 1569 1570 link->reserved_chanctx = new_ctx; 1571 link->reserved = *chanreq; 1572 link->reserved_radar_required = radar_required; 1573 link->reserved_ready = false; 1574 1575 return 0; 1576 } 1577 1578 static void 1579 ieee80211_link_chanctx_reservation_complete(struct ieee80211_link_data *link) 1580 { 1581 struct ieee80211_sub_if_data *sdata = link->sdata; 1582 1583 switch (sdata->vif.type) { 1584 case NL80211_IFTYPE_ADHOC: 1585 case NL80211_IFTYPE_AP: 1586 case NL80211_IFTYPE_MESH_POINT: 1587 case NL80211_IFTYPE_OCB: 1588 wiphy_work_queue(sdata->local->hw.wiphy, 1589 &link->csa.finalize_work); 1590 break; 1591 case NL80211_IFTYPE_STATION: 1592 wiphy_hrtimer_work_queue(sdata->local->hw.wiphy, 1593 &link->u.mgd.csa.switch_work, 0); 1594 break; 1595 case NL80211_IFTYPE_UNSPECIFIED: 1596 case NL80211_IFTYPE_AP_VLAN: 1597 case NL80211_IFTYPE_WDS: 1598 case NL80211_IFTYPE_MONITOR: 1599 case NL80211_IFTYPE_P2P_CLIENT: 1600 case NL80211_IFTYPE_P2P_GO: 1601 case NL80211_IFTYPE_P2P_DEVICE: 1602 case NL80211_IFTYPE_NAN: 1603 case NL80211_IFTYPE_NAN_DATA: 1604 case NL80211_IFTYPE_PD: 1605 case NUM_NL80211_IFTYPES: 1606 WARN_ON(1); 1607 break; 1608 } 1609 } 1610 1611 static void 1612 ieee80211_link_update_chanreq(struct ieee80211_link_data *link, 1613 const struct ieee80211_chan_req *chanreq) 1614 { 1615 struct ieee80211_sub_if_data *sdata = link->sdata; 1616 unsigned int link_id = link->link_id; 1617 struct ieee80211_sub_if_data *vlan; 1618 1619 link->conf->chanreq = *chanreq; 1620 1621 if (sdata->vif.type != NL80211_IFTYPE_AP) 1622 return; 1623 1624 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { 1625 struct ieee80211_bss_conf *vlan_conf; 1626 1627 if (vlan->vif.valid_links && 1628 !(vlan->vif.valid_links & BIT(link_id))) 1629 continue; 1630 1631 vlan_conf = wiphy_dereference(sdata->local->hw.wiphy, 1632 vlan->vif.link_conf[link_id]); 1633 if (WARN_ON(!vlan_conf)) 1634 continue; 1635 1636 vlan_conf->chanreq = *chanreq; 1637 } 1638 } 1639 1640 static int 1641 ieee80211_link_use_reserved_reassign(struct ieee80211_link_data *link) 1642 { 1643 struct ieee80211_sub_if_data *sdata = link->sdata; 1644 struct ieee80211_bss_conf *link_conf = link->conf; 1645 struct ieee80211_local *local = sdata->local; 1646 struct ieee80211_vif_chanctx_switch vif_chsw[1] = {}; 1647 struct ieee80211_chanctx *old_ctx, *new_ctx; 1648 const struct ieee80211_chan_req *chanreq; 1649 struct ieee80211_chan_req tmp; 1650 u64 changed = 0; 1651 int err; 1652 1653 lockdep_assert_wiphy(local->hw.wiphy); 1654 1655 new_ctx = link->reserved_chanctx; 1656 old_ctx = ieee80211_link_get_chanctx(link); 1657 1658 if (WARN_ON(!link->reserved_ready)) 1659 return -EBUSY; 1660 1661 if (WARN_ON(!new_ctx)) 1662 return -EINVAL; 1663 1664 if (WARN_ON(!old_ctx)) 1665 return -EINVAL; 1666 1667 if (WARN_ON(new_ctx->replace_state == 1668 IEEE80211_CHANCTX_REPLACES_OTHER)) 1669 return -EINVAL; 1670 1671 chanreq = ieee80211_chanctx_non_reserved_chandef(local, new_ctx, 1672 &link->reserved, 1673 &tmp); 1674 if (WARN_ON(!chanreq)) 1675 return -EINVAL; 1676 1677 if (link_conf->chanreq.oper.width != link->reserved.oper.width) 1678 changed = BSS_CHANGED_BANDWIDTH; 1679 1680 ieee80211_link_update_chanreq(link, &link->reserved); 1681 1682 _ieee80211_change_chanctx(local, new_ctx, old_ctx, chanreq, link); 1683 1684 vif_chsw[0].vif = &sdata->vif; 1685 vif_chsw[0].old_ctx = &old_ctx->conf; 1686 vif_chsw[0].new_ctx = &new_ctx->conf; 1687 vif_chsw[0].link_conf = link->conf; 1688 1689 link->reserved_chanctx = NULL; 1690 1691 err = drv_switch_vif_chanctx(local, vif_chsw, 1, 1692 CHANCTX_SWMODE_REASSIGN_VIF); 1693 if (err) { 1694 if (ieee80211_chanctx_refcount(local, new_ctx) == 0) 1695 ieee80211_free_chanctx(local, new_ctx, false); 1696 1697 goto out; 1698 } 1699 1700 link->radar_required = link->reserved_radar_required; 1701 rcu_assign_pointer(link_conf->chanctx_conf, &new_ctx->conf); 1702 1703 if (sdata->vif.type == NL80211_IFTYPE_AP) 1704 __ieee80211_link_copy_chanctx_to_vlans(link, false); 1705 1706 ieee80211_check_fast_xmit_iface(sdata); 1707 1708 if (ieee80211_chanctx_refcount(local, old_ctx) == 0) 1709 ieee80211_free_chanctx(local, old_ctx, false); 1710 1711 ieee80211_recalc_chanctx_min_def(local, new_ctx); 1712 ieee80211_recalc_smps_chanctx(local, new_ctx); 1713 ieee80211_recalc_radar_chanctx(local, new_ctx); 1714 1715 if (changed) 1716 ieee80211_link_info_change_notify(sdata, link, changed); 1717 1718 out: 1719 ieee80211_link_chanctx_reservation_complete(link); 1720 return err; 1721 } 1722 1723 static int 1724 ieee80211_link_use_reserved_assign(struct ieee80211_link_data *link) 1725 { 1726 struct ieee80211_sub_if_data *sdata = link->sdata; 1727 struct ieee80211_local *local = sdata->local; 1728 struct ieee80211_chanctx *old_ctx, *new_ctx; 1729 const struct ieee80211_chan_req *chanreq; 1730 struct ieee80211_chan_req tmp; 1731 int err; 1732 1733 old_ctx = ieee80211_link_get_chanctx(link); 1734 new_ctx = link->reserved_chanctx; 1735 1736 if (WARN_ON(!link->reserved_ready)) 1737 return -EINVAL; 1738 1739 if (WARN_ON(old_ctx)) 1740 return -EINVAL; 1741 1742 if (WARN_ON(!new_ctx)) 1743 return -EINVAL; 1744 1745 if (WARN_ON(new_ctx->replace_state == 1746 IEEE80211_CHANCTX_REPLACES_OTHER)) 1747 return -EINVAL; 1748 1749 chanreq = ieee80211_chanctx_non_reserved_chandef(local, new_ctx, 1750 &link->reserved, 1751 &tmp); 1752 if (WARN_ON(!chanreq)) 1753 return -EINVAL; 1754 1755 ieee80211_change_chanctx(local, new_ctx, new_ctx, chanreq); 1756 1757 link->reserved_chanctx = NULL; 1758 1759 err = ieee80211_assign_link_chanctx(link, new_ctx, false); 1760 if (err) { 1761 if (ieee80211_chanctx_refcount(local, new_ctx) == 0) 1762 ieee80211_free_chanctx(local, new_ctx, false); 1763 1764 goto out; 1765 } 1766 1767 out: 1768 ieee80211_link_chanctx_reservation_complete(link); 1769 return err; 1770 } 1771 1772 static bool 1773 ieee80211_link_has_in_place_reservation(struct ieee80211_link_data *link) 1774 { 1775 struct ieee80211_sub_if_data *sdata = link->sdata; 1776 struct ieee80211_chanctx *old_ctx, *new_ctx; 1777 1778 lockdep_assert_wiphy(sdata->local->hw.wiphy); 1779 1780 new_ctx = link->reserved_chanctx; 1781 old_ctx = ieee80211_link_get_chanctx(link); 1782 1783 if (!old_ctx) 1784 return false; 1785 1786 if (WARN_ON(!new_ctx)) 1787 return false; 1788 1789 if (old_ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED) 1790 return false; 1791 1792 if (new_ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1793 return false; 1794 1795 return true; 1796 } 1797 1798 static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local, 1799 int n_vifs) 1800 { 1801 struct ieee80211_vif_chanctx_switch *vif_chsw; 1802 struct ieee80211_chanctx *ctx, *old_ctx; 1803 int i, err; 1804 1805 lockdep_assert_wiphy(local->hw.wiphy); 1806 1807 vif_chsw = kzalloc_objs(vif_chsw[0], n_vifs); 1808 if (!vif_chsw) 1809 return -ENOMEM; 1810 1811 i = 0; 1812 list_for_each_entry(ctx, &local->chanctx_list, list) { 1813 struct ieee80211_chanctx_user_iter iter; 1814 1815 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1816 continue; 1817 1818 if (WARN_ON(!ctx->replace_ctx)) { 1819 err = -EINVAL; 1820 goto out; 1821 } 1822 1823 for_each_chanctx_user_reserved(local, ctx, &iter) { 1824 if (!ieee80211_link_has_in_place_reservation(iter.link)) 1825 continue; 1826 1827 old_ctx = ieee80211_link_get_chanctx(iter.link); 1828 vif_chsw[i].vif = &iter.sdata->vif; 1829 vif_chsw[i].old_ctx = &old_ctx->conf; 1830 vif_chsw[i].new_ctx = &ctx->conf; 1831 vif_chsw[i].link_conf = iter.link->conf; 1832 1833 i++; 1834 } 1835 } 1836 1837 err = drv_switch_vif_chanctx(local, vif_chsw, n_vifs, 1838 CHANCTX_SWMODE_SWAP_CONTEXTS); 1839 1840 out: 1841 kfree(vif_chsw); 1842 return err; 1843 } 1844 1845 static int ieee80211_chsw_switch_ctxs(struct ieee80211_local *local) 1846 { 1847 struct ieee80211_chanctx *ctx; 1848 int err; 1849 1850 lockdep_assert_wiphy(local->hw.wiphy); 1851 1852 list_for_each_entry(ctx, &local->chanctx_list, list) { 1853 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1854 continue; 1855 1856 if (ieee80211_chanctx_num_assigned(local, ctx) != 0) 1857 continue; 1858 1859 ieee80211_del_chanctx(local, ctx->replace_ctx, false); 1860 err = ieee80211_add_chanctx(local, ctx); 1861 if (err) 1862 goto err; 1863 } 1864 1865 return 0; 1866 1867 err: 1868 WARN_ON(ieee80211_add_chanctx(local, ctx)); 1869 list_for_each_entry_continue_reverse(ctx, &local->chanctx_list, list) { 1870 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1871 continue; 1872 1873 if (ieee80211_chanctx_num_assigned(local, ctx) != 0) 1874 continue; 1875 1876 ieee80211_del_chanctx(local, ctx, false); 1877 WARN_ON(ieee80211_add_chanctx(local, ctx->replace_ctx)); 1878 } 1879 1880 return err; 1881 } 1882 1883 static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) 1884 { 1885 struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx; 1886 int err, n_assigned, n_reserved, n_ready; 1887 int n_ctx = 0, n_vifs_switch = 0, n_vifs_assign = 0, n_vifs_ctxless = 0; 1888 1889 lockdep_assert_wiphy(local->hw.wiphy); 1890 1891 /* 1892 * If there are 2 independent pairs of channel contexts performing 1893 * cross-switch of their vifs this code will still wait until both are 1894 * ready even though it could be possible to switch one before the 1895 * other is ready. 1896 * 1897 * For practical reasons and code simplicity just do a single huge 1898 * switch. 1899 */ 1900 1901 /* 1902 * Verify if the reservation is still feasible. 1903 * - if it's not then disconnect 1904 * - if it is but not all vifs necessary are ready then defer 1905 */ 1906 1907 list_for_each_entry(ctx, &local->chanctx_list, list) { 1908 struct ieee80211_chanctx_user_iter iter; 1909 1910 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1911 continue; 1912 1913 if (WARN_ON(!ctx->replace_ctx)) { 1914 err = -EINVAL; 1915 goto err; 1916 } 1917 1918 n_ctx++; 1919 1920 n_assigned = 0; 1921 n_reserved = 0; 1922 n_ready = 0; 1923 1924 for_each_chanctx_user_assigned(local, ctx->replace_ctx, &iter) { 1925 n_assigned++; 1926 if (iter.link && iter.link->reserved_chanctx) { 1927 n_reserved++; 1928 if (iter.link->reserved_ready) 1929 n_ready++; 1930 } 1931 } 1932 1933 if (n_assigned != n_reserved) { 1934 if (n_ready != n_reserved) 1935 return -EAGAIN; 1936 1937 if (n_assigned == n_reserved + 1 && 1938 ieee80211_nan_try_evacuate(&local->hw, 1939 &ctx->replace_ctx->conf)) 1940 goto use_reserved; 1941 1942 wiphy_info(local->hw.wiphy, 1943 "channel context reservation cannot be finalized because some interfaces aren't switching\n"); 1944 err = -EBUSY; 1945 goto err; 1946 } 1947 1948 use_reserved: 1949 ctx->conf.radar_enabled = false; 1950 for_each_chanctx_user_reserved(local, ctx, &iter) { 1951 if (ieee80211_link_has_in_place_reservation(iter.link) && 1952 !iter.link->reserved_ready) 1953 return -EAGAIN; 1954 1955 old_ctx = ieee80211_link_get_chanctx(iter.link); 1956 if (old_ctx) { 1957 if (old_ctx->replace_state == 1958 IEEE80211_CHANCTX_WILL_BE_REPLACED) 1959 n_vifs_switch++; 1960 else 1961 n_vifs_assign++; 1962 } else { 1963 n_vifs_ctxless++; 1964 } 1965 1966 if (iter.radar_required) 1967 ctx->conf.radar_enabled = true; 1968 } 1969 } 1970 1971 if (WARN_ON(n_ctx == 0) || 1972 WARN_ON(n_vifs_switch == 0 && 1973 n_vifs_assign == 0 && 1974 n_vifs_ctxless == 0)) { 1975 err = -EINVAL; 1976 goto err; 1977 } 1978 1979 /* update station rate control and min width before switch */ 1980 list_for_each_entry(ctx, &local->chanctx_list, list) { 1981 struct ieee80211_chanctx_user_iter iter; 1982 1983 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1984 continue; 1985 1986 if (WARN_ON(!ctx->replace_ctx)) { 1987 err = -EINVAL; 1988 goto err; 1989 } 1990 1991 for_each_chanctx_user_reserved(local, ctx, &iter) { 1992 if (!ieee80211_link_has_in_place_reservation(iter.link)) 1993 continue; 1994 1995 ieee80211_chan_bw_change(local, 1996 ieee80211_link_get_chanctx(iter.link), 1997 true, true); 1998 } 1999 2000 _ieee80211_recalc_chanctx_min_def(local, ctx, NULL, true); 2001 } 2002 2003 /* 2004 * All necessary vifs are ready. Perform the switch now depending on 2005 * reservations and driver capabilities. 2006 */ 2007 2008 if (n_vifs_switch > 0) { 2009 err = ieee80211_chsw_switch_vifs(local, n_vifs_switch); 2010 if (err) 2011 goto err; 2012 } 2013 2014 if (n_vifs_assign > 0 || n_vifs_ctxless > 0) { 2015 err = ieee80211_chsw_switch_ctxs(local); 2016 if (err) 2017 goto err; 2018 } 2019 2020 /* 2021 * Update all structures, values and pointers to point to new channel 2022 * context(s). 2023 */ 2024 list_for_each_entry(ctx, &local->chanctx_list, list) { 2025 struct ieee80211_chanctx_user_iter iter; 2026 2027 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 2028 continue; 2029 2030 if (WARN_ON(!ctx->replace_ctx)) { 2031 err = -EINVAL; 2032 goto err; 2033 } 2034 2035 for_each_chanctx_user_reserved(local, ctx, &iter) { 2036 struct ieee80211_link_data *link = iter.link; 2037 struct ieee80211_sub_if_data *sdata = iter.sdata; 2038 struct ieee80211_bss_conf *link_conf = link->conf; 2039 u64 changed = 0; 2040 2041 if (!ieee80211_link_has_in_place_reservation(link)) 2042 continue; 2043 2044 rcu_assign_pointer(link_conf->chanctx_conf, 2045 &ctx->conf); 2046 2047 if (sdata->vif.type == NL80211_IFTYPE_AP) 2048 __ieee80211_link_copy_chanctx_to_vlans(link, 2049 false); 2050 2051 ieee80211_check_fast_xmit_iface(sdata); 2052 2053 link->radar_required = iter.radar_required; 2054 2055 if (link_conf->chanreq.oper.width != iter.chanreq->oper.width) 2056 changed = BSS_CHANGED_BANDWIDTH; 2057 2058 ieee80211_link_update_chanreq(link, &link->reserved); 2059 if (changed) 2060 ieee80211_link_info_change_notify(sdata, 2061 link, 2062 changed); 2063 2064 ieee80211_recalc_txpower(link, false); 2065 } 2066 2067 ieee80211_recalc_chanctx_chantype(local, ctx); 2068 ieee80211_recalc_smps_chanctx(local, ctx); 2069 ieee80211_recalc_radar_chanctx(local, ctx); 2070 ieee80211_recalc_chanctx_min_def(local, ctx); 2071 2072 for_each_chanctx_user_reserved(local, ctx, &iter) { 2073 if (ieee80211_link_get_chanctx(iter.link) != ctx) 2074 continue; 2075 2076 iter.link->reserved_chanctx = NULL; 2077 2078 ieee80211_link_chanctx_reservation_complete(iter.link); 2079 ieee80211_chan_bw_change(local, ctx, false, false); 2080 } 2081 2082 /* 2083 * This context might have been a dependency for an already 2084 * ready re-assign reservation interface that was deferred. Do 2085 * not propagate error to the caller though. The in-place 2086 * reservation for originally requested interface has already 2087 * succeeded at this point. 2088 */ 2089 for_each_chanctx_user_reserved(local, ctx, &iter) { 2090 struct ieee80211_link_data *link = iter.link; 2091 2092 if (WARN_ON(ieee80211_link_has_in_place_reservation(link))) 2093 continue; 2094 2095 if (!link->reserved_ready) 2096 continue; 2097 2098 if (ieee80211_link_get_chanctx(link)) 2099 err = ieee80211_link_use_reserved_reassign(link); 2100 else 2101 err = ieee80211_link_use_reserved_assign(link); 2102 2103 if (err) { 2104 link_info(link, 2105 "failed to finalize (re-)assign reservation (err=%d)\n", 2106 err); 2107 ieee80211_link_unreserve_chanctx(link); 2108 cfg80211_stop_iface(local->hw.wiphy, 2109 &link->sdata->wdev, 2110 GFP_KERNEL); 2111 } 2112 } 2113 } 2114 2115 /* 2116 * Finally free old contexts 2117 */ 2118 2119 list_for_each_entry_safe(ctx, ctx_tmp, &local->chanctx_list, list) { 2120 if (ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED) 2121 continue; 2122 2123 ctx->replace_ctx->replace_ctx = NULL; 2124 ctx->replace_ctx->replace_state = 2125 IEEE80211_CHANCTX_REPLACE_NONE; 2126 2127 list_del_rcu(&ctx->list); 2128 kfree_rcu(ctx, rcu_head); 2129 } 2130 2131 return 0; 2132 2133 err: 2134 list_for_each_entry(ctx, &local->chanctx_list, list) { 2135 struct ieee80211_chanctx_user_iter iter; 2136 2137 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 2138 continue; 2139 2140 for_each_chanctx_user_reserved(local, ctx, &iter) { 2141 ieee80211_link_unreserve_chanctx(iter.link); 2142 ieee80211_link_chanctx_reservation_complete(iter.link); 2143 } 2144 } 2145 2146 return err; 2147 } 2148 2149 void __ieee80211_link_release_channel(struct ieee80211_link_data *link, 2150 bool skip_idle_recalc) 2151 { 2152 struct ieee80211_sub_if_data *sdata = link->sdata; 2153 struct ieee80211_bss_conf *link_conf = link->conf; 2154 struct ieee80211_local *local = sdata->local; 2155 struct ieee80211_chanctx_conf *conf; 2156 struct ieee80211_chanctx *ctx; 2157 bool use_reserved_switch = false; 2158 2159 lockdep_assert_wiphy(local->hw.wiphy); 2160 2161 conf = rcu_dereference_protected(link_conf->chanctx_conf, 2162 lockdep_is_held(&local->hw.wiphy->mtx)); 2163 if (!conf) 2164 return; 2165 2166 ctx = container_of(conf, struct ieee80211_chanctx, conf); 2167 2168 if (link->reserved_chanctx) { 2169 if (link->reserved_chanctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER && 2170 ieee80211_chanctx_num_reserved(local, link->reserved_chanctx) > 1) 2171 use_reserved_switch = true; 2172 2173 ieee80211_link_unreserve_chanctx(link); 2174 } 2175 2176 ieee80211_assign_link_chanctx(link, NULL, false); 2177 if (ieee80211_chanctx_refcount(local, ctx) == 0) 2178 ieee80211_free_chanctx(local, ctx, skip_idle_recalc); 2179 2180 link->radar_required = false; 2181 2182 /* Unreserving may ready an in-place reservation. */ 2183 if (use_reserved_switch) 2184 ieee80211_vif_use_reserved_switch(local); 2185 } 2186 2187 struct ieee80211_chanctx * 2188 ieee80211_find_or_create_chanctx(struct ieee80211_sub_if_data *sdata, 2189 const struct ieee80211_chan_req *chanreq, 2190 enum ieee80211_chanctx_mode mode, 2191 bool assign_on_failure, 2192 bool *reused_ctx) 2193 { 2194 struct ieee80211_local *local = sdata->local; 2195 struct ieee80211_chanctx *ctx; 2196 int radio_idx; 2197 2198 lockdep_assert_wiphy(local->hw.wiphy); 2199 2200 ctx = ieee80211_find_chanctx(local, chanreq, mode); 2201 if (ctx) { 2202 *reused_ctx = true; 2203 return ctx; 2204 } 2205 2206 *reused_ctx = false; 2207 2208 if (!ieee80211_find_available_radio(local, chanreq, 2209 sdata->wdev.radio_mask, 2210 &radio_idx)) 2211 return ERR_PTR(-EBUSY); 2212 2213 return ieee80211_new_chanctx(local, chanreq, mode, 2214 assign_on_failure, radio_idx); 2215 } 2216 2217 static bool 2218 ieee80211_nan_evac_chanctx_filter(struct ieee80211_chanctx *ctx, 2219 void *filter_data) 2220 { 2221 return ctx == filter_data; 2222 } 2223 2224 static int 2225 ieee80211_try_nan_chan_evacuation(struct ieee80211_local *local, 2226 struct ieee80211_sub_if_data *sdata, 2227 const struct cfg80211_chan_def *chandef, 2228 enum ieee80211_chanctx_mode mode, 2229 u8 radar_detect_width) 2230 { 2231 struct ieee80211_sub_if_data *nan_sdata = ieee80211_find_nan_sdata(local); 2232 struct ieee80211_check_combinations_data comb_data = { 2233 .chandef = chandef, 2234 .chanmode = mode, 2235 .radar_detect = radar_detect_width, 2236 .radio_idx = -1, 2237 .chanctx_filter = ieee80211_nan_evac_chanctx_filter, 2238 }; 2239 struct ieee80211_nan_channel *evac_chan; 2240 struct ieee80211_chanctx *evac_ctx; 2241 int ret; 2242 2243 if (!nan_sdata) 2244 return -ENOENT; 2245 2246 /* Find an evacuation candidate... */ 2247 evac_chan = ieee80211_nan_find_evac_chan(local, nan_sdata, NULL); 2248 if (!evac_chan || WARN_ON(!evac_chan->chanctx_conf)) 2249 return -ENOENT; 2250 2251 evac_ctx = container_of(evac_chan->chanctx_conf, 2252 struct ieee80211_chanctx, conf); 2253 2254 /* 2255 * ... check combinations assuming to-be-evacuated ctx is already 2256 * released 2257 */ 2258 comb_data.filter_data = evac_ctx; 2259 ret = ieee80211_check_combinations_ext(sdata, &comb_data); 2260 if (ret < 0) 2261 return ret; 2262 2263 /* That helped! Let's evacuate the channel */ 2264 ieee80211_nan_evacuate_channel(nan_sdata, evac_chan); 2265 2266 /* Re-check, just to be on the safe-side */ 2267 ret = ieee80211_check_combinations(sdata, chandef, mode, 2268 radar_detect_width, -1); 2269 2270 /* That shouldn't happen, we checked before! */ 2271 WARN_ON(ret); 2272 return ret; 2273 } 2274 2275 int _ieee80211_link_use_channel(struct ieee80211_link_data *link, 2276 const struct ieee80211_chan_req *chanreq, 2277 enum ieee80211_chanctx_mode mode, 2278 bool assign_on_failure) 2279 { 2280 struct ieee80211_sub_if_data *sdata = link->sdata; 2281 struct ieee80211_local *local = sdata->local; 2282 struct ieee80211_chanctx *ctx; 2283 u8 radar_detect_width = 0; 2284 bool reused_ctx = false; 2285 int ret; 2286 2287 lockdep_assert_wiphy(local->hw.wiphy); 2288 2289 if (!ieee80211_vif_link_active(&sdata->vif, link->link_id)) { 2290 ieee80211_link_update_chanreq(link, chanreq); 2291 return 0; 2292 } 2293 2294 ret = cfg80211_chandef_dfs_required(local->hw.wiphy, 2295 &chanreq->oper, 2296 sdata->wdev.iftype); 2297 if (ret < 0) 2298 goto out; 2299 if (ret > 0) 2300 radar_detect_width = BIT(chanreq->oper.width); 2301 2302 link->radar_required = ret; 2303 2304 ret = ieee80211_check_combinations(sdata, &chanreq->oper, mode, 2305 radar_detect_width, -1); 2306 if (ret < 0) { 2307 /* Let's check if evacuating a NAN channel will help */ 2308 ret = ieee80211_try_nan_chan_evacuation(local, sdata, 2309 &chanreq->oper, 2310 mode, 2311 radar_detect_width); 2312 if (ret < 0) 2313 goto out; 2314 } 2315 2316 if (!local->in_reconfig) 2317 __ieee80211_link_release_channel(link, false); 2318 2319 ctx = ieee80211_find_or_create_chanctx(sdata, chanreq, mode, 2320 assign_on_failure, &reused_ctx); 2321 if (IS_ERR(ctx)) { 2322 ret = PTR_ERR(ctx); 2323 goto out; 2324 } 2325 2326 ieee80211_link_update_chanreq(link, chanreq); 2327 2328 ret = ieee80211_assign_link_chanctx(link, ctx, assign_on_failure); 2329 2330 /* 2331 * In case an existing channel context is being used, we marked it as 2332 * will_be_used, now that it is assigned - clear this indication 2333 */ 2334 if (reused_ctx) { 2335 WARN_ON(!ctx->will_be_used); 2336 ctx->will_be_used = false; 2337 } 2338 2339 if (ret) { 2340 /* if assign fails refcount stays the same */ 2341 if (ieee80211_chanctx_refcount(local, ctx) == 0) 2342 ieee80211_free_chanctx(local, ctx, false); 2343 goto out; 2344 } 2345 2346 ieee80211_recalc_smps_chanctx(local, ctx); 2347 ieee80211_recalc_radar_chanctx(local, ctx); 2348 out: 2349 if (ret) 2350 link->radar_required = false; 2351 2352 return ret; 2353 } 2354 2355 int ieee80211_link_use_reserved_context(struct ieee80211_link_data *link) 2356 { 2357 struct ieee80211_sub_if_data *sdata = link->sdata; 2358 struct ieee80211_local *local = sdata->local; 2359 struct ieee80211_chanctx *new_ctx; 2360 struct ieee80211_chanctx *old_ctx; 2361 int err; 2362 2363 lockdep_assert_wiphy(local->hw.wiphy); 2364 2365 new_ctx = link->reserved_chanctx; 2366 old_ctx = ieee80211_link_get_chanctx(link); 2367 2368 if (WARN_ON(!new_ctx)) 2369 return -EINVAL; 2370 2371 if (WARN_ON(new_ctx->replace_state == 2372 IEEE80211_CHANCTX_WILL_BE_REPLACED)) 2373 return -EINVAL; 2374 2375 if (WARN_ON(link->reserved_ready)) 2376 return -EINVAL; 2377 2378 link->reserved_ready = true; 2379 2380 if (new_ctx->replace_state == IEEE80211_CHANCTX_REPLACE_NONE) { 2381 if (old_ctx) 2382 return ieee80211_link_use_reserved_reassign(link); 2383 2384 return ieee80211_link_use_reserved_assign(link); 2385 } 2386 2387 /* 2388 * In-place reservation may need to be finalized now either if: 2389 * a) sdata is taking part in the swapping itself and is the last one 2390 * b) sdata has switched with a re-assign reservation to an existing 2391 * context readying in-place switching of old_ctx 2392 * 2393 * In case of (b) do not propagate the error up because the requested 2394 * sdata already switched successfully. Just spill an extra warning. 2395 * The ieee80211_vif_use_reserved_switch() already stops all necessary 2396 * interfaces upon failure. 2397 */ 2398 if ((old_ctx && 2399 old_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) || 2400 new_ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) { 2401 err = ieee80211_vif_use_reserved_switch(local); 2402 if (err && err != -EAGAIN) { 2403 if (new_ctx->replace_state == 2404 IEEE80211_CHANCTX_REPLACES_OTHER) 2405 return err; 2406 2407 wiphy_info(local->hw.wiphy, 2408 "depending in-place reservation failed (err=%d)\n", 2409 err); 2410 } 2411 } 2412 2413 return 0; 2414 } 2415 2416 int ieee80211_link_change_chanreq(struct ieee80211_link_data *link, 2417 const struct ieee80211_chan_req *chanreq, 2418 u64 *changed) 2419 { 2420 struct ieee80211_sub_if_data *sdata = link->sdata; 2421 struct ieee80211_bss_conf *link_conf = link->conf; 2422 struct ieee80211_local *local = sdata->local; 2423 struct ieee80211_chanctx_conf *conf; 2424 struct ieee80211_chanctx *ctx; 2425 const struct ieee80211_chan_req *compat; 2426 struct ieee80211_chan_req tmp; 2427 2428 lockdep_assert_wiphy(local->hw.wiphy); 2429 2430 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, 2431 &chanreq->oper, 2432 IEEE80211_CHAN_DISABLED)) 2433 return -EINVAL; 2434 2435 /* for non-HT 20 MHz the rest doesn't matter */ 2436 if (chanreq->oper.width == NL80211_CHAN_WIDTH_20_NOHT && 2437 cfg80211_chandef_identical(&chanreq->oper, &link_conf->chanreq.oper)) 2438 return 0; 2439 2440 /* but you cannot switch to/from it */ 2441 if (chanreq->oper.width == NL80211_CHAN_WIDTH_20_NOHT || 2442 link_conf->chanreq.oper.width == NL80211_CHAN_WIDTH_20_NOHT) 2443 return -EINVAL; 2444 2445 conf = rcu_dereference_protected(link_conf->chanctx_conf, 2446 lockdep_is_held(&local->hw.wiphy->mtx)); 2447 if (!conf) 2448 return -EINVAL; 2449 2450 ctx = container_of(conf, struct ieee80211_chanctx, conf); 2451 2452 compat = _ieee80211_chanctx_compatible(local, link, ctx, chanreq, &tmp); 2453 if (!compat) 2454 return -EINVAL; 2455 2456 switch (ctx->replace_state) { 2457 case IEEE80211_CHANCTX_REPLACE_NONE: 2458 if (!ieee80211_chanctx_reserved_chanreq(local, ctx, compat, 2459 &tmp)) 2460 return -EBUSY; 2461 break; 2462 case IEEE80211_CHANCTX_WILL_BE_REPLACED: 2463 /* TODO: Perhaps the bandwidth change could be treated as a 2464 * reservation itself? */ 2465 return -EBUSY; 2466 case IEEE80211_CHANCTX_REPLACES_OTHER: 2467 /* channel context that is going to replace another channel 2468 * context doesn't really exist and shouldn't be assigned 2469 * anywhere yet */ 2470 WARN_ON(1); 2471 break; 2472 } 2473 2474 ieee80211_link_update_chanreq(link, chanreq); 2475 2476 ieee80211_recalc_chanctx_chantype(local, ctx); 2477 2478 *changed |= BSS_CHANGED_BANDWIDTH; 2479 return 0; 2480 } 2481 2482 void ieee80211_link_release_channel(struct ieee80211_link_data *link) 2483 { 2484 struct ieee80211_sub_if_data *sdata = link->sdata; 2485 2486 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 2487 return; 2488 2489 lockdep_assert_wiphy(sdata->local->hw.wiphy); 2490 2491 if (rcu_access_pointer(link->conf->chanctx_conf)) 2492 __ieee80211_link_release_channel(link, false); 2493 } 2494 2495 void ieee80211_link_vlan_copy_chanctx(struct ieee80211_link_data *link) 2496 { 2497 struct ieee80211_sub_if_data *sdata = link->sdata; 2498 unsigned int link_id = link->link_id; 2499 struct ieee80211_bss_conf *link_conf = link->conf; 2500 struct ieee80211_bss_conf *ap_conf; 2501 struct ieee80211_local *local = sdata->local; 2502 struct ieee80211_sub_if_data *ap; 2503 struct ieee80211_chanctx_conf *conf; 2504 2505 lockdep_assert_wiphy(local->hw.wiphy); 2506 2507 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss)) 2508 return; 2509 2510 ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); 2511 2512 ap_conf = wiphy_dereference(local->hw.wiphy, 2513 ap->vif.link_conf[link_id]); 2514 conf = wiphy_dereference(local->hw.wiphy, 2515 ap_conf->chanctx_conf); 2516 rcu_assign_pointer(link_conf->chanctx_conf, conf); 2517 } 2518 2519 void ieee80211_iter_chan_contexts_atomic( 2520 struct ieee80211_hw *hw, 2521 void (*iter)(struct ieee80211_hw *hw, 2522 struct ieee80211_chanctx_conf *chanctx_conf, 2523 void *data), 2524 void *iter_data) 2525 { 2526 struct ieee80211_local *local = hw_to_local(hw); 2527 struct ieee80211_chanctx *ctx; 2528 2529 rcu_read_lock(); 2530 list_for_each_entry_rcu(ctx, &local->chanctx_list, list) 2531 if (ctx->driver_present) 2532 iter(hw, &ctx->conf, iter_data); 2533 rcu_read_unlock(); 2534 } 2535 EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic); 2536 2537 void ieee80211_iter_chan_contexts_mtx( 2538 struct ieee80211_hw *hw, 2539 void (*iter)(struct ieee80211_hw *hw, 2540 struct ieee80211_chanctx_conf *chanctx_conf, 2541 void *data), 2542 void *iter_data) 2543 { 2544 struct ieee80211_local *local = hw_to_local(hw); 2545 struct ieee80211_chanctx *ctx; 2546 2547 lockdep_assert_wiphy(hw->wiphy); 2548 2549 list_for_each_entry(ctx, &local->chanctx_list, list) 2550 if (ctx->driver_present) 2551 iter(hw, &ctx->conf, iter_data); 2552 } 2553 EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_mtx); 2554