driver-ops.h 23.6 KB
Newer Older
1
2
3
4
5
#ifndef __MAC80211_DRIVER_OPS
#define __MAC80211_DRIVER_OPS

#include <net/mac80211.h>
#include "ieee80211_i.h"
6
#include "trace.h"
7

8
9
static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata)
{
10
11
	WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER),
	     "%s:  Failed check-sdata-in-driver check, flags: 0x%x\n",
12
	     sdata->dev ? sdata->dev->name : sdata->name, sdata->flags);
13
14
}

15
16
17
18
19
20
21
22
23
24
static inline struct ieee80211_sub_if_data *
get_bss_sdata(struct ieee80211_sub_if_data *sdata)
{
	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
		sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
				     u.ap);

	return sdata;
}

25
26
27
static inline void drv_tx(struct ieee80211_local *local,
			  struct ieee80211_tx_control *control,
			  struct sk_buff *skb)
28
{
29
	local->ops->tx(&local->hw, control, skb);
30
31
}

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata,
				      u32 sset, u8 *data)
{
	struct ieee80211_local *local = sdata->local;
	if (local->ops->get_et_strings) {
		trace_drv_get_et_strings(local, sset);
		local->ops->get_et_strings(&local->hw, &sdata->vif, sset, data);
		trace_drv_return_void(local);
	}
}

static inline void drv_get_et_stats(struct ieee80211_sub_if_data *sdata,
				    struct ethtool_stats *stats,
				    u64 *data)
{
	struct ieee80211_local *local = sdata->local;
	if (local->ops->get_et_stats) {
		trace_drv_get_et_stats(local);
		local->ops->get_et_stats(&local->hw, &sdata->vif, stats, data);
		trace_drv_return_void(local);
	}
}

static inline int drv_get_et_sset_count(struct ieee80211_sub_if_data *sdata,
					int sset)
{
	struct ieee80211_local *local = sdata->local;
	int rv = 0;
	if (local->ops->get_et_sset_count) {
		trace_drv_get_et_sset_count(local, sset);
		rv = local->ops->get_et_sset_count(&local->hw, &sdata->vif,
						   sset);
		trace_drv_return_int(local, rv);
	}
	return rv;
}

69
70
static inline int drv_start(struct ieee80211_local *local)
{
71
72
	int ret;

73
74
	might_sleep();

75
	trace_drv_start(local);
76
77
78
	local->started = true;
	smp_mb();
	ret = local->ops->start(&local->hw);
79
	trace_drv_return_int(local, ret);
80
	return ret;
81
82
83
84
}

static inline void drv_stop(struct ieee80211_local *local)
{
85
86
	might_sleep();

87
	trace_drv_stop(local);
88
89
	local->ops->stop(&local->hw);
	trace_drv_return_void(local);
90
91
92
93
94
95
96
97

	/* sync away all work on the tasklet before clearing started */
	tasklet_disable(&local->tasklet);
	tasklet_enable(&local->tasklet);

	barrier();

	local->started = false;
98
99
}

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#ifdef CONFIG_PM
static inline int drv_suspend(struct ieee80211_local *local,
			      struct cfg80211_wowlan *wowlan)
{
	int ret;

	might_sleep();

	trace_drv_suspend(local);
	ret = local->ops->suspend(&local->hw, wowlan);
	trace_drv_return_int(local, ret);
	return ret;
}

static inline int drv_resume(struct ieee80211_local *local)
{
	int ret;

	might_sleep();

	trace_drv_resume(local);
	ret = local->ops->resume(&local->hw);
	trace_drv_return_int(local, ret);
	return ret;
}
125
126
127
128
129
130
131
132
133
134
135
136
137

static inline void drv_set_wakeup(struct ieee80211_local *local,
				  bool enabled)
{
	might_sleep();

	if (!local->ops->set_wakeup)
		return;

	trace_drv_set_wakeup(local, enabled);
	local->ops->set_wakeup(&local->hw, enabled);
	trace_drv_return_void(local);
}
138
139
#endif

