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 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
 532void drv_sta_rc_update(struct ieee80211_local *local,
 533                       struct ieee80211_sub_if_data *sdata,
 534                       struct ieee80211_sta *sta, u32 changed);
 535
 536static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local,
 537                                           struct ieee80211_sub_if_data *sdata,
 538                                           struct ieee80211_sta *sta)
 539{
 540        sdata = get_bss_sdata(sdata);
 541        if (!check_sdata_in_driver(sdata))
 542                return;
 543
 544        trace_drv_sta_rate_tbl_update(local, sdata, sta);
 545        if (local->ops->sta_rate_tbl_update)
 546                local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta);
 547
 548        trace_drv_return_void(local);
 549}
 550
 551static inline void drv_sta_statistics(struct ieee80211_local *local,
 552                                      struct ieee80211_sub_if_data *sdata,
 553                                      struct ieee80211_sta *sta,
 554                                      struct station_info *sinfo)
 555{
 556        sdata = get_bss_sdata(sdata);
 557        if (!check_sdata_in_driver(sdata))
 558                return;
 559
 560        trace_drv_sta_statistics(local, sdata, sta);
 561        if (local->ops->sta_statistics)
 562                local->ops->sta_statistics(&local->hw, &sdata->vif, sta, sinfo);
 563        trace_drv_return_void(local);
 564}
 565
 566int drv_conf_tx(struct ieee80211_local *local,
 567                struct ieee80211_sub_if_data *sdata, u16 ac,
 568                const struct ieee80211_tx_queue_params *params);
 569
 570u64 drv_get_tsf(struct ieee80211_local *local,
 571                struct ieee80211_sub_if_data *sdata);
 572void drv_set_tsf(struct ieee80211_local *local,
 573                 struct ieee80211_sub_if_data *sdata,
 574                 u64 tsf);
 575void drv_offset_tsf(struct ieee80211_local *local,
 576                    struct ieee80211_sub_if_data *sdata,
 577                    s64 offset);
 578void drv_reset_tsf(struct ieee80211_local *local,
 579                   struct ieee80211_sub_if_data *sdata);
 580
 581static inline int drv_tx_last_beacon(struct ieee80211_local *local)
 582{
 583        int ret = 0; /* default unsupported op for less congestion */
 584
 585        might_sleep();
 586
 587        trace_drv_tx_last_beacon(local);
 588        if (local->ops->tx_last_beacon)
 589                ret = local->ops->tx_last_beacon(&local->hw);
 590        trace_drv_return_int(local, ret);
 591        return ret;
 592}
 593
 594int drv_ampdu_action(struct ieee80211_local *local,
 595                     struct ieee80211_sub_if_data *sdata,
 596                     struct ieee80211_ampdu_params *params);
 597
 598static inline int drv_get_survey(struct ieee80211_local *local, int idx,
 599                                struct survey_info *survey)
 600{
 601        int ret = -EOPNOTSUPP;
 602
 603        trace_drv_get_survey(local, idx, survey);
 604
 605        if (local->ops->get_survey)
 606                ret = local->ops->get_survey(&local->hw, idx, survey);
 607
 608        trace_drv_return_int(local, ret);
 609
 610        return ret;
 611}
 612
 613static inline void drv_rfkill_poll(struct ieee80211_local *local)
 614{
 615        might_sleep();
 616
 617        if (local->ops->rfkill_poll)
 618                local->ops->rfkill_poll(&local->hw);
 619}
 620
 621static inline void drv_flush(struct ieee80211_local *local,
 622                             struct ieee80211_sub_if_data *sdata,
 623                             u32 queues, bool drop)
 624{
 625        struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL;
 626
 627        might_sleep();
 628
 629        if (sdata && !check_sdata_in_driver(sdata))
 630                return;
 631
 632        trace_drv_flush(local, queues, drop);
 633        if (local->ops->flush)
 634                local->ops->flush(&local->hw, vif, queues, drop);
 635        trace_drv_return_void(local);
 636}
 637
 638static inline void drv_channel_switch(struct ieee80211_local *local,
 639                                      struct ieee80211_sub_if_data *sdata,
 640                                      struct ieee80211_channel_switch *ch_switch)
 641{
 642        might_sleep();
 643
 644        trace_drv_channel_switch(local, sdata, ch_switch);
 645        local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch);
 646        trace_drv_return_void(local);
 647}
 648
 649
 650static inline int drv_set_antenna(struct ieee80211_local *local,
 651                                  u32 tx_ant, u32 rx_ant)
 652{
 653        int ret = -EOPNOTSUPP;
 654        might_sleep();
 655        if (local->ops->set_antenna)
 656                ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
 657        trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
 658        return ret;
 659}
 660
 661static inline int drv_get_antenna(struct ieee80211_local *local,
 662                                  u32 *tx_ant, u32 *rx_ant)
 663{
 664        int ret = -EOPNOTSUPP;
 665        might_sleep();
 666        if (local->ops->get_antenna)
 667                ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
 668        trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
 669        return ret;
 670}
 671
 672static inline int drv_remain_on_channel(struct ieee80211_local *local,
 673                                        struct ieee80211_sub_if_data *sdata,
 674                                        struct ieee80211_channel *chan,
 675                                        unsigned int duration,
 676                                        enum ieee80211_roc_type type)
 677{
 678        int ret;
 679
 680        might_sleep();
 681
 682        trace_drv_remain_on_channel(local, sdata, chan, duration, type);
 683        ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
 684                                            chan, duration, type);
 685        trace_drv_return_int(local, ret);
 686
 687        return ret;
 688}
 689
 690static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local)
 691{
 692        int ret;
 693
 694        might_sleep();
 695
 696        trace_drv_cancel_remain_on_channel(local);
 697        ret = local->ops->cancel_remain_on_channel(&local->hw);
 698        trace_drv_return_int(local, ret);
 699
 700        return ret;
 701}
 702
 703static inline int drv_set_ringparam(struct ieee80211_local *local,
 704                                    u32 tx, u32 rx)
 705{
 706        int ret = -ENOTSUPP;
 707
 708        might_sleep();
 709
 710        trace_drv_set_ringparam(local, tx, rx);
 711        if (local->ops->set_ringparam)
 712                ret = local->ops->set_ringparam(&local->hw, tx, rx);
 713        trace_drv_return_int(local, ret);
 714
 715        return ret;
 716}
 717
 718static inline void drv_get_ringparam(struct ieee80211_local *local,
 719                                     u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
 720{
 721        might_sleep();
 722
 723        trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
 724        if (local->ops->get_ringparam)
 725                local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
 726        trace_drv_return_void(local);
 727}
 728
 729static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
 730{
 731        bool ret = false;
 732
 733        might_sleep();
 734
 735        trace_drv_tx_frames_pending(local);
 736        if (local->ops->tx_frames_pending)
 737                ret = local->ops->tx_frames_pending(&local->hw);
 738        trace_drv_return_bool(local, ret);
 739
 740        return ret;
 741}
 742
 743static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
 744                                       struct ieee80211_sub_if_data *sdata,
 745                                       const struct cfg80211_bitrate_mask *mask)
 746{
 747        int ret = -EOPNOTSUPP;
 748
 749        might_sleep();
 750
 751        if (!check_sdata_in_driver(sdata))
 752                return -EIO;
 753
 754        trace_drv_set_bitrate_mask(local, sdata, mask);
 755        if (local->ops->set_bitrate_mask)
 756                ret = local->ops->set_bitrate_mask(&local->hw,
 757                                                   &sdata->vif, mask);
 758        trace_drv_return_int(local, ret);
 759
 760        return ret;
 761}
 762
 763static inline void drv_set_rekey_data(struct ieee80211_local *local,
 764                                      struct ieee80211_sub_if_data *sdata,
 765                                      struct cfg80211_gtk_rekey_data *data)
 766{
 767        if (!check_sdata_in_driver(sdata))
 768                return;
 769
 770        trace_drv_set_rekey_data(local, sdata, data);
 771        if (local->ops->set_rekey_data)
 772                local->ops->set_rekey_data(&local->hw, &sdata->vif, data);
 773        trace_drv_return_void(local);
 774}
 775
 776static inline void drv_event_callback(struct ieee80211_local *local,
 777                                      struct ieee80211_sub_if_data *sdata,
 778                                      const struct ieee80211_event *event)
 779{
 780        trace_drv_event_callback(local, sdata, event);
 781        if (local->ops->event_callback)
 782                local->ops->event_callback(&local->hw, &sdata->vif, event);
 783        trace_drv_return_void(local);
 784}
 785
 786static inline void
 787drv_release_buffered_frames(struct ieee80211_local *local,
 788                            struct sta_info *sta, u16 tids, int num_frames,
 789                            enum ieee80211_frame_release_type reason,
 790                            bool more_data)
 791{
 792        trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
 793                                          reason, more_data);
 794        if (local->ops->release_buffered_frames)
 795                local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
 796                                                    num_frames, reason,
 797                                                    more_data);
 798        trace_drv_return_void(local);
 799}
 800
 801static inline void
 802drv_allow_buffered_frames(struct ieee80211_local *local,
 803                          struct sta_info *sta, u16 tids, int num_frames,
 804                          enum ieee80211_frame_release_type reason,
 805                          bool more_data)
 806{
 807        trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
 808                                        reason, more_data);
 809        if (local->ops->allow_buffered_frames)
 810                local->ops->allow_buffered_frames(&local->hw, &sta->sta,
 811                                                  tids, num_frames, reason,
 812                                                  more_data);
 813        trace_drv_return_void(local);
 814}
 815
 816static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
 817                                      struct ieee80211_sub_if_data *sdata,
 818                                      u16 duration)
 819{
 820        might_sleep();
 821
 822        if (!check_sdata_in_driver(sdata))
 823                return;
 824        WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
 825
 826        trace_drv_mgd_prepare_tx(local, sdata, duration);
 827        if (local->ops->mgd_prepare_tx)
 828                local->ops->mgd_prepare_tx(&local->hw, &sdata->vif, duration);
 829        trace_drv_return_void(local);
 830}
 831
 832static inline void
 833drv_mgd_protect_tdls_discover(struct ieee80211_local *local,
 834                              struct ieee80211_sub_if_data *sdata)
 835{
 836        might_sleep();
 837
 838        if (!check_sdata_in_driver(sdata))
 839                return;
 840        WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
 841
 842        trace_drv_mgd_protect_tdls_discover(local, sdata);
 843        if (local->ops->mgd_protect_tdls_discover)
 844                local->ops->mgd_protect_tdls_discover(&local->hw, &sdata->vif);
 845        trace_drv_return_void(local);
 846}
 847
 848static inline int drv_add_chanctx(struct ieee80211_local *local,
 849                                  struct ieee80211_chanctx *ctx)
 850{
 851        int ret = -EOPNOTSUPP;
 852
 853        might_sleep();
 854
 855        trace_drv_add_chanctx(local, ctx);
 856        if (local->ops->add_chanctx)
 857                ret = local->ops->add_chanctx(&local->hw, &ctx->conf);
 858        trace_drv_return_int(local, ret);
 859        if (!ret)
 860                ctx->driver_present = true;
 861
 862        return ret;
 863}
 864
 865static inline void drv_remove_chanctx(struct ieee80211_local *local,
 866                                      struct ieee80211_chanctx *ctx)
 867{
 868        might_sleep();
 869
 870        if (WARN_ON(!ctx->driver_present))
 871                return;
 872
 873        trace_drv_remove_chanctx(local, ctx);
 874        if (local->ops->remove_chanctx)
 875                local->ops->remove_chanctx(&local->hw, &ctx->conf);
 876        trace_drv_return_void(local);
 877        ctx->driver_present = false;
 878}
 879
 880static inline void drv_change_chanctx(struct ieee80211_local *local,
 881                                      struct ieee80211_chanctx *ctx,
 882                                      u32 changed)
 883{
 884        might_sleep();
 885
 886        trace_drv_change_chanctx(local, ctx, changed);
 887        if (local->ops->change_chanctx) {
 888                WARN_ON_ONCE(!ctx->driver_present);
 889                local->ops->change_chanctx(&local->hw, &ctx->conf, changed);
 890        }
 891        trace_drv_return_void(local);
 892}
 893
 894static inline int drv_assign_vif_chanctx(struct ieee80211_local *local,
 895                                         struct ieee80211_sub_if_data *sdata,
 896                                         struct ieee80211_chanctx *ctx)
 897{
 898        int ret = 0;
 899
 900        if (!check_sdata_in_driver(sdata))
 901                return -EIO;
 902
 903        trace_drv_assign_vif_chanctx(local, sdata, ctx);
 904        if (local->ops->assign_vif_chanctx) {
 905                WARN_ON_ONCE(!ctx->driver_present);
 906                ret = local->ops->assign_vif_chanctx(&local->hw,
 907                                                     &sdata->vif,
 908                                                     &ctx->conf);
 909        }
 910        trace_drv_return_int(local, ret);
 911
 912        return ret;
 913}
 914
 915static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
 916                                            struct ieee80211_sub_if_data *sdata,
 917                                            struct ieee80211_chanctx *ctx)
 918{
 919        might_sleep();
 920
 921        if (!check_sdata_in_driver(sdata))
 922                return;
 923
 924        trace_drv_unassign_vif_chanctx(local, sdata, ctx);
 925        if (local->ops->unassign_vif_chanctx) {
 926                WARN_ON_ONCE(!ctx->driver_present);
 927                local->ops->unassign_vif_chanctx(&local->hw,
 928                                                 &sdata->vif,
 929                                                 &ctx->conf);
 930        }
 931        trace_drv_return_void(local);
 932}
 933
 934int drv_switch_vif_chanctx(struct ieee80211_local *local,
 935                           struct ieee80211_vif_chanctx_switch *vifs,
 936                           int n_vifs, enum ieee80211_chanctx_switch_mode mode);
 937
 938static inline int drv_start_ap(struct ieee80211_local *local,
 939                               struct ieee80211_sub_if_data *sdata)
 940{
 941        int ret = 0;
 942
 943        might_sleep();
 944
 945        if (!check_sdata_in_driver(sdata))
 946                return -EIO;
 947
 948        trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf);
 949        if (local->ops->start_ap)
 950                ret = local->ops->start_ap(&local->hw, &sdata->vif);
 951        trace_drv_return_int(local, ret);
 952        return ret;
 953}
 954
 955static inline void drv_stop_ap(struct ieee80211_local *local,
 956                               struct ieee80211_sub_if_data *sdata)
 957{
 958        if (!check_sdata_in_driver(sdata))
 959                return;
 960
 961        trace_drv_stop_ap(local, sdata);
 962        if (local->ops->stop_ap)
 963                local->ops->stop_ap(&local->hw, &sdata->vif);
 964        trace_drv_return_void(local);
 965}
 966
 967static inline void
 968drv_reconfig_complete(struct ieee80211_local *local,
 969                      enum ieee80211_reconfig_type reconfig_type)
 970{
 971        might_sleep();
 972
 973        trace_drv_reconfig_complete(local, reconfig_type);
 974        if (local->ops->reconfig_complete)
 975                local->ops->reconfig_complete(&local->hw, reconfig_type);
 976        trace_drv_return_void(local);
 977}
 978
 979static inline void
 980drv_set_default_unicast_key(struct ieee80211_local *local,
 981                            struct ieee80211_sub_if_data *sdata,
 982                            int key_idx)
 983{
 984        if (!check_sdata_in_driver(sdata))
 985                return;
 986
 987        WARN_ON_ONCE(key_idx < -1 || key_idx > 3);
 988
 989        trace_drv_set_default_unicast_key(local, sdata, key_idx);
 990        if (local->ops->set_default_unicast_key)
 991                local->ops->set_default_unicast_key(&local->hw, &sdata->vif,
 992                                                    key_idx);
 993        trace_drv_return_void(local);
 994}
 995
 996#if IS_ENABLED(CONFIG_IPV6)
 997static inline void drv_ipv6_addr_change(struct ieee80211_local *local,
 998                                        struct ieee80211_sub_if_data *sdata,
 999                                        struct inet6_dev *idev)
