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 void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata)
   9{
  10        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
  69static inline int drv_start(struct ieee80211_local *local)
  70{
  71        int ret;
  72
  73        might_sleep();
  74
  75        trace_drv_start(local);
  76        local->started = true;
  77        smp_mb();
  78        ret = local->ops->start(&local->hw);
  79        trace_drv_return_int(local, ret);
  80        return ret;
  81}
  82
  83static inline void drv_stop(struct ieee80211_local *local)
  84{
  85        might_sleep();
  86
  87        trace_drv_stop(local);
  88        local->ops->stop(&local->hw);
  89        trace_drv_return_void(local);
  90
  91        /* sync away all work on the tasklet before clearing started */
  92        tasklet_disable(&local->tasklet);
  93        tasklet_enable(&local->tasklet);
  94
  95        barrier();
  96
  97        local->started = false;
  98}
  99
 100#ifdef CONFIG_PM
 101static inline int drv_suspend(struct ieee80211_local *local,
 102                              struct cfg80211_wowlan *wowlan)
 103{
 104        int ret;
 105
 106        might_sleep();
 107
 108        trace_drv_suspend(local);
 109        ret = local->ops->suspend(&local->hw, wowlan);
 110        trace_drv_return_int(local, ret);
 111        return ret;
 112}
 113
 114static inline int drv_resume(struct ieee80211_local *local)
 115{
 116        int ret;
 117
 118        might_sleep();
 119
 120        trace_drv_resume(local);
 121        ret = local->ops->resume(&local->hw);
 122        trace_drv_return_int(local, ret);
 123        return ret;
 124}
 125
 126static inline void drv_set_wakeup(struct ieee80211_local *local,
 127                                  bool enabled)
 128{
 129        might_sleep();
 130
 131        if (!local->ops->set_wakeup)
 132                return;
 133
 134        trace_drv_set_wakeup(local, enabled);
 135        local->ops->set_wakeup(&local->hw, enabled);
 136        trace_drv_return_void(local);
 137}
 138#endif
 139
 140static inline int drv_add_interface(struct ieee80211_local *local,
 141                                    struct ieee80211_sub_if_data *sdata)
 142{
 143        int ret;
 144
 145        might_sleep();
 146
 147        if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
 148                    (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
 149                     !(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF) &&
 150                     !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))))
 151                return -EINVAL;
 152
 153        trace_drv_add_interface(local, sdata);
 154        ret = local->ops->add_interface(&local->hw, &sdata->vif);
 155        trace_drv_return_int(local, ret);
 156
 157        if (ret == 0)
 158                sdata->flags |= IEEE80211_SDATA_IN_DRIVER;
 159
 160        return ret;
 161}
 162
 163static inline int drv_change_interface(struct ieee80211_local *local,
 164                                       struct ieee80211_sub_if_data *sdata,
 165                                       enum nl80211_iftype type, bool p2p)
 166{
 167        int ret;
 168
 169        might_sleep();
 170
 171        check_sdata_in_driver(sdata);
 172
 173        trace_drv_change_interface(local, sdata, type, p2p);
 174        ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p);
 175        trace_drv_return_int(local, ret);
 176        return ret;
 177}
 178
 179static inline void drv_remove_interface(struct ieee80211_local *local,
 180                                        struct ieee80211_sub_if_data *sdata)
 181{
 182        might_sleep();
 183
 184        check_sdata_in_driver(sdata);
 185
 186        trace_drv_remove_interface(local, sdata);
 187        local->ops->remove_interface(&local->hw, &sdata->vif);
 188        sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER;
 189        trace_drv_return_void(local);
 190}
 191
 192static inline int drv_config(struct ieee80211_local *local, u32 changed)
 193{
 194        int ret;
 195
 196        might_sleep();
 197
 198        trace_drv_config(local, changed);
 199        ret = local->ops->config(&local->hw, changed);
 200        trace_drv_return_int(local, ret);
 201        return ret;
 202}
 203
 204static inline void drv_bss_info_changed(struct ieee80211_local *local,
 205                                        struct ieee80211_sub_if_data *sdata,
 206                                        struct ieee80211_bss_conf *info,
 207                                        u32 changed)
 208{
 209        might_sleep();
 210
 211        if (WARN_ON_ONCE(changed & (BSS_CHANGED_BEACON |
 212                                    BSS_CHANGED_BEACON_ENABLED) &&
 213                         sdata->vif.type != NL80211_IFTYPE_AP &&
 214                         sdata->vif.type != NL80211_IFTYPE_ADHOC &&
 215                         sdata->vif.type != NL80211_IFTYPE_MESH_POINT))
 216                return;
 217
 218        if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
 219                         sdata->vif.type == NL80211_IFTYPE_MONITOR))
 220                return;
 221
 222        check_sdata_in_driver(sdata);
 223
 224        trace_drv_bss_info_changed(local, sdata, info, changed);
 225        if (local->ops->bss_info_changed)
 226                local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed);
 227        trace_drv_return_void(local);
 228}
 229
 230static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
 231                                        struct netdev_hw_addr_list *mc_list)
 232{
 233        u64 ret = 0;
 234
 235        trace_drv_prepare_multicast(local, mc_list->count);
 236
 237        if (local->ops->prepare_multicast)
 238                ret = local->ops->prepare_multicast(&local->hw, mc_list);
 239
 240        trace_drv_return_u64(local, ret);
 241
 242        return ret;
 243}
 244
 245static inline void drv_set_multicast_list(struct ieee80211_local *local,
 246                                          struct ieee80211_sub_if_data *sdata,
 247                                          struct netdev_hw_addr_list *mc_list)
 248{
 249        bool allmulti = sdata->flags & IEEE80211_SDATA_ALLMULTI;
 250
 251        trace_drv_set_multicast_list(local, sdata, mc_list->count);
 252
 253        check_sdata_in_driver(sdata);
 254
 255        if (local->ops->set_multicast_list)
 256                local->ops->set_multicast_list(&local->hw, &sdata->vif,
 257                                               allmulti, mc_list);
 258        trace_drv_return_void(local);
 259}
 260
 261static inline void drv_configure_filter(struct ieee80211_local *local,
 262                                        unsigned int changed_flags,
 263                                        unsigned int *total_flags,
 264                                        u64 multicast)
 265{
 266        might_sleep();
 267
 268        trace_drv_configure_filter(local, changed_flags, total_flags,
 269                                   multicast);
 270        local->ops->configure_filter(&local->hw, changed_flags, total_flags,
 271                                     multicast);
 272        trace_drv_return_void(local);
 273}
 274
 275static inline int drv_set_tim(struct ieee80211_local *local,
 276                              struct ieee80211_sta *sta, bool set)
 277{
 278        int ret = 0;
 279        trace_drv_set_tim(local, sta, set);
 280        if (local->ops->set_tim)
 281                ret = local->ops->set_tim(&local->hw, sta, set);
 282        trace_drv_return_int(local, ret);
 283        return ret;
 284}
 285
 286static inline int drv_set_key(struct ieee80211_local *local,
 287                              enum set_key_cmd cmd,
 288                              struct ieee80211_sub_if_data *sdata,
 289                              struct ieee80211_sta *sta,
 290                              struct ieee80211_key_conf *key)
 291{
 292        int ret;
 293
 294        might_sleep();
 295
 296        sdata = get_bss_sdata(sdata);
 297        check_sdata_in_driver(sdata);
 298
 299        trace_drv_set_key(local, cmd, sdata, sta, key);
 300        ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key);
 301        trace_drv_return_int(local, ret);
 302        return ret;
 303}
 304
 305static inline void drv_update_tkip_key(struct ieee80211_local *local,
 306                                       struct ieee80211_sub_if_data *sdata,
 307                                       struct ieee80211_key_conf *conf,
 308                                       struct sta_info *sta, u32 iv32,
 309                                       u16 *phase1key)
 310{
 311        struct ieee80211_sta *ista = NULL;
 312
 313        if (sta)
 314                ista = &sta->sta;
 315
 316        sdata = get_bss_sdata(sdata);
 317        check_sdata_in_driver(sdata);
 318
 319        trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
 320        if (local->ops->update_tkip_key)
 321                local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
 322                                            ista, iv32, phase1key);
 323        trace_drv_return_void(local);
 324}
 325
 326static inline int drv_hw_scan(struct ieee80211_local *local,
 327                              struct ieee80211_sub_if_data *sdata,
 328                              struct cfg80211_scan_request *req)
 329{
 330        int ret;
 331
 332        might_sleep();
 333
 334        check_sdata_in_driver(sdata);
 335
 336        trace_drv_hw_scan(local, sdata);
 337        ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
 338        trace_drv_return_int(local, ret);
 339        return ret;
 340}
 341
 342static inline void drv_cancel_hw_scan(struct ieee80211_local *local,
 343                                      struct ieee80211_sub_if_data *sdata)
 344{
 345        might_sleep();
 346
 347        check_sdata_in_driver(sdata);
 348
 349        trace_drv_cancel_hw_scan(local, sdata);
 350        local->ops->cancel_hw_scan(&local->hw, &sdata->vif);
 351        trace_drv_return_void(local);
 352}
 353
 354static inline int
 355drv_sched_scan_start(struct ieee80211_local *local,
 356                     struct ieee80211_sub_if_data *sdata,
 357                     struct cfg80211_sched_scan_request *req,
 358                     struct ieee80211_sched_scan_ies *ies)
 359{
 360        int ret;
 361
 362        might_sleep();
 363
 364        check_sdata_in_driver(sdata);
 365
 366        trace_drv_sched_scan_start(local, sdata);
 367        ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
 368                                              req, ies);
 369        trace_drv_return_int(local, ret);
 370        return ret;
 371}
 372
 373static inline void drv_sched_scan_stop(struct ieee80211_local *local,
 374                                       struct ieee80211_sub_if_data *sdata)
 375{
 376        might_sleep();
 377
 378        check_sdata_in_driver(sdata);
 379
 380        trace_drv_sched_scan_stop(local, sdata);
 381        local->ops->sched_scan_stop(&local->hw, &sdata->vif);
 382        trace_drv_return_void(local);
 383}
 384
 385static inline void drv_sw_scan_start(struct ieee80211_local *local)
 386{
 387        might_sleep();
 388
 389        trace_drv_sw_scan_start(local);
 390        if (local->ops->sw_scan_start)
 391                local->ops->sw_scan_start(&local->hw);
 392        trace_drv_return_void(local);
 393}
 394
 395static inline void drv_sw_scan_complete(struct ieee80211_local *local)
 396{
 397        might_sleep();
 398
 399        trace_drv_sw_scan_complete(local);
 400        if (local->ops->sw_scan_complete)
 401                local->ops->sw_scan_complete(&local->hw);
 402        trace_drv_return_void(local);
 403}
 404
 405static inline int drv_get_stats(struct ieee80211_local *local,
 406                                struct ieee80211_low_level_stats *stats)
 407{
 408        int ret = -EOPNOTSUPP;
 409
 410        might_sleep();
 411
 412        if (local->ops->get_stats)
 413                ret = local->ops->get_stats(&local->hw, stats);
 414        trace_drv_get_stats(local, stats, ret);
 415
 416        return ret;
 417}
 418
 419static inline void drv_get_tkip_seq(struct ieee80211_local *local,
 420                                    u8 hw_key_idx, u32 *iv32, u16 *iv16)
 421{
 422        if (local->ops->get_tkip_seq)
 423                local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16);
 424        trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16);
 425}
 426
 427static inline int drv_set_frag_threshold(struct ieee80211_local *local,
 428                                        u32 value)
 429{
 430        int ret = 0;
 431
 432        might_sleep();
 433
 434        trace_drv_set_frag_threshold(local, value);
 435        if (local->ops->set_frag_threshold)
 436                ret = local->ops->set_frag_threshold(&local->hw, value);
 437        trace_drv_return_int(local, ret);
 438        return ret;
 439}
 440
 441static inline int drv_set_rts_threshold(struct ieee80211_local *local,
 442                                        u32 value)
 443{
 444        int ret = 0;
 445
 446        might_sleep();
 447
 448        trace_drv_set_rts_threshold(local, value);
 449        if (local->ops->set_rts_threshold)
 450                ret = local->ops->set_rts_threshold(&local->hw, value);
 451        trace_drv_return_int(local, ret);
 452        return ret;
 453}
 454
 455static inline int drv_set_coverage_class(struct ieee80211_local *local,
 456                                         u8 value)
 457{
 458        int ret = 0;
 459        might_sleep();
 460
 461        trace_drv_set_coverage_class(local, value);
 462        if (local->ops->set_coverage_class)
 463                local->ops->set_coverage_class(&local->hw, value);
 464        else
 465                ret = -EOPNOTSUPP;
 466
 467        trace_drv_return_int(local, ret);
 468        return ret;
 469}
 470
 471static inline void drv_sta_notify(struct ieee80211_local *local,
 472                                  struct ieee80211_sub_if_data *sdata,
 473                                  enum sta_notify_cmd cmd,
 474                                  struct ieee80211_sta *sta)
 475{
 476        sdata = get_bss_sdata(sdata);
 477        check_sdata_in_driver(sdata);
 478
 479        trace_drv_sta_notify(local, sdata, cmd, sta);
 480        if (local->ops->sta_notify)
 481                local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta);
 482        trace_drv_return_void(local);
 483}
 484
 485static inline int drv_sta_add(struct ieee80211_local *local,
 486                              struct ieee80211_sub_if_data *sdata,
 487                              struct ieee80211_sta *sta)
 488{
 489        int ret = 0;
 490
 491        might_sleep();
 492
 493        sdata = get_bss_sdata(sdata);
 494        check_sdata_in_driver(sdata);
 495
 496        trace_drv_sta_add(local, sdata, sta);
 497        if (local->ops->sta_add)
 498                ret = local->ops->sta_add(&local->hw, &sdata->vif, sta);
 499
 500        trace_drv_return_int(local, ret);
 501
 502        return ret;
 503}
 504
 505static inline void drv_sta_remove(struct ieee80211_local *local,
 506                                  struct ieee80211_sub_if_data *sdata,
 507                                  struct ieee80211_sta *sta)
 508{
 509        might_sleep();
 510
 511        sdata = get_bss_sdata(sdata);
 512        check_sdata_in_driver(sdata);
 513
 514        trace_drv_sta_remove(local, sdata, sta);
 515        if (local->ops->sta_remove)
 516                local->ops->sta_remove(&local->hw, &sdata->vif, sta);
 517
 518        trace_drv_return_void(local);
 519}
 520
 521#ifdef CONFIG_MAC80211_DEBUGFS
 522static inline void drv_sta_add_debugfs(struct ieee80211_local *local,
 523                                       struct ieee80211_sub_if_data *sdata,
 524                                       struct ieee80211_sta *sta,
 525                                       struct dentry *dir)
 526{
 527        might_sleep();
 528
 529        sdata = get_bss_sdata(sdata);
 530        check_sdata_in_driver(sdata);
 531
 532        if (local->ops->sta_add_debugfs)
 533                local->ops->sta_add_debugfs(&local->hw, &sdata->vif,
 534                                            sta, dir);
 535}
 536
 537static inline void drv_sta_remove_debugfs(struct ieee80211_local *local,
 538                                          struct ieee80211_sub_if_data *sdata,
 539                                          struct ieee80211_sta *sta,
 540                                          struct dentry *dir)
 541{
 542        might_sleep();
 543
 544        sdata = get_bss_sdata(sdata);
 545        check_sdata_in_driver(sdata);
 546
 547        if (local->ops->sta_remove_debugfs)
 548                local->ops->sta_remove_debugfs(&local->hw, &sdata->vif,
 549                                               sta, dir);
 550}
 551#endif
 552
 553static inline __must_check
 554int drv_sta_state(struct ieee80211_local *local,
 555                  struct ieee80211_sub_if_data *sdata,
 556                  struct sta_info *sta,
 557                  enum ieee80211_sta_state old_state,
 558                  enum ieee80211_sta_state new_state)
 559{
 560        int ret = 0;
 561
 562        might_sleep();
 563
 564        sdata = get_bss_sdata(sdata);
 565        check_sdata_in_driver(sdata);
 566
 567        trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state);
 568        if (local->ops->sta_state) {
 569                ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta,
 570                                            old_state, new_state);
 571        } else if (old_state == IEEE80211_STA_AUTH &&
 572                   new_state == IEEE80211_STA_ASSOC) {
 573                ret = drv_sta_add(local, sdata, &sta->sta);
 574                if (ret == 0)
 575                        sta->uploaded = true;
 576        } else if (old_state == IEEE80211_STA_ASSOC &&
 577                   new_state == IEEE80211_STA_AUTH) {
 578                drv_sta_remove(local, sdata, &sta->sta);
 579        }
 580        trace_drv_return_int(local, ret);
 581        return ret;
 582}
 583
 584static inline void drv_sta_rc_update(struct ieee80211_local *local,
 585                                     struct ieee80211_sub_if_data *sdata,
 586                                     struct ieee80211_sta *sta, u32 changed)
 587{
 588        sdata = get_bss_sdata(sdata);
 589        check_sdata_in_driver(sdata);
 590
 591        WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED &&
 592                (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
 593                 sdata->vif.type != NL80211_IFTYPE_MESH_POINT));
 594
 595        trace_drv_sta_rc_update(local, sdata, sta, changed);
 596        if (local->ops->sta_rc_update)
 597                local->ops->sta_rc_update(&local->hw, &sdata->vif,
 598                                          sta, changed);
 599
 600        trace_drv_return_void(local);
 601}
 602
 603static inline int drv_conf_tx(struct ieee80211_local *local,
 604                              struct ieee80211_sub_if_data *sdata, u16 ac,
 605                              const struct ieee80211_tx_queue_params *params)
 606{
 607        int ret = -EOPNOTSUPP;
 608
 609        might_sleep();
 610
 611        check_sdata_in_driver(sdata);
 612
 613        trace_drv_conf_tx(local, sdata, ac, params);
 614        if (local->ops->conf_tx)
 615                ret = local->ops->conf_tx(&local->hw, &sdata->vif,
 616                                          ac, params);
 617        trace_drv_return_int(local, ret);
 618        return ret;
 619}
 620
 621static inline u64 drv_get_tsf(struct ieee80211_local *local,
 622                              struct ieee80211_sub_if_data *sdata)
 623{
 624        u64 ret = -1ULL;
 625
 626        might_sleep();
 627
 628        check_sdata_in_driver(sdata);
 629
 630        trace_drv_get_tsf(local, sdata);
 631        if (local->ops->get_tsf)
 632                ret = local->ops->get_tsf(&local->hw, &sdata->vif);
 633        trace_drv_return_u64(local, ret);
 634        return ret;
 635}
 636
 637static inline void drv_set_tsf(struct ieee80211_local *local,
 638                               struct ieee80211_sub_if_data *sdata,
 639                               u64 tsf)
 640{
 641        might_sleep();
 642
 643        check_sdata_in_driver(sdata);
 644
 645        trace_drv_set_tsf(local, sdata, tsf);
 646        if (local->ops->set_tsf)
 647                local->ops->set_tsf(&local->hw, &sdata->vif, tsf);
 648        trace_drv_return_void(local);
 649}
 650
 651static inline void drv_reset_tsf(struct ieee80211_local *local,
 652                                 struct ieee80211_sub_if_data *sdata)
 653{
 654        might_sleep();
 655
 656        check_sdata_in_driver(sdata);
 657
 658        trace_drv_reset_tsf(local, sdata);
 659        if (local->ops->reset_tsf)
 660                local->ops->reset_tsf(&local->hw, &sdata->vif);
 661        trace_drv_return_void(local);
 662}
 663
 664static inline int drv_tx_last_beacon(struct ieee80211_local *local)
 665{
 666        int ret = 0; /* default unsupported op for less congestion */
 667
 668        might_sleep();
 669
 670        trace_drv_tx_last_beacon(local);
 671        if (local->ops->tx_last_beacon)
 672                ret = local->ops->tx_last_beacon(&local->hw);
 673        trace_drv_return_int(local, ret);
 674        return ret;
 675}
 676
 677static inline int drv_ampdu_action(struct ieee80211_local *local,
 678                                   struct ieee80211_sub_if_data *sdata,
 679                                   enum ieee80211_ampdu_mlme_action action,
 680                                   struct ieee80211_sta *sta, u16 tid,
 681                                   u16 *ssn, u8 buf_size)
 682{
 683        int ret = -EOPNOTSUPP;
 684
 685        might_sleep();
 686
 687        sdata = get_bss_sdata(sdata);
 688        check_sdata_in_driver(sdata);
 689
 690        trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size);
 691
 692        if (local->ops->ampdu_action)
 693                ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
 694                                               sta, tid, ssn, buf_size);
 695
 696        trace_drv_return_int(local, ret);
 697
 698        return ret;
 699}
 700
 701static inline int drv_get_survey(struct ieee80211_local *local, int idx,
 702                                struct survey_info *survey)
 703{
 704        int ret = -EOPNOTSUPP;
 705
 706        trace_drv_get_survey(local, idx, survey);
 707
 708        if (local->ops->get_survey)
 709                ret = local->ops->get_survey(&local->hw, idx, survey);
 710
 711        trace_drv_return_int(local, ret);
 712
 713        return ret;
 714}
 715
 716static inline void drv_rfkill_poll(struct ieee80211_local *local)
 717{
 718        might_sleep();
 719
 720        if (local->ops->rfkill_poll)
 721                local->ops->rfkill_poll(&local->hw);
 722}
 723
 724static inline void drv_flush(struct ieee80211_local *local,
 725                             u32 queues, bool drop)
 726{
 727        might_sleep();
 728
 729        trace_drv_flush(local, queues, drop);
 730        if (local->ops->flush)
 731                local->ops->flush(&local->hw, queues, drop);
 732        trace_drv_return_void(local);
 733}
 734
 735static inline void drv_channel_switch(struct ieee80211_local *local,
 736                                     struct ieee80211_channel_switch *ch_switch)
 737{
 738        might_sleep();
 739
 740        trace_drv_channel_switch(local, ch_switch);
 741        local->ops->channel_switch(&local->hw, ch_switch);
 742        trace_drv_return_void(local);
 743}
 744
 745
 746static inline int drv_set_antenna(struct ieee80211_local *local,
 747                                  u32 tx_ant, u32 rx_ant)
 748{
 749        int ret = -EOPNOTSUPP;
 750        might_sleep();
 751        if (local->ops->set_antenna)
 752                ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
 753        trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
 754        return ret;
 755}
 756
 757static inline int drv_get_antenna(struct ieee80211_local *local,
 758                                  u32 *tx_ant, u32 *rx_ant)
 759{
 760        int ret = -EOPNOTSUPP;
 761        might_sleep();
 762        if (local->ops->get_antenna)
 763                ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
 764        trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
 765        return ret;
 766}
 767
 768static inline int drv_remain_on_channel(struct ieee80211_local *local,
 769                                        struct ieee80211_sub_if_data *sdata,
 770                                        struct ieee80211_channel *chan,
 771                                        unsigned int duration,
 772                                        enum ieee80211_roc_type type)
 773{
 774        int ret;
 775
 776        might_sleep();
 777
 778        trace_drv_remain_on_channel(local, sdata, chan, duration, type);
 779        ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
 780                                            chan, duration, type);
 781        trace_drv_return_int(local, ret);
 782
 783        return ret;
 784}
 785
 786static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local)
 787{
 788        int ret;
 789
 790        might_sleep();
 791
 792        trace_drv_cancel_remain_on_channel(local);
 793        ret = local->ops->cancel_remain_on_channel(&local->hw);
 794        trace_drv_return_int(local, ret);
 795
 796        return ret;
 797}
 798
 799static inline int drv_set_ringparam(struct ieee80211_local *local,
 800                                    u32 tx, u32 rx)
 801{
 802        int ret = -ENOTSUPP;
 803
 804        might_sleep();
 805
 806        trace_drv_set_ringparam(local, tx, rx);
 807        if (local->ops->set_ringparam)
 808                ret = local->ops->set_ringparam(&local->hw, tx, rx);
 809        trace_drv_return_int(local, ret);
 810
 811        return ret;
 812}
 813
 814static inline void drv_get_ringparam(struct ieee80211_local *local,
 815                                     u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
 816{
 817        might_sleep();
 818
 819        trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
 820        if (local->ops->get_ringparam)
 821                local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
 822        trace_drv_return_void(local);
 823}
 824
 825static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
 826{
 827        bool ret = false;
 828
 829        might_sleep();
 830
 831        trace_drv_tx_frames_pending(local);
 832        if (local->ops->tx_frames_pending)
 833                ret = local->ops->tx_frames_pending(&local->hw);
 834        trace_drv_return_bool(local, ret);
 835
 836        return ret;
 837}
 838
 839static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
 840                                       struct ieee80211_sub_if_data *sdata,
 841                                       const struct cfg80211_bitrate_mask *mask)
 842{
 843        int ret = -EOPNOTSUPP;
 844
 845        might_sleep();
 846
 847        check_sdata_in_driver(sdata);
 848
 849        trace_drv_set_bitrate_mask(local, sdata, mask);
 850        if (local->ops->set_bitrate_mask)
 851                ret = local->ops->set_bitrate_mask(&local->hw,
 852                                                   &sdata->vif, mask);
 853        trace_drv_return_int(local, ret);
 854
 855        return ret;
 856}
 857
 858static inline void drv_set_rekey_data(struct ieee80211_local *local,
 859                                      struct ieee80211_sub_if_data *sdata,
 860                                      struct cfg80211_gtk_rekey_data *data)
 861{
 862        check_sdata_in_driver(sdata);
 863
 864        trace_drv_set_rekey_data(local, sdata, data);
 865        if (local->ops->set_rekey_data)
 866                local->ops->set_rekey_data(&local->hw, &sdata->vif, data);
 867        trace_drv_return_void(local);
 868}
 869
 870static inline void drv_rssi_callback(struct ieee80211_local *local,
 871                                     struct ieee80211_sub_if_data *sdata,
 872                                     const enum ieee80211_rssi_event event)
 873{
 874        trace_drv_rssi_callback(local, sdata, event);
 875        if (local->ops->rssi_callback)
 876                local->ops->rssi_callback(&local->hw, &sdata->vif, event);
 877        trace_drv_return_void(local);
 878}
 879
 880static inline void
 881drv_release_buffered_frames(struct ieee80211_local *local,
 882                            struct sta_info *sta, u16 tids, int num_frames,
 883                            enum ieee80211_frame_release_type reason,
 884                            bool more_data)
 885{
 886        trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
 887                                          reason, more_data);
 888        if (local->ops->release_buffered_frames)
 889                local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
 890                                                    num_frames, reason,
 891                                                    more_data);
 892        trace_drv_return_void(local);
 893}
 894
 895static inline void
 896drv_allow_buffered_frames(struct ieee80211_local *local,
 897                          struct sta_info *sta, u16 tids, int num_frames,
 898                          enum ieee80211_frame_release_type reason,
 899                          bool more_data)
 900{
 901        trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
 902                                        reason, more_data);
 903        if (local->ops->allow_buffered_frames)
 904                local->ops->allow_buffered_frames(&local->hw, &sta->sta,
 905                                                  tids, num_frames, reason,
 906                                                  more_data);
 907        trace_drv_return_void(local);
 908}
 909
 910static inline int drv_get_rssi(struct ieee80211_local *local,
 911                                struct ieee80211_sub_if_data *sdata,
 912                                struct ieee80211_sta *sta,
 913                                s8 *rssi_dbm)
 914{
 915        int ret;
 916
 917        might_sleep();
 918
 919        ret = local->ops->get_rssi(&local->hw, &sdata->vif, sta, rssi_dbm);
 920        trace_drv_get_rssi(local, sta, *rssi_dbm, ret);
 921
 922        return ret;
 923}
 924
 925static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
 926                                      struct ieee80211_sub_if_data *sdata)
 927{
 928        might_sleep();
 929
 930        check_sdata_in_driver(sdata);
 931        WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
 932
 933        trace_drv_mgd_prepare_tx(local, sdata);
 934        if (local->ops->mgd_prepare_tx)
 935                local->ops->mgd_prepare_tx(&local->hw, &sdata->vif);
 936        trace_drv_return_void(local);
 937}
 938
 939static inline int drv_add_chanctx(struct ieee80211_local *local,
 940                                  struct ieee80211_chanctx *ctx)
 941{
 942        int ret = -EOPNOTSUPP;
 943
 944        trace_drv_add_chanctx(local, ctx);
 945        if (local->ops->add_chanctx)
 946                ret = local->ops->add_chanctx(&local->hw, &ctx->conf);
 947        trace_drv_return_int(local, ret);
 948        if (!ret)
 949                ctx->driver_present = true;
 950
 951        return ret;
 952}
 953
 954static inline void drv_remove_chanctx(struct ieee80211_local *local,
 955                                      struct ieee80211_chanctx *ctx)
 956{
 957        trace_drv_remove_chanctx(local, ctx);
 958        if (local->ops->remove_chanctx)
 959                local->ops->remove_chanctx(&local->hw, &ctx->conf);
 960        trace_drv_return_void(local);
 961        ctx->driver_present = false;
 962}
 963
 964static inline void drv_change_chanctx(struct ieee80211_local *local,
 965                                      struct ieee80211_chanctx *ctx,
 966                                      u32 changed)
 967{
 968        trace_drv_change_chanctx(local, ctx, changed);
 969        if (local->ops->change_chanctx) {
 970                WARN_ON_ONCE(!ctx->driver_present);
 971                local->ops->change_chanctx(&local->hw, &ctx->conf, changed);
 972        }
 973        trace_drv_return_void(local);
 974}
 975
 976static inline int drv_assign_vif_chanctx(struct ieee80211_local *local,
 977                                         struct ieee80211_sub_if_data *sdata,
 978                                         struct ieee80211_chanctx *ctx)
 979{
 980        int ret = 0;
 981
 982        check_sdata_in_driver(sdata);
 983
 984        trace_drv_assign_vif_chanctx(local, sdata, ctx);
 985        if (local->ops->assign_vif_chanctx) {
 986                WARN_ON_ONCE(!ctx->driver_present);
 987                ret = local->ops->assign_vif_chanctx(&local->hw,
 988                                                     &sdata->vif,
 989                                                     &ctx->conf);
 990        }
 991        trace_drv_return_int(local, ret);
 992
 993        return ret;
 994}
 995
 996static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
 997                                            struct ieee80211_sub_if_data *sdata,
 998                                            struct ieee80211_chanctx *ctx)
 999{
1000        check_sdata_in_driver(sdata);
1001
1002        trace_drv_unassign_vif_chanctx(local, sdata, ctx);
1003        if (local->ops->unassign_vif_chanctx) {
1004                WARN_ON_ONCE(!ctx->driver_present);
1005                local->ops->unassign_vif_chanctx(&local->hw,
1006                                                 &sdata->vif,
1007                                                 &ctx->conf);
1008        }
1009        trace_drv_return_void(local);
1010}
1011
1012static inline int drv_start_ap(struct ieee80211_local *local,
1013                               struct ieee80211_sub_if_data *sdata)
1014{
1015        int ret = 0;
1016
1017        check_sdata_in_driver(sdata);
1018
1019        trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf);
1020        if (local->ops->start_ap)
1021                ret = local->ops->start_ap(&local->hw, &sdata->vif);
1022        trace_drv_return_int(local, ret);
1023        return ret;
1024}
1025
1026static inline void drv_stop_ap(struct ieee80211_local *local,
1027                               struct ieee80211_sub_if_data *sdata)
1028{
1029        check_sdata_in_driver(sdata);
1030
1031        trace_drv_stop_ap(local, sdata);
1032        if (local->ops->stop_ap)
1033                local->ops->stop_ap(&local->hw, &sdata->vif);
1034        trace_drv_return_void(local);
1035}
1036
1037static inline void drv_restart_complete(struct ieee80211_local *local)
1038{
1039        might_sleep();
1040
1041        trace_drv_restart_complete(local);
1042        if (local->ops->restart_complete)
1043                local->ops->restart_complete(&local->hw);
1044        trace_drv_return_void(local);
1045}
1046
1047static inline void
1048drv_set_default_unicast_key(struct ieee80211_local *local,
1049                            struct ieee80211_sub_if_data *sdata,
1050                            int key_idx)
1051{
1052        check_sdata_in_driver(sdata);
1053
1054        WARN_ON_ONCE(key_idx < -1 || key_idx > 3);
1055
1056        trace_drv_set_default_unicast_key(local, sdata, key_idx);
1057        if (local->ops->set_default_unicast_key)
1058                local->ops->set_default_unicast_key(&local->hw, &sdata->vif,
1059                                                    key_idx);
1060        trace_drv_return_void(local);
1061}
1062
1063#if IS_ENABLED(CONFIG_IPV6)
1064static inline void drv_ipv6_addr_change(struct ieee80211_local *local,
1065                                        struct ieee80211_sub_if_data *sdata,
1066                                        struct inet6_dev *idev)
1067{
1068        trace_drv_ipv6_addr_change(local, sdata);
1069        if (local->ops->ipv6_addr_change)
1070                local->ops->ipv6_addr_change(&local->hw, &sdata->vif, idev);
1071        trace_drv_return_void(local);
1072}
1073#endif
1074
1075static inline void
1076drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata,
1077                          struct cfg80211_chan_def *chandef)
1078{
1079        struct ieee80211_local *local = sdata->local;
1080
1081        if (local->ops->channel_switch_beacon) {
1082                trace_drv_channel_switch_beacon(local, sdata, chandef);
1083                local->ops->channel_switch_beacon(&local->hw, &sdata->vif,
1084                                                  chandef);
1085        }
1086}
1087
1088#endif /* __MAC80211_DRIVER_OPS */
1089