xref: /freebsd/sys/dev/bwn/if_bwnvar.h (revision d8a0fe102c0cfdfcd5b818f850eff09d8536c9bc)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer,
12  *    without modification.
13  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
15  *    redistribution must be conditioned upon including a substantially
16  *    similar Disclaimer requirement for further binary redistribution.
17  *
18  * NO WARRANTY
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
22  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
24  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29  * THE POSSIBILITY OF SUCH DAMAGES.
30  *
31  * $FreeBSD$
32  */
33 
34 #ifndef _IF_BWNVAR_H
35 #define	_IF_BWNVAR_H
36 
37 #include "if_bwn_siba.h"
38 
39 struct bwn_softc;
40 struct bwn_mac;
41 
42 extern driver_t bwn_driver;
43 
44 int	bwn_attach(device_t dev);
45 int	bwn_detach(device_t dev);
46 
47 #define	N(a)			(sizeof(a) / sizeof(a[0]))
48 #define	BWN_ALIGN			0x1000
49 #define	BWN_BUS_SPACE_MAXADDR_30BIT	0x3fffffff
50 #define	BWN_RETRY_SHORT			7
51 #define	BWN_RETRY_LONG			4
52 #define	BWN_STAID_MAX			64
53 #define	BWN_TXPWR_IGNORE_TIME		(1 << 0)
54 #define	BWN_TXPWR_IGNORE_TSSI		(1 << 1)
55 #define	BWN_HAS_TXMAG(phy)						\
56 	(((phy)->rev >= 2) && ((phy)->rf_ver == 0x2050) &&		\
57 	 ((phy)->rf_rev == 8))
58 #define	BWN_HAS_LOOPBACK(phy)						\
59 	(((phy)->rev > 1) || ((phy)->gmode))
60 #define	BWN_TXERROR_MAX			1000
61 #define	BWN_GETTIME(v)	do {						\
62 	struct timespec ts;						\
63 	nanouptime(&ts);						\
64 	(v) = ts.tv_nsec / 1000000 + ts.tv_sec * 1000;			\
65 } while (0)
66 #define	BWN_ISOLDFMT(mac)		((mac)->mac_fw.rev <= 351)
67 #define	BWN_TSSI2DBM(num, den)						\
68 	((int32_t)((num < 0) ? num / den : (num + den / 2) / den))
69 #define	BWN_HDRSIZE(mac)	bwn_tx_hdrsize(mac)
70 #define	BWN_MAXTXHDRSIZE	(112 + (sizeof(struct bwn_plcp6)))
71 
72 #define	BWN_PIO_COOKIE(tq, tp)						\
73 	((uint16_t)((((uint16_t)tq->tq_index + 1) << 12) | tp->tp_index))
74 #define	BWN_DMA_COOKIE(dr, slot)					\
75 	((uint16_t)(((uint16_t)dr->dr_index + 1) << 12) | (uint16_t)slot)
76 #define	BWN_READ_2(mac, o)		(siba_read_2(mac->mac_sc->sc_dev, o))
77 #define	BWN_READ_4(mac, o)		(siba_read_4(mac->mac_sc->sc_dev, o))
78 #define	BWN_WRITE_2(mac, o, v)						\
79 	(siba_write_2(mac->mac_sc->sc_dev, o, v))
80 #define	BWN_WRITE_2_F(mac, o, v) do { \
81 	(BWN_WRITE_2(mac, o, v)); \
82 	BWN_READ_2(mac, o); \
83 } while(0)
84 #define	BWN_WRITE_SETMASK2(mac, offset, mask, set)			\
85 	BWN_WRITE_2(mac, offset, (BWN_READ_2(mac, offset) & mask) | set)
86 #define	BWN_WRITE_4(mac, o, v)						\
87 	(siba_write_4(mac->mac_sc->sc_dev, o, v))
88 #define	BWN_WRITE_SETMASK4(mac, offset, mask, set)			\
89 	BWN_WRITE_4(mac, offset, (BWN_READ_4(mac, offset) & mask) | set)
90 #define	BWN_PIO_TXQOFFSET(mac)						\
91 	((siba_get_revid(mac->mac_sc->sc_dev) >= 11) ? 0x18 : 0)
92 #define	BWN_PIO_RXQOFFSET(mac)						\
93 	((siba_get_revid(mac->mac_sc->sc_dev) >= 11) ? 0x38 : 8)
94 #define	BWN_SEC_NEWAPI(mac)		(mac->mac_fw.rev >= 351)
95 #define	BWN_SEC_KEY2FW(mac, idx)					\
96 	(BWN_SEC_NEWAPI(mac) ? idx : ((idx >= 4) ? idx - 4 : idx))
97 #define	BWN_RF_READ(mac, r)		(mac->mac_phy.rf_read(mac, r))
98 #define	BWN_RF_WRITE(mac, r, v)		(mac->mac_phy.rf_write(mac, r, v))
99 #define	BWN_RF_MASK(mac, o, m)						\
100 	BWN_RF_WRITE(mac, o, BWN_RF_READ(mac, o) & m)
101 #define	BWN_RF_SETMASK(mac, offset, mask, set)				\
102 	BWN_RF_WRITE(mac, offset, (BWN_RF_READ(mac, offset) & mask) | set)
103 #define	BWN_RF_SET(mac, offset, set)					\
104 	BWN_RF_WRITE(mac, offset, BWN_RF_READ(mac, offset) | set)
105 #define	BWN_PHY_READ(mac, r)		(mac->mac_phy.phy_read(mac, r))
106 #define	BWN_PHY_WRITE(mac, r, v)					\
107 	(mac->mac_phy.phy_write(mac, r, v))
108 #define	BWN_PHY_SET(mac, offset, set)	do {				\
109 	if (mac->mac_phy.phy_maskset != NULL) {				\
110 		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
111 		    mac->mac_suspended > 0,				\
112 		    ("dont access PHY or RF registers after turning on MAC")); \
113 		mac->mac_phy.phy_maskset(mac, offset, 0xffff, set);	\
114 	} else								\
115 		BWN_PHY_WRITE(mac, offset,				\
116 		    BWN_PHY_READ(mac, offset) | (set));			\
117 } while (0)
118 #define	BWN_PHY_SETMASK(mac, offset, mask, set)	do {			\
119 	if (mac->mac_phy.phy_maskset != NULL) {				\
120 		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
121 		    mac->mac_suspended > 0,				\
122 		    ("dont access PHY or RF registers after turning on MAC")); \
123 		mac->mac_phy.phy_maskset(mac, offset, mask, set);	\
124 	} else								\
125 		BWN_PHY_WRITE(mac, offset,				\
126 		    (BWN_PHY_READ(mac, offset) & (mask)) | (set));	\
127 } while (0)
128 #define	BWN_PHY_MASK(mac, offset, mask)	do {				\
129 	if (mac->mac_phy.phy_maskset != NULL) {				\
130 		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
131 		    mac->mac_suspended > 0,				\
132 		    ("dont access PHY or RF registers after turning on MAC")); \
133 		mac->mac_phy.phy_maskset(mac, offset, mask, 0);		\
134 	} else								\
135 		BWN_PHY_WRITE(mac, offset,				\
136 		    BWN_PHY_READ(mac, offset) & mask);			\
137 } while (0)
138 #define	BWN_PHY_COPY(mac, dst, src)	do {				\
139 	KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||		\
140 	    mac->mac_suspended > 0,					\
141 	    ("dont access PHY or RF registers after turning on MAC"));	\
142 	BWN_PHY_WRITE(mac, dst, BWN_PHY_READ(mac, src));		\
143 } while (0)
144 #define BWN_LO_CALIB_EXPIRE		(1000 * (30 - 2))
145 #define BWN_LO_PWRVEC_EXPIRE		(1000 * (30 - 2))
146 #define BWN_LO_TXCTL_EXPIRE		(1000 * (180 - 4))
147 #define	BWN_DMA_BIT_MASK(n)		(((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
148 #define BWN_LPD(L, P, D)		(((L) << 2) | ((P) << 1) | ((D) << 0))
149 #define BWN_BITREV4(tmp)		(BWN_BITREV8(tmp) >> 4)
150 #define	BWN_BITREV8(byte)		(bwn_bitrev_table[byte])
151 #define	BWN_BBATTCMP(a, b)		((a)->att == (b)->att)
152 #define	BWN_RFATTCMP(a, b)						\
153 	(((a)->att == (b)->att) && ((a)->padmix == (b)->padmix))
154 #define	BWN_PIO_WRITE_2(mac, tq, offset, value)				\
155 	BWN_WRITE_2(mac, (tq)->tq_base + offset, value)
156 #define	BWN_PIO_READ_4(mac, tq, offset)					\
157 	BWN_READ_4(mac, tq->tq_base + offset)
158 #define	BWN_ISCCKRATE(rate)						\
159 	(rate == BWN_CCK_RATE_1MB || rate == BWN_CCK_RATE_2MB ||	\
160 	 rate == BWN_CCK_RATE_5MB || rate == BWN_CCK_RATE_11MB)
161 #define	BWN_ISOFDMRATE(rate)		(!BWN_ISCCKRATE(rate))
162 #define	BWN_BARRIER(mac, flags)		siba_barrier(mac->mac_sc->sc_dev, flags)
163 #define	BWN_DMA_READ(dr, offset)				\
164 	(BWN_READ_4(dr->dr_mac, dr->dr_base + offset))
165 #define	BWN_DMA_WRITE(dr, offset, value)			\
166 	(BWN_WRITE_4(dr->dr_mac, dr->dr_base + offset, value))
167 
168 
169 typedef enum {
170 	BWN_PHY_BAND_2G = 0,
171 	BWN_PHY_BAND_5G_LO = 1,
172 	BWN_PHY_BAND_5G_MI = 2,
173 	BWN_PHY_BAND_5G_HI = 3
174 } bwn_phy_band_t;
175 
176 typedef enum {
177 	BWN_BAND_2G,
178 	BWN_BAND_5G,
179 } bwn_band_t;
180 
181 typedef enum {
182 	BWN_CHAN_TYPE_20,
183 	BWN_CHAN_TYPE_20_HT,
184 	BWN_CHAN_TYPE_40_HT_U,
185 	BWN_CHAN_TYPE_40_HT_D,
186 } bwn_chan_type_t;
187 
188 struct bwn_rate {
189 	uint16_t			rateid;
190 	uint32_t			flags;
191 };
192 
193 #define	BWN_ANT0			0
194 #define	BWN_ANT1			1
195 #define	BWN_ANTAUTO0			2
196 #define	BWN_ANTAUTO1			3
197 #define	BWN_ANT2			4
198 #define	BWN_ANT3			8
199 #define	BWN_ANTAUTO			BWN_ANTAUTO0
200 #define	BWN_ANT_DEFAULT			BWN_ANTAUTO
201 #define	BWN_TX_SLOTS_PER_FRAME		2
202 
203 struct bwn_channel {
204 	unsigned			freq;
205 	unsigned			ieee;
206 	unsigned			maxTxPow;
207 };
208 
209 struct bwn_channelinfo {
210 	struct bwn_channel		channels[IEEE80211_CHAN_MAX];
211 	unsigned			nchannels;
212 };
213 
214 struct bwn_bbatt {
215 	uint8_t				att;
216 };
217 
218 struct bwn_bbatt_list {
219 	const struct bwn_bbatt		*array;
220 	uint8_t				len;
221 	uint8_t				min;
222 	uint8_t				max;
223 };
224 
225 struct bwn_rfatt {
226 	uint8_t				att;
227 	int				padmix;
228 };
229 
230 struct bwn_rfatt_list {
231 	const struct bwn_rfatt		*array;
232 	uint8_t				len;
233 	uint8_t				min;
234 	uint8_t				max;
235 };
236 
237 #define	BWN_DC_LT_SIZE			32
238 
239 struct bwn_loctl {
240 	int8_t				i;
241 	int8_t				q;
242 };
243 
244 typedef enum {
245 	BWN_TXPWR_RES_NEED_ADJUST,
246 	BWN_TXPWR_RES_DONE,
247 } bwn_txpwr_result_t;
248 
249 struct bwn_lo_calib {
250 	struct bwn_bbatt		bbatt;
251 	struct bwn_rfatt		rfatt;
252 	struct bwn_loctl		ctl;
253 	unsigned long			calib_time;
254 	TAILQ_ENTRY(bwn_lo_calib)	list;
255 };
256 
257 struct bwn_rxhdr4 {
258 	uint16_t			frame_len;
259 	uint8_t				pad1[2];
260 	uint16_t			phy_status0;
261 	union {
262 		struct {
263 			uint8_t		rssi;
264 			uint8_t		sig_qual;
265 		} __packed abg;
266 		struct {
267 			int8_t		power0;
268 			int8_t		power1;
269 		} __packed n;
270 	} __packed phy;
271 	union {
272 		struct {
273 			int8_t		power2;
274 			uint8_t		pad;
275 		} __packed n;
276 		struct {
277 			uint8_t		pad;
278 			int8_t		ht_power0;
279 		} __packed ht;
280 		uint16_t		phy_status2;
281 	} __packed ps2;
282 	union {
283 		struct {
284 			uint16_t	phy_status3;
285 		} __packed lp;
286 		struct {
287 			int8_t		phy_ht_power1;
288 			int8_t		phy_ht_power2;
289 		} __packed ht;
290 	} __packed ps3;
291 	union {
292 		struct {
293 			uint32_t	mac_status;
294 			uint16_t	mac_time;
295 			uint16_t	channel;
296 		} __packed r351;
297 		struct {
298 			uint16_t	phy_status4;
299 			uint16_t	phy_status5;
300 			uint32_t	mac_status;
301 			uint16_t	mac_time;
302 			uint16_t	channel;
303 		} __packed r598;
304 	} __packed ps4;
305 } __packed;
306 
307 struct bwn_txstatus {
308 	uint16_t			cookie;
309 	uint16_t			seq;
310 	uint8_t				phy_stat;
311 	uint8_t				framecnt;
312 	uint8_t				rtscnt;
313 	uint8_t				sreason;
314 	uint8_t				pm;
315 	uint8_t				im;
316 	uint8_t				ampdu;
317 	uint8_t				ack;
318 };
319 
320 #define	BWN_TXCTL_PA3DB			0x40
321 #define	BWN_TXCTL_PA2DB			0x20
322 #define	BWN_TXCTL_TXMIX			0x10
323 
324 struct bwn_txpwr_loctl {
325 	struct bwn_rfatt_list		rfatt;
326 	struct bwn_bbatt_list		bbatt;
327 	uint16_t			dc_lt[BWN_DC_LT_SIZE];
328 	TAILQ_HEAD(, bwn_lo_calib)	calib_list;
329 	unsigned long			pwr_vec_read_time;
330 	unsigned long			txctl_measured_time;
331 	uint8_t				tx_bias;
332 	uint8_t				tx_magn;
333 	uint64_t			power_vector;
334 };
335 
336 #define	BWN_OFDMTAB_DIR_UNKNOWN		0
337 #define	BWN_OFDMTAB_DIR_READ		1
338 #define	BWN_OFDMTAB_DIR_WRITE		2
339 
340 struct bwn_phy_g {
341 	unsigned			pg_flags;
342 #define	BWN_PHY_G_FLAG_TSSITABLE_ALLOC	(1 << 0)
343 #define	BWN_PHY_G_FLAG_RADIOCTX_VALID	(1 << 1)
344 	int				pg_aci_enable;
345 	int				pg_aci_wlan_automatic;
346 	int				pg_aci_hw_rssi;
347 	int				pg_rf_on;
348 	uint16_t			pg_radioctx_over;
349 	uint16_t			pg_radioctx_overval;
350 	uint16_t			pg_minlowsig[2];
351 	uint16_t			pg_minlowsigpos[2];
352 	int8_t				*pg_tssi2dbm;
353 	int				pg_idletssi;
354 	int				pg_curtssi;
355 	uint8_t				pg_avgtssi;
356 	struct bwn_bbatt		pg_bbatt;
357 	struct bwn_rfatt		pg_rfatt;
358 	uint8_t				pg_txctl;
359 	int				pg_bbatt_delta;
360 	int				pg_rfatt_delta;
361 
362 	struct bwn_txpwr_loctl		pg_loctl;
363 	int16_t				pg_max_lb_gain;
364 	int16_t				pg_trsw_rx_gain;
365 	int16_t				pg_lna_lod_gain;
366 	int16_t				pg_lna_gain;
367 	int16_t				pg_pga_gain;
368 	int				pg_immode;
369 #define	BWN_INTERFSTACK_SIZE	26
370 	uint32_t			pg_interfstack[BWN_INTERFSTACK_SIZE];
371 
372 	int16_t				pg_nrssi[2];
373 	int32_t				pg_nrssi_slope;
374 	int8_t				pg_nrssi_lt[64];
375 
376 	uint16_t			pg_lofcal;
377 
378 	uint16_t			pg_initval;
379 	uint16_t			pg_ofdmtab_addr;
380 	unsigned			pg_ofdmtab_dir;
381 };
382 
383 #define	BWN_IMMODE_NONE			0
384 #define	BWN_IMMODE_NONWLAN		1
385 #define	BWN_IMMODE_MANUAL		2
386 #define	BWN_IMMODE_AUTO			3
387 
388 #define	BWN_PHYLP_TXPCTL_UNKNOWN	0
389 #define	BWN_PHYLP_TXPCTL_OFF		1
390 #define	BWN_PHYLP_TXPCTL_ON_SW		2
391 #define	BWN_PHYLP_TXPCTL_ON_HW		3
392 
393 struct bwn_phy_lp {
394 	uint8_t				plp_chan;
395 	uint8_t				plp_chanfullcal;
396 	int32_t				plp_antenna;
397 	uint8_t				plp_txpctlmode;
398 	uint8_t				plp_txisoband_h;
399 	uint8_t				plp_txisoband_m;
400 	uint8_t				plp_txisoband_l;
401 	uint8_t				plp_rxpwroffset;
402 	int8_t				plp_txpwridx;
403 	uint16_t			plp_tssiidx;
404 	uint16_t			plp_tssinpt;
405 	uint8_t				plp_rssivf;
406 	uint8_t				plp_rssivc;
407 	uint8_t				plp_rssigs;
408 	uint8_t				plp_rccap;
409 	uint8_t				plp_bxarch;
410 	uint8_t				plp_crsusr_off;
411 	uint8_t				plp_crssys_off;
412 	uint32_t			plp_div;
413 	int32_t				plp_tonefreq;
414 	uint16_t			plp_digfilt[9];
415 };
416 
417 /* for LP */
418 struct bwn_txgain {
419 	uint16_t			tg_gm;
420 	uint16_t			tg_pga;
421 	uint16_t			tg_pad;
422 	uint16_t			tg_dac;
423 };
424 
425 struct bwn_rxcompco {
426 	uint8_t				rc_chan;
427 	int8_t				rc_c1;
428 	int8_t				rc_c0;
429 };
430 
431 struct bwn_phy_lp_iq_est {
432 	uint32_t			ie_iqprod;
433 	uint32_t			ie_ipwr;
434 	uint32_t			ie_qpwr;
435 };
436 
437 struct bwn_txgain_entry {
438 	uint8_t				te_gm;
439 	uint8_t				te_pga;
440 	uint8_t				te_pad;
441 	uint8_t				te_dac;
442 	uint8_t				te_bbmult;
443 };
444 
445 /* only for LP PHY */
446 struct bwn_stxtable {
447 	uint16_t			st_phyoffset;
448 	uint16_t			st_physhift;
449 	uint16_t			st_rfaddr;
450 	uint16_t			st_rfshift;
451 	uint16_t			st_mask;
452 };
453 
454 struct bwn_b206x_chan {
455 	uint8_t				bc_chan;
456 	uint16_t			bc_freq;
457 	const uint8_t			*bc_data;
458 };
459 
460 struct bwn_b206x_rfinit_entry {
461 	uint16_t			br_offset;
462 	uint16_t			br_valuea;
463 	uint16_t			br_valueg;
464 	uint8_t				br_flags;
465 };
466 
467 struct bwn_phy_n;
468 
469 struct bwn_phy {
470 	uint8_t				type;
471 	uint8_t				rev;
472 	uint8_t				analog;
473 
474 	int				supports_2ghz;
475 	int				supports_5ghz;
476 
477 	int				gmode;
478 	struct bwn_phy_g		phy_g;
479 	struct bwn_phy_lp		phy_lp;
480 
481 	/*
482 	 * I'd like the newer PHY code to not hide in the top-level
483 	 * structs..
484 	 */
485 	struct bwn_phy_n		*phy_n;
486 
487 	uint16_t			rf_manuf;
488 	uint16_t			rf_ver;
489 	uint8_t				rf_rev;
490 	int				rf_on;
491 	int				phy_do_full_init;
492 
493 	int				txpower;
494 	int				hwpctl;
495 	unsigned long			nexttime;
496 	unsigned int			chan;
497 	int				txerrors;
498 
499 	int				(*attach)(struct bwn_mac *);
500 	void				(*detach)(struct bwn_mac *);
501 	int				(*prepare_hw)(struct bwn_mac *);
502 	void				(*init_pre)(struct bwn_mac *);
503 	int				(*init)(struct bwn_mac *);
504 	void				(*exit)(struct bwn_mac *);
505 	uint16_t			(*phy_read)(struct bwn_mac *, uint16_t);
506 	void				(*phy_write)(struct bwn_mac *, uint16_t,
507 					    uint16_t);
508 	void				(*phy_maskset)(struct bwn_mac *,
509 					    uint16_t, uint16_t, uint16_t);
510 	uint16_t			(*rf_read)(struct bwn_mac *, uint16_t);
511 	void				(*rf_write)(struct bwn_mac *, uint16_t,
512 					    uint16_t);
513 	int				(*use_hwpctl)(struct bwn_mac *);
514 	void				(*rf_onoff)(struct bwn_mac *, int);
515 	void				(*switch_analog)(struct bwn_mac *, int);
516 	int				(*switch_channel)(struct bwn_mac *,
517 					    unsigned int);
518 	uint32_t			(*get_default_chan)(struct bwn_mac *);
519 	void				(*set_antenna)(struct bwn_mac *, int);
520 	int				(*set_im)(struct bwn_mac *, int);
521 	bwn_txpwr_result_t		(*recalc_txpwr)(struct bwn_mac *, int);
522 	void				(*set_txpwr)(struct bwn_mac *);
523 	void				(*task_15s)(struct bwn_mac *);
524 	void				(*task_60s)(struct bwn_mac *);
525 };
526 
527 struct bwn_chan_band {
528 	uint32_t			flags;
529 	uint8_t				nchan;
530 #define	BWN_MAX_CHAN_PER_BAND		14
531 	uint8_t				chan[BWN_MAX_CHAN_PER_BAND];
532 };
533 
534 #define	BWN_NR_WMEPARAMS		16
535 enum {
536 	BWN_WMEPARAM_TXOP = 0,
537 	BWN_WMEPARAM_CWMIN,
538 	BWN_WMEPARAM_CWMAX,
539 	BWN_WMEPARAM_CWCUR,
540 	BWN_WMEPARAM_AIFS,
541 	BWN_WMEPARAM_BSLOTS,
542 	BWN_WMEPARAM_REGGAP,
543 	BWN_WMEPARAM_STATUS,
544 };
545 
546 #define	BWN_WME_PARAMS(queue)	\
547 	(BWN_SHARED_EDCFQ + (BWN_NR_WMEPARAMS * sizeof(uint16_t) * (queue)))
548 #define	BWN_WME_BACKGROUND	BWN_WME_PARAMS(0)
549 #define	BWN_WME_BESTEFFORT	BWN_WME_PARAMS(1)
550 #define	BWN_WME_VIDEO		BWN_WME_PARAMS(2)
551 #define	BWN_WME_VOICE		BWN_WME_PARAMS(3)
552 
553 /*
554  * Radio capture format.
555  */
556 #define	BWN_RX_RADIOTAP_PRESENT (		\
557 	(1 << IEEE80211_RADIOTAP_TSFT)		| \
558 	(1 << IEEE80211_RADIOTAP_FLAGS)		| \
559 	(1 << IEEE80211_RADIOTAP_RATE)		| \
560 	(1 << IEEE80211_RADIOTAP_CHANNEL)	| \
561 	(1 << IEEE80211_RADIOTAP_ANTENNA)	| \
562 	(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)	| \
563 	(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)	| \
564 	0)
565 
566 struct bwn_rx_radiotap_header {
567 	struct ieee80211_radiotap_header wr_ihdr;
568 	uint64_t			wr_tsf;
569 	u_int8_t			wr_flags;
570 	u_int8_t			wr_rate;
571 	u_int16_t			wr_chan_freq;
572 	u_int16_t			wr_chan_flags;
573 	int8_t				wr_antsignal;
574 	int8_t				wr_antnoise;
575 	u_int8_t			wr_antenna;
576 };
577 
578 #define	BWN_TX_RADIOTAP_PRESENT (		\
579 	(1 << IEEE80211_RADIOTAP_FLAGS)		| \
580 	(1 << IEEE80211_RADIOTAP_RATE)		| \
581 	(1 << IEEE80211_RADIOTAP_CHANNEL)	| \
582 	(1 << IEEE80211_RADIOTAP_DBM_TX_POWER)	| \
583 	(1 << IEEE80211_RADIOTAP_ANTENNA)	| \
584 	0)
585 
586 struct bwn_tx_radiotap_header {
587 	struct ieee80211_radiotap_header wt_ihdr;
588 	u_int8_t			wt_flags;
589 	u_int8_t			wt_rate;
590 	u_int16_t			wt_chan_freq;
591 	u_int16_t			wt_chan_flags;
592 	u_int8_t			wt_txpower;
593 	u_int8_t			wt_antenna;
594 };
595 
596 struct bwn_stats {
597 	int32_t				rtsfail;
598 	int32_t				rts;
599 	int32_t				link_noise;
600 };
601 
602 /* Noise Calculation (Link Quality) */
603 struct bwn_noise {
604 	uint8_t				noi_running;
605 	uint8_t				noi_nsamples;
606 	int8_t				noi_samples[8][4];
607 };
608 
609 #define	BWN_DMA_30BIT			30
610 #define	BWN_DMA_32BIT			32
611 #define	BWN_DMA_64BIT			64
612 
613 struct bwn_dmadesc_meta {
614 	bus_dmamap_t			mt_dmap;
615 	bus_addr_t			mt_paddr;
616 	struct mbuf			*mt_m;
617 	struct ieee80211_node		*mt_ni;
618 	uint8_t				mt_txtype;
619 #define	BWN_DMADESC_METATYPE_HEADER	0
620 #define	BWN_DMADESC_METATYPE_BODY	1
621 	uint8_t				mt_islast;
622 };
623 
624 #define	BWN_DMAINTR_FATALMASK	\
625 	((1 << 10) | (1 << 11) | (1 << 12) | (1 << 14) | (1 << 15))
626 #define	BWN_DMAINTR_NONFATALMASK	(1 << 13)
627 #define	BWN_DMAINTR_RX_DONE		(1 << 16)
628 
629 #define	BWN_DMA32_DCTL_BYTECNT		0x00001fff
630 #define	BWN_DMA32_DCTL_ADDREXT_MASK	0x00030000
631 #define	BWN_DMA32_DCTL_ADDREXT_SHIFT	16
632 #define	BWN_DMA32_DCTL_DTABLEEND	0x10000000
633 #define	BWN_DMA32_DCTL_IRQ		0x20000000
634 #define	BWN_DMA32_DCTL_FRAMEEND		0x40000000
635 #define	BWN_DMA32_DCTL_FRAMESTART	0x80000000
636 struct bwn_dmadesc32 {
637 	uint32_t			control;
638 	uint32_t			address;
639 } __packed;
640 
641 #define	BWN_DMA64_DCTL0_DTABLEEND	0x10000000
642 #define	BWN_DMA64_DCTL0_IRQ		0x20000000
643 #define	BWN_DMA64_DCTL0_FRAMEEND	0x40000000
644 #define	BWN_DMA64_DCTL0_FRAMESTART	0x80000000
645 #define	BWN_DMA64_DCTL1_BYTECNT		0x00001fff
646 #define	BWN_DMA64_DCTL1_ADDREXT_MASK	0x00030000
647 #define	BWN_DMA64_DCTL1_ADDREXT_SHIFT	16
648 struct bwn_dmadesc64 {
649 	uint32_t			control0;
650 	uint32_t			control1;
651 	uint32_t			address_low;
652 	uint32_t			address_high;
653 } __packed;
654 
655 struct bwn_dmadesc_generic {
656 	union {
657 		struct bwn_dmadesc32 dma32;
658 		struct bwn_dmadesc64 dma64;
659 	} __packed dma;
660 } __packed;
661 
662 struct bwn_dma_ring;
663 
664 struct bwn_dma_ring {
665 	struct bwn_mac			*dr_mac;
666 	const struct bwn_dma_ops	*dr_ops;
667 	struct bwn_dmadesc_meta		*dr_meta;
668 	void				*dr_txhdr_cache;
669 	bus_dma_tag_t			dr_ring_dtag;
670 	bus_dma_tag_t			dr_txring_dtag;
671 	bus_dmamap_t			dr_spare_dmap; /* only for RX */
672 	bus_dmamap_t			dr_ring_dmap;
673 	bus_addr_t			dr_txring_paddr;
674 	void				*dr_ring_descbase;
675 	bus_addr_t			dr_ring_dmabase;
676 	int				dr_numslots;
677 	int				dr_usedslot;
678 	int				dr_curslot;
679 	uint32_t			dr_frameoffset;
680 	uint16_t			dr_rx_bufsize;
681 	uint16_t			dr_base;
682 	int				dr_index;
683 	uint8_t				dr_tx;
684 	uint8_t				dr_stop;
685 	int				dr_type;
686 
687 	void				(*getdesc)(struct bwn_dma_ring *,
688 					    int, struct bwn_dmadesc_generic **,
689 					    struct bwn_dmadesc_meta **);
690 	void				(*setdesc)(struct bwn_dma_ring *,
691 					    struct bwn_dmadesc_generic *,
692 					    bus_addr_t, uint16_t, int, int,
693 					    int);
694 	void				(*start_transfer)(struct bwn_dma_ring *,
695 					    int);
696 	void				(*suspend)(struct bwn_dma_ring *);
697 	void				(*resume)(struct bwn_dma_ring *);
698 	int				(*get_curslot)(struct bwn_dma_ring *);
699 	void				(*set_curslot)(struct bwn_dma_ring *,
700 					    int);
701 };
702 
703 struct bwn_dma {
704 	int				dmatype;
705 	bus_dma_tag_t			parent_dtag;
706 	bus_dma_tag_t			rxbuf_dtag;
707 	bus_dma_tag_t			txbuf_dtag;
708 
709 	struct bwn_dma_ring		*wme[5];
710 	struct bwn_dma_ring		*mcast;
711 	struct bwn_dma_ring		*rx;
712 	uint64_t			lastseq;	/* XXX FIXME */
713 };
714 
715 struct bwn_pio_rxqueue {
716 	struct bwn_mac			*prq_mac;
717 	uint16_t			prq_base;
718 	uint8_t				prq_rev;
719 };
720 
721 struct bwn_pio_txqueue;
722 struct bwn_pio_txpkt {
723 	struct bwn_pio_txqueue		*tp_queue;
724 	struct ieee80211_node		*tp_ni;
725 	struct mbuf			*tp_m;
726 	uint8_t				tp_index;
727 	TAILQ_ENTRY(bwn_pio_txpkt)	tp_list;
728 };
729 
730 #define	BWN_PIO_MAX_TXPACKETS		32
731 struct bwn_pio_txqueue {
732 	uint16_t			tq_base;
733 	uint16_t			tq_size;
734 	uint16_t			tq_used;
735 	uint16_t			tq_free;
736 	uint8_t				tq_index;
737 	struct bwn_pio_txpkt		tq_pkts[BWN_PIO_MAX_TXPACKETS];
738 	TAILQ_HEAD(, bwn_pio_txpkt)	tq_pktlist;
739 };
740 
741 struct bwn_pio {
742 	struct bwn_pio_txqueue		wme[5];
743 	struct bwn_pio_txqueue		mcast;
744 	struct bwn_pio_rxqueue		rx;
745 };
746 
747 struct bwn_plcp4 {
748 	union {
749 		uint32_t		data;
750 		uint8_t			raw[4];
751 	} __packed o;
752 } __packed;
753 
754 struct bwn_plcp6 {
755 	union {
756 		uint32_t		data;
757 		uint8_t			raw[6];
758 	} __packed o;
759 } __packed;
760 
761 struct bwn_txhdr {
762 	uint32_t			macctl;
763 	uint8_t				macfc[2];
764 	uint16_t			tx_festime;
765 	uint16_t			phyctl;
766 	uint16_t			phyctl_1;
767 	uint16_t			phyctl_1fb;
768 	uint16_t			phyctl_1rts;
769 	uint16_t			phyctl_1rtsfb;
770 	uint8_t				phyrate;
771 	uint8_t				phyrate_rts;
772 	uint8_t				eftypes;	/* extra frame types */
773 	uint8_t				chan;
774 	uint8_t				iv[16];
775 	uint8_t				addr1[IEEE80211_ADDR_LEN];
776 	uint16_t			tx_festime_fb;
777 	struct bwn_plcp6		rts_plcp_fb;
778 	uint16_t			rts_dur_fb;
779 	struct bwn_plcp6		plcp_fb;
780 	uint16_t			dur_fb;
781 	uint16_t			mimo_modelen;
782 	uint16_t			mimo_ratelen_fb;
783 	uint32_t			timeout;
784 
785 	union {
786 		/* format <= r351 */
787 		struct {
788 			uint8_t		pad0[2];
789 			uint16_t	cookie;
790 			uint16_t	tx_status;
791 			struct bwn_plcp6	rts_plcp;
792 			uint8_t		rts_frame[16];
793 			uint8_t		pad1[2];
794 			struct bwn_plcp6	plcp;
795 		} __packed r351;
796 		/* format > r410 < r598 */
797 		struct {
798 			uint16_t	mimo_antenna;
799 			uint16_t	preload_size;
800 			uint8_t		pad0[2];
801 			uint16_t	cookie;
802 			uint16_t	tx_status;
803 			struct bwn_plcp6	rts_plcp;
804 			uint8_t		rts_frame[16];
805 			uint8_t		pad1[2];
806 			struct bwn_plcp6	plcp;
807 		} __packed r410;
808 		struct {
809 			uint16_t	mimo_antenna;
810 			uint16_t	preload_size;
811 			uint8_t		pad0[2];
812 			uint16_t	cookie;
813 			uint16_t	tx_status;
814 			uint16_t	max_n_mpdus;
815 			uint16_t	max_a_bytes_mrt;
816 			uint16_t	max_a_bytes_fbr;
817 			uint16_t	min_m_bytes;
818 			struct bwn_plcp6	rts_plcp;
819 			uint8_t		rts_frame[16];
820 			uint8_t		pad1[2];
821 			struct bwn_plcp6	plcp;
822 		} __packed r598;
823 	} __packed body;
824 } __packed;
825 
826 #define	BWN_FWTYPE_UCODE		'u'
827 #define	BWN_FWTYPE_PCM			'p'
828 #define	BWN_FWTYPE_IV			'i'
829 struct bwn_fwhdr {
830 	uint8_t				type;
831 	uint8_t				ver;
832 	uint8_t				pad[2];
833 	uint32_t			size;
834 } __packed;
835 
836 #define	BWN_FWINITVALS_OFFSET_MASK	0x7fff
837 #define	BWN_FWINITVALS_32BIT		0x8000
838 struct bwn_fwinitvals {
839 	uint16_t			offset_size;
840 	union {
841 		uint16_t		d16;
842 		uint32_t		d32;
843 	} __packed data;
844 } __packed;
845 
846 enum bwn_fw_hdr_format {
847 	BWN_FW_HDR_598,
848 	BWN_FW_HDR_410,
849 	BWN_FW_HDR_351,
850 };
851 
852 enum bwn_fwtype {
853 	BWN_FWTYPE_DEFAULT,
854 	BWN_FWTYPE_OPENSOURCE,
855 	BWN_NR_FWTYPES,
856 };
857 
858 struct bwn_fwfile {
859 	const char			*filename;
860 	const struct firmware		*fw;
861 	enum bwn_fwtype			type;
862 };
863 
864 struct bwn_key {
865 	void				*keyconf;
866 	uint8_t				algorithm;
867 };
868 
869 struct bwn_fw {
870 	struct bwn_fwfile		ucode;
871 	struct bwn_fwfile		pcm;
872 	struct bwn_fwfile		initvals;
873 	struct bwn_fwfile		initvals_band;
874 	enum bwn_fw_hdr_format		fw_hdr_format;
875 
876 	uint16_t			rev;
877 	uint16_t			patch;
878 	uint8_t				opensource;
879 	uint8_t				no_pcmfile;
880 };
881 
882 struct bwn_lo_g_sm {
883 	int				curstate;
884 	int				nmeasure;
885 	int				multipler;
886 	uint16_t			feedth;
887 	struct bwn_loctl		loctl;
888 };
889 
890 struct bwn_lo_g_value {
891 	uint8_t				old_channel;
892 	uint16_t			phy_lomask;
893 	uint16_t			phy_extg;
894 	uint16_t			phy_dacctl_hwpctl;
895 	uint16_t			phy_dacctl;
896 	uint16_t			phy_hpwr_tssictl;
897 	uint16_t			phy_analogover;
898 	uint16_t			phy_analogoverval;
899 	uint16_t			phy_rfover;
900 	uint16_t			phy_rfoverval;
901 	uint16_t			phy_classctl;
902 	uint16_t			phy_crs0;
903 	uint16_t			phy_pgactl;
904 	uint16_t			phy_syncctl;
905 	uint16_t			phy_cck0;
906 	uint16_t			phy_cck1;
907 	uint16_t			phy_cck2;
908 	uint16_t			phy_cck3;
909 	uint16_t			phy_cck4;
910 	uint16_t			reg0;
911 	uint16_t			reg1;
912 	uint16_t			rf0;
913 	uint16_t			rf1;
914 	uint16_t			rf2;
915 };
916 
917 #define	BWN_LED_MAX			4
918 
919 #define	BWN_LED_EVENT_NONE		-1
920 #define	BWN_LED_EVENT_POLL		0
921 #define	BWN_LED_EVENT_TX		1
922 #define	BWN_LED_EVENT_RX		2
923 #define	BWN_LED_SLOWDOWN(dur)		(dur) = (((dur) * 3) / 2)
924 
925 struct bwn_led {
926 	uint8_t				led_flags;	/* BWN_LED_F_ */
927 	uint8_t				led_act;	/* BWN_LED_ACT_ */
928 	uint8_t				led_mask;
929 };
930 
931 #define	BWN_LED_F_ACTLOW		0x1
932 #define	BWN_LED_F_BLINK			0x2
933 #define	BWN_LED_F_POLLABLE		0x4
934 #define	BWN_LED_F_SLOW			0x8
935 
936 struct bwn_mac {
937 	struct bwn_softc		*mac_sc;
938 	unsigned			mac_status;
939 #define	BWN_MAC_STATUS_UNINIT		0
940 #define	BWN_MAC_STATUS_INITED		1
941 #define	BWN_MAC_STATUS_STARTED		2
942 	unsigned			mac_flags;
943 	/* use "Bad Frames Preemption" */
944 #define	BWN_MAC_FLAG_BADFRAME_PREEMP	(1 << 0)
945 #define	BWN_MAC_FLAG_DFQVALID		(1 << 1)
946 #define	BWN_MAC_FLAG_RADIO_ON		(1 << 2)
947 #define	BWN_MAC_FLAG_DMA		(1 << 3)
948 #define	BWN_MAC_FLAG_WME		(1 << 4)
949 #define	BWN_MAC_FLAG_HWCRYPTO		(1 << 5)
950 
951 	struct resource_spec		*mac_intr_spec;
952 #define	BWN_MSI_MESSAGES		1
953 	struct resource			*mac_res_irq[BWN_MSI_MESSAGES];
954 	void				*mac_intrhand[BWN_MSI_MESSAGES];
955 	int				mac_msi;
956 
957 	struct bwn_noise		mac_noise;
958 	struct bwn_phy			mac_phy;
959 	struct bwn_stats		mac_stats;
960 	uint32_t			mac_reason_intr;
961 	uint32_t			mac_reason[6];
962 	uint32_t			mac_intr_mask;
963 	int				mac_suspended;
964 
965 	struct bwn_fw			mac_fw;
966 
967 	union {
968 		struct bwn_dma		dma;
969 		struct bwn_pio		pio;
970 	} mac_method;
971 
972 	uint16_t			mac_ktp;	/* Key table pointer */
973 	uint8_t				mac_max_nr_keys;
974 	struct bwn_key			mac_key[58];
975 
976 	unsigned int			mac_task_state;
977 	struct task			mac_intrtask;
978 	struct task			mac_hwreset;
979 	struct task			mac_txpower;
980 
981 	TAILQ_ENTRY(bwn_mac)	mac_list;
982 };
983 
984 static inline int
985 bwn_tx_hdrsize(struct bwn_mac *mac)
986 {
987 	switch (mac->mac_fw.fw_hdr_format) {
988 	case BWN_FW_HDR_598:
989 		return (112 + (sizeof(struct bwn_plcp6)));
990 	case BWN_FW_HDR_410:
991 		return (104 + (sizeof(struct bwn_plcp6)));
992 	case BWN_FW_HDR_351:
993 		return (100 + (sizeof(struct bwn_plcp6)));
994 	default:
995 		printf("%s: unknown header format (%d)\n", __func__,
996 		    mac->mac_fw.fw_hdr_format);
997 		return (112 + (sizeof(struct bwn_plcp6)));
998 	}
999 }
1000 
1001 /*
1002  * Driver-specific vap state.
1003  */
1004 struct bwn_vap {
1005 	struct ieee80211vap		bv_vap;	/* base class */
1006 	int				(*bv_newstate)(struct ieee80211vap *,
1007 					    enum ieee80211_state, int);
1008 };
1009 #define	BWN_VAP(vap)			((struct bwn_vap *)(vap))
1010 #define	BWN_VAP_CONST(vap)		((const struct mwl_vap *)(vap))
1011 
1012 struct bwn_softc {
1013 	device_t			sc_dev;
1014 	const struct bwn_bus_ops	*sc_bus_ops;
1015 #if !BWN_USE_SIBA
1016 	void				*sc_bus_ctx;
1017 	struct bhnd_resource		*sc_mem_res;
1018 	int				 sc_mem_rid;
1019 #endif /* !BWN_USE_SIBA */
1020 	struct mtx			sc_mtx;
1021 	struct ieee80211com		sc_ic;
1022 	struct mbufq			sc_snd;
1023 	unsigned			sc_flags;
1024 #define	BWN_FLAG_ATTACHED		(1 << 0)
1025 #define	BWN_FLAG_INVALID		(1 << 1)
1026 #define	BWN_FLAG_NEED_BEACON_TP		(1 << 2)
1027 #define	BWN_FLAG_RUNNING		(1 << 3)
1028 	unsigned			sc_debug;
1029 
1030 	struct bwn_mac		*sc_curmac;
1031 	TAILQ_HEAD(, bwn_mac)	sc_maclist;
1032 
1033 	uint8_t				sc_bssid[IEEE80211_ADDR_LEN];
1034 	unsigned int			sc_filters;
1035 	uint8_t				sc_beacons[2];
1036 	uint8_t				sc_rf_enabled;
1037 
1038 	struct wmeParams		sc_wmeParams[4];
1039 
1040 	struct callout			sc_rfswitch_ch;	/* for laptop */
1041 	struct callout			sc_task_ch;
1042 	struct callout			sc_watchdog_ch;
1043 	int				sc_watchdog_timer;
1044 	struct taskqueue		*sc_tq;	/* private task queue */
1045 	int				(*sc_newstate)(struct ieee80211com *,
1046 					    enum ieee80211_state, int);
1047 	void				(*sc_node_cleanup)(
1048 					    struct ieee80211_node *);
1049 
1050 	int				sc_rx_rate;
1051 	int				sc_tx_rate;
1052 
1053 	int				sc_led_blinking;
1054 	int				sc_led_ticks;
1055 	struct bwn_led			*sc_blink_led;
1056 	struct callout			sc_led_blink_ch;
1057 	int				sc_led_blink_offdur;
1058 	struct bwn_led			sc_leds[BWN_LED_MAX];
1059 	int				sc_led_idle;
1060 	int				sc_led_blink;
1061 
1062 	struct bwn_tx_radiotap_header	sc_tx_th;
1063 	struct bwn_rx_radiotap_header	sc_rx_th;
1064 };
1065 
1066 #define	BWN_LOCK_INIT(sc) \
1067 	mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \
1068 	    MTX_NETWORK_LOCK, MTX_DEF)
1069 #define	BWN_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx)
1070 #define	BWN_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
1071 #define	BWN_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
1072 #define	BWN_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)
1073 
1074 static inline bwn_band_t
1075 bwn_channel_band(struct bwn_mac *mac, struct ieee80211_channel *c)
1076 {
1077 	if (IEEE80211_IS_CHAN_5GHZ(c))
1078 		return BWN_BAND_5G;
1079 	/* XXX check 2g, log error if not 2g or 5g? */
1080 	return BWN_BAND_2G;
1081 }
1082 
1083 static inline bwn_band_t
1084 bwn_current_band(struct bwn_mac *mac)
1085 {
1086 	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1087 	if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
1088 		return BWN_BAND_5G;
1089 	/* XXX check 2g, log error if not 2g or 5g? */
1090 	return BWN_BAND_2G;
1091 }
1092 
1093 static inline bool
1094 bwn_is_40mhz(struct bwn_mac *mac)
1095 {
1096 	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1097 
1098 	return !! (IEEE80211_IS_CHAN_HT40(ic->ic_curchan));
1099 }
1100 
1101 static inline int
1102 bwn_get_centre_freq(struct bwn_mac *mac)
1103 {
1104 
1105 	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1106 	/* XXX TODO: calculate correctly for HT40 mode */
1107 	return ic->ic_curchan->ic_freq;
1108 }
1109 
1110 static inline int
1111 bwn_get_chan_centre_freq(struct bwn_mac *mac, struct ieee80211_channel *chan)
1112 {
1113 
1114 	/* XXX TODO: calculate correctly for HT40 mode */
1115 	return chan->ic_freq;
1116 }
1117 
1118 static inline int
1119 bwn_get_chan(struct bwn_mac *mac)
1120 {
1121 
1122 	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1123 	/* XXX TODO: calculate correctly for HT40 mode */
1124 	return ic->ic_curchan->ic_ieee;
1125 }
1126 
1127 static inline struct ieee80211_channel *
1128 bwn_get_channel(struct bwn_mac *mac)
1129 {
1130 
1131 	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1132 	return ic->ic_curchan;
1133 }
1134 
1135 static inline bool
1136 bwn_is_chan_passive(struct bwn_mac *mac)
1137 {
1138 
1139 	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1140 	return !! IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan);
1141 }
1142 
1143 static inline bwn_chan_type_t
1144 bwn_get_chan_type(struct bwn_mac *mac, struct ieee80211_channel *c)
1145 {
1146 	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1147 	if (c == NULL)
1148 		c = ic->ic_curchan;
1149 	if (IEEE80211_IS_CHAN_HT40U(c))
1150 		return BWN_CHAN_TYPE_40_HT_U;
1151 	else if (IEEE80211_IS_CHAN_HT40D(c))
1152 		return BWN_CHAN_TYPE_40_HT_D;
1153 	else if (IEEE80211_IS_CHAN_HT20(c))
1154 		return BWN_CHAN_TYPE_20_HT;
1155 	else
1156 		return BWN_CHAN_TYPE_20;
1157 }
1158 
1159 static inline int
1160 bwn_get_chan_power(struct bwn_mac *mac, struct ieee80211_channel *c)
1161 {
1162 
1163 	/* return in dbm */
1164 	return c->ic_maxpower / 2;
1165 }
1166 
1167 #endif	/* !_IF_BWNVAR_H */
1168