140
static inline int drv_add_interface(struct ieee80211_local *local,
141
				    struct ieee80211_sub_if_data *sdata)
142
{
143
144
145
146
	int ret;

	might_sleep();

147
	if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
148
149
		    (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
		     !(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF))))
150
151
152
153
		return -EINVAL;

	trace_drv_add_interface(local, sdata);
	ret = local->ops->add_interface(&local->hw, &sdata->vif);
154
	trace_drv_return_int(local, ret);
155
156
157
158

	if (ret == 0)
		sdata->flags |= IEEE80211_SDATA_IN_DRIVER;

159
	return ret;
160
161
}

162
163
static inline int drv_change_interface(struct ieee80211_local *local,
				       struct ieee80211_sub_if_data *sdata,
164
				       enum nl80211_iftype type, bool p2p)
165
166
167
168
169
{
	int ret;

	might_sleep();

170
171
	check_sdata_in_driver(sdata);

172
173
	trace_drv_change_interface(local, sdata, type, p2p);
	ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p);
174
175
176
177
	trace_drv_return_int(local, ret);
	return ret;
}

178
static inline void drv_remove_interface(struct ieee80211_local *local,
179
					struct ieee80211_sub_if_data *sdata)
180
{
181
182
	might_sleep();

183
184
185
186
187
	check_sdata_in_driver(sdata);

	trace_drv_remove_interface(local, sdata);
	local->ops->remove_interface(&local->hw, &sdata->vif);
	sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER;
188
	trace_drv_return_void(local);
189
190
191
192
}

static inline int drv_config(struct ieee80211_local *local, u32 changed)
{
193
194
195
196
	int ret;

	might_sleep();

197
	trace_drv_config(local, changed);
198
	ret = local->ops->config(&local->hw, changed);
199
	trace_drv_return_int(local, ret);
200
	return ret;
201
202
203
}

static inline void drv_bss_info_changed(struct ieee80211_local *local,
Johannes Berg's avatar
Johannes Berg committed
204
					struct ieee80211_sub_if_data *sdata,
205
206
207
					struct ieee80211_bss_conf *info,
					u32 changed)
{
208
209
	might_sleep();

210
211
	check_sdata_in_driver(sdata);

212
	trace_drv_bss_info_changed(local, sdata, info, changed);
213
	if (local->ops->bss_info_changed)
Johannes Berg's avatar
Johannes Berg committed
214
		local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed);
215
	trace_drv_return_void(local);
216
217
}

218
static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
219
					struct netdev_hw_addr_list *mc_list)
220
221
222
{
	u64 ret = 0;

223
224
	trace_drv_prepare_multicast(local, mc_list->count);

225
	if (local->ops->prepare_multicast)
226
		ret = local->ops->prepare_multicast(&local->hw, mc_list);
227

228
	trace_drv_return_u64(local, ret);
229
230
231
232

	return ret;
}

233
234
235
static inline void drv_configure_filter(struct ieee80211_local *local,
					unsigned int changed_flags,
					unsigned int *total_flags,
236
					u64 multicast)
237
{
238
239
	might_sleep();

240
	trace_drv_configure_filter(local, changed_flags, total_flags,
241
				   multicast);
242
243
244
	local->ops->configure_filter(&local->hw, changed_flags, total_flags,
				     multicast);
	trace_drv_return_void(local);
245
246
247
248
249
}

static inline int drv_set_tim(struct ieee80211_local *local,
			      struct ieee80211_sta *sta, bool set)
{
250
	int ret = 0;
251
	trace_drv_set_tim(local, sta, set);
252
	if (local->ops->set_tim)
253
		ret = local->ops->set_tim(&local->hw, sta, set);
254
	trace_drv_return_int(local, ret);
255
	return ret;
256
257
258
}

