driver-ops.h 24.8 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();

J
Johannes Berg 已提交
75
	trace_drv_start(local);
76 77 78
	local->started = true;
	smp_mb();
	ret = local->ops->start(&local->hw);
J
Johannes Berg 已提交
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);
J
Johannes Berg 已提交
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);
J
Johannes Berg 已提交
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;
J
Johannes Berg 已提交
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();

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

static inline void drv_bss_info_changed(struct ieee80211_local *local,
J
Johannes Berg 已提交
204
					struct ieee80211_sub_if_data *sdata,
205 206 207
					struct ieee80211_bss_conf *info,
					u32 changed)
{
208 209
	might_sleep();

210 211 212 213 214 215
	WARN_ON_ONCE(changed & (BSS_CHANGED_BEACON |
				BSS_CHANGED_BEACON_ENABLED) &&
		     sdata->vif.type != NL80211_IFTYPE_AP &&
		     sdata->vif.type != NL80211_IFTYPE_ADHOC &&
		     sdata->vif.type != NL80211_IFTYPE_MESH_POINT);

216 217
	check_sdata_in_driver(sdata);

J
Johannes Berg 已提交
218
	trace_drv_bss_info_changed(local, sdata, info, changed);
219
	if (local->ops->bss_info_changed)
J
Johannes Berg 已提交
220
		local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed);
J
Johannes Berg 已提交
221
	trace_drv_return_void(local);
222 223
}

224
static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
225
					struct netdev_hw_addr_list *mc_list)
226 227 228
{
	u64 ret = 0;

J
Johannes Berg 已提交
229 230
	trace_drv_prepare_multicast(local, mc_list->count);

231
	if (local->ops->prepare_multicast)
232
		ret = local->ops->prepare_multicast(&local->hw, mc_list);
233

J
Johannes Berg 已提交
234
	trace_drv_return_u64(local, ret);
235 236 237 238

	return ret;
}

239 240 241
static inline void drv_configure_filter(struct ieee80211_local *local,
					unsigned int changed_flags,
					unsigned int *total_flags,
242
					u64 multicast)
243
{
244 245
	might_sleep();

246
	trace_drv_configure_filter(local, changed_flags, total_flags,
247
				   multicast);
J
Johannes Berg 已提交
248 249 250
	local->ops->configure_filter(&local->hw, changed_flags, total_flags,
				     multicast);
	trace_drv_return_void(local);
251 252 253 254 255
}

static inline int drv_set_tim(struct ieee80211_local *local,
			      struct ieee80211_sta *sta, bool set)
{
256
	int ret = 0;
J
Johannes Berg 已提交
257
	trace_drv_set_tim(local, sta, set);
258
	if (local->ops->set_tim)
259
		ret = local->ops->set_tim(&local->hw, sta, set);
J
Johannes Berg 已提交
260
	trace_drv_return_int(local, ret);
261
	return ret;
262 263 264
}

static inline int drv_set_key(struct ieee80211_local *local,
J
Johannes Berg 已提交
265 266
			      enum set_key_cmd cmd,
			      struct ieee80211_sub_if_data *sdata,
267 268 269
			      struct ieee80211_sta *sta,
			      struct ieee80211_key_conf *key)
{
270 271 272 273
	int ret;

	might_sleep();

274
	sdata = get_bss_sdata(sdata);
275 276
	check_sdata_in_driver(sdata);

J
Johannes Berg 已提交
277
	trace_drv_set_key(local, cmd, sdata, sta, key);
278
	ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key);
J
Johannes Berg 已提交
279
	trace_drv_return_int(local, ret);
280
	return ret;
281 282 283
}

static inline void drv_update_tkip_key(struct ieee80211_local *local,
284
				       struct ieee80211_sub_if_data *sdata,
285
				       struct ieee80211_key_conf *conf,
286
				       struct sta_info *sta, u32 iv32,
287 288
				       u16 *phase1key)
{
289 290 291 292 293
	struct ieee80211_sta *ista = NULL;

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

294
	sdata = get_bss_sdata(sdata);
295 296
	check_sdata_in_driver(sdata);

J
Johannes Berg 已提交
297
	trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
298
	if (local->ops->update_tkip_key)
299 300
		local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
					    ista, iv32, phase1key);
J
Johannes Berg 已提交
301
	trace_drv_return_void(local);
302 303 304
}

static inline int drv_hw_scan(struct ieee80211_local *local,
305
			      struct ieee80211_sub_if_data *sdata,
306 307
			      struct cfg80211_scan_request *req)
{
308 309 310 311
	int ret;

	might_sleep();

312 313
	check_sdata_in_driver(sdata);

314
	trace_drv_hw_scan(local, sdata);
315
	ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
J
Johannes Berg 已提交
316
	trace_drv_return_int(local, ret);
317
	return ret;
318 319
}

