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