1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3* Portions of this file 4* Copyright(c) 2016 Intel Deutschland GmbH 5* Copyright (C) 2018 - 2019 Intel Corporation 6*/ 7 8#ifndef __MAC80211_DRIVER_OPS 9#define __MAC80211_DRIVER_OPS 10 11#include <net/mac80211.h> 12#include "ieee80211_i.h" 13#include "trace.h" 14 15#define check_sdata_in_driver(sdata) ({ \ 16 !WARN_ONCE(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER), \ 17 "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", \ 18 sdata->dev ? sdata->dev->name : sdata->name, sdata->flags); \ 19}) 20 21static inline struct ieee80211_sub_if_data * 22get_bss_sdata(struct ieee80211_sub_if_data *sdata) 23{ 24 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 25 sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, 26 u.ap); 27 28 return sdata; 29} 30 31static inline void drv_tx(struct ieee80211_local *local, 32 struct ieee80211_tx_control *control, 33 struct sk_buff *skb) 34{ 35 local->ops->tx(&local->hw, control, skb); 36} 37 38static inline void drv_sync_rx_queues(struct ieee80211_local *local, 39 struct sta_info *sta) 40{ 41 if (local->ops->sync_rx_queues) { 42 trace_drv_sync_rx_queues(local, sta->sdata, &sta->sta); 43 local->ops->sync_rx_queues(&local->hw); 44 trace_drv_return_void(local); 45 } 46} 47 48static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata, 49 u32 sset, u8 *data) 50{ 51 struct ieee80211_local *local = sdata->local; 52 if (local->ops->get_et_strings) { 53 trace_drv_get_et_strings(local, sset); 54 local->ops->get_et_strings(&local->hw, &sdata->vif, sset, data); 55 trace_drv_return_void(local); 56 } 57} 58 59static inline void drv_get_et_stats(struct ieee80211_sub_if_data *sdata, 60 struct ethtool_stats *stats, 61 u64 *data) 62{ 63 struct ieee80211_local *local = sdata->local; 64 if (local->ops->get_et_stats) { 65 trace_drv_get_et_stats(local); 66 local->ops->get_et_stats(&local->hw, &sdata->vif, stats, data); 67 trace_drv_return_void(local); 68 } 69} 70 71static inline int drv_get_et_sset_count(struct ieee80211_sub_if_data *sdata, 72 int sset) 73{ 74 struct ieee80211_local *local = sdata->local; 75 int rv = 0; 76 if (local->ops->get_et_sset_count) { 77 trace_drv_get_et_sset_count(local, sset); 78 rv = local->ops->get_et_sset_count(&local->hw, &sdata->vif, 79 sset); 80 trace_drv_return_int(local, rv); 81 } 82 return rv; 83} 84 85int drv_start(struct ieee80211_local *local); 86void drv_stop(struct ieee80211_local *local); 87 88#ifdef CONFIG_PM 89static inline int drv_suspend(struct ieee80211_local *local, 90 struct cfg80211_wowlan *wowlan) 91{ 92 int ret; 93 94 might_sleep(); 95 96 trace_drv_suspend(local); 97 ret = local->ops->suspend(&local->hw, wowlan); 98 trace_drv_return_int(local, ret); 99 return ret; 100} 101 102static inline int drv_resume(struct ieee80211_local *local) 103{ 104 int ret; 105 106 might_sleep(); 107 108 trace_drv_resume(local); 109 ret = local->ops->resume(&local->hw); 110 trace_drv_return_int(local, ret); 111 return ret; 112} 113 114static inline void drv_set_wakeup(struct ieee80211_local *local, 115 bool enabled) 116{ 117 might_sleep(); 118 119 if (!local->ops->set_wakeup) 120 return; 121 122 trace_drv_set_wakeup(local, enabled); 123 local->ops->set_wakeup(&local->hw, enabled); 124 trace_drv_return_void(local); 125} 126#endif 127 128int drv_add_interface(struct ieee80211_local *local, 129 struct ieee80211_sub_if_data *sdata); 130 131int drv_change_interface(struct ieee80211_local *local, 132 struct ieee80211_sub_if_data *sdata, 133 enum nl80211_iftype type, bool p2p); 134 135void drv_remove_interface(struct ieee80211_local *local, 136 struct ieee80211_sub_if_data *sdata); 137 138static inline int drv_config(struct ieee80211_local *local, u32 changed) 139{ 140 int ret; 141 142 might_sleep(); 143 144 trace_drv_config(local, changed); 145 ret = local->ops->config(&local->hw, changed); 146 trace_drv_return_int(local, ret); 147 return ret; 148} 149 150static inline void drv_bss_info_changed(struct ieee80211_local *local, 151 struct ieee80211_sub_if_data *sdata, 152 struct ieee80211_bss_conf *info, 153 u32 changed) 154{ 155 might_sleep(); 156 157 if (WARN_ON_ONCE(changed & (BSS_CHANGED_BEACON | 158 BSS_CHANGED_BEACON_ENABLED) && 159 sdata->vif.type != NL80211_IFTYPE_AP && 160 sdata->vif.type != NL80211_IFTYPE_ADHOC && 161 sdata->vif.type != NL80211_IFTYPE_MESH_POINT && 162 sdata->vif.type != NL80211_IFTYPE_OCB)) 163 return; 164 165 if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE || 166 sdata->vif.type == NL80211_IFTYPE_NAN || 167 (sdata->vif.type == NL80211_IFTYPE_MONITOR && 168 !sdata->vif.mu_mimo_owner && 169 !(changed & BSS_CHANGED_TXPOWER)))) 170 return; 171 172 if (!check_sdata_in_driver(sdata)) 173 return; 174 175 trace_drv_bss_info_changed(local, sdata, info, changed); 176 if (local->ops->bss_info_changed) 177 local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed); 178 trace_drv_return_void(local); 179} 180 181static inline u64 drv_prepare_multicast(struct ieee80211_local *local, 182 struct netdev_hw_addr_list *mc_list) 183{ 184 u64 ret = 0; 185 186 trace_drv_prepare_multicast(local, mc_list->count); 187 188 if (local->ops->prepare_multicast) 189 ret = local->ops->prepare_multicast(&local->hw, mc_list); 190 191 trace_drv_return_u64(local, ret); 192 193 return ret; 194} 195 196static inline void drv_configure_filter(struct ieee80211_local *local, 197 unsigned int changed_flags, 198 unsigned int *total_flags, 199 u64 multicast) 200{ 201 might_sleep(); 202 203 trace_drv_configure_filter(local, changed_flags, total_flags, 204 multicast); 205 local->ops->configure_filter(&local->hw, changed_flags, total_flags, 206 multicast); 207 trace_drv_return_void(local); 208} 209 210static inline void drv_config_iface_filter(struct ieee80211_local *local, 211 struct ieee80211_sub_if_data *sdata, 212 unsigned int filter_flags, 213 unsigned int changed_flags) 214{ 215 might_sleep(); 216 217 trace_drv_config_iface_filter(local, sdata, filter_flags, 218 changed_flags); 219 if (local->ops->config_iface_filter) 220 local->ops->config_iface_filter(&local->hw, &sdata->vif, 221 filter_flags, 222 changed_flags); 223 trace_drv_return_void(local); 224} 225 226static inline int drv_set_tim(struct ieee80211_local *local, 227 struct ieee80211_sta *sta, bool set) 228{ 229 int ret = 0; 230 trace_drv_set_tim(local, sta, set); 231 if (local->ops->set_tim) 232 ret = local->ops->set_tim(&local->hw, sta, set); 233 trace_drv_return_int(local, ret); 234 return ret; 235} 236 237static inline int drv_set_key(struct ieee80211_local *local, 238 enum set_key_cmd cmd, 239 struct ieee80211_sub_if_data *sdata, 240 struct ieee80211_sta *sta, 241 struct ieee80211_key_conf *key) 242{ 243 int ret; 244 245 might_sleep(); 246 247 sdata = get_bss_sdata(sdata); 248 if (!check_sdata_in_driver(sdata)) 249 return -EIO; 250 251 trace_drv_set_key(local, cmd, sdata, sta, key); 252 ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); 253 trace_drv_return_int(local, ret); 254 return ret; 255} 256 257static inline void drv_update_tkip_key(struct ieee80211_local *local, 258 struct ieee80211_sub_if_data *sdata, 259 struct ieee80211_key_conf *conf, 260 struct sta_info *sta, u32 iv32, 261 u16 *phase1key) 262{ 263 struct ieee80211_sta *ista = NULL; 264 265 if (sta) 266 ista = &sta->sta; 267 268 sdata = get_bss_sdata(sdata); 269 if (!check_sdata_in_driver(sdata)) 270 return; 271 272 trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); 273 if (local->ops->update_tkip_key) 274 local->ops->update_tkip_key(&local->hw, &sdata->vif, conf, 275 ista, iv32, phase1key); 276 trace_drv_return_void(local); 277} 278 279static inline int drv_hw_scan(struct ieee80211_local *local, 280 struct ieee80211_sub_if_data *sdata, 281 struct ieee80211_scan_request *req) 282{ 283 int ret; 284 285 might_sleep(); 286 287 if (!check_sdata_in_driver(sdata)) 288 return -EIO; 289 290 trace_drv_hw_scan(local, sdata); 291 ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); 292 trace_drv_return_int(local, ret); 293 return ret; 294} 295 296static inline void drv_cancel_hw_scan(struct ieee80211_local *local, 297 struct ieee80211_sub_if_data *sdata) 298{ 299 might_sleep(); 300 301 if (!check_sdata_in_driver(sdata)) 302 return; 303 304 trace_drv_cancel_hw_scan(local, sdata); 305 local->ops->cancel_hw_scan(&local->hw, &sdata->vif); 306 trace_drv_return_void(local); 307} 308 309static inline int 310drv_sched_scan_start(struct ieee80211_local *local, 311 struct ieee80211_sub_if_data *sdata, 312 struct cfg80211_sched_scan_request *req, 313 struct ieee80211_scan_ies *ies) 314{ 315 int ret; 316 317 might_sleep(); 318 319 if (!check_sdata_in_driver(sdata)) 320 return -EIO; 321 322 trace_drv_sched_scan_start(local, sdata); 323 ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, 324 req, ies); 325 trace_drv_return_int(local, ret); 326 return ret; 327} 328 329static inline int drv_sched_scan_stop(struct ieee80211_local *local, 330 struct ieee80211_sub_if_data *sdata) 331{ 332 int ret; 333 334 might_sleep(); 335 336 if (!check_sdata_in_driver(sdata)) 337 return -EIO; 338 339 trace_drv_sched_scan_stop(local, sdata); 340 ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif); 341 trace_drv_return_int(local, ret); 342 343 return ret; 344} 345 346static inline void drv_sw_scan_start(struct ieee80211_local *local, 347 struct ieee80211_sub_if_data *sdata, 348 const u8 *mac_addr) 349{ 350 might_sleep(); 351 352 trace_drv_sw_scan_start(local, sdata, mac_addr); 353 if (local->ops->sw_scan_start) 354 local->ops->sw_scan_start(&local->hw, &sdata->vif, mac_addr); 355 trace_drv_return_void(local); 356} 357 358static inline void drv_sw_scan_complete(struct ieee80211_local *local, 359 struct ieee80211_sub_if_data *sdata) 360{ 361 might_sleep(); 362 363 trace_drv_sw_scan_complete(local, sdata); 364 if (local->ops->sw_scan_complete) 365 local->ops->sw_scan_complete(&local->hw, &sdata->vif); 366 trace_drv_return_void(local); 367} 368 369static inline int drv_get_stats(struct ieee80211_local *local, 370 struct ieee80211_low_level_stats *stats) 371{ 372 int ret = -EOPNOTSUPP; 373 374 might_sleep(); 375 376 if (local->ops->get_stats) 377 ret = local->ops->get_stats(&local->hw, stats); 378 trace_drv_get_stats(local, stats, ret); 379 380 return ret; 381} 382 383static inline void drv_get_key_seq(struct ieee80211_local *local, 384 struct ieee80211_key *key, 385 struct ieee80211_key_seq *seq) 386{ 387 if (local->ops->get_key_seq) 388 local->ops->get_key_seq(&local->hw, &key->conf, seq); 389 trace_drv_get_key_seq(local, &key->conf); 390} 391 392static inline int drv_set_frag_threshold(struct ieee80211_local *local, 393 u32 value) 394{ 395 int ret = 0; 396 397 might_sleep(); 398 399 trace_drv_set_frag_threshold(local, value); 400 if (local->ops->set_frag_threshold) 401 ret = local->ops->set_frag_threshold(&local->hw, value); 402 trace_drv_return_int(local, ret); 403 return ret; 404} 405 406static inline int drv_set_rts_threshold(struct ieee80211_local *local, 407 u32 value) 408{ 409 int ret = 0; 410 411 might_sleep(); 412 413 trace_drv_set_rts_threshold(local, value); 414 if (local->ops->set_rts_threshold) 415 ret = local->ops->set_rts_threshold(&local->hw, value); 416 trace_drv_return_int(local, ret); 417 return ret; 418} 419 420static inline int drv_set_coverage_class(struct ieee80211_local *local, 421 s16 value) 422{ 423 int ret = 0; 424 might_sleep(); 425 426 trace_drv_set_coverage_class(local, value); 427 if (local->ops->set_coverage_class) 428 local->ops->set_coverage_class(&local->hw, value); 429 else 430 ret = -EOPNOTSUPP; 431 432 trace_drv_return_int(local, ret); 433 return ret; 434} 435 436static inline void drv_sta_notify(struct ieee80211_local *local, 437 struct ieee80211_sub_if_data *sdata, 438 enum sta_notify_cmd cmd, 439 struct ieee80211_sta *sta) 440{ 441 sdata = get_bss_sdata(sdata); 442 if (!check_sdata_in_driver(sdata)) 443 return; 444 445 trace_drv_sta_notify(local, sdata, cmd, sta); 446 if (local->ops->sta_notify) 447 local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta); 448 trace_drv_return_void(local); 449} 450 451static inline int drv_sta_add(struct ieee80211_local *local, 452 struct ieee80211_sub_if_data *sdata, 453 struct ieee80211_sta *sta) 454{ 455 int ret = 0; 456 457 might_sleep(); 458 459 sdata = get_bss_sdata(sdata); 460 if (!check_sdata_in_driver(sdata)) 461 return -EIO; 462 463 trace_drv_sta_add(local, sdata, sta); 464 if (local->ops->sta_add) 465 ret = local->ops->sta_add(&local->hw, &sdata->vif, sta); 466 467 trace_drv_return_int(local, ret); 468 469 return ret; 470} 471 472static inline void drv_sta_remove(struct ieee80211_local *local, 473 struct ieee80211_sub_if_data *sdata, 474 struct ieee80211_sta *sta) 475{ 476 might_sleep(); 477 478 sdata = get_bss_sdata(sdata); 479 if (!check_sdata_in_driver(sdata)) 480 return; 481 482 trace_drv_sta_remove(local, sdata, sta); 483 if (local->ops->sta_remove) 484 local->ops->sta_remove(&local->hw, &sdata->vif, sta); 485 486 trace_drv_return_void(local); 487} 488 489#ifdef CONFIG_MAC80211_DEBUGFS 490static inline void drv_sta_add_debugfs(struct ieee80211_local *local, 491 struct ieee80211_sub_if_data *sdata, 492 struct ieee80211_sta *sta, 493 struct dentry *dir) 494{ 495 might_sleep(); 496 497 sdata = get_bss_sdata(sdata); 498 if (!check_sdata_in_driver(sdata)) 499 return; 500 501 if (local->ops->sta_add_debugfs) 502 local->ops->sta_add_debugfs(&local->hw, &sdata->vif, 503 sta, dir); 504} 505#endif 506 507static inline void drv_sta_pre_rcu_remove(struct ieee80211_local *local, 508 struct ieee80211_sub_if_data *sdata, 509 struct sta_info *sta) 510{ 511 might_sleep(); 512 513 sdata = get_bss_sdata(sdata); 514 if (!check_sdata_in_driver(sdata)) 515 return; 516 517 trace_drv_sta_pre_rcu_remove(local, sdata, &sta->sta); 518 if (local->ops->sta_pre_rcu_remove) 519 local->ops->sta_pre_rcu_remove(&local->hw, &sdata->vif, 520 &sta->sta); 521 trace_drv_return_void(local); 522} 523 524__must_check 525int drv_sta_state(struct ieee80211_local *local, 526 struct ieee80211_sub_if_data *sdata, 527 struct sta_info *sta, 528 enum ieee80211_sta_state old_state, 529 enum ieee80211_sta_state new_state); 530 531__must_check 532int drv_sta_set_txpwr(struct ieee80211_local *local, 533 struct ieee80211_sub_if_data *sdata, 534 struct sta_info *sta); 535 536void drv_sta_rc_update(struct ieee80211_local *local, 537 struct ieee80211_sub_if_data *sdata, 538 struct ieee80211_sta *sta, u32 changed); 539 540static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local, 541 struct ieee80211_sub_if_data *sdata, 542 struct ieee80211_sta *sta) 543{ 544 sdata = get_bss_sdata(sdata); 545 if (!check_sdata_in_driver(sdata)) 546 return; 547 548 trace_drv_sta_rate_tbl_update(local, sdata, sta); 549 if (local->ops->sta_rate_tbl_update) 550 local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta); 551 552 trace_drv_return_void(local); 553} 554 555static inline void drv_sta_statistics(struct ieee80211_local *local, 556 struct ieee80211_sub_if_data *sdata, 557 struct ieee80211_sta *sta, 558 struct station_info *sinfo) 559{ 560 sdata = get_bss_sdata(sdata); 561 if (!check_sdata_in_driver(sdata)) 562 return; 563 564 trace_drv_sta_statistics(local, sdata, sta); 565 if (local->ops->sta_statistics) 566 local->ops->sta_statistics(&local->hw, &sdata->vif, sta, sinfo); 567 trace_drv_return_void(local); 568} 569 570int drv_conf_tx(struct ieee80211_local *local, 571 struct ieee80211_sub_if_data *sdata, u16 ac, 572 const struct ieee80211_tx_queue_params *params); 573 574u64 drv_get_tsf(struct ieee80211_local *local, 575 struct ieee80211_sub_if_data *sdata); 576void drv_set_tsf(struct ieee80211_local *local, 577 struct ieee80211_sub_if_data *sdata, 578 u64 tsf); 579void drv_offset_tsf(struct ieee80211_local *local, 580 struct ieee80211_sub_if_data *sdata, 581 s64 offset); 582void drv_reset_tsf(struct ieee80211_local *local, 583 struct ieee80211_sub_if_data *sdata); 584 585static inline int drv_tx_last_beacon(struct ieee80211_local *local) 586{ 587 int ret = 0; /* default unsupported op for less congestion */ 588 589 might_sleep(); 590 591 trace_drv_tx_last_beacon(local); 592 if (local->ops->tx_last_beacon) 593 ret = local->ops->tx_last_beacon(&local->hw); 594 trace_drv_return_int(local, ret); 595 return ret; 596} 597 598int drv_ampdu_action(struct ieee80211_local *local, 599 struct ieee80211_sub_if_data *sdata, 600 struct ieee80211_ampdu_params *params); 601 602static inline int drv_get_survey(struct ieee80211_local *local, int idx, 603 struct survey_info *survey) 604{ 605 int ret = -EOPNOTSUPP; 606 607 trace_drv_get_survey(local, idx, survey); 608 609 if (local->ops->get_survey) 610 ret = local->ops->get_survey(&local->hw, idx, survey); 611 612 trace_drv_return_int(local, ret); 613 614 return ret; 615} 616 617static inline void drv_rfkill_poll(struct ieee80211_local *local) 618{ 619 might_sleep(); 620 621 if (local->ops->rfkill_poll) 622 local->ops->rfkill_poll(&local->hw); 623} 624 625static inline void drv_flush(struct ieee80211_local *local, 626 struct ieee80211_sub_if_data *sdata, 627 u32 queues, bool drop) 628{ 629 struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL; 630 631 might_sleep(); 632 633 if (sdata && !check_sdata_in_driver(sdata)) 634 return; 635 636 trace_drv_flush(local, queues, drop); 637 if (local->ops->flush) 638 local->ops->flush(&local->hw, vif, queues, drop); 639 trace_drv_return_void(local); 640} 641 642static inline void drv_channel_switch(struct ieee80211_local *local, 643 struct ieee80211_sub_if_data *sdata, 644 struct ieee80211_channel_switch *ch_switch) 645{ 646 might_sleep(); 647 648 trace_drv_channel_switch(local, sdata, ch_switch); 649 local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch); 650 trace_drv_return_void(local); 651} 652 653 654static inline int drv_set_antenna(struct ieee80211_local *local, 655 u32 tx_ant, u32 rx_ant) 656{ 657 int ret = -EOPNOTSUPP; 658 might_sleep(); 659 if (local->ops->set_antenna) 660 ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant); 661 trace_drv_set_antenna(local, tx_ant, rx_ant, ret); 662 return ret; 663} 664 665static inline int drv_get_antenna(struct ieee80211_local *local, 666 u32 *tx_ant, u32 *rx_ant) 667{ 668 int ret = -EOPNOTSUPP; 669 might_sleep(); 670 if (local->ops->get_antenna) 671 ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant); 672 trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret); 673 return ret; 674} 675 676static inline int drv_remain_on_channel(struct ieee80211_local *local, 677 struct ieee80211_sub_if_data *sdata, 678 struct ieee80211_channel *chan, 679 unsigned int duration, 680 enum ieee80211_roc_type type) 681{ 682 int ret; 683 684 might_sleep(); 685 686 trace_drv_remain_on_channel(local, sdata, chan, duration, type); 687 ret = local->ops->remain_on_channel(&local->hw, &sdata->vif, 688 chan, duration, type); 689 trace_drv_return_int(local, ret); 690 691 return ret; 692} 693 694static inline int 695drv_cancel_remain_on_channel(struct ieee80211_local *local, 696 struct ieee80211_sub_if_data *sdata) 697{ 698 int ret; 699 700 might_sleep(); 701 702 trace_drv_cancel_remain_on_channel(local, sdata); 703 ret = local->ops->cancel_remain_on_channel(&local->hw, &sdata->vif); 704 trace_drv_return_int(local, ret); 705 706 return ret; 707} 708 709static inline int drv_set_ringparam(struct ieee80211_local *local, 710 u32 tx, u32 rx) 711{ 712 int ret = -ENOTSUPP; 713 714 might_sleep(); 715 716 trace_drv_set_ringparam(local, tx, rx); 717 if (local->ops->set_ringparam) 718 ret = local->ops->set_ringparam(&local->hw, tx, rx); 719 trace_drv_return_int(local, ret); 720 721 return ret; 722} 723 724static inline void drv_get_ringparam(struct ieee80211_local *local, 725 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) 726{ 727 might_sleep(); 728 729 trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max); 730 if (local->ops->get_ringparam) 731 local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max); 732 trace_drv_return_void(local); 733} 734 735static inline bool drv_tx_frames_pending(struct ieee80211_local *local) 736{ 737 bool ret = false; 738 739 might_sleep(); 740 741 trace_drv_tx_frames_pending(local); 742 if (local->ops->tx_frames_pending) 743 ret = local->ops->tx_frames_pending(&local->hw); 744 trace_drv_return_bool(local, ret); 745 746 return ret; 747} 748 749static inline int drv_set_bitrate_mask(struct ieee80211_local *local, 750 struct ieee80211_sub_if_data *sdata, 751 const struct cfg80211_bitrate_mask *mask) 752{ 753 int ret = -EOPNOTSUPP; 754 755 might_sleep(); 756 757 if (!check_sdata_in_driver(sdata)) 758 return -EIO; 759 760 trace_drv_set_bitrate_mask(local, sdata, mask); 761 if (local->ops->set_bitrate_mask) 762 ret = local->ops->set_bitrate_mask(&local->hw, 763 &sdata->vif, mask); 764 trace_drv_return_int(local, ret); 765 766 return ret; 767} 768 769static inline void drv_set_rekey_data(struct ieee80211_local *local, 770 struct ieee80211_sub_if_data *sdata, 771 struct cfg80211_gtk_rekey_data *data) 772{ 773 if (!check_sdata_in_driver(sdata)) 774 return; 775 776 trace_drv_set_rekey_data(local, sdata, data); 777 if (local->ops->set_rekey_data) 778 local->ops->set_rekey_data(&local->hw, &sdata->vif, data); 779 trace_drv_return_void(local); 780} 781 782static inline void drv_event_callback(struct ieee80211_local *local, 783 struct ieee80211_sub_if_data *sdata, 784 const struct ieee80211_event *event) 785{ 786 trace_drv_event_callback(local, sdata, event); 787 if (local->ops->event_callback) 788 local->ops->event_callback(&local->hw, &sdata->vif, event); 789 trace_drv_return_void(local); 790} 791 792static inline void 793drv_release_buffered_frames(struct ieee80211_local *local, 794 struct sta_info *sta, u16 tids, int num_frames, 795 enum ieee80211_frame_release_type reason, 796 bool more_data) 797{ 798 trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames, 799 reason, more_data); 800 if (local->ops->release_buffered_frames) 801 local->ops->release_buffered_frames(&local->hw, &sta->sta, tids, 802 num_frames, reason, 803 more_data); 804 trace_drv_return_void(local); 805} 806 807static inline void 808drv_allow_buffered_frames(struct ieee80211_local *local, 809 struct sta_info *sta, u16 tids, int num_frames, 810 enum ieee80211_frame_release_type reason, 811 bool more_data) 812{ 813 trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames, 814 reason, more_data); 815 if (local->ops->allow_buffered_frames) 816 local->ops->allow_buffered_frames(&local->hw, &sta->sta, 817 tids, num_frames, reason, 818 more_data); 819 trace_drv_return_void(local); 820} 821 822static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, 823 struct ieee80211_sub_if_data *sdata, 824 u16 duration) 825{ 826 might_sleep(); 827 828 if (!check_sdata_in_driver(sdata)) 829 return; 830 WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); 831 832 trace_drv_mgd_prepare_tx(local, sdata, duration); 833 if (local->ops->mgd_prepare_tx) 834 local->ops->mgd_prepare_tx(&local->hw, &sdata->vif, duration); 835 trace_drv_return_void(local); 836} 837 838static inline void 839drv_mgd_protect_tdls_discover(struct ieee80211_local *local, 840 struct ieee80211_sub_if_data *sdata) 841{ 842 might_sleep(); 843 844 if (!check_sdata_in_driver(sdata)) 845 return; 846 WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); 847 848 trace_drv_mgd_protect_tdls_discover(local, sdata); 849 if (local->ops->mgd_protect_tdls_discover) 850 local->ops->mgd_protect_tdls_discover(&local->hw, &sdata->vif); 851 trace_drv_return_void(local); 852} 853 854static inline int drv_add_chanctx(struct ieee80211_local *local, 855 struct ieee80211_chanctx *ctx) 856{ 857 int ret = -EOPNOTSUPP; 858 859 might_sleep(); 860 861 trace_drv_add_chanctx(local, ctx); 862 if (local->ops->add_chanctx) 863 ret = local->ops->add_chanctx(&local->hw, &ctx->conf); 864 trace_drv_return_int(local, ret); 865 if (!ret) 866 ctx->driver_present = true; 867 868 return ret; 869} 870 871static inline void drv_remove_chanctx(struct ieee80211_local *local, 872 struct ieee80211_chanctx *ctx) 873{ 874 might_sleep(); 875 876 if (WARN_ON(!ctx->driver_present)) 877 return; 878 879 trace_drv_remove_chanctx(local, ctx); 880 if (local->ops->remove_chanctx) 881 local->ops->remove_chanctx(&local->hw, &ctx->conf); 882 trace_drv_return_void(local); 883 ctx->driver_present = false; 884} 885 886static inline void drv_change_chanctx(struct ieee80211_local *local, 887 struct ieee80211_chanctx *ctx, 888 u32 changed) 889{ 890 might_sleep(); 891 892 trace_drv_change_chanctx(local, ctx, changed); 893 if (local->ops->change_chanctx) { 894 WARN_ON_ONCE(!ctx->driver_present); 895 local->ops->change_chanctx(&local->hw, &ctx->conf, changed); 896 } 897 trace_drv_return_void(local); 898} 899 900static inline int drv_assign_vif_chanctx(struct ieee80211_local *local, 901 struct ieee80211_sub_if_data *sdata, 902 struct ieee80211_chanctx *ctx) 903{ 904 int ret = 0; 905 906 if (!check_sdata_in_driver(sdata)) 907 return -EIO; 908 909 trace_drv_assign_vif_chanctx(local, sdata, ctx); 910 if (local->ops->assign_vif_chanctx) { 911 WARN_ON_ONCE(!ctx->driver_present); 912 ret = local->ops->assign_vif_chanctx(&local->hw, 913 &sdata->vif, 914 &ctx->conf); 915 } 916 trace_drv_return_int(local, ret); 917 918 return ret; 919} 920 921static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local, 922 struct ieee80211_sub_if_data *sdata, 923 struct ieee80211_chanctx *ctx) 924{ 925 might_sleep(); 926 927 if (!check_sdata_in_driver(sdata)) 928 return; 929 930 trace_drv_unassign_vif_chanctx(local, sdata, ctx); 931 if (local->ops->unassign_vif_chanctx) { 932 WARN_ON_ONCE(!ctx->driver_present); 933 local->ops->unassign_vif_chanctx(&local->hw, 934 &sdata->vif, 935 &ctx->conf); 936 } 937 trace_drv_return_void(local); 938} 939 940int drv_switch_vif_chanctx(struct ieee80211_local *local, 941 struct ieee80211_vif_chanctx_switch *vifs, 942 int n_vifs, enum ieee80211_chanctx_switch_mode mode); 943 944static inline int drv_start_ap(struct ieee80211_local *local, 945 struct ieee80211_sub_if_data *sdata) 946{ 947 int ret = 0; 948 949 might_sleep(); 950 951 if (!check_sdata_in_driver(sdata)) 952 return -EIO; 953 954 trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf); 955 if (local->ops->start_ap) 956 ret = local->ops->start_ap(&local->hw, &sdata->vif); 957 trace_drv_return_int(local, ret); 958 return ret; 959} 960 961static inline void drv_stop_ap(struct ieee80211_local *local, 962 struct ieee80211_sub_if_data *sdata) 963{ 964 if (!check_sdata_in_driver(sdata)) 965 return; 966 967 trace_drv_stop_ap(local, sdata); 968 if (local->ops->stop_ap) 969 local->ops->stop_ap(&local->hw, &sdata->vif); 970 trace_drv_return_void(local); 971} 972 973static inline void 974drv_reconfig_complete(struct ieee80211_local *local, 975 enum ieee80211_reconfig_type reconfig_type) 976{ 977 might_sleep(); 978 979 trace_drv_reconfig_complete(local, reconfig_type); 980 if (local->ops->reconfig_complete) 981 local->ops->reconfig_complete(&local->hw, reconfig_type); 982 trace_drv_return_void(local); 983} 984 985static inline void 986drv_set_default_unicast_key(struct ieee80211_local *local, 987 struct ieee80211_sub_if_data *sdata, 988 int key_idx) 989{ 990 if (!check_sdata_in_driver(sdata)) 991 return; 992 993 WARN_ON_ONCE(key_idx < -1 || key_idx > 3); 994 995 trace_drv_set_default_unicast_key(local, sdata, key_idx); 996 if (local->ops->set_default_unicast_key) 997 local->ops->set_default_unicast_key(&local->hw, &sdata->vif, 998 key_idx); 999 trace_drv_return_void(local); 1000} 1001 1002#if IS_ENABLED(CONFIG_IPV6) 1003static inline void drv_ipv6_addr_change(struct ieee80211_local *local, 1004 struct ieee80211_sub_if_data *sdata, 1005 struct inet6_dev *idev) 1006{ 1007 trace_drv_ipv6_addr_change(local, sdata); 1008 if (local->ops->ipv6_addr_change) 1009 local->ops->ipv6_addr_change(&local->hw, &sdata->vif, idev); 1010 trace_drv_return_void(local); 1011} 1012#endif 1013 1014static inline void 1015drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata, 1016 struct cfg80211_chan_def *chandef) 1017{ 1018 struct ieee80211_local *local = sdata->local; 1019 1020 if (local->ops->channel_switch_beacon) { 1021 trace_drv_channel_switch_beacon(local, sdata, chandef); 1022 local->ops->channel_switch_beacon(&local->hw, &sdata->vif, 1023 chandef); 1024 } 1025} 1026 1027static inline int 1028drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata, 1029 struct ieee80211_channel_switch *ch_switch) 1030{ 1031 struct ieee80211_local *local = sdata->local; 1032 int ret = 0; 1033 1034 if (!check_sdata_in_driver(sdata)) 1035 return -EIO; 1036 1037 trace_drv_pre_channel_switch(local, sdata, ch_switch); 1038 if (local->ops->pre_channel_switch) 1039 ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif, 1040 ch_switch); 1041 trace_drv_return_int(local, ret); 1042 return ret; 1043} 1044 1045static inline int 1046drv_post_channel_switch(struct ieee80211_sub_if_data *sdata) 1047{ 1048 struct ieee80211_local *local = sdata->local; 1049 int ret = 0; 1050 1051 if (!check_sdata_in_driver(sdata)) 1052 return -EIO; 1053 1054 trace_drv_post_channel_switch(local, sdata); 1055 if (local->ops->post_channel_switch) 1056 ret = local->ops->post_channel_switch(&local->hw, &sdata->vif); 1057 trace_drv_return_int(local, ret); 1058 return ret; 1059} 1060 1061static inline void 1062drv_abort_channel_switch(struct ieee80211_sub_if_data *sdata) 1063{ 1064 struct ieee80211_local *local = sdata->local; 1065 1066 if (!check_sdata_in_driver(sdata)) 1067 return; 1068 1069 trace_drv_abort_channel_switch(local, sdata); 1070 1071 if (local->ops->abort_channel_switch) 1072 local->ops->abort_channel_switch(&local->hw, &sdata->vif); 1073} 1074 1075static inline void 1076drv_channel_switch_rx_beacon(struct ieee80211_sub_if_data *sdata, 1077 struct ieee80211_channel_switch *ch_switch) 1078{ 1079 struct ieee80211_local *local = sdata->local; 1080 1081 if (!check_sdata_in_driver(sdata)) 1082 return; 1083 1084 trace_drv_channel_switch_rx_beacon(local, sdata, ch_switch); 1085 if (local->ops->channel_switch_rx_beacon) 1086 local->ops->channel_switch_rx_beacon(&local->hw, &sdata->vif, 1087 ch_switch); 1088} 1089 1090static inline int drv_join_ibss(struct ieee80211_local *local, 1091 struct ieee80211_sub_if_data *sdata) 1092{ 1093 int ret = 0; 1094 1095 might_sleep(); 1096 if (!check_sdata_in_driver(sdata)) 1097 return -EIO; 1098 1099 trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf); 1100 if (local->ops->join_ibss) 1101 ret = local->ops->join_ibss(&local->hw, &sdata->vif); 1102 trace_drv_return_int(local, ret); 1103 return ret; 1104} 1105 1106static inline void drv_leave_ibss(struct ieee80211_local *local, 1107 struct ieee80211_sub_if_data *sdata) 1108{ 1109 might_sleep(); 1110 if (!check_sdata_in_driver(sdata)) 1111 return; 1112 1113 trace_drv_leave_ibss(local, sdata); 1114 if (local->ops->leave_ibss) 1115 local->ops->leave_ibss(&local->hw, &sdata->vif); 1116 trace_drv_return_void(local); 1117} 1118 1119static inline u32 drv_get_expected_throughput(struct ieee80211_local *local, 1120 struct sta_info *sta) 1121{ 1122 u32 ret = 0; 1123 1124 trace_drv_get_expected_throughput(&sta->sta); 1125 if (local->ops->get_expected_throughput && sta->uploaded) 1126 ret = local->ops->get_expected_throughput(&local->hw, &sta->sta); 1127 trace_drv_return_u32(local, ret); 1128 1129 return ret; 1130} 1131 1132static inline int drv_get_txpower(struct ieee80211_local *local, 1133 struct ieee80211_sub_if_data *sdata, int *dbm) 1134{ 1135 int ret; 1136 1137 if (!local->ops->get_txpower) 1138 return -EOPNOTSUPP; 1139 1140 ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm); 1141 trace_drv_get_txpower(local, sdata, *dbm, ret); 1142 1143 return ret; 1144} 1145 1146static inline int 1147drv_tdls_channel_switch(struct ieee80211_local *local, 1148 struct ieee80211_sub_if_data *sdata, 1149 struct ieee80211_sta *sta, u8 oper_class, 1150 struct cfg80211_chan_def *chandef, 1151 struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie) 1152{ 1153 int ret; 1154 1155 might_sleep(); 1156 if (!check_sdata_in_driver(sdata)) 1157 return -EIO; 1158 1159 if (!local->ops->tdls_channel_switch) 1160 return -EOPNOTSUPP; 1161 1162 trace_drv_tdls_channel_switch(local, sdata, sta, oper_class, chandef); 1163 ret = local->ops->tdls_channel_switch(&local->hw, &sdata->vif, sta, 1164 oper_class, chandef, tmpl_skb, 1165 ch_sw_tm_ie); 1166 trace_drv_return_int(local, ret); 1167 return ret; 1168} 1169 1170static inline void 1171drv_tdls_cancel_channel_switch(struct ieee80211_local *local, 1172 struct ieee80211_sub_if_data *sdata, 1173 struct ieee80211_sta *sta) 1174{ 1175 might_sleep(); 1176 if (!check_sdata_in_driver(sdata)) 1177 return; 1178 1179 if (!local->ops->tdls_cancel_channel_switch) 1180 return; 1181 1182 trace_drv_tdls_cancel_channel_switch(local, sdata, sta); 1183 local->ops->tdls_cancel_channel_switch(&local->hw, &sdata->vif, sta); 1184 trace_drv_return_void(local); 1185} 1186 1187static inline void 1188drv_tdls_recv_channel_switch(struct ieee80211_local *local, 1189 struct ieee80211_sub_if_data *sdata, 1190 struct ieee80211_tdls_ch_sw_params *params) 1191{ 1192 trace_drv_tdls_recv_channel_switch(local, sdata, params); 1193 if (local->ops->tdls_recv_channel_switch) 1194 local->ops->tdls_recv_channel_switch(&local->hw, &sdata->vif, 1195 params); 1196 trace_drv_return_void(local); 1197} 1198 1199static inline void drv_wake_tx_queue(struct ieee80211_local *local, 1200 struct txq_info *txq) 1201{ 1202 struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif); 1203 1204 /* In reconfig don't transmit now, but mark for waking later */ 1205 if (local->in_reconfig) { 1206 set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txq->flags); 1207 return; 1208 } 1209 1210 if (!check_sdata_in_driver(sdata)) 1211 return; 1212 1213 trace_drv_wake_tx_queue(local, sdata, txq); 1214 local->ops->wake_tx_queue(&local->hw, &txq->txq); 1215} 1216 1217static inline void schedule_and_wake_txq(struct ieee80211_local *local, 1218 struct txq_info *txqi) 1219{ 1220 ieee80211_schedule_txq(&local->hw, &txqi->txq); 1221 drv_wake_tx_queue(local, txqi); 1222} 1223 1224static inline int drv_can_aggregate_in_amsdu(struct ieee80211_local *local, 1225 struct sk_buff *head, 1226 struct sk_buff *skb) 1227{ 1228 if (!local->ops->can_aggregate_in_amsdu) 1229 return true; 1230 1231 return local->ops->can_aggregate_in_amsdu(&local->hw, head, skb); 1232} 1233 1234static inline int 1235drv_get_ftm_responder_stats(struct ieee80211_local *local, 1236 struct ieee80211_sub_if_data *sdata, 1237 struct cfg80211_ftm_responder_stats *ftm_stats) 1238{ 1239 u32 ret = -EOPNOTSUPP; 1240 1241 if (local->ops->get_ftm_responder_stats) 1242 ret = local->ops->get_ftm_responder_stats(&local->hw, 1243 &sdata->vif, 1244 ftm_stats); 1245 trace_drv_get_ftm_responder_stats(local, sdata, ftm_stats); 1246 1247 return ret; 1248} 1249 1250static inline int drv_start_pmsr(struct ieee80211_local *local, 1251 struct ieee80211_sub_if_data *sdata, 1252 struct cfg80211_pmsr_request *request) 1253{ 1254 int ret = -EOPNOTSUPP; 1255 1256 might_sleep(); 1257 if (!check_sdata_in_driver(sdata)) 1258 return -EIO; 1259 1260 trace_drv_start_pmsr(local, sdata); 1261 1262 if (local->ops->start_pmsr) 1263 ret = local->ops->start_pmsr(&local->hw, &sdata->vif, request); 1264 trace_drv_return_int(local, ret); 1265 1266 return ret; 1267} 1268 1269static inline void drv_abort_pmsr(struct ieee80211_local *local, 1270 struct ieee80211_sub_if_data *sdata, 1271 struct cfg80211_pmsr_request *request) 1272{ 1273 trace_drv_abort_pmsr(local, sdata); 1274 1275 might_sleep(); 1276 if (!check_sdata_in_driver(sdata)) 1277 return; 1278 1279 if (local->ops->abort_pmsr) 1280 local->ops->abort_pmsr(&local->hw, &sdata->vif, request); 1281 trace_drv_return_void(local); 1282} 1283 1284static inline int drv_start_nan(struct ieee80211_local *local, 1285 struct ieee80211_sub_if_data *sdata, 1286 struct cfg80211_nan_conf *conf) 1287{ 1288 int ret; 1289 1290 might_sleep(); 1291 check_sdata_in_driver(sdata); 1292 1293 trace_drv_start_nan(local, sdata, conf); 1294 ret = local->ops->start_nan(&local->hw, &sdata->vif, conf); 1295 trace_drv_return_int(local, ret); 1296 return ret; 1297} 1298 1299static inline void drv_stop_nan(struct ieee80211_local *local, 1300 struct ieee80211_sub_if_data *sdata) 1301{ 1302 might_sleep(); 1303 check_sdata_in_driver(sdata); 1304 1305 trace_drv_stop_nan(local, sdata); 1306 local->ops->stop_nan(&local->hw, &sdata->vif); 1307 trace_drv_return_void(local); 1308} 1309 1310static inline int drv_nan_change_conf(struct ieee80211_local *local, 1311 struct ieee80211_sub_if_data *sdata, 1312 struct cfg80211_nan_conf *conf, 1313 u32 changes) 1314{ 1315 int ret; 1316 1317 might_sleep(); 1318 check_sdata_in_driver(sdata); 1319 1320 if (!local->ops->nan_change_conf) 1321 return -EOPNOTSUPP; 1322 1323 trace_drv_nan_change_conf(local, sdata, conf, changes); 1324 ret = local->ops->nan_change_conf(&local->hw, &sdata->vif, conf, 1325 changes); 1326 trace_drv_return_int(local, ret); 1327 1328 return ret; 1329} 1330 1331static inline int drv_add_nan_func(struct ieee80211_local *local, 1332 struct ieee80211_sub_if_data *sdata, 1333 const struct cfg80211_nan_func *nan_func) 1334{ 1335 int ret; 1336 1337 might_sleep(); 1338 check_sdata_in_driver(sdata); 1339 1340 if (!local->ops->add_nan_func) 1341 return -EOPNOTSUPP; 1342 1343 trace_drv_add_nan_func(local, sdata, nan_func); 1344 ret = local->ops->add_nan_func(&local->hw, &sdata->vif, nan_func); 1345 trace_drv_return_int(local, ret); 1346 1347 return ret; 1348} 1349 1350static inline void drv_del_nan_func(struct ieee80211_local *local, 1351 struct ieee80211_sub_if_data *sdata, 1352 u8 instance_id) 1353{ 1354 might_sleep(); 1355 check_sdata_in_driver(sdata); 1356 1357 trace_drv_del_nan_func(local, sdata, instance_id); 1358 if (local->ops->del_nan_func) 1359 local->ops->del_nan_func(&local->hw, &sdata->vif, instance_id); 1360 trace_drv_return_void(local); 1361} 1362 1363static inline int drv_set_tid_config(struct ieee80211_local *local, 1364 struct ieee80211_sub_if_data *sdata, 1365 struct ieee80211_sta *sta, 1366 struct cfg80211_tid_config *tid_conf) 1367{ 1368 int ret; 1369 1370 might_sleep(); 1371 ret = local->ops->set_tid_config(&local->hw, &sdata->vif, sta, 1372 tid_conf); 1373 trace_drv_return_int(local, ret); 1374 1375 return ret; 1376} 1377 1378static inline int drv_reset_tid_config(struct ieee80211_local *local, 1379 struct ieee80211_sub_if_data *sdata, 1380 struct ieee80211_sta *sta, u8 tids) 1381{ 1382 int ret; 1383 1384 might_sleep(); 1385 ret = local->ops->reset_tid_config(&local->hw, &sdata->vif, sta, tids); 1386 trace_drv_return_int(local, ret); 1387 1388 return ret; 1389} 1390 1391static inline void drv_update_vif_offload(struct ieee80211_local *local, 1392 struct ieee80211_sub_if_data *sdata) 1393{ 1394 might_sleep(); 1395 check_sdata_in_driver(sdata); 1396 1397 if (!local->ops->update_vif_offload) 1398 return; 1399 1400 trace_drv_update_vif_offload(local, sdata); 1401 local->ops->update_vif_offload(&local->hw, &sdata->vif); 1402 trace_drv_return_void(local); 1403} 1404 1405static inline void drv_sta_set_4addr(struct ieee80211_local *local, 1406 struct ieee80211_sub_if_data *sdata, 1407 struct ieee80211_sta *sta, bool enabled) 1408{ 1409 sdata = get_bss_sdata(sdata); 1410 if (!check_sdata_in_driver(sdata)) 1411 return; 1412 1413 trace_drv_sta_set_4addr(local, sdata, sta, enabled); 1414 if (local->ops->sta_set_4addr) 1415 local->ops->sta_set_4addr(&local->hw, &sdata->vif, sta, enabled); 1416 trace_drv_return_void(local); 1417} 1418 1419#endif /* __MAC80211_DRIVER_OPS */ 1420