320 321 322 323 324
static inline void drv_cancel_hw_scan(struct ieee80211_local *local,
				      struct ieee80211_sub_if_data *sdata)
{
	might_sleep();

325 326
	check_sdata_in_driver(sdata);

327 328 329 330 331
	trace_drv_cancel_hw_scan(local, sdata);
	local->ops->cancel_hw_scan(&local->hw, &sdata->vif);
	trace_drv_return_void(local);
}

332 333 334 335 336 337 338 339 340 341
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();

342 343
	check_sdata_in_driver(sdata);

344 345 346 347 348 349 350 351 352 353 354 355
	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();

356 357
	check_sdata_in_driver(sdata);

358 359 360 361 362
	trace_drv_sched_scan_stop(local, sdata);
	local->ops->sched_scan_stop(&local->hw, &sdata->vif);
	trace_drv_return_void(local);
}

363 364
static inline void drv_sw_scan_start(struct ieee80211_local *local)
{
365 366
	might_sleep();

J
Johannes Berg 已提交
367
	trace_drv_sw_scan_start(local);
368 369
	if (local->ops->sw_scan_start)
		local->ops->sw_scan_start(&local->hw);
J
Johannes Berg 已提交
370
	trace_drv_return_void(local);
371 372 373 374
}

static inline void drv_sw_scan_complete(struct ieee80211_local *local)
{
375 376
	might_sleep();

J
Johannes Berg 已提交
377
	trace_drv_sw_scan_complete(local);
378 379
	if (local->ops->sw_scan_complete)
		local->ops->sw_scan_complete(&local->hw);
J
Johannes Berg 已提交
380
	trace_drv_return_void(local);
381 382 383 384 385
}

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

388 389
	might_sleep();

390 391 392 393 394
	if (local->ops->get_stats)
		ret = local->ops->get_stats(&local->hw, stats);
	trace_drv_get_stats(local, stats, ret);

	return ret;
395 396 397 398 399 400 401
}

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);
402
	trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16);
403 404
}

405 406 407 408 409 410 411 412 413 414 415 416 417 418
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;
}

419 420 421
static inline int drv_set_rts_threshold(struct ieee80211_local *local,
					u32 value)
{
422
	int ret = 0;
423 424 425

	might_sleep();

J
Johannes Berg 已提交
426
	trace_drv_set_rts_threshold(local, value);
427
	if (local->ops->set_rts_threshold)
428
		ret = local->ops->set_rts_threshold(&local->hw, value);
J
Johannes Berg 已提交
429
	trace_drv_return_int(local, ret);
430
	return ret;
431 432
}

433 434 435 436 437 438
static inline int drv_set_coverage_class(struct ieee80211_local *local,
					 u8 value)
{
	int ret = 0;
	might_sleep();

J
Johannes Berg 已提交
439
	trace_drv_set_coverage_class(local, value);
440 441 442 443 444
	if (local->ops->set_coverage_class)
		local->ops->set_coverage_class(&local->hw, value);
	else
		ret = -EOPNOTSUPP;

J
Johannes Berg 已提交
445
	trace_drv_return_int(local, ret);
446 447 448
	return ret;
}

449
static inline void drv_sta_notify(struct ieee80211_local *local,
J
Johannes Berg 已提交
450
				  struct ieee80211_sub_if_data *sdata,
451 452 453
				  enum sta_notify_cmd cmd,
				  struct ieee80211_sta *sta)
{
454
	sdata = get_bss_sdata(sdata);
455 456
	check_sdata_in_driver(sdata);

J
Johannes Berg 已提交
457
	trace_drv_sta_notify(local, sdata, cmd, sta);
458
	if (local->ops->sta_notify)
J
Johannes Berg 已提交
459
		local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta);
J
Johannes Berg 已提交
460
	trace_drv_return_void(local);
461 462
}

463 464 465 466 467 468 469 470
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();

471
	sdata = get_bss_sdata(sdata);
472 473
	check_sdata_in_driver(sdata);

J
Johannes Berg 已提交
474
	trace_drv_sta_add(local, sdata, sta);
475 476 477
	if (local->ops->sta_add)
		ret = local->ops->sta_add(&local->hw, &sdata->vif, sta);

J
Johannes Berg 已提交
478
	trace_drv_return_int(local, ret);
479 480 481 482 483 484 485 486 487 488

	return ret;
}

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

489
	sdata = get_bss_sdata(sdata);
490 491
	check_sdata_in_driver(sdata);

J
Johannes Berg 已提交
492
	trace_drv_sta_remove(local, sdata, sta);
