1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright 2015 Intel Deutschland GmbH 4 * Copyright (C) 2022-2024 Intel Corporation 5 */ 6 #include <net/mac80211.h> 7 #include "ieee80211_i.h" 8 #include "trace.h" 9 #include "driver-ops.h" 10 #include "debugfs_sta.h" 11 #include "debugfs_netdev.h" 12 13 int drv_start(struct ieee80211_local *local) 14 { 15 int ret; 16 17 might_sleep(); 18 lockdep_assert_wiphy(local->hw.wiphy); 19 20 if (WARN_ON(local->started)) 21 return -EALREADY; 22 23 trace_drv_start(local); 24 local->started = true; 25 /* allow rx frames */ 26 smp_mb(); 27 ret = local->ops->start(&local->hw); 28 trace_drv_return_int(local, ret); 29 30 if (ret) 31 local->started = false; 32 33 return ret; 34 } 35 36 void drv_stop(struct ieee80211_local *local, bool suspend) 37 { 38 might_sleep(); 39 lockdep_assert_wiphy(local->hw.wiphy); 40 41 if (WARN_ON(!local->started)) 42 return; 43 44 trace_drv_stop(local, suspend); 45 local->ops->stop(&local->hw, suspend); 46 trace_drv_return_void(local); 47 48 /* sync away all work on the tasklet before clearing started */ 49 tasklet_disable(&local->tasklet); 50 tasklet_enable(&local->tasklet); 51 52 barrier(); 53 54 local->started = false; 55 } 56 57 int drv_add_interface(struct ieee80211_local *local, 58 struct ieee80211_sub_if_data *sdata) 59 { 60 int ret; 61 62 might_sleep(); 63 lockdep_assert_wiphy(local->hw.wiphy); 64 65 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 66 (sdata->vif.type == NL80211_IFTYPE_MONITOR && 67 !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) && 68 !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR) && 69 !(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)))) 70 return -EINVAL; 71 72 trace_drv_add_interface(local, sdata); 73 ret = local->ops->add_interface(&local->hw, &sdata->vif); 74 trace_drv_return_int(local, ret); 75 76 if (ret) 77 return ret; 78 79 if (!(sdata->flags & IEEE80211_SDATA_IN_DRIVER)) { 80 sdata->flags |= IEEE80211_SDATA_IN_DRIVER; 81 82 drv_vif_add_debugfs(local, sdata); 83 /* initially vif is not MLD */ 84 ieee80211_link_debugfs_drv_add(&sdata->deflink); 85 } 86 87 return 0; 88 } 89 90 int drv_change_interface(struct ieee80211_local *local, 91 struct ieee80211_sub_if_data *sdata, 92 enum nl80211_iftype type, bool p2p) 93 { 94 int ret; 95 96 might_sleep(); 97 lockdep_assert_wiphy(local->hw.wiphy); 98 99 if (!check_sdata_in_driver(sdata)) 100 return -EIO; 101 102 trace_drv_change_interface(local, sdata, type, p2p); 103 ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); 104 trace_drv_return_int(local, ret); 105 return ret; 106 } 107 108 void drv_remove_interface(struct ieee80211_local *local, 109 struct ieee80211_sub_if_data *sdata) 110 { 111 might_sleep(); 112 lockdep_assert_wiphy(local->hw.wiphy); 113 114 if (!check_sdata_in_driver(sdata)) 115 return; 116 117 sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER; 118 119 /* 120 * Remove driver debugfs entries. 121 * The virtual monitor interface doesn't get a debugfs 122 * entry, so it's exempt here. 123 */ 124 if (sdata != rcu_access_pointer(local->monitor_sdata)) 125 ieee80211_debugfs_recreate_netdev(sdata, 126 sdata->vif.valid_links); 127 128 trace_drv_remove_interface(local, sdata); 129 local->ops->remove_interface(&local->hw, &sdata->vif); 130 trace_drv_return_void(local); 131 } 132 133 __must_check 134 int drv_sta_state(struct ieee80211_local *local, 135 struct ieee80211_sub_if_data *sdata, 136 struct sta_info *sta, 137 enum ieee80211_sta_state old_state, 138 enum ieee80211_sta_state new_state) 139 { 140 int ret = 0; 141 142 might_sleep(); 143 lockdep_assert_wiphy(local->hw.wiphy); 144 145 sdata = get_bss_sdata(sdata); 146 if (!check_sdata_in_driver(sdata)) 147 return -EIO; 148 149 trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state); 150 if (local->ops->sta_state) { 151 ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta, 152 old_state, new_state); 153 } else if (old_state == IEEE80211_STA_AUTH && 154 new_state == IEEE80211_STA_ASSOC) { 155 ret = drv_sta_add(local, sdata, &sta->sta); 156 if (ret == 0) { 157 sta->uploaded = true; 158 if (rcu_access_pointer(sta->sta.rates)) 159 drv_sta_rate_tbl_update(local, sdata, &sta->sta); 160 } 161 } else if (old_state == IEEE80211_STA_ASSOC && 162 new_state == IEEE80211_STA_AUTH) { 163 drv_sta_remove(local, sdata, &sta->sta); 164 } 165 trace_drv_return_int(local, ret); 166 return ret; 167 } 168 169 __must_check 170 int drv_sta_set_txpwr(struct ieee80211_local *local, 171 struct ieee80211_sub_if_data *sdata, 172 struct sta_info *sta) 173 { 174 int ret = -EOPNOTSUPP; 175 176 might_sleep(); 177 lockdep_assert_wiphy(local->hw.wiphy); 178 179 sdata = get_bss_sdata(sdata); 180 if (!check_sdata_in_driver(sdata)) 181 return -EIO; 182 183 trace_drv_sta_set_txpwr(local, sdata, &sta->sta); 184 if (local->ops->sta_set_txpwr) 185 ret = local->ops->sta_set_txpwr(&local->hw, &sdata->vif, 186 &sta->sta); 187 trace_drv_return_int(local, ret); 188 return ret; 189 } 190 191 void drv_link_sta_rc_update(struct ieee80211_local *local, 192 struct ieee80211_sub_if_data *sdata, 193 struct ieee80211_link_sta *link_sta, 194 u32 changed) 195 { 196 sdata = get_bss_sdata(sdata); 197 if (!check_sdata_in_driver(sdata)) 198 return; 199 200 WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED && 201 (sdata->vif.type != NL80211_IFTYPE_ADHOC && 202 sdata->vif.type != NL80211_IFTYPE_MESH_POINT)); 203 204 trace_drv_link_sta_rc_update(local, sdata, link_sta, changed); 205 if (local->ops->link_sta_rc_update) 206 local->ops->link_sta_rc_update(&local->hw, &sdata->vif, 207 link_sta, changed); 208 209 trace_drv_return_void(local); 210 } 211 212 int drv_conf_tx(struct ieee80211_local *local, 213 struct ieee80211_link_data *link, u16 ac, 214 const struct ieee80211_tx_queue_params *params) 215 { 216 struct ieee80211_sub_if_data *sdata = link->sdata; 217 int ret = -EOPNOTSUPP; 218 219 might_sleep(); 220 lockdep_assert_wiphy(local->hw.wiphy); 221 222 if (!check_sdata_in_driver(sdata)) 223 return -EIO; 224 225 if (!ieee80211_vif_link_active(&sdata->vif, link->link_id)) 226 return 0; 227 228 if (params->cw_min == 0 || params->cw_min > params->cw_max) { 229 /* 230 * If we can't configure hardware anyway, don't warn. We may 231 * never have initialized the CW parameters. 232 */ 233 WARN_ONCE(local->ops->conf_tx, 234 "%s: invalid CW_min/CW_max: %d/%d\n", 235 sdata->name, params->cw_min, params->cw_max); 236 return -EINVAL; 237 } 238 239 trace_drv_conf_tx(local, sdata, link->link_id, ac, params); 240 if (local->ops->conf_tx) 241 ret = local->ops->conf_tx(&local->hw, &sdata->vif, 242 link->link_id, ac, params); 243 trace_drv_return_int(local, ret); 244 return ret; 245 } 246 247 u64 drv_get_tsf(struct ieee80211_local *local, 248 struct ieee80211_sub_if_data *sdata) 249 { 250 u64 ret = -1ULL; 251 252 might_sleep(); 253 lockdep_assert_wiphy(local->hw.wiphy); 254 255 if (!check_sdata_in_driver(sdata)) 256 return ret; 257 258 trace_drv_get_tsf(local, sdata); 259 if (local->ops->get_tsf) 260 ret = local->ops->get_tsf(&local->hw, &sdata->vif); 261 trace_drv_return_u64(local, ret); 262 return ret; 263 } 264 265 void drv_set_tsf(struct ieee80211_local *local, 266 struct ieee80211_sub_if_data *sdata, 267 u64 tsf) 268 { 269 might_sleep(); 270 lockdep_assert_wiphy(local->hw.wiphy); 271 272 if (!check_sdata_in_driver(sdata)) 273 return; 274 275 trace_drv_set_tsf(local, sdata, tsf); 276 if (local->ops->set_tsf) 277 local->ops->set_tsf(&local->hw, &sdata->vif, tsf); 278 trace_drv_return_void(local); 279 } 280 281 void drv_offset_tsf(struct ieee80211_local *local, 282 struct ieee80211_sub_if_data *sdata, 283 s64 offset) 284 { 285 might_sleep(); 286 lockdep_assert_wiphy(local->hw.wiphy); 287 288 if (!check_sdata_in_driver(sdata)) 289 return; 290 291 trace_drv_offset_tsf(local, sdata, offset); 292 if (local->ops->offset_tsf) 293 local->ops->offset_tsf(&local->hw, &sdata->vif, offset); 294 trace_drv_return_void(local); 295 } 296 297 void drv_reset_tsf(struct ieee80211_local *local, 298 struct ieee80211_sub_if_data *sdata) 299 { 300 might_sleep(); 301 lockdep_assert_wiphy(local->hw.wiphy); 302 303 if (!check_sdata_in_driver(sdata)) 304 return; 305 306 trace_drv_reset_tsf(local, sdata); 307 if (local->ops->reset_tsf) 308 local->ops->reset_tsf(&local->hw, &sdata->vif); 309 trace_drv_return_void(local); 310 } 311 312 int drv_assign_vif_chanctx(struct ieee80211_local *local, 313 struct ieee80211_sub_if_data *sdata, 314 struct ieee80211_bss_conf *link_conf, 315 struct ieee80211_chanctx *ctx) 316 { 317 int ret = 0; 318 319 might_sleep(); 320 lockdep_assert_wiphy(local->hw.wiphy); 321 322 /* 323 * We should perhaps push emulate chanctx down and only 324 * make it call ->config() when the chanctx is actually 325 * assigned here (and unassigned below), but that's yet 326 * another change to all drivers to add assign/unassign 327 * emulation callbacks. Maybe later. 328 */ 329 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && 330 local->emulate_chanctx && 331 !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) 332 return 0; 333 334 if (!check_sdata_in_driver(sdata)) 335 return -EIO; 336 337 if (!ieee80211_vif_link_active(&sdata->vif, link_conf->link_id)) 338 return 0; 339 340 trace_drv_assign_vif_chanctx(local, sdata, link_conf, ctx); 341 if (local->ops->assign_vif_chanctx) { 342 WARN_ON_ONCE(!ctx->driver_present); 343 ret = local->ops->assign_vif_chanctx(&local->hw, 344 &sdata->vif, 345 link_conf, 346 &ctx->conf); 347 } 348 trace_drv_return_int(local, ret); 349 350 return ret; 351 } 352 353 void drv_unassign_vif_chanctx(struct ieee80211_local *local, 354 struct ieee80211_sub_if_data *sdata, 355 struct ieee80211_bss_conf *link_conf, 356 struct ieee80211_chanctx *ctx) 357 { 358 might_sleep(); 359 lockdep_assert_wiphy(local->hw.wiphy); 360 361 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && 362 local->emulate_chanctx && 363 !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) 364 return; 365 366 if (!check_sdata_in_driver(sdata)) 367 return; 368 369 if (!ieee80211_vif_link_active(&sdata->vif, link_conf->link_id)) 370 return; 371 372 trace_drv_unassign_vif_chanctx(local, sdata, link_conf, ctx); 373 if (local->ops->unassign_vif_chanctx) { 374 WARN_ON_ONCE(!ctx->driver_present); 375 local->ops->unassign_vif_chanctx(&local->hw, 376 &sdata->vif, 377 link_conf, 378 &ctx->conf); 379 } 380 trace_drv_return_void(local); 381 } 382 383 int drv_switch_vif_chanctx(struct ieee80211_local *local, 384 struct ieee80211_vif_chanctx_switch *vifs, 385 int n_vifs, enum ieee80211_chanctx_switch_mode mode) 386 { 387 int ret = 0; 388 int i; 389 390 might_sleep(); 391 lockdep_assert_wiphy(local->hw.wiphy); 392 393 if (!local->ops->switch_vif_chanctx) 394 return -EOPNOTSUPP; 395 396 for (i = 0; i < n_vifs; i++) { 397 struct ieee80211_chanctx *new_ctx = 398 container_of(vifs[i].new_ctx, 399 struct ieee80211_chanctx, 400 conf); 401 struct ieee80211_chanctx *old_ctx = 402 container_of(vifs[i].old_ctx, 403 struct ieee80211_chanctx, 404 conf); 405 406 WARN_ON_ONCE(!old_ctx->driver_present); 407 WARN_ON_ONCE((mode == CHANCTX_SWMODE_SWAP_CONTEXTS && 408 new_ctx->driver_present) || 409 (mode == CHANCTX_SWMODE_REASSIGN_VIF && 410 !new_ctx->driver_present)); 411 } 412 413 trace_drv_switch_vif_chanctx(local, vifs, n_vifs, mode); 414 ret = local->ops->switch_vif_chanctx(&local->hw, 415 vifs, n_vifs, mode); 416 trace_drv_return_int(local, ret); 417 418 if (!ret && mode == CHANCTX_SWMODE_SWAP_CONTEXTS) { 419 for (i = 0; i < n_vifs; i++) { 420 struct ieee80211_chanctx *new_ctx = 421 container_of(vifs[i].new_ctx, 422 struct ieee80211_chanctx, 423 conf); 424 struct ieee80211_chanctx *old_ctx = 425 container_of(vifs[i].old_ctx, 426 struct ieee80211_chanctx, 427 conf); 428 429 new_ctx->driver_present = true; 430 old_ctx->driver_present = false; 431 } 432 } 433 434 return ret; 435 } 436 437 int drv_ampdu_action(struct ieee80211_local *local, 438 struct ieee80211_sub_if_data *sdata, 439 struct ieee80211_ampdu_params *params) 440 { 441 int ret = -EOPNOTSUPP; 442 443 might_sleep(); 444 lockdep_assert_wiphy(local->hw.wiphy); 445 446 sdata = get_bss_sdata(sdata); 447 if (!check_sdata_in_driver(sdata)) 448 return -EIO; 449 450 trace_drv_ampdu_action(local, sdata, params); 451 452 if (local->ops->ampdu_action) 453 ret = local->ops->ampdu_action(&local->hw, &sdata->vif, params); 454 455 trace_drv_return_int(local, ret); 456 457 return ret; 458 } 459 460 void drv_link_info_changed(struct ieee80211_local *local, 461 struct ieee80211_sub_if_data *sdata, 462 struct ieee80211_bss_conf *info, 463 int link_id, u64 changed) 464 { 465 might_sleep(); 466 lockdep_assert_wiphy(local->hw.wiphy); 467 468 if (WARN_ON_ONCE(changed & (BSS_CHANGED_BEACON | 469 BSS_CHANGED_BEACON_ENABLED) && 470 sdata->vif.type != NL80211_IFTYPE_AP && 471 sdata->vif.type != NL80211_IFTYPE_ADHOC && 472 sdata->vif.type != NL80211_IFTYPE_MESH_POINT && 473 sdata->vif.type != NL80211_IFTYPE_OCB)) 474 return; 475 476 if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE || 477 sdata->vif.type == NL80211_IFTYPE_NAN || 478 (sdata->vif.type == NL80211_IFTYPE_MONITOR && 479 !sdata->vif.bss_conf.mu_mimo_owner && 480 !(changed & BSS_CHANGED_TXPOWER)))) 481 return; 482 483 if (!check_sdata_in_driver(sdata)) 484 return; 485 486 if (!ieee80211_vif_link_active(&sdata->vif, link_id)) 487 return; 488 489 trace_drv_link_info_changed(local, sdata, info, changed); 490 if (local->ops->link_info_changed) 491 local->ops->link_info_changed(&local->hw, &sdata->vif, 492 info, changed); 493 else if (local->ops->bss_info_changed) 494 local->ops->bss_info_changed(&local->hw, &sdata->vif, 495 info, changed); 496 trace_drv_return_void(local); 497 } 498 499 int drv_set_key(struct ieee80211_local *local, 500 enum set_key_cmd cmd, 501 struct ieee80211_sub_if_data *sdata, 502 struct ieee80211_sta *sta, 503 struct ieee80211_key_conf *key) 504 { 505 int ret; 506 507 might_sleep(); 508 lockdep_assert_wiphy(local->hw.wiphy); 509 510 sdata = get_bss_sdata(sdata); 511 if (!check_sdata_in_driver(sdata)) 512 return -EIO; 513 514 if (WARN_ON(key->link_id >= 0 && sdata->vif.active_links && 515 !(sdata->vif.active_links & BIT(key->link_id)))) 516 return -ENOLINK; 517 518 trace_drv_set_key(local, cmd, sdata, sta, key); 519 ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); 520 trace_drv_return_int(local, ret); 521 return ret; 522 } 523 524 int drv_change_vif_links(struct ieee80211_local *local, 525 struct ieee80211_sub_if_data *sdata, 526 u16 old_links, u16 new_links, 527 struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]) 528 { 529 struct ieee80211_link_data *link; 530 unsigned long links_to_add; 531 unsigned long links_to_rem; 532 unsigned int link_id; 533 int ret = -EOPNOTSUPP; 534 535 might_sleep(); 536 lockdep_assert_wiphy(local->hw.wiphy); 537 538 if (!check_sdata_in_driver(sdata)) 539 return -EIO; 540 541 if (old_links == new_links) 542 return 0; 543 544 links_to_add = ~old_links & new_links; 545 links_to_rem = old_links & ~new_links; 546 547 for_each_set_bit(link_id, &links_to_rem, IEEE80211_MLD_MAX_NUM_LINKS) { 548 link = rcu_access_pointer(sdata->link[link_id]); 549 550 ieee80211_link_debugfs_drv_remove(link); 551 } 552 553 trace_drv_change_vif_links(local, sdata, old_links, new_links); 554 if (local->ops->change_vif_links) 555 ret = local->ops->change_vif_links(&local->hw, &sdata->vif, 556 old_links, new_links, old); 557 trace_drv_return_int(local, ret); 558 559 if (ret) 560 return ret; 561 562 if (!local->in_reconfig && !local->resuming) { 563 for_each_set_bit(link_id, &links_to_add, 564 IEEE80211_MLD_MAX_NUM_LINKS) { 565 link = rcu_access_pointer(sdata->link[link_id]); 566 567 ieee80211_link_debugfs_drv_add(link); 568 } 569 } 570 571 return 0; 572 } 573 574 int drv_change_sta_links(struct ieee80211_local *local, 575 struct ieee80211_sub_if_data *sdata, 576 struct ieee80211_sta *sta, 577 u16 old_links, u16 new_links) 578 { 579 struct sta_info *info = container_of(sta, struct sta_info, sta); 580 struct link_sta_info *link_sta; 581 unsigned long links_to_add; 582 unsigned long links_to_rem; 583 unsigned int link_id; 584 int ret = -EOPNOTSUPP; 585 586 might_sleep(); 587 lockdep_assert_wiphy(local->hw.wiphy); 588 589 if (!check_sdata_in_driver(sdata)) 590 return -EIO; 591 592 old_links &= sdata->vif.active_links; 593 new_links &= sdata->vif.active_links; 594 595 if (old_links == new_links) 596 return 0; 597 598 links_to_add = ~old_links & new_links; 599 links_to_rem = old_links & ~new_links; 600 601 for_each_set_bit(link_id, &links_to_rem, IEEE80211_MLD_MAX_NUM_LINKS) { 602 link_sta = rcu_dereference_protected(info->link[link_id], 603 lockdep_is_held(&local->hw.wiphy->mtx)); 604 605 ieee80211_link_sta_debugfs_drv_remove(link_sta); 606 } 607 608 trace_drv_change_sta_links(local, sdata, sta, old_links, new_links); 609 if (local->ops->change_sta_links) 610 ret = local->ops->change_sta_links(&local->hw, &sdata->vif, sta, 611 old_links, new_links); 612 trace_drv_return_int(local, ret); 613 614 if (ret) 615 return ret; 616 617 /* during reconfig don't add it to debugfs again */ 618 if (local->in_reconfig || local->resuming) 619 return 0; 620 621 for_each_set_bit(link_id, &links_to_add, IEEE80211_MLD_MAX_NUM_LINKS) { 622 link_sta = rcu_dereference_protected(info->link[link_id], 623 lockdep_is_held(&local->hw.wiphy->mtx)); 624 ieee80211_link_sta_debugfs_drv_add(link_sta); 625 } 626 627 return 0; 628 } 629