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