static inline int drv_set_key(struct ieee80211_local *local,
Johannes Berg's avatar
Johannes Berg committed
259
260
			      enum set_key_cmd cmd,
			      struct ieee80211_sub_if_data *sdata,
261
262
263
			      struct ieee80211_sta *sta,
			      struct ieee80211_key_conf *key)
{
264
265
266
267
	int ret;

	might_sleep();

268
	sdata = get_bss_sdata(sdata);
269
270
	check_sdata_in_driver(sdata);

271
	trace_drv_set_key(local, cmd, sdata, sta, key);
272
	ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key);
273
	trace_drv_return_int(local, ret);
274
	return ret;
275
276
277
}

static inline void drv_update_tkip_key(struct ieee80211_local *local,
278
				       struct ieee80211_sub_if_data *sdata,
279
				       struct ieee80211_key_conf *conf,
280
				       struct sta_info *sta, u32 iv32,
281
282
				       u16 *phase1key)
{
283
284
285
286
287
	struct ieee80211_sta *ista = NULL;

	if (sta)
		ista = &sta->sta;

288
	sdata = get_bss_sdata(sdata);
289
290
	check_sdata_in_driver(sdata);

291
	trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
292
	if (local->ops->update_tkip_key)
293
294
		local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
					    ista, iv32, phase1key);
295
	trace_drv_return_void(local);
296
297
298
}

static inline int drv_hw_scan(struct ieee80211_local *local,
299
			      struct ieee80211_sub_if_data *sdata,
300
301
			      struct cfg80211_scan_request *req)
{
302
303
304
305
	int ret;

	might_sleep();

306
307
	check_sdata_in_driver(sdata);

308
	trace_drv_hw_scan(local, sdata);
309
	ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
310
	trace_drv_return_int(local, ret);
311
	return ret;
312
313
}

314
315
316
317
318
static inline void drv_cancel_hw_scan(struct ieee80211_local *local,
				      struct ieee80211_sub_if_data *sdata)
{
	might_sleep();

319
320
	check_sdata_in_driver(sdata);

321
322
323
324
325
	trace_drv_cancel_hw_scan(local, sdata);
	local->ops->cancel_hw_scan(&local->hw, &sdata->vif);
	trace_drv_return_void(local);
}

326
327
328
329
330
331
332
333
334
335
static inline int
drv_sched_scan_start(struct ieee80211_local *local,
		     struct ieee80211_sub_if_data *sdata,
		     struct cfg80211_sched_scan_request *req,
		     struct ieee80211_sched_scan_ies *ies)
{
	int ret;

	might_sleep();

336
337
	check_sdata_in_driver(sdata);

338
339
340
341
342
343
344
345
346
347
348
349
	trace_drv_sched_scan_start(local, sdata);
	ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
					      req, ies);
	trace_drv_return_int(local, ret);
	return ret;
}

static inline void drv_sched_scan_stop(struct ieee80211_local *local,
				       struct ieee80211_sub_if_data *sdata)
{
	might_sleep();

350
351
	check_sdata_in_driver(sdata);

352
353
354
355
356
	trace_drv_sched_scan_stop(local, sdata);
	local->ops->sched_scan_stop(&local->hw, &sdata->vif);
	trace_drv_return_void(local);
}

357
358
static inline void drv_sw_scan_start(struct ieee80211_local *local)
{
359
360
	might_sleep();

361
	trace_drv_sw_scan_start(local);
362
363
	if (local->ops->sw_scan_start)
		local->ops->sw_scan_start(&local->hw);
364
	trace_drv_return_void(local);
365
366
367
368
}

static inline void drv_sw_scan_complete(struct ieee80211_local *local)
{
369
370
	might_sleep();

371
	trace_drv_sw_scan_complete(local);
372
373
	if (local->ops->sw_scan_complete)
		local->ops->sw_scan_complete(&local->hw);
374
	trace_drv_return_void(local);
375
376
377
378
379
}