493 494 495
	if (local->ops->sta_remove)
		local->ops->sta_remove(&local->hw, &sdata->vif, sta);

J
Johannes Berg 已提交
496
	trace_drv_return_void(local);
497 498
}

499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
#ifdef CONFIG_MAC80211_DEBUGFS
static inline void drv_sta_add_debugfs(struct ieee80211_local *local,
				       struct ieee80211_sub_if_data *sdata,
				       struct ieee80211_sta *sta,
				       struct dentry *dir)
{
	might_sleep();

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

	if (local->ops->sta_add_debugfs)
		local->ops->sta_add_debugfs(&local->hw, &sdata->vif,
					    sta, dir);
}

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

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

	if (local->ops->sta_remove_debugfs)
		local->ops->sta_remove_debugfs(&local->hw, &sdata->vif,
					       sta, dir);
}
#endif

J
Johannes Berg 已提交
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
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);
546
	if (local->ops->sta_state) {
J
Johannes Berg 已提交
547 548
		ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta,
					    old_state, new_state);
549 550 551 552 553 554 555 556 557
	} 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);
	}
J
Johannes Berg 已提交
558 559 560 561
	trace_drv_return_int(local, ret);
	return ret;
}

562 563 564 565 566 567 568
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);

569 570 571
	WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED &&
		sdata->vif.type != NL80211_IFTYPE_ADHOC);

572 573 574 575 576 577 578 579
	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);
}

580
static inline int drv_conf_tx(struct ieee80211_local *local,
581
			      struct ieee80211_sub_if_data *sdata, u16 ac,
582 583
			      const struct ieee80211_tx_queue_params *params)
{
584
	int ret = -EOPNOTSUPP;
585 586 587

	might_sleep();

588 589
	check_sdata_in_driver(sdata);

590
	trace_drv_conf_tx(local, sdata, ac, params);
591
	if (local->ops->conf_tx)
592
		ret = local->ops->conf_tx(&local->hw, &sdata->vif,
593
					  ac, params);
J
Johannes Berg 已提交
594
	trace_drv_return_int(local, ret);
595
	return ret;
596 597
}

598 599
static inline u64 drv_get_tsf(struct ieee80211_local *local,
			      struct ieee80211_sub_if_data *sdata)
600
{
601
	u64 ret = -1ULL;
602 603 604

	might_sleep();

605 606
	check_sdata_in_driver(sdata);

607
	trace_drv_get_tsf(local, sdata);
608
	if (local->ops->get_tsf)
609
		ret = local->ops->get_tsf(&local->hw, &sdata->vif);
J
Johannes Berg 已提交
610
	trace_drv_return_u64(local, ret);
611
	return ret;
612 613
}

614 615 616
static inline void drv_set_tsf(struct ieee80211_local *local,
			       struct ieee80211_sub_if_data *sdata,
			       u64 tsf)
617
{
618 619
	might_sleep();

620 621
	check_sdata_in_driver(sdata);

622
	trace_drv_set_tsf(local, sdata, tsf);
623
	if (local->ops->set_tsf)
624
		local->ops->set_tsf(&local->hw, &sdata->vif, tsf);
J
Johannes Berg 已提交
625
	trace_drv_return_void(local);
626 627
}

628 629
static inline void drv_reset_tsf(struct ieee80211_local *local,
				 struct ieee80211_sub_if_data *sdata)
630
{
631 632
	might_sleep();

633 634
	check_sdata_in_driver(sdata);

635
	trace_drv_reset_tsf(local, sdata);
636
	if (local->ops->reset_tsf)
637
		local->ops->reset_tsf(&local->hw, &sdata->vif);
J
Johannes Berg 已提交
638
	trace_drv_return_void(local);
639 640 641 642
}

static inline int drv_tx_last_beacon(struct ieee80211_local *local)
{
643
	int ret = 0; /* default unsupported op for less congestion */
644 645 646

	might_sleep();

J
Johannes Berg 已提交
647
	trace_drv_tx_last_beacon(local);
648
	if (local->ops->tx_last_beacon)
649
		ret = local->ops->tx_last_beacon(&local->hw);
J
Johannes Berg 已提交
650
	trace_drv_return_int(local, ret);
651
	return ret;
652 653 654
}

static inline int drv_ampdu_action(struct ieee80211_local *local,
J
Johannes Berg 已提交
655
				   struct ieee80211_sub_if_data *sdata,
656 657
				   enum ieee80211_ampdu_mlme_action action,
				   struct ieee80211_sta *sta, u16 tid,
658
				   u16 *ssn, u8 buf_size)
659
{
660
	int ret = -EOPNOTSUPP;
661 662 663

	might_sleep();

664
	sdata = get_bss_sdata(sdata);
665 666
	check_sdata_in_driver(sdata);

667
	trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size);
