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 /* acquire mutex to prevent idle from changing */ 236 mutex_lock(&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 ctx = ERR_PTR(err); 250 251 ieee80211_recalc_idle(local); 252 goto out; 253 } 254 } 255 256 /* and keep the mutex held until the new chanctx is on the list */ 257 list_add_rcu(&ctx->list, &local->chanctx_list); 258 259 out: 260 mutex_unlock(&local->mtx); 261 262 return ctx; 263 } 264 265 static void ieee80211_free_chanctx(struct ieee80211_local *local, 266 struct ieee80211_chanctx *ctx) 267 { 268 bool check_single_channel = false; 269 lockdep_assert_held(&local->chanctx_mtx); 270 271 WARN_ON_ONCE(ctx->refcount != 0); 272 273 if (!local->use_chanctx) { 274 struct cfg80211_chan_def *chandef = &local->_oper_chandef; 275 chandef->width = NL80211_CHAN_WIDTH_20_NOHT; 276 chandef->center_freq1 = chandef->chan->center_freq; 277 chandef->center_freq2 = 0; 278 279 /* NOTE: Disabling radar is only valid here for 280 * single channel context. To be sure, check it ... 281 */ 282 if (local->hw.conf.radar_enabled) 283 check_single_channel = true; 284 local->hw.conf.radar_enabled = false; 285 286 ieee80211_hw_config(local, 0); 287 } else { 288 drv_remove_chanctx(local, ctx); 289 } 290 291 list_del_rcu(&ctx->list); 292 kfree_rcu(ctx, rcu_head); 293 294 /* throw a warning if this wasn't the only channel context. */ 295 WARN_ON(check_single_channel && !list_empty(&local->chanctx_list)); 296 297 mutex_lock(&local->mtx); 298 ieee80211_recalc_idle(local); 299 mutex_unlock(&local->mtx); 300 } 301 302 static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, 303 struct ieee80211_chanctx *ctx) 304 { 305 struct ieee80211_local *local = sdata->local; 306 int ret; 307 308 lockdep_assert_held(&local->chanctx_mtx); 309 310 ret = drv_assign_vif_chanctx(local, sdata, ctx); 311 if (ret) 312 return ret; 313 314 rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf); 315 ctx->refcount++; 316 317 ieee80211_recalc_txpower(sdata); 318 ieee80211_recalc_chanctx_min_def(local, ctx); 319 sdata->vif.bss_conf.idle = false; 320 321 if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && 322 sdata->vif.type != NL80211_IFTYPE_MONITOR) 323 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); 324 325 return 0; 326 } 327 328 static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, 329 struct ieee80211_chanctx *ctx) 330 { 331 struct ieee80211_chanctx_conf *conf = &ctx->conf; 332 struct ieee80211_sub_if_data *sdata; 333 const struct cfg80211_chan_def *compat = NULL; 334 335 lockdep_assert_held(&local->chanctx_mtx); 336 337 rcu_read_lock(); 338 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 339 340 if (!ieee80211_sdata_running(sdata)) 341 continue; 342 if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) 343 continue; 344 345 if (!compat) 346 compat = &sdata->vif.bss_conf.chandef; 347 348 compat = cfg80211_chandef_compatible( 349 &sdata->vif.bss_conf.chandef, compat); 350 if (!compat) 351 break; 352 } 353 rcu_read_unlock(); 354 355 if (WARN_ON_ONCE(!compat)) 356 return; 357 358 ieee80211_change_chanctx(local, ctx, compat); 359 } 360 361 static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata, 362 struct ieee80211_chanctx *ctx) 363 { 364 struct ieee80211_local *local = sdata->local; 365 366 lockdep_assert_held(&local->chanctx_mtx); 367 368 ctx->refcount--; 369 rcu_assign_pointer(sdata->vif.chanctx_conf, NULL); 370 371 sdata->vif.bss_conf.idle = true; 372 373 if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && 374 sdata->vif.type != NL80211_IFTYPE_MONITOR) 375 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); 376 377 drv_unassign_vif_chanctx(local, sdata, ctx); 378 379 if (ctx->refcount > 0) { 380 ieee80211_recalc_chanctx_chantype(sdata->local, ctx); 381 ieee80211_recalc_smps_chanctx(local, ctx); 382 ieee80211_recalc_radar_chanctx(local, ctx); 383 ieee80211_recalc_chanctx_min_def(local, ctx); 384 } 385 } 386 387 static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) 388 { 389 struct ieee80211_local *local = sdata->local; 390 struct ieee80211_chanctx_conf *conf; 391 struct ieee80211_chanctx *ctx; 392 393 lockdep_assert_held(&local->chanctx_mtx); 394 395 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 396 lockdep_is_held(&local->chanctx_mtx)); 397 if (!conf) 398 return; 399 400 ctx = container_of(conf, struct ieee80211_chanctx, conf); 401 402 ieee80211_unassign_vif_chanctx(sdata, ctx); 403 if (ctx->refcount == 0) 404 ieee80211_free_chanctx(local, ctx); 405 } 406 407 void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, 408 struct ieee80211_chanctx *chanctx) 409 { 410 bool radar_enabled; 411 412 lockdep_assert_held(&local->chanctx_mtx); 413 414 radar_enabled = ieee80211_is_radar_required(local); 415 416 if (radar_enabled == chanctx->conf.radar_enabled) 417 return; 418 419 chanctx->conf.radar_enabled = radar_enabled; 420 local->radar_detect_enabled = chanctx->conf.radar_enabled; 421 422 if (!local->use_chanctx) { 423 local->hw.conf.radar_enabled = chanctx->conf.radar_enabled; 424 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 425 } 426 427 drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR); 428 } 429 430 void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, 431 struct ieee80211_chanctx *chanctx) 432 { 433 struct ieee80211_sub_if_data *sdata; 434 u8 rx_chains_static, rx_chains_dynamic; 435 436 lockdep_assert_held(&local->chanctx_mtx); 437 438 rx_chains_static = 1; 439 rx_chains_dynamic = 1; 440 441 rcu_read_lock(); 442 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 443 u8 needed_static, needed_dynamic; 444 445 if (!ieee80211_sdata_running(sdata)) 446 continue; 447 448 if (rcu_access_pointer(sdata->vif.chanctx_conf) != 449 &chanctx->conf) 450 continue; 451 452 switch (sdata->vif.type) { 453 case NL80211_IFTYPE_P2P_DEVICE: 454 continue; 455 case NL80211_IFTYPE_STATION: 456 if (!sdata->u.mgd.associated) 457 continue; 458 break; 459 case NL80211_IFTYPE_AP_VLAN: 460 continue; 461 case NL80211_IFTYPE_AP: 462 case NL80211_IFTYPE_ADHOC: 463 case NL80211_IFTYPE_WDS: 464 case NL80211_IFTYPE_MESH_POINT: 465 break; 466 default: 467 WARN_ON_ONCE(1); 468 } 469 470 switch (sdata->smps_mode) { 471 default: 472 WARN_ONCE(1, "Invalid SMPS mode %d\n", 473 sdata->smps_mode); 474 /* fall through */ 475 case IEEE80211_SMPS_OFF: 476 needed_static = sdata->needed_rx_chains; 477 needed_dynamic = sdata->needed_rx_chains; 478 break; 479 case IEEE80211_SMPS_DYNAMIC: 480 needed_static = 1; 481 needed_dynamic = sdata->needed_rx_chains; 482 break; 483 case IEEE80211_SMPS_STATIC: 484 needed_static = 1; 485 needed_dynamic = 1; 486 break; 487 } 488 489 rx_chains_static = max(rx_chains_static, needed_static); 490 rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic); 491 } 492 rcu_read_unlock(); 493 494 if (!local->use_chanctx) { 495 if (rx_chains_static > 1) 496 local->smps_mode = IEEE80211_SMPS_OFF; 497 else if (rx_chains_dynamic > 1) 498 local->smps_mode = IEEE80211_SMPS_DYNAMIC; 499 else 500 local->smps_mode = IEEE80211_SMPS_STATIC; 501 ieee80211_hw_config(local, 0); 502 } 503 504 if (rx_chains_static == chanctx->conf.rx_chains_static && 505 rx_chains_dynamic == chanctx->conf.rx_chains_dynamic) 506 return; 507 508 chanctx->conf.rx_chains_static = rx_chains_static; 509 chanctx->conf.rx_chains_dynamic = rx_chains_dynamic; 510 drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS); 511 } 512 513 int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, 514 const struct cfg80211_chan_def *chandef, 515 enum ieee80211_chanctx_mode mode) 516 { 517 struct ieee80211_local *local = sdata->local; 518 struct ieee80211_chanctx *ctx; 519 int ret; 520 521 WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); 522 523 mutex_lock(&local->chanctx_mtx); 524 __ieee80211_vif_release_channel(sdata); 525 526 ctx = ieee80211_find_chanctx(local, chandef, mode); 527 if (!ctx) 528 ctx = ieee80211_new_chanctx(local, chandef, mode); 529 if (IS_ERR(ctx)) { 530 ret = PTR_ERR(ctx); 531 goto out; 532 } 533 534 sdata->vif.bss_conf.chandef = *chandef; 535 536 ret = ieee80211_assign_vif_chanctx(sdata, ctx); 537 if (ret) { 538 /* if assign fails refcount stays the same */ 539 if (ctx->refcount == 0) 540 ieee80211_free_chanctx(local, ctx); 541 goto out; 542 } 543 544 ieee80211_recalc_smps_chanctx(local, ctx); 545 ieee80211_recalc_radar_chanctx(local, ctx); 546 out: 547 mutex_unlock(&local->chanctx_mtx); 548 return ret; 549 } 550 551 int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, 552 u32 *changed) 553 { 554 struct ieee80211_local *local = sdata->local; 555 struct ieee80211_chanctx_conf *conf; 556 struct ieee80211_chanctx *ctx; 557 const struct cfg80211_chan_def *chandef = &sdata->csa_chandef; 558 int ret; 559 u32 chanctx_changed = 0; 560 561 /* should never be called if not performing a channel switch. */ 562 if (WARN_ON(!sdata->vif.csa_active)) 563 return -EINVAL; 564 565 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef, 566 IEEE80211_CHAN_DISABLED)) 567 return -EINVAL; 568 569 mutex_lock(&local->chanctx_mtx); 570 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 571 lockdep_is_held(&local->chanctx_mtx)); 572 if (!conf) { 573 ret = -EINVAL; 574 goto out; 575 } 576 577 ctx = container_of(conf, struct ieee80211_chanctx, conf); 578 if (ctx->refcount != 1) { 579 ret = -EINVAL; 580 goto out; 581 } 582 583 if (sdata->vif.bss_conf.chandef.width != chandef->width) { 584 chanctx_changed = IEEE80211_CHANCTX_CHANGE_WIDTH; 585 *changed |= BSS_CHANGED_BANDWIDTH; 586 } 587 588 sdata->vif.bss_conf.chandef = *chandef; 589 ctx->conf.def = *chandef; 590 591 chanctx_changed |= IEEE80211_CHANCTX_CHANGE_CHANNEL; 592 drv_change_chanctx(local, ctx, chanctx_changed); 593 594 ieee80211_recalc_chanctx_chantype(local, ctx); 595 ieee80211_recalc_smps_chanctx(local, ctx); 596 ieee80211_recalc_radar_chanctx(local, ctx); 597 ieee80211_recalc_chanctx_min_def(local, ctx); 598 599 ret = 0; 600 out: 601 mutex_unlock(&local->chanctx_mtx); 602 return ret; 603 } 604 605 int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, 606 const struct cfg80211_chan_def *chandef, 607 u32 *changed) 608 { 609 struct ieee80211_local *local = sdata->local; 610 struct ieee80211_chanctx_conf *conf; 611 struct ieee80211_chanctx *ctx; 612 int ret; 613 614 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef, 615 IEEE80211_CHAN_DISABLED)) 616 return -EINVAL; 617 618 mutex_lock(&local->chanctx_mtx); 619 if (cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef)) { 620 ret = 0; 621 goto out; 622 } 623 624 if (chandef->width == NL80211_CHAN_WIDTH_20_NOHT || 625 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) { 626 ret = -EINVAL; 627 goto out; 628 } 629 630 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 631 lockdep_is_held(&local->chanctx_mtx)); 632 if (!conf) { 633 ret = -EINVAL; 634 goto out; 635 } 636 637 ctx = container_of(conf, struct ieee80211_chanctx, conf); 638 if (!cfg80211_chandef_compatible(&conf->def, chandef)) { 639 ret = -EINVAL; 640 goto out; 641 } 642 643 sdata->vif.bss_conf.chandef = *chandef; 644 645 ieee80211_recalc_chanctx_chantype(local, ctx); 646 647 *changed |= BSS_CHANGED_BANDWIDTH; 648 ret = 0; 649 out: 650 mutex_unlock(&local->chanctx_mtx); 651 return ret; 652 } 653 654 void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) 655 { 656 WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); 657 658 mutex_lock(&sdata->local->chanctx_mtx); 659 __ieee80211_vif_release_channel(sdata); 660 mutex_unlock(&sdata->local->chanctx_mtx); 661 } 662 663 void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata) 664 { 665 struct ieee80211_local *local = sdata->local; 666 struct ieee80211_sub_if_data *ap; 667 struct ieee80211_chanctx_conf *conf; 668 669 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss)) 670 return; 671 672 ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); 673 674 mutex_lock(&local->chanctx_mtx); 675 676 conf = rcu_dereference_protected(ap->vif.chanctx_conf, 677 lockdep_is_held(&local->chanctx_mtx)); 678 rcu_assign_pointer(sdata->vif.chanctx_conf, conf); 679 mutex_unlock(&local->chanctx_mtx); 680 } 681 682 void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, 683 bool clear) 684 { 685 struct ieee80211_local *local = sdata->local; 686 struct ieee80211_sub_if_data *vlan; 687 struct ieee80211_chanctx_conf *conf; 688 689 ASSERT_RTNL(); 690 691 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP)) 692 return; 693 694 mutex_lock(&local->chanctx_mtx); 695 696 /* 697 * Check that conf exists, even when clearing this function 698 * must be called with the AP's channel context still there 699 * as it would otherwise cause VLANs to have an invalid 700 * channel context pointer for a while, possibly pointing 701 * to a channel context that has already been freed. 702 */ 703 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 704 lockdep_is_held(&local->chanctx_mtx)); 705 WARN_ON(!conf); 706 707 if (clear) 708 conf = NULL; 709 710 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) 711 rcu_assign_pointer(vlan->vif.chanctx_conf, conf); 712 713 mutex_unlock(&local->chanctx_mtx); 714 } 715 716 void ieee80211_iter_chan_contexts_atomic( 717 struct ieee80211_hw *hw, 718 void (*iter)(struct ieee80211_hw *hw, 719 struct ieee80211_chanctx_conf *chanctx_conf, 720 void *data), 721 void *iter_data) 722 { 723 struct ieee80211_local *local = hw_to_local(hw); 724 struct ieee80211_chanctx *ctx; 725 726 rcu_read_lock(); 727 list_for_each_entry_rcu(ctx, &local->chanctx_list, list) 728 if (ctx->driver_present) 729 iter(hw, &ctx->conf, iter_data); 730 rcu_read_unlock(); 731 } 732 EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic); 733