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