static inline int drv_get_stats(struct ieee80211_local *local,
				struct ieee80211_low_level_stats *stats)
{
380
381
	int ret = -EOPNOTSUPP;

382
383
	might_sleep();

384
385
386
387
388
	if (local->ops->get_stats)
		ret = local->ops->get_stats(&local->hw, stats);
	trace_drv_get_stats(local, stats, ret);

	return ret;
389
390
391
392
393
394
395
}

static inline void drv_get_tkip_seq(struct ieee80211_local *local,
				    u8 hw_key_idx, u32 *iv32, u16 *iv16)
{
	if (local->ops->get_tkip_seq)
		local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16);
396
	trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16);
397
398
}

399
400
401
402
403
404
405
406
407
408
409
410
411
412
static inline int drv_set_frag_threshold(struct ieee80211_local *local,
					u32 value)
{
	int ret = 0;

	might_sleep();

	trace_drv_set_frag_threshold(local, value);
	if (local->ops->set_frag_threshold)
		ret = local->ops->set_frag_threshold(&local->hw, value);
	trace_drv_return_int(local, ret);
	return ret;
}

413
414
415
static inline int drv_set_rts_threshold(struct ieee80211_local *local,
					u32 value)
{
416
	int ret = 0;
417
418
419

	might_sleep();

420
	trace_drv_set_rts_threshold(local, value);
421
	if (local->ops->set_rts_threshold)
422
		ret = local->ops->set_rts_threshold(&local->hw, value);
423
	trace_drv_return_int(local, ret);
424
	return ret;
425
426
}

427
428
429
430
431
432
static inline int drv_set_coverage_class(struct ieee80211_local *local,
					 u8 value)
{
	int ret = 0;
	might_sleep();

433
	trace_drv_set_coverage_class(local, value);
434
435
436
437
438
	if (local->ops->set_coverage_class)
		local->ops->set_coverage_class(&local->hw, value);
	else
		ret = -EOPNOTSUPP;

439
	trace_drv_return_int(local, ret);
440
441
442
	return ret;
}

443
static inline void drv_sta_notify(struct ieee80211_local *local,
Johannes Berg's avatar
Johannes Berg committed
444
				  struct ieee80211_sub_if_data *sdata,
445
446
447
				  enum sta_notify_cmd cmd,
				  struct ieee80211_sta *sta)
{
448
	sdata = get_bss_sdata(sdata);
449
450
	check_sdata_in_driver(sdata);

451
	trace_drv_sta_notify(local, sdata, cmd, sta);
452
	if (local->ops->sta_notify)
Johannes Berg's avatar
Johannes Berg committed
453
		local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta);
454
	trace_drv_return_void(local);
455
456
}

457
458
459
460
461
462
463
464
static inline int drv_sta_add(struct ieee80211_local *local,
			      struct ieee80211_sub_if_data *sdata,
			      struct ieee80211_sta *sta)
{
	int ret = 0;

	might_sleep();

465
	sdata = get_bss_sdata(sdata);
466
467
	check_sdata_in_driver(sdata);

468
	trace_drv_sta_add(local, sdata, sta);
469
470
471
	if (local->ops->sta_add)
		ret = local->ops->sta_add(&local->hw, &sdata->vif, sta);

472
	trace_drv_return_int(local, ret);
473
474
475
476
477
478
479
480
481
482

	return ret;
}

static inline void drv_sta_remove(struct ieee80211_local *local,
				  struct ieee80211_sub_if_data *sdata,
				  struct ieee80211_sta *sta)
{
	might_sleep();

483
	sdata = get_bss_sdata(sdata);
484
485
	check_sdata_in_driver(sdata);

486
	trace_drv_sta_remove(local, sdata, sta);
487
488
489
	if (local->ops->sta_remove)
		local->ops->sta_remove(&local->hw, &sdata->vif, sta);

490
	trace_drv_return_void(local);
491
492
}

