Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 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
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
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
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
/*-
 * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
 * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@FreeBSD.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
 * $FreeBSD$
 */

#ifndef IF_RTWNVAR_H
#define IF_RTWNVAR_H

#include "opt_rtwn.h"

#define RTWN_TX_DESC_SIZE	64

#define RTWN_BCN_MAX_SIZE	512
#define RTWN_CAM_ENTRY_LIMIT	64

#define RTWN_MACID_BC		1	/* Broadcast. */
#define RTWN_MACID_UNDEFINED	0x7fff
#define RTWN_MACID_VALID 	0x8000
#define RTWN_MACID_LIMIT	128

#define RTWN_TX_TIMEOUT		5000	/* ms */
#define RTWN_MAX_EPOUT		4
#define RTWN_PORT_COUNT		2

#define RTWN_LED_LINK		0
#define RTWN_LED_DATA		1

struct rtwn_rx_radiotap_header {
	struct ieee80211_radiotap_header wr_ihdr;
	uint64_t	wr_tsft;
	uint8_t		wr_flags;
	uint8_t		wr_rate;
	uint16_t	wr_chan_freq;
	uint16_t	wr_chan_flags;
	int8_t		wr_dbm_antsignal;
	int8_t		wr_dbm_antnoise;
} __packed __aligned(8);

#define RTWN_RX_RADIOTAP_PRESENT			\
	(1 << IEEE80211_RADIOTAP_TSFT |			\
	 1 << IEEE80211_RADIOTAP_FLAGS |		\
	 1 << IEEE80211_RADIOTAP_RATE |			\
	 1 << IEEE80211_RADIOTAP_CHANNEL |		\
	 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL |	\
	 1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)

struct rtwn_tx_radiotap_header {
	struct ieee80211_radiotap_header wt_ihdr;
	uint8_t		wt_flags;
	uint8_t		wt_pad;
	uint16_t	wt_chan_freq;
	uint16_t	wt_chan_flags;
} __packed;

#define RTWN_TX_RADIOTAP_PRESENT			\
	(1 << IEEE80211_RADIOTAP_FLAGS |		\
	 1 << IEEE80211_RADIOTAP_CHANNEL)

struct rtwn_tx_buf {
	uint8_t		txd[RTWN_TX_DESC_SIZE];
} __attribute__((aligned(4)));

#define RTWN_PHY_STATUS_SIZE	32
struct rtwn_tx_phystat {
	uint32_t	phydw[RTWN_PHY_STATUS_SIZE / sizeof(uint32_t)];
};

struct rtwn_softc;

union sec_param {
	struct ieee80211_key	key;
	int			macid;
};

#define CMD_FUNC_PROTO		void (*func)(struct rtwn_softc *, \
				    union sec_param *)

struct rtwn_cmdq {
	union sec_param		data;
	CMD_FUNC_PROTO;
};
#define RTWN_CMDQ_SIZE		16

struct rtwn_node {
	struct ieee80211_node	ni;	/* must be the first */
	int			id;

	struct rtwn_tx_phystat	last_physt;
	int			avg_pwdb;
};
#define RTWN_NODE(ni)		((struct rtwn_node *)(ni))

struct rtwn_vap {
	struct ieee80211vap	vap;
	int			id;
#define RTWN_VAP_ID_INVALID	-1
	int			curr_mode;

	struct rtwn_tx_buf	bcn_desc;
	struct mbuf		*bcn_mbuf;
	struct timeout_task	tx_beacon_csa;

	struct callout		tsf_sync_adhoc;
	struct task		tsf_sync_adhoc_task;

	const struct ieee80211_key	*keys[IEEE80211_WEP_NKID];

	int			(*newstate)(struct ieee80211vap *,
				    enum ieee80211_state, int);
	void			(*recv_mgmt)(struct ieee80211_node *,
				    struct mbuf *, int,
				    const struct ieee80211_rx_stats *,
				    int, int);
};
#define	RTWN_VAP(vap)		((struct rtwn_vap *)(vap))

/*
 * Rx data types.
 */
