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