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