enum {
	RTWN_RX_DATA,
	RTWN_RX_TX_REPORT,
	RTWN_RX_OTHER
};

/*
 * Firmware reset reasons.
 */
enum {
	RTWN_FW_RESET_DOWNLOAD,
	RTWN_FW_RESET_CHECKSUM,
	RTWN_FW_RESET_SHUTDOWN
};

/*
 * Rate control algorithm selection.
 */
enum {
	RTWN_RATECTL_NONE,
	RTWN_RATECTL_NET80211,
	RTWN_RATECTL_FW,
	RTWN_RATECTL_MAX
};

/*
 * Control h/w crypto usage.
 */
enum {
	RTWN_CRYPTO_SW,
	RTWN_CRYPTO_PAIR,
	RTWN_CRYPTO_FULL,
	RTWN_CRYPTO_MAX,
};

struct rtwn_softc {
	struct ieee80211com	sc_ic;
	struct mbufq		sc_snd;
	device_t		sc_dev;

#if 1
	int			sc_ht40;
#endif
	uint32_t		sc_debug;
	int			sc_hwcrypto;
	int			sc_ratectl_sysctl;
	int			sc_ratectl;

	uint8_t			sc_detached;
	uint8_t			sc_flags;
/* Device flags */
#define RTWN_FLAG_CCK_HIPWR	0x01
#define RTWN_FLAG_EXT_HDR	0x02
#define RTWN_FLAG_CAM_FIXED	0x04
/* Driver state */
#define RTWN_STARTED		0x08
#define RTWN_RUNNING		0x10
#define RTWN_FW_LOADED		0x20
#define RTWN_TEMP_MEASURED	0x40
#define RTWN_RCR_LOCKED		0x80

#define RTWN_CHIP_HAS_BCNQ1(_sc)	\
	((_sc)->bcn_status_reg[0] != (_sc)->bcn_status_reg[1])

	void			*sc_priv;
	const char		*name;
	int			sc_ant;

	struct rtwn_tx_phystat	last_physt;
	uint8_t			thcal_temp;
	int			cur_bcnq_id;

	int			nvaps;
	int			ap_vaps;
	int			bcn_vaps;
	int			mon_vaps;

	int			vaps_running;
	int			monvaps_running;

	uint16_t		next_rom_addr;
	uint8_t			keys_bmap[howmany(RTWN_CAM_ENTRY_LIMIT, NBBY)];

	struct rtwn_vap		*vaps[RTWN_PORT_COUNT];
	struct ieee80211_node	*node_list[RTWN_MACID_LIMIT];
	struct mtx		nt_mtx;

	struct callout		sc_calib_to;
	struct callout		sc_pwrmode_init;
#ifndef D4054
	struct callout		sc_watchdog_to;
	int			sc_tx_timer;
#endif

	struct mtx		sc_mtx;

	struct rtwn_cmdq	cmdq[RTWN_CMDQ_SIZE];
	struct mtx		cmdq_mtx;
	struct task		cmdq_task;
	uint8_t			cmdq_first;
	uint8_t			cmdq_last;

	struct wmeParams	cap_wmeParams[WME_NUM_AC];

	struct rtwn_rx_radiotap_header	sc_rxtap;
	struct rtwn_tx_radiotap_header	sc_txtap;

	int			ntxchains;
	int			nrxchains;

	int			ledlink;
	uint8_t			thermal_meter;

	int			sc_tx_n_active;
	uint8_t			qfullmsk;

	/* Firmware-specific */
	const char		*fwname;
	uint16_t		fwver;
	uint16_t		fwsig;
	int			fwcur;

	void		(*sc_node_free)(struct ieee80211_node *);
	void		(*sc_scan_curchan)(struct ieee80211_scan_state *,
			    unsigned long);

