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