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