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 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 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 28 enum ieee80211_chanctx_iter_type { 29 CHANCTX_ITER_ALL, 30 CHANCTX_ITER_RESERVED, 31 CHANCTX_ITER_ASSIGNED, 32 }; 33 34 static 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 47 next_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 89 next_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 136 static 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 148 static 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 160 int 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 172 static 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 188 static 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 197 static struct ieee80211_chanctx * 198 ieee80211_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 211 bool 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 221 static const struct ieee80211_chan_req * 222 ieee80211_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 242 static const struct ieee80211_chan_req * 243 ieee80211_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 262 static const struct ieee80211_chan_req * 263 ieee80211_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 284 static const struct ieee80211_chan_req * 285 ieee80211_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 308 static bool 309 ieee80211_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 330 static struct ieee80211_chanctx * 331 ieee80211_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 358 static 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 408 static enum nl80211_chan_width 409 ieee80211_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 429 static enum nl80211_chan_width 430 ieee80211_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 */ 511 static 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 553 static 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; 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 sdata = get_bss_sdata(sta->sdata); 572 573 for (link_id = 0; link_id < ARRAY_SIZE(sdata->link); link_id++) { 574 struct ieee80211_link_data *link = 575 rcu_dereference(sdata->link[link_id]); 576 struct ieee80211_bss_conf *link_conf; 577 struct cfg80211_chan_def *new_chandef; 578 struct link_sta_info *link_sta; 579 580 if (!link) 581 continue; 582 583 link_conf = link->conf; 584 585 if (rcu_access_pointer(link_conf->chanctx_conf) != &ctx->conf) 586 continue; 587 588 link_sta = rcu_dereference(sta->link[link_id]); 589 if (!link_sta) 590 continue; 591 592 if (reserved) 593 new_chandef = &link->reserved.oper; 594 else 595 new_chandef = &link_conf->chanreq.oper; 596 597 new_sta_bw = _ieee80211_sta_cur_vht_bw(link_sta, 598 new_chandef); 599 600 /* nothing change */ 601 if (new_sta_bw == link_sta->pub->bandwidth) 602 continue; 603 604 /* vif changed to narrow BW and narrow BW for station wasn't 605 * requested or vice versa */ 606 if ((new_sta_bw < link_sta->pub->bandwidth) == !narrowed) 607 continue; 608 609 link_sta->pub->bandwidth = new_sta_bw; 610 rate_control_rate_update(local, sband, link_sta, 611 IEEE80211_RC_BW_CHANGED); 612 } 613 } 614 rcu_read_unlock(); 615 } 616 617 /* 618 * recalc the min required chan width of the channel context, which is 619 * the max of min required widths of all the interfaces bound to this 620 * channel context. 621 */ 622 static void 623 _ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, 624 struct ieee80211_chanctx *ctx, 625 struct ieee80211_link_data *rsvd_for, 626 bool check_reserved) 627 { 628 u32 changed = __ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for, 629 check_reserved); 630 631 if (!changed) 632 return; 633 634 /* check is BW narrowed */ 635 ieee80211_chan_bw_change(local, ctx, false, true); 636 637 drv_change_chanctx(local, ctx, changed); 638 639 /* check is BW wider */ 640 ieee80211_chan_bw_change(local, ctx, false, false); 641 } 642 643 void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, 644 struct ieee80211_chanctx *ctx) 645 { 646 _ieee80211_recalc_chanctx_min_def(local, ctx, NULL, false); 647 } 648 649 static void _ieee80211_change_chanctx(struct ieee80211_local *local, 650 struct ieee80211_chanctx *ctx, 651 struct ieee80211_chanctx *old_ctx, 652 const struct ieee80211_chan_req *chanreq, 653 struct ieee80211_link_data *rsvd_for) 654 { 655 const struct cfg80211_chan_def *chandef = &chanreq->oper; 656 struct ieee80211_chan_req ctx_req = { 657 .oper = ctx->conf.def, 658 .ap = ctx->conf.ap, 659 }; 660 u32 changed = 0; 661 662 /* 5/10 MHz not handled here */ 663 switch (chandef->width) { 664 case NL80211_CHAN_WIDTH_1: 665 case NL80211_CHAN_WIDTH_2: 666 case NL80211_CHAN_WIDTH_4: 667 case NL80211_CHAN_WIDTH_8: 668 case NL80211_CHAN_WIDTH_16: 669 /* 670 * mac80211 currently only supports sharing identical 671 * chanctx's for S1G interfaces. 672 */ 673 WARN_ON(!ieee80211_chanreq_identical(&ctx_req, chanreq)); 674 return; 675 case NL80211_CHAN_WIDTH_20_NOHT: 676 case NL80211_CHAN_WIDTH_20: 677 case NL80211_CHAN_WIDTH_40: 678 case NL80211_CHAN_WIDTH_80: 679 case NL80211_CHAN_WIDTH_80P80: 680 case NL80211_CHAN_WIDTH_160: 681 case NL80211_CHAN_WIDTH_320: 682 break; 683 default: 684 WARN_ON(1); 685 } 686 687 /* Check maybe BW narrowed - we do this _before_ calling recalc_chanctx_min_def 688 * due to maybe not returning from it, e.g in case new context was added 689 * first time with all parameters up to date. 690 */ 691 ieee80211_chan_bw_change(local, old_ctx, false, true); 692 693 if (ieee80211_chanreq_identical(&ctx_req, chanreq)) { 694 _ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for, false); 695 return; 696 } 697 698 WARN_ON(ieee80211_chanctx_refcount(local, ctx) > 1 && 699 !cfg80211_chandef_compatible(&ctx->conf.def, &chanreq->oper)); 700 701 ieee80211_remove_wbrf(local, &ctx->conf.def); 702 703 if (!cfg80211_chandef_identical(&ctx->conf.def, &chanreq->oper)) { 704 if (ctx->conf.def.width != chanreq->oper.width) 705 changed |= IEEE80211_CHANCTX_CHANGE_WIDTH; 706 if (ctx->conf.def.punctured != chanreq->oper.punctured) 707 changed |= IEEE80211_CHANCTX_CHANGE_PUNCTURING; 708 } 709 if (!cfg80211_chandef_identical(&ctx->conf.ap, &chanreq->ap)) 710 changed |= IEEE80211_CHANCTX_CHANGE_AP; 711 ctx->conf.def = *chandef; 712 ctx->conf.ap = chanreq->ap; 713 714 /* check if min chanctx also changed */ 715 changed |= __ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for, 716 false); 717 718 ieee80211_add_wbrf(local, &ctx->conf.def); 719 720 drv_change_chanctx(local, ctx, changed); 721 722 /* check if BW is wider */ 723 ieee80211_chan_bw_change(local, old_ctx, false, false); 724 } 725 726 static void ieee80211_change_chanctx(struct ieee80211_local *local, 727 struct ieee80211_chanctx *ctx, 728 struct ieee80211_chanctx *old_ctx, 729 const struct ieee80211_chan_req *chanreq) 730 { 731 _ieee80211_change_chanctx(local, ctx, old_ctx, chanreq, NULL); 732 } 733 734 /* Note: if successful, the returned chanctx is reserved for the link */ 735 static struct ieee80211_chanctx * 736 ieee80211_find_chanctx(struct ieee80211_local *local, 737 struct ieee80211_link_data *link, 738 const struct ieee80211_chan_req *chanreq, 739 enum ieee80211_chanctx_mode mode) 740 { 741 struct ieee80211_chan_req tmp; 742 struct ieee80211_chanctx *ctx; 743 744 lockdep_assert_wiphy(local->hw.wiphy); 745 746 if (mode == IEEE80211_CHANCTX_EXCLUSIVE) 747 return NULL; 748 749 if (WARN_ON(link->reserved_chanctx)) 750 return NULL; 751 752 list_for_each_entry(ctx, &local->chanctx_list, list) { 753 const struct ieee80211_chan_req *compat; 754 755 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACE_NONE) 756 continue; 757 758 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) 759 continue; 760 761 compat = ieee80211_chanctx_compatible(ctx, chanreq, &tmp); 762 if (!compat) 763 continue; 764 765 compat = ieee80211_chanctx_reserved_chanreq(local, ctx, 766 compat, &tmp); 767 if (!compat) 768 continue; 769 770 /* 771 * Reserve the chanctx temporarily, as the driver might change 772 * active links during callbacks we make into it below and/or 773 * later during assignment, which could (otherwise) cause the 774 * context to actually be removed. 775 */ 776 link->reserved_chanctx = ctx; 777 778 ieee80211_change_chanctx(local, ctx, ctx, compat); 779 780 return ctx; 781 } 782 783 return NULL; 784 } 785 786 bool ieee80211_is_radar_required(struct ieee80211_local *local, 787 struct cfg80211_scan_request *req) 788 { 789 struct wiphy *wiphy = local->hw.wiphy; 790 struct ieee80211_link_data *link; 791 struct ieee80211_channel *chan; 792 int radio_idx; 793 794 lockdep_assert_wiphy(local->hw.wiphy); 795 796 if (!req) 797 return false; 798 799 for_each_sdata_link(local, link) { 800 if (link->radar_required) { 801 chan = link->conf->chanreq.oper.chan; 802 radio_idx = cfg80211_get_radio_idx_by_chan(wiphy, chan); 803 804 if (ieee80211_is_radio_idx_in_scan_req(wiphy, req, 805 radio_idx)) 806 return true; 807 } 808 } 809 810 return false; 811 } 812 813 static bool 814 ieee80211_chanctx_radar_required(struct ieee80211_local *local, 815 struct ieee80211_chanctx *ctx) 816 { 817 struct ieee80211_chanctx_user_iter iter; 818 819 lockdep_assert_wiphy(local->hw.wiphy); 820 821 for_each_chanctx_user_assigned(local, ctx, &iter) { 822 if (iter.radar_required) 823 return true; 824 } 825 826 return false; 827 } 828 829 static struct ieee80211_chanctx * 830 ieee80211_alloc_chanctx(struct ieee80211_local *local, 831 const struct ieee80211_chan_req *chanreq, 832 enum ieee80211_chanctx_mode mode, 833 int radio_idx) 834 { 835 struct ieee80211_chanctx *ctx; 836 837 lockdep_assert_wiphy(local->hw.wiphy); 838 839 ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL); 840 if (!ctx) 841 return NULL; 842 843 ctx->conf.def = chanreq->oper; 844 ctx->conf.ap = chanreq->ap; 845 ctx->conf.rx_chains_static = 1; 846 ctx->conf.rx_chains_dynamic = 1; 847 ctx->mode = mode; 848 ctx->conf.radar_enabled = false; 849 ctx->conf.radio_idx = radio_idx; 850 ctx->radar_detected = false; 851 __ieee80211_recalc_chanctx_min_def(local, ctx, NULL, false); 852 853 return ctx; 854 } 855 856 static int ieee80211_add_chanctx(struct ieee80211_local *local, 857 struct ieee80211_chanctx *ctx) 858 { 859 u32 changed; 860 int err; 861 862 lockdep_assert_wiphy(local->hw.wiphy); 863 864 ieee80211_add_wbrf(local, &ctx->conf.def); 865 866 /* turn idle off *before* setting channel -- some drivers need that */ 867 changed = ieee80211_idle_off(local); 868 if (changed) 869 ieee80211_hw_config(local, -1, changed); 870 871 err = drv_add_chanctx(local, ctx); 872 if (err) { 873 ieee80211_recalc_idle(local); 874 return err; 875 } 876 877 return 0; 878 } 879 880 static struct ieee80211_chanctx * 881 ieee80211_new_chanctx(struct ieee80211_local *local, 882 const struct ieee80211_chan_req *chanreq, 883 enum ieee80211_chanctx_mode mode, 884 bool assign_on_failure, 885 int radio_idx) 886 { 887 struct ieee80211_chanctx *ctx; 888 int err; 889 890 lockdep_assert_wiphy(local->hw.wiphy); 891 892 ctx = ieee80211_alloc_chanctx(local, chanreq, mode, radio_idx); 893 if (!ctx) 894 return ERR_PTR(-ENOMEM); 895 896 err = ieee80211_add_chanctx(local, ctx); 897 if (!assign_on_failure && err) { 898 kfree(ctx); 899 return ERR_PTR(err); 900 } 901 /* We ignored a driver error, see _ieee80211_set_active_links */ 902 WARN_ON_ONCE(err && !local->in_reconfig); 903 904 list_add_rcu(&ctx->list, &local->chanctx_list); 905 return ctx; 906 } 907 908 static void ieee80211_del_chanctx(struct ieee80211_local *local, 909 struct ieee80211_chanctx *ctx, 910 bool skip_idle_recalc) 911 { 912 lockdep_assert_wiphy(local->hw.wiphy); 913 914 drv_remove_chanctx(local, ctx); 915 916 if (!skip_idle_recalc) 917 ieee80211_recalc_idle(local); 918 919 ieee80211_remove_wbrf(local, &ctx->conf.def); 920 } 921 922 static void ieee80211_free_chanctx(struct ieee80211_local *local, 923 struct ieee80211_chanctx *ctx, 924 bool skip_idle_recalc) 925 { 926 lockdep_assert_wiphy(local->hw.wiphy); 927 928 WARN_ON_ONCE(ieee80211_chanctx_refcount(local, ctx) != 0); 929 930 list_del_rcu(&ctx->list); 931 ieee80211_del_chanctx(local, ctx, skip_idle_recalc); 932 kfree_rcu(ctx, rcu_head); 933 } 934 935 void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, 936 struct ieee80211_chanctx *ctx) 937 { 938 struct ieee80211_chanctx_conf *conf = &ctx->conf; 939 const struct ieee80211_chan_req *compat = NULL; 940 struct ieee80211_chanctx_user_iter iter; 941 struct ieee80211_chan_req tmp; 942 struct sta_info *sta; 943 944 lockdep_assert_wiphy(local->hw.wiphy); 945 946 for_each_chanctx_user_assigned(local, ctx, &iter) { 947 if (!compat) 948 compat = iter.chanreq; 949 950 compat = ieee80211_chanreq_compatible(iter.chanreq, 951 compat, &tmp); 952 if (WARN_ON_ONCE(!compat)) 953 return; 954 } 955 956 if (WARN_ON_ONCE(!compat)) 957 return; 958 959 /* TDLS peers can sometimes affect the chandef width */ 960 list_for_each_entry(sta, &local->sta_list, list) { 961 struct ieee80211_sub_if_data *sdata = sta->sdata; 962 struct ieee80211_chan_req tdls_chanreq = {}; 963 struct ieee80211_link_data *link; 964 int tdls_link_id; 965 966 if (!sta->uploaded || 967 !test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW) || 968 !test_sta_flag(sta, WLAN_STA_AUTHORIZED) || 969 !sta->tdls_chandef.chan) 970 continue; 971 972 tdls_link_id = ieee80211_tdls_sta_link_id(sta); 973 link = sdata_dereference(sdata->link[tdls_link_id], sdata); 974 if (!link) 975 continue; 976 977 if (rcu_access_pointer(link->conf->chanctx_conf) != conf) 978 continue; 979 980 tdls_chanreq.oper = sta->tdls_chandef; 981 982 /* note this always fills and returns &tmp if compat */ 983 compat = ieee80211_chanreq_compatible(&tdls_chanreq, 984 compat, &tmp); 985 if (WARN_ON_ONCE(!compat)) 986 return; 987 } 988 989 ieee80211_change_chanctx(local, ctx, ctx, compat); 990 } 991 992 static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, 993 struct ieee80211_chanctx *chanctx) 994 { 995 bool radar_enabled; 996 997 lockdep_assert_wiphy(local->hw.wiphy); 998 999 radar_enabled = ieee80211_chanctx_radar_required(local, chanctx); 1000 1001 if (radar_enabled == chanctx->conf.radar_enabled) 1002 return; 1003 1004 chanctx->conf.radar_enabled = radar_enabled; 1005 1006 drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR); 1007 } 1008 1009 static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link, 1010 struct ieee80211_chanctx *new_ctx, 1011 bool assign_on_failure) 1012 { 1013 struct ieee80211_sub_if_data *sdata = link->sdata; 1014 struct ieee80211_local *local = sdata->local; 1015 struct ieee80211_chanctx_conf *conf; 1016 struct ieee80211_chanctx *curr_ctx = NULL; 1017 bool new_idle; 1018 int ret; 1019 1020 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_NAN)) 1021 return -EOPNOTSUPP; 1022 1023 conf = rcu_dereference_protected(link->conf->chanctx_conf, 1024 lockdep_is_held(&local->hw.wiphy->mtx)); 1025 1026 if (conf && !local->in_reconfig) { 1027 curr_ctx = container_of(conf, struct ieee80211_chanctx, conf); 1028 1029 drv_unassign_vif_chanctx(local, sdata, link->conf, curr_ctx); 1030 conf = NULL; 1031 } 1032 1033 if (new_ctx) { 1034 /* recalc considering the link we'll use it for now */ 1035 _ieee80211_recalc_chanctx_min_def(local, new_ctx, link, false); 1036 1037 ret = drv_assign_vif_chanctx(local, sdata, link->conf, new_ctx); 1038 if (assign_on_failure || !ret) { 1039 /* Need to continue, see _ieee80211_set_active_links */ 1040 WARN_ON_ONCE(ret && !local->in_reconfig); 1041 ret = 0; 1042 1043 /* succeeded, so commit it to the data structures */ 1044 conf = &new_ctx->conf; 1045 } 1046 } else { 1047 ret = 0; 1048 } 1049 1050 rcu_assign_pointer(link->conf->chanctx_conf, conf); 1051 1052 if (curr_ctx && ieee80211_chanctx_num_assigned(local, curr_ctx) > 0) { 1053 ieee80211_recalc_chanctx_chantype(local, curr_ctx); 1054 ieee80211_recalc_smps_chanctx(local, curr_ctx); 1055 ieee80211_recalc_radar_chanctx(local, curr_ctx); 1056 ieee80211_recalc_chanctx_min_def(local, curr_ctx); 1057 } 1058 1059 if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) { 1060 ieee80211_recalc_txpower(link, false); 1061 ieee80211_recalc_chanctx_min_def(local, new_ctx); 1062 } 1063 1064 if (conf) { 1065 new_idle = false; 1066 } else { 1067 struct ieee80211_link_data *tmp; 1068 1069 new_idle = true; 1070 for_each_sdata_link(local, tmp) { 1071 if (rcu_access_pointer(tmp->conf->chanctx_conf)) { 1072 new_idle = false; 1073 break; 1074 } 1075 } 1076 } 1077 1078 if (new_idle != sdata->vif.cfg.idle) { 1079 sdata->vif.cfg.idle = new_idle; 1080 1081 if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && 1082 sdata->vif.type != NL80211_IFTYPE_MONITOR) 1083 ieee80211_vif_cfg_change_notify(sdata, BSS_CHANGED_IDLE); 1084 } 1085 1086 ieee80211_check_fast_xmit_iface(sdata); 1087 1088 return ret; 1089 } 1090 1091 void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, 1092 struct ieee80211_chanctx *chanctx) 1093 { 1094 struct ieee80211_chanctx_user_iter iter; 1095 struct ieee80211_sub_if_data *sdata; 1096 u8 rx_chains_static, rx_chains_dynamic; 1097 1098 lockdep_assert_wiphy(local->hw.wiphy); 1099 1100 rx_chains_static = 1; 1101 rx_chains_dynamic = 1; 1102 1103 for_each_chanctx_user_assigned(local, chanctx, &iter) { 1104 u8 needed_static, needed_dynamic; 1105 1106 switch (iter.iftype) { 1107 case NL80211_IFTYPE_STATION: 1108 if (!iter.sdata->u.mgd.associated) 1109 continue; 1110 break; 1111 case NL80211_IFTYPE_MONITOR: 1112 if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) 1113 continue; 1114 break; 1115 case NL80211_IFTYPE_AP: 1116 case NL80211_IFTYPE_ADHOC: 1117 case NL80211_IFTYPE_MESH_POINT: 1118 case NL80211_IFTYPE_OCB: 1119 break; 1120 default: 1121 continue; 1122 } 1123 1124 if (iter.iftype == NL80211_IFTYPE_MONITOR) { 1125 rx_chains_dynamic = rx_chains_static = local->rx_chains; 1126 break; 1127 } 1128 1129 switch (iter.link->smps_mode) { 1130 default: 1131 WARN_ONCE(1, "Invalid SMPS mode %d\n", 1132 iter.link->smps_mode); 1133 fallthrough; 1134 case IEEE80211_SMPS_OFF: 1135 needed_static = iter.link->needed_rx_chains; 1136 needed_dynamic = iter.link->needed_rx_chains; 1137 break; 1138 case IEEE80211_SMPS_DYNAMIC: 1139 needed_static = 1; 1140 needed_dynamic = iter.link->needed_rx_chains; 1141 break; 1142 case IEEE80211_SMPS_STATIC: 1143 needed_static = 1; 1144 needed_dynamic = 1; 1145 break; 1146 } 1147 1148 rx_chains_static = max(rx_chains_static, needed_static); 1149 rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic); 1150 } 1151 1152 /* Disable SMPS for the monitor interface */ 1153 sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata); 1154 if (sdata && 1155 rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) == &chanctx->conf) 1156 rx_chains_dynamic = rx_chains_static = local->rx_chains; 1157 1158 if (rx_chains_static == chanctx->conf.rx_chains_static && 1159 rx_chains_dynamic == chanctx->conf.rx_chains_dynamic) 1160 return; 1161 1162 chanctx->conf.rx_chains_static = rx_chains_static; 1163 chanctx->conf.rx_chains_dynamic = rx_chains_dynamic; 1164 drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS); 1165 } 1166 1167 static void 1168 __ieee80211_link_copy_chanctx_to_vlans(struct ieee80211_link_data *link, 1169 bool clear) 1170 { 1171 struct ieee80211_sub_if_data *sdata = link->sdata; 1172 unsigned int link_id = link->link_id; 1173 struct ieee80211_bss_conf *link_conf = link->conf; 1174 struct ieee80211_local *local __maybe_unused = sdata->local; 1175 struct ieee80211_sub_if_data *vlan; 1176 struct ieee80211_chanctx_conf *conf; 1177 1178 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP)) 1179 return; 1180 1181 lockdep_assert_wiphy(local->hw.wiphy); 1182 1183 /* Check that conf exists, even when clearing this function 1184 * must be called with the AP's channel context still there 1185 * as it would otherwise cause VLANs to have an invalid 1186 * channel context pointer for a while, possibly pointing 1187 * to a channel context that has already been freed. 1188 */ 1189 conf = rcu_dereference_protected(link_conf->chanctx_conf, 1190 lockdep_is_held(&local->hw.wiphy->mtx)); 1191 WARN_ON(!conf); 1192 1193 if (clear) 1194 conf = NULL; 1195 1196 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { 1197 struct ieee80211_bss_conf *vlan_conf; 1198 1199 vlan_conf = wiphy_dereference(local->hw.wiphy, 1200 vlan->vif.link_conf[link_id]); 1201 if (WARN_ON(!vlan_conf)) 1202 continue; 1203 1204 rcu_assign_pointer(vlan_conf->chanctx_conf, conf); 1205 } 1206 } 1207 1208 void ieee80211_link_copy_chanctx_to_vlans(struct ieee80211_link_data *link, 1209 bool clear) 1210 { 1211 struct ieee80211_local *local = link->sdata->local; 1212 1213 lockdep_assert_wiphy(local->hw.wiphy); 1214 1215 __ieee80211_link_copy_chanctx_to_vlans(link, clear); 1216 } 1217 1218 void ieee80211_link_unreserve_chanctx(struct ieee80211_link_data *link) 1219 { 1220 struct ieee80211_sub_if_data *sdata = link->sdata; 1221 struct ieee80211_chanctx *ctx = link->reserved_chanctx; 1222 1223 lockdep_assert_wiphy(sdata->local->hw.wiphy); 1224 1225 if (WARN_ON(!ctx)) 1226 return; 1227 1228 link->reserved_chanctx = NULL; 1229 1230 if (ieee80211_chanctx_refcount(sdata->local, ctx) == 0) { 1231 if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) { 1232 if (WARN_ON(!ctx->replace_ctx)) 1233 return; 1234 1235 WARN_ON(ctx->replace_ctx->replace_state != 1236 IEEE80211_CHANCTX_WILL_BE_REPLACED); 1237 WARN_ON(ctx->replace_ctx->replace_ctx != ctx); 1238 1239 ctx->replace_ctx->replace_ctx = NULL; 1240 ctx->replace_ctx->replace_state = 1241 IEEE80211_CHANCTX_REPLACE_NONE; 1242 1243 list_del_rcu(&ctx->list); 1244 kfree_rcu(ctx, rcu_head); 1245 } else { 1246 ieee80211_free_chanctx(sdata->local, ctx, false); 1247 } 1248 } 1249 } 1250 1251 static struct ieee80211_chanctx * 1252 ieee80211_replace_chanctx(struct ieee80211_local *local, 1253 const struct ieee80211_chan_req *chanreq, 1254 enum ieee80211_chanctx_mode mode, 1255 struct ieee80211_chanctx *curr_ctx) 1256 { 1257 struct ieee80211_chanctx *new_ctx, *ctx; 1258 struct wiphy *wiphy = local->hw.wiphy; 1259 const struct wiphy_radio *radio; 1260 1261 if (!curr_ctx || 1262 curr_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED || 1263 ieee80211_chanctx_num_reserved(local, curr_ctx) != 0) { 1264 /* 1265 * Another link already requested this context for a 1266 * reservation. Find another one hoping all links assigned 1267 * to it will also switch soon enough. 1268 * 1269 * TODO: This needs a little more work as some cases 1270 * (more than 2 chanctx capable devices) may fail which could 1271 * otherwise succeed provided some channel context juggling was 1272 * performed. 1273 * 1274 * Consider ctx1..3, link1..6, each ctx has 2 links. link1 and 1275 * link2 from ctx1 request new different chandefs starting 2 1276 * in-place reservations with ctx4 and ctx5 replacing ctx1 and 1277 * ctx2 respectively. Next link5 and link6 from ctx3 reserve 1278 * ctx4. If link3 and link4 remain on ctx2 as they are then this 1279 * fails unless `replace_ctx` from ctx5 is replaced with ctx3. 1280 */ 1281 list_for_each_entry(ctx, &local->chanctx_list, list) { 1282 if (ctx->replace_state != 1283 IEEE80211_CHANCTX_REPLACE_NONE) 1284 continue; 1285 1286 if (ieee80211_chanctx_num_reserved(local, ctx) != 0) 1287 continue; 1288 1289 if (ctx->conf.radio_idx >= 0) { 1290 radio = &wiphy->radio[ctx->conf.radio_idx]; 1291 if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper)) 1292 continue; 1293 } 1294 1295 curr_ctx = ctx; 1296 break; 1297 } 1298 } 1299 1300 /* 1301 * If that's true then all available contexts already have reservations 1302 * and cannot be used. 1303 */ 1304 if (!curr_ctx || 1305 curr_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED || 1306 ieee80211_chanctx_num_reserved(local, curr_ctx) != 0) 1307 return ERR_PTR(-EBUSY); 1308 1309 new_ctx = ieee80211_alloc_chanctx(local, chanreq, mode, -1); 1310 if (!new_ctx) 1311 return ERR_PTR(-ENOMEM); 1312 1313 new_ctx->replace_ctx = curr_ctx; 1314 new_ctx->replace_state = IEEE80211_CHANCTX_REPLACES_OTHER; 1315 1316 curr_ctx->replace_ctx = new_ctx; 1317 curr_ctx->replace_state = IEEE80211_CHANCTX_WILL_BE_REPLACED; 1318 1319 list_add_rcu(&new_ctx->list, &local->chanctx_list); 1320 1321 return new_ctx; 1322 } 1323 1324 static bool 1325 ieee80211_find_available_radio(struct ieee80211_local *local, 1326 const struct ieee80211_chan_req *chanreq, 1327 u32 radio_mask, int *radio_idx) 1328 { 1329 struct wiphy *wiphy = local->hw.wiphy; 1330 const struct wiphy_radio *radio; 1331 int i; 1332 1333 *radio_idx = -1; 1334 if (!wiphy->n_radio) 1335 return true; 1336 1337 for (i = 0; i < wiphy->n_radio; i++) { 1338 if (!(radio_mask & BIT(i))) 1339 continue; 1340 1341 radio = &wiphy->radio[i]; 1342 if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper)) 1343 continue; 1344 1345 if (!ieee80211_can_create_new_chanctx(local, i)) 1346 continue; 1347 1348 *radio_idx = i; 1349 return true; 1350 } 1351 1352 return false; 1353 } 1354 1355 int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link, 1356 const struct ieee80211_chan_req *chanreq, 1357 enum ieee80211_chanctx_mode mode, 1358 bool radar_required) 1359 { 1360 struct ieee80211_sub_if_data *sdata = link->sdata; 1361 struct ieee80211_local *local = sdata->local; 1362 struct ieee80211_chanctx *new_ctx, *curr_ctx; 1363 int radio_idx; 1364 1365 lockdep_assert_wiphy(local->hw.wiphy); 1366 1367 curr_ctx = ieee80211_link_get_chanctx(link); 1368 if (curr_ctx && !local->ops->switch_vif_chanctx) 1369 return -EOPNOTSUPP; 1370 1371 new_ctx = ieee80211_find_reservation_chanctx(local, chanreq, mode); 1372 if (!new_ctx) { 1373 if (ieee80211_can_create_new_chanctx(local, -1) && 1374 ieee80211_find_available_radio(local, chanreq, 1375 sdata->wdev.radio_mask, 1376 &radio_idx)) 1377 new_ctx = ieee80211_new_chanctx(local, chanreq, mode, 1378 false, radio_idx); 1379 else 1380 new_ctx = ieee80211_replace_chanctx(local, chanreq, 1381 mode, curr_ctx); 1382 if (IS_ERR(new_ctx)) 1383 return PTR_ERR(new_ctx); 1384 } 1385 1386 link->reserved_chanctx = new_ctx; 1387 link->reserved = *chanreq; 1388 link->reserved_radar_required = radar_required; 1389 link->reserved_ready = false; 1390 1391 return 0; 1392 } 1393 1394 static void 1395 ieee80211_link_chanctx_reservation_complete(struct ieee80211_link_data *link) 1396 { 1397 struct ieee80211_sub_if_data *sdata = link->sdata; 1398 1399 switch (sdata->vif.type) { 1400 case NL80211_IFTYPE_ADHOC: 1401 case NL80211_IFTYPE_AP: 1402 case NL80211_IFTYPE_MESH_POINT: 1403 case NL80211_IFTYPE_OCB: 1404 wiphy_work_queue(sdata->local->hw.wiphy, 1405 &link->csa.finalize_work); 1406 break; 1407 case NL80211_IFTYPE_STATION: 1408 wiphy_hrtimer_work_queue(sdata->local->hw.wiphy, 1409 &link->u.mgd.csa.switch_work, 0); 1410 break; 1411 case NL80211_IFTYPE_UNSPECIFIED: 1412 case NL80211_IFTYPE_AP_VLAN: 1413 case NL80211_IFTYPE_WDS: 1414 case NL80211_IFTYPE_MONITOR: 1415 case NL80211_IFTYPE_P2P_CLIENT: 1416 case NL80211_IFTYPE_P2P_GO: 1417 case NL80211_IFTYPE_P2P_DEVICE: 1418 case NL80211_IFTYPE_NAN: 1419 case NUM_NL80211_IFTYPES: 1420 WARN_ON(1); 1421 break; 1422 } 1423 } 1424 1425 static void 1426 ieee80211_link_update_chanreq(struct ieee80211_link_data *link, 1427 const struct ieee80211_chan_req *chanreq) 1428 { 1429 struct ieee80211_sub_if_data *sdata = link->sdata; 1430 unsigned int link_id = link->link_id; 1431 struct ieee80211_sub_if_data *vlan; 1432 1433 link->conf->chanreq = *chanreq; 1434 1435 if (sdata->vif.type != NL80211_IFTYPE_AP) 1436 return; 1437 1438 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { 1439 struct ieee80211_bss_conf *vlan_conf; 1440 1441 vlan_conf = wiphy_dereference(sdata->local->hw.wiphy, 1442 vlan->vif.link_conf[link_id]); 1443 if (WARN_ON(!vlan_conf)) 1444 continue; 1445 1446 vlan_conf->chanreq = *chanreq; 1447 } 1448 } 1449 1450 static int 1451 ieee80211_link_use_reserved_reassign(struct ieee80211_link_data *link) 1452 { 1453 struct ieee80211_sub_if_data *sdata = link->sdata; 1454 struct ieee80211_bss_conf *link_conf = link->conf; 1455 struct ieee80211_local *local = sdata->local; 1456 struct ieee80211_vif_chanctx_switch vif_chsw[1] = {}; 1457 struct ieee80211_chanctx *old_ctx, *new_ctx; 1458 const struct ieee80211_chan_req *chanreq; 1459 struct ieee80211_chan_req tmp; 1460 u64 changed = 0; 1461 int err; 1462 1463 lockdep_assert_wiphy(local->hw.wiphy); 1464 1465 new_ctx = link->reserved_chanctx; 1466 old_ctx = ieee80211_link_get_chanctx(link); 1467 1468 if (WARN_ON(!link->reserved_ready)) 1469 return -EBUSY; 1470 1471 if (WARN_ON(!new_ctx)) 1472 return -EINVAL; 1473 1474 if (WARN_ON(!old_ctx)) 1475 return -EINVAL; 1476 1477 if (WARN_ON(new_ctx->replace_state == 1478 IEEE80211_CHANCTX_REPLACES_OTHER)) 1479 return -EINVAL; 1480 1481 chanreq = ieee80211_chanctx_non_reserved_chandef(local, new_ctx, 1482 &link->reserved, 1483 &tmp); 1484 if (WARN_ON(!chanreq)) 1485 return -EINVAL; 1486 1487 if (link_conf->chanreq.oper.width != link->reserved.oper.width) 1488 changed = BSS_CHANGED_BANDWIDTH; 1489 1490 ieee80211_link_update_chanreq(link, &link->reserved); 1491 1492 _ieee80211_change_chanctx(local, new_ctx, old_ctx, chanreq, link); 1493 1494 vif_chsw[0].vif = &sdata->vif; 1495 vif_chsw[0].old_ctx = &old_ctx->conf; 1496 vif_chsw[0].new_ctx = &new_ctx->conf; 1497 vif_chsw[0].link_conf = link->conf; 1498 1499 link->reserved_chanctx = NULL; 1500 1501 err = drv_switch_vif_chanctx(local, vif_chsw, 1, 1502 CHANCTX_SWMODE_REASSIGN_VIF); 1503 if (err) { 1504 if (ieee80211_chanctx_refcount(local, new_ctx) == 0) 1505 ieee80211_free_chanctx(local, new_ctx, false); 1506 1507 goto out; 1508 } 1509 1510 link->radar_required = link->reserved_radar_required; 1511 rcu_assign_pointer(link_conf->chanctx_conf, &new_ctx->conf); 1512 1513 if (sdata->vif.type == NL80211_IFTYPE_AP) 1514 __ieee80211_link_copy_chanctx_to_vlans(link, false); 1515 1516 ieee80211_check_fast_xmit_iface(sdata); 1517 1518 if (ieee80211_chanctx_refcount(local, old_ctx) == 0) 1519 ieee80211_free_chanctx(local, old_ctx, false); 1520 1521 ieee80211_recalc_chanctx_min_def(local, new_ctx); 1522 ieee80211_recalc_smps_chanctx(local, new_ctx); 1523 ieee80211_recalc_radar_chanctx(local, new_ctx); 1524 1525 if (changed) 1526 ieee80211_link_info_change_notify(sdata, link, changed); 1527 1528 out: 1529 ieee80211_link_chanctx_reservation_complete(link); 1530 return err; 1531 } 1532 1533 static int 1534 ieee80211_link_use_reserved_assign(struct ieee80211_link_data *link) 1535 { 1536 struct ieee80211_sub_if_data *sdata = link->sdata; 1537 struct ieee80211_local *local = sdata->local; 1538 struct ieee80211_chanctx *old_ctx, *new_ctx; 1539 const struct ieee80211_chan_req *chanreq; 1540 struct ieee80211_chan_req tmp; 1541 int err; 1542 1543 old_ctx = ieee80211_link_get_chanctx(link); 1544 new_ctx = link->reserved_chanctx; 1545 1546 if (WARN_ON(!link->reserved_ready)) 1547 return -EINVAL; 1548 1549 if (WARN_ON(old_ctx)) 1550 return -EINVAL; 1551 1552 if (WARN_ON(!new_ctx)) 1553 return -EINVAL; 1554 1555 if (WARN_ON(new_ctx->replace_state == 1556 IEEE80211_CHANCTX_REPLACES_OTHER)) 1557 return -EINVAL; 1558 1559 chanreq = ieee80211_chanctx_non_reserved_chandef(local, new_ctx, 1560 &link->reserved, 1561 &tmp); 1562 if (WARN_ON(!chanreq)) 1563 return -EINVAL; 1564 1565 ieee80211_change_chanctx(local, new_ctx, new_ctx, chanreq); 1566 1567 link->reserved_chanctx = NULL; 1568 1569 err = ieee80211_assign_link_chanctx(link, new_ctx, false); 1570 if (err) { 1571 if (ieee80211_chanctx_refcount(local, new_ctx) == 0) 1572 ieee80211_free_chanctx(local, new_ctx, false); 1573 1574 goto out; 1575 } 1576 1577 out: 1578 ieee80211_link_chanctx_reservation_complete(link); 1579 return err; 1580 } 1581 1582 static bool 1583 ieee80211_link_has_in_place_reservation(struct ieee80211_link_data *link) 1584 { 1585 struct ieee80211_sub_if_data *sdata = link->sdata; 1586 struct ieee80211_chanctx *old_ctx, *new_ctx; 1587 1588 lockdep_assert_wiphy(sdata->local->hw.wiphy); 1589 1590 new_ctx = link->reserved_chanctx; 1591 old_ctx = ieee80211_link_get_chanctx(link); 1592 1593 if (!old_ctx) 1594 return false; 1595 1596 if (WARN_ON(!new_ctx)) 1597 return false; 1598 1599 if (old_ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED) 1600 return false; 1601 1602 if (new_ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1603 return false; 1604 1605 return true; 1606 } 1607 1608 static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local, 1609 int n_vifs) 1610 { 1611 struct ieee80211_vif_chanctx_switch *vif_chsw; 1612 struct ieee80211_chanctx *ctx, *old_ctx; 1613 int i, err; 1614 1615 lockdep_assert_wiphy(local->hw.wiphy); 1616 1617 vif_chsw = kzalloc_objs(vif_chsw[0], n_vifs); 1618 if (!vif_chsw) 1619 return -ENOMEM; 1620 1621 i = 0; 1622 list_for_each_entry(ctx, &local->chanctx_list, list) { 1623 struct ieee80211_chanctx_user_iter iter; 1624 1625 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1626 continue; 1627 1628 if (WARN_ON(!ctx->replace_ctx)) { 1629 err = -EINVAL; 1630 goto out; 1631 } 1632 1633 for_each_chanctx_user_reserved(local, ctx, &iter) { 1634 if (!ieee80211_link_has_in_place_reservation(iter.link)) 1635 continue; 1636 1637 old_ctx = ieee80211_link_get_chanctx(iter.link); 1638 vif_chsw[i].vif = &iter.sdata->vif; 1639 vif_chsw[i].old_ctx = &old_ctx->conf; 1640 vif_chsw[i].new_ctx = &ctx->conf; 1641 vif_chsw[i].link_conf = iter.link->conf; 1642 1643 i++; 1644 } 1645 } 1646 1647 err = drv_switch_vif_chanctx(local, vif_chsw, n_vifs, 1648 CHANCTX_SWMODE_SWAP_CONTEXTS); 1649 1650 out: 1651 kfree(vif_chsw); 1652 return err; 1653 } 1654 1655 static int ieee80211_chsw_switch_ctxs(struct ieee80211_local *local) 1656 { 1657 struct ieee80211_chanctx *ctx; 1658 int err; 1659 1660 lockdep_assert_wiphy(local->hw.wiphy); 1661 1662 list_for_each_entry(ctx, &local->chanctx_list, list) { 1663 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1664 continue; 1665 1666 if (ieee80211_chanctx_num_assigned(local, ctx) != 0) 1667 continue; 1668 1669 ieee80211_del_chanctx(local, ctx->replace_ctx, false); 1670 err = ieee80211_add_chanctx(local, ctx); 1671 if (err) 1672 goto err; 1673 } 1674 1675 return 0; 1676 1677 err: 1678 WARN_ON(ieee80211_add_chanctx(local, ctx)); 1679 list_for_each_entry_continue_reverse(ctx, &local->chanctx_list, list) { 1680 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1681 continue; 1682 1683 if (ieee80211_chanctx_num_assigned(local, ctx) != 0) 1684 continue; 1685 1686 ieee80211_del_chanctx(local, ctx, false); 1687 WARN_ON(ieee80211_add_chanctx(local, ctx->replace_ctx)); 1688 } 1689 1690 return err; 1691 } 1692 1693 static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) 1694 { 1695 struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx; 1696 int err, n_assigned, n_reserved, n_ready; 1697 int n_ctx = 0, n_vifs_switch = 0, n_vifs_assign = 0, n_vifs_ctxless = 0; 1698 1699 lockdep_assert_wiphy(local->hw.wiphy); 1700 1701 /* 1702 * If there are 2 independent pairs of channel contexts performing 1703 * cross-switch of their vifs this code will still wait until both are 1704 * ready even though it could be possible to switch one before the 1705 * other is ready. 1706 * 1707 * For practical reasons and code simplicity just do a single huge 1708 * switch. 1709 */ 1710 1711 /* 1712 * Verify if the reservation is still feasible. 1713 * - if it's not then disconnect 1714 * - if it is but not all vifs necessary are ready then defer 1715 */ 1716 1717 list_for_each_entry(ctx, &local->chanctx_list, list) { 1718 struct ieee80211_chanctx_user_iter iter; 1719 1720 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1721 continue; 1722 1723 if (WARN_ON(!ctx->replace_ctx)) { 1724 err = -EINVAL; 1725 goto err; 1726 } 1727 1728 n_ctx++; 1729 1730 n_assigned = 0; 1731 n_reserved = 0; 1732 n_ready = 0; 1733 1734 for_each_chanctx_user_assigned(local, ctx->replace_ctx, &iter) { 1735 n_assigned++; 1736 if (iter.link->reserved_chanctx) { 1737 n_reserved++; 1738 if (iter.link->reserved_ready) 1739 n_ready++; 1740 } 1741 } 1742 1743 if (n_assigned != n_reserved) { 1744 if (n_ready == n_reserved) { 1745 wiphy_info(local->hw.wiphy, 1746 "channel context reservation cannot be finalized because some interfaces aren't switching\n"); 1747 err = -EBUSY; 1748 goto err; 1749 } 1750 1751 return -EAGAIN; 1752 } 1753 1754 ctx->conf.radar_enabled = false; 1755 for_each_chanctx_user_reserved(local, ctx, &iter) { 1756 if (ieee80211_link_has_in_place_reservation(iter.link) && 1757 !iter.link->reserved_ready) 1758 return -EAGAIN; 1759 1760 old_ctx = ieee80211_link_get_chanctx(iter.link); 1761 if (old_ctx) { 1762 if (old_ctx->replace_state == 1763 IEEE80211_CHANCTX_WILL_BE_REPLACED) 1764 n_vifs_switch++; 1765 else 1766 n_vifs_assign++; 1767 } else { 1768 n_vifs_ctxless++; 1769 } 1770 1771 if (iter.radar_required) 1772 ctx->conf.radar_enabled = true; 1773 } 1774 } 1775 1776 if (WARN_ON(n_ctx == 0) || 1777 WARN_ON(n_vifs_switch == 0 && 1778 n_vifs_assign == 0 && 1779 n_vifs_ctxless == 0)) { 1780 err = -EINVAL; 1781 goto err; 1782 } 1783 1784 /* update station rate control and min width before switch */ 1785 list_for_each_entry(ctx, &local->chanctx_list, list) { 1786 struct ieee80211_chanctx_user_iter iter; 1787 1788 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1789 continue; 1790 1791 if (WARN_ON(!ctx->replace_ctx)) { 1792 err = -EINVAL; 1793 goto err; 1794 } 1795 1796 for_each_chanctx_user_reserved(local, ctx, &iter) { 1797 if (!ieee80211_link_has_in_place_reservation(iter.link)) 1798 continue; 1799 1800 ieee80211_chan_bw_change(local, 1801 ieee80211_link_get_chanctx(iter.link), 1802 true, true); 1803 } 1804 1805 _ieee80211_recalc_chanctx_min_def(local, ctx, NULL, true); 1806 } 1807 1808 /* 1809 * All necessary vifs are ready. Perform the switch now depending on 1810 * reservations and driver capabilities. 1811 */ 1812 1813 if (n_vifs_switch > 0) { 1814 err = ieee80211_chsw_switch_vifs(local, n_vifs_switch); 1815 if (err) 1816 goto err; 1817 } 1818 1819 if (n_vifs_assign > 0 || n_vifs_ctxless > 0) { 1820 err = ieee80211_chsw_switch_ctxs(local); 1821 if (err) 1822 goto err; 1823 } 1824 1825 /* 1826 * Update all structures, values and pointers to point to new channel 1827 * context(s). 1828 */ 1829 list_for_each_entry(ctx, &local->chanctx_list, list) { 1830 struct ieee80211_chanctx_user_iter iter; 1831 1832 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1833 continue; 1834 1835 if (WARN_ON(!ctx->replace_ctx)) { 1836 err = -EINVAL; 1837 goto err; 1838 } 1839 1840 for_each_chanctx_user_reserved(local, ctx, &iter) { 1841 struct ieee80211_link_data *link = iter.link; 1842 struct ieee80211_sub_if_data *sdata = iter.sdata; 1843 struct ieee80211_bss_conf *link_conf = link->conf; 1844 u64 changed = 0; 1845 1846 if (!ieee80211_link_has_in_place_reservation(link)) 1847 continue; 1848 1849 rcu_assign_pointer(link_conf->chanctx_conf, 1850 &ctx->conf); 1851 1852 if (sdata->vif.type == NL80211_IFTYPE_AP) 1853 __ieee80211_link_copy_chanctx_to_vlans(link, 1854 false); 1855 1856 ieee80211_check_fast_xmit_iface(sdata); 1857 1858 link->radar_required = iter.radar_required; 1859 1860 if (link_conf->chanreq.oper.width != iter.chanreq->oper.width) 1861 changed = BSS_CHANGED_BANDWIDTH; 1862 1863 ieee80211_link_update_chanreq(link, &link->reserved); 1864 if (changed) 1865 ieee80211_link_info_change_notify(sdata, 1866 link, 1867 changed); 1868 1869 ieee80211_recalc_txpower(link, false); 1870 } 1871 1872 ieee80211_recalc_chanctx_chantype(local, ctx); 1873 ieee80211_recalc_smps_chanctx(local, ctx); 1874 ieee80211_recalc_radar_chanctx(local, ctx); 1875 ieee80211_recalc_chanctx_min_def(local, ctx); 1876 1877 for_each_chanctx_user_reserved(local, ctx, &iter) { 1878 if (ieee80211_link_get_chanctx(iter.link) != ctx) 1879 continue; 1880 1881 iter.link->reserved_chanctx = NULL; 1882 1883 ieee80211_link_chanctx_reservation_complete(iter.link); 1884 ieee80211_chan_bw_change(local, ctx, false, false); 1885 } 1886 1887 /* 1888 * This context might have been a dependency for an already 1889 * ready re-assign reservation interface that was deferred. Do 1890 * not propagate error to the caller though. The in-place 1891 * reservation for originally requested interface has already 1892 * succeeded at this point. 1893 */ 1894 for_each_chanctx_user_reserved(local, ctx, &iter) { 1895 struct ieee80211_link_data *link = iter.link; 1896 1897 if (WARN_ON(ieee80211_link_has_in_place_reservation(link))) 1898 continue; 1899 1900 if (!link->reserved_ready) 1901 continue; 1902 1903 if (ieee80211_link_get_chanctx(link)) 1904 err = ieee80211_link_use_reserved_reassign(link); 1905 else 1906 err = ieee80211_link_use_reserved_assign(link); 1907 1908 if (err) { 1909 link_info(link, 1910 "failed to finalize (re-)assign reservation (err=%d)\n", 1911 err); 1912 ieee80211_link_unreserve_chanctx(link); 1913 cfg80211_stop_iface(local->hw.wiphy, 1914 &link->sdata->wdev, 1915 GFP_KERNEL); 1916 } 1917 } 1918 } 1919 1920 /* 1921 * Finally free old contexts 1922 */ 1923 1924 list_for_each_entry_safe(ctx, ctx_tmp, &local->chanctx_list, list) { 1925 if (ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED) 1926 continue; 1927 1928 ctx->replace_ctx->replace_ctx = NULL; 1929 ctx->replace_ctx->replace_state = 1930 IEEE80211_CHANCTX_REPLACE_NONE; 1931 1932 list_del_rcu(&ctx->list); 1933 kfree_rcu(ctx, rcu_head); 1934 } 1935 1936 return 0; 1937 1938 err: 1939 list_for_each_entry(ctx, &local->chanctx_list, list) { 1940 struct ieee80211_chanctx_user_iter iter; 1941 1942 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1943 continue; 1944 1945 for_each_chanctx_user_reserved(local, ctx, &iter) { 1946 ieee80211_link_unreserve_chanctx(iter.link); 1947 ieee80211_link_chanctx_reservation_complete(iter.link); 1948 } 1949 } 1950 1951 return err; 1952 } 1953 1954 void __ieee80211_link_release_channel(struct ieee80211_link_data *link, 1955 bool skip_idle_recalc) 1956 { 1957 struct ieee80211_sub_if_data *sdata = link->sdata; 1958 struct ieee80211_bss_conf *link_conf = link->conf; 1959 struct ieee80211_local *local = sdata->local; 1960 struct ieee80211_chanctx_conf *conf; 1961 struct ieee80211_chanctx *ctx; 1962 bool use_reserved_switch = false; 1963 1964 lockdep_assert_wiphy(local->hw.wiphy); 1965 1966 conf = rcu_dereference_protected(link_conf->chanctx_conf, 1967 lockdep_is_held(&local->hw.wiphy->mtx)); 1968 if (!conf) 1969 return; 1970 1971 ctx = container_of(conf, struct ieee80211_chanctx, conf); 1972 1973 if (link->reserved_chanctx) { 1974 if (link->reserved_chanctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER && 1975 ieee80211_chanctx_num_reserved(local, link->reserved_chanctx) > 1) 1976 use_reserved_switch = true; 1977 1978 ieee80211_link_unreserve_chanctx(link); 1979 } 1980 1981 ieee80211_assign_link_chanctx(link, NULL, false); 1982 if (ieee80211_chanctx_refcount(local, ctx) == 0) 1983 ieee80211_free_chanctx(local, ctx, skip_idle_recalc); 1984 1985 link->radar_required = false; 1986 1987 /* Unreserving may ready an in-place reservation. */ 1988 if (use_reserved_switch) 1989 ieee80211_vif_use_reserved_switch(local); 1990 } 1991 1992 int _ieee80211_link_use_channel(struct ieee80211_link_data *link, 1993 const struct ieee80211_chan_req *chanreq, 1994 enum ieee80211_chanctx_mode mode, 1995 bool assign_on_failure) 1996 { 1997 struct ieee80211_sub_if_data *sdata = link->sdata; 1998 struct ieee80211_local *local = sdata->local; 1999 struct ieee80211_chanctx *ctx; 2000 u8 radar_detect_width = 0; 2001 bool reserved = false; 2002 int radio_idx; 2003 int ret; 2004 2005 lockdep_assert_wiphy(local->hw.wiphy); 2006 2007 if (!ieee80211_vif_link_active(&sdata->vif, link->link_id)) { 2008 ieee80211_link_update_chanreq(link, chanreq); 2009 return 0; 2010 } 2011 2012 ret = cfg80211_chandef_dfs_required(local->hw.wiphy, 2013 &chanreq->oper, 2014 sdata->wdev.iftype); 2015 if (ret < 0) 2016 goto out; 2017 if (ret > 0) 2018 radar_detect_width = BIT(chanreq->oper.width); 2019 2020 link->radar_required = ret; 2021 2022 ret = ieee80211_check_combinations(sdata, &chanreq->oper, mode, 2023 radar_detect_width, -1); 2024 if (ret < 0) 2025 goto out; 2026 2027 if (!local->in_reconfig) 2028 __ieee80211_link_release_channel(link, false); 2029 2030 ctx = ieee80211_find_chanctx(local, link, chanreq, mode); 2031 /* Note: context is now reserved */ 2032 if (ctx) 2033 reserved = true; 2034 else if (!ieee80211_find_available_radio(local, chanreq, 2035 sdata->wdev.radio_mask, 2036 &radio_idx)) 2037 ctx = ERR_PTR(-EBUSY); 2038 else 2039 ctx = ieee80211_new_chanctx(local, chanreq, mode, 2040 assign_on_failure, radio_idx); 2041 if (IS_ERR(ctx)) { 2042 ret = PTR_ERR(ctx); 2043 goto out; 2044 } 2045 2046 ieee80211_link_update_chanreq(link, chanreq); 2047 2048 ret = ieee80211_assign_link_chanctx(link, ctx, assign_on_failure); 2049 2050 if (reserved) { 2051 /* remove reservation */ 2052 WARN_ON(link->reserved_chanctx != ctx); 2053 link->reserved_chanctx = NULL; 2054 } 2055 2056 if (ret) { 2057 /* if assign fails refcount stays the same */ 2058 if (ieee80211_chanctx_refcount(local, ctx) == 0) 2059 ieee80211_free_chanctx(local, ctx, false); 2060 goto out; 2061 } 2062 2063 ieee80211_recalc_smps_chanctx(local, ctx); 2064 ieee80211_recalc_radar_chanctx(local, ctx); 2065 out: 2066 if (ret) 2067 link->radar_required = false; 2068 2069 return ret; 2070 } 2071 2072 int ieee80211_link_use_reserved_context(struct ieee80211_link_data *link) 2073 { 2074 struct ieee80211_sub_if_data *sdata = link->sdata; 2075 struct ieee80211_local *local = sdata->local; 2076 struct ieee80211_chanctx *new_ctx; 2077 struct ieee80211_chanctx *old_ctx; 2078 int err; 2079 2080 lockdep_assert_wiphy(local->hw.wiphy); 2081 2082 new_ctx = link->reserved_chanctx; 2083 old_ctx = ieee80211_link_get_chanctx(link); 2084 2085 if (WARN_ON(!new_ctx)) 2086 return -EINVAL; 2087 2088 if (WARN_ON(new_ctx->replace_state == 2089 IEEE80211_CHANCTX_WILL_BE_REPLACED)) 2090 return -EINVAL; 2091 2092 if (WARN_ON(link->reserved_ready)) 2093 return -EINVAL; 2094 2095 link->reserved_ready = true; 2096 2097 if (new_ctx->replace_state == IEEE80211_CHANCTX_REPLACE_NONE) { 2098 if (old_ctx) 2099 return ieee80211_link_use_reserved_reassign(link); 2100 2101 return ieee80211_link_use_reserved_assign(link); 2102 } 2103 2104 /* 2105 * In-place reservation may need to be finalized now either if: 2106 * a) sdata is taking part in the swapping itself and is the last one 2107 * b) sdata has switched with a re-assign reservation to an existing 2108 * context readying in-place switching of old_ctx 2109 * 2110 * In case of (b) do not propagate the error up because the requested 2111 * sdata already switched successfully. Just spill an extra warning. 2112 * The ieee80211_vif_use_reserved_switch() already stops all necessary 2113 * interfaces upon failure. 2114 */ 2115 if ((old_ctx && 2116 old_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) || 2117 new_ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) { 2118 err = ieee80211_vif_use_reserved_switch(local); 2119 if (err && err != -EAGAIN) { 2120 if (new_ctx->replace_state == 2121 IEEE80211_CHANCTX_REPLACES_OTHER) 2122 return err; 2123 2124 wiphy_info(local->hw.wiphy, 2125 "depending in-place reservation failed (err=%d)\n", 2126 err); 2127 } 2128 } 2129 2130 return 0; 2131 } 2132 2133 /* 2134 * This is similar to ieee80211_chanctx_compatible(), but rechecks 2135 * against all the links actually using it (except the one that's 2136 * passed, since that one is changing). 2137 * This is done in order to allow changes to the AP's bandwidth for 2138 * wider bandwidth OFDMA purposes, which wouldn't be treated as 2139 * compatible by ieee80211_chanctx_recheck() but is OK if the link 2140 * requesting the update is the only one using it. 2141 */ 2142 static const struct ieee80211_chan_req * 2143 ieee80211_chanctx_recheck(struct ieee80211_local *local, 2144 struct ieee80211_link_data *skip_link, 2145 struct ieee80211_chanctx *ctx, 2146 const struct ieee80211_chan_req *req, 2147 struct ieee80211_chan_req *tmp) 2148 { 2149 const struct ieee80211_chan_req *ret = req; 2150 struct ieee80211_chanctx_user_iter iter; 2151 2152 lockdep_assert_wiphy(local->hw.wiphy); 2153 2154 for_each_chanctx_user_all(local, ctx, &iter) { 2155 if (iter.link == skip_link) 2156 continue; 2157 2158 ret = ieee80211_chanreq_compatible(ret, iter.chanreq, tmp); 2159 if (!ret) 2160 return NULL; 2161 } 2162 2163 *tmp = *ret; 2164 return tmp; 2165 } 2166 2167 int ieee80211_link_change_chanreq(struct ieee80211_link_data *link, 2168 const struct ieee80211_chan_req *chanreq, 2169 u64 *changed) 2170 { 2171 struct ieee80211_sub_if_data *sdata = link->sdata; 2172 struct ieee80211_bss_conf *link_conf = link->conf; 2173 struct ieee80211_local *local = sdata->local; 2174 struct ieee80211_chanctx_conf *conf; 2175 struct ieee80211_chanctx *ctx; 2176 const struct ieee80211_chan_req *compat; 2177 struct ieee80211_chan_req tmp; 2178 2179 lockdep_assert_wiphy(local->hw.wiphy); 2180 2181 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, 2182 &chanreq->oper, 2183 IEEE80211_CHAN_DISABLED)) 2184 return -EINVAL; 2185 2186 /* for non-HT 20 MHz the rest doesn't matter */ 2187 if (chanreq->oper.width == NL80211_CHAN_WIDTH_20_NOHT && 2188 cfg80211_chandef_identical(&chanreq->oper, &link_conf->chanreq.oper)) 2189 return 0; 2190 2191 /* but you cannot switch to/from it */ 2192 if (chanreq->oper.width == NL80211_CHAN_WIDTH_20_NOHT || 2193 link_conf->chanreq.oper.width == NL80211_CHAN_WIDTH_20_NOHT) 2194 return -EINVAL; 2195 2196 conf = rcu_dereference_protected(link_conf->chanctx_conf, 2197 lockdep_is_held(&local->hw.wiphy->mtx)); 2198 if (!conf) 2199 return -EINVAL; 2200 2201 ctx = container_of(conf, struct ieee80211_chanctx, conf); 2202 2203 compat = ieee80211_chanctx_recheck(local, link, ctx, chanreq, &tmp); 2204 if (!compat) 2205 return -EINVAL; 2206 2207 switch (ctx->replace_state) { 2208 case IEEE80211_CHANCTX_REPLACE_NONE: 2209 if (!ieee80211_chanctx_reserved_chanreq(local, ctx, compat, 2210 &tmp)) 2211 return -EBUSY; 2212 break; 2213 case IEEE80211_CHANCTX_WILL_BE_REPLACED: 2214 /* TODO: Perhaps the bandwidth change could be treated as a 2215 * reservation itself? */ 2216 return -EBUSY; 2217 case IEEE80211_CHANCTX_REPLACES_OTHER: 2218 /* channel context that is going to replace another channel 2219 * context doesn't really exist and shouldn't be assigned 2220 * anywhere yet */ 2221 WARN_ON(1); 2222 break; 2223 } 2224 2225 ieee80211_link_update_chanreq(link, chanreq); 2226 2227 ieee80211_recalc_chanctx_chantype(local, ctx); 2228 2229 *changed |= BSS_CHANGED_BANDWIDTH; 2230 return 0; 2231 } 2232 2233 void ieee80211_link_release_channel(struct ieee80211_link_data *link) 2234 { 2235 struct ieee80211_sub_if_data *sdata = link->sdata; 2236 2237 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 2238 return; 2239 2240 lockdep_assert_wiphy(sdata->local->hw.wiphy); 2241 2242 if (rcu_access_pointer(link->conf->chanctx_conf)) 2243 __ieee80211_link_release_channel(link, false); 2244 } 2245 2246 void ieee80211_link_vlan_copy_chanctx(struct ieee80211_link_data *link) 2247 { 2248 struct ieee80211_sub_if_data *sdata = link->sdata; 2249 unsigned int link_id = link->link_id; 2250 struct ieee80211_bss_conf *link_conf = link->conf; 2251 struct ieee80211_bss_conf *ap_conf; 2252 struct ieee80211_local *local = sdata->local; 2253 struct ieee80211_sub_if_data *ap; 2254 struct ieee80211_chanctx_conf *conf; 2255 2256 lockdep_assert_wiphy(local->hw.wiphy); 2257 2258 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss)) 2259 return; 2260 2261 ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); 2262 2263 ap_conf = wiphy_dereference(local->hw.wiphy, 2264 ap->vif.link_conf[link_id]); 2265 conf = wiphy_dereference(local->hw.wiphy, 2266 ap_conf->chanctx_conf); 2267 rcu_assign_pointer(link_conf->chanctx_conf, conf); 2268 } 2269 2270 void ieee80211_iter_chan_contexts_atomic( 2271 struct ieee80211_hw *hw, 2272 void (*iter)(struct ieee80211_hw *hw, 2273 struct ieee80211_chanctx_conf *chanctx_conf, 2274 void *data), 2275 void *iter_data) 2276 { 2277 struct ieee80211_local *local = hw_to_local(hw); 2278 struct ieee80211_chanctx *ctx; 2279 2280 rcu_read_lock(); 2281 list_for_each_entry_rcu(ctx, &local->chanctx_list, list) 2282 if (ctx->driver_present) 2283 iter(hw, &ctx->conf, iter_data); 2284 rcu_read_unlock(); 2285 } 2286 EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic); 2287 2288 void ieee80211_iter_chan_contexts_mtx( 2289 struct ieee80211_hw *hw, 2290 void (*iter)(struct ieee80211_hw *hw, 2291 struct ieee80211_chanctx_conf *chanctx_conf, 2292 void *data), 2293 void *iter_data) 2294 { 2295 struct ieee80211_local *local = hw_to_local(hw); 2296 struct ieee80211_chanctx *ctx; 2297 2298 lockdep_assert_wiphy(hw->wiphy); 2299 2300 list_for_each_entry(ctx, &local->chanctx_list, list) 2301 if (ctx->driver_present) 2302 iter(hw, &ctx->conf, iter_data); 2303 } 2304 EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_mtx); 2305