blob: b12ed52732c814b976bfc0084e680782faf5442d [file] [log] [blame]
Johannes Berg24487982009-04-23 18:52:52 +02001#ifndef __MAC80211_DRIVER_OPS
2#define __MAC80211_DRIVER_OPS
3
4#include <net/mac80211.h>
5#include "ieee80211_i.h"
Johannes Berg0a2b8bb2009-07-07 13:46:22 +02006#include "driver-trace.h"
Johannes Berg24487982009-04-23 18:52:52 +02007
Johannes Berg7b7eab62011-11-03 14:41:13 +01008static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata)
9{
10 WARN_ON(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER));
11}
12
Johannes Berg7bb45682011-02-24 14:42:06 +010013static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb)
Johannes Berg24487982009-04-23 18:52:52 +020014{
Johannes Berg7bb45682011-02-24 14:42:06 +010015 local->ops->tx(&local->hw, skb);
Johannes Berg24487982009-04-23 18:52:52 +020016}
17
18static inline int drv_start(struct ieee80211_local *local)
19{
Johannes Bergea77f122009-08-21 14:44:45 +020020 int ret;
21
Kalle Valoe1781ed2009-12-23 13:15:47 +010022 might_sleep();
23
Johannes Berg4efc76b2010-06-10 10:56:20 +020024 trace_drv_start(local);
Johannes Bergea77f122009-08-21 14:44:45 +020025 local->started = true;
26 smp_mb();
27 ret = local->ops->start(&local->hw);
Johannes Berg4efc76b2010-06-10 10:56:20 +020028 trace_drv_return_int(local, ret);
Johannes Berg0a2b8bb2009-07-07 13:46:22 +020029 return ret;
Johannes Berg24487982009-04-23 18:52:52 +020030}
31
32static inline void drv_stop(struct ieee80211_local *local)
33{
Kalle Valoe1781ed2009-12-23 13:15:47 +010034 might_sleep();
35
Johannes Berg0a2b8bb2009-07-07 13:46:22 +020036 trace_drv_stop(local);
Johannes Berg4efc76b2010-06-10 10:56:20 +020037 local->ops->stop(&local->hw);
38 trace_drv_return_void(local);
Johannes Bergea77f122009-08-21 14:44:45 +020039
40 /* sync away all work on the tasklet before clearing started */
41 tasklet_disable(&local->tasklet);
42 tasklet_enable(&local->tasklet);
43
44 barrier();
45
46 local->started = false;
Johannes Berg24487982009-04-23 18:52:52 +020047}
48
Johannes Bergeecc4802011-05-04 15:37:29 +020049#ifdef CONFIG_PM
50static inline int drv_suspend(struct ieee80211_local *local,
51 struct cfg80211_wowlan *wowlan)
52{
53 int ret;
54
55 might_sleep();
56
57 trace_drv_suspend(local);
58 ret = local->ops->suspend(&local->hw, wowlan);
59 trace_drv_return_int(local, ret);
60 return ret;
61}
62
63static inline int drv_resume(struct ieee80211_local *local)
64{
65 int ret;
66
67 might_sleep();
68
69 trace_drv_resume(local);
70 ret = local->ops->resume(&local->hw);
71 trace_drv_return_int(local, ret);
72 return ret;
73}
74#endif
75
Johannes Berg24487982009-04-23 18:52:52 +020076static inline int drv_add_interface(struct ieee80211_local *local,
Johannes Berg7b7eab62011-11-03 14:41:13 +010077 struct ieee80211_sub_if_data *sdata)
Johannes Berg24487982009-04-23 18:52:52 +020078{
Kalle Valoe1781ed2009-12-23 13:15:47 +010079 int ret;
80
81 might_sleep();
82
Johannes Berg7b7eab62011-11-03 14:41:13 +010083 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
84 sdata->vif.type == NL80211_IFTYPE_MONITOR))
85 return -EINVAL;
86
87 trace_drv_add_interface(local, sdata);
88 ret = local->ops->add_interface(&local->hw, &sdata->vif);
Johannes Berg4efc76b2010-06-10 10:56:20 +020089 trace_drv_return_int(local, ret);
Johannes Berg7b7eab62011-11-03 14:41:13 +010090
91 if (ret == 0)
92 sdata->flags |= IEEE80211_SDATA_IN_DRIVER;
93
Johannes Berg0a2b8bb2009-07-07 13:46:22 +020094 return ret;
Johannes Berg24487982009-04-23 18:52:52 +020095}
96
Johannes Berg34d4bc42010-08-27 12:35:58 +020097static inline int drv_change_interface(struct ieee80211_local *local,
98 struct ieee80211_sub_if_data *sdata,
Johannes Berg2ca27bc2010-09-16 14:58:23 +020099 enum nl80211_iftype type, bool p2p)
Johannes Berg34d4bc42010-08-27 12:35:58 +0200100{
101 int ret;
102
103 might_sleep();
104
Johannes Berg7b7eab62011-11-03 14:41:13 +0100105 check_sdata_in_driver(sdata);
106
Johannes Berg2ca27bc2010-09-16 14:58:23 +0200107 trace_drv_change_interface(local, sdata, type, p2p);
108 ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p);
Johannes Berg34d4bc42010-08-27 12:35:58 +0200109 trace_drv_return_int(local, ret);
110 return ret;
111}
112
Johannes Berg24487982009-04-23 18:52:52 +0200113static inline void drv_remove_interface(struct ieee80211_local *local,
Johannes Berg7b7eab62011-11-03 14:41:13 +0100114 struct ieee80211_sub_if_data *sdata)
Johannes Berg24487982009-04-23 18:52:52 +0200115{
Kalle Valoe1781ed2009-12-23 13:15:47 +0100116 might_sleep();
117
Johannes Berg7b7eab62011-11-03 14:41:13 +0100118 check_sdata_in_driver(sdata);
119
120 trace_drv_remove_interface(local, sdata);
121 local->ops->remove_interface(&local->hw, &sdata->vif);
122 sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER;
Johannes Berg4efc76b2010-06-10 10:56:20 +0200123 trace_drv_return_void(local);
Johannes Berg24487982009-04-23 18:52:52 +0200124}
125
126static inline int drv_config(struct ieee80211_local *local, u32 changed)
127{
Kalle Valoe1781ed2009-12-23 13:15:47 +0100128 int ret;
129
130 might_sleep();
131
Johannes Berg4efc76b2010-06-10 10:56:20 +0200132 trace_drv_config(local, changed);
Kalle Valoe1781ed2009-12-23 13:15:47 +0100133 ret = local->ops->config(&local->hw, changed);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200134 trace_drv_return_int(local, ret);
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200135 return ret;
Johannes Berg24487982009-04-23 18:52:52 +0200136}
137
138static inline void drv_bss_info_changed(struct ieee80211_local *local,
Johannes Berg12375ef2009-11-25 20:30:31 +0100139 struct ieee80211_sub_if_data *sdata,
Johannes Berg24487982009-04-23 18:52:52 +0200140 struct ieee80211_bss_conf *info,
141 u32 changed)
142{
Kalle Valoe1781ed2009-12-23 13:15:47 +0100143 might_sleep();
144
Johannes Berg7b7eab62011-11-03 14:41:13 +0100145 check_sdata_in_driver(sdata);
146
Johannes Berg4efc76b2010-06-10 10:56:20 +0200147 trace_drv_bss_info_changed(local, sdata, info, changed);
Johannes Berg24487982009-04-23 18:52:52 +0200148 if (local->ops->bss_info_changed)
Johannes Berg12375ef2009-11-25 20:30:31 +0100149 local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200150 trace_drv_return_void(local);
Johannes Berg24487982009-04-23 18:52:52 +0200151}
152
Johannes Bergb2abb6e2011-07-19 10:39:53 +0200153static inline int drv_tx_sync(struct ieee80211_local *local,
154 struct ieee80211_sub_if_data *sdata,
155 const u8 *bssid,
156 enum ieee80211_tx_sync_type type)
157{
158 int ret = 0;
159
160 might_sleep();
161
Johannes Berg7b7eab62011-11-03 14:41:13 +0100162 check_sdata_in_driver(sdata);
163
Johannes Bergb2abb6e2011-07-19 10:39:53 +0200164 trace_drv_tx_sync(local, sdata, bssid, type);
165 if (local->ops->tx_sync)
166 ret = local->ops->tx_sync(&local->hw, &sdata->vif,
167 bssid, type);
168 trace_drv_return_int(local, ret);
169 return ret;
170}
171
172static inline void drv_finish_tx_sync(struct ieee80211_local *local,
173 struct ieee80211_sub_if_data *sdata,
174 const u8 *bssid,
175 enum ieee80211_tx_sync_type type)
176{
177 might_sleep();
178
Johannes Berg7b7eab62011-11-03 14:41:13 +0100179 check_sdata_in_driver(sdata);
180
Johannes Bergb2abb6e2011-07-19 10:39:53 +0200181 trace_drv_finish_tx_sync(local, sdata, bssid, type);
182 if (local->ops->finish_tx_sync)
183 local->ops->finish_tx_sync(&local->hw, &sdata->vif,
184 bssid, type);
185 trace_drv_return_void(local);
186}
187
Johannes Berg3ac64be2009-08-17 16:16:53 +0200188static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
Jiri Pirko22bedad2010-04-01 21:22:57 +0000189 struct netdev_hw_addr_list *mc_list)
Johannes Berg24487982009-04-23 18:52:52 +0200190{
Johannes Berg3ac64be2009-08-17 16:16:53 +0200191 u64 ret = 0;
192
Johannes Berg4efc76b2010-06-10 10:56:20 +0200193 trace_drv_prepare_multicast(local, mc_list->count);
194
Johannes Berg3ac64be2009-08-17 16:16:53 +0200195 if (local->ops->prepare_multicast)
Jiri Pirko22bedad2010-04-01 21:22:57 +0000196 ret = local->ops->prepare_multicast(&local->hw, mc_list);
Johannes Berg3ac64be2009-08-17 16:16:53 +0200197
Johannes Berg4efc76b2010-06-10 10:56:20 +0200198 trace_drv_return_u64(local, ret);
Johannes Berg3ac64be2009-08-17 16:16:53 +0200199
200 return ret;
201}
202
203static inline void drv_configure_filter(struct ieee80211_local *local,
204 unsigned int changed_flags,
205 unsigned int *total_flags,
206 u64 multicast)
207{
208 might_sleep();
209
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200210 trace_drv_configure_filter(local, changed_flags, total_flags,
Johannes Berg3ac64be2009-08-17 16:16:53 +0200211 multicast);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200212 local->ops->configure_filter(&local->hw, changed_flags, total_flags,
213 multicast);
214 trace_drv_return_void(local);
Johannes Berg24487982009-04-23 18:52:52 +0200215}
216
217static inline int drv_set_tim(struct ieee80211_local *local,
218 struct ieee80211_sta *sta, bool set)
219{
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200220 int ret = 0;
Johannes Berg4efc76b2010-06-10 10:56:20 +0200221 trace_drv_set_tim(local, sta, set);
Johannes Berg24487982009-04-23 18:52:52 +0200222 if (local->ops->set_tim)
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200223 ret = local->ops->set_tim(&local->hw, sta, set);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200224 trace_drv_return_int(local, ret);
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200225 return ret;
Johannes Berg24487982009-04-23 18:52:52 +0200226}
227
228static inline int drv_set_key(struct ieee80211_local *local,
Johannes Berg12375ef2009-11-25 20:30:31 +0100229 enum set_key_cmd cmd,
230 struct ieee80211_sub_if_data *sdata,
Johannes Berg24487982009-04-23 18:52:52 +0200231 struct ieee80211_sta *sta,
232 struct ieee80211_key_conf *key)
233{
Kalle Valoe1781ed2009-12-23 13:15:47 +0100234 int ret;
235
236 might_sleep();
237
Johannes Berg7b7eab62011-11-03 14:41:13 +0100238 check_sdata_in_driver(sdata);
239
Johannes Berg4efc76b2010-06-10 10:56:20 +0200240 trace_drv_set_key(local, cmd, sdata, sta, key);
Kalle Valoe1781ed2009-12-23 13:15:47 +0100241 ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200242 trace_drv_return_int(local, ret);
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200243 return ret;
Johannes Berg24487982009-04-23 18:52:52 +0200244}
245
246static inline void drv_update_tkip_key(struct ieee80211_local *local,
Johannes Bergb3fbdcf2010-01-21 11:40:47 +0100247 struct ieee80211_sub_if_data *sdata,
Johannes Berg24487982009-04-23 18:52:52 +0200248 struct ieee80211_key_conf *conf,
Johannes Bergb3fbdcf2010-01-21 11:40:47 +0100249 struct sta_info *sta, u32 iv32,
Johannes Berg24487982009-04-23 18:52:52 +0200250 u16 *phase1key)
251{
Johannes Bergb3fbdcf2010-01-21 11:40:47 +0100252 struct ieee80211_sta *ista = NULL;
253
Johannes Bergb3fbdcf2010-01-21 11:40:47 +0100254 if (sta)
255 ista = &sta->sta;
256
Johannes Berg7b7eab62011-11-03 14:41:13 +0100257 check_sdata_in_driver(sdata);
258
Johannes Berg4efc76b2010-06-10 10:56:20 +0200259 trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
Johannes Berg24487982009-04-23 18:52:52 +0200260 if (local->ops->update_tkip_key)
Johannes Bergb3fbdcf2010-01-21 11:40:47 +0100261 local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
262 ista, iv32, phase1key);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200263 trace_drv_return_void(local);
Johannes Berg24487982009-04-23 18:52:52 +0200264}
265
266static inline int drv_hw_scan(struct ieee80211_local *local,
Johannes Berga060bbf2010-04-27 11:59:34 +0200267 struct ieee80211_sub_if_data *sdata,
Johannes Berg24487982009-04-23 18:52:52 +0200268 struct cfg80211_scan_request *req)
269{
Kalle Valoe1781ed2009-12-23 13:15:47 +0100270 int ret;
271
272 might_sleep();
273
Johannes Berg7b7eab62011-11-03 14:41:13 +0100274 check_sdata_in_driver(sdata);
275
Luciano Coelho79f460c2011-05-11 17:09:36 +0300276 trace_drv_hw_scan(local, sdata);
Johannes Berga060bbf2010-04-27 11:59:34 +0200277 ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200278 trace_drv_return_int(local, ret);
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200279 return ret;
Johannes Berg24487982009-04-23 18:52:52 +0200280}
281
Eliad Pellerb8564392011-06-13 12:47:30 +0300282static inline void drv_cancel_hw_scan(struct ieee80211_local *local,
283 struct ieee80211_sub_if_data *sdata)
284{
285 might_sleep();
286
Johannes Berg7b7eab62011-11-03 14:41:13 +0100287 check_sdata_in_driver(sdata);
288
Eliad Pellerb8564392011-06-13 12:47:30 +0300289 trace_drv_cancel_hw_scan(local, sdata);
290 local->ops->cancel_hw_scan(&local->hw, &sdata->vif);
291 trace_drv_return_void(local);
292}
293
Luciano Coelho79f460c2011-05-11 17:09:36 +0300294static inline int
295drv_sched_scan_start(struct ieee80211_local *local,
296 struct ieee80211_sub_if_data *sdata,
297 struct cfg80211_sched_scan_request *req,
298 struct ieee80211_sched_scan_ies *ies)
299{
300 int ret;
301
302 might_sleep();
303
Johannes Berg7b7eab62011-11-03 14:41:13 +0100304 check_sdata_in_driver(sdata);
305
Luciano Coelho79f460c2011-05-11 17:09:36 +0300306 trace_drv_sched_scan_start(local, sdata);
307 ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
308 req, ies);
309 trace_drv_return_int(local, ret);
310 return ret;
311}
312
313static inline void drv_sched_scan_stop(struct ieee80211_local *local,
314 struct ieee80211_sub_if_data *sdata)
315{
316 might_sleep();
317
Johannes Berg7b7eab62011-11-03 14:41:13 +0100318 check_sdata_in_driver(sdata);
319
Luciano Coelho79f460c2011-05-11 17:09:36 +0300320 trace_drv_sched_scan_stop(local, sdata);
321 local->ops->sched_scan_stop(&local->hw, &sdata->vif);
322 trace_drv_return_void(local);
323}
324
Johannes Berg24487982009-04-23 18:52:52 +0200325static inline void drv_sw_scan_start(struct ieee80211_local *local)
326{
Kalle Valoe1781ed2009-12-23 13:15:47 +0100327 might_sleep();
328
Johannes Berg4efc76b2010-06-10 10:56:20 +0200329 trace_drv_sw_scan_start(local);
Johannes Berg24487982009-04-23 18:52:52 +0200330 if (local->ops->sw_scan_start)
331 local->ops->sw_scan_start(&local->hw);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200332 trace_drv_return_void(local);
Johannes Berg24487982009-04-23 18:52:52 +0200333}
334
335static inline void drv_sw_scan_complete(struct ieee80211_local *local)
336{
Kalle Valoe1781ed2009-12-23 13:15:47 +0100337 might_sleep();
338
Johannes Berg4efc76b2010-06-10 10:56:20 +0200339 trace_drv_sw_scan_complete(local);
Johannes Berg24487982009-04-23 18:52:52 +0200340 if (local->ops->sw_scan_complete)
341 local->ops->sw_scan_complete(&local->hw);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200342 trace_drv_return_void(local);
Johannes Berg24487982009-04-23 18:52:52 +0200343}
344
345static inline int drv_get_stats(struct ieee80211_local *local,
346 struct ieee80211_low_level_stats *stats)
347{
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200348 int ret = -EOPNOTSUPP;
349
Kalle Valoe1781ed2009-12-23 13:15:47 +0100350 might_sleep();
351
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200352 if (local->ops->get_stats)
353 ret = local->ops->get_stats(&local->hw, stats);
354 trace_drv_get_stats(local, stats, ret);
355
356 return ret;
Johannes Berg24487982009-04-23 18:52:52 +0200357}
358
359static inline void drv_get_tkip_seq(struct ieee80211_local *local,
360 u8 hw_key_idx, u32 *iv32, u16 *iv16)
361{
362 if (local->ops->get_tkip_seq)
363 local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16);
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200364 trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16);
Johannes Berg24487982009-04-23 18:52:52 +0200365}
366
Arik Nemtsovf23a4782010-11-08 11:51:06 +0200367static inline int drv_set_frag_threshold(struct ieee80211_local *local,
368 u32 value)
369{
370 int ret = 0;
371
372 might_sleep();
373
374 trace_drv_set_frag_threshold(local, value);
375 if (local->ops->set_frag_threshold)
376 ret = local->ops->set_frag_threshold(&local->hw, value);
377 trace_drv_return_int(local, ret);
378 return ret;
379}
380
Johannes Berg24487982009-04-23 18:52:52 +0200381static inline int drv_set_rts_threshold(struct ieee80211_local *local,
382 u32 value)
383{
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200384 int ret = 0;
Kalle Valoe1781ed2009-12-23 13:15:47 +0100385
386 might_sleep();
387
Johannes Berg4efc76b2010-06-10 10:56:20 +0200388 trace_drv_set_rts_threshold(local, value);
Johannes Berg24487982009-04-23 18:52:52 +0200389 if (local->ops->set_rts_threshold)
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200390 ret = local->ops->set_rts_threshold(&local->hw, value);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200391 trace_drv_return_int(local, ret);
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200392 return ret;
Johannes Berg24487982009-04-23 18:52:52 +0200393}
394
Lukáš Turek310bc672009-12-21 22:50:48 +0100395static inline int drv_set_coverage_class(struct ieee80211_local *local,
396 u8 value)
397{
398 int ret = 0;
399 might_sleep();
400
Johannes Berg4efc76b2010-06-10 10:56:20 +0200401 trace_drv_set_coverage_class(local, value);
Lukáš Turek310bc672009-12-21 22:50:48 +0100402 if (local->ops->set_coverage_class)
403 local->ops->set_coverage_class(&local->hw, value);
404 else
405 ret = -EOPNOTSUPP;
406
Johannes Berg4efc76b2010-06-10 10:56:20 +0200407 trace_drv_return_int(local, ret);
Lukáš Turek310bc672009-12-21 22:50:48 +0100408 return ret;
409}
410
Johannes Berg24487982009-04-23 18:52:52 +0200411static inline void drv_sta_notify(struct ieee80211_local *local,
Johannes Berg12375ef2009-11-25 20:30:31 +0100412 struct ieee80211_sub_if_data *sdata,
Johannes Berg24487982009-04-23 18:52:52 +0200413 enum sta_notify_cmd cmd,
414 struct ieee80211_sta *sta)
415{
Johannes Berg7b7eab62011-11-03 14:41:13 +0100416 check_sdata_in_driver(sdata);
417
Johannes Berg4efc76b2010-06-10 10:56:20 +0200418 trace_drv_sta_notify(local, sdata, cmd, sta);
Johannes Berg24487982009-04-23 18:52:52 +0200419 if (local->ops->sta_notify)
Johannes Berg12375ef2009-11-25 20:30:31 +0100420 local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200421 trace_drv_return_void(local);
Johannes Berg24487982009-04-23 18:52:52 +0200422}
423
Johannes Berg34e89502010-02-03 13:59:58 +0100424static inline int drv_sta_add(struct ieee80211_local *local,
425 struct ieee80211_sub_if_data *sdata,
426 struct ieee80211_sta *sta)
427{
428 int ret = 0;
429
430 might_sleep();
431
Johannes Berg7b7eab62011-11-03 14:41:13 +0100432 check_sdata_in_driver(sdata);
433
Johannes Berg4efc76b2010-06-10 10:56:20 +0200434 trace_drv_sta_add(local, sdata, sta);
Johannes Berg34e89502010-02-03 13:59:58 +0100435 if (local->ops->sta_add)
436 ret = local->ops->sta_add(&local->hw, &sdata->vif, sta);
Johannes Berg34e89502010-02-03 13:59:58 +0100437
Johannes Berg4efc76b2010-06-10 10:56:20 +0200438 trace_drv_return_int(local, ret);
Johannes Berg34e89502010-02-03 13:59:58 +0100439
440 return ret;
441}
442
443static inline void drv_sta_remove(struct ieee80211_local *local,
444 struct ieee80211_sub_if_data *sdata,
445 struct ieee80211_sta *sta)
446{
447 might_sleep();
448
Johannes Berg7b7eab62011-11-03 14:41:13 +0100449 check_sdata_in_driver(sdata);
450
Johannes Berg4efc76b2010-06-10 10:56:20 +0200451 trace_drv_sta_remove(local, sdata, sta);
Johannes Berg34e89502010-02-03 13:59:58 +0100452 if (local->ops->sta_remove)
453 local->ops->sta_remove(&local->hw, &sdata->vif, sta);
Johannes Berg34e89502010-02-03 13:59:58 +0100454
Johannes Berg4efc76b2010-06-10 10:56:20 +0200455 trace_drv_return_void(local);
Johannes Berg34e89502010-02-03 13:59:58 +0100456}
457
Eliad Pellerf6f3def2011-09-25 20:06:54 +0300458static inline int drv_conf_tx(struct ieee80211_local *local,
459 struct ieee80211_sub_if_data *sdata, u16 queue,
Johannes Berg24487982009-04-23 18:52:52 +0200460 const struct ieee80211_tx_queue_params *params)
461{
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200462 int ret = -EOPNOTSUPP;
Kalle Valoe1781ed2009-12-23 13:15:47 +0100463
464 might_sleep();
465
Johannes Berg7b7eab62011-11-03 14:41:13 +0100466 check_sdata_in_driver(sdata);
467
Eliad Pellerf6f3def2011-09-25 20:06:54 +0300468 trace_drv_conf_tx(local, sdata, queue, params);
Johannes Berg24487982009-04-23 18:52:52 +0200469 if (local->ops->conf_tx)
Eliad Peller8a3a3c82011-10-02 10:15:52 +0200470 ret = local->ops->conf_tx(&local->hw, &sdata->vif,
471 queue, params);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200472 trace_drv_return_int(local, ret);
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200473 return ret;
Johannes Berg24487982009-04-23 18:52:52 +0200474}
475
Eliad Peller37a41b42011-09-21 14:06:11 +0300476static inline u64 drv_get_tsf(struct ieee80211_local *local,
477 struct ieee80211_sub_if_data *sdata)
Johannes Berg24487982009-04-23 18:52:52 +0200478{
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200479 u64 ret = -1ULL;
Kalle Valoe1781ed2009-12-23 13:15:47 +0100480
481 might_sleep();
482
Johannes Berg7b7eab62011-11-03 14:41:13 +0100483 check_sdata_in_driver(sdata);
484
Eliad Peller37a41b42011-09-21 14:06:11 +0300485 trace_drv_get_tsf(local, sdata);
Johannes Berg24487982009-04-23 18:52:52 +0200486 if (local->ops->get_tsf)
Eliad Peller37a41b42011-09-21 14:06:11 +0300487 ret = local->ops->get_tsf(&local->hw, &sdata->vif);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200488 trace_drv_return_u64(local, ret);
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200489 return ret;
Johannes Berg24487982009-04-23 18:52:52 +0200490}
491
Eliad Peller37a41b42011-09-21 14:06:11 +0300492static inline void drv_set_tsf(struct ieee80211_local *local,
493 struct ieee80211_sub_if_data *sdata,
494 u64 tsf)
Johannes Berg24487982009-04-23 18:52:52 +0200495{
Kalle Valoe1781ed2009-12-23 13:15:47 +0100496 might_sleep();
497
Johannes Berg7b7eab62011-11-03 14:41:13 +0100498 check_sdata_in_driver(sdata);
499
Eliad Peller37a41b42011-09-21 14:06:11 +0300500 trace_drv_set_tsf(local, sdata, tsf);
Johannes Berg24487982009-04-23 18:52:52 +0200501 if (local->ops->set_tsf)
Eliad Peller37a41b42011-09-21 14:06:11 +0300502 local->ops->set_tsf(&local->hw, &sdata->vif, tsf);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200503 trace_drv_return_void(local);
Johannes Berg24487982009-04-23 18:52:52 +0200504}
505
Eliad Peller37a41b42011-09-21 14:06:11 +0300506static inline void drv_reset_tsf(struct ieee80211_local *local,
507 struct ieee80211_sub_if_data *sdata)
Johannes Berg24487982009-04-23 18:52:52 +0200508{
Kalle Valoe1781ed2009-12-23 13:15:47 +0100509 might_sleep();
510
Johannes Berg7b7eab62011-11-03 14:41:13 +0100511 check_sdata_in_driver(sdata);
512
Eliad Peller37a41b42011-09-21 14:06:11 +0300513 trace_drv_reset_tsf(local, sdata);
Johannes Berg24487982009-04-23 18:52:52 +0200514 if (local->ops->reset_tsf)
Eliad Peller37a41b42011-09-21 14:06:11 +0300515 local->ops->reset_tsf(&local->hw, &sdata->vif);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200516 trace_drv_return_void(local);
Johannes Berg24487982009-04-23 18:52:52 +0200517}
518
519static inline int drv_tx_last_beacon(struct ieee80211_local *local)
520{
Tim Harvey91f44b02010-12-09 13:15:45 -0800521 int ret = 0; /* default unsuported op for less congestion */
Kalle Valoe1781ed2009-12-23 13:15:47 +0100522
523 might_sleep();
524
Johannes Berg4efc76b2010-06-10 10:56:20 +0200525 trace_drv_tx_last_beacon(local);
Johannes Berg24487982009-04-23 18:52:52 +0200526 if (local->ops->tx_last_beacon)
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200527 ret = local->ops->tx_last_beacon(&local->hw);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200528 trace_drv_return_int(local, ret);
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200529 return ret;
Johannes Berg24487982009-04-23 18:52:52 +0200530}
531
532static inline int drv_ampdu_action(struct ieee80211_local *local,
Johannes Berg12375ef2009-11-25 20:30:31 +0100533 struct ieee80211_sub_if_data *sdata,
Johannes Berg24487982009-04-23 18:52:52 +0200534 enum ieee80211_ampdu_mlme_action action,
535 struct ieee80211_sta *sta, u16 tid,
Johannes Berg0b01f032011-01-18 13:51:05 +0100536 u16 *ssn, u8 buf_size)
Johannes Berg24487982009-04-23 18:52:52 +0200537{
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200538 int ret = -EOPNOTSUPP;
Johannes Bergcfcdbde2010-06-10 10:21:48 +0200539
540 might_sleep();
541
Johannes Berg7b7eab62011-11-03 14:41:13 +0100542 check_sdata_in_driver(sdata);
543
Johannes Berg0b01f032011-01-18 13:51:05 +0100544 trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200545
Johannes Berg24487982009-04-23 18:52:52 +0200546 if (local->ops->ampdu_action)
Johannes Berg12375ef2009-11-25 20:30:31 +0100547 ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
Johannes Berg0b01f032011-01-18 13:51:05 +0100548 sta, tid, ssn, buf_size);
Johannes Berg85ad1812010-06-10 10:21:49 +0200549
Johannes Berg4efc76b2010-06-10 10:56:20 +0200550 trace_drv_return_int(local, ret);
551
Johannes Berg0a2b8bb2009-07-07 13:46:22 +0200552 return ret;
Johannes Berg24487982009-04-23 18:52:52 +0200553}
Johannes Berg1f87f7d2009-06-02 13:01:41 +0200554
Holger Schurig12897232010-04-19 10:23:57 +0200555static inline int drv_get_survey(struct ieee80211_local *local, int idx,
556 struct survey_info *survey)
557{
558 int ret = -EOPNOTSUPP;
John W. Linvillec466d4e2010-06-29 14:51:23 -0400559
560 trace_drv_get_survey(local, idx, survey);
561
Holger Schurig35dd0502010-06-07 16:33:49 +0200562 if (local->ops->get_survey)
Holger Schurig12897232010-04-19 10:23:57 +0200563 ret = local->ops->get_survey(&local->hw, idx, survey);
John W. Linvillec466d4e2010-06-29 14:51:23 -0400564
565 trace_drv_return_int(local, ret);
566
Holger Schurig12897232010-04-19 10:23:57 +0200567 return ret;
568}
Johannes Berg1f87f7d2009-06-02 13:01:41 +0200569
570static inline void drv_rfkill_poll(struct ieee80211_local *local)
571{
Kalle Valoe1781ed2009-12-23 13:15:47 +0100572 might_sleep();
573
Johannes Berg1f87f7d2009-06-02 13:01:41 +0200574 if (local->ops->rfkill_poll)
575 local->ops->rfkill_poll(&local->hw);
576}
Johannes Berga80f7c02009-12-23 13:15:32 +0100577
578static inline void drv_flush(struct ieee80211_local *local, bool drop)
579{
Kalle Valoe1781ed2009-12-23 13:15:47 +0100580 might_sleep();
581
Johannes Berga80f7c02009-12-23 13:15:32 +0100582 trace_drv_flush(local, drop);
583 if (local->ops->flush)
584 local->ops->flush(&local->hw, drop);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200585 trace_drv_return_void(local);
Johannes Berga80f7c02009-12-23 13:15:32 +0100586}
Johannes Berg5ce6e432010-05-11 16:20:57 +0200587
588static inline void drv_channel_switch(struct ieee80211_local *local,
589 struct ieee80211_channel_switch *ch_switch)
590{
591 might_sleep();
592
Johannes Berg5ce6e432010-05-11 16:20:57 +0200593 trace_drv_channel_switch(local, ch_switch);
Johannes Berg4efc76b2010-06-10 10:56:20 +0200594 local->ops->channel_switch(&local->hw, ch_switch);
595 trace_drv_return_void(local);
Johannes Berg5ce6e432010-05-11 16:20:57 +0200596}
597
Bruno Randolf15d96752010-11-10 12:50:56 +0900598
599static inline int drv_set_antenna(struct ieee80211_local *local,
600 u32 tx_ant, u32 rx_ant)
601{
602 int ret = -EOPNOTSUPP;
603 might_sleep();
604 if (local->ops->set_antenna)
605 ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
606 trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
607 return ret;
608}
609
610static inline int drv_get_antenna(struct ieee80211_local *local,
611 u32 *tx_ant, u32 *rx_ant)
612{
613 int ret = -EOPNOTSUPP;
614 might_sleep();
615 if (local->ops->get_antenna)
616 ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
617 trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
618 return ret;
619}
620
Johannes Berg21f83582010-12-18 17:20:47 +0100621static inline int drv_remain_on_channel(struct ieee80211_local *local,
622 struct ieee80211_channel *chan,
623 enum nl80211_channel_type chantype,
624 unsigned int duration)
625{
626 int ret;
627
628 might_sleep();
629
630 trace_drv_remain_on_channel(local, chan, chantype, duration);
631 ret = local->ops->remain_on_channel(&local->hw, chan, chantype,
632 duration);
633 trace_drv_return_int(local, ret);
634
635 return ret;
636}
637
638static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local)
639{
640 int ret;
641
642 might_sleep();
643
644 trace_drv_cancel_remain_on_channel(local);
645 ret = local->ops->cancel_remain_on_channel(&local->hw);
646 trace_drv_return_int(local, ret);
647
648 return ret;
649}
650
John W. Linville38c09152011-03-07 16:19:18 -0500651static inline int drv_set_ringparam(struct ieee80211_local *local,
652 u32 tx, u32 rx)
653{
654 int ret = -ENOTSUPP;
655
656 might_sleep();
657
658 trace_drv_set_ringparam(local, tx, rx);
659 if (local->ops->set_ringparam)
660 ret = local->ops->set_ringparam(&local->hw, tx, rx);
661 trace_drv_return_int(local, ret);
662
663 return ret;
664}
665
666static inline void drv_get_ringparam(struct ieee80211_local *local,
667 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
668{
669 might_sleep();
670
671 trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
672 if (local->ops->get_ringparam)
673 local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
674 trace_drv_return_void(local);
675}
676
Vivek Natarajane8306f92011-04-06 11:41:10 +0530677static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
678{
679 bool ret = false;
680
681 might_sleep();
682
683 trace_drv_tx_frames_pending(local);
684 if (local->ops->tx_frames_pending)
685 ret = local->ops->tx_frames_pending(&local->hw);
686 trace_drv_return_bool(local, ret);
687
688 return ret;
689}
Sujith Manoharanbdbfd6b2011-04-27 16:56:51 +0530690
691static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
692 struct ieee80211_sub_if_data *sdata,
693 const struct cfg80211_bitrate_mask *mask)
694{
695 int ret = -EOPNOTSUPP;
696
697 might_sleep();
698
Johannes Berg7b7eab62011-11-03 14:41:13 +0100699 check_sdata_in_driver(sdata);
700
Sujith Manoharanbdbfd6b2011-04-27 16:56:51 +0530701 trace_drv_set_bitrate_mask(local, sdata, mask);
702 if (local->ops->set_bitrate_mask)
703 ret = local->ops->set_bitrate_mask(&local->hw,
704 &sdata->vif, mask);
705 trace_drv_return_int(local, ret);
706
707 return ret;
708}
709
Johannes Bergc68f4b82011-07-05 16:35:41 +0200710static inline void drv_set_rekey_data(struct ieee80211_local *local,
711 struct ieee80211_sub_if_data *sdata,
712 struct cfg80211_gtk_rekey_data *data)
713{
Johannes Berg7b7eab62011-11-03 14:41:13 +0100714 check_sdata_in_driver(sdata);
715
Johannes Bergc68f4b82011-07-05 16:35:41 +0200716 trace_drv_set_rekey_data(local, sdata, data);
717 if (local->ops->set_rekey_data)
718 local->ops->set_rekey_data(&local->hw, &sdata->vif, data);
719 trace_drv_return_void(local);
720}
721
Meenakshi Venkataraman615f7b92011-07-08 08:46:22 -0700722static inline void drv_rssi_callback(struct ieee80211_local *local,
723 const enum ieee80211_rssi_event event)
724{
725 trace_drv_rssi_callback(local, event);
726 if (local->ops->rssi_callback)
727 local->ops->rssi_callback(&local->hw, event);
728 trace_drv_return_void(local);
729}
Johannes Berg4049e092011-09-29 16:04:32 +0200730
731static inline void
732drv_release_buffered_frames(struct ieee80211_local *local,
733 struct sta_info *sta, u16 tids, int num_frames,
734 enum ieee80211_frame_release_type reason,
735 bool more_data)
736{
737 trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
738 reason, more_data);
739 if (local->ops->release_buffered_frames)
740 local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
741 num_frames, reason,
742 more_data);
743 trace_drv_return_void(local);
744}
Johannes Berg40b96402011-09-29 16:04:38 +0200745
746static inline void
747drv_allow_buffered_frames(struct ieee80211_local *local,
748 struct sta_info *sta, u16 tids, int num_frames,
749 enum ieee80211_frame_release_type reason,
750 bool more_data)
751{
752 trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
753 reason, more_data);
754 if (local->ops->allow_buffered_frames)
755 local->ops->allow_buffered_frames(&local->hw, &sta->sta,
756 tids, num_frames, reason,
757 more_data);
758 trace_drv_return_void(local);
759}
Johannes Berg24487982009-04-23 18:52:52 +0200760#endif /* __MAC80211_DRIVER_OPS */