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 void ieee80211_change_chanctx(struct ieee80211_local *local, 13 struct ieee80211_chanctx *ctx, 14 const struct cfg80211_chan_def *chandef) 15 { 16 if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) 17 return; 18 19 WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef)); 20 21 ctx->conf.def = *chandef; 22 drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH); 23 24 if (!local->use_chanctx) { 25 local->_oper_chandef = *chandef; 26 ieee80211_hw_config(local, 0); 27 } 28 } 29 30 static struct ieee80211_chanctx * 31 ieee80211_find_chanctx(struct ieee80211_local *local, 32 const struct cfg80211_chan_def *chandef, 33 enum ieee80211_chanctx_mode mode) 34 { 35 struct ieee80211_chanctx *ctx; 36 37 lockdep_assert_held(&local->chanctx_mtx); 38 39 if (mode == IEEE80211_CHANCTX_EXCLUSIVE) 40 return NULL; 41 42 list_for_each_entry(ctx, &local->chanctx_list, list) { 43 const struct cfg80211_chan_def *compat; 44 45 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) 46 continue; 47 48 compat = cfg80211_chandef_compatible(&ctx->conf.def, chandef); 49 if (!compat) 50 continue; 51 52 ieee80211_change_chanctx(local, ctx, compat); 53 54 return ctx; 55 } 56 57 return NULL; 58 } 59 60 static bool ieee80211_is_radar_required(struct ieee80211_local *local) 61 { 62 struct ieee80211_sub_if_data *sdata; 63 64 rcu_read_lock(); 65 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 66 if (sdata->radar_required) { 67 rcu_read_unlock(); 68 return true; 69 } 70 } 71 rcu_read_unlock(); 72 73 return false; 74 } 75 76 static struct ieee80211_chanctx * 77 ieee80211_new_chanctx(struct ieee80211_local *local, 78 const struct cfg80211_chan_def *chandef, 79 enum ieee80211_chanctx_mode mode) 80 { 81 struct ieee80211_chanctx *ctx; 82 u32 changed; 83 int err; 84 85 lockdep_assert_held(&local->chanctx_mtx); 86 87 ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL); 88 if (!ctx) 89 return ERR_PTR(-ENOMEM); 90 91 ctx->conf.def = *chandef; 92 ctx->conf.rx_chains_static = 1; 93 ctx->conf.rx_chains_dynamic = 1; 94 ctx->mode = mode; 95 ctx->conf.radar_enabled = ieee80211_is_radar_required(local); 96 if (!local->use_chanctx) 97 local->hw.conf.radar_enabled = ctx->conf.radar_enabled; 98 99 /* acquire mutex to prevent idle from changing */ 100 mutex_lock(&local->mtx); 101 /* turn idle off *before* setting channel -- some drivers need that */ 102 changed = ieee80211_idle_off(local); 103 if (changed) 104 ieee80211_hw_config(local, changed); 105 106 if (!local->use_chanctx) { 107 local->_oper_chandef = *chandef; 108 ieee80211_hw_config(local, 0); 109 } else { 110 err = drv_add_chanctx(local, ctx); 111 if (err) { 112 kfree(ctx); 113 ctx = ERR_PTR(err); 114 115 ieee80211_recalc_idle(local); 116 goto out; 117 } 118 } 119 120 /* and keep the mutex held until the new chanctx is on the list */ 121 list_add_rcu(&ctx->list, &local->chanctx_list); 122 123 out: 124 mutex_unlock(&local->mtx); 125 126 return ctx; 127 } 128 129 static void ieee80211_free_chanctx(struct ieee80211_local *local, 130 struct ieee80211_chanctx *ctx) 131 { 132 bool check_single_channel = false; 133 lockdep_assert_held(&local->chanctx_mtx); 134 135 WARN_ON_ONCE(ctx->refcount != 0); 136 137 if (!local->use_chanctx) { 138 struct cfg80211_chan_def *chandef = &local->_oper_chandef; 139 chandef->width = NL80211_CHAN_WIDTH_20_NOHT; 140 chandef->center_freq1 = chandef->chan->center_freq; 141 chandef->center_freq2 = 0; 142 143 /* NOTE: Disabling radar is only valid here for 144 * single channel context. To be sure, check it ... 145 */ 146 if (local->hw.conf.radar_enabled) 147 check_single_channel = true; 148 local->hw.conf.radar_enabled = false; 149 150 ieee80211_hw_config(local, 0); 151 } else { 152 drv_remove_chanctx(local, ctx); 153 } 154 155 list_del_rcu(&ctx->list); 156 kfree_rcu(ctx, rcu_head); 157 158 /* throw a warning if this wasn't the only channel context. */ 159 WARN_ON(check_single_channel && !list_empty(&local->chanctx_list)); 160 161 mutex_lock(&local->mtx); 162 ieee80211_recalc_idle(local); 163 mutex_unlock(&local->mtx); 164 } 165 166 static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, 167 struct ieee80211_chanctx *ctx) 168 { 169 struct ieee80211_local *local = sdata->local; 170 int ret; 171 172 lockdep_assert_held(&local->chanctx_mtx); 173 174 ret = drv_assign_vif_chanctx(local, sdata, ctx); 175 if (ret) 176 return ret; 177 178 rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf); 179 ctx->refcount++; 180 181 ieee80211_recalc_txpower(sdata); 182 sdata->vif.bss_conf.idle = false; 183 184 if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && 185 sdata->vif.type != NL80211_IFTYPE_MONITOR) 186 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); 187 188 return 0; 189 } 190 191 static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, 192 struct ieee80211_chanctx *ctx) 193 { 194 struct ieee80211_chanctx_conf *conf = &ctx->conf; 195 struct ieee80211_sub_if_data *sdata; 196 const struct cfg80211_chan_def *compat = NULL; 197 198 lockdep_assert_held(&local->chanctx_mtx); 199 200 rcu_read_lock(); 201 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 202 203 if (!ieee80211_sdata_running(sdata)) 204 continue; 205 if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) 206 continue; 207 208 if (!compat) 209 compat = &sdata->vif.bss_conf.chandef; 210 211 compat = cfg80211_chandef_compatible( 212 &sdata->vif.bss_conf.chandef, compat); 213 if (!compat) 214 break; 215 } 216 rcu_read_unlock(); 217 218 if (WARN_ON_ONCE(!compat)) 219 return; 220 221 ieee80211_change_chanctx(local, ctx, compat); 222 } 223 224 static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata, 225 struct ieee80211_chanctx *ctx) 226 { 227 struct ieee80211_local *local = sdata->local; 228 229 lockdep_assert_held(&local->chanctx_mtx); 230 231 ctx->refcount--; 232 rcu_assign_pointer(sdata->vif.chanctx_conf, NULL); 233 234 sdata->vif.bss_conf.idle = true; 235 236 if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && 237 sdata->vif.type != NL80211_IFTYPE_MONITOR) 238 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); 239 240 drv_unassign_vif_chanctx(local, sdata, ctx); 241 242 if (ctx->refcount > 0) { 243 ieee80211_recalc_chanctx_chantype(sdata->local, ctx); 244 ieee80211_recalc_smps_chanctx(local, ctx); 245 ieee80211_recalc_radar_chanctx(local, ctx); 246 } 247 } 248 249 static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) 250 { 251 struct ieee80211_local *local = sdata->local; 252 struct ieee80211_chanctx_conf *conf; 253 struct ieee80211_chanctx *ctx; 254 255 lockdep_assert_held(&local->chanctx_mtx); 256 257 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 258 lockdep_is_held(&local->chanctx_mtx)); 259 if (!conf) 260 return; 261 262 ctx = container_of(conf, struct ieee80211_chanctx, conf); 263 264 ieee80211_unassign_vif_chanctx(sdata, ctx); 265 if (ctx->refcount == 0) 266 ieee80211_free_chanctx(local, ctx); 267 } 268 269 void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, 270 struct ieee80211_chanctx *chanctx) 271 { 272 bool radar_enabled; 273 274 lockdep_assert_held(&local->chanctx_mtx); 275 276 radar_enabled = ieee80211_is_radar_required(local); 277 278 if (radar_enabled == chanctx->conf.radar_enabled) 279 return; 280 281 chanctx->conf.radar_enabled = radar_enabled; 282 local->radar_detect_enabled = chanctx->conf.radar_enabled; 283 284 if (!local->use_chanctx) { 285 local->hw.conf.radar_enabled = chanctx->conf.radar_enabled; 286 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 287 } 288 289 drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR); 290 } 291 292 void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, 293 struct ieee80211_chanctx *chanctx) 294 { 295 struct ieee80211_sub_if_data *sdata; 296 u8 rx_chains_static, rx_chains_dynamic; 297 298 lockdep_assert_held(&local->chanctx_mtx); 299 300 rx_chains_static = 1; 301 rx_chains_dynamic = 1; 302 303 rcu_read_lock(); 304 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 305 u8 needed_static, needed_dynamic; 306 307 if (!ieee80211_sdata_running(sdata)) 308 continue; 309 310 if (rcu_access_pointer(sdata->vif.chanctx_conf) != 311 &chanctx->conf) 312 continue; 313 314 switch (sdata->vif.type) { 315 case NL80211_IFTYPE_P2P_DEVICE: 316 continue; 317 case NL80211_IFTYPE_STATION: 318 if (!sdata->u.mgd.associated) 319 continue; 320 break; 321 case NL80211_IFTYPE_AP_VLAN: 322 continue; 323 case NL80211_IFTYPE_AP: 324 case NL80211_IFTYPE_ADHOC: 325 case NL80211_IFTYPE_WDS: 326 case NL80211_IFTYPE_MESH_POINT: 327 break; 328 default: 329 WARN_ON_ONCE(1); 330 } 331 332 switch (sdata->smps_mode) { 333 default: 334 WARN_ONCE(1, "Invalid SMPS mode %d\n", 335 sdata->smps_mode); 336 /* fall through */ 337 case IEEE80211_SMPS_OFF: 338 needed_static = sdata->needed_rx_chains; 339 needed_dynamic = sdata->needed_rx_chains; 340 break; 341 case IEEE80211_SMPS_DYNAMIC: 342 needed_static = 1; 343 needed_dynamic = sdata->needed_rx_chains; 344 break; 345 case IEEE80211_SMPS_STATIC: 346 needed_static = 1; 347 needed_dynamic = 1; 348 break; 349 } 350 351 rx_chains_static = max(rx_chains_static, needed_static); 352 rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic); 353 } 354 rcu_read_unlock(); 355 356 if (!local->use_chanctx) { 357 if (rx_chains_static > 1) 358 local->smps_mode = IEEE80211_SMPS_OFF; 359 else if (rx_chains_dynamic > 1) 360 local->smps_mode = IEEE80211_SMPS_DYNAMIC; 361 else 362 local->smps_mode = IEEE80211_SMPS_STATIC; 363 ieee80211_hw_config(local, 0); 364 } 365 366 if (rx_chains_static == chanctx->conf.rx_chains_static && 367 rx_chains_dynamic == chanctx->conf.rx_chains_dynamic) 368 return; 369 370 chanctx->conf.rx_chains_static = rx_chains_static; 371 chanctx->conf.rx_chains_dynamic = rx_chains_dynamic; 372 drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS); 373 } 374 375 int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, 376 const struct cfg80211_chan_def *chandef, 377 enum ieee80211_chanctx_mode mode) 378 { 379 struct ieee80211_local *local = sdata->local; 380 struct ieee80211_chanctx *ctx; 381 int ret; 382 383 WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); 384 385 mutex_lock(&local->chanctx_mtx); 386 __ieee80211_vif_release_channel(sdata); 387 388 ctx = ieee80211_find_chanctx(local, chandef, mode); 389 if (!ctx) 390 ctx = ieee80211_new_chanctx(local, chandef, mode); 391 if (IS_ERR(ctx)) { 392 ret = PTR_ERR(ctx); 393 goto out; 394 } 395 396 sdata->vif.bss_conf.chandef = *chandef; 397 398 ret = ieee80211_assign_vif_chanctx(sdata, ctx); 399 if (ret) { 400 /* if assign fails refcount stays the same */ 401 if (ctx->refcount == 0) 402 ieee80211_free_chanctx(local, ctx); 403 goto out; 404 } 405 406 ieee80211_recalc_smps_chanctx(local, ctx); 407 ieee80211_recalc_radar_chanctx(local, ctx); 408 out: 409 mutex_unlock(&local->chanctx_mtx); 410 return ret; 411 } 412 413 int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, 414 const struct cfg80211_chan_def *chandef, 415 u32 *changed) 416 { 417 struct ieee80211_local *local = sdata->local; 418 struct ieee80211_chanctx_conf *conf; 419 struct ieee80211_chanctx *ctx; 420 int ret; 421 u32 chanctx_changed = 0; 422 423 /* should never be called if not performing a channel switch. */ 424 if (WARN_ON(!sdata->vif.csa_active)) 425 return -EINVAL; 426 427 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef, 428 IEEE80211_CHAN_DISABLED)) 429 return -EINVAL; 430 431 mutex_lock(&local->chanctx_mtx); 432 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 433 lockdep_is_held(&local->chanctx_mtx)); 434 if (!conf) { 435 ret = -EINVAL; 436 goto out; 437 } 438 439 ctx = container_of(conf, struct ieee80211_chanctx, conf); 440 if (ctx->refcount != 1) { 441 ret = -EINVAL; 442 goto out; 443 } 444 445 if (sdata->vif.bss_conf.chandef.width != chandef->width) { 446 chanctx_changed = IEEE80211_CHANCTX_CHANGE_WIDTH; 447 *changed |= BSS_CHANGED_BANDWIDTH; 448 } 449 450 sdata->vif.bss_conf.chandef = *chandef; 451 ctx->conf.def = *chandef; 452 453 chanctx_changed |= IEEE80211_CHANCTX_CHANGE_CHANNEL; 454 drv_change_chanctx(local, ctx, chanctx_changed); 455 456 ieee80211_recalc_chanctx_chantype(local, ctx); 457 ieee80211_recalc_smps_chanctx(local, ctx); 458 ieee80211_recalc_radar_chanctx(local, ctx); 459 460 ret = 0; 461 out: 462 mutex_unlock(&local->chanctx_mtx); 463 return ret; 464 } 465 466 int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, 467 const struct cfg80211_chan_def *chandef, 468 u32 *changed) 469 { 470 struct ieee80211_local *local = sdata->local; 471 struct ieee80211_chanctx_conf *conf; 472 struct ieee80211_chanctx *ctx; 473 int ret; 474 475 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef, 476 IEEE80211_CHAN_DISABLED)) 477 return -EINVAL; 478 479 mutex_lock(&local->chanctx_mtx); 480 if (cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef)) { 481 ret = 0; 482 goto out; 483 } 484 485 if (chandef->width == NL80211_CHAN_WIDTH_20_NOHT || 486 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) { 487 ret = -EINVAL; 488 goto out; 489 } 490 491 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 492 lockdep_is_held(&local->chanctx_mtx)); 493 if (!conf) { 494 ret = -EINVAL; 495 goto out; 496 } 497 498 ctx = container_of(conf, struct ieee80211_chanctx, conf); 499 if (!cfg80211_chandef_compatible(&conf->def, chandef)) { 500 ret = -EINVAL; 501 goto out; 502 } 503 504 sdata->vif.bss_conf.chandef = *chandef; 505 506 ieee80211_recalc_chanctx_chantype(local, ctx); 507 508 *changed |= BSS_CHANGED_BANDWIDTH; 509 ret = 0; 510 out: 511 mutex_unlock(&local->chanctx_mtx); 512 return ret; 513 } 514 515 void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) 516 { 517 WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); 518 519 mutex_lock(&sdata->local->chanctx_mtx); 520 __ieee80211_vif_release_channel(sdata); 521 mutex_unlock(&sdata->local->chanctx_mtx); 522 } 523 524 void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata) 525 { 526 struct ieee80211_local *local = sdata->local; 527 struct ieee80211_sub_if_data *ap; 528 struct ieee80211_chanctx_conf *conf; 529 530 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss)) 531 return; 532 533 ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); 534 535 mutex_lock(&local->chanctx_mtx); 536 537 conf = rcu_dereference_protected(ap->vif.chanctx_conf, 538 lockdep_is_held(&local->chanctx_mtx)); 539 rcu_assign_pointer(sdata->vif.chanctx_conf, conf); 540 mutex_unlock(&local->chanctx_mtx); 541 } 542 543 void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, 544 bool clear) 545 { 546 struct ieee80211_local *local = sdata->local; 547 struct ieee80211_sub_if_data *vlan; 548 struct ieee80211_chanctx_conf *conf; 549 550 ASSERT_RTNL(); 551 552 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP)) 553 return; 554 555 mutex_lock(&local->chanctx_mtx); 556 557 /* 558 * Check that conf exists, even when clearing this function 559 * must be called with the AP's channel context still there 560 * as it would otherwise cause VLANs to have an invalid 561 * channel context pointer for a while, possibly pointing 562 * to a channel context that has already been freed. 563 */ 564 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 565 lockdep_is_held(&local->chanctx_mtx)); 566 WARN_ON(!conf); 567 568 if (clear) 569 conf = NULL; 570 571 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) 572 rcu_assign_pointer(vlan->vif.chanctx_conf, conf); 573 574 mutex_unlock(&local->chanctx_mtx); 575 } 576 577 void ieee80211_iter_chan_contexts_atomic( 578 struct ieee80211_hw *hw, 579 void (*iter)(struct ieee80211_hw *hw, 580 struct ieee80211_chanctx_conf *chanctx_conf, 581 void *data), 582 void *iter_data) 583 { 584 struct ieee80211_local *local = hw_to_local(hw); 585 struct ieee80211_chanctx *ctx; 586 587 rcu_read_lock(); 588 list_for_each_entry_rcu(ctx, &local->chanctx_list, list) 589 if (ctx->driver_present) 590 iter(hw, &ctx->conf, iter_data); 591 rcu_read_unlock(); 592 } 593 EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic); 594