J
Johannes Berg 已提交
668

669
	if (local->ops->ampdu_action)
J
Johannes Berg 已提交
670
		ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
671
					       sta, tid, ssn, buf_size);
672

J
Johannes Berg 已提交
673 674
	trace_drv_return_int(local, ret);

675
	return ret;
676
}
J
Johannes Berg 已提交
677

678 679 680 681
static inline int drv_get_survey(struct ieee80211_local *local, int idx,
				struct survey_info *survey)
{
	int ret = -EOPNOTSUPP;
682 683 684

	trace_drv_get_survey(local, idx, survey);

685
	if (local->ops->get_survey)
686
		ret = local->ops->get_survey(&local->hw, idx, survey);
687 688 689

	trace_drv_return_int(local, ret);

690 691
	return ret;
}
J
Johannes Berg 已提交
692 693 694

static inline void drv_rfkill_poll(struct ieee80211_local *local)
{
695 696
	might_sleep();

J
Johannes Berg 已提交
697 698 699
	if (local->ops->rfkill_poll)
		local->ops->rfkill_poll(&local->hw);
}
700 701 702

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

705 706 707
	trace_drv_flush(local, drop);
	if (local->ops->flush)
		local->ops->flush(&local->hw, drop);
J
Johannes Berg 已提交
708
	trace_drv_return_void(local);
709
}
710 711 712 713 714 715 716

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);
J
Johannes Berg 已提交
717 718
	local->ops->channel_switch(&local->hw, ch_switch);
	trace_drv_return_void(local);
719 720
}

721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743

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;
}

744
static inline int drv_remain_on_channel(struct ieee80211_local *local,
745
					struct ieee80211_sub_if_data *sdata,
746 747 748 749 750 751 752
					struct ieee80211_channel *chan,
					unsigned int duration)
{
	int ret;

	might_sleep();

753
	trace_drv_remain_on_channel(local, sdata, chan, duration);
754
	ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
755
					    chan, duration);
756 757 758 759 760 761 762 763 764 765 766 767 768 769
	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);
770 771 772 773

	return ret;
}

774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799
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);
}

800 801 802 803 804 805 806 807 808 809 810 811 812
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;
}
813 814 815 816 817 818 819 820 821

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();

822 823
	check_sdata_in_driver(sdata);

824 825 826 827 828 829 830 831 832
	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;
}

833 834 835 836
static inline void drv_set_rekey_data(struct ieee80211_local *local,
				      struct ieee80211_sub_if_data *sdata,
				      struct cfg80211_gtk_rekey_data *data)
{
837 838
	check_sdata_in_driver(sdata);

839 840 841 842 843 844
	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);
}

845 846 847 848 849 850 851 852
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);
}
853 854 855 856 857 858 859 860 861 862 863 864 865 866 867

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);
}
868 869 870 871 872 873 874 875 876 877 878 879 880 881 882

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);
}
883 884 885 886 887 888 889 890 891 892 893 894 895 896 897

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;
}
J
Johannes Berg 已提交
898 899 900 901 902 903 904 905 906 907 908 909 910 911

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);
}
912 913 914 915 916 917 918 919 920 921

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);
922 923
	if (!ret)
		ctx->driver_present = true;
924 925 926 927 928 929 930 931 932 933 934

	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);
935
	ctx->driver_present = false;
936 937 938 939 940 941 942
}

static inline void drv_change_chanctx(struct ieee80211_local *local,
				      struct ieee80211_chanctx *ctx,
				      u32 changed)
{
	trace_drv_change_chanctx(local, ctx, changed);
943 944
	if (local->ops->change_chanctx) {
		WARN_ON_ONCE(!ctx->driver_present);
945
		local->ops->change_chanctx(&local->hw, &ctx->conf, changed);
946
	}
947 948 949 950 951 952 953 954 955 956 957 958
	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);
959 960
	if (local->ops->assign_vif_chanctx) {
		WARN_ON_ONCE(!ctx->driver_present);
961 962 963
		ret = local->ops->assign_vif_chanctx(&local->hw,
						     &sdata->vif,
						     &ctx->conf);
964
	}
965 966 967 968 969 970 971 972 973 974 975 976
	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);
977 978
	if (local->ops->unassign_vif_chanctx) {
		WARN_ON_ONCE(!ctx->driver_present);
979 980 981
		local->ops->unassign_vif_chanctx(&local->hw,
						 &sdata->vif,
						 &ctx->conf);
982
	}
983 984 985
	trace_drv_return_void(local);
}

986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
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);
}

1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
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);
}

1021
#endif /* __MAC80211_DRIVER_OPS */