493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
static inline __must_check
int drv_sta_state(struct ieee80211_local *local,
		  struct ieee80211_sub_if_data *sdata,
		  struct sta_info *sta,
		  enum ieee80211_sta_state old_state,
		  enum ieee80211_sta_state new_state)
{
	int ret = 0;

	might_sleep();

	sdata = get_bss_sdata(sdata);
	check_sdata_in_driver(sdata);

	trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state);
508
	if (local->ops->sta_state) {
509
510
		ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta,
					    old_state, new_state);
511
512
513
514
515
516
517
518
519
	} else if (old_state == IEEE80211_STA_AUTH &&
		   new_state == IEEE80211_STA_ASSOC) {
		ret = drv_sta_add(local, sdata, &sta->sta);
		if (ret == 0)
			sta->uploaded = true;
	} else if (old_state == IEEE80211_STA_ASSOC &&
		   new_state == IEEE80211_STA_AUTH) {
		drv_sta_remove(local, sdata, &sta->sta);
	}
520
521
522
523
	trace_drv_return_int(local, ret);
	return ret;
}

524
525
526
527
528
529
530
static inline void drv_sta_rc_update(struct ieee80211_local *local,
				     struct ieee80211_sub_if_data *sdata,
				     struct ieee80211_sta *sta, u32 changed)
{
	sdata = get_bss_sdata(sdata);
	check_sdata_in_driver(sdata);

531
532
533
	WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED &&
		sdata->vif.type != NL80211_IFTYPE_ADHOC);

534
535
536
537
538
539
540
541
	trace_drv_sta_rc_update(local, sdata, sta, changed);
	if (local->ops->sta_rc_update)
		local->ops->sta_rc_update(&local->hw, &sdata->vif,
					  sta, changed);

	trace_drv_return_void(local);
}

542
static inline int drv_conf_tx(struct ieee80211_local *local,
543
			      struct ieee80211_sub_if_data *sdata, u16 ac,
544
545
			      const struct ieee80211_tx_queue_params *params)
{
546
	int ret = -EOPNOTSUPP;
547
548
549

	might_sleep();

550
551
	check_sdata_in_driver(sdata);

552
	trace_drv_conf_tx(local, sdata, ac, params);
553
	if (local->ops->conf_tx)
554
		ret = local->ops->conf_tx(&local->hw, &sdata->vif,
555
					  ac, params);
556
	trace_drv_return_int(local, ret);
557
	return ret;
558
559
}

560
561
static inline u64 drv_get_tsf(struct ieee80211_local *local,
			      struct ieee80211_sub_if_data *sdata)
562
{
563
	u64 ret = -1ULL;
564
565
566

	might_sleep();

567
568
	check_sdata_in_driver(sdata);

569
	trace_drv_get_tsf(local, sdata);
570
	if (local->ops->get_tsf)
571
		ret = local->ops->get_tsf(&local->hw, &sdata->vif);
572
	trace_drv_return_u64(local, ret);
573
	return ret;
574
575
}

576
577
578
static inline void drv_set_tsf(struct ieee80211_local *local,
			       struct ieee80211_sub_if_data *sdata,
			       u64 tsf)
579
{
580
581
	might_sleep();

582
583
	check_sdata_in_driver(sdata);

584
	trace_drv_set_tsf(local, sdata, tsf);
585
	if (local->ops->set_tsf)
586
		local->ops->set_tsf(&local->hw, &sdata->vif, tsf);
587
	trace_drv_return_void(local);
588
589
}

590
591
static inline void drv_reset_tsf(struct ieee80211_local *local,
				 struct ieee80211_sub_if_data *sdata)
592
{
593
594
	might_sleep();

595
596
	check_sdata_in_driver(sdata);

597
	trace_drv_reset_tsf(local, sdata);
598
	if (local->ops->reset_tsf)
599
		local->ops->reset_tsf(&local->hw, &sdata->vif);
600
	trace_drv_return_void(local);
601
602
603
604
}

