1 /* 2 * mac80211 - channel management 3 */ 4 5 #include <linux/nl80211.h> 6 #include <linux/export.h> 7 #include <linux/rtnetlink.h> 8 #include <net/cfg80211.h> 9 #include "ieee80211_i.h" 10 #include "driver-ops.h" 11 12 static enum nl80211_chan_width ieee80211_get_sta_bw(struct ieee80211_sta *sta) 13 { 14 switch (sta->bandwidth) { 15 case IEEE80211_STA_RX_BW_20: 16 if (sta->ht_cap.ht_supported) 17 return NL80211_CHAN_WIDTH_20; 18 else 19 return NL80211_CHAN_WIDTH_20_NOHT; 20 case IEEE80211_STA_RX_BW_40: 21 return NL80211_CHAN_WIDTH_40; 22 case IEEE80211_STA_RX_BW_80: 23 return NL80211_CHAN_WIDTH_80; 24 case IEEE80211_STA_RX_BW_160: 25 /* 26 * This applied for both 160 and 80+80. since we use 27 * the returned value to consider degradation of 28 * ctx->conf.min_def, we have to make sure to take 29 * the bigger one (NL80211_CHAN_WIDTH_160). 30 * Otherwise we might try degrading even when not 31 * needed, as the max required sta_bw returned (80+80) 32 * might be smaller than the configured bw (160). 33 */ 34 return NL80211_CHAN_WIDTH_160; 35 default: 36 WARN_ON(1); 37 return NL80211_CHAN_WIDTH_20; 38 } 39 } 40 41 static enum nl80211_chan_width 42 ieee80211_get_max_required_bw(struct ieee80211_sub_if_data *sdata) 43 { 44 enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT; 45 struct sta_info *sta; 46 47 rcu_read_lock(); 48 list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) { 49 if (sdata != sta->sdata && 50 !(sta->sdata->bss && sta->sdata->bss == sdata->bss)) 51 continue; 52 53 if (!sta->uploaded) 54 continue; 55 56 max_bw = max(max_bw, ieee80211_get_sta_bw(&sta->sta)); 57 } 58 rcu_read_unlock(); 59 60 return max_bw; 61 } 62 63 static enum nl80211_chan_width 64 ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local, 65 struct ieee80211_chanctx_conf *conf) 66 { 67 struct ieee80211_sub_if_data *sdata; 68 enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT; 69 70 rcu_read_lock(); 71 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 72 struct ieee80211_vif *vif = &sdata->vif; 73 enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20_NOHT; 74 75 if (!ieee80211_sdata_running(sdata)) 76 continue; 77 78 if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) 79 continue; 80 81 switch (vif->type) { 82 case NL80211_IFTYPE_AP: 83 case NL80211_IFTYPE_AP_VLAN: 84 width = ieee80211_get_max_required_bw(sdata); 85 break; 86 case NL80211_IFTYPE_P2P_DEVICE: 87 continue; 88 case NL80211_IFTYPE_STATION: 89 case NL80211_IFTYPE_ADHOC: 90 case NL80211_IFTYPE_WDS: 91 case NL80211_IFTYPE_MESH_POINT: 92 width = vif->bss_conf.chandef.width; 93 break; 94 case NL80211_IFTYPE_UNSPECIFIED: 95 case NUM_NL80211_IFTYPES: 96 case NL80211_IFTYPE_MONITOR: 97 case NL80211_IFTYPE_P2P_CLIENT: 98 case NL80211_IFTYPE_P2P_GO: 99 WARN_ON_ONCE(1); 100 } 101 max_bw = max(max_bw, width); 102 } 103 rcu_read_unlock(); 104 105 return max_bw; 106 } 107 108 /* 109 * recalc the min required chan width of the channel context, which is 110 * the max of min required widths of all the interfaces bound to this 111 * channel context. 112 */ 113 void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, 114 struct ieee80211_chanctx *ctx) 115 { 116 enum nl80211_chan_width max_bw; 117 struct cfg80211_chan_def min_def; 118 119 lockdep_assert_held(&local->chanctx_mtx); 120 121 /* don't optimize 5MHz, 10MHz, and radar_enabled confs */ 122 if (ctx->conf.def.width == NL80211_CHAN_WIDTH_5 || 123 ctx->conf.def.width == NL80211_CHAN_WIDTH_10 || 124 ctx->conf.radar_enabled) { 125 ctx->conf.min_def = ctx->conf.def; 126 return; 127 } 128 129 max_bw = ieee80211_get_chanctx_max_required_bw(local, &ctx->conf); 130 131 /* downgrade chandef up to max_bw */ 132 min_def = ctx->conf.def; 133 while (min_def.width > max_bw) 134 ieee80211_chandef_downgrade(&min_def); 135 136 if (cfg80211_chandef_identical(&ctx->conf.min_def, &min_def)) 137 return; 138 139 ctx->conf.min_def = min_def; 140 if (!ctx->driver_present) 141 return; 142 143 drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_MIN_WIDTH); 144 } 145 146 static void ieee80211_change_chanctx(struct ieee80211_local *local, 147 struct ieee80211_chanctx *ctx, 148 const struct cfg80211_chan_def *chandef) 149 { 150 if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) 151 return; 152 153 WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef)); 154 155 ctx->conf.def = *chandef; 156 drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH); 157 ieee80211_recalc_chanctx_min_def(local, ctx); 158 159 if (!local->use_chanctx) { 160 local->_oper_chandef = *chandef; 161 ieee80211_hw_config(local, 0); 162 } 163 } 164 165 static struct ieee80211_chanctx * 166 ieee80211_find_chanctx(struct ieee80211_local *local, 167 const struct cfg80211_chan_def *chandef, 168 enum ieee80211_chanctx_mode mode) 169 { 170 struct ieee80211_chanctx *ctx; 171 172 lockdep_assert_held(&local->chanctx_mtx); 173 174 if (mode == IEEE80211_CHANCTX_EXCLUSIVE) 175 return NULL; 176 177 list_for_each_entry(ctx, &local->chanctx_list, list) { 178 const struct cfg80211_chan_def *compat; 179 180 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) 181 continue; 182 183 compat = cfg80211_chandef_compatible(&ctx->conf.def, chandef); 184 if (!compat) 185 continue; 186 187 ieee80211_change_chanctx(local, ctx, compat); 188 189 return ctx; 190 } 191 192 return NULL; 193 } 194 195 static bool ieee80211_is_radar_required(struct ieee80211_local *local) 196 { 197 struct ieee80211_sub_if_data *sdata; 198 199 rcu_read_lock(); 200 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 201 if (sdata->radar_required) { 202 rcu_read_unlock(); 203 return true; 204 } 205 } 206 rcu_read_unlock(); 207 208 return false; 209 } 210 211 static struct ieee80211_chanctx * 212 ieee80211_new_chanctx(struct ieee80211_local *local, 213 const struct cfg80211_chan_def *chandef, 214 enum ieee80211_chanctx_mode mode) 215 { 216 struct ieee80211_chanctx *ctx; 217 u32 changed; 218 int err; 219 220 lockdep_assert_held(&local->chanctx_mtx); 221 222 ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL); 223 if (!ctx) 224 return ERR_PTR(-ENOMEM); 225 226 ctx->conf.def = *chandef; 227 ctx->conf.rx_chains_static = 1; 228 ctx->conf.rx_chains_dynamic = 1; 229 ctx->mode = mode; 230 ctx->conf.radar_enabled = ieee80211_is_radar_required(local); 231 ieee80211_recalc_chanctx_min_def(local, ctx); 232 if (!local->use_chanctx) 233 local->hw.conf.radar_enabled = ctx->conf.radar_enabled; 234 235 /* we hold the mutex to prevent idle from changing */ 236 lockdep_assert_held(&local->mtx); 237 /* turn idle off *before* setting channel -- some drivers need that */ 238 changed = ieee80211_idle_off(local); 239 if (changed) 240 ieee80211_hw_config(local, changed); 241 242 if (!local->use_chanctx) { 243 local->_oper_chandef = *chandef; 244 ieee80211_hw_config(local, 0); 245 } else { 246 err = drv_add_chanctx(local, ctx); 247 if (err) { 248 kfree(ctx); 249 ieee80211_recalc_idle(local); 250 return ERR_PTR(err); 251 } 252 } 253 254 /* and keep the mutex held until the new chanctx is on the list */ 255 list_add_rcu(&ctx->list, &local->chanctx_list); 256 257 return ctx; 258 } 259 260 static void ieee80211_free_chanctx(struct ieee80211_local *local, 261 struct ieee80211_chanctx *ctx) 262 { 263 bool check_single_channel = false; 264 lockdep_assert_held(&local->chanctx_mtx); 265 266 WARN_ON_ONCE(ctx->refcount != 0); 267 268 if (!local->use_chanctx) { 269 struct cfg80211_chan_def *chandef = &local->_oper_chandef; 270 chandef->width = NL80211_CHAN_WIDTH_20_NOHT; 271 chandef->center_freq1 = chandef->chan->center_freq; 272 chandef->center_freq2 = 0; 273 274 /* NOTE: Disabling radar is only valid here for 275 * single channel context. To be sure, check it ... 276 */ 277 if (local->hw.conf.radar_enabled) 278 check_single_channel = true; 279 local->hw.conf.radar_enabled = false; 280 281 ieee80211_hw_config(local, 0); 282 } else { 283 drv_remove_chanctx(local, ctx); 284 } 285 286 list_del_rcu(&ctx->list); 287 kfree_rcu(ctx, rcu_head); 288 289 /* throw a warning if this wasn't the only channel context. */ 290 WARN_ON(check_single_channel && !list_empty(&local->chanctx_list)); 291 292 ieee80211_recalc_idle(local); 293 } 294 295 static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, 296 struct ieee80211_chanctx *ctx) 297 { 298 struct ieee80211_local *local = sdata->local; 299 int ret; 300 301 lockdep_assert_held(&local->chanctx_mtx); 302 303 ret = drv_assign_vif_chanctx(local, sdata, ctx); 304 if (ret) 305 return ret; 306 307 rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf); 308 ctx->refcount++; 309 310 ieee80211_recalc_txpower(sdata); 311 ieee80211_recalc_chanctx_min_def(local, ctx); 312 sdata->vif.bss_conf.idle = false; 313 314 if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && 315 sdata->vif.type != NL80211_IFTYPE_MONITOR) 316 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); 317 318 return 0; 319 } 320 321 static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, 322 struct ieee80211_chanctx *ctx) 323 { 324 struct ieee80211_chanctx_conf *conf = &ctx->conf; 325 struct ieee80211_sub_if_data *sdata; 326 const struct cfg80211_chan_def *compat = NULL; 327 328 lockdep_assert_held(&local->chanctx_mtx); 329 330 rcu_read_lock(); 331 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 332 333 if (!ieee80211_sdata_running(sdata)) 334 continue; 335 if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) 336 continue; 337 338 if (!compat) 339 compat = &sdata->vif.bss_conf.chandef; 340 341 compat = cfg80211_chandef_compatible( 342 &sdata->vif.bss_conf.chandef, compat); 343 if (!compat) 344 break; 345 } 346 rcu_read_unlock(); 347 348 if (WARN_ON_ONCE(!compat)) 349 return; 350 351 ieee80211_change_chanctx(local, ctx, compat); 352 } 353 354 static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, 355 struct ieee80211_chanctx *chanctx) 356 { 357 bool radar_enabled; 358 359 lockdep_assert_held(&local->chanctx_mtx); 360 /* for setting local->radar_detect_enabled */ 361 lockdep_assert_held(&local->mtx); 362 363 radar_enabled = ieee80211_is_radar_required(local); 364 365 if (radar_enabled == chanctx->conf.radar_enabled) 366 return; 367 368 chanctx->conf.radar_enabled = radar_enabled; 369 local->radar_detect_enabled = chanctx->conf.radar_enabled; 370 371 if (!local->use_chanctx) { 372 local->hw.conf.radar_enabled = chanctx->conf.radar_enabled; 373 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 374 } 375 376 drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR); 377 } 378 379 static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata, 380 struct ieee80211_chanctx *ctx) 381 { 382 struct ieee80211_local *local = sdata->local; 383 384 lockdep_assert_held(&local->chanctx_mtx); 385 386 ctx->refcount--; 387 rcu_assign_pointer(sdata->vif.chanctx_conf, NULL); 388 389 sdata->vif.bss_conf.idle = true; 390 391 if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && 392 sdata->vif.type != NL80211_IFTYPE_MONITOR) 393 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); 394 395 drv_unassign_vif_chanctx(local, sdata, ctx); 396 397 if (ctx->refcount > 0) { 398 ieee80211_recalc_chanctx_chantype(sdata->local, ctx); 399 ieee80211_recalc_smps_chanctx(local, ctx); 400 ieee80211_recalc_radar_chanctx(local, ctx); 401 ieee80211_recalc_chanctx_min_def(local, ctx); 402 } 403 } 404 405 static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) 406 { 407 struct ieee80211_local *local = sdata->local; 408 struct ieee80211_chanctx_conf *conf; 409 struct ieee80211_chanctx *ctx; 410 411 lockdep_assert_held(&local->chanctx_mtx); 412 413 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 414 lockdep_is_held(&local->chanctx_mtx)); 415 if (!conf) 416 return; 417 418 ctx = container_of(conf, struct ieee80211_chanctx, conf); 419 420 ieee80211_unassign_vif_chanctx(sdata, ctx); 421 if (ctx->refcount == 0) 422 ieee80211_free_chanctx(local, ctx); 423 } 424 425 void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, 426 struct ieee80211_chanctx *chanctx) 427 { 428 struct ieee80211_sub_if_data *sdata; 429 u8 rx_chains_static, rx_chains_dynamic; 430 431 lockdep_assert_held(&local->chanctx_mtx); 432 433 rx_chains_static = 1; 434 rx_chains_dynamic = 1; 435 436 rcu_read_lock(); 437 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 438 u8 needed_static, needed_dynamic; 439 440 if (!ieee80211_sdata_running(sdata)) 441 continue; 442 443 if (rcu_access_pointer(sdata->vif.chanctx_conf) != 444 &chanctx->conf) 445 continue; 446 447 switch (sdata->vif.type) { 448 case NL80211_IFTYPE_P2P_DEVICE: 449 continue; 450 case NL80211_IFTYPE_STATION: 451 if (!sdata->u.mgd.associated) 452 continue; 453 break; 454 case NL80211_IFTYPE_AP_VLAN: 455 continue; 456 case NL80211_IFTYPE_AP: 457 case NL80211_IFTYPE_ADHOC: 458 case NL80211_IFTYPE_WDS: 459 case NL80211_IFTYPE_MESH_POINT: 460 break; 461 default: 462 WARN_ON_ONCE(1); 463 } 464 465 switch (sdata->smps_mode) { 466 default: 467 WARN_ONCE(1, "Invalid SMPS mode %d\n", 468 sdata->smps_mode); 469 /* fall through */ 470 case IEEE80211_SMPS_OFF: 471 needed_static = sdata->needed_rx_chains; 472 needed_dynamic = sdata->needed_rx_chains; 473 break; 474 case IEEE80211_SMPS_DYNAMIC: 475 needed_static = 1; 476 needed_dynamic = sdata->needed_rx_chains; 477 break; 478 case IEEE80211_SMPS_STATIC: 479 needed_static = 1; 480 needed_dynamic = 1; 481 break; 482 } 483 484 rx_chains_static = max(rx_chains_static, needed_static); 485 rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic); 486 } 487 rcu_read_unlock(); 488 489 if (!local->use_chanctx) { 490 if (rx_chains_static > 1) 491 local->smps_mode = IEEE80211_SMPS_OFF; 492 else if (rx_chains_dynamic > 1) 493 local->smps_mode = IEEE80211_SMPS_DYNAMIC; 494 else 495 local->smps_mode = IEEE80211_SMPS_STATIC; 496 ieee80211_hw_config(local, 0); 497 } 498 499 if (rx_chains_static == chanctx->conf.rx_chains_static && 500 rx_chains_dynamic == chanctx->conf.rx_chains_dynamic) 501 return; 502 503 chanctx->conf.rx_chains_static = rx_chains_static; 504 chanctx->conf.rx_chains_dynamic = rx_chains_dynamic; 505 drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS); 506 } 507 508 int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, 509 const struct cfg80211_chan_def *chandef, 510 enum ieee80211_chanctx_mode mode) 511 { 512 struct ieee80211_local *local = sdata->local; 513 struct ieee80211_chanctx *ctx; 514 int ret; 515 516 lockdep_assert_held(&local->mtx); 517 518 WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); 519 520 mutex_lock(&local->chanctx_mtx); 521 __ieee80211_vif_release_channel(sdata); 522 523 ctx = ieee80211_find_chanctx(local, chandef, mode); 524 if (!ctx) 525 ctx = ieee80211_new_chanctx(local, chandef, mode); 526 if (IS_ERR(ctx)) { 527 ret = PTR_ERR(ctx); 528 goto out; 529 } 530 531 sdata->vif.bss_conf.chandef = *chandef; 532 533 ret = ieee80211_assign_vif_chanctx(sdata, ctx); 534 if (ret) { 535 /* if assign fails refcount stays the same */ 536 if (ctx->refcount == 0) 537 ieee80211_free_chanctx(local, ctx); 538 goto out; 539 } 540 541 ieee80211_recalc_smps_chanctx(local, ctx); 542 ieee80211_recalc_radar_chanctx(local, ctx); 543 out: 544 mutex_unlock(&local->chanctx_mtx); 545 return ret; 546 } 547 548 int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, 549 u32 *changed) 550 { 551 struct ieee80211_local *local = sdata->local; 552 struct ieee80211_chanctx_conf *conf; 553 struct ieee80211_chanctx *ctx; 554 const struct cfg80211_chan_def *chandef = &sdata->csa_chandef; 555 int ret; 556 u32 chanctx_changed = 0; 557 558 lockdep_assert_held(&local->mtx); 559 560 /* should never be called if not performing a channel switch. */ 561 if (WARN_ON(!sdata->vif.csa_active)) 562 return -EINVAL; 563 564 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef, 565 IEEE80211_CHAN_DISABLED)) 566 return -EINVAL; 567 568 mutex_lock(&local->chanctx_mtx); 569 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 570 lockdep_is_held(&local->chanctx_mtx)); 571 if (!conf) { 572 ret = -EINVAL; 573 goto out; 574 } 575 576 ctx = container_of(conf, struct ieee80211_chanctx, conf); 577 if (ctx->refcount != 1) { 578 ret = -EINVAL; 579 goto out; 580 } 581 582 if (sdata->vif.bss_conf.chandef.width != chandef->width) { 583 chanctx_changed = IEEE80211_CHANCTX_CHANGE_WIDTH; 584 *changed |= BSS_CHANGED_BANDWIDTH; 585 } 586 587 sdata->vif.bss_conf.chandef = *chandef; 588 ctx->conf.def = *chandef; 589 590 chanctx_changed |= IEEE80211_CHANCTX_CHANGE_CHANNEL; 591 drv_change_chanctx(local, ctx, chanctx_changed); 592 593 ieee80211_recalc_chanctx_chantype(local, ctx); 594 ieee80211_recalc_smps_chanctx(local, ctx); 595 ieee80211_recalc_radar_chanctx(local, ctx); 596 ieee80211_recalc_chanctx_min_def(local, ctx); 597 598 ret = 0; 599 out: 600 mutex_unlock(&local->chanctx_mtx); 601 return ret; 602 } 603 604 int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, 605 const struct cfg80211_chan_def *chandef, 606 u32 *changed) 607 { 608 struct ieee80211_local *local = sdata->local; 609 struct ieee80211_chanctx_conf *conf; 610 struct ieee80211_chanctx *ctx; 611 int ret; 612 613 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef, 614 IEEE80211_CHAN_DISABLED)) 615 return -EINVAL; 616 617 mutex_lock(&local->chanctx_mtx); 618 if (cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef)) { 619 ret = 0; 620 goto out; 621 } 622 623 if (chandef->width == NL80211_CHAN_WIDTH_20_NOHT || 624 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) { 625 ret = -EINVAL; 626 goto out; 627 } 628 629 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 630 lockdep_is_held(&local->chanctx_mtx)); 631 if (!conf) { 632 ret = -EINVAL; 633 goto out; 634 } 635 636 ctx = container_of(conf, struct ieee80211_chanctx, conf); 637 if (!cfg80211_chandef_compatible(&conf->def, chandef)) { 638 ret = -EINVAL; 639 goto out; 640 } 641 642 sdata->vif.bss_conf.chandef = *chandef; 643 644 ieee80211_recalc_chanctx_chantype(local, ctx); 645 646 *changed |= BSS_CHANGED_BANDWIDTH; 647 ret = 0; 648 out: 649 mutex_unlock(&local->chanctx_mtx); 650 return ret; 651 } 652 653 void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) 654 { 655 WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); 656 657 lockdep_assert_held(&sdata->local->mtx); 658 659 mutex_lock(&sdata->local->chanctx_mtx); 660 __ieee80211_vif_release_channel(sdata); 661 mutex_unlock(&sdata->local->chanctx_mtx); 662 } 663 664 void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata) 665 { 666 struct ieee80211_local *local = sdata->local; 667 struct ieee80211_sub_if_data *ap; 668 struct ieee80211_chanctx_conf *conf; 669 670 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss)) 671 return; 672 673 ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); 674 675 mutex_lock(&local->chanctx_mtx); 676 677 conf = rcu_dereference_protected(ap->vif.chanctx_conf, 678 lockdep_is_held(&local->chanctx_mtx)); 679 rcu_assign_pointer(sdata->vif.chanctx_conf, conf); 680 mutex_unlock(&local->chanctx_mtx); 681 } 682 683 void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, 684 bool clear) 685 { 686 struct ieee80211_local *local = sdata->local; 687 struct ieee80211_sub_if_data *vlan; 688 struct ieee80211_chanctx_conf *conf; 689 690 ASSERT_RTNL(); 691 692 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP)) 693 return; 694 695 mutex_lock(&local->chanctx_mtx); 696 697 /* 698 * Check that conf exists, even when clearing this function 699 * must be called with the AP's channel context still there 700 * as it would otherwise cause VLANs to have an invalid 701 * channel context pointer for a while, possibly pointing 702 * to a channel context that has already been freed. 703 */ 704 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 705 lockdep_is_held(&local->chanctx_mtx)); 706 WARN_ON(!conf); 707 708 if (clear) 709 conf = NULL; 710 711 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) 712 rcu_assign_pointer(vlan->vif.chanctx_conf, conf); 713 714 mutex_unlock(&local->chanctx_mtx); 715 } 716 717 void ieee80211_iter_chan_contexts_atomic( 718 struct ieee80211_hw *hw, 719 void (*iter)(struct ieee80211_hw *hw, 720 struct ieee80211_chanctx_conf *chanctx_conf, 721 void *data), 722 void *iter_data) 723 { 724 struct ieee80211_local *local = hw_to_local(hw); 725 struct ieee80211_chanctx *ctx; 726 727 rcu_read_lock(); 728 list_for_each_entry_rcu(ctx, &local->chanctx_list, list) 729 if (ctx->driver_present) 730 iter(hw, &ctx->conf, iter_data); 731 rcu_read_unlock(); 732 } 733 EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic); 734