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