static inline int drv_tx_last_beacon(struct ieee80211_local *local)
{
605
	int ret = 0; /* default unsuported op for less congestion */
606
607
608

	might_sleep();

609
	trace_drv_tx_last_beacon(local);
610
	if (local->ops->tx_last_beacon)
611
		ret = local->ops->tx_last_beacon(&local->hw);
612
	trace_drv_return_int(local, ret);
613
	return ret;
614
615
616
}

static inline int drv_ampdu_action(struct ieee80211_local *local,
Johannes Berg's avatar
Johannes Berg committed
617
				   struct ieee80211_sub_if_data *sdata,
618
619
				   enum ieee80211_ampdu_mlme_action action,
				   struct ieee80211_sta *sta, u16 tid,
620
				   u16 *ssn, u8 buf_size)
621
{
622
	int ret = -EOPNOTSUPP;
623
624
625

	might_sleep();

626
	sdata = get_bss_sdata(sdata);
627
628
	check_sdata_in_driver(sdata);

629
	trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size);
630

631
	if (local->ops->ampdu_action)
Johannes Berg's avatar
Johannes Berg committed
632
		ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
633
					       sta, tid, ssn, buf_size);
634

635
636
	trace_drv_return_int(local, ret);

637
	return ret;
638
}
Johannes Berg's avatar
Johannes Berg committed
639

640
641
642
643
static inline int drv_get_survey(struct ieee80211_local *local, int idx,
				struct survey_info *survey)
{
	int ret = -EOPNOTSUPP;
644
645
646

	trace_drv_get_survey(local, idx, survey);

647
	if (local->ops->get_survey)
648
		ret = local->ops->get_survey(&local->hw, idx, survey);
649
650
651

	trace_drv_return_int(local, ret);

652
653
	return ret;
}
Johannes Berg's avatar
Johannes Berg committed
654
655
656

static inline void drv_rfkill_poll(struct ieee80211_local *local)
{
657
658
	might_sleep();

Johannes Berg's avatar
Johannes Berg committed
659
660
661
	if (local->ops->rfkill_poll)
		local->ops->rfkill_poll(&local->hw);
}
662
663
664

static inline void drv_flush(struct ieee80211_local *local, bool drop)
{
665
666
	might_sleep();

667
668
669
	trace_drv_flush(local, drop);
	if (local->ops->flush)
		local->ops->flush(&local->hw, drop);
670
	trace_drv_return_void(local);
671
}
672
673
674
675
676
677
678

static inline void drv_channel_switch(struct ieee80211_local *local,
				     struct ieee80211_channel_switch *ch_switch)
{
	might_sleep();

	trace_drv_channel_switch(local, ch_switch);
679
680
	local->ops->channel_switch(&local->hw, ch_switch);
	trace_drv_return_void(local);
681
682
}

683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705

static inline int drv_set_antenna(struct ieee80211_local *local,
				  u32 tx_ant, u32 rx_ant)
{
	int ret = -EOPNOTSUPP;
	might_sleep();
	if (local->ops->set_antenna)
		ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
	trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
	return ret;
}

static inline int drv_get_antenna(struct ieee80211_local *local,
				  u32 *tx_ant, u32 *rx_ant)
{
	int ret = -EOPNOTSUPP;
	might_sleep();
	if (local->ops->get_antenna)
		ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
	trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
	return ret;
}

706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
static inline int drv_remain_on_channel(struct ieee80211_local *local,
					struct ieee80211_channel *chan,
					enum nl80211_channel_type chantype,
					unsigned int duration)
{
	int ret;

	might_sleep();

	trace_drv_remain_on_channel(local, chan, chantype, duration);
	ret = local->ops->remain_on_channel(&local->hw, chan, chantype,
					    duration);
	trace_drv_return_int(local, ret);

	return ret;
}

