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