	/* Interface-specific. */
	int		(*sc_write_1)(struct rtwn_softc *, uint16_t,
			    uint8_t);
	int		(*sc_write_2)(struct rtwn_softc *, uint16_t,
			    uint16_t);
	int		(*sc_write_4)(struct rtwn_softc *, uint16_t,
			    uint32_t);
	uint8_t		(*sc_read_1)(struct rtwn_softc *, uint16_t);
	uint16_t	(*sc_read_2)(struct rtwn_softc *, uint16_t);
	uint32_t	(*sc_read_4)(struct rtwn_softc *, uint16_t);
	/* XXX eliminate */
	void		(*sc_delay)(struct rtwn_softc *, int);
	int		(*sc_tx_start)(struct rtwn_softc *,
			    struct ieee80211_node *, struct mbuf *, uint8_t *,
			    uint8_t, int);
	void		(*sc_start_xfers)(struct rtwn_softc *);
	void		(*sc_reset_lists)(struct rtwn_softc *,
			    struct ieee80211vap *);
	void		(*sc_abort_xfers)(struct rtwn_softc *);
	int		(*sc_fw_write_block)(struct rtwn_softc *,
			    const uint8_t *, uint16_t, int);
	uint16_t	(*sc_get_qmap)(struct rtwn_softc *);
	void		(*sc_set_desc_addr)(struct rtwn_softc *);
	void		(*sc_drop_incorrect_tx)(struct rtwn_softc *);
	void		(*sc_beacon_update_begin)(struct rtwn_softc *,
			    struct ieee80211vap *);
	void		(*sc_beacon_update_end)(struct rtwn_softc *,
			    struct ieee80211vap *);
	void		(*sc_beacon_unload)(struct rtwn_softc *, int);

	/* XXX drop checks for PCIe? */
	int		bcn_check_interval;

	/* Device-specific. */
	uint32_t	(*sc_rf_read)(struct rtwn_softc *, int, uint8_t);
	void		(*sc_rf_write)(struct rtwn_softc *, int, uint8_t,
			    uint32_t);
	int		(*sc_check_condition)(struct rtwn_softc *,
			    const uint8_t[]);
	void		(*sc_efuse_postread)(struct rtwn_softc *);
	void		(*sc_parse_rom)(struct rtwn_softc *, uint8_t *);
	void		(*sc_set_led)(struct rtwn_softc *, int, int);
	int		(*sc_power_on)(struct rtwn_softc *);
	void		(*sc_power_off)(struct rtwn_softc *);
#ifndef RTWN_WITHOUT_UCODE
	void		(*sc_fw_reset)(struct rtwn_softc *, int);
	void		(*sc_fw_download_enable)(struct rtwn_softc *, int);
#endif
	int		(*sc_llt_init)(struct rtwn_softc *);
	int		(*sc_set_page_size)(struct rtwn_softc *);
	void		(*sc_lc_calib)(struct rtwn_softc *);
	void		(*sc_iq_calib)(struct rtwn_softc *);
	void		(*sc_read_chipid_vendor)(struct rtwn_softc *,
			    uint32_t);
	void		(*sc_adj_devcaps)(struct rtwn_softc *);
	void		(*sc_vap_preattach)(struct rtwn_softc *,
			    struct ieee80211vap *);
	void		(*sc_postattach)(struct rtwn_softc *);
	void		(*sc_detach_private)(struct rtwn_softc *);
	void		(*sc_fill_tx_desc)(struct rtwn_softc *,
			    struct ieee80211_node *, struct mbuf *,
			    void *, uint8_t, int);
	void		(*sc_fill_tx_desc_raw)(struct rtwn_softc *,
			    struct ieee80211_node *, struct mbuf *,
			    void *, const struct ieee80211_bpf_params *);
	void		(*sc_fill_tx_desc_null)(struct rtwn_softc *,
			    void *, int, int, int);
	void		(*sc_dump_tx_desc)(struct rtwn_softc *, const void *);
	uint8_t		(*sc_tx_radiotap_flags)(const void *);
	uint8_t		(*sc_rx_radiotap_flags)(const void *);
	void		(*sc_beacon_init)(struct rtwn_softc *, void *, int);
	void		(*sc_beacon_enable)(struct rtwn_softc *, int, int);
	void		(*sc_beacon_set_rate)(void *, int);
	void		(*sc_beacon_select)(struct rtwn_softc *, int);
	void		(*sc_set_chan)(struct rtwn_softc *,
			    struct ieee80211_channel *);
	void		(*sc_set_media_status)(struct rtwn_softc *, int);
#ifndef RTWN_WITHOUT_UCODE
	int		(*sc_set_rsvd_page)(struct rtwn_softc *, int, int,
			    int);
	int		(*sc_set_pwrmode)(struct rtwn_softc *,
			    struct ieee80211vap *, int);
	void		(*sc_set_rssi)(struct rtwn_softc *);
#endif
	void		(*sc_get_rx_stats)(struct rtwn_softc *,
			    struct ieee80211_rx_stats *, const void *,
			    const void *);
	int8_t		(*sc_get_rssi_cck)(struct rtwn_softc *, void *);
	int8_t		(*sc_get_rssi_ofdm)(struct rtwn_softc *, void *);
	int		(*sc_classify_intr)(struct rtwn_softc *, void *, int);
	void		(*sc_handle_tx_report)(struct rtwn_softc *, uint8_t *,
			    int);
	void		(*sc_handle_c2h_report)(struct rtwn_softc *,
			    uint8_t *, int);
	int		(*sc_check_frame)(struct rtwn_softc *, struct mbuf *);
	void		(*sc_temp_measure)(struct rtwn_softc *);
	uint8_t		(*sc_temp_read)(struct rtwn_softc *);
	void		(*sc_init_tx_agg)(struct rtwn_softc *);
	void		(*sc_init_rx_agg)(struct rtwn_softc *);
	void		(*sc_init_intr)(struct rtwn_softc *);
	void		(*sc_init_ampdu)(struct rtwn_softc *);
	void		(*sc_init_edca)(struct rtwn_softc *);
	void		(*sc_init_bb)(struct rtwn_softc *);
	void		(*sc_init_rf)(struct rtwn_softc *);
	void		(*sc_init_antsel)(struct rtwn_softc *);
	void		(*sc_post_init)(struct rtwn_softc *);
	int		(*sc_init_bcnq1_boundary)(struct rtwn_softc *);