static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local)
{
	int ret;

	might_sleep();

	trace_drv_cancel_remain_on_channel(local);
	ret = local->ops->cancel_remain_on_channel(&local->hw);
	trace_drv_return_int(local, ret);
732
733
734
735

	return ret;
}

736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
static inline int drv_set_ringparam(struct ieee80211_local *local,
				    u32 tx, u32 rx)
{
	int ret = -ENOTSUPP;

	might_sleep();

	trace_drv_set_ringparam(local, tx, rx);
	if (local->ops->set_ringparam)
		ret = local->ops->set_ringparam(&local->hw, tx, rx);
	trace_drv_return_int(local, ret);

	return ret;
}

static inline void drv_get_ringparam(struct ieee80211_local *local,
				     u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
{
	might_sleep();

	trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
	if (local->ops->get_ringparam)
		local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
	trace_drv_return_void(local);
}

762
763
764
765
766
767
768
769
770
771
772
773
774
static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
{
	bool ret = false;

	might_sleep();

	trace_drv_tx_frames_pending(local);
	if (local->ops->tx_frames_pending)
		ret = local->ops->tx_frames_pending(&local->hw);
	trace_drv_return_bool(local, ret);

	return ret;
}
775
776
777
778
779
780
781
782
783

static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
				       struct ieee80211_sub_if_data *sdata,
				       const struct cfg80211_bitrate_mask *mask)
{
	int ret = -EOPNOTSUPP;

	might_sleep();

784
785
	check_sdata_in_driver(sdata);

786
787
788
789
790
791
792
793
794
	trace_drv_set_bitrate_mask(local, sdata, mask);
	if (local->ops->set_bitrate_mask)
		ret = local->ops->set_bitrate_mask(&local->hw,
						   &sdata->vif, mask);
	trace_drv_return_int(local, ret);

	return ret;
}

795
796
797
798
static inline void drv_set_rekey_data(struct ieee80211_local *local,
				      struct ieee80211_sub_if_data *sdata,
				      struct cfg80211_gtk_rekey_data *data)
{
799
800
	check_sdata_in_driver(sdata);

801
802
803
804
805
806
	trace_drv_set_rekey_data(local, sdata, data);
	if (local->ops->set_rekey_data)
		local->ops->set_rekey_data(&local->hw, &sdata->vif, data);
	trace_drv_return_void(local);
}

807
808
809
810
811
812
813
814
static inline void drv_rssi_callback(struct ieee80211_local *local,
				     const enum ieee80211_rssi_event event)
{
	trace_drv_rssi_callback(local, event);
	if (local->ops->rssi_callback)
		local->ops->rssi_callback(&local->hw, event);
	trace_drv_return_void(local);
}
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829

static inline void
drv_release_buffered_frames(struct ieee80211_local *local,
			    struct sta_info *sta, u16 tids, int num_frames,
			    enum ieee80211_frame_release_type reason,
			    bool more_data)
{
	trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
					  reason, more_data);
	if (local->ops->release_buffered_frames)
		local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
						    num_frames, reason,
						    more_data);
	trace_drv_return_void(local);
}
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844

static inline void
drv_allow_buffered_frames(struct ieee80211_local *local,
			  struct sta_info *sta, u16 tids, int num_frames,
			  enum ieee80211_frame_release_type reason,
			  bool more_data)
{
	trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
					reason, more_data);
	if (local->ops->allow_buffered_frames)
		local->ops->allow_buffered_frames(&local->hw, &sta->sta,
						  tids, num_frames, reason,
						  more_data);
	trace_drv_return_void(local);
}
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859

static inline int drv_get_rssi(struct ieee80211_local *local,
				struct ieee80211_sub_if_data *sdata,
				struct ieee80211_sta *sta,
				s8 *rssi_dbm)
{
	int ret;

	might_sleep();

	ret = local->ops->get_rssi(&local->hw, &sdata->vif, sta, rssi_dbm);
	trace_drv_get_rssi(local, sta, *rssi_dbm, ret);

	return ret;
}
Johannes Berg's avatar
Johannes Berg committed
860
861
862
863
864
865
866
867
868
869
870
871
872
873

