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_NAN ||
 166                         (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
 167                          !sdata->vif.mu_mimo_owner)))
 168                return;
 169
 170        if (!check_sdata_in_driver(sdata))
 171                return;
 172
 173        trace_drv_bss_info_changed(local, sdata, info, changed);
 174        if (local->ops->bss_info_changed)
 175                local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed);
 176        trace_drv_return_void(local);
 177}
 178
 179static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
 180                                        struct netdev_hw_addr_list *mc_list)
 181{
 182        u64 ret = 0;
 183
 184        trace_drv_prepare_multicast(local, mc_list->count);
 185
 186        if (local->ops->prepare_multicast)
 187                ret = local->ops->prepare_multicast(&local->hw, mc_list);
 188
 189        trace_drv_return_u64(local, ret);
 190
 191        return ret;
 192}
 193
 194static inline void drv_configure_filter(struct ieee80211_local *local,
 195                                        unsigned int changed_flags,
 196                                        unsigned int *total_flags,
 197                                        u64 multicast)
 198{
 199        might_sleep();
 200
 201        trace_drv_configure_filter(local, changed_flags, total_flags,
 202                                   multicast);
 203        local->ops->configure_filter(&local->hw, changed_flags, total_flags,
 204                                     multicast);
 205        trace_drv_return_void(local);
 206}
 207
 208static inline void drv_config_iface_filter(struct ieee80211_local *local,
 209                                           struct ieee80211_sub_if_data *sdata,
 210                                           unsigned int filter_flags,
 211                                           unsigned int changed_flags)
 212{
 213        might_sleep();
 214
 215        trace_drv_config_iface_filter(local, sdata, filter_flags,
 216                                      changed_flags);
 217        if (local->ops->config_iface_filter)
 218                local->ops->config_iface_filter(&local->hw, &sdata->vif,
 219                                                filter_flags,
 220                                                changed_flags);
 221        trace_drv_return_void(local);
 222}
 223
 224static inline int drv_set_tim(struct ieee80211_local *local,
 225                              struct ieee80211_sta *sta, bool set)
 226{
 227        int ret = 0;
 228        trace_drv_set_tim(local, sta, set);
 229        if (local->ops->set_tim)
 230                ret = local->ops->set_tim(&local->hw, sta, set);
 231        trace_drv_return_int(local, ret);
 232        return ret;
 233}
 234
 235static inline int drv_set_key(struct ieee80211_local *local,
 236                              enum set_key_cmd cmd,
 237                              struct ieee80211_sub_if_data *sdata,
 238                              struct ieee80211_sta *sta,
 239                              struct ieee80211_key_conf *key)
 240{
 241        int ret;
 242
 243        might_sleep();
 244
 245        sdata = get_bss_sdata(sdata);
 246        if (!check_sdata_in_driver(sdata))
 247                return -EIO;
 248
 249        trace_drv_set_key(local, cmd, sdata, sta, key);
 250        ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key);
 251        trace_drv_return_int(local, ret);
 252        return ret;
 253}
 254
 255static inline void drv_update_tkip_key(struct ieee80211_local *local,
 256                                       struct ieee80211_sub_if_data *sdata,
 257                                       struct ieee80211_key_conf *conf,
 258                                       struct sta_info *sta, u32 iv32,
 259                                       u16 *phase1key)
 260{
 261        struct ieee80211_sta *ista = NULL;
 262
 263        if (sta)
 264                ista = &sta->sta;
 265
 266        sdata = get_bss_sdata(sdata);
 267        if (!check_sdata_in_driver(sdata))
 268                return;
 269
 270        trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
 271        if (local->ops->update_tkip_key)
 272                local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
 273                                            ista, iv32, phase1key);
 274        trace_drv_return_void(local);
 275}
 276
 277static inline int drv_hw_scan(struct ieee80211_local *local,
 278                              struct ieee80211_sub_if_data *sdata,
 279                              struct ieee80211_scan_request *req)
 280{
 281        int ret;
 282
 283        might_sleep();
 284
 285        if (!check_sdata_in_driver(sdata))
 286                return -EIO;
 287
 288        trace_drv_hw_scan(local, sdata);
 289        ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
 290        trace_drv_return_int(local, ret);
 291        return ret;
 292}
 293
 294static inline void drv_cancel_hw_scan(struct ieee80211_local *local,
 295                                      struct ieee80211_sub_if_data *sdata)
 296{
 297        might_sleep();
 298
 299        if (!check_sdata_in_driver(sdata))
 300                return;
 301
 302        trace_drv_cancel_hw_scan(local, sdata);
 303        local->ops->cancel_hw_scan(&local->hw, &sdata->vif);
 304        trace_drv_return_void(local);
 305}
 306
 307static inline int
 308drv_sched_scan_start(struct ieee80211_local *local,
 309                     struct ieee80211_sub_if_data *sdata,
 310                     struct cfg80211_sched_scan_request *req,
 311                     struct ieee80211_scan_ies *ies)
 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_start(local, sdata);
 321        ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
 322                                              req, ies);
 323        trace_drv_return_int(local, ret);
 324        return ret;
 325}
 326
 327static inline int drv_sched_scan_stop(struct ieee80211_local *local,
 328                                      struct ieee80211_sub_if_data *sdata)
 329{
 330        int ret;
 331
 332        might_sleep();
 333
 334        if (!check_sdata_in_driver(sdata))
 335                return -EIO;
 336
 337        trace_drv_sched_scan_stop(local, sdata);
 338        ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif);
 339        trace_drv_return_int(local, ret);
 340
 341        return ret;
 342}
 343
 344static inline void drv_sw_scan_start(struct ieee80211_local *local,
 345                                     struct ieee80211_sub_if_data *sdata,
 346                                     const u8 *mac_addr)
 347{
 348        might_sleep();
 349
 350        trace_drv_sw_scan_start(local, sdata, mac_addr);
 351        if (local->ops->sw_scan_start)
 352                local->ops->sw_scan_start(&local->hw, &sdata->vif, mac_addr);
 353        trace_drv_return_void(local);
 354}
 355
 356static inline void drv_sw_scan_complete(struct ieee80211_local *local,
 357                                        struct ieee80211_sub_if_data *sdata)
 358{
 359        might_sleep();
 360
 361        trace_drv_sw_scan_complete(local, sdata);
 362        if (local->ops->sw_scan_complete)
 363                local->ops->sw_scan_complete(&local->hw, &sdata->vif);
 364        trace_drv_return_void(local);
 365}
 366
 367static inline int drv_get_stats(struct ieee80211_local *local,
 368                                struct ieee80211_low_level_stats *stats)
 369{
 370        int ret = -EOPNOTSUPP;
 371
 372        might_sleep();
 373
 374        if (local->ops->get_stats)
 375                ret = local->ops->get_stats(&local->hw, stats);
 376        trace_drv_get_stats(local, stats, ret);
 377
 378        return ret;
 379}
 380
 381static inline void drv_get_key_seq(struct ieee80211_local *local,
 382                                   struct ieee80211_key *key,
 383                                   struct ieee80211_key_seq *seq)
 384{
 385        if (local->ops->get_key_seq)
 386                local->ops->get_key_seq(&local->hw, &key->conf, seq);
 387        trace_drv_get_key_seq(local, &key->conf);
 388}
 389
 390static inline int drv_set_frag_threshold(struct ieee80211_local *local,
 391                                        u32 value)
 392{
 393        int ret = 0;
 394
 395        might_sleep();
 396
 397        trace_drv_set_frag_threshold(local, value);
 398        if (local->ops->set_frag_threshold)
 399                ret = local->ops->set_frag_threshold(&local->hw, value);
 400        trace_drv_return_int(local, ret);
 401        return ret;
 402}
 403
 404static inline int drv_set_rts_threshold(struct ieee80211_local *local,
 405                                        u32 value)
 406{
 407        int ret = 0;
 408
 409        might_sleep();
 410
 411        trace_drv_set_rts_threshold(local, value);
 412        if (local->ops->set_rts_threshold)
 413                ret = local->ops->set_rts_threshold(&local->hw, value);
 414        trace_drv_return_int(local, ret);
 415        return ret;
 416}
 417
 418static inline int drv_set_coverage_class(struct ieee80211_local *local,
 419                                         s16 value)
 420{
 421        int ret = 0;
 422        might_sleep();
 423
 424        trace_drv_set_coverage_class(local, value);
 425        if (local->ops->set_coverage_class)
 426                local->ops->set_coverage_class(&local->hw, value);
 427        else
 428                ret = -EOPNOTSUPP;
 429
 430        trace_drv_return_int(local, ret);
 431        return ret;
 432}
 433
 434static inline void drv_sta_notify(struct ieee80211_local *local,
 435                                  struct ieee80211_sub_if_data *sdata,
 436                                  enum sta_notify_cmd cmd,
 437                                  struct ieee80211_sta *sta)
 438{
 439        sdata = get_bss_sdata(sdata);
 440        if (!check_sdata_in_driver(sdata))
 441                return;
 442
 443        trace_drv_sta_notify(local, sdata, cmd, sta);
 444        if (local->ops->sta_notify)
 445                local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta);
 446        trace_drv_return_void(local);
 447}
 448
 449static inline int drv_sta_add(struct ieee80211_local *local,
 450                              struct ieee80211_sub_if_data *sdata,
 451                              struct ieee80211_sta *sta)
 452{
 453        int ret = 0;
 454
 455        might_sleep();
 456
 457        sdata = get_bss_sdata(sdata);
 458        if (!check_sdata_in_driver(sdata))
 459                return -EIO;
 460
 461        trace_drv_sta_add(local, sdata, sta);
 462        if (local->ops->sta_add)
 463                ret = local->ops->sta_add(&local->hw, &sdata->vif, sta);
 464
 465        trace_drv_return_int(local, ret);
 466
 467        return ret;
 468}
 469
 470static inline void drv_sta_remove(struct ieee80211_local *local,
 471                                  struct ieee80211_sub_if_data *sdata,
 472                                  struct ieee80211_sta *sta)
 473{
 474        might_sleep();
 475
 476        sdata = get_bss_sdata(sdata);
 477        if (!check_sdata_in_driver(sdata))
 478                return;
 479
 480        trace_drv_sta_remove(local, sdata, sta);
 481        if (local->ops->sta_remove)
 482                local->ops->sta_remove(&local->hw, &sdata->vif, sta);
 483
 484        trace_drv_return_void(local);
 485}
 486
 487#ifdef CONFIG_MAC80211_DEBUGFS
 488static inline void drv_sta_add_debugfs(struct ieee80211_local *local,
 489                                       struct ieee80211_sub_if_data *sdata,
 490                                       struct ieee80211_sta *sta,
 491                                       struct dentry *dir)
 492{
 493        might_sleep();
 494
 495        sdata = get_bss_sdata(sdata);
 496        if (!check_sdata_in_driver(sdata))
 497                return;
 498
 499        if (local->ops->sta_add_debugfs)
 500                local->ops->sta_add_debugfs(&local->hw, &sdata->vif,
 501                                            sta, dir);
 502}
 503#endif
 504
 505static inline void drv_sta_pre_rcu_remove(struct ieee80211_local *local,
 506                                          struct ieee80211_sub_if_data *sdata,
 507                                          struct sta_info *sta)
 508{
 509        might_sleep();
 510
 511        sdata = get_bss_sdata(sdata);
 512        if (!check_sdata_in_driver(sdata))
 513                return;
 514
 515        trace_drv_sta_pre_rcu_remove(local, sdata, &sta->sta);
 516        if (local->ops->sta_pre_rcu_remove)
 517                local->ops->sta_pre_rcu_remove(&local->hw, &sdata->vif,
 518                                               &sta->sta);
 519        trace_drv_return_void(local);
 520}
 521
 522__must_check
 523int drv_sta_state(struct ieee80211_local *local,
 524                  struct ieee80211_sub_if_data *sdata,
 525                  struct sta_info *sta,
 526                  enum ieee80211_sta_state old_state,
 527                  enum ieee80211_sta_state new_state);
 528
 529void drv_sta_rc_update(struct ieee80211_local *local,
 530                       struct ieee80211_sub_if_data *sdata,
 531                       struct ieee80211_sta *sta, u32 changed);
 532
 533static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local,
 534                                           struct ieee80211_sub_if_data *sdata,
 535                                           struct ieee80211_sta *sta)
 536{
 537        sdata = get_bss_sdata(sdata);
 538        if (!check_sdata_in_driver(sdata))
 539                return;
 540
 541        trace_drv_sta_rate_tbl_update(local, sdata, sta);
 542        if (local->ops->sta_rate_tbl_update)
 543                local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta);
 544
 545        trace_drv_return_void(local);
 546}
 547
 548static inline void drv_sta_statistics(struct ieee80211_local *local,
 549                                      struct ieee80211_sub_if_data *sdata,
 550                                      struct ieee80211_sta *sta,
 551                                      struct station_info *sinfo)
 552{
 553        sdata = get_bss_sdata(sdata);
 554        if (!check_sdata_in_driver(sdata))
 555                return;
 556
 557        trace_drv_sta_statistics(local, sdata, sta);
 558        if (local->ops->sta_statistics)
 559                local->ops->sta_statistics(&local->hw, &sdata->vif, sta, sinfo);
 560        trace_drv_return_void(local);
 561}
 562
 563int drv_conf_tx(struct ieee80211_local *local,
 564                struct ieee80211_sub_if_data *sdata, u16 ac,
 565                const struct ieee80211_tx_queue_params *params);
 566
 567u64 drv_get_tsf(struct ieee80211_local *local,
 568                struct ieee80211_sub_if_data *sdata);
 569void drv_set_tsf(struct ieee80211_local *local,
 570                 struct ieee80211_sub_if_data *sdata,
 571                 u64 tsf);
 572void drv_offset_tsf(struct ieee80211_local *local,
 573                    struct ieee80211_sub_if_data *sdata,
 574                    s64 offset);
 575void drv_reset_tsf(struct ieee80211_local *local,
 576                   struct ieee80211_sub_if_data *sdata);
 577
 578static inline int drv_tx_last_beacon(struct ieee80211_local *local)
 579{
 580        int ret = 0; /* default unsupported op for less congestion */
 581
 582        might_sleep();
 583
 584        trace_drv_tx_last_beacon(local);
 585        if (local->ops->tx_last_beacon)
 586                ret = local->ops->tx_last_beacon(&local->hw);
 587        trace_drv_return_int(local, ret);
 588        return ret;
 589}
 590
 591int drv_ampdu_action(struct ieee80211_local *local,
 592                     struct ieee80211_sub_if_data *sdata,
 593                     struct ieee80211_ampdu_params *params);
 594
 595static inline int drv_get_survey(struct ieee80211_local *local, int idx,
 596                                struct survey_info *survey)
 597{
 598        int ret = -EOPNOTSUPP;
 599
 600        trace_drv_get_survey(local, idx, survey);
 601
 602        if (local->ops->get_survey)
 603                ret = local->ops->get_survey(&local->hw, idx, survey);
 604
 605        trace_drv_return_int(local, ret);
 606
 607        return ret;
 608}
 609
 610static inline void drv_rfkill_poll(struct ieee80211_local *local)
 611{
 612        might_sleep();
 613
 614        if (local->ops->rfkill_poll)
 615                local->ops->rfkill_poll(&local->hw);
 616}
 617
 618static inline void drv_flush(struct ieee80211_local *local,
 619                             struct ieee80211_sub_if_data *sdata,
 620                             u32 queues, bool drop)
 621{
 622        struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL;
 623
 624        might_sleep();
 625
 626        if (sdata && !check_sdata_in_driver(sdata))
 627                return;
 628
 629        trace_drv_flush(local, queues, drop);
 630        if (local->ops->flush)
 631                local->ops->flush(&local->hw, vif, queues, drop);
 632        trace_drv_return_void(local);
 633}
 634
 635static inline void drv_channel_switch(struct ieee80211_local *local,
 636                                      struct ieee80211_sub_if_data *sdata,
 637                                      struct ieee80211_channel_switch *ch_switch)
 638{
 639        might_sleep();
 640
 641        trace_drv_channel_switch(local, sdata, ch_switch);
 642        local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch);
 643        trace_drv_return_void(local);
 644}
 645
 646
 647static inline int drv_set_antenna(struct ieee80211_local *local,
 648                                  u32 tx_ant, u32 rx_ant)
 649{
 650        int ret = -EOPNOTSUPP;
 651        might_sleep();
 652        if (local->ops->set_antenna)
 653                ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
 654        trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
 655        return ret;
 656}
 657
 658static inline int drv_get_antenna(struct ieee80211_local *local,
 659                                  u32 *tx_ant, u32 *rx_ant)
 660{
 661        int ret = -EOPNOTSUPP;
 662        might_sleep();
 663        if (local->ops->get_antenna)
 664                ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
 665        trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
 666        return ret;
 667}
 668
 669static inline int drv_remain_on_channel(struct ieee80211_local *local,
 670                                        struct ieee80211_sub_if_data *sdata,
 671                                        struct ieee80211_channel *chan,
 672                                        unsigned int duration,
 673                                        enum ieee80211_roc_type type)
 674{
 675        int ret;
 676
 677        might_sleep();
 678
 679        trace_drv_remain_on_channel(local, sdata, chan, duration, type);
 680        ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
 681                                            chan, duration, type);
 682        trace_drv_return_int(local, ret);
 683
 684        return ret;
 685}
 686
 687static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local)
 688{
 689        int ret;
 690
 691        might_sleep();
 692
 693        trace_drv_cancel_remain_on_channel(local);
 694        ret = local->ops->cancel_remain_on_channel(&local->hw);
 695        trace_drv_return_int(local, ret);
 696
 697        return ret;
 698}
 699
 700static inline int drv_set_ringparam(struct ieee80211_local *local,
 701                                    u32 tx, u32 rx)
 702{
 703        int ret = -ENOTSUPP;
 704
 705        might_sleep();
 706
 707        trace_drv_set_ringparam(local, tx, rx);
 708        if (local->ops->set_ringparam)
 709                ret = local->ops->set_ringparam(&local->hw, tx, rx);
 710        trace_drv_return_int(local, ret);
 711
 712        return ret;
 713}
 714
 715static inline void drv_get_ringparam(struct ieee80211_local *local,
 716                                     u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
 717{
 718        might_sleep();
 719
 720        trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
 721        if (local->ops->get_ringparam)
 722                local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
 723        trace_drv_return_void(local);
 724}
 725
 726static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
 727{
 728        bool ret = false;
 729
 730        might_sleep();
 731
 732        trace_drv_tx_frames_pending(local);
 733        if (local->ops->tx_frames_pending)
 734                ret = local->ops->tx_frames_pending(&local->hw);
 735        trace_drv_return_bool(local, ret);
 736
 737        return ret;
 738}
 739
 740static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
 741                                       struct ieee80211_sub_if_data *sdata,
 742                                       const struct cfg80211_bitrate_mask *mask)
 743{
 744        int ret = -EOPNOTSUPP;
 745
 746        might_sleep();
 747
 748        if (!check_sdata_in_driver(sdata))
 749                return -EIO;
 750
 751        trace_drv_set_bitrate_mask(local, sdata, mask);
 752        if (local->ops->set_bitrate_mask)
 753                ret = local->ops->set_bitrate_mask(&local->hw,
 754                                                   &sdata->vif, mask);
 755        trace_drv_return_int(local, ret);
 756
 757        return ret;
 758}
 759
 760static inline void drv_set_rekey_data(struct ieee80211_local *local,
 761                                      struct ieee80211_sub_if_data *sdata,
 762                                      struct cfg80211_gtk_rekey_data *data)
 763{
 764        if (!check_sdata_in_driver(sdata))
 765                return;
 766
 767        trace_drv_set_rekey_data(local, sdata, data);
 768        if (local->ops->set_rekey_data)
 769                local->ops->set_rekey_data(&local->hw, &sdata->vif, data);
 770        trace_drv_return_void(local);
 771}
 772
 773static inline void drv_event_callback(struct ieee80211_local *local,
 774                                      struct ieee80211_sub_if_data *sdata,
 775                                      const struct ieee80211_event *event)
 776{
 777        trace_drv_event_callback(local, sdata, event);
 778        if (local->ops->event_callback)
 779                local->ops->event_callback(&local->hw, &sdata->vif, event);
 780        trace_drv_return_void(local);
 781}
 782
 783static inline void
 784drv_release_buffered_frames(struct ieee80211_local *local,
 785                            struct sta_info *sta, u16 tids, int num_frames,
 786                            enum ieee80211_frame_release_type reason,
 787                            bool more_data)
 788{
 789        trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
 790                                          reason, more_data);
 791        if (local->ops->release_buffered_frames)
 792                local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
 793                                                    num_frames, reason,
 794                                                    more_data);
 795        trace_drv_return_void(local);
 796}
 797
 798static inline void
 799drv_allow_buffered_frames(struct ieee80211_local *local,
 800                          struct sta_info *sta, u16 tids, int num_frames,
 801                          enum ieee80211_frame_release_type reason,
 802                          bool more_data)
 803{
 804        trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
 805                                        reason, more_data);
 806        if (local->ops->allow_buffered_frames)
 807                local->ops->allow_buffered_frames(&local->hw, &sta->sta,
 808                                                  tids, num_frames, reason,
 809                                                  more_data);
 810        trace_drv_return_void(local);
 811}
 812
 813static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
 814                                      struct ieee80211_sub_if_data *sdata)
 815{
 816        might_sleep();
 817
 818        if (!check_sdata_in_driver(sdata))
 819                return;
 820        WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
 821
 822        trace_drv_mgd_prepare_tx(local, sdata);
 823        if (local->ops->mgd_prepare_tx)
 824                local->ops->mgd_prepare_tx(&local->hw, &sdata->vif);
 825        trace_drv_return_void(local);
 826}
 827
 828static inline void
 829drv_mgd_protect_tdls_discover(struct ieee80211_local *local,
 830                              struct ieee80211_sub_if_data *sdata)
 831{
 832        might_sleep();
 833
 834        if (!check_sdata_in_driver(sdata))
 835                return;
 836        WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
 837
 838        trace_drv_mgd_protect_tdls_discover(local, sdata);
 839        if (local->ops->mgd_protect_tdls_discover)
 840                local->ops->mgd_protect_tdls_discover(&local->hw, &sdata->vif);
 841        trace_drv_return_void(local);
 842}
 843
 844static inline int drv_add_chanctx(struct ieee80211_local *local,
 845                                  struct ieee80211_chanctx *ctx)
 846{
 847        int ret = -EOPNOTSUPP;
 848
 849        might_sleep();
 850
 851        trace_drv_add_chanctx(local, ctx);
 852        if (local->ops->add_chanctx)
 853                ret = local->ops->add_chanctx(&local->hw, &ctx->conf);
 854        trace_drv_return_int(local, ret);
 855        if (!ret)
 856                ctx->driver_present = true;
 857
 858        return ret;
 859}
 860
 861static inline void drv_remove_chanctx(struct ieee80211_local *local,
 862                                      struct ieee80211_chanctx *ctx)
 863{
 864        might_sleep();
 865
 866        if (WARN_ON(!ctx->driver_present))
 867                return;
 868
 869        trace_drv_remove_chanctx(local, ctx);
 870        if (local->ops->remove_chanctx)
 871                local->ops->remove_chanctx(&local->hw, &ctx->conf);
 872        trace_drv_return_void(local);
 873        ctx->driver_present = false;
 874}
 875
 876static inline void drv_change_chanctx(struct ieee80211_local *local,
 877                                      struct ieee80211_chanctx *ctx,
 878                                      u32 changed)
 879{
 880        might_sleep();
 881
 882        trace_drv_change_chanctx(local, ctx, changed);
 883        if (local->ops->change_chanctx) {
 884                WARN_ON_ONCE(!ctx->driver_present);
 885                local->ops->change_chanctx(&local->hw, &ctx->conf, changed);
 886        }
 887        trace_drv_return_void(local);
 888}
 889
 890static inline int drv_assign_vif_chanctx(struct ieee80211_local *local,
 891                                         struct ieee80211_sub_if_data *sdata,
 892                                         struct ieee80211_chanctx *ctx)
 893{
 894        int ret = 0;
 895
 896        if (!check_sdata_in_driver(sdata))
 897                return -EIO;
 898
 899        trace_drv_assign_vif_chanctx(local, sdata, ctx);
 900        if (local->ops->assign_vif_chanctx) {
 901                WARN_ON_ONCE(!ctx->driver_present);
 902                ret = local->ops->assign_vif_chanctx(&local->hw,
 903                                                     &sdata->vif,
 904                                                     &ctx->conf);
 905        }
 906        trace_drv_return_int(local, ret);
 907
 908        return ret;
 909}
 910
 911static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
 912                                            struct ieee80211_sub_if_data *sdata,
 913                                            struct ieee80211_chanctx *ctx)
 914{
 915        might_sleep();
 916
 917        if (!check_sdata_in_driver(sdata))
 918                return;
 919
 920        trace_drv_unassign_vif_chanctx(local, sdata, ctx);
 921        if (local->ops->unassign_vif_chanctx) {
 922                WARN_ON_ONCE(!ctx->driver_present);
 923                local->ops->unassign_vif_chanctx(&local->hw,
 924                                                 &sdata->vif,
 925                                                 &ctx->conf);
 926        }
 927        trace_drv_return_void(local);
 928}
 929
 930int drv_switch_vif_chanctx(struct ieee80211_local *local,
 931                           struct ieee80211_vif_chanctx_switch *vifs,
 932                           int n_vifs, enum ieee80211_chanctx_switch_mode mode);
 933
 934static inline int drv_start_ap(struct ieee80211_local *local,
 935                               struct ieee80211_sub_if_data *sdata)
 936{
 937        int ret = 0;
 938
 939        might_sleep();
 940
 941        if (!check_sdata_in_driver(sdata))
 942                return -EIO;
 943
 944        trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf);
 945        if (local->ops->start_ap)
 946                ret = local->ops->start_ap(&local->hw, &sdata->vif);
 947        trace_drv_return_int(local, ret);
 948        return ret;
 949}
 950
 951static inline void drv_stop_ap(struct ieee80211_local *local,
 952                               struct ieee80211_sub_if_data *sdata)
 953{
 954        if (!check_sdata_in_driver(sdata))
 955                return;
 956
 957        trace_drv_stop_ap(local, sdata);
 958        if (local->ops->stop_ap)
 959                local->ops->stop_ap(&local->hw, &sdata->vif);
 960        trace_drv_return_void(local);
 961}
 962
 963static inline void
 964drv_reconfig_complete(struct ieee80211_local *local,
 965                      enum ieee80211_reconfig_type reconfig_type)
 966{
 967        might_sleep();
 968
 969        trace_drv_reconfig_complete(local, reconfig_type);
 970        if (local->ops->reconfig_complete)
 971                local->ops->reconfig_complete(&local->hw, reconfig_type);
 972        trace_drv_return_void(local);
 973}
 974
 975static inline void
 976drv_set_default_unicast_key(struct ieee80211_local *local,
 977                            struct ieee80211_sub_if_data *sdata,
 978                            int key_idx)
 979{
 980        if (!check_sdata_in_driver(sdata))
 981                return;
 982
 983        WARN_ON_ONCE(key_idx < -1 || key_idx > 3);
 984
 985        trace_drv_set_default_unicast_key(local, sdata, key_idx);
 986        if (local->ops->set_default_unicast_key)
 987                local->ops->set_default_unicast_key(&local->hw, &sdata->vif,
 988                                                    key_idx);
 989        trace_drv_return_void(local);
 990}
 991
 992#if IS_ENABLED(CONFIG_IPV6)
 993static inline void drv_ipv6_addr_change(struct ieee80211_local *local,
 994                                        struct ieee80211_sub_if_data *sdata,
 995                                        struct inet6_dev *idev)
 996{
 997        trace_drv_ipv6_addr_change(local, sdata);
 998        if (local->ops->ipv6_addr_change)
 999                local->ops->ipv6_addr_change(&local->hw, &sdata->vif, idev);
1000        trace_drv_return_void(local);
1001}
1002#endif
1003
1004static inline void
1005drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata,
1006                          struct cfg80211_chan_def *chandef)
1007{
1008        struct ieee80211_local *local = sdata->local;
1009
1010        if (local->ops->channel_switch_beacon) {
1011                trace_drv_channel_switch_beacon(local, sdata, chandef);
1012                local->ops->channel_switch_beacon(&local->hw, &sdata->vif,
1013                                                  chandef);
1014        }
1015}
1016
1017static inline int
1018drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata,
1019                       struct ieee80211_channel_switch *ch_switch)
1020{
1021        struct ieee80211_local *local = sdata->local;
1022        int ret = 0;
1023
1024        if (!check_sdata_in_driver(sdata))
1025                return -EIO;
1026
1027        trace_drv_pre_channel_switch(local, sdata, ch_switch);
1028        if (local->ops->pre_channel_switch)
1029                ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif,
1030                                                     ch_switch);
1031        trace_drv_return_int(local, ret);
1032        return ret;
1033}
1034
1035static inline int
1036drv_post_channel_switch(struct ieee80211_sub_if_data *sdata)
1037{
1038        struct ieee80211_local *local = sdata->local;
1039        int ret = 0;
1040
1041        if (!check_sdata_in_driver(sdata))
1042                return -EIO;
1043
1044        trace_drv_post_channel_switch(local, sdata);
1045        if (local->ops->post_channel_switch)
1046                ret = local->ops->post_channel_switch(&local->hw, &sdata->vif);
1047        trace_drv_return_int(local, ret);
1048        return ret;
1049}
1050
1051static inline int drv_join_ibss(struct ieee80211_local *local,
1052                                struct ieee80211_sub_if_data *sdata)
1053{
1054        int ret = 0;
1055
1056        might_sleep();
1057        if (!check_sdata_in_driver(sdata))
1058                return -EIO;
1059
1060        trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf);
1061        if (local->ops->join_ibss)
1062                ret = local->ops->join_ibss(&local->hw, &sdata->vif);
1063        trace_drv_return_int(local, ret);
1064        return ret;
1065}
1066
1067static inline void drv_leave_ibss(struct ieee80211_local *local,
1068                                  struct ieee80211_sub_if_data *sdata)
1069{
1070        might_sleep();
1071        if (!check_sdata_in_driver(sdata))
1072                return;
1073
1074        trace_drv_leave_ibss(local, sdata);
1075        if (local->ops->leave_ibss)
1076                local->ops->leave_ibss(&local->hw, &sdata->vif);
1077        trace_drv_return_void(local);
1078}
1079
1080static inline u32 drv_get_expected_throughput(struct ieee80211_local *local,
1081                                              struct sta_info *sta)
1082{
1083        u32 ret = 0;
1084
1085        trace_drv_get_expected_throughput(&sta->sta);
1086        if (local->ops->get_expected_throughput && sta->uploaded)
1087                ret = local->ops->get_expected_throughput(&local->hw, &sta->sta);
1088        trace_drv_return_u32(local, ret);
1089
1090        return ret;
1091}
1092
1093static inline int drv_get_txpower(struct ieee80211_local *local,
1094                                  struct ieee80211_sub_if_data *sdata, int *dbm)
1095{
1096        int ret;
1097
1098        if (!local->ops->get_txpower)
1099                return -EOPNOTSUPP;
1100
1101        ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm);
1102        trace_drv_get_txpower(local, sdata, *dbm, ret);
1103
1104        return ret;
1105}
1106
1107static inline int
1108drv_tdls_channel_switch(struct ieee80211_local *local,
1109                        struct ieee80211_sub_if_data *sdata,
1110                        struct ieee80211_sta *sta, u8 oper_class,
1111                        struct cfg80211_chan_def *chandef,
1112                        struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie)
1113{
1114        int ret;
1115
1116        might_sleep();
1117        if (!check_sdata_in_driver(sdata))
1118                return -EIO;
1119
1120        if (!local->ops->tdls_channel_switch)
1121                return -EOPNOTSUPP;
1122
1123        trace_drv_tdls_channel_switch(local, sdata, sta, oper_class, chandef);
1124        ret = local->ops->tdls_channel_switch(&local->hw, &sdata->vif, sta,
1125                                              oper_class, chandef, tmpl_skb,
1126                                              ch_sw_tm_ie);
1127        trace_drv_return_int(local, ret);
1128        return ret;
1129}
1130
1131static inline void
1132drv_tdls_cancel_channel_switch(struct ieee80211_local *local,
1133                               struct ieee80211_sub_if_data *sdata,
1134                               struct ieee80211_sta *sta)
1135{
1136        might_sleep();
1137        if (!check_sdata_in_driver(sdata))
1138                return;
1139
1140        if (!local->ops->tdls_cancel_channel_switch)
1141                return;
1142
1143        trace_drv_tdls_cancel_channel_switch(local, sdata, sta);
1144        local->ops->tdls_cancel_channel_switch(&local->hw, &sdata->vif, sta);
1145        trace_drv_return_void(local);
1146}
1147
1148static inline void
1149drv_tdls_recv_channel_switch(struct ieee80211_local *local,
1150                             struct ieee80211_sub_if_data *sdata,
1151                             struct ieee80211_tdls_ch_sw_params *params)
1152{
1153        trace_drv_tdls_recv_channel_switch(local, sdata, params);
1154        if (local->ops->tdls_recv_channel_switch)
1155                local->ops->tdls_recv_channel_switch(&local->hw, &sdata->vif,
1156                                                     params);
1157        trace_drv_return_void(local);
1158}
1159
1160static inline void drv_wake_tx_queue(struct ieee80211_local *local,
1161                                     struct txq_info *txq)
1162{
1163        struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif);
1164
1165        if (!check_sdata_in_driver(sdata))
1166                return;
1167
1168        trace_drv_wake_tx_queue(local, sdata, txq);
1169        local->ops->wake_tx_queue(&local->hw, &txq->txq);
1170}
1171
1172static inline int drv_start_nan(struct ieee80211_local *local,
1173                                struct ieee80211_sub_if_data *sdata,
1174                                struct cfg80211_nan_conf *conf)
1175{
1176        int ret;
1177
1178        might_sleep();
1179        check_sdata_in_driver(sdata);
1180
1181        trace_drv_start_nan(local, sdata, conf);
1182        ret = local->ops->start_nan(&local->hw, &sdata->vif, conf);
1183        trace_drv_return_int(local, ret);
1184        return ret;
1185}
1186
1187static inline void drv_stop_nan(struct ieee80211_local *local,
1188                                struct ieee80211_sub_if_data *sdata)
1189{
1190        might_sleep();
1191        check_sdata_in_driver(sdata);
1192
1193        trace_drv_stop_nan(local, sdata);
1194        local->ops->stop_nan(&local->hw, &sdata->vif);
1195        trace_drv_return_void(local);
1196}
1197
1198static inline int drv_nan_change_conf(struct ieee80211_local *local,
1199                                       struct ieee80211_sub_if_data *sdata,
1200                                       struct cfg80211_nan_conf *conf,
1201                                       u32 changes)
1202{
1203        int ret;
1204
1205        might_sleep();
1206        check_sdata_in_driver(sdata);
1207
1208        if (!local->ops->nan_change_conf)
1209                return -EOPNOTSUPP;
1210
1211        trace_drv_nan_change_conf(local, sdata, conf, changes);
1212        ret = local->ops->nan_change_conf(&local->hw, &sdata->vif, conf,
1213                                          changes);
1214        trace_drv_return_int(local, ret);
1215
1216        return ret;
1217}
1218
1219static inline int drv_add_nan_func(struct ieee80211_local *local,
1220                                   struct ieee80211_sub_if_data *sdata,
1221                                   const struct cfg80211_nan_func *nan_func)
1222{
1223        int ret;
1224
1225        might_sleep();
1226        check_sdata_in_driver(sdata);
1227
1228        if (!local->ops->add_nan_func)
1229                return -EOPNOTSUPP;
1230
1231        trace_drv_add_nan_func(local, sdata, nan_func);
1232        ret = local->ops->add_nan_func(&local->hw, &sdata->vif, nan_func);
1233        trace_drv_return_int(local, ret);
1234
1235        return ret;
1236}
1237
1238static inline void drv_del_nan_func(struct ieee80211_local *local,
1239                                   struct ieee80211_sub_if_data *sdata,
1240                                   u8 instance_id)
1241{
1242        might_sleep();
1243        check_sdata_in_driver(sdata);
1244
1245        trace_drv_del_nan_func(local, sdata, instance_id);
1246        if (local->ops->del_nan_func)
1247                local->ops->del_nan_func(&local->hw, &sdata->vif, instance_id);
1248        trace_drv_return_void(local);
1249}
1250
1251#endif /* __MAC80211_DRIVER_OPS */
1252