	const uint8_t			*chan_list_5ghz[3];
	int				chan_num_5ghz[3];

	const struct rtwn_mac_prog	*mac_prog;
	int				mac_size;
	const struct rtwn_bb_prog	*bb_prog;
	int				bb_size;
	const struct rtwn_agc_prog	*agc_prog;
	int				agc_size;
	const struct rtwn_rf_prog	*rf_prog;

	int				page_count;
	int				pktbuf_count;

	int				ackto;

	int				npubqpages;
	int				nhqpages;
	int				nnqpages;
	int				nlqpages;
	int				page_size;

	int				txdesc_len;
	int				efuse_maxlen;
	int				efuse_maplen;

	uint16_t			rx_dma_size;

	int				macid_limit;
	int				cam_entry_limit;
	int				fwsize_limit;
	int				temp_delta;

	uint16_t			bcn_status_reg[RTWN_PORT_COUNT];
	uint32_t			rcr;	/* Rx filter */
};
MALLOC_DECLARE(M_RTWN_PRIV);

#define	RTWN_LOCK(sc)			mtx_lock(&(sc)->sc_mtx)
#define	RTWN_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
#define	RTWN_ASSERT_LOCKED(sc)		mtx_assert(&(sc)->sc_mtx, MA_OWNED)

#define RTWN_CMDQ_LOCK_INIT(sc) \
	mtx_init(&(sc)->cmdq_mtx, "cmdq lock", NULL, MTX_DEF)
#define RTWN_CMDQ_LOCK(sc)		mtx_lock(&(sc)->cmdq_mtx)
#define RTWN_CMDQ_UNLOCK(sc)		mtx_unlock(&(sc)->cmdq_mtx)
#define RTWN_CMDQ_LOCK_INITIALIZED(sc)	mtx_initialized(&(sc)->cmdq_mtx)
#define RTWN_CMDQ_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->cmdq_mtx)