static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
				      struct ieee80211_sub_if_data *sdata)
{
	might_sleep();

	check_sdata_in_driver(sdata);
	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);

	trace_drv_mgd_prepare_tx(local, sdata);
	if (local->ops->mgd_prepare_tx)
		local->ops->mgd_prepare_tx(&local->hw, &sdata->vif);
	trace_drv_return_void(local);
}
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938

static inline int drv_add_chanctx(struct ieee80211_local *local,
				  struct ieee80211_chanctx *ctx)
{
	int ret = -EOPNOTSUPP;

	trace_drv_add_chanctx(local, ctx);
	if (local->ops->add_chanctx)
		ret = local->ops->add_chanctx(&local->hw, &ctx->conf);
	trace_drv_return_int(local, ret);

	return ret;
}

static inline void drv_remove_chanctx(struct ieee80211_local *local,
				      struct ieee80211_chanctx *ctx)
{
	trace_drv_remove_chanctx(local, ctx);
	if (local->ops->remove_chanctx)
		local->ops->remove_chanctx(&local->hw, &ctx->conf);
	trace_drv_return_void(local);
}

static inline void drv_change_chanctx(struct ieee80211_local *local,
				      struct ieee80211_chanctx *ctx,
				      u32 changed)
{
	trace_drv_change_chanctx(local, ctx, changed);
	if (local->ops->change_chanctx)
		local->ops->change_chanctx(&local->hw, &ctx->conf, changed);
	trace_drv_return_void(local);
}

static inline int drv_assign_vif_chanctx(struct ieee80211_local *local,
					 struct ieee80211_sub_if_data *sdata,
					 struct ieee80211_chanctx *ctx)
{
	int ret = 0;

	check_sdata_in_driver(sdata);

	trace_drv_assign_vif_chanctx(local, sdata, ctx);
	if (local->ops->assign_vif_chanctx)
		ret = local->ops->assign_vif_chanctx(&local->hw,
						     &sdata->vif,
						     &ctx->conf);
	trace_drv_return_int(local, ret);

	return ret;
}

static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
					    struct ieee80211_sub_if_data *sdata,
					    struct ieee80211_chanctx *ctx)
{
	check_sdata_in_driver(sdata);

	trace_drv_unassign_vif_chanctx(local, sdata, ctx);
	if (local->ops->unassign_vif_chanctx)
		local->ops->unassign_vif_chanctx(&local->hw,
						 &sdata->vif,
						 &ctx->conf);
	trace_drv_return_void(local);
}

939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
static inline int drv_start_ap(struct ieee80211_local *local,
			       struct ieee80211_sub_if_data *sdata)
{
	int ret = 0;

	check_sdata_in_driver(sdata);

	trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf);
	if (local->ops->start_ap)
		ret = local->ops->start_ap(&local->hw, &sdata->vif);
	trace_drv_return_int(local, ret);
	return ret;
}

static inline void drv_stop_ap(struct ieee80211_local *local,
			       struct ieee80211_sub_if_data *sdata)
{
	check_sdata_in_driver(sdata);

	trace_drv_stop_ap(local, sdata);
	if (local->ops->stop_ap)
		local->ops->stop_ap(&local->hw, &sdata->vif);
	trace_drv_return_void(local);
}

964
965
966
967
968
969
970
971
972
973
static inline void drv_restart_complete(struct ieee80211_local *local)
{
	might_sleep();

	trace_drv_restart_complete(local);
	if (local->ops->restart_complete)
		local->ops->restart_complete(&local->hw);
	trace_drv_return_void(local);
}

974
#endif /* __MAC80211_DRIVER_OPS */