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