#define RTWN_NT_LOCK_INIT(sc) \
	mtx_init(&(sc)->nt_mtx, "node table lock", NULL, MTX_DEF)
#define RTWN_NT_LOCK(sc)		mtx_lock(&(sc)->nt_mtx)
#define RTWN_NT_UNLOCK(sc)		mtx_unlock(&(sc)->nt_mtx)
#define RTWN_NT_LOCK_INITIALIZED(sc)	mtx_initialized(&(sc)->nt_mtx)
#define RTWN_NT_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->nt_mtx)

void	rtwn_sysctlattach(struct rtwn_softc *);

int	rtwn_attach(struct rtwn_softc *);
void	rtwn_detach(struct rtwn_softc *);
void	rtwn_resume(struct rtwn_softc *);
void	rtwn_suspend(struct rtwn_softc *);

/* Interface-specific. */
#define rtwn_write_1(_sc, _addr, _val) \
	(((_sc)->sc_write_1)((_sc), (_addr), (_val)))
#define rtwn_write_2(_sc, _addr, _val) \
	(((_sc)->sc_write_2)((_sc), (_addr), (_val)))
#define rtwn_write_4(_sc, _addr, _val) \
	(((_sc)->sc_write_4)((_sc), (_addr), (_val)))
#define rtwn_read_1(_sc, _addr) \
	(((_sc)->sc_read_1)((_sc), (_addr)))
#define rtwn_read_2(_sc, _addr) \
	(((_sc)->sc_read_2)((_sc), (_addr)))
#define rtwn_read_4(_sc, _addr) \
	(((_sc)->sc_read_4)((_sc), (_addr)))
#define rtwn_delay(_sc, _usec) \
	(((_sc)->sc_delay)((_sc), (_usec)))
#define rtwn_tx_start(_sc, _ni, _m, _desc, _type, _id) \
	(((_sc)->sc_tx_start)((_sc), (_ni), (_m), (_desc), (_type), (_id)))
#define rtwn_start_xfers(_sc) \
	(((_sc)->sc_start_xfers)((_sc)))
#define rtwn_reset_lists(_sc, _vap) \
	(((_sc)->sc_reset_lists)((_sc), (_vap)))
#define rtwn_abort_xfers(_sc) \
	(((_sc)->sc_abort_xfers)((_sc)))
#define rtwn_fw_write_block(_sc, _buf, _reg, _len) \
	(((_sc)->sc_fw_write_block)((_sc), (_buf), (_reg), (_len)))
#define rtwn_get_qmap(_sc) \
	(((_sc)->sc_get_qmap)((_sc)))
#define rtwn_set_desc_addr(_sc) \
	(((_sc)->sc_set_desc_addr)((_sc)))
#define rtwn_drop_incorrect_tx(_sc) \
	(((_sc)->sc_drop_incorrect_tx)((_sc)))
#define rtwn_beacon_update_begin(_sc, _vap) \
	(((_sc)->sc_beacon_update_begin)((_sc), (_vap)))
#define rtwn_beacon_update_end(_sc, _vap) \
	(((_sc)->sc_beacon_update_end)((_sc), (_vap)))
#define rtwn_beacon_unload(_sc, _id) \
	(((_sc)->sc_beacon_unload)((_sc), (_id)))

/* Aliases. */
#define	rtwn_bb_write		rtwn_write_4
#define	rtwn_bb_read		rtwn_read_4
#define	rtwn_bb_setbits		rtwn_setbits_4

/* Device-specific. */
#define rtwn_rf_read(_sc, _chain, _addr) \
	(((_sc)->sc_rf_read)((_sc), (_chain), (_addr)))
#define rtwn_rf_write(_sc, _chain, _addr, _val) \
	(((_sc)->sc_rf_write)((_sc), (_chain), (_addr), (_val)))
#define rtwn_check_condition(_sc, _cond) \
	(((_sc)->sc_check_condition)((_sc), (_cond)))
#define rtwn_efuse_postread(_sc) \
	(((_sc)->sc_efuse_postread)((_sc)))
