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