1000{
1001        trace_drv_ipv6_addr_change(local, sdata);
1002        if (local->ops->ipv6_addr_change)
1003                local->ops->ipv6_addr_change(&local->hw, &sdata->vif, idev);
1004        trace_drv_return_void(local);
1005}
1006#endif
1007
1008static inline void
1009drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata,
1010                          struct cfg80211_chan_def *chandef)
1011{
1012        struct ieee80211_local *local = sdata->local;
1013
1014        if (local->ops->channel_switch_beacon) {
1015                trace_drv_channel_switch_beacon(local, sdata, chandef);
1016                local->ops->channel_switch_beacon(&local->hw, &sdata->vif,
1017                                                  chandef);
1018        }
1019}
1020
1021static inline int
1022drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata,
1023                       struct ieee80211_channel_switch *ch_switch)
1024{
1025        struct ieee80211_local *local = sdata->local;
1026        int ret = 0;
1027
1028        if (!check_sdata_in_driver(sdata))
1029                return -EIO;
1030
1031        trace_drv_pre_channel_switch(local, sdata, ch_switch);
1032        if (local->ops->pre_channel_switch)
1033                ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif,
1034                                                     ch_switch);
1035        trace_drv_return_int(local, ret);
1036        return ret;
1037}
1038
1039static inline int
1040drv_post_channel_switch(struct ieee80211_sub_if_data *sdata)
1041{
1042        struct ieee80211_local *local = sdata->local;
1043        int ret = 0;
1044
1045        if (!check_sdata_in_driver(sdata))
1046                return -EIO;
1047
1048        trace_drv_post_channel_switch(local, sdata);
1049        if (local->ops->post_channel_switch)
1050                ret = local->ops->post_channel_switch(&local->hw, &sdata->vif);
1051        trace_drv_return_int(local, ret);
1052        return ret;
1053}
1054
1055static inline int drv_join_ibss(struct ieee80211_local *local,
1056                                struct ieee80211_sub_if_data *sdata)
1057{
1058        int ret = 0;
1059
1060        might_sleep();
1061        if (!check_sdata_in_driver(sdata))
1062                return -EIO;
1063
1064        trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf);
1065        if (local->ops->join_ibss)
1066                ret = local->ops->join_ibss(&local->hw, &sdata->vif);
1067        trace_drv_return_int(local, ret);
1068        return ret;
1069}
1070
1071static inline void drv_leave_ibss(struct ieee80211_local *local,
1072                                  struct ieee80211_sub_if_data *sdata)
1073{
1074        might_sleep();
1075        if (!check_sdata_in_driver(sdata))
1076                return;
1077
1078        trace_drv_leave_ibss(local, sdata);
1079        if (local->ops->leave_ibss)
1080                local->ops->leave_ibss(&local->hw, &sdata->vif);
1081        trace_drv_return_void(local);
1082}
1083
1084static inline u32 drv_get_expected_throughput(struct ieee80211_local *local,
1085                                              struct sta_info *sta)
1086{
1087        u32 ret = 0;
1088
1089        trace_drv_get_expected_throughput(&sta->sta);
1090        if (local->ops->get_expected_throughput && sta->uploaded)
1091                ret = local->ops->get_expected_throughput(&local->hw, &sta->sta);
1092        trace_drv_return_u32(local, ret);
1093
1094        return ret;
1095}
1096
1097static inline int drv_get_txpower(struct ieee80211_local *local,
1098                                  struct ieee80211_sub_if_data *sdata, int *dbm)
1099{
1100        int ret;
1101
1102        if (!local->ops->get_txpower)
1103                return -EOPNOTSUPP;
1104
1105        ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm);
1106        trace_drv_get_txpower(local, sdata, *dbm, ret);
1107
1108        return ret;
1109}
1110
1111static inline int
1112drv_tdls_channel_switch(struct ieee80211_local *local,
1113                        struct ieee80211_sub_if_data *sdata,
1114                        struct ieee80211_sta *sta, u8 oper_class,
1115                        struct cfg80211_chan_def *chandef,
1116                        struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie)
1117{
1118        int ret;
1119
1120        might_sleep();
1121        if (!check_sdata_in_driver(sdata))
1122                return -EIO;
1123
1124        if (!local->ops->tdls_channel_switch)
1125                return -EOPNOTSUPP;
1126
1127        trace_drv_tdls_channel_switch(local, sdata, sta, oper_class, chandef);
1128        ret = local->ops->tdls_channel_switch(&local->hw, &sdata->vif, sta,
1129                                              oper_class, chandef, tmpl_skb,
1130                                              ch_sw_tm_ie);
1131        trace_drv_return_int(local, ret);
1132        return ret;
1133}
1134
1135static inline void
1136drv_tdls_cancel_channel_switch(struct ieee80211_local *local,
1137                               struct ieee80211_sub_if_data *sdata,
1138                               struct ieee80211_sta *sta)
1139{
1140        might_sleep();
1141        if (!check_sdata_in_driver(sdata))
1142                return;
1143
1144        if (!local->ops->tdls_cancel_channel_switch)
1145                return;
1146
1147        trace_drv_tdls_cancel_channel_switch(local, sdata, sta);
1148        local->ops->tdls_cancel_channel_switch(&local->hw, &sdata->vif, sta);
1149        trace_drv_return_void(local);
1150}
1151
1152static inline void
1153drv_tdls_recv_channel_switch(struct ieee80211_local *local,
1154                             struct ieee80211_sub_if_data *sdata,
1155                             struct ieee80211_tdls_ch_sw_params *params)
1156{
1157        trace_drv_tdls_recv_channel_switch(local, sdata, params);
1158        if (local->ops->tdls_recv_channel_switch)
1159                local->ops->tdls_recv_channel_switch(&local->hw, &sdata->vif,
1160                                                     params);
1161        trace_drv_return_void(local);
1162}
1163
1164static inline void drv_wake_tx_queue(struct ieee80211_local *local,
1165                                     struct txq_info *txq)
1166{
1167        struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif);
1168
1169        if (!check_sdata_in_driver(sdata))
1170                return;
1171
1172        trace_drv_wake_tx_queue(local, sdata, txq);
1173        local->ops->wake_tx_queue(&local->hw, &txq->txq);
1174}
1175
1176static inline int drv_can_aggregate_in_amsdu(struct ieee80211_local *local,
1177                                             struct sk_buff *head,
1178                                             struct sk_buff *skb)
1179{
1180        if (!local->ops->can_aggregate_in_amsdu)
1181                return true;
1182
1183        return local->ops->can_aggregate_in_amsdu(&local->hw, head, skb);
1184}
1185
1186static inline int
1187drv_get_ftm_responder_stats(struct ieee80211_local *local,
1188                            struct ieee80211_sub_if_data *sdata,
1189                            struct cfg80211_ftm_responder_stats *ftm_stats)
1190{
1191        u32 ret = -EOPNOTSUPP;
1192
1193        if (local->ops->get_ftm_responder_stats)
1194                ret = local->ops->get_ftm_responder_stats(&local->hw,
1195                                                         &sdata->vif,
1196                                                         ftm_stats);
1197        trace_drv_get_ftm_responder_stats(local, sdata, ftm_stats);
1198
1199        return ret;
1200}
1201
1202static inline int drv_start_nan(struct ieee80211_local *local,
1203                                struct ieee80211_sub_if_data *sdata,
1204                                struct cfg80211_nan_conf *conf)
1205{
1206        int ret;
1207
1208        might_sleep();
1209        check_sdata_in_driver(sdata);
1210
1211        trace_drv_start_nan(local, sdata, conf);
1212        ret = local->ops->start_nan(&local->hw, &sdata->vif, conf);
1213        trace_drv_return_int(local, ret);
1214        return ret;
1215}
1216
1217static inline void drv_stop_nan(struct ieee80211_local *local,
1218                                struct ieee80211_sub_if_data *sdata)
1219{
1220        might_sleep();
1221        check_sdata_in_driver(sdata);
1222
1223        trace_drv_stop_nan(local, sdata);
1224        local->ops->stop_nan(&local->hw, &sdata->vif);
1225        trace_drv_return_void(local);
1226}
1227
1228static inline int drv_nan_change_conf(struct ieee80211_local *local,
1229                                       struct ieee80211_sub_if_data *sdata,
1230                                       struct cfg80211_nan_conf *conf,
1231                                       u32 changes)
1232{
1233        int ret;
1234
1235        might_sleep();
1236        check_sdata_in_driver(sdata);
1237
1238        if (!local->ops->nan_change_conf)
1239                return -EOPNOTSUPP;
1240
1241        trace_drv_nan_change_conf(local, sdata, conf, changes);
1242        ret = local->ops->nan_change_conf(&local->hw, &sdata->vif, conf,
1243                                          changes);
1244        trace_drv_return_int(local, ret);
1245
1246        return ret;
1247}
1248
1249static inline int drv_add_nan_func(struct ieee80211_local *local,
1250                                   struct ieee80211_sub_if_data *sdata,
1251                                   const struct cfg80211_nan_func *nan_func)
1252{
1253        int ret;
1254
1255        might_sleep();
1256        check_sdata_in_driver(sdata);
1257
1258        if (!local->ops->add_nan_func)
1259                return -EOPNOTSUPP;
1260
1261        trace_drv_add_nan_func(local, sdata, nan_func);
1262        ret = local->ops->add_nan_func(&local->hw, &sdata->vif, nan_func);
1263        trace_drv_return_int(local, ret);
1264
1265        return ret;
1266}
1267
1268static inline void drv_del_nan_func(struct ieee80211_local *local,
1269                                   struct ieee80211_sub_if_data *sdata,
1270                                   u8 instance_id)
1271{
1272        might_sleep();
1273        check_sdata_in_driver(sdata);
1274
1275        trace_drv_del_nan_func(local, sdata, instance_id);
1276        if (local->ops->del_nan_func)
1277                local->ops->del_nan_func(&local->hw, &sdata->vif, instance_id);
1278        trace_drv_return_void(local);
1279}
1280
1281#endif /* __MAC80211_DRIVER_OPS */
1282