#define rtwn_parse_rom(_sc, _rom) \
	(((_sc)->sc_parse_rom)((_sc), (_rom)))
#define rtwn_set_led(_sc, _led, _on) \
	(((_sc)->sc_set_led)((_sc), (_led), (_on)))
#define rtwn_get_rx_stats(_sc, _rxs, _desc, _physt) \
	(((_sc)->sc_get_rx_stats((_sc), (_rxs), (_desc), (_physt))))
#define rtwn_get_rssi_cck(_sc, _physt) \
	(((_sc)->sc_get_rssi_cck)((_sc), (_physt)))
#define rtwn_get_rssi_ofdm(_sc, _physt) \
	(((_sc)->sc_get_rssi_ofdm)((_sc), (_physt)))
#define rtwn_power_on(_sc) \
	(((_sc)->sc_power_on)((_sc)))
#define rtwn_power_off(_sc) \
	(((_sc)->sc_power_off)((_sc)))
#ifndef RTWN_WITHOUT_UCODE
#define rtwn_fw_reset(_sc, _reason) \
	(((_sc)->sc_fw_reset)((_sc), (_reason)))
#define rtwn_fw_download_enable(_sc, _enable) \
	(((_sc)->sc_fw_download_enable)((_sc), (_enable)))
#endif
#define rtwn_llt_init(_sc) \
	(((_sc)->sc_llt_init)((_sc)))
#define rtwn_set_page_size(_sc) \
	(((_sc)->sc_set_page_size)((_sc)))
#define rtwn_lc_calib(_sc) \
	(((_sc)->sc_lc_calib)((_sc)))
#define rtwn_iq_calib(_sc) \
	(((_sc)->sc_iq_calib)((_sc)))
#define rtwn_read_chipid_vendor(_sc, _reg) \
	(((_sc)->sc_read_chipid_vendor)((_sc), (_reg)))
#define rtwn_adj_devcaps(_sc) \
	(((_sc)->sc_adj_devcaps)((_sc)))
#define rtwn_vap_preattach(_sc, _vap) \
	(((_sc)->sc_vap_preattach)((_sc), (_vap)))
#define rtwn_postattach(_sc) \
	(((_sc)->sc_postattach)((_sc)))
#define rtwn_detach_private(_sc) \
	(((_sc)->sc_detach_private)((_sc)))
#define rtwn_fill_tx_desc(_sc, _ni, _m, \
	    _buf, _ridx, _maxretry) \
	(((_sc)->sc_fill_tx_desc)((_sc), (_ni), \
	    (_m), (_buf), (_ridx), (_maxretry)))
#define rtwn_fill_tx_desc_raw(_sc, _ni, _m, \
	    _buf, _params) \
	(((_sc)->sc_fill_tx_desc_raw)((_sc), (_ni), \
	    (_m), (_buf), (_params)))
#define rtwn_fill_tx_desc_null(_sc, _buf, _11b, _qos, _id) \
	(((_sc)->sc_fill_tx_desc_null)((_sc), \
	    (_buf), (_11b), (_qos), (_id)))
#define rtwn_dump_tx_desc(_sc, _desc) \
	(((_sc)->sc_dump_tx_desc)((_sc), (_desc)))
#define rtwn_tx_radiotap_flags(_sc, _buf) \
	(((_sc)->sc_tx_radiotap_flags)((_buf)))
#define rtwn_rx_radiotap_flags(_sc, _buf) \
	(((_sc)->sc_rx_radiotap_flags)((_buf)))
#define rtwn_set_chan(_sc, _c) \
	(((_sc)->sc_set_chan)((_sc), (_c)))
#ifndef RTWN_WITHOUT_UCODE
#define rtwn_set_rsvd_page(_sc, _resp, _null, _qos_null) \
	(((_sc)->sc_set_rsvd_page)((_sc), \
	    (_resp), (_null), (_qos_null)))
#define rtwn_set_pwrmode(_sc, _vap, _off) \
	(((_sc)->sc_set_pwrmode)((_sc), (_vap), (_off)))
#define rtwn_set_rssi(_sc) \
	(((_sc)->sc_set_rssi)((_sc)))
