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