#endif
#define rtwn_classify_intr(_sc, _buf, _len) \
	(((_sc)->sc_classify_intr)((_sc), (_buf), (_len)))
#define rtwn_handle_tx_report(_sc, _buf, _len) \
	(((_sc)->sc_handle_tx_report)((_sc), (_buf), (_len)))
#define rtwn_handle_c2h_report(_sc, _buf, _len) \
	(((_sc)->sc_handle_c2h_report)((_sc), (_buf), (_len)))
#define rtwn_check_frame(_sc, _m) \
	(((_sc)->sc_check_frame)((_sc), (_m)))
#define rtwn_beacon_init(_sc, _buf, _id) \
	(((_sc)->sc_beacon_init)((_sc), (_buf), (_id)))
#define rtwn_beacon_enable(_sc, _id, _enable) \
	(((_sc)->sc_beacon_enable)((_sc), (_id), (_enable)))
#define rtwn_beacon_set_rate(_sc, _buf, _is5ghz) \
	(((_sc)->sc_beacon_set_rate)((_buf), (_is5ghz)))
#define rtwn_beacon_select(_sc, _id) \
	(((_sc)->sc_beacon_select)((_sc), (_id)))
#define rtwn_temp_measure(_sc) \
	(((_sc)->sc_temp_measure)((_sc)))
#define rtwn_temp_read(_sc) \
	(((_sc)->sc_temp_read)((_sc)))
#define rtwn_init_tx_agg(_sc) \
	(((_sc)->sc_init_tx_agg)((_sc)))
#define rtwn_init_rx_agg(_sc) \
	(((_sc)->sc_init_rx_agg)((_sc)))
#define rtwn_init_intr(_sc) \
	(((_sc)->sc_init_intr)((_sc)))
#define rtwn_init_ampdu(_sc) \
	(((_sc)->sc_init_ampdu)((_sc)))
#define rtwn_init_edca(_sc) \
	(((_sc)->sc_init_edca)((_sc)))
#define rtwn_init_bb(_sc) \
	(((_sc)->sc_init_bb)((_sc)))
#define rtwn_init_rf(_sc) \
	(((_sc)->sc_init_rf)((_sc)))
#define rtwn_init_antsel(_sc) \
	(((_sc)->sc_init_antsel)((_sc)))
#define rtwn_post_init(_sc) \
	(((_sc)->sc_post_init)((_sc)))
#define rtwn_init_bcnq1_boundary(_sc) \
	(((_sc)->sc_init_bcnq1_boundary)((_sc)))

/*
 * Methods to access subfields in registers.
 */
static __inline int
rtwn_setbits_1(struct rtwn_softc *sc, uint16_t addr, uint8_t clr,
    uint8_t set)
{
	return (rtwn_write_1(sc, addr,
	    (rtwn_read_1(sc, addr) & ~clr) | set));
}

static __inline int
rtwn_setbits_1_shift(struct rtwn_softc *sc, uint16_t addr, uint32_t clr,
    uint32_t set, int shift)
{
	return (rtwn_setbits_1(sc, addr + shift, clr >> shift * NBBY,
	    set >> shift * NBBY));
}

static __inline int
rtwn_setbits_2(struct rtwn_softc *sc, uint16_t addr, uint16_t clr,
    uint16_t set)
{
	return (rtwn_write_2(sc, addr,
	    (rtwn_read_2(sc, addr) & ~clr) | set));
}

static __inline int
rtwn_setbits_4(struct rtwn_softc *sc, uint16_t addr, uint32_t clr,
    uint32_t set)
{
	return (rtwn_write_4(sc, addr,
	    (rtwn_read_4(sc, addr) & ~clr) | set));
}

static __inline void
rtwn_rf_setbits(struct rtwn_softc *sc, int chain, uint8_t addr,
    uint32_t clr, uint32_t set)
{
	rtwn_rf_write(sc, chain, addr,
	    (rtwn_rf_read(sc, chain, addr) & ~clr) | set);
}

#endif	/* IF_RTWNVAR_H */